mpp
mpp copied to clipboard
RGA拷贝mpp硬解码器中的数据
我将H264裸流数据解码之后得到yuv数据,将其拷贝到虚拟内存出现了耗时操作。所以我的想法是将解码器中的数据(MPPFrame fd或buffer)映射到RGA数据存储结构中,进行拷贝。但是运行之后提示我说RGA中src的内存为空,我想请教一下,优秀的开发者们,这个问题应该如何解决。
没有报错信息,无法判断……
没有报错信息,无法判断……
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,heightwidth/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;
}