From 4f178d08de674e51b08923fcda8b503a1264f919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= Date: Wed, 23 Oct 2019 08:57:40 +0200 Subject: [PATCH] Fix gtk color-space conversion in peerconnection_client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:6857 Change-Id: I3fc95237cc699569d165a3286e96422c77913cbf Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/158080 Reviewed-by: Kári Helgason Commit-Queue: Niels Moller Cr-Commit-Position: refs/heads/master@{#29585} --- .../peerconnection/client/linux/main_wnd.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/examples/peerconnection/client/linux/main_wnd.cc b/examples/peerconnection/client/linux/main_wnd.cc index 001172ce58..6b940ea108 100644 --- a/examples/peerconnection/client/linux/main_wnd.cc +++ b/examples/peerconnection/client/linux/main_wnd.cc @@ -504,7 +504,7 @@ void GtkMainWnd::OnRedraw() { void GtkMainWnd::Draw(GtkWidget* widget, cairo_t* cr) { #if GTK_MAJOR_VERSION != 2 - cairo_format_t format = CAIRO_FORMAT_RGB24; + cairo_format_t format = CAIRO_FORMAT_ARGB32; cairo_surface_t* surface = cairo_image_surface_create_for_data( draw_buffer_.get(), format, width_ * 2, height_ * 2, cairo_format_stride_for_width(format, width_ * 2)); @@ -554,13 +554,14 @@ void GtkMainWnd::VideoRenderer::OnFrame(const webrtc::VideoFrame& video_frame) { } SetSize(buffer->width(), buffer->height()); - // The order in the name of libyuv::I420To(ABGR,RGBA) is ambiguous because - // it doesn't tell you if it is referring to how it is laid out in memory as - // bytes or if endiannes is taken into account. - // This was supposed to be a call to libyuv::I420ToRGBA but it was resulting - // in a reddish video output (see https://bugs.webrtc.org/6857) because it - // was producing an unexpected byte order (ABGR, byte swapped). - libyuv::I420ToABGR(buffer->DataY(), buffer->StrideY(), buffer->DataU(), + // TODO(bugs.webrtc.org/6857): This conversion is correct for little-endian + // only. Cairo ARGB32 treats pixels as 32-bit values in *native* byte order, + // with B in the least significant byte of the 32-bit value. Which on + // little-endian means that memory layout is BGRA, with the B byte stored at + // lowest address. Libyuv's ARGB format (surprisingly?) uses the same + // little-endian format, with B in the first byte in memory, regardless of + // native endianness. + libyuv::I420ToARGB(buffer->DataY(), buffer->StrideY(), buffer->DataU(), buffer->StrideU(), buffer->DataV(), buffer->StrideV(), image_.get(), width_ * 4, buffer->width(), buffer->height());