近期想通过修改临滴哔站的九宫格例程尝试只调用4路摄像头显示,修改了源代码中如下内容:
1.修改最大通道数和max_img_count匹配四宫格模式:

2.修改四宫格分块显示尺寸:

3.修改行列排序,行数2,列数2:


4.修改相机id文件,将当前使用的4个相机使能,其他相机关闭:

出现报错如下:

考虑是否需要关闭视频相关控制芯片的通道?或者其他原因?求解各位大佬,谢谢宝贵建议。

  1. 不做任何更改, 编译及运行是否OK?
  2. 更改sample.ini文件, 打开4路摄像头, 是否运行正常?
  3. 源代码中, 需要注意摄像头的索引与打开时要一致!这里可以添加打印信息, 是否是期望的camera id, 不要有重复打开。

    Linx
    1.九宫格官方例程,不做任何更改编译没有问题,可以正常显示。
    2.运行正常。仅修改sample.ini文件,关闭对不需要的摄像头的使能(即enable=0),关闭的摄像头显示为纯白色,保留的四路可正常运行输出视频图像。
    3.保留摄像头索引查验正确,为期望的cameraid。
    附注:
    此处对代码的修改仅限于:
    1.将九宫格排布(即3×3窗口显示)调整为四宫格(即2×2窗口显示);
    2.将循环读取9个摄像头的功能,调整为循环读取4个摄像头并显示。
    对该问题的进一步分析,考虑如下:
    分析报错: “尝试关闭通道0,但它处于 PAUSED 状态,而不是 NULL 状态。在删除最终引用之前,您需要将元素显式设置为 NULL 状态,以允许它们进行清理。此问题也可能是由应用程序或同一元素中的 refcounting 错误引起的。”
    分析问题:
    1.是否为通道0状态使能问题。对摄像头控制的通道分为0和1两路(即摄像头id 00 01 02 03 和 11 12 13 14),分别由两个N4芯片使能控制,若只使用id=11 12 13 14的摄像头,是否需要关闭一个N4芯片对摄像头0通道的控制?
    2.是否为重复引用问题。修改内容仅限于对排列或获取循环中数字的修改,未涉及到其他变动,考虑原有九宫格代码不存在重复引用的报错问题,运行正常;如果修改后出现该问题,那么该问题可能存在重于哪个环节呢?
    感谢您的分享和答复!

    使用这个patch, 看看是否可以。

    diff --git a/examples/camera/main.cpp b/examples/camera/main.cpp
    index d485c91..266390f 100644
    --- a/examples/camera/main.cpp
    +++ b/examples/camera/main.cpp
    @@ -31,9 +31,11 @@
     using namespace std;
     using namespace cv;
     
    -const int max_channel = 8;
    +const int max_channel = 4;
     const int max_img_count = 16;
     
    +const int rows = 2;
    +const int cols = 2;
     /**
      * create memory pool for images gotten from camera.
      */
    @@ -145,12 +147,12 @@ int main(int argc, char **argv) {
         getScreenResolution(scrn_width, scrn_height);
         //printf("Screen resolution: %dx%d\n", scrn_width, scrn_height);
         if (scrn_width < 1920) {
    -        width = scrn_width / 3;
    +        width = scrn_width / rows;
             height = width * 480 / 640;
         }
     
         if (scrn_height < 1440) {
    -        height = scrn_height / 3;
    +        height = scrn_height / cols;
             width = height * 640 / 480;
         }
     
    @@ -229,28 +231,28 @@ int main(int argc, char **argv) {
         Mat blankimg(height, width, CV_8UC3, Scalar(255, 255, 255));
     
         int row = 0, col = 0;
    -    Mat showimgs[9];
    -    Mat extrow[3];
    +    Mat showimgs[rows * cols];
    +    Mat extrow[rows];
         vector < Mat > rowimgs;
         //std::cout << "Enter the main loop!" << endl;
         while (true) {
             rowimgs.clear();
    -        for (int row = 0; row < 3; row++) {
    +        for (int row = 0; row < rows; row++) {
                 //std::cout << "row = " << row << std::endl;
                 vector < Mat > colimgs;
    -            for (int col = 0; col < 3; col++) {
    -                if (cam_cfg[col + row * 3].isenabled) {
    +            for (int col = 0; col < cols; col++) {
    +                if (cam_cfg[col + row * rows].isenabled) {
                         cv::Mat *pimg = nullptr;
                         //std::cout << "row = " << row << ", col = " << col << std::endl;
    -                    _imgdata[col + row * 3].pop(pimg);
    +                    _imgdata[col + row * rows].pop(pimg);
                         if (nullptr == pimg) {
                             usleep(100);
                             continue;
                         }
     
    -                    showimgs[col + row * 3] = pimg->clone();
    -                    _idleimgbuf[col + row * 3].push(pimg);
    -                    colimgs.push_back(showimgs[col + row * 3]);
    +                    showimgs[col + row * rows] = pimg->clone();
    +                    _idleimgbuf[col + row * rows].push(pimg);
    +                    colimgs.push_back(showimgs[col + row * rows]);
                         //cv::resize(showimg[i], imgRoi[i], imgRoi[i].size());
                     } else {
                         //std::cout << "push blank image" << std::endl;

    另外, 把camera参数打印出来, 如下:

        /**
         * load image from camera
         */
        std::string capfmt = "v4l2src device=/dev/video" 
                              + std::to_string(cam_id)
                              + " ! video/x-raw,format=NV12,width="
                              + std::to_string(width) + ",height="
                              + std::to_string(height)
                              + ",framerate=30/1 ! videoconvert ! video/x-raw,format=BGR ! appsink";
    std::cout << capfmt << std::endl;

    或者, 如果还是出错, 则使用固定的size:

        /**
         * load image from camera
         */
        std::string capfmt = "v4l2src device=/dev/video" 
                              + std::to_string(cam_id)
                              + " ! video/x-raw,format=NV12,width="
                              + std::to_string(640) + ",height="
                              + std::to_string(480)
                              + ",framerate=30/1 ! videoconvert ! video/x-raw,format=BGR ! appsink";

      Linx
      修改后调试出现如下报错:

      嵌入式视频播放已暂停;模块 v4l2src0 报告:内部数据流错误

      使用固定大小640x480, 也打印capfmt参数,看看出现什么情况。