Issue #2393 - Part 3 - Remove extra copy of YUV buffer on Windows

This commit is contained in:
trav90 2023-11-28 14:41:34 -06:00 committed by roytam1
commit b09b3771c6
9 changed files with 70 additions and 20 deletions

View file

@ -9,9 +9,16 @@
#include "ImageContainer.h"
#include "mozilla/layers/SharedRGBImage.h"
#include "YCbCrUtils.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/KnowsCompositor.h"
#include <stdint.h>
#ifdef XP_WIN
#include "mozilla/WindowsVersion.h"
#include "mozilla/layers/D3D11YCbCrImage.h"
#endif
namespace mozilla {
using namespace mozilla::gfx;
@ -218,19 +225,14 @@ VideoData::ShallowCopyUpdateTimestampAndDuration(const VideoData* aOther,
return v.forget();
}
/* static */
bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
const VideoInfo& aInfo,
const YCbCrBuffer &aBuffer,
const IntRect& aPicture,
bool aCopyData)
PlanarYCbCrData
ConstructPlanarYCbCrData(const VideoInfo& aInfo,
const VideoData::YCbCrBuffer& aBuffer,
const IntRect& aPicture)
{
if (!aVideoImage) {
return false;
}
const YCbCrBuffer::Plane &Y = aBuffer.mPlanes[0];
const YCbCrBuffer::Plane &Cb = aBuffer.mPlanes[1];
const YCbCrBuffer::Plane &Cr = aBuffer.mPlanes[2];
const VideoData::YCbCrBuffer::Plane& Y = aBuffer.mPlanes[0];
const VideoData::YCbCrBuffer::Plane& Cb = aBuffer.mPlanes[1];
const VideoData::YCbCrBuffer::Plane& Cr = aBuffer.mPlanes[2];
PlanarYCbCrData data;
data.mYChannel = Y.mData + Y.mOffset;
@ -249,6 +251,21 @@ bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
data.mStereoMode = aInfo.mStereoMode;
data.mYUVColorSpace = aBuffer.mYUVColorSpace;
data.mColorRange = aBuffer.mColorRange;
return data;
}
/* static */ bool
VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
const VideoInfo& aInfo,
const YCbCrBuffer &aBuffer,
const IntRect& aPicture,
bool aCopyData)
{
if (!aVideoImage) {
return false;
}
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
aVideoImage->SetDelayedConversion(true);
if (aCopyData) {
@ -268,7 +285,8 @@ VideoData::CreateAndCopyData(const VideoInfo& aInfo,
const YCbCrBuffer& aBuffer,
bool aKeyframe,
int64_t aTimecode,
const IntRect& aPicture)
const IntRect& aPicture,
layers::KnowsCompositor* aAllocator)
{
if (!aContainer) {
// Create a dummy VideoData with no image. This gives us something to
@ -296,6 +314,23 @@ VideoData::CreateAndCopyData(const VideoInfo& aInfo,
0));
// Currently our decoder only knows how to output to ImageFormat::PLANAR_YCBCR
// format.
#if XP_WIN
// We disable this code path on Windows 7 due to intermittent crashes with old drivers.
// See Mozilla bug 1405110.
if (IsWin8OrLater() && !XRE_IsParentProcess() &&
aAllocator && aAllocator->GetCompositorBackendType()
== layers::LayersBackend::LAYERS_D3D11) {
RefPtr<layers::D3D11YCbCrImage> d3d11Image = new layers::D3D11YCbCrImage();
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
if (d3d11Image->SetData(layers::ImageBridgeChild::GetSingleton()
? layers::ImageBridgeChild::GetSingleton().get()
: aAllocator,
aContainer, data)) {
v->mImage = d3d11Image;
return v.forget();
}
}
#endif
if (!v->mImage) {
v->mImage = aContainer->CreatePlanarYCbCrImage();
}