本文是在上一篇opencv 打不开uvc camera的MJPEG格式的数据流的问题 的基础上,转用QCamera,最终能拿到camera数据。
ucv camera介绍
UVC全程是"USB Video Class",即USB视频类,是为USB视频捕获设备定义的一种协议,是由Microsoft和另几家设备厂商联合推出的标准协议,现在已经是USB org标准协议之一。
现在的主流操作系统(如Windows XP SP2 and later,Linux 2.4.6 and later,MacOS 10.5 and later)都提供了UVC设备驱动,所以UVC camera连上电脑是可以被直接识别的,而一般的USB摄像头需要安装额外的驱动才可以被识别。
QCamera获取uvc camera的MJPEG数据流
QList<QCameraInfo> cameras=QCameraInfo::availableCameras(); //获取所有可以支持的camera,包括Integrated camera和uvc camera
foreach (const QCameraInfo &camerasInfo, cameras) {
qDebug()<<"camera:"<<camerasInfo.description();
qDebug()<<"name:"<<camerasInfo.deviceName();
if(camerasInfo.description().contains("UVC")){
qDebug()<<"name:"<<camerasInfo.deviceName();
mCamera=new QCamera(camerasInfo); //由camerainfo创建qcamera
mCaptureVideoFrame=new CaptureVideoFrame(this); //视频帧接收类,因为需要用自己写的opengl渲染,所以有了这个类,用来拿到相机的当前帧
connect(mCaptureVideoFrame,SIGNAL(CaptureFrame(QVideoFrame)),this,SLOT(on_captrueframecallback(QVideoFrame)));
mCaptureVideoFrame->setSource(mCamera);
}
}
// mCamera->setViewfinder(mFinder); //通过viewfinder渲染出视频流
QCameraViewfinderSettings sets; //取景器设置
sets.setPixelFormat(QVideoFrame::Format_Jpeg); //设置视频格式为Jpeg,对应CaptureVideoFrame中的Format_Jpeg格式。
sets.setMinimumFrameRate(30); //设置最小的帧率
sets.setMaximumFrameRate(30); //设置最大的帧率
sets.setResolution(3840,2160); //设置获取的视频流的分辨率(因为此高分辨率是jpeg格式传输的)
mCamera->setViewfinderSettings(sets); //将取景器设置到qcamera
mCamera->start(); //开启相机
QList<QCameraViewfinderSettings > ViewSets = mCamera->supportedViewfinderSettings(); //可以打印出该camera支持的所有的分辨率及格式
foreach (QCameraViewfinderSettings ViewSet, ViewSets) {
qDebug()<<"haha"<<ViewSet.pixelFormat()<<" "<<ViewSet.resolution().width()<<" "<<ViewSet.resolution().height()<<","<<ViewSet.minimumFrameRate();
}
关于capturevideoframe.h
#ifndef CAPTUREVIDEOFRAME_H
#define CAPTUREVIDEOFRAME_H
#include <QAbstractVideoSurface>
#include <QVideoProbe>
#include <QCamera>
class CaptureVideoFrame:public QAbstractVideoSurface
{
Q_OBJECT
public:
explicit CaptureVideoFrame(QObject *parent=0);
~CaptureVideoFrame();
bool setSource(QCamera *pCamera); //设置qcamera
virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const; //重写支持的像素格式
signals:
void CaptureFrame(const QVideoFrame &frame);
private slots:
virtual bool present(const QVideoFrame &frame); //重写当前帧
private:
QVideoFrame m_Probe;
};
#endif // CAPTUREVIDEOFRAME_H
关于capturevideoframe.cpp
#include "capturevideoframe.h"
CaptureVideoFrame::CaptureVideoFrame(QObject *parent):QAbstractVideoSurface(parent)
{
}
QList<QVideoFrame::PixelFormat> CaptureVideoFrame::supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const{
Q_UNUSED(type);
QList<QVideoFrame::PixelFormat> lst;
lst.push_back(QVideoFrame::Format_Jpeg); //添加支持JPeg格式,否则获取不到数据
lst.push_back(QVideoFrame::Format_YUYV);
lst.push_back(QVideoFrame::Format_RGB32);
lst.push_back(QVideoFrame::Format_BGR32);
lst.push_back(QVideoFrame::Format_RGB565);
return lst;
}
CaptureVideoFrame::~CaptureVideoFrame(){
}
bool CaptureVideoFrame::setSource(QCamera *pCamera){
bool ret=true;
pCamera->setViewfinder(this);
return ret;
}
bool CaptureVideoFrame::present(const QVideoFrame &frame){
emit CaptureFrame(frame); //拿到数据帧,通过信号槽,最终通过opengl渲染出frame中的数据.
return true;
}
最终渲染出数据后还是蛮激动的,其实并不是很难,只是对格式不熟,所以卡住了,特地记录下。