您的位置:首页 > 其它

音视频解码模块阅读笔记

2015-04-20 19:35 169 查看
一,在进行音视频解码前,进行平台初始化工作:

InitPlatform(){

...

}

该函数主要完成如下工作:

先清空系统控制信息,视频缓冲区的信息

HI_MPI_SYS_Exit()

HI_MPI_VB_Exit()

接下来设置视频缓冲区

先配置几个视频缓冲区的大小

stVbConf.astCommPool[0].u32BlkSize = 720 * 576 * 2;/*D1*/

stVbConf.astCommPool[0].u32BlkCnt = 10;

stVbConf.astCommPool[1].u32BlkSize = 704 * 576 * 2;/*D1*/

stVbConf.astCommPool[1].u32BlkCnt = 52;

stVbConf.astCommPool[2].u32BlkSize = 384 * 576 * 2;/*2CIF*/

stVbConf.astCommPool[2].u32BlkCnt = 64;

stVbConf.astCommPool[3].u32BlkSize = 384 * 288 * 2;/*CIF*/

stVbConf.astCommPool[3].u32BlkCnt = 20;

设置系统中使用图像的字节对齐数,开发文档推荐配置成16 or 64就可以了,此时不是很明白。

stSysConf.u32AlignWidth=64;

HI_MPI_VB_SetConf(&stVbConf);

视频缓冲区初始化

HI_MPI_VB_Init

二,完成了系统平台的初始化,接下来进行音视频的输入处理。

在视频输入处理中有一个概念必须明确,vi设备端口,hi3520有4个vi设备端口,最大同时支持16ch视频输入。

也就是说1个vi设备端口对应4个视频输入端口。

视频输入的初始化得完成以下几个工作。

设置vi设备端口的属性 HI_MPI_VI_SetPubAttr

|

|

V

vi设备使能 HI_MPI_VI_Enable(ViDev)

|

|

设置vi设备端口接入各个vi通道的属性

在hi3520系统中,3520芯片外的数据是通过ITU-R BT656/601/1120接口或digital camera接口,存入芯片外的内存区域的,

当数据接口为ITU_R BT656时,一个vi设备能支持多个通道,最多支持4个,我们称之为ViChn0,ViChn1,ViChn2,ViChn3.

1,设置vi设备端口属性

设置属性接口函数,VI_DEV ViDevId vi输入设备端口,pstPubAttr设置属性值

HI_S32 HI_MPI_VI_SetPubAttr(VI_DEV ViDevId,const VI_PUB_ATTR_S *pstPubAttr);

typedef struct HiVI_PUB_ATTR_S

{

VI_INPUT_MODE_E enInputMode; /* video input mode */

VI_WORK_MODE_E enWorkMode; /* work mode(only for BT.601) */

VIDEO_NORM_E enViNorm; /* video input normal(only for BT.601) */

HI_BOOL bIsChromaChn; /* whether this device capture chroma data(only for BT.1120) */

HI_BOOL bChromaSwap; /* whether exchange U/V of chroma channel(only for BT.1120) */

} VI_PUB_ATTR_S;

HI_MPI_VI_Enable(ViDev);

2,设置完视频输入设备,接下来设置视频输入通道。

一个视频输入设备对应4个通道。

和视频输入设备设置一样,先设置通道属性

s32Ret=HI_MPI_VI_SetChnAttr(ViDev,ViChn,pstViChnAttr);

再接下来使能通道

s32Ret=HI_MPI_VI_EnableChn(ViDev,ViChn);

设置通道的每秒的帧数,N制下为30,PAL制下为25帧。

s32Ret=HI_MPI_VI_SetSrcFrameRate(ViDev,ViChn,u32SrcFrmRate);

整体上把握一下视频解码的流程,至少也得知道数据是如何采集的

STEP1:模拟信号的采集

模拟信号通过2866芯片采集,转换为数字信号。2866芯片是标准的AD,DA数据转换芯片。在我们的系统中主要实现模拟信号转数字信号输入,数字信号转模拟信号的输出。

2866最大可以同时采集4CH视频信号。

STEP2:模数转换

2866采集的4CH视频信号(模拟)转换为1CH数字信号送3520芯片。对于像本人这样的新手来说,此处可能会有点理解困难,为什么4CH模拟信号

输入2866转换输出的仅仅只是1CH数字信号。这就涉及到点点数电的知识了,数字信号简单讲就是高低电平,高电平代表1,低电平代表0,如何在1CH数字信号

里包括4路VI视频呢?假设下图是2866送出的视频数字信号一个时钟周期内的波形图,

-_--_-_--__---_--_-_--__---_--_-_--__----_--_-_--__----_--_-_--__-----_-

周期的前四个信号 -_-- 第一个信号值为VI1的视频信号,第二信号值为VI2的视频信号,第三个信号值得为VI3的视频信号,第四个信号值得为VI4的视频信号。

STEP3:2866输出视频数据到3520

此时引入一个概念,VI设备,什么是VI设备,对于3520来说,上一步2866采集的4CH模拟信号转换后的一路视频信号就是1个VI设备,该VI设备同时处理包括4路视频数据。

海思的VI模块所做的主要工作就是处理VI设备的4CH视频数据,将视频数据放入内存区域。至于以后这些内存数据是用于视频输出,还是视频编码,就另当别论了。

看了几天的视频输入和视频输出部分的代码,自已也写了一些自已的DEMO程序,慢慢对这一块有了自已的认识,争取早点将一只脚迈入门内吧。

前几次的笔记大多谈到视频输入的处理, 这次想重点谈谈视频输出的处理。

3520支持三种视频输出设备,HD设备,AD设备,SD设备。

typedef enum hiVO_DEV_E

{

VO_DEV_HD = 0, /* high definition device */

VO_DEV_AD = 1, /* assistant device */

VO_DEV_SD = 2, /* spot device */

VO_DEV_BUTT

} VO_DEV_E;

视频输出模块所做的工作大约就是将视频数据从内存中取出来,送相应的显示设备输出。


接下来准备以我们的产品为例,写写视频输出的处理过程。

机器起动是16画面输出,这点是如何实现的?

1 不同的视频输出设备(HD,AD,SD)的视频输出大小是不一样的, 所以我们必须设置进行VI和VO的绑定处理,16画面输出,要求VI视频通道数据分别与16个通道依次绑定

2视频输出设备图形层的大小,AD设备与SD设备设置图像的大小为D1(PAL为720*576, ntsc为720*480),HD设备根据用户设置的分辨率大小设定.

3因为我们的视频输出的是16个画面,所以要求设置VO通道的属性值,主要是大小和坐标,叠加优先级。




当进行切换画面时又是如何处理的?

主要处理过程和上述基本相同, 但还是有些不一样。

1 首先你必须 Disable VO输出

假设你上一次视频为16画面输出,行,先Disable 16个vo通道。

for(i = 0; i < ibind; i ++)//最大通道数

{

if(iRet = (HI_MPI_VO_DisableChn(VoDev,i)) != 0)

{

DEBUG_INFO(("DisableVideoOutput HI_MPI_VO_DisableChn err (0x%x) vochn=%d /n",iRet, i));

//return -1;

}

}

2 设置VI属性。

当切换到单画面时,设置VI采集数据的大小为D1


/*设置VI通道属性,设置为D1大小显示*/

retvalue = HI_MPI_VI_GetChnAttr(channel/4, channel%4, &stViChnAttr);

FAIL_RETURN(retvalue);

stViChnAttr.stCapRect.u32Width = 704;

stViChnAttr.stCapRect.u32Height = (TS_PAL == system)?288:240;

stViChnAttr.bDownScale = HI_FALSE;

stViChnAttr.enCapSel = VI_CAPSEL_BOTH;

retvalue = HI_MPI_VI_SetChnAttr(channel/4, channel%4, &stViChnAttr);

FAIL_RETURN(retvalue);

当切换到四画面,9画面,16画面,设置VI采集数据的大小为CIF.

/*设置VI通道属性,设置为CIF大小显示*/

retvalue = HI_MPI_VI_GetChnAttr(chn/4, chn%4, &stViChnAttr);

FAIL_RETURN(retvalue);

stViChnAttr.stCapRect.u32Width = 704;

stViChnAttr.stCapRect.u32Height = (TS_PAL==system)?288:240;

stViChnAttr.bDownScale = HI_TRUE;

stViChnAttr.enCapSel = VI_CAPSEL_BOTH;

retvalue = HI_MPI_VI_SetChnAttr(chn/4, chn%4, &stViChnAttr);

FAIL_RETURN(retvalue);

视频编解码的基本概念

1.什么是"帧"?

在最早的电影里面,一幅静止的图像被称做一"帧(Frame)",影片里的画面是每一秒钟有24帧,为什么是24帧,这个数字是怎么来的,因为人类眼睛的视觉暂留现象正好符合每秒24帧的标准,所以用多也没有意义还会浪费电影胶片,增加成本,所以就是24帧。

2.什么是"行"?

在我们用的传统CRT模似电视里面,一个电子束在水平方向的扫描被称之为行,或行扫描。

3.什么是"场"?

在我们用的传统CRT模似电视里面,一个行扫描,按垂直的方向扫描被称之为场,或场扫描。

4. 什么是NTSC制式?

NTSC(National Television System Committee)制式是1952年由美国国家电视制定委员会制定的彩色电视广播标准。美国、加拿大、以及中国台湾、韩国、菲律宾等国家采用的是这种制式。这种制式的彩色带宽为3.58Mhz,伴音带宽为6.0Mhz,每秒30帧画面。

5. 什么是PAL制式?

PAL(Phase Alternating Line),是1965年制定的电视制,主要应用于中国、香港、中东地区和欧洲一带。这种制式的彩色带宽为4.43Mhz伴音带宽为6.5Mhz,每秒 25帧画面,还有一种是SECAM制式德国地区采用的制式,因为应用比较少,就不多做介绍了。

6. 为何NTSC制为每秒30帧,而PAL制式每秒25帧?

这是因为采用NTSC的国家的市电为110V60HZ,所以电视里的场频信号直接就取样了交流电源的频率60HZ,因为两场组成一帧,所以60除以2等于30正好就是电视的帧数了,而我国的市电为220V50HZ,所以原因同上就是每秒25帧了。

7.什么是逐行?

电视的每帧画面是由若干条水平方向的扫描线组成的、PAL制为625行/帧,NTSC制为525行/帧。如果这一帧画面中所有的行是从上到下一行接一行地连续完成的,或者说扫描顺序是1、2、3……525,我们就称这种扫描方式为逐行扫描。

8.什么是隔行?

实际上,普通电视的一帧画面需要由两遍扫描来完成,第一遍只扫描奇数行,即第l、3、5……525行,第二遍扫描则只扫描偶数行,即第2、4、6……524行,这种扫描方式就是隔行扫描。一幅只含奇数行或偶数行的画面称为一“场(Field)”,其中只含奇数行的场称为奇数场或前场 (Top Field), 只含偶数行的场称为偶数场或后场(Bottom
Field)。也就是说一个奇数场加上一个偶数场等于一帧(一幅图象)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: