Commit 32dc96f0 authored by Ghislain MARY's avatar Ghislain MARY

Add marker handling so that the capture can be stopped.

parent 787772b7
......@@ -218,6 +218,8 @@ void MSWinRTCap::stop()
static_cast<MSWinRTMediaSink *>(mMediaSink.Get())->SetCaptureFilter(NULL);
IAsyncAction^ action = mCapture->StopRecordAsync();
action->Completed = ref new AsyncActionCompletedHandler([this](IAsyncAction^ asyncAction, Windows::Foundation::AsyncStatus asyncStatus) {
static_cast<MSWinRTMediaSink *>(mMediaSink.Get())->Shutdown();
mMediaSink = nullptr;
SetEvent(mStopCompleted);
});
WaitForSingleObjectEx(mStopCompleted, INFINITE, FALSE);
......
......@@ -74,6 +74,102 @@ static void ConvertPropertiesToMediaType(_In_ IMediaEncodingProperties ^mep, _Ou
MSWinRTMarker::MSWinRTMarker(MFSTREAMSINK_MARKER_TYPE eMarkerType) : _cRef(1), _eMarkerType(eMarkerType)
{
ZeroMemory(&_varMarkerValue, sizeof(_varMarkerValue));
ZeroMemory(&_varContextValue, sizeof(_varContextValue));
}
MSWinRTMarker::~MSWinRTMarker()
{
PropVariantClear(&_varMarkerValue);
PropVariantClear(&_varContextValue);
}
HRESULT MSWinRTMarker::Create(MFSTREAMSINK_MARKER_TYPE eMarkerType, const PROPVARIANT *pvarMarkerValue, const PROPVARIANT *pvarContextValue, IMarker **ppMarker)
{
if (ppMarker == nullptr)
return E_POINTER;
HRESULT hr = S_OK;
ComPtr<MSWinRTMarker> spMarker;
spMarker.Attach(new (std::nothrow) MSWinRTMarker(eMarkerType));
if (spMarker == nullptr)
hr = E_OUTOFMEMORY;
// Copy the marker data.
if (SUCCEEDED(hr)) {
if (pvarMarkerValue)
hr = PropVariantCopy(&spMarker->_varMarkerValue, pvarMarkerValue);
}
if (SUCCEEDED(hr)) {
if (pvarContextValue)
hr = PropVariantCopy(&spMarker->_varContextValue, pvarContextValue);
}
if (SUCCEEDED(hr))
*ppMarker = spMarker.Detach();
return hr;
}
// IUnknown methods.
IFACEMETHODIMP_(ULONG) MSWinRTMarker::AddRef()
{
return InterlockedIncrement(&_cRef);
}
IFACEMETHODIMP_(ULONG) MSWinRTMarker::Release()
{
ULONG cRef = InterlockedDecrement(&_cRef);
if (cRef == 0)
delete this;
return cRef;
}
IFACEMETHODIMP MSWinRTMarker::QueryInterface(REFIID riid, void **ppv)
{
if (ppv == nullptr)
return E_POINTER;
(*ppv) = nullptr;
HRESULT hr = S_OK;
if (riid == IID_IUnknown || riid == __uuidof(IMarker)) {
(*ppv) = static_cast<IMarker*>(this);
AddRef();
} else {
hr = E_NOINTERFACE;
}
return hr;
}
// IMarker methods.
IFACEMETHODIMP MSWinRTMarker::GetMarkerType(MFSTREAMSINK_MARKER_TYPE *pType)
{
if (pType == NULL)
return E_POINTER;
*pType = _eMarkerType;
return S_OK;
}
IFACEMETHODIMP MSWinRTMarker::GetMarkerValue(PROPVARIANT *pvar)
{
if (pvar == NULL)
return E_POINTER;
return PropVariantCopy(pvar, &_varMarkerValue);
}
IFACEMETHODIMP MSWinRTMarker::GetContext(PROPVARIANT *pvar)
{
if (pvar == NULL)
return E_POINTER;
return PropVariantCopy(pvar, &_varContextValue);
}
MSWinRTStreamSink::MSWinRTStreamSink(DWORD dwIdentifier)
: _cRef(1)
......@@ -350,14 +446,13 @@ IFACEMETHODIMP MSWinRTStreamSink::PlaceMarker(MFSTREAMSINK_MARKER_TYPE eMarkerTy
ms_message("MSWinRTStreamSink::PlaceMarker");
_mutex.lock();
HRESULT hr = S_OK;
#if 0 // TODO
ComPtr<IMarker> spMarker;
hr = CheckShutdown();
if (SUCCEEDED(hr))
hr = ValidateOperation(OpPlaceMarker);
if (SUCCEEDED(hr))
hr = CreateMarker(eMarkerType, pvarMarkerValue, pvarContextValue, &spMarker);
hr = MSWinRTMarker::Create(eMarkerType, pvarMarkerValue, pvarContextValue, &spMarker);
if (SUCCEEDED(hr))
hr = _SampleQueue.InsertBack(spMarker.Get());
......@@ -368,7 +463,6 @@ IFACEMETHODIMP MSWinRTStreamSink::PlaceMarker(MFSTREAMSINK_MARKER_TYPE eMarkerTy
hr = QueueAsyncOperation(OpPlaceMarker); // Increments ref count on pOp.
}
}
#endif
_mutex.unlock();
RETURN_HR(hr)
}
......@@ -856,12 +950,41 @@ bool MSWinRTStreamSink::ProcessSamplesFromQueue(bool fFlush)
fSendSamples = false;
}
}
} else {
ComPtr<IMarker> spMarker;
// Check if it is a marker
if (SUCCEEDED(spunkSample.As(&spMarker))) {
MFSTREAMSINK_MARKER_TYPE markerType;
PROPVARIANT var;
HRESULT hr;
PropVariantInit(&var);
hr = spMarker->GetMarkerType(&markerType);
if (FAILED(hr)) throw ref new Exception(hr);
// Get the context data.
hr = spMarker->GetContext(&var);
if (FAILED(hr)) throw ref new Exception(hr);
hr = QueueEvent(MEStreamSinkMarker, GUID_NULL, S_OK, &var);
PropVariantClear(&var);
if (FAILED(hr)) throw ref new Exception(hr);
if (markerType == MFSTREAMSINK_MARKER_ENDOFSEGMENT) {
fSendEOS = true;
}
}
#if 0 // TODO
else {
ComPtr<IMFMediaType> spType;
HRESULT hr = spunkSample.As(&spType);
if (FAILED(hr)) throw ref new Exception(hr);
if (!fFlush) {
spPacket = PrepareFormatChange(spType.Get());
}
}
#endif
}
if (fSendSamples)
{
if (FAILED(_SampleQueue.RemoveFront(spunkSample.ReleaseAndGetAddressOf())))
{
if (fSendSamples) {
if (FAILED(_SampleQueue.RemoveFront(spunkSample.ReleaseAndGetAddressOf()))) {
fNeedMoreSamples = true;
fSendSamples = false;
}
......
......@@ -31,11 +31,18 @@ using namespace Windows::Media::MediaProperties;
namespace libmswinrtvid {
//interface class ISinkCallback;
class MSWinRTCap;
class MSWinRTMediaSink;
interface DECLSPEC_UUID("3AC82233-933C-43a9-AF3D-ADC94EABF406") DECLSPEC_NOVTABLE IMarker : public IUnknown
{
IFACEMETHOD(GetMarkerType) (MFSTREAMSINK_MARKER_TYPE *pType) = 0;
IFACEMETHOD(GetMarkerValue) (PROPVARIANT *pvar) = 0;
IFACEMETHOD(GetContext) (PROPVARIANT *pvar) = 0;
};
template<class T>
class AsyncCallback : public IMFAsyncCallback
{
......@@ -96,6 +103,33 @@ namespace libmswinrtvid {
};
class MSWinRTMarker : public IMarker
{
public:
static HRESULT Create(MFSTREAMSINK_MARKER_TYPE eMarkerType, const PROPVARIANT *pvarMarkerValue, const PROPVARIANT *pvarContextValue, IMarker **ppMarker);
// IUnknown methods.
IFACEMETHOD(QueryInterface) (REFIID riid, void **ppv);
IFACEMETHOD_(ULONG, AddRef) ();
IFACEMETHOD_(ULONG, Release) ();
IFACEMETHOD(GetMarkerType) (MFSTREAMSINK_MARKER_TYPE *pType);
IFACEMETHOD(GetMarkerValue) (PROPVARIANT *pvar);
IFACEMETHOD(GetContext) (PROPVARIANT *pvar);
protected:
MFSTREAMSINK_MARKER_TYPE _eMarkerType;
PROPVARIANT _varMarkerValue;
PROPVARIANT _varContextValue;
private:
long _cRef;
MSWinRTMarker(MFSTREAMSINK_MARKER_TYPE eMarkerType);
virtual ~MSWinRTMarker();
};
class MSWinRTStreamSink : public IMFStreamSink, public IMFMediaTypeHandler
{
public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment