00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavcodec/get_bits.h"
00023 #include "libavcodec/unary.h"
00024 #include "avformat.h"
00025 #include "avio_internal.h"
00026
00028 #define MKMPCTAG(a, b) (a | (b << 8))
00029
00030 #define TAG_MPCK MKTAG('M','P','C','K')
00031
00033 enum MPCPacketTags{
00034 TAG_STREAMHDR = MKMPCTAG('S','H'),
00035 TAG_STREAMEND = MKMPCTAG('S','E'),
00036
00037 TAG_AUDIOPACKET = MKMPCTAG('A','P'),
00038
00039 TAG_SEEKTBLOFF = MKMPCTAG('S','O'),
00040 TAG_SEEKTABLE = MKMPCTAG('S','T'),
00041
00042 TAG_REPLAYGAIN = MKMPCTAG('R','G'),
00043 TAG_ENCINFO = MKMPCTAG('E','I'),
00044 };
00045
00046 static const int mpc8_rate[8] = { 44100, 48000, 37800, 32000, -1, -1, -1, -1 };
00047
00048 typedef struct {
00049 int ver;
00050 int frame;
00051 int64_t header_pos;
00052 int64_t samples;
00053 } MPCContext;
00054
00055 static inline int64_t bs_get_v(uint8_t **bs)
00056 {
00057 int64_t v = 0;
00058 int br = 0;
00059 int c;
00060
00061 do {
00062 c = **bs; (*bs)++;
00063 v <<= 7;
00064 v |= c & 0x7F;
00065 br++;
00066 if (br > 10)
00067 return -1;
00068 } while (c & 0x80);
00069
00070 return v - br;
00071 }
00072
00073 static int mpc8_probe(AVProbeData *p)
00074 {
00075 uint8_t *bs = p->buf + 4;
00076 uint8_t *bs_end = bs + p->buf_size;
00077 int64_t size;
00078
00079 if (p->buf_size < 16)
00080 return 0;
00081 if (AV_RL32(p->buf) != TAG_MPCK)
00082 return 0;
00083 while (bs < bs_end + 3) {
00084 int header_found = (bs[0] == 'S' && bs[1] == 'H');
00085 if (bs[0] < 'A' || bs[0] > 'Z' || bs[1] < 'A' || bs[1] > 'Z')
00086 return 0;
00087 bs += 2;
00088 size = bs_get_v(&bs);
00089 if (size < 2)
00090 return 0;
00091 if (bs + size - 2 >= bs_end)
00092 return AVPROBE_SCORE_MAX / 4 - 1;
00093 if (header_found) {
00094 if (size < 11 || size > 28)
00095 return 0;
00096 if (!AV_RL32(bs))
00097 return 0;
00098 return AVPROBE_SCORE_MAX;
00099 } else {
00100 bs += size - 2;
00101 }
00102 }
00103 return 0;
00104 }
00105
00106 static inline int64_t gb_get_v(GetBitContext *gb)
00107 {
00108 int64_t v = 0;
00109 int bits = 0;
00110 while(get_bits1(gb) && bits < 64-7){
00111 v <<= 7;
00112 v |= get_bits(gb, 7);
00113 bits += 7;
00114 }
00115 v <<= 7;
00116 v |= get_bits(gb, 7);
00117
00118 return v;
00119 }
00120
00121 static void mpc8_get_chunk_header(AVIOContext *pb, int *tag, int64_t *size)
00122 {
00123 int64_t pos;
00124 pos = avio_tell(pb);
00125 *tag = avio_rl16(pb);
00126 *size = ffio_read_varlen(pb);
00127 *size -= avio_tell(pb) - pos;
00128 }
00129
00130 static void mpc8_parse_seektable(AVFormatContext *s, int64_t off)
00131 {
00132 MPCContext *c = s->priv_data;
00133 int tag;
00134 int64_t size, pos, ppos[2];
00135 uint8_t *buf;
00136 int i, t, seekd;
00137 GetBitContext gb;
00138
00139 avio_seek(s->pb, off, SEEK_SET);
00140 mpc8_get_chunk_header(s->pb, &tag, &size);
00141 if(tag != TAG_SEEKTABLE){
00142 av_log(s, AV_LOG_ERROR, "No seek table at given position\n");
00143 return;
00144 }
00145 if(!(buf = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE)))
00146 return;
00147 avio_read(s->pb, buf, size);
00148 init_get_bits(&gb, buf, size * 8);
00149 size = gb_get_v(&gb);
00150 if(size > UINT_MAX/4 || size > c->samples/1152){
00151 av_log(s, AV_LOG_ERROR, "Seek table is too big\n");
00152 return;
00153 }
00154 seekd = get_bits(&gb, 4);
00155 for(i = 0; i < 2; i++){
00156 pos = gb_get_v(&gb) + c->header_pos;
00157 ppos[1 - i] = pos;
00158 av_add_index_entry(s->streams[0], pos, i, 0, 0, AVINDEX_KEYFRAME);
00159 }
00160 for(; i < size; i++){
00161 t = get_unary(&gb, 1, 33) << 12;
00162 t += get_bits(&gb, 12);
00163 if(t & 1)
00164 t = -(t & ~1);
00165 pos = (t >> 1) + ppos[0]*2 - ppos[1];
00166 av_add_index_entry(s->streams[0], pos, i << seekd, 0, 0, AVINDEX_KEYFRAME);
00167 ppos[1] = ppos[0];
00168 ppos[0] = pos;
00169 }
00170 av_free(buf);
00171 }
00172
00173 static void mpc8_handle_chunk(AVFormatContext *s, int tag, int64_t chunk_pos, int64_t size)
00174 {
00175 AVIOContext *pb = s->pb;
00176 int64_t pos, off;
00177
00178 switch(tag){
00179 case TAG_SEEKTBLOFF:
00180 pos = avio_tell(pb) + size;
00181 off = ffio_read_varlen(pb);
00182 mpc8_parse_seektable(s, chunk_pos + off);
00183 avio_seek(pb, pos, SEEK_SET);
00184 break;
00185 default:
00186 avio_skip(pb, size);
00187 }
00188 }
00189
00190 static int mpc8_read_header(AVFormatContext *s, AVFormatParameters *ap)
00191 {
00192 MPCContext *c = s->priv_data;
00193 AVIOContext *pb = s->pb;
00194 AVStream *st;
00195 int tag = 0;
00196 int64_t size, pos;
00197
00198 c->header_pos = avio_tell(pb);
00199 if(avio_rl32(pb) != TAG_MPCK){
00200 av_log(s, AV_LOG_ERROR, "Not a Musepack8 file\n");
00201 return -1;
00202 }
00203
00204 while(!url_feof(pb)){
00205 pos = avio_tell(pb);
00206 mpc8_get_chunk_header(pb, &tag, &size);
00207 if(tag == TAG_STREAMHDR)
00208 break;
00209 mpc8_handle_chunk(s, tag, pos, size);
00210 }
00211 if(tag != TAG_STREAMHDR){
00212 av_log(s, AV_LOG_ERROR, "Stream header not found\n");
00213 return -1;
00214 }
00215 pos = avio_tell(pb);
00216 avio_skip(pb, 4);
00217 c->ver = avio_r8(pb);
00218 if(c->ver != 8){
00219 av_log(s, AV_LOG_ERROR, "Unknown stream version %d\n", c->ver);
00220 return -1;
00221 }
00222 c->samples = ffio_read_varlen(pb);
00223 ffio_read_varlen(pb);
00224
00225 st = av_new_stream(s, 0);
00226 if (!st)
00227 return AVERROR(ENOMEM);
00228 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00229 st->codec->codec_id = CODEC_ID_MUSEPACK8;
00230 st->codec->bits_per_coded_sample = 16;
00231
00232 st->codec->extradata_size = 2;
00233 st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
00234 avio_read(pb, st->codec->extradata, st->codec->extradata_size);
00235
00236 st->codec->channels = (st->codec->extradata[1] >> 4) + 1;
00237 st->codec->sample_rate = mpc8_rate[st->codec->extradata[0] >> 5];
00238 av_set_pts_info(st, 32, 1152 << (st->codec->extradata[1]&3)*2, st->codec->sample_rate);
00239 st->duration = c->samples / (1152 << (st->codec->extradata[1]&3)*2);
00240 size -= avio_tell(pb) - pos;
00241
00242 return 0;
00243 }
00244
00245 static int mpc8_read_packet(AVFormatContext *s, AVPacket *pkt)
00246 {
00247 MPCContext *c = s->priv_data;
00248 int tag;
00249 int64_t pos, size;
00250
00251 while(!url_feof(s->pb)){
00252 pos = avio_tell(s->pb);
00253 mpc8_get_chunk_header(s->pb, &tag, &size);
00254 if (size < 0)
00255 return -1;
00256 if(tag == TAG_AUDIOPACKET){
00257 if(av_get_packet(s->pb, pkt, size) < 0)
00258 return AVERROR(ENOMEM);
00259 pkt->stream_index = 0;
00260 pkt->pts = c->frame;
00261 return 0;
00262 }
00263 if(tag == TAG_STREAMEND)
00264 return AVERROR(EIO);
00265 mpc8_handle_chunk(s, tag, pos, size);
00266 }
00267 return AVERROR_EOF;
00268 }
00269
00270 static int mpc8_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
00271 {
00272 AVStream *st = s->streams[stream_index];
00273 MPCContext *c = s->priv_data;
00274 int index = av_index_search_timestamp(st, timestamp, flags);
00275
00276 if(index < 0) return -1;
00277 avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
00278 c->frame = st->index_entries[index].timestamp;
00279 return 0;
00280 }
00281
00282
00283 AVInputFormat ff_mpc8_demuxer = {
00284 "mpc8",
00285 NULL_IF_CONFIG_SMALL("Musepack SV8"),
00286 sizeof(MPCContext),
00287 mpc8_probe,
00288 mpc8_read_header,
00289 mpc8_read_packet,
00290 NULL,
00291 mpc8_read_seek,
00292 };