海思平台是一个板子和一个系统和若干驱动和mpp的结合.
板子可以是你自己做的,但是soc一定要选用海思平台支持的芯片.某些芯片也一定要选用海思支持的,像ADC/编解码芯片还有神马sensor之类的
系统包括BootLoader,内核,文件系统.都可以是你自己准备的.如果你自己准备,肯定要适配海思平台的HDK,不如用SDK中的BootLoader,内核,文件系统
海思方案还包括很多模块,其中有mpp的各个模块及内存管理模块及AD驱动/NVP6114驱动
mpp的话,包括一些静态库和动态库和头文件
himm命令来写寄存器,然后用insmod加载模块
用himm命令写的好像都是关于soc的里面的关于设备的寄存器,不知道具体写了什么东西,也不知道himm 的实现,可以用strace追一下.
总的来说,这个部分可以分为两个部分
视频缓存池这里的话,分为两块
一个是针对输入通道,输入通道用的是公共缓存池
一个是针对编解码通道,编解码通道用的是独享缓存池
系统控制的话,分为多块,其中
一个是系统初始化
系统初始化的话,要先HI_MPI_SYS_SetConf,再HI_MPI_SYS_Init,
函数HI_MPI_SYS_SetConf有1参
参数 : 使用图像的stride 字节对齐数
函数HI_MPI_SYS_Init无参
一个是绑定
绑定就像一个两通水管接头,函数为HI_MPI_SYS_Bind
函数HI_MPI_SYS_Bind有2参
参1为原通道信息
模块类型(标识被绑定的模块是VI,还是VO,还是VPSS等)
DevId(设备Id)(在一个芯片中,一个模块对应多个设备)
ChnId(通道Id)(在一个芯片中,一个设备对应多个通道)
参2为原通道信息
模块类型
DevId
ChnId
注:
在VPSS中没有设备的概念,有一个GROUP的概念,该概念等同于设备的概念
所以在填充HI_MPI_SYS_Bind的参数的时候,参数1或参数2中的DevId可以填入GroupId
一个是时间戳
一个是映射接口
一个是设置寄存器
一个是分配内存
##模块2:VI
之前提过,视频缓存池中的公共缓存池适应输入通道,输入通道就是VI里面的一个概念
传输流程
在传输的过程中,外来的线首先要接到VIU(概念0)的设备(概念1),经设备解复用,视频流进入设备中的通路(way),然后进入与way绑定的通道(概念2),然后进入公共缓存池(概念3)
视频输入设备的时序
待填入
掩码
标识视频数据源的信息
级联
输出端输出BT1120时序传送到另一颗芯片的视频输入端
VI这块,大概分下面几块
1/使能设备(包括设置设备)
函数有HI_MPI_VI_SetDevAttr和HI_MPI_VI_EnableDev
函数HI_MPI_VI_SetDevAttr有两参
参1为dev号(设备id)
参2为结构体,标识属性
au32CompMask数组,掩码,用来描述视频流信息
函数HI_MPI_VI_EnableDev有一参
参为dev号
2/使能通道(次通道)(包括设置通道)
函数有HI_MPI_VI_SetChnAttr和HI_MPI_VI_EnableChn
函数HI_MPI_VI_SetChnAttr有两参
参1为chn号(通道id)
参2为结构体,标识属性
stCapRect,结构体,捕获区域原始坐标与宽高
stDestSize,结构体,目标宽高
enPixFormat,像素存储格式
s32SrcFrameRate,原始帧率
s32FrameRate,目标帧率
函数HI_MPI_VI_EnableChn有一参
参为chn号
3/修改设备与通道之间的绑定(有默认绑定,部分芯片不支持修改)
函数主要有HI_MPI_VI_ChnBind和HI_MPI_VI_GetChnBind
4/级联
函数有HI_MPI_VI_EnableCascade和HI_MPI_VI_EnableCascadeChn
VO模块会从内存相应位置(也就是从DDR中的公共视频缓存池)读取视频和图形数据,并通过相应(是怎么设置的?)的显示设备输出.
VO这块有几个层的概念
一个是视频层
一个是图形层
一个是鼠标层
视频层的话,只最多能有一层
图像层的话,也最多能有一层
鼠标层的话,也最多能有一层(可以为硬件鼠标层(api和图形层一致)或软件鼠标层(独立的api))
举例分析:
对于Hi3520D,如果HD0设备上叠加了视频层,图形层G0(/dev/fb0),鼠标层G3(/dev/fb3),则显示顺序从最下面到最上面依次是视频层,图形层,鼠标层
VO分为两块
一个是输出到HD
输出到HD的过程中存在图形层/视频层/PIP层/鼠标层的概念
一个VO模块有多个HD输出设备
一个HD输出设备有多个通道
一个通道的属性中有优先级(决定该通道位于视频层还是PIP层)的概念
一个是输出到SD
输出到SD的过程中不存在图形层/视频层/PIP层/鼠标层的概念,如果非要说有的话,那就是只有视频层一层
一个VO模块有多个SD输出设备
一个SD输出设备有多个通道
一个通道的属性中有优先级(决定该通道在叠加时在上层还是在下层)的概念
这里面涉及到一个问题,那就是在显示器上显示的问题.
高清设备 的多通道只能由一通道显示在显示器中.(PIP叠加也属于一个通道)
不能将多个通道的画面缩小成小画面然后叠加其他通道的小画面,合成一个画面显示在显示器中.
标清设备 的多通道可以通过TDE缩放,并叠加,合成一个画面显示在显示器中.
高清设备中的PIP叠加
将某个特定标清设备的视频层绑定到高清设备(绑定到高清设备还是高清设备的通道)上,与原有的视频层叠加.
标清设备的视频层此时只能作为此高清设备(难道PIP层是设备的概念,不是通道的概念?)的PIP层,不能作为其他高清设备
(难道视频层是设备的概念,不是通道的概念?)的视频层
设置该标清设备的输出为PIP
设置高清设备的通道为视频层
---------------------------------------------------------------------------------
设置设备公共属性并开启设备
---------------------------------------------------------------------------------
1/HI_MPI_VO_SetPubAttr
参数1,vo dev id
参数2,vo接口信息
参数3,帧率
2/HI_MPI_VO_Enable
参数, vo dev id
---------------------------------------------------------------------------------
设置视频层属性并开启视频层
---------------------------------------------------------------------------------
3/HI_MPI_VO_SetVideoLayerAttr
参数1,vo dev id
参数2,结构体,标识视频层属性
stDispRect,显示分辨率
stImageSize,视频层画布大小
u32DispFrmRt,显示帧率//PAL下为24,NTSC下为30
enPixFormat,像素格式//YUV
4/HI_MPI_VO_EnableVideoLayer
参数, vo dev id
---------------------------------------------------------------------------------
设置通道属性并开启通道(通道的个数和开启设备/开启视频层无直接关系)
---------------------------------------------------------------------------------
5/HI_MPI_VO_SetChnAttr
参数1,vo dev id
参数2,通道ID
参数3,结构体,标识通道属性
u32Priority,通道优先级,高清范围在[0,1].标清范围在[0,通道数量-1]
stRect,显示区域
bDeflicker,是否开启抗闪烁
5/HI_MPI_VO_EnableChn
参数1,vo dev id
参数2,通道ID
VPSS将进入VPSS通道的图像进行去噪/去隔行/缩放/锐化
VPSS模块有多个GROUP
一个GROUP有多个通道(通道分类为3种,分别是物理/直通/扩展)
物理通道:一个组的物理通道有多个,每个功能不同
直通通道:一个组有一个,只具备CROP(裁剪)功能
扩展通道:通过绑定物理通道可以将物理通道的输出作为扩展通道的输入,然后缩放,输出.
绑定示例
每个(特定vi设备的通道)可以和一个组的chn0绑定
每个(特定VO设备的通道)可以和一个组的通道绑定
-----------------------------------------------------------------------------
创建通道
-----------------------------------------------------------------------------
1/HI_MPI_VPSS_CreateGrp
参数1,组id
参数2,组属性
最大图像宽度
最大图像高度
像素格式
Die模式(去隔行/将交错的隔行视频源还原成逐行视频源)
功能开启开关(5个)
-----------------------------------------------------------------------------
设置组属性 及 设置组高级属性
-----------------------------------------------------------------------------
2/HI_MPI_VPSS_GetGrpAttr
参数1,组id
参数2,组属性
3/HI_MPI_VPSS_SetGrpAttr
参数1,组id
参数2,组属性
4/HI_MPI_VPSS_GetGrpParam
参数1,组id
参数2,高级组属性
5/HI_MPI_VPSS_SetGrpParam
参数1,组id
参数2,高级组属性
亮度
对比度
暗区增强
亮区增强
IE强度
IE锐度
空域去噪强度
...
-----------------------------------------------------------------------------
设置通道属性 及 使能通道
-----------------------------------------------------------------------------
6/HI_MPI_VPSS_SetChnAttr
参数1,组id
参数2,通道id
参数3,通道属性
7/HI_MPI_VPSS_EnableChn
参数1,组id
参数2,通道id
-----------------------------------------------------------------------------
开启组
-----------------------------------------------------------------------------
8/HI_MPI_VPSS_StartGrp
参数,组id
编码的话分为三块
从接收图像那块,输入可以分为三类(输入的都是YUV,只不过输入的途径不一样)
1. 用户读图像,发送?
2. VIU输出
3. VPSS输出
从编码那块,编码可以分为四类
1. H.264
2. JPEG
3. MJPEG
4. MPEG-4
编码的过程可以分为两个过程
1. 控制码率
2. 编码
REGION的意思就是叠加一些区域
区域的话分为两种
一种为Overlay(时间戳,通道号,位图,背景色更新?)/OverlayEx
Overlay只能在GROUP通道叠加
OverlayEx可以在VI通道叠加
一种为Cover(色块)/CoverEx
Cover/CoverEx可以在VI通道叠加
-----------------------------------------------------------------------------
创建区域,此时还没显示在通道
-----------------------------------------------------------------------------
1/HI_MPI_RGN_Create
参数1,区域句柄(ID)
参数2,结构体,区域属性
类型(Overlay/OverlayEx/Cover/CoverEx)
对应类型的区域属性(注意:Cover和CoverEx没有区域属性)
Overlay的区域属性(像素格式,区域背景色,区域的宽度)
OverlayEx的区域属性(像素格式,区域背景色,区域的宽度)
-----------------------------------------------------------------------------
将区域叠加到通道
-----------------------------------------------------------------------------
2/HI_MPI_RGN_AttachToChn
参数1,区域句柄(根据这个参数可以看出来,是attach到跟区域绑定的所有通道上的区域上,变化区域,所有通道会变化)
参数2,结构体,通道属性
模块类型
dev号
通道号
参数3,叠加到通道,显示时的属性
区域是否显示
区域类型(Overlay/OverlayEx/Cover/CoverEx)
属性,共同体(四种类型的属性)
Overlay(区域起点坐标,前景Alpha,背景 Alpha,区域层次,编码QP值,反色配置信息)
OverlayEx(区域起点坐标,前景Alpha,背景 Alpha,区域层次)
Cover(区域位置(起点坐标,宽高),区域颜色,层次)
CoverEx(区域位置(起点坐标,宽高),区域颜色,层次)
注:
前景Alpha : Alpha 位为 1 的像素点的透明度
背景Alpha : Alpha 位为 0 的像素点的透明度
-----------------------------------------------------------------------------
将位图叠加到区域(如果区域已经叠加到通道,那么会影响所有的被区域叠加的通道)
-----------------------------------------------------------------------------
3/HI_MPI_RGN_SetBitMap
参数1,区域句柄(ID)
参数2,位图信息,结构体
像素格式
宽度
长度
数据(这个数据可以利用位图转换函数填充,也可以手动填充)
-----------------------------------------------------------------------------
得到区域属性/设置区域属性
-----------------------------------------------------------------------------
4/HI_MPI_RGN_GetAttr
参数1,区域句柄(ID)
参数2,结构体,区域属性
5/HI_MPI_RGN_SetAttr
参数1,区域句柄(ID)
参数2,结构体,区域属性
-----------------------------------------------------------------------------
得到通道显示属性/设置通道显示属性
-----------------------------------------------------------------------------
6/HI_MPI_RGN_GetDisplayAttr
参数1,区域句柄(ID)
参数2,结构体,通道属性
参数3,叠加到通道,显示时的属性
7/HI_MPI_RGN_SetDisplayAttr
参数1,区域句柄(ID)
参数2,结构体,通道属性
参数3,叠加到通道,显示时的属性
海思媒体处理平台提供的解码是硬解码功能,提供的API都是针对驱动的接口.
进来的码流不是直接接到通道里的,而是要通过调用函数接口将码流发送到通道中
原始输入为视频流,分为两种方式输入(流式输入和按帧输入)
发送到通道中
解码的话分为两种(流式解码和按帧解码)
输出的话分为两种(按显示序输出/按编码序输出)
注:
流式解码:开始接A帧的码,然后接到下一帧B帧才能知道结束,然后处理A帧
按帧解码:开始接A帧的码,边接收边解码,直到接收完毕.//因为输入的码是按帧发送到输入端的
根据输入/解码/输出的不同匹配,可以构成下面三种图像输出方式
普通输出
流式输入->流式解码->显示序输出
按帧输入->按帧解码->显示序输出
直接输出
流式输入且按解码序输入->流式解码->解码序输出
按帧输出
按帧输入且按编码序输入->按帧解码->解码序输出
时间戳
时间戳只可以加在VIDEO_MODE_FRAME 下
时间戳加在VIDEO_MODE_STREAM下,为0
HI_MPI_VDEC_CreateChn
码流解码方式
HI_MPI_VDEC_SetChnParam
图象输出方式 s32DecOrderOutput
接口调用顺序:
ATTENTION : HDMI接口必须在VO后面,在音频输出前面
-----------------------------------------------------------------------------
HDMI初始化
-----------------------------------------------------------------------------
HI_MPI_HDMI_Init
参数为结构体
1/回调函数指针
2/回调函数参数
3/强制输出模式,枚举
HI_HDMI_FORCE_NULL 标准
HI_HDMI_FORCE_HDMI HDMI输出
HI_HDMI_FORCE_DVI DVI输出
HI_HDMI_INIT_BOOT_CONFIG 测试
HI_MPI_HDMI_Open
参数,接口号,枚举
HI_HDMI_ID_0 如果是HTMI,则取HI_HDMI_ID_0,即0
HI_HDMI_ID_BUTT
HI_MPI_HDMI_GetAttr
参数1,接口号
参数2,HDMI属性结构体
stAttr.bEnableHdmi = HI_TRUE;是否强制输出HDMI
stAttr.bEnableVideo = HI_TRUE;是否输出视频
stAttr.enVideoFmt = enVideoFmt;视频输出制式,枚举
stAttr.enVidOutMode = HI_HDMI_VIDEO_MODE_YCBCR444;
stAttr.enDeepColorMode = HI_HDMI_DEEP_COLOR_OFF;
stAttr.bxvYCCMode = HI_FALSE;
stAttr.bEnableAudio = HI_FALSE;
stAttr.enSoundIntf = HI_HDMI_SND_INTERFACE_I2S;
stAttr.bIsMultiChannel = HI_FALSE;
stAttr.enBitDepth = HI_HDMI_BIT_DEPTH_16;
stAttr.bEnableAviInfoFrame = HI_TRUE;
stAttr.bEnableAudInfoFrame = HI_TRUE;
stAttr.bEnableSpdInfoFrame = HI_FALSE;
stAttr.bEnableMpegInfoFrame = HI_FALSE;
stAttr.bDebugFlag = HI_FALSE;
stAttr.bHDCPEnable = HI_FALSE;
stAttr.b3DEnable = HI_FALSE;
HI_MPI_HDMI_SetAttr
参数1,接口号
参数2,HDMI属性结构体
HI_MPI_HDMI_Start
参数,接口号
Video detection analysis
VDA有两种模式,没有组和设备的概念,直接是通道.
通道分为两种(通过HI_MPI_VDA_CreateChn函数的第二个参数指定)
-----------------------------------------------------------------------------
创建通道
-----------------------------------------------------------------------------
HI_MPI_VDA_CreateChn
参数1,通道号
参数2,视频检测属性,结构体
工作模式,枚举
VDA_WORK_MODE_MD//运动
VDA_WORK_MODE_OD//遮挡
VDA_WORK_MODE_BUTT
工作模式属性,联合体
通道宽度//通道大小可以和输入源大小不一致
通道高度//输入源图像的宽和高都必须大于等于通道属性的宽和高
-----------------------------------------------------------------------------
绑定输入源
-----------------------------------------------------------------------------
HI_MPI_SYS_Bind
注意:绑定的时候dst的DEVid为0
-----------------------------------------------------------------------------
启动VDA
-----------------------------------------------------------------------------
HI_MPI_VDA_StartRecvPic
参数,通道号
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
怎么得到结果,结果怎么处理
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
一般来说创建一个线程,然后在线程里面通过函数HI_MPI_VDA_GetFd得到一个文件描述符,
然后监听这个文件描述符,如果有写入信息的话,然后通过一个函数HI_MPI_VDA_GetData得到数据,拿去处理,然后再通过一个函数HI_MPI_VDA_ReleaseData释放数据,循环
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
得到文件描述符
-----------------------------------------------------------------------------
HI_MPI_VDA_GetFd
参数,通道号
-----------------------------------------------------------------------------
得到数据
-----------------------------------------------------------------------------
HI_MPI_VDA_GetData
参数1,通道号
参数2,数据,结构体
工作模式
工作模式对应的数据,枚举体
宏块大小,枚举?
以宏块大小为单位的宽度
以宏块大小为单位的高度
时间戳
参数3,是否阻塞
-----------------------------------------------------------------------------
释放数据,在得到数据那个函数里面可能malloc了一些内存,所以需要free
-----------------------------------------------------------------------------
HI_MPI_VDA_ReleaseData
参数1,通道号
参数2,数据,结构体