]> 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 53af124f7ee4d3622b5d734ea6d80bf92a71961d..482db7d4fc4708eb3416ce7b49e18ddc40d94b9c 100644 (file)
 #include "rtp.h"
 
 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, bool b_last, int64_t i_length );
 
-int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id,
+int rtp_packetize_mpa( sout_stream_id_t *id,
                        block_t *in )
 {
     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
@@ -50,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;
@@ -76,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;
@@ -145,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 )|
@@ -156,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 );
 
@@ -179,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;
@@ -192,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 );
@@ -216,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;
@@ -229,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;
@@ -249,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;
@@ -268,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 )
         {
@@ -303,8 +326,7 @@ int rtp_packetize_mp4a_latm( sout_stream_t *p_stream, sout_stream_id_t *id,
     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;
@@ -316,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 );
 
@@ -348,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;
@@ -378,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  )|
@@ -389,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;
@@ -411,7 +429,7 @@ 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, bool b_last, int64_t i_length )
 {
@@ -433,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;
 
@@ -457,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 */
@@ -480,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;
@@ -511,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;
@@ -521,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;
@@ -535,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 */
@@ -560,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;
@@ -586,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;
 
@@ -607,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;
@@ -617,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 
@@ -641,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 )
     {
@@ -671,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 );
 
@@ -683,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 );
+}