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