Libav 0.7.1
|
00001 /* 00002 * Musepack demuxer 00003 * Copyright (c) 2006 Konstantin Shishkov 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "libavcodec/get_bits.h" 00023 #include "avformat.h" 00024 #include "apetag.h" 00025 #include "id3v1.h" 00026 #include "libavutil/dict.h" 00027 00028 #define MPC_FRAMESIZE 1152 00029 #define DELAY_FRAMES 32 00030 00031 static const int mpc_rate[4] = { 44100, 48000, 37800, 32000 }; 00032 typedef struct { 00033 int64_t pos; 00034 int size, skip; 00035 }MPCFrame; 00036 00037 typedef struct { 00038 int ver; 00039 uint32_t curframe, lastframe; 00040 uint32_t fcount; 00041 MPCFrame *frames; 00042 int curbits; 00043 int frames_noted; 00044 } MPCContext; 00045 00046 static int mpc_probe(AVProbeData *p) 00047 { 00048 const uint8_t *d = p->buf; 00049 if (d[0] == 'M' && d[1] == 'P' && d[2] == '+' && (d[3] == 0x17 || d[3] == 0x7)) 00050 return AVPROBE_SCORE_MAX; 00051 return 0; 00052 } 00053 00054 static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap) 00055 { 00056 MPCContext *c = s->priv_data; 00057 AVStream *st; 00058 00059 if(avio_rl24(s->pb) != MKTAG('M', 'P', '+', 0)){ 00060 av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); 00061 return -1; 00062 } 00063 c->ver = avio_r8(s->pb); 00064 if(c->ver != 0x07 && c->ver != 0x17){ 00065 av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver); 00066 return -1; 00067 } 00068 c->fcount = avio_rl32(s->pb); 00069 if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX){ 00070 av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n"); 00071 return -1; 00072 } 00073 c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); 00074 c->curframe = 0; 00075 c->lastframe = -1; 00076 c->curbits = 8; 00077 c->frames_noted = 0; 00078 00079 st = av_new_stream(s, 0); 00080 if (!st) 00081 return AVERROR(ENOMEM); 00082 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00083 st->codec->codec_id = CODEC_ID_MUSEPACK7; 00084 st->codec->channels = 2; 00085 st->codec->bits_per_coded_sample = 16; 00086 00087 st->codec->extradata_size = 16; 00088 st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); 00089 avio_read(s->pb, st->codec->extradata, 16); 00090 st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3]; 00091 av_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate); 00092 /* scan for seekpoints */ 00093 st->start_time = 0; 00094 st->duration = c->fcount; 00095 00096 /* try to read APE tags */ 00097 if (s->pb->seekable) { 00098 int64_t pos = avio_tell(s->pb); 00099 ff_ape_parse_tag(s); 00100 if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) 00101 ff_id3v1_read(s); 00102 avio_seek(s->pb, pos, SEEK_SET); 00103 } 00104 00105 return 0; 00106 } 00107 00108 static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt) 00109 { 00110 MPCContext *c = s->priv_data; 00111 int ret, size, size2, curbits, cur = c->curframe; 00112 int64_t tmp, pos; 00113 00114 if (c->curframe >= c->fcount) 00115 return -1; 00116 00117 if(c->curframe != c->lastframe + 1){ 00118 avio_seek(s->pb, c->frames[c->curframe].pos, SEEK_SET); 00119 c->curbits = c->frames[c->curframe].skip; 00120 } 00121 c->lastframe = c->curframe; 00122 c->curframe++; 00123 curbits = c->curbits; 00124 pos = avio_tell(s->pb); 00125 tmp = avio_rl32(s->pb); 00126 if(curbits <= 12){ 00127 size2 = (tmp >> (12 - curbits)) & 0xFFFFF; 00128 }else{ 00129 tmp = (tmp << 32) | avio_rl32(s->pb); 00130 size2 = (tmp >> (44 - curbits)) & 0xFFFFF; 00131 } 00132 curbits += 20; 00133 avio_seek(s->pb, pos, SEEK_SET); 00134 00135 size = ((size2 + curbits + 31) & ~31) >> 3; 00136 if(cur == c->frames_noted){ 00137 c->frames[cur].pos = pos; 00138 c->frames[cur].size = size; 00139 c->frames[cur].skip = curbits - 20; 00140 av_add_index_entry(s->streams[0], cur, cur, size, 0, AVINDEX_KEYFRAME); 00141 c->frames_noted++; 00142 } 00143 c->curbits = (curbits + size2) & 0x1F; 00144 00145 if (av_new_packet(pkt, size) < 0) 00146 return AVERROR(EIO); 00147 00148 pkt->data[0] = curbits; 00149 pkt->data[1] = (c->curframe > c->fcount); 00150 pkt->data[2] = 0; 00151 pkt->data[3] = 0; 00152 00153 pkt->stream_index = 0; 00154 pkt->pts = cur; 00155 ret = avio_read(s->pb, pkt->data + 4, size); 00156 if(c->curbits) 00157 avio_seek(s->pb, -4, SEEK_CUR); 00158 if(ret < size){ 00159 av_free_packet(pkt); 00160 return AVERROR(EIO); 00161 } 00162 pkt->size = ret + 4; 00163 00164 return 0; 00165 } 00166 00167 static int mpc_read_close(AVFormatContext *s) 00168 { 00169 MPCContext *c = s->priv_data; 00170 00171 av_freep(&c->frames); 00172 return 0; 00173 } 00174 00182 static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) 00183 { 00184 AVStream *st = s->streams[stream_index]; 00185 MPCContext *c = s->priv_data; 00186 AVPacket pkt1, *pkt = &pkt1; 00187 int ret; 00188 int index = av_index_search_timestamp(st, timestamp - DELAY_FRAMES, flags); 00189 uint32_t lastframe; 00190 00191 /* if found, seek there */ 00192 if (index >= 0){ 00193 c->curframe = st->index_entries[index].pos; 00194 return 0; 00195 } 00196 /* if timestamp is out of bounds, return error */ 00197 if(timestamp < 0 || timestamp >= c->fcount) 00198 return -1; 00199 timestamp -= DELAY_FRAMES; 00200 /* seek to the furthest known position and read packets until 00201 we reach desired position */ 00202 lastframe = c->curframe; 00203 if(c->frames_noted) c->curframe = c->frames_noted - 1; 00204 while(c->curframe < timestamp){ 00205 ret = av_read_frame(s, pkt); 00206 if (ret < 0){ 00207 c->curframe = lastframe; 00208 return -1; 00209 } 00210 av_free_packet(pkt); 00211 } 00212 return 0; 00213 } 00214 00215 00216 AVInputFormat ff_mpc_demuxer = { 00217 "mpc", 00218 NULL_IF_CONFIG_SMALL("Musepack"), 00219 sizeof(MPCContext), 00220 mpc_probe, 00221 mpc_read_header, 00222 mpc_read_packet, 00223 mpc_read_close, 00224 mpc_read_seek, 00225 .extensions = "mpc", 00226 };