花屏有很多种情况,大多数情况是由于网络传输丢包导致的,也有可能是解码错误导致的,也有可能是渲染有问题。
这里介绍下网络传输丢包的处理:
1、如果使用的是udp,那么可以尝试修改udp.c中的UDP_MAX_PKT_SIZE大小x10。
注:使用tcp:
AVDictionary *options = NULL;
av_dict_set(&options, "rtsp_transport", "tcp", 0);
2、修改rtpdec.c的源码,捕获丢包,比如当前packet存在丢包,那么将此帧丢掉,直到下一个关键帧,这样就不会因为丢包导致花屏,但会跳秒(卡顿)。
while (1) {
AVPacket pkt;
ret = av_read_frame(f->ctx, &pkt);
if (pkt.nLostPackets) {
// Do something.
} else {
// Do something
}
}
修改细节:
avformat.h中增加int av_read_frame_aozhen(AVFormatContext *s, AVPacket *pkt)函数:
// Add by zxn
int av_read_frame_aozhen(AVFormatContext *s, AVPacket *pkt);
utils.c中实现函数:
// Add by zxn
int av_read_frame_aozhen(AVFormatContext *s, AVPacket *pkt)
{
return av_read_frame(s,pkt);
}
avcodec.h中的AVPacket结构体增加成员变量int nIsLostPackets:
// Add by zxn
// 1 is lost packets, 0 is not lost packets.
int nIsLostPackets;
avpacket.c中的av_init_packets函数中对其初始化:
// Add by zxn
pkt->nIsLostPackets = 0;
utils.c中read_frame_internal函数增加临时变量int nIsLostPackets = 0,read_frame_internal函数调用ff_read_packet的后一句增加nIsLostPackets = cur_pkt.nIsLostPackets:
// Add by zxn
int nIsLostPackets = 0;
// Add by zxn
nIsLostPackets = cur_pkt.nIsLostPackets;
在函数末尾将nIsLostPackets赋值给pkt->nIsLostPackets:
// Add by zxn
if (nIsLostPackets)
{
pkt->nIsLostPackets = nIsLostPackets;
}
rtpdec.c中的rtp_parse_queued_packet函数里面增加丢包判断的代码:
// Add by zxn
int nIsLostPackets = 0;
// Mod by zxn
// Add some code to check lost packets.
#if 0
if (!has_next_packet(s))
av_log(s->ic, AV_LOG_WARNING,
"RTP: missed %d packets\n", s->queue->seq - s->seq - 1);
#else
if (!has_next_packet(s))
{
av_log(s->ic, AV_LOG_WARNING,
"RTP: missed %d packets\n", s->queue->seq - s->seq - 1);
nIsLostPackets = 1; // lost packets
}
#endif
//Add by zxn
if (nIsLostPackets)
{
pkt->nIsLostPackets = nIsLostPackets;
}
网友评论