3 * Copyright (c) 2011 Reimar Döffinger
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/mem.h"
33 uint32_t *packet_sizes
;
34 int packet_sizes_alloc
;
37 static int pmp_probe(const AVProbeData
*p
) {
38 if (AV_RN32(p
->buf
) == AV_RN32("pmpm") &&
39 AV_RL32(p
->buf
+ 4) == 1)
40 return AVPROBE_SCORE_MAX
;
44 static int pmp_header(AVFormatContext
*s
)
46 PMPContext
*pmp
= s
->priv_data
;
47 AVIOContext
*pb
= s
->pb
;
50 int audio_codec_id
= AV_CODEC_ID_NONE
;
54 int64_t fsize
= avio_size(pb
);
56 AVStream
*vst
= avformat_new_stream(s
, NULL
);
58 return AVERROR(ENOMEM
);
59 vst
->codecpar
->codec_type
= AVMEDIA_TYPE_VIDEO
;
61 switch (avio_rl32(pb
)) {
63 vst
->codecpar
->codec_id
= AV_CODEC_ID_MPEG4
;
66 vst
->codecpar
->codec_id
= AV_CODEC_ID_H264
;
69 av_log(s
, AV_LOG_ERROR
, "Unsupported video format\n");
72 index_cnt
= avio_rl32(pb
);
73 vst
->codecpar
->width
= avio_rl32(pb
);
74 vst
->codecpar
->height
= avio_rl32(pb
);
76 tb_num
= avio_rl32(pb
);
77 tb_den
= avio_rl32(pb
);
78 avpriv_set_pts_info(vst
, 32, tb_num
, tb_den
);
79 vst
->nb_frames
= index_cnt
;
80 vst
->duration
= index_cnt
;
82 switch (avio_rl32(pb
)) {
84 audio_codec_id
= AV_CODEC_ID_MP3
;
87 av_log(s
, AV_LOG_ERROR
, "AAC not yet correctly supported\n");
88 audio_codec_id
= AV_CODEC_ID_AAC
;
91 av_log(s
, AV_LOG_ERROR
, "Unsupported audio format\n");
94 pmp
->num_streams
= avio_rl16(pb
) + 1;
96 srate
= avio_rl32(pb
);
97 channels
= avio_rl32(pb
) + 1;
98 pos
= avio_tell(pb
) + 4LL*index_cnt
;
99 for (i
= 0; i
< index_cnt
; i
++) {
100 uint32_t size
= avio_rl32(pb
);
101 int flags
= size
& 1 ? AVINDEX_KEYFRAME
: 0;
103 av_log(s
, AV_LOG_FATAL
, "Encountered EOF while reading index.\n");
104 return AVERROR_INVALIDDATA
;
107 if (size
< 9 + 4*pmp
->num_streams
) {
108 av_log(s
, AV_LOG_ERROR
, "Packet too small\n");
109 return AVERROR_INVALIDDATA
;
111 av_add_index_entry(vst
, pos
, i
, size
, 0, flags
);
113 if (fsize
> 0 && i
== 0 && pos
> fsize
) {
114 av_log(s
, AV_LOG_ERROR
, "File ends before first packet\n");
115 return AVERROR_INVALIDDATA
;
118 for (i
= 1; i
< pmp
->num_streams
; i
++) {
119 AVStream
*ast
= avformat_new_stream(s
, NULL
);
121 return AVERROR(ENOMEM
);
122 ast
->codecpar
->codec_type
= AVMEDIA_TYPE_AUDIO
;
123 ast
->codecpar
->codec_id
= audio_codec_id
;
124 ast
->codecpar
->ch_layout
.nb_channels
= channels
;
125 ast
->codecpar
->sample_rate
= srate
;
126 avpriv_set_pts_info(ast
, 32, 1, srate
);
131 static int pmp_packet(AVFormatContext
*s
, AVPacket
*pkt
)
133 PMPContext
*pmp
= s
->priv_data
;
134 AVIOContext
*pb
= s
->pb
;
140 if (pmp
->cur_stream
== 0) {
142 pmp
->audio_packets
= avio_r8(pb
);
144 if (!pmp
->audio_packets
) {
145 av_log(s
, AV_LOG_ERROR
, "No audio packets.\n");
146 return AVERROR_INVALIDDATA
;
149 num_packets
= (pmp
->num_streams
- 1) * pmp
->audio_packets
+ 1;
151 pmp
->current_packet
= 0;
152 av_fast_malloc(&pmp
->packet_sizes
,
153 &pmp
->packet_sizes_alloc
,
154 num_packets
* sizeof(*pmp
->packet_sizes
));
155 if (!pmp
->packet_sizes_alloc
) {
156 av_log(s
, AV_LOG_ERROR
, "Cannot (re)allocate packet buffer\n");
157 return AVERROR(ENOMEM
);
159 for (i
= 0; i
< num_packets
; i
++)
160 pmp
->packet_sizes
[i
] = avio_rl32(pb
);
162 ret
= av_get_packet(pb
, pkt
, pmp
->packet_sizes
[pmp
->current_packet
]);
165 pkt
->stream_index
= pmp
->cur_stream
;
167 if (pmp
->current_packet
% pmp
->audio_packets
== 0)
168 pmp
->cur_stream
= (pmp
->cur_stream
+ 1) % pmp
->num_streams
;
169 pmp
->current_packet
++;
173 static int pmp_seek(AVFormatContext
*s
, int stream_index
, int64_t ts
, int flags
)
175 PMPContext
*pmp
= s
->priv_data
;
177 // fall back on default seek now
181 static int pmp_close(AVFormatContext
*s
)
183 PMPContext
*pmp
= s
->priv_data
;
184 av_freep(&pmp
->packet_sizes
);
188 const FFInputFormat ff_pmp_demuxer
= {
190 .p
.long_name
= NULL_IF_CONFIG_SMALL("Playstation Portable PMP"),
191 .priv_data_size
= sizeof(PMPContext
),
192 .read_probe
= pmp_probe
,
193 .read_header
= pmp_header
,
194 .read_packet
= pmp_packet
,
195 .read_seek
= pmp_seek
,
196 .read_close
= pmp_close
,