If somebody is interested in the soultion:
#include <QObject>
#include <QAbstractVideoFilter>
#include <QVideoFilterRunnable>
#include <QAbstractVideoFilter>
#include <QVideoFrame>
#include <QDebug>
#include <QThread>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QQmlContext>
#include "private/qvideoframe_p.h"
...
QImage MyVideoFilterRunnable::QVideoFrameToQImage(const QVideoFrame& videoFrame)
{
if ( videoFrame.handleType() == QAbstractVideoBuffer::NoHandle )
{
QImage image = qt_imageFromVideoFrame( videoFrame );
if ( image.isNull() )
{
return QImage();
}
if ( image.format() != QImage::Format_ARGB32 )
{
image = image.convertToFormat( QImage::Format_ARGB32 );
}
return image;
}
if ( videoFrame.handleType() == QAbstractVideoBuffer::GLTextureHandle )
{
QImage image( videoFrame.width(), videoFrame.height(), QImage::Format_ARGB32 );
GLuint textureId = static_cast<GLuint>( videoFrame.handle().toInt() );
QOpenGLContext* ctx = QOpenGLContext::currentContext();
QOpenGLFunctions* f = ctx->functions();
GLuint fbo;
f->glGenFramebuffers( 1, &fbo );
GLint prevFbo;
f->glGetIntegerv( GL_FRAMEBUFFER_BINDING, &prevFbo );
f->glBindFramebuffer( GL_FRAMEBUFFER, fbo );
f->glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0 );
f->glReadPixels( 0, 0, videoFrame.width(), videoFrame.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.bits() );
f->glBindFramebuffer( GL_FRAMEBUFFER, static_cast<GLuint>( prevFbo ) );
return image.rgbSwapped();
}
return QImage();
}
QVideoFrame MyVideoFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
{
...
m_filter->m_frame.copyData(*input);
QImage img = QVideoFrameToQImage( *input );
QImage imgRoi = img.copy(xMin, yMin, width, height);
QVideoFrame frameRoi = QVideoFrame(imgRoi);
*input = frameRoi;
m_filter->m_processThread = QtConcurrent::run(this, &MyVideoFilterRunnable::processVideoFrame, m_filter->m_frame);
return *input;
}