content/media/directshow/AudioSinkFilter.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/media/directshow/AudioSinkFilter.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,289 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#include "SampleSink.h"
    1.11 +#include "AudioSinkFilter.h"
    1.12 +#include "AudioSinkInputPin.h"
    1.13 +#include "VideoUtils.h"
    1.14 +#include "prlog.h"
    1.15 +
    1.16 +
    1.17 +#include <initguid.h>
    1.18 +#include <wmsdkidl.h>
    1.19 +
    1.20 +#define DELETE_RESET(p) { delete (p) ; (p) = nullptr ;}
    1.21 +
    1.22 +DEFINE_GUID(CLSID_MozAudioSinkFilter, 0x1872d8c8, 0xea8d, 0x4c34, 0xae, 0x96, 0x69, 0xde,
    1.23 +            0xf1, 0x33, 0x7b, 0x33);
    1.24 +
    1.25 +using namespace mozilla::media;
    1.26 +
    1.27 +namespace mozilla {
    1.28 +
    1.29 +#ifdef PR_LOGGING
    1.30 +PRLogModuleInfo* GetDirectShowLog();
    1.31 +#define LOG(...) PR_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
    1.32 +#else
    1.33 +#define LOG(...)
    1.34 +#endif
    1.35 +
    1.36 +AudioSinkFilter::AudioSinkFilter(const wchar_t* aObjectName, HRESULT* aOutResult)
    1.37 +  : BaseFilter(aObjectName, CLSID_MozAudioSinkFilter),
    1.38 +    mFilterCritSec("AudioSinkFilter::mFilterCritSec")
    1.39 +{
    1.40 +  (*aOutResult) = S_OK;
    1.41 +  mInputPin = new AudioSinkInputPin(L"AudioSinkInputPin",
    1.42 +                                    this,
    1.43 +                                    &mFilterCritSec,
    1.44 +                                    aOutResult);
    1.45 +}
    1.46 +
    1.47 +AudioSinkFilter::~AudioSinkFilter()
    1.48 +{
    1.49 +}
    1.50 +
    1.51 +int
    1.52 +AudioSinkFilter::GetPinCount()
    1.53 +{
    1.54 +  return 1;
    1.55 +}
    1.56 +
    1.57 +BasePin*
    1.58 +AudioSinkFilter::GetPin(int aIndex)
    1.59 +{
    1.60 +  CriticalSectionAutoEnter lockFilter(mFilterCritSec);
    1.61 +  return (aIndex == 0) ? static_cast<BasePin*>(mInputPin) : nullptr;
    1.62 +}
    1.63 +
    1.64 +HRESULT
    1.65 +AudioSinkFilter::Pause()
    1.66 +{
    1.67 +  CriticalSectionAutoEnter lockFilter(mFilterCritSec);
    1.68 +  if (mState == State_Stopped) {
    1.69 +    //  Change the state, THEN activate the input pin.
    1.70 +    mState = State_Paused;
    1.71 +    if (mInputPin && mInputPin->IsConnected()) {
    1.72 +      mInputPin->Active();
    1.73 +    }
    1.74 +  } else if (mState == State_Running) {
    1.75 +    mState = State_Paused;
    1.76 +  }
    1.77 +  return S_OK;
    1.78 +}
    1.79 +
    1.80 +HRESULT
    1.81 +AudioSinkFilter::Stop()
    1.82 +{
    1.83 +  CriticalSectionAutoEnter lockFilter(mFilterCritSec);
    1.84 +  mState = State_Stopped;
    1.85 +  if (mInputPin) {
    1.86 +    mInputPin->Inactive();
    1.87 +  }
    1.88 +
    1.89 +  GetSampleSink()->Flush();
    1.90 +
    1.91 +  return S_OK;
    1.92 +}
    1.93 +
    1.94 +HRESULT
    1.95 +AudioSinkFilter::Run(REFERENCE_TIME tStart)
    1.96 +{
    1.97 +  LOG("AudioSinkFilter::Run(%lld) [%4.2lf]",
    1.98 +      RefTimeToUsecs(tStart),
    1.99 +      double(RefTimeToUsecs(tStart)) / USECS_PER_S);
   1.100 +  return media::BaseFilter::Run(tStart);
   1.101 +}
   1.102 +
   1.103 +HRESULT
   1.104 +AudioSinkFilter::GetClassID( OUT CLSID * pCLSID )
   1.105 +{
   1.106 +  (* pCLSID) = CLSID_MozAudioSinkFilter;
   1.107 +  return S_OK;
   1.108 +}
   1.109 +
   1.110 +HRESULT
   1.111 +AudioSinkFilter::QueryInterface(REFIID aIId, void **aInterface)
   1.112 +{
   1.113 +  if (aIId == IID_IMediaSeeking) {
   1.114 +    *aInterface = static_cast<IMediaSeeking*>(this);
   1.115 +    AddRef();
   1.116 +    return S_OK;
   1.117 +  }
   1.118 +  return mozilla::media::BaseFilter::QueryInterface(aIId, aInterface);
   1.119 +}
   1.120 +
   1.121 +ULONG
   1.122 +AudioSinkFilter::AddRef()
   1.123 +{
   1.124 +  return ::InterlockedIncrement(&mRefCnt);
   1.125 +}
   1.126 +
   1.127 +ULONG
   1.128 +AudioSinkFilter::Release()
   1.129 +{
   1.130 +  unsigned long newRefCnt = ::InterlockedDecrement(&mRefCnt);
   1.131 +  if (!newRefCnt) {
   1.132 +    delete this;
   1.133 +  }
   1.134 +  return newRefCnt;
   1.135 +}
   1.136 +
   1.137 +SampleSink*
   1.138 +AudioSinkFilter::GetSampleSink()
   1.139 +{
   1.140 +  return mInputPin->GetSampleSink();
   1.141 +}
   1.142 +
   1.143 +
   1.144 +// IMediaSeeking implementation.
   1.145 +//
   1.146 +// Calls to IMediaSeeking are forwarded to the output pin that the
   1.147 +// AudioSinkInputPin is connected to, i.e. upstream towards the parser and
   1.148 +// source filters, which actually implement seeking.
   1.149 +#define ENSURE_CONNECTED_PIN_SEEKING \
   1.150 +  if (!mInputPin) { \
   1.151 +    return E_NOTIMPL; \
   1.152 +  } \
   1.153 +  RefPtr<IMediaSeeking> pinSeeking = mInputPin->GetConnectedPinSeeking(); \
   1.154 +  if (!pinSeeking) { \
   1.155 +    return E_NOTIMPL; \
   1.156 +  }
   1.157 +
   1.158 +HRESULT
   1.159 +AudioSinkFilter::GetCapabilities(DWORD* aCapabilities)
   1.160 +{
   1.161 +  ENSURE_CONNECTED_PIN_SEEKING
   1.162 +  return pinSeeking->GetCapabilities(aCapabilities);
   1.163 +}
   1.164 +
   1.165 +HRESULT
   1.166 +AudioSinkFilter::CheckCapabilities(DWORD* aCapabilities)
   1.167 +{
   1.168 +  ENSURE_CONNECTED_PIN_SEEKING
   1.169 +  return pinSeeking->CheckCapabilities(aCapabilities);
   1.170 +}
   1.171 +
   1.172 +HRESULT
   1.173 +AudioSinkFilter::IsFormatSupported(const GUID* aFormat)
   1.174 +{
   1.175 +  ENSURE_CONNECTED_PIN_SEEKING
   1.176 +  return pinSeeking->IsFormatSupported(aFormat);
   1.177 +}
   1.178 +
   1.179 +HRESULT
   1.180 +AudioSinkFilter::QueryPreferredFormat(GUID* aFormat)
   1.181 +{
   1.182 +  ENSURE_CONNECTED_PIN_SEEKING
   1.183 +  return pinSeeking->QueryPreferredFormat(aFormat);
   1.184 +}
   1.185 +
   1.186 +HRESULT
   1.187 +AudioSinkFilter::GetTimeFormat(GUID* aFormat)
   1.188 +{
   1.189 +  ENSURE_CONNECTED_PIN_SEEKING
   1.190 +  return pinSeeking->GetTimeFormat(aFormat);
   1.191 +}
   1.192 +
   1.193 +HRESULT
   1.194 +AudioSinkFilter::IsUsingTimeFormat(const GUID* aFormat)
   1.195 +{
   1.196 +  ENSURE_CONNECTED_PIN_SEEKING
   1.197 +  return pinSeeking->IsUsingTimeFormat(aFormat);
   1.198 +}
   1.199 +
   1.200 +HRESULT
   1.201 +AudioSinkFilter::SetTimeFormat(const GUID* aFormat)
   1.202 +{
   1.203 +  ENSURE_CONNECTED_PIN_SEEKING
   1.204 +  return pinSeeking->SetTimeFormat(aFormat);
   1.205 +}
   1.206 +
   1.207 +HRESULT
   1.208 +AudioSinkFilter::GetDuration(LONGLONG* aDuration)
   1.209 +{
   1.210 +  ENSURE_CONNECTED_PIN_SEEKING
   1.211 +  return pinSeeking->GetDuration(aDuration);
   1.212 +}
   1.213 +
   1.214 +HRESULT
   1.215 +AudioSinkFilter::GetStopPosition(LONGLONG* aStop)
   1.216 +{
   1.217 +  ENSURE_CONNECTED_PIN_SEEKING
   1.218 +  return pinSeeking->GetStopPosition(aStop);
   1.219 +}
   1.220 +
   1.221 +HRESULT
   1.222 +AudioSinkFilter::GetCurrentPosition(LONGLONG* aCurrent)
   1.223 +{
   1.224 +  ENSURE_CONNECTED_PIN_SEEKING
   1.225 +  return pinSeeking->GetCurrentPosition(aCurrent);
   1.226 +}
   1.227 +
   1.228 +HRESULT
   1.229 +AudioSinkFilter::ConvertTimeFormat(LONGLONG* aTarget,
   1.230 +                                   const GUID* aTargetFormat,
   1.231 +                                   LONGLONG aSource,
   1.232 +                                   const GUID* aSourceFormat)
   1.233 +{
   1.234 +  ENSURE_CONNECTED_PIN_SEEKING
   1.235 +  return pinSeeking->ConvertTimeFormat(aTarget,
   1.236 +                                       aTargetFormat,
   1.237 +                                       aSource,
   1.238 +                                       aSourceFormat);
   1.239 +}
   1.240 +
   1.241 +HRESULT
   1.242 +AudioSinkFilter::SetPositions(LONGLONG* aCurrent,
   1.243 +                              DWORD aCurrentFlags,
   1.244 +                              LONGLONG* aStop,
   1.245 +                              DWORD aStopFlags)
   1.246 +{
   1.247 +  ENSURE_CONNECTED_PIN_SEEKING
   1.248 +  return pinSeeking->SetPositions(aCurrent,
   1.249 +                                  aCurrentFlags,
   1.250 +                                  aStop,
   1.251 +                                  aStopFlags);
   1.252 +}
   1.253 +
   1.254 +HRESULT
   1.255 +AudioSinkFilter::GetPositions(LONGLONG* aCurrent,
   1.256 +                              LONGLONG* aStop)
   1.257 +{
   1.258 +  ENSURE_CONNECTED_PIN_SEEKING
   1.259 +  return pinSeeking->GetPositions(aCurrent, aStop);
   1.260 +}
   1.261 +
   1.262 +HRESULT
   1.263 +AudioSinkFilter::GetAvailable(LONGLONG* aEarliest,
   1.264 +                              LONGLONG* aLatest)
   1.265 +{
   1.266 +  ENSURE_CONNECTED_PIN_SEEKING
   1.267 +  return pinSeeking->GetAvailable(aEarliest, aLatest);
   1.268 +}
   1.269 +
   1.270 +HRESULT
   1.271 +AudioSinkFilter::SetRate(double aRate)
   1.272 +{
   1.273 +  ENSURE_CONNECTED_PIN_SEEKING
   1.274 +  return pinSeeking->SetRate(aRate);
   1.275 +}
   1.276 +
   1.277 +HRESULT
   1.278 +AudioSinkFilter::GetRate(double* aRate)
   1.279 +{
   1.280 +  ENSURE_CONNECTED_PIN_SEEKING
   1.281 +  return pinSeeking->GetRate(aRate);
   1.282 +}
   1.283 +
   1.284 +HRESULT
   1.285 +AudioSinkFilter::GetPreroll(LONGLONG* aPreroll)
   1.286 +{
   1.287 +  ENSURE_CONNECTED_PIN_SEEKING
   1.288 +  return pinSeeking->GetPreroll(aPreroll);
   1.289 +}
   1.290 +
   1.291 +} // namespace mozilla
   1.292 +

mercurial