live555+ffmpeg+ddraw 实现从设备端获取视频流,解码显示,live555采用tcp传输,但是H264数据当出现丢帧时,会有马赛克现象,所以丢帧必须有一定的策略。
1)内存管理采用内存池,初始化时,建立一个内存池链表;
节点的结构定义如下:
struct buffer_desc {
void *buffer;
unsigned int length;
unsigned int valid_len;
unsigned int frame_flag; //0:表示I帧,1表示P帧
};
2)live555 接收到一帧数据后,找到第一个00 00 00 01 后面的那个字节,通过那个字节判断当前帧是I帧还是P帧,加上一个I帧的还是P帧的标志位,从内存池中取一个Buff,将该帧数据copy到该buff,然后遍历这个Buff ,插入到另外一个包括H264数据的List链表的末尾;
3)解码时从H264 List链表的开头取出一个Buff,调用ffmpeg解码;解码后在将Buff归还给内存池链表;
4)异常情况,当内存池链表中没有Buff可以取时,说明解码和显示模块 很耗时;这个时候怎样确定丢帧策略;
4.1)此时live555收到的是数据是P帧,内存池又没有Buff可以取的事情下,这时,直接丢掉该帧数据;
4.2)如果live555收到的是I帧,那么从缓冲区取第一个不是I帧的Buff,丢掉这个Buff不解码,直接还给内存池,然后在取到该Buff,拷贝当前帧后,插入到H264的List链表;
4.3)如果live555收到的是I帧,且H264 List链表上的帧都是I帧了,这种情况几乎不会出现,但是也要考虑,这个时候,丢掉H264 List链表中的第一个I帧,然后将内存还给内存池,然后在取到该Buff,拷贝当前帧后,插入到H264的List链表;
由于live555 采用的是tcp传输,不可能出现包乱序和丢包的情况;丢帧只是客户端处理不过来造成的,几率是相当的小的,ffmpeg解码一帧1080p的数据,用的时间只有16ms;但是为了程序的鲁棒性,还是要考虑丢帧策略;所以写上以上的简单的策略,大家看看有没有好的丢帧策略,或者live555 udp传输下的丢包,丢帧策略,请给我留言,非常感谢!