Bug 1156472 - Part 6 - Connect HTMLMediaElement and AudioContext to the capture stream when capturing is needed. r=roc

This commit is contained in:
Paul Adenot 2015-07-24 14:28:17 +02:00
Родитель f692e0d9ce
Коммит b195db60a7
4 изменённых файлов: 64 добавлений и 18 удалений

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

@ -2030,6 +2030,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
mAllowCasting(false),
mIsCasting(false),
mAudioCaptured(false),
mAudioCapturedByWindow(false),
mPlayingBeforeSeek(false),
mPlayingThroughTheAudioChannelBeforeSeek(false),
mPausedForInactiveDocumentOrChannel(false),
@ -2097,6 +2098,11 @@ HTMLMediaElement::~HTMLMediaElement()
EndSrcMediaStreamPlayback();
}
if (mCaptureStreamPort) {
mCaptureStreamPort->Destroy();
mCaptureStreamPort = nullptr;
}
NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
"Destroyed media element should no longer be in element table");
@ -4475,8 +4481,7 @@ void HTMLMediaElement::UpdateAudioChannelPlayingState()
(!mPaused &&
(HasAttr(kNameSpaceID_None, nsGkAtoms::loop) ||
(mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA &&
!IsPlaybackEnded() &&
(!mSrcStream || HasAudio())) ||
!IsPlaybackEnded()) ||
mPlayingThroughTheAudioChannelBeforeSeek));
if (playingThroughTheAudioChannel != mPlayingThroughTheAudioChannel) {
mPlayingThroughTheAudioChannel = playingThroughTheAudioChannel;
@ -4504,9 +4509,9 @@ void HTMLMediaElement::UpdateAudioChannelPlayingState()
void
HTMLMediaElement::NotifyAudioChannelAgent(bool aPlaying)
{
// Immediately check if this should go to the MSG instead of the normal
// media playback route.
WindowAudioCaptureChanged();
// Immediately check if this should go to the MSG instead of the normal
// media playback route.
WindowAudioCaptureChanged();
// This is needed to pass nsContentUtils::IsCallerChrome().
// AudioChannel API should not called from content but it can happen that
@ -4680,11 +4685,33 @@ HTMLMediaElement::GetTopLevelPrincipal()
NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged()
{
MOZ_ASSERT(mAudioChannelAgent);
DebugOnly<bool> captured = OwnerDoc()->GetInnerWindow()->GetAudioCaptured();
MOZ_ASSERT(mAudioChannelAgent);
// Something is going to happen here!!
return NS_OK;
if (!OwnerDoc()->GetInnerWindow()) {
return NS_OK;
}
bool captured = OwnerDoc()->GetInnerWindow()->GetAudioCaptured();
if (captured != mAudioCapturedByWindow) {
if (captured) {
mAudioCapturedByWindow = true;
nsCOMPtr<nsPIDOMWindow> window =
do_QueryInterface(OwnerDoc()->GetParentObject());
uint64_t id = window->WindowID();
MediaStreamGraph* msg = MediaStreamGraph::GetInstance();
if (!mPlaybackStream) {
nsRefPtr<DOMMediaStream> stream = CaptureStreamInternal(false, msg);
mCaptureStreamPort = msg->ConnectToCaptureStream(id, stream->GetStream());
} else {
mCaptureStreamPort = msg->ConnectToCaptureStream(id, mPlaybackStream->GetStream());
}
} else {
// TODO: uncapture
}
}
return NS_OK;
}
AudioTrackList*

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

@ -1074,6 +1074,9 @@ protected:
// Holds a reference to a MediaInputPort connecting mSrcStream to mPlaybackStream.
nsRefPtr<MediaInputPort> mPlaybackStreamInputPort;
// Holds a reference to the stream connecting this stream to the capture sink.
nsRefPtr<MediaInputPort> mCaptureStreamPort;
// Holds a reference to a stream with mSrcStream as input but intended for
// playback. Used so we don't block playback of other video elements
// playing the same mSrcStream.
@ -1283,6 +1286,9 @@ protected:
// True if the sound is being captured.
bool mAudioCaptured;
// True if the sound is being captured by the window.
bool mAudioCapturedByWindow;
// If TRUE then the media element was actively playing before the currently
// in progress seeking. If FALSE then the media element is either not seeking
// or was not actively playing before the current seek. Used to decide whether

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

@ -313,12 +313,9 @@ AudioDestinationNode::AudioDestinationNode(AudioContext* aContext,
bool aIsOffline,
AudioChannel aChannel,
uint32_t aNumberOfChannels,
uint32_t aLength,
float aSampleRate)
: AudioNode(aContext,
aIsOffline ? aNumberOfChannels : 2,
ChannelCountMode::Explicit,
ChannelInterpretation::Speakers)
uint32_t aLength, float aSampleRate)
: AudioNode(aContext, aIsOffline ? aNumberOfChannels : 2,
ChannelCountMode::Explicit, ChannelInterpretation::Speakers)
, mFramesToProduce(aLength)
, mAudioChannel(AudioChannel::Normal)
, mIsOffline(aIsOffline)
@ -326,6 +323,7 @@ AudioDestinationNode::AudioDestinationNode(AudioContext* aContext,
, mExtraCurrentTime(0)
, mExtraCurrentTimeSinceLastStartedBlocking(0)
, mExtraCurrentTimeUpdatedSinceLastStableState(false)
, mCaptured(false)
{
bool startWithAudioDriver = true;
MediaStreamGraph* graph = aIsOffline ?
@ -510,13 +508,25 @@ AudioDestinationNode::WindowAudioCaptureChanged()
{
MOZ_ASSERT(mAudioChannelAgent);
if (!mStream) {
if (!mStream || Context()->IsOffline()) {
return NS_OK;
}
DebugOnly<bool> captured = GetOwner()->GetAudioCaptured();
bool captured = GetOwner()->GetAudioCaptured();
if (captured != mCaptured) {
if (captured) {
nsCOMPtr<nsPIDOMWindow> window = Context()->GetParentObject();
uint64_t id = window->WindowID();
mCaptureStreamPort =
mStream->Graph()->ConnectToCaptureStream(id, mStream);
} else {
mCaptureStreamPort->Disconnect();
mCaptureStreamPort->Destroy();
}
mCaptured = captured;
}
// XXXtodopadenot actually capture
return NS_OK;
}
@ -699,6 +709,7 @@ AudioDestinationNode::InputMuted(bool aMuted)
return;
}
WindowAudioCaptureChanged();
WindowVolumeChanged(volume, muted);
}

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

@ -99,6 +99,7 @@ private:
uint32_t mFramesToProduce;
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
nsRefPtr<MediaInputPort> mCaptureStreamPort;
nsRefPtr<Promise> mOfflineRenderingPromise;
@ -111,6 +112,7 @@ private:
double mExtraCurrentTime;
double mExtraCurrentTimeSinceLastStartedBlocking;
bool mExtraCurrentTimeUpdatedSinceLastStableState;
bool mCaptured;
};
} // namespace dom