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
pmpdec.c
Go to the documentation of this file.
1
/*
2
* PMP demuxer.
3
* Copyright (c) 2011 Reimar Döffinger
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/intreadwrite.h
"
23
#include "
avformat.h
"
24
#include "
internal.h
"
25
26
typedef
struct
{
27
int
cur_stream
;
28
int
num_streams
;
29
int
audio_packets
;
30
int
current_packet
;
31
uint32_t *
packet_sizes
;
32
int
packet_sizes_alloc
;
33
}
PMPContext
;
34
35
static
int
pmp_probe
(
AVProbeData
*p) {
36
if
(
AV_RN32
(p->
buf
) ==
AV_RN32
(
"pmpm"
) &&
37
AV_RL32
(p->
buf
+ 4) == 1)
38
return
AVPROBE_SCORE_MAX
;
39
return
0;
40
}
41
42
static
int
pmp_header
(
AVFormatContext
*
s
)
43
{
44
PMPContext
*pmp = s->
priv_data
;
45
AVIOContext
*pb = s->
pb
;
46
int
tb_num, tb_den;
47
uint32_t index_cnt;
48
int
audio_codec_id =
AV_CODEC_ID_NONE
;
49
int
srate, channels;
50
unsigned
i;
51
uint64_t pos;
52
int64_t fsize =
avio_size
(pb);
53
54
AVStream
*vst =
avformat_new_stream
(s, NULL);
55
if
(!vst)
56
return
AVERROR
(ENOMEM);
57
vst->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
58
avio_skip
(pb, 8);
59
switch
(
avio_rl32
(pb)) {
60
case
0:
61
vst->
codec
->
codec_id
=
AV_CODEC_ID_MPEG4
;
62
break
;
63
case
1:
64
vst->
codec
->
codec_id
=
AV_CODEC_ID_H264
;
65
break
;
66
default
:
67
av_log
(s,
AV_LOG_ERROR
,
"Unsupported video format\n"
);
68
break
;
69
}
70
index_cnt =
avio_rl32
(pb);
71
vst->
codec
->
width
=
avio_rl32
(pb);
72
vst->
codec
->
height
=
avio_rl32
(pb);
73
74
tb_num =
avio_rl32
(pb);
75
tb_den =
avio_rl32
(pb);
76
avpriv_set_pts_info
(vst, 32, tb_num, tb_den);
77
vst->
nb_frames
= index_cnt;
78
vst->
duration
= index_cnt;
79
80
switch
(
avio_rl32
(pb)) {
81
case
0:
82
audio_codec_id =
AV_CODEC_ID_MP3
;
83
break
;
84
case
1:
85
av_log
(s,
AV_LOG_ERROR
,
"AAC not yet correctly supported\n"
);
86
audio_codec_id =
AV_CODEC_ID_AAC
;
87
break
;
88
default
:
89
av_log
(s,
AV_LOG_ERROR
,
"Unsupported audio format\n"
);
90
break
;
91
}
92
pmp->
num_streams
=
avio_rl16
(pb) + 1;
93
avio_skip
(pb, 10);
94
srate =
avio_rl32
(pb);
95
channels =
avio_rl32
(pb) + 1;
96
pos =
avio_tell
(pb) + 4LL*index_cnt;
97
for
(i = 0; i < index_cnt; i++) {
98
uint32_t
size
=
avio_rl32
(pb);
99
int
flags
= size & 1 ?
AVINDEX_KEYFRAME
: 0;
100
if
(
url_feof
(pb)) {
101
av_log
(s,
AV_LOG_FATAL
,
"Encountered EOF while reading index.\n"
);
102
return
AVERROR_INVALIDDATA
;
103
}
104
size >>= 1;
105
if
(size < 9 + 4*pmp->num_streams) {
106
av_log
(s,
AV_LOG_ERROR
,
"Packet too small\n"
);
107
return
AVERROR_INVALIDDATA
;
108
}
109
av_add_index_entry
(vst, pos, i, size, 0, flags);
110
pos +=
size
;
111
if
(fsize > 0 && i == 0 && pos > fsize) {
112
av_log
(s,
AV_LOG_ERROR
,
"File ends before first packet\n"
);
113
return
AVERROR_INVALIDDATA
;
114
}
115
}
116
for
(i = 1; i < pmp->
num_streams
; i++) {
117
AVStream
*ast =
avformat_new_stream
(s, NULL);
118
if
(!ast)
119
return
AVERROR
(ENOMEM);
120
ast->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
121
ast->
codec
->
codec_id
= audio_codec_id;
122
ast->
codec
->
channels
= channels;
123
ast->
codec
->
sample_rate
= srate;
124
avpriv_set_pts_info
(ast, 32, 1, srate);
125
}
126
return
0;
127
}
128
129
static
int
pmp_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
130
{
131
PMPContext
*pmp = s->
priv_data
;
132
AVIOContext
*pb = s->
pb
;
133
int
ret
= 0;
134
int
i;
135
136
if
(
url_feof
(pb))
137
return
AVERROR_EOF
;
138
if
(pmp->
cur_stream
== 0) {
139
int
num_packets;
140
pmp->
audio_packets
=
avio_r8
(pb);
141
if
(!pmp->
audio_packets
) {
142
avpriv_request_sample
(s,
"0 audio packets"
);
143
return
AVERROR_PATCHWELCOME
;
144
}
145
num_packets = (pmp->
num_streams
- 1) * pmp->
audio_packets
+ 1;
146
avio_skip
(pb, 8);
147
pmp->
current_packet
= 0;
148
av_fast_malloc
(&pmp->
packet_sizes
,
149
&pmp->
packet_sizes_alloc
,
150
num_packets *
sizeof
(*pmp->
packet_sizes
));
151
if
(!pmp->
packet_sizes_alloc
) {
152
av_log
(s,
AV_LOG_ERROR
,
"Cannot (re)allocate packet buffer\n"
);
153
return
AVERROR
(ENOMEM);
154
}
155
for
(i = 0; i < num_packets; i++)
156
pmp->
packet_sizes
[i] =
avio_rl32
(pb);
157
}
158
ret =
av_get_packet
(pb, pkt, pmp->
packet_sizes
[pmp->
current_packet
]);
159
if
(ret >= 0) {
160
ret = 0;
161
// FIXME: this is a hack that should be removed once
162
// compute_pkt_fields() can handle timestamps properly
163
if
(pmp->
cur_stream
== 0)
164
pkt->
dts
= s->
streams
[0]->
cur_dts
++;
165
pkt->
stream_index
= pmp->
cur_stream
;
166
}
167
if
(pmp->
current_packet
% pmp->
audio_packets
== 0)
168
pmp->
cur_stream
= (pmp->
cur_stream
+ 1) % pmp->
num_streams
;
169
pmp->
current_packet
++;
170
return
ret;
171
}
172
173
static
int
pmp_seek
(
AVFormatContext
*
s
,
int
stream_index, int64_t ts,
int
flags
)
174
{
175
PMPContext
*pmp = s->
priv_data
;
176
pmp->
cur_stream
= 0;
177
// fall back on default seek now
178
return
-1;
179
}
180
181
static
int
pmp_close
(
AVFormatContext
*
s
)
182
{
183
PMPContext
*pmp = s->
priv_data
;
184
av_freep
(&pmp->
packet_sizes
);
185
return
0;
186
}
187
188
AVInputFormat
ff_pmp_demuxer
= {
189
.
name
=
"pmp"
,
190
.long_name =
NULL_IF_CONFIG_SMALL
(
"Playstation Portable PMP"
),
191
.priv_data_size =
sizeof
(
PMPContext
),
192
.
read_probe
=
pmp_probe
,
193
.
read_header
=
pmp_header
,
194
.
read_packet
=
pmp_packet
,
195
.
read_seek
=
pmp_seek
,
196
.
read_close
=
pmp_close
,
197
};
Generated on Wed Jul 10 2013 23:48:13 for FFmpeg by
1.8.2