[vlc-commits] Fix Metacube header handling with multiple header blocks.

Steinar H. Gunderson git at videolan.org
Mon Mar 30 15:13:48 CEST 2015


vlc | branch: master | Steinar H. Gunderson <steinar+vlc at gunderson.no> | Sun Mar 29 18:30:22 2015 +0000| [f367b695f1fa87c040466785092a001127904107] | committer: Jean-Baptiste Kempf

Fix Metacube header handling with multiple header blocks.

Some muxes, e.g. MP4, will send multiple header blocks. These are
merged by the HTTP server to a single header which is sent out to
the beginning of each client. However, they are _also_ sent out
directly on the wire to any client that connected before the first
block. In this case, we would send two separate Metacube header
blocks, which would have Cubemap (correctly) discard the first and
set only the second as header.

This would make us send only part of the MP4 header when sending
through Cubemap, if Cubemap connected before the first non-header
block, which would in turn confuse Chrome on Android (although not
Chrome on e.g. Linux). As Cubemap is pretty aggressive about
reconnecting (trying every 200 ms), this could easily happen in practice.

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f367b695f1fa87c040466785092a001127904107
---

 modules/access_output/http.c |   29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/modules/access_output/http.c b/modules/access_output/http.c
index f85eb42..f82e87c 100644
--- a/modules/access_output/http.c
+++ b/modules/access_output/http.c
@@ -380,13 +380,21 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
                 hdr.csum = hton16( metacube2_compute_crc( &hdr ) );
 
                 int i_header_size = p_sys->i_header_size + sizeof( hdr );
-                uint8_t *p_hdr_block = xmalloc( i_header_size );
-                memcpy( p_hdr_block, &hdr, sizeof( hdr ) );
-                memcpy( p_hdr_block + sizeof( hdr ), p_sys->p_header, p_sys->i_header_size );
-
-                httpd_StreamHeader( p_sys->p_httpd_stream, p_hdr_block, i_header_size );
-
-                free( p_hdr_block );
+                block_t *p_hdr_block = block_Alloc( i_header_size );
+                if( p_hdr_block == NULL ) {
+                    block_ChainRelease( p_buffer );
+                    return VLC_ENOMEM;
+                }
+                p_hdr_block->i_flags = 0;
+                memcpy( p_hdr_block->p_buffer, &hdr, sizeof( hdr ) );
+                memcpy( p_hdr_block->p_buffer + sizeof( hdr ), p_sys->p_header, p_sys->i_header_size );
+
+                /* send the combined header here instead of sending them as regular
+                 * data, so that we get them as a single Metacube header block */
+                httpd_StreamHeader( p_sys->p_httpd_stream, p_hdr_block->p_buffer, p_hdr_block->i_buffer );
+                httpd_StreamSend( p_sys->p_httpd_stream, p_hdr_block );
+
+                block_Release( p_hdr_block );
             }
             else
             {
@@ -406,6 +414,13 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
 
         if( p_sys->b_metacube )
         {
+            /* header data is combined into one packet and sent earlier */
+            if( p_buffer->i_flags & BLOCK_FLAG_HEADER ) {
+                block_Release( p_buffer );
+                p_buffer = p_next;
+                continue;
+            }
+
             /* prepend Metacube header */
             struct metacube2_block_header hdr;
             memcpy( hdr.sync, METACUBE2_SYNC, sizeof( METACUBE2_SYNC ) );



More information about the vlc-commits mailing list