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