海思笔记_海思 mjpeg 视频流 pc解码-程序员宅基地

技术标签: hisi  

 

第一章、海思hi3518e的底层

所使用的的cpu是海思HI3518E V200

1.1、hi3518e开发板的运行过程

通过串口转接线(不接电源线,txd接rxd,rxd接txd,地线接地线)连接上电脑,接网线。通过SecureCRT挂载到ubuntu16.0403中的/aston/rootfs。在SecureCRT的cmdline中./sample_venc进入运行模式。

设置windows的网络ip(192.168.1.20),让虚拟机linux、windows和海思开发板中设置的网络(192.168.1.10)三者保持同网段(192.168.1.1)。

关闭windows中的防火墙,打开vlc软件,在媒体中点打开网络串流,输入rtsp://192.168.1.10:554/stream_chn0.h264   在下面的选项(缓冲)选300ms。

1.2、视频的产生整个流程


sensor可以看成时光电传感器,镜头把光折射后缩小(大范围的光转小范围),光照射到sensor,sensor把光信号转成模拟电信号。模数转换出来。

图像处理ISP(image signal processing),处理曝光等等。

内置DSP进行视频编码压缩,编码和压缩是同个意思。h.264/h.265压缩算法,运算。所以hi3518e的SoC的cpu为arm+dsp。

视频流传输:网络传输、http/rtsp等。

 

接收端有两个处理方法:

视频存储或者视频回放。

视频存储:打包成MP4等格式存储。

视频回放:解码+播放。

 

 

mpp文件夹 视频编码

ko后缀文件,海思官方提供的驱动

extdrv外部驱动,sensor驱动

 

1.3、海思SDK

   海思hi3518e的bsp在osdrv中的opensource文件夹中。

   编译完后,uboot、kernel、jffs2的镜像在pub目录下。

在交叉编译工具链的选择:300和400。glibc库是gcc中最完整的库。uclibc是精简了glibc库。我们选择了uclibc库的arm-hisiv300-linux。安装后出现下列问题:

第一是sh脚本的链接文件有问题,本来是链接与dash的,需要换成bash。

第二是工具链是32位的,而我们的ubuntu系统是64位的,我们需要添加软件兼容包。

  

参考资料:

http://blog.csdn.net/ma57457/article/details/68923623

http://www.cnblogs.com/leaven/p/5084902.html

sudoaptitude install lib32zl

sudoaptitude install lib32stdc++6-4.8-dbg

安装完这个两个包后,加上先前先.bashrc添加的PATH路径,即可编译osdrv。

   在编译整个osdrv的时候出现的问题有:
第一、找不到mkimage,解决方法:把mkimage复制到一个路径(在PATH环境变量中指定的位置)。

第二、是找不到zlib,解决方法:整个osdrv是提供了zlib的,只是因为已经编译了zlib没有部署它。所以要做的就是部署zlib,把osdrv/tools/pc/zlib/tmp/lib下的全部库复制到osdrv/tools/pc/jffs2_tool/tmp/lib/,

和把osdrv/tools/pc/zlib/tmp/zlib-1.2.7下的zlib.h, zconf.h复制到osdrv/tools/pc/

jffs2_tool/tmp/include/;在次编译就可以完成jffs2的根文件系统。

第三、

是因为我们使用的ubuntu的版本太高,海思的SDK中使用的mtd-utils的版本过低导致的问题。

解决方法参考这片博客中http://blog.csdn.net/mtbiao/article/details/77052659

方法2:修改操作系统头文件/usr/include/netdb.h,将此宏__USE_XOPEN2K注释,如下图(注意#ifdef与#endif是一一对应的)。这个宏不止一个。

将Makefile中的hipctools下面除了jffs2编译和复制的内容外的全部去除,这样保证了不会出现很多错误。

   至此,我们就可以编译得到u-boot和kernel,jffs2的rootfs。分别名为:

 

   这些制作完毕后,需要进行烧录。uboot作为第一个烧录需要使用下列两种方法中的一种:

第一使用烧录工具对spi flash进行烧录。

第二使用海思官方提供的烧录工具进行烧录。

 

我选择的分区表:

BootLoader            1M         0x0-0x00100000

kernel                     3M         0x00100000-0x00400000

rootfs               12M              0x00400000-0x01000000

 

相关烧录命令:

前提:DDR地址为0x80000000-0x83FFFFFF

1、tftp更新并重新烧录uboot的命令序列:
mw.b 0x82000000 ff 0x100000        //擦除ddr中以0x82000000起,1M大小

tftp0x82000000 u-boot-hi3518ev200.bin              //tftp下载uboot

sfprobe 0                                    //选择spi flash (数字是表示第几块flash)

sferase 0x0 0x100000         //擦除spi flash中以0x0起,1M大小

sfwrite 0x82000000 0x0 0x100000        //     从ddr中0x82000000烧录到flash

2、tftp更新并重新烧录kernel的命令序列:

mw.b 0x82000000 ff 0x300000

tftp0x82000000 uImage_hi3518ev200

sfprobe 0

sferase 0x100000 0x300000             //0x100000起始位置,0x300000大小

sfwrite 0x82000000 0x100000 0x300000            

tftp更新并重新烧录rootfs的命令序列:

mw.b 0x82000000ff 0xc00000

tftp0x82000000 rootfs_uclibc_64k.jffs2

sf probe 0

sferase 0x400000 0xc00000

sf write0x82000000 0x400000 0xc00000

 

注:sf erase 0x400000 0xc00000 这句擦除flash的命令,实质是向flash中写ff。mw.b 0x820000000 ff 0xc00000是把ddr中12M空间写为ff。所以要保证flash和ddr中的擦除大小要一致,不然会在flash中校验出现错误。

 

设置bootcmd和bootargs:

set bootcmd ‘sfprobe 0; sf read 0x82000000 0x100000 0x300000; bootm 0x82000000’

 

setenvbootargs 'mem=32M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=jffs2mtdparts=hi_sfc:1M(boot),3M(kernel),12M(rootfs)'

注意:

root=/dev/mtdblock2代表我们rootfs在第三个分区
mem=32M,我们的内存是64M,而分配给kernel的只有32M,剩下的是给海思mpp(专门用于处理视频相关的)使用。

1.4、部署开发环境

1.4.1、mpp
   由海思官方以.ko(模块)和lib中的静动态库。

ko的使用,在ko文件夹中有一个load3518e,执行:

./load3518e-i -sensor ar0130 -osmem 32 -total 64

传参分别指定了sensor,osmem(linux kernel)的大小,total整体的大小。

1.4.2、kernel设置网络并挂载nfs
   在etc/profile中写入:
ifconfig lo 127.0.0.1

ifconfigeth0 192.168.1.10

保存。

在cmdline下输入下列命令挂载nfs服务器:
mount-t nfs -o nolock 192.168.1.141:/home/aston/rootfs/mnt

其中/home/aston/rootfs 是ubuntu中的地址

/mnt是开发板中rootfs的地址

 

小总结:在profile中要去添加做的是分别配置网络,安装ko模块,以及挂载nfs服务器。

再完成了这些操作后,可以重新制作一份rootfs,命令:

osdrv/pub/bin/pc/mkfs.jffs2-d osdrv/pub/rootfs_uclibc -l -e 0x10000 -o

osdrv/pub/rootfs_uclibc_64k.jffs2

   命令中使用的工具是相对路径。

 

第二章、mmp sample

1、基本知识
1.1、sensor和图片的知识
颜色的三个关键:亮度、色度、饱和度

 

sensor的工作原理:

光照在成像物体被反射->镜头汇聚->sensor光电转换->ADC模数转换成rawRGB

rawRGB通过特点的算法获得RGB。

rawRGB是sensor这种硬件的特点,因为不能通过sensor获取整个RGB数值,所以通过每个像素点为下表:           
 

   然后通过局部的计算获得一个RGB数据。

   图像处理:压缩、修整、显示等这些是rawRBG进来后的事情(我认为是在rawRGB转RGB前),也就是软件处理的内容。

观看的影响:分辨率,像素间隔,观看距离,fps(帧率)

1.2、像素格式
   

除了我们熟知的RGB外,还有YUV。

1.2.1、RGB
RGB565,RGB888,ARGB

我们要知道色度有三种red,green,blue。RGB的原理:通过改变色度的亮度来表达不同的颜色。

   助解:红色只有一个,RGB通过改变亮度来表示多种颜色。所以RGB888的24位数据就是在记录亮度。

 

RGB的优势:数字化处理,很适合我们使用。

RGB的劣势:与灰度图的兼容不好,表达颜色效率低。

1.2.2、YUV
       

    YUV是以YUV(Y:亮度;U、V:色度)来表示。

       YUV是以前黑白图片转彩色图片过程的一个产物。

 

YCBCR几乎和YUV相同,有细微差别。

1.2.2.1、YUV的两种格式

 

YUV分为planar(平面) packed(打包)。参考博客:

blog.csdn.net/sunnylgz/article/details/7580628

packed是把YUV数据分量存放在数组中(每一个像素点有一个数组),而planar是把YUV三种分别存放在三个数组中Y[],U[],V[]。

       packed适用于分点显示,比如取前面几个数组即可。

       而planar适用于下列情况,我们要改变图片的亮度,那么直接从Y[]数组进行修改。

 1.2.2.2、YUV planar的多种

       YUV,YUYV

(p)YUV422planar,YUV420 planar

(sp)YUV422semi planar,YUV420 semi planar

参考博客:

www.2cto.com/kf/201303/198023.html

blog.csdn.net/bingqingsuimeng/article/details/50716390

       看完后简单总结:
1、YUV420是以1个像素点对应一位Y,相邻的2*2的4个像素点对应一个U和一个V。

2、YUV422是以1个像素点对应一位Y,相邻的2个像素点对应一个U和一个V。

3、YUV420p和YUV420sp的区别在于UV的存放方式不同,YUV420p是以Y[];[U0,V0],[U1,V1]……UV以多个数组分别存放。而YUV420sp是以Y[],U[],V[]形式存放的。

4、YUV422p和YUV422sp的区别同3。

参考博客中图片。

 

助:RGB和YUV是可以通过数学公式(浮点计算)来切换,我们关心的是怎么让这条公式算的更快(比如通过DSP)。

1.3、海思MPP功能模块和视频缓存池
       海思的主要视频编解码过程如下图:

VI(video in)通过AD(模数转换)得到图像数据,VPSS对图像数据进行处理,VO实时输出,VENC视频编码器(制作对应的码流),VDA视频数据分析(在数据手册中有时被称为 智能处理IVE),VDEC对硬盘视频进行解码给VPSS处理。

PS:VGA并不是指VGA线,而是指640*480分辨率。

 

1.4、VENC sample

       VENC视频编码过程:

1.4.1、视频缓存池

VB:video buffer:视频缓存池

       在文件HiMPP IPC V2.0 媒体处理软件开发参考中2.2.1节。

       通过下面相关数据结构和API进行初始化:

VB_CONF_S,设置内容如下图:

 

       其中u32MaxPoolCnt是最大视频缓存池的个数,而VB_MAX_COMM_POOLS是最大公共视频缓存池个数。

 

HI_MPI_VB_SetConf

       配置

HI_MPI_VB_Init

       初始化

video buffer init over

1.4.2、mpp初始化
       这一阶段并不会让我们来完成,而是调用海思封装好的API。

       但是前提是我们要对视频缓存池的参数进行设置:

1)     通过Makefile中定义的SENSOR_TYPE来确定视频的最大的分辨率,并确认生成多少路码流。

2)     多少路码流就有多少个视频缓存池,设置视频缓存池大小,池中块数和块的大小(块大小被设置为g_u32BlkCnt = 4)。

 

调用API初始化mpp

1)     调用下列两个函数退出VB和SYS(保险举动):

HI_MPI_SYS_Exit();HI_MPI_VB_Exit();

2)     分别调用HI_MPI_VB_SetConf配置;HI_MPI_VB_Init初始化

3)     分别调用HI_MPI_SYS_SetConf配置;HI_MPI_SYS_Init初始化

1.4.3、VI
video in。

DC数字接口

rotate旋转

1.4.4、VPSS
VPSS video proesssub-system

可输出多种不同分辨率的图像。

VPSS单元支持的具体图像处理功能包括FRC(FrameRate Control帧率控制)、 Crop、 NR(Noise Reduce)、 LDC(Lens Distortion Correction)(图像畸变矫正)、 Rotate、 Cover/Overlay(覆盖)、 Scale(缩放)、Mirror/Flip、 FishEye(鱼眼处理)等。

有auto和user两种模式。

3518e只能使用 USER 模式,则需调用 MPI 接口进行设置,同时指定所需图像的大小和格式,此模式下各通道可与多个接收者绑定。需要特别注意的是, USER 模式主要用于对同一通道图像进行多路编码的场景,此模式下播放控制不生效,因此预览和回放场景下不建议使用 USER 模式。

3518e的VPSS流程:

      

GROUP:

VPSS 对用户提供组(GROUP)的概念。在线模式下仅能有一个;离线模式下最大可用数为VPSS_MAX_GRP_NUM个,各芯片的最大组数目有所不同,各 GROUP 分时复用 VPSS 硬件。每个VPSSGROUP 包含多个通道。

CHANNEL:

VPSS 组的通道。通道分为 2 种:物理通道和扩展通道。 VPSS 硬件提供多个物理通道,每个通道具有缩放、裁剪等功能。扩展通道具备缩放功能,它通过绑定物理通道,将物理通道输出作为自己的输入,把图像缩放成用户设置的目标分辨率输出。3518e有4个物理通道,8个拓展通道,每个通道有自己的特性。

离线模式:是指 VI 写出数据到 DDR,然后与之绑定的模块从 DDR 读取数据(LDC畸变矫正只能在离线模式中运行,除非自己在VPSS后在使用算法完成LDC,个人理解未证实)。

在线模式:在线是指 VI 与 VPSS 之间的在线数据流传输,在此模式下 VI 不会写出到 DDR,而是直接把数据流送给VPSS。(更快捷)

所以在线模式只能等到VPSS处理完之后分多个通道输出多个流。

默认设置为在线模式,是因为在load脚本中设置的。

具体:

       在load3518e(装载驱动的脚本)中,有这么一句代码:
insmod hi3518e_sys.ko vi_vpss_online=$b_arg_onlinesensor=$SNS_TYPE

加色的就是在线模式和离线模式的开关,所以只需把b_arg_online设置为0即可切换为离线模式。

1.4.5、VENC
       video encode。

1.4.5.1、图像压缩原理:

参考:http://blog.csdn.net/newchenxf/article/details/51693753

空间冗余;时间冗余;视觉冗余。

 

常用有失真压缩,找到平衡点。

VENC 模块,即视频编码模块。本模块支持多路实时编码,且每路编码独立,编码协议和编码 profile 可以不同。本模块支持视频编码同时,调度 Region 模块对编码图像内容进行叠加和遮挡。

 

BP高压

MP居中

HP高清

JPEG图片编码格式

MJPEG以前的视频编码格式

 

通道支持接收 YUV 格式图像输入,支持格式为 Semi-planar YUV 4:2:0 或 Semi-planar YUV 4:2:2,其中H.264/H.265 只支持 Semi-planar YUV 4:2:0, JPEG/MJPEG 支持 Semi planar YUV 4:2:0 或 Semi-planar YUV 4:2:2。另外,Hi3518EV200 能够支持单分量入(只存在 Y 分量)。通道模块接收外部原始图像数据,而不关心图像数据是来自哪个外部模块。

 

svc是H.264的补充编码标准。

CBR固定码率。

VBR可变码率,保证编码质量。

FIX Qp,固定Qp值。

Qp值越高,码率越低,质量越差。

Qp值越低,码率越高,质量越高。

 

第三章、ORTP

       视频网络传输的方法:ftp,http(网络缓冲,基于下载)

实时传输rtp(Real Time Protocol):ORTP,RTSP,RTCP

ORTP是开源的RTP库。

RTSP是专门传输视频流,实时流传输协议。

RTCP是RTP控制协议,传输过程中速率控制,可以看成RTP加上控制信息。

       ORTP有多个语言版本,我们使用的是C语言版本的。

实时传输在下层使用UDP,因为TCP/IP会校正数据,使用UDP更加适合。       RTP及RTCP的实现遵循国际标准RFC3550规定,只要符合规定即可自己写一个流传输。

 

ORTP库的移植:

       unzip解压zip类型的压缩包。

安装三步骤:配置,编译,安装。

配置前源码更改:

       在avprofile.c中av_profile_init函数添加新的payload  h.264。

rtp_profile_set_payload(profile,96,&payload_type_h264);

PS:96为h.264编码的编号,这是固定的。

(1)进入ortp目录执行./autogen.sh

(2)错误1:./autogen.sh: line 44: libtoolize: command not found

   解决:sudoapt-get install libtool*

(2)错误2:libtoolize:   error: Pleaseinstall GNU M4, or 'export M4=/path/to/gnu/m4'.

   解决:sudoapt-get install m4

(3)错误3:Automake - aclocal: command not found

   解决:sudoapt-get install automake

(4)继续执行./configure --prefix=/home/aston/sambashare/ortp-master/ortp--host=arm-hisiv300-linux

(5)make && make install

 

利用venc_sample源码进行添加ortp关键函数进行移植,初始化,发送。

在venc_sample.c中将视频数据通道数设置为1个。

在sample_comm_venc.c添加ortp init, ortp send函数,payload添加h.264支持。

在创建流文件处添加ortp初始化函数。

并将发送函数添加到原来进行写入流文件的函数处。

 

最后测试阶段:将主机ip设置为192.168.1.20,关闭防火墙,使用VLC打开demo文件进行配置,方可获取。

 

ortp中的调度机制是在维持多路会话之间的优先级,在ortp的调度机制是通过定时器一定时间去判断优先级哪个会话最大。

 

       Ortp的工作原理:建立一个对话,session给予通信双方。发送创建packet包进行发送。

       移植ortp库中,最复杂的是添加ortp相关初始化和发送函数到sample程序之中,编写发送函数中涉及到h.264的知识:

H.264 分为 VCL(编码层)和NAL(网络提取层)。网络提取层NAL维护了一个数据NALU(unsignedchar类型的)。发送的一个数据包中需要为其添加包头信息。当我们要发送的一个buffer大于规定的大小后就要拆成多个包进行发送,发送前就要对每个包进行添加包头信息的操作。

       NALU解析:

       一共是八个bit位,第0个bit位表示这一包信息的有效性(0为有效);第1和第2位表示这一包的重要性(11最重要,依次降低,00最不重要),重要性的作用在于当网络信号不好时,我们可以将不重要的包删去不发送;剩下的5位表示类型,在ortp传输中为28(RTP标志),标志类型可以在这个博客中看到一部分:http://www.cnblogs.com/jingzhishen/p/3965868.html。

 

在拆包时:NALU的数据被分开为两个字节写入rtp_session_send_with_ts发送函数,个人觉得应该是rtp_session_send_with_ts的设计方式,所以需要这么做。

 

vim 中快速操作:键盘按键:yyp复制粘贴

 

第四章、sensor

       改变sensor的过程:

第一点确定更改的sensor是否是已经在ko添加了的,如果体系中已有的,那么要更改文件profile,linux启动时给load3518e进行传参确定了ar0130,所以现在进行更改为ov9712,这里是确定加载的sensor驱动,reboot重启。

       第二点,在编译源码的Makefile.param中更改源码的sensor_type。

4.1、MIPI和LVDS和并口
       并口是低端的sensor(cmos电平信号,非差分信号),新型的sensor都是MIPI,LVDS或者HISPI等差分信号的。

       LVDS,低电压差分信号,使用的差分信号电压较低。优点低功耗;缺点低电压不好识别,所以抗干扰性差,但还是强于非差分的并口。

       主流使用的sensor基本上都是MIPI。

4.2、HI3518E的Sensor接口引脚复用设置
查看引脚定义框图、找到相应设置寄存器、himm工具。

Hi3518EV20X/Hi3516CV200经济型HD IP Camera Soc用户指南的管脚复用控制寄存器一节。

       通常复用寄存器的过程:load3518e脚本中改变sensor一些引脚,寄存器地址去数据手册管脚复用控制寄存器处找到对应的引脚名字,图文中有寄存器数据位的设置。有时需要用到硬件原理图。

4.3、sensor驱动
       Sensor驱动实际是库,依赖于i2c驱动。如果每次更改源代码,需要编译生成新的库,然后重新编译应用程序。

驱动中,sensor注册和3A注册用到的函数的具体意义:

 

 

 

 

 

在sensor设置中,有一个注册函数sensor_init中的sensor_init_720p_30fps会去sensor_write_register写寄存器。更改初始化寄存器的设置。

等等。

 

第五章、x210 wiFi驱动移植

       wifi的接口通常是SDIO和USB。我们使用的是USB接口的。

       移植需要做的几件事:

1)确定源码中:dev_id和lsusb显示出的id是一致的。从源码入口module_init(),依次找到dev_id。

2)Makefile修改,交叉编译工具链修改修改。      平台换成:三星 PLATFORM = SMDK          内核源码树:LINUX_SRC =  //linux内核源码树

Makefile中-DMT7601U,将宏MT7601U传到工程中。

3)可更改网卡名称:修改include/rtmp_def.h文件

#defineINF_MAIN_DEV_NAME "ra"

#defineINF_MBSSID_DEV_NAME "ra"
       找到这个文件的方法,直接grep  "wlan" * -nR 因为wlan和ra都是标准的名字。

4)     添加wpa_supplicant支持,在config.mk中将WPA_SUPPLICANT=y

 

makeclean && make 得到.ko文件。

将ko文件复制到rootfs中,安装并配置,详细见课件_USB WIFI网卡在X210上的移植和使用最全攻略。

配置命令:

网卡配置命令序列

insmodmt7601Usta.ko            //安装驱动程序

ifconfigra0 up                 //开启无线网卡

wpa_supplicant-B -c /etc/wpa_supplicant.conf -i ra0     //连接无线网络

wpa_cli-i ra0 status          //查看连接状态

ifconfigra0 192.168.1.200    //手动配置ip,同一网段

routeadd default gw 192.168.1.1 dev ra0                             //配置网关

ping192.168.1.1                         //ping 网关

ping8.8.8.8                             //ping 外网

vi/etc/resolv.conf                   //配置dns

nameserver192.168.1.1 

pingwww.baidu.com  

 

interface文件

5.1、wifi的ap模式
       wifi是有两种模式,一种为ap,一种是sta。

       ap模式通常使用于路由器中(可以理解为是热点),sta模式通常使用于手机等连接设备。

       使用的wifi设备是支持两种模式的,但是要分辨好不同的源码。

wifi做ap模式,pc机做sta模式:

编译ap源码,源码修改内容:

(1)include/rtmp_def.h中1627行左右,修改网络名始终为:wlan(可选,不做的话,网络名会是ra)

(2)在Makefile中添加新的PLATFORM =HISI_3518E,添加根据PLATFORM 为HISI_3518E的LINUX_SRC和CROSS_COMPILE,以及根据PLATFORM 为HISI_3518E的make命令。

(3)./os/linux/config.mk中添加EXTRA_FLAGS;因为EXTRA_FLAGS的数值是由PLATFORM的类型来确定的,所以要根据HISI_3518E来判断。

(4)修改Makefile或者手工复制xx.ko到/home/aston/rootfs(与设备挂载的文件夹)中。
 

部署并启动wifi功能:

接入usb类的wifi模块时,需要lsusb查看是否有这个新的usb设备,确认硬件层次上没有故障。

wifi做ap模式时,就需要设置SSID,加密类型,密码等。

1)从ap类型的源码中复制RT2870AP.dat,部署到HISI_3518E的板子上的/etc/Wireless/RT2870AP/RT2870AP.dat,修改内容:

       SSID=MT7601AP_WPA(这里的名字是在pc机上看到的连接ssid名)

       AuthMode=WPA2PSK(加密方式)

       EncrypType=TKIP;AES

       WPAPSK=1234567890(这个是密码)

2)insmod xx.ko安装ko驱动。

3)ifconfig –a查看是否有无线网卡,在重启无线网卡:ifconfig xxx up   or  

ifupxxx

4)再确认了开发板开启了wifi后,pc机连上这个wifi。

 

结合ortp实时无线传输:

因为我们在sample中将ip地址写死,所以此时需要进行修改。

1)开发板设置ip地址,给pc设置ip地址,确认这两个在同一频段。

2)将pc中设置的ip写到sample中,编译sample。

3)编辑demo,将demo中的ip地址改为现在开发板的ip地址。

现阶段IP地址设置:

无线:

windows:                       192.168.0.30

AP类型的wifi:             192.168.0.100

 

 

第六季、RTSP
 

       RTSP的传输:分为H.264,RTSP库的使用(视频传输,网络编程)。

H.264的编码原理,NAL单元(帧结构,传输过程中主要通过NAL)。

6.1、H.264
6.1.1、H.264编码原理
       图像冗余信息,是被编码压缩的第一要素。相关算法难度很高,用不着会。视频编码的关键点:压缩比,算法复杂度,解码还原度。

       压缩算法中的概念:宏块(MB,macroblock)压缩的最低单位,一个区域相似的像素点组成;片(slice)多个宏块组成一个片,一个或者多个片组成一帧(frame)。帧被分为:I帧,B帧,P帧。

I帧:非参考帧,没有对时间冗余进行优化,前后帧的参考优化。起始帧。

B帧:参考帧,前后帧的都参考。

P帧:参考帧,参考前一帧。

在sample示例代码中设置了不支持B帧。

       H.264 分为 VCL(编码层)和NAL(网络提取层)。网络提取层NAL维护了一个数据NALU(unsignedchar类型的)。

      

H.264有多个版本,会有差异,固本笔记只记录海思平台的H.264为主。

海思平台编码出的H.264码流都是一个序列sequence包含:1个sps+1个pps+1sei+1I帧+多个p帧。

       每一个单元从二进制文件中看,都是以00 00 0001(16进制)为开头,这个64位的数据被称为分割符。注:当帧内部有效数据有00 00 00 01时,H.264规定写为00 00 0300 01。

序列的基本构成:

 

CBR固定码率,清晰度动态变化。

VBR固定清晰度,码率动态变化,VBR内部通过调节Qp值来控制码率变化。

 

码率概念:编码器每秒编出的数据大小;码率设置得高,编码器在压缩时把尽可能多的数据进行压缩,反之,压缩的数据就少。

相对于码率的知识点,易于混淆的是算法复杂度,算法越复杂压缩得到的数据会越少,前面码率提到的数据大小是提供于编码器压缩的数据源大小。

算法复杂度相关的数据是编码器输出后的数据大小。

 

 

本章参考博客:

NALU相关解析:

https://blog.csdn.net/jefry_xdz/article/details/8461343

sps pps的内容:

http://www.cnblogs.com/wainiwann/p/7477794.html

h264中profile和level的含义:

https://blog.csdn.net/xiaojun111111/article/details/52090185

 

 

6.2、使用rtsp库进行传输
       h.264的payload:G726-32
 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39436605/article/details/97373183

智能推荐

【人工智能 Open AI】设计一个SQL Where DSL模型,使用 golang 代码来实现DSL的翻译成SQL。-程序员宅基地

文章浏览阅读2.4w次。设计一个SQL Where DSL模型,使用 golang 代码来实现DSL的翻译成SQL。

旋转变压器编码器软件解算方法与应用_abz解码-程序员宅基地

文章浏览阅读1.9w次,点赞18次,收藏140次。STM32F1单片机实现旋变软件解码1.硬件电路设计1,10khz 正弦信号发生器。要求电流能够达到500mA~1A左右,幅值7.5V。1.可以利用芯片输出10kzh方波,通过一次积分电路得到三角波,通过二次积分得到正弦波。2.可以通过芯片输出两路调制pwm波,再通过滤波器得到差分正弦波。设计2,输出信号调理电路。差分正弦信号,调理到0~3.3V模拟信号,用于连接stm32单片机。一种参考电路设计..._abz解码

一键生成Java调用时序图_sequenceoutline-程序员宅基地

文章浏览阅读233次。日常开发阅读源码时,容易忘记前面的代码,此时,如果有简略的时序图就能很方便理解整个结构。那么一键生成时序图及跳过某个调用就显得很有必要。IDEA插件SequenceOutline提供了一键生成时序图,并提供了转换成PlantUml的能力。_sequenceoutline

m在ISE平台下使用verilog开发基于FPGA的GMSK调制器-程序员宅基地

文章浏览阅读1k次。有好的功率频谱特性,较优的误码性能,特别是带外辐射小,很适用于工作在VHF和UHF频段的移动通信系统,越来越引起人们的关注。原始码元信号首先经过双极性编码,然后对其进行采样,经过插值提高数据采样率,通过高斯低通滤波器对原始信号进行带宽限制处理,然后对限带信号进行MSK基带调制,生成相互正交的I、Q两路基带信号,I、Q两路信号再分别与在载波 、 相乘,最终再通过加法器,使两路信号相加,得到最终的GMSK调制信号,通过DA送到天线部分。对于2FSK调制,有两个频率状态,分别对应符号“1”和“0”。

基于树莓派的AirPlay功能实现-程序员宅基地

文章浏览阅读2w次,点赞5次,收藏30次。手里有一个第一代的树莓派开发板,很长时间都没有使用过。今天尝试着搭建一个支持AirPlay的服务。顺便回顾一下树莓派的烧录、配置、远程登录等操作。

基于yum制作kylin系统docker镜像(CentOS Fedora yum rpm 根文件系统制作 参考)_kylin docker镜像-程序员宅基地

文章浏览阅读608次。安装 : kylin-gpg-keys-1.0-2.4.p15.ky10.aarch64 6/131。安装 : kylin-repos-1.0-2.4.p15.ky10.aarch64 7/131。_kylin docker镜像

随便推点

Android Design Support Library(二)用NavigationView实现抽屉菜单界面_安卓抽屉对界面-程序员宅基地

文章浏览阅读8.3k次,点赞6次,收藏17次。NavigationView在MD设计中非常重要,之前Google也提出了使用DrawerLayout来实现导航抽屉。这次,在Android Design Support Library中,Google提供了NavigationView来实现导航菜单界面。这次我们写的代码在Android用TabLayout实现类似网易选项卡动态滑动效果这篇文章代码的基础上进行修改,所以最好先看看上面这篇文章_安卓抽屉对界面

python如何测接口自动化_python接口自动化测试(一)-程序员宅基地

文章浏览阅读1.4k次。本节开始,开始介绍python的接口自动化测试,首先需要搭建python开发环境,到https://www.python.org/下载python版本直接安装就以了,建议 下载python2.7.11版本,当然,也是可以下载python最新版本的。接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管..._python 接口自动化测试

C语言课程设计物品竞拍管理(成品版!)_用c语言编程 个实时在线拍卖程序-程序员宅基地

文章浏览阅读1.4k次,点赞7次,收藏29次。任务要求设计一个类物品竞拍管理系统,实现的功能有:1.管理端和拍卖者端2.账户的注册登录3.拍卖品的增删改查(查分为通过物品名称、编号、类型查找)4.管理端输出所有已注册账户名称及已录入拍卖物名称5.竞拍系统由于涉及到账户注册登录及拍卖品增删改查,通过数组会更方便查找,但课设要求通过链表写入文件,我的思路便是通过数组及链表存储,数组方便查找。在程序初始化时先通过fgets及fscanf函数从文件中读取数据至数组。不足:每个账户只能录入一件拍卖品,但方便管理;竞拍系统可能._用c语言编程 个实时在线拍卖程序

【openGL教程08】基于C++的着色器(02)_opengl 2 着色器-程序员宅基地

文章浏览阅读1k次,点赞12次,收藏19次。着色器是openGL渲染的重要内容,客户如果想自我实现渲染灵活性,可以用着色器进行编程,这种程序小脚本被传送到GPU的显卡内部,起到动态灵活的着色作用。_opengl 2 着色器

maven 报错 To see the full stack trace of the errors, re-run Maven with the -e switch.Re-run Maven usi-程序员宅基地

文章浏览阅读1.2w次。今天从新安装idea后出现的问题错误信息:D:\dev\Java\jdk1.8\bin\java.exe -Dmaven.multiModuleProjectDirectory=E:\CiHai\test\online_chat\user_serve -Dmaven.home=D:\dev\maven\apache-maven-3.3.9 -Dclassworlds.conf=D:\dev\maven\apache-maven-3.3.9\bin\m2.conf "-Dmaven.ext.class.p_to see the full stack trace of the errors, re-run maven with the -e switch.

Qt 访问服务器上的图片(访问网络图片/网络文件)_qt 怎么接收巴法云上的图片-程序员宅基地

文章浏览阅读2.3k次,点赞2次,收藏15次。Qt 访问服务器上的图片(访问网络图片/网络文件)_qt 怎么接收巴法云上的图片