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