Bug 1960639 - Fix YU12/YV12 confusion in V4L2 decode r=stransky,media-playback-reviewers,aosmond
The V4L2 code in FFmpegDescToVA erroneously stored YUV420 as VA_FOURCC_YV12, but actually it should be VA_FOURCC_I420 (YV12 is for YVU420, not YUV420). This didn't make any difference when the format conversion was done by the GPU in Firefox's compositor, but now we're exporting YUV dmabufs (webrender-compositor and hdr mode), this causes colors to appear incorrect. Also, DmaBufSurface.mFOURCCFormat is stored as a VA_FOURCC_* enum, but the format passed to zwp_linux_buffer_params_v1::create_immed needs to be a DRM_FORMAT_* enum, so add a conversion in CreateWlBuffer(). Differential Revision: https://phabricator.services.mozilla.com/D245574
This commit is contained in:
committed by
david.turner@raspberrypi.com
parent
186b5eaa63
commit
b315f24a48
@@ -346,7 +346,7 @@ static Maybe<VADRMPRIMESurfaceDescriptor> FFmpegDescToVA(
|
||||
unsigned int offset = aDesc.layers[0].planes[0].offset;
|
||||
|
||||
if (aDesc.layers[0].format == DRM_FORMAT_YUV420) {
|
||||
vaDesc.fourcc = VA_FOURCC_YV12;
|
||||
vaDesc.fourcc = VA_FOURCC_I420;
|
||||
|
||||
// V4L2 expresses YUV420 as a single contiguous buffer containing
|
||||
// all three planes. DMABufSurfaceYUV expects the three planes
|
||||
|
||||
@@ -34,6 +34,13 @@
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
// DMABufLibWrapper defines its own version of this which collides with the
|
||||
// official version in drm_fourcc.h
|
||||
#ifdef DRM_FORMAT_MOD_INVALID
|
||||
# undef DRM_FORMAT_MOD_INVALID
|
||||
#endif
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
|
||||
#include "mozilla/widget/va_drmcommon.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/FileHandleWrapper.h"
|
||||
@@ -2028,9 +2035,10 @@ gfx::SurfaceFormat DMABufSurfaceYUV::GetFormat() {
|
||||
case VA_FOURCC_NV12:
|
||||
return gfx::SurfaceFormat::NV12;
|
||||
case VA_FOURCC_YV12:
|
||||
case VA_FOURCC_I420:
|
||||
return gfx::SurfaceFormat::YUV420;
|
||||
default:
|
||||
gfxCriticalNoteOnce << "DMABufSurfaceYUV::GetFormat() unknow format: "
|
||||
gfxCriticalNoteOnce << "DMABufSurfaceYUV::GetFormat() unknown format: "
|
||||
<< mFOURCCFormat;
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
@@ -2153,11 +2161,18 @@ wl_buffer* DMABufSurfaceYUV::CreateWlBuffer() {
|
||||
mBufferModifiers[i] >> 32, mBufferModifiers[i] & 0xffffffff);
|
||||
}
|
||||
|
||||
// The format passed to wayland needs to be a DRM_FORMAT_* enum. These are
|
||||
// largely the same as VA_FOURCC_* values except for I420/YUV420
|
||||
uint32_t format = GetFOURCCFormat();
|
||||
if (format == VA_FOURCC_I420) {
|
||||
format = DRM_FORMAT_YUV420;
|
||||
}
|
||||
|
||||
LOGDMABUF(
|
||||
" zwp_linux_buffer_params_v1_create_immed() [%d x %d], fourcc [%x]",
|
||||
GetWidth(), GetHeight(), GetFOURCCFormat());
|
||||
GetWidth(), GetHeight(), format);
|
||||
wl_buffer* buffer = zwp_linux_buffer_params_v1_create_immed(
|
||||
params, GetWidth(), GetHeight(), GetFOURCCFormat(), 0);
|
||||
params, GetWidth(), GetHeight(), format, 0);
|
||||
if (!buffer) {
|
||||
LOGDMABUF(
|
||||
" zwp_linux_buffer_params_v1_create_immed(): failed to create "
|
||||
|
||||
@@ -30,6 +30,9 @@ typedef void* EGLSyncKHR;
|
||||
#ifndef VA_FOURCC_NV12
|
||||
# define VA_FOURCC_NV12 0x3231564E
|
||||
#endif
|
||||
#ifndef VA_FOURCC_I420
|
||||
# define VA_FOURCC_I420 0x30323449
|
||||
#endif
|
||||
#ifndef VA_FOURCC_YV12
|
||||
# define VA_FOURCC_YV12 0x32315659
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user