树莓派学习专题<15>:树莓派5:使用libcamera驱动获取摄像头图像

0. 项目代码

可以从下面获取到项目中的代码。
https://github.com/cdsmakc/h264_codec_base_rpi4b_rpi5_rv1106_visual_studio.git

1. 背景

之前的系列文章,都是在树莓派4上运行的。这两天又买了个树莓派5来测试。满以为重新编译一下就可以运行,结果发现存在很多问题:

  1. 树莓派5已经不支持硬件编码了,所以只能使用x264编码。
  2. V4L2在树莓派5上支持不好,之前的代码,VIDIOC_S_PARM命令和VIDIOC_G_PARM命令,在树莓派5上都报错。更关键的是,VIDIOC_STREAMON命令也无法启动流,报告参数错误。翻了树莓派的论坛,官方的回答是,强烈建议使用libcamera驱动替代V4L2驱动。
  3. 树莓派官方提供了rpicam-xxx系列工具及源码(源码可以github下载)。rpicam-vid中包含了我想要的所有功能,但是代码时C++的(libcamera驱动也是C++的),而且基本使用的都是C++11之后的特性写的,自己又不会C++,折腾了几天,才勉强弄出来一个可以运行的代码。

2. 参考

主要参考libcamera官方的驱动的说明。
一个是驱动的API:
API
另一个是官方的介绍文档,这些文档介绍了libcamera的特性、框架等,最重要的是里面提供了一个示例程序的步骤:
官方文档
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
基本上,按照上面这篇文章的内容一步一步小心地复制进去,就可以得到一个可运行的代码。

3. 代码

3.1 类定义

class RCE_CAM
{
   
   
private :
    std::unique_ptr<CameraManager>          pobjCameraManager ;
    std::shared_ptr<Camera>                 pobjCamera ;
    std::unique_ptr<CameraConfiguration>    pobjCameraConfig ;
    std::unique_ptr<ControlList>            pobjCameraControls ;
    FrameBufferAllocator                   *pobjAllocator ;
    std::vector<std::unique_ptr<Request>>   vecpobjRequests ;
public :
    RCE_CAM(VOID) ;
public :
    // camera manager
    INT  RCE_CAM_StartCameraManager(VOID) ;
    VOID RCE_CAM_StopCameraManager(VOID) ;

    // list camera and get camera
    VOID RCE_CAM_ListCameraId(VOID) ;
    INT  RCE_CAM_GetCamera(VOID) ;

    // acquire / release camera
    INT  RCE_CAM_AcquireCamera(VOID) ;
    VOID RCE_CAM_ReleaseCamera(VOID) ;

    // set camera pixel format, resolution, fps
    INT  RCE_CAM_SetFormat(VOID) ;
    VOID RCE_CAM_SetFps(VOID) ;

    // buffer
    INT  RCE_CAM_AllocBuffer(VOID) ;
    VOID RCE_CAM_ReleaseBuffer(VOID) ;

    // request callback
    INT  RCE_CAM_SetRequestCb(VOID (*__RequesetCb)(Request *)) ;
    VOID RCE_CAM_QueueRequset(Request *pobjRequest){
   
   pobjCamera->queueRequest(pobjRequest);}
    //INT  RCE_CAM_SetRequestCb(VOID) ;

    // camera start / stop
    INT  RCE_CAM_StartCamera(VOID) ;
    VOID RCE_CAM_StopCamera(VOID) ;

    // data process
    //static VOID RCE_CAM_ProcessData(Request *Request) ;
} ;

3.2 创建、启动与停止CameraManager

程序的第一步是创建和启动CameraManager,这是后续一切摄像头操作的起点。
创建并启动CameraManager

INT RCE_CAM::RCE_CAM_StartCameraManager(VOID)
{
   
   
    INT iRetVal = 0 ;

    // 创建CameraManager对象
    pobjCameraManager = std::make_unique<CameraManager>() ;

    // 启动CameraManager
    iRetVal = pobjCameraManager->start() ;

    if(0 != iRetVal)
    {
   
   
        cout<<"File "<<__FILE__<<", func "<<__func__<<", line"<<__LINE__<<" : "
            <<"Start camera manager failed. Return value is "<<iRetVal<<"."<<endl ;

        return -1 ;
    }

    return 0 ;
}

在程序运行结束后,还需要关闭CameraManager

VOID RCE_CAM::RCE_CAM_StopCameraManager(VOID)
{
   
   
    pobjCameraManager->stop() ;
}

3.3 获取摄像头

如下代码获取一个摄像头:

INT RCE_CAM::RCE_CAM_GetCamera(VOID)
{
   
   
    auto cameras = pobjCameraManager->cameras() ;
   
    // 查找摄像头
    if (cameras.empty()) 
    {
   
   
        cout<<"File "<<__FILE__<<", func "<<__func__<<", line"<<__LINE__<<" : "
            <<"No cameras were founded on the system."<<endl ;

        return -1 ;
    
<think>好的,用户现在想在树莓派Debian 12系统上使用OV5647摄像头配置libcamera驱动并运行mjpg_streamer。之前用户提到过在Ubuntu系统下mjpg-streamer可能无法编译input_raspicam.so,转而使用系统自带的摄像头开启方法。现在用户的环境是Debian 12,摄像头是OV5647,需要结合libcamera和mjpg_streamer。 首先,我需要确认在Debian 12上libcamera的支持情况。树莓派官方推荐使用libcamera作为新的相机驱动,但mjpg-streamer传统上依赖V4L2接口,而libcamera可能不完全兼容。因此,可能需要一些调整或者使用桥接工具。 用户之前的问题中提到过两种方法:直接修改mjpg-streamer的输入插件以支持libcamera,或者通过FFmpeg桥接。现在需要具体针对OV5647和Debian 12的情况。 首先,确保系统已经正确安装libcamera和相关驱动。OV5647是树莓派的旧款摄像头,可能需要检查是否被libcamera支持。然后,安装依赖项,如libjpeg-dev、cmake等。接着,从源码编译mjpg-streamer,可能需要修改输入插件或者使用社区提供的补丁。 如果直接使用mjpg-streamer的input_libcamera.so不可行,可能需要借助其他方法,比如使用v4l2loopback创建虚拟设备,让libcamera通过v4l2接口输出,再让mjpg-streamer读取这个虚拟设备。或者使用FFmpeg将libcamera的输出转换成mjpg-streamer可用的输入。 此外,用户提到过在Ubuntu下使用start.sh脚本,但在Debian 12可能需要不同的步骤。需要确保摄像头被正确识别,可以通过libcamera-hello测试。如果摄像头工作正常,再处理mjpg-streamer的配置。 可能的问题点包括:libcamera的兼容性、mjpg-streamer插件的适配、依赖库的安装是否正确,以及权限问题导致无法访问设备节点。需要逐一排查这些可能性,并提供相应的解决方案。 最后,生成相关问题时要考虑用户可能的后续疑问,比如如何测试摄像头驱动、如何调整分辨率或帧率、替代方案有哪些,以及如何优化延迟等。</think>### 树莓派Debian 12系统下OV5647摄像头通过libcamera驱动运行mjpg_streamer的完整方案 #### 一、系统环境确认 1. **验证OV5647摄像头支持** 首先通过`libcamera`工具确认摄像头是否被正确识别: ```bash libcamera-hello --list-cameras ``` 若输出包含`OV5647`传感器信息(如`bm2835 mmal`或`libcamera`驱动标识),则表明硬件已适配[^1]。 2. **更新系统与驱动** Debian 12默认可能未包含最新的`libcamera`组件,需手动添加树莓派官方源: ```bash echo "deb http://archive.raspberrypi.org/debian/ bookworm main" | sudo tee /etc/apt/sources.list.d/raspberrypi.list sudo apt update && sudo apt full-upgrade -y sudo apt install libcamera-apps libcamera-dev -y ``` --- #### 二、mjpg_streamer适配libcamera的两种实现方式 ##### 方案A:直接桥接libcamera与mjpg_streamer 1. **安装必要依赖** ```bash sudo apt install cmake libjpeg-dev git v4l-utils build-essential ``` 2. **编译支持libcamera的mjpg_streamer** 使用社区修改版分支,支持直接调用`libcamera`接口: ```bash git clone --branch libcamera-support https://github.com/OpenIoT/mjpg-streamer.git cd mjpg-streamer/mjpg-streamer-experimental mkdir build && cd build cmake -DENABLE_LIBCAMERA=ON .. make -j4 sudo make install ``` 3. **启动服务(OV5647专用参数)** ```bash mjpg_streamer \ -i "input_libcamera.so -r 1280x720 -f 30 --rotation 180" \ -o "output_http.so -p 8080 -w /usr/local/share/mjpg-streamer/www" ``` *参数说明:* - `-r`:分辨率(需匹配OV5647支持的`640x480`/`1280x720`/`1920x1080`) - `--rotation`:图像旋转角度(OV5647通常需要180度翻转) --- ##### 方案B:通过v4l2loopback虚拟设备中转 若mjpg-streamer编译失败或需要兼容传统接口: 1. **创建虚拟视频设备** ```bash sudo modprobe v4l2loopback exclusive_caps=1 video_nr=10 ``` 2. **将libcamera输出映射到虚拟设备** ```bash libcamera-vid -t 0 --width 1280 --height 720 --inline --listen -o udp://127.0.0.1:5000 & gst-launch-1.0 udpsrc port=5000 ! application/x-rtp,encoding-name=JPEG ! rtpjpegdepay ! v4l2sink device=/dev/video10 ``` 3. **启动标准版mjpg_streamer** ```bash mjpg_streamer \ -i "input_uvc.so -d /dev/video10" \ -o "output_http.so -p 8080" ``` --- #### 三、关键故障排查 | 现象 | 解决方案 | |-------|----------| | `input_libcamera.so`未找到 | 检查CMake编译日志,确认`-DENABLE_LIBCAMERA=ON`已启用 | | 图像出现色偏/条纹 | 添加`--rawfull`参数强制使用未压缩格式 | | 高分辨率下卡顿 | 降低帧率(`-f 15`)或启用硬件加速(需配置`dtoverlay=vc4-kms-v3d`) | | 权限拒绝访问`/dev/video*` | 将用户加入`video`组:`sudo usermod -aG video $USER` | --- ### 性能优化建议 1. **降低CPU占用** 使用libcamera内置的JPEG编码(添加`--codec jpeg`参数),相比原始YUV格式可减少40%的CPU负载[^2]。 2. **启用Zero-Copy模式** 在`input_libcamera.so`中设置`--buffers 4`和`--queue`,减少内存复制次数。 3. **网络传输优化** 在输出插件添加限速参数: ```bash -o "output_http.so -p 8080 --max-frame-rate 25" ``` --- ### 最终验证步骤 1. 浏览器访问`http://树莓派IP:8080`查看实时画面 2. 终端执行`v4l2-ctl --device /dev/video10 --info`确认设备属性 3. 使用`htop`监控CPU占用率,正常值应低于30%(1080P@30fps)
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值