Newer
Older
/*
* AVR demuxer
* Copyright (c) 2012 Paul B Mahol
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/intreadwrite.h"
#include "avformat.h"
#include "internal.h"
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
static int avr_probe(AVProbeData *p)
{
if (AV_RL32(p->buf) == MKTAG('2', 'B', 'I', 'T'))
return AVPROBE_SCORE_MAX / 2;
return 0;
}
static int avr_read_header(AVFormatContext *s)
{
uint16_t chan, sign, bps;
AVStream *st;
st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
avio_skip(s->pb, 4); // magic
avio_skip(s->pb, 8); // sample_name
chan = avio_rb16(s->pb);
if (!chan) {
st->codec->channels = 1;
} else if (chan == 0xFFFFu) {
st->codec->channels = 2;
} else {
av_log_ask_for_sample(s, "unknown number of channels\n");
return AVERROR_PATCHWELCOME;
}
st->codec->bits_per_coded_sample = bps = avio_rb16(s->pb);
sign = avio_rb16(s->pb);
avio_skip(s->pb, 2); // loop
avio_skip(s->pb, 2); // midi
avio_skip(s->pb, 1); // replay speed
st->codec->sample_rate = avio_rb24(s->pb);
avio_skip(s->pb, 4 * 3);
avio_skip(s->pb, 2 * 3);
avio_skip(s->pb, 20);
avio_skip(s->pb, 64);
if (!sign && bps == 8) {
st->codec->codec_id = AV_CODEC_ID_PCM_U8;
} else if (!sign && bps == 16) {
st->codec->codec_id = AV_CODEC_ID_PCM_U16BE;
} else if (sign == 0xFFFFu && bps == 8) {
st->codec->codec_id = AV_CODEC_ID_PCM_S8;
} else if (sign == 0xFFFFu && bps == 16) {
st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
} else {
av_log_ask_for_sample(s, "unknown bits per sample\n");
return AVERROR_PATCHWELCOME;
}
st->codec->block_align = bps * st->codec->channels / 8;
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
return 0;
}
AVInputFormat ff_avr_demuxer = {
.name = "avr",
.long_name = NULL_IF_CONFIG_SMALL("AVR (Audio Visual Research)"),