]> git.sesse.net Git - vlc/blobdiff - modules/demux/avformat/demux.c
Dead initialization.
[vlc] / modules / demux / avformat / demux.c
index e413c00821076c684e49dd81f05bd2b8c15530c6..4bc6873e5af5cbb6e1c741d4439822c43bc3ca26 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * demux.c: demuxer using ffmpeg (libavformat).
  *****************************************************************************
- * Copyright (C) 2004-2007 the VideoLAN team
+ * Copyright (C) 2004-2009 the VideoLAN team
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
@@ -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 )
@@ -391,6 +438,8 @@ static int Demux( demux_t *p_demux )
         av_free_packet( &pkt );
         return 1;
     }
+    const AVStream *p_stream = p_sys->ic->streams[pkt.stream_index];
+
     if( ( p_frame = block_New( p_demux, pkt.size ) ) == NULL )
     {
         return 0;
@@ -406,17 +455,24 @@ static int Demux( demux_t *p_demux )
 
     p_frame->i_dts = ( pkt.dts == (int64_t)AV_NOPTS_VALUE ) ?
         0 : (pkt.dts) * 1000000 *
-        p_sys->ic->streams[pkt.stream_index]->time_base.num /
-        p_sys->ic->streams[pkt.stream_index]->time_base.den - i_start_time;
+        p_stream->time_base.num /
+        p_stream->time_base.den - i_start_time;
     p_frame->i_pts = ( pkt.pts == (int64_t)AV_NOPTS_VALUE ) ?
         0 : (pkt.pts) * 1000000 *
-        p_sys->ic->streams[pkt.stream_index]->time_base.num /
-        p_sys->ic->streams[pkt.stream_index]->time_base.den - i_start_time;
+        p_stream->time_base.num /
+        p_stream->time_base.den - i_start_time;
     if( pkt.duration > 0 )
         p_frame->i_length = pkt.duration * 1000000 *
-            p_sys->ic->streams[pkt.stream_index]->time_base.num /
-            p_sys->ic->streams[pkt.stream_index]->time_base.den - i_start_time;
+            p_stream->time_base.num /
+            p_stream->time_base.den - i_start_time;
 
+    if( pkt.dts != AV_NOPTS_VALUE && pkt.dts == pkt.pts &&
+        p_stream->codec->codec_type == CODEC_TYPE_VIDEO )
+    {
+        /* Add here notoriously bugged file formats/samples regarding PTS */
+        if( !strcmp( p_sys->fmt->name, "flv" ) )
+            p_frame->i_pts = 0;
+    }
 #ifdef AVFORMAT_DEBUG
     msg_Dbg( p_demux, "tk[%d] dts=%"PRId64" pts=%"PRId64,
              pkt.stream_index, p_frame->i_dts, p_frame->i_pts );
@@ -488,7 +544,6 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
 
         case DEMUX_SET_POSITION:
             f = (double) va_arg( args, double );
-            i64 = stream_Tell( p_demux->s );
             if( p_sys->i_pcr > 0 )
             {
                 i64 = p_sys->ic->duration * f;
@@ -503,12 +558,16 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                     (av_seek_frame( p_sys->ic, -1, i64, 0 ) < 0) )
                 {
                     int64_t i_size = stream_Size( p_demux->s );
+                    i64 = (i_size * f);
 
                     msg_Warn( p_demux, "DEMUX_SET_BYTE_POSITION: %"PRId64, i64 );
-                    if( av_seek_frame( p_sys->ic, -1, (i_size * f), AVSEEK_FLAG_BYTE ) < 0 )
+                    if( av_seek_frame( p_sys->ic, -1, i64, AVSEEK_FLAG_BYTE ) < 0 )
                         return VLC_EGENERIC;
                 }
-                UpdateSeekPoint( p_demux, i64 );
+                else
+                {
+                    UpdateSeekPoint( p_demux, i64 );
+                }
                 p_sys->i_pcr = -1; /* Invalidate time display */
             }
             return VLC_SUCCESS;
@@ -659,7 +718,7 @@ static int64_t IOSeek( void *opaque, int64_t offset, int whence )
 {
     URLContext *p_url = opaque;
     demux_t *p_demux = p_url->priv_data;
-    int64_t i_absolute = (int64_t)offset;
+    int64_t i_absolute;
     int64_t i_size = stream_Size( p_demux->s );
 
 #ifdef AVFORMAT_DEBUG