FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
bfi.c
Go to the documentation of this file.
1
/*
2
* Brute Force & Ignorance (BFI) demuxer
3
* Copyright (c) 2008 Sisir Koppaka
4
*
5
* This file is part of FFmpeg.
6
*
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.
11
*
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.
16
*
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
20
*/
21
22
/**
23
* @file
24
* @brief Brute Force & Ignorance (.bfi) file demuxer
25
* @author Sisir Koppaka ( sisir.koppaka at gmail dot com )
26
* @see http://wiki.multimedia.cx/index.php?title=BFI
27
*/
28
29
#include "
libavutil/channel_layout.h
"
30
#include "
libavutil/intreadwrite.h
"
31
#include "
avformat.h
"
32
#include "
internal.h
"
33
34
typedef
struct
BFIContext
{
35
int
nframes
;
36
int
audio_frame
;
37
int
video_frame
;
38
int
video_size
;
39
int
avflag
;
40
}
BFIContext
;
41
42
static
int
bfi_probe
(
AVProbeData
* p)
43
{
44
/* Check file header */
45
if
(
AV_RL32
(p->
buf
) ==
MKTAG
(
'B'
,
'F'
,
'&'
,
'I'
))
46
return
AVPROBE_SCORE_MAX
;
47
else
48
return
0;
49
}
50
51
static
int
bfi_read_header
(
AVFormatContext
*
s
)
52
{
53
BFIContext
*bfi = s->
priv_data
;
54
AVIOContext
*pb = s->
pb
;
55
AVStream
*vstream;
56
AVStream
*astream;
57
int
fps, chunk_header;
58
59
/* Initialize the video codec... */
60
vstream =
avformat_new_stream
(s, NULL);
61
if
(!vstream)
62
return
AVERROR
(ENOMEM);
63
64
/* Initialize the audio codec... */
65
astream =
avformat_new_stream
(s, NULL);
66
if
(!astream)
67
return
AVERROR
(ENOMEM);
68
69
/* Set the total number of frames. */
70
avio_skip
(pb, 8);
71
chunk_header =
avio_rl32
(pb);
72
bfi->
nframes
=
avio_rl32
(pb);
73
avio_rl32
(pb);
74
avio_rl32
(pb);
75
avio_rl32
(pb);
76
fps =
avio_rl32
(pb);
77
avio_skip
(pb, 12);
78
vstream->
codec
->
width
=
avio_rl32
(pb);
79
vstream->
codec
->
height
=
avio_rl32
(pb);
80
81
/*Load the palette to extradata */
82
avio_skip
(pb, 8);
83
vstream->
codec
->
extradata
=
av_malloc
(768);
84
if
(!vstream->
codec
->
extradata
)
85
return
AVERROR
(ENOMEM);
86
vstream->
codec
->
extradata_size
= 768;
87
avio_read
(pb, vstream->
codec
->
extradata
,
88
vstream->
codec
->
extradata_size
);
89
90
astream->
codec
->
sample_rate
=
avio_rl32
(pb);
91
92
/* Set up the video codec... */
93
avpriv_set_pts_info
(vstream, 32, 1, fps);
94
vstream->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
95
vstream->
codec
->
codec_id
=
AV_CODEC_ID_BFI
;
96
vstream->
codec
->
pix_fmt
=
AV_PIX_FMT_PAL8
;
97
vstream->
nb_frames
=
98
vstream->
duration
= bfi->
nframes
;
99
100
/* Set up the audio codec now... */
101
astream->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
102
astream->
codec
->
codec_id
=
AV_CODEC_ID_PCM_U8
;
103
astream->
codec
->
channels
= 1;
104
astream->
codec
->
channel_layout
=
AV_CH_LAYOUT_MONO
;
105
astream->
codec
->
bits_per_coded_sample
= 8;
106
astream->
codec
->
bit_rate
=
107
astream->
codec
->
sample_rate
* astream->
codec
->
bits_per_coded_sample
;
108
avio_seek
(pb, chunk_header - 3, SEEK_SET);
109
avpriv_set_pts_info
(astream, 64, 1, astream->
codec
->
sample_rate
);
110
return
0;
111
}
112
113
114
static
int
bfi_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
115
{
116
BFIContext
*bfi = s->
priv_data
;
117
AVIOContext
*pb = s->
pb
;
118
int
ret
, audio_offset, video_offset, chunk_size, audio_size = 0;
119
if
(bfi->
nframes
== 0 ||
url_feof
(pb)) {
120
return
AVERROR_EOF
;
121
}
122
123
/* If all previous chunks were completely read, then find a new one... */
124
if
(!bfi->
avflag
) {
125
uint32_t
state
= 0;
126
while
(state !=
MKTAG
(
'S'
,
'A'
,
'V'
,
'I'
)){
127
if
(
url_feof
(pb))
128
return
AVERROR
(EIO);
129
state = 256*state +
avio_r8
(pb);
130
}
131
/* Now that the chunk's location is confirmed, we proceed... */
132
chunk_size =
avio_rl32
(pb);
133
avio_rl32
(pb);
134
audio_offset =
avio_rl32
(pb);
135
avio_rl32
(pb);
136
video_offset =
avio_rl32
(pb);
137
audio_size = video_offset - audio_offset;
138
bfi->
video_size
= chunk_size - video_offset;
139
if
(audio_size < 0 || bfi->video_size < 0) {
140
av_log
(s,
AV_LOG_ERROR
,
"Invalid audio/video offsets or chunk size\n"
);
141
return
AVERROR_INVALIDDATA
;
142
}
143
144
//Tossing an audio packet at the audio decoder.
145
ret =
av_get_packet
(pb, pkt, audio_size);
146
if
(ret < 0)
147
return
ret
;
148
149
pkt->
pts
= bfi->
audio_frame
;
150
bfi->
audio_frame
+=
ret
;
151
}
else
if
(bfi->
video_size
> 0) {
152
153
//Tossing a video packet at the video decoder.
154
ret =
av_get_packet
(pb, pkt, bfi->
video_size
);
155
if
(ret < 0)
156
return
ret
;
157
158
pkt->
pts
= bfi->
video_frame
;
159
bfi->
video_frame
+= ret / bfi->
video_size
;
160
161
/* One less frame to read. A cursory decrement. */
162
bfi->
nframes
--;
163
}
else
{
164
/* Empty video packet */
165
ret =
AVERROR
(EAGAIN);
166
}
167
168
bfi->
avflag
= !bfi->
avflag
;
169
pkt->
stream_index
= bfi->
avflag
;
170
return
ret
;
171
}
172
173
AVInputFormat
ff_bfi_demuxer
= {
174
.
name
=
"bfi"
,
175
.long_name =
NULL_IF_CONFIG_SMALL
(
"Brute Force & Ignorance"
),
176
.priv_data_size =
sizeof
(
BFIContext
),
177
.
read_probe
=
bfi_probe
,
178
.
read_header
=
bfi_read_header
,
179
.
read_packet
=
bfi_read_packet
,
180
};
Generated on Sun Jul 20 2014 23:05:44 for FFmpeg by
1.8.2