3 * Copyright (c) 2011 Reimar Döffinger
5 * This file is part of Libav.
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.
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.
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
22 #include "libavutil/intreadwrite.h"
26 typedef struct PMPContext
{
31 uint32_t *packet_sizes
;
32 int packet_sizes_alloc
;
35 static int pmp_probe(AVProbeData
*p
)
37 if (!memcmp(p
->buf
, "pmpm\1\0\0\0", 8))
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 AVStream
*vst
= avformat_new_stream(s
, NULL
);
54 return AVERROR(ENOMEM
);
55 vst
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
57 switch (avio_rl32(pb
)) {
59 vst
->codec
->codec_id
= AV_CODEC_ID_MPEG4
;
62 vst
->codec
->codec_id
= AV_CODEC_ID_H264
;
65 av_log(s
, AV_LOG_ERROR
, "Unsupported video format\n");
68 index_cnt
= avio_rl32(pb
);
69 vst
->codec
->width
= avio_rl32(pb
);
70 vst
->codec
->height
= avio_rl32(pb
);
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
;
78 switch (avio_rl32(pb
)) {
80 audio_codec_id
= AV_CODEC_ID_MP3
;
83 av_log(s
, AV_LOG_WARNING
, "AAC is not yet correctly supported\n");
84 audio_codec_id
= AV_CODEC_ID_AAC
;
87 av_log(s
, AV_LOG_ERROR
, "Unsupported audio format\n");
90 pmp
->num_streams
= avio_rl16(pb
) + 1;
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
);
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
);
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;
109 av_add_index_entry(vst
, pos
, i
, size
, 0, flags
);
115 static int pmp_packet(AVFormatContext
*s
, AVPacket
*pkt
)
117 PMPContext
*pmp
= s
->priv_data
;
118 AVIOContext
*pb
= s
->pb
;
124 if (pmp
->cur_stream
== 0) {
126 pmp
->audio_packets
= avio_r8(pb
);
127 if (!pmp
->audio_packets
) {
128 av_log(s
, AV_LOG_ERROR
, "No audio packets.\n");
129 return AVERROR_INVALIDDATA
;
132 num_packets
= (pmp
->num_streams
- 1) * pmp
->audio_packets
+ 1;
134 pmp
->current_packet
= 0;
135 av_fast_malloc(&pmp
->packet_sizes
,
136 &pmp
->packet_sizes_alloc
,
137 num_packets
* sizeof(*pmp
->packet_sizes
));
138 if (!pmp
->packet_sizes_alloc
) {
139 av_log(s
, AV_LOG_ERROR
, "Cannot (re)allocate packet buffer\n");
140 return AVERROR(ENOMEM
);
142 for (i
= 0; i
< num_packets
; i
++)
143 pmp
->packet_sizes
[i
] = avio_rl32(pb
);
145 ret
= av_get_packet(pb
, pkt
, pmp
->packet_sizes
[pmp
->current_packet
]);
148 // FIXME: this is a hack that should be removed once
149 // compute_pkt_fields() can handle timestamps properly
150 if (pmp
->cur_stream
== 0)
151 pkt
->dts
= s
->streams
[0]->cur_dts
++;
152 pkt
->stream_index
= pmp
->cur_stream
;
154 pmp
->current_packet
++;
155 if (pmp
->current_packet
== 1 || pmp
->current_packet
> pmp
->audio_packets
)
156 pmp
->cur_stream
= (pmp
->cur_stream
+ 1) % pmp
->num_streams
;
161 static int pmp_seek(AVFormatContext
*s
, int stream_idx
, int64_t ts
, int flags
)
163 PMPContext
*pmp
= s
->priv_data
;
165 // fall back on default seek now
169 static int pmp_close(AVFormatContext
*s
)
171 PMPContext
*pmp
= s
->priv_data
;
172 av_freep(&pmp
->packet_sizes
);
176 AVInputFormat ff_pmp_demuxer
= {
178 .long_name
= NULL_IF_CONFIG_SMALL("Playstation Portable PMP"),
179 .priv_data_size
= sizeof(PMPContext
),
180 .read_probe
= pmp_probe
,
181 .read_header
= pmp_header
,
182 .read_packet
= pmp_packet
,
183 .read_seek
= pmp_seek
,
184 .read_close
= pmp_close
,