summaryrefslogtreecommitdiffstats
path: root/dom
diff options
context:
space:
mode:
Diffstat (limited to 'dom')
-rw-r--r--dom/media/DecoderTraits.cpp40
-rw-r--r--dom/media/ThreadPoolCOMListener.h4
-rw-r--r--dom/media/directshow/AudioSinkFilter.cpp285
-rw-r--r--dom/media/directshow/AudioSinkFilter.h95
-rw-r--r--dom/media/directshow/AudioSinkInputPin.cpp195
-rw-r--r--dom/media/directshow/AudioSinkInputPin.h76
-rw-r--r--dom/media/directshow/DirectShowDecoder.cpp65
-rw-r--r--dom/media/directshow/DirectShowDecoder.h45
-rw-r--r--dom/media/directshow/DirectShowReader.cpp360
-rw-r--r--dom/media/directshow/DirectShowReader.h110
-rw-r--r--dom/media/directshow/DirectShowUtils.cpp369
-rw-r--r--dom/media/directshow/DirectShowUtils.h125
-rw-r--r--dom/media/directshow/SampleSink.cpp159
-rw-r--r--dom/media/directshow/SampleSink.h67
-rw-r--r--dom/media/directshow/SourceFilter.cpp683
-rw-r--r--dom/media/directshow/SourceFilter.h75
-rw-r--r--dom/media/directshow/moz.build41
-rw-r--r--dom/media/moz.build8
-rw-r--r--dom/media/test/manifest.js4
-rw-r--r--dom/media/test/test_can_play_type_mpeg.html3
20 files changed, 6 insertions, 2803 deletions
diff --git a/dom/media/DecoderTraits.cpp b/dom/media/DecoderTraits.cpp
index 56ebd9ce9..473ca9533 100644
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -23,10 +23,6 @@
#include "AndroidMediaReader.h"
#include "AndroidMediaPluginHost.h"
#endif
-#ifdef MOZ_DIRECTSHOW
-#include "DirectShowDecoder.h"
-#include "DirectShowReader.h"
-#endif
#ifdef MOZ_FMP4
#include "MP4Decoder.h"
#include "MP4Demuxer.h"
@@ -125,14 +121,6 @@ IsAndroidMediaType(const nsACString& aType)
}
#endif
-#ifdef MOZ_DIRECTSHOW
-static bool
-IsDirectShowSupportedType(const nsACString& aType)
-{
- return DirectShowDecoder::GetSupportedCodecs(aType, nullptr);
-}
-#endif
-
#ifdef MOZ_FMP4
static bool
IsMP4SupportedType(const MediaContentType& aParsedType,
@@ -247,9 +235,6 @@ CanHandleCodecsType(const MediaContentType& aType,
if (IsFlacSupportedType(aType.GetMIMEType(), aType.GetCodecs())) {
return CANPLAY_YES;
}
-#ifdef MOZ_DIRECTSHOW
- DirectShowDecoder::GetSupportedCodecs(aType.GetMIMEType(), &codecList);
-#endif
#ifdef MOZ_ANDROID_OMX
if (MediaDecoder::IsAndroidMediaPluginEnabled()) {
EnsureAndroidMediaPluginHost()->FindDecoder(aType.GetMIMEType(), &codecList);
@@ -320,11 +305,6 @@ CanHandleMediaType(const MediaContentType& aType,
if (IsFlacSupportedType(aType.GetMIMEType())) {
return CANPLAY_MAYBE;
}
-#ifdef MOZ_DIRECTSHOW
- if (DirectShowDecoder::GetSupportedCodecs(aType.GetMIMEType(), nullptr)) {
- return CANPLAY_MAYBE;
- }
-#endif
#ifdef MOZ_ANDROID_OMX
if (MediaDecoder::IsAndroidMediaPluginEnabled() &&
EnsureAndroidMediaPluginHost()->FindDecoder(aType.GetMIMEType(), nullptr)) {
@@ -424,15 +404,6 @@ InstantiateDecoder(const nsACString& aType,
return decoder.forget();
}
-#ifdef MOZ_DIRECTSHOW
- // Note: DirectShow should come before WMF, so that we prefer DirectShow's
- // MP3 support over WMF's.
- if (IsDirectShowSupportedType(aType)) {
- decoder = new DirectShowDecoder(aOwner);
- return decoder.forget();
- }
-#endif
-
return nullptr;
}
@@ -484,13 +455,7 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac
if (IsWebMSupportedType(aType)) {
decoderReader =
new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()));
- } else
-#ifdef MOZ_DIRECTSHOW
- if (IsDirectShowSupportedType(aType)) {
- decoderReader = new DirectShowReader(aDecoder);
- } else
-#endif
- if (false) {} // dummy if to take care of the dangling else
+ }
return decoderReader;
}
@@ -518,9 +483,6 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
IsMP3SupportedType(aType) ||
IsAACSupportedType(aType) ||
IsFlacSupportedType(aType) ||
-#ifdef MOZ_DIRECTSHOW
- IsDirectShowSupportedType(aType) ||
-#endif
false;
}
diff --git a/dom/media/ThreadPoolCOMListener.h b/dom/media/ThreadPoolCOMListener.h
index 881013a78..424ca65d2 100644
--- a/dom/media/ThreadPoolCOMListener.h
+++ b/dom/media/ThreadPoolCOMListener.h
@@ -13,8 +13,8 @@
namespace mozilla {
// Thread pool listener which ensures that MSCOM is initialized and
-// deinitialized on the thread pool thread. We may call into WMF or
-// DirectShow on this thread, so we need MSCOM working.
+// deinitialized on the thread pool thread. We may call into WMF on
+// this thread, so we need MSCOM working.
class MSCOMInitThreadPoolListener final : public nsIThreadPoolListener {
~MSCOMInitThreadPoolListener() {}
public:
diff --git a/dom/media/directshow/AudioSinkFilter.cpp b/dom/media/directshow/AudioSinkFilter.cpp
deleted file mode 100644
index 9f23c0e00..000000000
--- a/dom/media/directshow/AudioSinkFilter.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SampleSink.h"
-#include "AudioSinkFilter.h"
-#include "AudioSinkInputPin.h"
-#include "VideoUtils.h"
-#include "mozilla/Logging.h"
-
-
-#include <initguid.h>
-#include <wmsdkidl.h>
-
-#define DELETE_RESET(p) { delete (p) ; (p) = nullptr ;}
-
-DEFINE_GUID(CLSID_MozAudioSinkFilter, 0x1872d8c8, 0xea8d, 0x4c34, 0xae, 0x96, 0x69, 0xde,
- 0xf1, 0x33, 0x7b, 0x33);
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-AudioSinkFilter::AudioSinkFilter(const wchar_t* aObjectName, HRESULT* aOutResult)
- : BaseFilter(aObjectName, CLSID_MozAudioSinkFilter),
- mFilterCritSec("AudioSinkFilter::mFilterCritSec")
-{
- (*aOutResult) = S_OK;
- mInputPin = new AudioSinkInputPin(L"AudioSinkInputPin",
- this,
- &mFilterCritSec,
- aOutResult);
-}
-
-AudioSinkFilter::~AudioSinkFilter()
-{
-}
-
-int
-AudioSinkFilter::GetPinCount()
-{
- return 1;
-}
-
-BasePin*
-AudioSinkFilter::GetPin(int aIndex)
-{
- CriticalSectionAutoEnter lockFilter(mFilterCritSec);
- return (aIndex == 0) ? static_cast<BasePin*>(mInputPin) : nullptr;
-}
-
-HRESULT
-AudioSinkFilter::Pause()
-{
- CriticalSectionAutoEnter lockFilter(mFilterCritSec);
- if (mState == State_Stopped) {
- // Change the state, THEN activate the input pin.
- mState = State_Paused;
- if (mInputPin && mInputPin->IsConnected()) {
- mInputPin->Active();
- }
- } else if (mState == State_Running) {
- mState = State_Paused;
- }
- return S_OK;
-}
-
-HRESULT
-AudioSinkFilter::Stop()
-{
- CriticalSectionAutoEnter lockFilter(mFilterCritSec);
- mState = State_Stopped;
- if (mInputPin) {
- mInputPin->Inactive();
- }
-
- GetSampleSink()->Flush();
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkFilter::Run(REFERENCE_TIME tStart)
-{
- LOG("AudioSinkFilter::Run(%lld) [%4.2lf]",
- RefTimeToUsecs(tStart),
- double(RefTimeToUsecs(tStart)) / USECS_PER_S);
- return media::BaseFilter::Run(tStart);
-}
-
-HRESULT
-AudioSinkFilter::GetClassID( OUT CLSID * pCLSID )
-{
- (* pCLSID) = CLSID_MozAudioSinkFilter;
- return S_OK;
-}
-
-HRESULT
-AudioSinkFilter::QueryInterface(REFIID aIId, void **aInterface)
-{
- if (aIId == IID_IMediaSeeking) {
- *aInterface = static_cast<IMediaSeeking*>(this);
- AddRef();
- return S_OK;
- }
- return mozilla::media::BaseFilter::QueryInterface(aIId, aInterface);
-}
-
-ULONG
-AudioSinkFilter::AddRef()
-{
- return ::InterlockedIncrement(&mRefCnt);
-}
-
-ULONG
-AudioSinkFilter::Release()
-{
- unsigned long newRefCnt = ::InterlockedDecrement(&mRefCnt);
- if (!newRefCnt) {
- delete this;
- }
- return newRefCnt;
-}
-
-SampleSink*
-AudioSinkFilter::GetSampleSink()
-{
- return mInputPin->GetSampleSink();
-}
-
-
-// IMediaSeeking implementation.
-//
-// Calls to IMediaSeeking are forwarded to the output pin that the
-// AudioSinkInputPin is connected to, i.e. upstream towards the parser and
-// source filters, which actually implement seeking.
-#define ENSURE_CONNECTED_PIN_SEEKING \
- if (!mInputPin) { \
- return E_NOTIMPL; \
- } \
- RefPtr<IMediaSeeking> pinSeeking = mInputPin->GetConnectedPinSeeking(); \
- if (!pinSeeking) { \
- return E_NOTIMPL; \
- }
-
-HRESULT
-AudioSinkFilter::GetCapabilities(DWORD* aCapabilities)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetCapabilities(aCapabilities);
-}
-
-HRESULT
-AudioSinkFilter::CheckCapabilities(DWORD* aCapabilities)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->CheckCapabilities(aCapabilities);
-}
-
-HRESULT
-AudioSinkFilter::IsFormatSupported(const GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->IsFormatSupported(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::QueryPreferredFormat(GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->QueryPreferredFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::GetTimeFormat(GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetTimeFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::IsUsingTimeFormat(const GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->IsUsingTimeFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::SetTimeFormat(const GUID* aFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->SetTimeFormat(aFormat);
-}
-
-HRESULT
-AudioSinkFilter::GetDuration(LONGLONG* aDuration)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetDuration(aDuration);
-}
-
-HRESULT
-AudioSinkFilter::GetStopPosition(LONGLONG* aStop)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetStopPosition(aStop);
-}
-
-HRESULT
-AudioSinkFilter::GetCurrentPosition(LONGLONG* aCurrent)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetCurrentPosition(aCurrent);
-}
-
-HRESULT
-AudioSinkFilter::ConvertTimeFormat(LONGLONG* aTarget,
- const GUID* aTargetFormat,
- LONGLONG aSource,
- const GUID* aSourceFormat)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->ConvertTimeFormat(aTarget,
- aTargetFormat,
- aSource,
- aSourceFormat);
-}
-
-HRESULT
-AudioSinkFilter::SetPositions(LONGLONG* aCurrent,
- DWORD aCurrentFlags,
- LONGLONG* aStop,
- DWORD aStopFlags)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->SetPositions(aCurrent,
- aCurrentFlags,
- aStop,
- aStopFlags);
-}
-
-HRESULT
-AudioSinkFilter::GetPositions(LONGLONG* aCurrent,
- LONGLONG* aStop)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetPositions(aCurrent, aStop);
-}
-
-HRESULT
-AudioSinkFilter::GetAvailable(LONGLONG* aEarliest,
- LONGLONG* aLatest)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetAvailable(aEarliest, aLatest);
-}
-
-HRESULT
-AudioSinkFilter::SetRate(double aRate)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->SetRate(aRate);
-}
-
-HRESULT
-AudioSinkFilter::GetRate(double* aRate)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetRate(aRate);
-}
-
-HRESULT
-AudioSinkFilter::GetPreroll(LONGLONG* aPreroll)
-{
- ENSURE_CONNECTED_PIN_SEEKING
- return pinSeeking->GetPreroll(aPreroll);
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/AudioSinkFilter.h b/dom/media/directshow/AudioSinkFilter.h
deleted file mode 100644
index 85abdfccf..000000000
--- a/dom/media/directshow/AudioSinkFilter.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(AudioSinkFilter_h_)
-#define AudioSinkFilter_h_
-
-#include "BaseFilter.h"
-#include "DirectShowUtils.h"
-#include "nsAutoPtr.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-
-class AudioSinkInputPin;
-class SampleSink;
-
-// Filter that acts as the end of the graph. Audio samples input into
-// this filter block the calling thread, and the calling thread is
-// unblocked when the decode thread extracts the sample. The samples
-// input into this filter are stored in the SampleSink, where the blocking
-// is implemented. The input pin owns the SampleSink.
-class AudioSinkFilter: public mozilla::media::BaseFilter,
- public IMediaSeeking
-{
-
-public:
- AudioSinkFilter(const wchar_t* aObjectName, HRESULT* aOutResult);
- virtual ~AudioSinkFilter();
-
- // Gets the input pin's sample sink.
- SampleSink* GetSampleSink();
-
- // IUnknown implementation.
- STDMETHODIMP QueryInterface(REFIID aIId, void **aInterface);
- STDMETHODIMP_(ULONG) AddRef();
- STDMETHODIMP_(ULONG) Release();
-
- // --------------------------------------------------------------------
- // CBaseFilter methods
- int GetPinCount ();
- mozilla::media::BasePin* GetPin ( IN int Index);
- STDMETHODIMP Pause ();
- STDMETHODIMP Stop ();
- STDMETHODIMP GetClassID ( OUT CLSID * pCLSID);
- STDMETHODIMP Run(REFERENCE_TIME tStart);
- // IMediaSeeking Methods...
-
- // We defer to SourceFilter, but we must expose the interface on
- // the output pins. Seeking commands come upstream from the renderers,
- // but they must be actioned at the source filters.
- STDMETHODIMP GetCapabilities(DWORD* aCapabilities);
- STDMETHODIMP CheckCapabilities(DWORD* aCapabilities);
- STDMETHODIMP IsFormatSupported(const GUID* aFormat);
- STDMETHODIMP QueryPreferredFormat(GUID* aFormat);
- STDMETHODIMP GetTimeFormat(GUID* aFormat);
- STDMETHODIMP IsUsingTimeFormat(const GUID* aFormat);
- STDMETHODIMP SetTimeFormat(const GUID* aFormat);
- STDMETHODIMP GetDuration(LONGLONG* pDuration);
- STDMETHODIMP GetStopPosition(LONGLONG* pStop);
- STDMETHODIMP GetCurrentPosition(LONGLONG* aCurrent);
- STDMETHODIMP ConvertTimeFormat(LONGLONG* aTarget,
- const GUID* aTargetFormat,
- LONGLONG aSource,
- const GUID* aSourceFormat);
- STDMETHODIMP SetPositions(LONGLONG* aCurrent,
- DWORD aCurrentFlags,
- LONGLONG* aStop,
- DWORD aStopFlags);
- STDMETHODIMP GetPositions(LONGLONG* aCurrent,
- LONGLONG* aStop);
- STDMETHODIMP GetAvailable(LONGLONG* aEarliest,
- LONGLONG* aLatest);
- STDMETHODIMP SetRate(double aRate);
- STDMETHODIMP GetRate(double* aRate);
- STDMETHODIMP GetPreroll(LONGLONG* aPreroll);
-
- // --------------------------------------------------------------------
- // class factory calls this
- static IUnknown * CreateInstance (IN LPUNKNOWN punk, OUT HRESULT * phr);
-
-private:
- CriticalSection mFilterCritSec;
-
- // Note: The input pin defers its refcounting to the sink filter, so when
- // the input pin is addrefed, what actually happens is the sink filter is
- // addrefed.
- nsAutoPtr<AudioSinkInputPin> mInputPin;
-};
-
-} // namespace mozilla
-
-#endif // AudioSinkFilter_h_
diff --git a/dom/media/directshow/AudioSinkInputPin.cpp b/dom/media/directshow/AudioSinkInputPin.cpp
deleted file mode 100644
index 85a6e3da3..000000000
--- a/dom/media/directshow/AudioSinkInputPin.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "AudioSinkInputPin.h"
-#include "AudioSinkFilter.h"
-#include "SampleSink.h"
-#include "mozilla/Logging.h"
-
-#include <wmsdkidl.h>
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-AudioSinkInputPin::AudioSinkInputPin(wchar_t* aObjectName,
- AudioSinkFilter* aFilter,
- mozilla::CriticalSection* aLock,
- HRESULT* aOutResult)
- : BaseInputPin(aObjectName, aFilter, aLock, aOutResult, aObjectName),
- mSegmentStartTime(0)
-{
- MOZ_COUNT_CTOR(AudioSinkInputPin);
- mSampleSink = new SampleSink();
-}
-
-AudioSinkInputPin::~AudioSinkInputPin()
-{
- MOZ_COUNT_DTOR(AudioSinkInputPin);
-}
-
-HRESULT
-AudioSinkInputPin::GetMediaType(int aPosition, MediaType* aOutMediaType)
-{
- NS_ENSURE_TRUE(aPosition >= 0, E_INVALIDARG);
- NS_ENSURE_TRUE(aOutMediaType, E_POINTER);
-
- if (aPosition > 0) {
- return S_FALSE;
- }
-
- // Note: We set output as PCM, as IEEE_FLOAT only works when using the
- // MP3 decoder as an MFT, and we can't do that while using DirectShow.
- aOutMediaType->SetType(&MEDIATYPE_Audio);
- aOutMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
- aOutMediaType->SetType(&FORMAT_WaveFormatEx);
- aOutMediaType->SetTemporalCompression(FALSE);
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::CheckMediaType(const MediaType* aMediaType)
-{
- if (!aMediaType) {
- return E_INVALIDARG;
- }
-
- GUID majorType = *aMediaType->Type();
- if (majorType != MEDIATYPE_Audio && majorType != WMMEDIATYPE_Audio) {
- return E_INVALIDARG;
- }
-
- if (*aMediaType->Subtype() != MEDIASUBTYPE_PCM) {
- return E_INVALIDARG;
- }
-
- if (*aMediaType->FormatType() != FORMAT_WaveFormatEx) {
- return E_INVALIDARG;
- }
-
- // We accept the media type, stash its layout format!
- WAVEFORMATEX* wfx = (WAVEFORMATEX*)(aMediaType->pbFormat);
- GetSampleSink()->SetAudioFormat(wfx);
-
- return S_OK;
-}
-
-AudioSinkFilter*
-AudioSinkInputPin::GetAudioSinkFilter()
-{
- return reinterpret_cast<AudioSinkFilter*>(mFilter);
-}
-
-SampleSink*
-AudioSinkInputPin::GetSampleSink()
-{
- return mSampleSink;
-}
-
-HRESULT
-AudioSinkInputPin::SetAbsoluteMediaTime(IMediaSample* aSample)
-{
- HRESULT hr;
- REFERENCE_TIME start = 0, end = 0;
- hr = aSample->GetTime(&start, &end);
- NS_ENSURE_TRUE(SUCCEEDED(hr), E_FAIL);
- {
- CriticalSectionAutoEnter lock(*mLock);
- start += mSegmentStartTime;
- end += mSegmentStartTime;
- }
- hr = aSample->SetMediaTime(&start, &end);
- NS_ENSURE_TRUE(SUCCEEDED(hr), E_FAIL);
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::Receive(IMediaSample* aSample )
-{
- HRESULT hr;
- NS_ENSURE_TRUE(aSample, E_POINTER);
-
- hr = BaseInputPin::Receive(aSample);
- if (SUCCEEDED(hr) && hr != S_FALSE) { // S_FALSE == flushing
- // Set the timestamp of the sample after being adjusted for
- // seeking/segments in the "media time" attribute. When we seek,
- // DirectShow starts a new "segment", and starts labeling samples
- // from time=0 again, so we need to correct for this to get the
- // actual timestamps after seeking.
- hr = SetAbsoluteMediaTime(aSample);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
- hr = GetSampleSink()->Receive(aSample);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
- }
- return S_OK;
-}
-
-already_AddRefed<IMediaSeeking>
-AudioSinkInputPin::GetConnectedPinSeeking()
-{
- RefPtr<IPin> peer = GetConnected();
- if (!peer)
- return nullptr;
- RefPtr<IMediaSeeking> seeking;
- peer->QueryInterface(static_cast<IMediaSeeking**>(getter_AddRefs(seeking)));
- return seeking.forget();
-}
-
-HRESULT
-AudioSinkInputPin::BeginFlush()
-{
- HRESULT hr = media::BaseInputPin::BeginFlush();
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- GetSampleSink()->Flush();
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::EndFlush()
-{
- HRESULT hr = media::BaseInputPin::EndFlush();
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- // Reset the EOS flag, so that if we're called after a seek we still work.
- GetSampleSink()->Reset();
-
- return S_OK;
-}
-
-HRESULT
-AudioSinkInputPin::EndOfStream(void)
-{
- HRESULT hr = media::BaseInputPin::EndOfStream();
- if (FAILED(hr) || hr == S_FALSE) {
- // Pin is stil flushing.
- return hr;
- }
- GetSampleSink()->SetEOS();
-
- return S_OK;
-}
-
-
-HRESULT
-AudioSinkInputPin::NewSegment(REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate)
-{
- CriticalSectionAutoEnter lock(*mLock);
- // Record the start time of the new segment, so that we can store the
- // correct absolute timestamp in the "media time" each incoming sample.
- mSegmentStartTime = tStart;
- return S_OK;
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/AudioSinkInputPin.h b/dom/media/directshow/AudioSinkInputPin.h
deleted file mode 100644
index 80503c641..000000000
--- a/dom/media/directshow/AudioSinkInputPin.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(AudioSinkInputPin_h_)
-#define AudioSinkInputPin_h_
-
-#include "BaseInputPin.h"
-#include "DirectShowUtils.h"
-#include "mozilla/RefPtr.h"
-#include "nsAutoPtr.h"
-
-namespace mozilla {
-
-namespace media {
- class MediaType;
-}
-
-class AudioSinkFilter;
-class SampleSink;
-
-
-// Input pin for capturing audio output of a DirectShow filter graph.
-// This is the input pin for the AudioSinkFilter.
-class AudioSinkInputPin: public mozilla::media::BaseInputPin
-{
-public:
- AudioSinkInputPin(wchar_t* aObjectName,
- AudioSinkFilter* aFilter,
- mozilla::CriticalSection* aLock,
- HRESULT* aOutResult);
- virtual ~AudioSinkInputPin();
-
- HRESULT GetMediaType (IN int iPos, OUT mozilla::media::MediaType * pmt);
- HRESULT CheckMediaType (IN const mozilla::media::MediaType * pmt);
- STDMETHODIMP Receive (IN IMediaSample *);
- STDMETHODIMP BeginFlush() override;
- STDMETHODIMP EndFlush() override;
-
- // Called when we start decoding a new segment, that happens directly after
- // a seek. This captures the segment's start time. Samples decoded by the
- // MP3 decoder have their timestamps offset from the segment start time.
- // Storing the segment start time enables us to set each sample's MediaTime
- // as an offset in the stream relative to the start of the stream, rather
- // than the start of the segment, i.e. its absolute time in the stream.
- STDMETHODIMP NewSegment(REFERENCE_TIME tStart,
- REFERENCE_TIME tStop,
- double dRate) override;
-
- STDMETHODIMP EndOfStream() override;
-
- // Returns the IMediaSeeking interface of the connected output pin.
- // We forward seeking requests upstream from the sink to the source
- // filters.
- already_AddRefed<IMediaSeeking> GetConnectedPinSeeking();
-
- SampleSink* GetSampleSink();
-
-private:
- AudioSinkFilter* GetAudioSinkFilter();
-
- // Sets the media time on the media sample, relative to the segment
- // start time.
- HRESULT SetAbsoluteMediaTime(IMediaSample* aSample);
-
- nsAutoPtr<SampleSink> mSampleSink;
-
- // Synchronized by the filter lock; BaseInputPin::mLock.
- REFERENCE_TIME mSegmentStartTime;
-};
-
-} // namespace mozilla
-
-#endif // AudioSinkInputPin_h_
diff --git a/dom/media/directshow/DirectShowDecoder.cpp b/dom/media/directshow/DirectShowDecoder.cpp
deleted file mode 100644
index da68b4daa..000000000
--- a/dom/media/directshow/DirectShowDecoder.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DirectShowDecoder.h"
-#include "DirectShowReader.h"
-#include "DirectShowUtils.h"
-#include "MediaDecoderStateMachine.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/WindowsVersion.h"
-
-namespace mozilla {
-
-MediaDecoderStateMachine* DirectShowDecoder::CreateStateMachine()
-{
- return new MediaDecoderStateMachine(this, new DirectShowReader(this));
-}
-
-/* static */
-bool
-DirectShowDecoder::GetSupportedCodecs(const nsACString& aType,
- char const *const ** aCodecList)
-{
- if (!IsEnabled()) {
- return false;
- }
-
- static char const *const mp3AudioCodecs[] = {
- "mp3",
- nullptr
- };
- if (aType.EqualsASCII("audio/mpeg") ||
- aType.EqualsASCII("audio/mp3")) {
- if (aCodecList) {
- *aCodecList = mp3AudioCodecs;
- }
- return true;
- }
-
- return false;
-}
-
-/* static */
-bool
-DirectShowDecoder::IsEnabled()
-{
- return CanDecodeMP3UsingDirectShow() &&
- Preferences::GetBool("media.directshow.enabled");
-}
-
-DirectShowDecoder::DirectShowDecoder(MediaDecoderOwner* aOwner)
- : MediaDecoder(aOwner)
-{
- MOZ_COUNT_CTOR(DirectShowDecoder);
-}
-
-DirectShowDecoder::~DirectShowDecoder()
-{
- MOZ_COUNT_DTOR(DirectShowDecoder);
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/DirectShowDecoder.h b/dom/media/directshow/DirectShowDecoder.h
deleted file mode 100644
index c4d371fbf..000000000
--- a/dom/media/directshow/DirectShowDecoder.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(DirectShowDecoder_h_)
-#define DirectShowDecoder_h_
-
-#include "MediaDecoder.h"
-
-namespace mozilla {
-
-// Decoder that uses DirectShow to playback MP3 files only.
-class DirectShowDecoder : public MediaDecoder
-{
-public:
-
- explicit DirectShowDecoder(MediaDecoderOwner* aOwner);
- virtual ~DirectShowDecoder();
-
- MediaDecoder* Clone(MediaDecoderOwner* aOwner) override {
- if (!IsEnabled()) {
- return nullptr;
- }
- return new DirectShowDecoder(aOwner);
- }
-
- MediaDecoderStateMachine* CreateStateMachine() override;
-
- // Returns true if aType is a MIME type that we render with the
- // DirectShow backend. If aCodecList is non null,
- // it is filled with a (static const) null-terminated list of strings
- // denoting the codecs we'll playback. Note that playback is strictly
- // limited to MP3 only.
- static bool GetSupportedCodecs(const nsACString& aType,
- char const *const ** aCodecList);
-
- // Returns true if the DirectShow backend is preffed on.
- static bool IsEnabled();
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/directshow/DirectShowReader.cpp b/dom/media/directshow/DirectShowReader.cpp
deleted file mode 100644
index cacf6f8de..000000000
--- a/dom/media/directshow/DirectShowReader.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DirectShowReader.h"
-#include "MediaDecoderReader.h"
-#include "mozilla/RefPtr.h"
-#include "DirectShowUtils.h"
-#include "AudioSinkFilter.h"
-#include "SourceFilter.h"
-#include "SampleSink.h"
-#include "VideoUtils.h"
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-// Windows XP's MP3 decoder filter. This is available on XP only, on Vista
-// and later we can use the DMO Wrapper filter and MP3 decoder DMO.
-const GUID DirectShowReader::CLSID_MPEG_LAYER_3_DECODER_FILTER =
-{ 0x38BE3000, 0xDBF4, 0x11D0, {0x86, 0x0E, 0x00, 0xA0, 0x24, 0xCF, 0xEF, 0x6D} };
-
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-DirectShowReader::DirectShowReader(AbstractMediaDecoder* aDecoder)
- : MediaDecoderReader(aDecoder),
- mMP3FrameParser(aDecoder->GetResource()->GetLength()),
-#ifdef DIRECTSHOW_REGISTER_GRAPH
- mRotRegister(0),
-#endif
- mNumChannels(0),
- mAudioRate(0),
- mBytesPerSample(0)
-{
- MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
- MOZ_COUNT_CTOR(DirectShowReader);
-}
-
-DirectShowReader::~DirectShowReader()
-{
- MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
- MOZ_COUNT_DTOR(DirectShowReader);
-#ifdef DIRECTSHOW_REGISTER_GRAPH
- if (mRotRegister) {
- RemoveGraphFromRunningObjectTable(mRotRegister);
- }
-#endif
-}
-
-// Try to parse the MP3 stream to make sure this is indeed an MP3, get the
-// estimated duration of the stream, and find the offset of the actual MP3
-// frames in the stream, as DirectShow doesn't like large ID3 sections.
-static nsresult
-ParseMP3Headers(MP3FrameParser *aParser, MediaResource *aResource)
-{
- const uint32_t MAX_READ_SIZE = 4096;
-
- uint64_t offset = 0;
- while (aParser->NeedsData() && !aParser->ParsedHeaders()) {
- uint32_t bytesRead;
- char buffer[MAX_READ_SIZE];
- nsresult rv = aResource->ReadAt(offset, buffer,
- MAX_READ_SIZE, &bytesRead);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (!bytesRead) {
- // End of stream.
- return NS_ERROR_FAILURE;
- }
-
- aParser->Parse(reinterpret_cast<uint8_t*>(buffer), bytesRead, offset);
- offset += bytesRead;
- }
-
- return aParser->IsMP3() ? NS_OK : NS_ERROR_FAILURE;
-}
-
-nsresult
-DirectShowReader::ReadMetadata(MediaInfo* aInfo,
- MetadataTags** aTags)
-{
- MOZ_ASSERT(OnTaskQueue());
- HRESULT hr;
- nsresult rv;
-
- // Create the filter graph, reference it by the GraphBuilder interface,
- // to make graph building more convenient.
- hr = CoCreateInstance(CLSID_FilterGraph,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IGraphBuilder,
- reinterpret_cast<void**>(static_cast<IGraphBuilder**>(getter_AddRefs(mGraph))));
- NS_ENSURE_TRUE(SUCCEEDED(hr) && mGraph, NS_ERROR_FAILURE);
-
- rv = ParseMP3Headers(&mMP3FrameParser, mDecoder->GetResource());
- NS_ENSURE_SUCCESS(rv, rv);
-
- #ifdef DIRECTSHOW_REGISTER_GRAPH
- hr = AddGraphToRunningObjectTable(mGraph, &mRotRegister);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
- #endif
-
- // Extract the interface pointers we'll need from the filter graph.
- hr = mGraph->QueryInterface(static_cast<IMediaControl**>(getter_AddRefs(mControl)));
- NS_ENSURE_TRUE(SUCCEEDED(hr) && mControl, NS_ERROR_FAILURE);
-
- hr = mGraph->QueryInterface(static_cast<IMediaSeeking**>(getter_AddRefs(mMediaSeeking)));
- NS_ENSURE_TRUE(SUCCEEDED(hr) && mMediaSeeking, NS_ERROR_FAILURE);
-
- // Build the graph. Create the filters we need, and connect them. We
- // build the entire graph ourselves to prevent other decoders installed
- // on the system being created and used.
-
- // Our source filters, wraps the MediaResource.
- mSourceFilter = new SourceFilter(MEDIATYPE_Stream, MEDIASUBTYPE_MPEG1Audio);
- NS_ENSURE_TRUE(mSourceFilter, NS_ERROR_FAILURE);
-
- rv = mSourceFilter->Init(mDecoder->GetResource(), mMP3FrameParser.GetMP3Offset());
- NS_ENSURE_SUCCESS(rv, rv);
-
- hr = mGraph->AddFilter(mSourceFilter, L"MozillaDirectShowSource");
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- // The MPEG demuxer.
- RefPtr<IBaseFilter> demuxer;
- hr = CreateAndAddFilter(mGraph,
- CLSID_MPEG1Splitter,
- L"MPEG1Splitter",
- getter_AddRefs(demuxer));
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- // Platform MP3 decoder.
- RefPtr<IBaseFilter> decoder;
- // Firstly try to create the MP3 decoder filter that ships with WinXP
- // directly. This filter doesn't normally exist on later versions of
- // Windows.
- hr = CreateAndAddFilter(mGraph,
- CLSID_MPEG_LAYER_3_DECODER_FILTER,
- L"MPEG Layer 3 Decoder",
- getter_AddRefs(decoder));
- if (FAILED(hr)) {
- // Failed to create MP3 decoder filter. Try to instantiate
- // the MP3 decoder DMO.
- hr = AddMP3DMOWrapperFilter(mGraph, getter_AddRefs(decoder));
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
- }
-
- // Sink, captures audio samples and inserts them into our pipeline.
- static const wchar_t* AudioSinkFilterName = L"MozAudioSinkFilter";
- mAudioSinkFilter = new AudioSinkFilter(AudioSinkFilterName, &hr);
- NS_ENSURE_TRUE(mAudioSinkFilter && SUCCEEDED(hr), NS_ERROR_FAILURE);
- hr = mGraph->AddFilter(mAudioSinkFilter, AudioSinkFilterName);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- // Join the filters.
- hr = ConnectFilters(mGraph, mSourceFilter, demuxer);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- hr = ConnectFilters(mGraph, demuxer, decoder);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- hr = ConnectFilters(mGraph, decoder, mAudioSinkFilter);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- WAVEFORMATEX format;
- mAudioSinkFilter->GetSampleSink()->GetAudioFormat(&format);
- NS_ENSURE_TRUE(format.wFormatTag == WAVE_FORMAT_PCM, NS_ERROR_FAILURE);
-
- mInfo.mAudio.mChannels = mNumChannels = format.nChannels;
- mInfo.mAudio.mRate = mAudioRate = format.nSamplesPerSec;
- mInfo.mAudio.mBitDepth = format.wBitsPerSample;
- mBytesPerSample = format.wBitsPerSample / 8;
-
- // Begin decoding!
- hr = mControl->Run();
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- DWORD seekCaps = 0;
- hr = mMediaSeeking->GetCapabilities(&seekCaps);
- mInfo.mMediaSeekable = SUCCEEDED(hr) && (AM_SEEKING_CanSeekAbsolute & seekCaps);
-
- int64_t duration = mMP3FrameParser.GetDuration();
- if (SUCCEEDED(hr)) {
- mInfo.mMetadataDuration.emplace(TimeUnit::FromMicroseconds(duration));
- }
-
- LOG("Successfully initialized DirectShow MP3 decoder.");
- LOG("Channels=%u Hz=%u duration=%lld bytesPerSample=%d",
- mInfo.mAudio.mChannels,
- mInfo.mAudio.mRate,
- RefTimeToUsecs(duration),
- mBytesPerSample);
-
- *aInfo = mInfo;
- // Note: The SourceFilter strips ID3v2 tags out of the stream.
- *aTags = nullptr;
-
- return NS_OK;
-}
-
-inline float
-UnsignedByteToAudioSample(uint8_t aValue)
-{
- return aValue * (2.0f / UINT8_MAX) - 1.0f;
-}
-
-bool
-DirectShowReader::Finish(HRESULT aStatus)
-{
- MOZ_ASSERT(OnTaskQueue());
-
- LOG("DirectShowReader::Finish(0x%x)", aStatus);
- // Notify the filter graph of end of stream.
- RefPtr<IMediaEventSink> eventSink;
- HRESULT hr = mGraph->QueryInterface(static_cast<IMediaEventSink**>(getter_AddRefs(eventSink)));
- if (SUCCEEDED(hr) && eventSink) {
- eventSink->Notify(EC_COMPLETE, aStatus, 0);
- }
- return false;
-}
-
-class DirectShowCopy
-{
-public:
- DirectShowCopy(uint8_t *aSource, uint32_t aBytesPerSample,
- uint32_t aSamples, uint32_t aChannels)
- : mSource(aSource)
- , mBytesPerSample(aBytesPerSample)
- , mSamples(aSamples)
- , mChannels(aChannels)
- , mNextSample(0)
- { }
-
- uint32_t operator()(AudioDataValue *aBuffer, uint32_t aSamples)
- {
- uint32_t maxSamples = std::min(aSamples, mSamples - mNextSample);
- uint32_t frames = maxSamples / mChannels;
- size_t byteOffset = mNextSample * mBytesPerSample;
- if (mBytesPerSample == 1) {
- for (uint32_t i = 0; i < maxSamples; ++i) {
- uint8_t *sample = mSource + byteOffset;
- aBuffer[i] = UnsignedByteToAudioSample(*sample);
- byteOffset += mBytesPerSample;
- }
- } else if (mBytesPerSample == 2) {
- for (uint32_t i = 0; i < maxSamples; ++i) {
- int16_t *sample = reinterpret_cast<int16_t *>(mSource + byteOffset);
- aBuffer[i] = AudioSampleToFloat(*sample);
- byteOffset += mBytesPerSample;
- }
- }
- mNextSample += maxSamples;
- return frames;
- }
-
-private:
- uint8_t * const mSource;
- const uint32_t mBytesPerSample;
- const uint32_t mSamples;
- const uint32_t mChannels;
- uint32_t mNextSample;
-};
-
-bool
-DirectShowReader::DecodeAudioData()
-{
- MOZ_ASSERT(OnTaskQueue());
- HRESULT hr;
-
- SampleSink* sink = mAudioSinkFilter->GetSampleSink();
- if (sink->AtEOS()) {
- // End of stream.
- return Finish(S_OK);
- }
-
- // Get the next chunk of audio samples. This blocks until the sample
- // arrives, or an error occurs (like the stream is shutdown).
- RefPtr<IMediaSample> sample;
- hr = sink->Extract(sample);
- if (FAILED(hr) || hr == S_FALSE) {
- return Finish(hr);
- }
-
- int64_t start = 0, end = 0;
- sample->GetMediaTime(&start, &end);
- LOG("DirectShowReader::DecodeAudioData [%4.2lf-%4.2lf]",
- RefTimeToSeconds(start),
- RefTimeToSeconds(end));
-
- LONG length = sample->GetActualDataLength();
- LONG numSamples = length / mBytesPerSample;
- LONG numFrames = length / mBytesPerSample / mNumChannels;
-
- BYTE* data = nullptr;
- hr = sample->GetPointer(&data);
- NS_ENSURE_TRUE(SUCCEEDED(hr), Finish(hr));
-
- mAudioCompactor.Push(mDecoder->GetResource()->Tell(),
- RefTimeToUsecs(start),
- mInfo.mAudio.mRate,
- numFrames,
- mNumChannels,
- DirectShowCopy(reinterpret_cast<uint8_t *>(data),
- mBytesPerSample,
- numSamples,
- mNumChannels));
- return true;
-}
-
-bool
-DirectShowReader::DecodeVideoFrame(bool &aKeyframeSkip,
- int64_t aTimeThreshold)
-{
- MOZ_ASSERT(OnTaskQueue());
- return false;
-}
-
-RefPtr<MediaDecoderReader::SeekPromise>
-DirectShowReader::Seek(SeekTarget aTarget, int64_t aEndTime)
-{
- nsresult res = SeekInternal(aTarget.GetTime().ToMicroseconds());
- if (NS_FAILED(res)) {
- return SeekPromise::CreateAndReject(res, __func__);
- } else {
- return SeekPromise::CreateAndResolve(aTarget.GetTime(), __func__);
- }
-}
-
-nsresult
-DirectShowReader::SeekInternal(int64_t aTargetUs)
-{
- HRESULT hr;
- MOZ_ASSERT(OnTaskQueue());
-
- LOG("DirectShowReader::Seek() target=%lld", aTargetUs);
-
- hr = mControl->Pause();
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- nsresult rv = ResetDecode();
- NS_ENSURE_SUCCESS(rv, rv);
-
- LONGLONG seekPosition = UsecsToRefTime(aTargetUs);
- hr = mMediaSeeking->SetPositions(&seekPosition,
- AM_SEEKING_AbsolutePositioning,
- nullptr,
- AM_SEEKING_NoPositioning);
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- hr = mControl->Run();
- NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
-
- return NS_OK;
-}
-
-} // namespace mozilla
diff --git a/dom/media/directshow/DirectShowReader.h b/dom/media/directshow/DirectShowReader.h
deleted file mode 100644
index 881b27c28..000000000
--- a/dom/media/directshow/DirectShowReader.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(DirectShowReader_h_)
-#define DirectShowReader_h_
-
-#include "windows.h" // HRESULT, DWORD
-#include "MediaDecoderReader.h"
-#include "MediaResource.h"
-#include "mozilla/RefPtr.h"
-#include "MP3FrameParser.h"
-
-// Add the graph to the Running Object Table so that we can connect
-// to this graph with GraphEdit/GraphStudio. Note: you must
-// also regsvr32 proppage.dll from the Windows SDK.
-// See: http://msdn.microsoft.com/en-us/library/ms787252(VS.85).aspx
-// #define DIRECTSHOW_REGISTER_GRAPH
-
-struct IGraphBuilder;
-struct IMediaControl;
-struct IMediaSeeking;
-
-namespace mozilla {
-
-class AudioSinkFilter;
-class SourceFilter;
-
-// Decoder backend for decoding MP3 using DirectShow. DirectShow operates as
-// a filter graph. The basic design of the DirectShowReader is that we have
-// a SourceFilter that wraps the MediaResource that connects to the
-// MP3 decoder filter. The MP3 decoder filter "pulls" data as it requires it
-// downstream on its own thread. When the MP3 decoder has produced a block of
-// decoded samples, its thread calls downstream into our AudioSinkFilter,
-// passing the decoded buffer in. The AudioSinkFilter inserts the samples into
-// a SampleSink object. The SampleSink blocks the MP3 decoder's thread until
-// the decode thread calls DecodeAudioData(), whereupon the SampleSink
-// releases the decoded samples to the decode thread, and unblocks the MP3
-// decoder's thread. The MP3 decoder can then request more data from the
-// SourceFilter, and decode more data. If the decode thread calls
-// DecodeAudioData() and there's no decoded samples waiting to be extracted
-// in the SampleSink, the SampleSink blocks the decode thread until the MP3
-// decoder produces a decoded sample.
-class DirectShowReader : public MediaDecoderReader
-{
-public:
- DirectShowReader(AbstractMediaDecoder* aDecoder);
-
- virtual ~DirectShowReader();
-
- bool DecodeAudioData() override;
- bool DecodeVideoFrame(bool &aKeyframeSkip,
- int64_t aTimeThreshold) override;
-
- nsresult ReadMetadata(MediaInfo* aInfo,
- MetadataTags** aTags) override;
-
- RefPtr<SeekPromise>
- Seek(SeekTarget aTarget, int64_t aEndTime) override;
-
- static const GUID CLSID_MPEG_LAYER_3_DECODER_FILTER;
-
-private:
- // Notifies the filter graph that playback is complete. aStatus is
- // the code to send to the filter graph. Always returns false, so
- // that we can just "return Finish()" from DecodeAudioData().
- bool Finish(HRESULT aStatus);
-
- nsresult SeekInternal(int64_t aTime);
-
- // DirectShow filter graph, and associated playback and seeking
- // control interfaces.
- RefPtr<IGraphBuilder> mGraph;
- RefPtr<IMediaControl> mControl;
- RefPtr<IMediaSeeking> mMediaSeeking;
-
- // Wraps the MediaResource, and feeds undecoded data into the filter graph.
- RefPtr<SourceFilter> mSourceFilter;
-
- // Sits at the end of the graph, removing decoded samples from the graph.
- // The graph will block while this is blocked, i.e. it will pause decoding.
- RefPtr<AudioSinkFilter> mAudioSinkFilter;
-
- // Some MP3s are variable bitrate, so DirectShow's duration estimation
- // can make its duration estimation based on the wrong bitrate. So we parse
- // the MP3 frames to get a more accuate estimate of the duration.
- MP3FrameParser mMP3FrameParser;
-
-#ifdef DIRECTSHOW_REGISTER_GRAPH
- // Used to add/remove the filter graph to the Running Object Table. You can
- // connect GraphEdit/GraphStudio to the graph to observe and/or debug its
- // topology and state.
- DWORD mRotRegister;
-#endif
-
- // Number of channels in the audio stream.
- uint32_t mNumChannels;
-
- // Samples per second in the audio stream.
- uint32_t mAudioRate;
-
- // Number of bytes per sample. Can be either 1 or 2.
- uint32_t mBytesPerSample;
-};
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/directshow/DirectShowUtils.cpp b/dom/media/directshow/DirectShowUtils.cpp
deleted file mode 100644
index b2afa7528..000000000
--- a/dom/media/directshow/DirectShowUtils.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DirectShowUtils.h"
-#include "dmodshow.h"
-#include "wmcodecdsp.h"
-#include "dmoreg.h"
-#include "mozilla/ArrayUtils.h"
-#include "mozilla/RefPtr.h"
-#include "nsPrintfCString.h"
-
-#define WARN(...) NS_WARNING(nsPrintfCString(__VA_ARGS__).get())
-
-namespace mozilla {
-
-// Create a table which maps GUIDs to a string representation of the GUID.
-// This is useful for debugging purposes, for logging the GUIDs of media types.
-// This is only available when logging is enabled, i.e. not in release builds.
-struct GuidToName {
- const char* name;
- const GUID guid;
-};
-
-#pragma push_macro("OUR_GUID_ENTRY")
-#undef OUR_GUID_ENTRY
-#define OUR_GUID_ENTRY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
- { #name, {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}} },
-
-static const GuidToName GuidToNameTable[] = {
-#include <uuids.h>
-};
-
-#pragma pop_macro("OUR_GUID_ENTRY")
-
-const char*
-GetDirectShowGuidName(const GUID& aGuid)
-{
- const size_t len = ArrayLength(GuidToNameTable);
- for (unsigned i = 0; i < len; i++) {
- if (IsEqualGUID(aGuid, GuidToNameTable[i].guid)) {
- return GuidToNameTable[i].name;
- }
- }
- return "Unknown";
-}
-
-void
-RemoveGraphFromRunningObjectTable(DWORD aRotRegister)
-{
- RefPtr<IRunningObjectTable> runningObjectTable;
- if (SUCCEEDED(GetRunningObjectTable(0, getter_AddRefs(runningObjectTable)))) {
- runningObjectTable->Revoke(aRotRegister);
- }
-}
-
-HRESULT
-AddGraphToRunningObjectTable(IUnknown *aUnkGraph, DWORD *aOutRotRegister)
-{
- HRESULT hr;
-
- RefPtr<IMoniker> moniker;
- RefPtr<IRunningObjectTable> runningObjectTable;
-
- hr = GetRunningObjectTable(0, getter_AddRefs(runningObjectTable));
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- const size_t STRING_LENGTH = 256;
- WCHAR wsz[STRING_LENGTH];
-
- StringCchPrintfW(wsz,
- STRING_LENGTH,
- L"FilterGraph %08x pid %08x",
- (DWORD_PTR)aUnkGraph,
- GetCurrentProcessId());
-
- hr = CreateItemMoniker(L"!", wsz, getter_AddRefs(moniker));
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- hr = runningObjectTable->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE,
- aUnkGraph,
- moniker,
- aOutRotRegister);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- return S_OK;
-}
-
-const char*
-GetGraphNotifyString(long evCode)
-{
-#define CASE(x) case x: return #x
- switch(evCode) {
- CASE(EC_ACTIVATE); // A video window is being activated or deactivated.
- CASE(EC_BANDWIDTHCHANGE); // Not supported.
- CASE(EC_BUFFERING_DATA); // The graph is buffering data, or has stopped buffering data.
- CASE(EC_BUILT); // Send by the Video Control when a graph has been built. Not forwarded to applications.
- CASE(EC_CLOCK_CHANGED); // The reference clock has changed.
- CASE(EC_CLOCK_UNSET); // The clock provider was disconnected.
- CASE(EC_CODECAPI_EVENT); // Sent by an encoder to signal an encoding event.
- CASE(EC_COMPLETE); // All data from a particular stream has been rendered.
- CASE(EC_CONTENTPROPERTY_CHANGED); // Not supported.
- CASE(EC_DEVICE_LOST); // A Plug and Play device was removed or has become available again.
- CASE(EC_DISPLAY_CHANGED); // The display mode has changed.
- CASE(EC_END_OF_SEGMENT); // The end of a segment has been reached.
- CASE(EC_EOS_SOON); // Not supported.
- CASE(EC_ERROR_STILLPLAYING); // An asynchronous command to run the graph has failed.
- CASE(EC_ERRORABORT); // An operation was aborted because of an error.
- CASE(EC_ERRORABORTEX); // An operation was aborted because of an error.
- CASE(EC_EXTDEVICE_MODE_CHANGE); // Not supported.
- CASE(EC_FILE_CLOSED); // The source file was closed because of an unexpected event.
- CASE(EC_FULLSCREEN_LOST); // The video renderer is switching out of full-screen mode.
- CASE(EC_GRAPH_CHANGED); // The filter graph has changed.
- CASE(EC_LENGTH_CHANGED); // The length of a source has changed.
- CASE(EC_LOADSTATUS); // Notifies the application of progress when opening a network file.
- CASE(EC_MARKER_HIT); // Not supported.
- CASE(EC_NEED_RESTART); // A filter is requesting that the graph be restarted.
- CASE(EC_NEW_PIN); // Not supported.
- CASE(EC_NOTIFY_WINDOW); // Notifies a filter of the video renderer's window.
- CASE(EC_OLE_EVENT); // A filter is passing a text string to the application.
- CASE(EC_OPENING_FILE); // The graph is opening a file, or has finished opening a file.
- CASE(EC_PALETTE_CHANGED); // The video palette has changed.
- CASE(EC_PAUSED); // A pause request has completed.
- CASE(EC_PLEASE_REOPEN); // The source file has changed.
- CASE(EC_PREPROCESS_COMPLETE); // Sent by the WM ASF Writer filter when it completes the pre-processing for multipass encoding.
- CASE(EC_PROCESSING_LATENCY); // Indicates the amount of time that a component is taking to process each sample.
- CASE(EC_QUALITY_CHANGE); // The graph is dropping samples, for quality control.
- //CASE(EC_RENDER_FINISHED); // Not supported.
- CASE(EC_REPAINT); // A video renderer requires a repaint.
- CASE(EC_SAMPLE_LATENCY); // Specifies how far behind schedule a component is for processing samples.
- //CASE(EC_SAMPLE_NEEDED); // Requests a new input sample from the Enhanced Video Renderer (EVR) filter.
- CASE(EC_SCRUB_TIME); // Specifies the time stamp for the most recent frame step.
- CASE(EC_SEGMENT_STARTED); // A new segment has started.
- CASE(EC_SHUTTING_DOWN); // The filter graph is shutting down, prior to being destroyed.
- CASE(EC_SNDDEV_IN_ERROR); // A device error has occurred in an audio capture filter.
- CASE(EC_SNDDEV_OUT_ERROR); // A device error has occurred in an audio renderer filter.
- CASE(EC_STARVATION); // A filter is not receiving enough data.
- CASE(EC_STATE_CHANGE); // The filter graph has changed state.
- CASE(EC_STATUS); // Contains two arbitrary status strings.
- CASE(EC_STEP_COMPLETE); // A filter performing frame stepping has stepped the specified number of frames.
- CASE(EC_STREAM_CONTROL_STARTED); // A stream-control start command has taken effect.
- CASE(EC_STREAM_CONTROL_STOPPED); // A stream-control stop command has taken effect.
- CASE(EC_STREAM_ERROR_STILLPLAYING); // An error has occurred in a stream. The stream is still playing.
- CASE(EC_STREAM_ERROR_STOPPED); // A stream has stopped because of an error.
- CASE(EC_TIMECODE_AVAILABLE); // Not supported.
- CASE(EC_UNBUILT); // Send by the Video Control when a graph has been torn down. Not forwarded to applications.
- CASE(EC_USERABORT); // The user has terminated playback.
- CASE(EC_VIDEO_SIZE_CHANGED); // The native video size has changed.
- CASE(EC_VIDEOFRAMEREADY); // A video frame is ready for display.
- CASE(EC_VMR_RECONNECTION_FAILED); // Sent by the VMR-7 and the VMR-9 when it was unable to accept a dynamic format change request from the upstream decoder.
- CASE(EC_VMR_RENDERDEVICE_SET); // Sent when the VMR has selected its rendering mechanism.
- CASE(EC_VMR_SURFACE_FLIPPED); // Sent when the VMR-7's allocator presenter has called the DirectDraw Flip method on the surface being presented.
- CASE(EC_WINDOW_DESTROYED); // The video renderer was destroyed or removed from the graph.
- CASE(EC_WMT_EVENT); // Sent by the WM ASF Reader filter when it reads ASF files protected by digital rights management (DRM).
- CASE(EC_WMT_INDEX_EVENT); // Sent when an application uses the WM ASF Writer to index Windows Media Video files.
- CASE(S_OK); // Success.
- CASE(VFW_S_AUDIO_NOT_RENDERED); // Partial success; the audio was not rendered.
- CASE(VFW_S_DUPLICATE_NAME); // Success; the Filter Graph Manager modified a filter name to avoid duplication.
- CASE(VFW_S_PARTIAL_RENDER); // Partial success; some of the streams in this movie are in an unsupported format.
- CASE(VFW_S_VIDEO_NOT_RENDERED); // Partial success; the video was not rendered.
- CASE(E_ABORT); // Operation aborted.
- CASE(E_OUTOFMEMORY); // Insufficient memory.
- CASE(E_POINTER); // Null pointer argument.
- CASE(VFW_E_CANNOT_CONNECT); // No combination of intermediate filters could be found to make the connection.
- CASE(VFW_E_CANNOT_RENDER); // No combination of filters could be found to render the stream.
- CASE(VFW_E_NO_ACCEPTABLE_TYPES); // There is no common media type between these pins.
- CASE(VFW_E_NOT_IN_GRAPH);
-
- default:
- return "Unknown Code";
- };
-#undef CASE
-}
-
-HRESULT
-CreateAndAddFilter(IGraphBuilder* aGraph,
- REFGUID aFilterClsId,
- LPCWSTR aFilterName,
- IBaseFilter **aOutFilter)
-{
- NS_ENSURE_TRUE(aGraph, E_POINTER);
- NS_ENSURE_TRUE(aOutFilter, E_POINTER);
- HRESULT hr;
-
- RefPtr<IBaseFilter> filter;
- hr = CoCreateInstance(aFilterClsId,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter));
- if (FAILED(hr)) {
- // Object probably not available on this system.
- WARN("CoCreateInstance failed, hr=%x", hr);
- return hr;
- }
-
- hr = aGraph->AddFilter(filter, aFilterName);
- if (FAILED(hr)) {
- WARN("AddFilter failed, hr=%x", hr);
- return hr;
- }
-
- filter.forget(aOutFilter);
-
- return S_OK;
-}
-
-HRESULT
-CreateMP3DMOWrapperFilter(IBaseFilter **aOutFilter)
-{
- NS_ENSURE_TRUE(aOutFilter, E_POINTER);
- HRESULT hr;
-
- // Create the wrapper filter.
- RefPtr<IBaseFilter> filter;
- hr = CoCreateInstance(CLSID_DMOWrapperFilter,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter));
- if (FAILED(hr)) {
- WARN("CoCreateInstance failed, hr=%x", hr);
- return hr;
- }
-
- // Query for IDMOWrapperFilter.
- RefPtr<IDMOWrapperFilter> dmoWrapper;
- hr = filter->QueryInterface(IID_IDMOWrapperFilter,
- getter_AddRefs(dmoWrapper));
- if (FAILED(hr)) {
- WARN("QueryInterface failed, hr=%x", hr);
- return hr;
- }
-
- hr = dmoWrapper->Init(CLSID_CMP3DecMediaObject, DMOCATEGORY_AUDIO_DECODER);
- if (FAILED(hr)) {
- // Can't instantiate MP3 DMO. It doesn't exist on Windows XP, we're
- // probably hitting that. Don't log warning to console, this is an
- // expected error.
- WARN("dmoWrapper Init failed, hr=%x", hr);
- return hr;
- }
-
- filter.forget(aOutFilter);
-
- return S_OK;
-}
-
-HRESULT
-AddMP3DMOWrapperFilter(IGraphBuilder* aGraph,
- IBaseFilter **aOutFilter)
-{
- NS_ENSURE_TRUE(aGraph, E_POINTER);
- NS_ENSURE_TRUE(aOutFilter, E_POINTER);
- HRESULT hr;
-
- // Create the wrapper filter.
- RefPtr<IBaseFilter> filter;
- hr = CreateMP3DMOWrapperFilter(getter_AddRefs(filter));
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- // Add the wrapper filter to graph.
- hr = aGraph->AddFilter(filter, L"MP3 Decoder DMO");
- if (FAILED(hr)) {
- WARN("AddFilter failed, hr=%x", hr);
- return hr;
- }
-
- filter.forget(aOutFilter);
-
- return S_OK;
-}
-
-bool
-CanDecodeMP3UsingDirectShow()
-{
- RefPtr<IBaseFilter> filter;
-
- // Can we create the MP3 demuxer filter?
- if (FAILED(CoCreateInstance(CLSID_MPEG1Splitter,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter)))) {
- return false;
- }
-
- // Can we create either the WinXP MP3 decoder filter or the MP3 DMO decoder?
- if (FAILED(CoCreateInstance(DirectShowReader::CLSID_MPEG_LAYER_3_DECODER_FILTER,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- getter_AddRefs(filter))) &&
- FAILED(CreateMP3DMOWrapperFilter(getter_AddRefs(filter)))) {
- return false;
- }
-
- // Else, we can create all of the components we need. Assume
- // DirectShow is going to work...
- return true;
-}
-
-// Match a pin by pin direction and connection state.
-HRESULT
-MatchUnconnectedPin(IPin* aPin,
- PIN_DIRECTION aPinDir,
- bool *aOutMatches)
-{
- NS_ENSURE_TRUE(aPin, E_POINTER);
- NS_ENSURE_TRUE(aOutMatches, E_POINTER);
-
- // Ensure the pin is unconnected.
- RefPtr<IPin> peer;
- HRESULT hr = aPin->ConnectedTo(getter_AddRefs(peer));
- if (hr != VFW_E_NOT_CONNECTED) {
- *aOutMatches = false;
- return hr;
- }
-
- // Ensure the pin is of the specified direction.
- PIN_DIRECTION pinDir;
- hr = aPin->QueryDirection(&pinDir);
- NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-
- *aOutMatches = (pinDir == aPinDir);
- return S_OK;
-}
-
-// Return the first unconnected input pin or output pin.
-already_AddRefed<IPin>
-GetUnconnectedPin(IBaseFilter* aFilter, PIN_DIRECTION aPinDir)
-{
- RefPtr<IEnumPins> enumPins;
-
- HRESULT hr = aFilter->EnumPins(getter_AddRefs(enumPins));
- NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
-
- // Test each pin to see if it matches the direction we're looking for.
- RefPtr<IPin> pin;
- while (S_OK == enumPins->Next(1, getter_AddRefs(pin), nullptr)) {
- bool matches = FALSE;
- if (SUCCEEDED(MatchUnconnectedPin(pin, aPinDir, &matches)) &&
- matches) {
- return pin.forget();
- }
- }
-
- return nullptr;
-}
-
-HRESULT
-ConnectFilters(IGraphBuilder* aGraph,
- IBaseFilter* aOutputFilter,
- IBaseFilter* aInputFilter)
-{
- RefPtr<IPin> output = GetUnconnectedPin(aOutputFilter, PINDIR_OUTPUT);
- NS_ENSURE_TRUE(output, E_FAIL);
-
- RefPtr<IPin> input = GetUnconnectedPin(aInputFilter, PINDIR_INPUT);
- NS_ENSURE_TRUE(output, E_FAIL);
-
- return aGraph->Connect(output, input);
-}
-
-} // namespace mozilla
-
-// avoid redefined macro in unified build
-#undef WARN
diff --git a/dom/media/directshow/DirectShowUtils.h b/dom/media/directshow/DirectShowUtils.h
deleted file mode 100644
index 3bbc122fc..000000000
--- a/dom/media/directshow/DirectShowUtils.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _DirectShowUtils_h_
-#define _DirectShowUtils_h_
-
-#include <stdint.h>
-#include "dshow.h"
-
-// XXXbz windowsx.h defines GetFirstChild, GetNextSibling,
-// GetPrevSibling are macros, apparently... Eeevil. We have functions
-// called that on some classes, so undef them.
-#undef GetFirstChild
-#undef GetNextSibling
-#undef GetPrevSibling
-
-#include "DShowTools.h"
-#include "mozilla/Logging.h"
-
-namespace mozilla {
-
-// Win32 "Event" wrapper. Must be paired with a CriticalSection to create a
-// Java-style "monitor".
-class Signal {
-public:
-
- Signal(CriticalSection* aLock)
- : mLock(aLock)
- {
- CriticalSectionAutoEnter lock(*mLock);
- mEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
- }
-
- ~Signal() {
- CriticalSectionAutoEnter lock(*mLock);
- CloseHandle(mEvent);
- }
-
- // Lock must be held.
- void Notify() {
- SetEvent(mEvent);
- }
-
- // Lock must be held. Check the wait condition before waiting!
- HRESULT Wait() {
- mLock->Leave();
- DWORD result = WaitForSingleObject(mEvent, INFINITE);
- mLock->Enter();
- return result == WAIT_OBJECT_0 ? S_OK : E_FAIL;
- }
-
-private:
- CriticalSection* mLock;
- HANDLE mEvent;
-};
-
-HRESULT
-AddGraphToRunningObjectTable(IUnknown *aUnkGraph, DWORD *aOutRotRegister);
-
-void
-RemoveGraphFromRunningObjectTable(DWORD aRotRegister);
-
-const char*
-GetGraphNotifyString(long evCode);
-
-// Creates a filter and adds it to a graph.
-HRESULT
-CreateAndAddFilter(IGraphBuilder* aGraph,
- REFGUID aFilterClsId,
- LPCWSTR aFilterName,
- IBaseFilter **aOutFilter);
-
-HRESULT
-AddMP3DMOWrapperFilter(IGraphBuilder* aGraph,
- IBaseFilter **aOutFilter);
-
-// Connects the output pin on aOutputFilter to an input pin on
-// aInputFilter, in aGraph.
-HRESULT
-ConnectFilters(IGraphBuilder* aGraph,
- IBaseFilter* aOutputFilter,
- IBaseFilter* aInputFilter);
-
-HRESULT
-MatchUnconnectedPin(IPin* aPin,
- PIN_DIRECTION aPinDir,
- bool *aOutMatches);
-
-// Converts from microseconds to DirectShow "Reference Time"
-// (hundreds of nanoseconds).
-inline int64_t
-UsecsToRefTime(const int64_t aUsecs)
-{
- return aUsecs * 10;
-}
-
-// Converts from DirectShow "Reference Time" (hundreds of nanoseconds)
-// to microseconds.
-inline int64_t
-RefTimeToUsecs(const int64_t hRefTime)
-{
- return hRefTime / 10;
-}
-
-// Converts from DirectShow "Reference Time" (hundreds of nanoseconds)
-// to seconds.
-inline double
-RefTimeToSeconds(const REFERENCE_TIME aRefTime)
-{
- return double(aRefTime) / 10000000;
-}
-
-const char*
-GetDirectShowGuidName(const GUID& aGuid);
-
-// Returns true if we can instantiate an MP3 demuxer and decoder filters.
-// Use this to detect whether MP3 support is installed.
-bool
-CanDecodeMP3UsingDirectShow();
-
-} // namespace mozilla
-
-#endif
diff --git a/dom/media/directshow/SampleSink.cpp b/dom/media/directshow/SampleSink.cpp
deleted file mode 100644
index fa5dc8d19..000000000
--- a/dom/media/directshow/SampleSink.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SampleSink.h"
-#include "AudioSinkFilter.h"
-#include "AudioSinkInputPin.h"
-#include "VideoUtils.h"
-#include "mozilla/Logging.h"
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-SampleSink::SampleSink()
- : mMonitor("SampleSink"),
- mIsFlushing(false),
- mAtEOS(false)
-{
- MOZ_COUNT_CTOR(SampleSink);
-}
-
-SampleSink::~SampleSink()
-{
- MOZ_COUNT_DTOR(SampleSink);
-}
-
-void
-SampleSink::SetAudioFormat(const WAVEFORMATEX* aInFormat)
-{
- NS_ENSURE_TRUE(aInFormat, );
- ReentrantMonitorAutoEnter mon(mMonitor);
- memcpy(&mAudioFormat, aInFormat, sizeof(WAVEFORMATEX));
-}
-
-void
-SampleSink::GetAudioFormat(WAVEFORMATEX* aOutFormat)
-{
- MOZ_ASSERT(aOutFormat);
- ReentrantMonitorAutoEnter mon(mMonitor);
- memcpy(aOutFormat, &mAudioFormat, sizeof(WAVEFORMATEX));
-}
-
-HRESULT
-SampleSink::Receive(IMediaSample* aSample)
-{
- ReentrantMonitorAutoEnter mon(mMonitor);
-
- while (true) {
- if (mIsFlushing) {
- return S_FALSE;
- }
- if (!mSample) {
- break;
- }
- if (mAtEOS) {
- return E_UNEXPECTED;
- }
- // Wait until the consumer thread consumes the sample.
- mon.Wait();
- }
-
- if (MOZ_LOG_TEST(gDirectShowLog, LogLevel::Debug)) {
- REFERENCE_TIME start = 0, end = 0;
- HRESULT hr = aSample->GetMediaTime(&start, &end);
- LOG("SampleSink::Receive() [%4.2lf-%4.2lf]",
- (double)RefTimeToUsecs(start) / USECS_PER_S,
- (double)RefTimeToUsecs(end) / USECS_PER_S);
- }
-
- mSample = aSample;
- // Notify the signal, to awaken the consumer thread in WaitForSample()
- // if necessary.
- mon.NotifyAll();
- return S_OK;
-}
-
-HRESULT
-SampleSink::Extract(RefPtr<IMediaSample>& aOutSample)
-{
- ReentrantMonitorAutoEnter mon(mMonitor);
- // Loop until we have a sample, or we should abort.
- while (true) {
- if (mIsFlushing) {
- return S_FALSE;
- }
- if (mSample) {
- break;
- }
- if (mAtEOS) {
- // Order is important here, if we have a sample, we should return it
- // before reporting EOS.
- return E_UNEXPECTED;
- }
- // Wait until the producer thread gives us a sample.
- mon.Wait();
- }
- aOutSample = mSample;
-
- if (MOZ_LOG_TEST(gDirectShowLog, LogLevel::Debug)) {
- int64_t start = 0, end = 0;
- mSample->GetMediaTime(&start, &end);
- LOG("SampleSink::Extract() [%4.2lf-%4.2lf]",
- (double)RefTimeToUsecs(start) / USECS_PER_S,
- (double)RefTimeToUsecs(end) / USECS_PER_S);
- }
-
- mSample = nullptr;
- // Notify the signal, to awaken the producer thread in Receive()
- // if necessary.
- mon.NotifyAll();
- return S_OK;
-}
-
-void
-SampleSink::Flush()
-{
- LOG("SampleSink::Flush()");
- ReentrantMonitorAutoEnter mon(mMonitor);
- mIsFlushing = true;
- mSample = nullptr;
- mon.NotifyAll();
-}
-
-void
-SampleSink::Reset()
-{
- LOG("SampleSink::Reset()");
- ReentrantMonitorAutoEnter mon(mMonitor);
- mIsFlushing = false;
- mAtEOS = false;
-}
-
-void
-SampleSink::SetEOS()
-{
- LOG("SampleSink::SetEOS()");
- ReentrantMonitorAutoEnter mon(mMonitor);
- mAtEOS = true;
- // Notify to unblock any threads waiting for samples in
- // Extract() or Receive(). Now that we're at EOS, no more samples
- // will come!
- mon.NotifyAll();
-}
-
-bool
-SampleSink::AtEOS()
-{
- ReentrantMonitorAutoEnter mon(mMonitor);
- return mAtEOS && !mSample;
-}
-
-} // namespace mozilla
-
diff --git a/dom/media/directshow/SampleSink.h b/dom/media/directshow/SampleSink.h
deleted file mode 100644
index 6a1af9fee..000000000
--- a/dom/media/directshow/SampleSink.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(SampleSink_h_)
-#define SampleSink_h_
-
-#include "BaseFilter.h"
-#include "DirectShowUtils.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/ReentrantMonitor.h"
-
-namespace mozilla {
-
-class SampleSink {
-public:
- SampleSink();
- virtual ~SampleSink();
-
- // Sets the audio format of the incoming samples. The upstream filter
- // calls this. This makes a copy.
- void SetAudioFormat(const WAVEFORMATEX* aInFormat);
-
- // Copies the format of incoming audio samples into into *aOutFormat.
- void GetAudioFormat(WAVEFORMATEX* aOutFormat);
-
- // Called when a sample is delivered by the DirectShow graph to the sink.
- // The decode thread retrieves the sample by calling WaitForSample().
- // Blocks if there's already a sample waiting to be consumed by the decode
- // thread.
- HRESULT Receive(IMediaSample* aSample);
-
- // Retrieves a sample from the sample queue, blocking until one becomes
- // available, or until an error occurs. Returns S_FALSE on EOS.
- HRESULT Extract(RefPtr<IMediaSample>& aOutSample);
-
- // Unblocks any threads waiting in GetSample().
- // Clears mSample, which unblocks upstream stream.
- void Flush();
-
- // Opens up the sink to receive more samples in PutSample().
- // Clears EOS flag.
- void Reset();
-
- // Marks that we've reacehd the end of stream.
- void SetEOS();
-
- // Returns whether we're at end of stream.
- bool AtEOS();
-
-private:
- // All data in this class is syncronized by mMonitor.
- ReentrantMonitor mMonitor;
- RefPtr<IMediaSample> mSample;
-
- // Format of the audio stream we're receiving.
- WAVEFORMATEX mAudioFormat;
-
- bool mIsFlushing;
- bool mAtEOS;
-};
-
-} // namespace mozilla
-
-#endif // SampleSink_h_
diff --git a/dom/media/directshow/SourceFilter.cpp b/dom/media/directshow/SourceFilter.cpp
deleted file mode 100644
index 4c5a0882c..000000000
--- a/dom/media/directshow/SourceFilter.cpp
+++ /dev/null
@@ -1,683 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SourceFilter.h"
-#include "MediaResource.h"
-#include "mozilla/RefPtr.h"
-#include "DirectShowUtils.h"
-#include "MP3FrameParser.h"
-#include "mozilla/Logging.h"
-#include <algorithm>
-
-using namespace mozilla::media;
-
-namespace mozilla {
-
-// Define to trace what's on...
-//#define DEBUG_SOURCE_TRACE 1
-
-#if defined (DEBUG_SOURCE_TRACE)
-static LazyLogModule gDirectShowLog("DirectShowDecoder");
-#define DIRECTSHOW_LOG(...) MOZ_LOG(gDirectShowLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-#else
-#define DIRECTSHOW_LOG(...)
-#endif
-
-static HRESULT
-DoGetInterface(IUnknown* aUnknown, void** aInterface)
-{
- if (!aInterface)
- return E_POINTER;
- *aInterface = aUnknown;
- aUnknown->AddRef();
- return S_OK;
-}
-
-// Stores details of IAsyncReader::Request().
-class ReadRequest {
-public:
-
- ReadRequest(IMediaSample* aSample,
- DWORD_PTR aDwUser,
- uint32_t aOffset,
- uint32_t aCount)
- : mSample(aSample),
- mDwUser(aDwUser),
- mOffset(aOffset),
- mCount(aCount)
- {
- MOZ_COUNT_CTOR(ReadRequest);
- }
-
- ~ReadRequest() {
- MOZ_COUNT_DTOR(ReadRequest);
- }
-
- RefPtr<IMediaSample> mSample;
- DWORD_PTR mDwUser;
- uint32_t mOffset;
- uint32_t mCount;
-};
-
-// A wrapper around media resource that presents only a partition of the
-// underlying resource to the caller to use. The partition returned is from
-// an offset to the end of stream, and this object deals with ensuring
-// the offsets and lengths etc are translated from the reduced partition
-// exposed to the caller, to the absolute offsets of the underlying stream.
-class MediaResourcePartition {
-public:
- MediaResourcePartition(MediaResource* aResource,
- int64_t aDataStart)
- : mResource(aResource),
- mDataOffset(aDataStart)
- {}
-
- int64_t GetLength() {
- int64_t len = mResource.GetLength();
- if (len == -1) {
- return len;
- }
- return std::max<int64_t>(0, len - mDataOffset);
- }
- nsresult ReadAt(int64_t aOffset, char* aBuffer,
- uint32_t aCount, uint32_t* aBytes)
- {
- return mResource.ReadAt(aOffset + mDataOffset,
- aBuffer,
- aCount,
- aBytes);
- }
- int64_t GetCachedDataEnd() {
- int64_t tell = mResource.GetResource()->Tell();
- int64_t dataEnd =
- mResource.GetResource()->GetCachedDataEnd(tell) - mDataOffset;
- return dataEnd;
- }
-private:
- // MediaResource from which we read data.
- MediaResourceIndex mResource;
- int64_t mDataOffset;
-};
-
-
-// Output pin for SourceFilter, which implements IAsyncReader, to
-// allow downstream filters to pull/read data from it. Downstream pins
-// register to read data using Request(), and asynchronously wait for the
-// reads to complete using WaitForNext(). They may also synchronously read
-// using SyncRead(). This class is a delegate (tear off) of
-// SourceFilter.
-//
-// We can expose only a segment of the MediaResource to the filter graph.
-// This is used to strip off the ID3v2 tags from the stream, as DirectShow
-// has trouble parsing some headers.
-//
-// Implements:
-// * IAsyncReader
-// * IPin
-// * IQualityControl
-// * IUnknown
-//
-class DECLSPEC_UUID("18e5cfb2-1015-440c-a65c-e63853235894")
-OutputPin : public IAsyncReader,
- public BasePin
-{
-public:
-
- OutputPin(MediaResource* aMediaResource,
- SourceFilter* aParent,
- CriticalSection& aFilterLock,
- int64_t aMP3DataStart);
- virtual ~OutputPin();
-
- // IUnknown
- // Defer to ref counting to BasePin, which defers to owning nsBaseFilter.
- STDMETHODIMP_(ULONG) AddRef() override { return BasePin::AddRef(); }
- STDMETHODIMP_(ULONG) Release() override { return BasePin::Release(); }
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override;
-
- // BasePin Overrides.
- // Determines if the pin accepts a specific media type.
- HRESULT CheckMediaType(const MediaType* aMediaType) override;
-
- // Retrieves a preferred media type, by index value.
- HRESULT GetMediaType(int aPosition, MediaType* aMediaType) override;
-
- // Releases the pin from a connection.
- HRESULT BreakConnect(void) override;
-
- // Determines whether a pin connection is suitable.
- HRESULT CheckConnect(IPin* aPin) override;
-
-
- // IAsyncReader overrides
-
- // The RequestAllocator method requests an allocator during the
- // pin connection.
- STDMETHODIMP RequestAllocator(IMemAllocator* aPreferred,
- ALLOCATOR_PROPERTIES* aProps,
- IMemAllocator** aActual) override;
-
- // The Request method queues an asynchronous request for data. Downstream
- // will call WaitForNext() when they want to retrieve the result.
- STDMETHODIMP Request(IMediaSample* aSample, DWORD_PTR aUserData) override;
-
- // The WaitForNext method waits for the next pending read request
- // to complete. This method fails if the graph is flushing.
- // Defers to SyncRead/5.
- STDMETHODIMP WaitForNext(DWORD aTimeout,
- IMediaSample** aSamples,
- DWORD_PTR* aUserData) override;
-
- // The SyncReadAligned method performs a synchronous read. The method
- // blocks until the request is completed. Defers to SyncRead/5. This
- // method does not fail if the graph is flushing.
- STDMETHODIMP SyncReadAligned(IMediaSample* aSample) override;
-
- // The SyncRead method performs a synchronous read. The method blocks
- // until the request is completed. Defers to SyncRead/5. This
- // method does not fail if the graph is flushing.
- STDMETHODIMP SyncRead(LONGLONG aPosition, LONG aLength, BYTE* aBuffer) override;
-
- // The Length method retrieves the total length of the stream.
- STDMETHODIMP Length(LONGLONG* aTotal, LONGLONG* aAvailable) override;
-
- // IPin Overrides
- STDMETHODIMP BeginFlush(void) override;
- STDMETHODIMP EndFlush(void) override;
-
- uint32_t GetAndResetBytesConsumedCount();
-
-private:
-
- // Protects thread-shared data/structures (mFlushCount, mPendingReads).
- // WaitForNext() also waits on this monitor
- CriticalSection& mPinLock;
-
- // Signal used with mPinLock to implement WaitForNext().
- Signal mSignal;
-
- // The filter that owns us. Weak reference, as we're a delegate (tear off).
- SourceFilter* mParentSource;
-
- MediaResourcePartition mResource;
-
- // Counter, inc'd in BeginFlush(), dec'd in EndFlush(). Calls to this can
- // come from multiple threads and can interleave, hence the counter.
- int32_t mFlushCount;
-
- // Number of bytes that have been read from the output pin since the last
- // time GetAndResetBytesConsumedCount() was called.
- uint32_t mBytesConsumed;
-
- // Deque of ReadRequest* for reads that are yet to be serviced.
- // nsReadRequest's are stored on the heap, popper must delete them.
- nsDeque mPendingReads;
-
- // Flags if the downstream pin has QI'd for IAsyncReader. We refuse
- // connection if they don't query, as it means they're assuming that we're
- // a push filter, and we're not.
- bool mQueriedForAsyncReader;
-
-};
-
-// For mingw __uuidof support
-#ifdef __CRT_UUID_DECL
-}
-__CRT_UUID_DECL(mozilla::OutputPin, 0x18e5cfb2,0x1015,0x440c,0xa6,0x5c,0xe6,0x38,0x53,0x23,0x58,0x94);
-namespace mozilla {
-#endif
-
-OutputPin::OutputPin(MediaResource* aResource,
- SourceFilter* aParent,
- CriticalSection& aFilterLock,
- int64_t aMP3DataStart)
- : BasePin(static_cast<BaseFilter*>(aParent),
- &aFilterLock,
- L"MozillaOutputPin",
- PINDIR_OUTPUT),
- mPinLock(aFilterLock),
- mSignal(&mPinLock),
- mParentSource(aParent),
- mResource(aResource, aMP3DataStart),
- mFlushCount(0),
- mBytesConsumed(0),
- mQueriedForAsyncReader(false)
-{
- MOZ_COUNT_CTOR(OutputPin);
- DIRECTSHOW_LOG("OutputPin::OutputPin()");
-}
-
-OutputPin::~OutputPin()
-{
- MOZ_COUNT_DTOR(OutputPin);
- DIRECTSHOW_LOG("OutputPin::~OutputPin()");
-}
-
-HRESULT
-OutputPin::BreakConnect()
-{
- mQueriedForAsyncReader = false;
- return BasePin::BreakConnect();
-}
-
-STDMETHODIMP
-OutputPin::QueryInterface(REFIID aIId, void** aInterface)
-{
- if (aIId == IID_IAsyncReader) {
- mQueriedForAsyncReader = true;
- return DoGetInterface(static_cast<IAsyncReader*>(this), aInterface);
- }
-
- if (aIId == __uuidof(OutputPin)) {
- AddRef();
- *aInterface = this;
- return S_OK;
- }
-
- return BasePin::QueryInterface(aIId, aInterface);
-}
-
-HRESULT
-OutputPin::CheckConnect(IPin* aPin)
-{
- // Our connection is only suitable if the downstream pin knows
- // that we're asynchronous (i.e. it queried for IAsyncReader).
- return mQueriedForAsyncReader ? S_OK : S_FALSE;
-}
-
-HRESULT
-OutputPin::CheckMediaType(const MediaType* aMediaType)
-{
- const MediaType *myMediaType = mParentSource->GetMediaType();
-
- if (IsEqualGUID(aMediaType->majortype, myMediaType->majortype) &&
- IsEqualGUID(aMediaType->subtype, myMediaType->subtype) &&
- IsEqualGUID(aMediaType->formattype, myMediaType->formattype))
- {
- DIRECTSHOW_LOG("OutputPin::CheckMediaType() Match: major=%s minor=%s TC=%d FSS=%d SS=%u",
- GetDirectShowGuidName(aMediaType->majortype),
- GetDirectShowGuidName(aMediaType->subtype),
- aMediaType->TemporalCompression(),
- aMediaType->bFixedSizeSamples,
- aMediaType->SampleSize());
- return S_OK;
- }
-
- DIRECTSHOW_LOG("OutputPin::CheckMediaType() Failed to match: major=%s minor=%s TC=%d FSS=%d SS=%u",
- GetDirectShowGuidName(aMediaType->majortype),
- GetDirectShowGuidName(aMediaType->subtype),
- aMediaType->TemporalCompression(),
- aMediaType->bFixedSizeSamples,
- aMediaType->SampleSize());
- return S_FALSE;
-}
-
-HRESULT
-OutputPin::GetMediaType(int aPosition, MediaType* aMediaType)
-{
- if (!aMediaType)
- return E_POINTER;
-
- if (aPosition == 0) {
- aMediaType->Assign(mParentSource->GetMediaType());
- return S_OK;
- }
- return VFW_S_NO_MORE_ITEMS;
-}
-
-static inline bool
-IsPowerOf2(int32_t x) {
- return ((-x & x) != x);
-}
-
-STDMETHODIMP
-OutputPin::RequestAllocator(IMemAllocator* aPreferred,
- ALLOCATOR_PROPERTIES* aProps,
- IMemAllocator** aActual)
-{
- // Require the downstream pin to suggest what they want...
- if (!aPreferred) return E_POINTER;
- if (!aProps) return E_POINTER;
- if (!aActual) return E_POINTER;
-
- // We only care about alignment - our allocator will reject anything
- // which isn't power-of-2 aligned, so so try a 4-byte aligned allocator.
- ALLOCATOR_PROPERTIES props;
- memcpy(&props, aProps, sizeof(ALLOCATOR_PROPERTIES));
- if (aProps->cbAlign == 0 || IsPowerOf2(aProps->cbAlign)) {
- props.cbAlign = 4;
- }
-
- // Limit allocator's number of buffers. We know that the media will most
- // likely be bound by network speed, not by decoding speed. We also
- // store the incoming data in a Gecko stream, if we don't limit buffers
- // here we'll end up duplicating a lot of storage. We must have enough
- // space for audio key frames to fit in the first batch of buffers however,
- // else pausing may fail for some downstream decoders.
- if (props.cBuffers > BaseFilter::sMaxNumBuffers) {
- props.cBuffers = BaseFilter::sMaxNumBuffers;
- }
-
- // The allocator properties that are actually used. We don't store
- // this, we need it for SetProperties() below to succeed.
- ALLOCATOR_PROPERTIES actualProps;
- HRESULT hr;
-
- if (aPreferred) {
- // Play nice and prefer the downstream pin's preferred allocator.
- hr = aPreferred->SetProperties(&props, &actualProps);
- if (SUCCEEDED(hr)) {
- aPreferred->AddRef();
- *aActual = aPreferred;
- return S_OK;
- }
- }
-
- // Else downstream hasn't requested a specific allocator, so create one...
-
- // Just create a default allocator. It's highly unlikely that we'll use
- // this anyway, as most parsers insist on using their own allocators.
- RefPtr<IMemAllocator> allocator;
- hr = CoCreateInstance(CLSID_MemoryAllocator,
- 0,
- CLSCTX_INPROC_SERVER,
- IID_IMemAllocator,
- getter_AddRefs(allocator));
- if(FAILED(hr) || (allocator == nullptr)) {
- NS_WARNING("Can't create our own DirectShow allocator.");
- return hr;
- }
-
- // See if we can make it suitable
- hr = allocator->SetProperties(&props, &actualProps);
- if (SUCCEEDED(hr)) {
- // We need to release our refcount on pAlloc, and addref
- // it to pass a refcount to the caller - this is a net nothing.
- allocator.forget(aActual);
- return S_OK;
- }
-
- NS_WARNING("Failed to pick an allocator");
- return hr;
-}
-
-STDMETHODIMP
-OutputPin::Request(IMediaSample* aSample, DWORD_PTR aDwUser)
-{
- if (!aSample) return E_FAIL;
-
- CriticalSectionAutoEnter lock(*mLock);
- NS_ASSERTION(!mFlushCount, "Request() while flushing");
-
- if (mFlushCount)
- return VFW_E_WRONG_STATE;
-
- REFERENCE_TIME refStart = 0, refEnd = 0;
- if (FAILED(aSample->GetTime(&refStart, &refEnd))) {
- NS_WARNING("Sample incorrectly timestamped");
- return VFW_E_SAMPLE_TIME_NOT_SET;
- }
-
- // Convert reference time to bytes.
- uint32_t start = (uint32_t)(refStart / 10000000);
- uint32_t end = (uint32_t)(refEnd / 10000000);
-
- uint32_t numBytes = end - start;
-
- ReadRequest* request = new ReadRequest(aSample,
- aDwUser,
- start,
- numBytes);
- // Memory for |request| is free when it's popped from the completed
- // reads list.
-
- // Push this onto the queue of reads to be serviced.
- mPendingReads.Push(request);
-
- // Notify any threads blocked in WaitForNext() which are waiting for mPendingReads
- // to become non-empty.
- mSignal.Notify();
-
- return S_OK;
-}
-
-STDMETHODIMP
-OutputPin::WaitForNext(DWORD aTimeout,
- IMediaSample** aOutSample,
- DWORD_PTR* aOutDwUser)
-{
- NS_ASSERTION(aTimeout == 0 || aTimeout == INFINITE,
- "Oops, we don't handle this!");
-
- *aOutSample = nullptr;
- *aOutDwUser = 0;
-
- LONGLONG offset = 0;
- LONG count = 0;
- BYTE* buf = nullptr;
-
- {
- CriticalSectionAutoEnter lock(*mLock);
-
- // Wait until there's a pending read to service.
- while (aTimeout && mPendingReads.GetSize() == 0 && !mFlushCount) {
- // Note: No need to guard against shutdown-during-wait here, as
- // typically the thread doing the pull will have already called
- // Request(), so we won't Wait() here anyway. SyncRead() will fail
- // on shutdown.
- mSignal.Wait();
- }
-
- nsAutoPtr<ReadRequest> request(reinterpret_cast<ReadRequest*>(mPendingReads.PopFront()));
- if (!request)
- return VFW_E_WRONG_STATE;
-
- *aOutSample = request->mSample;
- *aOutDwUser = request->mDwUser;
-
- offset = request->mOffset;
- count = request->mCount;
- buf = nullptr;
- request->mSample->GetPointer(&buf);
- NS_ASSERTION(buf != nullptr, "Invalid buffer!");
-
- if (mFlushCount) {
- return VFW_E_TIMEOUT;
- }
- }
-
- return SyncRead(offset, count, buf);
-}
-
-STDMETHODIMP
-OutputPin::SyncReadAligned(IMediaSample* aSample)
-{
- {
- // Ignore reads while flushing.
- CriticalSectionAutoEnter lock(*mLock);
- if (mFlushCount) {
- return S_FALSE;
- }
- }
-
- if (!aSample)
- return E_FAIL;
-
- REFERENCE_TIME lStart = 0, lEnd = 0;
- if (FAILED(aSample->GetTime(&lStart, &lEnd))) {
- NS_WARNING("Sample incorrectly timestamped");
- return VFW_E_SAMPLE_TIME_NOT_SET;
- }
-
- // Convert reference time to bytes.
- int32_t start = (int32_t)(lStart / 10000000);
- int32_t end = (int32_t)(lEnd / 10000000);
-
- int32_t numBytes = end - start;
-
- // If the range extends off the end of stream, truncate to the end of stream
- // as per IAsyncReader specificiation.
- int64_t streamLength = mResource.GetLength();
- if (streamLength != -1) {
- // We know the exact length of the stream, fail if the requested offset
- // is beyond it.
- if (start > streamLength) {
- return VFW_E_BADALIGN;
- }
-
- // If the end of the chunk to read is off the end of the stream,
- // truncate it to the end of the stream.
- if ((start + numBytes) > streamLength) {
- numBytes = (uint32_t)(streamLength - start);
- }
- }
-
- BYTE* buf=0;
- aSample->GetPointer(&buf);
-
- return SyncRead(start, numBytes, buf);
-}
-
-STDMETHODIMP
-OutputPin::SyncRead(LONGLONG aPosition,
- LONG aLength,
- BYTE* aBuffer)
-{
- MOZ_ASSERT(!NS_IsMainThread());
- NS_ENSURE_TRUE(aPosition >= 0, E_FAIL);
- NS_ENSURE_TRUE(aLength > 0, E_FAIL);
- NS_ENSURE_TRUE(aBuffer, E_POINTER);
-
- DIRECTSHOW_LOG("OutputPin::SyncRead(%lld, %d)", aPosition, aLength);
- {
- // Ignore reads while flushing.
- CriticalSectionAutoEnter lock(*mLock);
- if (mFlushCount) {
- return S_FALSE;
- }
- }
-
- uint32_t totalBytesRead = 0;
- nsresult rv = mResource.ReadAt(aPosition,
- reinterpret_cast<char*>(aBuffer),
- aLength,
- &totalBytesRead);
- if (NS_FAILED(rv)) {
- return E_FAIL;
- }
- if (totalBytesRead > 0) {
- CriticalSectionAutoEnter lock(*mLock);
- mBytesConsumed += totalBytesRead;
- }
- return (totalBytesRead == aLength) ? S_OK : S_FALSE;
-}
-
-STDMETHODIMP
-OutputPin::Length(LONGLONG* aTotal, LONGLONG* aAvailable)
-{
- HRESULT hr = S_OK;
- int64_t length = mResource.GetLength();
- if (length == -1) {
- hr = VFW_S_ESTIMATED;
- // Don't have a length. Just lie, it seems to work...
- *aTotal = INT32_MAX;
- } else {
- *aTotal = length;
- }
- if (aAvailable) {
- *aAvailable = mResource.GetCachedDataEnd();
- }
-
- DIRECTSHOW_LOG("OutputPin::Length() len=%lld avail=%lld", *aTotal, *aAvailable);
-
- return hr;
-}
-
-STDMETHODIMP
-OutputPin::BeginFlush()
-{
- CriticalSectionAutoEnter lock(*mLock);
- mFlushCount++;
- mSignal.Notify();
- return S_OK;
-}
-
-STDMETHODIMP
-OutputPin::EndFlush(void)
-{
- CriticalSectionAutoEnter lock(*mLock);
- mFlushCount--;
- return S_OK;
-}
-
-uint32_t
-OutputPin::GetAndResetBytesConsumedCount()
-{
- CriticalSectionAutoEnter lock(*mLock);
- uint32_t bytesConsumed = mBytesConsumed;
- mBytesConsumed = 0;
- return bytesConsumed;
-}
-
-SourceFilter::SourceFilter(const GUID& aMajorType,
- const GUID& aSubType)
- : BaseFilter(L"MozillaDirectShowSource", __uuidof(SourceFilter))
-{
- MOZ_COUNT_CTOR(SourceFilter);
- mMediaType.majortype = aMajorType;
- mMediaType.subtype = aSubType;
-
- DIRECTSHOW_LOG("SourceFilter Constructor(%s, %s)",
- GetDirectShowGuidName(aMajorType),
- GetDirectShowGuidName(aSubType));
-}
-
-SourceFilter::~SourceFilter()
-{
- MOZ_COUNT_DTOR(SourceFilter);
- DIRECTSHOW_LOG("SourceFilter Destructor()");
-}
-
-BasePin*
-SourceFilter::GetPin(int n)
-{
- if (n == 0) {
- NS_ASSERTION(mOutputPin != 0, "GetPin with no pin!");
- return static_cast<BasePin*>(mOutputPin);
- } else {
- return nullptr;
- }
-}
-
-// Get's the media type we're supplying.
-const MediaType*
-SourceFilter::GetMediaType() const
-{
- return &mMediaType;
-}
-
-nsresult
-SourceFilter::Init(MediaResource* aResource, int64_t aMP3Offset)
-{
- DIRECTSHOW_LOG("SourceFilter::Init()");
-
- mOutputPin = new OutputPin(aResource,
- this,
- mLock,
- aMP3Offset);
- NS_ENSURE_TRUE(mOutputPin != nullptr, NS_ERROR_FAILURE);
-
- return NS_OK;
-}
-
-uint32_t
-SourceFilter::GetAndResetBytesConsumedCount()
-{
- return mOutputPin->GetAndResetBytesConsumedCount();
-}
-
-
-} // namespace mozilla
diff --git a/dom/media/directshow/SourceFilter.h b/dom/media/directshow/SourceFilter.h
deleted file mode 100644
index d5ce2770e..000000000
--- a/dom/media/directshow/SourceFilter.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if !defined(nsDirectShowSource_h___)
-#define nsDirectShowSource_h___
-
-#include "BaseFilter.h"
-#include "BasePin.h"
-#include "MediaType.h"
-
-#include "nsDeque.h"
-#include "nsAutoPtr.h"
-#include "DirectShowUtils.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-
-class MediaResource;
-class OutputPin;
-
-
-// SourceFilter is an asynchronous DirectShow source filter which
-// reads from an MediaResource, and supplies data via a pull model downstream
-// using OutputPin. It us used to supply a generic byte stream into
-// DirectShow.
-//
-// Implements:
-// * IBaseFilter
-// * IMediaFilter
-// * IPersist
-// * IUnknown
-//
-class DECLSPEC_UUID("5c2a7ad0-ba82-4659-9178-c4719a2765d6")
-SourceFilter : public media::BaseFilter
-{
-public:
-
- // Constructs source filter to deliver given media type.
- SourceFilter(const GUID& aMajorType, const GUID& aSubType);
- ~SourceFilter();
-
- nsresult Init(MediaResource *aResource, int64_t aMP3Offset);
-
- // BaseFilter overrides.
- // Only one output - the byte stream.
- int GetPinCount() override { return 1; }
-
- media::BasePin* GetPin(int n) override;
-
- // Get's the media type we're supplying.
- const media::MediaType* GetMediaType() const;
-
- uint32_t GetAndResetBytesConsumedCount();
-
-protected:
-
- // Our async pull output pin.
- nsAutoPtr<OutputPin> mOutputPin;
-
- // Type of byte stream we output.
- media::MediaType mMediaType;
-
-};
-
-} // namespace mozilla
-
-// For mingw __uuidof support
-#ifdef __CRT_UUID_DECL
-__CRT_UUID_DECL(mozilla::SourceFilter, 0x5c2a7ad0,0xba82,0x4659,0x91,0x78,0xc4,0x71,0x9a,0x27,0x65,0xd6);
-#endif
-
-#endif
diff --git a/dom/media/directshow/moz.build b/dom/media/directshow/moz.build
deleted file mode 100644
index 8a9b76200..000000000
--- a/dom/media/directshow/moz.build
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXPORTS += [
- 'AudioSinkFilter.h',
- 'AudioSinkInputPin.h',
- 'DirectShowDecoder.h',
- 'DirectShowReader.h',
- 'DirectShowUtils.h',
-]
-
-UNIFIED_SOURCES += [
- 'DirectShowDecoder.cpp',
- 'DirectShowUtils.cpp',
- 'SourceFilter.cpp',
-]
-
-SOURCES += [
- 'AudioSinkFilter.cpp',
- 'AudioSinkInputPin.cpp',
- 'DirectShowReader.cpp',
- 'SampleSink.cpp',
-]
-
-# If WebRTC isn't being built, we need to compile the DirectShow base classes so that
-# they're available at link time.
-if not CONFIG['MOZ_WEBRTC']:
- SOURCES += [
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseFilter.cpp',
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/BaseInputPin.cpp',
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/BasePin.cpp',
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows/MediaType.cpp',
- ]
-
-FINAL_LIBRARY = 'xul'
-LOCAL_INCLUDES += [
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows',
-]
diff --git a/dom/media/moz.build b/dom/media/moz.build
index 4d036a5f6..b3db05af1 100644
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -42,9 +42,6 @@ DIRS += [
'standalone',
]
-if CONFIG['MOZ_DIRECTSHOW']:
- DIRS += ['directshow']
-
if CONFIG['MOZ_ANDROID_OMX']:
DIRS += ['android']
@@ -294,11 +291,6 @@ LOCAL_INCLUDES += [
'/netwerk/base',
]
-if CONFIG['MOZ_DIRECTSHOW']:
- LOCAL_INCLUDES += [
- '/media/webrtc/trunk/webrtc/modules/video_capture/windows',
- ]
-
if CONFIG['MOZ_WEBRTC']:
LOCAL_INCLUDES += [
'/media/webrtc/signaling/src/common',
diff --git a/dom/media/test/manifest.js b/dom/media/test/manifest.js
index 7e30cc97d..52e53a271 100644
--- a/dom/media/test/manifest.js
+++ b/dom/media/test/manifest.js
@@ -266,10 +266,10 @@ var gPlayTests = [
{ name:"small-shot.mp3", type:"audio/mpeg", duration:0.27 },
{ name:"owl.mp3", type:"audio/mpeg", duration:3.343 },
// owl.mp3 as above, but with something funny going on in the ID3v2 tag
- // that causes DirectShow to fail.
+ // that caused DirectShow to fail.
{ name:"owl-funny-id3.mp3", type:"audio/mpeg", duration:3.343 },
// owl.mp3 as above, but with something even funnier going on in the ID3v2 tag
- // that causes DirectShow to fail.
+ // that caused DirectShow to fail.
{ name:"owl-funnier-id3.mp3", type:"audio/mpeg", duration:3.343 },
// One second of silence with ~140KB of ID3 tags. Usually when the first MP3
// frame is at such a high offset into the file, MP3FrameParser will give up
diff --git a/dom/media/test/test_can_play_type_mpeg.html b/dom/media/test/test_can_play_type_mpeg.html
index 89e5fabef..514b5cc2f 100644
--- a/dom/media/test/test_can_play_type_mpeg.html
+++ b/dom/media/test/test_can_play_type_mpeg.html
@@ -151,8 +151,7 @@ var haveMp4 = (getPref("media.wmf.enabled") && IsWindowsVistaOrLater()) ||
check_mp4(document.getElementById('v'), haveMp4);
-var haveMp3 = getPref("media.directshow.enabled") ||
- (getPref("media.wmf.enabled") && IsWindowsVistaOrLater()) ||
+var haveMp3 = getPref("media.wmf.enabled") ||
(IsLinux() && getPref("media.ffmpeg.enabled")) ||
(IsSupportedAndroid() &&
((IsJellyBeanOrLater() && getPref("media.android-media-codec.enabled")) ||