content/media/directshow/SampleSink.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

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 using namespace mozilla::media;
michael@0 14
michael@0 15 namespace mozilla {
michael@0 16
michael@0 17 #ifdef PR_LOGGING
michael@0 18 PRLogModuleInfo* GetDirectShowLog();
michael@0 19 #define LOG(...) PR_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
michael@0 20 #else
michael@0 21 #define LOG(...)
michael@0 22 #endif
michael@0 23
michael@0 24 SampleSink::SampleSink()
michael@0 25 : mMonitor("SampleSink"),
michael@0 26 mIsFlushing(false),
michael@0 27 mAtEOS(false)
michael@0 28 {
michael@0 29 MOZ_COUNT_CTOR(SampleSink);
michael@0 30 }
michael@0 31
michael@0 32 SampleSink::~SampleSink()
michael@0 33 {
michael@0 34 MOZ_COUNT_DTOR(SampleSink);
michael@0 35 }
michael@0 36
michael@0 37 void
michael@0 38 SampleSink::SetAudioFormat(const WAVEFORMATEX* aInFormat)
michael@0 39 {
michael@0 40 NS_ENSURE_TRUE(aInFormat, );
michael@0 41 ReentrantMonitorAutoEnter mon(mMonitor);
michael@0 42 memcpy(&mAudioFormat, aInFormat, sizeof(WAVEFORMATEX));
michael@0 43 }
michael@0 44
michael@0 45 void
michael@0 46 SampleSink::GetAudioFormat(WAVEFORMATEX* aOutFormat)
michael@0 47 {
michael@0 48 MOZ_ASSERT(aOutFormat);
michael@0 49 ReentrantMonitorAutoEnter mon(mMonitor);
michael@0 50 memcpy(aOutFormat, &mAudioFormat, sizeof(WAVEFORMATEX));
michael@0 51 }
michael@0 52
michael@0 53 HRESULT
michael@0 54 SampleSink::Receive(IMediaSample* aSample)
michael@0 55 {
michael@0 56 ReentrantMonitorAutoEnter mon(mMonitor);
michael@0 57
michael@0 58 while (true) {
michael@0 59 if (mIsFlushing) {
michael@0 60 return S_FALSE;
michael@0 61 }
michael@0 62 if (!mSample) {
michael@0 63 break;
michael@0 64 }
michael@0 65 if (mAtEOS) {
michael@0 66 return E_UNEXPECTED;
michael@0 67 }
michael@0 68 // Wait until the consumer thread consumes the sample.
michael@0 69 mon.Wait();
michael@0 70 }
michael@0 71
michael@0 72 #ifdef PR_LOGGING
michael@0 73 REFERENCE_TIME start = 0, end = 0;
michael@0 74 HRESULT hr = aSample->GetMediaTime(&start, &end);
michael@0 75 LOG("SampleSink::Receive() [%4.2lf-%4.2lf]",
michael@0 76 (double)RefTimeToUsecs(start) / USECS_PER_S,
michael@0 77 (double)RefTimeToUsecs(end) / USECS_PER_S);
michael@0 78 #endif
michael@0 79
michael@0 80 mSample = aSample;
michael@0 81 // Notify the signal, to awaken the consumer thread in WaitForSample()
michael@0 82 // if necessary.
michael@0 83 mon.NotifyAll();
michael@0 84 return S_OK;
michael@0 85 }
michael@0 86
michael@0 87 HRESULT
michael@0 88 SampleSink::Extract(RefPtr<IMediaSample>& aOutSample)
michael@0 89 {
michael@0 90 ReentrantMonitorAutoEnter mon(mMonitor);
michael@0 91 // Loop until we have a sample, or we should abort.
michael@0 92 while (true) {
michael@0 93 if (mIsFlushing) {
michael@0 94 return S_FALSE;
michael@0 95 }
michael@0 96 if (mSample) {
michael@0 97 break;
michael@0 98 }
michael@0 99 if (mAtEOS) {
michael@0 100 // Order is important here, if we have a sample, we should return it
michael@0 101 // before reporting EOS.
michael@0 102 return E_UNEXPECTED;
michael@0 103 }
michael@0 104 // Wait until the producer thread gives us a sample.
michael@0 105 mon.Wait();
michael@0 106 }
michael@0 107 aOutSample = mSample;
michael@0 108
michael@0 109 #ifdef PR_LOGGING
michael@0 110 int64_t start = 0, end = 0;
michael@0 111 mSample->GetMediaTime(&start, &end);
michael@0 112 LOG("SampleSink::Extract() [%4.2lf-%4.2lf]",
michael@0 113 (double)RefTimeToUsecs(start) / USECS_PER_S,
michael@0 114 (double)RefTimeToUsecs(end) / USECS_PER_S);
michael@0 115 #endif
michael@0 116
michael@0 117 mSample = nullptr;
michael@0 118 // Notify the signal, to awaken the producer thread in Receive()
michael@0 119 // if necessary.
michael@0 120 mon.NotifyAll();
michael@0 121 return S_OK;
michael@0 122 }
michael@0 123
michael@0 124 void
michael@0 125 SampleSink::Flush()
michael@0 126 {
michael@0 127 LOG("SampleSink::Flush()");
michael@0 128 ReentrantMonitorAutoEnter mon(mMonitor);
michael@0 129 mIsFlushing = true;
michael@0 130 mSample = nullptr;
michael@0 131 mon.NotifyAll();
michael@0 132 }
michael@0 133
michael@0 134 void
michael@0 135 SampleSink::Reset()
michael@0 136 {
michael@0 137 LOG("SampleSink::Reset()");
michael@0 138 ReentrantMonitorAutoEnter mon(mMonitor);
michael@0 139 mIsFlushing = false;
michael@0 140 mAtEOS = false;
michael@0 141 }
michael@0 142
michael@0 143 void
michael@0 144 SampleSink::SetEOS()
michael@0 145 {
michael@0 146 LOG("SampleSink::SetEOS()");
michael@0 147 ReentrantMonitorAutoEnter mon(mMonitor);
michael@0 148 mAtEOS = true;
michael@0 149 // Notify to unblock any threads waiting for samples in
michael@0 150 // Extract() or Receive(). Now that we're at EOS, no more samples
michael@0 151 // will come!
michael@0 152 mon.NotifyAll();
michael@0 153 }
michael@0 154
michael@0 155 bool
michael@0 156 SampleSink::AtEOS()
michael@0 157 {
michael@0 158 ReentrantMonitorAutoEnter mon(mMonitor);
michael@0 159 return mAtEOS && !mSample;
michael@0 160 }
michael@0 161
michael@0 162 } // namespace mozilla
michael@0 163

mercurial