00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "avformat.h"
00027 #include "raw.h"
00028 #include "riff.h"
00029 #include "bswap.h"
00030
00031
00032 #define AU_UNKNOWN_SIZE ((uint32_t)(~0))
00033
00034 static int sol_probe(AVProbeData *p)
00035 {
00036
00037 uint16_t magic;
00038 magic=le2me_16(*((uint16_t*)p->buf));
00039 if ((magic == 0x0B8D || magic == 0x0C0D || magic == 0x0C8D) &&
00040 p->buf[2] == 'S' && p->buf[3] == 'O' &&
00041 p->buf[4] == 'L' && p->buf[5] == 0)
00042 return AVPROBE_SCORE_MAX;
00043 else
00044 return 0;
00045 }
00046
00047 #define SOL_DPCM 1
00048 #define SOL_16BIT 4
00049 #define SOL_STEREO 16
00050
00051 static int sol_codec_id(int magic, int type)
00052 {
00053 if (magic == 0x0B8D)
00054 {
00055 if (type & SOL_DPCM) return CODEC_ID_SOL_DPCM;
00056 else return CODEC_ID_PCM_U8;
00057 }
00058 if (type & SOL_DPCM)
00059 {
00060 if (type & SOL_16BIT) return CODEC_ID_SOL_DPCM;
00061 else if (magic == 0x0C8D) return CODEC_ID_SOL_DPCM;
00062 else return CODEC_ID_SOL_DPCM;
00063 }
00064 if (type & SOL_16BIT) return CODEC_ID_PCM_S16LE;
00065 return CODEC_ID_PCM_U8;
00066 }
00067
00068 static int sol_codec_type(int magic, int type)
00069 {
00070 if (magic == 0x0B8D) return 1;
00071 if (type & SOL_DPCM)
00072 {
00073 if (type & SOL_16BIT) return 3;
00074 else if (magic == 0x0C8D) return 1;
00075 else return 2;
00076 }
00077 return -1;
00078 }
00079
00080 static int sol_channels(int magic, int type)
00081 {
00082 if (magic == 0x0B8D || !(type & SOL_STEREO)) return 1;
00083 return 2;
00084 }
00085
00086 static int sol_read_header(AVFormatContext *s,
00087 AVFormatParameters *ap)
00088 {
00089 int size;
00090 unsigned int magic,tag;
00091 ByteIOContext *pb = s->pb;
00092 unsigned int id, codec, channels, rate, type;
00093 AVStream *st;
00094
00095
00096 magic = get_le16(pb);
00097 tag = get_le32(pb);
00098 if (tag != MKTAG('S', 'O', 'L', 0))
00099 return -1;
00100 rate = get_le16(pb);
00101 type = get_byte(pb);
00102 size = get_le32(pb);
00103 if (magic != 0x0B8D)
00104 get_byte(pb);
00105
00106 codec = sol_codec_id(magic, type);
00107 channels = sol_channels(magic, type);
00108
00109 if (codec == CODEC_ID_SOL_DPCM)
00110 id = sol_codec_type(magic, type);
00111 else id = 0;
00112
00113
00114 st = av_new_stream(s, 0);
00115 if (!st)
00116 return -1;
00117 st->codec->codec_type = CODEC_TYPE_AUDIO;
00118 st->codec->codec_tag = id;
00119 st->codec->codec_id = codec;
00120 st->codec->channels = channels;
00121 st->codec->sample_rate = rate;
00122 av_set_pts_info(st, 64, 1, rate);
00123 return 0;
00124 }
00125
00126 #define MAX_SIZE 4096
00127
00128 static int sol_read_packet(AVFormatContext *s,
00129 AVPacket *pkt)
00130 {
00131 int ret;
00132
00133 if (url_feof(s->pb))
00134 return AVERROR(EIO);
00135 ret= av_get_packet(s->pb, pkt, MAX_SIZE);
00136 pkt->stream_index = 0;
00137
00138
00139
00140 pkt->size = ret;
00141 return 0;
00142 }
00143
00144 static int sol_read_close(AVFormatContext *s)
00145 {
00146 return 0;
00147 }
00148
00149 AVInputFormat sol_demuxer = {
00150 "sol",
00151 "Sierra SOL Format",
00152 0,
00153 sol_probe,
00154 sol_read_header,
00155 sol_read_packet,
00156 sol_read_close,
00157 pcm_read_seek,
00158 };