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
paf.c
Go to the documentation of this file.
1
/*
2
* Packed Animation File demuxer
3
* Copyright (c) 2012 Paul B Mahol
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
#include "
libavutil/channel_layout.h
"
23
#include "
libavcodec/paf.h
"
24
#include "
avformat.h
"
25
#include "
internal.h
"
26
27
#define MAGIC "Packed Animation File V1.0\n(c) 1992-96 Amazing Studio\x0a\x1a"
28
29
typedef
struct
PAFDemuxContext
{
30
uint32_t
buffer_size
;
31
uint32_t
frame_blks
;
32
uint32_t
nb_frames
;
33
uint32_t
start_offset
;
34
uint32_t
preload_count
;
35
uint32_t
max_video_blks
;
36
uint32_t
max_audio_blks
;
37
38
uint32_t
current_frame
;
39
uint32_t
current_frame_count
;
40
uint32_t
current_frame_block
;
41
42
uint32_t *
blocks_count_table
;
43
uint32_t *
frames_offset_table
;
44
uint32_t *
blocks_offset_table
;
45
46
uint8_t
*
video_frame
;
47
int
video_size
;
48
49
uint8_t
*
audio_frame
;
50
uint8_t
*
temp_audio_frame
;
51
int
audio_size
;
52
53
int
got_audio
;
54
}
PAFDemuxContext
;
55
56
static
int
read_probe
(
AVProbeData
*p)
57
{
58
if
((p->
buf_size
>= strlen(
MAGIC
)) &&
59
!memcmp(p->
buf
,
MAGIC
, strlen(
MAGIC
)))
60
return
AVPROBE_SCORE_MAX
;
61
return
0;
62
}
63
64
static
int
read_close
(
AVFormatContext
*
s
)
65
{
66
PAFDemuxContext
*p = s->
priv_data
;
67
68
av_freep
(&p->
blocks_count_table
);
69
av_freep
(&p->
frames_offset_table
);
70
av_freep
(&p->
blocks_offset_table
);
71
av_freep
(&p->
video_frame
);
72
av_freep
(&p->
audio_frame
);
73
av_freep
(&p->
temp_audio_frame
);
74
75
return
0;
76
}
77
78
static
void
read_table
(
AVFormatContext
*
s
, uint32_t *
table
, uint32_t
count
)
79
{
80
int
i;
81
82
for
(i = 0; i <
count
; i++)
83
table[i] =
avio_rl32
(s->
pb
);
84
85
avio_skip
(s->
pb
, 4 * (
FFALIGN
(count, 512) - count));
86
}
87
88
static
int
read_header
(
AVFormatContext
*
s
)
89
{
90
PAFDemuxContext
*p = s->
priv_data
;
91
AVIOContext
*pb = s->
pb
;
92
AVStream
*ast, *vst;
93
int
ret
= 0;
94
95
avio_skip
(pb, 132);
96
97
vst =
avformat_new_stream
(s, 0);
98
if
(!vst)
99
return
AVERROR
(ENOMEM);
100
101
vst->
start_time
= 0;
102
vst->
nb_frames
=
103
vst->
duration
=
104
p->
nb_frames
=
avio_rl32
(pb);
105
avio_skip
(pb, 4);
106
107
vst->
codec
->
width
=
avio_rl32
(pb);
108
vst->
codec
->
height
=
avio_rl32
(pb);
109
avio_skip
(pb, 4);
110
111
vst->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
112
vst->
codec
->
codec_tag
= 0;
113
vst->
codec
->
codec_id
=
AV_CODEC_ID_PAF_VIDEO
;
114
avpriv_set_pts_info
(vst, 64, 1, 10);
115
116
ast =
avformat_new_stream
(s, 0);
117
if
(!ast)
118
return
AVERROR
(ENOMEM);
119
120
ast->
start_time
= 0;
121
ast->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
122
ast->
codec
->
codec_tag
= 0;
123
ast->
codec
->
codec_id
=
AV_CODEC_ID_PAF_AUDIO
;
124
ast->
codec
->
channels
= 2;
125
ast->
codec
->
channel_layout
=
AV_CH_LAYOUT_STEREO
;
126
ast->
codec
->
sample_rate
= 22050;
127
avpriv_set_pts_info
(ast, 64, 1, 22050);
128
129
p->
buffer_size
=
avio_rl32
(pb);
130
p->
preload_count
=
avio_rl32
(pb);
131
p->
frame_blks
=
avio_rl32
(pb);
132
p->
start_offset
=
avio_rl32
(pb);
133
p->
max_video_blks
=
avio_rl32
(pb);
134
p->
max_audio_blks
=
avio_rl32
(pb);
135
if
(p->
buffer_size
< 175 ||
136
p->
max_audio_blks
< 2 ||
137
p->
max_video_blks
< 1 ||
138
p->
frame_blks
< 1 ||
139
p->
nb_frames
< 1 ||
140
p->
preload_count
< 1 ||
141
p->
buffer_size
> 2048 ||
142
p->
max_video_blks
> 2048 ||
143
p->
max_audio_blks
> 2048 ||
144
p->
nb_frames
> INT_MAX /
sizeof
(uint32_t) ||
145
p->
frame_blks
> INT_MAX /
sizeof
(uint32_t))
146
return
AVERROR_INVALIDDATA
;
147
148
p->
blocks_count_table
=
av_mallocz
(p->
nb_frames
*
149
sizeof
(*p->
blocks_count_table
));
150
p->
frames_offset_table
=
av_mallocz
(p->
nb_frames
*
151
sizeof
(*p->
frames_offset_table
));
152
p->
blocks_offset_table
=
av_mallocz
(p->
frame_blks
*
153
sizeof
(*p->
blocks_offset_table
));
154
155
p->
video_size
= p->
max_video_blks
* p->
buffer_size
;
156
p->
video_frame
=
av_mallocz
(p->
video_size
);
157
158
p->
audio_size
= p->
max_audio_blks
* p->
buffer_size
;
159
p->
audio_frame
=
av_mallocz
(p->
audio_size
);
160
p->
temp_audio_frame
=
av_mallocz
(p->
audio_size
);
161
162
if
(!p->
blocks_count_table
||
163
!p->
frames_offset_table
||
164
!p->
blocks_offset_table
||
165
!p->
video_frame
||
166
!p->
audio_frame
||
167
!p->
temp_audio_frame
) {
168
ret =
AVERROR
(ENOMEM);
169
goto
fail;
170
}
171
172
avio_seek
(pb, p->
buffer_size
, SEEK_SET);
173
174
read_table
(s, p->
blocks_count_table
, p->
nb_frames
);
175
read_table
(s, p->
frames_offset_table
, p->
nb_frames
);
176
read_table
(s, p->
blocks_offset_table
, p->
frame_blks
);
177
178
p->
got_audio
= 0;
179
p->
current_frame
= 0;
180
p->
current_frame_block
= 0;
181
182
avio_seek
(pb, p->
start_offset
, SEEK_SET);
183
184
return
0;
185
186
fail:
187
read_close
(s);
188
189
return
ret
;
190
}
191
192
static
int
read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
193
{
194
PAFDemuxContext
*p = s->
priv_data
;
195
AVIOContext
*pb = s->
pb
;
196
uint32_t
count
,
offset
;
197
int
size
, i;
198
199
if
(p->
current_frame
>= p->
nb_frames
)
200
return
AVERROR_EOF
;
201
202
if
(
avio_feof
(pb))
203
return
AVERROR_EOF
;
204
205
if
(p->
got_audio
) {
206
if
(
av_new_packet
(pkt, p->
audio_size
) < 0)
207
return
AVERROR
(ENOMEM);
208
209
memcpy(pkt->
data
, p->
temp_audio_frame
, p->
audio_size
);
210
pkt->
duration
=
PAF_SOUND_SAMPLES
* (p->
audio_size
/
PAF_SOUND_FRAME_SIZE
);
211
pkt->
flags
|=
AV_PKT_FLAG_KEY
;
212
pkt->
stream_index
= 1;
213
p->
got_audio
= 0;
214
return
pkt->
size
;
215
}
216
217
count = (p->
current_frame
== 0) ? p->
preload_count
218
: p->
blocks_count_table
[p->
current_frame
- 1];
219
for
(i = 0; i <
count
; i++) {
220
if
(p->
current_frame_block
>= p->
frame_blks
)
221
return
AVERROR_INVALIDDATA
;
222
223
offset = p->
blocks_offset_table
[p->
current_frame_block
] & ~(1
U
<< 31);
224
if
(p->
blocks_offset_table
[p->
current_frame_block
] & (1
U
<< 31)) {
225
if
(offset > p->
audio_size
- p->
buffer_size
)
226
return
AVERROR_INVALIDDATA
;
227
228
avio_read
(pb, p->
audio_frame
+ offset, p->
buffer_size
);
229
if
(offset == (p->
max_audio_blks
- 2) * p->
buffer_size
) {
230
memcpy(p->
temp_audio_frame
, p->
audio_frame
, p->
audio_size
);
231
p->
got_audio
= 1;
232
}
233
}
else
{
234
if
(offset > p->
video_size
- p->
buffer_size
)
235
return
AVERROR_INVALIDDATA
;
236
237
avio_read
(pb, p->
video_frame
+ offset, p->
buffer_size
);
238
}
239
p->
current_frame_block
++;
240
}
241
242
if
(p->
frames_offset_table
[p->
current_frame
] >= p->
video_size
)
243
return
AVERROR_INVALIDDATA
;
244
245
size = p->
video_size
- p->
frames_offset_table
[p->
current_frame
];
246
247
if
(
av_new_packet
(pkt, size) < 0)
248
return
AVERROR
(ENOMEM);
249
250
pkt->
stream_index
= 0;
251
pkt->
duration
= 1;
252
memcpy(pkt->
data
, p->
video_frame
+ p->
frames_offset_table
[p->
current_frame
], size);
253
if
(pkt->
data
[0] & 0x20)
254
pkt->
flags
|=
AV_PKT_FLAG_KEY
;
255
p->
current_frame
++;
256
257
return
pkt->
size
;
258
}
259
260
AVInputFormat
ff_paf_demuxer
= {
261
.
name
=
"paf"
,
262
.long_name =
NULL_IF_CONFIG_SMALL
(
"Amazing Studio Packed Animation File"
),
263
.priv_data_size =
sizeof
(
PAFDemuxContext
),
264
.
read_probe
=
read_probe
,
265
.
read_header
=
read_header
,
266
.
read_packet
=
read_packet
,
267
.
read_close
=
read_close
,
268
};
Generated on Sun Mar 8 2015 02:35:11 for FFmpeg by
1.8.2