1
0

mft-util.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #include "util.h"
  2. #include <bfc/platform/types.h>
  3. #include <mferror.h>
  4. #include <mftransform.h>
  5. #include <wmcodecdsp.h>
  6. #include <Mfidl.h>
  7. #include <Mfapi.h>
  8. struct AACUserData {
  9. WORD wPayloadType;
  10. WORD wAudioProfileLevelIndication;
  11. WORD wStructType;
  12. WORD wReserved1;
  13. DWORD dwReserved2;
  14. uint8_t buffer[16];
  15. };
  16. HRESULT GetAACCodec(IMFTransform **pDecoder)
  17. {
  18. HRESULT hr = S_OK;
  19. UINT32 count = 0;
  20. IMFActivate **ppActivate = NULL; // Array of activation objects.
  21. MFT_REGISTER_TYPE_INFO info = { MFMediaType_Audio, MFAudioFormat_AAC };
  22. UINT32 unFlags = MFT_ENUM_FLAG_SYNCMFT |
  23. MFT_ENUM_FLAG_LOCALMFT |
  24. MFT_ENUM_FLAG_SORTANDFILTER;
  25. hr = MFTEnumEx(
  26. MFT_CATEGORY_AUDIO_DECODER,
  27. unFlags,
  28. &info, // Input type
  29. NULL, // Output type
  30. &ppActivate,
  31. &count
  32. );
  33. if (SUCCEEDED(hr) && count == 0)
  34. {
  35. hr = MF_E_TOPO_CODEC_NOT_FOUND;
  36. }
  37. // Create the first decoder in the list.
  38. if (SUCCEEDED(hr))
  39. {
  40. hr = ppActivate[0]->ActivateObject(IID_PPV_ARGS(pDecoder));
  41. }
  42. for (UINT32 i = 0; i < count; i++)
  43. {
  44. ppActivate[i]->Release();
  45. }
  46. CoTaskMemFree(ppActivate);
  47. return hr;
  48. }
  49. bool AssociateFloat(IMFTransform *decoder)
  50. {
  51. IMFMediaType *media_type;
  52. DWORD index=0;
  53. for (;;)
  54. {
  55. GUID subtype;
  56. UINT32 bps;
  57. HRESULT hr = decoder->GetOutputAvailableType(0, index++, &media_type);
  58. if (hr != S_OK)
  59. return false;
  60. if (media_type->GetGUID(MF_MT_SUBTYPE, &subtype) != S_OK
  61. || media_type->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, &bps) != S_OK)
  62. {
  63. media_type->Release();
  64. return false;
  65. }
  66. if (subtype == MFAudioFormat_Float && bps == 32)
  67. {
  68. hr = decoder->SetOutputType(0, media_type, 0);
  69. media_type->Release();
  70. return true;
  71. }
  72. media_type->Release();
  73. }
  74. }
  75. static uint32_t SampleRateForASC(const void *asc, size_t aacConfigLength)
  76. {
  77. const uint8_t *pAacConfig = (const uint8_t *)asc;
  78. const uint32_t samplingRates[]={96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,0};
  79. int index;
  80. if (aacConfigLength >= 5 && (pAacConfig[4] >> 7) == 1)
  81. {
  82. index = (pAacConfig[4] >> 3) & 0x7;
  83. } else if (aacConfigLength >= 2) {
  84. index = ((pAacConfig[0] & 0x7) << 1) | (pAacConfig[1] >> 7); // bits 5-8
  85. } else {
  86. index = 12;
  87. }
  88. return samplingRates[index];
  89. }
  90. HRESULT CreateAACDecoder(IMFTransform **pDecoder, const void *asc, size_t asc_bytes)
  91. {
  92. HRESULT hr;
  93. IMFMediaType *media_type;
  94. hr = GetAACCodec(pDecoder);
  95. if (FAILED(hr)) {
  96. return hr;
  97. }
  98. hr = MFCreateMediaType(&media_type);
  99. if (FAILED(hr)) {
  100. return hr;
  101. }
  102. hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
  103. hr = media_type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);
  104. //
  105. hr = media_type->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 0); // The stream contains raw_data_block elements only.
  106. uint8_t profile_level =0xFE;// MP4GetAudioProfileLevel(mp4_file);
  107. hr = media_type->SetUINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, profile_level);
  108. media_type->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, SampleRateForASC(asc, asc_bytes));
  109. // this is such a pain in the ass, it's part of an HEAACWAVEINFO struct packed together with the ASC data
  110. AACUserData aacinfo;
  111. aacinfo.wPayloadType = 0;
  112. aacinfo.wAudioProfileLevelIndication = profile_level;
  113. aacinfo.wStructType = 0;
  114. if (asc && asc_bytes) {
  115. if (asc_bytes > 16) { // don't overrun the buffer
  116. return E_FAIL;
  117. }
  118. memcpy(aacinfo.buffer, asc, asc_bytes);
  119. hr = media_type->SetBlob(MF_MT_USER_DATA, (const UINT8 *)&aacinfo, 12+(UINT)asc_bytes);
  120. }
  121. hr = (*pDecoder)->SetInputType(0, media_type, 0);
  122. if (FAILED(hr)) {
  123. return hr;
  124. }
  125. media_type->Release();
  126. media_type=0;
  127. AssociateFloat(*pDecoder);
  128. return S_OK;
  129. }
  130. HRESULT CreateADTSDecoder(IMFTransform **pDecoder)
  131. {
  132. HRESULT hr;
  133. IMFMediaType *media_type;
  134. hr = GetAACCodec(pDecoder);
  135. if (FAILED(hr)) {
  136. return hr;
  137. }
  138. hr = MFCreateMediaType(&media_type);
  139. if (FAILED(hr)) {
  140. return hr;
  141. }
  142. hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
  143. hr = media_type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);
  144. hr = media_type->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 1); // ADTS
  145. //hr = media_type->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16); // 16 bits per sample
  146. uint8_t profile_level =0xFE;// MP4GetAudioProfileLevel(mp4_file);
  147. hr = media_type->SetUINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, profile_level);
  148. const BYTE user_data[] = {0x01, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  149. hr = media_type->SetBlob(MF_MT_USER_DATA, user_data, sizeof(user_data));
  150. hr = (*pDecoder)->SetInputType(0, media_type, 0);
  151. if (FAILED(hr)) {
  152. return hr;
  153. }
  154. media_type->Release();
  155. media_type=0;
  156. AssociateFloat(*pDecoder);
  157. return S_OK;
  158. }