diff --git a/src/add-ons/media/plugins/musepack/MusePackDecoder.cpp b/src/add-ons/media/plugins/musepack/MusePackDecoder.cpp index 782843c811..220a30bf3b 100644 --- a/src/add-ons/media/plugins/musepack/MusePackDecoder.cpp +++ b/src/add-ons/media/plugins/musepack/MusePackDecoder.cpp @@ -5,9 +5,7 @@ #include "MusePackDecoder.h" - -#include -#include +#include "mpc/in_mpc.h" MusePackDecoder::MusePackDecoder() @@ -17,29 +15,59 @@ MusePackDecoder::MusePackDecoder() MusePackDecoder::~MusePackDecoder() { + delete fDecoder; } status_t MusePackDecoder::Setup(media_format *ioEncodedFormat, const void *infoBuffer, int32 infoSize) { + if (infoBuffer == NULL || infoSize != sizeof(MPC_decoder)) + return B_BAD_VALUE; + + fDecoder = (MPC_decoder *)infoBuffer; + return B_OK; } status_t -MusePackDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat) +MusePackDecoder::NegotiateOutputFormat(media_format *format) { + // ToDo: rework the underlying MPC engine to be more flexible + + format->type = B_MEDIA_RAW_AUDIO; + format->u.raw_audio.frame_rate = fDecoder->fInfo->simple.SampleFreq; + format->u.raw_audio.channel_count = fDecoder->fInfo->simple.Channels; + format->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT; + format->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN; + format->u.raw_audio.buffer_size = sizeof(MPC_SAMPLE_FORMAT) * FRAMELEN * 2 * 2; + // the buffer size is hardcoded in the MPC engine... + + if (format->u.raw_audio.channel_mask == 0) { + format->u.raw_audio.channel_mask = (format->u.raw_audio.channel_count == 1) ? + B_CHANNEL_LEFT : B_CHANNEL_LEFT | B_CHANNEL_RIGHT; + } + + return B_OK; } status_t MusePackDecoder::Seek(uint32 seekTo, int64 seekFrame, int64 *frame, bigtime_t seekTime, bigtime_t *time) { + return B_OK; } status_t -MusePackDecoder::Decode(void *buffer, int64 *frameCount, media_header *mediaHeader, media_decode_info *info) +MusePackDecoder::Decode(void *buffer, int64 *_frameCount, media_header *mediaHeader, media_decode_info *info) { + // ToDo: add error checking (check for broken frames) + + uint32 ring = fDecoder->Zaehler; + *_frameCount = fDecoder->DECODE((MPC_SAMPLE_FORMAT *)buffer); + fDecoder->UpdateBuffer(ring); + + return B_OK; } diff --git a/src/add-ons/media/plugins/musepack/MusePackDecoder.h b/src/add-ons/media/plugins/musepack/MusePackDecoder.h index ff1a514fb8..3fad36e467 100644 --- a/src/add-ons/media/plugins/musepack/MusePackDecoder.h +++ b/src/add-ons/media/plugins/musepack/MusePackDecoder.h @@ -9,6 +9,8 @@ #include "DecoderPlugin.h" #include +#include "mpc/mpc_dec.h" + class MusePackDecoder : public Decoder { public: @@ -27,6 +29,8 @@ class MusePackDecoder : public Decoder { media_header *mediaHeader, media_decode_info *info); private: + MPC_decoder *fDecoder; + StreamInfo *fInfo; }; #endif /* MUSEPACK_DECODER_H */ diff --git a/src/add-ons/media/plugins/musepack/MusePackReader.cpp b/src/add-ons/media/plugins/musepack/MusePackReader.cpp index 148f43330a..b3dfe33c0d 100644 --- a/src/add-ons/media/plugins/musepack/MusePackReader.cpp +++ b/src/add-ons/media/plugins/musepack/MusePackReader.cpp @@ -92,8 +92,19 @@ MusePackReader::GetStreamInfo(void *cookie, int64 *_frameCount, bigtime_t *_dura BMediaFormats formats; formats.GetFormatFor(description, format); - *_infoBuffer = NULL; - *_infoSize = 0; + // allocate and initialize internal decoder + MPC_decoder *decoder = new MPC_decoder(static_cast(Source())); + decoder->RESET_Globals(); + decoder->RESET_Synthesis(); + decoder->SetStreamInfo(&fInfo); + if (!decoder->FileInit()) { + delete decoder; + return B_ERROR; + } + + // we provide the stream info in this place + *_infoBuffer = (void *)decoder; + *_infoSize = sizeof(MPC_decoder); return B_OK; } @@ -102,7 +113,9 @@ MusePackReader::GetStreamInfo(void *cookie, int64 *_frameCount, bigtime_t *_dura status_t MusePackReader::Seek(void *cookie, uint32 seekTo, int64 *frame, bigtime_t *time) { - return B_ERROR; + // we don't care, let the decoder do the work... + // (MPC not really differentiates between decoder and container) + return B_OK; } @@ -110,6 +123,7 @@ status_t MusePackReader::GetNextChunk(void *cookie, void **chunkBuffer, int32 *chunkSize, media_header *mediaHeader) { + // this one will never be called by our decoder return B_ERROR; }