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

View file

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

View file

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

View file

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