00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/intreadwrite.h"
00023 #include "avformat.h"
00024 #include "internal.h"
00025 #include "pcm.h"
00026
00027 static int avr_probe(AVProbeData *p)
00028 {
00029 if (AV_RL32(p->buf) == MKTAG('2', 'B', 'I', 'T'))
00030 return AVPROBE_SCORE_MAX / 2;
00031 return 0;
00032 }
00033
00034 static int avr_read_header(AVFormatContext *s)
00035 {
00036 uint16_t chan, sign, bps;
00037 AVStream *st;
00038
00039 st = avformat_new_stream(s, NULL);
00040 if (!st)
00041 return AVERROR(ENOMEM);
00042
00043 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00044
00045 avio_skip(s->pb, 4);
00046 avio_skip(s->pb, 8);
00047
00048 chan = avio_rb16(s->pb);
00049 if (!chan) {
00050 st->codec->channels = 1;
00051 } else if (chan == 0xFFFFu) {
00052 st->codec->channels = 2;
00053 } else {
00054 av_log_ask_for_sample(s, "unknown number of channels\n");
00055 return AVERROR_PATCHWELCOME;
00056 }
00057
00058 st->codec->bits_per_coded_sample = bps = avio_rb16(s->pb);
00059
00060 sign = avio_rb16(s->pb);
00061
00062 avio_skip(s->pb, 2);
00063 avio_skip(s->pb, 2);
00064 avio_skip(s->pb, 1);
00065
00066 st->codec->sample_rate = avio_rb24(s->pb);
00067 avio_skip(s->pb, 4 * 3);
00068 avio_skip(s->pb, 2 * 3);
00069 avio_skip(s->pb, 20);
00070 avio_skip(s->pb, 64);
00071
00072 if (!sign && bps == 8) {
00073 st->codec->codec_id = AV_CODEC_ID_PCM_U8;
00074 } else if (!sign && bps == 16) {
00075 st->codec->codec_id = AV_CODEC_ID_PCM_U16BE;
00076 } else if (sign == 0xFFFFu && bps == 8) {
00077 st->codec->codec_id = AV_CODEC_ID_PCM_S8;
00078 } else if (sign == 0xFFFFu && bps == 16) {
00079 st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
00080 } else {
00081 av_log_ask_for_sample(s, "unknown bits per sample\n");
00082 return AVERROR_PATCHWELCOME;
00083 }
00084
00085 st->codec->block_align = bps * st->codec->channels / 8;
00086
00087 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00088 return 0;
00089 }
00090
00091 AVInputFormat ff_avr_demuxer = {
00092 .name = "avr",
00093 .long_name = NULL_IF_CONFIG_SMALL("AVR (Audio Visual Research)"),
00094 .read_probe = avr_probe,
00095 .read_header = avr_read_header,
00096 .read_packet = ff_pcm_read_packet,
00097 .read_seek = ff_pcm_read_seek,
00098 .extensions = "avr",
00099 .flags = AVFMT_GENERIC_INDEX,
00100 };