FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
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
159
return
0;
160
}
161
162
static
int
cin_read_packet
(
AVFormatContext
*s,
AVPacket
*
pkt
)
163
{
164
CinDemuxContext
*cin = s->
priv_data
;
165
AVIOContext
*pb = s->
pb
;
166
CinFrameHeader
*hdr = &cin->
frame_header
;
167
int
rc, palette_type, pkt_size;
168
int
ret;
169
170
if
(cin->
audio_buffer_size
== 0) {
171
rc =
cin_read_frame_header
(cin, pb);
172
if
(rc)
173
return
rc;
174
175
if
((int16_t)hdr->
pal_colors_count
< 0) {
176
hdr->
pal_colors_count
= -(int16_t)hdr->
pal_colors_count
;
177
palette_type = 1;
178
}
else
{
179
palette_type = 0;
180
}
181
182
/* palette and video packet */
183
pkt_size = (palette_type + 3) * hdr->
pal_colors_count
+ hdr->
video_frame_size
;
184
185
pkt_size =
ffio_limit
(pb, pkt_size);
186
187
ret =
av_new_packet
(pkt, 4 + pkt_size);
188
if
(ret < 0)
189
return
ret;
190
191
pkt->
stream_index
= cin->
video_stream_index
;
192
pkt->
pts
= cin->
video_stream_pts
++;
193
194
pkt->
data
[0] = palette_type;
195
pkt->
data
[1] = hdr->
pal_colors_count
& 0xFF;
196
pkt->
data
[2] = hdr->
pal_colors_count
>> 8;
197
pkt->
data
[3] = hdr->
video_frame_type
;
198
199
ret =
avio_read
(pb, &pkt->
data
[4], pkt_size);
200
if
(ret < 0) {
201
av_free_packet
(pkt);
202
return
ret;
203
}
204
if
(ret < pkt_size)
205
av_shrink_packet
(pkt, 4 + ret);
206
207
/* sound buffer will be processed on next read_packet() call */
208
cin->
audio_buffer_size
= hdr->
audio_frame_size
;
209
return
0;
210
}
211
212
/* audio packet */
213
ret =
av_get_packet
(pb, pkt, cin->
audio_buffer_size
);
214
if
(ret < 0)
215
return
ret;
216
217
pkt->
stream_index
= cin->
audio_stream_index
;
218
pkt->
pts
= cin->
audio_stream_pts
;
219
pkt->
duration
= cin->
audio_buffer_size
- (pkt->
pts
== 0);
220
cin->
audio_stream_pts
+= pkt->
duration
;
221
cin->
audio_buffer_size
= 0;
222
return
0;
223
}
224
225
AVInputFormat
ff_dsicin_demuxer
= {
226
.
name
=
"dsicin"
,
227
.long_name =
NULL_IF_CONFIG_SMALL
(
"Delphine Software International CIN"
),
228
.priv_data_size =
sizeof
(
CinDemuxContext
),
229
.
read_probe
=
cin_probe
,
230
.
read_header
=
cin_read_header
,
231
.
read_packet
=
cin_read_packet
,
232
};
Generated on Sat May 25 2013 03:58:46 for FFmpeg by
1.8.2