Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
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 Libav.
6
*
7
* Libav 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
* Libav 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 Libav; 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
PMPContext
{
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
{
37
if
(!memcmp(p->
buf
,
"pmpm\1\0\0\0"
, 8))
38
return
AVPROBE_SCORE_MAX
;
39
return
0;
40
}
41
42
static
int
pmp_header
(
AVFormatContext
*s,
AVFormatParameters
*ap)
43
{
44
PMPContext
*pmp = s->
priv_data
;
45
AVIOContext
*pb = s->
pb
;
46
int
tb_num, tb_den;
47
int
index_cnt;
48
int
audio_codec_id =
CODEC_ID_NONE
;
49
int
srate, channels;
50
int
i;
51
uint64_t pos;
52
AVStream
*vst =
avformat_new_stream
(s,
NULL
);
53
if
(!vst)
54
return
AVERROR
(ENOMEM);
55
vst->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
56
avio_skip
(pb, 8);
57
switch
(
avio_rl32
(pb)) {
58
case
0:
59
vst->
codec
->
codec_id
=
CODEC_ID_MPEG4
;
60
break
;
61
case
1:
62
vst->
codec
->
codec_id
=
CODEC_ID_H264
;
63
break
;
64
default
:
65
av_log
(s,
AV_LOG_ERROR
,
"Unsupported video format\n"
);
66
break
;
67
}
68
index_cnt =
avio_rl32
(pb);
69
vst->
codec
->
width
=
avio_rl32
(pb);
70
vst->
codec
->
height
=
avio_rl32
(pb);
71
72
tb_num =
avio_rl32
(pb);
73
tb_den =
avio_rl32
(pb);
74
avpriv_set_pts_info
(vst, 32, tb_num, tb_den);
75
vst->
nb_frames
= index_cnt;
76
vst->
duration
= index_cnt;
77
78
switch
(
avio_rl32
(pb)) {
79
case
0:
80
audio_codec_id =
CODEC_ID_MP3
;
81
break
;
82
case
1:
83
av_log
(s,
AV_LOG_WARNING
,
"AAC is not yet correctly supported\n"
);
84
audio_codec_id =
CODEC_ID_AAC
;
85
break
;
86
default
:
87
av_log
(s,
AV_LOG_ERROR
,
"Unsupported audio format\n"
);
88
break
;
89
}
90
pmp->
num_streams
=
avio_rl16
(pb) + 1;
91
avio_skip
(pb, 10);
92
srate =
avio_rl32
(pb);
93
channels =
avio_rl32
(pb) + 1;
94
for
(i = 1; i < pmp->
num_streams
; i++) {
95
AVStream
*ast =
avformat_new_stream
(s,
NULL
);
96
if
(!ast)
97
return
AVERROR
(ENOMEM);
98
ast->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
99
ast->
codec
->
codec_id
= audio_codec_id;
100
ast->
codec
->
channels
= channels;
101
ast->
codec
->
sample_rate
= srate;
102
avpriv_set_pts_info
(ast, 32, 1, srate);
103
}
104
pos =
avio_tell
(pb) + 4 * index_cnt;
105
for
(i = 0; i < index_cnt; i++) {
106
int
size
=
avio_rl32
(pb);
107
int
flags
= size & 1 ?
AVINDEX_KEYFRAME
: 0;
108
size >>= 1;
109
av_add_index_entry
(vst, pos, i, size, 0, flags);
110
pos +=
size
;
111
}
112
return
0;
113
}
114
115
static
int
pmp_packet
(
AVFormatContext
*s,
AVPacket
*pkt)
116
{
117
PMPContext
*pmp = s->
priv_data
;
118
AVIOContext
*pb = s->
pb
;
119
int
ret = 0;
120
int
i;
121
122
if
(pb->
eof_reached
)
123
return
AVERROR_EOF
;
124
if
(pmp->
cur_stream
== 0) {
125
int
num_packets;
126
pmp->
audio_packets
=
avio_r8
(pb);
127
num_packets = (pmp->
num_streams
- 1) * pmp->
audio_packets
+ 1;
128
avio_skip
(pb, 8);
129
pmp->
current_packet
= 0;
130
av_fast_malloc
(&pmp->
packet_sizes
,
131
&pmp->
packet_sizes_alloc
,
132
num_packets *
sizeof
(*pmp->
packet_sizes
));
133
if
(!pmp->
packet_sizes_alloc
) {
134
av_log
(s,
AV_LOG_ERROR
,
"Cannot (re)allocate packet buffer\n"
);
135
return
AVERROR
(ENOMEM);
136
}
137
for
(i = 0; i < num_packets; i++)
138
pmp->
packet_sizes
[i] =
avio_rl32
(pb);
139
}
140
ret =
av_get_packet
(pb, pkt, pmp->
packet_sizes
[pmp->
current_packet
]);
141
if
(ret > 0) {
142
ret = 0;
143
// FIXME: this is a hack that should be removed once
144
// compute_pkt_fields() can handle timestamps properly
145
if
(pmp->
cur_stream
== 0)
146
pkt->
dts
= s->
streams
[0]->
cur_dts
++;
147
pkt->
stream_index
= pmp->
cur_stream
;
148
}
149
pmp->
current_packet
++;
150
if
(pmp->
current_packet
== 1 || pmp->
current_packet
> pmp->
audio_packets
)
151
pmp->
cur_stream
= (pmp->
cur_stream
+ 1) % pmp->
num_streams
;
152
153
return
ret;
154
}
155
156
static
int
pmp_seek
(
AVFormatContext
*s,
int
stream_idx, int64_t ts,
int
flags
)
157
{
158
PMPContext
*pmp = s->
priv_data
;
159
pmp->
cur_stream
= 0;
160
// fallback to default seek now
161
return
-1;
162
}
163
164
static
int
pmp_close
(
AVFormatContext
*s)
165
{
166
PMPContext
*pmp = s->
priv_data
;
167
av_freep
(&pmp->
packet_sizes
);
168
return
0;
169
}
170
171
AVInputFormat
ff_pmp_demuxer
= {
172
.
name
=
"pmp"
,
173
.long_name =
NULL_IF_CONFIG_SMALL
(
"Playstation Portable PMP format"
),
174
.priv_data_size =
sizeof
(
PMPContext
),
175
.
read_probe
=
pmp_probe
,
176
.
read_header
=
pmp_header
,
177
.
read_packet
=
pmp_packet
,
178
.
read_seek
=
pmp_seek
,
179
.
read_close
=
pmp_close
,
180
};