Bug 789075 - Handle odd sized WebM video frames correctly. r=derf
authorMatthew Gregan <kinetik@flim.org>
Tue, 16 Oct 2012 16:03:43 +1300
changeset 110501 9fd563bfcf501899da930cf750546711ecf202f8
parent 110500 bf5f5e60f37c428e8ec10a4ad04758eedae7276e
child 110502 ef03cd944ba8930ce7bb781016f7371f062a6fa1
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersderf
bugs789075
milestone19.0a1
Bug 789075 - Handle odd sized WebM video frames correctly. r=derf
content/media/test/crashtests/789075-1.html
content/media/test/crashtests/789075.webm
content/media/test/crashtests/crashtests.list
content/media/webm/nsWebMReader.cpp
gfx/thebes/gfxUtils.cpp
new file mode 100644
--- /dev/null
+++ b/content/media/test/crashtests/789075-1.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+</head>
+<body>
+<video src="789075.webm" onloadedmetadata="document.documentElement.className=undefined"></video>
+</body>
+</html>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..602e53fca23f3619079e199fc20a0eb8ffa241fd
GIT binary patch
literal 12294
zc%1Fpy-NaN90%~{4ilHig2W;)3=9NMF$!J8t|Eej;Katte1W7$Dhpcf(L1|nY)dM_
zDGDiq5}h1cb987ZXlSkmw_emIq@};$`|x?-_dMU{IgV%k^-n$JIno>!F-tkI{xjdH
zPW+$-F|BMz!>i&R<wce9W=W2>jykK|f!rp$77UbG)gxUfreGl<U23fjQv8z*Nac3s
zJo}UN&YZ{E_ZAyVmd@I1*O@NSKe?~@{c>|FARndHccN>{gDIEb6~-KHm)8*=iG`OU
zQTP1#KVjqd*mr#eR*cptw{fpLoLE*el*_82h0vVmnT6)7v@Kam^A)K`$x!A+^ZVFq
zP26s^&IpIEl;n*>IG}{c#%jkgXHVKHJefAAs-`L$&l9~#SJ%_XY2q<A?AZkX00000
z000000000000000000000I<rRU!@Fb^xCr)cI$7SecufwcdYKLQ|^tm+jIOk`j(j<
--- a/content/media/test/crashtests/crashtests.list
+++ b/content/media/test/crashtests/crashtests.list
@@ -6,8 +6,9 @@ load 474744-1.html
 HTTP load 481136-1.html # needs to be HTTP to recognize the ogg as an audio file?
 load 493915-1.html
 skip-if(Android) load 495794-1.html
 load 492286-1.xhtml
 load 576612-1.html
 skip-if(Android) load 691096-1.html # Android sound API can't handle playing large number of sounds at once.
 load 752784-1.html
 HTTP load 795892-1.html
+load 789075-1.html
--- a/content/media/webm/nsWebMReader.cpp
+++ b/content/media/webm/nsWebMReader.cpp
@@ -700,24 +700,24 @@ bool nsWebMReader::DecodeVideoFrame(bool
       b.mPlanes[0].mData = img->planes[0];
       b.mPlanes[0].mStride = img->stride[0];
       b.mPlanes[0].mHeight = img->d_h;
       b.mPlanes[0].mWidth = img->d_w;
       b.mPlanes[0].mOffset = b.mPlanes[0].mSkip = 0;
 
       b.mPlanes[1].mData = img->planes[1];
       b.mPlanes[1].mStride = img->stride[1];
-      b.mPlanes[1].mHeight = img->d_h >> img->y_chroma_shift;
-      b.mPlanes[1].mWidth = img->d_w >> img->x_chroma_shift;
+      b.mPlanes[1].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
+      b.mPlanes[1].mWidth = (img->d_w + 1) >> img->x_chroma_shift;
       b.mPlanes[1].mOffset = b.mPlanes[1].mSkip = 0;
  
       b.mPlanes[2].mData = img->planes[2];
       b.mPlanes[2].mStride = img->stride[2];
-      b.mPlanes[2].mHeight = img->d_h >> img->y_chroma_shift;
-      b.mPlanes[2].mWidth = img->d_w >> img->x_chroma_shift;
+      b.mPlanes[2].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
+      b.mPlanes[2].mWidth = (img->d_w + 1) >> img->x_chroma_shift;
       b.mPlanes[2].mOffset = b.mPlanes[2].mSkip = 0;
   
       nsIntRect picture = mPicture;
       if (img->d_w != static_cast<uint32_t>(mInitialFrame.width) ||
           img->d_h != static_cast<uint32_t>(mInitialFrame.height)) {
         // Frame size is different from what the container reports. This is legal
         // in WebM, and we will preserve the ratio of the crop rectangle as it
         // was reported relative to the picture size reported by the container.
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -684,16 +684,22 @@ gfxUtils::GetYCbCrToRGBDestFormatAndSize
 
 void
 gfxUtils::ConvertYCbCrToRGB(const PlanarYCbCrImage::Data& aData,
                             const gfxASurface::gfxImageFormat& aDestFormat,
                             const gfxIntSize& aDestSize,
                             unsigned char* aDestBuffer,
                             int32_t aStride)
 {
+  // ConvertYCbCrToRGB et al. assume the chroma planes are rounded up if the
+  // luma plane is odd sized.
+  MOZ_ASSERT((aData.mCbCrSize.width == aData.mYSize.width ||
+              aData.mCbCrSize.width == (aData.mYSize.width + 1) >> 1) &&
+             (aData.mCbCrSize.height == aData.mYSize.height ||
+              aData.mCbCrSize.height == (aData.mYSize.height + 1) >> 1));
   gfx::YUVType yuvtype =
     gfx::TypeFromSize(aData.mYSize.width,
                       aData.mYSize.height,
                       aData.mCbCrSize.width,
                       aData.mCbCrSize.height);
 
   // Convert from YCbCr to RGB now, scaling the image if needed.
   if (aDestSize != aData.mPicSize) {