前言

本篇文档是在上一篇的基础上实现的,上一篇文档如下

 笔者尝试使用Qt自身的类获取视频帧,在win10下测试没问题,但鸿蒙平板上测试,总出问题,估计其他android设备应该类似。所以笔者尝试使用openCV的库来实现

一、拉取windows下的视频流

关键代码如下

cv::VideoCapture cap;
cap.open(0);
//cap.open("rtsp://admin:@192.168.18.102:554/stream1");

// check if we succeeded
if (!cap.isOpened()) {
    std::cerr << "ERROR! Unable to open camera\n";
    return ;
}

while(1)
{
    cv::Mat frame;
    cap.read(frame);
    if (frame.empty()) {
        std::cerr << "ERROR! blank frame grabbed\n";
        return;
    }

    cvtColor(frame, frame, cv::COLOR_RGB2RGBA);
    
    const int size = frame.rows * frame.cols * 4;
    QVideoFrameFormat frameFormat(QSize(frame.cols, frame.rows),             
    QVideoFrameFormat::Format_RGBA8888);
    QVideoFrame f(frameFormat);
    if (f.map(QVideoFrame::WriteOnly)) {
        memcpy(f.bits(0), frame.data, size);
        f.setStartTime(0);
        f.unmap();
        emit newFrame(f);
    }
}

 直接使用openCV获取视频帧,然后转换成RGBA的颜色空间,再包装成QVideoFrame。包装后的视频帧,就可以直接送到视频源中

但要注意,不同的摄像头,通过openCV获取到的视频帧,颜色空间可能不同。笔者使用的摄像头返回的是RGB,读者测试时一定要注意查看

二、拉取android下的视频流

android下获取视频帧,需要重新编译下openCV,笔者测试过openCV4.5.5和openCV4.6.0

 

关键代码如下

cv::VideoCapture cap;
cap.open(0);

// check if we succeeded
if (!cap.isOpened()) {
    std::cerr << "ERROR! Unable to open camera\n";
    return ;
}

while(1)
{
    cv::Mat frame;
    cap.read(frame);
    if (frame.empty()) {
        std::cerr << "ERROR! blank frame grabbed\n";
        return;
    }

    cvtColor(frame, frame, cv::COLOR_YUV2RGBA_NV12);
    
    const int size = frame.rows * frame.cols * 4;
    QVideoFrameFormat frameFormat(QSize(frame.cols, frame.rows), 
    QVideoFrameFormat::Format_RGBA8888);
    QVideoFrame f(frameFormat);
    if (f.map(QVideoFrame::WriteOnly)) {
        memcpy(f.bits(0), frame.data, size);
        f.setStartTime(0);
        f.unmap();
        emit newFrame(f);
    }
}

代码基本与windows的相同,但注意需要摄像头相关的权限

笔者使用鸿蒙平板测试的,获取的视频帧是yuv格式的。限于条件,笔者无其他测试设备,请该读者自行测试

遇到的问题:

1.笔者使用openCV测试,鸿蒙平板可以正常运行,但win10经常出现无法正常打开,需要更换下摄像头的USB插口

2.android存在旋转的问题

3.android下,无法打开USB外插摄像头,但Qt可以识别到

笔者测试使用的源码

后记

笔者测试时发现,鸿蒙平板默认是自动对焦的,获取的视频帧是默认是最低分辨率的