Opened 3 weeks ago

#7517 new defect

buffer_size not taken into account for RTP

Reported by: claus.keuker Owned by:
Priority: normal Component: avformat
Version: git-master Keywords: RTP packet loss
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Problem:


on a big machine with 48 cores I was trying to receive an mpeg_ts stream which 13 to 14 Mbits/s. I observed packet losses in the kernel (netstat -us - Udp packet receive errors increasing). I knew that the socket receive buffer size SO_RCVBUF had to be increased and I tried it with the RTP option ?buffer_size (which does exactly that for UDP). However, that had no effect.

Looking at the code (below) I found that RTP does not support this option and does also hardcode the underlying udp url options.

Making a quick hack (below) solved the problem for me (i.e. supporting the buffer_size option in rtpproto and hardcoding a fixed one in rtsp.c) but I think this option should

properly be supported for rtp_mpegts and also SDP based RTP (receiving multiple elementary streams through opening an sdp file - either packet type 33 (mpegts) or 96/97 (elementary)

Details


using commit d100dc6c9955af8b7a7a60a37a362a51c819222e from master

When running the following command to provide a stream source

fmpeg -re -i <10 MBits mp4 file> -bsf:v h264_mp4toannexb -vcodec copy -strict -2 -f rtp_mpegts rtp://127.0.0.1:9992/foo

and on the same machine (pls note that the -buffersize options were there to test whether this also influenced SO_RCVBUF)

./ffmpeg -re -bufsize 2000000 -i rtp://127.0.0.1:9992?buffer_size -bufsize 2000000 -bsf:v h264_mp4toannexb -vcodec copy -strict -2 -y foo.mp4 2>&1 | less

#### without my changes I get the a non-expected result result 131072 - which is way too small for my application and leads to packet loss in the kernel

ffmpeg version N-83693-gd100dc6-1~16.04.york0 Copyright (c) 2000-2017 the FFmpeg developers

built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.10) 20160609
configuration: --extra-version='1~16.04.york0' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopus --enable-libpulse --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libwavpack --enable-openal --enable-opengl --enable-libx264 --enable-static --disable-shared --extra-cflags='-fPIC -D_CKE_TEST_LOG_' --extra-ldlibflags=-fPIC
libavutil 55. 47.100 / 55. 47.100
libavcodec 57. 81.100 / 57. 81.100
libavformat 57. 66.102 / 57. 66.102
libavdevice 57. 3.100 / 57. 3.100
libavfilter 6. 74.100 / 6. 74.100
libavresample 3. 2. 0 / 3. 2. 0
libswscale 4. 3.101 / 4. 3.101
libswresample 2. 4.100 / 2. 4.100
libpostproc 54. 2.100 / 54. 2.100

[NULL @ 0x562278dc4f60] non-existing PPS 0 referenced
[h264 @ 0x562278dc4f60] non-existing PPS 0 referenced
[h264 @ 0x562278dc4f60] decode_slice_header error
[h264 @ 0x562278dc4f60] no frame!
[h264 @ 0x562278dc4f60] non-existing PPS 0 referenced

Last message repeated 1 times

[h264 @ 0x562278dc4f60] decode_slice_header error
[h264 @ 0x562278dc4f60] no frame!
[h264 @ 0x562278dc4f60] non-existing PPS 0 referenced

Last message repeated 1 times

[h264 @ 0x562278dc4f60] decode_slice_header error
[h264 @ 0x562278dc4f60] no frame!
[h264 @ 0x562278dc4f60] non-existing PPS 0 referenced

Last message repeated 1 times

[h264 @ 0x562278dc4f60] decode_slice_header error
[h264 @ 0x562278dc4f60] no frame!
cke_test_log:131072
cke_test_log:131072
cke_test_log:131072
cke_test_log:131072
cke_test_log:131072
cke_test_log:131072
cke_test_log:131072
cke_test_log:131072
cke_test_log:131072
cke_test_log:131072

#### with my changes I get the expected result (4000000 being the double as set - as expected by the SO_RCVBUF behavior

ffmpeg version N-83693-gd100dc6-1~16.04.york0 Copyright (c) 2000-2017 the FFmpeg developers

built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.10) 20160609
configuration: --extra-version='1~16.04.york0' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopus --enable-libpulse --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libwavpack --enable-openal --enable-opengl --enable-libx264 --enable-static --disable-shared --extra-cflags='-fPIC -D_CKE_TEST_LOG_ -D_CKE_TEST_' --extra-ldlibflags=-fPIC
libavutil 55. 47.100 / 55. 47.100
libavcodec 57. 81.100 / 57. 81.100
libavformat 57. 66.102 / 57. 66.102
libavdevice 57. 3.100 / 57. 3.100
libavfilter 6. 74.100 / 6. 74.100
libavresample 3. 2. 0 / 3. 2. 0
libswscale 4. 3.101 / 4. 3.101
libswresample 2. 4.100 / 2. 4.100
libpostproc 54. 2.100 / 54. 2.100

[NULL @ 0x55bb7c5c2fc0] non-existing PPS 0 referenced
[h264 @ 0x55bb7c5c2fc0] non-existing PPS 0 referenced
[h264 @ 0x55bb7c5c2fc0] decode_slice_header error
[h264 @ 0x55bb7c5c2fc0] no frame!
[h264 @ 0x55bb7c5c2fc0] non-existing PPS 0 referenced

Last message repeated 1 times

[h264 @ 0x55bb7c5c2fc0] decode_slice_header error
[h264 @ 0x55bb7c5c2fc0] no frame!
[h264 @ 0x55bb7c5c2fc0] non-existing PPS 0 referenced

Last message repeated 1 times

[h264 @ 0x55bb7c5c2fc0] decode_slice_header error
[h264 @ 0x55bb7c5c2fc0] no frame!
[h264 @ 0x55bb7c5c2fc0] non-existing PPS 0 referenced

Last message repeated 1 times

[h264 @ 0x55bb7c5c2fc0] decode_slice_header error
[h264 @ 0x55bb7c5c2fc0] no frame!
cke_test_log:2304
cke_test_log:2304
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000
cke_test_log:40000000

code changes:

rtsp.c:sdp_read_header

ff_url_join(url, sizeof(url), "rtp", NULL,

namebuf, rtsp_st->sdp_port,

#ifdef _CKE_TEST_

"?localport=%d&ttl=%d&connect=%d&write_to_source=%d&buffer_size=20000000",

#else

"?localport=%d&ttl=%d&connect=%d&write_to_source=%d",

#endif

rtsp_st->sdp_port, rtsp_st->sdp_ttl,
rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);

rtpproto.c:rtp_read

for (i = 1; i >= 0; i--) {

if (!(p[i].revents & POLLIN))

continue;

*addr_lens[i] = sizeof(*addrs[i]);
len = recvfrom(p[i].fd, buf, size, 0,

(struct sockaddr *)addrs[i], addr_lens[i]);

#ifdef _CKE_TEST_LOG_

{

int optval;
socklen_t optlen=sizeof(optval);
getsockopt(p[i].fd,SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
printf ("cke_test_log:%d\n",optval);

}

#endif

if (len < 0) {

if (ff_neterrno() == AVERROR(EAGAIN)

ff_neterrno() == AVERROR(EINTR))
continue;

return AVERROR(EIO);

}

rtpproto.c: rtp_open

if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {

s->local_rtpport = strtol(buf, NULL, 10);

}

#ifdef _CKE_TEST_

if (av_find_info_tag(buf, sizeof(buf), "buffer_size", p)) {

s->buffer_size = strtol(buf, NULL, 10);

}

#endif

if (av_find_info_tag(buf, sizeof(buf), "localrtpport", p)) {

s->local_rtpport = strtol(buf, NULL, 10);

}

Change History (0)

Note: See TracTickets for help on using tickets.