IMFMediaType* MediaSink::GetMediaTypeForStream(WORD streamNumber) { IMFASFStreamConfig *asfStreamConfig = nullptr; IMFASFProfile* mfAsfProfile; IMFMediaType* mfMediaType = nullptr; HRESULT hr; do { if (!SUCCEEDED(hr = _mfAsfContentInfo->GetProfile(&mfAsfProfile))) break; if (!SUCCEEDED(hr = mfAsfProfile->GetStreamByNumber(streamNumber, &asfStreamConfig))) break; if (!SUCCEEDED(hr = asfStreamConfig->GetMediaType(&mfMediaType))) break; } while (0); return mfMediaType; }
HRESULT CASFManager::SetupStreamDecoder (WORD wStreamNumber, GUID* pguidCurrentMediaType) { if (! m_pContentInfo) { return MF_E_NOT_INITIALIZED; } if (wStreamNumber == 0) { return E_INVALIDARG; } IMFASFProfile* pProfile = NULL; IMFMediaType* pMediaType = NULL; IMFASFStreamConfig *pStream = NULL; GUID guidMajorType = GUID_NULL; GUID guidSubType = GUID_NULL; GUID guidDecoderCategory = GUID_NULL; BOOL fIsCompressed = TRUE; CLSID *pDecoderCLSIDs = NULL; // Pointer to an array of CLISDs. UINT32 cDecoderCLSIDs = 0; // Size of the array. HRESULT hr = S_OK; //Get the profile object that stores stream information CHECK_HR(hr = m_pContentInfo->GetProfile(&pProfile)); //Get stream configuration object from the profile CHECK_HR(hr = pProfile->GetStreamByNumber(wStreamNumber, &pStream)); //Get the media type CHECK_HR(hr = pStream->GetMediaType(&pMediaType)); //Get the major media type CHECK_HR(hr = pMediaType->GetMajorType(&guidMajorType)); //Get the sub media type CHECK_HR(hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &guidSubType)); //find out if the media type is compressed CHECK_HR(hr = pMediaType->IsCompressedFormat(&fIsCompressed)); if (fIsCompressed) { //get decoder category if (guidMajorType == MFMediaType_Video) { guidDecoderCategory = MFT_CATEGORY_VIDEO_DECODER; } else if (guidMajorType == MFMediaType_Audio) { guidDecoderCategory = MFT_CATEGORY_AUDIO_DECODER; } else { CHECK_HR(hr = MF_E_INVALIDMEDIATYPE); } // Look for a decoder. MFT_REGISTER_TYPE_INFO tinfo; tinfo.guidMajorType = guidMajorType; tinfo.guidSubtype = guidSubType; CHECK_HR(hr = MFTEnum( guidDecoderCategory, 0, // Reserved &tinfo, // Input type to match. (Encoded type.) NULL, // Output type to match. (Don't care.) NULL, // Attributes to match. (None.) &pDecoderCLSIDs, // Receives a pointer to an array of CLSIDs. &cDecoderCLSIDs // Receives the size of the array. )); // MFTEnum can return zero matches. if (cDecoderCLSIDs == 0) { hr = MF_E_TOPO_CODEC_NOT_FOUND; } else { //if the CDecoder instance does not exist, create one. if (!m_pDecoder) { CHECK_HR(hr = CDecoder::CreateInstance(&m_pDecoder)); } //Load the first MFT in the array for the current media type CHECK_HR(hr = m_pDecoder->Initialize(pDecoderCLSIDs[0], pMediaType)); } *pguidCurrentMediaType = guidMajorType; } else { // Not compressed. Don't need a decoder. CHECK_HR(hr = MF_E_INVALIDREQUEST); } TRACE((L"Stream decoder loaded.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::SetupStreamDecoder failed.\n", hr); SAFE_RELEASE(pProfile); SAFE_RELEASE(pMediaType); SAFE_RELEASE(pStream); CoTaskMemFree(pDecoderCLSIDs); return hr; }
HRESULT CASFManager::EnumerateStreams (WORD** ppwStreamNumbers, GUID** ppguidMajorType, DWORD* pcbTotalStreams) { if (!ppwStreamNumbers || !ppguidMajorType || !pcbTotalStreams) { return E_INVALIDARG; } if (!m_pContentInfo) { return MF_E_NOT_INITIALIZED; } HRESULT hr = S_OK; IMFASFStreamConfig* pStream = NULL; IMFASFProfile* pProfile = NULL; *pcbTotalStreams =0; WORD* pwStreamNumbers; GUID* pguidMajorType; CHECK_HR(hr = m_pContentInfo->GetProfile(&pProfile)); CHECK_HR(hr = pProfile->GetStreamCount(pcbTotalStreams)); if (*pcbTotalStreams == 0) { SAFE_RELEASE(pProfile); return E_FAIL; } //create an array of stream numbers and initialize elements swith 0 pwStreamNumbers = new WORD[*pcbTotalStreams*sizeof(WORD)]; if (!pwStreamNumbers) { hr = E_OUTOFMEMORY; goto done; } ZeroMemory (pwStreamNumbers, *pcbTotalStreams*sizeof(WORD)); //create an array of guids and initialize elements with GUID_NULL. pguidMajorType = new GUID[*pcbTotalStreams*sizeof(GUID)]; if (!pguidMajorType) { hr = E_OUTOFMEMORY; goto done; } ZeroMemory (pguidMajorType, *pcbTotalStreams*sizeof(GUID)); //populate the arrays with stream numbers and guids from the profile object for (unsigned index = 0; index < *pcbTotalStreams; index++) { CHECK_HR(hr = pProfile->GetStream(index, &pwStreamNumbers[index], &pStream)); CHECK_HR(hr = pStream->GetStreamType(&pguidMajorType[index])); SAFE_RELEASE(pStream); } *ppwStreamNumbers = pwStreamNumbers; *ppguidMajorType = pguidMajorType; TRACE((L"Enumerated streams.\n")); done: LOG_MSG_IF_FAILED(L"CASFManager::EnumerateStreams failed.\n", hr); SAFE_RELEASE(pProfile); SAFE_RELEASE(pStream); if (FAILED (hr)) { SAFE_ARRAY_DELETE(pwStreamNumbers); SAFE_ARRAY_DELETE(pguidMajorType); } return hr; }