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
23 * @file libavformat/bfi.c
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
29 #include "libavutil/intreadwrite.h"
32 typedef struct BFIContext
{
40 static int bfi_probe(AVProbeData
* p
)
42 /* Check file header */
43 if (AV_RL32(p
->buf
) == MKTAG('B', 'F', '&', 'I'))
44 return AVPROBE_SCORE_MAX
;
49 static int bfi_read_header(AVFormatContext
* s
, AVFormatParameters
* ap
)
51 BFIContext
*bfi
= s
->priv_data
;
52 ByteIOContext
*pb
= s
->pb
;
55 int fps
, chunk_header
;
57 /* Initialize the video codec... */
58 vstream
= av_new_stream(s
, 0);
60 return AVERROR(ENOMEM
);
62 /* Initialize the audio codec... */
63 astream
= av_new_stream(s
, 0);
65 return AVERROR(ENOMEM
);
67 /* Set the total number of frames. */
69 chunk_header
= get_le32(pb
);
70 bfi
->nframes
= get_le32(pb
);
76 vstream
->codec
->width
= get_le32(pb
);
77 vstream
->codec
->height
= get_le32(pb
);
79 /*Load the palette to extradata */
81 vstream
->codec
->extradata
= av_malloc(768);
82 vstream
->codec
->extradata_size
= 768;
83 get_buffer(pb
, vstream
->codec
->extradata
,
84 vstream
->codec
->extradata_size
);
86 astream
->codec
->sample_rate
= get_le32(pb
);
88 /* Set up the video codec... */
89 av_set_pts_info(vstream
, 32, 1, fps
);
90 vstream
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
91 vstream
->codec
->codec_id
= CODEC_ID_BFI
;
92 vstream
->codec
->pix_fmt
= PIX_FMT_PAL8
;
94 /* Set up the audio codec now... */
95 astream
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
96 astream
->codec
->codec_id
= CODEC_ID_PCM_U8
;
97 astream
->codec
->channels
= 1;
98 astream
->codec
->bits_per_coded_sample
= 8;
99 astream
->codec
->bit_rate
=
100 astream
->codec
->sample_rate
* astream
->codec
->bits_per_coded_sample
;
101 url_fseek(pb
, chunk_header
- 3, SEEK_SET
);
102 av_set_pts_info(astream
, 64, 1, astream
->codec
->sample_rate
);
107 static int bfi_read_packet(AVFormatContext
* s
, AVPacket
* pkt
)
109 BFIContext
*bfi
= s
->priv_data
;
110 ByteIOContext
*pb
= s
->pb
;
111 int ret
, audio_offset
, video_offset
, chunk_size
, audio_size
= 0;
112 if (bfi
->nframes
== 0 || url_feof(pb
)) {
116 /* If all previous chunks were completely read, then find a new one... */
119 while(state
!= MKTAG('S','A','V','I')){
122 state
= 256*state
+ get_byte(pb
);
124 /* Now that the chunk's location is confirmed, we proceed... */
125 chunk_size
= get_le32(pb
);
127 audio_offset
= get_le32(pb
);
129 video_offset
= get_le32(pb
);
130 audio_size
= video_offset
- audio_offset
;
131 bfi
->video_size
= chunk_size
- video_offset
;
133 //Tossing an audio packet at the audio decoder.
134 ret
= av_get_packet(pb
, pkt
, audio_size
);
138 pkt
->pts
= bfi
->audio_frame
;
139 bfi
->audio_frame
+= ret
;
144 //Tossing a video packet at the video decoder.
145 ret
= av_get_packet(pb
, pkt
, bfi
->video_size
);
149 pkt
->pts
= bfi
->video_frame
;
150 bfi
->video_frame
+= ret
/ bfi
->video_size
;
152 /* One less frame to read. A cursory decrement. */
156 bfi
->avflag
= !bfi
->avflag
;
157 pkt
->stream_index
= bfi
->avflag
;
161 AVInputFormat bfi_demuxer
= {
163 NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),