| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 | 
							- #include "mkv_mp3_decoder.h"
 
- #include "../nsutil/pcm.h"
 
- int MKVDecoder::CreateAudioDecoder(const char *codec_id, const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data, unsigned int preferred_bits, unsigned int max_channels,bool floating_point, ifc_mkvaudiodecoder **decoder)
 
- {
 
- 	if (!strcmp(codec_id, "A_MPEG/L3")
 
- 		|| !strcmp(codec_id, "A_MPEG/L2")
 
- 		|| !strcmp(codec_id, "A_MPEG/L1"))
 
- 	{
 
- 		mpg123_handle *ctx = mpg123_new(NULL, NULL);
 
- 		if (!ctx)
 
- 			return CREATEDECODER_FAILURE;
 
- 		long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
 
- 		if (max_channels == 1) {
 
- 			flags |= MPG123_FORCE_MONO;
 
- 		}
 
- 		mpg123_param(ctx, MPG123_FLAGS, flags, 0);
 
- 		mpg123_param(ctx, MPG123_RVA, MPG123_RVA_OFF, 0);
 
- 		*decoder = new MKVMP3Decoder(ctx, preferred_bits, max_channels, floating_point);
 
- 		return CREATEDECODER_SUCCESS;
 
- 	}
 
- 	return CREATEDECODER_NOT_MINE;
 
- }
 
- #define CBCLASS MKVDecoder
 
- START_DISPATCH;
 
- CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
 
- END_DISPATCH;
 
- #undef CBCLASS
 
- #define FHG_DELAY 529
 
- MKVMP3Decoder::MKVMP3Decoder(mpg123_handle *mp3, unsigned int bps, unsigned max_channels, bool floating_point)
 
- : mp3(mp3), bits(bps?bps:16), max_channels(max_channels?max_channels:2), floating_point(floating_point)
 
- {
 
- 	decode_buffer=0;
 
- 	decode_buffer_length=0;
 
- 	sample_rate = 0;
 
- 	channels = 0;
 
- 	pregap = FHG_DELAY;
 
- 	mpg123_open_feed(mp3);
 
- }
 
- MKVMP3Decoder::~MKVMP3Decoder()
 
- {
 
- 	if (mp3) {
 
- 		mpg123_delete(mp3);
 
- 		mp3 = 0;
 
- 	}
 
- 	free(decode_buffer);
 
- }
 
- bool MKVMP3Decoder::_UpdateProperties()
 
- {
 
- 	if (mp3 && (!channels || !sample_rate)) {
 
- 		long sample_rate = 44100;
 
- 		int channels = 2;
 
- 		int encoding = 0;
 
- 		if (mpg123_getformat(mp3, &sample_rate, &channels, &encoding) == MPG123_OK) {
 
- 			this->channels = channels;
 
- 			this->sample_rate = sample_rate;
 
- 		}
 
- 	}
 
- 	return channels && sample_rate;
 
- }
 
- int MKVMP3Decoder::OutputFrameSize(size_t *frame_size)
 
- {
 
- 	if (_UpdateProperties()) {
 
- 		*frame_size = (bits/8) * channels * mpg123_spf(mp3);
 
- 		return MKV_SUCCESS;
 
- 	} else {
 
- 		return MKV_FAILURE;
 
- 	}
 
- }
 
- int MKVMP3Decoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat)
 
- {
 
- 	if (_UpdateProperties()) {
 
- 		*sampleRate = this->sample_rate;
 
- 		*channels = this->channels;
 
- 		*bitsPerSample = bits;
 
- 		*isFloat = floating_point;
 
- 		return MKV_SUCCESS;
 
- 	}
 
- 	else
 
- 	{
 
- 		return MKV_FAILURE;
 
- 	}
 
- }
 
- int MKVMP3Decoder::DecodeBlock(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
 
- {
 
- 	if (!mp3)
 
- 		return MKV_FAILURE;
 
- 	*outputBufferBytes = 0;
 
- 	mpg123_feed(mp3, (unsigned char *)inputBuffer, inputBufferBytes);
 
- 	for (;;) {
 
- 		if (!decode_buffer) {
 
- 			if (_UpdateProperties()) {
 
- 				decode_buffer_length = sizeof(float) * channels * mpg123_spf(mp3);
 
- 				decode_buffer = (float *)malloc(decode_buffer_length);
 
- 				if (!decode_buffer) {
 
- 					return MKV_FAILURE;
 
- 				}
 
- 			}
 
- 		}
 
- 		// get the decoded data out
 
- 		size_t pcm_buf_used=0;
 
- 		int err = mpg123_read(mp3, (unsigned char *)decode_buffer, decode_buffer_length, &pcm_buf_used);
 
- 		if (pcm_buf_used) {
 
- 			if (!_UpdateProperties()) {
 
- 				return MKV_FAILURE;
 
- 			}
 
- 			// deal with pregap
 
- 			size_t numSamples = pcm_buf_used / sizeof(float);
 
- 			size_t offset = min(numSamples, pregap * channels);
 
- 			numSamples -= offset;
 
- 			pregap -= (int)offset / channels;
 
- 			float *pcm_buf = decode_buffer + offset;
 
- 			// convert to destination sample format
 
- 			
 
- 			nsutil_pcm_FloatToInt_Interleaved(outputBuffer, pcm_buf, bits, numSamples);
 
- 			*outputBufferBytes += numSamples * bits / 8;
 
- 			outputBuffer = (char *)outputBuffer + numSamples * bits / 8;
 
- 			return MKV_SUCCESS;
 
- 		} else if (err == MPG123_NEED_MORE) {
 
- 			*outputBufferBytes = 0;
 
- 			return MKV_NEED_MORE_INPUT;
 
- 		} else if (err == MPG123_NEW_FORMAT) {
 
- 			continue;
 
- 		} else if (err == MPG123_OK) {
 
- 			continue;
 
- 		}
 
- 		else
 
- 			return MKV_FAILURE;
 
- 	}
 
- 	return MKV_SUCCESS;
 
- }
 
- void MKVMP3Decoder::Flush()
 
- {
 
- 	mpg123_open_feed(mp3);
 
- 	pregap = FHG_DELAY;
 
- }
 
- void MKVMP3Decoder::Close()
 
- {
 
- 	delete this;
 
- }
 
- #define CBCLASS MKVMP3Decoder
 
- START_DISPATCH;
 
- CB(OUTPUT_FRAME_SIZE, OutputFrameSize)
 
- CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
 
- CB(DECODE_BLOCK, DecodeBlock)
 
- VCB(FLUSH, Flush)
 
- VCB(CLOSE, Close)
 
- END_DISPATCH;
 
- #undef CBCLASS
 
 
  |