[MPlayer-dev-eng] [PATCH] Preliminary musepack support

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Wed Jun 1 19:00:33 CEST 2005


Hi,
On Wed, May 11, 2005 at 12:35:38PM +0200, Reimar D?ffinger wrote:
> On Wed, May 11, 2005 at 12:22:38PM +0200, Reimar D?ffinger wrote:
> > The most annoying thing is the order of the bytes in the bitstream:
> > 3 2 1 0 7 6 5 4 11 10 9 8 etc...
> 
> I forgot to say that I also want to change this, by calling bswap on
> every dword, so that reading data at an arbitrary point is simple (as
> long as it's less that 26 bits). This means that on little endian when
> reading more than 8 bits at once another bswap will be necessary, but
> who cares *g* (it will be neccessary on at least on architecture anyway
> and this is easier to do. And why not once give be an advantage *g*)

I decided to not do that part after all...
I attached a preview version of the new version. It does not support
bigendian machines up to now, but mpc-in-avi seems to work nicely
(though you waste up to 31 bits per frame), including seeking.
You need to patch the musepack decoder lib, though, and that patch is a
bit broken atm (i.e. it will probably work only with MPlayer).

Greetings,
Reimar Döffinger
-------------- next part --------------
Index: Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/Makefile,v
retrieving revision 1.322
diff -u -r1.322 Makefile
--- Makefile	7 May 2005 14:50:14 -0000	1.322
+++ Makefile	1 Jun 2005 16:43:00 -0000
@@ -32,7 +32,7 @@
 
 VO_LIBS = $(AA_LIB) $(X_LIB) $(SDL_LIB) $(GGI_LIB) $(MP1E_LIB) $(MLIB_LIB) $(SVGA_LIB) $(DIRECTFB_LIB) $(CACA_LIB)
 AO_LIBS = $(ARTS_LIB) $(ESD_LIB) $(JACK_LIB) $(NAS_LIB) $(SGIAUDIO_LIB) $(POLYP_LIB)
-CODEC_LIBS = $(AV_LIB) $(FAME_LIB) $(MAD_LIB) $(VORBIS_LIB) $(THEORA_LIB) $(FAAD_LIB) $(LIBLZO_LIB) $(DECORE_LIB) $(XVID_LIB) $(DTS_LIB) $(PNG_LIB) $(Z_LIB) $(JPEG_LIB) $(ALSA_LIB) $(XMMS_LIB) $(X264_LIB)
+CODEC_LIBS = $(AV_LIB) $(FAME_LIB) $(MAD_LIB) $(VORBIS_LIB) $(THEORA_LIB) $(FAAD_LIB) $(LIBLZO_LIB) $(DECORE_LIB) $(XVID_LIB) $(DTS_LIB) $(PNG_LIB) $(Z_LIB) $(JPEG_LIB) $(ALSA_LIB) $(XMMS_LIB) $(X264_LIB) $(MUSEPACK_LIB)
 COMMON_LIBS = libmpcodecs/libmpcodecs.a $(W32_LIB) $(DS_LIB) libaf/libaf.a libmpdemux/libmpdemux.a input/libinput.a postproc/libswscale.a osdep/libosdep.a $(DVDREAD_LIB) $(CODEC_LIBS) $(FREETYPE_LIB) $(TERMCAP_LIB) $(CDPARANOIA_LIB) $(MPLAYER_NETWORK_LIB) $(WIN32_LIB) $(GIF_LIB) $(MACOSX_FRAMEWORKS) $(SMBSUPPORT_LIB) $(FRIBIDI_LIB) $(FONTCONFIG_LIB) $(ENCA_LIB)
 
 CFLAGS = $(OPTFLAGS) -I. $(FREETYPE_INC) $(EXTRA_INC) $(CDPARANOIA_INC) $(SDL_INC) $(X11_INC) $(FRIBIDI_INC) $(DVB_INC) $(XVID_INC) $(FONTCONFIG_INC) $(CACA_INC) # -Wall
Index: configure
===================================================================
RCS file: /cvsroot/mplayer/main/configure,v
retrieving revision 1.1013
diff -u -r1.1013 configure
--- configure	1 Jun 2005 09:20:45 -0000	1.1013
+++ configure	1 Jun 2005 16:43:25 -0000
@@ -232,6 +232,7 @@
   --disable-liba52       disable builtin liba52 [enabled]
   --enable-libdts        enable libdts support [autodetect]
   --disable-libmpeg2     disable builtin libmpeg2 [enabled]
+  --disable-musepack     disable musepack support [autodetect]
   --disable-amr_nb       disable amr narrowband, floating point [autodetect]
   --disable-amr_nb-fixed disable amr narrowband, fixed point [autodetect]
   --disable-amr_wb       disable amr wideband, floating point [autodetect]
@@ -1471,6 +1472,7 @@
 _inet6=auto
 _gethostbyname2=auto
 _ftp=yes
+_musepack=auto
 _vstream=auto
 for ac_option do
   case "$ac_option" in
@@ -1589,6 +1591,8 @@
   --disable-libdts)	_libdts=no      ;;
   --enable-libmpeg2)	_libmpeg2=yes	;;
   --disable-libmpeg2)	_libmpeg2=no	;;
+  --enable-musepack)	_musepack=yes	;;
+  --disable-musepack)	_musepack=no	;;
   --enable-internal-matroska)  _matroska_internal=yes ;;
   --disable-internal-matroska) _matroska_internal=no ;;
   --enable-internal-faad)	_faad_internal=yes	_faad_external=no	;;
@@ -5441,6 +5431,25 @@
 fi
 echores "$_libmpeg2"
 
+echocheck "musepack support"
+if test "$_musepack" = auto ; then
+  _musepack=no
+  cat > $TMPC << EOF
+#include <mpcdec/mpcdec.h>
+int main(void) { mpc_streaminfo info; mpc_streaminfo_init(&info); return 0; }
+EOF
+  cc_check -lmpcdec $_ld_lm && _musepack=yes
+fi
+if test "$_musepack" = yes ; then
+  _def_musepack='#define HAVE_MUSEPACK 1'
+  _ld_musepack='-lmpcdec'
+  _codecmodules="musepack $_codecmodules"
+else
+  _def_musepack='#undef HAVE_MUSEPACK'
+  _nocodecmodules="musepack $_nocodecmodules"
+fi
+echores "$_musepack"
+
 
 echocheck "Matroska support"
 if test "$_matroska_internal" = yes ; then
@@ -6900,6 +6909,8 @@
 TREMOR = $_tremor_internal
 TREMOR_FLAGS = $_tremor_flags
 
+MUSEPACK = $_musepack
+
 UNRARLIB = $_unrarlib
 HAVE_FFPOSTPROCESS = $_def_haveffpostprocess
 PNG = $_mkf_png
@@ -7020,6 +7031,7 @@
 TOOLAME_LIB=$_toolame_lib
 TWOLAME=$_twolame
 TWOLAME_LIB=$_twolame_lib
+MUSEPACK_LIB = $_ld_musepack
 FAAC=$_faac
 FAAC_LIB=$_ld_faac
 AMR_NB=$_amr_nb
@@ -7560,6 +7572,9 @@
 /* enable Tremor as vorbis decoder */
 $_def_tremor
 
+/* enable musepack support */
+$_def_musepack
+
 /* enable OggTheora support */
 $_def_theora
 
Index: etc/codecs.conf
===================================================================
RCS file: /cvsroot/mplayer/main/etc/codecs.conf,v
retrieving revision 1.415
diff -u -r1.415 codecs.conf
--- etc/codecs.conf	26 May 2005 11:23:15 -0000	1.415
+++ etc/codecs.conf	1 Jun 2005 16:44:09 -0000
@@ -2459,6 +2489,12 @@
   driver ffmpeg
   dll "dts"
 
+audiocodec musepack
+  info "MPC/MpegPlus audio codec"
+  status  working
+  fourcc  "MPC "
+  driver libmusepack
+
 audiocodec ffamrnb
   info "AMR Narrowband"
   status working
Index: libmpcodecs/Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/Makefile,v
retrieving revision 1.141
diff -u -r1.141 Makefile
--- libmpcodecs/Makefile	7 May 2005 14:49:18 -0000	1.141
+++ libmpcodecs/Makefile	1 Jun 2005 16:44:45 -0000
@@ -56,6 +56,10 @@
 ENCODER_SRCS += ae_lavc.c
 endif
 
+ifeq ($(MUSEPACK),yes)
+AUDIO_SRCS += ad_mpc.c
+endif
+
 ifeq ($(FAAC),yes)
 ENCODER_SRCS += ae_faac.c
 endif
Index: libmpcodecs/ad.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/ad.c,v
retrieving revision 1.20
diff -u -r1.20 ad.c
--- libmpcodecs/ad.c	29 Dec 2004 19:51:56 -0000	1.20
+++ libmpcodecs/ad.c	1 Jun 2005 16:44:46 -0000
@@ -39,6 +39,7 @@
 extern ad_functions_t mpcodecs_ad_qtaudio;
 extern ad_functions_t mpcodecs_ad_ra1428;
 extern ad_functions_t mpcodecs_ad_twin;
+extern ad_functions_t mpcodecs_ad_libmusepack;
 
 ad_functions_t* mpcodecs_ad_drivers[] =
 {
@@ -87,5 +88,8 @@
   &mpcodecs_ad_libdv,
 #endif
   &mpcodecs_ad_ra1428,
+#ifdef HAVE_MUSEPACK
+  &mpcodecs_ad_libmusepack,
+#endif
   NULL
 };
Index: libmpcodecs/ad_mpc.c
===================================================================
RCS file: libmpcodecs/ad_mpc.c
diff -N libmpcodecs/ad_mpc.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libmpcodecs/ad_mpc.c	1 Jun 2005 16:44:47 -0000
@@ -0,0 +1,176 @@
+/**
+ * Musepack audio files decoder for MPlayer
+ * by Reza Jelveh <reza.jelveh at tuhh.de> and
+ * Reimar Döffinger <Reimar.Doeffinger at stud.uni-karlsruhe.de>
+ * License: GPL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "config.h"
+#include "ad_internal.h"
+#include "../libaf/af_format.h"
+#include "../libvo/fastmemcpy.h"
+
+static ad_info_t info = 
+{
+	"MPC/MPEGPlus audio decoder",
+	"libmusepack",
+	"Reza Jelveh and Reimar Döffinger",
+	"",
+	""
+};
+
+LIBAD_EXTERN(libmusepack)
+
+#include <mpcdec/mpcdec.h>
+
+#define MAX_FRAMESIZE MPC_DECODER_BUFFER_LENGTH
+
+typedef struct codecdata_s {
+  char *header;
+  int header_len;
+  sh_audio_t *sh;
+  uint32_t pos;
+  mpc_decoder decoder;
+} codecdata_t;
+
+/**
+ * \brief mpc_reader callback function for reading the header
+ */
+static mpc_int32_t cb_read(void *data, void *buf, mpc_int32_t size) {
+  codecdata_t *d = (codecdata_t *)data;
+  char *p = (char *)buf;
+  int s = size;
+  if (d->pos < d->header_len) {
+    if (s > d->header_len - d->pos)
+      s = d->header_len - d->pos;
+    memcpy(p, &d->header[d->pos], s);
+  } else
+    s = 0;
+  memset(&p[s], 0, size - s);
+  d->pos += size;
+  return size;
+}
+
+/**
+ * \brief dummy mpc_reader callback function for seeking
+ */
+static mpc_bool_t cb_seek(void *data, mpc_int32_t offset ) {
+  codecdata_t *d = (codecdata_t *)data;
+  d->pos = offset;
+  return 1;
+}
+
+/**
+ * \brief dummy mpc_reader callback function for getting stream position
+ */
+static mpc_int32_t cb_tell(void *data) {
+  codecdata_t *d = (codecdata_t *)data;
+  return d->pos;
+}
+
+/**
+ * \brief dummy mpc_reader callback function for getting stream length
+ */
+static mpc_int32_t cb_get_size(void *data) {
+  return 1 << 30;
+}
+
+/**
+ * \brief mpc_reader callback function, we cannot seek.
+ */
+static mpc_bool_t cb_canseek(void *data) {
+  return 0;
+}
+
+
+mpc_reader header_reader = {
+  .read = cb_read, .seek = cb_seek, .tell = cb_tell,
+  .get_size = cb_get_size, .canseek = cb_canseek
+};
+
+static int preinit(sh_audio_t *sh) {
+//  sh->audio_out_minsize = 2 * MPC_DECODER_BUFFER_LENGTH;
+  return 1;
+}
+
+static void uninit(sh_audio_t *sh) {
+  if (sh->codecdata)
+    free(sh->codecdata);
+}
+
+static int init(sh_audio_t *sh) {
+  mpc_streaminfo info;
+  codecdata_t *cd = malloc(sizeof(codecdata_t));
+
+  if (!sh->wf || (sh->wf->cbSize < 6 * 4)) {
+    mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Missing extradata!\n");
+    return 0;
+  }
+  cd->header = (char *)sh->wf;
+  cd->header = &cd->header[sizeof(WAVEFORMATEX)];
+  cd->header_len = sh->wf->cbSize;
+  cd->sh = sh;
+  cd->pos = 0;
+  sh->codecdata = (char *)cd;
+
+  /* read file's streaminfo data */
+  mpc_streaminfo_init(&info);
+  header_reader.data = cd;
+  if (mpc_streaminfo_read(&info, &header_reader) != ERROR_CODE_OK) {
+    mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Not a valid musepack file.\n");
+    return 0;
+  }
+  sh->i_bps = info.average_bitrate / 8;
+  sh->channels = info.channels;
+  sh->samplerate = info.sample_freq;
+  sh->samplesize = 4;
+  sh->sample_format =
+#if MPC_SAMPLE_FORMAT == float
+             AF_FORMAT_FLOAT_NE;
+#elif  MPC_SAMPLE_FORMAT == mpc_int32_t
+             AF_FORMAT_S32_NE;
+#else
+  #error musepack lib must use either float or mpc_int32_t sample format
+#endif
+
+  mpc_decoder_setup(&cd->decoder, NULL);
+  mpc_decoder_set_streaminfo(&cd->decoder, &info);
+  return 1;
+}
+
+static int decode_audio(sh_audio_t *sh, unsigned char *buf,
+                        int minlen, int maxlen) {
+  int status;
+  MPC_SAMPLE_FORMAT *sample_buffer = (MPC_SAMPLE_FORMAT *)buf;
+  mpc_uint32_t packet[MAX_FRAMESIZE];
+  
+  codecdata_t *cd = (codecdata_t *) sh->codecdata;
+  if (maxlen < MPC_DECODER_BUFFER_LENGTH) {
+    mp_msg(MSGT_DECAUDIO, MSGL_ERR, "maxlen too small in decode_audio\n");
+    return -1;
+  }
+  demux_read_data_pack(sh->ds, (void *)packet, MAX_FRAMESIZE);
+  status = mpc_decoder_decode_frame(&cd->decoder, packet, sample_buffer);
+  if (status == -1) // decode error
+    mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Error decoding file.\n");
+  if (status <= 0) // error or EOF
+    return -1;
+
+  status = MPC_FRAME_LENGTH * sh->channels; // one sample per channel
+#if MPC_SAMPLE_FORMAT == float || MPC_SAMPLE_FORMAT == mpc_int32_t
+  status *= 4;
+#else
+  // should not happen
+  status *= 2;
+#endif
+  return status;
+}
+
+static int control(sh_audio_t *sh, int cmd, void* arg, ...) {
+  return CONTROL_UNKNOWN;
+}
+
Index: libmpdemux/Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/Makefile,v
retrieving revision 1.91
diff -u -r1.91 Makefile
--- libmpdemux/Makefile	29 May 2005 12:53:59 -0000	1.91
+++ libmpdemux/Makefile	1 Jun 2005 16:44:48 -0000
@@ -3,7 +3,7 @@
 
 include ../config.mak
 
-SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_ty.c demux_ty_osd.c demux_pva.c demux_viv.c demuxer.c dvdnav_stream.c open.c parse_es.c stream.c stream_file.c stream_netstream.c stream_vcd.c stream_null.c stream_ftp.c stream_smb.c stream_vstream.c tv.c tvi_dummy.c tvi_v4l.c tvi_v4l2.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c cdda.c demux_rawaudio.c demux_rawvideo.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_alsa1x.c ai_oss.c audio_in.c demux_smjpeg.c demux_lmlm4.c cue_read.c extension.c demux_gif.c demux_ts.c demux_realaud.c url.c muxer_rawvideo.c demux_lavf.c demux_nsv.c demux_vqf.c stream_dvd.c stream_livedotcom.c
+SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_ty.c demux_ty_osd.c demux_pva.c demux_viv.c demuxer.c dvdnav_stream.c open.c parse_es.c stream.c stream_file.c stream_netstream.c stream_vcd.c stream_null.c stream_ftp.c stream_smb.c stream_vstream.c tv.c tvi_dummy.c tvi_v4l.c tvi_v4l2.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c cdda.c demux_rawaudio.c demux_rawvideo.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_alsa1x.c ai_oss.c audio_in.c demux_smjpeg.c demux_lmlm4.c cue_read.c extension.c demux_gif.c demux_ts.c demux_realaud.c url.c muxer_rawvideo.c demux_lavf.c demux_nsv.c demux_vqf.c stream_dvd.c stream_livedotcom.c demux_mpc.c
 ifeq ($(XMMS_PLUGINS),yes)
 SRCS += demux_xmms.c
 endif 
Index: libmpdemux/demux_mpc.c
===================================================================
RCS file: libmpdemux/demux_mpc.c
diff -N libmpdemux/demux_mpc.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libmpdemux/demux_mpc.c	1 Jun 2005 16:44:49 -0000
@@ -0,0 +1,145 @@
+
+#include "config.h"
+#include "../mp_msg.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "stream.h"
+#include "demuxer.h"
+#include "stheader.h"
+
+#include <string.h>
+
+#define HDR_SIZE (6 * 4)
+
+typedef struct da_priv {
+  float last_pts;
+  uint32_t dword;
+  int pos;
+} da_priv_t;
+
+extern void free_sh_audio(sh_audio_t* sh);
+
+static uint32_t get_bits(da_priv_t* priv, stream_t* s, int bits) {
+  uint32_t out = priv->dword;
+  uint32_t mask = (1 << bits) - 1;
+  priv->pos += bits;
+  if (priv->pos < 32) {
+    out >>= (32 - priv->pos);
+  }
+  else {
+    stream_read(s, (void *)&priv->dword, 4);
+    priv->pos -= 32;
+    if (priv->pos) {
+      out <<= priv->pos;
+      out |= priv->dword >> (32 - priv->pos);
+    }
+  }
+  return out & mask;
+}
+
+int demux_mpc_open(demuxer_t* demuxer) {
+  stream_t *s = demuxer->stream;
+  sh_audio_t* sh_audio;
+  uint8_t hdr[HDR_SIZE];
+  da_priv_t* priv;
+  int i;
+
+  stream_read(s, hdr, HDR_SIZE);
+  for (i = 0; i < 30000 && !s->eof; i++) {
+    if (hdr[0] == 'M' && hdr[1] == 'P' && hdr[2] == '+')
+      break;
+    memmove(hdr, &hdr[1], HDR_SIZE - 1);
+    stream_read(s, &hdr[HDR_SIZE - 1], 1);
+  }
+
+  if (hdr[0] != 'M' || hdr[1] != 'P' || hdr[2] != '+')
+    return 0;
+
+  sh_audio = new_sh_audio(demuxer,0);
+
+  {
+    char *wf = (char *)calloc(1, sizeof(WAVEFORMATEX) + HDR_SIZE);
+    char *header = &wf[sizeof(WAVEFORMATEX)];
+    const int freqs[4] = {44100, 48000, 37800, 32000};
+    sh_audio->format = mmioFOURCC('M', 'P', 'C', ' ');
+    memcpy(header, hdr, HDR_SIZE);
+    sh_audio->wf = (WAVEFORMATEX *)wf;
+    sh_audio->wf->wFormatTag = sh_audio->format;
+    sh_audio->wf->nChannels = 2;
+    sh_audio->wf->nSamplesPerSec = freqs[header[10] & 3];
+    sh_audio->wf->nBlockAlign = 32 * 36;
+    sh_audio->wf->wBitsPerSample = 16;
+    sh_audio->wf->nAvgBytesPerSec = 128 * 1024; // dummy to make mencoder not hang
+    sh_audio->wf->cbSize = HDR_SIZE;
+    demuxer->movi_start = stream_tell(s);
+    demuxer->movi_end = s->end_pos;
+  }
+
+  priv = (da_priv_t *)malloc(sizeof(da_priv_t));
+  priv->last_pts = -1;
+  priv->dword = 0;
+  priv->pos = 0;
+  stream_read(s, (void *)&priv->dword, 4);
+  priv->pos = 8;
+  demuxer->priv = priv;
+  demuxer->audio->id = 0;
+  demuxer->audio->sh = sh_audio;
+  sh_audio->ds = demuxer->audio;
+  sh_audio->samplerate = sh_audio->wf->nSamplesPerSec;
+  sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
+  sh_audio->audio.dwSampleSize = 0;
+  sh_audio->audio.dwScale = 32 * 36;
+  sh_audio->audio.dwRate = sh_audio->samplerate;
+
+  return 1;
+}
+
+int demux_mpc_fill_buffer(demux_stream_t *ds) {
+  int l;
+  int bit_len;
+  demux_packet_t* dp;
+  sh_audio_t* sh_audio = ds->sh;
+  demuxer_t* demux = ds->demuxer;
+  da_priv_t* priv = demux->priv;
+  stream_t* s = demux->stream;
+  sh_audio = ds->sh;
+
+  if (s->eof)
+    return 0;
+
+  bit_len = get_bits(priv, s, 20);
+  dp = new_demux_packet(4 * ((bit_len + 31) / 32));
+  for (l = 0; l < (bit_len / 32); l++) {
+    ((uint32_t *)dp->buffer)[l] = get_bits(priv, s, 32);
+  }
+  bit_len %= 32;
+  if (bit_len)
+    ((uint32_t *)dp->buffer)[l] = get_bits(priv, s, bit_len) << (32 - bit_len);
+  if (priv->last_pts < 0)
+    priv->last_pts = 0;
+  else
+    priv->last_pts += (36 * 32) / (float)sh_audio->samplerate;
+printf("\nlpts: %f\n", priv->last_pts);
+  ds->pts = priv->last_pts - (ds_tell_pts(demux->audio) -
+              sh_audio->a_in_buffer_len)/(float)sh_audio->i_bps;
+printf("pts: %f\n", ds->pts);
+  ds_add_packet(ds, dp);
+  return 1;
+}
+
+void demux_mpc_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
+// TODO
+}
+
+void demux_close_mpc(demuxer_t* demuxer) {
+  da_priv_t* priv = demuxer->priv;
+
+  if(!priv)
+    return;
+  free(priv);
+}
+
+int demux_mpc_control(demuxer_t *demuxer,int cmd, void *arg){
+  return DEMUXER_CTRL_NOTIMPL;
+}
Index: libmpdemux/demuxer.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demuxer.c,v
retrieving revision 1.188
diff -u -r1.188 demuxer.c
--- libmpdemux/demuxer.c	27 May 2005 12:38:29 -0000	1.188
+++ libmpdemux/demuxer.c	1 Jun 2005 16:44:54 -0000
@@ -209,6 +209,8 @@
 #endif
     case DEMUXER_TYPE_AUDIO:
       demux_close_audio(demuxer); break;
+    case DEMUXER_TYPE_MPC:
+      demux_close_mpc(demuxer); break;
 #ifdef HAVE_OGGVORBIS
     case DEMUXER_TYPE_OGG:
       demux_close_ogg(demuxer); break;
@@ -381,6 +383,7 @@
 #endif
     case DEMUXER_TYPE_Y4M: return demux_y4m_fill_buffer(demux);
     case DEMUXER_TYPE_AUDIO: return demux_audio_fill_buffer(ds);
+    case DEMUXER_TYPE_MPC: return demux_mpc_fill_buffer(ds);
 #ifdef HAVE_XMMS
     case DEMUXER_TYPE_XMMS: return demux_xmms_fill_buffer(demux,ds);
 #endif
@@ -1138,6 +1141,17 @@
     demuxer = NULL;
   }
 }
+//=============== Try to open as musepack file: =================
+if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MPC){
+  demuxer=new_demuxer(stream,DEMUXER_TYPE_MPC,audio_id,video_id,dvdsub_id);
+  if(demux_mpc_open(demuxer)){
+    mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat, "MPC");
+    file_format=DEMUXER_TYPE_MPC;
+  } else {
+    free_demuxer(demuxer);
+    demuxer = NULL;
+  }
+}
 #ifdef HAVE_XMMS
 //=============== Try to open as XMMS file: =================
 if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_XMMS){
@@ -1594,6 +1608,8 @@
       demux_seek_nuv(demuxer,rel_seek_secs,flags);  break;
   case DEMUXER_TYPE_AUDIO:
       demux_audio_seek(demuxer,rel_seek_secs,flags);  break;
+  case DEMUXER_TYPE_MPC:
+      demux_mpc_seek(demuxer,rel_seek_secs,flags);  break;
  case DEMUXER_TYPE_DEMUXERS:
       demux_demuxers_seek(demuxer,rel_seek_secs,flags);  break;
 #ifdef HAVE_OGGVORBIS
@@ -1715,6 +1731,8 @@
 	    return demux_avi_control(demuxer,cmd,arg);
 	case DEMUXER_TYPE_AUDIO:
 	    return demux_audio_control(demuxer,cmd,arg);
+	case DEMUXER_TYPE_MPC:
+	    return demux_mpc_control(demuxer,cmd,arg);
 #ifdef HAVE_OGGVORBIS
 	case DEMUXER_TYPE_OGG:
 	    return demux_ogg_control(demuxer,cmd,arg);
Index: libmpdemux/demuxer.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demuxer.h,v
retrieving revision 1.76
diff -u -r1.76 demuxer.h
--- libmpdemux/demuxer.h	28 Apr 2005 14:43:19 -0000	1.76
+++ libmpdemux/demuxer.h	1 Jun 2005 16:44:55 -0000
@@ -46,11 +46,12 @@
 #define DEMUXER_TYPE_NSV 36
 #define DEMUXER_TYPE_VQF 37
 #define DEMUXER_TYPE_AVS 38
+#define DEMUXER_TYPE_MPC 39
 
 // This should always match the higest demuxer type number.
 // Unless you want to disallow users to force the demuxer to some types
 #define DEMUXER_TYPE_MIN 0
-#define DEMUXER_TYPE_MAX 38
+#define DEMUXER_TYPE_MAX 39
 
 #define DEMUXER_TYPE_DEMUXERS (1<<16)
 // A virtual demuxer type for the network code
-------------- next part --------------
diff -ur libmpcdec-1.2/include/mpcdec/decoder.h libmpcdec-1.2.mine/include/mpcdec/decoder.h
--- libmpcdec-1.2/include/mpcdec/decoder.h	2005-05-05 23:24:17.000000000 +0200
+++ libmpcdec-1.2.mine/include/mpcdec/decoder.h	2005-06-01 13:32:52.000000000 +0200
@@ -61,7 +61,7 @@
 
     mpc_uint32_t  dword; /// actually decoded 32bit-word
     mpc_uint32_t  pos;   /// bit-position within dword
-    mpc_uint32_t  Speicher[MPC_DECODER_MEMSIZE]; /// read-buffer
+    mpc_uint32_t  *Speicher; /// read-buffer
     mpc_uint32_t  Zaehler; /// actual index within read-buffer
 
     mpc_uint32_t samples_to_skip;
diff -ur libmpcdec-1.2/include/mpcdec/mpcdec.h libmpcdec-1.2.mine/include/mpcdec/mpcdec.h
--- libmpcdec-1.2/include/mpcdec/mpcdec.h	2005-05-05 23:24:17.000000000 +0200
+++ libmpcdec-1.2.mine/include/mpcdec/mpcdec.h	2005-06-01 15:13:46.000000000 +0200
@@ -100,6 +100,8 @@
 /// \return TRUE if decoder was initalized successfully, FALSE otherwise    
 mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si);
 
+void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si);
+
 /// Sets decoder sample scaling factor.  All decoded samples will be multiplied
 /// by this factor.
 /// \param scale_factor multiplicative scaling factor
@@ -119,6 +121,11 @@
     mpc_uint32_t *vbr_update_acc, 
     mpc_uint32_t *vbr_update_bits);
 
+mpc_uint32_t mpc_decoder_decode_frame(
+    mpc_decoder *d,
+    mpc_uint32_t *in_buffer,
+    MPC_SAMPLE_FORMAT *out_buffer);
+
 /// Seeks to the specified sample in the source stream.
 mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample);
 
diff -ur libmpcdec-1.2/src/mpc_decoder.c libmpcdec-1.2.mine/src/mpc_decoder.c
--- libmpcdec-1.2/src/mpc_decoder.c	2005-05-05 23:24:24.000000000 +0200
+++ libmpcdec-1.2.mine/src/mpc_decoder.c	2005-06-01 17:31:19.000000000 +0200
@@ -313,6 +313,31 @@
     memset(d->MS_Flag         , 0, sizeof d->MS_Flag          );
 }
 
+mpc_uint32_t
+mpc_decoder_decode_frame(mpc_decoder *d, mpc_uint32_t *in_buffer,
+                            MPC_SAMPLE_FORMAT *out_buffer)
+{
+  mpc_decoder_reset_bitstream_decode(d);
+  d->Speicher = in_buffer;
+  d->dword = d->Speicher[0];
+  switch (d->StreamVersion) {
+    case 0x04:
+    case 0x05:
+    case 0x06:
+        mpc_decoder_read_bitstream_sv6(d);
+        break;
+    case 0x07:
+    case 0x17:
+        mpc_decoder_read_bitstream_sv7(d);
+        break;
+    default:
+        return (mpc_uint32_t)(-1);
+  }
+  mpc_decoder_requantisierung(d, d->Max_Band);
+  mpc_decoder_synthese_filter_float(d, out_buffer);
+  return mpc_decoder_bits_read(d);
+}
+
 static mpc_uint32_t
 mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer) 
 {
@@ -1174,7 +1199,7 @@
   mpc_decoder_init_huffman_sv7(d);
 }
 
-static void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si)
+void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si)
 {
     mpc_decoder_reset_synthesis(d);
     mpc_decoder_reset_globals(d);
@@ -1206,12 +1231,19 @@
     }
 
     // AB: fill buffer and initialize decoder
+    d->Speicher = (mpc_uint32_t *)malloc(MPC_DECODER_MEMSIZE);
     f_read_dword(d, d->Speicher, MEMSIZE );
     d->dword = d->Speicher[d->Zaehler = 0];
 
     return TRUE;
 }
 
+mpc_bool_t mpc_decoder_free(mpc_decoder *d)
+{
+  free(d->Speicher);
+  return TRUE;
+}
+
 //---------------------------------------------------------------
 // will seek from the beginning of the file to the desired
 // position in ms (given by seek_needed)


More information about the MPlayer-dev-eng mailing list