123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- #include "util.h"
- #include <bfc/platform/types.h>
- #include <mferror.h>
- #include <mftransform.h>
- #include <wmcodecdsp.h>
- #include <Mfidl.h>
- #include <Mfapi.h>
- struct AACUserData {
- WORD wPayloadType;
- WORD wAudioProfileLevelIndication;
- WORD wStructType;
- WORD wReserved1;
- DWORD dwReserved2;
- uint8_t buffer[16];
- };
- HRESULT GetAACCodec(IMFTransform **pDecoder)
- {
- HRESULT hr = S_OK;
- UINT32 count = 0;
- IMFActivate **ppActivate = NULL; // Array of activation objects.
- MFT_REGISTER_TYPE_INFO info = { MFMediaType_Audio, MFAudioFormat_AAC };
- UINT32 unFlags = MFT_ENUM_FLAG_SYNCMFT |
- MFT_ENUM_FLAG_LOCALMFT |
- MFT_ENUM_FLAG_SORTANDFILTER;
- hr = MFTEnumEx(
- MFT_CATEGORY_AUDIO_DECODER,
- unFlags,
- &info, // Input type
- NULL, // Output type
- &ppActivate,
- &count
- );
- if (SUCCEEDED(hr) && count == 0)
- {
- hr = MF_E_TOPO_CODEC_NOT_FOUND;
- }
- // Create the first decoder in the list.
- if (SUCCEEDED(hr))
- {
- hr = ppActivate[0]->ActivateObject(IID_PPV_ARGS(pDecoder));
- }
- for (UINT32 i = 0; i < count; i++)
- {
- ppActivate[i]->Release();
- }
- CoTaskMemFree(ppActivate);
- return hr;
- }
- bool AssociateFloat(IMFTransform *decoder)
- {
- IMFMediaType *media_type;
- DWORD index=0;
- for (;;)
- {
- GUID subtype;
- UINT32 bps;
- HRESULT hr = decoder->GetOutputAvailableType(0, index++, &media_type);
- if (hr != S_OK)
- return false;
- if (media_type->GetGUID(MF_MT_SUBTYPE, &subtype) != S_OK
- || media_type->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, &bps) != S_OK)
- {
- media_type->Release();
- return false;
- }
- if (subtype == MFAudioFormat_Float && bps == 32)
- {
- hr = decoder->SetOutputType(0, media_type, 0);
- media_type->Release();
- return true;
- }
- media_type->Release();
- }
- }
- static uint32_t SampleRateForASC(const void *asc, size_t aacConfigLength)
- {
- const uint8_t *pAacConfig = (const uint8_t *)asc;
- const uint32_t samplingRates[]={96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,0};
- int index;
- if (aacConfigLength >= 5 && (pAacConfig[4] >> 7) == 1)
- {
- index = (pAacConfig[4] >> 3) & 0x7;
- } else if (aacConfigLength >= 2) {
- index = ((pAacConfig[0] & 0x7) << 1) | (pAacConfig[1] >> 7); // bits 5-8
- } else {
- index = 12;
- }
- return samplingRates[index];
- }
- HRESULT CreateAACDecoder(IMFTransform **pDecoder, const void *asc, size_t asc_bytes)
- {
- HRESULT hr;
- IMFMediaType *media_type;
- hr = GetAACCodec(pDecoder);
- if (FAILED(hr)) {
- return hr;
- }
-
- hr = MFCreateMediaType(&media_type);
- if (FAILED(hr)) {
- return hr;
- }
- hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
- hr = media_type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);
- //
- hr = media_type->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 0); // The stream contains raw_data_block elements only.
- uint8_t profile_level =0xFE;// MP4GetAudioProfileLevel(mp4_file);
- hr = media_type->SetUINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, profile_level);
- media_type->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, SampleRateForASC(asc, asc_bytes));
-
- // this is such a pain in the ass, it's part of an HEAACWAVEINFO struct packed together with the ASC data
- AACUserData aacinfo;
- aacinfo.wPayloadType = 0;
- aacinfo.wAudioProfileLevelIndication = profile_level;
- aacinfo.wStructType = 0;
-
- if (asc && asc_bytes) {
- if (asc_bytes > 16) { // don't overrun the buffer
- return E_FAIL;
- }
- memcpy(aacinfo.buffer, asc, asc_bytes);
-
- hr = media_type->SetBlob(MF_MT_USER_DATA, (const UINT8 *)&aacinfo, 12+(UINT)asc_bytes);
- }
- hr = (*pDecoder)->SetInputType(0, media_type, 0);
- if (FAILED(hr)) {
- return hr;
- }
- media_type->Release();
- media_type=0;
- AssociateFloat(*pDecoder);
- return S_OK;
- }
- HRESULT CreateADTSDecoder(IMFTransform **pDecoder)
- {
- HRESULT hr;
- IMFMediaType *media_type;
- hr = GetAACCodec(pDecoder);
- if (FAILED(hr)) {
- return hr;
- }
-
- hr = MFCreateMediaType(&media_type);
- if (FAILED(hr)) {
- return hr;
- }
- hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
- hr = media_type->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_AAC);
- hr = media_type->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 1); // ADTS
- //hr = media_type->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16); // 16 bits per sample
- uint8_t profile_level =0xFE;// MP4GetAudioProfileLevel(mp4_file);
- hr = media_type->SetUINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, profile_level);
-
- const BYTE user_data[] = {0x01, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- hr = media_type->SetBlob(MF_MT_USER_DATA, user_data, sizeof(user_data));
- hr = (*pDecoder)->SetInputType(0, media_type, 0);
- if (FAILED(hr)) {
- return hr;
- }
- media_type->Release();
- media_type=0;
- AssociateFloat(*pDecoder);
- return S_OK;
- }
|