зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1228601 - [Part2] Swap width,height if necessary and apply rotation matrix while building layer.; r=mattwoodrow
MozReview-Commit-ID: Jlh6oRa32fj --HG-- extra : transplant_source : %C2%A5%8C%DA4TF%0C%D4%C9%C6%9C%98%25t%3C%B9%90%E8%B2
This commit is contained in:
Родитель
b0d32a9fb5
Коммит
650f34aa50
|
@ -60,8 +60,21 @@ nsresult HTMLVideoElement::GetVideoSize(nsIntSize* size)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
size->height = mMediaInfo.mVideo.mDisplay.height;
|
||||
size->width = mMediaInfo.mVideo.mDisplay.width;
|
||||
switch (mMediaInfo.mVideo.mRotation) {
|
||||
case VideoInfo::Rotation::kDegree_90:
|
||||
case VideoInfo::Rotation::kDegree_270: {
|
||||
size->width = mMediaInfo.mVideo.mDisplay.height;
|
||||
size->height = mMediaInfo.mVideo.mDisplay.width;
|
||||
break;
|
||||
}
|
||||
case VideoInfo::Rotation::kDegree_0:
|
||||
case VideoInfo::Rotation::kDegree_180:
|
||||
default: {
|
||||
size->height = mMediaInfo.mVideo.mDisplay.height;
|
||||
size->width = mMediaInfo.mVideo.mDisplay.width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,12 +76,31 @@ public:
|
|||
|
||||
uint32_t VideoWidth() const
|
||||
{
|
||||
return mMediaInfo.HasVideo() ? mMediaInfo.mVideo.mDisplay.width : 0;
|
||||
if (mMediaInfo.HasVideo()) {
|
||||
if (mMediaInfo.mVideo.mRotation == VideoInfo::Rotation::kDegree_90 ||
|
||||
mMediaInfo.mVideo.mRotation == VideoInfo::Rotation::kDegree_270) {
|
||||
return mMediaInfo.mVideo.mDisplay.height;
|
||||
}
|
||||
return mMediaInfo.mVideo.mDisplay.width;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t VideoHeight() const
|
||||
{
|
||||
return mMediaInfo.HasVideo() ? mMediaInfo.mVideo.mDisplay.height : 0;
|
||||
if (mMediaInfo.HasVideo()) {
|
||||
if (mMediaInfo.mVideo.mRotation == VideoInfo::Rotation::kDegree_90 ||
|
||||
mMediaInfo.mVideo.mRotation == VideoInfo::Rotation::kDegree_270) {
|
||||
return mMediaInfo.mVideo.mDisplay.width;
|
||||
}
|
||||
return mMediaInfo.mVideo.mDisplay.height;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
VideoInfo::Rotation RotationDegrees() const
|
||||
{
|
||||
return mMediaInfo.mVideo.mRotation;
|
||||
}
|
||||
|
||||
void GetPoster(nsAString& aValue)
|
||||
|
|
|
@ -41,6 +41,39 @@ NS_NewHTMLVideoFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
|||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsVideoFrame)
|
||||
|
||||
// A matrix to obtain a correct-rotated video frame.
|
||||
static Matrix
|
||||
ComputeRotationMatrix(gfxFloat aRotatedWidth,
|
||||
gfxFloat aRotatedHeight,
|
||||
VideoInfo::Rotation aDegrees)
|
||||
{
|
||||
Matrix shiftVideoCenterToOrigin;
|
||||
if (aDegrees == VideoInfo::Rotation::kDegree_90 ||
|
||||
aDegrees == VideoInfo::Rotation::kDegree_270) {
|
||||
shiftVideoCenterToOrigin = Matrix::Translation(-aRotatedHeight / 2.0,
|
||||
-aRotatedWidth / 2.0);
|
||||
} else {
|
||||
shiftVideoCenterToOrigin = Matrix::Translation(-aRotatedWidth / 2.0,
|
||||
-aRotatedHeight / 2.0);
|
||||
}
|
||||
|
||||
Matrix rotation = Matrix::Rotation(gfx::Float(aDegrees / 180.0 * M_PI));
|
||||
Matrix shiftLeftTopToOrigin = Matrix::Translation(aRotatedWidth / 2.0,
|
||||
aRotatedHeight / 2.0);
|
||||
return shiftVideoCenterToOrigin * rotation * shiftLeftTopToOrigin;
|
||||
}
|
||||
|
||||
static void
|
||||
SwapScaleWidthHeightForRotation(IntSize& aSize, VideoInfo::Rotation aDegrees)
|
||||
{
|
||||
if (aDegrees == VideoInfo::Rotation::kDegree_90 ||
|
||||
aDegrees == VideoInfo::Rotation::kDegree_270) {
|
||||
int32_t tmpWidth = aSize.width;
|
||||
aSize.width = aSize.height;
|
||||
aSize.height = tmpWidth;
|
||||
}
|
||||
}
|
||||
|
||||
nsVideoFrame::nsVideoFrame(nsStyleContext* aContext)
|
||||
: nsContainerFrame(aContext)
|
||||
{
|
||||
|
@ -172,7 +205,7 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||
RefPtr<ImageContainer> container = element->GetImageContainer();
|
||||
if (!container)
|
||||
return nullptr;
|
||||
|
||||
|
||||
// Retrieve the size of the decoded video frame, before being scaled
|
||||
// by pixel aspect ratio.
|
||||
mozilla::gfx::IntSize frameSize = container->GetCurrentSize();
|
||||
|
@ -200,8 +233,12 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||
if (destGFXRect.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VideoInfo::Rotation rotationDeg = element->RotationDegrees();
|
||||
IntSize scaleHint(static_cast<int32_t>(destGFXRect.Width()),
|
||||
static_cast<int32_t>(destGFXRect.Height()));
|
||||
// scaleHint is set regardless of rotation, so swap w/h if needed.
|
||||
SwapScaleWidthHeightForRotation(scaleHint, rotationDeg);
|
||||
container->SetScaleHint(scaleHint);
|
||||
|
||||
RefPtr<ImageLayer> layer = static_cast<ImageLayer*>
|
||||
|
@ -216,7 +253,13 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
|||
layer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(this));
|
||||
// Set a transform on the layer to draw the video in the right place
|
||||
gfxPoint p = destGFXRect.TopLeft() + aContainerParameters.mOffset;
|
||||
Matrix transform = Matrix::Translation(p.x, p.y);
|
||||
|
||||
Matrix preTransform = ComputeRotationMatrix(destGFXRect.Width(),
|
||||
destGFXRect.Height(),
|
||||
rotationDeg);
|
||||
|
||||
Matrix transform = preTransform * Matrix::Translation(p.x, p.y);
|
||||
|
||||
layer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
|
||||
layer->SetScaleToSize(scaleHint, ScaleMode::STRETCH);
|
||||
RefPtr<Layer> result = layer.forget();
|
||||
|
@ -356,7 +399,7 @@ public:
|
|||
MOZ_COUNT_DTOR(nsDisplayVideo);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
NS_DISPLAY_DECL_NAME("Video", TYPE_VIDEO)
|
||||
|
||||
// It would be great if we could override GetOpaqueRegion to return nonempty here,
|
||||
|
|
Загрузка…
Ссылка в новой задаче