rockchip-linux / mpp

Media Process Platform (MPP) module
527 stars 161 forks source link

RGA拷贝mpp硬解码器中的数据 #374

Open lawaarch opened 1 year ago

lawaarch commented 1 year ago

我将H264裸流数据解码之后得到yuv数据,将其拷贝到虚拟内存出现了耗时操作。所以我的想法是将解码器中的数据(MPPFrame fd或buffer)映射到RGA数据存储结构中,进行拷贝。但是运行之后提示我说RGA中src的内存为空,我想请教一下,优秀的开发者们,这个问题应该如何解决。

HermanChen commented 1 year ago

没有报错信息,无法判断……

lawaarch commented 1 year ago

没有报错信息,无法判断……

error:src has not fd and address for render

//自定义结构体 typedef struct { MppCtx ctx; MppApi *mpi;

MppPacket packet;
MppFrame frame;

MppCodingType type; // h264
MppDecCfg cfg; // 配置信息
size_t packet_size;

MppFrameFormat out_fmt;
/* input and output */
MppBufferGroup frm_grp;
MppBufferGroup pkt_grp;
RK_S32 frame_count;
size_t max_usage;
// 文件测试
int file_end = 0;

} decoder_t;

//函数实现 int get_buff_with_frame(decoder_t decoder, char yuv_buff, int len) { int ret=0; len = 0; RK_U32 width = 0; RK_U32 height = 0; RK_U32 h_stride = 0;RK_U32 v_stride = 0; MppFrameFormat fmt = MPP_FMT_YUV420P; MppBuffer buffer = NULL; RK_U8 base = NULL; char buf=yuv_buff; struct timeval start, end,start_head,end_tail;

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

width = mpp_frame_get_width(decoder->frame);
height = mpp_frame_get_height(decoder->frame);
h_stride = mpp_frame_get_hor_stride(decoder->frame);
v_stride = mpp_frame_get_ver_stride(decoder->frame);
fmt = mpp_frame_get_fmt(decoder->frame);
buffer = mpp_frame_get_buffer(decoder->frame);

RK_U32 buf_size = mpp_frame_get_buf_size(decoder->frame);
printf("w x h: %dx%d h_stride:%d v_stride:%d buf_size:%d\n",
       width, height, h_stride, v_stride, buf_size);

base = (RK_U8 *)mpp_buffer_get_ptr(buffer);
//我采用的fd映射
int fd=mpp_buffer_get_fd(buffer);
/*--------------RGA转换----------------*/
src_handle = importbuffer_fd(fd, buf_size);
dst_handle = importbuffer_virtualaddr(yuv_buff, buf_size);
if (src_handle == 0 || dst_handle == 0) {
    printf("importbuffer failed!\n");
    return -1;
}

src_img = wrapbuffer_handle(src_handle, width, height, fmt);
dst_img = wrapbuffer_handle(dst_handle, width, height, fmt);

ret = imcheck(src_img, dst_img, {}, {});
if (IM_STATUS_NOERROR != ret) 
{
    printf("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret));
    return -1;
}

ret = imcopy(src_img, dst_img);
if (ret == IM_STATUS_SUCCESS) 
{
    printf("%s running success!\n", "rga_copy_demo");
} else 
{
    printf("%s running failed, %s\n", "rga_copy_demo", imStrError((IM_STATUS)ret));
    return -1;
}

printf("output [0x%x, 0x%x, 0x%x, 0x%x]\n", yuv_buff[0], yuv_buff[1], yuv_buff[2], yuv_buff[3]);

//后面的不用看了 到RGA转换就出错了 if (NULL == buffer) { printf("buffer is null\n"); return -1; } RK_U32 i; RK_U8 base_y = base; RK_U8 base_c = base + h_stride v_stride; gettimeofday(&start, NULL); // switch (decoder->out_fmt) // { // case MPP_FMT_YUV420SP: // { // len=heightwidth3/2; // memcpy(yuv_buff,base_y,heightwidth); // memcpy(yuv_buff+heightwidth,base_c,height*width/2); // } // break; // case MPP_FMT_YUV420P: // { // for (i = 0; i < height; i++, base_y += h_stride) // {

//         memcpy(buf, base_y, width);
//         buf += width;
//         (*len) += width;
//     }
//     for (i = 0; i < height * width / 2; i += 2)
//     {
//         memcpy(buf, base_c + i, 1);
//         buf += 1;
//         (*len) += 1;
//     }
//     for (i = 1; i < height * width / 2; i += 2)
//     {
//         memcpy(buf, base_c + i, 1);
//         buf += 1;
//         (*len) += 1;
//     }

// }
// }
    gettimeofday(&end, NULL);
    printf("decode_time_get_buff=%06ld(ms)\n", 1000 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000);
//printf("yuv_len=%d\n", *len);
return 0;

}