基于ijkplayer在FFMpeg 中增加丢包数显示功能
目的: 在我们目前的应用场景中,使用ijkplayer
来进行RTSP 的拉流解码播放。但是我们设备端在传输层中并没有部署RTCP 的控制协议实现,所以无法对数据传输的丢包数进行反向收集,那就需要APP端对数据长度进行校验。
方案:
- 因为我们使用RTSP 数据传输协议,在ijkplayer 中,数据处理完全是交由
FFMpeg
来进行的,对上层和ijkplayer的SDK 层而言,收到数据包是不透明的,所以我们需要对FFMpeg
的源码进行修改。
2.在源码中,RTSP 协议传输对应的数据传输相关方法位于文件夹libavformat/rtsp.c
中,在read_packet
方法中,我们可以看到RTSP协议对应的传输类型判断(UDP or TCP)
#if CONFIG_RTSP_DEMUXER
case RTSP_LOWER_TRANSPORT_TCP:
len = ff_rtsp_tcp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE);
break;
#endif
case RTSP_LOWER_TRANSPORT_UDP:
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
len = udp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, (*rtsp_st)->rtp_handle, NULL, len);
break;
case RTSP_LOWER_TRANSPORT_CUSTOM:
if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP &&
wait_end && wait_end < av_gettime_relative())
len = AVERROR(EAGAIN);
else
len = avio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE);
len = pick_stream(s, rtsp_st, rt->recvbuf, len);
if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, NULL, s->pb, len);
break;
}
而在RTSP 协议上,实时流的传输是通过RTP
协议来完成的,所以我们可以看到其内部调用了ff_rtp_check_and_send_back_rr
用于检查数据和发送回调,跟踪该方法查看其实现。其中lost
参数即代表着丢帧数显示。
- 数据位于FFMpeg层中,需要通过构造对应的方法进行调用。查看libavformat.a 中对应的头文件暴露,发现仅在
avformat.h
中存在对外方法,将对应的方法增加到该文件中,提供给外部调用即可。