зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1306521 - Handle VP9 colorspace BT.709 on BasicCompositor r=nical,jwwang,jya,jrmuizel
This commit is contained in:
Родитель
c26d9eb6e6
Коммит
1d3ceeff04
|
@ -239,6 +239,7 @@ bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
|
||||||
data.mPicY = aPicture.y;
|
data.mPicY = aPicture.y;
|
||||||
data.mPicSize = aPicture.Size();
|
data.mPicSize = aPicture.Size();
|
||||||
data.mStereoMode = aInfo.mStereoMode;
|
data.mStereoMode = aInfo.mStereoMode;
|
||||||
|
data.mYUVColorSpace = aBuffer.mYUVColorSpace;
|
||||||
|
|
||||||
aVideoImage->SetDelayedConversion(true);
|
aVideoImage->SetDelayedConversion(true);
|
||||||
if (aCopyData) {
|
if (aCopyData) {
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
#if !defined(MediaData_h)
|
#if !defined(MediaData_h)
|
||||||
#define MediaData_h
|
#define MediaData_h
|
||||||
|
|
||||||
|
#include "AudioSampleFormat.h"
|
||||||
|
#include "ImageTypes.h"
|
||||||
#include "nsSize.h"
|
#include "nsSize.h"
|
||||||
#include "mozilla/gfx/Rect.h"
|
#include "mozilla/gfx/Rect.h"
|
||||||
#include "nsRect.h"
|
#include "nsRect.h"
|
||||||
#include "AudioSampleFormat.h"
|
|
||||||
#include "nsIMemoryReporter.h"
|
#include "nsIMemoryReporter.h"
|
||||||
#include "SharedBuffer.h"
|
#include "SharedBuffer.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
|
@ -443,6 +444,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
Plane mPlanes[3];
|
Plane mPlanes[3];
|
||||||
|
YUVColorSpace mYUVColorSpace = YUVColorSpace::BT601;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Constructs a VideoData object. If aImage is nullptr, creates a new Image
|
// Constructs a VideoData object. If aImage is nullptr, creates a new Image
|
||||||
|
|
|
@ -86,16 +86,22 @@ FFmpegLibWrapper::Link()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define AV_FUNC(func, ver) \
|
#define AV_FUNC_OPTION(func, ver) \
|
||||||
if ((ver) & version) { \
|
if ((ver) & version) { \
|
||||||
if (!(func = (decltype(func))PR_FindSymbol(((ver) & AV_FUNC_AVUTIL_MASK) ? mAVUtilLib : mAVCodecLib, #func))) { \
|
if (!(func = (decltype(func))PR_FindSymbol(((ver) & AV_FUNC_AVUTIL_MASK) ? mAVUtilLib : mAVCodecLib, #func))) { \
|
||||||
FFMPEG_LOG("Couldn't load function " # func); \
|
FFMPEG_LOG("Couldn't load function " # func); \
|
||||||
Unlink(); \
|
|
||||||
return false; \
|
|
||||||
} \
|
} \
|
||||||
} else { \
|
} else { \
|
||||||
func = (decltype(func))nullptr; \
|
func = (decltype(func))nullptr; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define AV_FUNC(func, ver) \
|
||||||
|
AV_FUNC_OPTION(func, ver) \
|
||||||
|
if ((ver) & version && !func) { \
|
||||||
|
Unlink(); \
|
||||||
|
return false; \
|
||||||
|
}
|
||||||
|
|
||||||
AV_FUNC(av_lockmgr_register, AV_FUNC_AVCODEC_ALL)
|
AV_FUNC(av_lockmgr_register, AV_FUNC_AVCODEC_ALL)
|
||||||
AV_FUNC(avcodec_alloc_context3, AV_FUNC_AVCODEC_ALL)
|
AV_FUNC(avcodec_alloc_context3, AV_FUNC_AVCODEC_ALL)
|
||||||
AV_FUNC(avcodec_close, AV_FUNC_AVCODEC_ALL)
|
AV_FUNC(avcodec_close, AV_FUNC_AVCODEC_ALL)
|
||||||
|
@ -118,7 +124,9 @@ FFmpegLibWrapper::Link()
|
||||||
AV_FUNC(av_frame_alloc, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57))
|
AV_FUNC(av_frame_alloc, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57))
|
||||||
AV_FUNC(av_frame_free, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57))
|
AV_FUNC(av_frame_free, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57))
|
||||||
AV_FUNC(av_frame_unref, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57))
|
AV_FUNC(av_frame_unref, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57))
|
||||||
|
AV_FUNC_OPTION(av_frame_get_colorspace, AV_FUNC_AVUTIL_ALL)
|
||||||
#undef AV_FUNC
|
#undef AV_FUNC
|
||||||
|
#undef AV_FUNC_OPTION
|
||||||
|
|
||||||
avcodec_register_all();
|
avcodec_register_all();
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -67,6 +67,9 @@ struct FFmpegLibWrapper
|
||||||
void (*av_frame_free)(AVFrame** frame);
|
void (*av_frame_free)(AVFrame** frame);
|
||||||
void (*av_frame_unref)(AVFrame* frame);
|
void (*av_frame_unref)(AVFrame* frame);
|
||||||
|
|
||||||
|
// libavutil optional
|
||||||
|
int (*av_frame_get_colorspace)(const AVFrame *frame);
|
||||||
|
|
||||||
PRLibrary* mAVCodecLib;
|
PRLibrary* mAVCodecLib;
|
||||||
PRLibrary* mAVUtilLib;
|
PRLibrary* mAVUtilLib;
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,19 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample,
|
||||||
b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = (mFrame->width + 1) >> 1;
|
b.mPlanes[1].mWidth = b.mPlanes[2].mWidth = (mFrame->width + 1) >> 1;
|
||||||
b.mPlanes[1].mHeight = b.mPlanes[2].mHeight = (mFrame->height + 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;
|
||||||
|
break;
|
||||||
|
case AVCOL_SPC_SMPTE170M:
|
||||||
|
case AVCOL_SPC_BT470BG:
|
||||||
|
b.mYUVColorSpace = YUVColorSpace::BT601;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NS_WARNING("Unsupported yuv color space.");
|
||||||
|
}
|
||||||
|
}
|
||||||
RefPtr<VideoData> v =
|
RefPtr<VideoData> v =
|
||||||
VideoData::CreateAndCopyData(mInfo,
|
VideoData::CreateAndCopyData(mInfo,
|
||||||
mImageContainer,
|
mImageContainer,
|
||||||
|
|
|
@ -942,6 +942,14 @@ struct ParamTraits<mozilla::StereoMode>
|
||||||
mozilla::StereoMode::MAX>
|
mozilla::StereoMode::MAX>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct ParamTraits<mozilla::YUVColorSpace>
|
||||||
|
: public ContiguousEnumSerializer<
|
||||||
|
mozilla::YUVColorSpace,
|
||||||
|
mozilla::YUVColorSpace::BT601,
|
||||||
|
mozilla::YUVColorSpace::UNKNOWN>
|
||||||
|
{};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct ParamTraits<mozilla::layers::ScrollableLayerGuid>
|
struct ParamTraits<mozilla::layers::ScrollableLayerGuid>
|
||||||
{
|
{
|
||||||
|
|
|
@ -158,6 +158,7 @@ BufferTextureData::CreateInternal(LayersIPCChannel* aAllocator,
|
||||||
BufferTextureData*
|
BufferTextureData*
|
||||||
BufferTextureData::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
BufferTextureData::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
||||||
int32_t aBufferSize,
|
int32_t aBufferSize,
|
||||||
|
YUVColorSpace aYUVColorSpace,
|
||||||
TextureFlags aTextureFlags)
|
TextureFlags aTextureFlags)
|
||||||
{
|
{
|
||||||
if (aBufferSize == 0 || !gfx::Factory::CheckBufferSize(aBufferSize)) {
|
if (aBufferSize == 0 || !gfx::Factory::CheckBufferSize(aBufferSize)) {
|
||||||
|
@ -171,6 +172,7 @@ BufferTextureData::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
||||||
// afterwards since we don't know the dimensions of the texture at this point.
|
// 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(), gfx::IntSize(),
|
||||||
0, 0, 0, StereoMode::MONO,
|
0, 0, 0, StereoMode::MONO,
|
||||||
|
aYUVColorSpace,
|
||||||
hasIntermediateBuffer);
|
hasIntermediateBuffer);
|
||||||
|
|
||||||
return CreateInternal(aAllocator->GetTextureForwarder(), desc, gfx::BackendType::NONE, aBufferSize,
|
return CreateInternal(aAllocator->GetTextureForwarder(), desc, gfx::BackendType::NONE, aBufferSize,
|
||||||
|
@ -182,6 +184,7 @@ BufferTextureData::CreateForYCbCr(KnowsCompositor* aAllocator,
|
||||||
gfx::IntSize aYSize,
|
gfx::IntSize aYSize,
|
||||||
gfx::IntSize aCbCrSize,
|
gfx::IntSize aCbCrSize,
|
||||||
StereoMode aStereoMode,
|
StereoMode aStereoMode,
|
||||||
|
YUVColorSpace aYUVColorSpace,
|
||||||
TextureFlags aTextureFlags)
|
TextureFlags aTextureFlags)
|
||||||
{
|
{
|
||||||
uint32_t bufSize = ImageDataSerializer::ComputeYCbCrBufferSize(aYSize, aCbCrSize);
|
uint32_t bufSize = ImageDataSerializer::ComputeYCbCrBufferSize(aYSize, aCbCrSize);
|
||||||
|
@ -201,7 +204,7 @@ BufferTextureData::CreateForYCbCr(KnowsCompositor* aAllocator,
|
||||||
: true;
|
: true;
|
||||||
|
|
||||||
YCbCrDescriptor descriptor = YCbCrDescriptor(aYSize, aCbCrSize, yOffset, cbOffset,
|
YCbCrDescriptor descriptor = YCbCrDescriptor(aYSize, aCbCrSize, yOffset, cbOffset,
|
||||||
crOffset, aStereoMode,
|
crOffset, aStereoMode, aYUVColorSpace,
|
||||||
hasIntermediateBuffer);
|
hasIntermediateBuffer);
|
||||||
|
|
||||||
return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder() : nullptr, descriptor,
|
return CreateInternal(aAllocator ? aAllocator->GetTextureForwarder() : nullptr, descriptor,
|
||||||
|
@ -244,6 +247,12 @@ BufferTextureData::GetCbCrSize() const
|
||||||
return ImageDataSerializer::CbCrSizeFromBufferDescriptor(mDescriptor);
|
return ImageDataSerializer::CbCrSizeFromBufferDescriptor(mDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Maybe<YUVColorSpace>
|
||||||
|
BufferTextureData::GetYUVColorSpace() const
|
||||||
|
{
|
||||||
|
return ImageDataSerializer::YUVColorSpaceFromBufferDescriptor(mDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
Maybe<StereoMode>
|
Maybe<StereoMode>
|
||||||
BufferTextureData::GetStereoMode() const
|
BufferTextureData::GetStereoMode() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
gfx::IntSize aYSize,
|
gfx::IntSize aYSize,
|
||||||
gfx::IntSize aCbCrSize,
|
gfx::IntSize aCbCrSize,
|
||||||
StereoMode aStereoMode,
|
StereoMode aStereoMode,
|
||||||
|
YUVColorSpace aYUVColorSpace,
|
||||||
TextureFlags aTextureFlags);
|
TextureFlags aTextureFlags);
|
||||||
|
|
||||||
// It is generally better to use CreateForYCbCr instead.
|
// It is generally better to use CreateForYCbCr instead.
|
||||||
|
@ -39,6 +40,7 @@ public:
|
||||||
// offsets in the buffer.
|
// offsets in the buffer.
|
||||||
static BufferTextureData* CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
static BufferTextureData* CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
||||||
int32_t aSize,
|
int32_t aSize,
|
||||||
|
YUVColorSpace aYUVColorSpace,
|
||||||
TextureFlags aTextureFlags);
|
TextureFlags aTextureFlags);
|
||||||
|
|
||||||
virtual bool Lock(OpenMode aMode, FenceHandle*) override { return true; }
|
virtual bool Lock(OpenMode aMode, FenceHandle*) override { return true; }
|
||||||
|
@ -63,6 +65,8 @@ public:
|
||||||
|
|
||||||
Maybe<gfx::IntSize> GetCbCrSize() const;
|
Maybe<gfx::IntSize> GetCbCrSize() const;
|
||||||
|
|
||||||
|
Maybe<YUVColorSpace> GetYUVColorSpace() const;
|
||||||
|
|
||||||
Maybe<StereoMode> GetStereoMode() const;
|
Maybe<StereoMode> GetStereoMode() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -688,6 +688,7 @@ struct PlanarYCbCrData {
|
||||||
uint32_t mPicY;
|
uint32_t mPicY;
|
||||||
gfx::IntSize mPicSize;
|
gfx::IntSize mPicSize;
|
||||||
StereoMode mStereoMode;
|
StereoMode mStereoMode;
|
||||||
|
YUVColorSpace mYUVColorSpace;
|
||||||
|
|
||||||
gfx::IntRect GetPictureRect() const {
|
gfx::IntRect GetPictureRect() const {
|
||||||
return gfx::IntRect(mPicX, mPicY,
|
return gfx::IntRect(mPicX, mPicY,
|
||||||
|
@ -700,6 +701,7 @@ struct PlanarYCbCrData {
|
||||||
, mCbChannel(nullptr), mCrChannel(nullptr)
|
, mCbChannel(nullptr), mCrChannel(nullptr)
|
||||||
, mCbCrStride(0), mCbCrSize(0, 0) , mCbSkip(0), mCrSkip(0)
|
, mCbCrStride(0), mCbCrSize(0, 0) , mCbSkip(0), mCrSkip(0)
|
||||||
, mPicX(0), mPicY(0), mPicSize(0, 0), mStereoMode(StereoMode::MONO)
|
, mPicX(0), mPicY(0), mPicSize(0, 0), mStereoMode(StereoMode::MONO)
|
||||||
|
, mYUVColorSpace(YUVColorSpace::BT601)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,20 @@ Maybe<gfx::IntSize> CbCrSizeFromBufferDescriptor(const BufferDescriptor& aDescri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor)
|
Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor)
|
||||||
{
|
{
|
||||||
switch (aDescriptor.type()) {
|
switch (aDescriptor.type()) {
|
||||||
|
@ -202,6 +216,7 @@ DataSourceSurfaceFromYCbCrDescriptor(uint8_t* aBuffer, const YCbCrDescriptor& aD
|
||||||
ycbcrData.mCbCrStride = cbCrStride;
|
ycbcrData.mCbCrStride = cbCrStride;
|
||||||
ycbcrData.mCbCrSize = cbCrSize;
|
ycbcrData.mCbCrSize = cbCrSize;
|
||||||
ycbcrData.mPicSize = ySize;
|
ycbcrData.mPicSize = ySize;
|
||||||
|
ycbcrData.mYUVColorSpace = aDescriptor.yUVColorSpace();
|
||||||
|
|
||||||
gfx::ConvertYCbCrToRGB(ycbcrData,
|
gfx::ConvertYCbCrToRGB(ycbcrData,
|
||||||
gfx::SurfaceFormat::B8G8R8X8,
|
gfx::SurfaceFormat::B8G8R8X8,
|
||||||
|
@ -236,6 +251,7 @@ ConvertAndScaleFromYCbCrDescriptor(uint8_t* aBuffer,
|
||||||
ycbcrData.mCbCrStride = cbCrStride;
|
ycbcrData.mCbCrStride = cbCrStride;
|
||||||
ycbcrData.mCbCrSize = cbCrSize;
|
ycbcrData.mCbCrSize = cbCrSize;
|
||||||
ycbcrData.mPicSize = ySize;
|
ycbcrData.mPicSize = ySize;
|
||||||
|
ycbcrData.mYUVColorSpace = aDescriptor.yUVColorSpace();
|
||||||
|
|
||||||
gfx::ConvertYCbCrToRGB(ycbcrData, aDestFormat, aDestSize, aDestBuffer, aStride);
|
gfx::ConvertYCbCrToRGB(ycbcrData, aDestFormat, aDestSize, aDestBuffer, aStride);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ gfx::IntSize SizeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
|
||||||
|
|
||||||
Maybe<gfx::IntSize> CbCrSizeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
|
Maybe<gfx::IntSize> CbCrSizeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
|
||||||
|
|
||||||
|
Maybe<YUVColorSpace> YUVColorSpaceFromBufferDescriptor(const BufferDescriptor& aDescriptor);
|
||||||
|
|
||||||
Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
|
Maybe<StereoMode> StereoModeFromBufferDescriptor(const BufferDescriptor& aDescriptor);
|
||||||
|
|
||||||
uint8_t* GetYChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor);
|
uint8_t* GetYChannel(uint8_t* aBuffer, const YCbCrDescriptor& aDescriptor);
|
||||||
|
|
|
@ -115,6 +115,13 @@ enum class StereoMode {
|
||||||
MAX,
|
MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class YUVColorSpace {
|
||||||
|
BT601,
|
||||||
|
BT709,
|
||||||
|
// This represents the unknown format.
|
||||||
|
UNKNOWN,
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -123,6 +123,7 @@ ImageClient::CreateTextureClientForImage(Image* aImage, KnowsCompositor* aForwar
|
||||||
}
|
}
|
||||||
texture = TextureClient::CreateForYCbCr(aForwarder,
|
texture = TextureClient::CreateForYCbCr(aForwarder,
|
||||||
data->mYSize, data->mCbCrSize, data->mStereoMode,
|
data->mYSize, data->mCbCrSize, data->mStereoMode,
|
||||||
|
data->mYUVColorSpace,
|
||||||
TextureFlags::DEFAULT);
|
TextureFlags::DEFAULT);
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -231,7 +232,6 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
|
||||||
RefPtr<GonkNativeHandle::NhObj> nhObj = overlayImage->GetSidebandStream().GetDupNhObj();
|
RefPtr<GonkNativeHandle::NhObj> nhObj = overlayImage->GetSidebandStream().GetDupNhObj();
|
||||||
GonkNativeHandle handle(nhObj);
|
GonkNativeHandle handle(nhObj);
|
||||||
if (!handle.IsValid()) {
|
if (!handle.IsValid()) {
|
||||||
gfxWarning() << "ImageClientSingle::UpdateImage failed in GetDupNhObj";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
source.handle() = OverlayHandle(handle);
|
source.handle() = OverlayHandle(handle);
|
||||||
|
|
|
@ -1280,6 +1280,7 @@ TextureClient::CreateForYCbCr(KnowsCompositor* aAllocator,
|
||||||
gfx::IntSize aYSize,
|
gfx::IntSize aYSize,
|
||||||
gfx::IntSize aCbCrSize,
|
gfx::IntSize aCbCrSize,
|
||||||
StereoMode aStereoMode,
|
StereoMode aStereoMode,
|
||||||
|
YUVColorSpace aYUVColorSpace,
|
||||||
TextureFlags aTextureFlags)
|
TextureFlags aTextureFlags)
|
||||||
{
|
{
|
||||||
// The only reason we allow aAllocator to be null is for gtests
|
// The only reason we allow aAllocator to be null is for gtests
|
||||||
|
@ -1293,7 +1294,8 @@ TextureClient::CreateForYCbCr(KnowsCompositor* aAllocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureData* data = BufferTextureData::CreateForYCbCr(aAllocator, aYSize, aCbCrSize,
|
TextureData* data = BufferTextureData::CreateForYCbCr(aAllocator, aYSize, aCbCrSize,
|
||||||
aStereoMode, aTextureFlags);
|
aStereoMode, aYUVColorSpace,
|
||||||
|
aTextureFlags);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -1306,6 +1308,7 @@ TextureClient::CreateForYCbCr(KnowsCompositor* aAllocator,
|
||||||
already_AddRefed<TextureClient>
|
already_AddRefed<TextureClient>
|
||||||
TextureClient::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
TextureClient::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
||||||
size_t aSize,
|
size_t aSize,
|
||||||
|
YUVColorSpace aYUVColorSpace,
|
||||||
TextureFlags aTextureFlags)
|
TextureFlags aTextureFlags)
|
||||||
{
|
{
|
||||||
// also test the validity of aAllocator
|
// also test the validity of aAllocator
|
||||||
|
@ -1315,7 +1318,7 @@ TextureClient::CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureData* data =
|
TextureData* data =
|
||||||
BufferTextureData::CreateForYCbCrWithBufferSize(aAllocator, aSize,
|
BufferTextureData::CreateForYCbCrWithBufferSize(aAllocator, aSize, aYUVColorSpace,
|
||||||
aTextureFlags);
|
aTextureFlags);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -367,6 +367,7 @@ public:
|
||||||
gfx::IntSize aYSize,
|
gfx::IntSize aYSize,
|
||||||
gfx::IntSize aCbCrSize,
|
gfx::IntSize aCbCrSize,
|
||||||
StereoMode aStereoMode,
|
StereoMode aStereoMode,
|
||||||
|
YUVColorSpace aYUVColorSpace,
|
||||||
TextureFlags aTextureFlags);
|
TextureFlags aTextureFlags);
|
||||||
|
|
||||||
// Creates and allocates a TextureClient (can be accessed through raw
|
// Creates and allocates a TextureClient (can be accessed through raw
|
||||||
|
@ -385,6 +386,7 @@ public:
|
||||||
static already_AddRefed<TextureClient>
|
static already_AddRefed<TextureClient>
|
||||||
CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
CreateForYCbCrWithBufferSize(KnowsCompositor* aAllocator,
|
||||||
size_t aSize,
|
size_t aSize,
|
||||||
|
YUVColorSpace aYUVColorSpace,
|
||||||
TextureFlags aTextureFlags);
|
TextureFlags aTextureFlags);
|
||||||
|
|
||||||
// Creates and allocates a TextureClient of the same type.
|
// Creates and allocates a TextureClient of the same type.
|
||||||
|
|
|
@ -106,6 +106,8 @@ YCbCrTextureClientAllocationHelper::IsCompatible(TextureClient* aTextureClient)
|
||||||
aTextureClient->GetSize() != mData.mYSize ||
|
aTextureClient->GetSize() != mData.mYSize ||
|
||||||
bufferData->GetCbCrSize().isNothing() ||
|
bufferData->GetCbCrSize().isNothing() ||
|
||||||
bufferData->GetCbCrSize().ref() != mData.mCbCrSize ||
|
bufferData->GetCbCrSize().ref() != mData.mCbCrSize ||
|
||||||
|
bufferData->GetYUVColorSpace().isNothing() ||
|
||||||
|
bufferData->GetYUVColorSpace().ref() != mData.mYUVColorSpace ||
|
||||||
bufferData->GetStereoMode().isNothing() ||
|
bufferData->GetStereoMode().isNothing() ||
|
||||||
bufferData->GetStereoMode().ref() != mData.mStereoMode) {
|
bufferData->GetStereoMode().ref() != mData.mStereoMode) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -119,6 +121,7 @@ YCbCrTextureClientAllocationHelper::Allocate(KnowsCompositor* aAllocator)
|
||||||
return TextureClient::CreateForYCbCr(aAllocator,
|
return TextureClient::CreateForYCbCr(aAllocator,
|
||||||
mData.mYSize, mData.mCbCrSize,
|
mData.mYSize, mData.mCbCrSize,
|
||||||
mData.mStereoMode,
|
mData.mStereoMode,
|
||||||
|
mData.mYUVColorSpace,
|
||||||
mTextureFlags);
|
mTextureFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ using struct mozilla::layers::MagicGrallocBufferHandle from "gfxipc/ShadowLayerU
|
||||||
using struct mozilla::layers::GrallocBufferRef from "gfxipc/ShadowLayerUtils.h";
|
using struct mozilla::layers::GrallocBufferRef from "gfxipc/ShadowLayerUtils.h";
|
||||||
using struct mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h";
|
using struct mozilla::layers::SurfaceDescriptorX11 from "gfxipc/ShadowLayerUtils.h";
|
||||||
using mozilla::StereoMode from "ImageTypes.h";
|
using mozilla::StereoMode from "ImageTypes.h";
|
||||||
|
using mozilla::YUVColorSpace from "ImageTypes.h";
|
||||||
using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
|
using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
|
||||||
using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
|
using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
|
||||||
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
|
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
|
||||||
|
@ -115,6 +116,7 @@ struct YCbCrDescriptor {
|
||||||
uint32_t cbOffset;
|
uint32_t cbOffset;
|
||||||
uint32_t crOffset;
|
uint32_t crOffset;
|
||||||
StereoMode stereoMode;
|
StereoMode stereoMode;
|
||||||
|
YUVColorSpace yUVColorSpace;
|
||||||
bool hasIntermediateBuffer;
|
bool hasIntermediateBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -116,8 +116,10 @@ SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX Add YUVColorSpace handling. Use YUVColorSpace::BT601 for now.
|
||||||
mTextureClient = TextureClient::CreateForYCbCrWithBufferSize(mCompositable->GetForwarder(),
|
mTextureClient = TextureClient::CreateForYCbCrWithBufferSize(mCompositable->GetForwarder(),
|
||||||
size,
|
size,
|
||||||
|
YUVColorSpace::BT601,
|
||||||
mCompositable->GetTextureFlags());
|
mCompositable->GetTextureFlags());
|
||||||
|
|
||||||
// get new buffer _without_ setting mBuffer.
|
// get new buffer _without_ setting mBuffer.
|
||||||
|
@ -163,7 +165,7 @@ SharedPlanarYCbCrImage::AdoptData(const Data &aData)
|
||||||
|
|
||||||
static_cast<BufferTextureData*>(mTextureClient->GetInternalData())->SetDesciptor(
|
static_cast<BufferTextureData*>(mTextureClient->GetInternalData())->SetDesciptor(
|
||||||
YCbCrDescriptor(aData.mYSize, aData.mCbCrSize, yOffset, cbOffset, crOffset,
|
YCbCrDescriptor(aData.mYSize, aData.mCbCrSize, yOffset, cbOffset, crOffset,
|
||||||
aData.mStereoMode, hasIntermediateBuffer)
|
aData.mStereoMode, aData.mYUVColorSpace, hasIntermediateBuffer)
|
||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -219,6 +221,7 @@ SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
|
||||||
mData.mPicY = aData.mPicY;
|
mData.mPicY = aData.mPicY;
|
||||||
mData.mPicSize = aData.mPicSize;
|
mData.mPicSize = aData.mPicSize;
|
||||||
mData.mStereoMode = aData.mStereoMode;
|
mData.mStereoMode = aData.mStereoMode;
|
||||||
|
mData.mYUVColorSpace = aData.mYUVColorSpace;
|
||||||
// those members are not always equal to aData's, due to potentially different
|
// those members are not always equal to aData's, due to potentially different
|
||||||
// packing.
|
// packing.
|
||||||
mData.mYSkip = 0;
|
mData.mYSkip = 0;
|
||||||
|
|
|
@ -258,6 +258,7 @@ TEST(Layers, TextureYCbCrSerialization) {
|
||||||
clientData.mYStride = ySurface->Stride();
|
clientData.mYStride = ySurface->Stride();
|
||||||
clientData.mCbCrStride = cbSurface->Stride();
|
clientData.mCbCrStride = cbSurface->Stride();
|
||||||
clientData.mStereoMode = StereoMode::MONO;
|
clientData.mStereoMode = StereoMode::MONO;
|
||||||
|
clientData.mYUVColorSpace = YUVColorSpace::BT601;
|
||||||
clientData.mYSkip = 0;
|
clientData.mYSkip = 0;
|
||||||
clientData.mCbSkip = 0;
|
clientData.mCbSkip = 0;
|
||||||
clientData.mCrSkip = 0;
|
clientData.mCrSkip = 0;
|
||||||
|
@ -266,7 +267,8 @@ TEST(Layers, TextureYCbCrSerialization) {
|
||||||
clientData.mPicX = 0;
|
clientData.mPicX = 0;
|
||||||
|
|
||||||
RefPtr<TextureClient> client = TextureClient::CreateForYCbCr(nullptr, clientData.mYSize, clientData.mCbCrSize,
|
RefPtr<TextureClient> client = TextureClient::CreateForYCbCr(nullptr, clientData.mYSize, clientData.mCbCrSize,
|
||||||
StereoMode::MONO, TextureFlags::DEALLOCATE_CLIENT);
|
StereoMode::MONO, YUVColorSpace::BT601,
|
||||||
|
TextureFlags::DEALLOCATE_CLIENT);
|
||||||
|
|
||||||
TestTextureClientYCbCr(client, clientData);
|
TestTextureClientYCbCr(client, clientData);
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,7 @@ ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
|
||||||
aData.mCbCrStride,
|
aData.mCbCrStride,
|
||||||
aStride,
|
aStride,
|
||||||
yuvtype,
|
yuvtype,
|
||||||
|
aData.mYUVColorSpace,
|
||||||
FILTER_BILINEAR);
|
FILTER_BILINEAR);
|
||||||
} else { // no prescale
|
} else { // no prescale
|
||||||
#if defined(HAVE_YCBCR_TO_RGB565)
|
#if defined(HAVE_YCBCR_TO_RGB565)
|
||||||
|
@ -147,7 +148,8 @@ ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData,
|
||||||
aData.mYStride,
|
aData.mYStride,
|
||||||
aData.mCbCrStride,
|
aData.mCbCrStride,
|
||||||
aStride,
|
aStride,
|
||||||
yuvtype);
|
yuvtype,
|
||||||
|
aData.mYUVColorSpace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ struct YUVBuferIter {
|
||||||
const uint8* src_v;
|
const uint8* src_v;
|
||||||
|
|
||||||
uint32 src_fourcc;
|
uint32 src_fourcc;
|
||||||
|
const struct YuvConstants* yuvconstants;
|
||||||
int y_index;
|
int y_index;
|
||||||
const uint8* src_row_y;
|
const uint8* src_row_y;
|
||||||
const uint8* src_row_u;
|
const uint8* src_row_u;
|
||||||
|
@ -200,15 +201,20 @@ static void YUVBuferIter_MoveToNextRowForI420(YUVBuferIter& iter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void YUVBuferIter_ConvertToARGBRow(YUVBuferIter& iter, uint8* argb_row) {
|
static __inline void YUVBuferIter_ConvertToARGBRow(YUVBuferIter& iter, uint8* argb_row) {
|
||||||
iter.YUVToARGBRow(iter.src_row_y, iter.src_row_u, iter.src_row_v, argb_row, &kYuvI601Constants, iter.src_width);
|
iter.YUVToARGBRow(iter.src_row_y, iter.src_row_u, iter.src_row_v, argb_row, iter.yuvconstants, iter.src_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void YUVBuferIter_Init(YUVBuferIter& iter, uint32 src_fourcc) {
|
void YUVBuferIter_Init(YUVBuferIter& iter, uint32 src_fourcc, mozilla::YUVColorSpace yuv_color_space) {
|
||||||
iter.src_fourcc = src_fourcc;
|
iter.src_fourcc = src_fourcc;
|
||||||
iter.y_index = 0;
|
iter.y_index = 0;
|
||||||
iter.src_row_y = iter.src_y;
|
iter.src_row_y = iter.src_y;
|
||||||
iter.src_row_u = iter.src_u;
|
iter.src_row_u = iter.src_u;
|
||||||
iter.src_row_v = iter.src_v;
|
iter.src_row_v = iter.src_v;
|
||||||
|
if (yuv_color_space == mozilla::YUVColorSpace::BT709) {
|
||||||
|
iter.yuvconstants = &kYuvH709Constants;
|
||||||
|
} else {
|
||||||
|
iter.yuvconstants = &kYuvI601Constants;
|
||||||
|
}
|
||||||
|
|
||||||
if (src_fourcc == FOURCC_I444) {
|
if (src_fourcc == FOURCC_I444) {
|
||||||
YUVBuferIter_InitI444(iter);
|
YUVBuferIter_InitI444(iter);
|
||||||
|
@ -241,7 +247,8 @@ static void ScaleYUVToARGBDown2(int src_width, int src_height,
|
||||||
uint8* dst_argb,
|
uint8* dst_argb,
|
||||||
int x, int dx, int y, int dy,
|
int x, int dx, int y, int dy,
|
||||||
enum FilterMode filtering,
|
enum FilterMode filtering,
|
||||||
uint32 src_fourcc) {
|
uint32 src_fourcc,
|
||||||
|
mozilla::YUVColorSpace yuv_color_space) {
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
// Allocate 2 rows of ARGB for source conversion.
|
// Allocate 2 rows of ARGB for source conversion.
|
||||||
|
@ -259,7 +266,7 @@ static void ScaleYUVToARGBDown2(int src_width, int src_height,
|
||||||
iter.src_y = src_y;
|
iter.src_y = src_y;
|
||||||
iter.src_u = src_u;
|
iter.src_u = src_u;
|
||||||
iter.src_v = src_v;
|
iter.src_v = src_v;
|
||||||
YUVBuferIter_Init(iter, src_fourcc);
|
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
|
||||||
|
|
||||||
void (*ScaleARGBRowDown2)(const uint8* src_argb, ptrdiff_t src_stride,
|
void (*ScaleARGBRowDown2)(const uint8* src_argb, ptrdiff_t src_stride,
|
||||||
uint8* dst_argb, int dst_width) =
|
uint8* dst_argb, int dst_width) =
|
||||||
|
@ -377,7 +384,8 @@ static void ScaleYUVToARGBDownEven(int src_width, int src_height,
|
||||||
uint8* dst_argb,
|
uint8* dst_argb,
|
||||||
int x, int dx, int y, int dy,
|
int x, int dx, int y, int dy,
|
||||||
enum FilterMode filtering,
|
enum FilterMode filtering,
|
||||||
uint32 src_fourcc) {
|
uint32 src_fourcc,
|
||||||
|
mozilla::YUVColorSpace yuv_color_space) {
|
||||||
int j;
|
int j;
|
||||||
// Allocate 2 rows of ARGB for source conversion.
|
// Allocate 2 rows of ARGB for source conversion.
|
||||||
const int kRowSize = (src_width * 4 + 15) & ~15;
|
const int kRowSize = (src_width * 4 + 15) & ~15;
|
||||||
|
@ -424,7 +432,7 @@ static void ScaleYUVToARGBDownEven(int src_width, int src_height,
|
||||||
iter.src_y = src_y;
|
iter.src_y = src_y;
|
||||||
iter.src_u = src_u;
|
iter.src_u = src_u;
|
||||||
iter.src_v = src_v;
|
iter.src_v = src_v;
|
||||||
YUVBuferIter_Init(iter, src_fourcc);
|
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
|
||||||
|
|
||||||
const int dyi = dy >> 16;
|
const int dyi = dy >> 16;
|
||||||
int lastyi = yi;
|
int lastyi = yi;
|
||||||
|
@ -497,7 +505,8 @@ static void ScaleYUVToARGBBilinearDown(int src_width, int src_height,
|
||||||
uint8* dst_argb,
|
uint8* dst_argb,
|
||||||
int x, int dx, int y, int dy,
|
int x, int dx, int y, int dy,
|
||||||
enum FilterMode filtering,
|
enum FilterMode filtering,
|
||||||
uint32 src_fourcc) {
|
uint32 src_fourcc,
|
||||||
|
mozilla::YUVColorSpace yuv_color_space) {
|
||||||
int j;
|
int j;
|
||||||
void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
|
void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
|
||||||
ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
|
ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
|
||||||
|
@ -583,7 +592,7 @@ static void ScaleYUVToARGBBilinearDown(int src_width, int src_height,
|
||||||
iter.src_y = src_y;
|
iter.src_y = src_y;
|
||||||
iter.src_u = src_u;
|
iter.src_u = src_u;
|
||||||
iter.src_v = src_v;
|
iter.src_v = src_v;
|
||||||
YUVBuferIter_Init(iter, src_fourcc);
|
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
|
||||||
iter.MoveTo(iter, yi);
|
iter.MoveTo(iter, yi);
|
||||||
|
|
||||||
// TODO(fbarchard): Consider not allocating row buffer for kFilterLinear.
|
// TODO(fbarchard): Consider not allocating row buffer for kFilterLinear.
|
||||||
|
@ -665,7 +674,8 @@ static void ScaleYUVToARGBBilinearUp(int src_width, int src_height,
|
||||||
uint8* dst_argb,
|
uint8* dst_argb,
|
||||||
int x, int dx, int y, int dy,
|
int x, int dx, int y, int dy,
|
||||||
enum FilterMode filtering,
|
enum FilterMode filtering,
|
||||||
uint32 src_fourcc) {
|
uint32 src_fourcc,
|
||||||
|
mozilla::YUVColorSpace yuv_color_space) {
|
||||||
int j;
|
int j;
|
||||||
void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
|
void (*InterpolateRow)(uint8* dst_argb, const uint8* src_argb,
|
||||||
ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
|
ptrdiff_t src_stride, int dst_width, int source_y_fraction) =
|
||||||
|
@ -762,7 +772,7 @@ static void ScaleYUVToARGBBilinearUp(int src_width, int src_height,
|
||||||
iter.src_y = src_y;
|
iter.src_y = src_y;
|
||||||
iter.src_u = src_u;
|
iter.src_u = src_u;
|
||||||
iter.src_v = src_v;
|
iter.src_v = src_v;
|
||||||
YUVBuferIter_Init(iter, src_fourcc);
|
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
|
||||||
iter.MoveTo(iter, yi);
|
iter.MoveTo(iter, yi);
|
||||||
|
|
||||||
// Allocate 2 rows of ARGB.
|
// Allocate 2 rows of ARGB.
|
||||||
|
@ -848,7 +858,8 @@ static void ScaleYUVToARGBSimple(int src_width, int src_height,
|
||||||
const uint8* src_v,
|
const uint8* src_v,
|
||||||
uint8* dst_argb,
|
uint8* dst_argb,
|
||||||
int x, int dx, int y, int dy,
|
int x, int dx, int y, int dy,
|
||||||
uint32 src_fourcc) {
|
uint32 src_fourcc,
|
||||||
|
mozilla::YUVColorSpace yuv_color_space) {
|
||||||
int j;
|
int j;
|
||||||
void (*ScaleARGBCols)(uint8* dst_argb, const uint8* src_argb,
|
void (*ScaleARGBCols)(uint8* dst_argb, const uint8* src_argb,
|
||||||
int dst_width, int x, int dx) =
|
int dst_width, int x, int dx) =
|
||||||
|
@ -890,7 +901,7 @@ static void ScaleYUVToARGBSimple(int src_width, int src_height,
|
||||||
iter.src_y = src_y;
|
iter.src_y = src_y;
|
||||||
iter.src_u = src_u;
|
iter.src_u = src_u;
|
||||||
iter.src_v = src_v;
|
iter.src_v = src_v;
|
||||||
YUVBuferIter_Init(iter, src_fourcc);
|
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
|
||||||
iter.MoveTo(iter, yi);
|
iter.MoveTo(iter, yi);
|
||||||
|
|
||||||
int lasty = yi;
|
int lasty = yi;
|
||||||
|
@ -916,7 +927,8 @@ static void YUVToARGBCopy(const uint8* src_y, int src_stride_y,
|
||||||
int src_width, int src_height,
|
int src_width, int src_height,
|
||||||
uint8* dst_argb, int dst_stride_argb,
|
uint8* dst_argb, int dst_stride_argb,
|
||||||
int dst_width, int dst_height,
|
int dst_width, int dst_height,
|
||||||
uint32 src_fourcc)
|
uint32 src_fourcc,
|
||||||
|
mozilla::YUVColorSpace yuv_color_space)
|
||||||
{
|
{
|
||||||
YUVBuferIter iter;
|
YUVBuferIter iter;
|
||||||
iter.src_width = src_width;
|
iter.src_width = src_width;
|
||||||
|
@ -927,7 +939,7 @@ static void YUVToARGBCopy(const uint8* src_y, int src_stride_y,
|
||||||
iter.src_y = src_y;
|
iter.src_y = src_y;
|
||||||
iter.src_u = src_u;
|
iter.src_u = src_u;
|
||||||
iter.src_v = src_v;
|
iter.src_v = src_v;
|
||||||
YUVBuferIter_Init(iter, src_fourcc);
|
YUVBuferIter_Init(iter, src_fourcc, yuv_color_space);
|
||||||
|
|
||||||
for (int j = 0; j < dst_height; ++j) {
|
for (int j = 0; j < dst_height; ++j) {
|
||||||
YUVBuferIter_ConvertToARGBRow(iter, dst_argb);
|
YUVBuferIter_ConvertToARGBRow(iter, dst_argb);
|
||||||
|
@ -943,7 +955,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
|
||||||
uint8* dst_argb, int dst_stride_argb,
|
uint8* dst_argb, int dst_stride_argb,
|
||||||
int dst_width, int dst_height,
|
int dst_width, int dst_height,
|
||||||
enum FilterMode filtering,
|
enum FilterMode filtering,
|
||||||
uint32 src_fourcc)
|
uint32 src_fourcc,
|
||||||
|
mozilla::YUVColorSpace yuv_color_space)
|
||||||
{
|
{
|
||||||
// Initial source x/y coordinate and step values as 16.16 fixed point.
|
// Initial source x/y coordinate and step values as 16.16 fixed point.
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
@ -979,7 +992,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
|
||||||
dst_argb,
|
dst_argb,
|
||||||
x, dx, y, dy,
|
x, dx, y, dy,
|
||||||
filtering,
|
filtering,
|
||||||
src_fourcc);
|
src_fourcc,
|
||||||
|
yuv_color_space);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ScaleYUVToARGBDownEven(src_width, src_height,
|
ScaleYUVToARGBDownEven(src_width, src_height,
|
||||||
|
@ -994,7 +1008,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
|
||||||
dst_argb,
|
dst_argb,
|
||||||
x, dx, y, dy,
|
x, dx, y, dy,
|
||||||
filtering,
|
filtering,
|
||||||
src_fourcc);
|
src_fourcc,
|
||||||
|
yuv_color_space);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Optimized odd scale down. ie 3, 5, 7, 9x.
|
// Optimized odd scale down. ie 3, 5, 7, 9x.
|
||||||
|
@ -1008,7 +1023,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
|
||||||
src_width, src_height,
|
src_width, src_height,
|
||||||
dst_argb, dst_stride_argb,
|
dst_argb, dst_stride_argb,
|
||||||
dst_width, dst_height,
|
dst_width, dst_height,
|
||||||
src_fourcc);
|
src_fourcc,
|
||||||
|
yuv_color_space);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1027,7 +1043,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
|
||||||
dst_argb,
|
dst_argb,
|
||||||
x, dx, y, dy,
|
x, dx, y, dy,
|
||||||
filtering,
|
filtering,
|
||||||
src_fourcc);
|
src_fourcc,
|
||||||
|
yuv_color_space);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (filtering) {
|
if (filtering) {
|
||||||
|
@ -1043,7 +1060,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
|
||||||
dst_argb,
|
dst_argb,
|
||||||
x, dx, y, dy,
|
x, dx, y, dy,
|
||||||
filtering,
|
filtering,
|
||||||
src_fourcc);
|
src_fourcc,
|
||||||
|
yuv_color_space);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ScaleYUVToARGBSimple(src_width, src_height,
|
ScaleYUVToARGBSimple(src_width, src_height,
|
||||||
|
@ -1057,7 +1075,8 @@ static void ScaleYUVToARGB(const uint8* src_y, int src_stride_y,
|
||||||
src_v,
|
src_v,
|
||||||
dst_argb,
|
dst_argb,
|
||||||
x, dx, y, dy,
|
x, dx, y, dy,
|
||||||
src_fourcc);
|
src_fourcc,
|
||||||
|
yuv_color_space);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsConvertSupported(uint32 src_fourcc)
|
bool IsConvertSupported(uint32 src_fourcc)
|
||||||
|
@ -1075,6 +1094,7 @@ int YUVToARGBScale(const uint8* src_y, int src_stride_y,
|
||||||
const uint8* src_u, int src_stride_u,
|
const uint8* src_u, int src_stride_u,
|
||||||
const uint8* src_v, int src_stride_v,
|
const uint8* src_v, int src_stride_v,
|
||||||
uint32 src_fourcc,
|
uint32 src_fourcc,
|
||||||
|
mozilla::YUVColorSpace yuv_color_space,
|
||||||
int src_width, int src_height,
|
int src_width, int src_height,
|
||||||
uint8* dst_argb, int dst_stride_argb,
|
uint8* dst_argb, int dst_stride_argb,
|
||||||
int dst_width, int dst_height,
|
int dst_width, int dst_height,
|
||||||
|
@ -1095,7 +1115,8 @@ int YUVToARGBScale(const uint8* src_y, int src_stride_y,
|
||||||
dst_argb, dst_stride_argb,
|
dst_argb, dst_stride_argb,
|
||||||
dst_width, dst_height,
|
dst_width, dst_height,
|
||||||
filtering,
|
filtering,
|
||||||
src_fourcc);
|
src_fourcc,
|
||||||
|
yuv_color_space);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "libyuv/basic_types.h"
|
#include "libyuv/basic_types.h"
|
||||||
#include "libyuv/scale.h" // For FilterMode
|
#include "libyuv/scale.h" // For FilterMode
|
||||||
|
|
||||||
|
#include "ImageTypes.h" // For YUVColorSpace
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
namespace libyuv {
|
namespace libyuv {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -23,6 +25,7 @@ int YUVToARGBScale(const uint8* src_y, int src_stride_y,
|
||||||
const uint8* src_u, int src_stride_u,
|
const uint8* src_u, int src_stride_u,
|
||||||
const uint8* src_v, int src_stride_v,
|
const uint8* src_v, int src_stride_v,
|
||||||
uint32 src_fourcc,
|
uint32 src_fourcc,
|
||||||
|
mozilla::YUVColorSpace yuv_color_space,
|
||||||
int src_width, int src_height,
|
int src_width, int src_height,
|
||||||
uint8* dst_argb, int dst_stride_argb,
|
uint8* dst_argb, int dst_stride_argb,
|
||||||
int dst_width, int dst_height,
|
int dst_width, int dst_height,
|
||||||
|
|
|
@ -75,7 +75,8 @@ void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||||
int y_pitch,
|
int y_pitch,
|
||||||
int uv_pitch,
|
int uv_pitch,
|
||||||
int rgb_pitch,
|
int rgb_pitch,
|
||||||
YUVType yuv_type) {
|
YUVType yuv_type,
|
||||||
|
YUVColorSpace yuv_color_space) {
|
||||||
|
|
||||||
|
|
||||||
// Deprecated function's conversion is accurate.
|
// Deprecated function's conversion is accurate.
|
||||||
|
@ -87,7 +88,13 @@ void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||||
// The function is still fast on some old intel chips.
|
// The function is still fast on some old intel chips.
|
||||||
// See Bug 1256475.
|
// See Bug 1256475.
|
||||||
bool use_deprecated = gfxPrefs::YCbCrAccurateConversion() ||
|
bool use_deprecated = gfxPrefs::YCbCrAccurateConversion() ||
|
||||||
(supports_mmx() && supports_sse() && !supports_sse3());
|
(supports_mmx() && supports_sse() && !supports_sse3() &&
|
||||||
|
yuv_color_space == YUVColorSpace::BT601);
|
||||||
|
// The deprecated function only support BT601.
|
||||||
|
// See Bug 1210357.
|
||||||
|
if (yuv_color_space != YUVColorSpace::BT601) {
|
||||||
|
use_deprecated = false;
|
||||||
|
}
|
||||||
if (use_deprecated) {
|
if (use_deprecated) {
|
||||||
ConvertYCbCrToRGB32_deprecated(y_buf, u_buf, v_buf, rgb_buf,
|
ConvertYCbCrToRGB32_deprecated(y_buf, u_buf, v_buf, rgb_buf,
|
||||||
pic_x, pic_y, pic_width, pic_height,
|
pic_x, pic_y, pic_width, pic_height,
|
||||||
|
@ -120,12 +127,22 @@ void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||||
const uint8* src_y = y_buf + y_pitch * pic_y + pic_x;
|
const uint8* src_y = y_buf + y_pitch * pic_y + pic_x;
|
||||||
const uint8* src_u = u_buf + (uv_pitch * pic_y + pic_x) / 2;
|
const uint8* src_u = u_buf + (uv_pitch * pic_y + pic_x) / 2;
|
||||||
const uint8* src_v = v_buf + (uv_pitch * pic_y + pic_x) / 2;
|
const uint8* src_v = v_buf + (uv_pitch * pic_y + pic_x) / 2;
|
||||||
DebugOnly<int> err = libyuv::I420ToARGB(src_y, y_pitch,
|
if (yuv_color_space == YUVColorSpace::BT709) {
|
||||||
src_u, uv_pitch,
|
DebugOnly<int> err = libyuv::H420ToARGB(src_y, y_pitch,
|
||||||
src_v, uv_pitch,
|
src_u, uv_pitch,
|
||||||
rgb_buf, rgb_pitch,
|
src_v, uv_pitch,
|
||||||
pic_width, pic_height);
|
rgb_buf, rgb_pitch,
|
||||||
MOZ_ASSERT(!err);
|
pic_width, pic_height);
|
||||||
|
MOZ_ASSERT(!err);
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(yuv_color_space == YUVColorSpace::BT601);
|
||||||
|
DebugOnly<int> err = libyuv::I420ToARGB(src_y, y_pitch,
|
||||||
|
src_u, uv_pitch,
|
||||||
|
src_v, uv_pitch,
|
||||||
|
rgb_buf, rgb_pitch,
|
||||||
|
pic_width, pic_height);
|
||||||
|
MOZ_ASSERT(!err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,6 +274,7 @@ void ScaleYCbCrToRGB32(const uint8* y_buf,
|
||||||
int uv_pitch,
|
int uv_pitch,
|
||||||
int rgb_pitch,
|
int rgb_pitch,
|
||||||
YUVType yuv_type,
|
YUVType yuv_type,
|
||||||
|
YUVColorSpace yuv_color_space,
|
||||||
ScaleFilter filter) {
|
ScaleFilter filter) {
|
||||||
|
|
||||||
bool use_deprecated = gfxPrefs::YCbCrAccurateConversion() ||
|
bool use_deprecated = gfxPrefs::YCbCrAccurateConversion() ||
|
||||||
|
@ -265,6 +283,11 @@ void ScaleYCbCrToRGB32(const uint8* y_buf,
|
||||||
supports_sse3() ||
|
supports_sse3() ||
|
||||||
#endif
|
#endif
|
||||||
(supports_mmx() && supports_sse() && !supports_sse3());
|
(supports_mmx() && supports_sse() && !supports_sse3());
|
||||||
|
// The deprecated function only support BT601.
|
||||||
|
// See Bug 1210357.
|
||||||
|
if (yuv_color_space != YUVColorSpace::BT601) {
|
||||||
|
use_deprecated = false;
|
||||||
|
}
|
||||||
if (use_deprecated) {
|
if (use_deprecated) {
|
||||||
ScaleYCbCrToRGB32_deprecated(y_buf, u_buf, v_buf,
|
ScaleYCbCrToRGB32_deprecated(y_buf, u_buf, v_buf,
|
||||||
rgb_buf,
|
rgb_buf,
|
||||||
|
@ -283,6 +306,7 @@ void ScaleYCbCrToRGB32(const uint8* y_buf,
|
||||||
u_buf, uv_pitch,
|
u_buf, uv_pitch,
|
||||||
v_buf, uv_pitch,
|
v_buf, uv_pitch,
|
||||||
FourCCFromYUVType(yuv_type),
|
FourCCFromYUVType(yuv_type),
|
||||||
|
yuv_color_space,
|
||||||
source_width, source_height,
|
source_width, source_height,
|
||||||
rgb_buf, rgb_pitch,
|
rgb_buf, rgb_pitch,
|
||||||
width, height,
|
width, height,
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#define MEDIA_BASE_YUV_CONVERT_H_
|
#define MEDIA_BASE_YUV_CONVERT_H_
|
||||||
|
|
||||||
#include "chromium_types.h"
|
#include "chromium_types.h"
|
||||||
|
#include "ImageTypes.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
@ -55,7 +56,8 @@ void ConvertYCbCrToRGB32(const uint8* yplane,
|
||||||
int ystride,
|
int ystride,
|
||||||
int uvstride,
|
int uvstride,
|
||||||
int rgbstride,
|
int rgbstride,
|
||||||
YUVType yuv_type);
|
YUVType yuv_type,
|
||||||
|
YUVColorSpace yuv_color_space);
|
||||||
|
|
||||||
void ConvertYCbCrToRGB32_deprecated(const uint8* yplane,
|
void ConvertYCbCrToRGB32_deprecated(const uint8* yplane,
|
||||||
const uint8* uplane,
|
const uint8* uplane,
|
||||||
|
@ -84,6 +86,7 @@ void ScaleYCbCrToRGB32(const uint8* yplane,
|
||||||
int uvstride,
|
int uvstride,
|
||||||
int rgbstride,
|
int rgbstride,
|
||||||
YUVType yuv_type,
|
YUVType yuv_type,
|
||||||
|
YUVColorSpace yuv_color_space,
|
||||||
ScaleFilter filter);
|
ScaleFilter filter);
|
||||||
|
|
||||||
void ScaleYCbCrToRGB32_deprecated(const uint8* yplane,
|
void ScaleYCbCrToRGB32_deprecated(const uint8* yplane,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче