这篇我们正式来了解一下解码器,VDEC是RV1126的解码模块,它的主要作用是通过RV1126读取编码后的数据,然后通过这个VDEC模块解码每一帧的数据。我们来看看初始化VDEC的数据结构。"VDEC_CHN_ATTR_S" 描述解码通道属性结构体
第一个成员
- CODEC_TYPE_E enCodecType:就是要和编码保持一致的,264编的,就264解没有什么问题
- VIDEO_MODE_E enMode;输入模式分为流和帧模式,后面会详细说说

- VIDEO_DECODEC_MODE_E enDecodecMode;是选择硬件解码还是软件解码

配置VDEC,配置完之后还不使用,要使用先使能它
int main(int argc, char const*argv[])
{RK_MPI_SYS_Init();//多媒体处理接口(MPI)进行系统初始化//定义VDEC解码器初始化VDEC_CHN_ATTR_S Vdec;Vdec.enCodecType = RK_CODEC_TYPE_H264; // 编码格式h264,和编码保持一样Vdec.enMode = VIDEO_MODE_FRAME; //编码输入格式,有两种输入,以帧/流格式输入,这里选择帧Vdec.enDecodecMode = VIDEO_DECODEC_HADRWARE; //看是硬件解码还是软解码,一般都是使用return 0;
}
使能解码器的api RK_S32 RK_MPI_VDEC_CreateChn(VDEC_CHN VdChn, const VDEC_CHN_ATTR_S *pstAttr);
第一个参数:解码通道号一般默认是从0开始,VdChn,取值范围是[0, VDEC_MAX_CHN_NUM)。VDEC_MAX_CHN_NUM是16
第二个参数:VDEC_CHN_ATTR_S结构体指针
//使能Vdevint ret = RK_MPI_VDEC_CreateChn( 0, &Vdec);if(ret < 0 ){printf("解码器使能失败\n");return -1;}
使能之后解码器就可以工作起来了。
注意:enDecodeMode有两种模式,一种是帧模式,另外一种是流模式。
- 流模式:指的是开发者发送任意长度的码流到解码器,由解码器内部识别一帧码流,在收到下一 帧码流才结束。
- 帧模式:开发者需要发送一帧完整的数据帧到解码器,每调用一次发送接口,解码器认为帧码流 已经结束了。所以使用帧模式发送数据的时候,需要保证一帧完整的数据帧才能够保证解码器不会出错。
下面通过画图详细聊聊这两种格式
我们假设我们要传输的是一个解压后的H264文件,假设H264的一帧的数据数据“sps+pps+i”
所以我们在传输一个完整的H264文件是这样的“00 00 01+ sps + pps + i 00 00 01 + sps + pps + i......。”
流格式
其实原理跟流水一样,只要编码端有数据,会源源不断的往解码器发送数据。假设每次都传输1000个字节。
但是前面已经说了H264一帧的数据格式:“sps+pps+i”,传输的时候要加上00 00 01 作为起始码,所以这样就可能牵扯的另外的一个问题,比如最后的一千接是00 00 01,或者是sps,或者是pps, 或者是i。所以这一帧数据就是不完整的, 解码器就要有能力找到他们并且拼接起来成为一帧完整的数据。并且解码出来。
帧模式
帧格式很好理解,就是每次传输都是传输一个完整的一帧H264数据。和快递一样,每次到了,都是一个完整的快递而不是半个。
现在一般选择帧格式,可以减轻解码器的压力,这样就不用去找这些零散的数据了。