123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- // used to decode an MPEG-1 audio object in an MPEG-4 ISO Media file
- #include "mp3_in_mp4.h"
- #include "api__mp3-mpg123.h"
- #include "../nsutil/pcm.h"
- // {B6CB4A7C-A8D0-4c55-8E60-9F7A7A23DA0F}
- static const GUID playbackConfigGroupGUID =
- { 0xb6cb4a7c, 0xa8d0, 0x4c55, { 0x8e, 0x60, 0x9f, 0x7a, 0x7a, 0x23, 0xda, 0xf } };
- #define FHG_DELAY 529
- MPEG4_MP3::MPEG4_MP3()
- {
- channels = 0;
- gain = 1;
- floatingPoint = false;
- decoder = 0;
- sample_rate = 0;
- bits = 16;
- pregap = FHG_DELAY;
- }
- MPEG4_MP3::~MPEG4_MP3()
- {
- if (decoder) {
- mpg123_delete(decoder);
- decoder = 0;
- }
- }
- int MPEG4_MP3::OpenEx(size_t _bits, size_t _maxChannels, bool useFloat)
- {
- _bits = bits;
- floatingPoint = useFloat;
- if (floatingPoint)
- bits = 32;
- else
- bits = (int)_bits;
- decoder = mpg123_new(NULL, NULL);
- long flags = MPG123_QUIET|MPG123_FORCE_FLOAT|MPG123_SKIP_ID3V2|MPG123_IGNORE_STREAMLENGTH|MPG123_IGNORE_INFOFRAME;
- if (_maxChannels == 1) {
- flags |= MPG123_FORCE_MONO;
- }
- mpg123_param(decoder, MPG123_FLAGS, flags, 0);
- mpg123_param(decoder, MPG123_RVA, MPG123_RVA_OFF, 0);
- mpg123_open_feed(decoder);
- return MP4_SUCCESS;
- }
- const char *MPEG4_MP3::GetCodecInfoString()
- {
- return 0;
- }
- int MPEG4_MP3::CanHandleCodec(const char *codecName)
- {
- if (!lstrcmpA(codecName, "mp4a"))
- return 1;
- else
- return 0;
- }
- int MPEG4_MP3::CanHandleType(unsigned __int8 type)
- {
- switch(type)
- {
- case MP4_MPEG4_LAYER3_AUDIO:
- case MP4_MPEG4_LAYER2_AUDIO:
- case MP4_MPEG4_LAYER1_AUDIO:
- case MP4_TYPE_MPEG1_AUDIO:
- case MP4_TYPE_MPEG2_AUDIO:
- //case MP4_TYPE_MPEG4_AUDIO:
- return 1;
- default:
- return 0;
- }
- }
- int MPEG4_MP3::DecodeSample(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
- {
- if (!decoder)
- return MP4_FAILURE;
- *outputBufferBytes = 0;
- mpg123_feed(decoder, (unsigned char *)inputBuffer, inputBufferBytes);
- for (;;) {
- // get the decoded data out
- size_t pcm_buf_used=0;
- float decodeBuf[1152*2];
- int err = mpg123_read(decoder, (unsigned char *)decodeBuf, sizeof(decodeBuf), &pcm_buf_used);
- if (pcm_buf_used) {
- if (!_UpdateProperties()) {
- return MP4_FAILURE;
- }
- // deal with pregap
- int numSamples = (int)pcm_buf_used / sizeof(float);
- int offset = min(numSamples, pregap * channels);
- numSamples -= offset;
- pregap -= offset / channels;
- float *pcm_buf = decodeBuf + 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 MP4_SUCCESS;
- } else if (err == MPG123_NEED_MORE) {
- *outputBufferBytes = 0;
- return MP4_NEED_MORE_INPUT;
- } else if (err == MPG123_NEW_FORMAT) {
- continue;
- } else if (err == MPG123_OK) {
- continue;
- }
- else
- return MP4_FAILURE;
- }
- return MP4_SUCCESS;
- }
- bool MPEG4_MP3::_UpdateProperties()
- {
- if (decoder && (!channels || !sample_rate)) {
- long sample_rate = 44100;
- int channels = 2;
- int encoding = 0;
- if (mpg123_getformat(decoder, &sample_rate, &channels, &encoding) == MPG123_OK) {
- this->channels = channels;
- this->sample_rate = sample_rate;
- }
- }
- return channels && sample_rate;
- }
- int MPEG4_MP3::GetOutputPropertiesEx(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat)
- {
- if (_UpdateProperties()) {
- *sampleRate = this->sample_rate;
- *channels = this->channels;
- *bitsPerSample = bits;
- *isFloat = floatingPoint;
- return MP4_SUCCESS;
- } else {
- return MP4_FAILURE;
- }
- }
- int MPEG4_MP3::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample)
- {
- bool dummy;
- return GetOutputPropertiesEx(sampleRate, channels, bitsPerSample, &dummy);
- }
- void MPEG4_MP3::Close()
- {
- if (decoder) {
- mpg123_delete(decoder);
- decoder = 0;
- }
- }
- void MPEG4_MP3::Flush()
- {
- mpg123_open_feed(decoder);
- pregap = FHG_DELAY;
- }
- int MPEG4_MP3::SetGain(float _gain)
- {
- gain = _gain;
- return MP4_SUCCESS;
- }
- int MPEG4_MP3::GetCurrentBitrate(unsigned int *bitrate)
- {
- mpg123_frameinfo frameInfo;
- if (mpg123_info(decoder, &frameInfo) == MPG123_OK) {
- *bitrate = frameInfo.bitrate;
- return MP4_SUCCESS;
- } else {
- return MP4_FAILURE;
- }
- }
- int MPEG4_MP3::OutputFrameSize(size_t *frameSize)
- {
- if (_UpdateProperties()) {
- *frameSize = (bits/8) * channels * mpg123_spf(decoder);
- return MP4_SUCCESS;
- } else {
- return MP4_FAILURE;
- }
- }
- int MPEG4_MP3::CanHandleMPEG4Type(unsigned __int8 type)
- {
- switch (type)
- {
- case MP4_MPEG4_LAYER1_AUDIO:
- case MP4_MPEG4_LAYER2_AUDIO:
- case MP4_MPEG4_LAYER3_AUDIO:
- return 1;
- default:
- return 0;
- }
- }
- #define CBCLASS MPEG4_MP3
- START_DISPATCH;
- CB(MPEG4_AUDIO_OPEN_EX, OpenEx)
- CB(MPEG4_AUDIO_CODEC_INFO_STRING, GetCodecInfoString)
- CB(MPEG4_AUDIO_BITRATE, GetCurrentBitrate)
- CB(MPEG4_AUDIO_FRAMESIZE, OutputFrameSize)
- CB(MPEG4_AUDIO_OUTPUTINFO, GetOutputProperties)
- CB(MPEG4_AUDIO_OUTPUTINFO_EX, GetOutputPropertiesEx)
- CB(MPEG4_AUDIO_DECODE, DecodeSample)
- VCB(MPEG4_AUDIO_FLUSH, Flush)
- VCB(MPEG4_AUDIO_CLOSE, Close)
- CB(MPEG4_AUDIO_HANDLES_CODEC, CanHandleCodec)
- CB(MPEG4_AUDIO_HANDLES_TYPE, CanHandleType)
- CB(MPEG4_AUDIO_HANDLES_MPEG4_TYPE, CanHandleMPEG4Type)
- CB(MPEG4_AUDIO_SET_GAIN, SetGain)
- END_DISPATCH;
|