hi3518c + live555 实时传输 客户端显示的时候延时问题初步解决

来源:互联网 发布:动漫周边网店淘宝 编辑:程序博客网 时间:2024/05/23 17:19

题记:在上个月,用hi3518c+live555,实现在局域网中传输视频后,然后延时太大,大概延时域网中720p的画面延时在8s,640*480 在5s,320*240在3s左右,当时没有多去研究,然后直接去根据其他人的帖子写了在客户端播放的android程序。最近,想在放假之前将延时问题解决掉。经过在网上的答疑,现在将可能引起延时问题以及解决的方法做一总结,但是有的方法还没有去试。

可能原因一:编码速度快于live555传输速度

      海思压缩好H.264放在里面,程序去取,但是live555,直接去取,网络发送的速度肯定赶不上他采集压缩的速度,所以这个时候,就要做一个fifo,当一个中间的作用,把海思自带缓冲池里面的数据,实时的取出来放到fifo,里面。比如定义fifo的空间为1024K,这个时候,如果超出1024K就丢掉一些数据,这样保证每次取到的数据都是最新的视频数据,这样看起来延时就稍多了。

这种方法,想之后再去试下,现在贴出,用fifo的测试程序:


//============================================================================// Name        : FIFOTest01.cpp// Author      : frank// Version     :// Copyright   : Your copyright notice// Description : Hello World in C++, Ansi-style//============================================================================//http://blog.chinaunix.net/uid-12045105-id-2963178.html#include <iostream>using namespace std;#define BUFSIZE 2048#define WR 1 //写数据标志#define RD 0 //读数据标志typedef struct FifoType{  unsigned int buffer[BUFSIZE];        /* Circular buffer */  unsigned int w_idx;            /* Index of write */  unsigned int r_idx;         /* Index of read */ }*pFifoType; int fifoctl(pFifoType priv ,int data ,const unsigned char flag) {    int temp = -1;    unsigned int widx = 0;    widx = priv->w_idx;    /* Save the old index before proceeding */    if (flag == WR) //write data        {        /* Save it to buffer */        if (((priv->w_idx + 1)) == priv->r_idx) {            /* Adjust read index since buffer is full */            /* Keep the latest one and drop the oldest one */            priv->r_idx = (priv->r_idx + 1);            cout<< "buffer full\n";        }        priv->buffer[priv->w_idx] = data;        //cout <<"before priv->w_idx= "<< priv->w_idx + 1<< endl;        priv->w_idx = (priv->w_idx + 1);        cout <<"after priv->w_idx= "<< priv->w_idx<< endl;        }    else //read data        {        if ((priv->r_idx == widx))            cout << "buffer empty\n";        else            {            temp= priv->buffer[priv->r_idx];            priv->r_idx = (priv->r_idx + 1);            cout<< "priv->r_idx " << priv->r_idx << endl;            }        }     return temp;    }int  main(){    int i = 0;    int data = 0;    pFifoType priv = new FifoType;    priv->r_idx = 0;    priv->w_idx = 0;    for(i = 0; i < 3; i++)     fifoctl(priv,i,WR);    for(i = 0; i < 4 ; i++)//    {    data = fifoctl(priv,data,RD);    cout << data << endl;    }    delete priv;    priv = NULL;    return 0;}

可能原因二:时间戳问题

这个问题也是在海思群里问的各位同学,说可能l在将数据打包成RTP数据包的时候出现时间戳问题;附上聊天记录

海思-延时-问题同  10:42:51http://bbs.csdn.net/topics/360174753海思-延时-问题同  10:43:00live555 MediaSubsession有个函数:getNormalPlayTime帮你计算了你想要的pts。海思-延时-问题同  10:43:38视频90K的采样率,根据帧率打。海思-延时-问题同  10:44:11好像它这个时间戳,并不是绝对时间,而是相对时间海思-延时-问题同  10:44:20所以可能就会越放越慢海思-延时-问题同  10:44:27延时越大Frank范  10:44:41不是越放越慢。而是一直差不多是一个速度海思-延时-问题同  10:44:40我之前好像就是这样的Frank范  10:45:12难道不是编码的速度快,而传输的速度慢么海思-延时-问题同  10:47:13http://xingyunbaijunwei.blog.163.com/blog/static/765380672012362040605/这个文章不错Frank范  10:50:50好,Frank范  10:51:11你觉得是不是编码速度快,传输速度慢呢Frank范  10:51:22昨天有个人是这样建议我的Frank范  10:51:29让我做个fifo海思-延时-问题同  10:51:29嗯海思-延时-问题同  10:51:39编码不用怀疑,不会慢的海思-延时-问题同  10:52:03我当时是用共享内存Frank范  10:52:12就是编码的数据都放到缓存池中,然后来不及发海思-延时-问题同  10:52:55也不是,应该是时间戳问题,live555存者不发

这是另外一个热心朋友提示我的:

1、看看是不是编码本身造成的

2、时间戳有没有更新

你抓包看,看不同的数据包时间戳是不是打对了

发现epochtime数据包大概70/s,也就是说打包的时间戳是没问题的。

分包的时间戳是不变的

但是如果不同的不包的时间戳都一样,那播放器会等好久才会解一包数据

那么延时会很大

3还有即使查查每次调用到你拷贝数据的那个地方的时间,看看他调用到你拷贝数据哪里的时间每次是多少

4你可以启用一个线程编码,编码后放到队列里面,然后发送时候直接从队列里面取已经编码好的数据。

可能原因三:缓存池问题

这个缓存池问题,是我刚开始知道有延迟的时候就认为是这个问题。但是后来又写了个客户端播放器,然后再去看海思这部分代码的时候就忘了一些,

再加上最近快放假了,学习效率有点地,进度比较慢。最近一周把海思的代码以及当时自己加的live555部分代码又都过了一遍,然后过完之后想先试试缓存池的问题。还真发现问题了。

(1)测试通道1,也就是640*460情况时。发现修改

stVbConf.astCommPool[1].u32BlkSize= ××;

stVbConf.astCommPool[1].u32BlkCnt= ××;

这两个参数,播放器没有反应,修改[2]的参数的时候也没有反应,但是修改[0]的时候就有反应了,我修改:

stVbConf.astCommPool[0].u32BlkSize = u32BlkSize; 
stVbConf.astCommPool[0].u32BlkCnt = 5;//尤其是这个地方

发现再用我的客户端软件再去播放的时候就延时在1s之内,具体没测。难道,海思在MPP系统初始化之前所创建的视频缓存池0 ,1,2 ,视频输入的时候不管分辨率是什么样的都是先在视频缓存池0中取么。估计应该是这样的吧。之前是因为缓存池设置过大包括0,1,2所以播放延时会很大都存储在了缓存池中。

但是为什么用vlc的时候,播放一段时间之后就会卡住呢,只有自己的播放器是可以用的。

(2)测试通道0,720p情况

缓存池设置和上面的相同。可以,但是还是vlc播放不出来,只有自己的播放器可以播放。

(3)测试通道2,320*240的时候

这种情况有点特殊,应该这种低分辨率的需要的缓存小才对,但是测试的结果确是:

必须要设置

stVbConf.astCommPool[0].u32BlkSize= u32BlkSize; //每个缓存块大小768*576*2

stVbConf.astCommPool[0].u32BlkCnt= 8;//8的时候才可以

后面还要继续研究下问题所在,到底是怎么回事,更行ing.


0 0