mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 997593 - Add more color conversion code to support encoding QCOM Venus NV12 images. r=roc
This commit is contained in:
parent
716b37bff9
commit
f0b0c7c2ab
@ -199,14 +199,6 @@ VideoTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
|
||||
if (!chunk.IsNull()) {
|
||||
gfx::IntSize imgsize = chunk.mFrame.GetImage()->GetSize();
|
||||
gfxIntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize();
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// Block the video frames come from video source.
|
||||
if (chunk.mFrame.GetImage()->GetFormat() != ImageFormat::PLANAR_YCBCR) {
|
||||
LOG("Can't encode this ImageFormat %x", chunk.mFrame.GetImage()->GetFormat());
|
||||
NotifyCancel();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
nsresult rv = Init(imgsize.width, imgsize.height,
|
||||
intrinsicSize.width, intrinsicSize.height,
|
||||
aTrackRate);
|
||||
|
@ -299,9 +299,10 @@ ConvertPlanarYCbCrToNV12(const PlanarYCbCrData* aSource, uint8_t* aDestination)
|
||||
|
||||
// Convert pixels in graphic buffer to NV12 format. aSource is the layer image
|
||||
// containing source graphic buffer, and aDestination is the destination of
|
||||
// conversion. Currently only 2 source format are supported:
|
||||
// conversion. Currently 3 source format are supported:
|
||||
// - NV21/HAL_PIXEL_FORMAT_YCrCb_420_SP (from camera preview window).
|
||||
// - YV12/HAL_PIXEL_FORMAT_YV12 (from video decoder).
|
||||
// - QCOM proprietary/HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS (from Flame HW video decoder)
|
||||
static void
|
||||
ConvertGrallocImageToNV12(GrallocImage* aSource, uint8_t* aDestination)
|
||||
{
|
||||
@ -309,9 +310,6 @@ ConvertGrallocImageToNV12(GrallocImage* aSource, uint8_t* aDestination)
|
||||
sp<GraphicBuffer> graphicBuffer = aSource->GetGraphicBuffer();
|
||||
|
||||
int pixelFormat = graphicBuffer->getPixelFormat();
|
||||
// Only support NV21 (from camera) or YV12 (from HW decoder output) for now.
|
||||
NS_ENSURE_TRUE_VOID(pixelFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
|
||||
pixelFormat == HAL_PIXEL_FORMAT_YV12);
|
||||
|
||||
void* imgPtr = nullptr;
|
||||
graphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_MASK, &imgPtr);
|
||||
@ -353,6 +351,26 @@ ConvertGrallocImageToNV12(GrallocImage* aSource, uint8_t* aDestination)
|
||||
yuv.mCbSkip = 0;
|
||||
ConvertPlanarYCbCrToNV12(&yuv, aDestination);
|
||||
break;
|
||||
// From QCOM video decoder on Flame. See bug 997593.
|
||||
case GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
|
||||
// Venus formats are doucmented in kernel/include/media/msm_media_info.h:
|
||||
yuv.mYChannel = static_cast<uint8_t*>(imgPtr);
|
||||
yuv.mYSkip = 0;
|
||||
yuv.mYSize.width = graphicBuffer->getWidth();
|
||||
yuv.mYSize.height = graphicBuffer->getHeight();
|
||||
// - Y & UV Width aligned to 128
|
||||
yuv.mYStride = (yuv.mYSize.width + 127) & ~127;
|
||||
yuv.mCbCrSize.width = yuv.mYSize.width / 2;
|
||||
yuv.mCbCrSize.height = yuv.mYSize.height / 2;
|
||||
// - Y height aligned to 32
|
||||
yuv.mCbChannel = yuv.mYChannel + (yuv.mYStride * ((yuv.mYSize.height + 31) & ~31));
|
||||
// Interleaved VU plane.
|
||||
yuv.mCbSkip = 1;
|
||||
yuv.mCrChannel = yuv.mCbChannel + 1;
|
||||
yuv.mCrSkip = 1;
|
||||
yuv.mCbCrStride = yuv.mYStride;
|
||||
ConvertPlanarYCbCrToNV12(&yuv, aDestination);
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Unsupported input gralloc image type. Should never be here.");
|
||||
}
|
||||
@ -369,6 +387,31 @@ OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
|
||||
NS_ENSURE_TRUE(aWidth == mWidth && aHeight == mHeight && aTimestamp >= 0,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
Image* img = const_cast<Image*>(aImage);
|
||||
ImageFormat format = ImageFormat::PLANAR_YCBCR;
|
||||
if (img) {
|
||||
format = img->GetFormat();
|
||||
gfx::IntSize size = img->GetSize();
|
||||
// Validate input image.
|
||||
NS_ENSURE_TRUE(aWidth == size.width, NS_ERROR_INVALID_ARG);
|
||||
NS_ENSURE_TRUE(aHeight == size.height, NS_ERROR_INVALID_ARG);
|
||||
if (format == ImageFormat::PLANAR_YCBCR) {
|
||||
NS_ENSURE_TRUE(static_cast<PlanarYCbCrImage*>(img)->IsValid(),
|
||||
NS_ERROR_INVALID_ARG);
|
||||
} else if (format == ImageFormat::GRALLOC_PLANAR_YCBCR) {
|
||||
// Reject unsupported gralloc-ed buffers.
|
||||
int halFormat = static_cast<GrallocImage*>(img)->GetGraphicBuffer()->getPixelFormat();
|
||||
NS_ENSURE_TRUE(halFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP ||
|
||||
halFormat == HAL_PIXEL_FORMAT_YV12 ||
|
||||
halFormat == GrallocImage::HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS,
|
||||
NS_ERROR_INVALID_ARG);
|
||||
} else {
|
||||
// TODO: support RGB to YUV color conversion.
|
||||
NS_ERROR("Unsupported input image type.");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
status_t result;
|
||||
|
||||
// Dequeue an input buffer.
|
||||
@ -385,30 +428,20 @@ OMXVideoEncoder::Encode(const Image* aImage, int aWidth, int aHeight,
|
||||
// Buffer should be large enough to hold input image data.
|
||||
MOZ_ASSERT(dstSize >= yLen + uvLen);
|
||||
|
||||
inBuf->setRange(0, yLen + uvLen);
|
||||
|
||||
if (!aImage) {
|
||||
dstSize = yLen + uvLen;
|
||||
inBuf->setRange(0, dstSize);
|
||||
if (!img) {
|
||||
// Generate muted/black image directly in buffer.
|
||||
dstSize = yLen + uvLen;
|
||||
// Fill Y plane.
|
||||
memset(dst, 0x10, yLen);
|
||||
// Fill UV plane.
|
||||
memset(dst + yLen, 0x80, uvLen);
|
||||
} else {
|
||||
Image* img = const_cast<Image*>(aImage);
|
||||
ImageFormat format = img->GetFormat();
|
||||
|
||||
MOZ_ASSERT(aWidth == img->GetSize().width &&
|
||||
aHeight == img->GetSize().height);
|
||||
|
||||
if (format == ImageFormat::GRALLOC_PLANAR_YCBCR) {
|
||||
ConvertGrallocImageToNV12(static_cast<GrallocImage*>(img), dst);
|
||||
} else if (format == ImageFormat::PLANAR_YCBCR) {
|
||||
ConvertPlanarYCbCrToNV12(static_cast<PlanarYCbCrImage*>(img)->GetData(),
|
||||
dst);
|
||||
} else {
|
||||
// TODO: support RGB to YUV color conversion.
|
||||
NS_ERROR("Unsupported input image type.");
|
||||
dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user