mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 1193075 - add viewport constraints for independent scrolling in tab sharing. r=smaug, r=jesup
--HG-- extra : transplant_source : %F8%AE%16%B7D%EFN%CC%16%A7%0C%B9%07%3F%D4%7B%E5%3Co%97
This commit is contained in:
parent
ae6d7ff3ef
commit
8a441a9cf1
@ -1878,6 +1878,15 @@ MediaManager::GetUserMedia(nsPIDOMWindow* aWindow,
|
||||
break;
|
||||
|
||||
case dom::MediaSourceEnum::Browser:
|
||||
// If no window id is passed in then default to the caller's window.
|
||||
// Functional defaults are helpful in tests, but also a natural outcome
|
||||
// of the constraints API's limited semantics for requiring input.
|
||||
if (!vc.mBrowserWindow.WasPassed()) {
|
||||
nsPIDOMWindow *outer = aWindow->GetOuterWindow();
|
||||
vc.mBrowserWindow.Construct(outer->WindowID());
|
||||
}
|
||||
// | Fall through
|
||||
// V
|
||||
case dom::MediaSourceEnum::Screen:
|
||||
case dom::MediaSourceEnum::Application:
|
||||
case dom::MediaSourceEnum::Window:
|
||||
|
@ -72,9 +72,9 @@ var tests = [
|
||||
|
||||
var mustSupport = [
|
||||
'width', 'height', 'frameRate', 'facingMode', 'deviceId',
|
||||
// Yet to add:
|
||||
// 'aspectRatio', 'frameRate', 'volume', 'sampleRate', 'sampleSize',
|
||||
// 'echoCancellation', 'latency', 'groupId'
|
||||
// Yet to add:
|
||||
// 'aspectRatio', 'frameRate', 'volume', 'sampleRate', 'sampleSize',
|
||||
// 'echoCancellation', 'latency', 'groupId'
|
||||
|
||||
// http://fluffy.github.io/w3c-screen-share/#screen-based-video-constraints
|
||||
// OBE by http://w3c.github.io/mediacapture-screen-share
|
||||
@ -82,6 +82,7 @@ var mustSupport = [
|
||||
|
||||
// Experimental https://bugzilla.mozilla.org/show_bug.cgi?id=1131568#c3
|
||||
'browserWindow', 'scrollWithPage',
|
||||
'viewportOffsetX', 'viewportOffsetY', 'viewportWidth', 'viewportHeight'
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -31,9 +31,17 @@ using namespace mozilla::gfx;
|
||||
NS_IMPL_ISUPPORTS(MediaEngineTabVideoSource, nsIDOMEventListener, nsITimerCallback)
|
||||
|
||||
MediaEngineTabVideoSource::MediaEngineTabVideoSource()
|
||||
: mData(NULL), mDataSize(0), mMonitor("MediaEngineTabVideoSource"), mTabSource(nullptr)
|
||||
{
|
||||
}
|
||||
: mBufWidthMax(0)
|
||||
, mBufHeightMax(0)
|
||||
, mWindowId(0)
|
||||
, mScrollWithPage(false)
|
||||
, mViewportOffsetX(0)
|
||||
, mViewportOffsetY(0)
|
||||
, mViewportWidth(0)
|
||||
, mViewportHeight(0)
|
||||
, mTimePerFrame(0)
|
||||
, mDataSize(0)
|
||||
, mMonitor("MediaEngineTabVideoSource") {}
|
||||
|
||||
nsresult
|
||||
MediaEngineTabVideoSource::StartRunnable::Run()
|
||||
@ -123,23 +131,39 @@ MediaEngineTabVideoSource::Allocate(const dom::MediaTrackConstraints& aConstrain
|
||||
const MediaEnginePrefs& aPrefs,
|
||||
const nsString& aDeviceId)
|
||||
{
|
||||
// windowId and scrollWithPage are not proper constraints, so just read them.
|
||||
// They have no well-defined behavior in advanced, so ignore them there.
|
||||
// windowId is not a proper constraint, so just read it.
|
||||
// It has no well-defined behavior in advanced, so ignore it there.
|
||||
|
||||
mWindowId = aConstraints.mBrowserWindow.WasPassed() ?
|
||||
aConstraints.mBrowserWindow.Value() : -1;
|
||||
|
||||
return Restart(aConstraints, aPrefs, aDeviceId);
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineTabVideoSource::Restart(const dom::MediaTrackConstraints& aConstraints,
|
||||
const mozilla::MediaEnginePrefs& aPrefs,
|
||||
const nsString& aDeviceId)
|
||||
{
|
||||
// scrollWithPage is not proper a constraint, so just read it.
|
||||
// It has no well-defined behavior in advanced, so ignore it there.
|
||||
|
||||
mScrollWithPage = aConstraints.mScrollWithPage.WasPassed() ?
|
||||
aConstraints.mScrollWithPage.Value() : true;
|
||||
aConstraints.mScrollWithPage.Value() : false;
|
||||
|
||||
FlattenedConstraints c(aConstraints);
|
||||
|
||||
mBufWidthMax = c.mWidth.Clamp(c.mWidth.mIdeal.WasPassed() ?
|
||||
c.mWidth.mIdeal.Value() : DEFAULT_TABSHARE_VIDEO_MAX_WIDTH);
|
||||
mBufHeightMax = c.mHeight.Clamp(c.mHeight.mIdeal.WasPassed() ?
|
||||
c.mHeight.mIdeal.Value() : DEFAULT_TABSHARE_VIDEO_MAX_HEIGHT);
|
||||
double frameRate = c.mFrameRate.Clamp(c.mFrameRate.mIdeal.WasPassed() ?
|
||||
c.mFrameRate.mIdeal.Value() : DEFAULT_TABSHARE_VIDEO_FRAMERATE);
|
||||
mBufWidthMax = c.mWidth.Get(DEFAULT_TABSHARE_VIDEO_MAX_WIDTH);
|
||||
mBufHeightMax = c.mHeight.Get(DEFAULT_TABSHARE_VIDEO_MAX_HEIGHT);
|
||||
double frameRate = c.mFrameRate.Get(DEFAULT_TABSHARE_VIDEO_FRAMERATE);
|
||||
mTimePerFrame = std::max(10, int(1000.0 / (frameRate > 0? frameRate : 1)));
|
||||
|
||||
if (!mScrollWithPage) {
|
||||
mViewportOffsetX = c.mViewportOffsetX.Get(0);
|
||||
mViewportOffsetY = c.mViewportOffsetY.Get(0);
|
||||
mViewportWidth = c.mViewportWidth.Get(INT32_MAX);
|
||||
mViewportHeight = c.mViewportHeight.Get(INT32_MAX);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -192,30 +216,32 @@ MediaEngineTabVideoSource::Draw() {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t innerWidth, innerHeight;
|
||||
win->GetInnerWidth(&innerWidth);
|
||||
win->GetInnerHeight(&innerHeight);
|
||||
|
||||
if (innerWidth == 0 || innerHeight == 0) {
|
||||
if (mScrollWithPage || mViewportWidth == INT32_MAX) {
|
||||
win->GetInnerWidth(&mViewportWidth);
|
||||
}
|
||||
if (mScrollWithPage || mViewportHeight == INT32_MAX) {
|
||||
win->GetInnerHeight(&mViewportHeight);
|
||||
}
|
||||
if (!mViewportWidth || !mViewportHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
float pixelRatio;
|
||||
win->GetDevicePixelRatio(&pixelRatio);
|
||||
const int deviceInnerWidth = (int)(pixelRatio * innerWidth);
|
||||
const int deviceInnerHeight = (int)(pixelRatio * innerHeight);
|
||||
|
||||
IntSize size;
|
||||
{
|
||||
float pixelRatio;
|
||||
win->GetDevicePixelRatio(&pixelRatio);
|
||||
const int32_t deviceWidth = (int32_t)(pixelRatio * mViewportWidth);
|
||||
const int32_t deviceHeight = (int32_t)(pixelRatio * mViewportHeight);
|
||||
|
||||
if ((deviceInnerWidth <= mBufWidthMax) && (deviceInnerHeight <= mBufHeightMax)) {
|
||||
size = IntSize(deviceInnerWidth, deviceInnerHeight);
|
||||
} else {
|
||||
if ((deviceWidth <= mBufWidthMax) && (deviceHeight <= mBufHeightMax)) {
|
||||
size = IntSize(deviceWidth, deviceHeight);
|
||||
} else {
|
||||
const float scaleWidth = (float)mBufWidthMax / (float)deviceWidth;
|
||||
const float scaleHeight = (float)mBufHeightMax / (float)deviceHeight;
|
||||
const float scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight;
|
||||
|
||||
const float scaleWidth = (float)mBufWidthMax / (float)deviceInnerWidth;
|
||||
const float scaleHeight = (float)mBufHeightMax / (float)deviceInnerHeight;
|
||||
const float scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight;
|
||||
|
||||
size = IntSize((int)(scale * deviceInnerWidth), (int)(scale * deviceInnerHeight));
|
||||
size = IntSize((int)(scale * deviceWidth), (int)(scale * deviceHeight));
|
||||
}
|
||||
}
|
||||
|
||||
gfxImageFormat format = gfxImageFormat::RGB24;
|
||||
@ -225,28 +251,30 @@ MediaEngineTabVideoSource::Draw() {
|
||||
mDataSize = stride * size.height;
|
||||
mData = static_cast<unsigned char*>(malloc(mDataSize));
|
||||
}
|
||||
|
||||
if (!mData) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<nsPresContext> presContext;
|
||||
nsIDocShell* docshell = win->GetDocShell();
|
||||
if (docshell) {
|
||||
docshell->GetPresContext(getter_AddRefs(presContext));
|
||||
}
|
||||
if (!presContext) {
|
||||
return;
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
{
|
||||
RefPtr<nsPresContext> presContext;
|
||||
nsIDocShell* docshell = win->GetDocShell();
|
||||
if (docshell) {
|
||||
docshell->GetPresContext(getter_AddRefs(presContext));
|
||||
}
|
||||
if (!presContext) {
|
||||
return;
|
||||
}
|
||||
presShell = presContext->PresShell();
|
||||
}
|
||||
|
||||
nscolor bgColor = NS_RGB(255, 255, 255);
|
||||
nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
|
||||
uint32_t renderDocFlags = 0;
|
||||
if (!mScrollWithPage) {
|
||||
renderDocFlags |= nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
|
||||
}
|
||||
nsRect r(0, 0, nsPresContext::CSSPixelsToAppUnits((float)innerWidth),
|
||||
nsPresContext::CSSPixelsToAppUnits((float)innerHeight));
|
||||
uint32_t renderDocFlags = mScrollWithPage? 0 :
|
||||
nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
|
||||
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 =
|
||||
@ -259,8 +287,8 @@ MediaEngineTabVideoSource::Draw() {
|
||||
return;
|
||||
}
|
||||
RefPtr<gfxContext> context = new gfxContext(dt);
|
||||
context->SetMatrix(context->CurrentMatrix().Scale((((float) size.width)/innerWidth),
|
||||
(((float) size.height)/innerHeight)));
|
||||
context->SetMatrix(context->CurrentMatrix().Scale((((float) size.width)/mViewportWidth),
|
||||
(((float) size.height)/mViewportHeight)));
|
||||
|
||||
NS_ENSURE_SUCCESS_VOID(presShell->RenderDocument(r, renderDocFlags, bgColor, context));
|
||||
|
||||
@ -291,15 +319,6 @@ MediaEngineTabVideoSource::Stop(mozilla::SourceMediaStream*, mozilla::TrackID)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineTabVideoSource::Restart(const dom::MediaTrackConstraints& aConstraints,
|
||||
const mozilla::MediaEnginePrefs& aPrefs,
|
||||
const nsString& aDeviceId)
|
||||
{
|
||||
// TODO
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaEngineTabVideoSource::Config(bool, uint32_t, bool, uint32_t, bool, uint32_t, int32_t)
|
||||
{
|
||||
|
@ -76,11 +76,15 @@ protected:
|
||||
~MediaEngineTabVideoSource() {}
|
||||
|
||||
private:
|
||||
int mBufWidthMax;
|
||||
int mBufHeightMax;
|
||||
int32_t mBufWidthMax;
|
||||
int32_t mBufHeightMax;
|
||||
int64_t mWindowId;
|
||||
bool mScrollWithPage;
|
||||
int mTimePerFrame;
|
||||
int32_t mViewportOffsetX;
|
||||
int32_t mViewportOffsetY;
|
||||
int32_t mViewportWidth;
|
||||
int32_t mViewportHeight;
|
||||
int32_t mTimePerFrame;
|
||||
ScopedFreePtr<unsigned char> mData;
|
||||
size_t mDataSize;
|
||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
||||
|
@ -48,6 +48,9 @@ struct NormalizedConstraintSet
|
||||
template<class ConstrainRange>
|
||||
void SetFrom(const ConstrainRange& aOther);
|
||||
ValueType Clamp(ValueType n) const { return std::max(mMin, std::min(n, mMax)); }
|
||||
ValueType Get(ValueType defaultValue) const {
|
||||
return Clamp(mIdeal.WasPassed() ? mIdeal.Value() : defaultValue);
|
||||
}
|
||||
bool Intersects(const Range& aOther) const {
|
||||
return mMax >= aOther.mMin && mMin <= aOther.mMax;
|
||||
}
|
||||
@ -72,12 +75,17 @@ struct NormalizedConstraintSet
|
||||
// Do you need to add your constraint here? Only if your code uses flattening
|
||||
LongRange mWidth, mHeight;
|
||||
DoubleRange mFrameRate;
|
||||
LongRange mViewportOffsetX, mViewportOffsetY, mViewportWidth, mViewportHeight;
|
||||
|
||||
NormalizedConstraintSet(const dom::MediaTrackConstraintSet& aOther,
|
||||
bool advanced)
|
||||
: mWidth(aOther.mWidth, advanced)
|
||||
, mHeight(aOther.mHeight, advanced)
|
||||
, mFrameRate(aOther.mFrameRate, advanced) {}
|
||||
, mFrameRate(aOther.mFrameRate, advanced)
|
||||
, mViewportOffsetX(aOther.mViewportOffsetX, advanced)
|
||||
, mViewportOffsetY(aOther.mViewportOffsetY, advanced)
|
||||
, mViewportWidth(aOther.mViewportWidth, advanced)
|
||||
, mViewportHeight(aOther.mViewportHeight, advanced) {}
|
||||
};
|
||||
|
||||
struct FlattenedConstraints : public NormalizedConstraintSet
|
||||
|
@ -50,6 +50,10 @@ dictionary MediaTrackConstraintSet {
|
||||
long long browserWindow;
|
||||
boolean scrollWithPage;
|
||||
ConstrainDOMString deviceId;
|
||||
ConstrainLong viewportOffsetX;
|
||||
ConstrainLong viewportOffsetY;
|
||||
ConstrainLong viewportWidth;
|
||||
ConstrainLong viewportHeight;
|
||||
};
|
||||
|
||||
dictionary MediaTrackConstraints : MediaTrackConstraintSet {
|
||||
|
@ -29,7 +29,12 @@ dictionary MediaTrackSupportedConstraints {
|
||||
boolean mediaSource = true;
|
||||
|
||||
// Experimental https://bugzilla.mozilla.org/show_bug.cgi?id=1131568#c3
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1193075
|
||||
|
||||
boolean browserWindow = true;
|
||||
boolean scrollWithPage = true;
|
||||
boolean viewportOffsetX = true;
|
||||
boolean viewportOffsetY = true;
|
||||
boolean viewportWidth = true;
|
||||
boolean viewportHeight = true;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user