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
dsicin.c
Go to the documentation of this file.
1
/*
2
* Delphine Software International CIN File Demuxer
3
* Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
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
* Delphine Software International CIN file demuxer
25
*/
26
27
#include "
libavutil/channel_layout.h
"
28
#include "
libavutil/intreadwrite.h
"
29
#include "
avformat.h
"
30
#include "
internal.h
"
31
#include "
avio_internal.h
"
32
33
34
typedef
struct
CinFileHeader
{
35
int
video_frame_size
;
36
int
video_frame_width
;
37
int
video_frame_height
;
38
int
audio_frequency
;
39
int
audio_bits
;
40
int
audio_stereo
;
41
int
audio_frame_size
;
42
}
CinFileHeader
;
43
44
typedef
struct
CinFrameHeader
{
45
int
audio_frame_type
;
46
int
video_frame_type
;
47
int
pal_colors_count
;
48
int
audio_frame_size
;
49
int
video_frame_size
;
50
}
CinFrameHeader
;
51
52
typedef
struct
CinDemuxContext
{
53
int
audio_stream_index
;
54
int
video_stream_index
;
55
CinFileHeader
file_header
;
56
int64_t
audio_stream_pts
;
57
int64_t
video_stream_pts
;
58
CinFrameHeader
frame_header
;
59
int
audio_buffer_size
;
60
}
CinDemuxContext
;
61
62
63
static
int
cin_probe
(
AVProbeData
*p)
64
{
65
/* header starts with this special marker */
66
if
(
AV_RL32
(&p->
buf
[0]) != 0x55AA0000)
67
return
0;
68
69
/* for accuracy, check some header field values */
70
if
(
AV_RL32
(&p->
buf
[12]) != 22050 || p->
buf
[16] != 16 || p->
buf
[17] != 0)
71
return
0;
72
73
return
AVPROBE_SCORE_MAX
;
74
}
75
76
static
int
cin_read_file_header
(
CinDemuxContext
*cin,
AVIOContext
*pb) {
77
CinFileHeader
*hdr = &cin->
file_header
;
78
79
if
(
avio_rl32
(pb) != 0x55AA0000)
80
return
AVERROR_INVALIDDATA
;
81
82
hdr->
video_frame_size
=
avio_rl32
(pb);
83
hdr->
video_frame_width
=
avio_rl16
(pb);
84
hdr->
video_frame_height
=
avio_rl16
(pb);
85
hdr->
audio_frequency
=
avio_rl32
(pb);
86
hdr->
audio_bits
=
avio_r8
(pb);
87
hdr->
audio_stereo
=
avio_r8
(pb);
88
hdr->
audio_frame_size
=
avio_rl16
(pb);
89
90
if
(hdr->
audio_frequency
!= 22050 || hdr->
audio_bits
!= 16 || hdr->
audio_stereo
!= 0)
91
return
AVERROR_INVALIDDATA
;
92
93
return
0;
94
}
95
96
static
int
cin_read_header
(
AVFormatContext
*
s
)
97
{
98
int
rc;
99
CinDemuxContext
*cin = s->
priv_data
;
100
CinFileHeader
*hdr = &cin->
file_header
;
101
AVIOContext
*pb = s->
pb
;
102
AVStream
*st;
103
104
rc =
cin_read_file_header
(cin, pb);
105
if
(rc)
106
return
rc;
107
108
cin->
video_stream_pts
= 0;
109
cin->
audio_stream_pts
= 0;
110
cin->
audio_buffer_size
= 0;
111
112
/* initialize the video decoder stream */
113
st =
avformat_new_stream
(s, NULL);
114
if
(!st)
115
return
AVERROR
(ENOMEM);
116
117
avpriv_set_pts_info
(st, 32, 1, 12);
118
cin->
video_stream_index
= st->
index
;
119
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
120
st->
codec
->
codec_id
=
AV_CODEC_ID_DSICINVIDEO
;
121
st->
codec
->
codec_tag
= 0;
/* no fourcc */
122
st->
codec
->
width
= hdr->
video_frame_width
;
123
st->
codec
->
height
= hdr->
video_frame_height
;
124
125
/* initialize the audio decoder stream */
126
st =
avformat_new_stream
(s, NULL);
127
if
(!st)
128
return
AVERROR
(ENOMEM);
129
130
avpriv_set_pts_info
(st, 32, 1, 22050);
131
cin->
audio_stream_index
= st->
index
;
132
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
133
st->
codec
->
codec_id
=
AV_CODEC_ID_DSICINAUDIO
;
134
st->
codec
->
codec_tag
= 0;
/* no tag */
135
st->
codec
->
channels
= 1;
136
st->
codec
->
channel_layout
=
AV_CH_LAYOUT_MONO
;
137
st->
codec
->
sample_rate
= 22050;
138
st->
codec
->
bits_per_coded_sample
= 8;
139
st->
codec
->
bit_rate
= st->
codec
->
sample_rate
* st->
codec
->
bits_per_coded_sample
* st->
codec
->
channels
;
140
141
return
0;
142
}
143
144
static
int
cin_read_frame_header
(
CinDemuxContext
*cin,
AVIOContext
*pb) {
145
CinFrameHeader
*hdr = &cin->
frame_header
;
146
147
hdr->
video_frame_type
=
avio_r8
(pb);
148
hdr->
audio_frame_type
=
avio_r8
(pb);
149
hdr->
pal_colors_count
=
avio_rl16
(pb);
150
hdr->
video_frame_size
=
avio_rl32
(pb);
151
hdr->
audio_frame_size
=
avio_rl32
(pb);
152
153
if
(
url_feof
(pb) || pb->
error
)
154
return
AVERROR
(EIO);
155
156
if
(
avio_rl32
(pb) != 0xAA55AA55)
157
return
AVERROR_INVALIDDATA
;
158
if
(hdr->
video_frame_size
< 0 || hdr->
audio_frame_size
< 0)
159
return
AVERROR_INVALIDDATA
;
160
161
return
0;
162
}
163
164
static
int
cin_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
165
{
166
CinDemuxContext
*cin = s->
priv_data
;
167
AVIOContext
*pb = s->
pb
;
168
CinFrameHeader
*hdr = &cin->
frame_header
;
169
int
rc, palette_type, pkt_size;
170
int
ret
;
171
172
if
(cin->
audio_buffer_size
== 0) {
173
rc =
cin_read_frame_header
(cin, pb);
174
if
(rc)
175
return
rc;
176
177
if
((int16_t)hdr->
pal_colors_count
< 0) {
178
hdr->
pal_colors_count
= -(int16_t)hdr->
pal_colors_count
;
179
palette_type = 1;
180
}
else
{
181
palette_type = 0;
182
}
183
184
/* palette and video packet */
185
pkt_size = (palette_type + 3) * hdr->
pal_colors_count
+ hdr->
video_frame_size
;
186
187
pkt_size =
ffio_limit
(pb, pkt_size);
188
189
ret =
av_new_packet
(pkt, 4 + pkt_size);
190
if
(ret < 0)
191
return
ret
;
192
193
pkt->
stream_index
= cin->
video_stream_index
;
194
pkt->
pts
= cin->
video_stream_pts
++;
195
196
pkt->
data
[0] = palette_type;
197
pkt->
data
[1] = hdr->
pal_colors_count
& 0xFF;
198
pkt->
data
[2] = hdr->
pal_colors_count
>> 8;
199
pkt->
data
[3] = hdr->
video_frame_type
;
200
201
ret =
avio_read
(pb, &pkt->
data
[4], pkt_size);
202
if
(ret < 0) {
203
av_free_packet
(pkt);
204
return
ret
;
205
}
206
if
(ret < pkt_size)
207
av_shrink_packet
(pkt, 4 + ret);
208
209
/* sound buffer will be processed on next read_packet() call */
210
cin->
audio_buffer_size
= hdr->
audio_frame_size
;
211
return
0;
212
}
213
214
/* audio packet */
215
ret =
av_get_packet
(pb, pkt, cin->
audio_buffer_size
);
216
if
(ret < 0)
217
return
ret
;
218
219
pkt->
stream_index
= cin->
audio_stream_index
;
220
pkt->
pts
= cin->
audio_stream_pts
;
221
pkt->
duration
= cin->
audio_buffer_size
- (pkt->
pts
== 0);
222
cin->
audio_stream_pts
+= pkt->
duration
;
223
cin->
audio_buffer_size
= 0;
224
return
0;
225
}
226
227
AVInputFormat
ff_dsicin_demuxer
= {
228
.
name
=
"dsicin"
,
229
.long_name =
NULL_IF_CONFIG_SMALL
(
"Delphine Software International CIN"
),
230
.priv_data_size =
sizeof
(
CinDemuxContext
),
231
.
read_probe
=
cin_probe
,
232
.
read_header
=
cin_read_header
,
233
.
read_packet
=
cin_read_packet
,
234
};
Generated on Sun Mar 23 2014 23:50:10 for FFmpeg by
1.8.2