static int vmd_read_header(AVFormatContext *s,

                           AVFormatParameters *ap)

{

    VmdDemuxContext *vmd = (VmdDemuxContext *)s->priv_data;

    ByteIOContext *pb = &s->pb;

    AVStream *st;

    unsigned int toc_offset;

    unsigned char *raw_frame_table;

    int raw_frame_table_size;

    offset_t current_offset;

    int i, j;

    unsigned int total_frames;

    int64_t video_pts_inc = 0;

    int64_t current_video_pts = 0;

    unsigned char chunk[BYTES_PER_FRAME_RECORD];

    int lastframe = 0;



    /* fetch the main header, including the 2 header length bytes */

    url_fseek(pb, 0, SEEK_SET);

    if (get_buffer(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE)

        return AVERROR_IO;



    vmd->audio_sample_counter = 0;

    vmd->audio_frame_divisor = 1;

    vmd->audio_block_align = 1;



    /* start up the decoders */

    st = av_new_stream(s, 0);

    if (!st)

        return AVERROR_NOMEM;

    av_set_pts_info(st, 33, 1, 90000);

    vmd->video_stream_index = st->index;

    st->codec->codec_type = CODEC_TYPE_VIDEO;

    st->codec->codec_id = CODEC_ID_VMDVIDEO;

    st->codec->codec_tag = 0;  /* no fourcc */

    st->codec->width = LE_16(&vmd->vmd_header[12]);

    st->codec->height = LE_16(&vmd->vmd_header[14]);

    st->codec->time_base.num = 1;

    st->codec->time_base.den = 10;

    st->codec->extradata_size = VMD_HEADER_SIZE;

    st->codec->extradata = av_mallocz(VMD_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

    memcpy(st->codec->extradata, vmd->vmd_header, VMD_HEADER_SIZE);



    /* if sample rate is 0, assume no audio */

    vmd->sample_rate = LE_16(&vmd->vmd_header[804]);

    if (vmd->sample_rate) {

        st = av_new_stream(s, 0);

        if (!st)

            return AVERROR_NOMEM;

        av_set_pts_info(st, 33, 1, 90000);

        vmd->audio_stream_index = st->index;

        st->codec->codec_type = CODEC_TYPE_AUDIO;

        st->codec->codec_id = CODEC_ID_VMDAUDIO;

        st->codec->codec_tag = 0;  /* no fourcc */

        st->codec->channels = vmd->audio_channels = (vmd->vmd_header[811] & 0x80) ? 2 : 1;

        st->codec->sample_rate = vmd->sample_rate;

        st->codec->block_align = vmd->audio_block_align =

            LE_16(&vmd->vmd_header[806]);

        if (st->codec->block_align & 0x8000) {

            st->codec->bits_per_sample = 16;

            st->codec->block_align = -(st->codec->block_align - 0x10000);

            vmd->audio_block_align = -(vmd->audio_block_align - 0x10000);

        } else {

            st->codec->bits_per_sample = 8;


        st->codec->bit_rate = st->codec->sample_rate *

            st->codec->bits_per_sample * st->codec->channels;



        /* for calculating pts */

        vmd->audio_frame_divisor = st->codec->channels;



        video_pts_inc = 90000;

        video_pts_inc *= st->codec->block_align;

        video_pts_inc /= st->codec->sample_rate;

        video_pts_inc /= st->codec->channels;

    } else {

        /* if no audio, assume 10 frames/second */

        video_pts_inc = 90000 / 10;




    toc_offset = LE_32(&vmd->vmd_header[812]);

    vmd->frame_count = LE_16(&vmd->vmd_header[6]);

    vmd->frames_per_block = LE_16(&vmd->vmd_header[18]);

    url_fseek(pb, toc_offset, SEEK_SET);



    raw_frame_table = NULL;

    vmd->frame_table = NULL;

    raw_frame_table_size = vmd->frame_count * 6;

    raw_frame_table = av_malloc(raw_frame_table_size);





    vmd->frame_table = av_malloc(vmd->frame_count * vmd->frames_per_block * sizeof(vmd_frame_t));

    if (!raw_frame_table || !vmd->frame_table) {

        av_free(raw_frame_table);

        av_free(vmd->frame_table);

        return AVERROR_NOMEM;


    if (get_buffer(pb, raw_frame_table, raw_frame_table_size) !=

        raw_frame_table_size) {

        av_free(raw_frame_table);

        av_free(vmd->frame_table);

        return AVERROR_IO;




    total_frames = 0;

    for (i = 0; i < vmd->frame_count; i++) {



        current_offset = LE_32(&raw_frame_table[6 * i + 2]);



        /* handle each entry in index block */

        for (j = 0; j < vmd->frames_per_block; j++) {

            int type;

            uint32_t size;



            get_buffer(pb, chunk, BYTES_PER_FRAME_RECORD);

            type = chunk[0];

            size = LE_32(&chunk[2]);

            if(!size)

                continue;

            switch(type) {

            case 1: /* Audio Chunk */

                vmd->frame_table[total_frames].frame_offset = current_offset;

                vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;

                vmd->frame_table[total_frames].frame_size = size;

                memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);

                total_frames++;

                break;

            case 2: /* Video Chunk */

                vmd->frame_table[total_frames].frame_offset = current_offset;

                vmd->frame_table[total_frames].frame_size = size;

                vmd->frame_table[total_frames].stream_index = vmd->video_stream_index;

                memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);

                vmd->frame_table[total_frames].pts = current_video_pts;

                if (lastframe) {

                    vmd->frame_table[lastframe].pts = current_video_pts - video_pts_inc;


                lastframe = total_frames;

                total_frames++;

                break;


            current_offset += size;


        current_video_pts += video_pts_inc;




    av_free(raw_frame_table);



    vmd->current_frame = 0;

    vmd->frame_count = total_frames;



    return 0;

static int vmd_read_header(AVFormatContext *s,

                           AVFormatParameters *ap)

{

    VmdDemuxContext *vmd = (VmdDemuxContext *)s->priv_data;

    ByteIOContext *pb = &s->pb;

    AVStream *st;

    unsigned int toc_offset;

    unsigned char *raw_frame_table;

    int raw_frame_table_size;

    offset_t current_offset;

    int i, j;

    unsigned int total_frames;

    int64_t video_pts_inc = 0;

    int64_t current_video_pts = 0;

    unsigned char chunk[BYTES_PER_FRAME_RECORD];

    int lastframe = 0;



    

    url_fseek(pb, 0, SEEK_SET);

    if (get_buffer(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE)

        return AVERROR_IO;



    vmd->audio_sample_counter = 0;

    vmd->audio_frame_divisor = 1;

    vmd->audio_block_align = 1;



    

    st = av_new_stream(s, 0);

    if (!st)

        return AVERROR_NOMEM;

    av_set_pts_info(st, 33, 1, 90000);

    vmd->video_stream_index = st->index;

    st->codec->codec_type = CODEC_TYPE_VIDEO;

    st->codec->codec_id = CODEC_ID_VMDVIDEO;

    st->codec->codec_tag = 0;  

    st->codec->width = LE_16(&vmd->vmd_header[12]);

    st->codec->height = LE_16(&vmd->vmd_header[14]);

    st->codec->time_base.num = 1;

    st->codec->time_base.den = 10;

    st->codec->extradata_size = VMD_HEADER_SIZE;

    st->codec->extradata = av_mallocz(VMD_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

    memcpy(st->codec->extradata, vmd->vmd_header, VMD_HEADER_SIZE);



    

    vmd->sample_rate = LE_16(&vmd->vmd_header[804]);

    if (vmd->sample_rate) {

        st = av_new_stream(s, 0);

        if (!st)

            return AVERROR_NOMEM;

        av_set_pts_info(st, 33, 1, 90000);

        vmd->audio_stream_index = st->index;

        st->codec->codec_type = CODEC_TYPE_AUDIO;

        st->codec->codec_id = CODEC_ID_VMDAUDIO;

        st->codec->codec_tag = 0;  

        st->codec->channels = vmd->audio_channels = (vmd->vmd_header[811] & 0x80) ? 2 : 1;

        st->codec->sample_rate = vmd->sample_rate;

        st->codec->block_align = vmd->audio_block_align =

            LE_16(&vmd->vmd_header[806]);

        if (st->codec->block_align & 0x8000) {

            st->codec->bits_per_sample = 16;

            st->codec->block_align = -(st->codec->block_align - 0x10000);

            vmd->audio_block_align = -(vmd->audio_block_align - 0x10000);

        } else {

            st->codec->bits_per_sample = 8;


        st->codec->bit_rate = st->codec->sample_rate *

            st->codec->bits_per_sample * st->codec->channels;



        

        vmd->audio_frame_divisor = st->codec->channels;



        video_pts_inc = 90000;

        video_pts_inc *= st->codec->block_align;

        video_pts_inc /= st->codec->sample_rate;

        video_pts_inc /= st->codec->channels;

    } else {

        

        video_pts_inc = 90000 / 10;




    toc_offset = LE_32(&vmd->vmd_header[812]);

    vmd->frame_count = LE_16(&vmd->vmd_header[6]);

    vmd->frames_per_block = LE_16(&vmd->vmd_header[18]);

    url_fseek(pb, toc_offset, SEEK_SET);



    raw_frame_table = NULL;

    vmd->frame_table = NULL;

    raw_frame_table_size = vmd->frame_count * 6;

    raw_frame_table = av_malloc(raw_frame_table_size);





    vmd->frame_table = av_malloc(vmd->frame_count * vmd->frames_per_block * sizeof(vmd_frame_t));

    if (!raw_frame_table || !vmd->frame_table) {

        av_free(raw_frame_table);

        av_free(vmd->frame_table);

        return AVERROR_NOMEM;


    if (get_buffer(pb, raw_frame_table, raw_frame_table_size) !=

        raw_frame_table_size) {

        av_free(raw_frame_table);

        av_free(vmd->frame_table);

        return AVERROR_IO;




    total_frames = 0;

    for (i = 0; i < vmd->frame_count; i++) {



        current_offset = LE_32(&raw_frame_table[6 * i + 2]);



        

        for (j = 0; j < vmd->frames_per_block; j++) {

            int type;

            uint32_t size;



            get_buffer(pb, chunk, BYTES_PER_FRAME_RECORD);

            type = chunk[0];

            size = LE_32(&chunk[2]);

            if(!size)

                continue;

            switch(type) {

            case 1: 

                vmd->frame_table[total_frames].frame_offset = current_offset;

                vmd->frame_table[total_frames].stream_index = vmd->audio_stream_index;

                vmd->frame_table[total_frames].frame_size = size;

                memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);

                total_frames++;

                break;

            case 2: 

                vmd->frame_table[total_frames].frame_offset = current_offset;

                vmd->frame_table[total_frames].frame_size = size;

                vmd->frame_table[total_frames].stream_index = vmd->video_stream_index;

                memcpy(vmd->frame_table[total_frames].frame_record, chunk, BYTES_PER_FRAME_RECORD);

                vmd->frame_table[total_frames].pts = current_video_pts;

                if (lastframe) {

                    vmd->frame_table[lastframe].pts = current_video_pts - video_pts_inc;


                lastframe = total_frames;

                total_frames++;

                break;


            current_offset += size;


        current_video_pts += video_pts_inc;




    av_free(raw_frame_table);



    vmd->current_frame = 0;

    vmd->frame_count = total_frames;



    return 0;

static int FUNC_0(AVFormatContext *VAR_0,

                           AVFormatParameters *VAR_1)

{

    VmdDemuxContext *vmd = (VmdDemuxContext *)VAR_0->priv_data;

    ByteIOContext *pb = &VAR_0->pb;

    AVStream *st;

    unsigned int VAR_2;

    unsigned char *VAR_3;

    int VAR_4;

    offset_t current_offset;

    int VAR_5, VAR_6;

    unsigned int VAR_7;

    int64_t video_pts_inc = 0;

    int64_t current_video_pts = 0;

    unsigned char VAR_8[BYTES_PER_FRAME_RECORD];

    int VAR_9 = 0;



    

    url_fseek(pb, 0, SEEK_SET);

    if (get_buffer(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE)

        return AVERROR_IO;



    vmd->audio_sample_counter = 0;

    vmd->audio_frame_divisor = 1;

    vmd->audio_block_align = 1;



    

    st = av_new_stream(VAR_0, 0);

    if (!st)

        return AVERROR_NOMEM;

    av_set_pts_info(st, 33, 1, 90000);

    vmd->video_stream_index = st->index;

    st->codec->codec_type = CODEC_TYPE_VIDEO;

    st->codec->codec_id = CODEC_ID_VMDVIDEO;

    st->codec->codec_tag = 0;  

    st->codec->width = LE_16(&vmd->vmd_header[12]);

    st->codec->height = LE_16(&vmd->vmd_header[14]);

    st->codec->time_base.num = 1;

    st->codec->time_base.den = 10;

    st->codec->extradata_size = VMD_HEADER_SIZE;

    st->codec->extradata = av_mallocz(VMD_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

    memcpy(st->codec->extradata, vmd->vmd_header, VMD_HEADER_SIZE);



    

    vmd->sample_rate = LE_16(&vmd->vmd_header[804]);

    if (vmd->sample_rate) {

        st = av_new_stream(VAR_0, 0);

        if (!st)

            return AVERROR_NOMEM;

        av_set_pts_info(st, 33, 1, 90000);

        vmd->audio_stream_index = st->index;

        st->codec->codec_type = CODEC_TYPE_AUDIO;

        st->codec->codec_id = CODEC_ID_VMDAUDIO;

        st->codec->codec_tag = 0;  

        st->codec->channels = vmd->audio_channels = (vmd->vmd_header[811] & 0x80) ? 2 : 1;

        st->codec->sample_rate = vmd->sample_rate;

        st->codec->block_align = vmd->audio_block_align =

            LE_16(&vmd->vmd_header[806]);

        if (st->codec->block_align & 0x8000) {

            st->codec->bits_per_sample = 16;

            st->codec->block_align = -(st->codec->block_align - 0x10000);

            vmd->audio_block_align = -(vmd->audio_block_align - 0x10000);

        } else {

            st->codec->bits_per_sample = 8;


        st->codec->bit_rate = st->codec->sample_rate *

            st->codec->bits_per_sample * st->codec->channels;



        

        vmd->audio_frame_divisor = st->codec->channels;



        video_pts_inc = 90000;

        video_pts_inc *= st->codec->block_align;

        video_pts_inc /= st->codec->sample_rate;

        video_pts_inc /= st->codec->channels;

    } else {

        

        video_pts_inc = 90000 / 10;




    VAR_2 = LE_32(&vmd->vmd_header[812]);

    vmd->frame_count = LE_16(&vmd->vmd_header[6]);

    vmd->frames_per_block = LE_16(&vmd->vmd_header[18]);

    url_fseek(pb, VAR_2, SEEK_SET);



    VAR_3 = NULL;

    vmd->frame_table = NULL;

    VAR_4 = vmd->frame_count * 6;

    VAR_3 = av_malloc(VAR_4);





    vmd->frame_table = av_malloc(vmd->frame_count * vmd->frames_per_block * sizeof(vmd_frame_t));

    if (!VAR_3 || !vmd->frame_table) {

        av_free(VAR_3);

        av_free(vmd->frame_table);

        return AVERROR_NOMEM;


    if (get_buffer(pb, VAR_3, VAR_4) !=

        VAR_4) {

        av_free(VAR_3);

        av_free(vmd->frame_table);

        return AVERROR_IO;




    VAR_7 = 0;

    for (VAR_5 = 0; VAR_5 < vmd->frame_count; VAR_5++) {



        current_offset = LE_32(&VAR_3[6 * VAR_5 + 2]);



        

        for (VAR_6 = 0; VAR_6 < vmd->frames_per_block; VAR_6++) {

            int type;

            uint32_t size;



            get_buffer(pb, VAR_8, BYTES_PER_FRAME_RECORD);

            type = VAR_8[0];

            size = LE_32(&VAR_8[2]);

            if(!size)

                continue;

            switch(type) {

            case 1: 

                vmd->frame_table[VAR_7].frame_offset = current_offset;

                vmd->frame_table[VAR_7].stream_index = vmd->audio_stream_index;

                vmd->frame_table[VAR_7].frame_size = size;

                memcpy(vmd->frame_table[VAR_7].frame_record, VAR_8, BYTES_PER_FRAME_RECORD);

                VAR_7++;

                break;

            case 2: 

                vmd->frame_table[VAR_7].frame_offset = current_offset;

                vmd->frame_table[VAR_7].frame_size = size;

                vmd->frame_table[VAR_7].stream_index = vmd->video_stream_index;

                memcpy(vmd->frame_table[VAR_7].frame_record, VAR_8, BYTES_PER_FRAME_RECORD);

                vmd->frame_table[VAR_7].pts = current_video_pts;

                if (VAR_9) {

                    vmd->frame_table[VAR_9].pts = current_video_pts - video_pts_inc;


                VAR_9 = VAR_7;

                VAR_7++;

                break;


            current_offset += size;


        current_video_pts += video_pts_inc;




    av_free(VAR_3);



    vmd->current_frame = 0;

    vmd->frame_count = VAR_7;



    return 0;

static int FUNC_0(AVFormatContext *VAR_0,
AVFormatParameters *VAR_1)
{ VmdDemuxContext *vmd = (VmdDemuxContext *)VAR_0->priv_data; ByteIOContext *pb = &VAR_0->pb; AVStream *st; unsigned int VAR_2; unsigned char *VAR_3; int VAR_4; offset_t current_offset; int VAR_5, VAR_6; unsigned int VAR_7; int64_t video_pts_inc = 0; int64_t current_video_pts = 0; unsigned char VAR_8[BYTES_PER_FRAME_RECORD]; int VAR_9 = 0; url_fseek(pb, 0, SEEK_SET); if (get_buffer(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE)
return AVERROR_IO; vmd->audio_sample_counter = 0; vmd->audio_frame_divisor = 1; vmd->audio_block_align = 1; st = av_new_stream(VAR_0, 0); if (!st)
return AVERROR_NOMEM; av_set_pts_info(st, 33, 1, 90000); vmd->video_stream_index = st->index; st->codec->codec_type = CODEC_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_VMDVIDEO; st->codec->codec_tag = 0; st->codec->width = LE_16(&vmd->vmd_header[12]); st->codec->height = LE_16(&vmd->vmd_header[14]); st->codec->time_base.num = 1; st->codec->time_base.den = 10; st->codec->extradata_size = VMD_HEADER_SIZE; st->codec->extradata = av_mallocz(VMD_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(st->codec->extradata, vmd->vmd_header, VMD_HEADER_SIZE); vmd->sample_rate = LE_16(&vmd->vmd_header[804]); if (vmd->sample_rate) { st = av_new_stream(VAR_0, 0); if (!st)
return AVERROR_NOMEM; av_set_pts_info(st, 33, 1, 90000); vmd->audio_stream_index = st->index; st->codec->codec_type = CODEC_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_VMDAUDIO; st->codec->codec_tag = 0; st->codec->channels = vmd->audio_channels = (vmd->vmd_header[811] & 0x80) ? 2 : 1; st->codec->sample_rate = vmd->sample_rate; st->codec->block_align = vmd->audio_block_align =
LE_16(&vmd->vmd_header[806]); if (st->codec->block_align & 0x8000) { st->codec->bits_per_sample = 16; st->codec->block_align = -(st->codec->block_align - 0x10000); vmd->audio_block_align = -(vmd->audio_block_align - 0x10000); } else { st->codec->bits_per_sample = 8; st->codec->bit_rate = st->codec->sample_rate *
st->codec->bits_per_sample * st->codec->channels; vmd->audio_frame_divisor = st->codec->channels; video_pts_inc = 90000; video_pts_inc *= st->codec->block_align; video_pts_inc /= st->codec->sample_rate; video_pts_inc /= st->codec->channels; } else { video_pts_inc = 90000 / 10; VAR_2 = LE_32(&vmd->vmd_header[812]); vmd->frame_count = LE_16(&vmd->vmd_header[6]); vmd->frames_per_block = LE_16(&vmd->vmd_header[18]); url_fseek(pb, VAR_2, SEEK_SET); VAR_3 = NULL; vmd->frame_table = NULL; VAR_4 = vmd->frame_count * 6; VAR_3 = av_malloc(VAR_4); vmd->frame_table = av_malloc(vmd->frame_count * vmd->frames_per_block * sizeof(vmd_frame_t)); if (!VAR_3 || !vmd->frame_table) { av_free(VAR_3); av_free(vmd->frame_table); return AVERROR_NOMEM; if (get_buffer(pb, VAR_3, VAR_4) !=
VAR_4) { av_free(VAR_3); av_free(vmd->frame_table); return AVERROR_IO; VAR_7 = 0; for (VAR_5 = 0; VAR_5 < vmd->frame_count; VAR_5++) { current_offset = LE_32(&VAR_3[6 * VAR_5 + 2]); for (VAR_6 = 0; VAR_6 < vmd->frames_per_block; VAR_6++) { int type; uint32_t size; get_buffer(pb, VAR_8, BYTES_PER_FRAME_RECORD); type = VAR_8[0]; size = LE_32(&VAR_8[2]); if(!size)
continue; switch(type) { case 1:
vmd->frame_table[VAR_7].frame_offset = current_offset; vmd->frame_table[VAR_7].stream_index = vmd->audio_stream_index; vmd->frame_table[VAR_7].frame_size = size; memcpy(vmd->frame_table[VAR_7].frame_record, VAR_8, BYTES_PER_FRAME_RECORD); VAR_7++; break; case 2:
vmd->frame_table[VAR_7].frame_offset = current_offset; vmd->frame_table[VAR_7].frame_size = size; vmd->frame_table[VAR_7].stream_index = vmd->video_stream_index; memcpy(vmd->frame_table[VAR_7].frame_record, VAR_8, BYTES_PER_FRAME_RECORD); vmd->frame_table[VAR_7].pts = current_video_pts; if (VAR_9) { vmd->frame_table[VAR_9].pts = current_video_pts - video_pts_inc; VAR_9 = VAR_7; VAR_7++; break; current_offset += size; current_video_pts += video_pts_inc; av_free(VAR_3); vmd->current_frame = 0; vmd->frame_count = VAR_7; return 0;