[vlc-commits] livehttp: fix padding to work with iOS/Android

Ilkka Ollakka git at videolan.org
Tue Mar 19 14:58:42 CET 2013


vlc | branch: master | Ilkka Ollakka <ileoo at videolan.org> | Tue Mar 19 15:34:01 2013 +0200| [25057a578369b3b08b3f04bfb81ef10d5d0c7274] | committer: Ilkka Ollakka

livehttp: fix padding to work with iOS/Android

Don't pad individual ts-packets, but pad just segments.

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

 modules/access_output/livehttp.c |   79 ++++++++++++++++++++++++++++----------
 1 file changed, 59 insertions(+), 20 deletions(-)

diff --git a/modules/access_output/livehttp.c b/modules/access_output/livehttp.c
index ebb6b3a..34bd318 100644
--- a/modules/access_output/livehttp.c
+++ b/modules/access_output/livehttp.c
@@ -175,6 +175,8 @@ struct sout_access_out_sys_t
     uint8_t aes_ivs[16];
     gcry_cipher_hd_t aes_ctx;
     char *key_uri;
+    uint8_t stuffing_bytes[16];
+    ssize_t stuffing_size;
 };
 
 static int CryptSetup( sout_access_out_t *p_access );
@@ -210,6 +212,7 @@ static int Open( vlc_object_t *p_this )
     p_sys->b_caching = var_GetBool( p_access, SOUT_CFG_PREFIX "caching") ;
     p_sys->b_generate_iv = var_GetBool( p_access, SOUT_CFG_PREFIX "generate-iv") ;
 
+    p_sys->stuffing_size = 0;
 
     /* 5 elements is from harrison-stetson algorithm to start from some number
      * if we don't have numsegs defined
@@ -545,6 +548,21 @@ static void closeCurrentSegment( sout_access_out_t *p_access, sout_access_out_sy
 {
     if ( p_sys->i_handle >= 0 )
     {
+    if( p_sys->key_uri )
+    {
+        size_t pad = 16 - p_sys->stuffing_size;
+            memset(&p_sys->stuffing_bytes[p_sys->stuffing_size], pad, pad);
+        gcry_error_t err = gcry_cipher_encrypt( p_sys->aes_ctx, p_sys->stuffing_bytes, 16, NULL, 0 );
+
+            if( err ) {
+        msg_Err( p_access, "Couldn't encrypt 16 bytes: %s", gpg_strerror(err) );
+        } else {
+                int ret = write( p_sys->i_handle, p_sys->stuffing_bytes, 16 );
+        if( ret != 16 )
+                    msg_Err( p_access, "Couldn't write 16 bytes" );
+            }
+            p_sys->stuffing_size = 0;
+    }
         close( p_sys->i_handle );
         p_sys->i_handle = -1;
         if ( p_sys->psz_cursegPath )
@@ -566,28 +584,37 @@ static void Close( vlc_object_t * p_this )
     sout_access_out_sys_t *p_sys = p_access->p_sys;
 
     msg_Dbg( p_access, "Flushing buffer to last file");
+    bool crypted = false;
     while( p_sys->block_buffer )
     {
-        if( p_sys->key_uri )
+        if( p_sys->key_uri && !crypted)
         {
+            if( p_sys->stuffing_size )
+            {
+                p_sys->block_buffer = block_Realloc( p_sys->block_buffer, p_sys->stuffing_size, p_sys->block_buffer->i_buffer );
+                if( unlikely(!p_sys->block_buffer) )
+                    return;
+                memcpy( p_sys->block_buffer->p_buffer, p_sys->stuffing_bytes, p_sys->stuffing_size );
+                p_sys->stuffing_size = 0;
+            }
             size_t original = p_sys->block_buffer->i_buffer;
-            size_t padded = (p_sys->block_buffer->i_buffer + 15 ) & ~15;
-            if( padded == p_sys->block_buffer->i_buffer )
-                padded += 16;
-            p_sys->block_buffer = block_Realloc( p_sys->block_buffer, 0, padded );
-            if( !p_sys->block_buffer )
-                break;
-            int pad = padded - original;
-            memset( &p_sys->block_buffer->p_buffer[original], pad, pad );
+            size_t padded = (original + 15 ) & ~15;
+            size_t pad = padded - original;
+            if( pad )
+            {
+                p_sys->stuffing_size = 16 - pad;
+                p_sys->block_buffer->i_buffer -= p_sys->stuffing_size;
+                memcpy( p_sys->stuffing_bytes, &p_sys->block_buffer->p_buffer[p_sys->block_buffer->i_buffer], p_sys->stuffing_size );
+            }
 
             gcry_error_t err = gcry_cipher_encrypt( p_sys->aes_ctx,
-                                p_sys->block_buffer->p_buffer, padded, NULL, 0 );
+                                p_sys->block_buffer->p_buffer, p_sys->block_buffer->i_buffer, NULL, 0 );
             if( err )
             {
                 msg_Err( p_access, "Encryption failure: %s ", gpg_strerror(err) );
                 break;
             }
-
+            crypted = true;
         }
         ssize_t val = write( p_sys->i_handle, p_sys->block_buffer->p_buffer, p_sys->block_buffer->i_buffer );
         if ( val == -1 )
@@ -609,6 +636,7 @@ static void Close( vlc_object_t * p_this )
            block_t *p_next = p_sys->block_buffer->p_next;
            block_Release (p_sys->block_buffer);
            p_sys->block_buffer = p_next;
+           crypted=false;
         }
         else
         {
@@ -697,6 +725,7 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
     {
         if ( ( p_sys->b_splitanywhere || ( p_buffer->i_flags & BLOCK_FLAG_HEADER ) ) )
         {
+            bool crypted = false;
             block_t *output = p_sys->block_buffer;
             p_sys->block_buffer = NULL;
 
@@ -716,25 +745,34 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
 
             while( output )
             {
-                if( p_sys->key_uri )
+                if( p_sys->key_uri && !crypted )
                 {
+                    if( p_sys->stuffing_size )
+                    {
+                        output = block_Realloc( output, p_sys->stuffing_size, output->i_buffer );
+                        if( unlikely(!output ) )
+                            return VLC_ENOMEM;
+                        memcpy( output->p_buffer, p_sys->stuffing_bytes, p_sys->stuffing_size );
+                        p_sys->stuffing_size = 0;
+                    }
                     size_t original = output->i_buffer;
                     size_t padded = (output->i_buffer + 15 ) & ~15;
-                    if( padded == output->i_buffer )
-                        padded += 16;
-                    output = block_Realloc( output, 0, padded );
-                    if( !output )
-                        return VLC_ENOMEM;
-                    int pad = padded - original;
-                    memset( &output->p_buffer[original], pad, pad );
+                    size_t pad = padded - original;
+                    if( pad )
+                    {
+                        p_sys->stuffing_size = 16-pad;
+                        output->i_buffer -= p_sys->stuffing_size;
+                        memcpy(p_sys->stuffing_bytes, &output->p_buffer[output->i_buffer], p_sys->stuffing_size);
+                    }
 
                     gcry_error_t err = gcry_cipher_encrypt( p_sys->aes_ctx,
-                                        output->p_buffer, padded, NULL, 0 );
+                                        output->p_buffer, output->i_buffer, NULL, 0 );
                     if( err )
                     {
                         msg_Err( p_access, "Encryption failure: %s ", gpg_strerror(err) );
                         return -1;
                     }
+                    crypted=true;
 
                 }
                 ssize_t val = write( p_sys->i_handle, output->p_buffer, output->i_buffer );
@@ -754,6 +792,7 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
                    block_t *p_next = output->p_next;
                    block_Release (output);
                    output = p_next;
+                   crypted=false;
                 }
                 else
                 {



More information about the vlc-commits mailing list