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 #include "ircam.h"
00027
00028 static int ircam_probe(AVProbeData *p)
00029 {
00030 if ((p->buf[0] == 0x64 && p->buf[1] == 0xA3 && p->buf[3] == 0x00 &&
00031 p->buf[2] >= 1 && p->buf[2] <= 4) ||
00032 (p->buf[3] == 0x64 && p->buf[2] == 0xA3 && p->buf[0] == 0x00 &&
00033 p->buf[1] >= 1 && p->buf[1] <= 3) &&
00034 AV_RN32(p->buf + 4) && AV_RN32(p->buf + 8))
00035 return AVPROBE_SCORE_MAX / 4 * 3;
00036 return 0;
00037 }
00038
00039 static const struct endianess {
00040 uint32_t magic;
00041 int is_le;
00042 } table[] = {
00043 { 0x64A30100, 0 },
00044 { 0x64A30200, 1 },
00045 { 0x64A30300, 0 },
00046 { 0x64A30400, 1 },
00047 { 0x0001A364, 1 },
00048 { 0x0002A364, 0 },
00049 { 0x0003A364, 1 },
00050 };
00051
00052 static int ircam_read_header(AVFormatContext *s)
00053 {
00054 uint32_t magic, sample_rate, channels, tag;
00055 const AVCodecTag *tags;
00056 int le = -1, i;
00057 AVStream *st;
00058
00059 magic = avio_rl32(s->pb);
00060 for (i = 0; i < 7; i++) {
00061 if (magic == table[i].magic) {
00062 le = table[i].is_le;
00063 break;
00064 }
00065 }
00066
00067 if (le == 1) {
00068 sample_rate = av_int2float(avio_rl32(s->pb));
00069 channels = avio_rl32(s->pb);
00070 tag = avio_rl32(s->pb);
00071 tags = ff_codec_ircam_le_tags;
00072 } else if (le == 0) {
00073 sample_rate = av_int2float(avio_rb32(s->pb));
00074 channels = avio_rb32(s->pb);
00075 tag = avio_rb32(s->pb);
00076 tags = ff_codec_ircam_be_tags;
00077 } else {
00078 return AVERROR_INVALIDDATA;
00079 }
00080
00081 if (!channels || !sample_rate)
00082 return AVERROR_INVALIDDATA;
00083
00084 st = avformat_new_stream(s, NULL);
00085 if (!st)
00086 return AVERROR(ENOMEM);
00087
00088 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00089 st->codec->channels = channels;
00090 st->codec->sample_rate = sample_rate;
00091
00092 st->codec->codec_id = ff_codec_get_id(tags, tag);
00093 if (st->codec->codec_id == AV_CODEC_ID_NONE) {
00094 av_log(s, AV_LOG_ERROR, "unknown tag %X\n", tag);
00095 return AVERROR_INVALIDDATA;
00096 }
00097
00098 st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
00099 st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8;
00100 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00101 avio_skip(s->pb, 1008);
00102
00103 return 0;
00104 }
00105
00106 AVInputFormat ff_ircam_demuxer = {
00107 .name = "ircam",
00108 .long_name = NULL_IF_CONFIG_SMALL("Berkeley/IRCAM/CARL Sound Format"),
00109 .read_probe = ircam_probe,
00110 .read_header = ircam_read_header,
00111 .read_packet = ff_pcm_read_packet,
00112 .read_seek = ff_pcm_read_seek,
00113 .extensions = "sf,ircam",
00114 .flags = AVFMT_GENERIC_INDEX,
00115 };