00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/channel_layout.h"
00023 #include "libavutil/intreadwrite.h"
00024 #include "avformat.h"
00025 #include "internal.h"
00026 #include "ast.h"
00027
00028 static int ast_probe(AVProbeData *p)
00029 {
00030 if (AV_RL32(p->buf) == MKTAG('S','T','R','M') &&
00031 AV_RB16(p->buf + 10) &&
00032 AV_RB16(p->buf + 12) &&
00033 AV_RB32(p->buf + 16))
00034 return AVPROBE_SCORE_MAX / 3 * 2;
00035 return 0;
00036 }
00037
00038 static int ast_read_header(AVFormatContext *s)
00039 {
00040 int depth;
00041 AVStream *st;
00042
00043 st = avformat_new_stream(s, NULL);
00044 if (!st)
00045 return AVERROR(ENOMEM);
00046
00047 avio_skip(s->pb, 8);
00048 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00049 st->codec->codec_id = ff_codec_get_id(ff_codec_ast_tags, avio_rb16(s->pb));
00050
00051 depth = avio_rb16(s->pb);
00052 if (depth != 16) {
00053 av_log_ask_for_sample(s, "unsupported depth %d\n", depth);
00054 return AVERROR_INVALIDDATA;
00055 }
00056
00057 st->codec->channels = avio_rb16(s->pb);
00058 if (!st->codec->channels)
00059 return AVERROR_INVALIDDATA;
00060
00061 if (st->codec->channels == 2)
00062 st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
00063 else if (st->codec->channels == 4)
00064 st->codec->channel_layout = AV_CH_LAYOUT_4POINT0;
00065
00066 avio_skip(s->pb, 2);
00067 st->codec->sample_rate = avio_rb32(s->pb);
00068 if (st->codec->sample_rate <= 0)
00069 return AVERROR_INVALIDDATA;
00070 st->start_time = 0;
00071 st->duration = avio_rb32(s->pb);
00072 avio_skip(s->pb, 40);
00073 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00074
00075 return 0;
00076 }
00077
00078 static int ast_read_packet(AVFormatContext *s, AVPacket *pkt)
00079 {
00080 uint32_t type, size;
00081 int64_t pos;
00082 int ret;
00083
00084 if (url_feof(s->pb))
00085 return AVERROR_EOF;
00086
00087 pos = avio_tell(s->pb);
00088 type = avio_rl32(s->pb);
00089 size = avio_rb32(s->pb);
00090 if (size > INT_MAX / s->streams[0]->codec->channels)
00091 return AVERROR_INVALIDDATA;
00092
00093 size *= s->streams[0]->codec->channels;
00094 if ((ret = avio_skip(s->pb, 24)) < 0)
00095 return ret;
00096
00097 if (type == MKTAG('B','L','C','K')) {
00098 ret = av_get_packet(s->pb, pkt, size);
00099 pkt->stream_index = 0;
00100 pkt->pos = pos;
00101 } else {
00102 av_log(s, AV_LOG_ERROR, "unknown chunk %x\n", type);
00103 avio_skip(s->pb, size);
00104 ret = AVERROR_INVALIDDATA;
00105 }
00106
00107 return ret;
00108 }
00109
00110 AVInputFormat ff_ast_demuxer = {
00111 .name = "ast",
00112 .long_name = NULL_IF_CONFIG_SMALL("AST (Audio Stream)"),
00113 .read_probe = ast_probe,
00114 .read_header = ast_read_header,
00115 .read_packet = ast_read_packet,
00116 .extensions = "ast",
00117 .flags = AVFMT_GENERIC_INDEX,
00118 .codec_tag = (const AVCodecTag* const []){ff_codec_ast_tags, 0},
00119 };