雄迈sdk+Linux Qt摄像头实时显示

1、简述:
此文章使用的是雄迈官网下载的sdk在Linux布置环境,并且配合qt进行可视化界面显示,由于雄迈摄像头获取的图像数据是YUN420P格式的,而qt的QImage只支持RGB32图像显示,所以需要使用ffmpeg对图像数据格式进行转化。
2、具体操作:
首先在雄迈官网下载相关的sdk:
https://developer.jftech.com/docs/?menusId=57e91028bdc14909b269ddb19180d30a&lang=zh
下载版本
将sdk中的Linux-x64-libXNetSDK.so和include文件夹放在指定文件夹,并在.pro文件中指明添加路径。
注意:libXNetSDK.so文件需要看清使用的系统,sdk中有Windows和Linux两种使用场景
并配置ffmpeg指明文件路径。如下图所示:
在这里插入图片描述
核心执行代码:

	//初始化结构体
	SXSDKInitParam initParam;
    memset(&initParam,0,sizeof(SXSDKInitParam));
    // SDK初始化
    XSDK_Init(&initParam);
    XSDK_SetSDKIntAttr(1024, 0);
    
	//登录结构体初始化
    SXSDKLoginParam LoginParam;
    memset(&LoginParam,0,sizeof(SXSDKLoginParam));
    
    QString Id = "192.168.1.199";
    char* ptr =Id.toLatin1().data();
    strcpy(LoginParam.sDevId,ptr);

    QString name = "admin";
    char* ptr1 =name.toLatin1().data();
    strcpy(LoginParam.sUserName,ptr1);

    QString pw = "";
    char* ptr2 =pw.toLatin1().data();
    strcpy(LoginParam.sPassword,ptr2);

    LoginParam.nDevPort = 34567;
    LoginParam.nCnnType = EDEV_CNN_TYPE_AUTO;
    g_hDevice = XSDK_DevLoginSyn(&LoginParam,4000);
	//查看登录是否成功,大于0表示成功,此处可以省略
    if (g_hDevice > 0 && LoginParam.nCnnType != EDEV_CNN_TYPE_DAS)
    {
    	//获取系统配置,主要是获取通道数
        int nResult = GetDevSystemInfo();

        if (nResult < 0)
        {
            qDebug() <<"Get device systeminfo error";
        }
    }
    qDebug() << "g_hDevice:" <<g_hDevice;

    SXMediaRealPlayReq param;
    memset(&param,0,sizeof(SXMediaRealPlayReq));

    param.nChannel = 0;						// 通道号(必填)
    param.nStreamType = 0;							// 0:主码流 1:辅码流
    param.nDecodeType = DECODE_RESULT_YUV420;
    param.nRequestType = EUIMSG_YUV_DATA;	//帧数据
    param.result = RealPlayMediaCallBack;			// 结果回调(必填)

    che = XSDK_MediaRealPlay(g_hDevice, &param);
    connect(&testDecoder,&H265Decoder::sig_GetOneFrame,this,&MainWindow::addimage);
    if(che > 0){
        qDebug() << "读取成功" << che;
    }
int MainWindow::GetDevSystemInfo()
{
    if (g_hDevice > 0)
    {
        char szOutBuffer[40960] = { 0 };
        int  nInOutSize = sizeof(szOutBuffer);
        int nResult = XSDK_DevGetSysConfigSyn(g_hDevice, "SystemInfo", szOutBuffer, &nInOutSize, 4000, 1020);

        if (nResult >= 0)
        {
            XSDK_CFG::SystemInfo cfg;
            cfg.Parse(szOutBuffer);

            int g_nChannelNum = cfg.DigChannel.Value() + cfg.VideoOutChannel.Value();
            qDebug() <<"通道数:" <<g_nChannelNum;
        }
        return nResult;
    }
    return -1;
}
//槽响应函数,用于刷新可视化界面显示
void MainWindow::addimage(QImage image){
    ui->label->clear();
    //这里对图像进行了缩放,将图像大小适应于QLabel的大小
    ui->label->setPixmap(QPixmap::fromImage(image).scaled(ui->label->width(),ui->label->height(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
}

ffmpeg解码的实现:

//初始化
void H265Decoder::InitPlay(int width,int height)
{
    //width和heigt为传入的分辨率的大小
    int yuvSize = width * height * 3 /2;
    yuvBuffer = (uint8_t *)malloc(yuvSize);
    //为每帧图像分配内存
    pFrame = av_frame_alloc();
    pFrameRGB = av_frame_alloc();
    int numBytes = avpicture_get_size(AV_PIX_FMT_RGB32, width,height);
    rgbBuffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
    avpicture_fill((AVPicture *)pFrameRGB, rgbBuffer, AV_PIX_FMT_RGB32,width, height);
    //特别注意 img_convert_ctx 该在做H264流媒体解码时候,发现sws_getContext /sws_scale内存泄露问题,
    //注意sws_getContext只能调用一次,在初始化时候调用即可,另外调用完后,在析构函数中使用sws_free_Context,将它的内存释放。
    //设置图像转换上下文
    img_convert_ctx = sws_getContext(width, height, AV_PIX_FMT_YUV420P, width, height, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);
}
//实时接收yuv数据转换成rgb32 str是yuv数据,len为长度
void H265Decoder::wb_yuv(void* str,int width,int height)
{
    avpicture_fill((AVPicture *)pFrame, (uint8_t *)str, AV_PIX_FMT_YUV420P, width, height);//这里的长度和高度跟之前保持一致
    //转换图像格式,将解压出来的YUV420P的图像转换为RGB的图像
    sws_scale(img_convert_ctx,
              (uint8_t const * const *) pFrame->data,
              pFrame->linesize, 0, height, pFrameRGB->data,
              pFrameRGB->linesize);
    //把这个RGB数据 用QImage加载
    QImage tmpImg((uchar *)rgbBuffer,width,height,QImage::Format_RGB32);
    QImage image = tmpImg.copy(); //把图像复制一份 传递给界面显示
    emit sig_GetOneFrame(image);  //发送信号,将次imamge发送到要显示的控件,用paintEvent绘制出来
}

将创建的文件继承于QObject,并在头文件中加入Q_OBJECT,即可使用信号与槽

程序最初想使用ffmpeg对图像一帧一帧的解析显示,但是获取的图像通过ffmpeg解析,一直显示
在这里插入图片描述
这个问题我一直没解决,希望有大佬可以指点一下。
通过申请工单的方式联系到开发者,在其指导下使用了YUN420P数据进行展示。

解码参考:https://blog.csdn.net/ASKLW/article/details/73332233

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

布丁小站

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值