]> git.sesse.net Git - vlc/blobdiff - modules/stream_out/rtpfmt.c
Use var_Inherit* instead of var_CreateGet*.
[vlc] / modules / stream_out / rtpfmt.c
index 71111bb670137d01d245c73a2701d2d21d48f27b..482db7d4fc4708eb3416ce7b49e18ddc40d94b9c 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * rtp.c: rtp stream output module
+ * rtpfmt.c: RTP payload formats
  *****************************************************************************
  * Copyright (C) 2003-2004 the VideoLAN team
  * Copyright © 2007 Rémi Denis-Courmont
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-#include <vlc/vlc.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
 #include <vlc_sout.h>
 #include <vlc_block.h>
 
 #include "rtp.h"
 
-int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id,
+int
+rtp_packetize_h264_nal( sout_stream_id_t *id,
+                        const uint8_t *p_data, int i_data, int64_t i_pts,
+                        int64_t i_dts, bool b_last, int64_t i_length );
+
+int rtp_packetize_mpa( sout_stream_id_t *id,
                        block_t *in )
 {
     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
@@ -41,16 +50,14 @@ int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id,
     for( i = 0; i < i_count; i++ )
     {
         int           i_payload = __MIN( i_max, i_data );
-        block_t *out = block_New( p_stream, 16 + i_payload );
+        block_t *out = block_Alloc( 16 + i_payload );
 
         /* rtp common header */
         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
         /* mbz set to 0 */
-        out->p_buffer[12] = 0;
-        out->p_buffer[13] = 0;
+        SetWBE( out->p_buffer + 12, 0 );
         /* fragment offset in the current frame */
-        out->p_buffer[14] = ( (i*i_max) >> 8 )&0xff;
-        out->p_buffer[15] = ( (i*i_max)      )&0xff;
+        SetWBE( out->p_buffer + 14, i * i_max );
         memcpy( &out->p_buffer[16], p_data, i_payload );
 
         out->i_buffer   = 16 + i_payload;
@@ -67,8 +74,7 @@ int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id,
 }
 
 /* rfc2250 */
-int rtp_packetize_mpv( sout_stream_t *p_stream, sout_stream_id_t *id,
-                       block_t *in )
+int rtp_packetize_mpv( sout_stream_id_t *id, block_t *in )
 {
     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
@@ -136,8 +142,8 @@ int rtp_packetize_mpv( sout_stream_t *p_stream, sout_stream_id_t *id,
     for( i = 0; i < i_count; i++ )
     {
         int           i_payload = __MIN( i_max, i_data );
-        block_t *out = block_New( p_stream,
-                                             16 + i_payload );
+        block_t *out = block_Alloc( 16 + i_payload );
+        /* MBZ:5 T:1 TR:10 AN:1 N:1 S:1 B:1 E:1 P:3 FBV:1 BFC:3 FFV:1 FFC:3 */
         uint32_t      h = ( i_temporal_ref << 16 )|
                           ( b_sequence_start << 13 )|
                           ( b_start_slice << 12 )|
@@ -147,13 +153,9 @@ int rtp_packetize_mpv( sout_stream_t *p_stream, sout_stream_id_t *id,
 
         /* rtp common header */
         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
-                              in->i_pts > 0 ? in->i_pts : in->i_dts );
+                          in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts );
 
-        /* MBZ:5 T:1 TR:10 AN:1 N:1 S:1 B:1 E:1 P:3 FBV:1 BFC:3 FFV:1 FFC:3 */
-        out->p_buffer[12] = ( h >> 24 )&0xff;
-        out->p_buffer[13] = ( h >> 16 )&0xff;
-        out->p_buffer[14] = ( h >>  8 )&0xff;
-        out->p_buffer[15] = ( h       )&0xff;
+        SetDWBE( out->p_buffer + 12, h );
 
         memcpy( &out->p_buffer[16], p_data, i_payload );
 
@@ -170,8 +172,7 @@ int rtp_packetize_mpv( sout_stream_t *p_stream, sout_stream_id_t *id,
     return VLC_SUCCESS;
 }
 
-int rtp_packetize_ac3( sout_stream_t *p_stream, sout_stream_id_t *id,
-                       block_t *in )
+int rtp_packetize_ac3( sout_stream_id_t *id, block_t *in )
 {
     int     i_max   = rtp_mtu (id) - 2; /* payload max in one packet */
     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
@@ -183,7 +184,7 @@ int rtp_packetize_ac3( sout_stream_t *p_stream, sout_stream_id_t *id,
     for( i = 0; i < i_count; i++ )
     {
         int           i_payload = __MIN( i_max, i_data );
-        block_t *out = block_New( p_stream, 14 + i_payload );
+        block_t *out = block_Alloc( 14 + i_payload );
 
         /* rtp common header */
         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
@@ -207,8 +208,7 @@ int rtp_packetize_ac3( sout_stream_t *p_stream, sout_stream_id_t *id,
     return VLC_SUCCESS;
 }
 
-int rtp_packetize_split( sout_stream_t *p_stream, sout_stream_id_t *id,
-                         block_t *in )
+int rtp_packetize_split( sout_stream_id_t *id, block_t *in )
 {
     int     i_max   = rtp_mtu (id); /* payload max in one packet */
     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
@@ -220,11 +220,11 @@ int rtp_packetize_split( sout_stream_t *p_stream, sout_stream_id_t *id,
     for( i = 0; i < i_count; i++ )
     {
         int           i_payload = __MIN( i_max, i_data );
-        block_t *out = block_New( p_stream, 12 + i_payload );
+        block_t *out = block_Alloc( 12 + i_payload );
 
         /* rtp common header */
         rtp_packetize_common( id, out, (i == i_count - 1),
-                              (in->i_pts > 0 ? in->i_pts : in->i_dts) );
+                      (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
         memcpy( &out->p_buffer[12], p_data, i_payload );
 
         out->i_buffer   = 12 + i_payload;
@@ -240,9 +240,41 @@ int rtp_packetize_split( sout_stream_t *p_stream, sout_stream_id_t *id,
     return VLC_SUCCESS;
 }
 
+/* split and convert from little endian to network byte order */
+int rtp_packetize_swab( sout_stream_id_t *id, block_t *in )
+{
+    int     i_max   = rtp_mtu (id); /* payload max in one packet */
+    int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
+
+    uint8_t *p_data = in->p_buffer;
+    int     i_data  = in->i_buffer;
+    int     i;
+
+    for( i = 0; i < i_count; i++ )
+    {
+        int           i_payload = __MIN( i_max, i_data );
+        block_t *out = block_Alloc( 12 + i_payload );
+
+        /* rtp common header */
+        rtp_packetize_common( id, out, (i == i_count - 1),
+                      (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
+        swab( p_data, out->p_buffer + 12, i_payload );
+
+        out->i_buffer = 12 + i_payload;
+        out->i_dts    = in->i_dts + i * in->i_length / i_count;
+        out->i_length = in->i_length / i_count;
+
+        rtp_packetize_send( id, out );
+
+        p_data += i_payload;
+        i_data -= i_payload;
+    }
+
+    return VLC_SUCCESS;
+}
+
 /* rfc3016 */
-int rtp_packetize_mp4a_latm( sout_stream_t *p_stream, sout_stream_id_t *id,
-                             block_t *in )
+int rtp_packetize_mp4a_latm( sout_stream_id_t *id, block_t *in )
 {
     int     i_max   = rtp_mtu (id) - 2;              /* payload max in one packet */
     int     latmhdrsize = in->i_buffer / 0xff + 1;
@@ -259,11 +291,11 @@ int rtp_packetize_mp4a_latm( sout_stream_t *p_stream, sout_stream_id_t *id,
 
         if( i != 0 )
             latmhdrsize = 0;
-        out = block_New( p_stream, 12 + latmhdrsize + i_payload );
+        out = block_Alloc( 12 + latmhdrsize + i_payload );
 
         /* rtp common header */
         rtp_packetize_common( id, out, ((i == i_count - 1) ? 1 : 0),
-                              (in->i_pts > 0 ? in->i_pts : in->i_dts) );
+                      (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
 
         if( i == 0 )
         {
@@ -294,68 +326,7 @@ int rtp_packetize_mp4a_latm( sout_stream_t *p_stream, sout_stream_id_t *id,
     return VLC_SUCCESS;
 }
 
-int rtp_packetize_l16( sout_stream_t *p_stream, sout_stream_id_t *id,
-                       block_t *in )
-{
-    const uint8_t *p_data = in->p_buffer;
-    size_t i_data  = in->i_buffer;
-    size_t i_plen = 2 * rtp_plen (id, 20);
-
-    for( unsigned i_packet = 0; i_data > 0; i_packet++ )
-    {
-        int           i_payload = __MIN( i_plen, i_data );
-        block_t *out = block_New( p_stream, 12 + i_payload );
-
-        /* rtp common header */
-        rtp_packetize_common( id, out, 0,
-                              (in->i_pts > 0 ? in->i_pts : in->i_dts) );
-        memcpy( &out->p_buffer[12], p_data, i_payload );
-
-        out->i_buffer = 12 + i_payload;
-        out->i_dts    = in->i_dts + i_packet * 20000;
-        out->i_length = i_payload * 20000 / i_plen;
-
-        rtp_packetize_send( id, out );
-
-        p_data += i_payload;
-        i_data -= i_payload;
-    }
-
-    return VLC_SUCCESS;
-}
-
-int rtp_packetize_l8( sout_stream_t *p_stream, sout_stream_id_t *id,
-                      block_t *in )
-{
-    const uint8_t *p_data = in->p_buffer;
-    size_t i_data  = in->i_buffer;
-    size_t i_plen = rtp_plen (id, 20);
-
-    for( unsigned i_packet = 0; i_data > 0; i_packet++ )
-    {
-        int           i_payload = __MIN( i_plen, i_data );
-        block_t *out = block_New( p_stream, 12 + i_payload );
-
-        /* rtp common header */
-        rtp_packetize_common( id, out, 0,
-                              (in->i_pts > 0 ? in->i_pts : in->i_dts) );
-        memcpy( &out->p_buffer[12], p_data, i_payload );
-
-        out->i_buffer = 12 + i_payload;
-        out->i_dts    = in->i_dts + i_packet * 20000;
-        out->i_length = i_payload * 20000 / i_plen;
-
-        rtp_packetize_send( id, out );
-
-        p_data += i_payload;
-        i_data -= i_payload;
-    }
-
-    return VLC_SUCCESS;
-}
-
-int rtp_packetize_mp4a( sout_stream_t *p_stream, sout_stream_id_t *id,
-                        block_t *in )
+int rtp_packetize_mp4a( sout_stream_id_t *id, block_t *in )
 {
     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
@@ -367,18 +338,17 @@ int rtp_packetize_mp4a( sout_stream_t *p_stream, sout_stream_id_t *id,
     for( i = 0; i < i_count; i++ )
     {
         int           i_payload = __MIN( i_max, i_data );
-        block_t *out = block_New( p_stream, 16 + i_payload );
+        block_t *out = block_Alloc( 16 + i_payload );
 
         /* rtp common header */
         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
-                              (in->i_pts > 0 ? in->i_pts : in->i_dts) );
+                      (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
         /* AU headers */
         /* AU headers length (bits) */
         out->p_buffer[12] = 0;
         out->p_buffer[13] = 2*8;
         /* for each AU length 13 bits + idx 3bits, */
-        out->p_buffer[14] = ( in->i_buffer >> 5 )&0xff;
-        out->p_buffer[15] = ( (in->i_buffer&0xff)<<3 )|0;
+        SetWBE( out->p_buffer + 14, (in->i_buffer << 3) | 0 );
 
         memcpy( &out->p_buffer[16], p_data, i_payload );
 
@@ -399,8 +369,7 @@ int rtp_packetize_mp4a( sout_stream_t *p_stream, sout_stream_id_t *id,
 /* rfc2429 */
 #define RTP_H263_HEADER_SIZE (2)  // plen = 0
 #define RTP_H263_PAYLOAD_START (14)  // plen = 0
-int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
-                        block_t *in )
+int rtp_packetize_h263( sout_stream_id_t *id, block_t *in )
 {
     uint8_t *p_data = in->p_buffer;
     int     i_data  = in->i_buffer;
@@ -429,8 +398,7 @@ int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
     for( i = 0; i < i_count; i++ )
     {
         int      i_payload = __MIN( i_max, i_data );
-        block_t *out = block_New( p_stream,
-                                  RTP_H263_PAYLOAD_START + i_payload );
+        block_t *out = block_Alloc( RTP_H263_PAYLOAD_START + i_payload );
         b_p_bit = (i == 0) ? 1 : 0;
         h = ( b_p_bit << 10 )|
             ( b_v_bit << 9  )|
@@ -440,11 +408,10 @@ int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
         /* rtp common header */
         //b_m_bit = 1; // always contains end of frame
         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
-                              in->i_pts > 0 ? in->i_pts : in->i_dts );
+                          in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts );
 
         /* h263 header */
-        out->p_buffer[12] = ( h >>  8 )&0xff;
-        out->p_buffer[13] = ( h       )&0xff;
+        SetWBE( out->p_buffer + 12, h );
         memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );
 
         out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;
@@ -462,9 +429,9 @@ int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
 
 /* rfc3984 */
 int
-rtp_packetize_h264_nal( sout_stream_t *p_stream, sout_stream_id_t *id,
+rtp_packetize_h264_nal( sout_stream_id_t *id,
                         const uint8_t *p_data, int i_data, int64_t i_pts,
-                        int64_t i_dts, vlc_bool_t b_last, int64_t i_length )
+                        int64_t i_dts, bool b_last, int64_t i_length )
 {
     const int i_max = rtp_mtu (id); /* payload max in one packet */
     int i_nal_hdr;
@@ -484,7 +451,7 @@ rtp_packetize_h264_nal( sout_stream_t *p_stream, sout_stream_id_t *id,
     if( i_data <= i_max )
     {
         /* Single NAL unit packet */
-        block_t *out = block_New( p_stream, 12 + i_data );
+        block_t *out = block_Alloc( 12 + i_data );
         out->i_dts    = i_dts;
         out->i_length = i_length;
 
@@ -508,12 +475,13 @@ rtp_packetize_h264_nal( sout_stream_t *p_stream, sout_stream_id_t *id,
         for( i = 0; i < i_count; i++ )
         {
             const int i_payload = __MIN( i_data, i_max-2 );
-            block_t *out = block_New( p_stream, 12 + 2 + i_payload );
+            block_t *out = block_Alloc( 12 + 2 + i_payload );
             out->i_dts    = i_dts + i * i_length / i_count;
             out->i_length = i_length / i_count;
 
             /* */
-            rtp_packetize_common( id, out, (b_last && i_payload == i_data), i_pts );
+            rtp_packetize_common( id, out, (b_last && i_payload == i_data),
+                                    i_pts );
             out->i_buffer = 14 + i_payload;
 
             /* FU indicator */
@@ -531,8 +499,7 @@ rtp_packetize_h264_nal( sout_stream_t *p_stream, sout_stream_id_t *id,
     return VLC_SUCCESS;
 }
 
-int rtp_packetize_h264( sout_stream_t *p_stream, sout_stream_id_t *id,
-                        block_t *in )
+int rtp_packetize_h264( sout_stream_id_t *id, block_t *in )
 {
     const uint8_t *p_buffer = in->p_buffer;
     int i_buffer = in->i_buffer;
@@ -562,9 +529,9 @@ int rtp_packetize_h264( sout_stream_t *p_stream, sout_stream_id_t *id,
             }
         }
         /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
-        rtp_packetize_h264_nal( p_stream, id, p_buffer, i_size,
-                                (in->i_pts > 0 ? in->i_pts : in->i_dts), in->i_dts,
-                                (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );
+        rtp_packetize_h264_nal( id, p_buffer, i_size,
+                (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts), in->i_dts,
+                (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );
 
         i_buffer -= i_skip;
         p_buffer += i_skip;
@@ -572,8 +539,7 @@ int rtp_packetize_h264( sout_stream_t *p_stream, sout_stream_id_t *id,
     return VLC_SUCCESS;
 }
 
-int rtp_packetize_amr( sout_stream_t *p_stream, sout_stream_id_t *id,
-                       block_t *in )
+int rtp_packetize_amr( sout_stream_id_t *id, block_t *in )
 {
     int     i_max   = rtp_mtu (id) - 2; /* payload max in one packet */
     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
@@ -586,11 +552,11 @@ int rtp_packetize_amr( sout_stream_t *p_stream, sout_stream_id_t *id,
     for( i = 0; i < i_count; i++ )
     {
         int           i_payload = __MIN( i_max, i_data );
-        block_t *out = block_New( p_stream, 14 + i_payload );
+        block_t *out = block_Alloc( 14 + i_payload );
 
         /* rtp common header */
         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
-                              (in->i_pts > 0 ? in->i_pts : in->i_dts) );
+                      (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
         /* Payload header */
         out->p_buffer[12] = 0xF0; /* CMR */
         out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */
@@ -611,8 +577,7 @@ int rtp_packetize_amr( sout_stream_t *p_stream, sout_stream_id_t *id,
     return VLC_SUCCESS;
 }
 
-int rtp_packetize_t140( sout_stream_t *p_stream, sout_stream_id_t *id,
-                        block_t *in )
+int rtp_packetize_t140( sout_stream_id_t *id, block_t *in )
 {
     const size_t   i_max  = rtp_mtu (id);
     const uint8_t *p_data = in->p_buffer;
@@ -637,7 +602,7 @@ int rtp_packetize_t140( sout_stream_t *p_stream, sout_stream_id_t *id,
             }
         }
 
-        block_t *out = block_New( p_stream, 12 + i_payload );
+        block_t *out = block_Alloc( 12 + i_payload );
         if( out == NULL )
             return VLC_SUCCESS;
 
@@ -658,8 +623,7 @@ int rtp_packetize_t140( sout_stream_t *p_stream, sout_stream_id_t *id,
 }
 
 
-int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id,
-                       block_t *in )
+int rtp_packetize_spx( sout_stream_id_t *id, block_t *in )
 {
     uint8_t *p_buffer = in->p_buffer;
     int i_data_size, i_payload_size, i_payload_padding;
@@ -668,10 +632,7 @@ int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id,
     block_t *p_out;
 
     if ( in->i_buffer > rtp_mtu (id) )
-    {
-        msg_Warn( p_stream, "Cannot send packet larger than output MTU" );
         return VLC_SUCCESS;
-    }
 
     /*
       RFC for Speex in RTP says that each packet must end on an octet 
@@ -692,7 +653,7 @@ int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id,
       Allocate a new RTP p_output block of the appropriate size. 
       Allow for 12 extra bytes of RTP header. 
     */
-    p_out = block_New( p_stream, 12 + i_payload_size );
+    p_out = block_Alloc( 12 + i_payload_size );
 
     if ( i_payload_padding )
     {
@@ -722,7 +683,8 @@ int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id,
     }
 
     /* Add the RTP header to our p_output buffer. */
-    rtp_packetize_common( id, p_out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) );
+    rtp_packetize_common( id, p_out, 0,
+                        (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
     /* Copy the Speex payload to the p_output buffer */
     memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );
 
@@ -734,3 +696,55 @@ int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id,
     rtp_packetize_send( id, p_out );
     return VLC_SUCCESS;
 }
+
+static int rtp_packetize_g726( sout_stream_id_t *id, block_t *in, int i_pad )
+{
+    int     i_max   = (rtp_mtu( id )- 12 + i_pad - 1) & ~i_pad;
+    int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
+
+    uint8_t *p_data = in->p_buffer;
+    int     i_data  = in->i_buffer;
+    int     i_packet = 0;
+
+    while( i_data > 0 )
+    {
+        int           i_payload = __MIN( i_max, i_data );
+        block_t *out = block_New( p_stream, 12 + i_payload );
+
+        /* rtp common header */
+        rtp_packetize_common( id, out, 0,
+                      (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
+
+        memcpy( &out->p_buffer[12], p_data, i_payload );
+
+        out->i_buffer   = 12 + i_payload;
+        out->i_dts    = in->i_dts + i_packet++ * in->i_length / i_count;
+        out->i_length = in->i_length / i_count;
+
+        rtp_packetize_send( id, out );
+
+        p_data += i_payload;
+        i_data -= i_payload;
+    }
+    return VLC_SUCCESS;
+}
+
+int rtp_packetize_g726_16( sout_stream_id_t *id, block_t *in )
+{
+    return rtp_packetize_g726( id, in, 4 );
+}
+
+int rtp_packetize_g726_24( sout_stream_id_t *id, block_t *in )
+{
+    return rtp_packetize_g726( id, in, 8 );
+}
+
+int rtp_packetize_g726_32( sout_stream_id_t *id, block_t *in )
+{
+    return rtp_packetize_g726( id, in, 2 );
+}
+
+int rtp_packetize_g726_40( sout_stream_id_t *id, block_t *in )
+{
+    return rtp_packetize_g726( id, in, 8 );
+}