virtual void updateState(const RenderState &state,
        QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
    {
        Q_UNUSED(oldMaterial);

        VideoMaterial *material = static_cast<VideoMaterial *>(newMaterial);
        if (m_id_rgbTexture > 0) {
            program()->setUniformValue(m_id_rgbTexture, 0);
        } else {
            program()->setUniformValue(m_id_yTexture, 0);
            program()->setUniformValue(m_id_uTexture, 1);
            program()->setUniformValue(m_id_vTexture, 2);
        }

        if (state.isOpacityDirty()) {
            material->setFlag(QSGMaterial::Blending,
                qFuzzyCompare(state.opacity(), 1.0f) ? false : true);
            program()->setUniformValue(m_id_opacity, GLfloat(state.opacity()));
        }

        if (state.isMatrixDirty())
            program()->setUniformValue(m_id_matrix, state.combinedMatrix());

        program()->setUniformValue(m_id_colorMatrix, material->m_colorMatrix);

        material->bind();
    }
Beispiel #2
0
void OpenGLVideoPrivate::bindAttributes(VideoShader* shader, const QRectF &t, const QRectF &r)
{
    // also check size change for normalizedROI computation if roi is not normalized
    const bool roi_changed = valiad_tex_width != material->validTextureWidth() || roi != r || video_size != material->frameSize();
    const int tc = shader->textureLocationCount();
    if (roi_changed) {
        roi = r;
        valiad_tex_width = material->validTextureWidth();
        video_size = material->frameSize();
    }
    if (tex_target != shader->textureTarget()) {
        tex_target = shader->textureTarget();
        update_geo = true;
    }
    QRectF& target_rect = rect;
    if (target.isValid()) {
        if (roi_changed || target != t) {
            target = t;
            update_geo = true;
            //target_rect = target (if valid). // relate to gvf bug?
        }
    } else {
        if (roi_changed) {
            update_geo = true;
        }
    }
    if (!update_geo) {
        gr.bindBuffers(&geometry);
        return;
    }
    //qDebug("updating geometry...");
    // setTextureCount may change the vertex data. Call it before setRect()
    geometry.setTextureCount(shader->textureTarget() == GL_TEXTURE_RECTANGLE ? tc : 1);
    geometry.setRect(target_rect, material->mapToTexture(0, roi));
    if (shader->textureTarget() == GL_TEXTURE_RECTANGLE) {
        for (int i = 1; i < tc; ++i) {
            // tc can > planes, but that will compute chroma plane
            geometry.setTextureRect(material->mapToTexture(i, roi), i);
        }
    }
    update_geo = false;
    gr.updateBuffers(&geometry);
    gr.bindBuffers(&geometry);
}
VideoMaterial *VideoMaterial::create(const BufferFormat & format)
{
    VideoMaterial *material = NULL;

    switch (format.videoFormat()) {
    // BGRx
    case GST_VIDEO_FORMAT_BGRx:
    case GST_VIDEO_FORMAT_BGRA:
        material = new VideoMaterialImpl<qtvideosink_glsl_bgrxFragmentShader>;
        material->initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
        break;
    case GST_VIDEO_FORMAT_BGR:
        material = new VideoMaterialImpl<qtvideosink_glsl_bgrxFragmentShader>;
        material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
        break;

    // xRGB
    case GST_VIDEO_FORMAT_xRGB:
    case GST_VIDEO_FORMAT_ARGB:
    case GST_VIDEO_FORMAT_AYUV:
        material = new VideoMaterialImpl<qtvideosink_glsl_xrgbFragmentShader>;
        material->initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
        break;

    // RGBx
    case GST_VIDEO_FORMAT_RGB:
    case GST_VIDEO_FORMAT_v308:
        material = new VideoMaterialImpl<qtvideosink_glsl_rgbxFragmentShader>;
        material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
        break;
    case GST_VIDEO_FORMAT_RGB16:
        material = new VideoMaterialImpl<qtvideosink_glsl_rgbxFragmentShader>;
        material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
        break;

    // YUV 420 planar
    case GST_VIDEO_FORMAT_I420:
    case GST_VIDEO_FORMAT_YV12:
        material = new VideoMaterialImpl<qtvideosink_glsl_yuvPlanarFragmentShader>;
        material->initYuv420PTextureInfo(
            (format.videoFormat() == GST_VIDEO_FORMAT_YV12) /* uvSwapped */,
            format.frameSize());
        break;

    default:
        Q_ASSERT(false);
        break;
    }

    material->init(format.colorMatrix());
    return material;
}
Beispiel #4
0
void OpenGLVideoPrivate::bindAttributes(VideoShader* shader, const QRectF &t, const QRectF &r)
{
    const bool tex_rect = shader->textureTarget() == GL_TEXTURE_RECTANGLE;
    // also check size change for normalizedROI computation if roi is not normalized
    const bool roi_changed = valiad_tex_width != material->validTextureWidth() || roi != r || video_size != material->frameSize();
    const int tc = shader->textureLocationCount();
    if (roi_changed) {
        roi = r;
        valiad_tex_width = material->validTextureWidth();
        video_size = material->frameSize();
    }
    if (tex_target != shader->textureTarget()) {
        tex_target = shader->textureTarget();
        update_geo = true;
    }
    QRectF& target_rect = rect;
    if (target.isValid()) {
        if (roi_changed || target != t) {
            target = t;
            update_geo = true;
        }
    } else {
        if (roi_changed) {
            update_geo = true;
        }
    }
    if (!update_geo)
        goto end;
    //qDebug("updating geometry...");
    geometry.setRect(target_rect, material->mapToTexture(0, roi));
    if (tex_rect) {
        geometry.setTextureCount(tc);
        for (int i = 1; i < tc; ++i) {
            // tc can > planes, but that will compute chroma plane
            geometry.setTextureRect(material->mapToTexture(i, roi), i);
        }
    }
    update_geo = false;
    if (!try_vbo)
        goto end;
    { //VAO scope BEGIN
#if QT_VAO
    if (try_vao) {
        //qDebug("updating vao...");
        if (!vao.isCreated()) {
            if (!vao.create()) {
                try_vao = false;
                qDebug("VAO is not supported");
            }
        }
    }
    QOpenGLVertexArrayObject::Binder vao_bind(&vao);
    Q_UNUSED(vao_bind);
#endif
    if (!vbo.isCreated()) {
        if (!vbo.create()) {
            try_vbo = false; // not supported by OpenGL
            try_vao = false; // also disable VAO. destroy?
            qWarning("VBO is not supported");
            goto end;
        }
    }
    //qDebug("updating vbo...");
    vbo.bind(); //check here
    vbo.allocate(geometry.data(), geometry.size());
#if QT_VAO
    if (try_vao) {
        shader->program()->setAttributeBuffer(0, GL_FLOAT, 0, geometry.tupleSize(), geometry.stride());
        shader->program()->setAttributeBuffer(1, GL_FLOAT, geometry.tupleSize()*sizeof(float), geometry.tupleSize(), geometry.stride());
        if (tex_rect) {
            for (int i = 1; i < tc; ++i) {
                shader->program()->setAttributeBuffer(i + 1, GL_FLOAT, i*geometry.textureSize() + geometry.tupleSize()*sizeof(float), geometry.tupleSize(), geometry.stride());
            }
        }
        char const *const *attr = shader->attributeNames();
        for (int i = 0; attr[i]; ++i) {
            shader->program()->enableAttributeArray(i); //TODO: in setActiveShader
        }
    }
#endif
    vbo.release();
    } //VAO scope END
end:
#if QT_VAO
    if (try_vao && vao.isCreated()) {
        vao.bind();
        return;
    }
#endif
    if (try_vbo && vbo.isCreated()) {
        vbo.bind();
        shader->program()->setAttributeBuffer(0, GL_FLOAT, 0, geometry.tupleSize(), geometry.stride());
        shader->program()->setAttributeBuffer(1, GL_FLOAT, geometry.tupleSize()*sizeof(float), geometry.tupleSize(), geometry.stride());
        if (tex_rect) {
            for (int i = 1; i < tc; ++i) {
                shader->program()->setAttributeBuffer(i + 1, GL_FLOAT, i*geometry.textureSize() + geometry.tupleSize()*sizeof(float), geometry.tupleSize(), geometry.stride());
            }
        }
    } else {
        shader->program()->setAttributeArray(0, GL_FLOAT, geometry.data(0), geometry.tupleSize(), geometry.stride());
        shader->program()->setAttributeArray(1, GL_FLOAT, geometry.data(1), geometry.tupleSize(), geometry.stride());
        if (tex_rect) {
            for (int i = 1; i < tc; ++i) {
                shader->program()->setAttributeArray(i + 1, GL_FLOAT, geometry.data(1), i*geometry.textureSize() + geometry.tupleSize(), geometry.stride());
            }
        }
    }
    char const *const *attr = shader->attributeNames();
    for (int i = 0; attr[i]; ++i) {
        shader->program()->enableAttributeArray(i); //TODO: in setActiveShader
    }
}