一点背景:
我正在写一个媒体播放器,我必须在任何给定的视频上绘制一个大点云和一些更多的几何形状。复杂性还在于我们没有定义的视频格式,它可以采用任何格式。 (fps,决议)
一个限制是我们需要使用QT特定组件,如果QT中没有选项,任何外部库都将被讨论。
我确实实现了QAbstractVideoSurface
来读取帧,然后使用动态数据对其进行编辑。我在后面提到的代码中遇到了两个具体问题:
QPainter
的点,根据图像的分辨率变得非常慢。在低分辨率下,性能与实时性一样好,但在高分辨率下则非常糟糕。 首先,我知道这是一个众所周知的问题并得到广泛讨论,但我找到的答案都不适合我,因为所有这些答案最终都会出现在特定情况下。
我必须接受,在我完成这项任务之前,我对媒体处理一无所知,因为一切都是在飞行中发生的,我没有时间阅读大量文本。但是,如果你指出我正确的文件,我会从乞讨到结束。 :)
现在,下面是我的QAbstractVideoSurface
实施方法的代码:
bool VideoFrameGrabber::present(const QVideoFrame &frame)
{
if (frame.isValid())
{
QVideoFrame cloneFrame(frame);
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
qDebug()<<"1 "<<QTime::currentTime().msecsSinceStartOfDay();
const QImage image(cloneFrame.bits(),
cloneFrame.width(),
cloneFrame.height(),
QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat()));
qDebug()<<"2 "<<QTime::currentTime().msecsSinceStartOfDay();
imageEdited = image;
qDebug()<<"3 "<<QTime::currentTime().msecsSinceStartOfDay();
QPainter p(&imageEdited);
qDebug()<<"4 "<<QTime::currentTime().msecsSinceStartOfDay();
if(rectMetaData.count() > 0){
while(rectMetaData.at(rectSequence).frameNumber == frameSequence && rectSequence < rectCount-1)
{
if(rectMetaData.at(rectSequence).fillStatus){ p.setBrush(QBrush(QColor(rectMetaData.at(rectSequence).color)));
} else {
p.setPen(rectMetaData.at(rectSequence).color);
}
p.drawRect(rectMetaData.at(rectSequence).x1,
rectMetaData.at(rectSequence).y1,
rectMetaData.at(rectSequence).x2,
rectMetaData.at(rectSequence).y2);
rectSequence++;
}
}
qDebug()<<"5 "<<QTime::currentTime().msecsSinceStartOfDay();
if(circleMetaData.count() > 0){
while(circleMetaData.at(circleSequence).frameNumber == frameSequence && circleSequence < circleCount-1)
{
if(circleMetaData.at(circleSequence).fillStatus)
{
p.setBrush(QBrush(QColor(circleMetaData.at(circleSequence).color)));
} else {
p.setPen(circleMetaData.at(circleSequence).color);
}
p.drawEllipse(circleMetaData.at(circleSequence).centerX,
circleMetaData.at(circleSequence).centerY,
circleMetaData.at(circleSequence).radiusX,
circleMetaData.at(circleSequence).radiusY);
circleSequence++;
}
}
qDebug()<<"6 "<<QTime::currentTime().msecsSinceStartOfDay();
p.end();
//imageEdited.save(QString("frame"+QString::number(frameSequence)+".jpg"));
frameSequence++;
cloneFrame.unmap();
}
if (surfaceFormat().pixelFormat() != frame.pixelFormat()
|| surfaceFormat().frameSize() != frame.size()) {
setError(IncorrectFormatError);
stop();
return false;
} else {
currentFrame = QVideoFrame(imageEdited);
// check by reconverting above to image if it is lost in this conversion
// else it is a rendering problem
widget->repaint(targetRect);
return true;
}
}
两种不同视频情况下的调试输出是:
30 FPS, 1920*1080 pixels
1 68862821
2 68862822
3 68862822
4 68862892
5 68862893
6 68862893
25 FPS, 1280*720 pixels
1 69319622
2 69319622
3 69319623
4 69319653
5 69319654
6 69319654
请指出一些适合这两个问题的解决方案。
使用Windows 10 64位/ Intel I5第二代2.3 Gig 2 Core / 8 gig RAM捕获以上性能有人想比较。