我已经使用 QCamera 和 QAbstractVideoSurface 实现了相机捕捉。我将 QAbstractVideoSurface 扩展为派生类,以将捕获编组到缓冲区中以供将来处理。一切正常,但我在更改输入捕获的捕获分辨率时遇到问题。
使用 setNativeResolution() 似乎不起作用。
下面是代码的简要说明。
#ifndef _CAPTURE_BUFFER_H_
#define _CAPTURE_BUFFER_H_
#include <QMutex>
#include <QWidget>
#include <QImage>
#include <QVideoFrame>
#include <QAbstractVideoSurface>
#include <QVideoSurfaceFormat>
#include <control/qcircularbuffer.h>
class CaptureBuffer: public QAbstractVideoSurface
{
Q_OBJECT
public:
CaptureBuffer(int size = 30);
QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const;
bool start(const QVideoSurfaceFormat& format);
void stop();
bool present(const QVideoFrame& frame);
bool isEmpty() const;
void pushBack(const QVideoFrame& new_frame);
void popFront();
bool top(QVideoFrame& frame);
bool back(QVideoFrame& frame);
const QImage::Format& image_format() const {return m_image_format;}
const QSize& image_size() const {return m_image_size;}
protected:
void setNativeResolution(const QSize & resolution);
private:
QSize m_image_size;
QImage::Format m_image_format;
QCircularBuffer<QVideoFrame> m_buffer;
QMutex m_buffer_mutex;
};
#endif
CaptureBuffer::CaptureBuffer(int size) :
m_buffer(QCircularBuffer<QVideoFrame>(size))
{
}
QList<QVideoFrame::PixelFormat> CaptureBuffer::supportedPixelFormats(
QAbstractVideoBuffer::HandleType handleType) const
{
if (handleType == QAbstractVideoBuffer::NoHandle) {
return QList<QVideoFrame::PixelFormat>()
<< QVideoFrame::Format_RGB24
<< QVideoFrame::Format_RGB32
<< QVideoFrame::Format_ARGB32
<< QVideoFrame::Format_ARGB32_Premultiplied
<< QVideoFrame::Format_RGB565
<< QVideoFrame::Format_RGB555;
} else {
return QList<QVideoFrame::PixelFormat>();
}
}
bool CaptureBuffer::start(const QVideoSurfaceFormat& format)
{
const QImage::Format image_format = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
const QSize size = format.frameSize();
if (image_format != QImage::Format_Invalid && !size.isEmpty()) {
m_image_format = image_format;
m_image_size = size;
QAbstractVideoSurface::start(format);
return true;
} else {
return false;
}
}
void CaptureBuffer::stop()
{
QAbstractVideoSurface::stop();
}
bool CaptureBuffer::present(const QVideoFrame& frame)
{
pushBack(frame);
return true;
}
bool CaptureBuffer::isEmpty() const
{
return m_buffer.empty();
}
void CaptureBuffer::pushBack(const QVideoFrame& frame)
{
m_buffer_mutex.lock();
m_buffer.push_back(frame);
m_buffer_mutex.unlock();
}
void CaptureBuffer::popFront()
{
m_buffer_mutex.lock();
m_buffer.pop_front();
m_buffer_mutex.unlock();
}
bool CaptureBuffer::top(QVideoFrame& frame)
{
if(m_buffer.empty())
return false;
m_buffer_mutex.lock();
frame = m_buffer.front();
m_buffer_mutex.unlock();
return true;
}
bool CaptureBuffer::back(QVideoFrame& frame)
{
if(m_buffer.empty())
return false;
m_buffer_mutex.lock();
frame = m_buffer.back();
m_buffer_mutex.unlock();
return true;
}
void CaptureBuffer::setNativeResolution( const QSize & resolution )
{
QAbstractVideoSurface::setNativeResolution(resolution);
}
以下是 QCamera 的使用方式和附加到捕获缓冲区的方式:
m_camera = camera;
m_camera->setCaptureMode(QCamera::CaptureVideo);
m_camera->setViewfinder(m_capture_buffer);
m_camera->start();
鉴于网络摄像头支持此分辨率,如何将输入捕获分辨率从 640 x 480 调整为 1280 x 720 等。