Browse Source

bug 1215089

Bill Gianopoulos 4 years ago
parent
commit
e2197a64c3

+ 65 - 0
rel-253/libdav1d/patches/1215089-1-59a1.patch

@@ -0,0 +1,65 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1507152402 -7200
+# Node ID 0e317864f85c46dca5f4a3ad0ca45d6e243bafb5
+# Parent  79eea0c0cbb2af26ca89c39017b8c6200820781a
+Bug 1215089 - P1: Properly use frame dimensions to determine planes divisors. r=jgilbert
+
+There's no guarantee that the stride of the uv planes is twice as wide as the y plane's stride. This relationship is only true between the planes' width.
+
+MozReview-Commit-ID: JInge1c86Z1
+
+diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp
+--- a/gfx/gl/GLBlitHelper.cpp
++++ b/gfx/gl/GLBlitHelper.cpp
+@@ -696,25 +696,23 @@ GLBlitHelper::BlitImage(layers::PlanarYC
+                            << yuvData->mYSize.height << ", "
+                            << yuvData->mCbCrSize.width << ","
+                            << yuvData->mCbCrSize.height << ", "
+                            << yuvData->mYStride << ","
+                            << yuvData->mCbCrStride;
+         return false;
+     }
+ 
+-    const gfx::IntSize yTexSize(yuvData->mYStride, yuvData->mYSize.height);
+-    const gfx::IntSize uvTexSize(yuvData->mCbCrStride, yuvData->mCbCrSize.height);
+     gfx::IntSize divisors;
+-    if (!GuessDivisors(yTexSize, uvTexSize, &divisors)) {
++    if (!GuessDivisors(yuvData->mYSize, yuvData->mCbCrSize, &divisors)) {
+         gfxCriticalError() << "GuessDivisors failed:"
+-                           << yTexSize.width << ","
+-                           << yTexSize.height << ", "
+-                           << uvTexSize.width << ","
+-                           << uvTexSize.height;
++                           << yuvData->mYSize.width << ","
++                           << yuvData->mYSize.height << ", "
++                           << yuvData->mCbCrSize.width << ","
++                           << yuvData->mCbCrSize.height;
+         return false;
+     }
+ 
+     // --
+ 
+     // RED textures aren't valid in GLES2, and ALPHA textures are not valid in desktop GL Core Profiles.
+     // So use R8 textures on GL3.0+ and GLES3.0+, but LUMINANCE/LUMINANCE/UNSIGNED_BYTE otherwise.
+     GLenum internalFormat;
+@@ -728,16 +726,18 @@ GLBlitHelper::BlitImage(layers::PlanarYC
+         internalFormat = LOCAL_GL_LUMINANCE;
+         unpackFormat = LOCAL_GL_LUMINANCE;
+     }
+ 
+     // --
+ 
+     const ScopedSaveMultiTex saveTex(mGL, 3, LOCAL_GL_TEXTURE_2D);
+     const ResetUnpackState reset(mGL);
++    const gfx::IntSize yTexSize(yuvData->mYStride, yuvData->mYSize.height);
++    const gfx::IntSize uvTexSize(yuvData->mCbCrStride, yuvData->mCbCrSize.height);
+ 
+     if (yTexSize != mYuvUploads_YSize ||
+         uvTexSize != mYuvUploads_UVSize)
+     {
+         mYuvUploads_YSize = yTexSize;
+         mYuvUploads_UVSize = uvTexSize;
+ 
+         mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
+

+ 36 - 0
rel-253/libdav1d/patches/1215089-10-59a1.patch

@@ -0,0 +1,36 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1506727360 -7200
+# Node ID 7b28ae5ebc77776cd8f9e5237d84826ae2234255
+# Parent  6c08410e3a753413da781b426db13d2296749a91
+Bug 1215089 - P10: Enable 10/12 bits video with OGL compositor. r=mattwoodrow
+
+MozReview-Commit-ID: AOSZla0ZX4S
+
+diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
++++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+@@ -300,18 +300,20 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
+   }
+ 
+   if ((mCodecContext->pix_fmt == AV_PIX_FMT_YUV420P10LE ||
+        mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P10LE
+ #if LIBAVCODEC_VERSION_MAJOR >= 57
+        || mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P12LE
+ #endif
+        ) &&
+-      (!mImageAllocator || mImageAllocator->GetCompositorBackendType()
+-                           != layers::LayersBackend::LAYERS_BASIC)) {
++      (!mImageAllocator || (mImageAllocator->GetCompositorBackendType()
++                            != layers::LayersBackend::LAYERS_BASIC &&
++                            mImageAllocator->GetCompositorBackendType()
++                            != layers::LayersBackend::LAYERS_OPENGL))) {
+     return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+                        RESULT_DETAIL("unsupported format type (hdr)"));
+   }
+ 
+   // If we've decoded a frame then we need to output it
+   int64_t pts = mPtsContext.GuessCorrectPts(mFrame->pkt_pts, mFrame->pkt_dts);
+   // Retrieve duration from dts.
+   // We use the first entry found matching this dts (this is done to
+

+ 65 - 0
rel-253/libdav1d/patches/1215089-11-59a1.patch

@@ -0,0 +1,65 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1507160548 -7200
+# Node ID edb7fa9379c7a4464a9624948a3da7d3b73bf902
+# Parent  7b28ae5ebc77776cd8f9e5237d84826ae2234255
+Bug 1215089 - P11. Correctly use stride parameter in place of width with webrender. r=mattwoodrow
+
+MozReview-Commit-ID: KcI6fcOgSkX
+
+diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp
+--- a/gfx/layers/composite/TextureHost.cpp
++++ b/gfx/layers/composite/TextureHost.cpp
+@@ -640,18 +640,18 @@ BufferTextureHost::AddWRImage(wr::WebRen
+     wr::ImageDescriptor descriptor(GetSize(),
+                                    ImageDataSerializer::ComputeRGBStride(GetFormat(), GetSize().width),
+                                    GetFormat());
+     aAPI->AddExternalImageBuffer(aImageKeys[0], descriptor, aExtID);
+   } else {
+     MOZ_ASSERT(aImageKeys.length() == 3);
+ 
+     const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
+-    wr::ImageDescriptor yDescriptor(desc.ySize(), desc.ySize().width, gfx::SurfaceFormat::A8);
+-    wr::ImageDescriptor cbcrDescriptor(desc.cbCrSize(), desc.cbCrSize().width, gfx::SurfaceFormat::A8);
++    wr::ImageDescriptor yDescriptor(desc.ySize(), desc.yStride(), gfx::SurfaceFormat::A8);
++    wr::ImageDescriptor cbcrDescriptor(desc.cbCrSize(), desc.cbCrStride(), gfx::SurfaceFormat::A8);
+     aAPI->AddExternalImage(aImageKeys[0],
+                            yDescriptor,
+                            aExtID,
+                            wr::WrExternalImageBufferType::ExternalBuffer,
+                            0);
+     aAPI->AddExternalImage(aImageKeys[1],
+                            cbcrDescriptor,
+                            aExtID,
+diff --git a/gfx/webrender_bindings/RenderBufferTextureHost.cpp b/gfx/webrender_bindings/RenderBufferTextureHost.cpp
+--- a/gfx/webrender_bindings/RenderBufferTextureHost.cpp
++++ b/gfx/webrender_bindings/RenderBufferTextureHost.cpp
+@@ -59,25 +59,25 @@ RenderBufferTextureHost::Lock()
+       if (NS_WARN_IF(!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mMap))) {
+         mSurface = nullptr;
+         return false;
+       }
+     } else {
+       const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
+ 
+       mYSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetYChannel(GetBuffer(), desc),
+-                                                                desc.ySize().width,
++                                                                desc.yStride(),
+                                                                 desc.ySize(),
+                                                                 gfx::SurfaceFormat::A8);
+       mCbSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetCbChannel(GetBuffer(), desc),
+-                                                                 desc.cbCrSize().width,
++                                                                 desc.cbCrStride(),
+                                                                  desc.cbCrSize(),
+                                                                  gfx::SurfaceFormat::A8);
+       mCrSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetCrChannel(GetBuffer(), desc),
+-                                                                 desc.cbCrSize().width,
++                                                                 desc.cbCrStride(),
+                                                                  desc.cbCrSize(),
+                                                                  gfx::SurfaceFormat::A8);
+       if (NS_WARN_IF(!mYSurface || !mCbSurface || !mCrSurface)) {
+         mYSurface = mCbSurface = mCrSurface = nullptr;
+         return false;
+       }
+       if (NS_WARN_IF(!mYSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mYMap) ||
+                      !mCbSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCbMap) ||

+ 73 - 0
rel-253/libdav1d/patches/1215089-2-59a1.patch

@@ -0,0 +1,73 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1498770423 -7200
+# Node ID 9dc83d91c3364d36053b7ad9860271f4e67d0ddd
+# Parent  0e317864f85c46dca5f4a3ad0ca45d6e243bafb5
+Bug 1215089 - P2: Add YUV422 support to ffmpeg decoder. r=kentuckyfriedtakahe
+
+This allows for VP9 profile 1 support.
+
+MozReview-Commit-ID: KymoerXNyzA
+
+diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
++++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+@@ -12,16 +12,17 @@
+ #include "VPXDecoder.h"
+ #include "mozilla/layers/KnowsCompositor.h"
+ 
+ #include "libavutil/pixfmt.h"
+ #if LIBAVCODEC_VERSION_MAJOR < 54
+ #define AVPixelFormat PixelFormat
+ #define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
+ #define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P
++#define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P
+ #define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P
+ #define AV_PIX_FMT_NONE PIX_FMT_NONE
+ #endif
+ #include "mozilla/PodOperations.h"
+ #include "mozilla/TaskQueue.h"
+ #include "nsThreadUtils.h"
+ #include "prsystem.h"
+ 
+@@ -43,16 +44,19 @@ static AVPixelFormat
+ ChoosePixelFormat(AVCodecContext* aCodecContext, const AVPixelFormat* aFormats)
+ {
+   FFMPEG_LOG("Choosing FFmpeg pixel format for video decoding.");
+   for (; *aFormats > -1; aFormats++) {
+     switch (*aFormats) {
+       case AV_PIX_FMT_YUV444P:
+         FFMPEG_LOG("Requesting pixel format YUV444P.");
+         return AV_PIX_FMT_YUV444P;
++      case AV_PIX_FMT_YUV422P:
++        FFMPEG_LOG("Requesting pixel format YUV422P.");
++        return AV_PIX_FMT_YUV422P;
+       case AV_PIX_FMT_YUV420P:
+         FFMPEG_LOG("Requesting pixel format YUV420P.");
+         return AV_PIX_FMT_YUV420P;
+       case AV_PIX_FMT_YUVJ420P:
+         FFMPEG_LOG("Requesting pixel format YUVJ420P.");
+         return AV_PIX_FMT_YUVJ420P;
+       default:
+         break;
+@@ -315,16 +319,19 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
+   b.mPlanes[1].mOffset = b.mPlanes[1].mSkip = 0;
+   b.mPlanes[2].mOffset = b.mPlanes[2].mSkip = 0;
+ 
+   b.mPlanes[0].mWidth = mFrame->width;
+   b.mPlanes[0].mHeight = mFrame->height;
+   if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P) {
+     b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = mFrame->width;
+     b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = mFrame->height;
++  } else if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV422P) {
++    b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = (mFrame->width + 1) >> 1;
++    b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = mFrame->height;
+   } else {
+     b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = (mFrame->width + 1) >> 1;
+     b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = (mFrame->height + 1) >> 1;
+   }
+   if (mLib->av_frame_get_colorspace) {
+     switch (mLib->av_frame_get_colorspace(mFrame)) {
+       case AVCOL_SPC_BT709:
+         b.mYUVColorSpace = YUVColorSpace::BT709;
+

+ 87 - 0
rel-253/libdav1d/patches/1215089-3-59a1.patch

@@ -0,0 +1,87 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1498770560 -7200
+# Node ID bcfc414429b64c64c9e7932250b82c1369352f11
+# Parent  9dc83d91c3364d36053b7ad9860271f4e67d0ddd
+Bug 1215089 - P3: Add mBitDepth member to YCbCr data structure. r=kamidphish,mattwoodrow
+
+MozReview-Commit-ID: BNLawJOfj3w
+
+diff --git a/dom/media/MediaData.cpp b/dom/media/MediaData.cpp
+--- a/dom/media/MediaData.cpp
++++ b/dom/media/MediaData.cpp
+@@ -248,16 +248,17 @@ ConstructPlanarYCbCrData(const VideoInfo
+   data.mCbCrStride = Cb.mStride;
+   data.mCbSkip = Cb.mSkip;
+   data.mCrSkip = Cr.mSkip;
+   data.mPicX = aPicture.x;
+   data.mPicY = aPicture.y;
+   data.mPicSize = aPicture.Size();
+   data.mStereoMode = aInfo.mStereoMode;
+   data.mYUVColorSpace = aBuffer.mYUVColorSpace;
++  data.mBitDepth = aBuffer.mBitDepth;
+   return data;
+ }
+ 
+ /* static */ bool
+ VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
+                                const VideoInfo& aInfo,
+                                const YCbCrBuffer &aBuffer,
+                                const IntRect& aPicture,
+diff --git a/dom/media/MediaData.h b/dom/media/MediaData.h
+--- a/dom/media/MediaData.h
++++ b/dom/media/MediaData.h
+@@ -461,16 +461,17 @@ public:
+       uint32_t mHeight;
+       uint32_t mStride;
+       uint32_t mOffset;
+       uint32_t mSkip;
+     };
+ 
+     Plane mPlanes[3];
+     YUVColorSpace mYUVColorSpace = YUVColorSpace::BT601;
++    uint32_t mBitDepth = 8;
+   };
+ 
+   class Listener
+   {
+   public:
+     virtual void OnSentToCompositor() = 0;
+     virtual ~Listener() { }
+   };
+diff --git a/gfx/layers/ImageContainer.h b/gfx/layers/ImageContainer.h
+--- a/gfx/layers/ImageContainer.h
++++ b/gfx/layers/ImageContainer.h
+@@ -739,29 +739,31 @@ struct PlanarYCbCrData {
+   int32_t mCbSkip;
+   int32_t mCrSkip;
+   // Picture region
+   uint32_t mPicX;
+   uint32_t mPicY;
+   gfx::IntSize mPicSize;
+   StereoMode mStereoMode;
+   YUVColorSpace mYUVColorSpace;
++  uint32_t mBitDepth;
+ 
+   gfx::IntRect GetPictureRect() const {
+     return gfx::IntRect(mPicX, mPicY,
+                      mPicSize.width,
+                      mPicSize.height);
+   }
+ 
+   PlanarYCbCrData()
+     : mYChannel(nullptr), mYStride(0), mYSize(0, 0), mYSkip(0)
+     , mCbChannel(nullptr), mCrChannel(nullptr)
+     , mCbCrStride(0), mCbCrSize(0, 0) , mCbSkip(0), mCrSkip(0)
+     , mPicX(0), mPicY(0), mPicSize(0, 0), mStereoMode(StereoMode::MONO)
+     , mYUVColorSpace(YUVColorSpace::BT601)
++    , mBitDepth(8)
+   {}
+ };
+ 
+ /****** Image subtypes for the different formats ******/
+ 
+ /**
+  * We assume that the image data is in the REC 470M color space (see
+  * Theora specification, section 4.3.1).
+

+ 108 - 0
rel-253/libdav1d/patches/1215089-4-59a1.patch

@@ -0,0 +1,108 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1498770666 -7200
+# Node ID 6a76cec689e24232e0f99695e76a3629f9e1df62
+# Parent  bcfc414429b64c64c9e7932250b82c1369352f11
+Bug 1215089 - P4: Add support to 10 and 12 bits YUV images to FFmpeg decoder. r=kentuckyfriedtakahe
+
+This allows for decoding VP9 profile 2 and 3.
+
+At this stage, it is not possible to render the decoded frames.
+
+MozReview-Commit-ID: DFXMvaM8Ynb
+
+diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
++++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+@@ -14,16 +14,18 @@
+ 
+ #include "libavutil/pixfmt.h"
+ #if LIBAVCODEC_VERSION_MAJOR < 54
+ #define AVPixelFormat PixelFormat
+ #define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
+ #define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P
+ #define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P
+ #define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P
++#define AV_PIX_FMT_YUV420P10LE PIX_FMT_YUV420P10LE
++#define AV_PIX_FMT_YUV444P10LE PIX_FMT_YUV444P10LE
+ #define AV_PIX_FMT_NONE PIX_FMT_NONE
+ #endif
+ #include "mozilla/PodOperations.h"
+ #include "mozilla/TaskQueue.h"
+ #include "nsThreadUtils.h"
+ #include "prsystem.h"
+ 
+ 
+@@ -53,16 +55,27 @@ ChoosePixelFormat(AVCodecContext* aCodec
+         FFMPEG_LOG("Requesting pixel format YUV422P.");
+         return AV_PIX_FMT_YUV422P;
+       case AV_PIX_FMT_YUV420P:
+         FFMPEG_LOG("Requesting pixel format YUV420P.");
+         return AV_PIX_FMT_YUV420P;
+       case AV_PIX_FMT_YUVJ420P:
+         FFMPEG_LOG("Requesting pixel format YUVJ420P.");
+         return AV_PIX_FMT_YUVJ420P;
++      case AV_PIX_FMT_YUV420P10LE:
++        FFMPEG_LOG("Requesting pixel format YUV420P10LE.");
++        return AV_PIX_FMT_YUV420P10LE;
++      case AV_PIX_FMT_YUV444P10LE:
++        FFMPEG_LOG("Requesting pixel format YUV444P10LE.");
++        return AV_PIX_FMT_YUV444P10LE;
++#if LIBAVCODEC_VERSION_MAJOR >= 57
++      case AV_PIX_FMT_YUV444P12LE:
++        FFMPEG_LOG("Requesting pixel format YUV444P12LE.");
++        return AV_PIX_FMT_YUV444P12LE;
++#endif
+       default:
+         break;
+     }
+   }
+ 
+   NS_WARNING("FFmpeg does not share any supported pixel formats.");
+   return AV_PIX_FMT_NONE;
+ }
+@@ -316,25 +329,42 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
+   b.mPlanes[2].mStride = mFrame->linesize[2];
+ 
+   b.mPlanes[0].mOffset = b.mPlanes[0].mSkip = 0;
+   b.mPlanes[1].mOffset = b.mPlanes[1].mSkip = 0;
+   b.mPlanes[2].mOffset = b.mPlanes[2].mSkip = 0;
+ 
+   b.mPlanes[0].mWidth = mFrame->width;
+   b.mPlanes[0].mHeight = mFrame->height;
+-  if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P) {
++  if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P ||
++      mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P10LE
++#if LIBAVCODEC_VERSION_MAJOR >= 57
++      ||
++      mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P12LE
++#endif
++      ) {
+     b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = mFrame->width;
+     b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = mFrame->height;
++    if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P10LE) {
++      b.mBitDepth = 10;
++    }
++#if LIBAVCODEC_VERSION_MAJOR >= 57
++    else if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P12LE) {
++      b.mBitDepth = 12;
++    }
++#endif
+   } else if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV422P) {
+     b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = (mFrame->width + 1) >> 1;
+     b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = mFrame->height;
+   } else {
+     b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = (mFrame->width + 1) >> 1;
+     b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = (mFrame->height + 1) >> 1;
++    if (mCodecContext->pix_fmt == AV_PIX_FMT_YUV420P10LE) {
++      b.mBitDepth = 10;
++    }
+   }
+   if (mLib->av_frame_get_colorspace) {
+     switch (mLib->av_frame_get_colorspace(mFrame)) {
+       case AVCOL_SPC_BT709:
+         b.mYUVColorSpace = YUVColorSpace::BT709;
+         break;
+       case AVCOL_SPC_SMPTE170M:
+       case AVCOL_SPC_BT470BG:
+

+ 240 - 0
rel-253/libdav1d/patches/1215089-5-59a1.patch

@@ -0,0 +1,240 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1506685389 -7200
+# Node ID daf9357023dcc2e42cdced264f4cce6671b2b2ec
+# Parent  6a76cec689e24232e0f99695e76a3629f9e1df62
+Bug 1215089 - P5: Convert 10/12 bits YUV image to 8 bits prior conversion to RGB. r=mattwoodrow
+
+For now, convert 10/12 bits YUV image to 8 bits. Native support will be tracked in bug 1379948
+
+MozReview-Commit-ID: LOr9X5xxKY7
+
+diff --git a/gfx/ycbcr/YCbCrUtils.cpp b/gfx/ycbcr/YCbCrUtils.cpp
+--- a/gfx/ycbcr/YCbCrUtils.cpp
++++ b/gfx/ycbcr/YCbCrUtils.cpp
+@@ -61,100 +61,183 @@ GetYCbCrToRGBDestFormatAndSize(const lay
+     if (aData.mPicX != 0 || aData.mPicY != 0 || yuvtype == YV24)
+       prescale = false;
+   }
+   if (!prescale) {
+     aSuggestedSize = aData.mPicSize;
+   }
+ }
+ 
++static inline void
++ConvertYCbCr16to8Line(uint8_t* aDst,
++                      int aStride,
++                      const uint16_t* aSrc,
++                      int aStride16,
++                      int aWidth,
++                      int aHeight,
++                      int aBitDepth)
++{
++  uint16_t mask = (1 << aBitDepth) - 1;
++
++  for (int i = 0; i < aHeight; i++) {
++    for (int j = 0; j < aWidth; j++) {
++      uint16_t val = (aSrc[j] & mask) >> (aBitDepth - 8);
++      aDst[j] = val;
++    }
++    aDst += aStride;
++    aSrc += aStride16;
++  }
++}
++
+ void
+ ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
+                   const SurfaceFormat& aDestFormat,
+                   const IntSize& 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));
++
++  // Used if converting to 8 bits YUV.
++  UniquePtr<uint8_t[]> yChannel;
++  UniquePtr<uint8_t[]> cbChannel;
++  UniquePtr<uint8_t[]> crChannel;
++  layers::PlanarYCbCrData dstData;
++  const layers::PlanarYCbCrData& srcData = aData.mBitDepth == 8 ? aData : dstData;
++
++  if (aData.mBitDepth != 8) {
++    MOZ_ASSERT(aData.mBitDepth > 8 && aData.mBitDepth <= 16);
++    // Convert to 8 bits data first.
++    dstData.mPicSize = aData.mPicSize;
++    dstData.mPicX = aData.mPicX;
++    dstData.mPicY = aData.mPicY;
++    dstData.mYSize = aData.mYSize;
++    // We align the destination stride to 32 bytes, so that libyuv can use
++    // SSE optimised code.
++    dstData.mYStride = (aData.mYSize.width + 31) & ~31;
++    dstData.mCbCrSize = aData.mCbCrSize;
++    dstData.mCbCrStride = (aData.mCbCrSize.width + 31) & ~31;
++    dstData.mYUVColorSpace = aData.mYUVColorSpace;
++    dstData.mBitDepth = 8;
++
++    size_t ySize = GetAlignedStride<1>(dstData.mYStride, aData.mYSize.height);
++    size_t cbcrSize =
++      GetAlignedStride<1>(dstData.mCbCrStride, aData.mCbCrSize.height);
++    if (ySize == 0 || cbcrSize == 0) {
++      return;
++    }
++    yChannel = MakeUnique<uint8_t[]>(ySize);
++    cbChannel = MakeUnique<uint8_t[]>(cbcrSize);
++    crChannel = MakeUnique<uint8_t[]>(cbcrSize);
++
++    dstData.mYChannel = yChannel.get();
++    dstData.mCbChannel = cbChannel.get();
++    dstData.mCrChannel = crChannel.get();
++
++    ConvertYCbCr16to8Line(dstData.mYChannel,
++                          dstData.mYStride,
++                          reinterpret_cast<uint16_t*>(aData.mYChannel),
++                          aData.mYStride / 2,
++                          aData.mYSize.width,
++                          aData.mYSize.height,
++                          aData.mBitDepth);
++
++    ConvertYCbCr16to8Line(dstData.mCbChannel,
++                          dstData.mCbCrStride,
++                          reinterpret_cast<uint16_t*>(aData.mCbChannel),
++                          aData.mCbCrStride / 2,
++                          aData.mCbCrSize.width,
++                          aData.mCbCrSize.height,
++                          aData.mBitDepth);
++
++    ConvertYCbCr16to8Line(dstData.mCrChannel,
++                          dstData.mCbCrStride,
++                          reinterpret_cast<uint16_t*>(aData.mCrChannel),
++                          aData.mCbCrStride / 2,
++                          aData.mCbCrSize.width,
++                          aData.mCbCrSize.height,
++                          aData.mBitDepth);
++  }
++
+   YUVType yuvtype =
+-    TypeFromSize(aData.mYSize.width,
+-                 aData.mYSize.height,
+-                 aData.mCbCrSize.width,
+-                 aData.mCbCrSize.height);
++    TypeFromSize(srcData.mYSize.width,
++                 srcData.mYSize.height,
++                 srcData.mCbCrSize.width,
++                 srcData.mCbCrSize.height);
+ 
+   // Convert from YCbCr to RGB now, scaling the image if needed.
+-  if (aDestSize != aData.mPicSize) {
++  if (aDestSize != srcData.mPicSize) {
+ #if defined(HAVE_YCBCR_TO_RGB565)
+     if (aDestFormat == SurfaceFormat::R5G6B5_UINT16) {
+-      ScaleYCbCrToRGB565(aData.mYChannel,
+-                         aData.mCbChannel,
+-                         aData.mCrChannel,
++      ScaleYCbCrToRGB565(srcData.mYChannel,
++                         srcData.mCbChannel,
++                         srcData.mCrChannel,
+                          aDestBuffer,
+-                         aData.mPicX,
+-                         aData.mPicY,
+-                         aData.mPicSize.width,
+-                         aData.mPicSize.height,
++                         srcData.mPicX,
++                         srcData.mPicY,
++                         srcData.mPicSize.width,
++                         srcData.mPicSize.height,
+                          aDestSize.width,
+                          aDestSize.height,
+-                         aData.mYStride,
+-                         aData.mCbCrStride,
++                         srcData.mYStride,
++                         srcData.mCbCrStride,
+                          aStride,
+                          yuvtype,
+                          FILTER_BILINEAR);
+     } else
+ #endif
+-      ScaleYCbCrToRGB32(aData.mYChannel, //
+-                        aData.mCbChannel,
+-                        aData.mCrChannel,
++      ScaleYCbCrToRGB32(srcData.mYChannel, //
++                        srcData.mCbChannel,
++                        srcData.mCrChannel,
+                         aDestBuffer,
+-                        aData.mPicSize.width,
+-                        aData.mPicSize.height,
++                        srcData.mPicSize.width,
++                        srcData.mPicSize.height,
+                         aDestSize.width,
+                         aDestSize.height,
+-                        aData.mYStride,
+-                        aData.mCbCrStride,
++                        srcData.mYStride,
++                        srcData.mCbCrStride,
+                         aStride,
+                         yuvtype,
+-                        aData.mYUVColorSpace,
++                        srcData.mYUVColorSpace,
+                         FILTER_BILINEAR);
+   } else { // no prescale
+ #if defined(HAVE_YCBCR_TO_RGB565)
+     if (aDestFormat == SurfaceFormat::R5G6B5_UINT16) {
+-      ConvertYCbCrToRGB565(aData.mYChannel,
+-                           aData.mCbChannel,
+-                           aData.mCrChannel,
++      ConvertYCbCrToRGB565(srcData.mYChannel,
++                           srcData.mCbChannel,
++                           srcData.mCrChannel,
+                            aDestBuffer,
+-                           aData.mPicX,
+-                           aData.mPicY,
+-                           aData.mPicSize.width,
+-                           aData.mPicSize.height,
+-                           aData.mYStride,
+-                           aData.mCbCrStride,
++                           srcData.mPicX,
++                           srcData.mPicY,
++                           srcData.mPicSize.width,
++                           srcData.mPicSize.height,
++                           srcData.mYStride,
++                           srcData.mCbCrStride,
+                            aStride,
+                            yuvtype);
+     } else // aDestFormat != SurfaceFormat::R5G6B5_UINT16
+ #endif
+-      ConvertYCbCrToRGB32(aData.mYChannel, //
+-                          aData.mCbChannel,
+-                          aData.mCrChannel,
++      ConvertYCbCrToRGB32(srcData.mYChannel, //
++                          srcData.mCbChannel,
++                          srcData.mCrChannel,
+                           aDestBuffer,
+-                          aData.mPicX,
+-                          aData.mPicY,
+-                          aData.mPicSize.width,
+-                          aData.mPicSize.height,
+-                          aData.mYStride,
+-                          aData.mCbCrStride,
++                          srcData.mPicX,
++                          srcData.mPicY,
++                          srcData.mPicSize.width,
++                          srcData.mPicSize.height,
++                          srcData.mYStride,
++                          srcData.mCbCrStride,
+                           aStride,
+                           yuvtype,
+-                          aData.mYUVColorSpace);
++                          srcData.mYUVColorSpace);
+   }
+ }
+ 
+ void
+ ConvertYCbCrAToARGB(const uint8_t* aSrcY,
+                     const uint8_t* aSrcU,
+                     const uint8_t* aSrcV,
+                     const uint8_t* aSrcA,
+

+ 192 - 0
rel-253/libdav1d/patches/1215089-6-59a1.patch

@@ -0,0 +1,192 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1507080405 -7200
+# Node ID 84bcd57f2404a4fc48a42b36e5f553c8dec001ff
+# Parent  daf9357023dcc2e42cdced264f4cce6671b2b2ec
+Bug 1215089 - P6: Remove dead code. r=mattwoodrow
+
+The method isn't called and the comments referring to it are no longer applicable.
+
+MozReview-Commit-ID: 2FFWhj7wzht
+
+diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp
+--- a/gfx/layers/ImageContainer.cpp
++++ b/gfx/layers/ImageContainer.cpp
+@@ -587,36 +587,24 @@ gfxImageFormat
+ PlanarYCbCrImage::GetOffscreenFormat()
+ {
+   return mOffscreenFormat == SurfaceFormat::UNKNOWN ?
+     gfxVars::OffscreenFormat() :
+     mOffscreenFormat;
+ }
+ 
+ bool
+-PlanarYCbCrImage::AdoptData(const Data &aData)
++PlanarYCbCrImage::AdoptData(const Data& aData)
+ {
+   mData = aData;
+   mSize = aData.mPicSize;
+   mOrigin = gfx::IntPoint(aData.mPicX, aData.mPicY);
+   return true;
+ }
+ 
+-uint8_t*
+-RecyclingPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
+-{
+-  // get new buffer
+-  mBuffer = AllocateBuffer(aSize);
+-  if (mBuffer) {
+-    // update buffer size
+-    mBufferSize = aSize;
+-  }
+-  return mBuffer.get();
+-}
+-
+ already_AddRefed<gfx::SourceSurface>
+ PlanarYCbCrImage::GetAsSourceSurface()
+ {
+   if (mSourceSurface) {
+     RefPtr<gfx::SourceSurface> surface(mSourceSurface);
+     return surface.forget();
+   }
+ 
+diff --git a/gfx/layers/ImageContainer.h b/gfx/layers/ImageContainer.h
+--- a/gfx/layers/ImageContainer.h
++++ b/gfx/layers/ImageContainer.h
+@@ -805,28 +805,19 @@ public:
+ 
+   /**
+    * This makes a copy of the data buffers, in order to support functioning
+    * in all different layer managers.
+    */
+   virtual bool CopyData(const Data& aData) = 0;
+ 
+   /**
+-   * This doesn't make a copy of the data buffers. Can be used when mBuffer is
+-   * pre allocated with AllocateAndGetNewBuffer(size) and then AdoptData is
+-   * called to only update the picture size, planes etc. fields in mData.
+-   * The GStreamer media backend uses this to decode into PlanarYCbCrImage(s)
+-   * directly.
++   * This doesn't make a copy of the data buffers.
+    */
+-  virtual bool AdoptData(const Data &aData);
+-
+-  /**
+-   * This allocates and returns a new buffer
+-   */
+-  virtual uint8_t* AllocateAndGetNewBuffer(uint32_t aSize) = 0;
++  virtual bool AdoptData(const Data& aData);
+ 
+   /**
+    * Ask this Image to not convert YUV to RGB during SetData, and make
+    * the original data available through GetData. This is optional,
+    * and not all PlanarYCbCrImages will support it.
+    */
+   virtual void SetDelayedConversion(bool aDelayed) { }
+ 
+@@ -872,17 +863,16 @@ protected:
+   uint32_t mBufferSize;
+ };
+ 
+ class RecyclingPlanarYCbCrImage: public PlanarYCbCrImage {
+ public:
+   explicit RecyclingPlanarYCbCrImage(BufferRecycleBin *aRecycleBin) : mRecycleBin(aRecycleBin) {}
+   virtual ~RecyclingPlanarYCbCrImage() override;
+   virtual bool CopyData(const Data& aData) override;
+-  virtual uint8_t* AllocateAndGetNewBuffer(uint32_t aSize) override;
+   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
+ protected:
+ 
+   /**
+    * Return a buffer to store image data in.
+    */
+   mozilla::UniquePtr<uint8_t[]> AllocateBuffer(uint32_t aSize);
+ 
+diff --git a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
+--- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
++++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
+@@ -100,57 +100,19 @@ SharedPlanarYCbCrImage::CopyData(const P
+   if (!UpdateYCbCrTextureClient(mTextureClient, aData)) {
+     MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
+     return false;
+   }
+   mTextureClient->MarkImmutable();
+   return true;
+ }
+ 
+-// needs to be overriden because the parent class sets mBuffer which we
+-// do not want to happen.
+-uint8_t*
+-SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
++bool
++SharedPlanarYCbCrImage::AdoptData(const Data& aData)
+ {
+-  MOZ_ASSERT(!mTextureClient, "This image already has allocated data");
+-  size_t size = ImageDataSerializer::ComputeYCbCrBufferSize(aSize);
+-  if (!size) {
+-    return nullptr;
+-  }
+-
+-  // XXX Add YUVColorSpace handling. Use YUVColorSpace::BT601 for now.
+-  mTextureClient = TextureClient::CreateForYCbCrWithBufferSize(mCompositable->GetForwarder(),
+-                                                               size,
+-                                                               YUVColorSpace::BT601,
+-                                                               mCompositable->GetTextureFlags());
+-
+-  // get new buffer _without_ setting mBuffer.
+-  if (!mTextureClient) {
+-    return nullptr;
+-  }
+-
+-  // update buffer size
+-  mBufferSize = size;
+-
+-  MappedYCbCrTextureData mapped;
+-  if (mTextureClient->BorrowMappedYCbCrData(mapped)) {
+-    // The caller expects a pointer to the beginning of the writable part of the
+-    // buffer which is where the y channel starts by default.
+-    return mapped.y.data;
+-  } else {
+-    MOZ_CRASH("GFX: Cannot borrow mapped YCbCr data");
+-  }
+-}
+-
+-bool
+-SharedPlanarYCbCrImage::AdoptData(const Data &aData)
+-{
+-  // AdoptData is used to update YUV plane offsets without (re)allocating
+-  // memory previously allocated with AllocateAndGetNewBuffer().
+-
+   MOZ_ASSERT(mTextureClient, "This Image should have already allocated data");
+   if (!mTextureClient) {
+     return false;
+   }
+   mData = aData;
+   mSize = aData.mPicSize;
+   mOrigin = gfx::IntPoint(aData.mPicX, aData.mPicY);
+ 
+diff --git a/gfx/layers/ipc/SharedPlanarYCbCrImage.h b/gfx/layers/ipc/SharedPlanarYCbCrImage.h
+--- a/gfx/layers/ipc/SharedPlanarYCbCrImage.h
++++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.h
+@@ -31,20 +31,19 @@ protected:
+   ~SharedPlanarYCbCrImage();
+ 
+ public:
+   virtual TextureClient* GetTextureClient(KnowsCompositor* aForwarder) override;
+   virtual uint8_t* GetBuffer() override;
+ 
+   virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
+   virtual bool CopyData(const PlanarYCbCrData& aData) override;
+-  virtual bool AdoptData(const Data &aData) override;
++  virtual bool AdoptData(const Data& aData) override;
+ 
+   virtual bool Allocate(PlanarYCbCrData& aData);
+-  virtual uint8_t* AllocateAndGetNewBuffer(uint32_t aSize) override;
+ 
+   virtual bool IsValid() override;
+ 
+   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
+   {
+     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
+   }
+ 

+ 1158 - 0
rel-253/libdav1d/patches/1215089-7-59a1.patch

@@ -0,0 +1,1158 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1506695876 -7200
+# Node ID b55e89b5df041a28c7bf34d6896224a7e2d94929
+# Parent  84bcd57f2404a4fc48a42b36e5f553c8dec001ff
+Bug 1215089 - P7: Add support for 10/12 bits YUV surface with basic compositor. r=mattwoodrow
+
+MozReview-Commit-ID: Ej4MbvHnSk9
+
+diff --git a/gfx/2d/Tools.h b/gfx/2d/Tools.h
+--- a/gfx/2d/Tools.h
++++ b/gfx/2d/Tools.h
+@@ -88,30 +88,44 @@ Distance(Point aA, Point aB)
+ 
+ static inline int
+ BytesPerPixel(SurfaceFormat aFormat)
+ {
+   switch (aFormat) {
+   case SurfaceFormat::A8:
+     return 1;
+   case SurfaceFormat::R5G6B5_UINT16:
++  case SurfaceFormat::A16:
+     return 2;
+   case SurfaceFormat::R8G8B8:
+   case SurfaceFormat::B8G8R8:
+     return 3;
+   case SurfaceFormat::HSV:
+   case SurfaceFormat::Lab:
+     return 3 * sizeof(float);
+   case SurfaceFormat::Depth:
+     return sizeof(uint16_t);
+   default:
+     return 4;
+   }
+ }
+ 
++static inline SurfaceFormat
++SurfaceFormatForAlphaBitDepth(uint32_t aBitDepth)
++{
++  if (aBitDepth == 8) {
++    return SurfaceFormat::A8;
++  } else if (aBitDepth == 10 ||
++             aBitDepth == 12) {
++    return SurfaceFormat::A16;
++  }
++  MOZ_ASSERT_UNREACHABLE("Unsupported alpha bit depth");
++  return SurfaceFormat::UNKNOWN;
++}
++
+ static inline bool
+ IsOpaqueFormat(SurfaceFormat aFormat) {
+   switch (aFormat) {
+     case SurfaceFormat::B8G8R8X8:
+     case SurfaceFormat::R8G8B8X8:
+     case SurfaceFormat::X8R8G8B8:
+     case SurfaceFormat::YUV:
+     case SurfaceFormat::NV12:
+diff --git a/gfx/2d/Types.h b/gfx/2d/Types.h
+--- a/gfx/2d/Types.h
++++ b/gfx/2d/Types.h
+@@ -53,16 +53,17 @@ enum class SurfaceFormat : int8_t {
+ 
+   // The _UINT16 suffix here indicates that the name reflects the layout when
+   // viewed as a uint16_t value. In memory these values are stored using native
+   // endianness.
+   R5G6B5_UINT16,                    // 0bRRRRRGGGGGGBBBBB
+ 
+   // This one is a single-byte, so endianness isn't an issue.
+   A8,
++  A16,
+ 
+   R8G8,
+ 
+   // These ones are their own special cases.
+   YUV,
+   NV12,
+   YUV422,
+   HSV,
+diff --git a/gfx/layers/BufferTexture.cpp b/gfx/layers/BufferTexture.cpp
+--- a/gfx/layers/BufferTexture.cpp
++++ b/gfx/layers/BufferTexture.cpp
+@@ -155,67 +155,83 @@ BufferTextureData::CreateInternal(Layers
+     return new ShmemTextureData(aDesc, aMoz2DBackend, shm);
+   }
+ }
+ 
+ BufferTextureData*
+ BufferTextureData::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
+                                                 int32_t aBufferSize,
+                                                 YUVColorSpace aYUVColorSpace,
++                                                uint32_t aBitDepth,
+                                                 TextureFlags aTextureFlags)
+ {
+   if (aBufferSize == 0 || !gfx::Factory::CheckBufferSize(aBufferSize)) {
+     return nullptr;
+   }
+ 
+   bool hasIntermediateBuffer = aAllocator ? ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
+                                                                          aAllocator->GetCompositorBackendType())
+                                           : true;
+ 
+   // Initialize the metadata with something, even if it will have to be rewritten
+   // afterwards since we don't know the dimensions of the texture at this point.
+-  BufferDescriptor desc = YCbCrDescriptor(gfx::IntSize(), gfx::IntSize(),
++  BufferDescriptor desc = YCbCrDescriptor(gfx::IntSize(), 0, gfx::IntSize(), 0,
+                                           0, 0, 0, StereoMode::MONO,
+                                           aYUVColorSpace,
++                                          aBitDepth,
+                                           hasIntermediateBuffer);
+ 
+   return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder() : nullptr,
+                        desc, gfx::BackendType::NONE, aBufferSize, aTextureFlags);
+ }
+ 
+ BufferTextureData*
+ BufferTextureData::CreateForYCbCr(KnowsCompositor* aAllocator,
+                                   gfx::IntSize aYSize,
++                                  uint32_t aYStride,
+                                   gfx::IntSize aCbCrSize,
++                                  uint32_t aCbCrStride,
+                                   StereoMode aStereoMode,
+                                   YUVColorSpace aYUVColorSpace,
++                                  uint32_t aBitDepth,
+                                   TextureFlags aTextureFlags)
+ {
+-  uint32_t bufSize = ImageDataSerializer::ComputeYCbCrBufferSize(aYSize, aCbCrSize);
++  uint32_t bufSize = ImageDataSerializer::ComputeYCbCrBufferSize(
++    aYSize, aYStride, aCbCrSize, aCbCrStride);
+   if (bufSize == 0) {
+     return nullptr;
+   }
+ 
+   uint32_t yOffset;
+   uint32_t cbOffset;
+   uint32_t crOffset;
+-  ImageDataSerializer::ComputeYCbCrOffsets(aYSize.width, aYSize.height,
+-                                          aCbCrSize.width, aCbCrSize.height,
+-                                          yOffset, cbOffset, crOffset);
++  ImageDataSerializer::ComputeYCbCrOffsets(aYStride, aYSize.height,
++                                           aCbCrStride, aCbCrSize.height,
++                                           yOffset, cbOffset, crOffset);
+ 
+-  bool hasIntermediateBuffer = aAllocator ? ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
+-                                                                         aAllocator->GetCompositorBackendType())
+-                                          : true;
++  bool hasIntermediateBuffer =
++    aAllocator
++      ? ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
++                                     aAllocator->GetCompositorBackendType())
++      : true;
+ 
+-  YCbCrDescriptor descriptor = YCbCrDescriptor(aYSize, aCbCrSize, yOffset, cbOffset,
+-                                               crOffset, aStereoMode, aYUVColorSpace,
++  YCbCrDescriptor descriptor = YCbCrDescriptor(aYSize, aYStride,
++                                               aCbCrSize, aCbCrStride,
++                                               yOffset, cbOffset, crOffset,
++                                               aStereoMode,
++                                               aYUVColorSpace,
++                                               aBitDepth,
+                                                hasIntermediateBuffer);
+ 
+- return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder() : nullptr, descriptor,
+-                       gfx::BackendType::NONE, bufSize, aTextureFlags);
++  return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder()
++                                   : nullptr,
++                        descriptor,
++                        gfx::BackendType::NONE,
++                        bufSize,
++                        aTextureFlags);
+ }
+ 
+ void
+ BufferTextureData::FillInfo(TextureData::Info& aInfo) const
+ {
+   aInfo.size = GetSize();
+   aInfo.format = GetFormat();
+   aInfo.hasSynchronization = false;
+@@ -250,16 +266,22 @@ BufferTextureData::GetCbCrSize() const
+ }
+ 
+ Maybe<YUVColorSpace>
+ BufferTextureData::GetYUVColorSpace() const
+ {
+   return ImageDataSerializer::YUVColorSpaceFromBufferDescriptor(mDescriptor);
+ }
+ 
++Maybe<uint32_t>
++BufferTextureData::GetBitDepth() const
++{
++  return ImageDataSerializer::BitDepthFromBufferDescriptor(mDescriptor);
++}
++
+ Maybe<StereoMode>
+ BufferTextureData::GetStereoMode() const
+ {
+   return ImageDataSerializer::StereoModeFromBufferDescriptor(mDescriptor);
+ }
+ 
+ gfx::SurfaceFormat
+ BufferTextureData::GetFormat() const
+@@ -328,27 +350,27 @@ BufferTextureData::BorrowMappedYCbCrData
+   auto ySize = desc.ySize();
+   auto cbCrSize = desc.cbCrSize();
+ 
+   aMap.stereoMode = desc.stereoMode();
+   aMap.metadata = nullptr;
+ 
+   aMap.y.data = data + desc.yOffset();
+   aMap.y.size = ySize;
+-  aMap.y.stride = ySize.width;
++  aMap.y.stride = desc.yStride();
+   aMap.y.skip = 0;
+ 
+   aMap.cb.data = data + desc.cbOffset();
+   aMap.cb.size = cbCrSize;
+-  aMap.cb.stride = cbCrSize.width;
++  aMap.cb.stride = desc.cbCrStride();
+   aMap.cb.skip = 0;
+ 
+   aMap.cr.data = data + desc.crOffset();
+   aMap.cr.size = cbCrSize;
+-  aMap.cr.stride = cbCrSize.width;
++  aMap.cr.stride = desc.cbCrStride();
+   aMap.cr.skip = 0;
+ 
+   return true;
+ }
+ 
+ bool
+ BufferTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
+ {
+diff --git a/gfx/layers/BufferTexture.h b/gfx/layers/BufferTexture.h
+--- a/gfx/layers/BufferTexture.h
++++ b/gfx/layers/BufferTexture.h
+@@ -26,27 +26,31 @@ public:
+                                    gfx::BackendType aMoz2DBackend,
+                                    LayersBackend aLayersBackend,
+                                    TextureFlags aFlags,
+                                    TextureAllocationFlags aAllocFlags,
+                                    LayersIPCChannel* aAllocator);
+ 
+   static BufferTextureData* CreateForYCbCr(KnowsCompositor* aAllocator,
+                                            gfx::IntSize aYSize,
++                                           uint32_t aYStride,
+                                            gfx::IntSize aCbCrSize,
++                                           uint32_t aCbCrStride,
+                                            StereoMode aStereoMode,
+                                            YUVColorSpace aYUVColorSpace,
++                                           uint32_t aBitDepth,
+                                            TextureFlags aTextureFlags);
+ 
+   // It is generally better to use CreateForYCbCr instead.
+   // This creates a half-initialized texture since we don't know the sizes and
+   // offsets in the buffer.
+   static BufferTextureData* CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
+                                                          int32_t aSize,
+                                                          YUVColorSpace aYUVColorSpace,
++                                                         uint32_t aBitDepth,
+                                                          TextureFlags aTextureFlags);
+ 
+   virtual bool Lock(OpenMode aMode) override { return true; }
+ 
+   virtual void Unlock() override {}
+ 
+   virtual void FillInfo(TextureData::Info& aInfo) const override;
+ 
+@@ -63,16 +67,18 @@ public:
+ 
+   // Don't use this.
+   void SetDesciptor(const BufferDescriptor& aDesc);
+ 
+   Maybe<gfx::IntSize> GetCbCrSize() const;
+ 
+   Maybe<YUVColorSpace> GetYUVColorSpace() const;
+ 
++  Maybe<uint32_t> GetBitDepth() const;
++
+   Maybe<StereoMode> GetStereoMode() const;
+ 
+ protected:
+   gfx::IntSize GetSize() const;
+ 
+   gfx::SurfaceFormat GetFormat() const;
+ 
+   static BufferTextureData* CreateInternal(LayersIPCChannel* aAllocator,
+diff --git a/gfx/layers/Effects.h b/gfx/layers/Effects.h
+--- a/gfx/layers/Effects.h
++++ b/gfx/layers/Effects.h
+@@ -157,24 +157,26 @@ struct EffectRGB : public TexturedEffect
+     : TexturedEffect(EffectTypes::RGB, aTexture, aPremultiplied, aSamplingFilter)
+   {}
+ 
+   virtual const char* Name() { return "EffectRGB"; }
+ };
+ 
+ struct EffectYCbCr : public TexturedEffect
+ {
+-  EffectYCbCr(TextureSource *aSource, YUVColorSpace aYUVColorSpace, gfx::SamplingFilter aSamplingFilter)
++  EffectYCbCr(TextureSource *aSource, YUVColorSpace aYUVColorSpace, uint32_t aBitDepth, gfx::SamplingFilter aSamplingFilter)
+     : TexturedEffect(EffectTypes::YCBCR, aSource, false, aSamplingFilter)
+     , mYUVColorSpace(aYUVColorSpace)
++    , mBitDepth(aBitDepth)
+   {}
+ 
+   virtual const char* Name() { return "EffectYCbCr"; }
+ 
+   YUVColorSpace mYUVColorSpace;
++  uint32_t mBitDepth;
+ };
+ 
+ struct EffectNV12 : public TexturedEffect
+ {
+   EffectNV12(TextureSource *aSource, gfx::SamplingFilter aSamplingFilter)
+     : TexturedEffect(EffectTypes::NV12, aSource, false, aSamplingFilter)
+   {}
+ 
+@@ -266,17 +268,18 @@ CreateTexturedEffect(TextureHost* aHost,
+                      bool isAlphaPremultiplied)
+ {
+   MOZ_ASSERT(aHost);
+   MOZ_ASSERT(aSource);
+ 
+   RefPtr<TexturedEffect> result;
+   if (aHost->GetReadFormat() == gfx::SurfaceFormat::YUV) {
+     MOZ_ASSERT(aHost->GetYUVColorSpace() != YUVColorSpace::UNKNOWN);
+-    result = new EffectYCbCr(aSource, aHost->GetYUVColorSpace(), aSamplingFilter);
++    result = new EffectYCbCr(
++      aSource, aHost->GetYUVColorSpace(), aHost->GetBitDepth(), aSamplingFilter);
+   } else {
+     result = CreateTexturedEffect(aHost->GetReadFormat(),
+                                   aSource,
+                                   aSamplingFilter,
+                                   isAlphaPremultiplied);
+   }
+   return result.forget();
+ }
+diff --git a/gfx/layers/ImageDataSerializer.cpp b/gfx/layers/ImageDataSerializer.cpp
+--- a/gfx/layers/ImageDataSerializer.cpp
++++ b/gfx/layers/ImageDataSerializer.cpp
+@@ -67,28 +67,22 @@ ComputeYCbCrBufferSize(const gfx::IntSiz
+ {
+   MOZ_ASSERT(aYSize.height >= 0 && aYSize.width >= 0);
+ 
+   if (aYSize.height < 0 || aYSize.width < 0 || aCbCrSize.height < 0 || aCbCrSize.width < 0 ||
+       !gfx::Factory::AllowedSurfaceSize(IntSize(aYStride, aYSize.height)) ||
+       !gfx::Factory::AllowedSurfaceSize(IntSize(aCbCrStride, aCbCrSize.height))) {
+     return 0;
+   }
++
+   // Overflow checks are performed in AllowedSurfaceSize
+   return GetAlignedStride<4>(aYSize.height, aYStride) +
+          2 * GetAlignedStride<4>(aCbCrSize.height, aCbCrStride);
+ }
+ 
+-// Minimum required shmem size in bytes
+-uint32_t
+-ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize)
+-{
+-  return ComputeYCbCrBufferSize(aYSize, aYSize.width, aCbCrSize, aCbCrSize.width);
+-}
+-
+ uint32_t
+ ComputeYCbCrBufferSize(const gfx::IntSize& aYSize, const gfx::IntSize& aCbCrSize,
+                        uint32_t aYOffset, uint32_t aCbOffset, uint32_t aCrOffset)
+ {
+   MOZ_ASSERT(aYSize.height >= 0 && aYSize.width >= 0);
+ 
+   int32_t yStride = aYSize.width;
+   int32_t cbCrStride = aCbCrSize.width;
+@@ -168,37 +162,47 @@ Maybe<gfx::IntSize> CbCrSizeFromBufferDe
+       return Some(aDescriptor.get_YCbCrDescriptor().cbCrSize());
+     default:
+       MOZ_CRASH("GFX:  CbCrSizeFromBufferDescriptor");
+   }
+ }
+ 
+ Maybe<YUVColorSpace> YUVColorSpaceFromBufferDescriptor(const BufferDescriptor& aDescriptor)
+ {
+-{
+   switch (aDescriptor.type()) {
+     case BufferDescriptor::TRGBDescriptor:
+       return Nothing();
+     case BufferDescriptor::TYCbCrDescriptor:
+       return Some(aDescriptor.get_YCbCrDescriptor().yUVColorSpace());
+     default:
+-      MOZ_CRASH("GFX:  CbCrSizeFromBufferDescriptor");
++      MOZ_CRASH("GFX:  YUVColorSpaceFromBufferDescriptor");
+   }
+ }
++
++Maybe<uint32_t> BitDepthFromBufferDescriptor(const BufferDescriptor& aDescriptor)
++{
++  switch (aDescriptor.type()) {
++    case BufferDescriptor::TRGBDescriptor:
++      return Nothing();
++    case BufferDescriptor::TYCbCrDescriptor:
++      return Some(aDescriptor.get_YCbCrDescriptor().bitDepth());
++    default:
++      MOZ_CRASH("GFX:  BitDepthFromBufferDescriptor");
++  }
+ }
+ 
+ Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor)
+ {
+   switch (aDescriptor.type()) {
+     case BufferDescriptor::TRGBDescriptor:
+       return Nothing();
+     case BufferDescriptor::TYCbCrDescriptor:
+       return Some(aDescriptor.get_YCbCrDescriptor().stereoMode());
+     default:
+-      MOZ_CRASH("GFX:  CbCrSizeFromBufferDescriptor");
++      MOZ_CRASH("GFX:  StereoModeFromBufferDescriptor");
+   }
+ }
+ 
+ uint8_t* GetYChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor)
+ {
+   return aBuffer + aDescriptor.yOffset();
+ }
+ 
+@@ -211,19 +215,16 @@ uint8_t* GetCrChannel(uint8_t* aBuffer, 
+ {
+   return aBuffer + aDescriptor.crOffset();
+ }
+ 
+ already_AddRefed<DataSourceSurface>
+ DataSourceSurfaceFromYCbCrDescriptor(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor, gfx::DataSourceSurface* aSurface)
+ {
+   gfx::IntSize ySize = aDescriptor.ySize();
+-  gfx::IntSize cbCrSize = aDescriptor.cbCrSize();
+-  int32_t yStride = ySize.width;
+-  int32_t cbCrStride = cbCrSize.width;
+ 
+   RefPtr<DataSourceSurface> result;
+   if (aSurface) {
+     MOZ_ASSERT(aSurface->GetSize() == ySize);
+     MOZ_ASSERT(aSurface->GetFormat() == gfx::SurfaceFormat::B8G8R8X8);
+     if (aSurface->GetSize() == ySize &&
+         aSurface->GetFormat() == gfx::SurfaceFormat::B8G8R8X8) {
+       result = aSurface;
+@@ -240,24 +241,25 @@ DataSourceSurfaceFromYCbCrDescriptor(uin
+ 
+   DataSourceSurface::MappedSurface map;
+   if (NS_WARN_IF(!result->Map(DataSourceSurface::MapType::WRITE, &map))) {
+     return nullptr;
+   }
+ 
+   layers::PlanarYCbCrData ycbcrData;
+   ycbcrData.mYChannel     = GetYChannel(aBuffer, aDescriptor);
+-  ycbcrData.mYStride      = yStride;
++  ycbcrData.mYStride      = aDescriptor.yStride();
+   ycbcrData.mYSize        = ySize;
+   ycbcrData.mCbChannel    = GetCbChannel(aBuffer, aDescriptor);
+   ycbcrData.mCrChannel    = GetCrChannel(aBuffer, aDescriptor);
+-  ycbcrData.mCbCrStride   = cbCrStride;
+-  ycbcrData.mCbCrSize     = cbCrSize;
++  ycbcrData.mCbCrStride   = aDescriptor.cbCrStride();
++  ycbcrData.mCbCrSize     = aDescriptor.cbCrSize();
+   ycbcrData.mPicSize      = ySize;
+   ycbcrData.mYUVColorSpace = aDescriptor.yUVColorSpace();
++  ycbcrData.mBitDepth     = aDescriptor.bitDepth();
+ 
+   gfx::ConvertYCbCrToRGB(ycbcrData,
+                          gfx::SurfaceFormat::B8G8R8X8,
+                          ySize,
+                          map.mData,
+                          map.mStride);
+ 
+   result->Unmap();
+@@ -268,30 +270,27 @@ void
+ ConvertAndScaleFromYCbCrDescriptor(uint8_t* aBuffer,
+                                    const YCbCrDescriptor& aDescriptor,
+                                    const gfx::SurfaceFormat& aDestFormat,
+                                    const gfx::IntSize& aDestSize,
+                                    unsigned char* aDestBuffer,
+                                    int32_t aStride)
+ {
+   MOZ_ASSERT(aBuffer);
+-  gfx::IntSize ySize = aDescriptor.ySize();
+-  gfx::IntSize cbCrSize = aDescriptor.cbCrSize();
+-  int32_t yStride = ySize.width;
+-  int32_t cbCrStride = cbCrSize.width;
+ 
+   layers::PlanarYCbCrData ycbcrData;
+   ycbcrData.mYChannel     = GetYChannel(aBuffer, aDescriptor);
+-  ycbcrData.mYStride      = yStride;
+-  ycbcrData.mYSize        = ySize;
++  ycbcrData.mYStride      = aDescriptor.yStride();;
++  ycbcrData.mYSize        = aDescriptor.ySize();
+   ycbcrData.mCbChannel    = GetCbChannel(aBuffer, aDescriptor);
+   ycbcrData.mCrChannel    = GetCrChannel(aBuffer, aDescriptor);
+-  ycbcrData.mCbCrStride   = cbCrStride;
+-  ycbcrData.mCbCrSize     = cbCrSize;
+-  ycbcrData.mPicSize      = ySize;
++  ycbcrData.mCbCrStride   = aDescriptor.cbCrStride();
++  ycbcrData.mCbCrSize     = aDescriptor.cbCrSize();
++  ycbcrData.mPicSize      = aDescriptor.ySize();
+   ycbcrData.mYUVColorSpace = aDescriptor.yUVColorSpace();
++  ycbcrData.mBitDepth     = aDescriptor.bitDepth();
+ 
+   gfx::ConvertYCbCrToRGB(ycbcrData, aDestFormat, aDestSize, aDestBuffer, aStride);
+ }
+ 
+ } // namespace ImageDataSerializer
+ } // namespace layers
+ } // namespace mozilla
+diff --git a/gfx/layers/ImageDataSerializer.h b/gfx/layers/ImageDataSerializer.h
+--- a/gfx/layers/ImageDataSerializer.h
++++ b/gfx/layers/ImageDataSerializer.h
+@@ -40,18 +40,16 @@ uint32_t ComputeRGBBufferSize(gfx::IntSi
+ ///This function is meant as a helper to know how much shared memory we need
+ ///to allocate in a shmem in order to place a shared YCbCr image blob of
+ ///given dimensions.
+ uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize,
+                                 int32_t aYStride,
+                                 const gfx::IntSize& aCbCrSize,
+                                 int32_t aCbCrStride);
+ uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize,
+-                                const gfx::IntSize& aCbCrSize);
+-uint32_t ComputeYCbCrBufferSize(const gfx::IntSize& aYSize,
+                                 const gfx::IntSize& aCbCrSize,
+                                 uint32_t aYOffset,
+                                 uint32_t aCbOffset,
+                                 uint32_t aCrOffset);
+ uint32_t ComputeYCbCrBufferSize(uint32_t aBufferSize);
+ 
+ void ComputeYCbCrOffsets(int32_t yStride, int32_t yHeight,
+                          int32_t cbCrStride, int32_t cbCrHeight,
+@@ -60,16 +58,19 @@ void ComputeYCbCrOffsets(int32_t yStride
+ gfx::SurfaceFormat FormatFromBufferDescriptor(const BufferDescriptor& aDescriptor);
+ 
+ gfx::IntSize SizeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
+ 
+ Maybe<gfx::IntSize> CbCrSizeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
+ 
+ Maybe<YUVColorSpace> YUVColorSpaceFromBufferDescriptor(const BufferDescriptor& aDescriptor);
+ 
++Maybe<uint32_t> BitDepthFromBufferDescriptor(const BufferDescriptor& aDescriptor);
++
++
+ Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
+ 
+ uint8_t* GetYChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor);
+ 
+ uint8_t* GetCbChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor);
+ 
+ uint8_t* GetCrChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor);
+ 
+diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp
+--- a/gfx/layers/client/ImageClient.cpp
++++ b/gfx/layers/client/ImageClient.cpp
+@@ -97,18 +97,21 @@ ImageClient::CreateTextureClientForImage
+   RefPtr<TextureClient> texture;
+   if (aImage->GetFormat() == ImageFormat::PLANAR_YCBCR) {
+     PlanarYCbCrImage* ycbcr = static_cast<PlanarYCbCrImage*>(aImage);
+     const PlanarYCbCrData* data = ycbcr->GetData();
+     if (!data) {
+       return nullptr;
+     }
+     texture = TextureClient::CreateForYCbCr(aForwarder,
+-                                            data->mYSize, data->mCbCrSize, data->mStereoMode,
++                                            data->mYSize, data->mYStride,
++                                            data->mCbCrSize, data->mCbCrStride,
++                                            data->mStereoMode,
+                                             data->mYUVColorSpace,
++                                            data->mBitDepth,
+                                             TextureFlags::DEFAULT);
+     if (!texture) {
+       return nullptr;
+     }
+ 
+     TextureClientAutoLock autoLock(texture, OpenMode::OPEN_WRITE_ONLY);
+     if (!autoLock.Succeeded()) {
+       return nullptr;
+diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp
+--- a/gfx/layers/client/TextureClient.cpp
++++ b/gfx/layers/client/TextureClient.cpp
+@@ -1253,82 +1253,90 @@ TextureClient::CreateForRawBufferAccess(
+ 
+   return MakeAndAddRef<TextureClient>(texData, aTextureFlags, aAllocator);
+ }
+ 
+ // static
+ already_AddRefed<TextureClient>
+ TextureClient::CreateForYCbCr(KnowsCompositor* aAllocator,
+                               gfx::IntSize aYSize,
++                              uint32_t aYStride,
+                               gfx::IntSize aCbCrSize,
++                              uint32_t aCbCrStride,
+                               StereoMode aStereoMode,
+                               YUVColorSpace aYUVColorSpace,
++                              uint32_t aBitDepth,
+                               TextureFlags aTextureFlags)
+ {
+   if (!aAllocator || !aAllocator->GetLayersIPCActor()->IPCOpen()) {
+     return nullptr;
+   }
+ 
+   if (!gfx::Factory::AllowedSurfaceSize(aYSize)) {
+     return nullptr;
+   }
+ 
+-  TextureData* data = BufferTextureData::CreateForYCbCr(aAllocator, aYSize, aCbCrSize,
+-                                                        aStereoMode, aYUVColorSpace,
+-                                                        aTextureFlags);
++  TextureData* data =
++    BufferTextureData::CreateForYCbCr(aAllocator,
++                                      aYSize, aYStride,
++                                      aCbCrSize, aCbCrStride,
++                                      aStereoMode, aYUVColorSpace,
++                                      aBitDepth, aTextureFlags);
+   if (!data) {
+     return nullptr;
+   }
+ 
+   return MakeAndAddRef<TextureClient>(data, aTextureFlags,
+                                       aAllocator->GetTextureForwarder());
+ }
+ 
+ // static
+ already_AddRefed<TextureClient>
+ TextureClient::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
+                                             size_t aSize,
+                                             YUVColorSpace aYUVColorSpace,
++                                            uint32_t aBitDepth,
+                                             TextureFlags aTextureFlags)
+ {
+   if (!aAllocator || !aAllocator->GetLayersIPCActor()->IPCOpen()) {
+     return nullptr;
+   }
+ 
+-  TextureData* data =
+-    BufferTextureData::CreateForYCbCrWithBufferSize(aAllocator, aSize, aYUVColorSpace,
+-                                                    aTextureFlags);
++  TextureData* data = BufferTextureData::CreateForYCbCrWithBufferSize(
++    aAllocator, aSize, aYUVColorSpace, aBitDepth, aTextureFlags);
+   if (!data) {
+     return nullptr;
+   }
+ 
+   return MakeAndAddRef<TextureClient>(data, aTextureFlags,
+                                       aAllocator->GetTextureForwarder());
+ }
+ 
+-TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, LayersIPCChannel* aAllocator)
+-: AtomicRefCountedWithFinalize("TextureClient")
+-, mAllocator(aAllocator)
+-, mActor(nullptr)
+-, mData(aData)
+-, mFlags(aFlags)
+-, mOpenMode(OpenMode::OPEN_NONE)
++TextureClient::TextureClient(TextureData* aData,
++                             TextureFlags aFlags,
++                             LayersIPCChannel* aAllocator)
++  : AtomicRefCountedWithFinalize("TextureClient")
++  , mAllocator(aAllocator)
++  , mActor(nullptr)
++  , mData(aData)
++  , mFlags(aFlags)
++  , mOpenMode(OpenMode::OPEN_NONE)
+ #ifdef DEBUG
+-, mExpectedDtRefs(0)
++  , mExpectedDtRefs(0)
+ #endif
+-, mIsLocked(false)
+-, mIsReadLocked(false)
+-, mUpdated(false)
+-, mAddedToCompositableClient(false)
+-, mWorkaroundAnnoyingSharedSurfaceLifetimeIssues(false)
+-, mWorkaroundAnnoyingSharedSurfaceOwnershipIssues(false)
+-, mFwdTransactionId(0)
+-, mSerial(++sSerialCounter)
++  , mIsLocked(false)
++  , mIsReadLocked(false)
++  , mUpdated(false)
++  , mAddedToCompositableClient(false)
++  , mWorkaroundAnnoyingSharedSurfaceLifetimeIssues(false)
++  , mWorkaroundAnnoyingSharedSurfaceOwnershipIssues(false)
++  , mFwdTransactionId(0)
++  , mSerial(++sSerialCounter)
+ #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL
+-, mPoolTracker(nullptr)
++  , mPoolTracker(nullptr)
+ #endif
+ {
+   mData->FillInfo(mInfo);
+   mFlags |= mData->GetTextureFlags();
+ }
+ 
+ bool TextureClient::CopyToTextureClient(TextureClient* aTarget,
+                                         const gfx::IntRect* aRect,
+@@ -1754,24 +1762,28 @@ UpdateYCbCrTextureClient(TextureClient* 
+     return false;
+   }
+ 
+   MappedYCbCrTextureData srcData;
+   srcData.y.data = aData.mYChannel;
+   srcData.y.size = aData.mYSize;
+   srcData.y.stride = aData.mYStride;
+   srcData.y.skip = aData.mYSkip;
++  MOZ_ASSERT(aData.mBitDepth == 8 || (aData.mBitDepth > 8 && aData.mBitDepth <= 16));
++  srcData.y.bytesPerPixel = (aData.mBitDepth > 8) ? 2 : 1;
+   srcData.cb.data = aData.mCbChannel;
+   srcData.cb.size = aData.mCbCrSize;
+   srcData.cb.stride = aData.mCbCrStride;
+   srcData.cb.skip = aData.mCbSkip;
++  srcData.cb.bytesPerPixel = (aData.mBitDepth > 8) ? 2 : 1;
+   srcData.cr.data = aData.mCrChannel;
+   srcData.cr.size = aData.mCbCrSize;
+   srcData.cr.stride = aData.mCbCrStride;
+   srcData.cr.skip = aData.mCrSkip;
++  srcData.cr.bytesPerPixel = (aData.mBitDepth > 8) ? 2 : 1;
+   srcData.metadata = nullptr;
+ 
+   if (!srcData.CopyInto(mapped)) {
+     NS_WARNING("Failed to copy image data!");
+     return false;
+   }
+ 
+   if (TextureRequiresLocking(aTexture->GetFlags())) {
+@@ -1806,25 +1818,29 @@ MappedYCbCrChannelData::CopyInto(MappedY
+     return true;
+   }
+ 
+   for (int32_t i = 0; i < size.height; ++i) {
+     if (aDst.skip == 0 && skip == 0) {
+       // fast-ish path
+       memcpy(aDst.data + i * aDst.stride,
+              data + i * stride,
+-             size.width);
++             size.width * bytesPerPixel);
+     } else {
+       // slow path
+       uint8_t* src = data + i * stride;
+       uint8_t* dst = aDst.data + i * aDst.stride;
+       for (int32_t j = 0; j < size.width; ++j) {
+-        *dst = *src;
+-        src += 1 + skip;
+-        dst += 1 + aDst.skip;
++        for (uint32_t k = 0; k < bytesPerPixel; ++k) {
++          *dst = *src;
++          src += 1;
++          dst += 1;
++        }
++        src += skip;
++        dst += aDst.skip;
+       }
+     }
+   }
+   return true;
+ }
+ 
+ } // namespace layers
+ } // namespace mozilla
+diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h
+--- a/gfx/layers/client/TextureClient.h
++++ b/gfx/layers/client/TextureClient.h
+@@ -135,16 +135,17 @@ struct MappedTextureData
+ };
+ 
+ struct MappedYCbCrChannelData
+ {
+   uint8_t* data;
+   gfx::IntSize size;
+   int32_t stride;
+   int32_t skip;
++  uint32_t bytesPerPixel;
+ 
+   bool CopyInto(MappedYCbCrChannelData& aDst);
+ };
+ 
+ struct MappedYCbCrTextureData {
+   MappedYCbCrChannelData y;
+   MappedYCbCrChannelData cb;
+   MappedYCbCrChannelData cr;
+@@ -343,19 +344,22 @@ public:
+                     BackendSelector aSelector,
+                     TextureFlags aTextureFlags,
+                     TextureAllocationFlags aAllocFlags);
+ 
+   // Creates and allocates a TextureClient supporting the YCbCr format.
+   static already_AddRefed<TextureClient>
+   CreateForYCbCr(KnowsCompositor* aAllocator,
+                  gfx::IntSize aYSize,
++                 uint32_t aYStride,
+                  gfx::IntSize aCbCrSize,
++                 uint32_t aCbCrStride,
+                  StereoMode aStereoMode,
+                  YUVColorSpace aYUVColorSpace,
++                 uint32_t aBitDepth,
+                  TextureFlags aTextureFlags);
+ 
+   // Creates and allocates a TextureClient (can be accessed through raw
+   // pointers).
+   static already_AddRefed<TextureClient>
+   CreateForRawBufferAccess(KnowsCompositor* aAllocator,
+                            gfx::SurfaceFormat aFormat,
+                            gfx::IntSize aSize,
+@@ -365,16 +369,17 @@ public:
+ 
+   // Creates and allocates a TextureClient (can beaccessed through raw
+   // pointers) with a certain buffer size. It's unfortunate that we need this.
+   // providing format and sizes could let us do more optimization.
+   static already_AddRefed<TextureClient>
+   CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
+                                size_t aSize,
+                                YUVColorSpace aYUVColorSpace,
++                               uint32_t aBitDepth,
+                                TextureFlags aTextureFlags);
+ 
+   // Creates and allocates a TextureClient of the same type.
+   already_AddRefed<TextureClient>
+   CreateSimilar(LayersBackend aLayersBackend = LayersBackend::LAYERS_NONE,
+                 TextureFlags aFlags = TextureFlags::DEFAULT,
+                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const;
+ 
+diff --git a/gfx/layers/client/TextureClientRecycleAllocator.cpp b/gfx/layers/client/TextureClientRecycleAllocator.cpp
+--- a/gfx/layers/client/TextureClientRecycleAllocator.cpp
++++ b/gfx/layers/client/TextureClientRecycleAllocator.cpp
+@@ -104,30 +104,34 @@ YCbCrTextureClientAllocationHelper::IsCo
+ 
+   BufferTextureData* bufferData = aTextureClient->GetInternalData()->AsBufferTextureData();
+   if (!bufferData ||
+       aTextureClient->GetSize() != mData.mYSize ||
+       bufferData->GetCbCrSize().isNothing() ||
+       bufferData->GetCbCrSize().ref() != mData.mCbCrSize ||
+       bufferData->GetYUVColorSpace().isNothing() ||
+       bufferData->GetYUVColorSpace().ref() != mData.mYUVColorSpace ||
++      bufferData->GetBitDepth().isNothing() ||
++      bufferData->GetBitDepth().ref() != mData.mBitDepth ||
+       bufferData->GetStereoMode().isNothing() ||
+       bufferData->GetStereoMode().ref() != mData.mStereoMode) {
+     return false;
+   }
+   return true;
+ }
+ 
+ already_AddRefed<TextureClient>
+ YCbCrTextureClientAllocationHelper::Allocate(KnowsCompositor* aAllocator)
+ {
+   return TextureClient::CreateForYCbCr(aAllocator,
+-                                       mData.mYSize, mData.mCbCrSize,
++                                       mData.mYSize, mData.mYStride,
++                                       mData.mCbCrSize, mData.mCbCrStride,
+                                        mData.mStereoMode,
+                                        mData.mYUVColorSpace,
++                                       mData.mBitDepth,
+                                        mTextureFlags);
+ }
+ 
+ TextureClientRecycleAllocator::TextureClientRecycleAllocator(KnowsCompositor* aAllocator)
+   : mSurfaceAllocator(aAllocator)
+   , mMaxPooledSize(kMaxPooledSized)
+   , mLock("TextureClientRecycleAllocatorImp.mLock")
+   , mIsDestroyed(false)
+diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp
+--- a/gfx/layers/composite/TextureHost.cpp
++++ b/gfx/layers/composite/TextureHost.cpp
+@@ -485,17 +485,17 @@ TextureSource::~TextureSource()
+ }
+ 
+ const char*
+ TextureSource::Name() const
+ {
+   MOZ_CRASH("GFX: TextureSource without class name");
+   return "TextureSource";
+ }
+-  
++
+ BufferTextureHost::BufferTextureHost(const BufferDescriptor& aDesc,
+                                      TextureFlags aFlags)
+ : TextureHost(aFlags)
+ , mUpdateSerial(1)
+ , mLocked(false)
+ , mNeedsFullUpdate(false)
+ {
+   mDescriptor = aDesc;
+@@ -934,16 +934,26 @@ BufferTextureHost::GetYUVColorSpace() co
+ {
+   if (mFormat == gfx::SurfaceFormat::YUV) {
+     const YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
+     return desc.yUVColorSpace();
+   }
+   return YUVColorSpace::UNKNOWN;
+ }
+ 
++uint32_t
++BufferTextureHost::GetBitDepth() const
++{
++  if (mFormat == gfx::SurfaceFormat::YUV) {
++    const YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
++    return desc.bitDepth();
++  }
++  return 8;
++}
++
+ bool
+ BufferTextureHost::UploadIfNeeded()
+ {
+   return MaybeUpload(!mNeedsFullUpdate ? &mMaybeUpdatedRegion : nullptr);
+ }
+ 
+ bool
+ BufferTextureHost::MaybeUpload(nsIntRegion *aRegion)
+@@ -1039,29 +1049,29 @@ BufferTextureHost::Upload(nsIntRegion *a
+       MOZ_ASSERT(mFirstSource->GetNextSibling()->GetNextSibling());
+       srcY = mFirstSource;
+       srcU = mFirstSource->GetNextSibling()->AsDataTextureSource();
+       srcV = mFirstSource->GetNextSibling()->GetNextSibling()->AsDataTextureSource();
+     }
+ 
+     RefPtr<gfx::DataSourceSurface> tempY =
+       gfx::Factory::CreateWrappingDataSourceSurface(ImageDataSerializer::GetYChannel(buf, desc),
+-                                                    desc.ySize().width,
++                                                    desc.yStride(),
+                                                     desc.ySize(),
+-                                                    gfx::SurfaceFormat::A8);
++                                                    SurfaceFormatForAlphaBitDepth(desc.bitDepth()));
+     RefPtr<gfx::DataSourceSurface> tempCb =
+       gfx::Factory::CreateWrappingDataSourceSurface(ImageDataSerializer::GetCbChannel(buf, desc),
+-                                                    desc.cbCrSize().width,
++                                                    desc.cbCrStride(),
+                                                     desc.cbCrSize(),
+-                                                    gfx::SurfaceFormat::A8);
++                                                    SurfaceFormatForAlphaBitDepth(desc.bitDepth()));
+     RefPtr<gfx::DataSourceSurface> tempCr =
+       gfx::Factory::CreateWrappingDataSourceSurface(ImageDataSerializer::GetCrChannel(buf, desc),
+-                                                    desc.cbCrSize().width,
++                                                    desc.cbCrStride(),
+                                                     desc.cbCrSize(),
+-                                                    gfx::SurfaceFormat::A8);
++                                                    SurfaceFormatForAlphaBitDepth(desc.bitDepth()));
+     // We don't support partial updates for Y U V textures
+     NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures");
+     if (!tempY ||
+         !tempCb ||
+         !tempCr ||
+         !srcY->Update(tempY) ||
+         !srcU->Update(tempCb) ||
+         !srcV->Update(tempCr)) {
+diff --git a/gfx/layers/composite/TextureHost.h b/gfx/layers/composite/TextureHost.h
+--- a/gfx/layers/composite/TextureHost.h
++++ b/gfx/layers/composite/TextureHost.h
+@@ -435,16 +435,21 @@ public:
+    * Return the format used for reading the texture.
+    * Apple's YCBCR_422 is R8G8B8X8.
+    */
+   virtual gfx::SurfaceFormat GetReadFormat() const { return GetFormat(); }
+ 
+   virtual YUVColorSpace GetYUVColorSpace() const { return YUVColorSpace::UNKNOWN; }
+ 
+   /**
++   * Return the bit depth of the image. Used with YUV textures.
++   */
++  virtual uint32_t GetBitDepth() const { return 8; }
++
++  /**
+    * Called during the transaction. The TextureSource may or may not be composited.
+    *
+    * Note that this is called outside of lock/unlock.
+    */
+   virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) {}
+ 
+   /**
+    * Called at composition time, just before compositing the TextureSource composited.
+@@ -731,16 +736,18 @@ public:
+    *
+    * If the shared format is YCbCr and the compositor does not support it,
+    * GetFormat will be RGB32 (even though mFormat is SurfaceFormat::YUV).
+    */
+   virtual gfx::SurfaceFormat GetFormat() const override;
+ 
+   virtual YUVColorSpace GetYUVColorSpace() const override;
+ 
++  virtual uint32_t GetBitDepth() const override;
++
+   virtual gfx::IntSize GetSize() const override { return mSize; }
+ 
+   virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
+ 
+   virtual bool HasIntermediateBuffer() const override { return mHasIntermediateBuffer; }
+ 
+   virtual BufferTextureHost* AsBufferTextureHost() override { return this; }
+ 
+diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces.ipdlh
+--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
++++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
+@@ -95,22 +95,25 @@ struct SurfaceDescriptorGPUVideo {
+ struct RGBDescriptor {
+   IntSize size;
+   SurfaceFormat format;
+   bool hasIntermediateBuffer;
+ };
+ 
+ struct YCbCrDescriptor {
+   IntSize ySize;
++  uint32_t yStride;
+   IntSize cbCrSize;
++  uint32_t cbCrStride;
+   uint32_t yOffset;
+   uint32_t cbOffset;
+   uint32_t crOffset;
+   StereoMode stereoMode;
+   YUVColorSpace yUVColorSpace;
++  uint32_t bitDepth;
+   bool hasIntermediateBuffer;
+ };
+ 
+ union BufferDescriptor {
+   RGBDescriptor;
+   YCbCrDescriptor;
+ };
+ 
+diff --git a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
+--- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
++++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
+@@ -117,23 +117,31 @@ SharedPlanarYCbCrImage::AdoptData(const 
+   mOrigin = gfx::IntPoint(aData.mPicX, aData.mPicY);
+ 
+   uint8_t *base = GetBuffer();
+   uint32_t yOffset = aData.mYChannel - base;
+   uint32_t cbOffset = aData.mCbChannel - base;
+   uint32_t crOffset = aData.mCrChannel - base;
+ 
+   auto fwd = mCompositable->GetForwarder();
+-  bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(gfx::SurfaceFormat::YUV,
+-                                                            fwd->GetCompositorBackendType());
++  bool hasIntermediateBuffer = ComputeHasIntermediateBuffer(
++    gfx::SurfaceFormat::YUV, fwd->GetCompositorBackendType());
+ 
+-  static_cast<BufferTextureData*>(mTextureClient->GetInternalData())->SetDesciptor(
+-    YCbCrDescriptor(aData.mYSize, aData.mCbCrSize, yOffset, cbOffset, crOffset,
+-                    aData.mStereoMode, aData.mYUVColorSpace, hasIntermediateBuffer)
+-  );
++  static_cast<BufferTextureData*>(mTextureClient->GetInternalData())
++    ->SetDesciptor(YCbCrDescriptor(aData.mYSize,
++                                   aData.mYStride,
++                                   aData.mCbCrSize,
++                                   aData.mCbCrStride,
++                                   yOffset,
++                                   cbOffset,
++                                   crOffset,
++                                   aData.mStereoMode,
++                                   aData.mYUVColorSpace,
++                                   aData.mBitDepth,
++                                   hasIntermediateBuffer));
+ 
+   return true;
+ }
+ 
+ bool
+ SharedPlanarYCbCrImage::IsValid() {
+   return mTextureClient && mTextureClient->IsValid();
+ }
+@@ -179,28 +187,30 @@ SharedPlanarYCbCrImage::Allocate(PlanarY
+   mData.mCrChannel = aData.mCrChannel;
+   mData.mYSize = aData.mYSize;
+   mData.mCbCrSize = aData.mCbCrSize;
+   mData.mPicX = aData.mPicX;
+   mData.mPicY = aData.mPicY;
+   mData.mPicSize = aData.mPicSize;
+   mData.mStereoMode = aData.mStereoMode;
+   mData.mYUVColorSpace = aData.mYUVColorSpace;
++  mData.mBitDepth = aData.mBitDepth;
+   // those members are not always equal to aData's, due to potentially different
+   // packing.
+   mData.mYSkip = 0;
+   mData.mCbSkip = 0;
+   mData.mCrSkip = 0;
+-  mData.mYStride = mData.mYSize.width;
+-  mData.mCbCrStride = mData.mCbCrSize.width;
++  mData.mYStride = aData.mYStride;
++  mData.mCbCrStride = aData.mCbCrStride;
+ 
+   // do not set mBuffer like in PlanarYCbCrImage because the later
+   // will try to manage this memory without knowing it belongs to a
+   // shmem.
+-  mBufferSize = ImageDataSerializer::ComputeYCbCrBufferSize(mData.mYSize, mData.mCbCrSize);
++  mBufferSize = ImageDataSerializer::ComputeYCbCrBufferSize(
++    mData.mYSize, mData.mYStride, mData.mCbCrSize, mData.mCbCrStride);
+   mSize = mData.mPicSize;
+   mOrigin = gfx::IntPoint(aData.mPicX, aData.mPicY);
+ 
+   mTextureClient->Unlock();
+ 
+   return mBufferSize > 0;
+ }
+ 
+diff --git a/gfx/tests/gtest/TestTextures.cpp b/gfx/tests/gtest/TestTextures.cpp
+--- a/gfx/tests/gtest/TestTextures.cpp
++++ b/gfx/tests/gtest/TestTextures.cpp
+@@ -261,16 +261,17 @@ TEST(Layers, TextureYCbCrSerialization) 
+   clientData.mCrChannel = crSurface->Data();
+   clientData.mYSize = ySurface->GetSize();
+   clientData.mPicSize = ySurface->GetSize();
+   clientData.mCbCrSize = cbSurface->GetSize();
+   clientData.mYStride = ySurface->Stride();
+   clientData.mCbCrStride = cbSurface->Stride();
+   clientData.mStereoMode = StereoMode::MONO;
+   clientData.mYUVColorSpace = YUVColorSpace::BT601;
++  clientData.mBitDepth = 8;
+   clientData.mYSkip = 0;
+   clientData.mCbSkip = 0;
+   clientData.mCrSkip = 0;
+   clientData.mCrSkip = 0;
+   clientData.mPicX = 0;
+   clientData.mPicX = 0;
+ 
+   uint32_t namespaceId = 1;
+@@ -289,16 +290,16 @@ TEST(Layers, TextureYCbCrSerialization) 
+     retry--;
+   }
+ 
+   // Skip this testing if IPDL connection is not ready
+   if (!retry && !imageBridge->IPCOpen()) {
+     return;
+   }
+ 
+-  RefPtr<TextureClient> client = TextureClient::CreateForYCbCr(imageBridge, clientData.mYSize, clientData.mCbCrSize,
++  RefPtr<TextureClient> client = TextureClient::CreateForYCbCr(imageBridge, clientData.mYSize, clientData.mYStride, clientData.mCbCrSize, clientData.mCbCrStride,
+                                                                StereoMode::MONO, YUVColorSpace::BT601,
+-                                                               TextureFlags::DEALLOCATE_CLIENT);
++                                                               8, TextureFlags::DEALLOCATE_CLIENT);
+ 
+   TestTextureClientYCbCr(client, clientData);
+ 
+   // XXX - Test more texture client types.
+ }
+diff --git a/gfx/tests/gtest/TextureHelper.h b/gfx/tests/gtest/TextureHelper.h
+--- a/gfx/tests/gtest/TextureHelper.h
++++ b/gfx/tests/gtest/TextureHelper.h
+@@ -57,19 +57,24 @@ CreateYCbCrTextureClientWithBackend(Laye
+   clientData.mCbSkip = 0;
+   clientData.mCrSkip = 0;
+   clientData.mCrSkip = 0;
+   clientData.mPicX = 0;
+   clientData.mPicX = 0;
+ 
+   // Create YCbCrTexture for basice backend.
+   if (aLayersBackend == LayersBackend::LAYERS_BASIC) {
+-    return TextureClient::CreateForYCbCr(nullptr, clientData.mYSize,
+-                                         clientData.mCbCrSize, StereoMode::MONO,
++    return TextureClient::CreateForYCbCr(nullptr,
++                                         clientData.mYSize,
++                                         clientData.mYStride,
++                                         clientData.mCbCrSize,
++                                         clientData.mCbCrStride,
++                                         StereoMode::MONO,
+                                          YUVColorSpace::BT601,
++                                         8,
+                                          TextureFlags::DEALLOCATE_CLIENT);
+   }
+ 
+ #ifdef XP_WIN
+   RefPtr<ID3D11Device> device = DeviceManagerDx::Get()->GetContentDevice();
+ 
+   if (device && aLayersBackend == LayersBackend::LAYERS_D3D11) {
+     // Create YCbCrD3D11TextureData

+ 42 - 0
rel-253/libdav1d/patches/1215089-8-59a1.patch

@@ -0,0 +1,42 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1506713990 -7200
+# Node ID 073ff4644573a77a071e158bf88ab1c6a8713ab3
+# Parent  b55e89b5df041a28c7bf34d6896224a7e2d94929
+Bug 1215089 - P8: Only enable 10/12 bits videos with software compositor. r=mattwoodrow
+
+MozReview-Commit-ID: 2tdeH2kdZ3P
+
+diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
++++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+@@ -294,16 +294,28 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(
+ 
+   if (!decoded) {
+     if (aGotFrame) {
+       *aGotFrame = false;
+     }
+     return NS_OK;
+   }
+ 
++  if ((mCodecContext->pix_fmt == AV_PIX_FMT_YUV420P10LE ||
++       mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P10LE
++#if LIBAVCODEC_VERSION_MAJOR >= 57
++       || mCodecContext->pix_fmt == AV_PIX_FMT_YUV444P12LE
++#endif
++       ) &&
++      (!mImageAllocator || mImageAllocator->GetCompositorBackendType()
++                           != layers::LayersBackend::LAYERS_BASIC)) {
++    return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
++                       RESULT_DETAIL("unsupported format type (hdr)"));
++  }
++
+   // If we've decoded a frame then we need to output it
+   int64_t pts = mPtsContext.GuessCorrectPts(mFrame->pkt_pts, mFrame->pkt_dts);
+   // Retrieve duration from dts.
+   // We use the first entry found matching this dts (this is done to
+   // handle damaged file with multiple frames with the same dts)
+ 
+   int64_t duration;
+   if (!mDurationMap.Find(mFrame->pkt_dts, duration)) {
+

+ 238 - 0
rel-253/libdav1d/patches/1215089-9-59a1.patch

@@ -0,0 +1,238 @@
+# HG changeset patch
+# User Jean-Yves Avenard <jyavenard@mozilla.com>
+# Date 1506714689 -7200
+# Node ID 6c08410e3a753413da781b426db13d2296749a91
+# Parent  073ff4644573a77a071e158bf88ab1c6a8713ab3
+Bug 1215089 - P9: Add support for 10/12 bits YUV surface with OpenGL compositor. r=mattwoodrow
+
+MozReview-Commit-ID: BR9G7cyopz0
+
+diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp
+--- a/gfx/gl/GLContext.cpp
++++ b/gfx/gl/GLContext.cpp
+@@ -3012,17 +3012,18 @@ GetBytesPerTexel(GLenum format, GLenum t
+             case LOCAL_GL_RGBA:
+             case LOCAL_GL_BGRA_EXT:
+                 return 4 * multiplier;
+             default:
+                 break;
+         }
+     } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
+                type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
+-               type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
++               type == LOCAL_GL_UNSIGNED_SHORT_5_6_5 ||
++               type == LOCAL_GL_UNSIGNED_SHORT)
+     {
+         return 2;
+     }
+ 
+     gfxCriticalError() << "Unknown texture type " << type << " or format " << format;
+     return 0;
+ }
+ 
+diff --git a/gfx/gl/GLUploadHelpers.cpp b/gfx/gl/GLUploadHelpers.cpp
+--- a/gfx/gl/GLUploadHelpers.cpp
++++ b/gfx/gl/GLUploadHelpers.cpp
+@@ -459,16 +459,24 @@ UploadImageDataToTexture(GLContext* gl,
+             surfaceFormat = SurfaceFormat::R5G6B5_UINT16;
+             break;
+         case SurfaceFormat::A8:
+             internalFormat = format = LOCAL_GL_LUMINANCE;
+             type = LOCAL_GL_UNSIGNED_BYTE;
+             // We don't have a specific luminance shader
+             surfaceFormat = SurfaceFormat::A8;
+             break;
++        case SurfaceFormat::A16:
++            format = LOCAL_GL_LUMINANCE;
++            internalFormat = LOCAL_GL_LUMINANCE16;
++            type = LOCAL_GL_UNSIGNED_SHORT;
++            // We don't have a specific luminance shader
++            surfaceFormat = SurfaceFormat::A8;
++            pixelSize = 2;
++            break;
+         default:
+             NS_ASSERTION(false, "Unhandled image surface format!");
+     }
+ 
+     if (aOutUploadSize) {
+         *aOutUploadSize = 0;
+     }
+ 
+diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp
+--- a/gfx/layers/opengl/CompositorOGL.cpp
++++ b/gfx/layers/opengl/CompositorOGL.cpp
+@@ -827,18 +827,28 @@ CompositorOGL::GetShaderConfigFor(Effect
+ {
+   ShaderConfigOGL config;
+ 
+   switch(aEffect->mType) {
+   case EffectTypes::SOLID_COLOR:
+     config.SetRenderColor(true);
+     break;
+   case EffectTypes::YCBCR:
++  {
+     config.SetYCbCr(true);
++    EffectYCbCr* effectYCbCr =
++      static_cast<EffectYCbCr*>(aEffect);
++    uint32_t pixelBits = (8 * BytesPerPixel(SurfaceFormatForAlphaBitDepth(effectYCbCr->mBitDepth)));
++    uint32_t paddingBits = pixelBits - effectYCbCr->mBitDepth;
++    // OpenGL expects values between [0,255], this range needs to be adjusted
++    // according to the bit depth.
++    // So we will scale the YUV values by this amount.
++    config.SetColorMultiplier(pow(2, paddingBits));
+     break;
++  }
+   case EffectTypes::NV12:
+     config.SetNV12(true);
+     config.SetTextureTarget(LOCAL_GL_TEXTURE_RECTANGLE_ARB);
+     break;
+   case EffectTypes::COMPONENT_ALPHA:
+   {
+     config.SetComponentAlpha(true);
+     EffectComponentAlpha* effectComponentAlpha =
+diff --git a/gfx/layers/opengl/OGLShaderProgram.cpp b/gfx/layers/opengl/OGLShaderProgram.cpp
+--- a/gfx/layers/opengl/OGLShaderProgram.cpp
++++ b/gfx/layers/opengl/OGLShaderProgram.cpp
+@@ -110,16 +110,23 @@ ShaderConfigOGL::SetOpacity(bool aEnable
+ void
+ ShaderConfigOGL::SetYCbCr(bool aEnabled)
+ {
+   SetFeature(ENABLE_TEXTURE_YCBCR, aEnabled);
+   MOZ_ASSERT(!(mFeatures & ENABLE_TEXTURE_NV12));
+ }
+ 
+ void
++ShaderConfigOGL::SetColorMultiplier(uint32_t aMultiplier)
++{
++  MOZ_ASSERT(mFeatures & ENABLE_TEXTURE_YCBCR, "Multiplier only supported with YCbCr!");
++  mMultiplier = aMultiplier;
++}
++
++void
+ ShaderConfigOGL::SetNV12(bool aEnabled)
+ {
+   SetFeature(ENABLE_TEXTURE_NV12, aEnabled);
+   MOZ_ASSERT(!(mFeatures & ENABLE_TEXTURE_YCBCR));
+ }
+ 
+ void
+ ShaderConfigOGL::SetComponentAlpha(bool aEnabled)
+@@ -436,21 +443,22 @@ ProgramProfileOGL::GetProfileFor(ShaderC
+           fs << "  COLOR_PRECISION float cb = " << texture2D << "(uCbTexture, coord * uCbCrTexCoordMultiplier).r;" << endl;
+           fs << "  COLOR_PRECISION float cr = " << texture2D << "(uCbTexture, coord * uCbCrTexCoordMultiplier).a;" << endl;
+         } else {
+           fs << "  COLOR_PRECISION float y = " << texture2D << "(uYTexture, coord).r;" << endl;
+           fs << "  COLOR_PRECISION float cb = " << texture2D << "(uCbTexture, coord).r;" << endl;
+           fs << "  COLOR_PRECISION float cr = " << texture2D << "(uCbTexture, coord).a;" << endl;
+         }
+       }
+-
+-      fs << "  y = y - 0.06275;" << endl;
+-      fs << "  cb = cb - 0.50196;" << endl;
+-      fs << "  cr = cr - 0.50196;" << endl;
+       fs << "  vec3 yuv = vec3(y, cb, cr);" << endl;
++      if (aConfig.mMultiplier != 1) {
++        fs << "  yuv *= " << aConfig.mMultiplier << ".0;" << endl;
++      }
++      fs << "  vec3 coeff = vec3(0.06275, 0.50196, 0.50196 );" << endl;
++      fs << "  yuv -= coeff;" << endl;
+       fs << "  color.rgb = uYuvColorMatrix * yuv;" << endl;
+       fs << "  color.a = 1.0;" << endl;
+     } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) {
+       if (aConfig.mFeatures & ENABLE_TEXTURE_RECT) {
+         fs << "  COLOR_PRECISION vec3 onBlack = " << texture2D << "(uBlackTexture, coord * uTexCoordMultiplier).rgb;" << endl;
+         fs << "  COLOR_PRECISION vec3 onWhite = " << texture2D << "(uWhiteTexture, coord * uTexCoordMultiplier).rgb;" << endl;
+       } else {
+         fs << "  COLOR_PRECISION vec3 onBlack = " << texture2D << "(uBlackTexture, coord).rgb;" << endl;
+diff --git a/gfx/layers/opengl/OGLShaderProgram.h b/gfx/layers/opengl/OGLShaderProgram.h
+--- a/gfx/layers/opengl/OGLShaderProgram.h
++++ b/gfx/layers/opengl/OGLShaderProgram.h
+@@ -207,52 +207,61 @@ public:
+     float f1;
+     float f16v[16];
+   } mValue;
+ };
+ 
+ class ShaderConfigOGL
+ {
+ public:
+-  ShaderConfigOGL() :
+-    mFeatures(0),
+-    mCompositionOp(gfx::CompositionOp::OP_OVER)
+-  {}
++  ShaderConfigOGL()
++    : mFeatures(0)
++    , mMultiplier(1)
++    , mCompositionOp(gfx::CompositionOp::OP_OVER)
++  {
++  }
+ 
+   void SetRenderColor(bool aEnabled);
+   void SetTextureTarget(GLenum aTarget);
+   void SetRBSwap(bool aEnabled);
+   void SetNoAlpha(bool aEnabled);
+   void SetOpacity(bool aEnabled);
+   void SetYCbCr(bool aEnabled);
+   void SetNV12(bool aEnabled);
+   void SetComponentAlpha(bool aEnabled);
+   void SetColorMatrix(bool aEnabled);
+   void SetBlur(bool aEnabled);
+   void SetMask(bool aEnabled);
+   void SetDEAA(bool aEnabled);
+   void SetCompositionOp(gfx::CompositionOp aOp);
+   void SetNoPremultipliedAlpha();
+   void SetDynamicGeometry(bool aEnabled);
++  void SetColorMultiplier(uint32_t aMultiplier);
+ 
+-  bool operator< (const ShaderConfigOGL& other) const {
++  bool operator< (const ShaderConfigOGL& other) const
++  {
+     return mFeatures < other.mFeatures ||
+            (mFeatures == other.mFeatures &&
+-            (int)mCompositionOp < (int)other.mCompositionOp);
++            (int)mCompositionOp < (int)other.mCompositionOp) ||
++           (mFeatures == other.mFeatures &&
++            (int)mCompositionOp == (int)other.mCompositionOp &&
++            mMultiplier < other.mMultiplier);
+   }
+ 
+ public:
+-  void SetFeature(int aBitmask, bool aState) {
++  void SetFeature(int aBitmask, bool aState)
++  {
+     if (aState)
+       mFeatures |= aBitmask;
+     else
+       mFeatures &= (~aBitmask);
+   }
+ 
+   int mFeatures;
++  uint32_t mMultiplier;
+   gfx::CompositionOp mCompositionOp;
+ };
+ 
+ static inline ShaderConfigOGL
+ ShaderConfigFromTargetAndFormat(GLenum aTarget,
+                                 gfx::SurfaceFormat aFormat)
+ {
+   ShaderConfigOGL config;
+@@ -394,17 +403,17 @@ public:
+   void SetTextureTransform(const gfx::Matrix4x4& aMatrix) {
+     SetMatrixUniform(KnownUniform::TextureTransform, aMatrix);
+   }
+ 
+   void SetTextureRects(const gfx::Rect* aRects) {
+     float vals[16] = { aRects[0].x, aRects[0].y, aRects[0].Width(), aRects[0].Height(),
+                        aRects[1].x, aRects[1].y, aRects[1].Width(), aRects[1].Height(),
+                        aRects[2].x, aRects[2].y, aRects[2].Width(), aRects[2].Height(),
+-                       aRects[3].x, aRects[3].y, aRects[3].Width(), aRects[3].Height() }; 
++                       aRects[3].x, aRects[3].y, aRects[3].Width(), aRects[3].Height() };
+     SetUniform(KnownUniform::TextureRects, 16, vals);
+   }
+ 
+   void SetRenderOffset(const nsIntPoint& aOffset) {
+     float vals[4] = { float(aOffset.x), float(aOffset.y) };
+     SetUniform(KnownUniform::RenderTargetOffset, 2, vals);
+   }
+ 
+