From 87dc22b053922c27058576e5c056bbf855b5b8a0 Mon Sep 17 00:00:00 2001 From: Jochen Henneberg Date: Sat, 6 Apr 2024 02:28:44 +0200 Subject: [PATCH] qt: Fixup for dummy textures * Initialize dummy texture Ids * Ensure YUV->RGB matrix set for dummy textures Part-of: --- .../gst-plugins-good/ext/qt/gstqsgmaterial.cc | 64 ++++++++++++------- .../gst-plugins-good/ext/qt/gstqsgmaterial.h | 3 + 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/subprojects/gst-plugins-good/ext/qt/gstqsgmaterial.cc b/subprojects/gst-plugins-good/ext/qt/gstqsgmaterial.cc index f5c3759515..a24789e961 100644 --- a/subprojects/gst-plugins-good/ext/qt/gstqsgmaterial.cc +++ b/subprojects/gst-plugins-good/ext/qt/gstqsgmaterial.cc @@ -220,6 +220,7 @@ GstQSGMaterial::GstQSGMaterial () this->buffer_ = NULL; this->buffer_was_bound = FALSE; this->sync_buffer_ = gst_buffer_new (); + memset (&this->dummy_textures, 0, sizeof (this->dummy_textures)); } GstQSGMaterial::~GstQSGMaterial () @@ -338,6 +339,32 @@ GstQSGMaterial::createShader() const return new GstQSGMaterialShader(v_format, vertex, fragment); } +void +GstQSGMaterial::initYuvShaders (GstQSGMaterialShader *shader, + const GstVideoColorimetry *cinfo) +{ + g_return_if_fail (shader); + + if (cinfo && gst_video_colorimetry_matches (cinfo, + GST_VIDEO_COLORIMETRY_BT709)) { + this->cms_offset = (gfloat *) from_yuv_bt709_offset; + this->cms_ycoeff = (gfloat *) from_yuv_bt709_rcoeff; + this->cms_ucoeff = (gfloat *) from_yuv_bt709_gcoeff; + this->cms_vcoeff = (gfloat *) from_yuv_bt709_bcoeff; + } else { + /* defaults/bt601 */ + this->cms_offset = (gfloat *) from_yuv_bt601_offset; + this->cms_ycoeff = (gfloat *) from_yuv_bt601_rcoeff; + this->cms_ucoeff = (gfloat *) from_yuv_bt601_gcoeff; + this->cms_vcoeff = (gfloat *) from_yuv_bt601_bcoeff; + } + + shader->program()->setUniformValue(shader->cms_uniform_offset, QVector3D(this->cms_offset[0], this->cms_offset[1], this->cms_offset[2])); + shader->program()->setUniformValue(shader->cms_uniform_ycoeff, QVector3D(this->cms_ycoeff[0], this->cms_ycoeff[1], this->cms_ycoeff[2])); + shader->program()->setUniformValue(shader->cms_uniform_ucoeff, QVector3D(this->cms_ucoeff[0], this->cms_ucoeff[1], this->cms_ucoeff[2])); + shader->program()->setUniformValue(shader->cms_uniform_vcoeff, QVector3D(this->cms_vcoeff[0], this->cms_vcoeff[1], this->cms_vcoeff[2])); +} + /* only called from the streaming thread with scene graph thread blocked */ void GstQSGMaterial::setCaps (GstCaps * caps) @@ -426,28 +453,10 @@ GstQSGMaterial::bind(GstQSGMaterialShader *shader, GstVideoFormat v_format) gst_gl_sync_meta_wait (sync_meta, qt_context); - if (this->v_frame.info.finfo->flags & GST_VIDEO_FORMAT_FLAG_YUV) { - if (gst_video_colorimetry_matches (&this->v_frame.info.colorimetry, - GST_VIDEO_COLORIMETRY_BT709)) { - this->cms_offset = (gfloat *) from_yuv_bt709_offset; - this->cms_ycoeff = (gfloat *) from_yuv_bt709_rcoeff; - this->cms_ucoeff = (gfloat *) from_yuv_bt709_gcoeff; - this->cms_vcoeff = (gfloat *) from_yuv_bt709_bcoeff; - } else { - /* defaults/bt601 */ - this->cms_offset = (gfloat *) from_yuv_bt601_offset; - this->cms_ycoeff = (gfloat *) from_yuv_bt601_rcoeff; - this->cms_ucoeff = (gfloat *) from_yuv_bt601_gcoeff; - this->cms_vcoeff = (gfloat *) from_yuv_bt601_bcoeff; - } - - shader->program()->setUniformValue(shader->cms_uniform_offset, QVector3D(this->cms_offset[0], this->cms_offset[1], this->cms_offset[2])); - shader->program()->setUniformValue(shader->cms_uniform_ycoeff, QVector3D(this->cms_ycoeff[0], this->cms_ycoeff[1], this->cms_ycoeff[2])); - shader->program()->setUniformValue(shader->cms_uniform_ucoeff, QVector3D(this->cms_ucoeff[0], this->cms_ucoeff[1], this->cms_ucoeff[2])); - shader->program()->setUniformValue(shader->cms_uniform_vcoeff, QVector3D(this->cms_vcoeff[0], this->cms_vcoeff[1], this->cms_vcoeff[2])); - } else { + if (this->v_frame.info.finfo->flags & GST_VIDEO_FORMAT_FLAG_YUV) + initYuvShaders (shader, &this->v_frame.info.colorimetry); + else this->cms_offset = this->cms_ycoeff = this->cms_ucoeff = this->cms_vcoeff = NULL; - } /* reversed iteration order so that glActiveTexture(GL_TEXTURE0) is last which keeps * us in the default GL state expected by several other qml components @@ -475,6 +484,9 @@ out: QOpenGLFunctions *funcs = qglcontext->functions (); const GstVideoFormatInfo *finfo = gst_video_format_get_info (v_format); + if (finfo->flags == GST_VIDEO_FORMAT_FLAG_YUV) + initYuvShaders (shader, nullptr); + /* Create dummy texture if not already present. * Use the Qt OpenGL functions instead of the GstGL ones, * since we are using the Qt OpenGL context here, and we must @@ -492,14 +504,20 @@ out: const int tex_sidelength = 64; std::vector < guint8 > dummy_data (tex_sidelength * tex_sidelength * 4, 0); + guint8 *data = dummy_data.data(); + switch (v_format) { case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_RGB: + for (gsize j = 0; j < tex_sidelength; j++) { + for (gsize k = 0; k < tex_sidelength; k++) { + data[(j * tex_sidelength + k) * 4 + 3] = 0xFF; // opaque + } + } break; case GST_VIDEO_FORMAT_YV12: if (i == 1 || i == 2) { - guint8 *data = dummy_data.data(); for (gsize j = 0; j < tex_sidelength; j++) { for (gsize k = 0; k < tex_sidelength; k++) { data[(j * tex_sidelength + k) * 4 + 0] = 0x7F; @@ -517,7 +535,7 @@ out: funcs->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); funcs->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); funcs->glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, tex_sidelength, - tex_sidelength, 0, GL_RGBA, GL_UNSIGNED_BYTE, &dummy_data[0]); + tex_sidelength, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); } g_assert (this->dummy_textures[i] != 0); diff --git a/subprojects/gst-plugins-good/ext/qt/gstqsgmaterial.h b/subprojects/gst-plugins-good/ext/qt/gstqsgmaterial.h index 308cbbf09e..b9fa88ae83 100644 --- a/subprojects/gst-plugins-good/ext/qt/gstqsgmaterial.h +++ b/subprojects/gst-plugins-good/ext/qt/gstqsgmaterial.h @@ -52,6 +52,9 @@ public: QSGMaterialShader *createShader() const override; private: + void initYuvShaders(GstQSGMaterialShader *shader, + const GstVideoColorimetry *cinfo); + GstBuffer * buffer_; gboolean buffer_was_bound; GstBuffer * sync_buffer_;