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);

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐