~mterry/qtvideo-node/dont-install-tests

« back to all changes in this revision

Viewing changes to src/shadervideonodeplugin.cpp

  • Committer: Tarmac
  • Author(s): Guenter Schwann
  • Date: 2012-11-09 10:57:05 UTC
  • mfrom: (5.1.1 qtvideonode-plugin-tests)
  • Revision ID: tarmac-20121109105705-4i02o2phcmtfowde
* Spliting up code in separate files
* Add a unit test.

Approved by PS Jenkins bot, Michael Zanetti.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 */
19
19
 
20
20
#include "shadervideonodeplugin.h"
21
 
 
22
 
#include "camera_compatibility_layer.h"
23
 
 
24
 
#include <QDebug>
25
 
#include <QMutex>
26
 
#include <QtQuick/qsgmaterial.h>
27
 
 
28
 
class ShaderVideoShader : public QSGMaterialShader
29
 
{
30
 
public:
31
 
    ShaderVideoShader(QVideoFrame::PixelFormat pixelFormat)
32
 
        : QSGMaterialShader(),
33
 
          m_pixelFormat(pixelFormat)
34
 
    {
35
 
    }
36
 
 
37
 
    void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial);
38
 
 
39
 
    virtual char const *const *attributeNames() const {
40
 
        static const char *names[] = {
41
 
            "qt_VertexPosition",
42
 
            "qt_VertexTexCoord",
43
 
            0
44
 
        };
45
 
        return names;
46
 
    }
47
 
 
48
 
    int m_tex_matrix;
49
 
 
50
 
protected:
51
 
 
52
 
    virtual const char *vertexShader() const {
53
 
        const char *shader =
54
 
            "#extension GL_OES_EGL_image_external : require     \n"
55
 
            "uniform highp mat4 qt_Matrix;                      \n"
56
 
            "attribute highp vec4 qt_VertexPosition;            \n"
57
 
            "attribute highp vec2 qt_VertexTexCoord;            \n"
58
 
            "varying highp vec2 qt_TexCoord;                    \n"
59
 
            "uniform mat4 s_tex_Matrix;                         \n"
60
 
            "void main() {                                      \n"
61
 
            "    qt_TexCoord = (s_tex_Matrix * vec4(qt_VertexTexCoord, 0.0, 1.0)).xy;\n"
62
 
            "    gl_Position = qt_Matrix * qt_VertexPosition;   \n"
63
 
            "}";
64
 
        return shader;
65
 
    }
66
 
 
67
 
    virtual const char *fragmentShader() const {
68
 
        static const char *shader =
69
 
            "#extension GL_OES_EGL_image_external : require      \n"
70
 
            "uniform samplerExternalOES sTexture;                \n"
71
 
            "uniform lowp float opacity;                         \n"
72
 
            "varying highp vec2 qt_TexCoord;                     \n"
73
 
            "void main()                                         \n"
74
 
            "{                                                   \n"
75
 
            "  gl_FragColor = texture2D( sTexture, qt_TexCoord );\n"
76
 
            "}                                                   \n";
77
 
        return shader;
78
 
    }
79
 
 
80
 
    virtual void initialize() {
81
 
        m_id_matrix = program()->uniformLocation("qt_Matrix");
82
 
        m_id_Texture = program()->uniformLocation("sTexture");
83
 
        m_id_opacity = program()->uniformLocation("opacity");
84
 
        m_tex_matrix = program()->uniformLocation("s_tex_Matrix");
85
 
    }
86
 
 
87
 
    int m_id_matrix;
88
 
    int m_id_Texture;
89
 
    int m_id_opacity;
90
 
    QVideoFrame::PixelFormat m_pixelFormat;
91
 
};
92
 
 
93
 
class ShaderVideoMaterial : public QSGMaterial
94
 
{
95
 
public:
96
 
    ShaderVideoMaterial(const QVideoSurfaceFormat &format)
97
 
        : m_format(format),
98
 
          m_camControl(0),
99
 
          m_videoShader(0)
100
 
    {}
101
 
    ~ShaderVideoMaterial() {}
102
 
 
103
 
    QSGMaterialShader *createShader() const {
104
 
        m_videoShader = new ShaderVideoShader(m_format.pixelFormat());
105
 
        return m_videoShader;
106
 
    }
107
 
 
108
 
    virtual QSGMaterialType *type() const {
109
 
        static QSGMaterialType theType;
110
 
        return &theType;
111
 
    }
112
 
 
113
 
    void setCamControl(CameraControl *cc) {
114
 
        m_camControl = cc;
115
 
    }
116
 
 
117
 
    CameraControl *cameraControl() const { return m_camControl; }
118
 
 
119
 
    void bind()
120
 
    {
121
 
        if (!m_camControl) {
122
 
            qWarning() << "No valid CameraControl";
123
 
            return;
124
 
        }
125
 
 
126
 
        android_camera_update_preview_texture(m_camControl);
127
 
 
128
 
        android_camera_get_preview_texture_transformation(m_camControl, m_textureMatrix);
129
 
        flipMatrixY();
130
 
        glUniformMatrix4fv(m_videoShader->m_tex_matrix, 1, GL_FALSE, m_textureMatrix);
131
 
 
132
 
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
133
 
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
134
 
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
135
 
        glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
136
 
    }
137
 
 
138
 
    // As long as coordinates are 0..1, the y is flipped
139
 
    void flipMatrixY()
140
 
    {
141
 
        // reduced way to multiplay the matrix with following matrix and assigin it back again
142
 
        // 1  0  0  0
143
 
        // 0 -1  0  1
144
 
        // 0  0  1  0
145
 
        // 0  0  0  1
146
 
        m_textureMatrix[1] = -m_textureMatrix[1] + m_textureMatrix[3];
147
 
        m_textureMatrix[5] = -m_textureMatrix[5] + m_textureMatrix[7];
148
 
        m_textureMatrix[9] = -m_textureMatrix[9] + m_textureMatrix[11];
149
 
        m_textureMatrix[13] = -m_textureMatrix[13] + m_textureMatrix[15];
150
 
    }
151
 
 
152
 
private:
153
 
    QVideoSurfaceFormat m_format;
154
 
    CameraControl *m_camControl;
155
 
    mutable ShaderVideoShader *m_videoShader;
156
 
    GLfloat m_textureMatrix[16];
157
 
    GLfloat m_flippedTextureMatrix[16];
158
 
};
159
 
 
160
 
 
161
 
 
162
 
ShaderVideoNode::ShaderVideoNode(const QVideoSurfaceFormat &format) :
163
 
    m_format(format)
164
 
{
165
 
    m_material = new ShaderVideoMaterial(format);
166
 
    setMaterial(m_material);
167
 
}
168
 
 
169
 
void ShaderVideoNode::setCurrentFrame(const QVideoFrame &frame)
170
 
{
171
 
    QMutexLocker ml(&m_guard);
172
 
    if (! m_material->cameraControl()) {
173
 
        if (!frame.availableMetaData().contains("CamControl")) {
174
 
            qDebug() << "No camera control included in video frame";
175
 
            return;
176
 
        }
177
 
        int ci = frame.metaData("CamControl").toInt();
178
 
        m_material->setCamControl((CameraControl*)ci);
179
 
    }
180
 
    markDirty(DirtyMaterial);
181
 
}
182
 
 
183
 
 
 
21
#include "shadervideonode.h"
184
22
 
185
23
QList<QVideoFrame::PixelFormat> ShaderVideoNodePlugin::supportedPixelFormats(
186
24
                                        QAbstractVideoBuffer::HandleType handleType) const
192
30
        pixelFormats.append(QVideoFrame::Format_ARGB32);
193
31
        pixelFormats.append(QVideoFrame::Format_BGR32);
194
32
        pixelFormats.append(QVideoFrame::Format_BGRA32);
 
33
        pixelFormats.append(QVideoFrame::Format_User); // handling a GL texture of the aal library for the camera
195
34
    }
196
35
 
197
36
    return pixelFormats;
204
43
 
205
44
    return 0;
206
45
}
207
 
 
208
 
 
209
 
 
210
 
void ShaderVideoShader::updateState(const RenderState &state,
211
 
                                                QSGMaterial *newMaterial,
212
 
                                                QSGMaterial *oldMaterial)
213
 
{
214
 
    Q_UNUSED(oldMaterial);
215
 
    ShaderVideoMaterial *mat = dynamic_cast<ShaderVideoMaterial *>(newMaterial);
216
 
    program()->setUniformValue(m_id_Texture, 0);
217
 
 
218
 
    if (state.isMatrixDirty())
219
 
        program()->setUniformValue(m_id_matrix, state.combinedMatrix());
220
 
 
221
 
    mat->bind();
222
 
 
223
 
//    if (state.isOpacityDirty()) {
224
 
//        mat->m_opacity = state.opacity();
225
 
//        mat->updateBlending();
226
 
//        program()->setUniformValue(m_id_opacity, GLfloat(mat->m_opacity));
227
 
//    }
228
 
}