Bug 1248323: P2. Add readback code for converting YUV422 MacIOSurfaces into RGB. r=nical

MozReview-Commit-ID: 4jhP5fgXZhq

--HG--
extra : rebase_source : 3746097a71746723de541b1a7fb1b8971e914075
This commit is contained in:
Jean-Yves Avenard 2016-02-23 23:47:29 +11:00
Родитель 0f2fbc9d88
Коммит 5d1c0dea05
1 изменённых файлов: 62 добавлений и 3 удалений

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

@ -13,6 +13,9 @@ using namespace gfx;
namespace layers {
#define ALIGNED_32(x) ((x+31)&~31)
#define ALIGNEDPTR_32(x) reinterpret_cast<uint8_t*>((reinterpret_cast<uintptr_t>(x)+31)&~31)
static already_AddRefed<SourceSurface>
CreateSourceSurfaceFromLockedMacIOSurface(MacIOSurface* aSurface)
{
@ -21,13 +24,16 @@ CreateSourceSurfaceFromLockedMacIOSurface(MacIOSurface* aSurface)
size_t ioHeight = aSurface->GetDevicePixelHeight();
SurfaceFormat ioFormat = aSurface->GetFormat();
if (ioFormat == SurfaceFormat::NV12 &&
if ((ioFormat == SurfaceFormat::NV12 || ioFormat == SurfaceFormat::YUV422) &&
(ioWidth > PlanarYCbCrImage::MAX_DIMENSION ||
ioHeight > PlanarYCbCrImage::MAX_DIMENSION)) {
return nullptr;
}
SurfaceFormat format = ioFormat == SurfaceFormat::NV12 ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8;
SurfaceFormat format =
(ioFormat == SurfaceFormat::NV12 || ioFormat == SurfaceFormat::YUV422)
? SurfaceFormat::B8G8R8X8
: SurfaceFormat::B8G8R8A8;
RefPtr<DataSourceSurface> dataSurface =
Factory::CreateDataSourceSurface(IntSize(ioWidth, ioHeight), format);
@ -69,13 +75,66 @@ CreateSourceSurfaceFromLockedMacIOSurface(MacIOSurface* aSurface)
PlanarYCbCrData data;
data.mYChannel = (uint8_t*)aSurface->GetBaseAddressOfPlane(0);
data.mYStride = aSurface->GetBytesPerRow(0);
data.mYSize = IntSize(aSurface->GetDevicePixelWidth(0), aSurface->GetDevicePixelHeight(0));
data.mYSize = IntSize(ioWidth, ioHeight);
data.mCbChannel = cbPlane.get();
data.mCrChannel = crPlane.get();
data.mCbCrStride = cbCrWidth;
data.mCbCrSize = IntSize(cbCrWidth, cbCrHeight);
data.mPicSize = data.mYSize;
ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
} else if (ioFormat == SurfaceFormat::YUV422) {
/* Convert to YV16 */
size_t cbCrWidth = (ioWidth+1)>>1;
size_t cbCrHeight = ioHeight;
// Ensure our stride is a multiple of 32 to allow for memory aligned rows.
size_t cbCrStride = ALIGNED_32(cbCrWidth);
size_t strideDelta = cbCrStride - cbCrWidth;
MOZ_ASSERT(strideDelta <= 31);
auto yPlane = MakeUnique<uint8_t[]>(cbCrStride * 2 * ioHeight + 31);
auto cbPlane = MakeUnique<uint8_t[]>(cbCrStride * cbCrHeight + 31);
auto crPlane = MakeUnique<uint8_t[]>(cbCrStride * cbCrHeight + 31);
uint8_t* src = (uint8_t*)aSurface->GetBaseAddress();
uint8_t* yDest = ALIGNEDPTR_32(yPlane.get());
uint8_t* cbDest = ALIGNEDPTR_32(cbPlane.get());
uint8_t* crDest = ALIGNEDPTR_32(crPlane.get());
for (size_t i = 0; i < ioHeight; i++) {
uint8_t* rowSrc = src + bytesPerRow * i;
for (size_t j = 0; j < cbCrWidth; j++) {
*cbDest = *rowSrc;
cbDest++;
rowSrc++;
*yDest = *rowSrc;
yDest++;
rowSrc++;
*crDest = *rowSrc;
crDest++;
rowSrc++;
*yDest = *rowSrc;
yDest++;
rowSrc++;
}
if (strideDelta) {
cbDest += strideDelta;
crDest += strideDelta;
yDest += strideDelta << 1;
}
}
/* Convert to RGB */
PlanarYCbCrData data;
data.mYChannel = ALIGNEDPTR_32(yPlane.get());
data.mYStride = cbCrStride * 2;
data.mYSize = IntSize(ioWidth, ioHeight);
data.mCbChannel = ALIGNEDPTR_32(cbPlane.get());
data.mCrChannel = ALIGNEDPTR_32(crPlane.get());
data.mCbCrStride = cbCrStride;
data.mCbCrSize = IntSize(cbCrWidth, cbCrHeight);
data.mPicSize = data.mYSize;
ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
} else {
unsigned char* ioData = (unsigned char*)aSurface->GetBaseAddress();