зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
0f2fbc9d88
Коммит
5d1c0dea05
|
@ -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();
|
||||
|
|
Загрузка…
Ссылка в новой задаче