Commit 185c7b6b authored by Kostya Shishkov's avatar Kostya Shishkov

Musepack SV7 decoding support

Originally committed as revision 7375 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent f8aa696f
......@@ -66,6 +66,7 @@ version <next>
- TIFF picture decoder
- GIF picture decoder
- Intel Music decoder
- Musepack decoder
version 0.4.9-pre1:
......
......@@ -137,6 +137,7 @@ Codecs:
lzo.h, lzo.c Reimar Doeffinger
mdec.c Michael Niedermayer
mjpeg.c Michael Niedermayer
mpc* Kostya Shishkov
mpeg12.c, mpeg12data.h Michael Niedermayer
mpegvideo.c, mpegvideo.h Michael Niedermayer
msmpeg4.c, msmpeg4data.h Michael Niedermayer
......@@ -211,6 +212,7 @@ Muxers/Demuxers:
matroska.c Aurelien Jacobs
mov.c Francois Revol, Michael Niedermayer
movenc.c Michael Niedermayer, Baptiste Coudurier
mpc.c Kostya Shishkov
mpegts* Mans Rullgard
mtv.c Reynaldo H. Verdejo Pinochet
mxf.c Baptiste Coudurier
......
......@@ -1090,6 +1090,8 @@ following image formats are supported:
@item Cin Audio @tab @tab X
@tab Codec used in Delphine Software games.
@item Intel Music Coder @tab @tab X
@item Musepack @tab @tab X
@tab Only SV7 is supported
@end multitable
@code{X} means that encoding (resp. decoding) is supported.
......
......@@ -101,6 +101,7 @@ OBJS-$(CONFIG_MACE3_DECODER) += mace.o
OBJS-$(CONFIG_MACE6_DECODER) += mace.o
OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
OBJS-$(CONFIG_MP2_ENCODER) += mpegaudio.o
OBJS-$(CONFIG_MPC7_DECODER) += mpc.o
OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o
OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o
OBJS-$(CONFIG_MSZH_DECODER) += lcl.o
......
......@@ -197,6 +197,7 @@ void avcodec_register_all(void)
REGISTER_ENCODER(MP3LAME, mp3lame);
#endif
REGISTER_DECODER(MP3ON4, mp3on4);
REGISTER_DECODER(MPC7, mpc7);
#ifdef CONFIG_LIBVORBIS
if (!ENABLE_VORBIS_ENCODER) REGISTER_ENCODER(OGGVORBIS, oggvorbis);
if (!ENABLE_VORBIS_DECODER) REGISTER_DECODER(OGGVORBIS, oggvorbis);
......
......@@ -37,8 +37,8 @@ extern "C" {
#define AV_STRINGIFY(s) AV_TOSTRING(s)
#define AV_TOSTRING(s) #s
#define LIBAVCODEC_VERSION_INT ((51<<16)+(27<<8)+0)
#define LIBAVCODEC_VERSION 51.27.0
#define LIBAVCODEC_VERSION_INT ((51<<16)+(28<<8)+0)
#define LIBAVCODEC_VERSION 51.28.0
#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT
#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
......@@ -237,6 +237,7 @@ enum CodecID {
CODEC_ID_WAVPACK,
CODEC_ID_DSICINAUDIO,
CODEC_ID_IMC,
CODEC_ID_MUSEPACK7,
/* subtitle codecs */
CODEC_ID_DVD_SUBTITLE= 0x17000,
......@@ -2317,6 +2318,7 @@ extern AVCodec dsicinaudio_decoder;
extern AVCodec tiertexseqvideo_decoder;
extern AVCodec tiff_decoder;
extern AVCodec imc_decoder;
extern AVCodec mpc7_decoder;
/* pcm codecs */
#define PCM_CODEC(id, name) \
......
This diff is collapsed.
This diff is collapsed.
......@@ -62,6 +62,7 @@ OBJS-$(CONFIG_TG2_MUXER) += movenc.o riff.o isom.o
OBJS-$(CONFIG_MP3_DEMUXER) += mp3.o
OBJS-$(CONFIG_MP2_MUXER) += mp3.o
OBJS-$(CONFIG_MP3_MUXER) += mp3.o
OBJS-$(CONFIG_MPC_DEMUXER) += mpc.o
OBJS-$(CONFIG_MPEG1SYSTEM_MUXER) += mpeg.o
OBJS-$(CONFIG_MPEG1VCD_MUXER) += mpeg.o
OBJS-$(CONFIG_MPEG2VOB_MUXER) += mpeg.o
......
......@@ -100,6 +100,7 @@ void av_register_all(void)
REGISTER_MUXER (MP2, mp2);
REGISTER_MUXDEMUX(MP3, mp3);
REGISTER_MUXER (MP4, mp4);
REGISTER_DEMUXER (MPC, mpc);
REGISTER_MUXER (MPEG1SYSTEM, mpeg1system);
REGISTER_MUXER (MPEG1VCD, mpeg1vcd);
REGISTER_MUXER (MPEG1VIDEO, mpeg1video);
......
......@@ -82,6 +82,7 @@ extern AVOutputFormat tg2_muxer;
extern AVInputFormat mp3_demuxer;
extern AVOutputFormat mp2_muxer;
extern AVOutputFormat mp3_muxer;
extern AVInputFormat mpc_demuxer;
extern AVOutputFormat mpeg1system_muxer;
extern AVOutputFormat mpeg1vcd_muxer;
extern AVOutputFormat mpeg2vob_muxer;
......
......@@ -25,8 +25,8 @@
extern "C" {
#endif
#define LIBAVFORMAT_VERSION_INT ((51<<16)+(6<<8)+0)
#define LIBAVFORMAT_VERSION 51.6.0
#define LIBAVFORMAT_VERSION_INT ((51<<16)+(7<<8)+0)
#define LIBAVFORMAT_VERSION 51.7.0
#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT
#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION)
......
/*
* Musepack demuxer
* Copyright (c) 2006 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avformat.h"
#include "bitstream.h"
#define MPC_FRAMESIZE 1152
static const int mpc_rate[4] = { 44100, 48000, 37800, 32000 };
typedef struct {
int64_t pos;
int size, skip;
}MPCFrame;
typedef struct {
int ver;
uint32_t curframe, lastframe;
uint32_t fcount;
MPCFrame *frames;
int curbits;
int frames_noted;
} MPCContext;
static int mpc_probe(AVProbeData *p)
{
const uint8_t *d = p->buf;
if (p->buf_size < 32)
return 0;
if (d[0] == 'M' && d[1] == 'P' && d[2] == '+' && (d[3] == 0x17 || d[3] == 0x7))
return AVPROBE_SCORE_MAX;
return 0;
}
static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
MPCContext *c = s->priv_data;
AVStream *st;
if(get_le24(&s->pb) != MKTAG('M', 'P', '+', 0)){
av_log(s, AV_LOG_ERROR, "Not a Musepack file\n");
return -1;
}
c->ver = get_byte(&s->pb);
if(c->ver != 0x07 && c->ver != 0x17){
av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver);
return -1;
}
c->fcount = get_le32(&s->pb);
if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX){
av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n");
return -1;
}
c->frames = av_malloc(c->fcount * sizeof(MPCFrame));
c->curframe = 0;
c->lastframe = -1;
c->curbits = 8;
st = av_new_stream(s, 0);
if (!st)
return AVERROR_NOMEM;
st->codec->codec_type = CODEC_TYPE_AUDIO;
st->codec->codec_id = CODEC_ID_MUSEPACK7;
st->codec->channels = 2;
st->codec->bits_per_sample = 16;
st->codec->extradata_size = 16;
st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
get_buffer(&s->pb, st->codec->extradata, 16);
st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3];
av_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate);
/* scan for seekpoints */
s->start_time = 0;
s->duration = (int64_t)c->fcount * MPC_FRAMESIZE * AV_TIME_BASE / st->codec->sample_rate;
return 0;
}
static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt)
{
MPCContext *c = s->priv_data;
int ret, size, size2, curbits, cur = c->curframe;
int64_t tmp, pos;
if (c->curframe > c->fcount)
return -1;
if(c->curframe != c->lastframe + 1){
url_fseek(&s->pb, c->frames[c->curframe].pos, SEEK_SET);
c->curbits = c->frames[c->curframe].skip;
}
c->lastframe = c->curframe;
c->curframe++;
curbits = c->curbits;
pos = url_ftell(&s->pb);
tmp = get_le32(&s->pb);
if(curbits <= 12){
size2 = (tmp >> (12 - curbits)) & 0xFFFFF;
}else{
tmp = (tmp << 32) | get_le32(&s->pb);
size2 = (tmp >> (44 - curbits)) & 0xFFFFF;
}
curbits += 20;
url_fseek(&s->pb, pos, SEEK_SET);
size = ((size2 + curbits + 31) & ~31) >> 3;
if(cur == c->frames_noted){
c->frames[cur].pos = pos;
c->frames[cur].size = size;
c->frames[cur].skip = curbits - 20;
av_add_index_entry(s->streams[0], cur, cur, size, 0, AVINDEX_KEYFRAME);
c->frames_noted++;
}
c->curbits = (curbits + size2) & 0x1F;
if (av_new_packet(pkt, size) < 0)
return AVERROR_IO;
pkt->data[0] = curbits;
pkt->data[1] = (c->curframe > c->fcount);
pkt->stream_index = 0;
ret = get_buffer(&s->pb, pkt->data + 4, size);
if(c->curbits)
url_fseek(&s->pb, -4, SEEK_CUR);
if(ret < size){
av_free_packet(pkt);
return AVERROR_IO;
}
pkt->size = ret + 4;
return 0;
}
static int mpc_read_close(AVFormatContext *s)
{
MPCContext *c = s->priv_data;
av_freep(&c->frames);
return 0;
}
static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
{
AVStream *st = s->streams[stream_index];
MPCContext *c = s->priv_data;
int index = av_index_search_timestamp(st, timestamp, flags);
if (index < 0)
return -1;
c->curframe = st->index_entries[index].pos;
return 0;
}
AVInputFormat mpc_demuxer = {
"mpc",
"musepack",
sizeof(MPCContext),
mpc_probe,
mpc_read_header,
mpc_read_packet,
mpc_read_close,
mpc_read_seek,
.extensions = "mpc",
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment