qt: Fixup for dummy textures

* Initialize dummy texture Ids
* Ensure YUV->RGB matrix set for dummy textures

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6578>
This commit is contained in:
Jochen Henneberg 2024-04-06 02:28:44 +02:00
parent 448a461a40
commit 87dc22b053
2 changed files with 44 additions and 23 deletions

View file

@ -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);

View file

@ -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_;