⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipmovie.c

📁 F:图像处理资料264264书籍ffmpeg-0.4.9-pre1VideoStream.rar 一个视频解压缩源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Interplay MVE File Demuxer * Copyright (c) 2003 The ffmpeg Project * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//** * @file ipmovie.c * Interplay MVE file demuxer * by Mike Melanson (melanson@pcisys.net) * For more information regarding the Interplay MVE file format, visit: *   http://www.pcisys.net/~melanson/codecs/ * The aforementioned site also contains a command line utility for parsing * IP MVE files so that you can get a good idea of the typical structure of * such files. This demuxer is not the best example to use if you are trying * to write your own as it uses a rather roundabout approach for splitting * up and sending out the chunks. */#include "avformat.h"/* debugging support: #define DEBUG_IPMOVIE as non-zero to see extremely * verbose information about the demux process */#define DEBUG_IPMOVIE 0#if DEBUG_IPMOVIE#define debug_ipmovie printf#elsestatic inline void debug_ipmovie(const char *format, ...) { }#endif#define IPMOVIE_SIGNATURE "Interplay MVE File\x1A\0"#define IPMOVIE_SIGNATURE_SIZE 20#define CHUNK_PREAMBLE_SIZE 4#define OPCODE_PREAMBLE_SIZE 4#define CHUNK_INIT_AUDIO   0x0000#define CHUNK_AUDIO_ONLY   0x0001#define CHUNK_INIT_VIDEO   0x0002#define CHUNK_VIDEO        0x0003#define CHUNK_SHUTDOWN     0x0004#define CHUNK_END          0x0005/* these last types are used internally */#define CHUNK_DONE         0xFFFC#define CHUNK_NOMEM        0xFFFD#define CHUNK_EOF          0xFFFE#define CHUNK_BAD          0xFFFF#define OPCODE_END_OF_STREAM           0x00#define OPCODE_END_OF_CHUNK            0x01#define OPCODE_CREATE_TIMER            0x02#define OPCODE_INIT_AUDIO_BUFFERS      0x03#define OPCODE_START_STOP_AUDIO        0x04#define OPCODE_INIT_VIDEO_BUFFERS      0x05#define OPCODE_UNKNOWN_06              0x06#define OPCODE_SEND_BUFFER             0x07#define OPCODE_AUDIO_FRAME             0x08#define OPCODE_SILENCE_FRAME           0x09#define OPCODE_INIT_VIDEO_MODE         0x0A#define OPCODE_CREATE_GRADIENT         0x0B#define OPCODE_SET_PALETTE             0x0C#define OPCODE_SET_PALETTE_COMPRESSED  0x0D#define OPCODE_UNKNOWN_0E              0x0E#define OPCODE_SET_DECODING_MAP        0x0F#define OPCODE_UNKNOWN_10              0x10#define OPCODE_VIDEO_DATA              0x11#define OPCODE_UNKNOWN_12              0x12#define OPCODE_UNKNOWN_13              0x13#define OPCODE_UNKNOWN_14              0x14#define OPCODE_UNKNOWN_15              0x15#define PALETTE_COUNT 256typedef struct IPMVEContext {    unsigned char *buf;    int buf_size;    float fps;    int frame_pts_inc;    unsigned int video_width;    unsigned int video_height;    int64_t video_pts;    unsigned int audio_bits;    unsigned int audio_channels;    unsigned int audio_sample_rate;    unsigned int audio_type;    unsigned int audio_frame_count;    int video_stream_index;    int audio_stream_index;    offset_t audio_chunk_offset;    int audio_chunk_size;    offset_t video_chunk_offset;    int video_chunk_size;    offset_t decode_map_chunk_offset;    int decode_map_chunk_size;    offset_t next_chunk_offset;    AVPaletteControl palette_control;} IPMVEContext;static int load_ipmovie_packet(IPMVEContext *s, ByteIOContext *pb,     AVPacket *pkt) {    int chunk_type;    int64_t audio_pts = 0;    if (s->audio_chunk_offset) {        /* adjust for PCM audio by skipping chunk header */        if (s->audio_type != CODEC_ID_INTERPLAY_DPCM) {            s->audio_chunk_offset += 6;            s->audio_chunk_size -= 6;        }        url_fseek(pb, s->audio_chunk_offset, SEEK_SET);        s->audio_chunk_offset = 0;        /* figure out the audio pts */        audio_pts = 90000;        audio_pts *= s->audio_frame_count;        audio_pts /= s->audio_sample_rate;        if (av_new_packet(pkt, s->audio_chunk_size))            return CHUNK_NOMEM;        pkt->stream_index = s->audio_stream_index;        pkt->pts = audio_pts;        if (get_buffer(pb, pkt->data, s->audio_chunk_size) !=             s->audio_chunk_size) {            av_free_packet(pkt);            return CHUNK_EOF;        }        /* audio frame maintenance */        if (s->audio_type != CODEC_ID_INTERPLAY_DPCM)            s->audio_frame_count +=            (s->audio_chunk_size / s->audio_channels / (s->audio_bits / 8));        else            s->audio_frame_count +=                (s->audio_chunk_size - 6) / s->audio_channels;        debug_ipmovie("sending audio frame with pts %lld (%d audio frames)\n",            audio_pts, s->audio_frame_count);        chunk_type = CHUNK_VIDEO;    } else if (s->decode_map_chunk_offset) {        /* send both the decode map and the video data together */        if (av_new_packet(pkt, s->decode_map_chunk_size + s->video_chunk_size))            return CHUNK_NOMEM;        url_fseek(pb, s->decode_map_chunk_offset, SEEK_SET);        s->decode_map_chunk_offset = 0;        if (get_buffer(pb, pkt->data, s->decode_map_chunk_size) !=             s->decode_map_chunk_size) {            av_free_packet(pkt);            return CHUNK_EOF;        }        url_fseek(pb, s->video_chunk_offset, SEEK_SET);        s->video_chunk_offset = 0;        if (get_buffer(pb, pkt->data + s->decode_map_chunk_size,            s->video_chunk_size) != s->video_chunk_size) {            av_free_packet(pkt);            return CHUNK_EOF;        }        pkt->stream_index = s->video_stream_index;        pkt->pts = s->video_pts;        debug_ipmovie("sending video frame with pts %lld\n",            pkt->pts);        s->video_pts += s->frame_pts_inc;        chunk_type = CHUNK_VIDEO;    } else {        url_fseek(pb, s->next_chunk_offset, SEEK_SET);        chunk_type = CHUNK_DONE;    }    return chunk_type;}/* This function loads and processes a single chunk in an IP movie file. * It returns the type of chunk that was processed. */static int process_ipmovie_chunk(IPMVEContext *s, ByteIOContext *pb,     AVPacket *pkt){    unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE];    int chunk_type;    int chunk_size;    unsigned char opcode_preamble[OPCODE_PREAMBLE_SIZE];    unsigned char opcode_type;    unsigned char opcode_version;    int opcode_size;    unsigned char scratch[1024];    int i, j;    int first_color, last_color;    int audio_flags;    unsigned char r, g, b;    /* see if there are any pending packets */    chunk_type = load_ipmovie_packet(s, pb, pkt);    if ((chunk_type == CHUNK_VIDEO) && (chunk_type != CHUNK_DONE))        return chunk_type;    /* read the next chunk, wherever the file happens to be pointing */    if (url_feof(pb))        return CHUNK_EOF;    if (get_buffer(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=        CHUNK_PREAMBLE_SIZE)        return CHUNK_BAD;    chunk_size = LE_16(&chunk_preamble[0]);    chunk_type = LE_16(&chunk_preamble[2]);    debug_ipmovie("chunk type 0x%04X, 0x%04X bytes: ", chunk_type, chunk_size);    switch (chunk_type) {    case CHUNK_INIT_AUDIO:        debug_ipmovie("initialize audio\n");        break;    case CHUNK_AUDIO_ONLY:        debug_ipmovie("audio only\n");        break;    case CHUNK_INIT_VIDEO:        debug_ipmovie("initialize video\n");        break;    case CHUNK_VIDEO:        debug_ipmovie("video (and audio)\n");        break;    case CHUNK_SHUTDOWN:        debug_ipmovie("shutdown\n");        break;    case CHUNK_END:        debug_ipmovie("end\n");        break;    default:        debug_ipmovie("invalid chunk\n");        chunk_type = CHUNK_BAD;        break;    }    while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) {        /* read the next chunk, wherever the file happens to be pointing */       if (url_feof(pb)) {            chunk_type = CHUNK_EOF;            break;        }        if (get_buffer(pb, opcode_preamble, CHUNK_PREAMBLE_SIZE) !=            CHUNK_PREAMBLE_SIZE) {            chunk_type = CHUNK_BAD;            break;        }        opcode_size = LE_16(&opcode_preamble[0]);        opcode_type = opcode_preamble[2];        opcode_version = opcode_preamble[3];        chunk_size -= OPCODE_PREAMBLE_SIZE;        chunk_size -= opcode_size;        if (chunk_size < 0) {            debug_ipmovie("chunk_size countdown just went negative\n");            chunk_type = CHUNK_BAD;            break;        }        debug_ipmovie("  opcode type %02X, version %d, 0x%04X bytes: ",            opcode_type, opcode_version, opcode_size);        switch (opcode_type) {        case OPCODE_END_OF_STREAM:            debug_ipmovie("end of stream\n");            url_fseek(pb, opcode_size, SEEK_CUR);            break;        case OPCODE_END_OF_CHUNK:            debug_ipmovie("end of chunk\n");            url_fseek(pb, opcode_size, SEEK_CUR);            break;        case OPCODE_CREATE_TIMER:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -