//发送端收到接收端发来的rtcp nack命令,需要丢包重传
int32_t yang_rtcpush_on_rtcp_nack(YangRtcContext *context,
YangRtcPushStream *pub, YangRtcpCommon *rtcp) {
//容错处理
if (context == NULL || pub == NULL||rtcp==NULL)
return ERROR_RTC_PUBLISH;
int32_t err = Yang_Ok;
//根据rtcp->nack->mediaSsrc判断是音频包丢失还是视频包丢失,拿到保存发送音视频包的queue
YangPublishNackBuffer *que = NULL;
uint32_t ssrc = rtcp->nack->mediaSsrc;
if (ssrc == pub->audioSsrc) que = pub->audio_queue;
if (ssrc == pub->videoSsrc) que = pub->video_queue;
if (!ssrc) return yang_error_wrap(err, "track response nack ssrc=%u", ssrc);
//将存放发送音视频包的quque传入yang_rtcpush_on_recv_nack中。
if (que && (err = yang_rtcpush_on_recv_nack(context, pub, que,rtcp->nack)) != Yang_Ok) {
return yang_error_wrap(err, "track response nack. ssrc=%u", ssrc);
}
return err;
}
//从发送音视频包的队列中取出对应的包进行发送。
int32_t yang_rtcpush_on_recv_nack(YangRtcContext *context,
YangRtcPushStream *pub, YangPublishNackBuffer *que,
YangRtcpNack *nack) {
if (context == NULL || pub == NULL)
return ERROR_RTC_PUBLISH;
int32_t err = Yang_Ok;
//遍历nack->nacks数组
for (int32_t i = 0; i < nack->vsize; ++i) {
//拿到丢包对应的sequence
uint16_t seq = nack->nacks[i];
//根据sequence从que队列中取出对应的rtp包。
YangSendNackBuffer *pkt = yang_rtcpush_fetch_rtp_packet(context, pub,
que, seq);
if (pkt == NULL) {
continue;
}
yang_trace("\nsendlostsn=%hu,", seq);
//nackCount统计加一
context->stats.sendStats.nackCount++;
//调用yang_send_nackpacket方法发送rtp包的payload.
if ((err = yang_send_nackpacket(context, pkt->payload, pkt->nb))!= Yang_Ok) {
return yang_error_wrap(err, "raw send");
}
}
return err;
}