美文网首页
FFmpeg丢包花屏处理

FFmpeg丢包花屏处理

作者: Goning | 来源:发表于2018-07-04 11:37 被阅读226次

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

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

    相关文章

      网友评论

          本文标题:FFmpeg丢包花屏处理

          本文链接:https://www.haomeiwen.com/subject/nhfeuftx.html