123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- #include "ADTS_MPG123.h"
- #include "../winamp/wa_ipc.h"
- #include <math.h>
- #include "../nsutil/pcm.h"
- #include <assert.h>
- ADTS_MPG123::ADTS_MPG123() : decoder(0), gain(1.f)
- {
- decoderDelay = 529;
-
- bitsPerSample = 0;
- allowRG = false;
- useFloat = false;
- channels = 0;
- sampleRate = 0;
- decode_buffer = 0;
- decode_buffer_length = 0;
- }
- ADTS_MPG123::~ADTS_MPG123()
- {
- if (decoder) {
- mpg123_delete(decoder);
- decoder = 0;
- }
- free(decode_buffer);
- }
- int ADTS_MPG123::Initialize(bool forceMono, bool reverseStereo, bool allowSurround, int maxBits, bool _allowRG, bool _useFloat, bool _useCRC)
- {
- allowRG = _allowRG;
- useFloat = _useFloat;
- int downmix = 0;
- if (reverseStereo)
- downmix = 2;
- else
- downmix = forceMono ? 1 : 0;
- bitsPerSample = maxBits;
- decoder = mpg123_new(NULL, NULL);
- long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
- if (forceMono) {
- flags |= MPG123_FORCE_MONO;
- }
- mpg123_param(decoder, MPG123_FLAGS, flags, 0);
- mpg123_param(decoder, MPG123_RVA, MPG123_RVA_OFF, 0);
- return 0;
- }
- bool ADTS_MPG123::Open(ifc_mpeg_stream_reader *file)
- {
- mpg123_open_feed(decoder);
- if (allowRG) {
- gain = file->MPEGStream_Gain();
- }
- return true;
- }
- void ADTS_MPG123::Close()
- {
- if (decoder) {
- mpg123_delete(decoder);
- decoder = 0;
- }
- }
- bool ADTS_MPG123::_UpdateProperties()
- {
- if (decoder && (!channels || !sampleRate)) {
- long sample_rate = 44100;
- int channels = 2;
- int encoding = 0;
- if (mpg123_getformat(decoder, &sample_rate, &channels, &encoding) == MPG123_OK) {
- this->channels = channels;
- this->sampleRate = sample_rate;
- }
- }
- return channels && sampleRate;
- }
- void ADTS_MPG123::GetOutputParameters(size_t *numBits, int *numChannels, int *sampleRate)
- {
- _UpdateProperties();
- *sampleRate = this->sampleRate;
- *numChannels = this->channels;
- *numBits = bitsPerSample;
- }
- void ADTS_MPG123::CalculateFrameSize(int *frameSize)
- {
- _UpdateProperties();
- *frameSize = (int)(bitsPerSample/8) * channels * mpg123_spf(decoder);
- #if 0 // TODO?
- if (decoder->GetStreamInfo()->GetLayer() == 1)
- *frameSize *= 3;
- #endif
- }
- void ADTS_MPG123::Flush(ifc_mpeg_stream_reader *file)
- {
- mpg123_open_feed(decoder);
- }
- size_t ADTS_MPG123::GetCurrentBitrate()
- {
- mpg123_frameinfo frameInfo;
- if (mpg123_info(decoder, &frameInfo) == MPG123_OK) {
- return frameInfo.bitrate;
- } else {
- return 0;
- }
- }
- size_t ADTS_MPG123::GetDecoderDelay()
- {
- return decoderDelay;
- }
- static void Decimate(const float *input, void *output, size_t numSamples, size_t *outputWritten, int bitsPerSample, bool useFloat, float gain)
- {
- if (!useFloat)
- {
- // TODO seen a few crashes reported where 'output' is 0
- nsutil_pcm_FloatToInt_Interleaved_Gain(output, input, bitsPerSample, numSamples, gain);
- }
- else if (gain != 1.f)
- {
- float *data = (float *)output;
- for (size_t i=0;i<numSamples;i++)
- data[i]*=gain;
- //data[i]=input[i]*gain;
- }
- *outputWritten = numSamples * (bitsPerSample / 8);
- }
- int ADTS_MPG123::_Read(ifc_mpeg_stream_reader *_file)
- {
- int err;
- do {
- unsigned char buffer[4096];
- size_t bytes = 0;
- _file->MPEGStream_Read(buffer, sizeof(buffer), &bytes);
- err = mpg123_feed(decoder, buffer, bytes);
- } while (err == MPG123_NEED_MORE);
- switch(err) {
- case MPG123_OK:
- return adts::SUCCESS;
- case MPG123_NEED_MORE:
- if (_file->MPEGStream_EOF()) {
- return adts::ENDOFFILE;
- } else {
- return adts::NEEDMOREDATA;
- }
- default:
- return adts::FAILURE;
- }
- }
- /*
- notes for mp3 surround implementations
- need to check the first two frames for ancillary data
- store first valid in temp
- store second valid frame in delay line
- decimate first valid into output buffer
- ancillary data is stored one frame behind, so PCM data decoded from mp3 frame n combines with anc data from frame n+1
- */
- int ADTS_MPG123::Sync(ifc_mpeg_stream_reader *_file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate)
- {
- if (outputWritten) {
- *outputWritten = 0;
- }
- int err = _Read(_file);
- if (err == adts::SUCCESS) {
- err = mpg123_read(decoder, 0, 0, 0);
- if (err == MPG123_NEED_MORE) {
- return adts::NEEDMOREDATA;
- }
- if (err != MPG123_NEW_FORMAT
- && err != MPG123_OK) {
- return adts::FAILURE;
- }
- _UpdateProperties();
- mpg123_frameinfo frameInfo;
- err = mpg123_info(decoder, &frameInfo);
- if (err == MPG123_OK) {
- *bitrate = frameInfo.bitrate;
- return adts::SUCCESS;
- } else {
- return adts::NEEDMOREDATA;
- }
- } else {
- return err;
- }
- }
- int ADTS_MPG123::Decode(ifc_mpeg_stream_reader *_file, unsigned __int8 *output, size_t outputSize, size_t *outputWritten, size_t *bitrate, size_t *endCut)
- {
- bool retried=false;
- for (;;) {
- if (!decode_buffer) {
- int channels = 2;
- long sample_rate;
- int encoding;
- if (mpg123_getformat(decoder, &sample_rate, &channels, &encoding) == MPG123_OK) {
- this->channels = channels;
- decode_buffer_length = sizeof(float) * channels * mpg123_spf(decoder);
- decode_buffer = (float *)malloc(decode_buffer_length);
- if (!decode_buffer) {
- return adts::FAILURE;
- }
- }
- }
- float *flData=useFloat?(float *)output:decode_buffer;
- size_t flDataSize=useFloat?outputSize:decode_buffer_length;
- size_t done=0;
- int err = mpg123_read(decoder, (unsigned char *)flData, flDataSize, &done);
- switch(err) {
- case MPG123_OK:
- {
- Decimate(flData, output, done / sizeof(float), outputWritten, (int)bitsPerSample, useFloat, (float)gain);
- mpg123_frameinfo frameInfo;
- if (mpg123_info(decoder, &frameInfo) == MPG123_OK) {
- *bitrate = frameInfo.bitrate;
- }
- }
- return adts::SUCCESS;
- case MPG123_NEW_FORMAT:
- assert(done == 0);
- return adts::SUCCESS;
- case MPG123_NEED_MORE:
- if (done) {
- Decimate(flData, output, done / sizeof(float), outputWritten, (int)bitsPerSample, useFloat, (float)gain);
- mpg123_frameinfo frameInfo;
- if (mpg123_info(decoder, &frameInfo) == MPG123_OK) {
- *bitrate = frameInfo.bitrate;
- }
- return adts::SUCCESS;
- } else if (_file->MPEGStream_EOF()) {
- return adts::ENDOFFILE;
- } else {
- if (retried) {
- return adts::NEEDMOREDATA;
- } else {
- retried=true;
- err = _Read(_file);
- if (err != adts::SUCCESS) {
- return err;
- } else {
- break;
- }
- }
- }
- default:
- assert(done == 0);
- return adts::FAILURE;
- }
- }
- }
- int ADTS_MPG123::GetLayer()
- {
- if (decoder) {
- mpg123_frameinfo frameInfo;
- mpg123_info(decoder, &frameInfo);
- return frameInfo.layer;
- } else {
- return 0;
- }
- }
- void ADTS_MPG123::Release()
- {
- delete this;
- }
|