1
0

MFTDecoder.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include "MFTDecoder.h"
  2. #include "util.h"
  3. #include "../nsutil/pcm.h"
  4. #include <Mfapi.h>
  5. #include <Mferror.h>
  6. static // Release the events that an MFT might allocate in IMFTransform::ProcessOutput().
  7. void ReleaseEventCollection(MFT_OUTPUT_DATA_BUFFER* pBuffers)
  8. {
  9. if (pBuffers->pEvents)
  10. {
  11. pBuffers->pEvents->Release();
  12. pBuffers->pEvents = NULL;
  13. }
  14. }
  15. MFTDecoder::MFTDecoder()
  16. {
  17. decoder=0;
  18. output_buffer=0;
  19. output_sample=0;
  20. }
  21. MFTDecoder::~MFTDecoder()
  22. {
  23. if (decoder) {
  24. decoder->Release();
  25. }
  26. decoder = 0;
  27. if (output_buffer) {
  28. output_buffer->Release();
  29. }
  30. output_buffer = 0;
  31. if (output_sample) {
  32. output_sample->Release();
  33. }
  34. output_sample = 0;
  35. }
  36. HRESULT MFTDecoder::Open(const void *asc, size_t asc_bytes)
  37. {
  38. HRESULT hr = CreateAACDecoder(&decoder, asc, asc_bytes);
  39. if (SUCCEEDED(hr)) {
  40. decoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
  41. }
  42. return hr;
  43. }
  44. HRESULT MFTDecoder::Open()
  45. {
  46. HRESULT hr = CreateADTSDecoder(&decoder);
  47. if (SUCCEEDED(hr)) {
  48. decoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0);
  49. decoder->ProcessMessage(MFT_MESSAGE_NOTIFY_START_OF_STREAM, 0);
  50. }
  51. return hr;
  52. }
  53. void MFTDecoder::Flush()
  54. {
  55. if (decoder) {
  56. decoder->ProcessMessage(MFT_MESSAGE_COMMAND_FLUSH, 0);
  57. }
  58. }
  59. HRESULT MFTDecoder::GetOutputProperties(uint32_t *sampleRate, uint32_t *channels)
  60. {
  61. HRESULT hr;
  62. IMFMediaType *media_type;
  63. UINT32 local_sample_rate, local_channels;
  64. if (!decoder) {
  65. return E_FAIL;
  66. }
  67. hr = decoder->GetOutputCurrentType(0, &media_type);
  68. if (FAILED(hr)) {
  69. return hr;
  70. }
  71. if (FAILED(hr=media_type->GetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, &local_sample_rate))
  72. || FAILED(hr=media_type->GetUINT32(MF_MT_AUDIO_NUM_CHANNELS, &local_channels))) {
  73. media_type->Release();
  74. return hr;
  75. }
  76. *sampleRate = local_sample_rate;
  77. *channels = local_channels;
  78. return hr;
  79. }
  80. HRESULT MFTDecoder::Feed(const void *inputBuffer, size_t inputBufferBytes)
  81. {
  82. HRESULT hr;
  83. if (inputBuffer && inputBufferBytes) {
  84. IMFMediaBuffer *media_buffer=0;
  85. IMFSample *media_sample=0;
  86. MFCreateMemoryBuffer((DWORD)inputBufferBytes, &media_buffer);
  87. MFCreateSample(&media_sample);
  88. media_sample->AddBuffer(media_buffer);
  89. BYTE *buffer;
  90. DWORD max_length, current_length;
  91. media_buffer->Lock(&buffer, &max_length, &current_length);
  92. memcpy(buffer, inputBuffer, inputBufferBytes);
  93. media_buffer->Unlock();
  94. media_buffer->SetCurrentLength((DWORD)inputBufferBytes);
  95. hr = decoder->ProcessInput(0, media_sample, 0);
  96. media_sample->Release();
  97. media_buffer->Release();
  98. media_sample=0;
  99. media_buffer=0;
  100. } else {
  101. decoder->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0);
  102. decoder->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0);
  103. }
  104. return S_OK;
  105. }
  106. HRESULT MFTDecoder::Decode(void *outputBuffer, size_t *outputBufferBytes, unsigned int bitsPerSample, bool isFloat, double gain)
  107. {
  108. HRESULT hr;
  109. if (!output_sample) {
  110. MFT_OUTPUT_STREAM_INFO output_stream_info;
  111. hr = decoder->GetOutputStreamInfo(0, &output_stream_info);
  112. if (FAILED(hr)) {
  113. return hr;
  114. }
  115. MFCreateMemoryBuffer(output_stream_info.cbSize, &output_buffer);
  116. MFCreateSample(&output_sample);
  117. output_sample->AddBuffer(output_buffer);
  118. }
  119. output_buffer->SetCurrentLength(0);
  120. MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0, output_sample, 0, 0};
  121. DWORD status=0;
  122. hr = decoder->ProcessOutput(0, 1, &output_data_buffer, &status);
  123. if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
  124. *outputBufferBytes = 0;
  125. return S_OK;
  126. } else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
  127. AssociateFloat(decoder);
  128. *outputBufferBytes = 0;
  129. return hr;
  130. }
  131. IMFMediaBuffer *decimation_buffer;
  132. hr = output_data_buffer.pSample->ConvertToContiguousBuffer(&decimation_buffer);
  133. float *pcm;
  134. DWORD max_length, current_length;
  135. decimation_buffer->Lock((BYTE **)&pcm, &max_length, &current_length);
  136. size_t num_samples = current_length / 4;
  137. *outputBufferBytes = num_samples*bitsPerSample/8;
  138. if (!isFloat)
  139. {
  140. nsutil_pcm_FloatToInt_Interleaved_Gain(outputBuffer, pcm, bitsPerSample, num_samples, (float)gain);
  141. }
  142. else
  143. {
  144. for (size_t i = 0;i != num_samples;i++)
  145. ((float *)outputBuffer)[i] = pcm[i] * (float)gain;
  146. }
  147. decimation_buffer->Unlock();
  148. decimation_buffer->Release();
  149. ReleaseEventCollection(&output_data_buffer);
  150. return S_OK;
  151. }
  152. HRESULT MFTDecoder::OutputBlockSizeSamples(size_t *frameSize)
  153. {
  154. HRESULT hr;
  155. MFT_OUTPUT_STREAM_INFO output_stream_info;
  156. if (!decoder) {
  157. return E_FAIL;
  158. }
  159. hr = decoder->GetOutputStreamInfo(0, &output_stream_info);
  160. if (FAILED(hr)) {
  161. return hr;
  162. }
  163. *frameSize = output_stream_info.cbSize;
  164. return hr;
  165. }
  166. bool MFTDecoder::AcceptingInput()
  167. {
  168. DWORD flags;
  169. if (decoder && SUCCEEDED(decoder->GetInputStatus(0, &flags))) {
  170. if (flags & MFT_INPUT_STATUS_ACCEPT_DATA) {
  171. return true;
  172. }
  173. }
  174. return false;
  175. }