mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-13 02:37:32 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
195
dom/media/directshow/AudioSinkInputPin.cpp
Normal file
195
dom/media/directshow/AudioSinkInputPin.cpp
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/* -*- 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
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue