00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00029 #include "libavutil/intreadwrite.h"
00030 #include "avformat.h"
00031
00032 typedef struct BFIContext {
00033 int nframes;
00034 int audio_frame;
00035 int video_frame;
00036 int video_size;
00037 int avflag;
00038 } BFIContext;
00039
00040 static int bfi_probe(AVProbeData * p)
00041 {
00042
00043 if (AV_RL32(p->buf) == MKTAG('B', 'F', '&', 'I'))
00044 return AVPROBE_SCORE_MAX;
00045 else
00046 return 0;
00047 }
00048
00049 static int bfi_read_header(AVFormatContext * s, AVFormatParameters * ap)
00050 {
00051 BFIContext *bfi = s->priv_data;
00052 AVIOContext *pb = s->pb;
00053 AVStream *vstream;
00054 AVStream *astream;
00055 int fps, chunk_header;
00056
00057
00058 vstream = av_new_stream(s, 0);
00059 if (!vstream)
00060 return AVERROR(ENOMEM);
00061
00062
00063 astream = av_new_stream(s, 0);
00064 if (!astream)
00065 return AVERROR(ENOMEM);
00066
00067
00068 avio_skip(pb, 8);
00069 chunk_header = avio_rl32(pb);
00070 bfi->nframes = avio_rl32(pb);
00071 avio_rl32(pb);
00072 avio_rl32(pb);
00073 avio_rl32(pb);
00074 fps = avio_rl32(pb);
00075 avio_skip(pb, 12);
00076 vstream->codec->width = avio_rl32(pb);
00077 vstream->codec->height = avio_rl32(pb);
00078
00079
00080 avio_skip(pb, 8);
00081 vstream->codec->extradata = av_malloc(768);
00082 vstream->codec->extradata_size = 768;
00083 avio_read(pb, vstream->codec->extradata,
00084 vstream->codec->extradata_size);
00085
00086 astream->codec->sample_rate = avio_rl32(pb);
00087
00088
00089 av_set_pts_info(vstream, 32, 1, fps);
00090 vstream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00091 vstream->codec->codec_id = CODEC_ID_BFI;
00092 vstream->codec->pix_fmt = PIX_FMT_PAL8;
00093
00094
00095 astream->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00096 astream->codec->codec_id = CODEC_ID_PCM_U8;
00097 astream->codec->channels = 1;
00098 astream->codec->bits_per_coded_sample = 8;
00099 astream->codec->bit_rate =
00100 astream->codec->sample_rate * astream->codec->bits_per_coded_sample;
00101 avio_seek(pb, chunk_header - 3, SEEK_SET);
00102 av_set_pts_info(astream, 64, 1, astream->codec->sample_rate);
00103 return 0;
00104 }
00105
00106
00107 static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt)
00108 {
00109 BFIContext *bfi = s->priv_data;
00110 AVIOContext *pb = s->pb;
00111 int ret, audio_offset, video_offset, chunk_size, audio_size = 0;
00112 if (bfi->nframes == 0 || url_feof(pb)) {
00113 return AVERROR(EIO);
00114 }
00115
00116
00117 if (!bfi->avflag) {
00118 uint32_t state = 0;
00119 while(state != MKTAG('S','A','V','I')){
00120 if (url_feof(pb))
00121 return AVERROR(EIO);
00122 state = 256*state + avio_r8(pb);
00123 }
00124
00125 chunk_size = avio_rl32(pb);
00126 avio_rl32(pb);
00127 audio_offset = avio_rl32(pb);
00128 avio_rl32(pb);
00129 video_offset = avio_rl32(pb);
00130 audio_size = video_offset - audio_offset;
00131 bfi->video_size = chunk_size - video_offset;
00132
00133
00134 ret = av_get_packet(pb, pkt, audio_size);
00135 if (ret < 0)
00136 return ret;
00137
00138 pkt->pts = bfi->audio_frame;
00139 bfi->audio_frame += ret;
00140 }
00141
00142 else {
00143
00144
00145 ret = av_get_packet(pb, pkt, bfi->video_size);
00146 if (ret < 0)
00147 return ret;
00148
00149 pkt->pts = bfi->video_frame;
00150 bfi->video_frame += ret / bfi->video_size;
00151
00152
00153 bfi->nframes--;
00154 }
00155
00156 bfi->avflag = !bfi->avflag;
00157 pkt->stream_index = bfi->avflag;
00158 return ret;
00159 }
00160
00161 AVInputFormat ff_bfi_demuxer = {
00162 "bfi",
00163 NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
00164 sizeof(BFIContext),
00165 bfi_probe,
00166 bfi_read_header,
00167 bfi_read_packet,
00168 };