Bug 1081819 - Let the output stream itself process input data from MediaStreamAudioDestinationNode::mStream. r=roc

This commit is contained in:
Andreas Pehrson 2015-03-02 17:08:40 +08:00
Родитель b1a684cc86
Коммит 307e15ba05
3 изменённых файлов: 10 добавлений и 66 удалений

Просмотреть файл

@ -50,8 +50,7 @@ PRLogModuleInfo* gTrackUnionStreamLog;
#endif
TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
ProcessedMediaStream(aWrapper),
mFilterCallback(nullptr)
ProcessedMediaStream(aWrapper)
{
#ifdef PR_LOGGING
if (!gTrackUnionStreamLog) {
@ -114,7 +113,7 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
break;
}
}
if (!found && (!mFilterCallback || mFilterCallback(tracks.get()))) {
if (!found) {
bool trackFinished = false;
trackAdded = true;
uint32_t mapIndex = AddTrack(mInputs[i], tracks.get(), aFrom);
@ -153,14 +152,6 @@ TrackUnionStream::TrackUnionStream(DOMMediaStream* aWrapper) :
}
}
// Consumers may specify a filtering callback to apply to every input track.
// Returns true to allow the track to act as an input; false to reject it entirely.
void TrackUnionStream::SetTrackIDFilter(TrackIDFilterCallback aCallback)
{
mFilterCallback = aCallback;
}
// Forward SetTrackEnabled(output_track_id, enabled) to the Source MediaStream,
// translating the output track ID into the correct ID in the source.
void TrackUnionStream::ForwardTrackEnabled(TrackID aOutputID, bool aEnabled)

Просмотреть файл

@ -21,19 +21,11 @@ public:
virtual void RemoveInput(MediaInputPort* aPort) MOZ_OVERRIDE;
virtual void ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) MOZ_OVERRIDE;
// Consumers may specify a filtering callback to apply to every input track.
// Returns true to allow the track to act as an input; false to reject it entirely.
typedef bool (*TrackIDFilterCallback)(StreamBuffer::Track*);
void SetTrackIDFilter(TrackIDFilterCallback aCallback);
// Forward SetTrackEnabled(output_track_id, enabled) to the Source MediaStream,
// translating the output track ID into the correct ID in the source.
virtual void ForwardTrackEnabled(TrackID aOutputID, bool aEnabled) MOZ_OVERRIDE;
protected:
TrackIDFilterCallback mFilterCallback;
// Only non-ended tracks are allowed to persist in this map.
struct TrackMapEntry {
// mEndOfConsumedInputTicks is the end of the input ticks that we've consumed.

Просмотреть файл

@ -23,60 +23,21 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(MediaStreamAudioDestinationNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(MediaStreamAudioDestinationNode, AudioNode)
static const int MEDIA_STREAM_DEST_TRACK_ID = 2;
static_assert(MEDIA_STREAM_DEST_TRACK_ID != AudioNodeStream::AUDIO_TRACK,
"MediaStreamAudioDestinationNode::MEDIA_STREAM_DEST_TRACK_ID must be a different value than AudioNodeStream::AUDIO_TRACK");
class MediaStreamDestinationEngine : public AudioNodeEngine {
public:
MediaStreamDestinationEngine(AudioNode* aNode, ProcessedMediaStream* aOutputStream)
: AudioNodeEngine(aNode)
, mOutputStream(aOutputStream)
{
MOZ_ASSERT(mOutputStream);
}
virtual void ProcessBlock(AudioNodeStream* aStream,
const AudioChunk& aInput,
AudioChunk* aOutput,
bool* aFinished) MOZ_OVERRIDE
{
*aOutput = aInput;
StreamBuffer::Track* track = mOutputStream->EnsureTrack(MEDIA_STREAM_DEST_TRACK_ID);
AudioSegment* segment = track->Get<AudioSegment>();
segment->AppendAndConsumeChunk(aOutput);
}
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
{
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
private:
ProcessedMediaStream* mOutputStream;
};
// This callback is used to ensure that only the audio data for this track is audible
static bool FilterAudioNodeStreamTrack(StreamBuffer::Track* aTrack)
{
return aTrack->GetID() == MEDIA_STREAM_DEST_TRACK_ID;
}
MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(AudioContext* aContext)
: AudioNode(aContext,
2,
ChannelCountMode::Explicit,
ChannelInterpretation::Speakers)
, mDOMStream(DOMAudioNodeMediaStream::CreateTrackUnionStream(GetOwner(),
this))
, mDOMStream(DOMAudioNodeMediaStream::CreateTrackUnionStream(GetOwner(), this))
{
TrackUnionStream* tus = static_cast<TrackUnionStream*>(mDOMStream->GetStream());
MOZ_ASSERT(tus == mDOMStream->GetStream()->AsProcessedStream());
tus->SetTrackIDFilter(FilterAudioNodeStreamTrack);
// Ensure an audio track with the correct ID is exposed to JS
mDOMStream->CreateDOMTrack(AudioNodeStream::AUDIO_TRACK, MediaSegment::AUDIO);
MediaStreamDestinationEngine* engine = new MediaStreamDestinationEngine(this, tus);
mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM);
mPort = tus->AllocateInputPort(mStream, 0);
ProcessedMediaStream* outputStream = mDOMStream->GetStream()->AsProcessedStream();
MOZ_ASSERT(!!outputStream);
AudioNodeEngine* engine = new AudioNodeEngine(this);
mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::EXTERNAL_STREAM);
mPort = outputStream->AllocateInputPort(mStream);
nsIDocument* doc = aContext->GetParentObject()->GetExtantDoc();
if (doc) {