summaryrefslogtreecommitdiff
path: root/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp')
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp610
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;
}
-