FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
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
int
index_cnt;
48
int
audio_codec_id =
AV_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
=
AV_CODEC_ID_MPEG4
;
60
break
;
61
case
1:
62
vst->
codec
->
codec_id
=
AV_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 =
AV_CODEC_ID_MP3
;
81
break
;
82
case
1:
83
av_log
(s,
AV_LOG_ERROR
,
"AAC not yet correctly supported\n"
);
84
audio_codec_id =
AV_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
(
url_feof
(pb))
123
return
AVERROR_EOF
;
124
if
(pmp->
cur_stream
== 0) {
125
int
num_packets;
126
pmp->
audio_packets
=
avio_r8
(pb);
127
if
(!pmp->
audio_packets
) {
128
av_log_ask_for_sample
(s,
"0 audio packets\n"
);
129
return
AVERROR_PATCHWELCOME
;
130
}
131
num_packets = (pmp->
num_streams
- 1) * pmp->
audio_packets
+ 1;
132
avio_skip
(pb, 8);
133
pmp->
current_packet
= 0;
134
av_fast_malloc
(&pmp->
packet_sizes
,
135
&pmp->
packet_sizes_alloc
,
136
num_packets *
sizeof
(*pmp->
packet_sizes
));
137
if
(!pmp->
packet_sizes_alloc
) {
138
av_log
(s,
AV_LOG_ERROR
,
"Cannot (re)allocate packet buffer\n"
);
139
return
AVERROR
(ENOMEM);
140
}
141
for
(i = 0; i < num_packets; i++)
142
pmp->
packet_sizes
[i] =
avio_rl32
(pb);
143
}
144
ret =
av_get_packet
(pb, pkt, pmp->
packet_sizes
[pmp->
current_packet
]);
145
if
(ret >= 0) {
146
ret = 0;
147
// FIXME: this is a hack that should be removed once
148
// compute_pkt_fields() can handle timestamps properly
149
if
(pmp->
cur_stream
== 0)
150
pkt->
dts
= s->
streams
[0]->
cur_dts
++;
151
pkt->
stream_index
= pmp->
cur_stream
;
152
}
153
if
(pmp->
current_packet
% pmp->
audio_packets
== 0)
154
pmp->
cur_stream
= (pmp->
cur_stream
+ 1) % pmp->
num_streams
;
155
pmp->
current_packet
++;
156
return
ret;
157
}
158
159
static
int
pmp_seek
(
AVFormatContext
*s,
int
stream_index, int64_t ts,
int
flags
)
160
{
161
PMPContext
*pmp = s->
priv_data
;
162
pmp->
cur_stream
= 0;
163
// fallback to default seek now
164
return
-1;
165
}
166
167
static
int
pmp_close
(
AVFormatContext
*s)
168
{
169
PMPContext
*pmp = s->
priv_data
;
170
av_freep
(&pmp->
packet_sizes
);
171
return
0;
172
}
173
174
AVInputFormat
ff_pmp_demuxer
= {
175
.
name
=
"pmp"
,
176
.long_name =
NULL_IF_CONFIG_SMALL
(
"Playstation Portable PMP"
),
177
.priv_data_size =
sizeof
(
PMPContext
),
178
.
read_probe
=
pmp_probe
,
179
.
read_header
=
pmp_header
,
180
.
read_packet
=
pmp_packet
,
181
.
read_seek
=
pmp_seek
,
182
.
read_close
=
pmp_close
,
183
};
Generated on Sat May 25 2013 03:58:48 for FFmpeg by
1.8.2