123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- #include "flv_mp3_decoder.h"
- #include "../nsutil/pcm.h"
- int FLVDecoderCreator::CreateAudioDecoder(int stereo, int bits, int sample_rate, int format_type, ifc_flvaudiodecoder **decoder)
- {
- if (format_type == FLV::AUDIO_FORMAT_MP3 || format_type == FLV::AUDIO_FORMAT_MP3_8KHZ)
- {
- 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 (!stereo) {
- flags |= MPG123_FORCE_MONO;
- }
- mpg123_param(ctx, MPG123_FLAGS, flags, 0);
- mpg123_param(ctx, MPG123_RVA, MPG123_RVA_OFF, 0);
- *decoder = new FLVMP3(ctx);
- return CREATEDECODER_SUCCESS;
- }
- return CREATEDECODER_NOT_MINE;
- }
- int FLVDecoderCreator::HandlesAudio(int format_type)
- {
- if (format_type == FLV::AUDIO_FORMAT_MP3 || format_type == FLV::AUDIO_FORMAT_MP3_8KHZ)
- {
- return CREATEDECODER_SUCCESS;
- }
- return CREATEDECODER_NOT_MINE;
- }
- #define CBCLASS FLVDecoderCreator
- START_DISPATCH;
- CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
- CB(HANDLES_AUDIO, HandlesAudio)
- END_DISPATCH;
- #undef CBCLASS
- /* --- */
- #define FHG_DELAY 529
- FLVMP3::FLVMP3(mpg123_handle *mp3) : mp3(mp3)
- {
- mpg123_open_feed(mp3);
- bits = 16;
- pregap = FHG_DELAY;
- max_channels = 2;
- channels = 0;
- decode_buffer = 0;
- decode_buffer_length = 0;
- }
- FLVMP3::~FLVMP3()
- {
- if (mp3) {
- mpg123_delete(mp3);
- mp3 = 0;
- }
- free(decode_buffer);
- }
- int FLVMP3::GetOutputFormat(unsigned int *sample_rate, unsigned int *_channels, unsigned int *_bits)
- {
- mpg123_frameinfo frameInfo;
- if (mpg123_info(mp3, &frameInfo) == MPG123_OK)
- {
- *sample_rate = frameInfo.rate;
- channels = (frameInfo.mode == MPG123_M_MONO)?1:2;
- *_channels = channels;
- *_bits = bits;
- return FLV_AUDIO_SUCCESS;
- }
- else
- {
- return FLV_AUDIO_FAILURE;
- }
- }
- int FLVMP3::DecodeSample(const void *input_buffer, size_t input_buffer_bytes, void *samples, size_t *samples_size_bytes, double *bitrate)
- {
- if (!mp3)
- return FLV_AUDIO_FAILURE;
- mpg123_feed(mp3, (unsigned char *)input_buffer, input_buffer_bytes);
- *samples_size_bytes = 0;
- *bitrate = 0;
- for (;;) {
- if (!decode_buffer) {
- int channels = 2;
- long sample_rate;
- int encoding;
- if (mpg123_getformat(mp3, &sample_rate, &channels, &encoding) == MPG123_OK) {
- this->channels = channels;
- decode_buffer_length = sizeof(float) * channels * mpg123_spf(mp3);
- decode_buffer = (float *)malloc(decode_buffer_length);
- if (!decode_buffer) {
- return FLV_AUDIO_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 (!channels) {
- long sample_rate = 44100;
- int channels = 2;
- int encoding = 0;
- if (mpg123_getformat(mp3, &sample_rate, &channels, &encoding) == MPG123_OK) {
- this->channels = channels;
- } else {
- return FLV_AUDIO_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(samples, pcm_buf, bits, numSamples);
- *samples_size_bytes += numSamples * bits / 8;
- samples = (char *)samples + numSamples * bits / 8;
- mpg123_frameinfo frameInfo;
- if (mpg123_info(mp3, &frameInfo) == MPG123_OK) {
- *bitrate = frameInfo.bitrate;
- }
- return FLV_AUDIO_SUCCESS;
- } else if (err == MPG123_NEED_MORE) {
- *samples_size_bytes = 0;
- return FLV_AUDIO_NEEDS_MORE_INPUT;
- } else if (err == MPG123_NEW_FORMAT) {
- continue;
- } else if (err == MPG123_OK) {
- continue;
- }
- else
- return FLV_AUDIO_FAILURE;
- }
- return FLV_AUDIO_SUCCESS;
- }
- void FLVMP3::Flush()
- {
- mpg123_open_feed(mp3);
- pregap = FHG_DELAY;
- }
- void FLVMP3::Close()
- {
- if (mp3) {
- mpg123_delete(mp3);
- mp3 = 0;
- }
- delete this;
- }
- void FLVMP3::SetPreferences(unsigned int _max_channels, unsigned int preferred_bits)
- {
- if (preferred_bits)
- bits = preferred_bits;
- if (max_channels > _max_channels)
- max_channels = _max_channels;
- 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(mp3, MPG123_FLAGS, flags, 0);
- mpg123_param(mp3, MPG123_RVA, MPG123_RVA_OFF, 0);
- }
- #define CBCLASS FLVMP3
- START_DISPATCH;
- CB(FLV_AUDIO_GETOUTPUTFORMAT, GetOutputFormat)
- CB(FLV_AUDIO_DECODE, DecodeSample)
- VCB(FLV_AUDIO_FLUSH, Flush)
- VCB(FLV_AUDIO_CLOSE, Close)
- VCB(FLV_AUDIO_SETPREFERENCES, SetPreferences)
- END_DISPATCH;
- #undef CBCLASS
|