]> git.sesse.net Git - vlc/commitdiff
rtp: improve PCM packetization (fixes #6505) and try zero copy
authorRémi Denis-Courmont <remi@remlab.net>
Thu, 25 Sep 2014 18:47:38 +0000 (21:47 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Thu, 25 Sep 2014 19:21:57 +0000 (22:21 +0300)
rtp_packetize_split() sets the marker bit according to video semantics,
and uses incorrect timestamp interpolation for PCM.

modules/stream_out/rtpfmt.c

index fb1e43fce5109ba8e24865411f389c9d95866ca3..acdfe1775cc5ea83ca7e78852a58f8f742d7ef73 100644 (file)
@@ -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 )
 {