使用MPP硬解码大小为1920*1080、编码方式为H265的视频帧,将得到的NV12格式的MppFrame转换成RGB888格式的QImage(示例中frame代表MppFrame):
#define SRC_FORMAT RK_FORMAT_YCbCr_420_SP
#define DST_FORMAT RK_FORMAT_RGB_888
MppBuffer buff = mpp_frame_get_buffer(frame);
int width = mpp_frame_get_width(frame);
int height = mpp_frame_get_height(frame);
int h_stride = mpp_frame_get_hor_stride(frame);
int v_stride = mpp_frame_get_ver_stride(frame);
char *dst_buff = (char *)malloc(h_stride*v_stride*get_bpp_from_format(DST_FORMAT));
char *b = (char *)mpp_buffer_get_ptr(buff);
int ret = 0;
//相当于初始化dst_buff
memset(dst_buff,0x00,h_stride*v_stride*get_bpp_from_format(DST_FORMAT));
src = wrapbuffer_virtualaddr(b, h_stride, v_stride, SRC_FORMAT);
dst = wrapbuffer_virtualaddr(dst_buff, width, height, DST_FORMAT);
if(src.width == 0 || dst.width == 0) {
qDebug() << "wrapbuffer_virtualaddr error!";
return -1;
}
src.format = SRC_FORMAT;
dst.format = DST_FORMAT;
//查看RGA基本信息,支持的分辨率,支持的格式等。
ret = imcheck(src, dst, {}, {});
if(IM_STATUS_NOERROR != ret){
qDebug() << "check rga info error!";
return -1;
}
//进行格式转换,YUV420SP转RGB888,返回值为1成功
STATUS = imcvtcolor(src, dst, src.format, dst.format, IM_COLOR_SPACE_DEFAULT, 1);
if(IM_STATUS_SUCCESS != STATUS){
qDebug() << "格式转换失败,返回值: " << STATUS;
}
//qDebug() << QThread::currentThread() << "格式转换over";
//uchar *datas = (uchar *)dst_buff;
QImage qimg((uchar *)dst_buff,width,height,QImage::Format_RGB888);
if(!qimg.isNull())
{
int num = width - (h_stride - width)*0.83;
//通过copy数据来消除右侧原本用于数据对齐产生的绿边
emit sig_GetOneFrame(qimg.copy(0,0,num,height)); //此处必须用qimg.copy(),不能直接用qimg!!!!
//qimg.save(QString("%1/test.png").arg(qApp->applicationDirPath()),"PNG", 100);
}
if(dst_buff != NULL){
free(dst_buff);
//qDebug() << QThread::currentThread() << "free(dst_buff) over";
}