我想用QT制作视频会议应用。我是新手。如果有人有这方面的例子,我会很感激。
现在,我正在尝试使用qabstractvideosurface的子类在屏幕上显示相机图片。任何人都知道如何做到这一点?
答案 0 :(得分:17)
QAbstractVideoSurface
是视频帧的制作者和消费者之间的接口。
您只需要实现两个函数:
QVideoFrame
假设您想要使用经典的QWidget
进行显示。在这种情况下,您可以选择使用QImage
在小部件上绘图。
第一个Qt保证在大多数平台上绘制一个QImage
RGB24(或BGR24)。所以
QList<QVideoFrame::PixelFormat> LabelBasedVideoSurface::supportedPixelFormats(
QAbstractVideoBuffer::HandleType handleType) const
{
if (handleType == QAbstractVideoBuffer::NoHandle) {
return QList<QVideoFrame::PixelFormat>()
<< QVideoFrame::Format_RGB24;
} else {
return QList<QVideoFrame::PixelFormat>();
}
}
现在展示QVideoFrame,将其数据映射到QImage,并将QImage绘制到窗口小部件。为简单起见,我将使用QLabel
,我可以直接访问(无信号无槽)。
bool LabelBasedVideoSurface::present(const QVideoFrame &frame)
{
if (notMyFormat(frame.pixelFormat())) {
setError(IncorrectFormatError);
return false;
} else {
QVideoFrame frametodraw(frame);
if(!frametodraw.map(QAbstractVideoBuffer::ReadOnly))
{
setError(ResourceError);
return false;
}
//this is a shallow operation. it just refer the frame buffer
QImage image(
frametodraw.bits(),
frametodraw.width(),
frametodraw.height(),
frametodraw.bytesPerLine(),
QImage::Format_RGB444);
mylabel->resize(image.size());
//QPixmap::fromImage create a new buffer for the pixmap
mylabel->setPixmap(QPixmap::fromImage(image));
//we can release the data
frametodraw.unmap();
mylabel->update();
return true;
}
}
这个例子显然不是最佳的。
QVideoFrame
可能会存储在视频内存中这一事实并非现金。您可以编写自己的小部件,并实现paintEvent以获得更好的性能。此外,您对present()
的行为方式有几个设计自由。例如:
mylabel->repaint()
而不是mylabel->update()