content/media/directshow/AudioSinkInputPin.cpp

Fri, 16 Jan 2015 04:50:19 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 04:50:19 +0100
branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
permissions
-rw-r--r--

Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32

     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 "AudioSinkInputPin.h"
     8 #include "AudioSinkFilter.h"
     9 #include "SampleSink.h"
    10 #include "prlog.h"
    12 #include <wmsdkidl.h>
    14 using namespace mozilla::media;
    16 namespace mozilla {
    18 #ifdef PR_LOGGING
    19 PRLogModuleInfo* GetDirectShowLog();
    20 #define LOG(...) PR_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
    21 #else
    22 #define LOG(...)
    23 #endif
    25 AudioSinkInputPin::AudioSinkInputPin(wchar_t* aObjectName,
    26                                      AudioSinkFilter* aFilter,
    27                                      mozilla::CriticalSection* aLock,
    28                                      HRESULT* aOutResult)
    29   : BaseInputPin(aObjectName, aFilter, aLock, aOutResult, aObjectName),
    30     mSegmentStartTime(0)
    31 {
    32   MOZ_COUNT_CTOR(AudioSinkInputPin);
    33   mSampleSink = new SampleSink();
    34 }
    36 AudioSinkInputPin::~AudioSinkInputPin()
    37 {
    38   MOZ_COUNT_DTOR(AudioSinkInputPin);
    39 }
    41 HRESULT
    42 AudioSinkInputPin::GetMediaType(int aPosition, MediaType* aOutMediaType)
    43 {
    44   NS_ENSURE_TRUE(aPosition >= 0, E_INVALIDARG);
    45   NS_ENSURE_TRUE(aOutMediaType, E_POINTER);
    47   if (aPosition > 0) {
    48     return S_FALSE;
    49   }
    51   // Note: We set output as PCM, as IEEE_FLOAT only works when using the
    52   // MP3 decoder as an MFT, and we can't do that while using DirectShow.
    53   aOutMediaType->SetType(&MEDIATYPE_Audio);
    54   aOutMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
    55   aOutMediaType->SetType(&FORMAT_WaveFormatEx);
    56   aOutMediaType->SetTemporalCompression(FALSE);
    58   return S_OK;
    59 }
    61 HRESULT
    62 AudioSinkInputPin::CheckMediaType(const MediaType* aMediaType)
    63 {
    64   if (!aMediaType) {
    65     return E_INVALIDARG;
    66   }
    68   GUID majorType = *aMediaType->Type();
    69   if (majorType != MEDIATYPE_Audio && majorType != WMMEDIATYPE_Audio) {
    70     return E_INVALIDARG;
    71   }
    73   if (*aMediaType->Subtype() != MEDIASUBTYPE_PCM) {
    74     return E_INVALIDARG;
    75   }
    77   if (*aMediaType->FormatType() != FORMAT_WaveFormatEx) {
    78     return E_INVALIDARG;
    79   }
    81   // We accept the media type, stash its layout format!
    82   WAVEFORMATEX* wfx = (WAVEFORMATEX*)(aMediaType->pbFormat);
    83   GetSampleSink()->SetAudioFormat(wfx);
    85   return S_OK;
    86 }
    88 AudioSinkFilter*
    89 AudioSinkInputPin::GetAudioSinkFilter()
    90 {
    91   return reinterpret_cast<AudioSinkFilter*>(mFilter);
    92 }
    94 SampleSink*
    95 AudioSinkInputPin::GetSampleSink()
    96 {
    97   return mSampleSink;
    98 }
   100 HRESULT
   101 AudioSinkInputPin::SetAbsoluteMediaTime(IMediaSample* aSample)
   102 {
   103   HRESULT hr;
   104   REFERENCE_TIME start = 0, end = 0;
   105   hr = aSample->GetTime(&start, &end);
   106   NS_ENSURE_TRUE(SUCCEEDED(hr), E_FAIL);
   107   {
   108     CriticalSectionAutoEnter lock(*mLock);
   109     start += mSegmentStartTime;
   110     end += mSegmentStartTime;
   111   }
   112   hr = aSample->SetMediaTime(&start, &end);
   113   NS_ENSURE_TRUE(SUCCEEDED(hr), E_FAIL);
   114   return S_OK;
   115 }
   117 HRESULT
   118 AudioSinkInputPin::Receive(IMediaSample* aSample )
   119 {
   120   HRESULT hr;
   121   NS_ENSURE_TRUE(aSample, E_POINTER);
   123   hr = BaseInputPin::Receive(aSample);
   124   if (SUCCEEDED(hr) && hr != S_FALSE) { // S_FALSE == flushing
   125     // Set the timestamp of the sample after being adjusted for
   126     // seeking/segments in the "media time" attribute. When we seek,
   127     // DirectShow starts a new "segment", and starts labeling samples
   128     // from time=0 again, so we need to correct for this to get the
   129     // actual timestamps after seeking.
   130     hr = SetAbsoluteMediaTime(aSample);
   131     NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
   132     hr = GetSampleSink()->Receive(aSample);
   133     NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
   134   }
   135   return S_OK;
   136 }
   138 TemporaryRef<IMediaSeeking>
   139 AudioSinkInputPin::GetConnectedPinSeeking()
   140 {
   141   RefPtr<IPin> peer = GetConnected();
   142   if (!peer)
   143     return nullptr;
   144   RefPtr<IMediaSeeking> seeking;
   145   peer->QueryInterface(static_cast<IMediaSeeking**>(byRef(seeking)));
   146   return seeking;
   147 }
   149 HRESULT
   150 AudioSinkInputPin::BeginFlush()
   151 {
   152   HRESULT hr = media::BaseInputPin::BeginFlush();
   153   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
   155   GetSampleSink()->Flush();
   157   return S_OK;
   158 }
   160 HRESULT
   161 AudioSinkInputPin::EndFlush()
   162 {
   163   HRESULT hr = media::BaseInputPin::EndFlush();
   164   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
   166   // Reset the EOS flag, so that if we're called after a seek we still work.
   167   GetSampleSink()->Reset();
   169   return S_OK;
   170 }
   172 HRESULT
   173 AudioSinkInputPin::EndOfStream(void)
   174 {
   175   HRESULT hr = media::BaseInputPin::EndOfStream();
   176   if (FAILED(hr) || hr == S_FALSE) {
   177     // Pin is stil flushing.
   178     return hr;
   179   }
   180   GetSampleSink()->SetEOS();
   182   return S_OK;
   183 }
   186 HRESULT
   187 AudioSinkInputPin::NewSegment(REFERENCE_TIME tStart,
   188                               REFERENCE_TIME tStop,
   189                               double dRate)
   190 {
   191   CriticalSectionAutoEnter lock(*mLock);
   192   // Record the start time of the new segment, so that we can store the
   193   // correct absolute timestamp in the "media time" each incoming sample.
   194   mSegmentStartTime = tStart;
   195   return S_OK;
   196 }
   198 } // namespace mozilla

mercurial