]> git.sesse.net Git - vlc/blobdiff - modules/demux/avformat/demux.c
Merge branch '1.0-bugfix'
[vlc] / modules / demux / avformat / demux.c
index 842e9054648e3a4ed094a55232435aa394403b83..16a9cb04718bb52ed7877c007648fbfc453391d2 100644 (file)
@@ -36,6 +36,7 @@
 #include <vlc_meta.h>
 #include <vlc_input.h>
 #include <vlc_charset.h>
+#include <vlc_avcodec.h>
 
 /* ffmpeg header */
 #if defined(HAVE_LIBAVFORMAT_AVFORMAT_H)
@@ -46,6 +47,7 @@
 
 #include "../../codec/avcodec/avcodec.h"
 #include "avformat.h"
+#include "../vobsub.h"
 
 //#define AVFORMAT_DEBUG 1
 
@@ -205,13 +207,16 @@ int OpenDemux( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
 
+    vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
     if( av_find_stream_info( p_sys->ic ) < 0 )
     {
+        vlc_avcodec_unlock();
         msg_Err( p_demux, "av_find_stream_info failed" );
         if( !b_avfmt_nofile ) p_sys->fmt->flags ^= AVFMT_NOFILE;
         CloseDemux( p_this );
         return VLC_EGENERIC;
     }
+    vlc_avcodec_unlock();
     if( !b_avfmt_nofile ) p_sys->fmt->flags ^= AVFMT_NOFILE;
 
     for( i = 0; i < p_sys->ic->nb_streams; i++ )
@@ -267,6 +272,48 @@ int OpenDemux( vlc_object_t *p_this )
 
         case CODEC_TYPE_SUBTITLE:
             es_format_Init( &fmt, SPU_ES, fcc );
+            if( strncmp( p_sys->ic->iformat->name, "matroska", 8 ) == 0 &&
+                cc->codec_id == CODEC_ID_DVD_SUBTITLE &&
+                cc->extradata != NULL &&
+                cc->extradata_size > 0 )
+            {
+                char *psz_start;
+                char *psz_buf = malloc( cc->extradata_size + 1);
+                if( psz_buf != NULL )
+                {
+                    memcpy( psz_buf, cc->extradata , cc->extradata_size );
+                    psz_buf[cc->extradata_size] = '\0';
+
+                    psz_start = strstr( psz_buf, "size:" );
+                    if( psz_start &&
+                        vobsub_size_parse( psz_start,
+                                           &fmt.subs.spu.i_original_frame_width,
+                                           &fmt.subs.spu.i_original_frame_height ) == VLC_SUCCESS )
+                    {
+                        msg_Dbg( p_demux, "original frame size: %dx%d",
+                                 fmt.subs.spu.i_original_frame_width,
+                                 fmt.subs.spu.i_original_frame_height );
+                    }
+                    else
+                    {
+                        msg_Warn( p_demux, "reading original frame size failed" );
+                    }
+
+                    psz_start = strstr( psz_buf, "palette:" );
+                    if( psz_start &&
+                        vobsub_palette_parse( psz_start, &fmt.subs.spu.palette[1] ) == VLC_SUCCESS )
+                    {
+                        fmt.subs.spu.palette[0] =  0xBeef;
+                        msg_Dbg( p_demux, "vobsub palette read" );
+                    }
+                    else
+                    {
+                        msg_Warn( p_demux, "reading original palette failed" );
+                    }
+                    free( psz_buf );
+                }
+            }
+
             psz_type = "subtitle";
             break;
 
@@ -294,7 +341,7 @@ int OpenDemux( vlc_object_t *p_this )
             msg_Warn( p_demux, "unsupported track type in ffmpeg demux" );
             break;
         }
-        fmt.psz_language = strdup( p_sys->ic->streams[i]->language );
+        fmt.psz_language = p_sys->ic->streams[i]->language;
 
 #ifdef HAVE_FFMPEG_CODEC_ATTACHMENT
         if( cc->codec_type != CODEC_TYPE_ATTACHMENT )
@@ -320,8 +367,9 @@ int OpenDemux( vlc_object_t *p_this )
              ( p_sys->ic->duration != (int64_t)AV_NOPTS_VALUE ) ?
              p_sys->ic->duration * 1000000 / AV_TIME_BASE : -1 );
 
-#if HAVE_FFMPEG_CHAPTERS
-    p_sys->p_title = vlc_input_title_New();
+#ifdef HAVE_FFMPEG_CHAPTERS
+    if( p_sys->ic->nb_chapters > 0 )
+        p_sys->p_title = vlc_input_title_New();
     for( i = 0; i < p_sys->ic->nb_chapters; i++ )
     {
         seekpoint_t *s = vlc_seekpoint_New();
@@ -542,6 +590,14 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             UpdateSeekPoint( p_demux, i64 );
             return VLC_SUCCESS;
 
+        case DEMUX_HAS_UNSUPPORTED_META:
+        {
+            bool *pb_bool = (bool*)va_arg( args, bool* );
+            *pb_bool = true;
+            return VLC_SUCCESS;
+        }
+
+
         case DEMUX_GET_META:
         {
             vlc_meta_t *p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
@@ -676,8 +732,12 @@ static int64_t IOSeek( void *opaque, int64_t offset, int whence )
             return -1;
 
     }
+
     if( i_absolute < 0 )
-        i_absolute = 0;
+    {
+        msg_Dbg( p_demux, "Trying to seek before the beginning" );
+        return -1;
+    }
 
     if( i_size > 0 && i_absolute >= i_size )
     {