mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1156472 - Part 6 - Connect HTMLMediaElement and AudioContext to the capture stream when capturing is needed. r=roc
This commit is contained in:
parent
f692e0d9ce
commit
b195db60a7
@ -2030,6 +2030,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
|
|||||||
mAllowCasting(false),
|
mAllowCasting(false),
|
||||||
mIsCasting(false),
|
mIsCasting(false),
|
||||||
mAudioCaptured(false),
|
mAudioCaptured(false),
|
||||||
|
mAudioCapturedByWindow(false),
|
||||||
mPlayingBeforeSeek(false),
|
mPlayingBeforeSeek(false),
|
||||||
mPlayingThroughTheAudioChannelBeforeSeek(false),
|
mPlayingThroughTheAudioChannelBeforeSeek(false),
|
||||||
mPausedForInactiveDocumentOrChannel(false),
|
mPausedForInactiveDocumentOrChannel(false),
|
||||||
@ -2097,6 +2098,11 @@ HTMLMediaElement::~HTMLMediaElement()
|
|||||||
EndSrcMediaStreamPlayback();
|
EndSrcMediaStreamPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mCaptureStreamPort) {
|
||||||
|
mCaptureStreamPort->Destroy();
|
||||||
|
mCaptureStreamPort = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
|
NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
|
||||||
"Destroyed media element should no longer be in element table");
|
"Destroyed media element should no longer be in element table");
|
||||||
|
|
||||||
@ -4475,8 +4481,7 @@ void HTMLMediaElement::UpdateAudioChannelPlayingState()
|
|||||||
(!mPaused &&
|
(!mPaused &&
|
||||||
(HasAttr(kNameSpaceID_None, nsGkAtoms::loop) ||
|
(HasAttr(kNameSpaceID_None, nsGkAtoms::loop) ||
|
||||||
(mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA &&
|
(mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA &&
|
||||||
!IsPlaybackEnded() &&
|
!IsPlaybackEnded()) ||
|
||||||
(!mSrcStream || HasAudio())) ||
|
|
||||||
mPlayingThroughTheAudioChannelBeforeSeek));
|
mPlayingThroughTheAudioChannelBeforeSeek));
|
||||||
if (playingThroughTheAudioChannel != mPlayingThroughTheAudioChannel) {
|
if (playingThroughTheAudioChannel != mPlayingThroughTheAudioChannel) {
|
||||||
mPlayingThroughTheAudioChannel = playingThroughTheAudioChannel;
|
mPlayingThroughTheAudioChannel = playingThroughTheAudioChannel;
|
||||||
@ -4504,9 +4509,9 @@ void HTMLMediaElement::UpdateAudioChannelPlayingState()
|
|||||||
void
|
void
|
||||||
HTMLMediaElement::NotifyAudioChannelAgent(bool aPlaying)
|
HTMLMediaElement::NotifyAudioChannelAgent(bool aPlaying)
|
||||||
{
|
{
|
||||||
// Immediately check if this should go to the MSG instead of the normal
|
// Immediately check if this should go to the MSG instead of the normal
|
||||||
// media playback route.
|
// media playback route.
|
||||||
WindowAudioCaptureChanged();
|
WindowAudioCaptureChanged();
|
||||||
|
|
||||||
// This is needed to pass nsContentUtils::IsCallerChrome().
|
// This is needed to pass nsContentUtils::IsCallerChrome().
|
||||||
// AudioChannel API should not called from content but it can happen that
|
// AudioChannel API should not called from content but it can happen that
|
||||||
@ -4680,11 +4685,33 @@ HTMLMediaElement::GetTopLevelPrincipal()
|
|||||||
|
|
||||||
NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged()
|
NS_IMETHODIMP HTMLMediaElement::WindowAudioCaptureChanged()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mAudioChannelAgent);
|
MOZ_ASSERT(mAudioChannelAgent);
|
||||||
DebugOnly<bool> captured = OwnerDoc()->GetInnerWindow()->GetAudioCaptured();
|
|
||||||
|
|
||||||
// Something is going to happen here!!
|
if (!OwnerDoc()->GetInnerWindow()) {
|
||||||
return NS_OK;
|
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*
|
AudioTrackList*
|
||||||
|
@ -1074,6 +1074,9 @@ protected:
|
|||||||
// Holds a reference to a MediaInputPort connecting mSrcStream to mPlaybackStream.
|
// Holds a reference to a MediaInputPort connecting mSrcStream to mPlaybackStream.
|
||||||
nsRefPtr<MediaInputPort> mPlaybackStreamInputPort;
|
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
|
// 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
|
// playback. Used so we don't block playback of other video elements
|
||||||
// playing the same mSrcStream.
|
// playing the same mSrcStream.
|
||||||
@ -1283,6 +1286,9 @@ protected:
|
|||||||
// True if the sound is being captured.
|
// True if the sound is being captured.
|
||||||
bool mAudioCaptured;
|
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
|
// 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
|
// 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
|
// or was not actively playing before the current seek. Used to decide whether
|
||||||
|
@ -313,12 +313,9 @@ AudioDestinationNode::AudioDestinationNode(AudioContext* aContext,
|
|||||||
bool aIsOffline,
|
bool aIsOffline,
|
||||||
AudioChannel aChannel,
|
AudioChannel aChannel,
|
||||||
uint32_t aNumberOfChannels,
|
uint32_t aNumberOfChannels,
|
||||||
uint32_t aLength,
|
uint32_t aLength, float aSampleRate)
|
||||||
float aSampleRate)
|
: AudioNode(aContext, aIsOffline ? aNumberOfChannels : 2,
|
||||||
: AudioNode(aContext,
|
ChannelCountMode::Explicit, ChannelInterpretation::Speakers)
|
||||||
aIsOffline ? aNumberOfChannels : 2,
|
|
||||||
ChannelCountMode::Explicit,
|
|
||||||
ChannelInterpretation::Speakers)
|
|
||||||
, mFramesToProduce(aLength)
|
, mFramesToProduce(aLength)
|
||||||
, mAudioChannel(AudioChannel::Normal)
|
, mAudioChannel(AudioChannel::Normal)
|
||||||
, mIsOffline(aIsOffline)
|
, mIsOffline(aIsOffline)
|
||||||
@ -326,6 +323,7 @@ AudioDestinationNode::AudioDestinationNode(AudioContext* aContext,
|
|||||||
, mExtraCurrentTime(0)
|
, mExtraCurrentTime(0)
|
||||||
, mExtraCurrentTimeSinceLastStartedBlocking(0)
|
, mExtraCurrentTimeSinceLastStartedBlocking(0)
|
||||||
, mExtraCurrentTimeUpdatedSinceLastStableState(false)
|
, mExtraCurrentTimeUpdatedSinceLastStableState(false)
|
||||||
|
, mCaptured(false)
|
||||||
{
|
{
|
||||||
bool startWithAudioDriver = true;
|
bool startWithAudioDriver = true;
|
||||||
MediaStreamGraph* graph = aIsOffline ?
|
MediaStreamGraph* graph = aIsOffline ?
|
||||||
@ -510,13 +508,25 @@ AudioDestinationNode::WindowAudioCaptureChanged()
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(mAudioChannelAgent);
|
MOZ_ASSERT(mAudioChannelAgent);
|
||||||
|
|
||||||
if (!mStream) {
|
if (!mStream || Context()->IsOffline()) {
|
||||||
return NS_OK;
|
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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,6 +709,7 @@ AudioDestinationNode::InputMuted(bool aMuted)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowAudioCaptureChanged();
|
||||||
WindowVolumeChanged(volume, muted);
|
WindowVolumeChanged(volume, muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +99,7 @@ private:
|
|||||||
uint32_t mFramesToProduce;
|
uint32_t mFramesToProduce;
|
||||||
|
|
||||||
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
|
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
|
||||||
|
nsRefPtr<MediaInputPort> mCaptureStreamPort;
|
||||||
|
|
||||||
nsRefPtr<Promise> mOfflineRenderingPromise;
|
nsRefPtr<Promise> mOfflineRenderingPromise;
|
||||||
|
|
||||||
@ -111,6 +112,7 @@ private:
|
|||||||
double mExtraCurrentTime;
|
double mExtraCurrentTime;
|
||||||
double mExtraCurrentTimeSinceLastStartedBlocking;
|
double mExtraCurrentTimeSinceLastStartedBlocking;
|
||||||
bool mExtraCurrentTimeUpdatedSinceLastStableState;
|
bool mExtraCurrentTimeUpdatedSinceLastStableState;
|
||||||
|
bool mCaptured;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
Loading…
Reference in New Issue
Block a user