From: Steinar H. Gunderson Date: Sun, 29 Mar 2015 19:30:22 +0000 (+0200) Subject: Fix Metacube header handling with multiple header blocks. X-Git-Url: https://git.sesse.net/?p=vlc;a=commitdiff_plain;h=807e6d7966367d850d2e8b395d3bd212a7c26e49 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. --- diff --git a/modules/access_output/http.c b/modules/access_output/http.c index f85eb42161..6180840669 100644 --- a/modules/access_output/http.c +++ b/modules/access_output/http.c @@ -380,13 +380,17 @@ 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 ); + block_t* p_hdr_block = block_Alloc( i_header_size ); + 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 ); - httpd_StreamHeader( p_sys->p_httpd_stream, p_hdr_block, 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 ); - free( p_hdr_block ); + block_Release( p_hdr_block ); } else { @@ -406,6 +410,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 ) );