2 * Brute Force & Ignorance (BFI) demuxer
3 * Copyright (c) 2008 Sisir Koppaka
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * @brief Brute Force & Ignorance (.bfi) file demuxer
25 * @author Sisir Koppaka ( sisir.koppaka at gmail dot com )
26 * @sa http://wiki.multimedia.cx/index.php?title=BFI
31 typedef struct BFIContext
{
39 static int bfi_probe(AVProbeData
* p
)
41 /* Check file header */
42 if (AV_RL32(p
->buf
) == MKTAG('B', 'F', '&', 'I'))
43 return AVPROBE_SCORE_MAX
;
48 static int bfi_read_header(AVFormatContext
* s
, AVFormatParameters
* ap
)
50 BFIContext
*bfi
= s
->priv_data
;
51 ByteIOContext
*pb
= s
->pb
;
54 int fps
, chunk_header
;
56 /* Initialize the video codec... */
57 vstream
= av_new_stream(s
, 0);
59 return AVERROR(ENOMEM
);
61 /* Initialize the audio codec... */
62 astream
= av_new_stream(s
, 0);
64 return AVERROR(ENOMEM
);
66 /* Set the total number of frames. */
68 chunk_header
= get_le32(pb
);
69 bfi
->nframes
= get_le32(pb
);
75 vstream
->codec
->width
= get_le32(pb
);
76 vstream
->codec
->height
= get_le32(pb
);
78 /*Load the palette to extradata */
80 vstream
->codec
->extradata
= av_malloc(768);
81 vstream
->codec
->extradata_size
= 768;
82 get_buffer(pb
, vstream
->codec
->extradata
,
83 vstream
->codec
->extradata_size
);
85 astream
->codec
->sample_rate
= get_le32(pb
);
87 /* Set up the video codec... */
88 av_set_pts_info(vstream
, 32, 1, fps
);
89 vstream
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
90 vstream
->codec
->codec_id
= CODEC_ID_BFI
;
91 vstream
->codec
->pix_fmt
= PIX_FMT_PAL8
;
93 /* Set up the audio codec now... */
94 astream
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
95 astream
->codec
->codec_id
= CODEC_ID_PCM_U8
;
96 astream
->codec
->channels
= 1;
97 astream
->codec
->bits_per_sample
= 8;
98 astream
->codec
->bit_rate
=
99 astream
->codec
->sample_rate
* astream
->codec
->bits_per_sample
;
100 url_fseek(pb
, chunk_header
- 3, SEEK_SET
);
101 av_set_pts_info(astream
, 64, 1, astream
->codec
->sample_rate
);
106 static int bfi_read_packet(AVFormatContext
* s
, AVPacket
* pkt
)
108 BFIContext
*bfi
= s
->priv_data
;
109 ByteIOContext
*pb
= s
->pb
;
110 int ret
, audio_offset
, video_offset
, chunk_size
, audio_size
= 0;
111 if (bfi
->nframes
== 0 || url_feof(pb
)) {
115 /* If all previous chunks were completely read, then find a new one... */
118 while(state
!= MKTAG('S','A','V','I')){
121 state
= 256*state
+ get_byte(pb
);
123 /* Now that the chunk's location is confirmed, we proceed... */
124 chunk_size
= get_le32(pb
);
126 audio_offset
= get_le32(pb
);
128 video_offset
= get_le32(pb
);
129 audio_size
= video_offset
- audio_offset
;
130 bfi
->video_size
= chunk_size
- video_offset
;
132 //Tossing an audio packet at the audio decoder.
133 ret
= av_get_packet(pb
, pkt
, audio_size
);
137 pkt
->pts
= bfi
->audio_frame
;
138 bfi
->audio_frame
+= ret
;
143 //Tossing a video packet at the video decoder.
144 ret
= av_get_packet(pb
, pkt
, bfi
->video_size
);
148 pkt
->pts
= bfi
->video_frame
;
149 bfi
->video_frame
+= ret
/ bfi
->video_size
;
151 /* One less frame to read. A cursory decrement. */
155 bfi
->avflag
= !bfi
->avflag
;
156 pkt
->stream_index
= bfi
->avflag
;
160 AVInputFormat bfi_demuxer
= {
162 NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),