HRESULT CheckDX9RotationSupport(_In_ ID3D11VideoDevice* pVideoDevice) { HRESULT hr = S_OK; // // check if the DX9 device is ok // New drivers should have an DXVA-HD rotation cap set // D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc = {}; D3D11_VIDEO_PROCESSOR_CAPS caps; ComPtr<ID3D11VideoProcessorEnumerator> spVideoProcEnum = nullptr; DMFTCHECKNULL_GOTO(pVideoDevice, done, E_NOTIMPL); desc.InputWidth = 640; desc.InputHeight = 480; desc.OutputWidth = 640; desc.OutputHeight = 480; DMFTCHECKHR_GOTO(pVideoDevice->CreateVideoProcessorEnumerator(&desc, &spVideoProcEnum), done); DMFTCHECKHR_GOTO(spVideoProcEnum->GetVideoProcessorCaps(&caps), done); if (!(caps.FeatureCaps & D3D11_VIDEO_PROCESSOR_FEATURE_CAPS_ROTATION)) { hr = E_NOTIMPL; } done: return hr; }
STDMETHODIMP IsOptimizedPlanarVideoInputImageOutputPair( _In_ IMFMediaType *inMediaType, _In_ IMFMediaType *outMediaType, _Out_ bool *optimized, _Out_ bool *optimizedxvpneeded ) { HRESULT hr = S_OK; GUID guidInputSubType = GUID_NULL; GUID guidOutputSubType = GUID_NULL; UINT32 uWidthIn = 0, uHeightIn = 0, uWidthOut = 0, uHeightOut = 0; DMFTCHECKHR_GOTO(inMediaType->GetGUID(MF_MT_SUBTYPE, &guidInputSubType), done); DMFTCHECKHR_GOTO(outMediaType->GetGUID(MF_MT_SUBTYPE, &guidOutputSubType), done); *optimized = false; //Assume we aren't optimized . Optimized = (ip = YU12|NV12 and op = JPEG) *optimizedxvpneeded = true; //Assume we need xvps if (IsEqualGUID(guidInputSubType, MFVideoFormat_YV12) || IsEqualGUID(guidInputSubType, MFVideoFormat_NV12)) { if (IsEqualGUID(guidOutputSubType, GUID_ContainerFormatJpeg)) { *optimized = true; } } if (!*optimized) { goto done; } DMFTCHECKHR_GOTO(MFGetAttributeSize(inMediaType, MF_MT_FRAME_SIZE, &uWidthIn, &uHeightIn), done); DMFTCHECKHR_GOTO(MFGetAttributeSize(outMediaType, MF_MT_FRAME_SIZE, &uWidthOut, &uHeightOut), done); if ((uWidthIn == uWidthOut) && (uHeightIn == uHeightOut)) { *optimizedxvpneeded = false; } if (!*optimizedxvpneeded) { UINT32 nominalRange; hr = inMediaType->GetUINT32(MF_MT_VIDEO_NOMINAL_RANGE, &nominalRange); if (FAILED(hr) || nominalRange != MFNominalRange_0_255) { //XVP needed since nominal range is not 0-255 for YV12 or NV12 fed into WIC *optimizedxvpneeded = true; } hr = S_OK; } done: return hr; }
PCHAR CMediaTypePrinter::ToString() { // //Following are the important ones of Mediatype attributes // HRESULT hr = S_OK; PROPVARIANT var; LPSTR pTempBaseStr; MF_ATTRIBUTE_TYPE pType; GUID attrGuid; GUID impGuids[] = { MF_MT_SUBTYPE, MF_MT_FRAME_SIZE, MF_MT_SAMPLE_SIZE, MF_MT_FRAME_RATE, MF_MT_DEFAULT_STRIDE, MF_XVP_DISABLE_FRC }; if (pMediaType && !m_pBuffer) { buffLen = MEDIAPRINTER_STARTLEN; m_pBuffer = new char[buffLen]; m_pBuffer[0] = 0; for (UINT32 ulIndex = 0; ulIndex < ARRAYSIZE(impGuids); ulIndex++) { PropVariantInit(&var); checkAdjustBufferCap(m_pBuffer, buffLen); attrGuid = impGuids[ulIndex]; DMFTCHECKHR_GOTO(pMediaType->GetItemType(attrGuid, &pType), done); DMFTCHECKHR_GOTO(pMediaType->GetItem(attrGuid, &var), done); if (ulIndex > 0) strcat_s(m_pBuffer, MEDIAPRINTER_STARTLEN, " : "); strcat_s(m_pBuffer, buffLen, GetGUIDNameConst(attrGuid)); strcat_s(m_pBuffer, buffLen, "="); pTempBaseStr = DumpAttribute(pType, var); strcat_s(m_pBuffer, buffLen, pTempBaseStr); delete(pTempBaseStr); PropVariantClear(&var); } } done: return m_pBuffer; }
STDMETHODIMP UnLockAsynMFT(IMFTransform* pTransform) { HRESULT hr = S_OK; IMFAttributes *pAttributes; UINT32 unValue; DMFTCHECKNULL_GOTO(pTransform,done, E_INVALIDARG); DMFTCHECKHR_GOTO(pTransform->GetAttributes(&pAttributes),done); DMFTCHECKHR_GOTO(pAttributes->GetUINT32(MF_TRANSFORM_ASYNC, &unValue), done); if (unValue) { DMFTCHECKHR_GOTO(pAttributes->SetUINT32(MF_TRANSFORM_ASYNC, true), done); } done: return hr; }
STDMETHODIMP_(DeviceStreamState) CCustomPin::SetState( _In_ DeviceStreamState State ) { HRESULT hr = S_OK; DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! Id:%d Transition into state: %d ", streamId(), State); DeviceStreamState oldState = setPreferredStreamState( State ); if ( oldState != State ) { ComPtr<IMFMediaType> preferredMediaType = nullptr; if (State == DeviceStreamState_Run) { GetMediaTypeAt(0, preferredMediaType.ReleaseAndGetAddressOf()); } setPreferredMediaType(preferredMediaType.Get()); setPreferredStreamState( State ); { // // Notify the device transform manager that we have changed state // ComPtr<IMFMediaEvent> pEvent = nullptr; DMFTCHECKHR_GOTO( MFCreateMediaEvent(METransformInputStreamStateChanged, GUID_NULL, S_OK, NULL, pEvent.ReleaseAndGetAddressOf()), done ); DMFTCHECKHR_GOTO( pEvent->SetUINT32(MF_EVENT_MFT_INPUT_STREAM_ID, streamId()), done ); DMFTCHECKHR_GOTO( Parent()->QueueEvent(pEvent.Get()), done ); } // // Wait to be notified back from the pipeline. // DMFTCHECKHR_GOTO( WaitForSetInputPinMediaChange(),done ); } done: DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr); return oldState; }
/*++ Description: Rudimentary function to print the complete Media type --*/ PCHAR CMediaTypePrinter::ToCompleteString( ) { HRESULT hr = S_OK; UINT32 attrCount = 0; GUID attrGuid = { 0 }; char *tempStore = nullptr; PROPVARIANT var; LPSTR pTempBaseStr; MF_ATTRIBUTE_TYPE pType; if ( pMediaType && !m_pBuffer ) { DMFTCHECKHR_GOTO(pMediaType->GetCount(&attrCount), done); buffLen = MEDIAPRINTER_STARTLEN; m_pBuffer = new char[buffLen]; m_pBuffer[0] = 0; for ( UINT32 ulIndex = 0; ulIndex < attrCount; ulIndex++ ) { PropVariantInit( &var ); checkAdjustBufferCap( m_pBuffer, buffLen ); DMFTCHECKHR_GOTO( pMediaType->GetItemByIndex( ulIndex, &attrGuid, &var ), done ); DMFTCHECKHR_GOTO( pMediaType->GetItemType( attrGuid, &pType ), done ); if ( ulIndex > 0 ) strcat_s(m_pBuffer, MEDIAPRINTER_STARTLEN, " : "); strcat_s( m_pBuffer, buffLen, GetGUIDNameConst( attrGuid ) ); strcat_s( m_pBuffer, buffLen, "=" ); pTempBaseStr = DumpAttribute( pType, var ); strcat_s( m_pBuffer, buffLen, pTempBaseStr ); delete( pTempBaseStr ); PropVariantClear( &var ); } done: if ( tempStore ) { delete( tempStore ); } } return m_pBuffer; }
HRESULT IsDXOptimal(_In_ IUnknown *pDeviceManager, _Out_ BOOL *pIsOptimal) { HRESULT hr = S_OK; ComPtr<IMFDXGIDeviceManager> spDXGIDeviceManager = nullptr; ComPtr<ID3D11Device> spD3D11 = nullptr; ComPtr<ID3D11VideoDevice> spVideoDevice = nullptr; HANDLE hDevice = NULL; BOOL locked = FALSE; *pIsOptimal = false; DMFTCHECKNULL_GOTO( pDeviceManager, done, E_INVALIDARG ); DMFTCHECKHR_GOTO( pDeviceManager->QueryInterface(IID_PPV_ARGS( &spDXGIDeviceManager )), done ); DMFTCHECKHR_GOTO( spDXGIDeviceManager->OpenDeviceHandle( &hDevice ), done ); DMFTCHECKHR_GOTO( spDXGIDeviceManager->LockDevice( hDevice, IID_PPV_ARGS( &spD3D11 ), TRUE), done ); locked = TRUE; DMFTCHECKHR_GOTO( spD3D11.As(&spVideoDevice), done ); if (spD3D11->GetFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) { if (FAILED(CheckDX9RotationSupport(spVideoDevice.Get()))) { goto done; } } *pIsOptimal = TRUE; done: if (hDevice) { if (locked) { spDXGIDeviceManager->UnlockDevice(hDevice, false); } spDXGIDeviceManager->CloseDeviceHandle(hDevice); } return hr; }
STDMETHODIMP CMediaEventGenerator::QueryInterface( _In_ REFIID iid, _COM_Outptr_ void** ppv) { HRESULT hr = S_OK; *ppv = NULL; if (iid == __uuidof(IUnknown) || iid == __uuidof(IMFMediaEventGenerator)) { *ppv = static_cast<IMFMediaEventGenerator*>(this); AddRef(); } else { hr = E_NOINTERFACE; DMFTCHECKHR_GOTO(hr, done); } done: return hr; }
/* Description: This is used whenever there is a media type change on an output pin and the Output queue is being reconfigured. The possible return values for the function are as follows DeviceMftTransformXVPIllegal -> If either of the mediatypes or both are NULL DeviceMftTransformXVPDisruptiveIn -> If the mediatype at the output pin is greater than the input pin. This will result in change of the media type on the input DeviceMftTransformXVPDisruptiveOut -> This is a reconfiguration or addition of the XVP in the Output pin queue DeviceMftTransformXVPCurrent -> No XVP needed at all Note: This iteration doesn't support decoder. The next one will and this function will accordingly change */ STDMETHODIMP CompareMediaTypesForXVP( _In_opt_ IMFMediaType *inMediaType, _In_ IMFMediaType *newMediaType, _Inout_ MF_TRANSFORM_XVP_OPERATION *operation ) { UINT32 unWidthin, unHeightin, unWidthNew, unHeightNew = 0; HRESULT hr = S_OK; GUID guidTypeA = GUID_NULL; GUID guidTypeB = GUID_NULL; *operation = DeviceMftTransformXVPIllegal; if ((!inMediaType) || (!newMediaType)) { goto done; } DMFTCHECKHR_GOTO( MFGetAttributeSize( inMediaType, MF_MT_FRAME_SIZE, &unWidthin, &unHeightin ), done ); DMFTCHECKHR_GOTO( MFGetAttributeSize( newMediaType, MF_MT_FRAME_SIZE, &unWidthNew, &unHeightNew ), done ); if ( SUCCEEDED( inMediaType->GetGUID( MF_MT_MAJOR_TYPE, &guidTypeA ) ) && SUCCEEDED( newMediaType->GetGUID( MF_MT_MAJOR_TYPE, &guidTypeB ) ) && IsEqualGUID( guidTypeA, guidTypeB ) ) { if ( SUCCEEDED( inMediaType->GetGUID ( MF_MT_SUBTYPE, &guidTypeA ) ) && SUCCEEDED( newMediaType->GetGUID( MF_MT_SUBTYPE, &guidTypeB ) ) && IsEqualGUID( guidTypeA, guidTypeB ) ) { //Comparing the MF_MT_AM_FORMAT_TYPE for the directshow format guid #if 0 if (SUCCEEDED(inMediaType->GetGUID(MF_MT_AM_FORMAT_TYPE, &guidTypeA)) && SUCCEEDED(newMediaType->GetGUID(MF_MT_AM_FORMAT_TYPE, &guidTypeB)) && IsEqualGUID(guidTypeA, guidTypeB)) #endif { if (!(( unWidthin == unWidthNew ) && ( unHeightin == unHeightNew ) ) ) { if ( ( unWidthNew > unWidthin ) || ( unHeightNew > unHeightin ) ) { *operation = DeviceMftTransformXVPDisruptiveIn; //Media type needs to change at input } else { *operation = DeviceMftTransformXVPDisruptiveOut; //Media type needs to change at output } goto done; } if ( MFGetAttributeUINT32( inMediaType, MF_MT_SAMPLE_SIZE, 0 ) != MFGetAttributeUINT32( newMediaType, MF_MT_SAMPLE_SIZE, 0 ) ) { hr = S_FALSE; //Sample sizes differ. goto done; } else { //Same media type.. No XVP needed or the current XVP is fine! *operation = DeviceMftTransformXVPCurrent; } } } else { //This is a disruptive operation. Actually a decoder operation! *operation = DeviceMftTransformXVPDisruptiveIn; } } done: return hr; }