Commit 787772b7 authored by Ghislain MARY's avatar Ghislain MARY

Handle capture stopping.

parent 49749086
......@@ -70,6 +70,11 @@ MSWinRTCap::MSWinRTCap()
ms_error("[MSWinRTCap] Could not create stop event [%i]", GetLastError());
return;
}
mPreviewStopCompleted = CreateEventEx(NULL, L"Local\\MSWinRTCapPreviewStop", 0, EVENT_ALL_ACCESS);
if (!mPreviewStopCompleted) {
ms_error("[MSWinRTCap] Could not create preview stop event [%i]", GetLastError());
return;
}
mIsInitialized = true;
smInstantiated = true;
......@@ -79,6 +84,10 @@ MSWinRTCap::~MSWinRTCap()
{
stop();
deactivate();
if (mPreviewStopCompleted) {
CloseHandle(mPreviewStopCompleted);
mPreviewStopCompleted = NULL;
}
if (mStopCompleted) {
CloseHandle(mStopCompleted);
mStopCompleted = NULL;
......@@ -144,6 +153,12 @@ int MSWinRTCap::activate()
int MSWinRTCap::deactivate()
{
IAsyncAction^ action = mCapture->StopPreviewAsync();
action->Completed = ref new AsyncActionCompletedHandler([this](IAsyncAction^ asyncAction, Windows::Foundation::AsyncStatus asyncStatus) {
SetEvent(mPreviewStopCompleted);
});
WaitForSingleObjectEx(mPreviewStopCompleted, INFINITE, FALSE);
mCameraSensorRotation = 0;
mIsActivated = false;
return 0;
......@@ -186,6 +201,8 @@ void MSWinRTCap::start()
action->Completed = ref new AsyncActionCompletedHandler([this](IAsyncAction^ asyncAction, Windows::Foundation::AsyncStatus asyncStatus) {
if (asyncStatus == Windows::Foundation::AsyncStatus::Completed)
mIsStarted = true;
else
ms_error("[MSWinRTCap] StartRecordToCustomSinkAsync failed");
SetEvent(mStartCompleted);
});
WaitForSingleObjectEx(mStartCompleted, INFINITE, FALSE);
......@@ -198,6 +215,13 @@ void MSWinRTCap::stop()
if (!mIsStarted) return;
static_cast<MSWinRTMediaSink *>(mMediaSink.Get())->SetCaptureFilter(NULL);
IAsyncAction^ action = mCapture->StopRecordAsync();
action->Completed = ref new AsyncActionCompletedHandler([this](IAsyncAction^ asyncAction, Windows::Foundation::AsyncStatus asyncStatus) {
SetEvent(mStopCompleted);
});
WaitForSingleObjectEx(mStopCompleted, INFINITE, FALSE);
ms_mutex_lock(&mMutex);
// Free samples that have already been sent
while ((m = ms_queue_get(&mSampleToFreeQueue)) != NULL) {
......@@ -208,6 +232,7 @@ void MSWinRTCap::stop()
freemsg(m);
}
ms_mutex_unlock(&mMutex);
mIsStarted = false;
}
int MSWinRTCap::feed(MSFilter *f)
......@@ -229,11 +254,6 @@ int MSWinRTCap::feed(MSFilter *f)
}
static void freeSample(void *sample)
{
delete[] sample;
}
void MSWinRTCap::OnSampleAvailable(BYTE *buf, DWORD bufLen, LONGLONG presentationTime)
{
mblk_t *m;
......
......@@ -92,6 +92,7 @@ namespace libmswinrtvid
HANDLE mStartCompleted;
HANDLE mStopCompleted;
HANDLE mPreviewStartCompleted;
HANDLE mPreviewStopCompleted;
Windows::UI::Xaml::Controls::CaptureElement^ mCaptureElement;
Platform::String^ mDeviceId;
Platform::Agile<MediaCapture^> mCapture;
......
......@@ -180,14 +180,15 @@ IFACEMETHODIMP MSWinRTStreamSink::QueryInterface(REFIID riid, void **ppv)
IFACEMETHODIMP_(ULONG) MSWinRTStreamSink::AddRef()
{
ms_message("MSWinRTStreamSink::AddRef");
return InterlockedIncrement(&_cRef);
long cRef = InterlockedIncrement(&_cRef);
ms_message("MSWinRTStreamSink::AddRef -> %d", cRef);
return cRef;
}
IFACEMETHODIMP_(ULONG) MSWinRTStreamSink::Release()
{
ms_message("MSWinRTStreamSink::Release");
long cRef = InterlockedDecrement(&_cRef);
ms_message("MSWinRTStreamSink::Release -> %d", cRef);
if (cRef == 0)
delete this;
return cRef;
......@@ -385,11 +386,9 @@ IFACEMETHODIMP MSWinRTStreamSink::Flush()
throw ref new Exception(hr);
}
#if 0 // TODO
// Note: Even though we are flushing data, we still need to send
// any marker events that were queued.
DropSamplesFromQueue();
#endif
} catch (Exception ^exc) {
hr = exc->HResult;
}
......@@ -426,6 +425,11 @@ IFACEMETHODIMP MSWinRTStreamSink::IsMediaTypeSupported(/* [in] */ IMFMediaType *
if (FAILED(pMediaType->GetGUID(MF_MT_SUBTYPE, &guiNewSubtype)) || guiNewSubtype != _guiCurrentSubtype)
hr = MF_E_INVALIDMEDIATYPE;
}
if (SUCCEEDED(hr)) {
UINT64 frameSize = 0;
pMediaType->GetUINT64(MF_MT_FRAME_SIZE, &frameSize);
ms_message("MSWinRTStreamSink::IsMediaTypeSupported: %dx%d", (frameSize & 0xffffffff00000000) >> 32, frameSize & 0xffffffff);
}
// We don't return any "close match" types.
if (ppMediaType)
......@@ -841,8 +845,6 @@ bool MSWinRTStreamSink::ProcessSamplesFromQueue(bool fFlush)
while (fSendSamples) {
ComPtr<IMFSample> spSample;
//ComPtr<IBufferPacket> spPacket;
bool fProcessingSample = false;
// Figure out if this is a marker or a sample.
// If this is a sample, write it to the file.
......@@ -850,67 +852,11 @@ bool MSWinRTStreamSink::ProcessSamplesFromQueue(bool fFlush)
if (SUCCEEDED(spunkSample.As(&spSample))) {
if (!fFlush) {
// Prepare sample for sending
PrepareSample(spSample.Get());
#if 0 // TODO
spPacket = PrepareSample(spSample.Get(), false);
#endif
fProcessingSample = true;
}
}
#if 0
else {
ComPtr<IMarker> spMarker;
// Check if it is a marker
if (SUCCEEDED(spunkSample.As(&spMarker))) {
MFSTREAMSINK_MARKER_TYPE markerType;
PROPVARIANT var;
PropVariantInit(&var);
ThrowIfError(spMarker->GetMarkerType(&markerType));
// Get the context data.
ThrowIfError(spMarker->GetContext(&var));
HRESULT 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;
} else {
ComPtr<IMFMediaType> spType;
ThrowIfError(spunkSample.As(&spType));
if (!fFlush)
spPacket = PrepareFormatChange(spType.Get());
}
}
#endif
#if 0 // TODO
if (spPacket) {
ComPtr<MSWinRTStreamSink> spThis = this;
// Send the sample
concurrency::create_task(_networkSender->SendAsync(spPacket.Get())).then([this, spThis, fProcessingSample](concurrency::task<void>& sendTask)
{
AutoLock lock(_critSec);
try
{
sendTask.get();
ThrowIfError(CheckShutdown());
if (_state == State_Started && fProcessingSample)
{
// If we are still in started state request another sample
ThrowIfError(QueueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, nullptr));
}
}
catch (Exception ^exc)
{
HandleError(exc->HResult);
if (FAILED(PrepareSample(spSample.Get()))) {
fSendSamples = false;
}
});
// We stop if we processed a sample otherwise keep looking
fSendSamples = !fProcessingSample;
}
}
#endif
if (fSendSamples)
{
......@@ -920,7 +866,6 @@ bool MSWinRTStreamSink::ProcessSamplesFromQueue(bool fFlush)
fSendSamples = false;
}
}
}
if (fSendEOS)
......@@ -1130,7 +1075,7 @@ IFACEMETHODIMP MSWinRTMediaSink::GetStreamSinkById(DWORD dwStreamSinkIdentifier,
hr = _stream->GetIdentifier(&dwId);
if (SUCCEEDED(hr)) {
if (dwId == dwStreamSinkIdentifier)
spResult = _stream;
spResult = _stream; // implicit AddRef
else
hr = MF_E_INVALIDSTREAMNUMBER;
} else {
......@@ -1138,7 +1083,6 @@ IFACEMETHODIMP MSWinRTMediaSink::GetStreamSinkById(DWORD dwStreamSinkIdentifier,
}
if (SUCCEEDED(hr)) {
*ppStreamSink = spResult.Get();
(*ppStreamSink)->AddRef();
}
}
......
......@@ -281,7 +281,10 @@ namespace libmswinrtvid {
LONGLONG GetStartTime() const { return _llStartTime; }
void ReportEndOfStream();
void SetCaptureFilter(MSWinRTCap *capture) { _capture = capture; }
void SetCaptureFilter(MSWinRTCap *capture) {
_capture = capture;
if (capture == NULL) _stream.Get()->Release();
}
void OnSampleAvailable(BYTE *buf, DWORD bufLen, LONGLONG presentationTime);
private:
......
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