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