diff options
Diffstat (limited to 'contrib/ffmpeg/libavformat/bethsoftvid.c')
-rw-r--r-- | contrib/ffmpeg/libavformat/bethsoftvid.c | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/contrib/ffmpeg/libavformat/bethsoftvid.c b/contrib/ffmpeg/libavformat/bethsoftvid.c deleted file mode 100644 index 594779698..000000000 --- a/contrib/ffmpeg/libavformat/bethsoftvid.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Bethsoft VID format Demuxer - * Copyright (c) 2007 Nicholas Tung - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file bethsoftvid.c - * @brief Bethesda Softworks VID (.vid) file demuxer - * @author Nicholas Tung [ntung (at. ntung com] (2007-03) - * @sa http://wiki.multimedia.cx/index.php?title=Bethsoft_VID - * @sa http://www.svatopluk.com/andux/docs/dfvid.html - */ - -#include "avformat.h" -#include "bethsoftvideo.h" - -typedef struct BVID_DemuxContext -{ - int nframes; - /** delay value between frames, added to individual frame delay. - * custom units, which will be added to other custom units (~=16ms according - * to free, unofficial documentation) */ - int bethsoft_global_delay; - - /** video presentation time stamp. - * delay = 16 milliseconds * (global_delay + per_frame_delay) */ - int video_pts; - - int is_finished; - -} BVID_DemuxContext; - -static int vid_probe(AVProbeData *p) -{ - // little endian VID tag, file starts with "VID\0" - if (AV_RL32(p->buf) != MKTAG('V', 'I', 'D', 0)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int vid_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - BVID_DemuxContext *vid = s->priv_data; - ByteIOContext *pb = s->pb; - AVStream *stream; - - /* load main header. Contents: - * bytes: 'V' 'I' 'D' - * int16s: always_512, nframes, width, height, delay, always_14 - */ - url_fseek(pb, 5, SEEK_CUR); - vid->nframes = get_le16(pb); - - stream = av_new_stream(s, 0); - if (!stream) - return AVERROR(ENOMEM); - av_set_pts_info(stream, 32, 1, 60); // 16 ms increments, i.e. 60 fps - stream->codec->codec_type = CODEC_TYPE_VIDEO; - stream->codec->codec_id = CODEC_ID_BETHSOFTVID; - stream->codec->width = get_le16(pb); - stream->codec->height = get_le16(pb); - stream->codec->pix_fmt = PIX_FMT_PAL8; - vid->bethsoft_global_delay = get_le16(pb); - get_le16(pb); - - // done with video codec, set up audio codec - stream = av_new_stream(s, 0); - if (!stream) - return AVERROR(ENOMEM); - stream->codec->codec_type = CODEC_TYPE_AUDIO; - stream->codec->codec_id = CODEC_ID_PCM_U8; - stream->codec->channels = 1; - stream->codec->sample_rate = 11025; - stream->codec->bits_per_sample = 8; - stream->codec->bit_rate = stream->codec->channels * stream->codec->sample_rate * stream->codec->bits_per_sample; - - return 0; -} - -#define BUFFER_PADDING_SIZE 1000 -static int read_frame(BVID_DemuxContext *vid, ByteIOContext *pb, AVPacket *pkt, - uint8_t block_type, AVFormatContext *s, int npixels) -{ - uint8_t * vidbuf_start = NULL; - int vidbuf_nbytes = 0; - int code; - int bytes_copied = 0; - int position; - unsigned int vidbuf_capacity; - - vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); - if(!vidbuf_start) - return AVERROR(ENOMEM); - - // save the file position for the packet, include block type - position = url_ftell(pb) - 1; - - vidbuf_start[vidbuf_nbytes++] = block_type; - - // get the video delay (next int16), and set the presentation time - vid->video_pts += vid->bethsoft_global_delay + get_le16(pb); - - // set the y offset if it exists (decoder header data should be in data section) - if(block_type == VIDEO_YOFF_P_FRAME){ - if(get_buffer(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) - goto fail; - vidbuf_nbytes += 2; - } - - do{ - vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE); - if(!vidbuf_start) - return AVERROR(ENOMEM); - - code = get_byte(pb); - vidbuf_start[vidbuf_nbytes++] = code; - - if(code >= 0x80){ // rle sequence - if(block_type == VIDEO_I_FRAME) - vidbuf_start[vidbuf_nbytes++] = get_byte(pb); - } else if(code){ // plain sequence - if(get_buffer(pb, &vidbuf_start[vidbuf_nbytes], code) != code) - goto fail; - vidbuf_nbytes += code; - } - bytes_copied += code & 0x7F; - if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied - // may contain a 0 byte even if read all pixels - if(get_byte(pb)) - url_fseek(pb, -1, SEEK_CUR); - break; - } - if(bytes_copied > npixels) - goto fail; - } while(code); - - // copy data into packet - if(av_new_packet(pkt, vidbuf_nbytes) < 0) - goto fail; - memcpy(pkt->data, vidbuf_start, vidbuf_nbytes); - av_free(vidbuf_start); - - pkt->pos = position; - pkt->stream_index = 0; // use the video decoder, which was initialized as the first stream - pkt->pts = vid->video_pts; - - vid->nframes--; // used to check if all the frames were read - return vidbuf_nbytes; -fail: - av_free(vidbuf_start); - return -1; -} - -static int vid_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - BVID_DemuxContext *vid = s->priv_data; - ByteIOContext *pb = s->pb; - unsigned char block_type; - int audio_length; - int ret_value; - - if(vid->is_finished || url_feof(pb)) - return AVERROR(EIO); - - block_type = get_byte(pb); - switch(block_type){ - case PALETTE_BLOCK: - url_fseek(pb, -1, SEEK_CUR); // include block type - ret_value = av_get_packet(pb, pkt, 3 * 256 + 1); - if(ret_value != 3 * 256 + 1){ - av_free_packet(pkt); - return AVERROR(EIO); - } - pkt->stream_index = 0; - return ret_value; - - case FIRST_AUDIO_BLOCK: - get_le16(pb); - // soundblaster DAC used for sample rate, as on specification page (link above) - s->streams[1]->codec->sample_rate = 1000000 / (256 - get_byte(pb)); - s->streams[1]->codec->bit_rate = s->streams[1]->codec->channels * s->streams[1]->codec->sample_rate * s->streams[1]->codec->bits_per_sample; - case AUDIO_BLOCK: - audio_length = get_le16(pb); - ret_value = av_get_packet(pb, pkt, audio_length); - pkt->stream_index = 1; - return (ret_value != audio_length ? AVERROR(EIO) : ret_value); - - case VIDEO_P_FRAME: - case VIDEO_YOFF_P_FRAME: - case VIDEO_I_FRAME: - return read_frame(vid, pb, pkt, block_type, s, - s->streams[0]->codec->width * s->streams[0]->codec->height); - - case EOF_BLOCK: - if(vid->nframes != 0) - av_log(s, AV_LOG_VERBOSE, "reached terminating character but not all frames read.\n"); - vid->is_finished = 1; - return AVERROR(EIO); - default: - av_log(s, AV_LOG_ERROR, "unknown block (character = %c, decimal = %d, hex = %x)!!!\n", - block_type, block_type, block_type); return -1; - } - - return 0; -} - -AVInputFormat bethsoftvid_demuxer = { - "bethsoftvid", - "Bethesda Softworks 'Daggerfall' VID format", - sizeof(BVID_DemuxContext), - vid_probe, - vid_read_header, - vid_read_packet, -}; |