summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeihsun Yeh <[email protected]>2018-08-01 17:14:16 -0700
committerPeihsun Yeh <[email protected]>2018-08-01 17:14:16 -0700
commit58a4f43a0c75285c30ce4806d011553ebc3f563d (patch)
treeb05a73141f86e504f44a01ef95cb9df66564d9ea
parentedcb51e041d612e3fb8a0c0a9135d989c881ccc9 (diff)
fix up of media source
-rw-r--r--general/SimpleMediaSource/MediaSource/MediaSource.vcxproj8
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp586
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaSource.h87
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp348
-rw-r--r--general/SimpleMediaSource/MediaSource/SimpleMediaStream.h14
-rw-r--r--general/SimpleMediaSource/MediaSource/stdafx.h57
6 files changed, 552 insertions, 548 deletions
diff --git a/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj
index b1f8a7f4..da95eecd 100644
--- a/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj
+++ b/general/SimpleMediaSource/MediaSource/MediaSource.vcxproj
@@ -78,7 +78,7 @@
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
- <AdditionalDependencies>mfplat.lib;RuntimeObject.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>mfplat.lib;RuntimeObject.lib;Mfsensorgroup.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -89,7 +89,7 @@
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
- <AdditionalDependencies>mfplat.lib;RuntimeObject.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>mfplat.lib;RuntimeObject.lib;Mfsensorgroup.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -104,7 +104,7 @@
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>mfplat.lib;RuntimeObject.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>mfplat.lib;RuntimeObject.lib;Mfsensorgroup.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -119,7 +119,7 @@
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalDependencies>mfplat.lib;RuntimeObject.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalDependencies>mfplat.lib;RuntimeObject.lib;Mfsensorgroup.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp
index 34b6f2e2..1729fbcf 100644
--- a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.cpp
@@ -1,72 +1,62 @@
-#include "SimpleMediaSource.h"
-#include "SimpleMediaStream.h"
+#include "stdafx.h"
///////////////////////////////////////////////////////////////////////////////
-HRESULT SimpleMediaSource::RuntimeClassInitialize()
+HRESULT
+SimpleMediaSource::RuntimeClassInitialize(
+ )
{
HRESULT hr = S_OK;
- if (SUCCEEDED(hr))
- {
- hr = MFCreateAttributes(&_spAttributes, 10);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = MFCreateEventQueue(&_spEventQueue);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = MakeAndInitialize<SimpleMediaStream>(&_stream, this);
- }
-
- if (SUCCEEDED(hr))
+ RETURN_IF_FAILED (MFCreateAttributes(&_spAttributes, 10));
+ RETURN_IF_FAILED (MFCreateEventQueue(&_spEventQueue));
+ RETURN_IF_FAILED (MakeAndInitialize<SimpleMediaStream>(&_stream, this));
{
ComPtr<IMFStreamDescriptor> streamDescriptor(_stream.Get()->_spStreamDesc.Get());
- hr = MFCreatePresentationDescriptor(NUM_STREAMS, streamDescriptor.GetAddressOf(), &_spPresentationDescriptor);
+ RETURN_IF_FAILED (MFCreatePresentationDescriptor(NUM_STREAMS, streamDescriptor.GetAddressOf(), &_spPresentationDescriptor));
}
- if (SUCCEEDED(hr))
- {
- _wasStreamPreviouslySelected = false;
- _sourceState = SourceState::Stopped;
- }
+ _wasStreamPreviouslySelected = false;
+ _sourceState = SourceState::Stopped;
return hr;
}
// IMFMediaEventGenerator methods.
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::BeginGetEvent(IMFAsyncCallback *pCallback, IUnknown *punkState)
+IFACEMETHODIMP
+SimpleMediaSource::BeginGetEvent(
+ _In_ IMFAsyncCallback *pCallback,
+ _In_ IUnknown *punkState
+ )
{
+ HRESULT hr = S_OK;
auto lock = _critSec.Lock();
- HRESULT hr = _CheckShutdownRequiresLock();
- if (SUCCEEDED(hr))
- {
- hr = _spEventQueue->BeginGetEvent(pCallback, punkState);
- }
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->BeginGetEvent(pCallback, punkState));
return hr;
}
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::EndGetEvent(IMFAsyncResult *pResult, IMFMediaEvent **ppEvent)
+IFACEMETHODIMP
+SimpleMediaSource::EndGetEvent(
+ _In_ IMFAsyncResult *pResult,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
{
+ HRESULT hr = S_OK;
auto lock = _critSec.Lock();
- HRESULT hr = _CheckShutdownRequiresLock();
- if (SUCCEEDED(hr))
- {
- hr = _spEventQueue->EndGetEvent(pResult, ppEvent);
- }
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->EndGetEvent(pResult, ppEvent));
return hr;
}
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::GetEvent(DWORD dwFlags, IMFMediaEvent **ppEvent)
+IFACEMETHODIMP
+SimpleMediaSource::GetEvent(
+ DWORD dwFlags,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
{
// NOTE:
// GetEvent can block indefinitely, so we don't hold the lock.
@@ -79,369 +69,398 @@ IFACEMETHODIMP SimpleMediaSource::GetEvent(DWORD dwFlags, IMFMediaEvent **ppEven
{
auto lock = _critSec.Lock();
- hr = _CheckShutdownRequiresLock();
- if (SUCCEEDED(hr))
- {
- spQueue = _spEventQueue;
- }
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ spQueue = _spEventQueue;
}
// Now get the event.
- if (SUCCEEDED(hr))
- {
- hr = spQueue->GetEvent(dwFlags, ppEvent);
- }
+ RETURN_IF_FAILED (_spEventQueue->GetEvent(dwFlags, ppEvent));
return hr;
}
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::QueueEvent(
+IFACEMETHODIMP
+SimpleMediaSource::QueueEvent(
MediaEventType eventType,
REFGUID guidExtendedType,
HRESULT hrStatus,
- _In_opt_ PROPVARIANT const *pvValue)
+ _In_opt_ PROPVARIANT const *pvValue
+ )
{
+ HRESULT hr = S_OK;
auto lock = _critSec.Lock();
- HRESULT hr = _CheckShutdownRequiresLock();
- if (SUCCEEDED(hr))
- {
- hr = _spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue);
- }
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
return hr;
}
// IMFMediaSource methods
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::CreatePresentationDescriptor(
- IMFPresentationDescriptor **ppPresentationDescriptor)
+IFACEMETHODIMP
+SimpleMediaSource::CreatePresentationDescriptor(
+ _COM_Outptr_ IMFPresentationDescriptor **ppPresentationDescriptor
+ )
{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
if (ppPresentationDescriptor == nullptr)
{
return E_POINTER;
}
-
*ppPresentationDescriptor = nullptr;
- auto lock = _critSec.Lock();
-
- HRESULT hr = _CheckShutdownRequiresLock();
- if (SUCCEEDED(hr))
- {
- hr = _spPresentationDescriptor->Clone(ppPresentationDescriptor);
- }
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spPresentationDescriptor->Clone(ppPresentationDescriptor));
return hr;
}
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::GetCharacteristics(DWORD *pdwCharacteristics)
+IFACEMETHODIMP
+SimpleMediaSource::GetCharacteristics(
+ _Out_ DWORD *pdwCharacteristics
+ )
{
- *pdwCharacteristics = 0;
-
+ HRESULT hr = S_OK;
auto lock = _critSec.Lock();
- HRESULT hr = _CheckShutdownRequiresLock();
- if (SUCCEEDED(hr))
+ if (nullptr == pdwCharacteristics)
{
- *pdwCharacteristics = MFMEDIASOURCE_IS_LIVE;
+ return E_POINTER;
}
+ *pdwCharacteristics = 0;
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ *pdwCharacteristics = MFMEDIASOURCE_IS_LIVE;
return hr;
}
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::Pause()
+IFACEMETHODIMP
+SimpleMediaSource::Pause(
+ )
{
- // Pause() not required/needed for live sources
- HRESULT hr = MF_E_INVALID_STATE_TRANSITION;
-
- return hr;
+ // Pause() not required/needed
+ return MF_E_INVALID_STATE_TRANSITION;
}
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::Shutdown()
+
+IFACEMETHODIMP
+SimpleMediaSource::Shutdown(
+ )
{
HRESULT hr = S_OK;
- {
- auto lock = _critSec.Lock();
+ auto lock = _critSec.Lock();
- _sourceState = SourceState::Shutdown;
+ _sourceState = SourceState::Shutdown;
- _spAttributes.Reset();
- _spPresentationDescriptor.Reset();
+ _spAttributes.Reset();
+ _spPresentationDescriptor.Reset();
- if (_spEventQueue != nullptr)
- {
- _spEventQueue->Shutdown();
- _spEventQueue.Reset();
- }
+ if (_spEventQueue != nullptr)
+ {
+ _spEventQueue->Shutdown();
+ _spEventQueue.Reset();
+ }
- if (_stream != nullptr)
- {
- _stream.Get()->Shutdown();
- _stream.Reset();
- }
+ if (_stream != nullptr)
+ {
+ _stream.Get()->Shutdown();
+ _stream.Reset();
}
+
return hr;
}
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::Start(
+IFACEMETHODIMP
+SimpleMediaSource::Start(
_In_ IMFPresentationDescriptor *pPresentationDescriptor,
_In_opt_ const GUID *pguidTimeFormat,
- _In_ const PROPVARIANT *pvarStartPos)
+ _In_ const PROPVARIANT *pvarStartPos
+ )
{
HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ DWORD count = 0;
+ PROPVARIANT startTime;
+ BOOL selected = false;
+ ComPtr<IMFStreamDescriptor> streamDesc;
+ DWORD streamIndex = 0;
if (pPresentationDescriptor == nullptr || pvarStartPos == nullptr)
{
- hr = E_INVALIDARG;
+ return E_INVALIDARG;
}
else if (pguidTimeFormat != nullptr && *pguidTimeFormat != GUID_NULL)
{
- hr = MF_E_UNSUPPORTED_TIME_FORMAT;
+ return MF_E_UNSUPPORTED_TIME_FORMAT;
}
- do
- {
- BREAK_ON_FAIL(hr);
-
- auto lock = _critSec.Lock();
- BREAK_ON_FAIL(hr = _CheckShutdownRequiresLock());
-
- if (_sourceState != SourceState::Stopped)
- {
- hr = MF_E_INVALID_STATE_TRANSITION;
- break;
- }
-
- _sourceState = SourceState::Started;
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- // This checks the passed in PresentationDescriptor matches the member of streams we
- // have defined internally and that at least one stream is selected
- BREAK_ON_FAIL(hr = _ValidatePresentationDescriptor(pPresentationDescriptor));
-
- DWORD count = 0;
- BREAK_ON_FAIL(hr = pPresentationDescriptor->GetStreamDescriptorCount(&count));
-
- PROPVARIANT startTime;
- BREAK_ON_FAIL(hr = InitPropVariantFromInt64(MFGetSystemTime(), &startTime));
+ if (_sourceState != SourceState::Stopped)
+ {
+ return MF_E_INVALID_STATE_TRANSITION;
+ }
- // Send event that the source started. Include error code in case it failed.
- BREAK_ON_FAIL(hr = _spEventQueue->QueueEventParamVar(MESourceStarted, GUID_NULL, hr, &startTime));
+ _sourceState = SourceState::Started;
- // Open and un-pause the selected stream(s)
- BOOL selected = false;
- ComPtr<IMFStreamDescriptor> spStreamDescriptor;
- BREAK_ON_FAIL(hr = pPresentationDescriptor->GetStreamDescriptorByIndex(0, &selected, &spStreamDescriptor));
+ // This checks the passed in PresentationDescriptor matches the member of streams we
+ // have defined internally and that at least one stream is selected
+ RETURN_IF_FAILED (_ValidatePresentationDescriptor(pPresentationDescriptor));
+ RETURN_IF_FAILED (pPresentationDescriptor->GetStreamDescriptorCount(&count));
+ RETURN_IF_FAILED (InitPropVariantFromInt64(MFGetSystemTime(), &startTime));
- DWORD streamIndex = 0;
- BREAK_ON_FAIL(hr = spStreamDescriptor->GetStreamIdentifier(&streamIndex));
+ // Send event that the source started. Include error code in case it failed.
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(MESourceStarted,
+ GUID_NULL,
+ hr,
+ &startTime));
- if (streamIndex >= NUM_STREAMS)
- {
- hr = MF_E_INVALIDSTREAMNUMBER;
- break;
- }
+ // We're hardcoding this to the first descriptor
+ // since this sample is a single stream sample. For
+ // multiple streams, we need to walk the list of streams
+ // and for each selected stream, send the MEUpdatedStream
+ // or MENewStream event along with the MEStreamStarted
+ // event.
+ RETURN_IF_FAILED (pPresentationDescriptor->GetStreamDescriptorByIndex(0,
+ &selected,
+ &streamDesc));
+ RETURN_IF_FAILED (streamDesc->GetStreamIdentifier(&streamIndex));
+ if (streamIndex >= NUM_STREAMS)
+ {
+ return MF_E_INVALIDSTREAMNUMBER;
+ }
- if (selected)
- {
- // Update our internal PresentationDescriptor
- BREAK_ON_FAIL(hr = _spPresentationDescriptor->SelectStream(streamIndex));
- BREAK_ON_FAIL(hr = _stream.Get()->SetStreamState(MF_STREAM_STATE_RUNNING));
+ if (selected)
+ {
+ ComPtr<IUnknown> spunkStream;
+ MediaEventType met = (_wasStreamPreviouslySelected ? MEUpdatedStream : MENewStream);
- ComPtr<IUnknown> spunkStream;
- BREAK_ON_FAIL(hr = _stream.As(&spunkStream));
+ // Update our internal PresentationDescriptor
+ RETURN_IF_FAILED (_spPresentationDescriptor->SelectStream(streamIndex));
+ RETURN_IF_FAILED (_stream.Get()->SetStreamState(MF_STREAM_STATE_RUNNING));
+ RETURN_IF_FAILED (_stream.As(&spunkStream));
- BREAK_ON_FAIL(hr = _spEventQueue->QueueEventParamUnk(_wasStreamPreviouslySelected ? MEUpdatedStream : MENewStream,
- GUID_NULL, S_OK, spunkStream.Get()));
- BREAK_ON_FAIL(hr = _stream.Get()->QueueEvent(MEStreamStarted, GUID_NULL, S_OK, &startTime));
- }
- _wasStreamPreviouslySelected = selected;
+ // Send the MEUpdatedStream/MENewStream to our source event
+ // queue.
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamUnk(met,
+ GUID_NULL,
+ S_OK,
+ spunkStream.Get()));
- } while (false);
+ // But for our stream started (MEStreamStarted), we post to our
+ // stream event queue.
+ RETURN_IF_FAILED (_stream.Get()->QueueEvent(MEStreamStarted,
+ GUID_NULL,
+ S_OK,
+ &startTime));
+ }
+ _wasStreamPreviouslySelected = selected;
return hr;
}
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::Stop()
+IFACEMETHODIMP
+SimpleMediaSource::Stop(
+ )
{
HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ PROPVARIANT stopTime;
+ DWORD count = 0;
+ MF_STREAM_STATE state;
- do
+ if (_sourceState != SourceState::Started)
{
- auto lock = _critSec.Lock();
-
- if (_sourceState != SourceState::Started)
- {
- BREAK_ON_FAIL(hr = MF_E_INVALID_STATE_TRANSITION);
- }
-
- BREAK_ON_FAIL(hr = _CheckShutdownRequiresLock());
-
- PROPVARIANT stopTime;
- BREAK_ON_FAIL(hr = InitPropVariantFromInt64(MFGetSystemTime(), &stopTime));
-
- DWORD count = 0;
- BREAK_ON_FAIL(hr = _spPresentationDescriptor->GetStreamDescriptorCount(&count));
- // Deselect the streams and send the stream stopped events.
- MF_STREAM_STATE state;
- hr = _stream.Get()->GetStreamState(&state);
- if (FAILED(hr))
- {
- continue;
- }
- _wasStreamPreviouslySelected = (state == MF_STREAM_STATE_RUNNING);
- hr = _stream.Get()->SetStreamState(MF_STREAM_STATE_STOPPED);
- if (FAILED(hr))
- {
- continue;
- }
- _spPresentationDescriptor->DeselectStream(0);
- hr = _stream.Get()->QueueEvent(MEStreamStopped, GUID_NULL, hr, &stopTime);
- if (FAILED(hr))
- {
- continue;
- }
+ return MF_E_INVALID_STATE_TRANSITION;
+ }
- BREAK_ON_FAIL(hr = _spEventQueue->QueueEventParamVar(MESourceStopped, GUID_NULL, hr, &stopTime));
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (InitPropVariantFromInt64(MFGetSystemTime(), &stopTime));
+ RETURN_IF_FAILED (_spPresentationDescriptor->GetStreamDescriptorCount(&count));
- } while (false);
+ // Deselect the streams and send the stream stopped events.
+ RETURN_IF_FAILED (_stream.Get()->GetStreamState(&state));
+ _wasStreamPreviouslySelected = (state == MF_STREAM_STATE_RUNNING);
+ RETURN_IF_FAILED (_stream.Get()->SetStreamState(MF_STREAM_STATE_STOPPED));
+ _spPresentationDescriptor->DeselectStream(0);
+ RETURN_IF_FAILED (_stream.Get()->QueueEvent(MEStreamStopped, GUID_NULL, hr, &stopTime));
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(MESourceStopped, GUID_NULL, hr, &stopTime));
return hr;
}
// IMFMediaSourceEx
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::GetSourceAttributes(_Outptr_ IMFAttributes **ppAttributes)
+IFACEMETHODIMP
+SimpleMediaSource::GetSourceAttributes(
+ _COM_Outptr_ IMFAttributes** sourceAttributes
+ )
{
- if (ppAttributes == nullptr)
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ if (nullptr == sourceAttributes)
{
return E_POINTER;
}
- auto lock = _critSec.Lock();
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- HRESULT hr = _CheckShutdownRequiresLock();
- if (SUCCEEDED(hr))
+ *sourceAttributes = nullptr;
+ if (_spAttributes.Get() == nullptr)
{
- *ppAttributes = _spAttributes.Get();
- (*ppAttributes)->AddRef();
- }
- else
- {
- hr = E_UNEXPECTED;
+ ComPtr<IMFSensorProfileCollection> profileCollection;
+ ComPtr<IMFSensorProfile> profile;
+
+ // Create our source attribute store.
+ RETURN_IF_FAILED (MFCreateAttributes(_spAttributes.GetAddressOf(), 1));
+
+ // Create an empty profile collection...
+ RETURN_IF_FAILED (MFCreateSensorProfileCollection(&profileCollection));
+
+ // In this example since we have just one stream, we only have one
+ // pin to add: Pin0.
+
+ // Legacy profile is mandatory. This is to ensure non-profile
+ // aware applications can still function, but with degraded
+ // feature sets.
+ RETURN_IF_FAILED (MFCreateSensorProfile(KSCAMERAPROFILE_Legacy, 0, nullptr,
+ profile.ReleaseAndGetAddressOf()));
+ RETURN_IF_FAILED (profile->AddProfileFilter(0, L"((RES==;FRT<=30,1;SUT==))"));
+ RETURN_IF_FAILED (profileCollection->AddProfile(profile.Get()));
+
+ // High Frame Rate profile will only allow >=60fps.
+ RETURN_IF_FAILED (MFCreateSensorProfile(KSCAMERAPROFILE_HighFrameRate, 0, nullptr,
+ profile.ReleaseAndGetAddressOf()));
+ RETURN_IF_FAILED (profile->AddProfileFilter(0, L"((RES==;FRT>=60,1;SUT==))"));
+ RETURN_IF_FAILED (profileCollection->AddProfile(profile.Get()));
+
+
+ // Se the profile collection to the attribute store of the IMFTransform.
+ RETURN_IF_FAILED (_spAttributes->SetUnknown(MF_DEVICEMFT_SENSORPROFILE_COLLECTION,
+ profileCollection.Get()));
}
- return hr;
+ return _spAttributes.CopyTo(sourceAttributes);
}
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::GetStreamAttributes(DWORD dwStreamIdentifier, _Outptr_ IMFAttributes **ppAttributes)
+
+IFACEMETHODIMP
+SimpleMediaSource::GetStreamAttributes(
+ DWORD dwStreamIdentifier,
+ _COM_Outptr_ IMFAttributes **ppAttributes
+ )
{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
if (ppAttributes == nullptr)
{
return E_POINTER;
}
-
- auto lock = _critSec.Lock();
-
*ppAttributes = nullptr;
- HRESULT hr = _CheckShutdownRequiresLock();
- if (SUCCEEDED(hr))
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ if (dwStreamIdentifier >= NUM_STREAMS)
{
- if (dwStreamIdentifier >= NUM_STREAMS)
- {
- hr = MF_E_INVALIDSTREAMNUMBER;
- }
- else
- {
- *ppAttributes = _stream.Get()->_spAttributes.Get();
- (*ppAttributes)->AddRef();
- }
+ return MF_E_INVALIDSTREAMNUMBER;
}
else
{
- hr = E_UNEXPECTED;
+ *ppAttributes = _stream.Get()->_spAttributes.Get();
+ (*ppAttributes)->AddRef();
}
return hr;
}
-///////////////////////////////////////////////////////////////////////////////
-IFACEMETHODIMP SimpleMediaSource::SetD3DManager(_In_opt_ IUnknown* /*pManager*/)
+IFACEMETHODIMP
+SimpleMediaSource::SetD3DManager(
+ _In_opt_ IUnknown* /*pManager*/
+ )
{
- // No need to implement this method in our case.
- HRESULT hr = E_NOTIMPL;
- return hr;
+ // Return code is ignored by the frame work, this is a
+ // best effort attempt to inform the media source of the
+ // DXGI manager to use if DX surface support is available.
+
+ return E_NOTIMPL;
}
// IMFGetService methods
-///////////////////////////////////////////////////////////////////////////////
_Use_decl_annotations_
-IFACEMETHODIMP SimpleMediaSource::GetService(REFGUID guidService, REFIID riid, LPVOID * ppvObject)
+IFACEMETHODIMP
+SimpleMediaSource::GetService(
+ _In_ REFGUID guidService,
+ _In_ REFIID riid,
+ _Out_ LPVOID * ppvObject
+ )
{
- HRESULT hr = _CheckShutdownRequiresLock();
- if (SUCCEEDED(hr))
- {
- if (!ppvObject)
- {
- hr = E_INVALIDARG;
- }
- else
- {
- *ppvObject = NULL;
- }
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- hr = MF_E_UNSUPPORTED_SERVICE;
+ if (!ppvObject)
+ {
+ return E_POINTER;
}
+ *ppvObject = NULL;
- return hr;
+ // We have no supported service, just return
+ // MF_E_UNSUPPORTED_SERVICE for all calls.
+
+ return MF_E_UNSUPPORTED_SERVICE;
}
// IKsControl methods
_Use_decl_annotations_
-IFACEMETHODIMP SimpleMediaSource::KsProperty(
- PKSPROPERTY pProperty,
- ULONG ulPropertyLength,
- LPVOID pPropertyData,
- ULONG ulDataLength,
- ULONG* pBytesReturned)
+IFACEMETHODIMP
+SimpleMediaSource::KsProperty(
+ _In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned
+ )
{
- return E_NOTIMPL;
+ // ERROR_SET_NOT_FOUND is the standard error code returned
+ // by the AV Stream driver framework when a miniport
+ // driver does not register a handler for a KS operation.
+ // We want to mimic the driver behavior here if we don't
+ // support controls.
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
}
-///////////////////////////////////////////////////////////////////////////////
_Use_decl_annotations_
IFACEMETHODIMP SimpleMediaSource::KsMethod(
- PKSMETHOD pMethod,
- ULONG ulMethodLength,
- LPVOID pMethodData,
- ULONG ulDataLength,
- ULONG* pBytesReturned)
+ _In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
+ _In_ ULONG ulMethodLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pMethodData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned
+ )
{
- return E_NOTIMPL;
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
}
-///////////////////////////////////////////////////////////////////////////////
_Use_decl_annotations_
IFACEMETHODIMP SimpleMediaSource::KsEvent(
- _In_opt_ PKSEVENT pEvent,
+ _In_reads_bytes_opt_(ulEventLength) PKSEVENT pEvent,
_In_ ULONG ulEventLength,
- _Inout_opt_ LPVOID pEventData,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pEventData,
_In_ ULONG ulDataLength,
- _Out_opt_ ULONG* pBytesReturned)
+ _Out_opt_ ULONG* pBytesReturned
+ )
{
- return E_NOTIMPL;
+ return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
}
-///////////////////////////////////////////////////////////////////////////////
-HRESULT SimpleMediaSource::_CheckShutdownRequiresLock()
+/// Internal methods.
+HRESULT
+SimpleMediaSource::_CheckShutdownRequiresLock(
+ )
{
if (_sourceState == SourceState::Shutdown)
{
@@ -456,51 +475,50 @@ HRESULT SimpleMediaSource::_CheckShutdownRequiresLock()
return S_OK;
}
-///////////////////////////////////////////////////////////////////////////////
-HRESULT SimpleMediaSource::_ValidatePresentationDescriptor(IMFPresentationDescriptor *pPD)
+HRESULT
+SimpleMediaSource::_ValidatePresentationDescriptor(
+ _In_ IMFPresentationDescriptor *pPD
+ )
{
+ HRESULT hr = S_OK;
+ DWORD cStreams = 0;
+ bool anySelected = false;
+
if (pPD == nullptr)
{
return E_INVALIDARG;
}
- HRESULT hr = S_OK;
- DWORD cStreams = 0;
- bool anySelected = false;
-
// The caller's PD must have the same number of streams as ours.
- hr = pPD->GetStreamDescriptorCount(&cStreams);
-
+ RETURN_IF_FAILED (pPD->GetStreamDescriptorCount(&cStreams));
if (SUCCEEDED(hr) && (cStreams != NUM_STREAMS))
{
- hr = E_INVALIDARG;
+ return E_INVALIDARG;
}
// The caller must select at least one stream.
- for (UINT32 i = 0; SUCCEEDED(hr) && i < cStreams; ++i)
+ for (UINT32 i = 0; i < cStreams; ++i)
{
ComPtr<IMFStreamDescriptor> spSD;
BOOL fSelected = FALSE;
- hr = pPD->GetStreamDescriptorByIndex(i, &fSelected, &spSD);
+ DWORD dwId = 0;
- if (SUCCEEDED(hr))
- {
- anySelected |= !!fSelected;
+ RETURN_IF_FAILED (pPD->GetStreamDescriptorByIndex(i, &fSelected, &spSD));
- DWORD dwId = 0;
- hr = spSD->GetStreamIdentifier(&dwId);
+ anySelected |= !!fSelected;
- if (SUCCEEDED(hr) && dwId >= NUM_STREAMS)
- {
- hr = E_INVALIDARG;
- }
+ RETURN_IF_FAILED (spSD->GetStreamIdentifier(&dwId));
+ if (dwId >= NUM_STREAMS)
+ {
+ return E_INVALIDARG;
}
}
if (!anySelected)
{
- hr = E_INVALIDARG;
+ return E_INVALIDARG;
}
return hr;
-} \ No newline at end of file
+}
+
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
index 85b9227f..019926c8 100644
--- a/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaSource.h
@@ -3,43 +3,6 @@
// Represents a simple media source that only has one stream and outputs a static image
#include "stdafx.h"
-#include "SimpleMediaStream.h"
-
-#define BREAK_ON_FAIL(value) if FAILED(value) break;
-
-#if !defined(_IKsControl_)
-#define _IKsControl_
-interface DECLSPEC_UUID("28F54685-06FD-11D2-B27A-00A0C9223196") IKsControl;
-#undef INTERFACE
-#define INTERFACE IKsControl
-DECLARE_INTERFACE_(IKsControl, IUnknown)
-{
- STDMETHOD(KsProperty)(
- THIS_
- IN PKSPROPERTY Property,
- IN ULONG PropertyLength,
- IN OUT LPVOID PropertyData,
- IN ULONG DataLength,
- OUT ULONG* BytesReturned
- ) PURE;
- STDMETHOD(KsMethod)(
- THIS_
- IN PKSMETHOD Method,
- IN ULONG MethodLength,
- IN OUT LPVOID MethodData,
- IN ULONG DataLength,
- OUT ULONG* BytesReturned
- ) PURE;
- STDMETHOD(KsEvent)(
- THIS_
- IN PKSEVENT Event OPTIONAL,
- IN ULONG EventLength,
- IN OUT LPVOID EventData,
- IN ULONG DataLength,
- OUT ULONG* BytesReturned
- ) PURE;
-};
-#endif //!defined(_IKsControl_)
class SimpleMediaStream;
@@ -70,49 +33,39 @@ public:
IFACEMETHOD(GetCharacteristics)(_Out_ DWORD *pdwCharacteristics);
IFACEMETHOD(Pause)();
IFACEMETHOD(Shutdown)();
- IFACEMETHOD(Start)(
- _In_ IMFPresentationDescriptor *pPresentationDescriptor,
- _In_ const GUID *pguidTimeFormat,
- _In_ const PROPVARIANT *pvarStartPosition);
+ IFACEMETHOD(Start)(_In_ IMFPresentationDescriptor *pPresentationDescriptor, _In_ const GUID *pguidTimeFormat, _In_ const PROPVARIANT *pvarStartPosition);
IFACEMETHOD(Stop)();
// IMFMediaSourceEx
- IFACEMETHOD(GetSourceAttributes)(_Outptr_ IMFAttributes **ppAttributes);
- IFACEMETHOD(GetStreamAttributes)(DWORD dwStreamIdentifier, _Outptr_ IMFAttributes **ppAttributes);
+ IFACEMETHOD(GetSourceAttributes)(_COM_Outptr_ IMFAttributes **ppAttributes);
+ IFACEMETHOD(GetStreamAttributes)(DWORD dwStreamIdentifier, _COM_Outptr_ IMFAttributes **ppAttributes);
IFACEMETHOD(SetD3DManager)(_In_opt_ IUnknown *pManager);
// IMFGetService
- IFACEMETHOD(GetService)(REFGUID guidService, REFIID riid, _Out_opt_ LPVOID *ppvObject);
+ IFACEMETHOD(GetService)(_In_ REFGUID guidService, _In_ REFIID riid, _Out_ LPVOID *ppvObject);
// IKsControl
- IFACEMETHOD(KsProperty)(
- _In_ PKSPROPERTY pProperty,
- ULONG ulPropertyLength,
- _Inout_ LPVOID pPropertyData,
- ULONG ulDataLength,
- _Out_ ULONG* pBytesReturned);
-
- IFACEMETHOD(KsMethod)(
- _In_ PKSMETHOD pMethod,
- ULONG ulMethodLength,
- _Inout_ LPVOID pMethodData,
- ULONG ulDataLength,
- _Out_ ULONG* pBytesReturned
- );
-
- IFACEMETHOD(KsEvent)(
- _In_opt_ PKSEVENT pEvent,
- ULONG ulEventLength,
- _Inout_opt_ LPVOID pEventData,
- ULONG ulDataLength,
- _Out_opt_ ULONG* pBytesReturned
- );
+ IFACEMETHOD(KsProperty)(_In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
+ _In_ ULONG ulPropertyLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pPropertyData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned);
+ IFACEMETHOD(KsMethod)(_In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
+ _In_ ULONG ulMethodLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pMethodData,
+ _In_ ULONG ulDataLength,
+ _Out_ ULONG* pBytesReturned);
+ IFACEMETHOD(KsEvent)(_In_reads_bytes_opt_(ulEventLength) PKSEVENT pEvent,
+ _In_ ULONG ulEventLength,
+ _Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pEventData,
+ _In_ ULONG ulDataLength,
+ _Out_opt_ ULONG* pBytesReturned);
public:
HRESULT RuntimeClassInitialize();
private:
HRESULT _CheckShutdownRequiresLock();
- HRESULT _ValidatePresentationDescriptor(IMFPresentationDescriptor *pPresentationDescriptor);
+ HRESULT _ValidatePresentationDescriptor(_In_ IMFPresentationDescriptor *pPresentationDescriptor);
CriticalSection _critSec;
SourceState _sourceState{ SourceState::Invalid };
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
index 2f8b603b..7685b12e 100644
--- a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.cpp
@@ -1,4 +1,4 @@
-#include "SimpleMediaStream.h"
+#include "stdafx.h"
#define NUM_IMAGE_ROWS 240
#define NUM_IMAGE_COLS 320
@@ -6,22 +6,23 @@
#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)
-#define CHECKHR_GOTO( val, label ) \
-hr = (val); \
-if( FAILED( hr ) ) { \
- goto label; \
-}
-
-HRESULT SimpleMediaStream::RuntimeClassInitialize(_In_ SimpleMediaSource *pSource)
+HRESULT
+SimpleMediaStream::RuntimeClassInitialize(
+ _In_ SimpleMediaSource *pSource
+ )
{
HRESULT hr = S_OK;
ComPtr<IMFMediaTypeHandler> spTypeHandler;
ComPtr<IMFAttributes> attrs;
- AsWeak(pSource, &_wpSource);
+ if (nullptr == pSource)
+ {
+ return E_INVALIDARG;
+ }
+ RETURN_IF_FAILED (pSource->QueryInterface(IID_PPV_ARGS(&_parent)));
// Initialize media type and set the video output media type.
- CHECKHR_GOTO(MFCreateMediaType(&_spMediaType), done);
+ 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);
@@ -30,52 +31,56 @@ HRESULT SimpleMediaStream::RuntimeClassInitialize(_In_ SimpleMediaSource *pSourc
MFSetAttributeRatio(_spMediaType.Get(), MF_MT_FRAME_RATE, 30, 1);
MFSetAttributeRatio(_spMediaType.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1);
- CHECKHR_GOTO(MFCreateAttributes(&_spAttributes, 10), done);
- CHECKHR_GOTO(this->_SetStreamAttributes(_spAttributes.Get()), done);
- CHECKHR_GOTO(MFCreateEventQueue(&_spEventQueue), done);
+ RETURN_IF_FAILED (MFCreateAttributes(&_spAttributes, 10));
+ RETURN_IF_FAILED (this->_SetStreamAttributes(_spAttributes.Get()));
+ RETURN_IF_FAILED (MFCreateEventQueue(&_spEventQueue));
// Initialize stream descriptors
- CHECKHR_GOTO(MFCreateStreamDescriptor(0, 1, _spMediaType.GetAddressOf(), &_spStreamDesc), done);
+ RETURN_IF_FAILED (MFCreateStreamDescriptor(0, 1, _spMediaType.GetAddressOf(), &_spStreamDesc));
- CHECKHR_GOTO(_spStreamDesc->GetMediaTypeHandler(&spTypeHandler), done);
- CHECKHR_GOTO(spTypeHandler->SetCurrentMediaType(_spMediaType.Get()), done);
- CHECKHR_GOTO(this->_SetStreamDescriptorAttributes(_spStreamDesc.Get()), done);
+ RETURN_IF_FAILED (_spStreamDesc->GetMediaTypeHandler(&spTypeHandler));
+ RETURN_IF_FAILED (spTypeHandler->SetCurrentMediaType(_spMediaType.Get()));
+ RETURN_IF_FAILED (this->_SetStreamDescriptorAttributes(_spStreamDesc.Get()));
-done:
return hr;
}
-////////////////////////////////////////////////////////////////////////////////////////////////////
// IMFMediaEventGenerator
-IFACEMETHODIMP SimpleMediaStream::BeginGetEvent(IMFAsyncCallback *pCallback, IUnknown *punkState)
+IFACEMETHODIMP
+SimpleMediaStream::BeginGetEvent(
+ _In_ IMFAsyncCallback *pCallback,
+ _In_ IUnknown *punkState
+ )
{
+ HRESULT hr = S_OK;
auto lock = _critSec.Lock();
- HRESULT hr = _CheckShutdownRequiresLock();
-
- if (SUCCEEDED(hr))
- {
- hr = _spEventQueue->BeginGetEvent(pCallback, punkState);
- }
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->BeginGetEvent(pCallback, punkState));
return hr;
}
-IFACEMETHODIMP SimpleMediaStream::EndGetEvent(IMFAsyncResult *pResult, IMFMediaEvent **ppEvent)
+IFACEMETHODIMP
+SimpleMediaStream::EndGetEvent(
+ _In_ IMFAsyncResult *pResult,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
{
+ HRESULT hr = S_OK;
auto lock = _critSec.Lock();
- HRESULT hr = _CheckShutdownRequiresLock();
-
- if (SUCCEEDED(hr))
- {
- hr = _spEventQueue->EndGetEvent(pResult, ppEvent);
- }
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->EndGetEvent(pResult, ppEvent));
return hr;
}
-IFACEMETHODIMP SimpleMediaStream::GetEvent(DWORD dwFlags, IMFMediaEvent **ppEvent)
+IFACEMETHODIMP
+SimpleMediaStream::GetEvent(
+ DWORD dwFlags,
+ _COM_Outptr_ IMFMediaEvent **ppEvent
+ )
{
// NOTE:
// GetEvent can block indefinitely, so we don't hold the lock.
@@ -88,90 +93,80 @@ IFACEMETHODIMP SimpleMediaStream::GetEvent(DWORD dwFlags, IMFMediaEvent **ppEven
{
auto lock = _critSec.Lock();
- // Check shutdown
- hr = _CheckShutdownRequiresLock();
-
- if (SUCCEEDED(hr))
- {
- spQueue = _spEventQueue;
- }
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ spQueue = _spEventQueue;
}
// Now get the event.
- if (SUCCEEDED(hr))
- {
- hr = spQueue->GetEvent(dwFlags, ppEvent);
- }
+ RETURN_IF_FAILED (_spEventQueue->GetEvent(dwFlags, ppEvent));
return hr;
}
-IFACEMETHODIMP SimpleMediaStream::QueueEvent(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, const PROPVARIANT *pvValue)
+IFACEMETHODIMP
+SimpleMediaStream::QueueEvent(
+ MediaEventType eventType,
+ REFGUID guidExtendedType,
+ HRESULT hrStatus,
+ _In_opt_ PROPVARIANT const *pvValue
+ )
{
+ HRESULT hr = S_OK;
auto lock = _critSec.Lock();
- HRESULT hr = _CheckShutdownRequiresLock();
- if (SUCCEEDED(hr))
- {
- hr = _spEventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue);
- }
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
return hr;
}
-//////////////////////////////////////////////////////////////////////////////////////////
// IMFMediaStream
-IFACEMETHODIMP SimpleMediaStream::GetMediaSource(IMFMediaSource **ppMediaSource)
+IFACEMETHODIMP
+SimpleMediaStream::GetMediaSource(
+ _COM_Outptr_ IMFMediaSource **ppMediaSource
+ )
{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
if (ppMediaSource == nullptr)
{
return E_POINTER;
}
*ppMediaSource = nullptr;
- auto lock = _critSec.Lock();
- HRESULT hr = _CheckShutdownRequiresLock();
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- if (SUCCEEDED(hr))
- {
- ComPtr<SimpleMediaSource> spSource;
- _wpSource.As(&spSource);
- if (spSource != nullptr)
- {
- hr = spSource->QueryInterface(IID_PPV_ARGS(ppMediaSource));
- }
- else
- {
- hr = E_UNEXPECTED;
- }
- }
+ *ppMediaSource = _parent.Get();
+ (*ppMediaSource)->AddRef();
return hr;
}
-IFACEMETHODIMP SimpleMediaStream::GetStreamDescriptor(IMFStreamDescriptor **ppStreamDescriptor)
+IFACEMETHODIMP
+SimpleMediaStream::GetStreamDescriptor(
+ _COM_Outptr_ IMFStreamDescriptor **ppStreamDescriptor
+ )
{
+ HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+
if (ppStreamDescriptor == nullptr)
{
return E_POINTER;
}
-
*ppStreamDescriptor = nullptr;
- auto lock = _critSec.Lock();
- HRESULT hr = _CheckShutdownRequiresLock();
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
- if (SUCCEEDED(hr))
+ if (_spStreamDesc != nullptr)
{
- if (_spStreamDesc != nullptr)
- {
- *ppStreamDescriptor = _spStreamDesc.Get();
- (*ppStreamDescriptor)->AddRef();
- }
- else
- {
- return E_UNEXPECTED;
- }
+ *ppStreamDescriptor = _spStreamDesc.Get();
+ (*ppStreamDescriptor)->AddRef();
+ }
+ else
+ {
+ return E_UNEXPECTED;
}
return hr;
@@ -188,11 +183,16 @@ IFACEMETHODIMP SimpleMediaStream::GetStreamDescriptor(IMFStreamDescriptor **ppSt
pitch - line length in bytes
len - length of buffer in bytes
*/
-HRESULT WriteSampleData(BYTE *pBuf, LONG pitch, DWORD len)
+HRESULT
+WriteSampleData(
+ _Inout_updates_bytes_(len) BYTE *pBuf,
+ _In_ LONG pitch,
+ _In_ DWORD len
+ )
{
if (pBuf == nullptr)
{
- return E_POINTER;
+ return E_INVALIDARG;
}
const int NUM_ROWS = len / abs(pitch);
@@ -209,101 +209,63 @@ HRESULT WriteSampleData(BYTE *pBuf, LONG pitch, DWORD len)
return S_OK;
}
-IFACEMETHODIMP SimpleMediaStream::RequestSample(IUnknown *pToken)
+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;
- HRESULT hr = _CheckShutdownRequiresLock();
-
- if (SUCCEEDED(hr))
+ 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)
{
- ComPtr<IMFSample> spSample;
-
- ComPtr<IMFMediaBuffer> spOutputBuffer;
- hr = MFCreate2DMediaBuffer(NUM_IMAGE_COLS, NUM_IMAGE_ROWS, D3DFMT_X8R8G8B8, false, &spOutputBuffer);
-
- LONG pitch = IMAGE_ROW_SIZE_BYTES;
- BYTE *bufferStart = nullptr; // not used, since in this example we know the image will be top down, so bufferStart == pBuf
- DWORD bufferLength = IMAGE_BUFFER_SIZE_BYTES;
-
- BYTE *pBuf = nullptr;
- ComPtr<IMF2DBuffer2> spBuffer2D;
- if (SUCCEEDED(hr))
- {
- hr = spOutputBuffer.As(&spBuffer2D);
- }
-
- if (SUCCEEDED(hr))
- {
- if (spBuffer2D != nullptr)
- {
- hr = spBuffer2D->Lock2DSize(MF2DBuffer_LockFlags_Write, &pBuf, &pitch, &bufferStart, &bufferLength);
- }
- else
- {
- hr = spOutputBuffer->Lock(&pBuf, nullptr, nullptr);
- }
- }
-
- if (SUCCEEDED(hr))
- {
- hr = WriteSampleData(pBuf, pitch, bufferLength);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = spOutputBuffer->SetCurrentLength(bufferLength);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = spBuffer2D->Unlock2D();
- }
-
- if (SUCCEEDED(hr))
- {
- hr = MFCreateSample(&spSample);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = spSample->AddBuffer(spOutputBuffer.Get());
- }
-
- // set timestamp
- if (SUCCEEDED(hr))
- {
- hr = spSample->SetSampleTime(MFGetSystemTime());
- }
- if (SUCCEEDED(hr))
- {
- hr = spSample->SetSampleDuration(330000);
- }
-
- if (pToken != nullptr)
- {
- hr = spSample->SetUnknown(MFSampleExtension_Token, pToken);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = _spEventQueue->QueueEventParamUnk(MEMediaSample, GUID_NULL, S_OK, spSample.Get());
- }
+ RETURN_IF_FAILED (sample->SetUnknown(MFSampleExtension_Token, pToken));
}
+ RETURN_IF_FAILED (_spEventQueue->QueueEventParamUnk(MEMediaSample,
+ GUID_NULL,
+ S_OK,
+ sample.Get()));
return hr;
}
//////////////////////////////////////////////////////////////////////////////////////////
// IMFMediaStream2
-IFACEMETHODIMP SimpleMediaStream::SetStreamState(MF_STREAM_STATE state)
+IFACEMETHODIMP
+SimpleMediaStream::SetStreamState(
+ MF_STREAM_STATE state
+ )
{
- bool runningState = false;
- auto lock = _critSec.Lock();
-
HRESULT hr = S_OK;
+ auto lock = _critSec.Lock();
+ bool runningState = false;
- CHECKHR_GOTO(_CheckShutdownRequiresLock(), done);
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
switch (state)
{
@@ -326,12 +288,16 @@ done:
return hr;
}
-IFACEMETHODIMP SimpleMediaStream::GetStreamState(_Out_ MF_STREAM_STATE *pState)
+IFACEMETHODIMP
+SimpleMediaStream::GetStreamState(
+ _Out_ MF_STREAM_STATE *pState
+ )
{
+ HRESULT hr = S_OK;
auto lock = _critSec.Lock();
BOOLEAN pauseState = false;
- HRESULT hr = _CheckShutdownRequiresLock();
+ RETURN_IF_FAILED (_CheckShutdownRequiresLock());
if (SUCCEEDED(hr))
{
@@ -341,12 +307,15 @@ IFACEMETHODIMP SimpleMediaStream::GetStreamState(_Out_ MF_STREAM_STATE *pState)
return hr;
}
-HRESULT SimpleMediaStream::Shutdown()
+HRESULT
+SimpleMediaStream::Shutdown(
+ )
{
HRESULT hr = S_OK;
auto lock = _critSec.Lock();
_isShutdown = true;
+ _parent.Reset();
if (_spEventQueue != nullptr)
{
@@ -360,12 +329,12 @@ HRESULT SimpleMediaStream::Shutdown()
_isSelected = false;
- _wpSource.Reset();
-
return hr;
}
-HRESULT SimpleMediaStream::_CheckShutdownRequiresLock()
+HRESULT
+SimpleMediaStream::_CheckShutdownRequiresLock(
+ )
{
if (_isShutdown)
{
@@ -380,28 +349,43 @@ HRESULT SimpleMediaStream::_CheckShutdownRequiresLock()
return S_OK;
}
-HRESULT SimpleMediaStream::_SetStreamAttributes(IMFAttributes *pAttributeStore)
+HRESULT
+SimpleMediaStream::_SetStreamAttributes(
+ _In_ IMFAttributes *pAttributeStore
+ )
{
HRESULT hr = S_OK;
- if (SUCCEEDED(hr)) { hr = pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE); }
- if (SUCCEEDED(hr)) { hr = pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, STREAMINDEX); }
- if (SUCCEEDED(hr)) { hr = pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1); }
+ if (nullptr == pAttributeStore)
+ {
+ return E_INVALIDARG;
+ }
- if (SUCCEEDED(hr)) { hr = pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, _MFFrameSourceTypes::MFFrameSourceTypes_Color); }
+ 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;
}
-HRESULT SimpleMediaStream::_SetStreamDescriptorAttributes(IMFAttributes *pAttributeStore)
+HRESULT
+SimpleMediaStream::_SetStreamDescriptorAttributes(
+ _In_ IMFAttributes *pAttributeStore
+ )
{
HRESULT hr = S_OK;
- if (SUCCEEDED(hr)) { hr = pAttributeStore->SetGUID(MF_DEVICESTREAM_STREAM_CATEGORY, PINNAME_VIDEO_CAPTURE); }
- if (SUCCEEDED(hr)) { hr = pAttributeStore->SetUINT32(MF_DEVICESTREAM_STREAM_ID, STREAMINDEX); }
- if (SUCCEEDED(hr)) { hr = pAttributeStore->SetUINT32(MF_DEVICESTREAM_FRAMESERVER_SHARED, 1); }
+ if (nullptr == pAttributeStore)
+ {
+ return E_INVALIDARG;
+ }
- if (SUCCEEDED(hr)) { hr = pAttributeStore->SetUINT32(MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES, _MFFrameSourceTypes::MFFrameSourceTypes_Color); }
+ 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;
-} \ No newline at end of file
+}
+
diff --git a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h
index b804b1ea..56351f47 100644
--- a/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h
+++ b/general/SimpleMediaSource/MediaSource/SimpleMediaStream.h
@@ -1,7 +1,6 @@
#pragma once
#include "stdafx.h"
-#include "SimpleMediaSource.h"
class SimpleMediaSource;
@@ -29,19 +28,20 @@ public:
IFACEMETHOD(SetStreamState)(MF_STREAM_STATE state);
IFACEMETHOD(GetStreamState)(_Out_ MF_STREAM_STATE *pState);
-public:
+ // Non-interface methods.
HRESULT RuntimeClassInitialize(_In_ SimpleMediaSource* pSource);
HRESULT Shutdown();
-private:
- HRESULT _CheckShutdownRequiresLock();
+
+protected:
+ HRESULT _CheckShutdownRequiresLock();
HRESULT _SetStreamAttributes(IMFAttributes* pAttributeStore);
HRESULT _SetStreamDescriptorAttributes(IMFAttributes* pAttributeStore);
-private:
- CriticalSection _critSec;
- WeakRef _wpSource;
+ CriticalSection _critSec;
+
+ ComPtr<IMFMediaSource> _parent;
ComPtr<IMFMediaEventQueue> _spEventQueue;
ComPtr<IMFAttributes> _spAttributes;
ComPtr<IMFMediaType> _spMediaType;
diff --git a/general/SimpleMediaSource/MediaSource/stdafx.h b/general/SimpleMediaSource/MediaSource/stdafx.h
index 4702e47e..73bec0b4 100644
--- a/general/SimpleMediaSource/MediaSource/stdafx.h
+++ b/general/SimpleMediaSource/MediaSource/stdafx.h
@@ -7,12 +7,12 @@
// Windows Header Files:
#include <windows.h>
-#include <minwindef.h>
-#include <ks.h>
#include <propvarutil.h>
//#include <mfstd.h> // Must be included before <initguid.h>, or else DirectDraw GUIDs will be defined twice. See the comment in <uuids.h>.
#include <ole2.h>
#include <initguid.h>
+#include <ks.h>
+#include <ksmedia.h>
#include <mfapi.h>
#include <mferror.h>
#include <mfidl.h>
@@ -21,7 +21,56 @@
#include <winmeta.h>
#include <wrl.h>
#include <d3d9types.h>
-#include <ksmedia.h>
using namespace Microsoft::WRL;
-using namespace Microsoft::WRL::Wrappers; \ No newline at end of file
+using namespace Microsoft::WRL::Wrappers;
+
+#if !defined(_IKsControl_)
+#define _IKsControl_
+interface DECLSPEC_UUID("28F54685-06FD-11D2-B27A-00A0C9223196") IKsControl;
+#undef INTERFACE
+#define INTERFACE IKsControl
+DECLARE_INTERFACE_(IKsControl, IUnknown)
+{
+ STDMETHOD(KsProperty)(
+ THIS_
+ IN PKSPROPERTY Property,
+ IN ULONG PropertyLength,
+ IN OUT LPVOID PropertyData,
+ IN ULONG DataLength,
+ OUT ULONG* BytesReturned
+ ) PURE;
+ STDMETHOD(KsMethod)(
+ THIS_
+ IN PKSMETHOD Method,
+ IN ULONG MethodLength,
+ IN OUT LPVOID MethodData,
+ IN ULONG DataLength,
+ OUT ULONG* BytesReturned
+ ) PURE;
+ STDMETHOD(KsEvent)(
+ THIS_
+ IN PKSEVENT Event OPTIONAL,
+ IN ULONG EventLength,
+ IN OUT LPVOID EventData,
+ IN ULONG DataLength,
+ OUT ULONG* BytesReturned
+ ) PURE;
+};
+#endif // _IKsControl_
+
+#include "SimpleMediaStream.h"
+#include "SimpleMediaSource.h"
+
+
+// Basic macros to handle HRESULT checks.
+// Recommend adding implementation specific logging within the failure case.
+#ifndef RETURN_IF_FAILED
+#define RETURN_IF_FAILED( val ) \
+ hr = (val); \
+ if ( FAILED( hr ) ) \
+ { \
+ return hr; \
+ }
+#endif
+