您的位置:首页 > 其它

ti8168芯片调整h264编码I帧大小的方法

2017-03-14 17:39 447 查看
在ti81xx系列芯片上,实现硬件h264编码的码流,I帧特别大,而P帧又特别小,这样编码虽说编码效率较高(信息和残差分离的比较好),但是通过网络传输的时候会增加网络的冲击,导致视频丢包,例如,在1080P 60帧的编码中,会出现30万byte的一帧,而普通的帧不过1万byte左右。

可以通过更改DVR RDK的encLink_h264.c的方法,解决这个问题。

文件路径为:

DVRRDK_04.00.00.03/dvr_rdk/mcfw/src_bios6/links_m3video/iva_enc/encLink_h264.c


更改的代码为:

dynamicParams->rateControlParams.maxPicSizeRatioI = 960;


改为300左右,如果出现大的P帧,也可以增加设置,例如

dynamicParams->rateControlParams.maxPicSizeRatioP = 250;


重新编译固件,在

~/DVR_RDK/dvr_rdk


下输入

make -s dvr_rdk_bios6


生成结果在

~/DVR_RDK/dvr_rdk/bin/ti816x/firmware


下面,替换相应的firmware,可以得到平缓的视频byte流,不过这样会增加编码器的性能消耗。

同事给出了通过网络来解决解决I帧过大的问题,如上文所说的,30万byte一帧,60帧每秒,其瞬时带宽占用为1800万byte每秒,即17.17Mbyte/s,即137.33Mbit/s,需要千兆网络作为RTP的发送服务端。

另外,udp的sendto函数,作为非阻塞的函数,不会因为发送丢包而返回失败,所以需要解决sendto丢包的问题,可以通过设置sendto的缓冲区及缓冲队列的长度来解决问题。

需要引入的头文件为:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>


设置缓冲区大小的方法为:

int value = 102400*100;
socklen_t valSize = sizeof(value);
setsockopt(udpfd, SOL_SOCKET, SO_SNDBUFFORCE,(char *)&value, valSize);
value =0;
getsockopt(udpfd, SOL_SOCKET, SO_SNDBUF,(char *)&value, &valSize);
printf("socket size: %d\n",value);


设置队列长度的方法为

struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));
if (-1 == ioctl(udpfd, SIOCGIFTXQLEN, &ifr))
printf( "failed to get dev eth0 queue length\n");
printf( "Dev eth0 queue length:%d\n ", ifr.ifr_qlen);
ifr.ifr_qlen = 1000000;
if (-1 == ioctl(udpfd, SIOCSIFTXQLEN, &ifr))
printf( "failed to set dev eth0 queue length\n");
if (-1 == ioctl(udpfd, SIOCGIFTXQLEN, &ifr))
printf( "failed to get dev eth0 queue length\n");
printf( "Dev eth0 queue length:%d\n ", ifr.ifr_qlen);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: