diff options
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; } - |
