int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,

                              AVIOContext *avio)

{

    int len, need_keyframe, missing_packets;

    AVIOContext *pb;

    uint8_t *buf;

    int64_t now;

    uint16_t first_missing, missing_mask;



    if (!fd && !avio)

        return -1;



    need_keyframe = s->handler && s->handler->need_keyframe &&

                    s->handler->need_keyframe(s->dynamic_protocol_context);

    missing_packets = find_missing_packets(s, &first_missing, &missing_mask);



    if (!need_keyframe && !missing_packets)

        return 0;



    /* Send new feedback if enough time has elapsed since the last

     * feedback packet. */



    now = av_gettime();

    if (s->last_feedback_time &&

        (now - s->last_feedback_time) < MIN_FEEDBACK_INTERVAL)

        return 0;

    s->last_feedback_time = now;



    if (!fd)

        pb = avio;

    else if (avio_open_dyn_buf(&pb) < 0)

        return -1;



    if (need_keyframe) {

        avio_w8(pb, (RTP_VERSION << 6) | 1); /* PLI */

        avio_w8(pb, RTCP_PSFB);

        avio_wb16(pb, 2); /* length in words - 1 */

        // our own SSRC: we use the server's SSRC + 1 to avoid conflicts

        avio_wb32(pb, s->ssrc + 1);

        avio_wb32(pb, s->ssrc); // server SSRC

    }



    if (missing_packets) {

        avio_w8(pb, (RTP_VERSION << 6) | 1); /* NACK */

        avio_w8(pb, RTCP_RTPFB);

        avio_wb16(pb, 3); /* length in words - 1 */

        avio_wb32(pb, s->ssrc + 1);

        avio_wb32(pb, s->ssrc); // server SSRC



        avio_wb16(pb, first_missing);

        avio_wb16(pb, missing_mask);

    }



    avio_flush(pb);

    if (!fd)

        return 0;

    len = avio_close_dyn_buf(pb, &buf);

    if (len > 0 && buf) {

        ffurl_write(fd, buf, len);

        av_free(buf);

    }

    return 0;

}

int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,

                              AVIOContext *avio)

{

    int len, need_keyframe, missing_packets;

    AVIOContext *pb;

    uint8_t *buf;

    int64_t now;

    uint16_t first_missing, missing_mask;



    if (!fd && !avio)

        return -1;



    need_keyframe = s->handler && s->handler->need_keyframe &&

                    s->handler->need_keyframe(s->dynamic_protocol_context);

    missing_packets = find_missing_packets(s, &first_missing, &missing_mask);



    if (!need_keyframe && !missing_packets)

        return 0;



    





    now = av_gettime();

    if (s->last_feedback_time &&

        (now - s->last_feedback_time) < MIN_FEEDBACK_INTERVAL)

        return 0;

    s->last_feedback_time = now;



    if (!fd)

        pb = avio;

    else if (avio_open_dyn_buf(&pb) < 0)

        return -1;



    if (need_keyframe) {

        avio_w8(pb, (RTP_VERSION << 6) | 1); 

        avio_w8(pb, RTCP_PSFB);

        avio_wb16(pb, 2); 

        

        avio_wb32(pb, s->ssrc + 1);

        avio_wb32(pb, s->ssrc); 

    }



    if (missing_packets) {

        avio_w8(pb, (RTP_VERSION << 6) | 1); 

        avio_w8(pb, RTCP_RTPFB);

        avio_wb16(pb, 3); 

        avio_wb32(pb, s->ssrc + 1);

        avio_wb32(pb, s->ssrc); 



        avio_wb16(pb, first_missing);

        avio_wb16(pb, missing_mask);

    }



    avio_flush(pb);

    if (!fd)

        return 0;

    len = avio_close_dyn_buf(pb, &buf);

    if (len > 0 && buf) {

        ffurl_write(fd, buf, len);

        av_free(buf);

    }

    return 0;

}

    uint16_t first_missing, missing_mask;
int FUNC_0(RTPDemuxContext *VAR_0, URLContext *VAR_1,

                              AVIOContext *VAR_2)

{

    int VAR_3, VAR_4, VAR_5;

    AVIOContext *pb;

    uint8_t *buf;

    int64_t now;

    uint16_t first_missing, missing_mask;



    if (!VAR_1 && !VAR_2)

        return -1;



    VAR_4 = VAR_0->handler && VAR_0->handler->VAR_4 &&

                    VAR_0->handler->VAR_4(VAR_0->dynamic_protocol_context);

    VAR_5 = find_missing_packets(VAR_0, &first_missing, &missing_mask);



    if (!VAR_4 && !VAR_5)

        return 0;



    





    now = av_gettime();

    if (VAR_0->last_feedback_time &&

        (now - VAR_0->last_feedback_time) < MIN_FEEDBACK_INTERVAL)

        return 0;

    VAR_0->last_feedback_time = now;



    if (!VAR_1)

        pb = VAR_2;

    else if (avio_open_dyn_buf(&pb) < 0)

        return -1;



    if (VAR_4) {

        avio_w8(pb, (RTP_VERSION << 6) | 1); 

        avio_w8(pb, RTCP_PSFB);

        avio_wb16(pb, 2); 

        

        avio_wb32(pb, VAR_0->ssrc + 1);

        avio_wb32(pb, VAR_0->ssrc); 

    }



    if (VAR_5) {

        avio_w8(pb, (RTP_VERSION << 6) | 1); 

        avio_w8(pb, RTCP_RTPFB);

        avio_wb16(pb, 3); 

        avio_wb32(pb, VAR_0->ssrc + 1);

        avio_wb32(pb, VAR_0->ssrc); 



        avio_wb16(pb, first_missing);

        avio_wb16(pb, missing_mask);

    }



    avio_flush(pb);

    if (!VAR_1)

        return 0;

    VAR_3 = avio_close_dyn_buf(pb, &buf);

    if (VAR_3 > 0 && buf) {

        ffurl_write(VAR_1, buf, VAR_3);

        av_free(buf);

    }

    return 0;

}

int FUNC_0(RTPDemuxContext *VAR_0, URLContext *VAR_1,
AVIOContext *VAR_2)
{ int VAR_3, VAR_4, VAR_5; AVIOContext *pb; uint8_t *buf; int64_t now; uint16_t first_missing, missing_mask; if (!VAR_1 && !VAR_2)
return -1; VAR_4 = VAR_0->handler && VAR_0->handler->VAR_4 &&
VAR_0->handler->VAR_4(VAR_0->dynamic_protocol_context); VAR_5 = find_missing_packets(VAR_0, &first_missing, &missing_mask); if (!VAR_4 && !VAR_5)
return 0; now = av_gettime(); if (VAR_0->last_feedback_time &&
(now - VAR_0->last_feedback_time) < MIN_FEEDBACK_INTERVAL)
return 0; VAR_0->last_feedback_time = now; if (!VAR_1)
pb = VAR_2; else if (avio_open_dyn_buf(&pb) < 0)
return -1; if (VAR_4) { avio_w8(pb, (RTP_VERSION << 6) | 1); avio_w8(pb, RTCP_PSFB); avio_wb16(pb, 2); avio_wb32(pb, VAR_0->ssrc + 1); avio_wb32(pb, VAR_0->ssrc); } if (VAR_5) { avio_w8(pb, (RTP_VERSION << 6) | 1); avio_w8(pb, RTCP_RTPFB); avio_wb16(pb, 3); avio_wb32(pb, VAR_0->ssrc + 1); avio_wb32(pb, VAR_0->ssrc); avio_wb16(pb, first_missing); avio_wb16(pb, missing_mask); } avio_flush(pb); if (!VAR_1)
return 0; VAR_3 = avio_close_dyn_buf(pb, &buf); if (VAR_3 > 0 && buf) { ffurl_write(VAR_1, buf, VAR_3); av_free(buf); } return 0; }