[FFmpeg-trac] #7517(avformat:new): buffer_size not taken into account for RTP

FFmpeg trac at avcodec.org
Thu Oct 25 12:06:14 EEST 2018


#7517: buffer_size not taken into account for RTP
-------------------------------------+-------------------------------------
             Reporter:               |                     Type:  defect
  claus.keuker                       |                 Priority:  normal
               Status:  new          |                  Version:  git-
            Component:  avformat     |  master
             Keywords:  RTP packet   |               Blocked By:
  loss                               |  Reproduced by developer:  0
             Blocking:               |
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
 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);
         }

--
Ticket URL: <https://trac.ffmpeg.org/ticket/7517>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list