[avstream/sampledevicemft] Fix format change error for YUY2 (#984)
This commit is contained in:
Родитель
a24deb382e
Коммит
d35df21596
|
@ -30,7 +30,7 @@ CBasePin::CBasePin( _In_ ULONG id, _In_ CMultipinMft *parent) :
|
|||
, m_setMediaType(nullptr)
|
||||
, m_nRefCount(0)
|
||||
, m_state(DeviceStreamState_Stop)
|
||||
, m_dwWorkQueueId(MFASYNC_CALLBACK_QUEUE_UNDEFINED)
|
||||
, m_dwWorkQueueId(MFASYNC_CALLBACK_QUEUE_MULTITHREADED)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ STDMETHODIMP COutPin::AddPin(
|
|||
|
||||
}
|
||||
#if defined MF_DEVICEMFT_ADD_GRAYSCALER_ // Take this out to remove the gray scaler
|
||||
m_queue = new (std::nothrow) CPinQueueWithGrayScale(inputPinId);
|
||||
m_queue = new (std::nothrow) CPinQueueWithGrayScale(inputPinId,Parent());
|
||||
#else
|
||||
m_queue = new (std::nothrow) CPinQueue(inputPinId,Parent());
|
||||
#endif
|
||||
|
|
|
@ -638,7 +638,17 @@ class CTranslateOutPin : public COutPin {
|
|||
MFVideoFormat_H264,
|
||||
MFVideoFormat_MJPG
|
||||
};
|
||||
// @@@@README : This is what the compressed media types will be translated into
|
||||
|
||||
// @@@@README
|
||||
// If you translate to YUY2 in D3D mode it is a suboptimal path, because the
|
||||
// pipeline i.e. Frameserver will lock the surface into a staging buffer and
|
||||
// map it to the client process like Teams, Camera App etc.
|
||||
// Ideally when translating to YUY2, don't pass the D3D Manager to the
|
||||
// Decoder (CDecoderTee) or the Video Processor (CXVPTee). The pipeline will
|
||||
// shove the system buffer back into the DX surface on the client side, if the App
|
||||
// demands DX surfaces. NV12 is sharable from frameserver to clients and hence
|
||||
// the preferred format to decode into.
|
||||
// The below subtype is what the compressed media types will be translated into.
|
||||
const GUID translatedGUID = MFVideoFormat_NV12; // Translating to NV12
|
||||
public:
|
||||
CTranslateOutPin(_In_ ULONG id = 0,
|
||||
|
|
|
@ -224,7 +224,7 @@ STDMETHODIMP CPinQueueWithGrayScale::RecreateTee( _In_ IMFMediaType *inMediatyp
|
|||
||IsEqualCLSID(gInputSubType, MFVideoFormat_RGB32))
|
||||
{
|
||||
CGrayTee *pTee = NULL;
|
||||
pTee = new (std::nothrow) CGrayTee(m_spTeer);
|
||||
pTee = new (std::nothrow) CGrayTee(m_spTeer.Get());
|
||||
DMFTCHECKHR_GOTO(pTee->SetMediaTypes(inMediatype, outMediatype), done);
|
||||
m_spTeer = dynamic_cast< Ctee* >(pTee);
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ HRESULT CVideoProcTee::SetMediaTypes(_In_ IMFMediaType* pInMediaType, _In_ IMFMe
|
|||
HRESULT hr = S_OK;
|
||||
ComPtr<IMFTransform> spTransform;
|
||||
DMFTCHECKHR_GOTO(CWrapTee::SetMediaTypes(pInMediaType, pOutMediaType),done);
|
||||
DMFTCHECKHR_GOTO(Configure(pInMediaType, pOutMediaType, spTransform.GetAddressOf()), done);
|
||||
DMFTCHECKHR_GOTO(Configure(pInMediaType, pOutMediaType, spTransform.ReleaseAndGetAddressOf()), done);
|
||||
m_spVideoProcessor = spTransform;
|
||||
//
|
||||
// Start streaming
|
||||
|
@ -610,12 +610,14 @@ STDMETHODIMP CDecoderTee::Configure(_In_opt_ IMFMediaType *inType,
|
|||
m_pOutputMediaType.Get(),
|
||||
spTransform.ReleaseAndGetAddressOf(), m_hwMFT)))
|
||||
{
|
||||
m_hwMFT = TRUE;
|
||||
hr = ConfigDecoder(spTransform.Get(), gInSubType);
|
||||
}
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// Try creating SW deocder
|
||||
hr = S_OK;
|
||||
m_hwMFT = FALSE;
|
||||
DMFTCHECKHR_GOTO(EnumSWDecoder(spTransform.ReleaseAndGetAddressOf(), gInSubType), done);
|
||||
DMFTCHECKHR_GOTO(ConfigDecoder(spTransform.Get(), gInSubType), done);
|
||||
}
|
||||
|
@ -907,7 +909,7 @@ HRESULT CDecoderTee::ProcessFormatChange()
|
|||
// Also note, The platform doesn't support dynamic media type changes from the stream coming from the
|
||||
// source.
|
||||
//
|
||||
ComPtr<CXvptee> spXvpTee;
|
||||
ComPtr<CVideoProcTee> spXvpTee;
|
||||
DMFTCHECKHR_GOTO(m_pOutputMediaType->GetGUID(MF_MT_SUBTYPE, &guidPreviousSubType), done);
|
||||
|
||||
for (DWORD i = 0; ; i++)
|
||||
|
@ -935,9 +937,21 @@ HRESULT CDecoderTee::ProcessFormatChange()
|
|||
//
|
||||
// Create the XVP and insert it into the chain manually. set the output to the mediatype requested by the platform
|
||||
//
|
||||
spXvpTee = new (std::nothrow) CXvptee(m_spObjectWrapped.Get() ,m_streamCategory);
|
||||
if (m_bXvpAdded && m_spXvp.Get())
|
||||
{
|
||||
// The XVP was already created. change the xvp to handle format change
|
||||
spXvpTee = m_spXvp;
|
||||
}
|
||||
else
|
||||
{
|
||||
spXvpTee = new (std::nothrow) CXvptee(m_spObjectWrapped.Get(), m_streamCategory);
|
||||
m_spXvp = spXvpTee;
|
||||
}
|
||||
DMFTCHECKNULL_GOTO(spXvpTee.Get(), done, E_OUTOFMEMORY);
|
||||
(VOID)spXvpTee->SetD3DManager(m_spDeviceManagerUnk.Get());
|
||||
if(m_hwMFT)
|
||||
{
|
||||
(VOID)spXvpTee->SetD3DManager(m_spDeviceManagerUnk.Get());
|
||||
}
|
||||
DMFTCHECKHR_GOTO(spXvpTee->SetMediaTypes(spDecoderOutputMediaType.Get(), m_pOutputMediaType.Get()), done);
|
||||
m_spObjectWrapped = spXvpTee;
|
||||
|
||||
|
@ -965,6 +979,8 @@ HRESULT CDecoderTee::ConfigDecoder(_In_ IMFTransform* pTransform, _In_ GUID guid
|
|||
DWORD dwMediaTypeIndex = 0;
|
||||
DWORD dwFlags = 0;
|
||||
ComPtr<IMFDXGIDeviceManager> spDxgiManager;
|
||||
DWORD dwDesiredFlags = MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA;
|
||||
|
||||
UNREFERENCED_PARAMETER(guidSubType);
|
||||
DMFTCHECKNULL_GOTO(pTransform, done, E_INVALIDARG);
|
||||
|
||||
|
@ -995,7 +1011,7 @@ HRESULT CDecoderTee::ConfigDecoder(_In_ IMFTransform* pTransform, _In_ GUID guid
|
|||
DMFTCHECKHR_GOTO(m_pOutputMediaType->GetMajorType(&guidMajorType), done);
|
||||
DMFTCHECKHR_GOTO(m_pOutputMediaType->GetGUID(MF_MT_SUBTYPE, &guidSubtype), done);
|
||||
|
||||
if (m_spDeviceManagerUnk.Get())
|
||||
if (m_hwMFT && m_spDeviceManagerUnk.Get())
|
||||
{
|
||||
DMFTCHECKHR_GOTO(m_spDeviceManagerUnk.As(&spDxgiManager), done);
|
||||
if (m_D3daware && SUCCEEDED(IsDXFormatSupported(spDxgiManager.Get(), guidSubtype, nullptr, nullptr)))
|
||||
|
@ -1025,22 +1041,30 @@ HRESULT CDecoderTee::ConfigDecoder(_In_ IMFTransform* pTransform, _In_ GUID guid
|
|||
spMediaType = nullptr;
|
||||
dwMediaTypeIndex++;
|
||||
}
|
||||
|
||||
// If cannot find a matchig mediatype, bail out.
|
||||
DMFTCHECKNULL_GOTO(spMediaType.Get(), done, MF_E_INVALIDMEDIATYPE);
|
||||
|
||||
// Try to set output type on the MJPG decoder.
|
||||
DMFTCHECKHR_GOTO(pTransform->MFTSetOutputType(m_dwMFTOutputId, spMediaType.Get(), 0), done);
|
||||
if (S_OK != (spMediaType->IsEqual(m_pOutputMediaType.Get(), &dwFlags)))
|
||||
hr = spMediaType->IsEqual(m_pOutputMediaType.Get(), &dwFlags);
|
||||
if ((S_OK == hr) ||
|
||||
(hr == S_FALSE && ((dwFlags & dwDesiredFlags) == dwDesiredFlags)))
|
||||
{
|
||||
// Try to set output type on the MJPG decoder.
|
||||
DMFTCHECKHR_GOTO(pTransform->MFTSetOutputType(m_dwMFTOutputId, spMediaType.Get(), 0), done);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the media type and also create an XVP to manage the conversion
|
||||
DMFTCHECKHR_GOTO(pTransform->MFTSetOutputType(m_dwMFTOutputId, spMediaType.Get(), 0), done);
|
||||
ComPtr<CXvptee> spXvpTee = new (std::nothrow) CXvptee(m_spObjectWrapped.Get(), m_streamCategory);
|
||||
DMFTCHECKNULL_GOTO(spXvpTee.Get(), done, E_OUTOFMEMORY);
|
||||
(VOID)spXvpTee->SetD3DManager(m_spDeviceManagerUnk.Get());
|
||||
if (m_hwMFT)
|
||||
{
|
||||
(VOID)spXvpTee->SetD3DManager(m_spDeviceManagerUnk.Get());
|
||||
}
|
||||
DMFTCHECKHR_GOTO(spXvpTee->SetMediaTypes(spMediaType.Get(), m_pOutputMediaType.Get()), done);
|
||||
m_spObjectWrapped = spXvpTee;
|
||||
m_pOutputMediaType = spMediaType;
|
||||
//Recreate the Allocator
|
||||
DMFTCHECKHR_GOTO(CreateAllocator(), done);
|
||||
m_bXvpAdded = TRUE;
|
||||
}
|
||||
done:
|
||||
|
|
|
@ -201,11 +201,11 @@ public:
|
|||
private:
|
||||
DWORD m_dwInPinId; /* This is the input pin */
|
||||
IMFSampleList m_sampleList; /* List storing the samples */
|
||||
IMFDeviceTransform* m_pTransform; /* Weak reference to the the device MFT */
|
||||
GUID m_streamCategory;
|
||||
ULONG m_cRef;
|
||||
protected:
|
||||
ComPtr<Ctee> m_spTeer; /*Tee that acts as a passthrough or an XVP */
|
||||
IMFDeviceTransform* m_pTransform; /* Weak reference to the the device MFT */
|
||||
ComPtr<Ctee> m_spTeer; /*Tee that acts as a passthrough or an XVP */
|
||||
};
|
||||
|
||||
|
||||
|
@ -473,6 +473,7 @@ protected:
|
|||
DWORD m_lNeedInputRequest;
|
||||
GUID m_streamCategory; // Needed for bind flags
|
||||
BOOL m_bXvpAdded;
|
||||
ComPtr<CVideoProcTee> m_spXvp;
|
||||
DWORD m_dwMFTInputId;
|
||||
DWORD m_dwMFTOutputId;
|
||||
ComPtr<IMFSample> m_spUnprocessedSample;
|
||||
|
|
|
@ -1292,7 +1292,10 @@ UpdateAllocatorAttributes(
|
|||
level = spDevice->GetFeatureLevel();
|
||||
dwBindFlags |= ((level >= D3D_FEATURE_LEVEL_10_0) ? D3D11_BIND_SHADER_RESOURCE : 0);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
dwBindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||
}
|
||||
DMFTCHECKHR_GOTO(pAttributes->SetUINT32(MF_SA_D3D11_BINDFLAGS, dwBindFlags), done);
|
||||
|
||||
done:
|
||||
|
|
Загрузка…
Ссылка в новой задаче