NSVAACDecoder.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include "NSVAACDecoder.h"
  2. #include <assert.h>
  3. #include "api.h"
  4. #include "../nsv/nsvlib.h"
  5. #include "api.h"
  6. #include "../nsv/nsvlib.h"
  7. #include "../nsv/dec_if.h"
  8. #include <string.h>
  9. #include <bfc/platform/export.h>
  10. #include "NSVAACDecoder.h"
  11. #include <bfc/error.h>
  12. #ifndef MIN
  13. #define MIN(a,b) (((a) < (b)) ? (a) : (b))
  14. #endif
  15. NSVAACDecoder *NSVAACDecoder::CreateDecoder()
  16. {
  17. CAccessUnitPtr access_unit = CAccessUnit_Create(0, 0);
  18. if (!access_unit)
  19. return 0;
  20. NSVAACDecoder *decoder=0;
  21. WASABI_API_MEMMGR->New(&decoder);
  22. if (!decoder)
  23. {
  24. CAccessUnit_Destroy(&access_unit);
  25. return 0;
  26. }
  27. decoder->Initialize(access_unit);
  28. return decoder;
  29. }
  30. NSVAACDecoder::NSVAACDecoder()
  31. {
  32. access_unit = 0;
  33. composition_unit = 0;
  34. decoder = 0;
  35. source_position=0;
  36. out_left=0;
  37. in_position=0;
  38. }
  39. NSVAACDecoder::~NSVAACDecoder()
  40. {
  41. mp4AudioDecoder_Destroy(&decoder);
  42. CAccessUnit_Destroy(&access_unit);
  43. CCompositionUnit_Destroy(&composition_unit);
  44. }
  45. void NSVAACDecoder::Initialize(CAccessUnitPtr _access_unit)
  46. {
  47. access_unit = _access_unit;
  48. }
  49. void NSVAACDecoder::flush()
  50. {
  51. if (decoder)
  52. mp4AudioDecoder_Reset(decoder, MP4AUDIODECPARAM_DEFAULT, 0);
  53. }
  54. static void ConfigureADTS(CSAudioSpecificConfig* asc, nsaac_adts_header_t header)
  55. {
  56. asc->m_aot = (AUDIO_OBJECT_TYPE)(header->profile + 1);
  57. asc->m_channelConfiguration = header->channel_configuration;
  58. asc->m_channels = nsaac_adts_get_channel_count(header);
  59. asc->m_nrOfStreams = 1;
  60. asc->m_samplesPerFrame = 1024;
  61. asc->m_samplingFrequencyIndex = header->sample_rate_index;
  62. asc->m_samplingFrequency = nsaac_adts_get_samplerate(header);
  63. asc->m_avgBitRate = 0; /* only needed for tvq */
  64. asc->m_mpsPresentFlag = -1;
  65. asc->m_saocPresentFlag = -1;
  66. asc->m_ldmpsPresentFlag = -1;
  67. }
  68. // returns -1 on error, 0 on success (done with data in 'in'), 1 on success
  69. // but to pass 'in' again next time around.
  70. int NSVAACDecoder::decode(void *in, int in_len, void *out, int *out_len, unsigned int out_fmt[8])
  71. {
  72. if (out_left)
  73. {
  74. unsigned int channels;
  75. unsigned int sample_rate;
  76. if (CCompositionUnit_GetChannels(composition_unit, &channels) != MP4AUDIODEC_OK
  77. || CCompositionUnit_GetSamplingRate(composition_unit, &sample_rate) != MP4AUDIODEC_OK)
  78. return -1;
  79. out_fmt[0] = NSV_MAKETYPE('P', 'C', 'M', ' ');
  80. out_fmt[1] = sample_rate;
  81. out_fmt[2] = channels;
  82. out_fmt[3] = 16;
  83. const uint8_t *audio_output=0;
  84. CCompositionUnit_GetPcmPtr(composition_unit, &audio_output);
  85. size_t copy_size = min(out_left, *out_len);
  86. memcpy(out, audio_output + source_position, copy_size);
  87. *out_len = copy_size;
  88. out_left -= copy_size;
  89. source_position += copy_size;
  90. return 1;
  91. ;
  92. }
  93. in = (uint8_t *)in + in_position;
  94. in_len -= in_position;
  95. if (in_len > 7)
  96. {
  97. ADTSHeader header;
  98. if (nsaac_adts_parse(&header, (const uint8_t *)in) == NErr_Success)
  99. {
  100. if (!decoder)
  101. {
  102. CSAudioSpecificConfig asc;
  103. memset(&asc, 0, sizeof(asc));
  104. ConfigureADTS(&asc, &header);
  105. CSAudioSpecificConfig *asc_array = &asc;
  106. decoder = mp4AudioDecoder_Create(&asc_array, 1);
  107. if (decoder)
  108. {
  109. mp4AudioDecoder_SetParam(decoder, TDL_MODE, SWITCH_ON);
  110. mp4AudioDecoder_SetParam(decoder, CONCEALMENT_ENERGYINTERPOLATION, SWITCH_OFF);
  111. composition_unit = CCompositionUnit_Create(max(asc.m_channels, 8), asc.m_samplesPerFrame * 2, asc.m_samplingFrequency, 6144, CUBUFFER_PCMTYPE_INT16);
  112. }
  113. if (!decoder || !composition_unit)
  114. {
  115. in_position=0;
  116. return -1;
  117. }
  118. }
  119. if (header.frame_length > in_len)
  120. {
  121. in_position=0;
  122. return -1;
  123. }
  124. if (header.frame_length != in_len)
  125. {
  126. in_position+=header.frame_length;
  127. }
  128. else
  129. {
  130. in_position=0;
  131. }
  132. CAccessUnit_Reset(access_unit);
  133. CAccessUnit_Assign(access_unit, (const uint8_t *)in + 7, header.frame_length-7);
  134. CCompositionUnit_Reset(composition_unit);
  135. MP4_RESULT result = mp4AudioDecoder_DecodeFrame(decoder, &access_unit, composition_unit);
  136. if (result == MP4AUDIODEC_OK)
  137. {
  138. unsigned int channels;
  139. unsigned int samples_per_channel;
  140. unsigned int sample_rate;
  141. if (CCompositionUnit_GetSamplesPerChannel(composition_unit, &samples_per_channel) != MP4AUDIODEC_OK
  142. || CCompositionUnit_GetChannels(composition_unit, &channels) != MP4AUDIODEC_OK
  143. || CCompositionUnit_GetSamplingRate(composition_unit, &sample_rate) != MP4AUDIODEC_OK)
  144. return -1;
  145. size_t num_samples = samples_per_channel * channels;
  146. size_t output_size = num_samples * 2 /* 16 bits */;
  147. const uint16_t *audio_output=0;
  148. CCompositionUnit_GetPcmPtr(composition_unit, &audio_output);
  149. size_t copy_size = min(output_size, *out_len);
  150. memcpy(out, audio_output, copy_size);
  151. *out_len = copy_size;
  152. out_left = output_size - copy_size;
  153. source_position = copy_size;
  154. out_fmt[0] = NSV_MAKETYPE('P', 'C', 'M', ' ');
  155. out_fmt[1] = sample_rate;
  156. out_fmt[2] = channels;
  157. out_fmt[3] = 16;
  158. int br;
  159. CCompositionUnit_GetProperty(composition_unit, CUBUFFER_AVGBITRATE, &br);
  160. out_fmt[4] =br/1000;
  161. if (in_position)
  162. return 1;
  163. return 0;
  164. }
  165. else
  166. {
  167. return -1;
  168. }
  169. }
  170. else
  171. {
  172. in_position=0;
  173. return -1;
  174. }
  175. }
  176. *out_len = 0;
  177. in_position=0;
  178. return 0;
  179. }
  180. IAudioDecoder *NSVDecoder::CreateAudioDecoder(FOURCC format, IAudioOutput **output)
  181. {
  182. switch (format)
  183. {
  184. case NSV_MAKETYPE('A', 'A', 'C', ' ') :
  185. case NSV_MAKETYPE('A', 'A', 'C', 'P'):
  186. case NSV_MAKETYPE('A', 'P', 'L', ' '):
  187. {
  188. NSVAACDecoder *dec = NSVAACDecoder::CreateDecoder();
  189. return dec;
  190. }
  191. default:
  192. return 0;
  193. }
  194. }
  195. #define CBCLASS NSVDecoder
  196. START_DISPATCH;
  197. CB(SVC_NSVFACTORY_CREATEAUDIODECODER, CreateAudioDecoder)
  198. END_DISPATCH;
  199. #undef CBCLASS