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 Sun Mar 8 2015 02:35:11 for FFmpeg by
1.8.2