mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
158 lines
4.4 KiB
C++
158 lines
4.4 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "WMFSourceReaderCallback.h"
|
|
#include "WMFUtils.h"
|
|
|
|
namespace mozilla {
|
|
|
|
#ifdef PR_LOGGING
|
|
static PRLogModuleInfo* gWMFSourceReaderCallbackLog = nullptr;
|
|
#define LOG(...) PR_LOG(gWMFSourceReaderCallbackLog, PR_LOG_DEBUG, (__VA_ARGS__))
|
|
#else
|
|
#define LOG(...)
|
|
#endif
|
|
|
|
// IUnknown Methods
|
|
STDMETHODIMP
|
|
WMFSourceReaderCallback::QueryInterface(REFIID aIId, void **aInterface)
|
|
{
|
|
LOG("WMFSourceReaderCallback::QueryInterface %s", GetGUIDName(aIId).get());
|
|
|
|
if (aIId == IID_IMFSourceReaderCallback) {
|
|
return DoGetInterface(static_cast<WMFSourceReaderCallback*>(this), aInterface);
|
|
}
|
|
if (aIId == IID_IUnknown) {
|
|
return DoGetInterface(static_cast<WMFSourceReaderCallback*>(this), aInterface);
|
|
}
|
|
|
|
*aInterface = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
NS_IMPL_THREADSAFE_ADDREF(WMFSourceReaderCallback)
|
|
NS_IMPL_THREADSAFE_RELEASE(WMFSourceReaderCallback)
|
|
|
|
WMFSourceReaderCallback::WMFSourceReaderCallback()
|
|
: mMonitor("WMFSourceReaderCallback")
|
|
, mResultStatus(S_OK)
|
|
, mStreamFlags(0)
|
|
, mTimestamp(0)
|
|
, mSample(nullptr)
|
|
, mReadFinished(false)
|
|
{
|
|
#ifdef PR_LOGGING
|
|
if (!gWMFSourceReaderCallbackLog) {
|
|
gWMFSourceReaderCallbackLog = PR_NewLogModule("WMFSourceReaderCallback");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
HRESULT
|
|
WMFSourceReaderCallback::NotifyReadComplete(HRESULT aReadStatus,
|
|
DWORD aStreamIndex,
|
|
DWORD aStreamFlags,
|
|
LONGLONG aTimestamp,
|
|
IMFSample *aSample)
|
|
{
|
|
// Note: aSample can be NULL on success if more data is required!
|
|
ReentrantMonitorAutoEnter mon(mMonitor);
|
|
|
|
if (mSample) {
|
|
// The WMFReader should have called Wait() to retrieve the last
|
|
// sample returned by the last ReadSample() call, but if we're
|
|
// aborting the read before Wait() is called the sample ref
|
|
// can be non-null.
|
|
mSample->Release();
|
|
mSample = nullptr;
|
|
}
|
|
|
|
if (SUCCEEDED(aReadStatus)) {
|
|
if (aSample) {
|
|
mTimestamp = aTimestamp;
|
|
mSample = aSample;
|
|
mSample->AddRef();
|
|
}
|
|
}
|
|
|
|
mResultStatus = aReadStatus;
|
|
mStreamFlags = aStreamFlags;
|
|
|
|
// Set the sentinal value and notify the monitor, so that threads waiting
|
|
// in Wait() are awoken.
|
|
mReadFinished = true;
|
|
mon.NotifyAll();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
WMFSourceReaderCallback::OnReadSample(HRESULT aReadStatus,
|
|
DWORD aStreamIndex,
|
|
DWORD aStreamFlags,
|
|
LONGLONG aTimestamp,
|
|
IMFSample *aSample)
|
|
{
|
|
LOG("WMFSourceReaderCallback::OnReadSample() hr=0x%x flags=0x%x time=%lld sample=%p",
|
|
aReadStatus, aStreamFlags, aTimestamp, aSample);
|
|
return NotifyReadComplete(aReadStatus,
|
|
aStreamIndex,
|
|
aStreamFlags,
|
|
aTimestamp,
|
|
aSample);
|
|
}
|
|
|
|
HRESULT
|
|
WMFSourceReaderCallback::Cancel()
|
|
{
|
|
LOG("WMFSourceReaderCallback::Cancel()");
|
|
return NotifyReadComplete(E_ABORT,
|
|
0,
|
|
0,
|
|
0,
|
|
nullptr);
|
|
}
|
|
|
|
STDMETHODIMP
|
|
WMFSourceReaderCallback::OnEvent(DWORD, IMFMediaEvent *)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
WMFSourceReaderCallback::OnFlush(DWORD)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT
|
|
WMFSourceReaderCallback::Wait(DWORD* aStreamFlags,
|
|
LONGLONG* aTimeStamp,
|
|
IMFSample** aSample)
|
|
{
|
|
ReentrantMonitorAutoEnter mon(mMonitor);
|
|
LOG("WMFSourceReaderCallback::Wait() starting wait");
|
|
while (!mReadFinished) {
|
|
mon.Wait();
|
|
}
|
|
mReadFinished = false;
|
|
LOG("WMFSourceReaderCallback::Wait() done waiting");
|
|
|
|
*aStreamFlags = mStreamFlags;
|
|
*aTimeStamp = mTimestamp;
|
|
*aSample = mSample;
|
|
HRESULT hr = mResultStatus;
|
|
|
|
mSample = nullptr;
|
|
mTimestamp = 0;
|
|
mStreamFlags = 0;
|
|
mResultStatus = S_OK;
|
|
|
|
return hr;
|
|
}
|
|
|
|
} // namespace mozilla
|