diff options
| author | j-leungyy <[email protected]> | 2021-05-25 09:06:09 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-05-25 09:06:09 -0700 |
| commit | 4fe5787f122fdfc45253b45f9fad3983f53d86df (patch) | |
| tree | a11e06f8951d4b7b847f6f5a708f86df87d637db /general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp | |
| parent | 53afd12aadb8aff15097f1546d4f80c6074e0bdc (diff) | |
update simplemediasource sample (#614)
* update simplemediasource wrl to winrtcpp COM, add mediatype NV12 (SimpleFrameGenerator), fix Mediatype missing attribute (bitrate), add IMFActivate, IMFSampleAllocator interface and implementation, update hardcode arg with named variables, cleanup sample for StreamIndex and StreamId, add sample KSControl
* address PR-it1 comments
* address comment from PR-it2, replace manual define of IKSControl by ksproxy.h
* remove unuse header
* address comment from PR
* fix sdk to latest, add driversign algorithm
* remove nudget, use submodule
Diffstat (limited to 'general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp')
| -rw-r--r-- | general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp | 610 |
1 files changed, 311 insertions, 299 deletions
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp index 7685b12e..c22d7421 100644 --- a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp +++ b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp @@ -1,391 +1,403 @@ -#include "stdafx.h" +// +// Copyright (C) Microsoft Corporation. All rights reserved. +// -#define NUM_IMAGE_ROWS 240 -#define NUM_IMAGE_COLS 320 +#include "pch.h" + +#define NUM_IMAGE_ROWS 480 +#define NUM_IMAGE_COLS 640 #define BYTES_PER_PIXEL 4 #define IMAGE_BUFFER_SIZE_BYTES (NUM_IMAGE_ROWS * NUM_IMAGE_COLS * BYTES_PER_PIXEL) #define IMAGE_ROW_SIZE_BYTES (NUM_IMAGE_COLS * BYTES_PER_PIXEL) -HRESULT -SimpleMediaStream::RuntimeClassInitialize( - _In_ SimpleMediaSource *pSource - ) +namespace winrt::WindowsSample::implementation { - HRESULT hr = S_OK; - ComPtr<IMFMediaTypeHandler> spTypeHandler; - ComPtr<IMFAttributes> attrs; - - if (nullptr == pSource) + HRESULT SimpleMediaStream::Initialize( + _In_ SimpleMediaSource* pSource, + _In_ DWORD dwStreamId, + _In_ MFSampleAllocatorUsage allocatorUsage + ) { - return E_INVALIDARG; - } - RETURN_IF_FAILED (pSource->QueryInterface(IID_PPV_ARGS(&_parent))); + wil::com_ptr_nothrow<IMFMediaTypeHandler> spTypeHandler; + wil::com_ptr_nothrow<IMFAttributes> attrs; - // Initialize media type and set the video output media type. - RETURN_IF_FAILED (MFCreateMediaType(&_spMediaType)); - _spMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); - _spMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32); - _spMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); - _spMediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); - MFSetAttributeSize(_spMediaType.Get(), MF_MT_FRAME_SIZE, NUM_IMAGE_COLS, NUM_IMAGE_ROWS); - MFSetAttributeRatio(_spMediaType.Get(), MF_MT_FRAME_RATE, 30, 1); - MFSetAttributeRatio(_spMediaType.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1); + RETURN_HR_IF_NULL(E_INVALIDARG, pSource); + m_parent = pSource; - RETURN_IF_FAILED (MFCreateAttributes(&_spAttributes, 10)); - RETURN_IF_FAILED (this->_SetStreamAttributes(_spAttributes.Get())); - RETURN_IF_FAILED (MFCreateEventQueue(&_spEventQueue)); + m_dwStreamId = dwStreamId; + m_allocatorUsage = allocatorUsage; - // Initialize stream descriptors - RETURN_IF_FAILED (MFCreateStreamDescriptor(0, 1, _spMediaType.GetAddressOf(), &_spStreamDesc)); + const uint32_t NUM_MEDIATYPES = 2; + wil::unique_cotaskmem_array_ptr<wil::com_ptr_nothrow<IMFMediaType>> mediaTypeList = wilEx::make_unique_cotaskmem_array<wil::com_ptr_nothrow<IMFMediaType>>(NUM_MEDIATYPES); - RETURN_IF_FAILED (_spStreamDesc->GetMediaTypeHandler(&spTypeHandler)); - RETURN_IF_FAILED (spTypeHandler->SetCurrentMediaType(_spMediaType.Get())); - RETURN_IF_FAILED (this->_SetStreamDescriptorAttributes(_spStreamDesc.Get())); - - return hr; -} + // Initialize media type and set the video output media type. + wil::com_ptr_nothrow<IMFMediaType> spMediaType; + RETURN_IF_FAILED(MFCreateMediaType(&spMediaType)); + spMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); + spMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12); + spMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); + spMediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); + MFSetAttributeSize(spMediaType.get(), MF_MT_FRAME_SIZE, NUM_IMAGE_COLS, NUM_IMAGE_ROWS); + MFSetAttributeRatio(spMediaType.get(), MF_MT_FRAME_RATE, 30, 1); + // frame size * pixle bit size * framerate + uint32_t bitrate = (uint32_t)(NUM_IMAGE_COLS * 1.5 * NUM_IMAGE_ROWS * 8* 30); + spMediaType->SetUINT32(MF_MT_AVG_BITRATE, bitrate); + MFSetAttributeRatio(spMediaType.get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1); + mediaTypeList[0] = spMediaType.detach(); -// IMFMediaEventGenerator -IFACEMETHODIMP -SimpleMediaStream::BeginGetEvent( - _In_ IMFAsyncCallback *pCallback, - _In_ IUnknown *punkState - ) -{ - HRESULT hr = S_OK; - auto lock = _critSec.Lock(); + RETURN_IF_FAILED(MFCreateMediaType(&spMediaType)); + spMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); + spMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32); + spMediaType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); + spMediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); + MFSetAttributeSize(spMediaType.get(), MF_MT_FRAME_SIZE, NUM_IMAGE_COLS, NUM_IMAGE_ROWS); + MFSetAttributeRatio(spMediaType.get(), MF_MT_FRAME_RATE, 30, 1); + // frame size * pixle bit size * framerate + bitrate = NUM_IMAGE_COLS * NUM_IMAGE_ROWS * 4 * 8* 30; + spMediaType->SetUINT32(MF_MT_AVG_BITRATE, bitrate); + MFSetAttributeRatio(spMediaType.get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1); + mediaTypeList[1] = spMediaType.detach(); - RETURN_IF_FAILED (_CheckShutdownRequiresLock()); - RETURN_IF_FAILED (_spEventQueue->BeginGetEvent(pCallback, punkState)); + RETURN_IF_FAILED(MFCreateAttributes(&m_spAttributes, 10)); + RETURN_IF_FAILED(_SetStreamAttributes(m_spAttributes.get())); - return hr; -} + RETURN_IF_FAILED(MFCreateEventQueue(&m_spEventQueue)); -IFACEMETHODIMP -SimpleMediaStream::EndGetEvent( - _In_ IMFAsyncResult *pResult, - _COM_Outptr_ IMFMediaEvent **ppEvent - ) -{ - HRESULT hr = S_OK; - auto lock = _critSec.Lock(); + // Initialize stream descriptors + RETURN_IF_FAILED(MFCreateStreamDescriptor(m_dwStreamId /*StreamId*/, NUM_MEDIATYPES /*MT count*/, mediaTypeList.get(), &m_spStreamDesc)); - RETURN_IF_FAILED (_CheckShutdownRequiresLock()); - RETURN_IF_FAILED (_spEventQueue->EndGetEvent(pResult, ppEvent)); + RETURN_IF_FAILED(m_spStreamDesc->GetMediaTypeHandler(&spTypeHandler)); + RETURN_IF_FAILED(spTypeHandler->SetCurrentMediaType(mediaTypeList[0])); + RETURN_IF_FAILED(_SetStreamDescriptorAttributes(m_spStreamDesc.get())); - return hr; -} + return S_OK; + } -IFACEMETHODIMP -SimpleMediaStream::GetEvent( - DWORD dwFlags, - _COM_Outptr_ IMFMediaEvent **ppEvent - ) -{ - // NOTE: - // GetEvent can block indefinitely, so we don't hold the lock. - // This requires some juggling with the event queue pointer. + // IMFMediaEventGenerator + IFACEMETHODIMP SimpleMediaStream::BeginGetEvent( + _In_ IMFAsyncCallback* pCallback, + _In_ IUnknown* punkState + ) + { + winrt::slim_lock_guard lock(m_Lock); - HRESULT hr = S_OK; + RETURN_IF_FAILED(_CheckShutdownRequiresLock()); + RETURN_IF_FAILED(m_spEventQueue->BeginGetEvent(pCallback, punkState)); - ComPtr<IMFMediaEventQueue> spQueue; + return S_OK; + } + IFACEMETHODIMP SimpleMediaStream::EndGetEvent( + _In_ IMFAsyncResult* pResult, + _COM_Outptr_ IMFMediaEvent** ppEvent + ) { - auto lock = _critSec.Lock(); + winrt::slim_lock_guard lock(m_Lock); - RETURN_IF_FAILED (_CheckShutdownRequiresLock()); - spQueue = _spEventQueue; + RETURN_IF_FAILED(_CheckShutdownRequiresLock()); + RETURN_IF_FAILED(m_spEventQueue->EndGetEvent(pResult, ppEvent)); + + return S_OK; } - // Now get the event. - RETURN_IF_FAILED (_spEventQueue->GetEvent(dwFlags, ppEvent)); + IFACEMETHODIMP SimpleMediaStream::GetEvent( + _In_ DWORD dwFlags, + _COM_Outptr_ IMFMediaEvent** ppEvent + ) + { + // NOTE: + // GetEvent can block indefinitely, so we don't hold the lock. + // This requires some juggling with the event queue pointer. - return hr; -} + wil::com_ptr_nothrow<IMFMediaEventQueue> spQueue; -IFACEMETHODIMP -SimpleMediaStream::QueueEvent( - MediaEventType eventType, - REFGUID guidExtendedType, - HRESULT hrStatus, - _In_opt_ PROPVARIANT const *pvValue - ) -{ - HRESULT hr = S_OK; - auto lock = _critSec.Lock(); + { + winrt::slim_lock_guard lock(m_Lock); - RETURN_IF_FAILED (_CheckShutdownRequiresLock()); - RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue)); + RETURN_IF_FAILED(_CheckShutdownRequiresLock()); + spQueue = m_spEventQueue; + } - return hr; -} + // Now get the event. + RETURN_IF_FAILED(spQueue->GetEvent(dwFlags, ppEvent)); -// IMFMediaStream -IFACEMETHODIMP -SimpleMediaStream::GetMediaSource( - _COM_Outptr_ IMFMediaSource **ppMediaSource - ) -{ - HRESULT hr = S_OK; - auto lock = _critSec.Lock(); + return S_OK; + } - if (ppMediaSource == nullptr) + IFACEMETHODIMP SimpleMediaStream::QueueEvent( + _In_ MediaEventType eventType, + _In_ REFGUID guidExtendedType, + _In_ HRESULT hrStatus, + _In_opt_ PROPVARIANT const* pvValue + ) { - return E_POINTER; + winrt::slim_lock_guard lock(m_Lock); + + RETURN_IF_FAILED(_CheckShutdownRequiresLock()); + RETURN_IF_FAILED(m_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue)); + + return S_OK; } - *ppMediaSource = nullptr; - RETURN_IF_FAILED (_CheckShutdownRequiresLock()); + // IMFMediaStream + IFACEMETHODIMP SimpleMediaStream::GetMediaSource( + _COM_Outptr_ IMFMediaSource** ppMediaSource + ) + { + winrt::slim_lock_guard lock(m_Lock); - *ppMediaSource = _parent.Get(); - (*ppMediaSource)->AddRef(); + RETURN_HR_IF_NULL(E_POINTER, ppMediaSource); + *ppMediaSource = nullptr; - return hr; -} + RETURN_IF_FAILED(_CheckShutdownRequiresLock()); + RETURN_IF_FAILED(m_parent.copy_to(ppMediaSource)); -IFACEMETHODIMP -SimpleMediaStream::GetStreamDescriptor( - _COM_Outptr_ IMFStreamDescriptor **ppStreamDescriptor - ) -{ - HRESULT hr = S_OK; - auto lock = _critSec.Lock(); + return S_OK; + } - if (ppStreamDescriptor == nullptr) + IFACEMETHODIMP SimpleMediaStream::GetStreamDescriptor( + _COM_Outptr_ IMFStreamDescriptor** ppStreamDescriptor + ) { - return E_POINTER; - } - *ppStreamDescriptor = nullptr; + winrt::slim_lock_guard lock(m_Lock); - RETURN_IF_FAILED (_CheckShutdownRequiresLock()); + RETURN_HR_IF_NULL(E_POINTER, ppStreamDescriptor); + *ppStreamDescriptor = nullptr; - if (_spStreamDesc != nullptr) - { - *ppStreamDescriptor = _spStreamDesc.Get(); - (*ppStreamDescriptor)->AddRef(); + RETURN_IF_FAILED(_CheckShutdownRequiresLock()); + + if (m_spStreamDesc != nullptr) + { + RETURN_IF_FAILED(m_spStreamDesc.copy_to(ppStreamDescriptor)); + } + else + { + return E_UNEXPECTED; + } + + return S_OK; } - else + + IFACEMETHODIMP SimpleMediaStream::RequestSample( + _In_ IUnknown* pToken + ) { - return E_UNEXPECTED; - } + winrt::slim_lock_guard lock(m_Lock); + wil::com_ptr_nothrow<IMFSample> sample; + wil::com_ptr_nothrow<IMFMediaBuffer> outputBuffer; + LONG pitch = 0; + BYTE* bufferStart = nullptr; // not used + DWORD bufferLength = 0; + BYTE* pbuf = nullptr; + wil::com_ptr_nothrow<IMF2DBuffer2> buffer2D; - return hr; -} + RETURN_IF_FAILED(_CheckShutdownRequiresLock()); -/* - Writes to a buffer representing a 2D image. - Writes a different constant to each line based on row number and current time. + if (m_streamState != MF_STREAM_STATE_RUNNING) + { + RETURN_HR_MSG(MF_E_INVALIDREQUEST, "Stream is not in running state, state:%d", m_streamState); + } - Assumes top down image, no negative stride and pBuf points to the begnning of the buffer of length len. + RETURN_IF_FAILED(m_spSampleAllocator->AllocateSample(&sample)); + RETURN_IF_FAILED(sample->GetBufferByIndex(0, &outputBuffer)); + RETURN_IF_FAILED(outputBuffer->QueryInterface(IID_PPV_ARGS(&buffer2D))); + RETURN_IF_FAILED(buffer2D->Lock2DSize(MF2DBuffer_LockFlags_Write, + &pbuf, + &pitch, + &bufferStart, + &bufferLength)); + - Param: - pBuf - pointer to beginning of buffer - pitch - line length in bytes - len - length of buffer in bytes -*/ -HRESULT -WriteSampleData( - _Inout_updates_bytes_(len) BYTE *pBuf, - _In_ LONG pitch, - _In_ DWORD len - ) -{ - if (pBuf == nullptr) - { - return E_INVALIDARG; - } + RETURN_IF_FAILED(m_spFrameGenerator->CreateFrame(pbuf, bufferLength, pitch, m_rgbMask)); + RETURN_IF_FAILED(buffer2D->Unlock2D()); - const int NUM_ROWS = len / abs(pitch); + RETURN_IF_FAILED(sample->SetSampleTime(MFGetSystemTime())); + RETURN_IF_FAILED(sample->SetSampleDuration(333333)); + if (pToken != nullptr) + { + RETURN_IF_FAILED(sample->SetUnknown(MFSampleExtension_Token, pToken)); + } + RETURN_IF_FAILED(m_spEventQueue->QueueEventParamUnk(MEMediaSample, + GUID_NULL, + S_OK, + sample.get())); - LONGLONG curSysTimeInS = MFGetSystemTime() / (MFTIME)10000000; - int offset = curSysTimeInS % NUM_ROWS; + return S_OK; + } - for (int r = 0; r < NUM_ROWS; r++) + ////////////////////////////////////////////////////////////////////////////////////////// + // IMFMediaStream2 + IFACEMETHODIMP SimpleMediaStream::SetStreamState(MF_STREAM_STATE state) { - int grayColor = r + offset; - memset(pBuf + (pitch * r), (BYTE)(grayColor % NUM_ROWS), pitch); - } + winrt::slim_lock_guard lock(m_Lock); + RETURN_IF_FAILED(_CheckShutdownRequiresLock()); - return S_OK; -} + switch (state) + { + case MF_STREAM_STATE_PAUSED: + // because not supported + break; -IFACEMETHODIMP -SimpleMediaStream::RequestSample( - _In_ IUnknown *pToken - ) -{ - HRESULT hr = S_OK; - auto lock = _critSec.Lock(); - ComPtr<IMFSample> sample; - ComPtr<IMFMediaBuffer> outputBuffer; - LONG pitch = IMAGE_ROW_SIZE_BYTES; - BYTE *bufferStart = nullptr; // not used - DWORD bufferLength = 0; - BYTE *pbuf = nullptr; - ComPtr<IMF2DBuffer2> buffer2D; + case MF_STREAM_STATE_RUNNING: + m_streamState = state; + break; - RETURN_IF_FAILED (_CheckShutdownRequiresLock()); - RETURN_IF_FAILED (MFCreateSample(&sample)); - RETURN_IF_FAILED (MFCreate2DMediaBuffer(NUM_IMAGE_COLS, - NUM_IMAGE_ROWS, - D3DFMT_X8R8G8B8, - false, - &outputBuffer)); - RETURN_IF_FAILED (outputBuffer.As(&buffer2D)); - RETURN_IF_FAILED (buffer2D->Lock2DSize(MF2DBuffer_LockFlags_Write, - &pbuf, - &pitch, - &bufferStart, - &bufferLength)); - RETURN_IF_FAILED (WriteSampleData(pbuf, pitch, bufferLength)); - RETURN_IF_FAILED (buffer2D->Unlock2D()); - RETURN_IF_FAILED (sample->AddBuffer(outputBuffer.Get())); - RETURN_IF_FAILED (sample->SetSampleTime(MFGetSystemTime())); - RETURN_IF_FAILED (sample->SetSampleDuration(333333)); - if (pToken != nullptr) - { - RETURN_IF_FAILED (sample->SetUnknown(MFSampleExtension_Token, pToken)); - } - RETURN_IF_FAILED (_spEventQueue->QueueEventParamUnk(MEMediaSample, - GUID_NULL, - S_OK, - sample.Get())); + case MF_STREAM_STATE_STOPPED: + m_streamState = state; - return hr; -} + break; -////////////////////////////////////////////////////////////////////////////////////////// -// IMFMediaStream2 -IFACEMETHODIMP -SimpleMediaStream::SetStreamState( - MF_STREAM_STATE state - ) -{ - HRESULT hr = S_OK; - auto lock = _critSec.Lock(); - bool runningState = false; + default: + return MF_E_INVALID_STATE_TRANSITION; + break; + } - RETURN_IF_FAILED (_CheckShutdownRequiresLock()); + return S_OK; + } - switch (state) + IFACEMETHODIMP SimpleMediaStream::GetStreamState( + _Out_ MF_STREAM_STATE* pState + ) { - case MF_STREAM_STATE_PAUSED: - goto done; // because not supported - case MF_STREAM_STATE_RUNNING: - runningState = true; - break; - case MF_STREAM_STATE_STOPPED: - runningState = false; - break; - default: - hr = MF_E_INVALID_STATE_TRANSITION; - break; - } + winrt::slim_lock_guard lock(m_Lock); + RETURN_IF_FAILED(_CheckShutdownRequiresLock()); - _isSelected = runningState; + *pState = m_streamState; -done: - return hr; -} + return S_OK; + } -IFACEMETHODIMP -SimpleMediaStream::GetStreamState( - _Out_ MF_STREAM_STATE *pState - ) -{ - HRESULT hr = S_OK; - auto lock = _critSec.Lock(); - BOOLEAN pauseState = false; + ////////////////////////////////////////////////////////////////////////////////////////// + // Public methods + HRESULT SimpleMediaStream::Start() + { + winrt::slim_lock_guard lock(m_Lock); - RETURN_IF_FAILED (_CheckShutdownRequiresLock()); + // Create the allocator if one doesn't exist + if (m_allocatorUsage == MFSampleAllocatorUsage_UsesProvidedAllocator) + { + RETURN_HR_IF_NULL_MSG(E_POINTER, m_spSampleAllocator, "Sample allocator is not set"); + } + else + { + RETURN_IF_FAILED(MFCreateVideoSampleAllocatorEx(IID_PPV_ARGS(&m_spSampleAllocator))); + } - if (SUCCEEDED(hr)) - { - *pState = (_isSelected ? MF_STREAM_STATE_RUNNING : MF_STREAM_STATE_STOPPED); - } + wil::com_ptr_nothrow<IMFMediaTypeHandler> spMTHandler; + RETURN_IF_FAILED(m_spStreamDesc->GetMediaTypeHandler(&spMTHandler)); - return hr; -} + wil::com_ptr_nothrow<IMFMediaType> spMediaType; + UINT32 width, height; + GUID subType; + RETURN_IF_FAILED(spMTHandler->GetCurrentMediaType(&spMediaType)); + RETURN_IF_FAILED(spMediaType->GetGUID(MF_MT_SUBTYPE, &subType)); + MFGetAttributeSize(spMediaType.get(), MF_MT_FRAME_SIZE, &width, &height); -HRESULT -SimpleMediaStream::Shutdown( - ) -{ - HRESULT hr = S_OK; - auto lock = _critSec.Lock(); + DEBUG_MSG(L"Initialize sample allocator for mediatype: %s, %dx%d ", winrt::to_hstring(subType).data(), width, height); + RETURN_IF_FAILED(m_spSampleAllocator->InitializeSampleAllocator(10, spMediaType.get())); + if (m_spFrameGenerator == nullptr) + { + m_spFrameGenerator = wil::make_unique_nothrow<SimpleFrameGenerator>(); + RETURN_IF_NULL_ALLOC_MSG(m_spFrameGenerator, "Fail to create SimpleFrameGenerator"); + } + RETURN_IF_FAILED(m_spFrameGenerator->Initialize(spMediaType.get())); + + // Post MEStreamStarted event to signal stream has started + RETURN_IF_FAILED(m_spEventQueue->QueueEventParamVar(MEStreamStarted, GUID_NULL, S_OK, nullptr)); - _isShutdown = true; - _parent.Reset(); + return S_OK; + } - if (_spEventQueue != nullptr) + HRESULT SimpleMediaStream::Stop() { - hr = _spEventQueue->Shutdown(); - _spEventQueue.Reset(); + winrt::slim_lock_guard lock(m_Lock); + + // Post MEStreamStopped event to signal stream has stopped + RETURN_IF_FAILED(m_spEventQueue->QueueEventParamVar(MEStreamStopped, GUID_NULL, S_OK, nullptr)); + return S_OK; } - _spAttributes.Reset(); - _spMediaType.Reset(); - _spStreamDesc.Reset(); + HRESULT SimpleMediaStream::Shutdown() + { + winrt::slim_lock_guard lock(m_Lock); - _isSelected = false; + m_bIsShutdown = true; + m_parent.reset(); - return hr; -} + if (m_spEventQueue != nullptr) + { + m_spEventQueue->Shutdown(); + m_spEventQueue.reset(); + } -HRESULT -SimpleMediaStream::_CheckShutdownRequiresLock( - ) -{ - if (_isShutdown) - { - return MF_E_SHUTDOWN; + m_spAttributes.reset(); + m_spStreamDesc.reset(); + + m_streamState = MF_STREAM_STATE_STOPPED; + + return S_OK; } - if (_spEventQueue == nullptr) + HRESULT SimpleMediaStream::SetSampleAllocator(IMFVideoSampleAllocator* pAllocator) { - return E_UNEXPECTED; + winrt::slim_lock_guard lock(m_Lock); + + if (m_streamState == MF_STREAM_STATE_RUNNING) + { + RETURN_HR_MSG(MF_E_INVALIDREQUEST, "Cannot update allocator when the stream is streaming"); + } + m_spSampleAllocator.reset(); + m_spSampleAllocator = pAllocator; + return S_OK; } - return S_OK; -} -HRESULT -SimpleMediaStream::_SetStreamAttributes( - _In_ IMFAttributes *pAttributeStore - ) -{ - HRESULT hr = S_OK; + + ////////////////////////////////////////////////////////////////////////////////////////// + // Private methods - if (nullptr == pAttributeStore) + HRESULT SimpleMediaStream::_CheckShutdownRequiresLock() { - return E_INVALIDARG; + if (m_bIsShutdown) + { + return MF_E_SHUTDOWN; + } + + if (m_spEventQueue == nullptr) + { + return E_UNEXPECTED; + + } + return S_OK; } - RETURN_IF_FAILED (pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE)); - RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, STREAMINDEX)); - RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1)); - RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, _MFFrameSourceTypes::MFFrameSourceTypes_Color)); + HRESULT SimpleMediaStream::_SetStreamAttributes( + _In_ IMFAttributes* pAttributeStore + ) + { + RETURN_HR_IF_NULL(E_INVALIDARG, pAttributeStore); - return hr; -} + RETURN_IF_FAILED(pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE)); + RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, m_dwStreamId)); + RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1)); + RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, MFFrameSourceTypes::MFFrameSourceTypes_Color)); -HRESULT -SimpleMediaStream::_SetStreamDescriptorAttributes( - _In_ IMFAttributes *pAttributeStore - ) -{ - HRESULT hr = S_OK; + return S_OK; + } - if (nullptr == pAttributeStore) + HRESULT SimpleMediaStream::_SetStreamDescriptorAttributes( + _In_ IMFAttributes* pAttributeStore + ) { - return E_INVALIDARG; + RETURN_HR_IF_NULL(E_INVALIDARG, pAttributeStore); + + RETURN_IF_FAILED(pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE)); + RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, m_dwStreamId)); + RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1)); + RETURN_IF_FAILED(pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, MFFrameSourceTypes::MFFrameSourceTypes_Color)); + + return S_OK; } - RETURN_IF_FAILED (pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE)); - RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, STREAMINDEX)); - RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1)); - RETURN_IF_FAILED (pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, _MFFrameSourceTypes::MFFrameSourceTypes_Color)); - return hr; } - |
