]> git.sesse.net Git - vlc/blobdiff - modules/demux/mjpeg.c
demux: ts: Better missing PCR fixes
[vlc] / modules / demux / mjpeg.c
index e87899e1ffb46edab805b6bc0f019fe214c4b543..af6fceae8e31e0758df693aff5d31ee720be7190 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * mjpeg.c : demuxes mjpeg webcam http streams
  *****************************************************************************
- * Copyright (C) 2004 the VideoLAN team
+ * Copyright (C) 2004 VLC authors and VideoLAN
  * $Id$
  *
  * Authors: Henry Jen (slowhog) <henryjen@ztune.net>
@@ -9,19 +9,19 @@
  *          Sigmund Augdal (Dnumgis)
  *          Laurent Aimar <fenrir@via.ecp.fr>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * 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 General Public License for more details.
+ * 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 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.
+ * 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.
  *****************************************************************************/
 
 /*****************************************************************************
@@ -148,17 +148,16 @@ static char* GetLine( demux_t *p_demux, int *p_pos )
             i_size = p_sys->i_data_peeked - *p_pos;
         }
     }
-    *p_pos += ( i + 1 );
+    *p_pos += i + 1;
     if( i > 0 && p_buf[i - 1] == '\r' )
     {
         i--;
     }
     p_line = malloc( i + 1 );
-    if( p_line == NULL )
+    if( unlikely( p_line == NULL ) )
         return NULL;
     strncpy ( p_line, (char*)p_buf, i );
     p_line[i] = '\0';
-//    msg_Dbg( p_demux, "i = %d, pos = %d, %s", i, *p_pos, p_line );
     return p_line;
 }
 
@@ -190,33 +189,8 @@ static bool CheckMimeHeader( demux_t *p_demux, int *p_header_size )
     if( strncmp( (char *)p_sys->p_peek, "--", 2 ) != 0
         && strncmp( (char *)p_sys->p_peek, "\r\n--", 4 ) != 0 )
     {
-        /* Some broken stream may lack the first boundary */
-        if ( p_sys->psz_separator == NULL )
-        {
-            msg_Warn( p_demux, "Malformed stream. Trying to work around");
-            char *content_type = stream_ContentType( p_demux->s );
-            if ( content_type == NULL )
-                return false;
-            const char* boundary = strstr( content_type, "boundary=--" );
-            if ( boundary != NULL )
-            {
-                p_sys->psz_separator = strdup( boundary + strlen( "boundary=--" ) );
-                msg_Dbg( p_demux, "Video boundary extracted from Content-Type: %s", p_sys->psz_separator );
-                free( content_type );
-                /* Skip to HTTP header parsing as there's no boundary to extract
-                 * from the stream */
-            }
-            else
-            {
-                free( content_type );
-                return false;
-            }
-        }
-        else
-        {
-            *p_header_size = 0;
-            return false;
-        }
+        *p_header_size = 0;
+        return false;
     }
     else
     {
@@ -341,6 +315,31 @@ static int Open( vlc_object_t * p_this )
     p_sys->psz_separator = NULL;
     p_sys->i_frame_size_estimate = 15 * 1024;
 
+    char *content_type = stream_ContentType( p_demux->s );
+    if ( content_type )
+    {
+        //FIXME: this is not fully match to RFC
+        char* boundary = strstr( content_type, "boundary=" );
+        if( boundary )
+        {
+           boundary += strlen( "boundary=" );
+           size_t len = strlen( boundary );
+           if( len > 2 && boundary[0] == '"'
+               && boundary[len-1] == '"' )
+           {
+               boundary[len-1] = '\0';
+               boundary++;
+           }
+            p_sys->psz_separator = strdup( boundary );
+            if( !p_sys->psz_separator )
+            {
+                free( content_type );
+                goto error;
+            }
+        }
+        free( content_type );
+    }
+
     b_matched = CheckMimeHeader( p_demux, &i_size);
     if( b_matched )
     {
@@ -390,6 +389,7 @@ static int Open( vlc_object_t * p_this )
     return VLC_SUCCESS;
 
 error:
+    free( p_sys->psz_separator );
     free( p_sys );
     return VLC_EGENERIC;
 }
@@ -462,7 +462,8 @@ static int MimeDemux( demux_t *p_demux )
 
     if( i_size > 0 )
     {
-        stream_Read( p_demux->s, NULL, i_size );
+        if( stream_Read( p_demux->s, NULL, i_size ) != i_size )
+            return 0;
     }
     else if( i_size < 0 )
     {
@@ -508,8 +509,13 @@ static int MimeDemux( demux_t *p_demux )
             }
         }
 
-        if( !strncmp( p_sys->psz_separator, (char *)(p_sys->p_peek + i + 2),
-                      strlen( p_sys->psz_separator ) ) )
+        /* Handle old and new style of separators */
+        if (!strncmp(p_sys->psz_separator, (char *)(p_sys->p_peek + i + 2),
+                     strlen( p_sys->psz_separator ))
+         || ((strlen(p_sys->psz_separator) > 4)
+          && !strncmp(p_sys->psz_separator, "--", 2)
+          && !strncmp(p_sys->psz_separator, (char *)(p_sys->p_peek + i),
+                      strlen( p_sys->psz_separator))))
         {
             break;
         }