树莓派学习专题<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 ;
    
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值