Bug 1749047 - Attach color space information to decoded video frame going over IPC. r=pehrsons

Differential Revision: https://phabricator.services.mozilla.com/D196338
This commit is contained in:
Paul Adenot 2023-12-22 21:39:17 +00:00
parent 870313cab7
commit 1528bf51a4
4 changed files with 74 additions and 23 deletions

View file

@ -19,22 +19,32 @@ using namespace gfx;
using namespace layers;
RemoteImageHolder::RemoteImageHolder() = default;
RemoteImageHolder::RemoteImageHolder(layers::IGPUVideoSurfaceManager* aManager,
layers::VideoBridgeSource aSource,
const gfx::IntSize& aSize,
const gfx::ColorDepth& aColorDepth,
const layers::SurfaceDescriptor& aSD)
RemoteImageHolder::RemoteImageHolder(
layers::IGPUVideoSurfaceManager* aManager,
layers::VideoBridgeSource aSource, const gfx::IntSize& aSize,
const gfx::ColorDepth& aColorDepth, const layers::SurfaceDescriptor& aSD,
gfx::YUVColorSpace aYUVColorSpace, gfx::ColorSpace2 aColorPrimaries,
gfx::TransferFunction aTransferFunction, gfx::ColorRange aColorRange)
: mSource(aSource),
mSize(aSize),
mColorDepth(aColorDepth),
mSD(Some(aSD)),
mManager(aManager) {}
mManager(aManager),
mYUVColorSpace(aYUVColorSpace),
mColorPrimaries(aColorPrimaries),
mTransferFunction(aTransferFunction),
mColorRange(aColorRange) {}
RemoteImageHolder::RemoteImageHolder(RemoteImageHolder&& aOther)
: mSource(aOther.mSource),
mSize(aOther.mSize),
mColorDepth(aOther.mColorDepth),
mSD(std::move(aOther.mSD)),
mManager(aOther.mManager) {
mManager(aOther.mManager),
mYUVColorSpace(aOther.mYUVColorSpace),
mColorPrimaries(aOther.mColorPrimaries),
mTransferFunction(aOther.mTransferFunction),
mColorRange(aOther.mColorRange) {
aOther.mSD = Nothing();
}
@ -119,7 +129,9 @@ already_AddRefed<layers::Image> RemoteImageHolder::TransferToImage(
SurfaceDescriptorRemoteDecoder remoteSD =
static_cast<const SurfaceDescriptorGPUVideo&>(*mSD);
remoteSD.source() = Some(mSource);
image = new GPUVideoImage(mManager, remoteSD, mSize, mColorDepth);
image = new GPUVideoImage(mManager, remoteSD, mSize, mColorDepth,
mYUVColorSpace, mColorPrimaries,
mTransferFunction, mColorRange);
}
mSD = Nothing();
mManager = nullptr;
@ -147,6 +159,10 @@ RemoteImageHolder::~RemoteImageHolder() {
WriteIPDLParam(aWriter, aActor, aParam.mSize);
WriteIPDLParam(aWriter, aActor, aParam.mColorDepth);
WriteIPDLParam(aWriter, aActor, aParam.mSD);
WriteIPDLParam(aWriter, aActor, aParam.mYUVColorSpace);
WriteIPDLParam(aWriter, aActor, aParam.mColorPrimaries);
WriteIPDLParam(aWriter, aActor, aParam.mTransferFunction);
WriteIPDLParam(aWriter, aActor, aParam.mColorRange);
// Empty this holder.
aParam.mSD = Nothing();
aParam.mManager = nullptr;
@ -158,7 +174,11 @@ RemoteImageHolder::~RemoteImageHolder() {
if (!ReadIPDLParam(aReader, aActor, &aResult->mSource) ||
!ReadIPDLParam(aReader, aActor, &aResult->mSize) ||
!ReadIPDLParam(aReader, aActor, &aResult->mColorDepth) ||
!ReadIPDLParam(aReader, aActor, &aResult->mSD)) {
!ReadIPDLParam(aReader, aActor, &aResult->mSD) ||
!ReadIPDLParam(aReader, aActor, &aResult->mYUVColorSpace) ||
!ReadIPDLParam(aReader, aActor, &aResult->mColorPrimaries) ||
!ReadIPDLParam(aReader, aActor, &aResult->mTransferFunction) ||
!ReadIPDLParam(aReader, aActor, &aResult->mColorRange)) {
return false;
}

View file

@ -25,11 +25,12 @@ class RemoteImageHolder final {
public:
RemoteImageHolder();
RemoteImageHolder(layers::IGPUVideoSurfaceManager* aManager,
layers::VideoBridgeSource aSource,
const gfx::IntSize& aSize,
const gfx::ColorDepth& aColorDepth,
const layers::SurfaceDescriptor& aSD);
RemoteImageHolder(
layers::IGPUVideoSurfaceManager* aManager,
layers::VideoBridgeSource aSource, const gfx::IntSize& aSize,
const gfx::ColorDepth& aColorDepth, const layers::SurfaceDescriptor& aSD,
gfx::YUVColorSpace aYUVColorSpace, gfx::ColorSpace2 aColorPrimaries,
gfx::TransferFunction aTransferFunction, gfx::ColorRange aColorRange);
RemoteImageHolder(RemoteImageHolder&& aOther);
// Ensure we never copy this object.
RemoteImageHolder(const RemoteImageHolder& aOther) = delete;
@ -51,14 +52,18 @@ class RemoteImageHolder final {
gfx::ColorDepth mColorDepth = gfx::ColorDepth::COLOR_8;
Maybe<layers::SurfaceDescriptor> mSD;
RefPtr<layers::IGPUVideoSurfaceManager> mManager;
gfx::YUVColorSpace mYUVColorSpace = {};
gfx::ColorSpace2 mColorPrimaries = {};
gfx::TransferFunction mTransferFunction = {};
gfx::ColorRange mColorRange = {};
};
template <>
struct ipc::IPDLParamTraits<RemoteImageHolder> {
static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
RemoteImageHolder&& aParam);
static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
RemoteImageHolder* aResult);
template <>
struct ipc::IPDLParamTraits<RemoteImageHolder> {
static void Write(IPC::MessageWriter* aWriter, IProtocol* aActor,
RemoteImageHolder&& aParam);
static bool Read(IPC::MessageReader* aReader, IProtocol* aActor,
RemoteImageHolder* aResult);
};
} // namespace mozilla

View file

@ -218,6 +218,11 @@ MediaResult RemoteVideoDecoderParent::ProcessDecodedData(
IntSize size;
bool needStorage = false;
YUVColorSpace YUVColorSpace = gfx::YUVColorSpace::Default;
ColorSpace2 colorPrimaries = gfx::ColorSpace2::UNKNOWN;
TransferFunction transferFunction = gfx::TransferFunction::BT709;
ColorRange colorRange = gfx::ColorRange::LIMITED;
if (mKnowsCompositor) {
texture = video->mImage->GetTextureClient(mKnowsCompositor);
@ -249,6 +254,10 @@ MediaResult RemoteVideoDecoderParent::ProcessDecodedData(
"Expected Planar YCbCr image in "
"RemoteVideoDecoderParent::ProcessDecodedData");
}
YUVColorSpace = image->GetData()->mYUVColorSpace;
colorPrimaries = image->GetData()->mColorPrimaries;
transferFunction = image->GetData()->mTransferFunction;
colorRange = image->GetData()->mColorRange;
SurfaceDescriptorBuffer sdBuffer;
nsresult rv = image->BuildSurfaceDescriptorBuffer(
@ -282,7 +291,8 @@ MediaResult RemoteVideoDecoderParent::ProcessDecodedData(
: (XRE_IsRDDProcess()
? VideoBridgeSource::RddProcess
: VideoBridgeSource::MFMediaEngineCDMProcess),
size, video->mImage->GetColorDepth(), sd),
size, video->mImage->GetColorDepth(), sd, YUVColorSpace,
colorPrimaries, transferFunction, colorRange),
video->mFrameID);
array.AppendElement(std::move(output));

View file

@ -39,10 +39,18 @@ class GPUVideoImage final : public Image {
public:
GPUVideoImage(IGPUVideoSurfaceManager* aManager,
const SurfaceDescriptorGPUVideo& aSD, const gfx::IntSize& aSize,
const gfx::ColorDepth& aColorDepth)
const gfx::ColorDepth& aColorDepth,
gfx::YUVColorSpace aYUVColorSpace,
gfx::ColorSpace2 aColorPrimaries,
gfx::TransferFunction aTransferFunction,
gfx::ColorRange aColorRange)
: Image(nullptr, ImageFormat::GPU_VIDEO),
mSize(aSize),
mColorDepth(aColorDepth) {
mColorDepth(aColorDepth),
mColorSpace(aColorPrimaries),
mYUVColorSpace(aYUVColorSpace),
mTransferFunction(aTransferFunction),
mColorRange(aColorRange) {
// Create the TextureClient immediately since the GPUVideoTextureData
// is responsible for deallocating the SurfaceDescriptor.
//
@ -62,6 +70,10 @@ class GPUVideoImage final : public Image {
gfx::IntSize GetSize() const override { return mSize; }
gfx::ColorDepth GetColorDepth() const override { return mColorDepth; }
gfx::ColorSpace2 GetColorPrimaries() const { return mColorSpace; }
gfx::YUVColorSpace GetYUVColorSpace() const { return mYUVColorSpace; }
gfx::TransferFunction GetTransferFunction() const { return mTransferFunction; }
gfx::ColorRange GetColorRange() const { return mColorRange; }
Maybe<SurfaceDescriptor> GetDesc() override {
return GetDescFromTexClient(mTextureClient);
@ -97,7 +109,11 @@ class GPUVideoImage final : public Image {
private:
gfx::IntSize mSize;
gfx::ColorDepth mColorDepth;
gfx::ColorSpace2 mColorSpace;
gfx::YUVColorSpace mYUVColorSpace;
RefPtr<TextureClient> mTextureClient;
gfx::TransferFunction mTransferFunction;
gfx::ColorRange mColorRange;
};
} // namespace layers