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
(
avio_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
(
avio_feof
(pb))
137
return
AVERROR_EOF
;
138
if
(pmp->
cur_stream
== 0) {
139
int
num_packets;
140
pmp->
audio_packets
=
avio_r8
(pb);
141
142
if
(!pmp->
audio_packets
) {
143
av_log
(s,
AV_LOG_ERROR
,
"No audio packets.\n"
);
144
return
AVERROR_INVALIDDATA
;
145
}
146
147
num_packets = (pmp->
num_streams
- 1) * pmp->
audio_packets
+ 1;
148
avio_skip
(pb, 8);
149
pmp->
current_packet
= 0;
150
av_fast_malloc
(&pmp->
packet_sizes
,
151
&pmp->
packet_sizes_alloc
,
152
num_packets *
sizeof
(*pmp->
packet_sizes
));
153
if
(!pmp->
packet_sizes_alloc
) {
154
av_log
(s,
AV_LOG_ERROR
,
"Cannot (re)allocate packet buffer\n"
);
155
return
AVERROR
(ENOMEM);
156
}
157
for
(i = 0; i < num_packets; i++)
158
pmp->
packet_sizes
[i] =
avio_rl32
(pb);
159
}
160
ret =
av_get_packet
(pb, pkt, pmp->
packet_sizes
[pmp->
current_packet
]);
161
if
(ret >= 0) {
162
ret = 0;
163
pkt->
stream_index
= pmp->
cur_stream
;
164
}
165
if
(pmp->
current_packet
% pmp->
audio_packets
== 0)
166
pmp->
cur_stream
= (pmp->
cur_stream
+ 1) % pmp->
num_streams
;
167
pmp->
current_packet
++;
168
return
ret;
169
}
170
171
static
int
pmp_seek
(
AVFormatContext
*
s
,
int
stream_index, int64_t ts,
int
flags
)
172
{
173
PMPContext
*pmp = s->
priv_data
;
174
pmp->
cur_stream
= 0;
175
// fall back on default seek now
176
return
-1;
177
}
178
179
static
int
pmp_close
(
AVFormatContext
*
s
)
180
{
181
PMPContext
*pmp = s->
priv_data
;
182
av_freep
(&pmp->
packet_sizes
);
183
return
0;
184
}
185
186
AVInputFormat
ff_pmp_demuxer
= {
187
.
name
=
"pmp"
,
188
.long_name =
NULL_IF_CONFIG_SMALL
(
"Playstation Portable PMP"
),
189
.priv_data_size =
sizeof
(
PMPContext
),
190
.
read_probe
=
pmp_probe
,
191
.
read_header
=
pmp_header
,
192
.
read_packet
=
pmp_packet
,
193
.
read_seek
=
pmp_seek
,
194
.
read_close
=
pmp_close
,
195
};
Generated on Fri Dec 5 2014 04:42:13 for FFmpeg by
1.8.2