Bug 556889 - Honour video aspect ratio in layers rendering. r=roc

This commit is contained in:
Chris Pearce 2010-04-27 20:53:44 +12:00
Родитель a7a6d145d9
Коммит fce92ab150
9 изменённых файлов: 98 добавлений и 1 удалений

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

@ -167,6 +167,11 @@ public:
return mManager;
}
/**
* Returns the size of the image in pixels.
*/
virtual gfxIntSize GetCurrentSize() = 0;
protected:
LayerManager* mManager;

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

@ -225,6 +225,7 @@ public:
virtual void SetCurrentImage(Image* aImage);
virtual already_AddRefed<Image> GetCurrentImage();
virtual already_AddRefed<gfxASurface> GetCurrentAsSurface(gfxIntSize* aSize);
virtual gfxIntSize GetCurrentSize();
protected:
Monitor mMonitor;
@ -294,6 +295,13 @@ BasicImageContainer::GetCurrentAsSurface(gfxIntSize* aSizeResult)
return ToImageData(mImage)->GetAsSurface();
}
gfxIntSize
BasicImageContainer::GetCurrentSize()
{
MonitorAutoEnter mon(mMonitor);
return !mImage ? gfxIntSize(0,0) : ToImageData(mImage)->GetSize();
}
already_AddRefed<ImageContainer>
BasicLayerManager::CreateImageContainer()
{

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

@ -88,6 +88,30 @@ ImageContainerOGL::GetCurrentAsSurface(gfxIntSize *aSize)
return nsnull;
}
gfxIntSize
ImageContainerOGL::GetCurrentSize()
{
MutexAutoLock lock(mActiveImageLock);
if (!mActiveImage) {
return gfxIntSize(0,0);
}
if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
PlanarYCbCrImageOGL *yuvImage =
static_cast<PlanarYCbCrImageOGL*>(mActiveImage.get());
if (!yuvImage->HasData()) {
return gfxIntSize(0,0);
}
return yuvImage->mSize;
} else if (mActiveImage->GetFormat() == Image::CAIRO_SURFACE) {
CairoImageOGL *cairoImage =
static_cast<CairoImageOGL*>(mActiveImage.get());
return cairoImage->mSize;
}
return gfxIntSize(0,0);
}
LayerOGL::LayerType
ImageLayerOGL::GetType()
{

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

@ -59,6 +59,9 @@ public:
virtual already_AddRefed<Image> GetCurrentImage();
virtual already_AddRefed<gfxASurface> GetCurrentAsSurface(gfxIntSize* aSize);
virtual gfxIntSize GetCurrentSize();
private:
typedef mozilla::Mutex Mutex;

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

@ -222,6 +222,14 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
container = tmpContainer.forget();
}
// Retrieve the size of the decoded video frame, before being scaled
// by pixel aspect ratio.
gfxIntSize frameSize = container->GetCurrentSize();
if (frameSize.width == 0 || frameSize.height == 0) {
// No image, or zero-sized image. No point creating a layer.
return nsnull;
}
// Compute the rectangle in which to paint the video. We need to use
// the largest rectangle that fills our content-box and has the
// correct aspect ratio.
@ -241,7 +249,7 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
// Set a transform on the layer to draw the video in the right place
gfxMatrix transform;
transform.Translate(r.pos);
transform.Scale(r.Width()/videoSize.width, r.Height()/videoSize.height);
transform.Scale(r.Width()/frameSize.width, r.Height()/frameSize.height);
layer->SetTransform(gfx3DMatrix::From2D(transform));
nsRefPtr<Layer> result = layer.forget();
return result.forget();

Двоичные данные
layout/reftests/ogg-video/black100x100-aspect3to2.ogv Normal file

Двоичный файл не отображается.

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

@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<html>
<body style="background:white;">
<div style="background-color: black; width: 150px; height: 100px; position: absolute; left: 10px; top: 10px;"></div>
<!-- Left side vertical. -->
<div style="position: absolute; left: 9px; top: 9px; width: 2px; height: 102px; z-index: 2; background: red;"></div>
<!-- Right side vertical. -->
<div style="position: absolute; left: 159px; top: 9px; width: 2px; height: 102px; z-index: 2; background: red;"></div>
<!-- Top horizontal bar. -->
<div style="position: absolute; left: 9px; top: 9px; width: 152px; height: 2px; z-index: 2; background: red;"></div>
<!-- Bottom horizontal bar. -->
<div style="position: absolute; left: 9px; top: 109px; width: 152px; height: 2px; z-index: 2; background: red;"></div>
</body>
</html>

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

@ -0,0 +1,29 @@
<!DOCTYPE HTML>
<html>
<body style="background:white;">
<!--
Test if video displays correctly with a 3:2 aspect ratio.
It should display at w=150 h=100.
On some Linux systems, the scaling to preserve the aspect ratio can sample
the pixels outside visible region. This results in a thin grey line down
some sides of the scaled picture. We add red bars over the edges to
overwrite such happenings, to make the test reliable.
-->
<video src="black100x100-aspect3to2.ogv"
style="position:absolute; left: 10px; top: 10px; z-index: 1;">
</video>
<!-- Left side vertical. -->
<div style="position: absolute; left: 9px; top: 9px; width: 2px; height: 102px; z-index: 2; background: red;"></div>
<!-- Right side vertical. -->
<div style="position: absolute; left: 159px; top: 9px; width: 2px; height: 102px; z-index: 2; background: red;"></div>
<!-- Top horizontal bar. -->
<div style="position: absolute; left: 9px; top: 9px; width: 152px; height: 2px; z-index: 2; background: red;"></div>
<!-- Bottom horizontal bar. -->
<div style="position: absolute; left: 9px; top: 109px; width: 152px; height: 2px; z-index: 2; background: red;"></div>
</body>
</html>

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

@ -4,6 +4,7 @@ skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") HTTP(..) == aspect-ratio-2a.xhtml aspect-rat
skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") HTTP(..) == aspect-ratio-2b.xhtml aspect-ratio-2-ref.html
HTTP(..) == aspect-ratio-3a.xhtml aspect-ratio-3-ref.xhtml
HTTP(..) == aspect-ratio-3b.xhtml aspect-ratio-3-ref.xhtml
== encoded-aspect-ratio-1.html encoded-aspect-ratio-1-ref.html
HTTP(..) == basic-1.xhtml basic-1-ref.html
HTTP(..) == canvas-1a.xhtml basic-1-ref.html
HTTP(..) == canvas-1b.xhtml basic-1-ref.html