[vlc-devel] RFC3016 (LATM) streaming

Alex Antropoff alant at transtelecom.md
Tue Mar 14 21:31:56 CET 2006


Hello, I make simple patch to modules/stream_out/rtp.c which adds
'rfc3016' config variable into stream config and 
possibility to stream aac using MP4A-LATM packetizer.
It works, now I can stream tv/radio to our mobiles.
May be it doesn't conforms to vlc coding rules, but works ;-)

PS. Is it possible to change H263-1998 to H263-2000 ?
VLC works with both variants, but korean mobiles wants exactly H263-2000.

-- 
Regards, 
Alex Antropoff
-------------- next part --------------
diff -ru vlc-svn-20060314.orig/modules/stream_out/rtp.c vlc-svn-20060314/modules/stream_out/rtp.c
--- vlc-svn-20060314.orig/modules/stream_out/rtp.c	2006-03-14 21:14:14.000000000 +0200
+++ vlc-svn-20060314/modules/stream_out/rtp.c	2006-03-14 21:24:02.000000000 +0200
@@ -83,6 +83,10 @@
 #define TTL_LONGTEXT N_( \
     "Allows you to specify the Time-To-Live for the output stream." )
 
+#define RFC3016_TEXT N_("RFC3016(LATM)")
+#define RFC3016_LONGTEXT N_( \
+    "Allows you to specify using RFC3016 for MPEG4 audio streaming." )
+
 static int  Open ( vlc_object_t * );
 static void Close( vlc_object_t * );
 
@@ -122,6 +126,9 @@
     add_integer( SOUT_CFG_PREFIX "ttl", 0, NULL, TTL_TEXT,
                  TTL_LONGTEXT, VLC_TRUE );
 
+    add_bool( SOUT_CFG_PREFIX "rfc3016", 0, NULL, RFC3016_TEXT,
+                 RFC3016_LONGTEXT, VLC_TRUE );
+
     set_callbacks( Open, Close );
 vlc_module_end();
 
@@ -130,7 +137,7 @@
  *****************************************************************************/
 static const char *ppsz_sout_options[] = {
     "dst", "name", "port", "port-audio", "port-video", "*sdp", "ttl", "mux",
-    "description", "url","email", NULL
+    "description", "url","email", "rfc3016", NULL
 };
 
 static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );
@@ -188,6 +195,7 @@
     int  i_port_audio;
     int  i_port_video;
     int  i_ttl;
+    vlc_bool_t b_rfc3016;
 
     /* when need to use a private one or when using muxer */
     int i_payload_type;
@@ -375,6 +383,10 @@
     }
     p_sys->i_ttl = val.i_int;
 
+
+    var_Get( p_stream, SOUT_CFG_PREFIX "rfc3016", &val );
+    p_sys->b_rfc3016 = val.b_bool;
+
     p_sys->i_payload_type = 96;
     p_sys->i_es = 0;
     p_sys->es   = NULL;
@@ -884,6 +896,7 @@
 static int rtp_packetize_ac3  ( sout_stream_t *, sout_stream_id_t *, block_t * );
 static int rtp_packetize_split( sout_stream_t *, sout_stream_id_t *, block_t * );
 static int rtp_packetize_mp4a ( sout_stream_t *, sout_stream_id_t *, block_t * );
+static int rtp_packetize_mp4a_latm ( sout_stream_t *, sout_stream_id_t *, block_t * );
 static int rtp_packetize_h263 ( sout_stream_t *, sout_stream_id_t *, block_t * );
 static int rtp_packetize_amr  ( sout_stream_t *, sout_stream_id_t *, block_t * );
 
@@ -1070,10 +1083,12 @@
         }
         case VLC_FOURCC( 'm', 'p', '4', 'a' ):
         {
-            char hexa[2*p_fmt->i_extra +1];
-
             id->i_payload_type = p_sys->i_payload_type++;
             id->i_clock_rate = p_fmt->audio.i_rate;
+
+            if(!p_sys->b_rfc3016){
+            char hexa[2*p_fmt->i_extra +1];
+
             id->psz_rtpmap = malloc( strlen( "mpeg4-generic/" ) + 12 );
             sprintf( id->psz_rtpmap, "mpeg4-generic/%d", p_fmt->audio.i_rate );
             id->pf_packetize = rtp_packetize_mp4a;
@@ -1083,6 +1098,36 @@
                      "streamtype=5; profile-level-id=15; mode=AAC-hbr; "
                      "config=%s; SizeLength=13;IndexLength=3; "
                      "IndexDeltaLength=3; Profile=1;", hexa );
+            } else {
+            char hexa[13];
+            int i;
+            unsigned char config[6];
+            unsigned int aacsrates[15] = {
+                    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
+                            16000, 12000, 11025, 8000, 7350, 0, 0
+                            };
+                for(i=0;i<15;i++){
+                if (p_fmt->audio.i_rate == aacsrates[i]) {
+                        break;
+                   }
+                }
+                
+                config[0]=0x40;
+                config[1]=0;
+                config[2]=0x20|i;
+                config[3]=p_fmt->audio.i_channels<<4;
+                config[4]=0x3f;
+                config[5]=0xc0;
+
+                id->psz_rtpmap = malloc( strlen( "MP4A-LATM/" ) + 14 );
+                sprintf( id->psz_rtpmap, "MP4A-LATM/%d/%d", p_fmt->audio.i_rate, p_fmt->audio.i_channels );
+                id->pf_packetize = rtp_packetize_mp4a_latm;
+                id->psz_fmtp = malloc( 200);
+                sprintf_hexa( hexa, config, 6 );
+                sprintf( id->psz_fmtp,
+                         "profile-level-id=15; object=2; cpresent=0; config=%s", hexa );
+
+            }         
             break;
         }
         case VLC_FOURCC( 's', 'a', 'm', 'r' ):
@@ -2042,6 +2087,58 @@
     return VLC_SUCCESS;
 }
 
+static int rtp_packetize_mp4a_latm( sout_stream_t *p_stream, sout_stream_id_t *id,
+                                block_t *in )
+{
+    int     i_max   = id->i_mtu - 14; /* payload max in one packet */
+    int     latmhdrsize = in->i_buffer/0xff + 1;
+    int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
+
+    uint8_t *p_data = in->p_buffer, *pheader;
+    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;
+
+        if(i!=0)
+            latmhdrsize = 0;
+        out = block_New( p_stream, 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) );
+        
+        
+        if(!i){
+            int tmp = in->i_buffer;
+
+            pheader=out->p_buffer+12;
+            while (tmp > 0xfe){
+                *pheader = 0xff;
+                pheader++;
+                tmp -= 0xff;
+            }
+            *pheader = tmp;
+        }
+
+        memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload );
+
+        out->i_buffer   = 12 + latmhdrsize + 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;
+}
+
 static int rtp_packetize_l16( sout_stream_t *p_stream, sout_stream_id_t *id,
                               block_t *in )
 {


More information about the vlc-devel mailing list