зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset bc4680ea08a9 (bug 1307042) for android mda test failures a=backout CLOSED TREE
This commit is contained in:
Родитель
265355461f
Коммит
5739609d11
|
@ -13,7 +13,6 @@
|
||||||
#include "ImageTypes.h"
|
#include "ImageTypes.h"
|
||||||
#include "prmem.h"
|
#include "prmem.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "MediaStreamGraph.h"
|
|
||||||
|
|
||||||
#include "nsIFilePicker.h"
|
#include "nsIFilePicker.h"
|
||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
|
@ -368,13 +367,14 @@ private:
|
||||||
/**
|
/**
|
||||||
* Default audio source.
|
* Default audio source.
|
||||||
*/
|
*/
|
||||||
|
NS_IMPL_ISUPPORTS(MediaEngineDefaultAudioSource, nsITimerCallback)
|
||||||
NS_IMPL_ISUPPORTS0(MediaEngineDefaultAudioSource)
|
|
||||||
|
|
||||||
MediaEngineDefaultAudioSource::MediaEngineDefaultAudioSource()
|
MediaEngineDefaultAudioSource::MediaEngineDefaultAudioSource()
|
||||||
: MediaEngineAudioSource(kReleased)
|
: MediaEngineAudioSource(kReleased)
|
||||||
, mLastNotify(0)
|
, mPrincipalHandle(PRINCIPAL_HANDLE_NONE)
|
||||||
{}
|
, mTimer(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
MediaEngineDefaultAudioSource::~MediaEngineDefaultAudioSource()
|
MediaEngineDefaultAudioSource::~MediaEngineDefaultAudioSource()
|
||||||
{}
|
{}
|
||||||
|
@ -453,15 +453,43 @@ MediaEngineDefaultAudioSource::Start(SourceMediaStream* aStream, TrackID aID,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||||
|
if (!mTimer) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSource = aStream;
|
||||||
|
|
||||||
|
// We try to keep the appended data at this size.
|
||||||
|
// Make it two timer intervals to try to avoid underruns.
|
||||||
|
mBufferSize = 2 * (AUDIO_RATE * DEFAULT_AUDIO_TIMER_MS) / 1000;
|
||||||
|
|
||||||
// AddTrack will take ownership of segment
|
// AddTrack will take ownership of segment
|
||||||
AudioSegment* segment = new AudioSegment();
|
AudioSegment* segment = new AudioSegment();
|
||||||
aStream->AddAudioTrack(aID, AUDIO_RATE, 0, segment, SourceMediaStream::ADDTRACK_QUEUED);
|
AppendToSegment(*segment, mBufferSize);
|
||||||
|
mSource->AddAudioTrack(aID, AUDIO_RATE, 0, segment, SourceMediaStream::ADDTRACK_QUEUED);
|
||||||
|
|
||||||
// Remember TrackID so we can finish later
|
// Remember TrackID so we can finish later
|
||||||
mTrackID = aID;
|
mTrackID = aID;
|
||||||
|
|
||||||
mLastNotify = 0;
|
// Remember PrincipalHandle since we don't append in NotifyPull.
|
||||||
|
mPrincipalHandle = aPrincipalHandle;
|
||||||
|
|
||||||
|
mLastNotify = TimeStamp::Now();
|
||||||
|
|
||||||
|
// 1 Audio frame per 10ms
|
||||||
|
// We'd like to do this for Android Debug as well, but that breaks tests that check for
|
||||||
|
// audio frequency data.
|
||||||
|
#if defined(MOZ_WIDGET_GONK) && defined(DEBUG)
|
||||||
|
// emulator debug is very, very slow and has problems dealing with realtime audio inputs
|
||||||
|
mTimer->InitWithCallback(this, DEFAULT_AUDIO_TIMER_MS*10,
|
||||||
|
nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP);
|
||||||
|
#else
|
||||||
|
mTimer->InitWithCallback(this, DEFAULT_AUDIO_TIMER_MS,
|
||||||
|
nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP);
|
||||||
|
#endif
|
||||||
mState = kStarted;
|
mState = kStarted;
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,6 +499,13 @@ MediaEngineDefaultAudioSource::Stop(SourceMediaStream *aSource, TrackID aID)
|
||||||
if (mState != kStarted) {
|
if (mState != kStarted) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
if (!mTimer) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mTimer->Cancel();
|
||||||
|
mTimer = nullptr;
|
||||||
|
|
||||||
aSource->EndTrack(aID);
|
aSource->EndTrack(aID);
|
||||||
|
|
||||||
mState = kStopped;
|
mState = kStopped;
|
||||||
|
@ -489,8 +524,7 @@ MediaEngineDefaultAudioSource::Restart(AllocationHandle* aHandle,
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaEngineDefaultAudioSource::AppendToSegment(AudioSegment& aSegment,
|
MediaEngineDefaultAudioSource::AppendToSegment(AudioSegment& aSegment,
|
||||||
TrackTicks aSamples,
|
TrackTicks aSamples)
|
||||||
const PrincipalHandle& aPrincipalHandle)
|
|
||||||
{
|
{
|
||||||
RefPtr<SharedBuffer> buffer = SharedBuffer::Create(aSamples * sizeof(int16_t));
|
RefPtr<SharedBuffer> buffer = SharedBuffer::Create(aSamples * sizeof(int16_t));
|
||||||
int16_t* dest = static_cast<int16_t*>(buffer->Data());
|
int16_t* dest = static_cast<int16_t*>(buffer->Data());
|
||||||
|
@ -498,24 +532,28 @@ MediaEngineDefaultAudioSource::AppendToSegment(AudioSegment& aSegment,
|
||||||
mSineGenerator->generate(dest, aSamples);
|
mSineGenerator->generate(dest, aSamples);
|
||||||
AutoTArray<const int16_t*,1> channels;
|
AutoTArray<const int16_t*,1> channels;
|
||||||
channels.AppendElement(dest);
|
channels.AppendElement(dest);
|
||||||
aSegment.AppendFrames(buffer.forget(), channels, aSamples, aPrincipalHandle);
|
aSegment.AppendFrames(buffer.forget(), channels, aSamples, mPrincipalHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
NS_IMETHODIMP
|
||||||
MediaEngineDefaultAudioSource::NotifyPull(MediaStreamGraph* aGraph,
|
MediaEngineDefaultAudioSource::Notify(nsITimer* aTimer)
|
||||||
SourceMediaStream *aSource,
|
|
||||||
TrackID aID,
|
|
||||||
StreamTime aDesiredTime,
|
|
||||||
const PrincipalHandle& aPrincipalHandle)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aID == mTrackID);
|
TimeStamp now = TimeStamp::Now();
|
||||||
|
TimeDuration timeSinceLastNotify = now - mLastNotify;
|
||||||
|
mLastNotify = now;
|
||||||
|
TrackTicks samplesSinceLastNotify =
|
||||||
|
RateConvertTicksRoundUp(AUDIO_RATE, 1000000, timeSinceLastNotify.ToMicroseconds());
|
||||||
|
|
||||||
|
// If it's been longer since the last Notify() than mBufferSize holds, we
|
||||||
|
// have underrun and the MSG had to append silence while waiting for us
|
||||||
|
// to push more data. In this case we reset to mBufferSize again.
|
||||||
|
TrackTicks samplesToAppend = std::min(samplesSinceLastNotify, mBufferSize);
|
||||||
|
|
||||||
AudioSegment segment;
|
AudioSegment segment;
|
||||||
// avoid accumulating rounding errors
|
AppendToSegment(segment, samplesToAppend);
|
||||||
TrackTicks desired = aSource->TimeToTicksRoundUp(AUDIO_RATE, aDesiredTime);
|
mSource->AppendToTrack(mTrackID, &segment);
|
||||||
TrackTicks delta = desired - mLastNotify;
|
|
||||||
mLastNotify += delta;
|
return NS_OK;
|
||||||
AppendToSegment(segment, delta, aPrincipalHandle);
|
|
||||||
aSource->AppendToTrack(mTrackID, &segment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -97,7 +97,8 @@ protected:
|
||||||
nsCOMPtr<nsITimer> mTimer;
|
nsCOMPtr<nsITimer> mTimer;
|
||||||
// mMonitor protects mImage access/changes, and transitions of mState
|
// mMonitor protects mImage access/changes, and transitions of mState
|
||||||
// from kStarted to kStopped (which are combined with EndTrack() and
|
// from kStarted to kStopped (which are combined with EndTrack() and
|
||||||
// image changes).
|
// image changes). Note that mSources is not accessed from other threads
|
||||||
|
// for video and is not protected.
|
||||||
Monitor mMonitor;
|
Monitor mMonitor;
|
||||||
RefPtr<layers::Image> mImage;
|
RefPtr<layers::Image> mImage;
|
||||||
|
|
||||||
|
@ -110,7 +111,8 @@ protected:
|
||||||
|
|
||||||
class SineWaveGenerator;
|
class SineWaveGenerator;
|
||||||
|
|
||||||
class MediaEngineDefaultAudioSource : public MediaEngineAudioSource
|
class MediaEngineDefaultAudioSource : public nsITimerCallback,
|
||||||
|
public MediaEngineAudioSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MediaEngineDefaultAudioSource();
|
MediaEngineDefaultAudioSource();
|
||||||
|
@ -133,14 +135,22 @@ public:
|
||||||
const nsString& aDeviceId,
|
const nsString& aDeviceId,
|
||||||
const char** aOutBadConstraint) override;
|
const char** aOutBadConstraint) override;
|
||||||
void SetDirectListeners(bool aHasDirectListeners) override {};
|
void SetDirectListeners(bool aHasDirectListeners) override {};
|
||||||
void inline AppendToSegment(AudioSegment& aSegment,
|
void AppendToSegment(AudioSegment& aSegment,
|
||||||
TrackTicks aSamples,
|
TrackTicks aSamples);
|
||||||
const PrincipalHandle& aPrincipalHandle);
|
|
||||||
void NotifyPull(MediaStreamGraph* aGraph,
|
void NotifyPull(MediaStreamGraph* aGraph,
|
||||||
SourceMediaStream *aSource,
|
SourceMediaStream *aSource,
|
||||||
TrackID aId,
|
TrackID aId,
|
||||||
StreamTime aDesiredTime,
|
StreamTime aDesiredTime,
|
||||||
const PrincipalHandle& aPrincipalHandle) override;
|
const PrincipalHandle& aPrincipalHandle) override
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
StreamTracks::Track* data = aSource->FindTrack(aId);
|
||||||
|
NS_WARNING_ASSERTION(
|
||||||
|
!data || data->IsEnded() ||
|
||||||
|
aDesiredTime <= aSource->GetEndOfAppendedData(aId),
|
||||||
|
"MediaEngineDefaultAudioSource data underrun");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void NotifyOutputData(MediaStreamGraph* aGraph,
|
void NotifyOutputData(MediaStreamGraph* aGraph,
|
||||||
AudioDataValue* aBuffer, size_t aFrames,
|
AudioDataValue* aBuffer, size_t aFrames,
|
||||||
|
@ -170,15 +180,19 @@ public:
|
||||||
const nsString& aDeviceId) const override;
|
const nsString& aDeviceId) const override;
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
NS_DECL_NSITIMERCALLBACK
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~MediaEngineDefaultAudioSource();
|
~MediaEngineDefaultAudioSource();
|
||||||
|
|
||||||
TrackID mTrackID;
|
TrackID mTrackID;
|
||||||
|
PrincipalHandle mPrincipalHandle;
|
||||||
|
nsCOMPtr<nsITimer> mTimer;
|
||||||
|
|
||||||
TrackTicks mLastNotify; // Accessed in ::Start(), then on NotifyPull (from MSG thread)
|
TimeStamp mLastNotify;
|
||||||
|
TrackTicks mBufferSize;
|
||||||
|
|
||||||
// Created on Allocate, then accessed from NotifyPull (MSG thread)
|
SourceMediaStream* mSource;
|
||||||
nsAutoPtr<SineWaveGenerator> mSineGenerator;
|
nsAutoPtr<SineWaveGenerator> mSineGenerator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -238,8 +238,6 @@ class Fake_MediaStream {
|
||||||
double StreamTimeToSeconds(mozilla::StreamTime aTime);
|
double StreamTimeToSeconds(mozilla::StreamTime aTime);
|
||||||
mozilla::StreamTime
|
mozilla::StreamTime
|
||||||
TicksToTimeRoundDown(mozilla::TrackRate aRate, mozilla::TrackTicks aTicks);
|
TicksToTimeRoundDown(mozilla::TrackRate aRate, mozilla::TrackTicks aTicks);
|
||||||
mozilla::TrackTicks TimeToTicksRoundUp(mozilla::TrackRate aRate,
|
|
||||||
mozilla::StreamTime aTime);
|
|
||||||
|
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Fake_MediaStream);
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Fake_MediaStream);
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,6 @@ double Fake_MediaStream::StreamTimeToSeconds(mozilla::StreamTime aTime) {
|
||||||
return static_cast<double>(aTime)/GRAPH_RATE;
|
return static_cast<double>(aTime)/GRAPH_RATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::TrackTicks Fake_MediaStream::TimeToTicksRoundUp(mozilla::TrackRate aRate,
|
|
||||||
mozilla::StreamTime aTime) {
|
|
||||||
return (aTime * aRate) / GRAPH_RATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::StreamTime
|
mozilla::StreamTime
|
||||||
Fake_MediaStream::TicksToTimeRoundDown(mozilla::TrackRate aRate,
|
Fake_MediaStream::TicksToTimeRoundDown(mozilla::TrackRate aRate,
|
||||||
mozilla::TrackTicks aTicks) {
|
mozilla::TrackTicks aTicks) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче