content/media/directshow/AudioSinkFilter.cpp

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "SampleSink.h"
michael@0 8 #include "AudioSinkFilter.h"
michael@0 9 #include "AudioSinkInputPin.h"
michael@0 10 #include "VideoUtils.h"
michael@0 11 #include "prlog.h"
michael@0 12
michael@0 13
michael@0 14 #include <initguid.h>
michael@0 15 #include <wmsdkidl.h>
michael@0 16
michael@0 17 #define DELETE_RESET(p) { delete (p) ; (p) = nullptr ;}
michael@0 18
michael@0 19 DEFINE_GUID(CLSID_MozAudioSinkFilter, 0x1872d8c8, 0xea8d, 0x4c34, 0xae, 0x96, 0x69, 0xde,
michael@0 20 0xf1, 0x33, 0x7b, 0x33);
michael@0 21
michael@0 22 using namespace mozilla::media;
michael@0 23
michael@0 24 namespace mozilla {
michael@0 25
michael@0 26 #ifdef PR_LOGGING
michael@0 27 PRLogModuleInfo* GetDirectShowLog();
michael@0 28 #define LOG(...) PR_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
michael@0 29 #else
michael@0 30 #define LOG(...)
michael@0 31 #endif
michael@0 32
michael@0 33 AudioSinkFilter::AudioSinkFilter(const wchar_t* aObjectName, HRESULT* aOutResult)
michael@0 34 : BaseFilter(aObjectName, CLSID_MozAudioSinkFilter),
michael@0 35 mFilterCritSec("AudioSinkFilter::mFilterCritSec")
michael@0 36 {
michael@0 37 (*aOutResult) = S_OK;
michael@0 38 mInputPin = new AudioSinkInputPin(L"AudioSinkInputPin",
michael@0 39 this,
michael@0 40 &mFilterCritSec,
michael@0 41 aOutResult);
michael@0 42 }
michael@0 43
michael@0 44 AudioSinkFilter::~AudioSinkFilter()
michael@0 45 {
michael@0 46 }
michael@0 47
michael@0 48 int
michael@0 49 AudioSinkFilter::GetPinCount()
michael@0 50 {
michael@0 51 return 1;
michael@0 52 }
michael@0 53
michael@0 54 BasePin*
michael@0 55 AudioSinkFilter::GetPin(int aIndex)
michael@0 56 {
michael@0 57 CriticalSectionAutoEnter lockFilter(mFilterCritSec);
michael@0 58 return (aIndex == 0) ? static_cast<BasePin*>(mInputPin) : nullptr;
michael@0 59 }
michael@0 60
michael@0 61 HRESULT
michael@0 62 AudioSinkFilter::Pause()
michael@0 63 {
michael@0 64 CriticalSectionAutoEnter lockFilter(mFilterCritSec);
michael@0 65 if (mState == State_Stopped) {
michael@0 66 // Change the state, THEN activate the input pin.
michael@0 67 mState = State_Paused;
michael@0 68 if (mInputPin && mInputPin->IsConnected()) {
michael@0 69 mInputPin->Active();
michael@0 70 }
michael@0 71 } else if (mState == State_Running) {
michael@0 72 mState = State_Paused;
michael@0 73 }
michael@0 74 return S_OK;
michael@0 75 }
michael@0 76
michael@0 77 HRESULT
michael@0 78 AudioSinkFilter::Stop()
michael@0 79 {
michael@0 80 CriticalSectionAutoEnter lockFilter(mFilterCritSec);
michael@0 81 mState = State_Stopped;
michael@0 82 if (mInputPin) {
michael@0 83 mInputPin->Inactive();
michael@0 84 }
michael@0 85
michael@0 86 GetSampleSink()->Flush();
michael@0 87
michael@0 88 return S_OK;
michael@0 89 }
michael@0 90
michael@0 91 HRESULT
michael@0 92 AudioSinkFilter::Run(REFERENCE_TIME tStart)
michael@0 93 {
michael@0 94 LOG("AudioSinkFilter::Run(%lld) [%4.2lf]",
michael@0 95 RefTimeToUsecs(tStart),
michael@0 96 double(RefTimeToUsecs(tStart)) / USECS_PER_S);
michael@0 97 return media::BaseFilter::Run(tStart);
michael@0 98 }
michael@0 99
michael@0 100 HRESULT
michael@0 101 AudioSinkFilter::GetClassID( OUT CLSID * pCLSID )
michael@0 102 {
michael@0 103 (* pCLSID) = CLSID_MozAudioSinkFilter;
michael@0 104 return S_OK;
michael@0 105 }
michael@0 106
michael@0 107 HRESULT
michael@0 108 AudioSinkFilter::QueryInterface(REFIID aIId, void **aInterface)
michael@0 109 {
michael@0 110 if (aIId == IID_IMediaSeeking) {
michael@0 111 *aInterface = static_cast<IMediaSeeking*>(this);
michael@0 112 AddRef();
michael@0 113 return S_OK;
michael@0 114 }
michael@0 115 return mozilla::media::BaseFilter::QueryInterface(aIId, aInterface);
michael@0 116 }
michael@0 117
michael@0 118 ULONG
michael@0 119 AudioSinkFilter::AddRef()
michael@0 120 {
michael@0 121 return ::InterlockedIncrement(&mRefCnt);
michael@0 122 }
michael@0 123
michael@0 124 ULONG
michael@0 125 AudioSinkFilter::Release()
michael@0 126 {
michael@0 127 unsigned long newRefCnt = ::InterlockedDecrement(&mRefCnt);
michael@0 128 if (!newRefCnt) {
michael@0 129 delete this;
michael@0 130 }
michael@0 131 return newRefCnt;
michael@0 132 }
michael@0 133
michael@0 134 SampleSink*
michael@0 135 AudioSinkFilter::GetSampleSink()
michael@0 136 {
michael@0 137 return mInputPin->GetSampleSink();
michael@0 138 }
michael@0 139
michael@0 140
michael@0 141 // IMediaSeeking implementation.
michael@0 142 //
michael@0 143 // Calls to IMediaSeeking are forwarded to the output pin that the
michael@0 144 // AudioSinkInputPin is connected to, i.e. upstream towards the parser and
michael@0 145 // source filters, which actually implement seeking.
michael@0 146 #define ENSURE_CONNECTED_PIN_SEEKING \
michael@0 147 if (!mInputPin) { \
michael@0 148 return E_NOTIMPL; \
michael@0 149 } \
michael@0 150 RefPtr<IMediaSeeking> pinSeeking = mInputPin->GetConnectedPinSeeking(); \
michael@0 151 if (!pinSeeking) { \
michael@0 152 return E_NOTIMPL; \
michael@0 153 }
michael@0 154
michael@0 155 HRESULT
michael@0 156 AudioSinkFilter::GetCapabilities(DWORD* aCapabilities)
michael@0 157 {
michael@0 158 ENSURE_CONNECTED_PIN_SEEKING
michael@0 159 return pinSeeking->GetCapabilities(aCapabilities);
michael@0 160 }
michael@0 161
michael@0 162 HRESULT
michael@0 163 AudioSinkFilter::CheckCapabilities(DWORD* aCapabilities)
michael@0 164 {
michael@0 165 ENSURE_CONNECTED_PIN_SEEKING
michael@0 166 return pinSeeking->CheckCapabilities(aCapabilities);
michael@0 167 }
michael@0 168
michael@0 169 HRESULT
michael@0 170 AudioSinkFilter::IsFormatSupported(const GUID* aFormat)
michael@0 171 {
michael@0 172 ENSURE_CONNECTED_PIN_SEEKING
michael@0 173 return pinSeeking->IsFormatSupported(aFormat);
michael@0 174 }
michael@0 175
michael@0 176 HRESULT
michael@0 177 AudioSinkFilter::QueryPreferredFormat(GUID* aFormat)
michael@0 178 {
michael@0 179 ENSURE_CONNECTED_PIN_SEEKING
michael@0 180 return pinSeeking->QueryPreferredFormat(aFormat);
michael@0 181 }
michael@0 182
michael@0 183 HRESULT
michael@0 184 AudioSinkFilter::GetTimeFormat(GUID* aFormat)
michael@0 185 {
michael@0 186 ENSURE_CONNECTED_PIN_SEEKING
michael@0 187 return pinSeeking->GetTimeFormat(aFormat);
michael@0 188 }
michael@0 189
michael@0 190 HRESULT
michael@0 191 AudioSinkFilter::IsUsingTimeFormat(const GUID* aFormat)
michael@0 192 {
michael@0 193 ENSURE_CONNECTED_PIN_SEEKING
michael@0 194 return pinSeeking->IsUsingTimeFormat(aFormat);
michael@0 195 }
michael@0 196
michael@0 197 HRESULT
michael@0 198 AudioSinkFilter::SetTimeFormat(const GUID* aFormat)
michael@0 199 {
michael@0 200 ENSURE_CONNECTED_PIN_SEEKING
michael@0 201 return pinSeeking->SetTimeFormat(aFormat);
michael@0 202 }
michael@0 203
michael@0 204 HRESULT
michael@0 205 AudioSinkFilter::GetDuration(LONGLONG* aDuration)
michael@0 206 {
michael@0 207 ENSURE_CONNECTED_PIN_SEEKING
michael@0 208 return pinSeeking->GetDuration(aDuration);
michael@0 209 }
michael@0 210
michael@0 211 HRESULT
michael@0 212 AudioSinkFilter::GetStopPosition(LONGLONG* aStop)
michael@0 213 {
michael@0 214 ENSURE_CONNECTED_PIN_SEEKING
michael@0 215 return pinSeeking->GetStopPosition(aStop);
michael@0 216 }
michael@0 217
michael@0 218 HRESULT
michael@0 219 AudioSinkFilter::GetCurrentPosition(LONGLONG* aCurrent)
michael@0 220 {
michael@0 221 ENSURE_CONNECTED_PIN_SEEKING
michael@0 222 return pinSeeking->GetCurrentPosition(aCurrent);
michael@0 223 }
michael@0 224
michael@0 225 HRESULT
michael@0 226 AudioSinkFilter::ConvertTimeFormat(LONGLONG* aTarget,
michael@0 227 const GUID* aTargetFormat,
michael@0 228 LONGLONG aSource,
michael@0 229 const GUID* aSourceFormat)
michael@0 230 {
michael@0 231 ENSURE_CONNECTED_PIN_SEEKING
michael@0 232 return pinSeeking->ConvertTimeFormat(aTarget,
michael@0 233 aTargetFormat,
michael@0 234 aSource,
michael@0 235 aSourceFormat);
michael@0 236 }
michael@0 237
michael@0 238 HRESULT
michael@0 239 AudioSinkFilter::SetPositions(LONGLONG* aCurrent,
michael@0 240 DWORD aCurrentFlags,
michael@0 241 LONGLONG* aStop,
michael@0 242 DWORD aStopFlags)
michael@0 243 {
michael@0 244 ENSURE_CONNECTED_PIN_SEEKING
michael@0 245 return pinSeeking->SetPositions(aCurrent,
michael@0 246 aCurrentFlags,
michael@0 247 aStop,
michael@0 248 aStopFlags);
michael@0 249 }
michael@0 250
michael@0 251 HRESULT
michael@0 252 AudioSinkFilter::GetPositions(LONGLONG* aCurrent,
michael@0 253 LONGLONG* aStop)
michael@0 254 {
michael@0 255 ENSURE_CONNECTED_PIN_SEEKING
michael@0 256 return pinSeeking->GetPositions(aCurrent, aStop);
michael@0 257 }
michael@0 258
michael@0 259 HRESULT
michael@0 260 AudioSinkFilter::GetAvailable(LONGLONG* aEarliest,
michael@0 261 LONGLONG* aLatest)
michael@0 262 {
michael@0 263 ENSURE_CONNECTED_PIN_SEEKING
michael@0 264 return pinSeeking->GetAvailable(aEarliest, aLatest);
michael@0 265 }
michael@0 266
michael@0 267 HRESULT
michael@0 268 AudioSinkFilter::SetRate(double aRate)
michael@0 269 {
michael@0 270 ENSURE_CONNECTED_PIN_SEEKING
michael@0 271 return pinSeeking->SetRate(aRate);
michael@0 272 }
michael@0 273
michael@0 274 HRESULT
michael@0 275 AudioSinkFilter::GetRate(double* aRate)
michael@0 276 {
michael@0 277 ENSURE_CONNECTED_PIN_SEEKING
michael@0 278 return pinSeeking->GetRate(aRate);
michael@0 279 }
michael@0 280
michael@0 281 HRESULT
michael@0 282 AudioSinkFilter::GetPreroll(LONGLONG* aPreroll)
michael@0 283 {
michael@0 284 ENSURE_CONNECTED_PIN_SEEKING
michael@0 285 return pinSeeking->GetPreroll(aPreroll);
michael@0 286 }
michael@0 287
michael@0 288 } // namespace mozilla
michael@0 289

mercurial