Bug 1254102 - Add "blackout" mode. If the window is not legal, output a black square. r?jesup
MozReview-Commit-ID: GlBy8fUZwIE
--- a/dom/media/webrtc/MediaEngineTabVideoSource.cpp
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.cpp
@@ -37,16 +37,17 @@ MediaEngineTabVideoSource::MediaEngineTa
, mWindowId(0)
, mScrollWithPage(false)
, mViewportOffsetX(0)
, mViewportOffsetY(0)
, mViewportWidth(0)
, mViewportHeight(0)
, mTimePerFrame(0)
, mDataSize(0)
+ , mBlackedoutWindow(false)
, mMonitor("MediaEngineTabVideoSource") {}
nsresult
MediaEngineTabVideoSource::StartRunnable::Run()
{
mVideoSource->Draw();
mVideoSource->mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
mVideoSource->mTimer->InitWithCallback(mVideoSource, mVideoSource->mTimePerFrame, nsITimer:: TYPE_REPEATING_SLACK);
@@ -75,40 +76,48 @@ MediaEngineTabVideoSource::HandleEvent(n
return NS_OK;
}
NS_IMETHODIMP
MediaEngineTabVideoSource::Notify(nsITimer*) {
Draw();
return NS_OK;
}
-#define LOGTAG "TabVideo"
nsresult
MediaEngineTabVideoSource::InitRunnable::Run()
{
if (mVideoSource->mWindowId != -1) {
- nsCOMPtr<nsPIDOMWindowOuter> window =
- nsGlobalWindow::GetOuterWindowWithId(mVideoSource->mWindowId)->AsOuter();
- if (window) {
- mVideoSource->mWindow = window;
+ nsGlobalWindow* globalWindow =
+ nsGlobalWindow::GetOuterWindowWithId(mVideoSource->mWindowId);
+ if (!globalWindow) {
+ // We can't access the window, just send a blacked out screen.
+ mVideoSource->mWindow = nullptr;
+ mVideoSource->mBlackedoutWindow = true;
+ } else {
+ nsCOMPtr<nsPIDOMWindowOuter> window = globalWindow->AsOuter();
+ if (window) {
+ mVideoSource->mWindow = window;
+ mVideoSource->mBlackedoutWindow = false;
+ }
}
}
- if (!mVideoSource->mWindow) {
+ if (!mVideoSource->mWindow && !mVideoSource->mBlackedoutWindow) {
nsresult rv;
mVideoSource->mTabSource = do_GetService(NS_TABSOURCESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<mozIDOMWindowProxy> win;
rv = mVideoSource->mTabSource->GetTabToStream(getter_AddRefs(win));
NS_ENSURE_SUCCESS(rv, rv);
if (!win)
return NS_OK;
mVideoSource->mWindow = nsPIDOMWindowOuter::From(win);
+ MOZ_ASSERT(mVideoSource->mWindow);
}
nsCOMPtr<nsIRunnable> start(new StartRunnable(mVideoSource));
start->Run();
return NS_OK;
}
void
MediaEngineTabVideoSource::GetName(nsAString_internal& aName)
@@ -206,34 +215,43 @@ MediaEngineTabVideoSource::NotifyPull(Me
// This can fail if either a) we haven't added the track yet, or b)
// we've removed or finished the track.
aSource->AppendToTrack(aID, &(segment));
}
}
void
MediaEngineTabVideoSource::Draw() {
- if (!mWindow) {
+ if (!mWindow && !mBlackedoutWindow) {
return;
}
- if (mScrollWithPage || mViewportWidth == INT32_MAX) {
- mWindow->GetInnerWidth(&mViewportWidth);
- }
- if (mScrollWithPage || mViewportHeight == INT32_MAX) {
- mWindow->GetInnerHeight(&mViewportHeight);
- }
- if (!mViewportWidth || !mViewportHeight) {
- return;
+ if (mWindow) {
+ if (mScrollWithPage || mViewportWidth == INT32_MAX) {
+ mWindow->GetInnerWidth(&mViewportWidth);
+ }
+ if (mScrollWithPage || mViewportHeight == INT32_MAX) {
+ mWindow->GetInnerHeight(&mViewportHeight);
+ }
+ if (!mViewportWidth || !mViewportHeight) {
+ return;
+ }
+ } else {
+ mViewportWidth = 640;
+ mViewportHeight = 480;
}
IntSize size;
{
float pixelRatio;
- mWindow->GetDevicePixelRatio(&pixelRatio);
+ if (mWindow) {
+ mWindow->GetDevicePixelRatio(&pixelRatio);
+ } else {
+ pixelRatio = 1.0f;
+ }
const int32_t deviceWidth = (int32_t)(pixelRatio * mViewportWidth);
const int32_t deviceHeight = (int32_t)(pixelRatio * mViewportHeight);
if ((deviceWidth <= mBufWidthMax) && (deviceHeight <= mBufHeightMax)) {
size = IntSize(deviceWidth, deviceHeight);
} else {
const float scaleWidth = (float)mBufWidthMax / (float)deviceWidth;
const float scaleHeight = (float)mBufHeightMax / (float)deviceHeight;
@@ -250,69 +268,73 @@ MediaEngineTabVideoSource::Draw() {
mDataSize = stride * size.height;
mData = MakeUniqueFallible<unsigned char[]>(mDataSize);
}
if (!mData) {
return;
}
nsCOMPtr<nsIPresShell> presShell;
- {
+ if (mWindow) {
RefPtr<nsPresContext> presContext;
nsIDocShell* docshell = mWindow->GetDocShell();
if (docshell) {
docshell->GetPresContext(getter_AddRefs(presContext));
}
if (!presContext) {
return;
}
presShell = presContext->PresShell();
}
- nscolor bgColor = NS_RGB(255, 255, 255);
- uint32_t renderDocFlags = mScrollWithPage? 0 :
- (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
- nsIPresShell::RENDER_DOCUMENT_RELATIVE);
- nsRect r(nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetX),
- nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetY),
- nsPresContext::CSSPixelsToAppUnits((float)mViewportWidth),
- nsPresContext::CSSPixelsToAppUnits((float)mViewportHeight));
-
RefPtr<layers::ImageContainer> container = layers::LayerManager::CreateImageContainer();
RefPtr<DrawTarget> dt =
Factory::CreateDrawTargetForData(BackendType::CAIRO,
mData.get(),
size,
stride,
SurfaceFormat::B8G8R8X8);
if (!dt) {
return;
}
RefPtr<gfxContext> context = new gfxContext(dt);
context->SetMatrix(context->CurrentMatrix().Scale((((float) size.width)/mViewportWidth),
(((float) size.height)/mViewportHeight)));
- NS_ENSURE_SUCCESS_VOID(presShell->RenderDocument(r, renderDocFlags, bgColor, context));
+ if (mWindow) {
+ nscolor bgColor = NS_RGB(255, 255, 255);
+ uint32_t renderDocFlags = mScrollWithPage? 0 :
+ (nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING |
+ nsIPresShell::RENDER_DOCUMENT_RELATIVE);
+ nsRect r(nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetX),
+ nsPresContext::CSSPixelsToAppUnits((float)mViewportOffsetY),
+ nsPresContext::CSSPixelsToAppUnits((float)mViewportWidth),
+ nsPresContext::CSSPixelsToAppUnits((float)mViewportHeight));
+ NS_ENSURE_SUCCESS_VOID(presShell->RenderDocument(r, renderDocFlags, bgColor, context));
+ }
RefPtr<SourceSurface> surface = dt->Snapshot();
if (!surface) {
return;
}
RefPtr<layers::SourceSurfaceImage> image = new layers::SourceSurfaceImage(size, surface);
MonitorAutoLock mon(mMonitor);
mImage = image;
}
nsresult
MediaEngineTabVideoSource::Stop(mozilla::SourceMediaStream*, mozilla::TrackID)
{
- if (!mWindow)
+ // If mBlackedoutWindow is true, we may be running
+ // despite mWindow == nullptr.
+ if (!mWindow && !mBlackedoutWindow) {
return NS_OK;
+ }
NS_DispatchToMainThread(new StopRunnable(this));
return NS_OK;
}
bool
MediaEngineTabVideoSource::IsFake()
{
--- a/dom/media/webrtc/MediaEngineTabVideoSource.h
+++ b/dom/media/webrtc/MediaEngineTabVideoSource.h
@@ -84,14 +84,16 @@ private:
int32_t mViewportOffsetX;
int32_t mViewportOffsetY;
int32_t mViewportWidth;
int32_t mViewportHeight;
int32_t mTimePerFrame;
UniquePtr<unsigned char[]> mData;
size_t mDataSize;
nsCOMPtr<nsPIDOMWindowOuter> mWindow;
+ // If this is set, we will run despite mWindow == nullptr.
+ bool mBlackedoutWindow;
RefPtr<layers::SourceSurfaceImage> mImage;
nsCOMPtr<nsITimer> mTimer;
Monitor mMonitor;
nsCOMPtr<nsITabSource> mTabSource;
};
}