/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
staticinline uint16_t safeShift10BitBy6(const uint16_t& a10BitLSB) { // a10BitLSB is a 10-bit value packed into the least significant bits of // a 16 bit value. This function asserts that the 6 MSBs are zero, then // shifts the 10 LSBs by 6 to become the MSBs.
MOZ_ASSERT((a10BitLSB & 0b1111'1100'0000'0000) == 0); return a10BitLSB << 6;
}
// We can only support 4:2:2 and 4:2:0 formats currently. switch (aData.mChromaSubsampling) { case ChromaSubsampling::HALF_WIDTH: case ChromaSubsampling::HALF_WIDTH_AND_HEIGHT: break; default: returnfalse;
}
auto ySize = aData.YDataSize(); auto cbcrSize = aData.CbCrDataSize();
RefPtr<MacIOSurface> surf = allocator->Allocate(
ySize, cbcrSize, aData.mChromaSubsampling, aData.mYUVColorSpace,
aData.mTransferFunction, aData.mColorRange, aData.mColorDepth);
if (NS_WARN_IF(!surf) || NS_WARN_IF(!surf->Lock(false))) { returnfalse;
}
if (surf->GetFormat() == SurfaceFormat::YUY2) { // If the CbCrSize's height is half of the YSize's height, then we'll // need to duplicate the CbCr data on every second row.
size_t heightScale = ySize.height / cbcrSize.height;
// The underlying IOSurface has format // kCVPixelFormatType_422YpCbCr8FullRange or // kCVPixelFormatType_422YpCbCr8_yuvs, which uses a 4:2:2 Y`0 Cb Y`1 Cr // layout. See CVPixelBuffer.h for the full list of format descriptions.
MOZ_ASSERT(ySize.height > 0);
uint8_t* dst = (uint8_t*)surf->GetBaseAddressOfPlane(0);
size_t stride = surf->GetBytesPerRow(0); for (size_t i = 0; i < (size_t)ySize.height; i++) { // Compute the row addresses. If the input was 4:2:0, then // we divide i by 2, so that each source row of CbCr maps to // two dest rows.
uint8_t* rowYSrc = aData.mYChannel + aData.mYStride * i;
uint8_t* rowCbSrc =
aData.mCbChannel + aData.mCbCrStride * (i / heightScale);
uint8_t* rowCrSrc =
aData.mCrChannel + aData.mCbCrStride * (i / heightScale);
uint8_t* rowDst = dst + stride * i;
// Iterate across the CbCr width (which we have guaranteed to be half of // the surface width), and write two 16bit pixels each time. for (size_t j = 0; j < (size_t)cbcrSize.width; j++) {
*rowDst = *rowYSrc;
rowDst++;
rowYSrc++;
// Time to decide if we are creating a single planar or bi-planar surface. // We limit ourselves to macOS's single planar and bi-planar formats for // simplicity reasons, possibly gaining some small memory or performance // benefit relative to the tri-planar formats. We try and use as few // planes as possible. // 4:2:0 formats are always bi-planar, because there is no 4:2:0 single // planar format. // 4:2:2 formats with 8 bit color are single planar, otherwise bi-planar.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.