[vlc-commits] rtp: improve PCM packetization (fixes #6505) and try zero copy

Rémi Denis-Courmont git at videolan.org
Thu Sep 25 21:31:27 CEST 2014


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Sep 25 21:47:38 2014 +0300| [2db8c89d323a03de8205612a90cf53d2db4a6cc8] | committer: Rémi Denis-Courmont

rtp: improve PCM packetization (fixes #6505) and try zero copy

rtp_packetize_split() sets the marker bit according to video semantics,
and uses incorrect timestamp interpolation for PCM.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2db8c89d323a03de8205612a90cf53d2db4a6cc8
---

 modules/stream_out/rtpfmt.c |   41 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/modules/stream_out/rtpfmt.c b/modules/stream_out/rtpfmt.c
index fb1e43f..acdfe17 100644
--- a/modules/stream_out/rtpfmt.c
+++ b/modules/stream_out/rtpfmt.c
@@ -41,6 +41,7 @@ static int rtp_packetize_mpv  (sout_stream_id_sys_t *, block_t *);
 static int rtp_packetize_ac3  (sout_stream_id_sys_t *, block_t *);
 static int rtp_packetize_simple(sout_stream_id_sys_t *, block_t *);
 static int rtp_packetize_split(sout_stream_id_sys_t *, block_t *);
+static int rtp_packetize_pcm(sout_stream_id_sys_t *, block_t *);
 static int rtp_packetize_swab (sout_stream_id_sys_t *, block_t *);
 static int rtp_packetize_mp4a (sout_stream_id_sys_t *, block_t *);
 static int rtp_packetize_mp4a_latm (sout_stream_id_sys_t *, block_t *);
@@ -197,13 +198,13 @@ int rtp_get_fmt( vlc_object_t *obj, es_format_t *p_fmt, const char *mux,
             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
                 rtp_fmt->payload_type = 0;
             rtp_fmt->ptname = "PCMU";
-            rtp_fmt->pf_packetize = rtp_packetize_split;
+            rtp_fmt->pf_packetize = rtp_packetize_pcm;
             break;
         case VLC_CODEC_ALAW:
             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
                 rtp_fmt->payload_type = 8;
             rtp_fmt->ptname = "PCMA";
-            rtp_fmt->pf_packetize = rtp_packetize_split;
+            rtp_fmt->pf_packetize = rtp_packetize_pcm;
             break;
         case VLC_CODEC_S16B:
         case VLC_CODEC_S16L:
@@ -218,17 +219,17 @@ int rtp_get_fmt( vlc_object_t *obj, es_format_t *p_fmt, const char *mux,
             }
             rtp_fmt->ptname = "L16";
             if( p_fmt->i_codec == VLC_CODEC_S16B )
-                rtp_fmt->pf_packetize = rtp_packetize_split;
+                rtp_fmt->pf_packetize = rtp_packetize_pcm;
             else
                 rtp_fmt->pf_packetize = rtp_packetize_swab;
             break;
         case VLC_CODEC_U8:
             rtp_fmt->ptname = "L8";
-            rtp_fmt->pf_packetize = rtp_packetize_split;
+            rtp_fmt->pf_packetize = rtp_packetize_pcm;
             break;
         case VLC_CODEC_S24B:
             rtp_fmt->ptname = "L24";
-            rtp_fmt->pf_packetize = rtp_packetize_split;
+            rtp_fmt->pf_packetize = rtp_packetize_pcm;
             break;
         case VLC_CODEC_MPGA:
             rtp_fmt->payload_type = 14;
@@ -894,6 +895,36 @@ static int rtp_packetize_split( sout_stream_id_sys_t *id, block_t *in )
     return VLC_SUCCESS;
 }
 
+static int rtp_packetize_pcm(sout_stream_id_sys_t *id, block_t *in)
+{
+    unsigned max = rtp_mtu(id);
+
+    while (in->i_buffer > max)
+    {
+        unsigned duration = (in->i_length * max) / in->i_buffer;
+        bool marker = (in->i_flags & BLOCK_FLAG_DISCONTINUITY) != 0;
+
+        block_t *out = block_Alloc(12 + max);
+        if (unlikely(out == NULL))
+        {
+            block_Release(in);
+            return VLC_ENOMEM;
+        }
+
+        rtp_packetize_common(id, out, marker, in->i_pts);
+        memcpy(out->p_buffer + 12, in->p_buffer, max);
+        rtp_packetize_send(id, out);
+
+        in->p_buffer += max;
+        in->i_buffer -= max;
+        in->i_pts += duration;
+        in->i_length -= duration;
+        in->i_flags &= ~BLOCK_FLAG_DISCONTINUITY;
+    }
+
+    return rtp_packetize_simple(id, in); /* zero copy for the last frame */
+}
+
 /* split and convert from little endian to network byte order */
 static int rtp_packetize_swab( sout_stream_id_sys_t *id, block_t *in )
 {



More information about the vlc-commits mailing list