Bug 830707. Part 3: Don't constrain AudioSegment to a fixed number of channels. r=jesup

--HG--
extra : rebase_source : feacede00821b6673ce04c886a9c3727a4989404
This commit is contained in:
Robert O'Callahan 2013-01-21 09:44:44 +13:00
parent 64750c3cc4
commit ee2ea45fed
11 changed files with 16 additions and 76 deletions

View File

@ -87,30 +87,12 @@ class AudioSegment : public MediaSegmentBase<AudioSegment, AudioChunk> {
public:
typedef mozilla::AudioSampleFormat SampleFormat;
AudioSegment() : MediaSegmentBase<AudioSegment, AudioChunk>(AUDIO), mChannels(0) {}
AudioSegment() : MediaSegmentBase<AudioSegment, AudioChunk>(AUDIO) {}
bool IsInitialized()
{
return mChannels > 0;
}
void Init(int32_t aChannels)
{
NS_ASSERTION(aChannels > 0, "Bad number of channels");
NS_ASSERTION(!IsInitialized(), "Already initialized");
mChannels = aChannels;
}
int32_t GetChannels()
{
NS_ASSERTION(IsInitialized(), "Not initialized");
return mChannels;
}
void AppendFrames(already_AddRefed<ThreadSharedObject> aBuffer,
const nsTArray<const float*>& aChannelData,
int32_t aDuration)
{
NS_ASSERTION(mChannels > 0, "Not initialized");
NS_ASSERTION(!aBuffer.get() || aChannelData.Length() == uint32_t(mChannels),
"Wrong number of channels");
AudioChunk* chunk = AppendChunk(aDuration);
chunk->mBuffer = aBuffer;
for (uint32_t channel = 0; channel < aChannelData.Length(); ++channel) {
@ -123,9 +105,6 @@ public:
const nsTArray<const int16_t*>& aChannelData,
int32_t aDuration)
{
NS_ASSERTION(mChannels > 0, "Not initialized");
NS_ASSERTION(!aBuffer.get() || aChannelData.Length() == uint32_t(mChannels),
"Wrong number of channels");
AudioChunk* chunk = AppendChunk(aDuration);
chunk->mBuffer = aBuffer;
for (uint32_t channel = 0; channel < aChannelData.Length(); ++channel) {
@ -134,27 +113,21 @@ public:
chunk->mVolume = 1.0f;
chunk->mBufferFormat = AUDIO_FORMAT_S16;
}
// Consumes aChunk, and returns a pointer to the persistent copy of aChunk
// in the segment.
AudioChunk* AppendAndConsumeChunk(AudioChunk* aChunk)
{
AudioChunk* chunk = AppendChunk(aChunk->mDuration);
chunk->mBuffer = aChunk->mBuffer.forget();
chunk->mChannelData.SwapElements(aChunk->mChannelData);
chunk->mVolume = aChunk->mVolume;
chunk->mBufferFormat = aChunk->mBufferFormat;
return chunk;
}
void ApplyVolume(float aVolume);
/**
* aOutput must have a matching number of channels, but we will automatically
* convert sample formats.
*/
void WriteTo(AudioStream* aOutput);
// Segment-generic methods not in MediaSegmentBase
void InitFrom(const AudioSegment& aOther)
{
NS_ASSERTION(mChannels == 0, "Channels already set");
mChannels = aOther.mChannels;
}
void CheckCompatible(const AudioSegment& aOther) const
{
NS_ASSERTION(aOther.mChannels == mChannels, "Non-matching channels");
}
static Type StaticType() { return AUDIO; }
protected:
int32_t mChannels;
};
}

View File

@ -517,9 +517,6 @@ void MediaDecoderStateMachine::SendStreamAudio(AudioData* aAudio,
aStream->mLastAudioPacketTime = aAudio->mTime;
aStream->mLastAudioPacketEndTime = aAudio->GetEnd();
NS_ASSERTION(aOutput->GetChannels() == int32_t(aAudio->mChannels),
"Wrong number of channels");
// This logic has to mimic AudioLoop closely to make sure we write
// the exact same silences
CheckedInt64 audioWrittenOffset = UsecsToFrames(mInfo.mAudioRate,
@ -532,7 +529,6 @@ void MediaDecoderStateMachine::SendStreamAudio(AudioData* aAudio,
LOG(PR_LOG_DEBUG, ("%p Decoder writing %d frames of silence to MediaStream",
mDecoder.get(), int32_t(frameOffset.value() - audioWrittenOffset.value())));
AudioSegment silence;
silence.InitFrom(*aOutput);
silence.InsertNullDataAtStart(frameOffset.value() - audioWrittenOffset.value());
aStream->mAudioFramesWritten += silence.GetDuration();
aOutput->AppendFrom(&silence);
@ -604,7 +600,6 @@ void MediaDecoderStateMachine::SendStreamData()
if (!stream->mStreamInitialized) {
if (mInfo.mHasAudio) {
AudioSegment* audio = new AudioSegment();
audio->Init(mInfo.mAudioChannels);
mediaStream->AddTrack(TRACK_AUDIO, mInfo.mAudioRate, 0, audio);
}
if (mInfo.mHasVideo) {
@ -620,7 +615,6 @@ void MediaDecoderStateMachine::SendStreamData()
// is captured, only the decoder thread pops from the queue (see below).
mReader->AudioQueue().GetElementsAfter(stream->mLastAudioPacketTime, &audio);
AudioSegment output;
output.Init(mInfo.mAudioChannels);
for (uint32_t i = 0; i < audio.Length(); ++i) {
SendStreamAudio(audio[i], stream, &output);
}

View File

@ -119,9 +119,7 @@ template <class C, class Chunk> class MediaSegmentBase : public MediaSegment {
public:
virtual MediaSegment* CreateEmptyClone() const
{
C* s = new C();
s->InitFrom(*static_cast<const C*>(this));
return s;
return new C();
}
virtual void AppendFrom(MediaSegment* aSource)
{
@ -142,11 +140,6 @@ public:
{
AppendSliceInternal(aOther, aStart, aEnd);
}
void InitToSlice(const C& aOther, TrackTicks aStart, TrackTicks aEnd)
{
static_cast<C*>(this)->InitFrom(aOther);
AppendSliceInternal(aOther, aStart, aEnd);
}
/**
* Replace the first aDuration ticks with null media data, because the data
* will not be required again.
@ -215,7 +208,6 @@ protected:
*/
void AppendFromInternal(MediaSegmentBase<C, Chunk>* aSource)
{
static_cast<C*>(this)->CheckCompatible(*static_cast<C*>(aSource));
MOZ_ASSERT(aSource->mDuration >= 0);
mDuration += aSource->mDuration;
aSource->mDuration = 0;
@ -230,7 +222,6 @@ protected:
void AppendSliceInternal(const MediaSegmentBase<C, Chunk>& aSource,
TrackTicks aStart, TrackTicks aEnd)
{
static_cast<C*>(this)->CheckCompatible(static_cast<const C&>(aSource));
NS_ASSERTION(aStart <= aEnd, "Endpoints inverted");
NS_ASSERTION(aStart >= 0 && aEnd <= aSource.mDuration,
"Slice out of range");

View File

@ -1158,14 +1158,14 @@ MediaStreamGraphImpl::CreateOrDestroyAudioStreams(GraphTime aAudioOutputStartTim
// XXX allocating a AudioStream could be slow so we're going to have to do
// something here ... preallocation, async allocation, multiplexing onto a single
// stream ...
AudioSegment* audio = tracks->Get<AudioSegment>();
MediaStream::AudioOutputStream* audioOutputStream =
aStream->mAudioOutputStreams.AppendElement();
audioOutputStream->mAudioPlaybackStartTime = aAudioOutputStartTime;
audioOutputStream->mBlockedAudioTime = 0;
audioOutputStream->mStream = AudioStream::AllocateStream();
audioOutputStream->mStream->Init(audio->GetChannels(),
tracks->GetRate(), AUDIO_CHANNEL_NORMAL);
// XXX for now, allocate stereo output. But we need to fix this to
// match the system's ideal channel configuration.
audioOutputStream->mStream->Init(2, tracks->GetRate(), AUDIO_CHANNEL_NORMAL);
audioOutputStream->mTrackID = tracks->GetID();
}
}
@ -1211,7 +1211,6 @@ MediaStreamGraphImpl::PlayAudio(MediaStream* aStream,
end = std::min(end, aTo);
AudioSegment output;
output.InitFrom(*audio);
if (blocked) {
// Track total blocked time in aStream->mBlockedAudioTime so that
// the amount of silent samples we've inserted for blocking never gets

View File

@ -104,12 +104,6 @@ public:
}
// Segment-generic methods not in MediaSegmentBase
void InitFrom(const VideoSegment& aOther)
{
}
void CheckCompatible(const VideoSegment& aOther) const
{
}
static Type StaticType() { return VIDEO; }
};

View File

@ -17,7 +17,6 @@
#include "nsISupportsUtils.h"
#endif
#define CHANNELS 1
#define VIDEO_RATE USECS_PER_S
#define AUDIO_RATE 16000
@ -336,7 +335,6 @@ MediaEngineDefaultAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
// AddTrack will take ownership of segment
AudioSegment* segment = new AudioSegment();
segment->Init(CHANNELS);
mSource->AddTrack(aID, AUDIO_RATE, 0, segment);
// We aren't going to add any more tracks
@ -382,7 +380,6 @@ NS_IMETHODIMP
MediaEngineDefaultAudioSource::Notify(nsITimer* aTimer)
{
AudioSegment segment;
segment.Init(CHANNELS);
segment.InsertNullDataAtStart(AUDIO_RATE/100); // 10ms of fake data
mSource->AppendToTrack(mTrackID, &segment);

View File

@ -149,7 +149,6 @@ MediaEngineWebRTCAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
}
AudioSegment* segment = new AudioSegment();
segment->Init(CHANNELS);
aStream->AddTrack(aID, SAMPLE_FREQUENCY, 0, segment);
aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
LOG(("Initial audio"));
@ -363,7 +362,6 @@ MediaEngineWebRTCAudioSource::Process(const int channel,
memcpy(dest, audio10ms, length * sizeof(sample));
AudioSegment segment;
segment.Init(CHANNELS);
nsAutoTArray<const sample*,1> channels;
channels.AppendElement(dest);
segment.AppendFrames(buffer.forget(), channels, length);

View File

@ -842,7 +842,6 @@ MediaPipelineReceiveAudio::PipelineListener::PipelineListener(
conduit_(conduit),
played_(0) {
mozilla::AudioSegment *segment = new mozilla::AudioSegment();
segment->Init(1); // 1 Channel
source_->AddTrack(track_id_, 16000, 0, segment);
source_->AdvanceKnownTracksTime(STREAM_TIME_MAX);
}
@ -875,7 +874,6 @@ NotifyPull(MediaStreamGraph* graph, StreamTime desired_time) {
MOZ_MTLOG(PR_LOG_DEBUG, "Audio conduit returned buffer of length " << samples_length);
AudioSegment segment;
segment.Init(1);
nsAutoTArray<const int16_t*,1> channels;
channels.AppendElement(samples_data);
segment.AppendFrames(samples.forget(), channels, samples_length);

View File

@ -53,7 +53,6 @@ Fake_AudioGenerator(nsDOMMediaStream* aStream) : mStream(aStream), mCount(0) {
// Make a track
mozilla::AudioSegment *segment = new mozilla::AudioSegment();
segment->Init(1); // 1 Channel
mStream->GetStream()->AsSourceStream()->AddTrack(1, 16000, 0, segment);
// Set the timer
@ -71,7 +70,6 @@ Fake_AudioGenerator(nsDOMMediaStream* aStream) : mStream(aStream), mCount(0) {
}
mozilla::AudioSegment segment;
segment.Init(1);
nsAutoTArray<const int16_t*,1> channelData;
channelData.AppendElement(data);
segment.AppendFrames(samples.forget(), channelData, 1600);

View File

@ -99,7 +99,6 @@ void Fake_AudioStreamSource::Periodic() {
}
mozilla::AudioSegment segment;
segment.Init(1);
nsAutoTArray<const int16_t *,1> channels;
channels.AppendElement(data);
segment.AppendFrames(samples.forget(), channels, AUDIO_BUFFER_SIZE);

View File

@ -166,7 +166,6 @@ class TestAgentReceive : public TestAgent {
audio->SetPullEnabled(true);
mozilla::AudioSegment* segment= new mozilla::AudioSegment();
segment->Init(1);
audio->AddTrack(0, 100, 0, segment);
audio->AdvanceKnownTracksTime(mozilla::STREAM_TIME_MAX);