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"
31 uint32_t *packet_sizes
;
32 int packet_sizes_alloc
;
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
;
42 static int pmp_header(AVFormatContext
*s
)
44 PMPContext
*pmp
= s
->priv_data
;
45 AVIOContext
*pb
= s
->pb
;
48 int audio_codec_id
= AV_CODEC_ID_NONE
;
52 int64_t fsize
= avio_size(pb
);
54 AVStream
*vst
= avformat_new_stream(s
, NULL
);
56 return AVERROR(ENOMEM
);
57 vst
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
59 switch (avio_rl32(pb
)) {
61 vst
->codec
->codec_id
= AV_CODEC_ID_MPEG4
;
64 vst
->codec
->codec_id
= AV_CODEC_ID_H264
;
67 av_log(s
, AV_LOG_ERROR
, "Unsupported video format\n");
70 index_cnt
= avio_rl32(pb
);
71 vst
->codec
->width
= avio_rl32(pb
);
72 vst
->codec
->height
= avio_rl32(pb
);
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
;
80 switch (avio_rl32(pb
)) {
82 audio_codec_id
= AV_CODEC_ID_MP3
;
85 av_log(s
, AV_LOG_ERROR
, "AAC not yet correctly supported\n");
86 audio_codec_id
= AV_CODEC_ID_AAC
;
89 av_log(s
, AV_LOG_ERROR
, "Unsupported audio format\n");
92 pmp
->num_streams
= avio_rl16(pb
) + 1;
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;
101 av_log(s
, AV_LOG_FATAL
, "Encountered EOF while reading index.\n");
102 return AVERROR_INVALIDDATA
;
105 if (size
< 9 + 4*pmp
->num_streams
) {
106 av_log(s
, AV_LOG_ERROR
, "Packet too small\n");
107 return AVERROR_INVALIDDATA
;
109 av_add_index_entry(vst
, pos
, i
, size
, 0, flags
);
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
;
116 for (i
= 1; i
< pmp
->num_streams
; i
++) {
117 AVStream
*ast
= avformat_new_stream(s
, NULL
);
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
);
129 static int pmp_packet(AVFormatContext
*s
, AVPacket
*pkt
)
131 PMPContext
*pmp
= s
->priv_data
;
132 AVIOContext
*pb
= s
->pb
;
138 if (pmp
->cur_stream
== 0) {
140 pmp
->audio_packets
= avio_r8(pb
);
142 if (!pmp
->audio_packets
) {
143 av_log(s
, AV_LOG_ERROR
, "No audio packets.\n");
144 return AVERROR_INVALIDDATA
;
147 num_packets
= (pmp
->num_streams
- 1) * pmp
->audio_packets
+ 1;
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
);
157 for (i
= 0; i
< num_packets
; i
++)
158 pmp
->packet_sizes
[i
] = avio_rl32(pb
);
160 ret
= av_get_packet(pb
, pkt
, pmp
->packet_sizes
[pmp
->current_packet
]);
163 pkt
->stream_index
= pmp
->cur_stream
;
165 if (pmp
->current_packet
% pmp
->audio_packets
== 0)
166 pmp
->cur_stream
= (pmp
->cur_stream
+ 1) % pmp
->num_streams
;
167 pmp
->current_packet
++;
171 static int pmp_seek(AVFormatContext
*s
, int stream_index
, int64_t ts
, int flags
)
173 PMPContext
*pmp
= s
->priv_data
;
175 // fall back on default seek now
179 static int pmp_close(AVFormatContext
*s
)
181 PMPContext
*pmp
= s
->priv_data
;
182 av_freep(&pmp
->packet_sizes
);
186 AVInputFormat ff_pmp_demuxer
= {
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
,