Bug 971695 - 2/2 - make YCbCrImageDataSerializer check data size - r=nical

This commit is contained in:
Benoit Jacob 2014-02-20 16:04:13 -05:00
Родитель 9b3a0b05a4
Коммит 4aaf0bcadc
9 изменённых файлов: 103 добавлений и 57 удалений

Просмотреть файл

@ -51,70 +51,83 @@ struct YCbCrBufferInfo
StereoMode mStereoMode;
};
static YCbCrBufferInfo* GetYCbCrBufferInfo(uint8_t* aData)
static YCbCrBufferInfo* GetYCbCrBufferInfo(uint8_t* aData, size_t aDataSize)
{
return reinterpret_cast<YCbCrBufferInfo*>(aData);
return aDataSize >= sizeof(YCbCrBufferInfo)
? reinterpret_cast<YCbCrBufferInfo*>(aData)
: nullptr;
}
bool YCbCrImageDataDeserializerBase::IsValid()
void YCbCrImageDataDeserializerBase::Validate()
{
if (mData == nullptr) {
return false;
mIsValid = false;
if (!mData) {
return;
}
return true;
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
if (!info) {
return;
}
size_t requiredSize = ComputeMinBufferSize(
IntSize(info->mYWidth, info->mYHeight),
info->mYStride,
IntSize(info->mCbCrWidth, info->mCbCrHeight),
info->mCbCrStride);
mIsValid = requiredSize <= mDataSize;
}
uint8_t* YCbCrImageDataDeserializerBase::GetYData()
{
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
return reinterpret_cast<uint8_t*>(info) + info->mYOffset;
}
uint8_t* YCbCrImageDataDeserializerBase::GetCbData()
{
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
return reinterpret_cast<uint8_t*>(info) + info->mCbOffset;
}
uint8_t* YCbCrImageDataDeserializerBase::GetCrData()
{
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
return reinterpret_cast<uint8_t*>(info) + info->mCrOffset;
}
uint8_t* YCbCrImageDataDeserializerBase::GetData()
{
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
return (reinterpret_cast<uint8_t*>(info)) + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
}
uint32_t YCbCrImageDataDeserializerBase::GetYStride()
{
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
return info->mYStride;
}
uint32_t YCbCrImageDataDeserializerBase::GetCbCrStride()
{
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
return info->mCbCrStride;
}
gfx::IntSize YCbCrImageDataDeserializerBase::GetYSize()
{
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
return gfx::IntSize(info->mYWidth, info->mYHeight);
}
gfx::IntSize YCbCrImageDataDeserializerBase::GetCbCrSize()
{
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
return gfx::IntSize(info->mCbCrWidth, info->mCbCrHeight);
}
StereoMode YCbCrImageDataDeserializerBase::GetStereoMode()
{
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
return info->mStereoMode;
}
@ -126,17 +139,24 @@ static size_t ComputeOffset(uint32_t aHeight, uint32_t aStride)
// Minimum required shmem size in bytes
size_t
YCbCrImageDataSerializer::ComputeMinBufferSize(const gfx::IntSize& aYSize,
const gfx::IntSize& aCbCrSize)
YCbCrImageDataDeserializerBase::ComputeMinBufferSize(const gfx::IntSize& aYSize,
uint32_t aYStride,
const gfx::IntSize& aCbCrSize,
uint32_t aCbCrStride)
{
uint32_t yStride = aYSize.width;
uint32_t CbCrStride = aCbCrSize.width;
return ComputeOffset(aYSize.height, yStride)
+ 2 * ComputeOffset(aCbCrSize.height, CbCrStride)
return ComputeOffset(aYSize.height, aYStride)
+ 2 * ComputeOffset(aCbCrSize.height, aCbCrStride)
+ MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
}
// Minimum required shmem size in bytes
size_t
YCbCrImageDataDeserializerBase::ComputeMinBufferSize(const gfx::IntSize& aYSize,
const gfx::IntSize& aCbCrSize)
{
return ComputeMinBufferSize(aYSize, aYSize.width, aCbCrSize, aCbCrSize.width);
}
// Offset in bytes
static size_t ComputeOffset(uint32_t aSize)
{
@ -145,7 +165,7 @@ static size_t ComputeOffset(uint32_t aSize)
// Minimum required shmem size in bytes
size_t
YCbCrImageDataSerializer::ComputeMinBufferSize(uint32_t aSize)
YCbCrImageDataDeserializerBase::ComputeMinBufferSize(uint32_t aSize)
{
return ComputeOffset(aSize) + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
}
@ -160,7 +180,8 @@ YCbCrImageDataSerializer::InitializeBufferInfo(uint32_t aYOffset,
const gfx::IntSize& aCbCrSize,
StereoMode aStereoMode)
{
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData);
YCbCrBufferInfo* info = GetYCbCrBufferInfo(mData, mDataSize);
MOZ_ASSERT(info); // OK to assert here, this method is client-side-only
uint32_t info_size = MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo));
info->mYOffset = info_size + aYOffset;
info->mCbOffset = info_size + aCbOffset;
@ -172,6 +193,7 @@ YCbCrImageDataSerializer::InitializeBufferInfo(uint32_t aYOffset,
info->mCbCrWidth = aCbCrSize.width;
info->mCbCrHeight = aCbCrSize.height;
info->mStereoMode = aStereoMode;
Validate();
}
void

Просмотреть файл

@ -30,7 +30,7 @@ class Image;
class YCbCrImageDataDeserializerBase
{
public:
bool IsValid();
bool IsValid() const { return mIsValid; }
/**
* Returns the Y channel data pointer.
@ -73,11 +73,32 @@ public:
* Return a pointer to the begining of the data buffer.
*/
uint8_t* GetData();
/**
* 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.
*/
static size_t ComputeMinBufferSize(const gfx::IntSize& aYSize,
uint32_t aYStride,
const gfx::IntSize& aCbCrSize,
uint32_t aCbCrStride);
static size_t ComputeMinBufferSize(const gfx::IntSize& aYSize,
const gfx::IntSize& aCbCrSize);
static size_t ComputeMinBufferSize(uint32_t aSize);
protected:
YCbCrImageDataDeserializerBase(uint8_t* aData)
: mData (aData) {}
YCbCrImageDataDeserializerBase(uint8_t* aData, size_t aDataSize)
: mData (aData)
, mDataSize(aDataSize)
, mIsValid(false)
{}
void Validate();
uint8_t* mData;
size_t mDataSize;
bool mIsValid;
};
/**
@ -95,16 +116,12 @@ protected:
class MOZ_STACK_CLASS YCbCrImageDataSerializer : public YCbCrImageDataDeserializerBase
{
public:
YCbCrImageDataSerializer(uint8_t* aData) : YCbCrImageDataDeserializerBase(aData) {}
/**
* 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.
*/
static size_t ComputeMinBufferSize(const gfx::IntSize& aYSize,
const gfx::IntSize& aCbCrSize);
static size_t ComputeMinBufferSize(uint32_t aSize);
YCbCrImageDataSerializer(uint8_t* aData, size_t aDataSize)
: YCbCrImageDataDeserializerBase(aData, aDataSize)
{
// a serializer needs to be usable before correct buffer info has been written to it
mIsValid = !!mData;
}
/**
* Write the image informations in the buffer for given dimensions.
@ -149,7 +166,11 @@ public:
class MOZ_STACK_CLASS YCbCrImageDataDeserializer : public YCbCrImageDataDeserializerBase
{
public:
YCbCrImageDataDeserializer(uint8_t* aData) : YCbCrImageDataDeserializerBase(aData) {}
YCbCrImageDataDeserializer(uint8_t* aData, size_t aDataSize)
: YCbCrImageDataDeserializerBase(aData, aDataSize)
{
Validate();
}
/**
* Convert the YCbCr data into RGB and return a DataSourceSurface.

Просмотреть файл

@ -180,7 +180,8 @@ public:
bool ConvertImageToRGB(const SurfaceDescriptor& aImage)
{
YCbCrImageDataDeserializer deserializer(aImage.get_YCbCrImage().data().get<uint8_t>());
YCbCrImageDataDeserializer deserializer(aImage.get_YCbCrImage().data().get<uint8_t>(),
aImage.get_YCbCrImage().data().Size<uint8_t>());
PlanarYCbCrData data;
DeserializerToPlanarYCbCrImageData(deserializer, data);

Просмотреть файл

@ -617,7 +617,7 @@ BufferTextureClient::UpdateYCbCr(const PlanarYCbCrData& aData)
MOZ_ASSERT(IsValid());
MOZ_ASSERT(aData.mCbSkip == aData.mCrSkip);
YCbCrImageDataSerializer serializer(GetBuffer());
YCbCrImageDataSerializer serializer(GetBuffer(), GetBufferSize());
MOZ_ASSERT(serializer.IsValid());
if (!serializer.CopyData(aData.mYChannel, aData.mCbChannel, aData.mCrChannel,
aData.mYSize, aData.mYStride,
@ -647,7 +647,7 @@ BufferTextureClient::AllocateForYCbCr(gfx::IntSize aYSize,
if (!Allocate(bufSize)) {
return false;
}
YCbCrImageDataSerializer serializer(GetBuffer());
YCbCrImageDataSerializer serializer(GetBuffer(), GetBufferSize());
serializer.InitializeBufferInfo(aYSize,
aCbCrSize,
aStereoMode);
@ -970,7 +970,7 @@ AutoLockYCbCrClient::Update(PlanarYCbCrImage* aImage)
ipc::Shmem& shmem = mDescriptor->get_YCbCrImage().data();
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>(), shmem.Size<uint8_t>());
if (!serializer.CopyData(data->mYChannel, data->mCbChannel, data->mCrChannel,
data->mYSize, data->mYStride,
data->mCbCrSize, data->mCbCrStride,
@ -999,7 +999,7 @@ bool AutoLockYCbCrClient::EnsureDeprecatedTextureClient(PlanarYCbCrImage* aImage
needsAllocation = true;
} else {
ipc::Shmem& shmem = mDescriptor->get_YCbCrImage().data();
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>(), shmem.Size<uint8_t>());
if (serializer.GetYSize() != data->mYSize ||
serializer.GetCbCrSize() != data->mCbCrSize) {
needsAllocation = true;
@ -1020,7 +1020,7 @@ bool AutoLockYCbCrClient::EnsureDeprecatedTextureClient(PlanarYCbCrImage* aImage
return false;
}
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>());
YCbCrImageDataSerializer serializer(shmem.get<uint8_t>(), shmem.Size<uint8_t>());
serializer.InitializeBufferInfo(data->mYSize,
data->mCbCrSize,
data->mStereoMode);

Просмотреть файл

@ -494,7 +494,7 @@ BufferTextureHost::Upload(nsIntRegion *aRegion)
NS_WARNING("BufferTextureHost: unsupported format!");
return false;
} else if (mFormat == gfx::SurfaceFormat::YUV) {
YCbCrImageDataDeserializer yuvDeserializer(GetBuffer());
YCbCrImageDataDeserializer yuvDeserializer(GetBuffer(), GetBufferSize());
MOZ_ASSERT(yuvDeserializer.IsValid());
if (!mCompositor->SupportsEffect(EFFECT_YCBCR)) {
@ -585,7 +585,7 @@ BufferTextureHost::GetAsSurface()
NS_WARNING("BufferTextureHost: unsupported format!");
return nullptr;
} else if (mFormat == gfx::SurfaceFormat::YUV) {
YCbCrImageDataDeserializer yuvDeserializer(GetBuffer());
YCbCrImageDataDeserializer yuvDeserializer(GetBuffer(), GetBufferSize());
if (!yuvDeserializer.IsValid()) {
return nullptr;
}

Просмотреть файл

@ -896,7 +896,8 @@ DeprecatedTextureHostYCbCrD3D11::UpdateImpl(const SurfaceDescriptor& aImage,
{
MOZ_ASSERT(aImage.type() == SurfaceDescriptor::TYCbCrImage);
YCbCrImageDataDeserializer yuvDeserializer(aImage.get_YCbCrImage().data().get<uint8_t>());
YCbCrImageDataDeserializer yuvDeserializer(aImage.get_YCbCrImage().data().get<uint8_t>(),
aImage.get_YCbCrImage().data().Size<uint8_t>());
gfx::IntSize gfxCbCrSize = yuvDeserializer.GetCbCrSize();

Просмотреть файл

@ -442,7 +442,8 @@ DeprecatedTextureHostYCbCrD3D9::UpdateImpl(const SurfaceDescriptor& aImage,
return;
}
YCbCrImageDataDeserializer yuvDeserializer(aImage.get_YCbCrImage().data().get<uint8_t>());
YCbCrImageDataDeserializer yuvDeserializer(aImage.get_YCbCrImage().data().get<uint8_t>(),
aImage.get_YCbCrImage().data().Size<uint8_t>());
mSize = yuvDeserializer.GetYSize();
IntSize cbCrSize = yuvDeserializer.GetCbCrSize();

Просмотреть файл

@ -125,7 +125,7 @@ SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
mData.mCbCrSize);
mSize = mData.mPicSize;
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
mData.mYChannel = serializer.GetYData();
mData.mCbChannel = serializer.GetCbData();
mData.mCrChannel = serializer.GetCrData();
@ -148,7 +148,7 @@ SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
// update buffer size
mBufferSize = size;
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
return serializer.GetData();
}
@ -163,7 +163,7 @@ SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
* with AllocateAndGetNewBuffer(), that we subtract from the Y, Cb, Cr
* channels to compute 0-based offsets to pass to InitializeBufferInfo.
*/
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
uint8_t *base = serializer.GetData();
uint32_t yOffset = aData.mYChannel - base;
uint32_t cbOffset = aData.mCbChannel - base;
@ -207,7 +207,7 @@ SharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
return false;
}
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer());
YCbCrImageDataSerializer serializer(mTextureClient->GetBuffer(), mTextureClient->GetBufferSize());
serializer.InitializeBufferInfo(aData.mYSize,
aData.mCbCrSize,
aData.mStereoMode);
@ -258,7 +258,7 @@ DeprecatedSharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
mData.mCbCrSize);
mSize = mData.mPicSize;
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>(), mShmem.Size<uint8_t>());
MOZ_ASSERT(aData.mCbSkip == aData.mCrSkip);
if (!serializer.CopyData(aData.mYChannel, aData.mCbChannel, aData.mCrChannel,
aData.mYSize, aData.mYStride,
@ -287,7 +287,7 @@ DeprecatedSharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
// update buffer size
mBufferSize = size;
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>(), mShmem.Size<uint8_t>());
return serializer.GetData();
}
@ -296,7 +296,7 @@ DeprecatedSharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
{
mData = aData;
mSize = aData.mPicSize;
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>(), mShmem.Size<uint8_t>());
serializer.InitializeBufferInfo(aData.mYSize,
aData.mCbCrSize,
aData.mStereoMode);
@ -327,7 +327,7 @@ DeprecatedSharedPlanarYCbCrImage::Allocate(PlanarYCbCrData& aData)
return false;
}
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>());
YCbCrImageDataSerializer serializer(mShmem.get<uint8_t>(), mShmem.Size<uint8_t>());
serializer.InitializeBufferInfo(aData.mYSize,
aData.mCbCrSize,
aData.mStereoMode);

Просмотреть файл

@ -181,7 +181,7 @@ void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) {
// This will work iff the compositor is not BasicCompositor
ASSERT_EQ(host->GetFormat(), mozilla::gfx::SurfaceFormat::YUV);
YCbCrImageDataDeserializer yuvDeserializer(host->GetBuffer());
YCbCrImageDataDeserializer yuvDeserializer(host->GetBuffer(), host->GetBufferSize());
ASSERT_TRUE(yuvDeserializer.IsValid());
PlanarYCbCrData data;
data.mYChannel = yuvDeserializer.GetYData();