summaryrefslogtreecommitdiffstats
path: root/dom/media/directshow/AudioSinkFilter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/directshow/AudioSinkFilter.cpp')
-rw-r--r--dom/media/directshow/AudioSinkFilter.cpp285
1 files changed, 285 insertions, 0 deletions
diff --git a/dom/media/directshow/AudioSinkFilter.cpp b/dom/media/directshow/AudioSinkFilter.cpp
new file mode 100644
index 000000000..9f23c0e00
--- /dev/null
+++ b/dom/media/directshow/AudioSinkFilter.cpp
@@ -0,0 +1,285 @@
+/* -*- 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 "SampleSink.h"
+#include "AudioSinkFilter.h"
+#include "AudioSinkInputPin.h"
+#include "VideoUtils.h"
+#include "mozilla/Logging.h"
+
+
+#include <initguid.h>
+#include <wmsdkidl.h>
+
+#define DELETE_RESET(p) { delete (p) ; (p) = nullptr ;}
+
+DEFINE_GUID(CLSID_MozAudioSinkFilter, 0x1872d8c8, 0xea8d, 0x4c34, 0xae, 0x96, 0x69, 0xde,
+ 0xf1, 0x33, 0x7b, 0x33);
+
+using namespace mozilla::media;
+
+namespace mozilla {
+
+static LazyLogModule gDirectShowLog("DirectShowDecoder");
+#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
+
+AudioSinkFilter::AudioSinkFilter(const wchar_t* aObjectName, HRESULT* aOutResult)
+ : BaseFilter(aObjectName, CLSID_MozAudioSinkFilter),
+ mFilterCritSec("AudioSinkFilter::mFilterCritSec")
+{
+ (*aOutResult) = S_OK;
+ mInputPin = new AudioSinkInputPin(L"AudioSinkInputPin",
+ this,
+ &mFilterCritSec,
+ aOutResult);
+}
+
+AudioSinkFilter::~AudioSinkFilter()
+{
+}
+
+int
+AudioSinkFilter::GetPinCount()
+{
+ return 1;
+}
+
+BasePin*
+AudioSinkFilter::GetPin(int aIndex)
+{
+ CriticalSectionAutoEnter lockFilter(mFilterCritSec);
+ return (aIndex == 0) ? static_cast<BasePin*>(mInputPin) : nullptr;
+}
+
+HRESULT
+AudioSinkFilter::Pause()
+{
+ CriticalSectionAutoEnter lockFilter(mFilterCritSec);
+ if (mState == State_Stopped) {
+ // Change the state, THEN activate the input pin.
+ mState = State_Paused;
+ if (mInputPin && mInputPin->IsConnected()) {
+ mInputPin->Active();
+ }
+ } else if (mState == State_Running) {
+ mState = State_Paused;
+ }
+ return S_OK;
+}
+
+HRESULT
+AudioSinkFilter::Stop()
+{
+ CriticalSectionAutoEnter lockFilter(mFilterCritSec);
+ mState = State_Stopped;
+ if (mInputPin) {
+ mInputPin->Inactive();
+ }
+
+ GetSampleSink()->Flush();
+
+ return S_OK;
+}
+
+HRESULT
+AudioSinkFilter::Run(REFERENCE_TIME tStart)
+{
+ LOG("AudioSinkFilter::Run(%lld) [%4.2lf]",
+ RefTimeToUsecs(tStart),
+ double(RefTimeToUsecs(tStart)) / USECS_PER_S);
+ return media::BaseFilter::Run(tStart);
+}
+
+HRESULT
+AudioSinkFilter::GetClassID( OUT CLSID * pCLSID )
+{
+ (* pCLSID) = CLSID_MozAudioSinkFilter;
+ return S_OK;
+}
+
+HRESULT
+AudioSinkFilter::QueryInterface(REFIID aIId, void **aInterface)
+{
+ if (aIId == IID_IMediaSeeking) {
+ *aInterface = static_cast<IMediaSeeking*>(this);
+ AddRef();
+ return S_OK;
+ }
+ return mozilla::media::BaseFilter::QueryInterface(aIId, aInterface);
+}
+
+ULONG
+AudioSinkFilter::AddRef()
+{
+ return ::InterlockedIncrement(&mRefCnt);
+}
+
+ULONG
+AudioSinkFilter::Release()
+{
+ unsigned long newRefCnt = ::InterlockedDecrement(&mRefCnt);
+ if (!newRefCnt) {
+ delete this;
+ }
+ return newRefCnt;
+}
+
+SampleSink*
+AudioSinkFilter::GetSampleSink()
+{
+ return mInputPin->GetSampleSink();
+}
+
+
+// IMediaSeeking implementation.
+//
+// Calls to IMediaSeeking are forwarded to the output pin that the
+// AudioSinkInputPin is connected to, i.e. upstream towards the parser and
+// source filters, which actually implement seeking.
+#define ENSURE_CONNECTED_PIN_SEEKING \
+ if (!mInputPin) { \
+ return E_NOTIMPL; \
+ } \
+ RefPtr<IMediaSeeking> pinSeeking = mInputPin->GetConnectedPinSeeking(); \
+ if (!pinSeeking) { \
+ return E_NOTIMPL; \
+ }
+
+HRESULT
+AudioSinkFilter::GetCapabilities(DWORD* aCapabilities)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->GetCapabilities(aCapabilities);
+}
+
+HRESULT
+AudioSinkFilter::CheckCapabilities(DWORD* aCapabilities)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->CheckCapabilities(aCapabilities);
+}
+
+HRESULT
+AudioSinkFilter::IsFormatSupported(const GUID* aFormat)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->IsFormatSupported(aFormat);
+}
+
+HRESULT
+AudioSinkFilter::QueryPreferredFormat(GUID* aFormat)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->QueryPreferredFormat(aFormat);
+}
+
+HRESULT
+AudioSinkFilter::GetTimeFormat(GUID* aFormat)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->GetTimeFormat(aFormat);
+}
+
+HRESULT
+AudioSinkFilter::IsUsingTimeFormat(const GUID* aFormat)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->IsUsingTimeFormat(aFormat);
+}
+
+HRESULT
+AudioSinkFilter::SetTimeFormat(const GUID* aFormat)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->SetTimeFormat(aFormat);
+}
+
+HRESULT
+AudioSinkFilter::GetDuration(LONGLONG* aDuration)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->GetDuration(aDuration);
+}
+
+HRESULT
+AudioSinkFilter::GetStopPosition(LONGLONG* aStop)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->GetStopPosition(aStop);
+}
+
+HRESULT
+AudioSinkFilter::GetCurrentPosition(LONGLONG* aCurrent)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->GetCurrentPosition(aCurrent);
+}
+
+HRESULT
+AudioSinkFilter::ConvertTimeFormat(LONGLONG* aTarget,
+ const GUID* aTargetFormat,
+ LONGLONG aSource,
+ const GUID* aSourceFormat)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->ConvertTimeFormat(aTarget,
+ aTargetFormat,
+ aSource,
+ aSourceFormat);
+}
+
+HRESULT
+AudioSinkFilter::SetPositions(LONGLONG* aCurrent,
+ DWORD aCurrentFlags,
+ LONGLONG* aStop,
+ DWORD aStopFlags)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->SetPositions(aCurrent,
+ aCurrentFlags,
+ aStop,
+ aStopFlags);
+}
+
+HRESULT
+AudioSinkFilter::GetPositions(LONGLONG* aCurrent,
+ LONGLONG* aStop)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->GetPositions(aCurrent, aStop);
+}
+
+HRESULT
+AudioSinkFilter::GetAvailable(LONGLONG* aEarliest,
+ LONGLONG* aLatest)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->GetAvailable(aEarliest, aLatest);
+}
+
+HRESULT
+AudioSinkFilter::SetRate(double aRate)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->SetRate(aRate);
+}
+
+HRESULT
+AudioSinkFilter::GetRate(double* aRate)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->GetRate(aRate);
+}
+
+HRESULT
+AudioSinkFilter::GetPreroll(LONGLONG* aPreroll)
+{
+ ENSURE_CONNECTED_PIN_SEEKING
+ return pinSeeking->GetPreroll(aPreroll);
+}
+
+} // namespace mozilla
+