Line data Source code
1 : /*
2 : * SVAG demuxer
3 : * Copyright (c) 2015 Paul B Mahol
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 "avformat.h"
23 : #include "internal.h"
24 :
25 6217 : static int svag_probe(AVProbeData *p)
26 : {
27 6217 : if (memcmp(p->buf, "Svag", 4))
28 6217 : return 0;
29 :
30 0 : return AVPROBE_SCORE_MAX;
31 : }
32 :
33 0 : static int svag_read_header(AVFormatContext *s)
34 : {
35 : unsigned size, align;
36 : AVStream *st;
37 :
38 0 : avio_skip(s->pb, 4);
39 :
40 0 : st = avformat_new_stream(s, NULL);
41 0 : if (!st)
42 0 : return AVERROR(ENOMEM);
43 :
44 0 : size = avio_rl32(s->pb);
45 0 : st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
46 0 : st->codecpar->codec_id = AV_CODEC_ID_ADPCM_PSX;
47 0 : st->codecpar->sample_rate = avio_rl32(s->pb);
48 0 : if (st->codecpar->sample_rate <= 0)
49 0 : return AVERROR_INVALIDDATA;
50 0 : st->codecpar->channels = avio_rl32(s->pb);
51 0 : if (st->codecpar->channels <= 0 || st->codecpar->channels > 8)
52 0 : return AVERROR_INVALIDDATA;
53 0 : st->duration = size / (16 * st->codecpar->channels) * 28;
54 0 : align = avio_rl32(s->pb);
55 0 : if (align <= 0 || align > INT_MAX / st->codecpar->channels)
56 0 : return AVERROR_INVALIDDATA;
57 0 : st->codecpar->block_align = align * st->codecpar->channels;
58 0 : avio_skip(s->pb, 0x800 - avio_tell(s->pb));
59 0 : avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
60 :
61 0 : return 0;
62 : }
63 :
64 0 : static int svag_read_packet(AVFormatContext *s, AVPacket *pkt)
65 : {
66 0 : AVCodecParameters *par = s->streams[0]->codecpar;
67 :
68 0 : return av_get_packet(s->pb, pkt, par->block_align);
69 : }
70 :
71 : AVInputFormat ff_svag_demuxer = {
72 : .name = "svag",
73 : .long_name = NULL_IF_CONFIG_SMALL("Konami PS2 SVAG"),
74 : .read_probe = svag_probe,
75 : .read_header = svag_read_header,
76 : .read_packet = svag_read_packet,
77 : .extensions = "svag",
78 : };
|