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

This commit is contained in:
Chris Pearce 2010-04-08 20:16:02 +12:00
parent 2fcd3aa8fa
commit 8ae321bbc6
9 changed files with 62 additions and 1 deletions

View File

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

View File

@ -198,6 +198,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;
@ -267,6 +268,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()
{

View File

@ -89,6 +89,28 @@ 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()
{

View File

@ -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;

View File

@ -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();

Binary file not shown.

View File

@ -0,0 +1,8 @@
<!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. -->
<video src="black100x100-aspect3to2.ogv"></video>
</body>
</html>

View File

@ -0,0 +1,6 @@
<!DOCTYPE HTML>
<html>
<body style="background:white;">
<div style="background-color: black; width: 150px; height: 100px"></div>
</body>
</html>

View File

@ -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 ref-black150x100.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