MP4AACDecoder.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include "MP4AACDecoder.h"
  2. #include <Mferror.h>
  3. #include <Mfapi.h>
  4. #include "../external_dependencies/libmp4v2/mp4.h"
  5. #include "util.h"
  6. #include "../nsutil/pcm.h"
  7. MP4AACDecoder::MP4AACDecoder()
  8. {
  9. isFloat = false;
  10. gain=1.0f;
  11. channels = 0;
  12. }
  13. MP4AACDecoder::~MP4AACDecoder()
  14. {
  15. }
  16. int MP4AACDecoder::OpenMP4(MP4FileHandle mp4_file, MP4TrackId mp4_track, size_t output_bits, size_t maxChannels, bool useFloat)
  17. {
  18. HRESULT hr;
  19. unsigned char *buffer;
  20. uint32_t buffer_size;
  21. if (useFloat) {
  22. this->bitsPerSample = 32;
  23. } else if (output_bits) {
  24. this->bitsPerSample = (unsigned int)output_bits;
  25. } else {
  26. this->bitsPerSample = 16;
  27. }
  28. this->isFloat = useFloat;
  29. if (MP4GetTrackESConfiguration(mp4_file, mp4_track, (uint8_t **)&buffer, &buffer_size) && buffer) {
  30. hr = decoder.Open(buffer, buffer_size);
  31. if (SUCCEEDED(hr)) {
  32. uint32_t local_sample_rate, local_channels;
  33. hr = decoder.GetOutputProperties(&local_sample_rate, &local_channels);
  34. if (SUCCEEDED(hr)) {
  35. this->channels = local_channels;
  36. return MP4_SUCCESS;
  37. }
  38. }
  39. }
  40. return MP4_FAILURE;
  41. }
  42. void MP4AACDecoder::Close()
  43. {
  44. }
  45. void MP4AACDecoder::Flush()
  46. {
  47. decoder.Flush();
  48. }
  49. int MP4AACDecoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *_bitsPerSample)
  50. {
  51. bool dummy;
  52. return GetOutputPropertiesEx(sampleRate, channels, _bitsPerSample, &dummy);
  53. }
  54. int MP4AACDecoder::GetOutputPropertiesEx(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *useFloat)
  55. {
  56. HRESULT hr;
  57. UINT32 local_sample_rate, local_channels;
  58. hr = decoder.GetOutputProperties(&local_sample_rate, &local_channels);
  59. if (FAILED(hr)) {
  60. return MP4_FAILURE;
  61. }
  62. *sampleRate = local_sample_rate;
  63. *channels = local_channels;
  64. *bitsPerSample = this->bitsPerSample;
  65. *useFloat = this->isFloat;
  66. return MP4_SUCCESS;
  67. }
  68. int MP4AACDecoder::DecodeSample(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
  69. {
  70. HRESULT hr;
  71. hr = decoder.Feed(inputBuffer, inputBufferBytes);
  72. if (FAILED(hr)) {
  73. return MP4_FAILURE;
  74. }
  75. hr = decoder.Decode(outputBuffer, outputBufferBytes, this->bitsPerSample, this->isFloat, this->gain);
  76. if (FAILED(hr)) {
  77. return MP4_FAILURE;
  78. }
  79. return MP4_SUCCESS;
  80. }
  81. int MP4AACDecoder::OutputFrameSize(size_t *frameSize)
  82. {
  83. if (channels == 0) {
  84. return MP4_FAILURE;
  85. }
  86. size_t local_frame_size;
  87. if (FAILED(decoder.OutputBlockSizeSamples(&local_frame_size))) {
  88. return MP4_FAILURE;
  89. }
  90. *frameSize = local_frame_size / channels;
  91. return MP4_SUCCESS;
  92. }
  93. int MP4AACDecoder::CanHandleCodec(const char *codecName)
  94. {
  95. return !strcmp(codecName, "mp4a");
  96. }
  97. int MP4AACDecoder::CanHandleType(uint8_t type)
  98. {
  99. switch (type)
  100. {
  101. case MP4_TYPE_MPEG4_AUDIO:
  102. return 1;
  103. case MP4_TYPE_MPEG2_AAC_LC_AUDIO:
  104. return 1;
  105. default:
  106. return 0;
  107. }
  108. }
  109. int MP4AACDecoder::CanHandleMPEG4Type(uint8_t type)
  110. {
  111. switch (type)
  112. {
  113. case MP4_MPEG4_TYPE_AAC_LC_AUDIO:
  114. case MP4_MPEG4_TYPE_AAC_HE_AUDIO:
  115. case MP4_MPEG4_TYPE_PARAMETRIC_STEREO:
  116. return 1;
  117. default:
  118. return 0;
  119. }
  120. }
  121. void MP4AACDecoder::EndOfStream()
  122. {
  123. decoder.Feed(0, 0);
  124. }
  125. #ifdef CBCLASS
  126. #undef CBCLASS
  127. #endif
  128. #define CBCLASS MP4AACDecoder
  129. START_DISPATCH;
  130. CB(MPEG4_AUDIO_OPENMP4, OpenMP4)
  131. #if 0
  132. CB(MPEG4_AUDIO_BITRATE, GetCurrentBitrate)
  133. #endif
  134. CB(MPEG4_AUDIO_FRAMESIZE, OutputFrameSize)
  135. CB(MPEG4_AUDIO_OUTPUTINFO, GetOutputProperties)
  136. CB(MPEG4_AUDIO_OUTPUTINFO_EX, GetOutputPropertiesEx)
  137. CB(MPEG4_AUDIO_DECODE, DecodeSample)
  138. VCB(MPEG4_AUDIO_FLUSH, Flush)
  139. VCB(MPEG4_AUDIO_CLOSE, Close)
  140. CB(MPEG4_AUDIO_HANDLES_CODEC, CanHandleCodec)
  141. CB(MPEG4_AUDIO_HANDLES_TYPE, CanHandleType)
  142. CB(MPEG4_AUDIO_HANDLES_MPEG4_TYPE, CanHandleMPEG4Type)
  143. CB(MPEG4_AUDIO_SET_GAIN, SetGain)
  144. END_DISPATCH;