RK3568基于mpp实现硬解码(三):rga 实现图像格式转换
·
mpp硬解码后的图像帧保存在MppFrame之中,并且解码后图像格式是NV12。在QT中需要转换为RGB格式才能显示。
rga库链接参考:https://github.com/airockchip/librga
相关代码实现
void MediaPlay::playFrame(QVector<MppFrame> vecFrame)
{
for(const MppFrame frame : vecFrame){
int src_width, src_height, src_format;
int dst_width, dst_height, dst_format;
char *src_buf, *dst_buf;
int src_buf_size, dst_buf_size;
int ret = 0;
rga_buffer_t src_img, dst_img;
rga_buffer_handle_t src_handle, dst_handle;
memset(&src_img, 0, sizeof(src_img));
memset(&dst_img, 0, sizeof(dst_img));
// 获取MppFrame的参数
src_width = mpp_frame_get_hor_stride(frame);
src_height = mpp_frame_get_ver_stride(frame);
src_format = RK_FORMAT_YCbCr_420_SP;//对应mpp_frame_get_fmt(mppFrame)中的MPP_FMT_YUV420SP
//转换后图像参数
dst_width = src_width;
dst_height = src_height;
dst_format = RK_FORMAT_RGB_888; //RK_FORMAT_RGB_888对应QImage::Format_RGB888
// src_buf_size = dst_buf_size = dataSize; //错误的大小
src_buf_size = src_width * src_height * get_bpp_from_format(src_format);
dst_buf_size = dst_width * dst_height * get_bpp_from_format(dst_format);
//Q1:为什么mppFrame非NULL,但是会有mpp_frame_get_buffer返回0x00的情况?
// size_t dataSize = mpp_buffer_get_size(buffer); //获取buffer数据的总大小
MppBuffer buffer = mpp_frame_get_buffer(frame);
if(!buffer){
myDebug() << "mpp_frame_get_buffer result is NULL";
return;
}
src_buf = (char *)mpp_buffer_get_ptr(buffer); //指向图像数据
dst_buf = (char *)malloc(dst_buf_size);
memset(dst_buf, 0x80, dst_buf_size);
src_handle = importbuffer_virtualaddr(src_buf, src_buf_size);
dst_handle = importbuffer_virtualaddr(dst_buf, dst_buf_size);
//失败处理
if (src_handle == 0 || dst_handle == 0) {
myDebug() << "importbuffer failed!";
releseRGA(src_handle,dst_handle,dst_buf);
return;
}
src_img = wrapbuffer_handle(src_handle, src_width, src_height, src_format);
dst_img = wrapbuffer_handle(dst_handle, dst_width, dst_height, dst_format);
ret = imcheck(src_img, dst_img, {}, {});
if (IM_STATUS_NOERROR != ret) {
printf("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret));
return;
}
ret = imcvtcolor(src_img, dst_img, src_format, dst_format); //转换成rgb格式
if (ret != IM_STATUS_SUCCESS) {
myDebug() << "imcvtcolor running failed";
releseRGA(src_handle,dst_handle,dst_buf);
return;
}
QImage img((unsigned char*)dst_buf, src_width, src_height, QImage::Format_RGB888);
QImage cpImg = img.copy(); //深拷贝
emit signalImage(cpImg);
releseRGA(src_handle,dst_handle,dst_buf);
}
}
调用到imcvtcolor时程序崩溃,提示: RgaBlit(1465) RGA_BLIT fail: Invalid argument
g: decode_get_frame get frame 223
RgaBlit(1465) RGA_BLIT fail: Invalid argument
RgaBlit(1466) RGA_BLIT fail: Invalid argument
handl-fd-vir-phy-hnd-format[2429, 0, (nil), (nil), 0, 0]
rect[0, 0, 1920, 1080, 1920, 1080, 2560, 0]
f-blend-size-rotation-col-log-mmu[0, 0, 0, 0, 0, 0, 0]
handl-fd-vir-phy-hnd-format[2651, 0, (nil), (nil), 0, 0]
rect[0, 0, 1920, 1080, 1920, 1080, 512, 0]
f-blend-size-rotation-col-log-mmu[0, 0, 0, 0, 0, 0, 0]
This output the user patamaters when rga call blit fail
14131 im2d_rga_impl rga_task_submit(1943): Failed to call RockChipRga interface, please use 'dmesg' command to view driver error log.
14131 im2d_rga_impl rga_dump_channel_info(1418): src_channel:
rect[x,y,w,h] = [0, 0, 0, 0]
image[w,h,ws,hs,f] = [1920, 1080, 1920, 1080, nv12]
buffer[handle,fd,va,pa] = [2429, 0, 0, 0]
color_space = 0x0, global_alpha = 0x0, rd_mode = 0x0
14131 im2d_rga_impl rga_dump_channel_info(1418): dst_channel:
rect[x,y,w,h] = [0, 0, 0, 0]
image[w,h,ws,hs,f] = [1920, 1080, 1920, 1080, rgb888]
buffer[handle,fd,va,pa] = [2651, 0, 0, 0]
color_space = 0x0, global_alpha = 0x0, rd_mode = 0x0
14131 im2d_rga_impl rga_dump_opt(1468): opt version[0x0]:
14131 im2d_rga_impl rga_dump_opt(1469): set_core[0x0], priority[0]
14131 im2d_rga_impl rga_task_submit(1952): acquir_fence[-1], release_fence_ptr[0x0], usage[0x80000]
mpp[11662]: mpp_log: decode_get_frame get frame 224
RgaBlit(1465) RGA_BLIT fail: Invalid argument
RgaBlit(1466) RGA_BLIT fail: Invalid argument
handl-fd-vir-phy-hnd-format[2435, 0, (nil), (nil), 0, 0]
rect[0, 0, 1920, 1080, 1920, 1080, 2560, 0]
f-blend-size-rotation-col-log-mmu[0, 0, 0, 0, 0, 0, 0]
handl-fd-vir-phy-hnd-format[2652, 0, (nil), (nil), 0, 0]
rect[0, 0, 1920, 1080, 1920, 1080, 512, 0]
f-blend-size-rotation-col-log-mmu[0, 0, 0, 0, 0, 0, 0]
This output the user patamaters when rga call blit fail
14173 im2d_rga_impl rga_task_submit(1943): Failed to call RockChipRga interface, please use 'dmesg' command to view driver error log.
14173 im2d_rga_impl rga_dump_channel_info(1418): src_channel:
rect[x,y,w,h] = [0, 0, 0, 0]
image[w,h,ws,hs,f] = [1920, 1080, 1920, 1080, nv12]
buffer[handle,fd,va,pa] = [2435, 0, 0, 0]
color_space = 0x0, global_alpha = 0x0, rd_mode = 0x0
14173 im2d_rga_impl rga_dump_channel_info(1418): dst_channel:
rect[x,y,w,h] = [0, 0, 0, 0]
image[w,h,ws,hs,f] = [1920, 1080, 1920, 1080, rgb888]
buffer[handle,fd,va,pa] = [2652, 0, 0, 0]
color_space = 0x0, global_alpha = 0x0, rd_mode = 0x0
14173 im2d_rga_impl rga_dump_opt(1468): opt version[0x0]:
14173 im2d_rga_impl rga_dump_opt(1469): set_core[0x0], priority[0]
14173 im2d_rga_impl rga_task_submit(1952): acquir_fence[-1], release_fence_ptr[0x0], usage[0x80000]
[ 8979.806251] rga_mm: [tgid:12169] Destroy handle[2843] when the user exits
通过dmesg | grep rga打印内核信息
dmesg message
[ 64.003759] rga_job: request[274] task[0] job_commit failed.
[ 64.003769] rga_job: rga request[274] commit failed!
[ 64.003775] rga: request[274] submit failed!
[ 64.044178] rga_mm: Only get buffer 4177920 byte from handle[227], but current required 8294400 byte
[ 64.044232] rga_mm: handle[227] Can't get y/rgb address info!
[ 64.044238] rga_mm: Can't get src buffer info from handle!
[ 64.044245] rga_mm: failed to get buffer from handle
[ 64.044253] rga_job: rga_job_commit: failed to map job info
[ 64.044319] rga_job: request[275] task[0] job_commit failed.
[ 64.044327] rga_job: rga request[275] commit failed!
[ 64.044335] rga: request[275] submit failed!
[ 64.074635] rga_mm: Only get buffer 4177920 byte from handle[218], but current required 8294400 byte
[ 64.074687] rga_mm: handle[218] Can't get y/rgb address info!
[ 64.074694] rga_mm: Can't get src buffer info from handle!
[ 64.074699] rga_mm: failed to get buffer from handle
[ 64.074706] rga_job: rga_job_commit: failed to map job info
[ 64.074768] rga_job: request[276] task[0] job_commit failed.
[ 64.074777] rga_job: rga request[276] commit failed!
[ 64.074782] rga: request[276] submit failed!
[ 64.123287] rga_mm: Only get buffer 4177920 byte from handle[220], but current required 8294400 byte
[ 64.123325] rga_mm: handle[220] Can't get y/rgb address info!
[ 64.123332] rga_mm: Can't get src buffer info from handle!
[ 64.123337] rga_mm: failed to get buffer from handle
[ 64.123343] rga_job: rga_job_commit: failed to map job info
[ 64.123468] rga_job: request[277] task[0] job_commit failed.
[ 64.123479] rga_job: rga request[277] commit failed!
[ 64.123485] rga: request[277] submit failed!
[ 64.163073] rga_mm: Only get buffer 4177920 byte from handle[222], but current required 8294400 byte
[ 64.163131] rga_mm: handle[222] Can't get y/rgb address info!
[ 64.163137] rga_mm: Can't get src buffer info from handle!
[ 64.163142] rga_mm: failed to get buffer from handle
[ 64.163148] rga_job: rga_job_commit: failed to map job info
[ 64.163198] rga_job: request[278] task[0] job_commit failed.
[ 64.163207] rga_job: rga request[278] commit failed!
[ 64.163213] rga: request[278] submit failed!
[ 64.214974] rga_mm: Only get buffer 4177920 byte from handle[227], but current required 8294400 byte
[ 64.215087] rga_mm: handle[227] Can't get y/rgb address info!
[ 64.215095] rga_mm: Can't get src buffer info from handle!
[ 64.215102] rga_mm: failed to get buffer from handle
[ 64.215108] rga_job: rga_job_commit: failed to map job info
[ 64.215177] rga_job: request[279] task[0] job_commit failed.
[ 64.215186] rga_job: rga request[279] commit failed!
[ 64.215193] rga: request[279] submit failed!
[ 64.254708] rga_mm: Only get buffer 4177920 byte from handle[218], but current required 8294400 byte
[ 64.254746] rga_mm: handle[218] Can't get y/rgb address info!
[ 64.254752] rga_mm: Can't get src buffer info from handle!
[ 64.254757] rga_mm: failed to get buffer from handle
[ 64.254763] rga_job: rga_job_commit: failed to map job info
[ 64.254810] rga_job: request[280] task[0] job_commit failed.
[ 64.254817] rga_job: rga request[280] commit failed!
[ 64.254823] rga: request[280] submit failed
核心错误:RGA buffer 大小不足,导致提交任务失败
rga_mm: Only get buffer 4177920 byte from handle[218], but current required 8294400 byte
意思是:通过 handle[218] 分配的 RGA buffer 大小只有 4177920 字节 而当前操作需要 8294400 字节 因此 RGA 内核驱动无法解析 buffer 内容(地址找不到、格式不匹配),后续一系列失败:
具体见这段代码:src_buf_size和dst_buf_size的大小不是mpp_buffer_get_size来决定的,需要根据官方demo给出的公式来计算
//size_t dataSize = mpp_buffer_get_size(buffer); //获取buffer数据的总大小
//src_buf_size = dst_buf_size = dataSize; //错误的大小
src_buf_size = src_width * src_height * get_bpp_from_format(src_format);
dst_buf_size = dst_width * dst_height * get_bpp_from_format(dst_format);
更多推荐



所有评论(0)