]> git.sesse.net Git - vlc/commitdiff
rtmp_amf_flv: Try and refactor a bit by reducing overly long
authorJP Dinger <jpd@videolan.org>
Sun, 15 Nov 2009 22:18:01 +0000 (23:18 +0100)
committerJP Dinger <jpd@videolan.org>
Sun, 15 Nov 2009 22:33:38 +0000 (23:33 +0100)
indexed accesses and packing up repetetive free() calls. Also
some cosmetics. Should not add functional changes but should make
it a bit more readable.

modules/access/rtmp/rtmp_amf_flv.c

index 804e0f43befb088bb4e4ae49be1821fc709d52b3..40cdc5aa6792821af1cd522f92ba76ba895102f5 100644 (file)
@@ -228,13 +228,6 @@ const uint8_t FLV_VIDEO_FRAME_TYPE_DISPOSABLE_INTER_FRAME = 0x30;
 /*****************************************************************************
  * static RTMP functions:
  ******************************************************************************/
-static void rtmp_handler_null       ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet );
-static void rtmp_handler_chunk_size ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet );
-static void rtmp_handler_invoke     ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet );
-static void rtmp_handler_audio_data ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet );
-static void rtmp_handler_video_data ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet );
-static void rtmp_handler_notify     ( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet );
-
 static rtmp_packet_t *rtmp_new_packet( rtmp_control_thread_t *p_thread, uint8_t stream_index, uint32_t timestamp, uint8_t content_type, uint32_t src_dst, rtmp_body_t *body );
 static block_t *rtmp_new_block( rtmp_control_thread_t *p_thread, uint8_t *buffer, int32_t length_buffer );
 
@@ -386,6 +379,24 @@ rtmp_handshake_active( vlc_object_t *p_this, int fd )
     return 0;
 }
 
+static int
+write_rtmp( rtmp_control_thread_t *p_thread, uint8_t *buf,
+            rtmp_packet_t *pkt, const char *errmsg )
+{
+    int32_t enclen = pkt->length_encoded;
+    int ret = net_Write( p_thread, p_thread->fd, NULL, buf, enclen );
+    free( pkt->body->body );
+    free( pkt->body );
+    free( pkt );
+    free( buf );
+    if( ret != enclen )
+    {
+        msg_Err( p_thread, errmsg );
+        return 0;
+    }
+    return 1;
+}
+
 int
 rtmp_connect_active( rtmp_control_thread_t *p_thread )
 {
@@ -393,7 +404,6 @@ rtmp_connect_active( rtmp_control_thread_t *p_thread )
     rtmp_body_t *rtmp_body;
     uint8_t *tmp_buffer;
     char *tmp_url;
-    ssize_t i_ret;
 
     /* Build NetConnection.connect call */
     rtmp_body = rtmp_body_new( -1 );
@@ -501,20 +511,9 @@ rtmp_connect_active( rtmp_control_thread_t *p_thread )
     tmp_buffer = rtmp_encode_packet( p_thread, rtmp_packet );
 
     /* Call NetConnection.connect */
-    i_ret = net_Write( p_thread, p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded );
-    if( i_ret != rtmp_packet->length_encoded )
-    {
-        free( rtmp_packet->body->body );
-        free( rtmp_packet->body );
-        free( rtmp_packet );
-        free( tmp_buffer );
-        msg_Err( p_thread, "failed send call NetConnection.connect" );
+    if( !write_rtmp( p_thread, tmp_buffer, rtmp_packet,
+                     "failed send call NetConnection.connect" ) )
         return -1;
-    }
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
-    free( tmp_buffer );
 
     /* Wait for NetConnection.connect result */
     vlc_mutex_lock( &p_thread->lock );
@@ -557,20 +556,10 @@ rtmp_connect_active( rtmp_control_thread_t *p_thread )
     tmp_buffer = rtmp_encode_packet( p_thread, rtmp_packet );
 
     /* Call NetStream.createStream */
-    i_ret = net_Write( p_thread, p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded );
-    if( i_ret != rtmp_packet->length_encoded )
-    {
-        free( rtmp_packet->body->body );
-        free( rtmp_packet->body );
-        free( rtmp_packet );
-        free( tmp_buffer );
-        msg_Err( p_thread, "failed send call NetStream.createStream" );
+    if( !write_rtmp( p_thread, tmp_buffer, rtmp_packet,
+                     "failed send call NetStream.createStream" ) )
         return -1;
-    }
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
-    free( tmp_buffer );
+
 /*TODO: read server stream number*/
     /* Build ping packet */
     rtmp_body = rtmp_body_new( -1 );
@@ -587,20 +576,9 @@ rtmp_connect_active( rtmp_control_thread_t *p_thread )
     tmp_buffer = rtmp_encode_packet( p_thread, rtmp_packet );
 
     /* Send ping packet */
-    i_ret = net_Write( p_thread, p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded );
-    if( i_ret != rtmp_packet->length_encoded )
-    {
-        free( rtmp_packet->body->body );
-        free( rtmp_packet->body );
-        free( rtmp_packet );
-        free( tmp_buffer );
-        msg_Err( p_thread, "failed send ping BUFFER_TIME_CLIENT" );
+    if( !write_rtmp( p_thread, tmp_buffer, rtmp_packet,
+                     "failed send ping BUFFER_TIME_CLIENT" ) )
         return -1;
-    }
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
-    free( tmp_buffer );
 
     /* Build NetStream.play call */
     rtmp_body = rtmp_body_new( -1 );
@@ -632,20 +610,10 @@ rtmp_connect_active( rtmp_control_thread_t *p_thread )
     tmp_buffer = rtmp_encode_packet( p_thread, rtmp_packet );
 
     /* Call NetStream.play */
-    i_ret = net_Write( p_thread, p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded );
-    if( i_ret != rtmp_packet->length_encoded )
-    {
-        free( rtmp_packet->body->body );
-        free( rtmp_packet->body );
-        free( rtmp_packet );
-        free( tmp_buffer );
-        msg_Err( p_thread, "failed send call NetStream.play" );
+    if( !write_rtmp( p_thread, tmp_buffer, rtmp_packet,
+                     "failed send call NetStream.play" ) )
         return -1;
-    }
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
-    free( tmp_buffer );
+
 
     /* Build ping packet */
     rtmp_body = rtmp_body_new( -1 );
@@ -662,20 +630,9 @@ rtmp_connect_active( rtmp_control_thread_t *p_thread )
     tmp_buffer = rtmp_encode_packet( p_thread, rtmp_packet );
 
     /* Send ping packet */
-    i_ret = net_Write( p_thread, p_thread->fd, NULL, tmp_buffer, rtmp_packet->length_encoded );
-    if( i_ret != rtmp_packet->length_encoded )
-    {
-        free( rtmp_packet->body->body );
-        free( rtmp_packet->body );
-        free( rtmp_packet );
-        free( tmp_buffer );
-        msg_Err( p_thread, "failed send ping BUFFER_TIME_CLIENT" );
+    if( !write_rtmp( p_thread, tmp_buffer, rtmp_packet,
+                     "failed send ping BUFFER_TIME_CLIENT" ) )
         return -1;
-    }
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
-    free( tmp_buffer );
 
     /* Wait for NetStream.play.start result */
     vlc_cond_wait( &p_thread->wait, &p_thread->lock );
@@ -712,6 +669,14 @@ rtmp_connect_passive( rtmp_control_thread_t *p_thread )
     return 0;
 }
 
+static void
+rtmp_packet_free( rtmp_packet_t *pkt )
+{
+    free( pkt->body->body );
+    free( pkt->body );
+    free( pkt );
+}
+
 /* TODO
 int
 rtmp_seek( access_t *p_access, int64_t i_pos )
@@ -754,26 +719,13 @@ msg_Warn(p_access, "i_pos %lld", i_pos);
     tmp_buffer = rtmp_encode_packet( p_access, rtmp_packet ); 
 
     // Call NetStream.seek //
-    i_ret = net_Write( p_access, p_sys->fd, NULL, tmp_buffer, rtmp_packet->length_encoded );
-    if( i_ret < rtmp_packet->length_encoded )
-    {
-        free( rtmp_packet->body->body );
-        free( rtmp_packet->body );
-        free( rtmp_packet );
-        free( tmp_buffer );
-        msg_Err( p_access, "failed call NetStream.seek" );
+    if( !write_rtmp( p_thread, tmp_buffer, rtmp_packet,
+                     "failed call NetStream.seek" ) )
         return -1;
-    }
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
-    free( tmp_buffer );
 
     // Receive TODO: see what //
     rtmp_packet = rtmp_read_net_packet( p_access, p_sys->fd );
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
+    rtmp_packet_free( rtmp_packet );
 
     return 0;
 }
@@ -933,28 +885,28 @@ rtmp_read_net_packet( rtmp_control_thread_t *p_thread )
     int stream_index;
     int bytes_left;
     uint8_t p_read[12];
-    rtmp_packet_t *rtmp_packet;
+    rtmp_packet_t *header;
     ssize_t i_ret;
 
-
     for(;;)
     {
         i_ret = net_Read( p_thread, p_thread->fd, NULL, p_read, 1, true );
         if( i_ret != 1 )
             goto error;
 
-        length_header = rtmp_decode_header_size( (vlc_object_t *) p_thread, p_read[0] & RTMP_HEADER_SIZE_MASK );
+        length_header = rtmp_decode_header_size( (vlc_object_t *) p_thread,
+                                          p_read[0] & RTMP_HEADER_SIZE_MASK );
         stream_index = p_read[0] & RTMP_HEADER_STREAM_INDEX_MASK;
+        header = p_thread->rtmp_headers_recv+stream_index;
 
         i_ret = net_Read( p_thread, p_thread->fd, NULL, p_read + 1, length_header - 1, true );
         if( i_ret != length_header - 1 )
             goto error;
 
         /* Update timestamp if not is an interchunk packet */
-        if( length_header == 1 && p_thread->rtmp_headers_recv[stream_index].body == NULL )
+        if( length_header == 1 && header->body == NULL )
         {
-            p_thread->rtmp_headers_recv[stream_index].timestamp +=
-                p_thread->rtmp_headers_recv[stream_index].timestamp_relative;
+            header->timestamp += header->timestamp_relative;
         }
 
         /* Length 4 and 8 headers have relative timestamp */
@@ -962,17 +914,16 @@ rtmp_read_net_packet( rtmp_control_thread_t *p_thread )
         {
             p_read[0] = 0;
 
-            p_thread->rtmp_headers_recv[stream_index].timestamp_relative = ntoh32( *(uint32_t *) p_read );
-            p_thread->rtmp_headers_recv[stream_index].timestamp +=
-                p_thread->rtmp_headers_recv[stream_index].timestamp_relative;
+            header->timestamp_relative = ntoh32( *(uint32_t *) p_read );
+            header->timestamp += header->timestamp_relative;
         }
 
         if( length_header >= 8 )
         {
             p_read[3] = 0;
 
-            p_thread->rtmp_headers_recv[stream_index].length_body = ntoh32( *(uint32_t *) (p_read + 3) );
-            p_thread->rtmp_headers_recv[stream_index].content_type = p_read[7];
+            header->length_body = ntoh32( *(uint32_t *) (p_read + 3) );
+            header->content_type = p_read[7];
         }
 
         /* Length 12 headers have absolute timestamp */
@@ -980,47 +931,44 @@ rtmp_read_net_packet( rtmp_control_thread_t *p_thread )
         {
             p_read[0] = 0;
 
-            p_thread->rtmp_headers_recv[stream_index].timestamp = ntoh32( *(uint32_t *) p_read );
-            p_thread->rtmp_headers_recv[stream_index].src_dst = ntoh32( *(uint32_t *) (p_read + 8) );
+            header->timestamp = ntoh32( *(uint32_t *) p_read );
+            header->src_dst = ntoh32( *(uint32_t *) (p_read + 8) );
         }
 
-        if( p_thread->rtmp_headers_recv[stream_index].body == NULL )
+        if( header->body == NULL )
         {
-            p_thread->rtmp_headers_recv[stream_index].body =
-                rtmp_body_new( p_thread->rtmp_headers_recv[stream_index].length_body );
+            header->body = rtmp_body_new( header->length_body );
         }
 
-        bytes_left = p_thread->rtmp_headers_recv[stream_index].body->length_buffer -
-            p_thread->rtmp_headers_recv[stream_index].body->length_body;
+        bytes_left = header->body->length_buffer - header->body->length_body;
 
         if( bytes_left > p_thread->chunk_size_recv )
             bytes_left = p_thread->chunk_size_recv;
 
         i_ret = net_Read( p_thread, p_thread->fd, NULL,
-            p_thread->rtmp_headers_recv[stream_index].body->body +
-            p_thread->rtmp_headers_recv[stream_index].body->length_body,
-            bytes_left, true );
+            header->body->body + header->body->length_body, bytes_left, true );
+
         if( i_ret != bytes_left )
             goto error;
 
-        p_thread->rtmp_headers_recv[stream_index].body->length_body += bytes_left;
+        header->body->length_body += bytes_left;
 
-        if( p_thread->rtmp_headers_recv[stream_index].length_body == p_thread->rtmp_headers_recv[stream_index].body->length_body )
+        if( header->length_body == header->body->length_body )
         {
-            rtmp_packet = (rtmp_packet_t *) malloc( sizeof( rtmp_packet_t ) );
-            if( !rtmp_packet ) goto error;
+            rtmp_packet_t *rpkt = (rtmp_packet_t*)malloc(sizeof(rtmp_packet_t));
+            if( !rpkt ) goto error;
 
-            rtmp_packet->stream_index = stream_index;
-            rtmp_packet->timestamp = p_thread->rtmp_headers_recv[stream_index].timestamp;
-            rtmp_packet->timestamp_relative = p_thread->rtmp_headers_recv[stream_index].timestamp_relative;
-            rtmp_packet->content_type = p_thread->rtmp_headers_recv[stream_index].content_type;
-            rtmp_packet->src_dst = p_thread->rtmp_headers_recv[stream_index].src_dst;
-            rtmp_packet->length_body = p_thread->rtmp_headers_recv[stream_index].length_body;
-            rtmp_packet->body = p_thread->rtmp_headers_recv[stream_index].body;
+            rpkt->stream_index       = stream_index;
+            rpkt->timestamp          = header->timestamp;
+            rpkt->timestamp_relative = header->timestamp_relative;
+            rpkt->content_type       = header->content_type;
+            rpkt->src_dst            = header->src_dst;
+            rpkt->length_body        = header->length_body;
+            rpkt->body               = header->body;
 
-            p_thread->rtmp_headers_recv[stream_index].body = NULL;
+            header->body = NULL;
 
-            return rtmp_packet;
+            return rpkt;
         }
     }
 
@@ -1029,44 +977,21 @@ error:
     return NULL;
 }
 
-void
-rtmp_init_handler( rtmp_handler_t *rtmp_handler )
-{
-    rtmp_handler[RTMP_CONTENT_TYPE_CHUNK_SIZE] = rtmp_handler_chunk_size;
-    rtmp_handler[RTMP_CONTENT_TYPE_UNKNOWN_02] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_BYTES_READ] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_PING] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_SERVER_BW] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_CLIENT_BW] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_UNKNOWN_07] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_AUDIO_DATA] = rtmp_handler_audio_data;
-    rtmp_handler[RTMP_CONTENT_TYPE_VIDEO_DATA] = rtmp_handler_video_data;
-    rtmp_handler[RTMP_CONTENT_TYPE_UNKNOWN_0A_0E] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_FLEX_STREAM] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_FLEX_SHARED_OBJECT] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_MESSAGE] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_NOTIFY] = rtmp_handler_notify;
-    rtmp_handler[RTMP_CONTENT_TYPE_SHARED_OBJECT] = rtmp_handler_null;
-    rtmp_handler[RTMP_CONTENT_TYPE_INVOKE] = rtmp_handler_invoke;
-}
 
 static void
 rtmp_handler_null( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet )
 {
     VLC_UNUSED(p_thread);
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
+    rtmp_packet_free( rtmp_packet );
 }
 
 static void
-rtmp_handler_chunk_size( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet )
+rtmp_handler_chunk_size( rtmp_control_thread_t *p_thread,
+                         rtmp_packet_t *rtmp_packet )
 {
-    p_thread->chunk_size_recv = ntoh32( *(uint32_t *) (rtmp_packet->body->body) );
-
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
+    p_thread->chunk_size_recv =
+                            ntoh32( *(uint32_t *) (rtmp_packet->body->body) );
+    rtmp_packet_free( rtmp_packet );
 }
 
 static void
@@ -1087,9 +1012,7 @@ rtmp_handler_audio_data( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_pa
     p_buffer = rtmp_new_block( p_thread, rtmp_packet->body->body, rtmp_packet->body->length_body );
     block_FifoPut( p_thread->p_fifo_input, p_buffer );
 
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
+    rtmp_packet_free( rtmp_packet );
 }
 
 static void
@@ -1109,9 +1032,7 @@ rtmp_handler_video_data( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_pa
     p_buffer = rtmp_new_block( p_thread, rtmp_packet->body->body, rtmp_packet->body->length_body );
     block_FifoPut( p_thread->p_fifo_input, p_buffer );
 
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
+    rtmp_packet_free( rtmp_packet );
 }
 
 static void
@@ -1125,9 +1046,7 @@ rtmp_handler_notify( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
     p_buffer = rtmp_new_block( p_thread, rtmp_packet->body->body, rtmp_packet->body->length_body );
     block_FifoPut( p_thread->p_fifo_input, p_buffer );
 
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
+    rtmp_packet_free( rtmp_packet );
 }
 
 static void
@@ -1163,9 +1082,7 @@ rtmp_handler_invoke( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
             msg_Err( p_thread, "failed send connection bandwith" );
             goto error;
         }
-        free( tmp_rtmp_packet->body->body );
-        free( tmp_rtmp_packet->body );
-        free( tmp_rtmp_packet );
+        rtmp_packet_free( rtmp_packet );
         free( tmp_buffer );
 
         /* Server bandwith */
@@ -1179,9 +1096,7 @@ rtmp_handler_invoke( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
             msg_Err( p_thread, "failed send server bandwith" );
             goto error;
         }
-        free( tmp_rtmp_packet->body->body );
-        free( tmp_rtmp_packet->body );
-        free( tmp_rtmp_packet );
+        rtmp_packet_free( rtmp_packet );
         free( tmp_buffer );
 
         /* Clear stream */
@@ -1195,9 +1110,7 @@ rtmp_handler_invoke( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
             msg_Err( p_thread, "failed send clear stream" );
             goto error;
         }
-        free( tmp_rtmp_packet->body->body );
-        free( tmp_rtmp_packet->body );
-        free( tmp_rtmp_packet );
+        rtmp_packet_free( rtmp_packet );
         free( tmp_buffer );
 
         /* Reply NetConnection.connect */
@@ -1211,9 +1124,7 @@ rtmp_handler_invoke( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
             msg_Err( p_thread, "failed send reply NetConnection.connect" );
             goto error;
         }
-        free( tmp_rtmp_packet->body->body );
-        free( tmp_rtmp_packet->body );
-        free( tmp_rtmp_packet );
+        rtmp_packet_free( rtmp_packet );
         free( tmp_buffer );
     }
     else if( strcmp( "createStream", string ) == 0 )
@@ -1232,9 +1143,7 @@ rtmp_handler_invoke( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
             msg_Err( p_thread, "failed send reply createStream" );
             goto error;
         }
-        free( tmp_rtmp_packet->body->body );
-        free( tmp_rtmp_packet->body );
-        free( tmp_rtmp_packet );
+        rtmp_packet_free( rtmp_packet );
         free( tmp_buffer );
 
         /* Reset stream */
@@ -1248,9 +1157,7 @@ rtmp_handler_invoke( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
             msg_Err( p_thread, "failed send reset stream" );
             goto error;
         }
-        free( tmp_rtmp_packet->body->body );
-        free( tmp_rtmp_packet->body );
-        free( tmp_rtmp_packet );
+        rtmp_packet_free( rtmp_packet );
         free( tmp_buffer );
 
         /* Clear stream */
@@ -1264,9 +1171,7 @@ rtmp_handler_invoke( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
             msg_Err( p_thread, "failed send clear stream" );
             goto error;
         }
-        free( tmp_rtmp_packet->body->body );
-        free( tmp_rtmp_packet->body );
-        free( tmp_rtmp_packet );
+        rtmp_packet_free( rtmp_packet );
         free( tmp_buffer );
     }
     else if( strcmp( "publish", string ) == 0 )
@@ -1302,9 +1207,7 @@ rtmp_handler_invoke( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
             msg_Err( p_thread, "failed send reply NetStream.play.reset" );
             goto error;
         }
-        free( tmp_rtmp_packet->body->body );
-        free( tmp_rtmp_packet->body );
-        free( tmp_rtmp_packet );
+        rtmp_packet_free( rtmp_packet );
         free( tmp_buffer );
 
         /* Reply NetStream.play.start */
@@ -1318,9 +1221,7 @@ rtmp_handler_invoke( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
             msg_Err( p_thread, "failed send reply NetStream.play.start" );
             goto error;
         }
-        free( tmp_rtmp_packet->body->body );
-        free( tmp_rtmp_packet->body );
-        free( tmp_rtmp_packet );
+        rtmp_packet_free( rtmp_packet );
         free( tmp_buffer );
 
         free( string2 );
@@ -1445,27 +1346,25 @@ rtmp_handler_invoke( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet
         }
     }
     
-    free( rtmp_packet->body->body );
-    free( rtmp_packet->body );
-    free( rtmp_packet );
-
+    rtmp_packet_free( rtmp_packet );
     return;
 
 error:
     free( string );
-    free( tmp_rtmp_packet->body->body );
-    free( tmp_rtmp_packet->body );
-    free( tmp_rtmp_packet );
+    rtmp_packet_free( rtmp_packet );
     free( tmp_buffer );
 }
 
 /* length header calculated automatically based on last packet in the same channel */
 /* timestamps passed are always absolute */
 static rtmp_packet_t *
-rtmp_new_packet( rtmp_control_thread_t *p_thread, uint8_t stream_index, uint32_t timestamp, uint8_t content_type, uint32_t src_dst, rtmp_body_t *body )
+rtmp_new_packet( rtmp_control_thread_t *p_thread, uint8_t stream_index,
+                 uint32_t timestamp, uint8_t content_type,
+                 uint32_t src_dst, rtmp_body_t *body )
 {
     int interchunk_headers;
     rtmp_packet_t *rtmp_packet;
+    rtmp_packet_t *rtmp_send = p_thread->rtmp_headers_send+stream_index;
 
     rtmp_packet = (rtmp_packet_t *) malloc( sizeof( rtmp_packet_t ) );
     if( !rtmp_packet ) return NULL;
@@ -1474,31 +1373,31 @@ rtmp_new_packet( rtmp_control_thread_t *p_thread, uint8_t stream_index, uint32_t
     if( body->length_body % p_thread->chunk_size_send == 0 )
         interchunk_headers--;
 
-    if( src_dst != p_thread->rtmp_headers_send[stream_index].src_dst )
+    if( src_dst != rtmp_send->src_dst )
     {
-        p_thread->rtmp_headers_send[stream_index].timestamp = timestamp;
-        p_thread->rtmp_headers_send[stream_index].length_body = body->length_body;
-        p_thread->rtmp_headers_send[stream_index].content_type = content_type;
-        p_thread->rtmp_headers_send[stream_index].src_dst = src_dst;
+        rtmp_send->timestamp = timestamp;
+        rtmp_send->length_body = body->length_body;
+        rtmp_send->content_type = content_type;
+        rtmp_send->src_dst = src_dst;
         
         rtmp_packet->length_header = 12;
     }
-    else if( content_type != p_thread->rtmp_headers_send[stream_index].content_type
-        || body->length_body != p_thread->rtmp_headers_send[stream_index].length_body )
+    else if( content_type != rtmp_send->content_type
+        || body->length_body != rtmp_send->length_body )
     {
-        p_thread->rtmp_headers_send[stream_index].timestamp_relative = 
-            timestamp - p_thread->rtmp_headers_send[stream_index].timestamp;
-        p_thread->rtmp_headers_send[stream_index].timestamp = timestamp;
-        p_thread->rtmp_headers_send[stream_index].length_body = body->length_body;
-        p_thread->rtmp_headers_send[stream_index].content_type = content_type;
+        rtmp_send->timestamp_relative =
+            timestamp - rtmp_send->timestamp;
+        rtmp_send->timestamp = timestamp;
+        rtmp_send->length_body = body->length_body;
+        rtmp_send->content_type = content_type;
 
         rtmp_packet->length_header = 8;
     }
-    else if( timestamp != p_thread->rtmp_headers_send[stream_index].timestamp )
+    else if( timestamp != rtmp_send->timestamp )
     {
-        p_thread->rtmp_headers_send[stream_index].timestamp_relative = 
-            timestamp - p_thread->rtmp_headers_send[stream_index].timestamp;
-        p_thread->rtmp_headers_send[stream_index].timestamp = timestamp;
+        rtmp_send->timestamp_relative =
+            timestamp - rtmp_send->timestamp;
+        rtmp_send->timestamp = timestamp;
 
         rtmp_packet->length_header = 4;
     }
@@ -1516,9 +1415,11 @@ rtmp_new_packet( rtmp_control_thread_t *p_thread, uint8_t stream_index, uint32_t
     else
     {
         rtmp_packet->timestamp = timestamp;
-        rtmp_packet->timestamp_relative = p_thread->rtmp_headers_send[stream_index].timestamp_relative;
+        rtmp_packet->timestamp_relative = rtmp_send->timestamp_relative;
     }
-    rtmp_packet->length_encoded = rtmp_packet->length_header + body->length_body + interchunk_headers;
+
+    rtmp_packet->length_encoded = rtmp_packet->length_header
+                                + body->length_body + interchunk_headers;
     rtmp_packet->length_body = body->length_body;
     rtmp_packet->content_type = content_type;
     rtmp_packet->src_dst = src_dst;
@@ -1572,8 +1473,10 @@ rtmp_new_block( rtmp_control_thread_t *p_thread, uint8_t *buffer, int32_t length
     return p_buffer;
 }
 
-/* call sequence for each packet rtmp_new_packet -> rtmp_encode_packet -> send */
-/* no parallelism allowed because of optimization in header length */
+/* Call sequence for each packet:
+ * rtmp_new_packet -> rtmp_encode_packet -> send .
+ * No parallelism allowed because of optimization in header length. */
+
 uint8_t *
 rtmp_encode_packet( rtmp_control_thread_t *p_thread, rtmp_packet_t *rtmp_packet )
 {
@@ -1670,7 +1573,7 @@ rtmp_encode_server_bw( rtmp_control_thread_t *p_thread, uint32_t number )
     rtmp_body_append( rtmp_body, (uint8_t *) &number, sizeof( uint32_t ) );
 
     rtmp_packet = rtmp_new_packet( p_thread, RTMP_DEFAULT_STREAM_INDEX_CONTROL,
-        0, RTMP_CONTENT_TYPE_SERVER_BW, RTMP_SRC_DST_CONNECT_OBJECT, rtmp_body );
+      0, RTMP_CONTENT_TYPE_SERVER_BW, RTMP_SRC_DST_CONNECT_OBJECT, rtmp_body );
     free( rtmp_body->body );
     free( rtmp_body );
 
@@ -2068,7 +1971,7 @@ rtmp_body_reset( rtmp_body_t *rtmp_body )
 static void
 rtmp_body_append( rtmp_body_t *rtmp_body, uint8_t *buffer, uint32_t length )
 {
-    if( rtmp_body->length_body + length > rtmp_body->length_buffer )
+    if( (rtmp_body->length_body + length) > rtmp_body->length_buffer )
     {
         uint8_t *tmp;
         rtmp_body->length_buffer = rtmp_body->length_body + length;
@@ -2506,7 +2409,8 @@ flv_build_onMetaData( access_t *p_access, uint64_t duration, uint8_t stereo, uin
     rtmp_body_append( rtmp_body, tmp_buffer, AMF_DATATYPE_SIZE_END_OF_OBJECT );
     free( tmp_buffer );
 
-    rtmp_packet = rtmp_new_packet( p_access->p_sys->p_thread, RTMP_DEFAULT_STREAM_INDEX_INVOKE,
+    rtmp_packet = rtmp_new_packet( p_access->p_sys->p_thread,
+        RTMP_DEFAULT_STREAM_INDEX_INVOKE,
         0, RTMP_CONTENT_TYPE_NOTIFY, 0, rtmp_body );
     free( rtmp_body->body );
     free( rtmp_body );
@@ -2517,21 +2421,22 @@ flv_build_onMetaData( access_t *p_access, uint64_t duration, uint8_t stereo, uin
 block_t *
 flv_get_metadata( access_t *p_access )
 {
-    access_sys_t *p_sys = p_access->p_sys;
-    rtmp_packet_t *flv_metadata_packet;
-    block_t *p_buffer;
-
-    flv_metadata_packet = flv_build_onMetaData( p_access, 0, p_sys->p_thread->metadata_stereo,
-        p_sys->p_thread->metadata_samplesize, p_sys->p_thread->metadata_samplerate,
-        p_sys->p_thread->metadata_audiocodecid, p_sys->p_thread->metadata_videocodecid );
-    flv_rebuild( p_sys->p_thread, flv_metadata_packet );
-    p_buffer = rtmp_new_block( p_sys->p_thread, flv_metadata_packet->body->body, flv_metadata_packet->body->length_buffer );
-
-    free( flv_metadata_packet->body->body );
-    free( flv_metadata_packet->body );
-    free( flv_metadata_packet );
-
-    return p_buffer;
+    rtmp_control_thread_t *p_thread=p_access->p_sys->p_thread;
+    block_t *p_buf;
+
+    rtmp_packet_t *p_md = flv_build_onMetaData( p_access, 0,
+        p_thread->metadata_stereo,
+        p_thread->metadata_samplesize,
+        p_thread->metadata_samplerate,
+        p_thread->metadata_audiocodecid,
+        p_thread->metadata_videocodecid );
+
+    flv_rebuild( p_thread, p_md );
+    p_buf = rtmp_new_block( p_thread,
+                            p_md->body->body, p_md->body->length_buffer );
+
+    rtmp_packet_free( p_md );
+    return p_buf;
 }
 
 block_t *
@@ -2561,3 +2466,24 @@ flv_insert_header( access_t *p_access, block_t *first_packet )
 
     return first_packet;
 }
+
+void
+rtmp_init_handler( rtmp_handler_t *rtmp_handler )
+{
+    rtmp_handler[RTMP_CONTENT_TYPE_CHUNK_SIZE] = rtmp_handler_chunk_size;
+    rtmp_handler[RTMP_CONTENT_TYPE_UNKNOWN_02] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_BYTES_READ] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_PING] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_SERVER_BW] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_CLIENT_BW] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_UNKNOWN_07] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_AUDIO_DATA] = rtmp_handler_audio_data;
+    rtmp_handler[RTMP_CONTENT_TYPE_VIDEO_DATA] = rtmp_handler_video_data;
+    rtmp_handler[RTMP_CONTENT_TYPE_UNKNOWN_0A_0E] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_FLEX_STREAM] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_FLEX_SHARED_OBJECT] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_MESSAGE] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_NOTIFY] = rtmp_handler_notify;
+    rtmp_handler[RTMP_CONTENT_TYPE_SHARED_OBJECT] = rtmp_handler_null;
+    rtmp_handler[RTMP_CONTENT_TYPE_INVOKE] = rtmp_handler_invoke;
+}