12#include <spa/buffer/buffer.h>
13#include <spa/param/video/raw.h>
19static void mirrorVertically(uchar *data,
int height,
int stride)
21 const int halfHeight = height / 2;
22 std::vector<uchar> temp(stride);
23 for (
int y = 0; y < halfHeight; ++y) {
24 auto cur = &data[y * stride], dest = &data[(height - y - 1) * stride];
25 memcpy(temp.data(), cur, stride);
26 memcpy(cur, dest, stride);
27 memcpy(dest, temp.data(), stride);
31static GLenum closestGLType(spa_video_format
format)
34 case SPA_VIDEO_FORMAT_RGB:
36 case SPA_VIDEO_FORMAT_BGR:
38 case SPA_VIDEO_FORMAT_RGBx:
39 case SPA_VIDEO_FORMAT_RGBA:
41 case SPA_VIDEO_FORMAT_BGRA:
42 case SPA_VIDEO_FORMAT_BGRx:
45 qDebug() <<
"unknown format" <<
format;
50static void doGrabTexture(GLTexture *texture, spa_data *spa, spa_video_format
format)
52 const QSize size = texture->size();
56 if (invertNeededAndSupported) {
57 glGetBooleanv(GL_PACK_INVERT_MESA, &prev);
58 glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE);
65 GLFramebuffer fbo(texture);
67 glReadPixels(0, 0, size.width(), size.height(), closestGLType(
format), GL_UNSIGNED_BYTE, spa->data);
70 glGetTextureImage(texture->texture(), 0, closestGLType(
format), GL_UNSIGNED_BYTE, spa->chunk->size, spa->data);
72 glGetTexImage(texture->target(), 0, closestGLType(
format), GL_UNSIGNED_BYTE, spa->data);
75 if (invertNeededAndSupported) {
77 glPixelStorei(GL_PACK_INVERT_MESA, prev);
79 }
else if (invertNeeded) {
80 mirrorVertically(
static_cast<uchar *
>(spa->data), size.height(), spa->chunk->stride);
84static void grabTexture(GLTexture *texture, spa_data *spa, spa_video_format
format)
86 const OutputTransform contentTransform = texture->contentTransform();
88 doGrabTexture(texture, spa,
format);
90 const QSize size = contentTransform.map(texture->size());
92 if (!backingTexture) {
98 QMatrix4x4 projectionMatrix;
99 projectionMatrix.scale(1, -1);
100 projectionMatrix.ortho(QRect(QPoint(), size));
103 GLFramebuffer fbo(backingTexture.get());
105 texture->render(size);
107 doGrabTexture(backingTexture.get(), spa,
format);
static GLFramebuffer * popFramebuffer()
static void pushFramebuffer(GLFramebuffer *fbo)
@ ModelViewProjectionMatrix
static std::unique_ptr< GLTexture > allocate(GLenum internalFormat, const QSize &size, int levels=1)