完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.RGA
简单的说,RGA就是一个用来处理图片的硬件,和CPU相互独立,可以独立完成图片的处理,在瑞芯微这边提供的库是阻塞的,可以自己实现为异步的。 2.RGA错误使用 这里使用RGA,主要是用于一个快速的格式转换,在这部分实现中,阻塞或者异步都影响不大。上一章节简单说明了一下RGA的使用,经过测试那样做,有点问题,资源泄漏,就算在析构中手动释放申请的资源,后面还是会有问题,比如每一帧的转换都请求一个句柄,转换完就算释放。 void QSmartCamera::draw_viewfinder(QSharedPointer { QRgaYUV2RGB convert(STREAM_WIDTH,STREAM_HEIGHT,RK_FORMAT_YCbCr_420_P,(unsigned char *)d->data(), STREAM_WIDTH,STREAM_HEIGHT,RK_FORMAT_RGB_888); unsigned char *frame = convert.get_data(); if(frame) { qDebug() << "rga convert ok"; QImage image(frame,STREAM_WIDTH,STREAM_HEIGHT,QImage::Format_RGB888); draw_image_rects(image,lastRect); QDatetime now = QDateTime::currentDateTime(); ui->label->setPixmap(QPixmap::fromImage(create_image_text(image,now.toString(),40,QPoint(50,50)))); } } 然后析构函数实现 QRgaYUV2RGB::~QRgaYUV2RGB() { qDebug() << "Deinit ------------"; rkRga.RkRgaUnmap(&bo_src); rkRga.RkRgaUnmap(&bo_dst); rkRga.RkRgaFreeBuffer(bo_src.fd,&bo_src); rkRga.RkRgaFreeBuffer(bo_dst.fd,&bo_dst); rkRga.RkRgaFree(&bo_src); rkRga.RkRgaFree(&bo_dst); } 这样每次使用完之后,析构会释放资源,但是发现处理五百多次之后,就无法请求到资源,并且产生内核错误信息。 3.RGA实现 这里就直接子类化了RGA class QRgaYUV2RGB : public RockchipRga { public: QRgaYUV2RGB(int sw,int sh,RgaSURF_FORMAT sf, int dw,int dh,RgaSURF_FORMAT df); ~QRgaYUV2RGB(); public: unsigned char *get_data(unsigned char *frame); private: bo_t bo_src, bo_dst; rga_info_t src; rga_info_t dst; int sf_size,df_size; }; 实现如下 QRgaYUV2RGB::QRgaYUV2RGB(int sw,int sh,RgaSURF_FORMAT sf, int dw,int dh,RgaSURF_FORMAT df) :RockchipRga() { int ret = 0; this->RkRgaInit(); ret = this->RkRgaGetAllocBuffer(&bo_src, sw, sh, 32); ret = this->RkRgaGetAllocBuffer(&bo_dst, dw, dh, 32); this->RkRgaGetMmap(&bo_src); this->RkRgaGetMmap(&bo_dst); sf_size = get_buf_size_by_w_h_f(sw,sh,sf); df_size = get_buf_size_by_w_h_f(dw,dh,df); memset(&src, 0, sizeof(rga_info_t)); src.fd = -1; src.mmuFlag = 1; memset(&dst, 0, sizeof(rga_info_t)); dst.fd = -1; dst.mmuFlag = 1; ret = this->RkRgaGetBufferFd(&bo_src, &src.fd); printf("src.fd =%d n",src.fd); if (ret) { printf("rgaGetsrcFd fail : %sn", strerror(errno)); } /********** get dst_Fd **********/ ret = this->RkRgaGetBufferFd(&bo_dst, &dst.fd); printf("dst.fd =%d n",dst.fd); if (ret) { printf("rgaGetdstFd error : %sn", strerror(errno)); } rga_set_rect(&src.rect, 0,0,sw,sh,sw/*stride*/,sh,sf); rga_set_rect(&dst.rect, 0,0,dw,dh,dw/*stride*/,dh,df); } QRgaYUV2RGB::~QRgaYUV2RGB() { qDebug() << "Deinit ------------"; this->RkRgaUnmap(&bo_src); this->RkRgaUnmap(&bo_dst); this->RkRgaFreeBuffer(bo_src.fd,&bo_src); this->RkRgaFreeBuffer(bo_dst.fd,&bo_dst); this->RkRgaFree(&bo_src); this->RkRgaFree(&bo_dst); } unsigned char *QRgaYUV2RGB::get_data(unsigned char *frame) { memset(bo_src.ptr,sf_size,0); memcpy(bo_src.ptr,frame,sf_size); memset(bo_dst.ptr,df_size,0); if(RkRgaBlit(&src, &dst, NULL)) return nullptr; return (unsigned char *)bo_dst.ptr; } 这样的析构仍然是有问题的, 只是这样处理之后,得到一个常驻内存的句柄,每次通过get_data来转换数据,且这个内存是在之前申请的,所以直接返回仍然有效。 4.更新帧捕获 根据前面测测试结果,发现自定义的viewfinder有问题,目前不确定问题原因,所以暂时先取消。所有数据通过QVideoProbe得到 connect(m_probe.data(),&QVideoProbe::videoFrameProbed,[this](QVideoFrame f){ f.map(QAbstractVideoBuffer::ReadOnly); QSharedPointer f.unmap(); if(needHandle) //每次等那边处理完了再处理下一帧,不然会导致qt内部队列满,处理很慢 { needHandle = false; QMutexLocker ll(&locker); frameVec.append(a); } emit handleFrame(a); //绘图 draw_viewfinder(a); }); 在draw_viewfinder中绘制数据到屏幕上 5.使用转换模块 在QSmartCamera添加成员QScopedPointer m_rga.reset(new QRgaYUV2RGB(STREAM_WIDTH,STREAM_HEIGHT,RK_FORMAT_YCbCr_420_P, STREAM_WIDTH,STREAM_HEIGHT,RK_FORMAT_RGB_888)); 在捕获帧之后,通过这里刷新到label上,此时CPU,使用在25-30左右,比之前的80%+明显降低 void QSmartCamera::draw_viewfinder(QSharedPointer { // QRgaYUV2RGB convert(STREAM_WIDTH,STREAM_HEIGHT,RK_FORMAT_YCbCr_420_P,(unsigned char *)d->data(), // STREAM_WIDTH,STREAM_HEIGHT,RK_FORMAT_RGB_888); // unsigned char *frame = convert.get_data(); unsigned char *frame = m_rga->get_data((unsigned char *)d->data()); if(frame) { qDebug() << "rga convert ok"; QImage image(frame,STREAM_WIDTH,STREAM_HEIGHT,QImage::Format_RGB888); draw_image_rects(image,lastRect); QDateTime now = QDateTime::currentDateTime(); ui->label->setPixmap(QPixmap::fromImage(create_image_text(image,now.toString(),40,QPoint(50,50)))); } } 原作者:嘉木有鱼 |
|
相关推荐
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
569 浏览 0 评论
839 浏览 1 评论
737 浏览 1 评论
1957 浏览 1 评论
3204 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 07:59 , Processed in 0.423644 second(s), Total 37, Slave 31 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号