FFmpeg丢包花屏处理

2018-07-04  本文已影响226人  Goning

花屏有很多种情况,大多数情况是由于网络传输丢包导致的,也有可能是解码错误导致的,也有可能是渲染有问题。

这里介绍下网络传输丢包的处理:
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;
}

参考:https://www.cnblogs.com/highway-9/p/5595101.html

上一篇 下一篇

猜你喜欢

热点阅读