int select_input_mediatype(IMFTransform *transform, int in_stream_id, ADTSData adts, UINT8 *user_data, UINT32 user_data_len, GUID audio_format) { HRESULT hr = S_OK; IMFMediaType *t; // actually you can get rid of the whole block of searching and filtering mess // if you know the exact parameters of your media stream hr = MFCreateMediaType(&t); if (FAILED(hr)) { ReportError(L"Unable to create an empty MediaType", hr); return -1; } // basic definition t->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio); t->SetGUID(MF_MT_SUBTYPE, audio_format); // see https://docs.microsoft.com/en-us/windows/desktop/medfound/aac-decoder#example-media-types // and https://docs.microsoft.com/zh-cn/windows/desktop/api/mmreg/ns-mmreg-heaacwaveinfo_tag // for the meaning of the byte array below // for integrate into a larger project, it is recommended to wrap the parameters into a struct // and pass that struct into the function // const UINT8 aac_data[] = { 0x01, 0x00, 0xfe, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x11, 0x90 }; // 0: raw aac 1: adts 2: adif 3: latm/laos t->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 1); t->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, adts.channels); t->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, adts.samplerate); // 0xfe = 254 = "unspecified" t->SetUINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, 254); t->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1); t->SetBlob(MF_MT_USER_DATA, user_data, user_data_len); hr = transform->SetInputType(in_stream_id, t, 0); if (FAILED(hr)) { ReportError(L"failed to select input types for MFT", hr); return -1; } return 0; }
STDMETHODIMP CDecWMV9MFT::InitDecoder(AVCodecID codec, const CMediaType *pmt) { HRESULT hr = S_OK; DbgLog((LOG_TRACE, 10, L"CDecWMV9MFT::InitDecoder(): Initializing WMV9 MFT decoder")); DestroyDecoder(false); BITMAPINFOHEADER *pBMI = nullptr; REFERENCE_TIME rtAvg = 0; DWORD dwARX = 0, dwARY = 0; videoFormatTypeHandler(*pmt, &pBMI, &rtAvg, &dwARX, &dwARY); size_t extralen = 0; BYTE *extra = nullptr; getExtraData(*pmt, nullptr, &extralen); if (extralen > 0) { extra = (BYTE *)av_mallocz(extralen + FF_INPUT_BUFFER_PADDING_SIZE); getExtraData(*pmt, extra, &extralen); } if (codec == AV_CODEC_ID_VC1 && extralen) { size_t i = 0; for (i = 0; i < (extralen - 4); i++) { uint32_t code = AV_RB32(extra + i); if ((code & ~0xFF) == 0x00000100) break; } if (i == 0) { memmove(extra + 1, extra, extralen); *extra = 0; extralen++; } else if (i > 1) { DbgLog((LOG_TRACE, 10, L"-> VC-1 Header at position %u (should be 0 or 1)", i)); } } if (extralen > 0) { m_vc1Header = new CVC1HeaderParser(extra, extralen, codec); } /* Create input type */ m_nCodecId = codec; IMFMediaType *pMTIn = nullptr; MF.CreateMediaType(&pMTIn); pMTIn->SetUINT32(MF_MT_COMPRESSED, TRUE); pMTIn->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, FALSE); pMTIn->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, FALSE); pMTIn->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); pMTIn->SetGUID(MF_MT_SUBTYPE, VerifySubtype(codec, pmt->subtype)); MFSetAttributeSize(pMTIn, MF_MT_FRAME_SIZE, pBMI->biWidth, pBMI->biHeight); UINT32 rateNum = 0, rateDen = 0; MF.AverageTimePerFrameToFrameRate(rtAvg, &rateNum, &rateDen); MFSetAttributeRatio(pMTIn, MF_MT_FRAME_RATE, rateNum, rateDen); pMTIn->SetBlob(MF_MT_USER_DATA, extra, (UINT32)extralen); av_freep(&extra); hr = m_pMFT->SetInputType(0, pMTIn, 0); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> Failed to set input type on MFT")); return hr; } /* Create output type */ hr = SelectOutputType(); SafeRelease(&pMTIn); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> Failed to set output type on MFT")); return hr; } IMFMediaType *pMTOut = nullptr; m_pMFT->GetOutputCurrentType(0, &pMTOut); m_bInterlaced = MFGetAttributeUINT32(pMTOut, MF_MT_INTERLACE_MODE, MFVideoInterlace_Unknown) > MFVideoInterlace_Progressive; SafeRelease(&pMTOut); m_bManualReorder = (codec == AV_CODEC_ID_VC1) && !(m_pCallback->GetDecodeFlags() & LAV_VIDEO_DEC_FLAG_ONLY_DTS); return S_OK; }