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 "avformat.h"
00024 #include "internal.h"
00025 #include "apetag.h"
00026 #include "id3v1.h"
00027 #include "libavutil/dict.h"
00028
00029 #define MPC_FRAMESIZE 1152
00030 #define DELAY_FRAMES 32
00031
00032 static const int mpc_rate[4] = { 44100, 48000, 37800, 32000 };
00033 typedef struct {
00034 int64_t pos;
00035 int size, skip;
00036 }MPCFrame;
00037
00038 typedef struct {
00039 int ver;
00040 uint32_t curframe, lastframe;
00041 uint32_t fcount;
00042 MPCFrame *frames;
00043 int curbits;
00044 int frames_noted;
00045 } MPCContext;
00046
00047 static int mpc_probe(AVProbeData *p)
00048 {
00049 const uint8_t *d = p->buf;
00050 if (d[0] == 'M' && d[1] == 'P' && d[2] == '+' && (d[3] == 0x17 || d[3] == 0x7))
00051 return AVPROBE_SCORE_MAX;
00052 return 0;
00053 }
00054
00055 static int mpc_read_header(AVFormatContext *s)
00056 {
00057 MPCContext *c = s->priv_data;
00058 AVStream *st;
00059
00060 if(avio_rl24(s->pb) != MKTAG('M', 'P', '+', 0)){
00061 av_log(s, AV_LOG_ERROR, "Not a Musepack file\n");
00062 return AVERROR_INVALIDDATA;
00063 }
00064 c->ver = avio_r8(s->pb);
00065 if(c->ver != 0x07 && c->ver != 0x17){
00066 av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver);
00067 return AVERROR_INVALIDDATA;
00068 }
00069 c->fcount = avio_rl32(s->pb);
00070 if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX){
00071 av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n");
00072 return AVERROR_INVALIDDATA;
00073 }
00074 if(c->fcount){
00075 c->frames = av_malloc(c->fcount * sizeof(MPCFrame));
00076 if(!c->frames){
00077 av_log(s, AV_LOG_ERROR, "Cannot allocate seektable\n");
00078 return AVERROR(ENOMEM);
00079 }
00080 }else{
00081 av_log(s, AV_LOG_WARNING, "Container reports no frames\n");
00082 }
00083 c->curframe = 0;
00084 c->lastframe = -1;
00085 c->curbits = 8;
00086 c->frames_noted = 0;
00087
00088 st = avformat_new_stream(s, NULL);
00089 if (!st)
00090 return AVERROR(ENOMEM);
00091 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00092 st->codec->codec_id = AV_CODEC_ID_MUSEPACK7;
00093 st->codec->channels = 2;
00094 st->codec->bits_per_coded_sample = 16;
00095
00096 st->codec->extradata_size = 16;
00097 st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
00098 avio_read(s->pb, st->codec->extradata, 16);
00099 st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3];
00100 avpriv_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate);
00101
00102 st->start_time = 0;
00103 st->duration = c->fcount;
00104
00105
00106 if (s->pb->seekable) {
00107 int64_t pos = avio_tell(s->pb);
00108 ff_ape_parse_tag(s);
00109 if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
00110 ff_id3v1_read(s);
00111 avio_seek(s->pb, pos, SEEK_SET);
00112 }
00113
00114 return 0;
00115 }
00116
00117 static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt)
00118 {
00119 MPCContext *c = s->priv_data;
00120 int ret, size, size2, curbits, cur = c->curframe;
00121 unsigned tmp;
00122 int64_t pos;
00123
00124 if (c->curframe >= c->fcount && c->fcount)
00125 return AVERROR_EOF;
00126
00127 if(c->curframe != c->lastframe + 1){
00128 avio_seek(s->pb, c->frames[c->curframe].pos, SEEK_SET);
00129 c->curbits = c->frames[c->curframe].skip;
00130 }
00131 c->lastframe = c->curframe;
00132 c->curframe++;
00133 curbits = c->curbits;
00134 pos = avio_tell(s->pb);
00135 tmp = avio_rl32(s->pb);
00136 if(curbits <= 12){
00137 size2 = (tmp >> (12 - curbits)) & 0xFFFFF;
00138 }else{
00139 size2 = (tmp << (curbits - 12) | avio_rl32(s->pb) >> (44 - curbits)) & 0xFFFFF;
00140 }
00141 curbits += 20;
00142 avio_seek(s->pb, pos, SEEK_SET);
00143
00144 size = ((size2 + curbits + 31) & ~31) >> 3;
00145 if(cur == c->frames_noted && c->fcount){
00146 c->frames[cur].pos = pos;
00147 c->frames[cur].size = size;
00148 c->frames[cur].skip = curbits - 20;
00149 av_add_index_entry(s->streams[0], cur, cur, size, 0, AVINDEX_KEYFRAME);
00150 c->frames_noted++;
00151 }
00152 c->curbits = (curbits + size2) & 0x1F;
00153
00154 if ((ret = av_new_packet(pkt, size)) < 0)
00155 return ret;
00156
00157 pkt->data[0] = curbits;
00158 pkt->data[1] = (c->curframe > c->fcount) && c->fcount;
00159 pkt->data[2] = 0;
00160 pkt->data[3] = 0;
00161
00162 pkt->stream_index = 0;
00163 pkt->pts = cur;
00164 ret = avio_read(s->pb, pkt->data + 4, size);
00165 if(c->curbits)
00166 avio_seek(s->pb, -4, SEEK_CUR);
00167 if(ret < size){
00168 av_free_packet(pkt);
00169 return ret < 0 ? ret : AVERROR(EIO);
00170 }
00171 pkt->size = ret + 4;
00172
00173 return 0;
00174 }
00175
00176 static int mpc_read_close(AVFormatContext *s)
00177 {
00178 MPCContext *c = s->priv_data;
00179
00180 av_freep(&c->frames);
00181 return 0;
00182 }
00183
00191 static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
00192 {
00193 AVStream *st = s->streams[stream_index];
00194 MPCContext *c = s->priv_data;
00195 AVPacket pkt1, *pkt = &pkt1;
00196 int ret;
00197 int index = av_index_search_timestamp(st, FFMAX(timestamp - DELAY_FRAMES, 0), flags);
00198 uint32_t lastframe;
00199
00200
00201 if (index >= 0 && st->index_entries[st->nb_index_entries-1].timestamp >= timestamp - DELAY_FRAMES){
00202 c->curframe = st->index_entries[index].pos;
00203 return 0;
00204 }
00205
00206 if(timestamp < 0 || timestamp >= c->fcount)
00207 return -1;
00208 timestamp -= DELAY_FRAMES;
00209
00210
00211 lastframe = c->curframe;
00212 if(c->frames_noted) c->curframe = c->frames_noted - 1;
00213 while(c->curframe < timestamp){
00214 ret = av_read_frame(s, pkt);
00215 if (ret < 0){
00216 c->curframe = lastframe;
00217 return ret;
00218 }
00219 av_free_packet(pkt);
00220 }
00221 return 0;
00222 }
00223
00224
00225 AVInputFormat ff_mpc_demuxer = {
00226 .name = "mpc",
00227 .long_name = NULL_IF_CONFIG_SMALL("Musepack"),
00228 .priv_data_size = sizeof(MPCContext),
00229 .read_probe = mpc_probe,
00230 .read_header = mpc_read_header,
00231 .read_packet = mpc_read_packet,
00232 .read_close = mpc_read_close,
00233 .read_seek = mpc_read_seek,
00234 .extensions = "mpc",
00235 };