首先,不涉及视频解码,仅涉及解码之后的视频缩放、颜色空间转换(如YUV转RGB)、贴图。本文主要说明的是在QT框架没有使用OpenGl的情况下,如何让解码后的视频更高效的展示出来。
海思底层解码出来的视频都是YUV格式的,而QT的贴图格式是RGB,并且QT的视频展示框的宽高往往和解码出来的YUV不一样。所以要把解码出来的视频展示出来需要对源YUV做缩放、然后转RGB,QT的QImage类自带缩放功能,但是使用软缩放效率太低,相关的YUV转RGB的代码做转换也是一样效率很低,特别对于一些CPU能力比较低的芯片视频完全没法看。本文中的方案主要通过以下流程来实现:
图 1.视频播放流程
从解码器拿出来YUV图片,使用VGS缩放到与展示框大小差不多(由于对齐的原因一般不会完全相同),缩放之后的YUV经过IVE模块转成BGR,最后用TDE将BGR转成RGB。整个流程都使用硬件模块实现,大大提高效率。
一. 缩放
利用VGS做YUV的缩放,代码片段如下:
#include <hi_comm_vgs.h>
#include <mpi_vgs.h>
// src: 源图像
// dst:目标图像
// 将src指向的源图像缩放到由dst指向的宽高的大小,并且图像输入到dst对应的内存中
// note: 都需要开辟好空间
int ImgScale(VIDEO_FRAME_INFO_S *src,VIDEO_FRAME_INFO_S *dst) {
HI_S32 ret;
VGS_HANDLE vgs_handle;
ret = HI_MPI_VGS_BeginJob(&vgs_handle);
if (ret != HI_SUCCESS) {
printf("HI_MPI_VGS_BeginJob failed:%#x\n", ret);
return ret;
}
VGS_TASK_ATTR_S vgs_task;
memset(&vgs_task, 0, sizeof(vgs_task));
memcpy(&vgs_task.stImageIn,src,sizeof(vgs_task.stImageIn));
memcpy(&vgs_task.stImgOut,dst,sizeof(vgs_task.stImgOut));
ret