Update the VLC Metacube patch to apply against current VLC master.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 1 Oct 2013 22:19:10 +0000 (00:19 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 1 Oct 2013 22:19:10 +0000 (00:19 +0200)
This version is identical to the one that was sent to the VLC mailing list
for upstream inclusion (but not accepted), so it also contains some other
cleanups.

vlc-metacube.diff

index fbde59d..91de18b 100644 (file)
@@ -32,10 +32,10 @@ index 0000000..dfbfd24
 +
 +#endif  /* !defined(_METACUBE_H) */
 diff --git a/include/vlc_httpd.h b/include/vlc_httpd.h
-index 6100dd0..7a14515 100644
+index 9eb0b15..8eacf68 100644
 --- a/include/vlc_httpd.h
 +++ b/include/vlc_httpd.h
-@@ -135,10 +135,10 @@ VLC_API void httpd_RedirectDelete( httpd_redirect_t * );
+@@ -135,7 +135,7 @@ VLC_API void httpd_RedirectDelete( httpd_redirect_t * );
  
  
  typedef struct httpd_stream_t httpd_stream_t;
@@ -43,25 +43,31 @@ index 6100dd0..7a14515 100644
 +VLC_API httpd_stream_t * httpd_StreamNew( httpd_host_t *, const char *psz_url, const char *psz_mime, const char *psz_user, const char *psz_password, bool b_metacube ) VLC_USED;
  VLC_API void httpd_StreamDelete( httpd_stream_t * );
  VLC_API int httpd_StreamHeader( httpd_stream_t *, uint8_t *p_data, int i_data );
--VLC_API int httpd_StreamSend( httpd_stream_t *, uint8_t *p_data, int i_data );
-+VLC_API int httpd_StreamSend( httpd_stream_t *, uint8_t *p_data, int i_data, bool b_header, bool b_keyframe );
- /* Msg functions facilities */
+ VLC_API int httpd_StreamSend( httpd_stream_t *, const block_t *p_block );
 diff --git a/modules/access_output/http.c b/modules/access_output/http.c
-index 364768c..f667e08 100644
+index bf75130..e608f8d 100644
 --- a/modules/access_output/http.c
 +++ b/modules/access_output/http.c
-@@ -72,6 +72,8 @@ vlc_module_begin ()
+@@ -57,6 +57,9 @@ static void Close( vlc_object_t * );
+ #define MIME_TEXT N_("Mime")
+ #define MIME_LONGTEXT N_("MIME returned by the server (autodetected " \
+                         "if not specified)." )
++#define METACUBE_TEXT N_("Metacube")
++#define METACUBE_LONGTEXT N_("Use the Metacube protocol. Needed for streaming " \
++                             "to the Cubemap reflector.")
+ vlc_module_begin ()
+@@ -72,6 +75,8 @@ vlc_module_begin ()
                    PASS_TEXT, PASS_LONGTEXT, true )
      add_string( SOUT_CFG_PREFIX "mime", "",
                  MIME_TEXT, MIME_LONGTEXT, true )
 +    add_bool( SOUT_CFG_PREFIX "metacube", false,
-+              "Use the metacube protocol", "Use the metacube protocol", true )
++              METACUBE_TEXT, METACUBE_LONGTEXT, true )
      set_callbacks( Open, Close )
  vlc_module_end ()
  
-@@ -80,7 +82,7 @@ vlc_module_end ()
+@@ -80,7 +85,7 @@ vlc_module_end ()
   * Exported prototypes
   *****************************************************************************/
  static const char *const ppsz_sout_options[] = {
@@ -70,16 +76,16 @@ index 364768c..f667e08 100644
  };
  
  static ssize_t Write( sout_access_out_t *, block_t * );
-@@ -114,6 +116,8 @@ static int Open( vlc_object_t *p_this )
+@@ -114,6 +119,8 @@ static int Open( vlc_object_t *p_this )
      char                *psz_pwd;
      char                *psz_mime;
  
-+    bool                    b_metacube;
++    bool                b_metacube;
 +
      if( !( p_sys = p_access->p_sys =
                  malloc( sizeof( sout_access_out_sys_t ) ) ) )
          return VLC_ENOMEM ;
-@@ -189,9 +193,11 @@ static int Open( vlc_object_t *p_this )
+@@ -189,9 +196,11 @@ static int Open( vlc_object_t *p_this )
          psz_mime = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "mime" );
      }
  
@@ -92,29 +98,8 @@ index 364768c..f667e08 100644
      free( psz_user );
      free( psz_pwd );
      free( psz_mime );
-@@ -263,8 +269,10 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
-     while( p_buffer )
-     {
-         block_t *p_next;
-+        bool b_header_block = p_buffer->i_flags & BLOCK_FLAG_HEADER;
-+        bool b_keyframe = p_buffer->i_flags & BLOCK_FLAG_TYPE_I;
--        if( p_buffer->i_flags & BLOCK_FLAG_HEADER )
-+        if( b_header_block )
-         {
-             /* gather header */
-             if( p_sys->b_header_complete )
-@@ -297,7 +305,7 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
-         i_len += p_buffer->i_buffer;
-         /* send data */
-         i_err = httpd_StreamSend( p_sys->p_httpd_stream, p_buffer->p_buffer,
--                                  p_buffer->i_buffer );
-+                                  p_buffer->i_buffer, b_header_block, b_keyframe );
-         p_next = p_buffer->p_next;
-         block_Release( p_buffer );
 diff --git a/src/Makefile.am b/src/Makefile.am
-index 639d157..89f78bc 100644
+index a7f42ef..18ffaa0 100644
 --- a/src/Makefile.am
 +++ b/src/Makefile.am
 @@ -480,6 +480,7 @@ SOURCES_libvlc_common = \
@@ -126,40 +111,18 @@ index 639d157..89f78bc 100644
  
  SOURCES_libvlc_sout = \
 diff --git a/src/network/httpd.c b/src/network/httpd.c
-index bbfbd18..8e0b130 100644
+index ff7e653..b8f6768 100644
 --- a/src/network/httpd.c
 +++ b/src/network/httpd.c
-@@ -39,6 +39,7 @@
- #include <vlc_charset.h>
+@@ -40,6 +40,7 @@
  #include <vlc_url.h>
  #include <vlc_mime.h>
+ #include <vlc_block.h>
 +#include <metacube2.h>
  #include "../libvlc.h"
  
  #include <string.h>
-@@ -66,6 +67,7 @@
- #endif
- static void httpd_ClientClean( httpd_client_t *cl );
-+static void httpd_AppendData( httpd_stream_t *stream, uint8_t *p_data, int i_data );
- /* each host run in his own thread */
- struct httpd_host_t
-@@ -159,6 +161,13 @@ struct httpd_client_t
-     int     i_buffer;
-     uint8_t *p_buffer;
-+    /*
-+     * If waiting for a keyframe, this is the position (in bytes) of the
-+     * last keyframe the stream saw before this client connected.
-+     * Otherwise, -1.
-+     */
-+    int64_t i_keyframe_wait_to_pass;
-+
-     /* */
-     httpd_message_t query;  /* client -> httpd */
-     httpd_message_t answer; /* httpd -> client */
-@@ -621,11 +630,20 @@ struct httpd_stream_t
+@@ -630,6 +631,7 @@ struct httpd_stream_t
      httpd_url_t *url;
  
      char    *psz_mime;
@@ -167,37 +130,7 @@ index bbfbd18..8e0b130 100644
  
      /* Header to send as first packet */
      uint8_t *p_header;
-     int     i_header;
-+    /* Some muxes, in particular the avformat mux, can mark given blocks
-+     * as keyframes, to ensure that the stream starts with one.
-+     * (This is particularly important for WebM streaming to certain
-+     * browsers.) Store if we've ever seen any such keyframe blocks,
-+     * and if so, the byte position of the start of the last one. */
-+    bool        b_has_keyframes;
-+    int64_t     i_last_keyframe_seen_pos;
-+
-     /* circular buffer */
-     int         i_buffer_size;      /* buffer size, can't be reallocated smaller */
-     uint8_t     *p_buffer;          /* buffer */
-@@ -659,6 +677,16 @@ static int httpd_StreamCallBack( httpd_callback_sys_t *p_sys,
-             /* fprintf( stderr, "httpd_StreamCallBack: no data\n" ); */
-             return VLC_EGENERIC;    /* wait, no data available */
-         }
-+        if( cl->i_keyframe_wait_to_pass >= 0 )
-+        {
-+            if( stream->i_last_keyframe_seen_pos <= cl->i_keyframe_wait_to_pass )
-+                /* still waiting for the next keyframe */
-+                return VLC_EGENERIC;
-+
-+            /* seek to the new keyframe */
-+            answer->i_body_offset = stream->i_last_keyframe_seen_pos;
-+            cl->i_keyframe_wait_to_pass = -1;
-+        }
-         if( answer->i_body_offset + stream->i_buffer_size <
-             stream->i_buffer_pos )
-         {
-@@ -712,11 +740,31 @@ static int httpd_StreamCallBack( httpd_callback_sys_t *p_sys,
+@@ -739,9 +741,25 @@ static int httpd_StreamCallBack( httpd_callback_sys_t *p_sys,
              /* Send the header */
              if( stream->i_header > 0 )
              {
@@ -210,7 +143,7 @@ index bbfbd18..8e0b130 100644
 +                    memcpy( hdr.sync, METACUBE2_SYNC, sizeof(METACUBE2_SYNC) );
 +                    hdr.size = htonl( stream->i_header );
 +                    hdr.flags = htons( METACUBE_FLAGS_HEADER );
-+                    hdr.csum = htons( metacube2_compute_crc( &hdr ));
++                    hdr.csum = htons( metacube2_compute_crc( &hdr ) );
 +
 +                    answer->i_body = stream->i_header + sizeof( hdr );
 +                    answer->p_body = xmalloc( answer->i_body );
@@ -225,14 +158,8 @@ index bbfbd18..8e0b130 100644
 +                }
              }
              answer->i_body_offset = stream->i_buffer_last_pos;
-+            if( stream->b_has_keyframes )
-+                cl->i_keyframe_wait_to_pass = stream->i_last_keyframe_seen_pos;
-+            else
-+                cl->i_keyframe_wait_to_pass = -1;
-             vlc_mutex_unlock( &stream->lock );
-         }
-         else
-@@ -758,13 +806,16 @@ static int httpd_StreamCallBack( httpd_callback_sys_t *p_sys,
+             if( stream->b_has_keyframes )
+@@ -789,13 +807,16 @@ static int httpd_StreamCallBack( httpd_callback_sys_t *p_sys,
              httpd_MsgAdd( answer, "Content-type",  "%s", stream->psz_mime );
          }
          httpd_MsgAdd( answer, "Cache-Control", "%s", "no-cache" );
@@ -250,7 +177,7 @@ index bbfbd18..8e0b130 100644
  {
      httpd_stream_t *stream = xmalloc( sizeof( httpd_stream_t ) );
  
-@@ -783,6 +834,7 @@ httpd_stream_t *httpd_StreamNew( httpd_host_t *host,
+@@ -814,6 +835,7 @@ httpd_stream_t *httpd_StreamNew( httpd_host_t *host,
      {
          stream->psz_mime = strdup( vlc_mime_Ext2Mime( psz_url ) );
      }
@@ -258,101 +185,58 @@ index bbfbd18..8e0b130 100644
      stream->i_header = 0;
      stream->p_header = NULL;
      stream->i_buffer_size = 5000000;    /* 5 Mo per stream */
-@@ -791,6 +843,8 @@ httpd_stream_t *httpd_StreamNew( httpd_host_t *host,
-      * (this way i_body_offset can never be 0) */
-     stream->i_buffer_pos = 1;
-     stream->i_buffer_last_pos = 1;
-+    stream->b_has_keyframes = false;
-+    stream->i_last_keyframe_seen_pos = 0;
-     httpd_UrlCatch( stream->url, HTTPD_MSG_HEAD, httpd_StreamCallBack,
-                     (httpd_callback_sys_t*)stream );
-@@ -819,22 +873,10 @@ int httpd_StreamHeader( httpd_stream_t *stream, uint8_t *p_data, int i_data )
-     return VLC_SUCCESS;
- }
--int httpd_StreamSend( httpd_stream_t *stream, uint8_t *p_data, int i_data )
-+static void httpd_AppendData( httpd_stream_t *stream, uint8_t *p_data, int i_data )
- {
--    int i_count;
--    int i_pos;
--
--    if( i_data < 0 || p_data == NULL )
--    {
--        return VLC_SUCCESS;
--    }
--    vlc_mutex_lock( &stream->lock );
--
--    /* save this pointer (to be used by new connection) */
--    stream->i_buffer_last_pos = stream->i_buffer_pos;
--
--    i_pos = stream->i_buffer_pos % stream->i_buffer_size;
--    i_count = i_data;
-+    int i_pos = stream->i_buffer_pos % stream->i_buffer_size;
-+    int i_count = i_data;
-     while( i_count > 0)
-     {
-         int i_copy;
-@@ -850,6 +892,40 @@ int httpd_StreamSend( httpd_stream_t *stream, uint8_t *p_data, int i_data )
+@@ -890,6 +912,20 @@ int httpd_StreamSend( httpd_stream_t *stream, const block_t *p_block )
+         stream->i_last_keyframe_seen_pos = stream->i_buffer_pos;
      }
  
-     stream->i_buffer_pos += i_data;
-+}
-+
-+int httpd_StreamSend( httpd_stream_t *stream, uint8_t *p_data, int i_data, bool b_header, bool b_keyframe )
-+{
-+    if( i_data < 0 || p_data == NULL )
-+    {
-+        return VLC_SUCCESS;
-+    }
-+    vlc_mutex_lock( &stream->lock );
-+
-+    /* save this pointer (to be used by new connection) */
-+    stream->i_buffer_last_pos = stream->i_buffer_pos;
-+
-+    if( b_keyframe )
-+    {
-+        stream->b_has_keyframes = true;
-+        stream->i_last_keyframe_seen_pos = stream->i_buffer_pos;
-+    }
-+
 +    if( stream->b_metacube )
 +    {
 +        struct metacube2_block_header hdr;
 +        memcpy( hdr.sync, METACUBE2_SYNC, sizeof(METACUBE2_SYNC) );
-+        hdr.size = htonl( i_data );
++        hdr.size = htonl( p_block->i_buffer );
 +        hdr.flags = htons( 0 );
-+        if( b_header )
++        if( p_block->i_flags & BLOCK_FLAG_HEADER )
 +            hdr.flags |= htons( METACUBE_FLAGS_HEADER );
-+        if( stream->b_has_keyframes && !b_keyframe )
++        if( stream->b_has_keyframes && !( p_block->i_flags & BLOCK_FLAG_TYPE_I ) )
 +            hdr.flags |= htons( METACUBE_FLAGS_NOT_SUITABLE_FOR_STREAM_START );
-+        hdr.csum = htons( metacube2_compute_crc( &hdr ));
++        hdr.csum = htons( metacube2_compute_crc( &hdr ) );
 +        httpd_AppendData( stream, (uint8_t *)&hdr, sizeof(hdr) );
 +    }
 +
-+    httpd_AppendData( stream, p_data, i_data );
+     httpd_AppendData( stream, p_block->p_buffer, p_block->i_buffer );
  
      vlc_mutex_unlock( &stream->lock );
-     return VLC_SUCCESS;
-@@ -1273,6 +1349,7 @@ static void httpd_ClientInit( httpd_client_t *cl, mtime_t now )
-     cl->i_buffer_size = HTTPD_CL_BUFSIZE;
-     cl->i_buffer = 0;
-     cl->p_buffer = xmalloc( cl->i_buffer_size );
-+    cl->i_keyframe_wait_to_pass = -1;
-     cl->b_stream_mode = false;
-     httpd_MsgInit( &cl->query );
 diff --git a/src/network/metacube2.c b/src/network/metacube2.c
 new file mode 100644
-index 0000000..7b2dacf
+index 0000000..353ce88
 --- /dev/null
 +++ b/src/network/metacube2.c
-@@ -0,0 +1,49 @@
+@@ -0,0 +1,69 @@
 +/*
-+ * Implementation of Metacube2 utility functions.
++ * Implementation of Metacube2 utility functions. Taken from the Cubemap
++ * distribution and then relicensed by the author to LGPL2.1+ for inclusion
++ * into VLC.
 + *
 + * Note: This file is meant to compile as both C and C++, for easier inclusion
 + * in other projects.
++ *
++ * Copyright (C) 2013 Steinar H. Gunderson
++ *
++ * Author: Steinar H. Gunderson <steinar+vlc@gunderson.no>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU Lesser General Public License as published by
++ * the Free Software Foundation; either version 2.1 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * along with this program; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 + */
 +
 +#include <stdlib.h>