[{"id":12520,"web_url":"https://patchwork.libcamera.org/comment/12520/","msgid":"<CA+yuoHoY3ytmmiBH8sHmJHFWbkQiaedasXZ-wWPri3qdxOAsog@mail.gmail.com>","date":"2020-09-15T09:00:54","subject":"Re: [libcamera-devel] [PATCH v7 0/4] qcam: accelerate format\n\tconversion by OpenGL shader","submitter":{"id":24,"url":"https://patchwork.libcamera.org/api/people/24/","name":"Show Liu","email":"show.liu@linaro.org"},"content":"Hi Laurent,\n\nOn Tue, Sep 15, 2020 at 10:46 AM Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> Hello,\n>\n> This patch series is an updated version of Show's v6. I've updated the\n> patches during review as I wanted to test my review comments, and it\n> would be pointless for Show to do the same independently to post a v7.\n>\n> The series only incorporates review comments. Show, could you please let\n> me know if you're fine with the result ? To make the comparison easier,\n> here's the diff between v6 and v7.\n>\n> diff --git a/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> b/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> index 80478c5d0dd4..67633a11ee0f 100644\n> --- a/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> +++ b/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> @@ -18,10 +18,10 @@ void main(void)\n>         vec3 yuv;\n>         vec3 rgb;\n>         mat3 yuv2rgb_bt601_mat = mat3(\n> -                                     vec3(1.164,  1.164, 1.164),\n> -                                     vec3(0.000, -0.392, 2.017),\n> -                                     vec3(1.596, -0.813, 0.000)\n> -                                );\n> +               vec3(1.164,  1.164, 1.164),\n> +               vec3(0.000, -0.392, 2.017),\n> +               vec3(1.596, -0.813, 0.000)\n> +       );\n>\n>         yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n>         yuv.y = texture2D(tex_u, textureOut).r - 0.500;\n> diff --git a/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> b/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> index 3794be843590..086c5b6d11bd 100644\n> --- a/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> +++ b/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> @@ -18,10 +18,10 @@ void main(void)\n>         vec3 yuv;\n>         vec3 rgb;\n>         mat3 yuv2rgb_bt601_mat = mat3(\n> -                                     vec3(1.164,  1.164, 1.164),\n> -                                     vec3(0.000, -0.392, 2.017),\n> -                                     vec3(1.596, -0.813, 0.000)\n> -                                );\n> +               vec3(1.164,  1.164, 1.164),\n> +               vec3(0.000, -0.392, 2.017),\n> +               vec3(1.596, -0.813, 0.000)\n> +       );\n>\n>         yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n>         yuv.y = texture2D(tex_u, textureOut).g - 0.500;\n> diff --git a/src/qcam/assets/shader/NV_3_planes_f.glsl\n> b/src/qcam/assets/shader/NV_3_planes_f.glsl\n> index fca9b659ca05..4bc941842710 100644\n> --- a/src/qcam/assets/shader/NV_3_planes_f.glsl\n> +++ b/src/qcam/assets/shader/NV_3_planes_f.glsl\n> @@ -19,10 +19,10 @@ void main(void)\n>         vec3 yuv;\n>         vec3 rgb;\n>         mat3 yuv2rgb_bt601_mat = mat3(\n> -                                     vec3(1.164,  1.164, 1.164),\n> -                                     vec3(0.000, -0.392, 2.017),\n> -                                     vec3(1.596, -0.813, 0.000)\n> -                                );\n> +               vec3(1.164,  1.164, 1.164),\n> +               vec3(0.000, -0.392, 2.017),\n> +               vec3(1.596, -0.813, 0.000)\n> +       );\n>\n>         yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n>         yuv.y = texture2D(tex_u, textureOut).r - 0.500;\n> diff --git a/src/qcam/main.cpp b/src/qcam/main.cpp\n> index 4b7d04100c08..f60d3cef0ecb 100644\n> --- a/src/qcam/main.cpp\n> +++ b/src/qcam/main.cpp\n> @@ -33,9 +33,9 @@ OptionsParser::Options parseOptions(int argc, char\n> *argv[])\n>                          ArgumentRequired, \"camera\");\n>         parser.addOption(OptHelp, OptionNone, \"Display this help message\",\n>                          \"help\");\n> -       parser.addOption(OptRendered, OptionString,\n> -                        \"Choose the renderer type {qt,gles} (default:\n> qt)\", \"renderer\",\n> -                        ArgumentRequired, \"render\");\n> +       parser.addOption(OptRenderer, OptionString,\n> +                        \"Choose the renderer type {qt,gles} (default:\n> qt)\",\n> +                        \"renderer\", ArgumentRequired, \"renderer\");\n>         parser.addOption(OptStream, &streamKeyValue,\n>                          \"Set configuration of a camera stream\", \"stream\",\n> true);\n>\n> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> index 315102c39526..e5233f4fb706 100644\n> --- a/src/qcam/main_window.cpp\n> +++ b/src/qcam/main_window.cpp\n> @@ -28,6 +28,8 @@\n>  #include <libcamera/version.h>\n>\n>  #include \"dng_writer.h\"\n> +#include \"viewfinder_gl.h\"\n> +#include \"viewfinder_qt.h\"\n>\n>  using namespace libcamera;\n>\n> @@ -95,9 +97,6 @@ MainWindow::MainWindow(CameraManager *cm, const\n> OptionsParser::Options &options)\n>  {\n>         int ret;\n>\n> -       /* Render Type Qt or GLES, and set Qt by default */\n> -       std::string renderType_ = \"qt\";\n> -\n>         /*\n>          * Initialize the UI: Create the toolbar, set the window title and\n>          * create the viewfinder widget.\n> @@ -108,17 +107,19 @@ MainWindow::MainWindow(CameraManager *cm, const\n> OptionsParser::Options &options)\n>         setWindowTitle(title_);\n>         connect(&titleTimer_, SIGNAL(timeout()), this,\n> SLOT(updateTitle()));\n>\n> -       if (options_.isSet(OptRendered))\n> -               renderType_ = options_[OptRendered].toString();\n> +       /* Renderer type Qt or GLES, select Qt by default. */\n> +       std::string renderType = \"qt\";\n> +       if (options_.isSet(OptRenderer))\n> +               renderType = options_[OptRenderer].toString();\n>\n> -       if (renderType_ == \"qt\") {\n> +       if (renderType == \"qt\") {\n>                 ViewFinderQt *viewfinder = new ViewFinderQt(this);\n>                 connect(viewfinder, &ViewFinderQt::renderComplete,\n>                         this, &MainWindow::queueRequest);\n>                 viewfinder_ = viewfinder;\n>                 setCentralWidget(viewfinder);\n>  #ifndef QT_NO_OPENGL\n> -       } else if (renderType_ == \"gles\") {\n> +       } else if (renderType == \"gles\") {\n>                 ViewFinderGL *viewfinder = new ViewFinderGL(this);\n>                 connect(viewfinder, &ViewFinderGL::renderComplete,\n>                         this, &MainWindow::queueRequest);\n> @@ -127,7 +128,7 @@ MainWindow::MainWindow(CameraManager *cm, const\n> OptionsParser::Options &options)\n>  #endif\n>         } else {\n>                 qWarning() << \"Invalid render type\"\n> -                          << QString::fromStdString(renderType_);\n> +                          << QString::fromStdString(renderType);\n>                 quit();\n>                 return;\n>         }\n> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> index 251f78bf6833..5c61a4dfce53 100644\n> --- a/src/qcam/main_window.h\n> +++ b/src/qcam/main_window.h\n> @@ -26,8 +26,6 @@\n>\n>  #include \"../cam/stream_options.h\"\n>  #include \"viewfinder.h\"\n> -#include \"viewfinder_gl.h\"\n> -#include \"viewfinder_qt.h\"\n>\n>  using namespace libcamera;\n>\n> @@ -39,7 +37,7 @@ class HotplugEvent;\n>  enum {\n>         OptCamera = 'c',\n>         OptHelp = 'h',\n> -       OptRendered = 'r',\n> +       OptRenderer = 'r',\n>         OptStream = 's',\n>  };\n>\n> diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp\n> index 84f48666af5b..fbe21dcf1ad2 100644\n> --- a/src/qcam/viewfinder_gl.cpp\n> +++ b/src/qcam/viewfinder_gl.cpp\n> @@ -19,7 +19,7 @@ static const QList<libcamera::PixelFormat>\n> supportedFormats{\n>         libcamera::formats::NV24,\n>         libcamera::formats::NV42,\n>         libcamera::formats::YUV420,\n> -       libcamera::formats::YVU420\n> +       libcamera::formats::YVU420,\n>  };\n>\n>  ViewFinderGL::ViewFinderGL(QWidget *parent)\n> @@ -35,9 +35,6 @@ ViewFinderGL::ViewFinderGL(QWidget *parent)\n>  ViewFinderGL::~ViewFinderGL()\n>  {\n>         removeShader();\n> -\n> -       if (vertexBuffer_.isCreated())\n> -               vertexBuffer_.destroy();\n>  }\n>\n>  const QList<libcamera::PixelFormat> &ViewFinderGL::nativeFormats() const\n> @@ -48,9 +45,7 @@ const QList<libcamera::PixelFormat>\n> &ViewFinderGL::nativeFormats() const\n>  int ViewFinderGL::setFormat(const libcamera::PixelFormat &format,\n>                             const QSize &size)\n>  {\n> -       int ret = 0;\n> -\n> -       /* If the fragment is ceeated remove it and create a new one */\n> +       /* If the fragment is created remove it and create a new one. */\n>         if (fragmentShader_) {\n>                 if (shaderProgram_.isLinked()) {\n>                         shaderProgram_.release();\n> @@ -59,14 +54,14 @@ int ViewFinderGL::setFormat(const\n> libcamera::PixelFormat &format,\n>                 }\n>         }\n>\n> -       if (selectFormat(format)) {\n> -               format_ = format;\n> -               size_ = size;\n> -       } else {\n> -               ret = -1;\n> -       }\n> +       if (!selectFormat(format))\n> +               return -1;\n> +\n> +       format_ = format;\n> +       size_ = size;\n> +\n>         updateGeometry();\n> -       return ret;\n> +       return 0;\n>  }\n>\n>  void ViewFinderGL::stop()\n> @@ -279,10 +274,10 @@ void ViewFinderGL::initializeGL()\n>                 },\n>                 {\n>                         /* Texture coordinates */\n> -                       { 1.0f, 0.0f },\n> -                       { 1.0f, 1.0f },\n>                         { 0.0f, 1.0f },\n>                         { 0.0f, 0.0f },\n> +                       { 1.0f, 0.0f },\n> +                       { 1.0f, 1.0f },\n>                 },\n>         };\n>\n> @@ -306,7 +301,7 @@ void ViewFinderGL::doRender()\n>         case libcamera::formats::NV61:\n>         case libcamera::formats::NV24:\n>         case libcamera::formats::NV42:\n> -               /* activate texture Y */\n> +               /* Activate texture Y */\n>                 glActiveTexture(GL_TEXTURE0);\n>                 configureTexture(id_y_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n> @@ -320,7 +315,7 @@ void ViewFinderGL::doRender()\n>                              yuvData_);\n>                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n>\n> -               /* activate texture UV/VU */\n> +               /* Activate texture UV/VU */\n>                 glActiveTexture(GL_TEXTURE1);\n>                 configureTexture(id_u_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n> @@ -336,7 +331,7 @@ void ViewFinderGL::doRender()\n>                 break;\n>\n>         case libcamera::formats::YUV420:\n> -               /* activate texture Y */\n> +               /* Activate texture Y */\n>                 glActiveTexture(GL_TEXTURE0);\n>                 configureTexture(id_y_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n> @@ -350,7 +345,7 @@ void ViewFinderGL::doRender()\n>                              yuvData_);\n>                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n>\n> -               /* activate texture U */\n> +               /* Activate texture U */\n>                 glActiveTexture(GL_TEXTURE1);\n>                 configureTexture(id_u_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n> @@ -364,7 +359,7 @@ void ViewFinderGL::doRender()\n>                              (char *)yuvData_ + size_.width() *\n> size_.height());\n>                 shaderProgram_.setUniformValue(textureUniformU_, 1);\n>\n> -               /* activate texture V */\n> +               /* Activate texture V */\n>                 glActiveTexture(GL_TEXTURE2);\n>                 configureTexture(id_v_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n> @@ -380,7 +375,7 @@ void ViewFinderGL::doRender()\n>                 break;\n>\n>         case libcamera::formats::YVU420:\n> -               /* activate texture Y */\n> +               /* Activate texture Y */\n>                 glActiveTexture(GL_TEXTURE0);\n>                 configureTexture(id_y_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n> @@ -394,7 +389,7 @@ void ViewFinderGL::doRender()\n>                              yuvData_);\n>                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n>\n> -               /* activate texture V */\n> +               /* Activate texture V */\n>                 glActiveTexture(GL_TEXTURE2);\n>                 configureTexture(id_v_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n> @@ -406,9 +401,9 @@ void ViewFinderGL::doRender()\n>                              GL_RED,\n>                              GL_UNSIGNED_BYTE,\n>                              (char *)yuvData_ + size_.width() *\n> size_.height());\n> -               shaderProgram_.setUniformValue(textureUniformV_, 1);\n> +               shaderProgram_.setUniformValue(textureUniformV_, 2);\n>\n> -               /* activate texture U */\n> +               /* Activate texture U */\n>                 glActiveTexture(GL_TEXTURE1);\n>                 configureTexture(id_u_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n> @@ -420,7 +415,7 @@ void ViewFinderGL::doRender()\n>                              GL_RED,\n>                              GL_UNSIGNED_BYTE,\n>                              (char *)yuvData_ + size_.width() *\n> size_.height() * 5 / 4);\n> -               shaderProgram_.setUniformValue(textureUniformU_, 2);\n> +               shaderProgram_.setUniformValue(textureUniformU_, 1);\n>\n\nI applied the above changes and tested on my rockpi4b with imx219. It's\nrunning well.\nBut I have only the imx219 camera module to test with qcam, which means\nqcam only verified NV12 format is correct.\nSo I use another small tool to test other formats and shader code.\nWhen the format YVU420 and YUV420 use the same shader code.\n+               shaderProgram_.setUniformValue(textureUniformV_, 2);\n...\n+               shaderProgram_.setUniformValue(textureUniformU_, 1);\nabove change cause the color became blue in format YVU420.\nThe original value is correct I think.\n\nThanks,\nShow\n\n                break;\n>\n>         default:\n>\n> Show Liu (4):\n>   qcam: Add OpenGL shader code as Qt resource\n>   qcam: New viewfinder hierarchy\n>   qcam: Add ViewFinderGL class to accelerate the format conversion\n>   qcam: Add additional command line option to select the renderer type\n>\n>  meson.build                                   |   1 +\n>  src/qcam/assets/shader/NV_2_planes_UV_f.glsl  |  32 ++\n>  src/qcam/assets/shader/NV_2_planes_VU_f.glsl  |  32 ++\n>  src/qcam/assets/shader/NV_3_planes_f.glsl     |  33 ++\n>  src/qcam/assets/shader/NV_vertex_shader.glsl  |  16 +\n>  src/qcam/assets/shader/shaders.qrc            |   9 +\n>  src/qcam/main.cpp                             |   3 +\n>  src/qcam/main_window.cpp                      |  32 +-\n>  src/qcam/main_window.h                        |   1 +\n>  src/qcam/meson.build                          |  20 +-\n>  src/qcam/viewfinder.h                         |  57 +--\n>  src/qcam/viewfinder_gl.cpp                    | 451 ++++++++++++++++++\n>  src/qcam/viewfinder_gl.h                      |  96 ++++\n>  .../{viewfinder.cpp => viewfinder_qt.cpp}     |  24 +-\n>  src/qcam/viewfinder_qt.h                      |  64 +++\n>  15 files changed, 806 insertions(+), 65 deletions(-)\n>  create mode 100644 src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n>  create mode 100644 src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n>  create mode 100644 src/qcam/assets/shader/NV_3_planes_f.glsl\n>  create mode 100644 src/qcam/assets/shader/NV_vertex_shader.glsl\n>  create mode 100644 src/qcam/assets/shader/shaders.qrc\n>  create mode 100644 src/qcam/viewfinder_gl.cpp\n>  create mode 100644 src/qcam/viewfinder_gl.h\n>  rename src/qcam/{viewfinder.cpp => viewfinder_qt.cpp} (86%)\n>  create mode 100644 src/qcam/viewfinder_qt.h\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\n>\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 005EDC3B5D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 15 Sep 2020 09:01:10 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 66C7D62DF5;\n\tTue, 15 Sep 2020 11:01:10 +0200 (CEST)","from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com\n\t[IPv6:2607:f8b0:4864:20::1029])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D37A16036A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 15 Sep 2020 11:01:07 +0200 (CEST)","by mail-pj1-x1029.google.com with SMTP id kk9so1394649pjb.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 15 Sep 2020 02:01:07 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=linaro.org header.i=@linaro.org\n\theader.b=\"vyvBJ7w8\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=kWf+ioNH/GF3pZu1Wyhne/2fWh3H8oVuurnZv1rrWMA=;\n\tb=vyvBJ7w8/QdUkoMXU5Qs4rYaFFGdjck9MINR3mjIz9+zRqiBkBB6ZlPStm1Tt3LuOk\n\t9R0XXv8JHh/UpsmUH53ML0ejBXpkjY2TpIbYpr+3bYBEtFXqTJ1flgJr7AKEIG9aWz+V\n\tl3tuePpw4pQHH4Mu7IGTrAUhUGJ/hjKl6WyfoFDBviOiXu229KYkB44U2LuNfL9HmOEO\n\tEq3WrvYV4ZkeLb7tfLw6UM7282C+OXqmsLP2RODLiNMHVQYCrh/8KTZpEOm8U+Hbu6Di\n\tiurZVITYt5CZ8mG0oxkvYZc/euLS1sHa5o8g/hNSp7jvyUjwubD4qJHWNkmmADsh8gU5\n\t3Sxg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=kWf+ioNH/GF3pZu1Wyhne/2fWh3H8oVuurnZv1rrWMA=;\n\tb=nxlIC+u3Bt0oE6wre1Tj9VLC3sdXFSiU2ixyA/ZT4RZSFyF/YOYSg6mf1UA1AidFhm\n\tkjweFGfNtn0I5GT6vZYugi67zJxZsxTGgFoUOOeywlT5ytdDOg+zrh0tPtAbGwQtLxd0\n\tqkLYjsw2Bi/u3OxcfnMyq5UlRKZh7+708HAy+SlYEl6TmZLp6xzjDBrxkjwW6g8iDTr9\n\tJS+nj5XLBPp6ixi1k5m7UlxMUHD5i7US6U6EH5ckXD5wTRWzByttlXn5S+QAyHqui2ak\n\t6OVWW5dJ95kZZpMh01IsEvagLdbmEdwzRalr7DwMJqJ/PRRWiWnt8rSxk6ElGqs44KB6\n\t/wpw==","X-Gm-Message-State":"AOAM5314aAbliPbqWYXDIcgrVHIhQJJSvD6w6LlP1z2YytrM7IznBarG\n\tswOeuYtJ0OmMHQ2AvBzX5712sngYQDywwc9YxrmBUWSSwLFteg==","X-Google-Smtp-Source":"ABdhPJwCxGgl6TbstY6DY7gA3YGkyIPOKlZer1fynIxutv68rWy6s+pLZu06NGYBjm1FNWvoyM37hUBegsQHnfXL/qo=","X-Received":"by 2002:a17:90a:a40d:: with SMTP id\n\ty13mr3101101pjp.183.1600160465822; \n\tTue, 15 Sep 2020 02:01:05 -0700 (PDT)","MIME-Version":"1.0","References":"<20200915024623.30667-1-laurent.pinchart@ideasonboard.com>","In-Reply-To":"<20200915024623.30667-1-laurent.pinchart@ideasonboard.com>","From":"Show Liu <show.liu@linaro.org>","Date":"Tue, 15 Sep 2020 17:00:54 +0800","Message-ID":"<CA+yuoHoY3ytmmiBH8sHmJHFWbkQiaedasXZ-wWPri3qdxOAsog@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v7 0/4] qcam: accelerate format\n\tconversion by OpenGL shader","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"multipart/mixed;\n\tboundary=\"===============4173875362482268480==\"","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":12539,"web_url":"https://patchwork.libcamera.org/comment/12539/","msgid":"<20200916023307.GK14954@pendragon.ideasonboard.com>","date":"2020-09-16T02:33:07","subject":"Re: [libcamera-devel] [PATCH v7 0/4] qcam: accelerate format\n\tconversion by OpenGL shader","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Show,\n\nOn Tue, Sep 15, 2020 at 05:00:54PM +0800, Show Liu wrote:\n> On Tue, Sep 15, 2020 at 10:46 AM Laurent Pinchart wrote:\n> > Hello,\n> >\n> > This patch series is an updated version of Show's v6. I've updated the\n> > patches during review as I wanted to test my review comments, and it\n> > would be pointless for Show to do the same independently to post a v7.\n> >\n> > The series only incorporates review comments. Show, could you please let\n> > me know if you're fine with the result ? To make the comparison easier,\n> > here's the diff between v6 and v7.\n> >\n> > diff --git a/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> > b/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> > index 80478c5d0dd4..67633a11ee0f 100644\n> > --- a/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> > +++ b/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> > @@ -18,10 +18,10 @@ void main(void)\n> >         vec3 yuv;\n> >         vec3 rgb;\n> >         mat3 yuv2rgb_bt601_mat = mat3(\n> > -                                     vec3(1.164,  1.164, 1.164),\n> > -                                     vec3(0.000, -0.392, 2.017),\n> > -                                     vec3(1.596, -0.813, 0.000)\n> > -                                );\n> > +               vec3(1.164,  1.164, 1.164),\n> > +               vec3(0.000, -0.392, 2.017),\n> > +               vec3(1.596, -0.813, 0.000)\n> > +       );\n> >\n> >         yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n> >         yuv.y = texture2D(tex_u, textureOut).r - 0.500;\n> > diff --git a/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> > b/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> > index 3794be843590..086c5b6d11bd 100644\n> > --- a/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> > +++ b/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> > @@ -18,10 +18,10 @@ void main(void)\n> >         vec3 yuv;\n> >         vec3 rgb;\n> >         mat3 yuv2rgb_bt601_mat = mat3(\n> > -                                     vec3(1.164,  1.164, 1.164),\n> > -                                     vec3(0.000, -0.392, 2.017),\n> > -                                     vec3(1.596, -0.813, 0.000)\n> > -                                );\n> > +               vec3(1.164,  1.164, 1.164),\n> > +               vec3(0.000, -0.392, 2.017),\n> > +               vec3(1.596, -0.813, 0.000)\n> > +       );\n> >\n> >         yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n> >         yuv.y = texture2D(tex_u, textureOut).g - 0.500;\n> > diff --git a/src/qcam/assets/shader/NV_3_planes_f.glsl\n> > b/src/qcam/assets/shader/NV_3_planes_f.glsl\n> > index fca9b659ca05..4bc941842710 100644\n> > --- a/src/qcam/assets/shader/NV_3_planes_f.glsl\n> > +++ b/src/qcam/assets/shader/NV_3_planes_f.glsl\n> > @@ -19,10 +19,10 @@ void main(void)\n> >         vec3 yuv;\n> >         vec3 rgb;\n> >         mat3 yuv2rgb_bt601_mat = mat3(\n> > -                                     vec3(1.164,  1.164, 1.164),\n> > -                                     vec3(0.000, -0.392, 2.017),\n> > -                                     vec3(1.596, -0.813, 0.000)\n> > -                                );\n> > +               vec3(1.164,  1.164, 1.164),\n> > +               vec3(0.000, -0.392, 2.017),\n> > +               vec3(1.596, -0.813, 0.000)\n> > +       );\n> >\n> >         yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n> >         yuv.y = texture2D(tex_u, textureOut).r - 0.500;\n> > diff --git a/src/qcam/main.cpp b/src/qcam/main.cpp\n> > index 4b7d04100c08..f60d3cef0ecb 100644\n> > --- a/src/qcam/main.cpp\n> > +++ b/src/qcam/main.cpp\n> > @@ -33,9 +33,9 @@ OptionsParser::Options parseOptions(int argc, char\n> > *argv[])\n> >                          ArgumentRequired, \"camera\");\n> >         parser.addOption(OptHelp, OptionNone, \"Display this help message\",\n> >                          \"help\");\n> > -       parser.addOption(OptRendered, OptionString,\n> > -                        \"Choose the renderer type {qt,gles} (default:\n> > qt)\", \"renderer\",\n> > -                        ArgumentRequired, \"render\");\n> > +       parser.addOption(OptRenderer, OptionString,\n> > +                        \"Choose the renderer type {qt,gles} (default:\n> > qt)\",\n> > +                        \"renderer\", ArgumentRequired, \"renderer\");\n> >         parser.addOption(OptStream, &streamKeyValue,\n> >                          \"Set configuration of a camera stream\", \"stream\",\n> > true);\n> >\n> > diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> > index 315102c39526..e5233f4fb706 100644\n> > --- a/src/qcam/main_window.cpp\n> > +++ b/src/qcam/main_window.cpp\n> > @@ -28,6 +28,8 @@\n> >  #include <libcamera/version.h>\n> >\n> >  #include \"dng_writer.h\"\n> > +#include \"viewfinder_gl.h\"\n> > +#include \"viewfinder_qt.h\"\n> >\n> >  using namespace libcamera;\n> >\n> > @@ -95,9 +97,6 @@ MainWindow::MainWindow(CameraManager *cm, const\n> > OptionsParser::Options &options)\n> >  {\n> >         int ret;\n> >\n> > -       /* Render Type Qt or GLES, and set Qt by default */\n> > -       std::string renderType_ = \"qt\";\n> > -\n> >         /*\n> >          * Initialize the UI: Create the toolbar, set the window title and\n> >          * create the viewfinder widget.\n> > @@ -108,17 +107,19 @@ MainWindow::MainWindow(CameraManager *cm, const\n> > OptionsParser::Options &options)\n> >         setWindowTitle(title_);\n> >         connect(&titleTimer_, SIGNAL(timeout()), this,\n> > SLOT(updateTitle()));\n> >\n> > -       if (options_.isSet(OptRendered))\n> > -               renderType_ = options_[OptRendered].toString();\n> > +       /* Renderer type Qt or GLES, select Qt by default. */\n> > +       std::string renderType = \"qt\";\n> > +       if (options_.isSet(OptRenderer))\n> > +               renderType = options_[OptRenderer].toString();\n> >\n> > -       if (renderType_ == \"qt\") {\n> > +       if (renderType == \"qt\") {\n> >                 ViewFinderQt *viewfinder = new ViewFinderQt(this);\n> >                 connect(viewfinder, &ViewFinderQt::renderComplete,\n> >                         this, &MainWindow::queueRequest);\n> >                 viewfinder_ = viewfinder;\n> >                 setCentralWidget(viewfinder);\n> >  #ifndef QT_NO_OPENGL\n> > -       } else if (renderType_ == \"gles\") {\n> > +       } else if (renderType == \"gles\") {\n> >                 ViewFinderGL *viewfinder = new ViewFinderGL(this);\n> >                 connect(viewfinder, &ViewFinderGL::renderComplete,\n> >                         this, &MainWindow::queueRequest);\n> > @@ -127,7 +128,7 @@ MainWindow::MainWindow(CameraManager *cm, const\n> > OptionsParser::Options &options)\n> >  #endif\n> >         } else {\n> >                 qWarning() << \"Invalid render type\"\n> > -                          << QString::fromStdString(renderType_);\n> > +                          << QString::fromStdString(renderType);\n> >                 quit();\n> >                 return;\n> >         }\n> > diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> > index 251f78bf6833..5c61a4dfce53 100644\n> > --- a/src/qcam/main_window.h\n> > +++ b/src/qcam/main_window.h\n> > @@ -26,8 +26,6 @@\n> >\n> >  #include \"../cam/stream_options.h\"\n> >  #include \"viewfinder.h\"\n> > -#include \"viewfinder_gl.h\"\n> > -#include \"viewfinder_qt.h\"\n> >\n> >  using namespace libcamera;\n> >\n> > @@ -39,7 +37,7 @@ class HotplugEvent;\n> >  enum {\n> >         OptCamera = 'c',\n> >         OptHelp = 'h',\n> > -       OptRendered = 'r',\n> > +       OptRenderer = 'r',\n> >         OptStream = 's',\n> >  };\n> >\n> > diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp\n> > index 84f48666af5b..fbe21dcf1ad2 100644\n> > --- a/src/qcam/viewfinder_gl.cpp\n> > +++ b/src/qcam/viewfinder_gl.cpp\n> > @@ -19,7 +19,7 @@ static const QList<libcamera::PixelFormat>\n> > supportedFormats{\n> >         libcamera::formats::NV24,\n> >         libcamera::formats::NV42,\n> >         libcamera::formats::YUV420,\n> > -       libcamera::formats::YVU420\n> > +       libcamera::formats::YVU420,\n> >  };\n> >\n> >  ViewFinderGL::ViewFinderGL(QWidget *parent)\n> > @@ -35,9 +35,6 @@ ViewFinderGL::ViewFinderGL(QWidget *parent)\n> >  ViewFinderGL::~ViewFinderGL()\n> >  {\n> >         removeShader();\n> > -\n> > -       if (vertexBuffer_.isCreated())\n> > -               vertexBuffer_.destroy();\n> >  }\n> >\n> >  const QList<libcamera::PixelFormat> &ViewFinderGL::nativeFormats() const\n> > @@ -48,9 +45,7 @@ const QList<libcamera::PixelFormat>\n> > &ViewFinderGL::nativeFormats() const\n> >  int ViewFinderGL::setFormat(const libcamera::PixelFormat &format,\n> >                             const QSize &size)\n> >  {\n> > -       int ret = 0;\n> > -\n> > -       /* If the fragment is ceeated remove it and create a new one */\n> > +       /* If the fragment is created remove it and create a new one. */\n> >         if (fragmentShader_) {\n> >                 if (shaderProgram_.isLinked()) {\n> >                         shaderProgram_.release();\n> > @@ -59,14 +54,14 @@ int ViewFinderGL::setFormat(const\n> > libcamera::PixelFormat &format,\n> >                 }\n> >         }\n> >\n> > -       if (selectFormat(format)) {\n> > -               format_ = format;\n> > -               size_ = size;\n> > -       } else {\n> > -               ret = -1;\n> > -       }\n> > +       if (!selectFormat(format))\n> > +               return -1;\n> > +\n> > +       format_ = format;\n> > +       size_ = size;\n> > +\n> >         updateGeometry();\n> > -       return ret;\n> > +       return 0;\n> >  }\n> >\n> >  void ViewFinderGL::stop()\n> > @@ -279,10 +274,10 @@ void ViewFinderGL::initializeGL()\n> >                 },\n> >                 {\n> >                         /* Texture coordinates */\n> > -                       { 1.0f, 0.0f },\n> > -                       { 1.0f, 1.0f },\n> >                         { 0.0f, 1.0f },\n> >                         { 0.0f, 0.0f },\n> > +                       { 1.0f, 0.0f },\n> > +                       { 1.0f, 1.0f },\n> >                 },\n> >         };\n> >\n> > @@ -306,7 +301,7 @@ void ViewFinderGL::doRender()\n> >         case libcamera::formats::NV61:\n> >         case libcamera::formats::NV24:\n> >         case libcamera::formats::NV42:\n> > -               /* activate texture Y */\n> > +               /* Activate texture Y */\n> >                 glActiveTexture(GL_TEXTURE0);\n> >                 configureTexture(id_y_);\n> >                 glTexImage2D(GL_TEXTURE_2D,\n> > @@ -320,7 +315,7 @@ void ViewFinderGL::doRender()\n> >                              yuvData_);\n> >                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n> >\n> > -               /* activate texture UV/VU */\n> > +               /* Activate texture UV/VU */\n> >                 glActiveTexture(GL_TEXTURE1);\n> >                 configureTexture(id_u_);\n> >                 glTexImage2D(GL_TEXTURE_2D,\n> > @@ -336,7 +331,7 @@ void ViewFinderGL::doRender()\n> >                 break;\n> >\n> >         case libcamera::formats::YUV420:\n> > -               /* activate texture Y */\n> > +               /* Activate texture Y */\n> >                 glActiveTexture(GL_TEXTURE0);\n> >                 configureTexture(id_y_);\n> >                 glTexImage2D(GL_TEXTURE_2D,\n> > @@ -350,7 +345,7 @@ void ViewFinderGL::doRender()\n> >                              yuvData_);\n> >                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n> >\n> > -               /* activate texture U */\n> > +               /* Activate texture U */\n> >                 glActiveTexture(GL_TEXTURE1);\n> >                 configureTexture(id_u_);\n> >                 glTexImage2D(GL_TEXTURE_2D,\n> > @@ -364,7 +359,7 @@ void ViewFinderGL::doRender()\n> >                              (char *)yuvData_ + size_.width() *\n> > size_.height());\n> >                 shaderProgram_.setUniformValue(textureUniformU_, 1);\n> >\n> > -               /* activate texture V */\n> > +               /* Activate texture V */\n> >                 glActiveTexture(GL_TEXTURE2);\n> >                 configureTexture(id_v_);\n> >                 glTexImage2D(GL_TEXTURE_2D,\n> > @@ -380,7 +375,7 @@ void ViewFinderGL::doRender()\n> >                 break;\n> >\n> >         case libcamera::formats::YVU420:\n> > -               /* activate texture Y */\n> > +               /* Activate texture Y */\n> >                 glActiveTexture(GL_TEXTURE0);\n> >                 configureTexture(id_y_);\n> >                 glTexImage2D(GL_TEXTURE_2D,\n> > @@ -394,7 +389,7 @@ void ViewFinderGL::doRender()\n> >                              yuvData_);\n> >                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n> >\n> > -               /* activate texture V */\n> > +               /* Activate texture V */\n> >                 glActiveTexture(GL_TEXTURE2);\n> >                 configureTexture(id_v_);\n> >                 glTexImage2D(GL_TEXTURE_2D,\n> > @@ -406,9 +401,9 @@ void ViewFinderGL::doRender()\n> >                              GL_RED,\n> >                              GL_UNSIGNED_BYTE,\n> >                              (char *)yuvData_ + size_.width() *\n> > size_.height());\n> > -               shaderProgram_.setUniformValue(textureUniformV_, 1);\n> > +               shaderProgram_.setUniformValue(textureUniformV_, 2);\n> >\n> > -               /* activate texture U */\n> > +               /* Activate texture U */\n> >                 glActiveTexture(GL_TEXTURE1);\n> >                 configureTexture(id_u_);\n> >                 glTexImage2D(GL_TEXTURE_2D,\n> > @@ -420,7 +415,7 @@ void ViewFinderGL::doRender()\n> >                              GL_RED,\n> >                              GL_UNSIGNED_BYTE,\n> >                              (char *)yuvData_ + size_.width() *\n> > size_.height() * 5 / 4);\n> > -               shaderProgram_.setUniformValue(textureUniformU_, 2);\n> > +               shaderProgram_.setUniformValue(textureUniformU_, 1);\n> >\n> \n> I applied the above changes and tested on my rockpi4b with imx219. It's\n> running well.\n> But I have only the imx219 camera module to test with qcam, which means\n> qcam only verified NV12 format is correct.\n> So I use another small tool to test other formats and shader code.\n\nWould it be possible to share that tool ?\n\n> When the format YVU420 and YUV420 use the same shader code.\n> +               shaderProgram_.setUniformValue(textureUniformV_, 2);\n> ...\n> +               shaderProgram_.setUniformValue(textureUniformU_, 1);\n> above change cause the color became blue in format YVU420.\n> The original value is correct I think.\n\nThere's something I don't get then. The common shader is written as\n\n        yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n        yuv.y = texture2D(tex_u, textureOut).r - 0.500;\n        yuv.z = texture2D(tex_v, textureOut).r - 0.500;\n\nso it expects Y in the tex_y uniform, U in the tex_u uniform and V in\nthe tex_v uniform. We retrieve the uniforms with\n\n        textureUniformY_ = shaderProgram_.uniformLocation(\"tex_y\");\n        textureUniformU_ = shaderProgram_.uniformLocation(\"tex_u\");\n        textureUniformV_ = shaderProgram_.uniformLocation(\"tex_v\");\n\nFor YUV420, we have\n\n        case libcamera::formats::YUV420:\n                /* Activate texture Y */\n                glActiveTexture(GL_TEXTURE0);\n                configureTexture(id_y_);\n                glTexImage2D(...);\n                shaderProgram_.setUniformValue(textureUniformY_, 0);\n\n                /* Activate texture U */\n                glActiveTexture(GL_TEXTURE1);\n                configureTexture(id_u_);\n                glTexImage2D(GL_TEXTURE_2D,\n                             0,\n                             GL_RED,\n                             size_.width() / horzSubSample_,\n                             size_.height() / vertSubSample_,\n                             0,\n                             GL_RED,\n                             GL_UNSIGNED_BYTE,\n                             (char *)yuvData_ + size_.width() * size_.height());\n                shaderProgram_.setUniformValue(textureUniformU_, 1);\n\n                /* Activate texture V */\n                glActiveTexture(GL_TEXTURE2);\n                configureTexture(id_v_);\n                glTexImage2D(GL_TEXTURE_2D,\n                             0,\n                             GL_RED,\n                             size_.width() / horzSubSample_,\n                             size_.height() / vertSubSample_,\n                             0,\n                             GL_RED,\n                             GL_UNSIGNED_BYTE,\n                             (char *)yuvData_ + size_.width() * size_.height() * 5 / 4);\n                shaderProgram_.setUniformValue(textureUniformV_, 2);\n\nWe store 0, which I assume corresponds to GL_TEXTURE0, in\ntextureUniformY_, 1 in textureUniformU_ and 2 in textureUniformV_.\nGL_TEXTURE[012] are filled with the Y, U and V data respectively. So\nfar, so good.\n\nFor YVU420, we have\n\n        case libcamera::formats::YVU420:\n                /* Activate texture Y */\n                glActiveTexture(GL_TEXTURE0);\n                configureTexture(id_y_);\n                glTexImage2D(...);\n                shaderProgram_.setUniformValue(textureUniformY_, 0);\n\n                /* Activate texture V */\n                glActiveTexture(GL_TEXTURE2);\n                configureTexture(id_v_);\n                glTexImage2D(GL_TEXTURE_2D,\n                             0,\n                             GL_RED,\n                             size_.width() / horzSubSample_,\n                             size_.height() / vertSubSample_,\n                             0,\n                             GL_RED,\n                             GL_UNSIGNED_BYTE,\n                             (char *)yuvData_ + size_.width() * size_.height());\n                shaderProgram_.setUniformValue(textureUniformV_, 2);\n\n                /* Activate texture U */\n                glActiveTexture(GL_TEXTURE1);\n                configureTexture(id_u_);\n                glTexImage2D(GL_TEXTURE_2D,\n                             0,\n                             GL_RED,\n                             size_.width() / horzSubSample_,\n                             size_.height() / vertSubSample_,\n                             0,\n                             GL_RED,\n                             GL_UNSIGNED_BYTE,\n                             (char *)yuvData_ + size_.width() * size_.height() * 5 / 4);\n                shaderProgram_.setUniformValue(textureUniformU_, 1);\n\nWe handle Y the same way. We also store V in GL_TEXTURE2, and set\ntextureUniformV_ to 2 accordingly. The difference is in the\nglTexImage2D() call, that's where we swap U and V. What am I missing ?\n\n> >               break;\n> >\n> >         default:\n> >\n> > Show Liu (4):\n> >   qcam: Add OpenGL shader code as Qt resource\n> >   qcam: New viewfinder hierarchy\n> >   qcam: Add ViewFinderGL class to accelerate the format conversion\n> >   qcam: Add additional command line option to select the renderer type\n> >\n> >  meson.build                                   |   1 +\n> >  src/qcam/assets/shader/NV_2_planes_UV_f.glsl  |  32 ++\n> >  src/qcam/assets/shader/NV_2_planes_VU_f.glsl  |  32 ++\n> >  src/qcam/assets/shader/NV_3_planes_f.glsl     |  33 ++\n> >  src/qcam/assets/shader/NV_vertex_shader.glsl  |  16 +\n> >  src/qcam/assets/shader/shaders.qrc            |   9 +\n> >  src/qcam/main.cpp                             |   3 +\n> >  src/qcam/main_window.cpp                      |  32 +-\n> >  src/qcam/main_window.h                        |   1 +\n> >  src/qcam/meson.build                          |  20 +-\n> >  src/qcam/viewfinder.h                         |  57 +--\n> >  src/qcam/viewfinder_gl.cpp                    | 451 ++++++++++++++++++\n> >  src/qcam/viewfinder_gl.h                      |  96 ++++\n> >  .../{viewfinder.cpp => viewfinder_qt.cpp}     |  24 +-\n> >  src/qcam/viewfinder_qt.h                      |  64 +++\n> >  15 files changed, 806 insertions(+), 65 deletions(-)\n> >  create mode 100644 src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> >  create mode 100644 src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> >  create mode 100644 src/qcam/assets/shader/NV_3_planes_f.glsl\n> >  create mode 100644 src/qcam/assets/shader/NV_vertex_shader.glsl\n> >  create mode 100644 src/qcam/assets/shader/shaders.qrc\n> >  create mode 100644 src/qcam/viewfinder_gl.cpp\n> >  create mode 100644 src/qcam/viewfinder_gl.h\n> >  rename src/qcam/{viewfinder.cpp => viewfinder_qt.cpp} (86%)\n> >  create mode 100644 src/qcam/viewfinder_qt.h","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B0BF6C3B5B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 16 Sep 2020 02:33:39 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3AD6162E1B;\n\tWed, 16 Sep 2020 04:33:39 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E5DE862C8C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 16 Sep 2020 04:33:37 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5259357F;\n\tWed, 16 Sep 2020 04:33:37 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"jp+K+HFJ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1600223617;\n\tbh=nG6IHvlJ5CUVbd1pPEbYZel+oxiJsW6qToslgSfzTPU=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=jp+K+HFJ0eoKQJoCf04yiXPZuVOiPAgnRENkX++N3I87XvM7MyW4MTvJNuxKfgtDr\n\tQD0KLkkngSeoF1pUP2RNtow+2FYwo6zK2E+S4CfPPseYqdKA7cP+/eZOxxejoEVyBX\n\tNTbC5D74V2sf+qTNce1lfl83Xr/r3cqyDT4cX9mc=","Date":"Wed, 16 Sep 2020 05:33:07 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Show Liu <show.liu@linaro.org>","Message-ID":"<20200916023307.GK14954@pendragon.ideasonboard.com>","References":"<20200915024623.30667-1-laurent.pinchart@ideasonboard.com>\n\t<CA+yuoHoY3ytmmiBH8sHmJHFWbkQiaedasXZ-wWPri3qdxOAsog@mail.gmail.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<CA+yuoHoY3ytmmiBH8sHmJHFWbkQiaedasXZ-wWPri3qdxOAsog@mail.gmail.com>","Subject":"Re: [libcamera-devel] [PATCH v7 0/4] qcam: accelerate format\n\tconversion by OpenGL shader","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":12540,"web_url":"https://patchwork.libcamera.org/comment/12540/","msgid":"<CA+yuoHr38j_yXtFkg+NQK278V65HEdKnjFqTiXn+NfkOM+_-XQ@mail.gmail.com>","date":"2020-09-16T03:21:02","subject":"Re: [libcamera-devel] [PATCH v7 0/4] qcam: accelerate format\n\tconversion by OpenGL shader","submitter":{"id":24,"url":"https://patchwork.libcamera.org/api/people/24/","name":"Show Liu","email":"show.liu@linaro.org"},"content":"Hi Laurent,\n\nOn Wed, Sep 16, 2020 at 10:33 AM Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> Hi Show,\n>\n> On Tue, Sep 15, 2020 at 05:00:54PM +0800, Show Liu wrote:\n> > On Tue, Sep 15, 2020 at 10:46 AM Laurent Pinchart wrote:\n> > > Hello,\n> > >\n> > > This patch series is an updated version of Show's v6. I've updated the\n> > > patches during review as I wanted to test my review comments, and it\n> > > would be pointless for Show to do the same independently to post a v7.\n> > >\n> > > The series only incorporates review comments. Show, could you please\n> let\n> > > me know if you're fine with the result ? To make the comparison easier,\n> > > here's the diff between v6 and v7.\n> > >\n> > > diff --git a/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> > > b/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> > > index 80478c5d0dd4..67633a11ee0f 100644\n> > > --- a/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> > > +++ b/src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> > > @@ -18,10 +18,10 @@ void main(void)\n> > >         vec3 yuv;\n> > >         vec3 rgb;\n> > >         mat3 yuv2rgb_bt601_mat = mat3(\n> > > -                                     vec3(1.164,  1.164, 1.164),\n> > > -                                     vec3(0.000, -0.392, 2.017),\n> > > -                                     vec3(1.596, -0.813, 0.000)\n> > > -                                );\n> > > +               vec3(1.164,  1.164, 1.164),\n> > > +               vec3(0.000, -0.392, 2.017),\n> > > +               vec3(1.596, -0.813, 0.000)\n> > > +       );\n> > >\n> > >         yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n> > >         yuv.y = texture2D(tex_u, textureOut).r - 0.500;\n> > > diff --git a/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> > > b/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> > > index 3794be843590..086c5b6d11bd 100644\n> > > --- a/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> > > +++ b/src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> > > @@ -18,10 +18,10 @@ void main(void)\n> > >         vec3 yuv;\n> > >         vec3 rgb;\n> > >         mat3 yuv2rgb_bt601_mat = mat3(\n> > > -                                     vec3(1.164,  1.164, 1.164),\n> > > -                                     vec3(0.000, -0.392, 2.017),\n> > > -                                     vec3(1.596, -0.813, 0.000)\n> > > -                                );\n> > > +               vec3(1.164,  1.164, 1.164),\n> > > +               vec3(0.000, -0.392, 2.017),\n> > > +               vec3(1.596, -0.813, 0.000)\n> > > +       );\n> > >\n> > >         yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n> > >         yuv.y = texture2D(tex_u, textureOut).g - 0.500;\n> > > diff --git a/src/qcam/assets/shader/NV_3_planes_f.glsl\n> > > b/src/qcam/assets/shader/NV_3_planes_f.glsl\n> > > index fca9b659ca05..4bc941842710 100644\n> > > --- a/src/qcam/assets/shader/NV_3_planes_f.glsl\n> > > +++ b/src/qcam/assets/shader/NV_3_planes_f.glsl\n> > > @@ -19,10 +19,10 @@ void main(void)\n> > >         vec3 yuv;\n> > >         vec3 rgb;\n> > >         mat3 yuv2rgb_bt601_mat = mat3(\n> > > -                                     vec3(1.164,  1.164, 1.164),\n> > > -                                     vec3(0.000, -0.392, 2.017),\n> > > -                                     vec3(1.596, -0.813, 0.000)\n> > > -                                );\n> > > +               vec3(1.164,  1.164, 1.164),\n> > > +               vec3(0.000, -0.392, 2.017),\n> > > +               vec3(1.596, -0.813, 0.000)\n> > > +       );\n> > >\n> > >         yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n> > >         yuv.y = texture2D(tex_u, textureOut).r - 0.500;\n> > > diff --git a/src/qcam/main.cpp b/src/qcam/main.cpp\n> > > index 4b7d04100c08..f60d3cef0ecb 100644\n> > > --- a/src/qcam/main.cpp\n> > > +++ b/src/qcam/main.cpp\n> > > @@ -33,9 +33,9 @@ OptionsParser::Options parseOptions(int argc, char\n> > > *argv[])\n> > >                          ArgumentRequired, \"camera\");\n> > >         parser.addOption(OptHelp, OptionNone, \"Display this help\n> message\",\n> > >                          \"help\");\n> > > -       parser.addOption(OptRendered, OptionString,\n> > > -                        \"Choose the renderer type {qt,gles} (default:\n> > > qt)\", \"renderer\",\n> > > -                        ArgumentRequired, \"render\");\n> > > +       parser.addOption(OptRenderer, OptionString,\n> > > +                        \"Choose the renderer type {qt,gles} (default:\n> > > qt)\",\n> > > +                        \"renderer\", ArgumentRequired, \"renderer\");\n> > >         parser.addOption(OptStream, &streamKeyValue,\n> > >                          \"Set configuration of a camera stream\",\n> \"stream\",\n> > > true);\n> > >\n> > > diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> > > index 315102c39526..e5233f4fb706 100644\n> > > --- a/src/qcam/main_window.cpp\n> > > +++ b/src/qcam/main_window.cpp\n> > > @@ -28,6 +28,8 @@\n> > >  #include <libcamera/version.h>\n> > >\n> > >  #include \"dng_writer.h\"\n> > > +#include \"viewfinder_gl.h\"\n> > > +#include \"viewfinder_qt.h\"\n> > >\n> > >  using namespace libcamera;\n> > >\n> > > @@ -95,9 +97,6 @@ MainWindow::MainWindow(CameraManager *cm, const\n> > > OptionsParser::Options &options)\n> > >  {\n> > >         int ret;\n> > >\n> > > -       /* Render Type Qt or GLES, and set Qt by default */\n> > > -       std::string renderType_ = \"qt\";\n> > > -\n> > >         /*\n> > >          * Initialize the UI: Create the toolbar, set the window title\n> and\n> > >          * create the viewfinder widget.\n> > > @@ -108,17 +107,19 @@ MainWindow::MainWindow(CameraManager *cm, const\n> > > OptionsParser::Options &options)\n> > >         setWindowTitle(title_);\n> > >         connect(&titleTimer_, SIGNAL(timeout()), this,\n> > > SLOT(updateTitle()));\n> > >\n> > > -       if (options_.isSet(OptRendered))\n> > > -               renderType_ = options_[OptRendered].toString();\n> > > +       /* Renderer type Qt or GLES, select Qt by default. */\n> > > +       std::string renderType = \"qt\";\n> > > +       if (options_.isSet(OptRenderer))\n> > > +               renderType = options_[OptRenderer].toString();\n> > >\n> > > -       if (renderType_ == \"qt\") {\n> > > +       if (renderType == \"qt\") {\n> > >                 ViewFinderQt *viewfinder = new ViewFinderQt(this);\n> > >                 connect(viewfinder, &ViewFinderQt::renderComplete,\n> > >                         this, &MainWindow::queueRequest);\n> > >                 viewfinder_ = viewfinder;\n> > >                 setCentralWidget(viewfinder);\n> > >  #ifndef QT_NO_OPENGL\n> > > -       } else if (renderType_ == \"gles\") {\n> > > +       } else if (renderType == \"gles\") {\n> > >                 ViewFinderGL *viewfinder = new ViewFinderGL(this);\n> > >                 connect(viewfinder, &ViewFinderGL::renderComplete,\n> > >                         this, &MainWindow::queueRequest);\n> > > @@ -127,7 +128,7 @@ MainWindow::MainWindow(CameraManager *cm, const\n> > > OptionsParser::Options &options)\n> > >  #endif\n> > >         } else {\n> > >                 qWarning() << \"Invalid render type\"\n> > > -                          << QString::fromStdString(renderType_);\n> > > +                          << QString::fromStdString(renderType);\n> > >                 quit();\n> > >                 return;\n> > >         }\n> > > diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> > > index 251f78bf6833..5c61a4dfce53 100644\n> > > --- a/src/qcam/main_window.h\n> > > +++ b/src/qcam/main_window.h\n> > > @@ -26,8 +26,6 @@\n> > >\n> > >  #include \"../cam/stream_options.h\"\n> > >  #include \"viewfinder.h\"\n> > > -#include \"viewfinder_gl.h\"\n> > > -#include \"viewfinder_qt.h\"\n> > >\n> > >  using namespace libcamera;\n> > >\n> > > @@ -39,7 +37,7 @@ class HotplugEvent;\n> > >  enum {\n> > >         OptCamera = 'c',\n> > >         OptHelp = 'h',\n> > > -       OptRendered = 'r',\n> > > +       OptRenderer = 'r',\n> > >         OptStream = 's',\n> > >  };\n> > >\n> > > diff --git a/src/qcam/viewfinder_gl.cpp b/src/qcam/viewfinder_gl.cpp\n> > > index 84f48666af5b..fbe21dcf1ad2 100644\n> > > --- a/src/qcam/viewfinder_gl.cpp\n> > > +++ b/src/qcam/viewfinder_gl.cpp\n> > > @@ -19,7 +19,7 @@ static const QList<libcamera::PixelFormat>\n> > > supportedFormats{\n> > >         libcamera::formats::NV24,\n> > >         libcamera::formats::NV42,\n> > >         libcamera::formats::YUV420,\n> > > -       libcamera::formats::YVU420\n> > > +       libcamera::formats::YVU420,\n> > >  };\n> > >\n> > >  ViewFinderGL::ViewFinderGL(QWidget *parent)\n> > > @@ -35,9 +35,6 @@ ViewFinderGL::ViewFinderGL(QWidget *parent)\n> > >  ViewFinderGL::~ViewFinderGL()\n> > >  {\n> > >         removeShader();\n> > > -\n> > > -       if (vertexBuffer_.isCreated())\n> > > -               vertexBuffer_.destroy();\n> > >  }\n> > >\n> > >  const QList<libcamera::PixelFormat> &ViewFinderGL::nativeFormats()\n> const\n> > > @@ -48,9 +45,7 @@ const QList<libcamera::PixelFormat>\n> > > &ViewFinderGL::nativeFormats() const\n> > >  int ViewFinderGL::setFormat(const libcamera::PixelFormat &format,\n> > >                             const QSize &size)\n> > >  {\n> > > -       int ret = 0;\n> > > -\n> > > -       /* If the fragment is ceeated remove it and create a new one */\n> > > +       /* If the fragment is created remove it and create a new one.\n> */\n> > >         if (fragmentShader_) {\n> > >                 if (shaderProgram_.isLinked()) {\n> > >                         shaderProgram_.release();\n> > > @@ -59,14 +54,14 @@ int ViewFinderGL::setFormat(const\n> > > libcamera::PixelFormat &format,\n> > >                 }\n> > >         }\n> > >\n> > > -       if (selectFormat(format)) {\n> > > -               format_ = format;\n> > > -               size_ = size;\n> > > -       } else {\n> > > -               ret = -1;\n> > > -       }\n> > > +       if (!selectFormat(format))\n> > > +               return -1;\n> > > +\n> > > +       format_ = format;\n> > > +       size_ = size;\n> > > +\n> > >         updateGeometry();\n> > > -       return ret;\n> > > +       return 0;\n> > >  }\n> > >\n> > >  void ViewFinderGL::stop()\n> > > @@ -279,10 +274,10 @@ void ViewFinderGL::initializeGL()\n> > >                 },\n> > >                 {\n> > >                         /* Texture coordinates */\n> > > -                       { 1.0f, 0.0f },\n> > > -                       { 1.0f, 1.0f },\n> > >                         { 0.0f, 1.0f },\n> > >                         { 0.0f, 0.0f },\n> > > +                       { 1.0f, 0.0f },\n> > > +                       { 1.0f, 1.0f },\n> > >                 },\n> > >         };\n> > >\n> > > @@ -306,7 +301,7 @@ void ViewFinderGL::doRender()\n> > >         case libcamera::formats::NV61:\n> > >         case libcamera::formats::NV24:\n> > >         case libcamera::formats::NV42:\n> > > -               /* activate texture Y */\n> > > +               /* Activate texture Y */\n> > >                 glActiveTexture(GL_TEXTURE0);\n> > >                 configureTexture(id_y_);\n> > >                 glTexImage2D(GL_TEXTURE_2D,\n> > > @@ -320,7 +315,7 @@ void ViewFinderGL::doRender()\n> > >                              yuvData_);\n> > >                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n> > >\n> > > -               /* activate texture UV/VU */\n> > > +               /* Activate texture UV/VU */\n> > >                 glActiveTexture(GL_TEXTURE1);\n> > >                 configureTexture(id_u_);\n> > >                 glTexImage2D(GL_TEXTURE_2D,\n> > > @@ -336,7 +331,7 @@ void ViewFinderGL::doRender()\n> > >                 break;\n> > >\n> > >         case libcamera::formats::YUV420:\n> > > -               /* activate texture Y */\n> > > +               /* Activate texture Y */\n> > >                 glActiveTexture(GL_TEXTURE0);\n> > >                 configureTexture(id_y_);\n> > >                 glTexImage2D(GL_TEXTURE_2D,\n> > > @@ -350,7 +345,7 @@ void ViewFinderGL::doRender()\n> > >                              yuvData_);\n> > >                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n> > >\n> > > -               /* activate texture U */\n> > > +               /* Activate texture U */\n> > >                 glActiveTexture(GL_TEXTURE1);\n> > >                 configureTexture(id_u_);\n> > >                 glTexImage2D(GL_TEXTURE_2D,\n> > > @@ -364,7 +359,7 @@ void ViewFinderGL::doRender()\n> > >                              (char *)yuvData_ + size_.width() *\n> > > size_.height());\n> > >                 shaderProgram_.setUniformValue(textureUniformU_, 1);\n> > >\n> > > -               /* activate texture V */\n> > > +               /* Activate texture V */\n> > >                 glActiveTexture(GL_TEXTURE2);\n> > >                 configureTexture(id_v_);\n> > >                 glTexImage2D(GL_TEXTURE_2D,\n> > > @@ -380,7 +375,7 @@ void ViewFinderGL::doRender()\n> > >                 break;\n> > >\n> > >         case libcamera::formats::YVU420:\n> > > -               /* activate texture Y */\n> > > +               /* Activate texture Y */\n> > >                 glActiveTexture(GL_TEXTURE0);\n> > >                 configureTexture(id_y_);\n> > >                 glTexImage2D(GL_TEXTURE_2D,\n> > > @@ -394,7 +389,7 @@ void ViewFinderGL::doRender()\n> > >                              yuvData_);\n> > >                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n> > >\n> > > -               /* activate texture V */\n> > > +               /* Activate texture V */\n> > >                 glActiveTexture(GL_TEXTURE2);\n> > >                 configureTexture(id_v_);\n> > >                 glTexImage2D(GL_TEXTURE_2D,\n> > > @@ -406,9 +401,9 @@ void ViewFinderGL::doRender()\n> > >                              GL_RED,\n> > >                              GL_UNSIGNED_BYTE,\n> > >                              (char *)yuvData_ + size_.width() *\n> > > size_.height());\n> > > -               shaderProgram_.setUniformValue(textureUniformV_, 1);\n> > > +               shaderProgram_.setUniformValue(textureUniformV_, 2);\n> > >\n> > > -               /* activate texture U */\n> > > +               /* Activate texture U */\n> > >                 glActiveTexture(GL_TEXTURE1);\n> > >                 configureTexture(id_u_);\n> > >                 glTexImage2D(GL_TEXTURE_2D,\n> > > @@ -420,7 +415,7 @@ void ViewFinderGL::doRender()\n> > >                              GL_RED,\n> > >                              GL_UNSIGNED_BYTE,\n> > >                              (char *)yuvData_ + size_.width() *\n> > > size_.height() * 5 / 4);\n> > > -               shaderProgram_.setUniformValue(textureUniformU_, 2);\n> > > +               shaderProgram_.setUniformValue(textureUniformU_, 1);\n> > >\n> >\n> > I applied the above changes and tested on my rockpi4b with imx219. It's\n> > running well.\n> > But I have only the imx219 camera module to test with qcam, which means\n> > qcam only verified NV12 format is correct.\n> > So I use another small tool to test other formats and shader code.\n>\n> Would it be possible to share that tool ?\n>\n> > When the format YVU420 and YUV420 use the same shader code.\n> > +               shaderProgram_.setUniformValue(textureUniformV_, 2);\n> > ...\n> > +               shaderProgram_.setUniformValue(textureUniformU_, 1);\n> > above change cause the color became blue in format YVU420.\n> > The original value is correct I think.\n>\n> There's something I don't get then. The common shader is written as\n>\n>         yuv.x = texture2D(tex_y, textureOut).r - 0.063;\n>         yuv.y = texture2D(tex_u, textureOut).r - 0.500;\n>         yuv.z = texture2D(tex_v, textureOut).r - 0.500;\n>\n> so it expects Y in the tex_y uniform, U in the tex_u uniform and V in\n> the tex_v uniform. We retrieve the uniforms with\n>\n>         textureUniformY_ = shaderProgram_.uniformLocation(\"tex_y\");\n>         textureUniformU_ = shaderProgram_.uniformLocation(\"tex_u\");\n>         textureUniformV_ = shaderProgram_.uniformLocation(\"tex_v\");\n>\n> For YUV420, we have\n>\n>         case libcamera::formats::YUV420:\n>                 /* Activate texture Y */\n>                 glActiveTexture(GL_TEXTURE0);\n>                 configureTexture(id_y_);\n>                 glTexImage2D(...);\n>                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n>\n>                 /* Activate texture U */\n>                 glActiveTexture(GL_TEXTURE1);\n>                 configureTexture(id_u_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n>                              0,\n>                              GL_RED,\n>                              size_.width() / horzSubSample_,\n>                              size_.height() / vertSubSample_,\n>                              0,\n>                              GL_RED,\n>                              GL_UNSIGNED_BYTE,\n>                              (char *)yuvData_ + size_.width() *\n> size_.height());\n>                 shaderProgram_.setUniformValue(textureUniformU_, 1);\n>\n>                 /* Activate texture V */\n>                 glActiveTexture(GL_TEXTURE2);\n>                 configureTexture(id_v_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n>                              0,\n>                              GL_RED,\n>                              size_.width() / horzSubSample_,\n>                              size_.height() / vertSubSample_,\n>                              0,\n>                              GL_RED,\n>                              GL_UNSIGNED_BYTE,\n>                              (char *)yuvData_ + size_.width() *\n> size_.height() * 5 / 4);\n>                 shaderProgram_.setUniformValue(textureUniformV_, 2);\n>\n> We store 0, which I assume corresponds to GL_TEXTURE0, in\n> textureUniformY_, 1 in textureUniformU_ and 2 in textureUniformV_.\n> GL_TEXTURE[012] are filled with the Y, U and V data respectively. So\n> far, so good.\n>\n> For YVU420, we have\n>\n>         case libcamera::formats::YVU420:\n>                 /* Activate texture Y */\n>                 glActiveTexture(GL_TEXTURE0);\n>                 configureTexture(id_y_);\n>                 glTexImage2D(...);\n>                 shaderProgram_.setUniformValue(textureUniformY_, 0);\n>\n>                 /* Activate texture V */\n>                 glActiveTexture(GL_TEXTURE2);\n>                 configureTexture(id_v_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n>                              0,\n>                              GL_RED,\n>                              size_.width() / horzSubSample_,\n>                              size_.height() / vertSubSample_,\n>                              0,\n>                              GL_RED,\n>                              GL_UNSIGNED_BYTE,\n>                              (char *)yuvData_ + size_.width() *\n> size_.height());\n>                 shaderProgram_.setUniformValue(textureUniformV_, 2);\n>\n>                 /* Activate texture U */\n>                 glActiveTexture(GL_TEXTURE1);\n>                 configureTexture(id_u_);\n>                 glTexImage2D(GL_TEXTURE_2D,\n>                              0,\n>                              GL_RED,\n>                              size_.width() / horzSubSample_,\n>                              size_.height() / vertSubSample_,\n>                              0,\n>                              GL_RED,\n>                              GL_UNSIGNED_BYTE,\n>                              (char *)yuvData_ + size_.width() *\n> size_.height() * 5 / 4);\n>                 shaderProgram_.setUniformValue(textureUniformU_, 1);\n>\n> We handle Y the same way. We also store V in GL_TEXTURE2, and set\n> textureUniformV_ to 2 accordingly. The difference is in the\n> glTexImage2D() call, that's where we swap U and V. What am I missing ?\n>\nYeah. you are right.\nSorry, my fault. I activated the wrong texture(GL_TEXTURE1/2) in that tool.\n\n\nThanks,\nShow\n\n\n> > >               break;\n> > >\n> > >         default:\n> > >\n> > > Show Liu (4):\n> > >   qcam: Add OpenGL shader code as Qt resource\n> > >   qcam: New viewfinder hierarchy\n> > >   qcam: Add ViewFinderGL class to accelerate the format conversion\n> > >   qcam: Add additional command line option to select the renderer type\n> > >\n> > >  meson.build                                   |   1 +\n> > >  src/qcam/assets/shader/NV_2_planes_UV_f.glsl  |  32 ++\n> > >  src/qcam/assets/shader/NV_2_planes_VU_f.glsl  |  32 ++\n> > >  src/qcam/assets/shader/NV_3_planes_f.glsl     |  33 ++\n> > >  src/qcam/assets/shader/NV_vertex_shader.glsl  |  16 +\n> > >  src/qcam/assets/shader/shaders.qrc            |   9 +\n> > >  src/qcam/main.cpp                             |   3 +\n> > >  src/qcam/main_window.cpp                      |  32 +-\n> > >  src/qcam/main_window.h                        |   1 +\n> > >  src/qcam/meson.build                          |  20 +-\n> > >  src/qcam/viewfinder.h                         |  57 +--\n> > >  src/qcam/viewfinder_gl.cpp                    | 451 ++++++++++++++++++\n> > >  src/qcam/viewfinder_gl.h                      |  96 ++++\n> > >  .../{viewfinder.cpp => viewfinder_qt.cpp}     |  24 +-\n> > >  src/qcam/viewfinder_qt.h                      |  64 +++\n> > >  15 files changed, 806 insertions(+), 65 deletions(-)\n> > >  create mode 100644 src/qcam/assets/shader/NV_2_planes_UV_f.glsl\n> > >  create mode 100644 src/qcam/assets/shader/NV_2_planes_VU_f.glsl\n> > >  create mode 100644 src/qcam/assets/shader/NV_3_planes_f.glsl\n> > >  create mode 100644 src/qcam/assets/shader/NV_vertex_shader.glsl\n> > >  create mode 100644 src/qcam/assets/shader/shaders.qrc\n> > >  create mode 100644 src/qcam/viewfinder_gl.cpp\n> > >  create mode 100644 src/qcam/viewfinder_gl.h\n> > >  rename src/qcam/{viewfinder.cpp => viewfinder_qt.cpp} (86%)\n> > >  create mode 100644 src/qcam/viewfinder_qt.h\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id C15C8BF01C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 16 Sep 2020 03:21:17 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3EE2D62E1B;\n\tWed, 16 Sep 2020 05:21:17 +0200 (CEST)","from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com\n\t[IPv6:2607:f8b0:4864:20::62c])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 27B1062C8C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 16 Sep 2020 05:21:15 +0200 (CEST)","by mail-pl1-x62c.google.com with SMTP id y6so2415440plt.9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 15 Sep 2020 20:21:15 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=linaro.org header.i=@linaro.org\n\theader.b=\"TMz5Kos6\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=JIOhWSAR+iAAsV6pU4WlYzwYQgw/aXkNFjZJcdHRwx0=;\n\tb=TMz5Kos6pM+cFJso1Hf0LDXwyMBzZyx3RKKPw6QPd/W3OoXGRwZDZAS6qm6BdNql5p\n\t2xbn5nrHo7RO+TNDmhc7iLWJ+YdOKKtCPGOTjqVjyt1JrVwS8fTSlRc3VobMLEin2D4d\n\t7KezL84S/BtuAiKFpLLw9/v1lT8TzpfzscFYfu2Pty3JMIRSu1bbMiNVN1R2/jzsGekN\n\tIs2ICOcmH+4b17YyS7kBajtUhjrPPjUmpcfqmO6nDJNwqP9kzDp8Z/8wlV3USWsqAc1Y\n\tewt+BUE5FVYoz0MREpdyxQOklxCuHDyDZnEkGdO8PikiFl2cslzuZTusET7uht6cNGnE\n\t2fBg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=JIOhWSAR+iAAsV6pU4WlYzwYQgw/aXkNFjZJcdHRwx0=;\n\tb=pCyhViX8bolVhNataAw82UxGB9YiXinwY/KB7vgWNm1CuAyjDIYfPNnCgbY4b+/gmD\n\tURtzZA6G52TYqgHJTZBMAftakxlyfvKtOGJiQpYiA1+KqnHqmdBeP/fSoe1LjKi0QYP1\n\tybOkoLZKWIlXwvdsL6WlieI82f6j6eTCnQqvLc3ExX6JPsxZYHPMFMJIoJLmybuO//Vy\n\toV4k/FO9V7gTY9pt2E/fSkGDdyWT5ZSUIkzf8PeE/IWGqGw5tzmv4WG0C0OLX1gZZ76u\n\tTGMXBsBVtecDQqI7UMa3F+9O54IUBYRjgffGqjL2xHtXuFnNCp39EziR8qSFTtxb5T+n\n\t6p8w==","X-Gm-Message-State":"AOAM533EBZprQ8xVVOuBZRbUQDEu9yw1OhtEM433QznMaaLEeyvthlPp\n\tzelaArT/Q/3qLZBMtkSU9QhCOvbG1Zp7R3aw+Cxy2A==","X-Google-Smtp-Source":"ABdhPJwFOgVZpmGLW5vVVn5YytK1QvZdukEIjtp8TGnAb0wL8oMnm1xsE97VdHZ5jUBQVR1qY8D9Wgic57Ag2Zzmq38=","X-Received":"by 2002:a17:902:8c96:b029:d0:ad87:6668 with SMTP id\n\tt22-20020a1709028c96b02900d0ad876668mr22058931plo.2.1600226473204;\n\tTue, 15 Sep 2020 20:21:13 -0700 (PDT)","MIME-Version":"1.0","References":"<20200915024623.30667-1-laurent.pinchart@ideasonboard.com>\n\t<CA+yuoHoY3ytmmiBH8sHmJHFWbkQiaedasXZ-wWPri3qdxOAsog@mail.gmail.com>\n\t<20200916023307.GK14954@pendragon.ideasonboard.com>","In-Reply-To":"<20200916023307.GK14954@pendragon.ideasonboard.com>","From":"Show Liu <show.liu@linaro.org>","Date":"Wed, 16 Sep 2020 11:21:02 +0800","Message-ID":"<CA+yuoHr38j_yXtFkg+NQK278V65HEdKnjFqTiXn+NfkOM+_-XQ@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v7 0/4] qcam: accelerate format\n\tconversion by OpenGL shader","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"multipart/mixed;\n\tboundary=\"===============0551724839627569876==\"","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]