OSDN Git Service

Fixup armv8-a building, and make multiarch builds work
[android-x86/external-ffmpeg.git] / libavformat / musx.c
1 /*
2  * MUSX demuxer
3  * Copyright (c) 2016 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 "libavutil/avassert.h"
23 #include "avformat.h"
24 #include "internal.h"
25
26 static int musx_probe(AVProbeData *p)
27 {
28     if (memcmp(p->buf, "MUSX", 4))
29         return 0;
30
31     return AVPROBE_SCORE_MAX / 5 * 2;
32 }
33
34 static int musx_read_header(AVFormatContext *s)
35 {
36     unsigned type, version, coding, offset;
37     AVStream *st;
38
39     avio_skip(s->pb, 8);
40     version = avio_rl32(s->pb);
41     if (version != 10 &&
42         version != 6 &&
43         version != 5 &&
44         version != 4 &&
45         version != 201) {
46         avpriv_request_sample(s, "Unsupported version: %d", version);
47         return AVERROR_PATCHWELCOME;
48     }
49     avio_skip(s->pb, 4);
50
51     st = avformat_new_stream(s, NULL);
52     if (!st)
53         return AVERROR(ENOMEM);
54
55     if (version == 201) {
56         avio_skip(s->pb, 8);
57         offset = avio_rl32(s->pb);
58         st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
59         st->codecpar->codec_id    = AV_CODEC_ID_ADPCM_PSX;
60         st->codecpar->channels    = 2;
61         st->codecpar->sample_rate = 32000;
62         st->codecpar->block_align = 0x80 * st->codecpar->channels;
63     }  else if (version == 10) {
64         type = avio_rl32(s->pb);
65         st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
66         offset = 0x800;
67         switch (type) {
68         case MKTAG('P', 'S', '3', '_'):
69             st->codecpar->channels    = 2;
70             st->codecpar->sample_rate = 44100;
71             avio_skip(s->pb, 44);
72             coding = avio_rl32(s->pb);
73             if (coding == MKTAG('D', 'A', 'T', '4') ||
74                 coding == MKTAG('D', 'A', 'T', '8')) {
75                 avio_skip(s->pb, 4);
76                 st->codecpar->channels   = avio_rl32(s->pb);
77                 if (st->codecpar->channels <= 0 ||
78                     st->codecpar->channels > INT_MAX / 0x20)
79                     return AVERROR_INVALIDDATA;
80                 st->codecpar->sample_rate = avio_rl32(s->pb);
81             }
82             st->codecpar->codec_id   = AV_CODEC_ID_ADPCM_IMA_DAT4;
83             st->codecpar->block_align = 0x20 * st->codecpar->channels;
84             break;
85         case MKTAG('W', 'I', 'I', '_'):
86             avio_skip(s->pb, 44);
87             coding = avio_rl32(s->pb);
88             if (coding != MKTAG('D', 'A', 'T', '4') &&
89                 coding != MKTAG('D', 'A', 'T', '8')) {
90                 avpriv_request_sample(s, "Unsupported coding: %X", coding);
91                 return AVERROR_PATCHWELCOME;
92             }
93             avio_skip(s->pb, 4);
94             st->codecpar->codec_id   = AV_CODEC_ID_ADPCM_IMA_DAT4;
95             st->codecpar->channels   = avio_rl32(s->pb);
96             if (st->codecpar->channels <= 0 ||
97                 st->codecpar->channels > INT_MAX / 0x20)
98                 return AVERROR_INVALIDDATA;
99             st->codecpar->sample_rate = avio_rl32(s->pb);
100             st->codecpar->block_align = 0x20 * st->codecpar->channels;
101             break;
102         case MKTAG('X', 'E', '_', '_'):
103             st->codecpar->codec_id    = AV_CODEC_ID_ADPCM_IMA_DAT4;
104             st->codecpar->channels    = 2;
105             st->codecpar->sample_rate = 32000;
106             st->codecpar->block_align = 0x20 * st->codecpar->channels;
107             break;
108         case MKTAG('P', 'S', 'P', '_'):
109             st->codecpar->codec_id    = AV_CODEC_ID_ADPCM_PSX;
110             st->codecpar->channels    = 2;
111             st->codecpar->sample_rate = 32768;
112             st->codecpar->block_align = 0x80 * st->codecpar->channels;
113             break;
114         case MKTAG('P', 'S', '2', '_'):
115             st->codecpar->codec_id    = AV_CODEC_ID_ADPCM_PSX;
116             st->codecpar->channels    = 2;
117             st->codecpar->sample_rate = 32000;
118             st->codecpar->block_align = 0x80 * st->codecpar->channels;
119             break;
120         default:
121             avpriv_request_sample(s, "Unsupported type: %X", type);
122             return AVERROR_PATCHWELCOME;
123         }
124     } else if (version == 6 || version == 5 || version == 4) {
125         type = avio_rl32(s->pb);
126         avio_skip(s->pb, 20);
127         st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
128         st->codecpar->channels    = 2;
129         switch (type) {
130         case MKTAG('G', 'C', '_', '_'):
131             st->codecpar->codec_id    = AV_CODEC_ID_ADPCM_IMA_DAT4;
132             st->codecpar->block_align = 0x20 * st->codecpar->channels;
133             st->codecpar->sample_rate = 32000;
134             offset = avio_rb32(s->pb);
135             break;
136         case MKTAG('P', 'S', '2', '_'):
137             st->codecpar->codec_id    = AV_CODEC_ID_ADPCM_PSX;
138             st->codecpar->block_align = 0x80 * st->codecpar->channels;
139             st->codecpar->sample_rate = 32000;
140             offset = avio_rl32(s->pb);
141             break;
142         case MKTAG('X', 'B', '_', '_'):
143             st->codecpar->codec_id    = AV_CODEC_ID_ADPCM_IMA_DAT4;
144             st->codecpar->block_align = 0x20 * st->codecpar->channels;
145             st->codecpar->sample_rate = 44100;
146             offset = avio_rl32(s->pb);
147             break;
148         default:
149             avpriv_request_sample(s, "Unsupported type: %X", type);
150             return AVERROR_PATCHWELCOME;
151         }
152     } else {
153         av_assert0(0);
154     }
155
156     avio_seek(s->pb, offset, SEEK_SET);
157
158     avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
159
160     return 0;
161 }
162
163 static int musx_read_packet(AVFormatContext *s, AVPacket *pkt)
164 {
165     AVCodecParameters *par = s->streams[0]->codecpar;
166
167     return av_get_packet(s->pb, pkt, par->block_align);
168 }
169
170 AVInputFormat ff_musx_demuxer = {
171     .name           = "musx",
172     .long_name      = NULL_IF_CONFIG_SMALL("Eurocom MUSX"),
173     .read_probe     = musx_probe,
174     .read_header    = musx_read_header,
175     .read_packet    = musx_read_packet,
176     .extensions     = "musx",
177 };