FLVAACDecoder.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include "FLVAACDecoder.h"
  2. #include <math.h>
  3. #include "../nsutil/pcm.h"
  4. int FLVDecoder::CreateAudioDecoder(int stereo, int bits, int sample_rate, int format_type, ifc_flvaudiodecoder **decoder)
  5. {
  6. if (format_type == FLV::AUDIO_FORMAT_AAC)
  7. {
  8. CAccessUnitPtr access_unit = CAccessUnit_Create(0, 0);
  9. if (!access_unit)
  10. return CREATEDECODER_FAILURE;
  11. FLVAAC *aac = new FLVAAC(access_unit);
  12. if (!aac)
  13. {
  14. CAccessUnit_Destroy(&access_unit);
  15. return CREATEDECODER_FAILURE;
  16. }
  17. *decoder = aac;
  18. return CREATEDECODER_SUCCESS;
  19. }
  20. return CREATEDECODER_NOT_MINE;
  21. }
  22. int FLVDecoder::HandlesAudio(int format_type)
  23. {
  24. if (format_type == FLV::AUDIO_FORMAT_AAC)
  25. {
  26. return CREATEDECODER_SUCCESS;
  27. }
  28. return CREATEDECODER_NOT_MINE;
  29. }
  30. #define CBCLASS FLVDecoder
  31. START_DISPATCH;
  32. CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
  33. CB(HANDLES_AUDIO, HandlesAudio)
  34. END_DISPATCH;
  35. #undef CBCLASS
  36. /* --- */
  37. FLVAAC::FLVAAC(CAccessUnitPtr access_unit) : access_unit(access_unit)
  38. {
  39. bps = 16;
  40. preDelay=0;
  41. got_decoder_config = false;
  42. decoder = 0;
  43. composition_unit = 0;
  44. }
  45. int FLVAAC::GetOutputFormat(unsigned int *sample_rate, unsigned int *channels, unsigned int *_bits)
  46. {
  47. /* TODO: verify that it's safe to call these, e.g. one frame has been decoded successfully */
  48. CCompositionUnit_GetSamplingRate(composition_unit, sample_rate);
  49. CCompositionUnit_GetChannels(composition_unit, channels);
  50. *_bits = bps;
  51. return FLV_AUDIO_SUCCESS;
  52. }
  53. int FLVAAC::DecodeSample(const void *input_buffer, size_t input_buffer_bytes, void *samples, size_t *samples_size_bytes, double *bitrate)
  54. {
  55. const uint8_t *type = (const uint8_t *)input_buffer;
  56. if (type[0] == 0)
  57. {
  58. CSAudioSpecificConfig asc;
  59. memset(&asc, 0, sizeof(asc));
  60. if (mp4AudioDecoder_ascParse(type+1, input_buffer_bytes-1, &asc) == MP4AUDIODEC_OK)
  61. {
  62. CSAudioSpecificConfig *asc_array = &asc;;
  63. decoder = mp4AudioDecoder_Create(&asc_array, 1);
  64. if (decoder)
  65. {
  66. mp4AudioDecoder_SetParam(decoder, TDL_MODE, SWITCH_OFF);
  67. mp4AudioDecoder_SetParam(decoder, CONCEALMENT_ENERGYINTERPOLATION, SWITCH_OFF);
  68. composition_unit = CCompositionUnit_Create(max(asc.m_channels, 8), asc.m_samplesPerFrame * 2, asc.m_samplingFrequency, 6144, CUBUFFER_PCMTYPE_FLOAT);
  69. if (composition_unit)
  70. {
  71. got_decoder_config=true;
  72. *samples_size_bytes=0;
  73. return FLV_AUDIO_SUCCESS;
  74. }
  75. mp4AudioDecoder_Destroy(&decoder);
  76. }
  77. }
  78. return FLV_AUDIO_FAILURE;
  79. }
  80. else if (type[0] == 1)
  81. {
  82. CAccessUnit_Reset(access_unit);
  83. CAccessUnit_Assign(access_unit, type+1, input_buffer_bytes-1);
  84. CCompositionUnit_Reset(composition_unit);
  85. MP4_RESULT result = mp4AudioDecoder_DecodeFrame(decoder, &access_unit, composition_unit);
  86. if (result == MP4AUDIODEC_OK)
  87. {
  88. unsigned int channels;
  89. unsigned int samples_per_channel;
  90. CCompositionUnit_GetSamplesPerChannel(composition_unit, &samples_per_channel);
  91. CCompositionUnit_GetChannels(composition_unit, &channels);
  92. const float *audio_output = 0;
  93. size_t num_samples = samples_per_channel * channels;
  94. size_t output_size = num_samples * (bps/8);
  95. if (output_size > *samples_size_bytes)
  96. return FLV_AUDIO_FAILURE;
  97. *samples_size_bytes = output_size;
  98. CCompositionUnit_GetPcmPtr(composition_unit, &audio_output);
  99. nsutil_pcm_FloatToInt_Interleaved_Gain(samples, audio_output, bps, num_samples, 1.0f/32768.0f);
  100. int br;
  101. CCompositionUnit_GetProperty(composition_unit, CUBUFFER_CURRENTBITRATE, &br);
  102. *bitrate = (double)br/1000.0;
  103. return FLV_AUDIO_SUCCESS;
  104. }
  105. else
  106. return FLV_AUDIO_FAILURE;
  107. }
  108. else
  109. return FLV_AUDIO_FAILURE;
  110. }
  111. void FLVAAC::Flush()
  112. {
  113. mp4AudioDecoder_Reset(decoder, MP4AUDIODECPARAM_DEFAULT, 0);
  114. }
  115. void FLVAAC::Close()
  116. {
  117. mp4AudioDecoder_Destroy(&decoder);
  118. CAccessUnit_Destroy(&access_unit);
  119. CCompositionUnit_Destroy(&composition_unit);
  120. delete this;
  121. }
  122. int FLVAAC::Ready()
  123. {
  124. return !!got_decoder_config;
  125. }
  126. void FLVAAC::SetPreferences(unsigned int _max_channels, unsigned int preferred_bits)
  127. {
  128. if (preferred_bits)
  129. bps = preferred_bits;
  130. // TODO: max channels
  131. }
  132. #define CBCLASS FLVAAC
  133. START_DISPATCH;
  134. CB(FLV_AUDIO_GETOUTPUTFORMAT, GetOutputFormat)
  135. CB(FLV_AUDIO_DECODE, DecodeSample)
  136. VCB(FLV_AUDIO_FLUSH, Flush)
  137. VCB(FLV_AUDIO_CLOSE, Close)
  138. CB(FLV_AUDIO_READY, Ready)
  139. VCB(FLV_AUDIO_SETPREFERENCES, SetPreferences)
  140. END_DISPATCH;
  141. #undef CBCLASS