Bug 1219330 - Handle PlanaYCbCrImage::SetData failure. r=jya, jesup

This commit is contained in:
Nicolas Silva 2015-11-03 12:24:26 +01:00
parent c1d1624064
commit 1ebb1e2bb7
13 changed files with 72 additions and 47 deletions

View File

@ -198,14 +198,14 @@ VideoData::ShallowCopyUpdateTimestampAndDuration(const VideoData* aOther,
}
/* static */
void VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
const VideoInfo& aInfo,
const YCbCrBuffer &aBuffer,
const IntRect& aPicture,
bool aCopyData)
{
if (!aVideoImage) {
return;
return false;
}
const YCbCrBuffer::Plane &Y = aBuffer.mPlanes[0];
const YCbCrBuffer::Plane &Cb = aBuffer.mPlanes[1];
@ -229,9 +229,9 @@ void VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
aVideoImage->SetDelayedConversion(true);
if (aCopyData) {
aVideoImage->SetData(data);
return aVideoImage->SetData(data);
} else {
aVideoImage->SetDataNoCopy(data);
return aVideoImage->SetDataNoCopy(data);
}
}
@ -330,12 +330,10 @@ VideoData::Create(const VideoInfo& aInfo,
"Wrong format?");
PlanarYCbCrImage* videoImage = static_cast<PlanarYCbCrImage*>(v->mImage.get());
if (!aImage) {
VideoData::SetVideoDataToImage(videoImage, aInfo, aBuffer, aPicture,
true /* aCopyData */);
} else {
VideoData::SetVideoDataToImage(videoImage, aInfo, aBuffer, aPicture,
false /* aCopyData */);
bool shouldCopyData = (aImage == nullptr);
if (!VideoData::SetVideoDataToImage(videoImage, aInfo, aBuffer, aPicture,
shouldCopyData)) {
return nullptr;
}
#ifdef MOZ_WIDGET_GONK
@ -346,8 +344,10 @@ VideoData::Create(const VideoInfo& aInfo,
return nullptr;
}
videoImage = static_cast<PlanarYCbCrImage*>(v->mImage.get());
VideoData::SetVideoDataToImage(videoImage, aInfo, aBuffer, aPicture,
true /* aCopyData */);
if(!VideoData::SetVideoDataToImage(videoImage, aInfo, aBuffer, aPicture,
true /* aCopyData */)) {
return nullptr;
}
}
#endif
return v.forget();
@ -473,7 +473,9 @@ VideoData::Create(const VideoInfo& aInfo,
data.mPicSize = aPicture.Size();
data.mGraphicBuffer = aBuffer;
videoImage->SetData(data);
if (!videoImage->SetData(data)) {
return nullptr;
}
return v.forget();
}

View File

@ -283,7 +283,7 @@ public:
// Initialize PlanarYCbCrImage. Only When aCopyData is true,
// video data is copied to PlanarYCbCrImage.
static void SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
static bool SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
const VideoInfo& aInfo,
const YCbCrBuffer &aBuffer,
const IntRect& aPicture,

View File

@ -80,7 +80,10 @@ VideoFrame::CreateBlackImage(const gfx::IntSize& aSize)
data.mStereoMode = StereoMode::MONO;
// SetData copies data, so we can free data.
planar->SetData(data);
if (!planar->SetData(data)) {
MOZ_ASSERT(false);
return nullptr;
}
return image.forget();
}

View File

@ -250,10 +250,16 @@ MediaEngineDefaultVideoSource::Notify(nsITimer* aTimer)
0, 0);
#endif
ycbcr_image->SetData(data);
bool setData = ycbcr_image->SetData(data);
MOZ_ASSERT(setData);
// SetData copies data, so we can free the frame
ReleaseFrame(data);
if (!setData) {
return NS_ERROR_FAILURE;
}
MonitorAutoLock lock(mMonitor);
// implicitly releases last image

View File

@ -315,7 +315,10 @@ MediaEngineRemoteVideoSource::DeliverFrame(unsigned char* buffer,
data.mPicSize = IntSize(mWidth, mHeight);
data.mStereoMode = StereoMode::MONO;
videoImage->SetData(data);
if (!videoImage->SetData(data)) {
MOZ_ASSERT(false);
return 0;
}
#ifdef DEBUG
static uint32_t frame_num = 0;

View File

@ -57,7 +57,7 @@ GrallocImage::~GrallocImage()
{
}
void
bool
GrallocImage::SetData(const Data& aData)
{
MOZ_ASSERT(!mTextureClient, "TextureClient is already set");
@ -70,7 +70,7 @@ GrallocImage::SetData(const Data& aData)
if (gfxPlatform::GetPlatform()->IsInGonkEmulator()) {
// Emulator does not support HAL_PIXEL_FORMAT_YV12.
return;
return false;
}
RefPtr<GrallocTextureClientOGL> textureClient =
@ -88,7 +88,7 @@ GrallocImage::SetData(const Data& aData)
sp<GraphicBuffer> graphicBuffer = textureClient->GetGraphicBuffer();
if (!result || !graphicBuffer.get()) {
mTextureClient = nullptr;
return;
return false;
}
mTextureClient = textureClient;
@ -96,7 +96,7 @@ GrallocImage::SetData(const Data& aData)
void* vaddr;
if (graphicBuffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
&vaddr) != OK) {
return;
return false;
}
uint8_t* yChannel = static_cast<uint8_t*>(vaddr);
@ -144,12 +144,14 @@ GrallocImage::SetData(const Data& aData)
mData.mYChannel = nullptr;
mData.mCrChannel = nullptr;
mData.mCbChannel = nullptr;
return true;
}
void GrallocImage::SetData(const GrallocData& aData)
bool GrallocImage::SetData(const GrallocData& aData)
{
mTextureClient = static_cast<GrallocTextureClientOGL*>(aData.mGraphicBuffer.get());
mSize = aData.mPicSize;
return true;
}
/**

View File

@ -66,13 +66,13 @@ public:
* This makes a copy of the data buffers, in order to support functioning
* in all different layer managers.
*/
virtual void SetData(const Data& aData);
virtual bool SetData(const Data& aData);
/**
* Share the SurfaceDescriptor without making the copy, in order
* to support functioning in all different layer managers.
*/
virtual void SetData(const GrallocData& aData);
virtual bool SetData(const GrallocData& aData);
// From [android 4.0.4]/hardware/msm7k/libgralloc-qsd8k/gralloc_priv.h
enum {

View File

@ -484,7 +484,7 @@ CopyPlane(uint8_t *aDst, const uint8_t *aSrc,
}
}
void
bool
PlanarYCbCrImage::CopyData(const Data& aData)
{
mData = aData;
@ -496,7 +496,7 @@ PlanarYCbCrImage::CopyData(const Data& aData)
// get new buffer
mBuffer = AllocateBuffer(size);
if (!mBuffer)
return;
return false;
// update buffer size
mBufferSize = size;
@ -513,12 +513,13 @@ PlanarYCbCrImage::CopyData(const Data& aData)
mData.mCbCrSize, mData.mCbCrStride, mData.mCrSkip);
mSize = aData.mPicSize;
return true;
}
void
bool
PlanarYCbCrImage::SetData(const Data &aData)
{
CopyData(aData);
return CopyData(aData);
}
gfxImageFormat
@ -529,11 +530,12 @@ PlanarYCbCrImage::GetOffscreenFormat()
mOffscreenFormat;
}
void
bool
PlanarYCbCrImage::SetDataNoCopy(const Data &aData)
{
mData = aData;
mSize = aData.mPicSize;
return true;
}
uint8_t*

View File

@ -656,7 +656,7 @@ public:
* This makes a copy of the data buffers, in order to support functioning
* in all different layer managers.
*/
virtual void SetData(const Data& aData);
virtual bool SetData(const Data& aData);
/**
* This doesn't make a copy of the data buffers. Can be used when mBuffer is
@ -665,7 +665,7 @@ public:
* The GStreamer media backend uses this to decode into PlanarYCbCrImage(s)
* directly.
*/
virtual void SetDataNoCopy(const Data &aData);
virtual bool SetDataNoCopy(const Data &aData);
/**
* This allocates and returns a new buffer
@ -709,7 +709,7 @@ protected:
*
* @param aData Input image data.
*/
void CopyData(const Data& aData);
bool CopyData(const Data& aData);
/**
* Return a buffer to store image data in.

View File

@ -48,7 +48,7 @@ public:
}
}
virtual void SetData(const Data& aData) override;
virtual bool SetData(const Data& aData) override;
virtual void SetDelayedConversion(bool aDelayed) override { mDelayedConversion = aDelayed; }
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
@ -91,20 +91,20 @@ public:
}
};
void
bool
BasicPlanarYCbCrImage::SetData(const Data& aData)
{
PlanarYCbCrImage::SetData(aData);
if (mDelayedConversion) {
return;
return false;
}
// Do some sanity checks to prevent integer overflow
if (aData.mYSize.width > PlanarYCbCrImage::MAX_DIMENSION ||
aData.mYSize.height > PlanarYCbCrImage::MAX_DIMENSION) {
NS_ERROR("Illegal image source width or height");
return;
return false;
}
gfx::SurfaceFormat format = gfx::ImageFormatToSurfaceFormat(GetOffscreenFormat());
@ -114,7 +114,7 @@ BasicPlanarYCbCrImage::SetData(const Data& aData)
if (size.width > PlanarYCbCrImage::MAX_DIMENSION ||
size.height > PlanarYCbCrImage::MAX_DIMENSION) {
NS_ERROR("Illegal image dest width or height");
return;
return false;
}
gfxImageFormat iFormat = gfx::SurfaceFormatToImageFormat(format);
@ -122,12 +122,14 @@ BasicPlanarYCbCrImage::SetData(const Data& aData)
mDecodedBuffer = AllocateBuffer(size.height * mStride);
if (!mDecodedBuffer) {
// out of memory
return;
return false;
}
gfx::ConvertYCbCrToRGB(aData, format, size, mDecodedBuffer, mStride);
SetOffscreenFormat(iFormat);
mSize = size;
return true;
}
already_AddRefed<gfx::SourceSurface>

View File

@ -80,7 +80,7 @@ SharedPlanarYCbCrImage::GetAsSourceSurface()
return PlanarYCbCrImage::GetAsSourceSurface();
}
void
bool
SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
{
// If mTextureClient has not already been allocated (through Allocate(aData))
@ -88,20 +88,21 @@ SharedPlanarYCbCrImage::SetData(const PlanarYCbCrData& aData)
// been called since it will trigger a full copy.
PlanarYCbCrData data = aData;
if (!mTextureClient && !Allocate(data)) {
return;
return false;
}
MOZ_ASSERT(mTextureClient->AsTextureClientYCbCr());
if (!mTextureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) {
MOZ_ASSERT(false, "Failed to lock the texture.");
return;
return false;
}
TextureClientAutoUnlock unlock(mTextureClient);
if (!mTextureClient->AsTextureClientYCbCr()->UpdateYCbCr(aData)) {
MOZ_ASSERT(false, "Failed to copy YCbCr data into the TextureClient");
return;
return false;
}
mTextureClient->MarkImmutable();
return true;
}
// needs to be overriden because the parent class sets mBuffer which we
@ -131,12 +132,12 @@ SharedPlanarYCbCrImage::AllocateAndGetNewBuffer(uint32_t aSize)
return serializer.GetData();
}
void
bool
SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
{
MOZ_ASSERT(mTextureClient, "This Image should have already allocated data");
if (!mTextureClient) {
return;
return false;
}
mData = aData;
mSize = aData.mPicSize;
@ -159,6 +160,7 @@ SharedPlanarYCbCrImage::SetDataNoCopy(const Data &aData)
aData.mYSize,
aData.mCbCrSize,
aData.mStereoMode);
return true;
}
uint8_t*

View File

@ -35,8 +35,8 @@ public:
virtual uint8_t* GetBuffer() override;
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
virtual void SetData(const PlanarYCbCrData& aData) override;
virtual void SetDataNoCopy(const Data &aData) override;
virtual bool SetData(const PlanarYCbCrData& aData) override;
virtual bool SetDataNoCopy(const Data &aData) override;
virtual bool Allocate(PlanarYCbCrData& aData);
virtual uint8_t* AllocateBuffer(uint32_t aSize) override;

View File

@ -1501,7 +1501,10 @@ void MediaPipelineReceiveVideo::PipelineListener::RenderVideoFrame(
yuvData.mPicSize = IntSize(width_, height_);
yuvData.mStereoMode = StereoMode::MONO;
yuvImage->SetData(yuvData);
if (!yuvImage->SetData(yuvData)) {
MOZ_ASSERT(false);
return;
}
image_ = image.forget();
}