]> git.sesse.net Git - vlc/blobdiff - modules/codec/ffmpeg/video.c
* all: - increased avcodec version needed to 4680 (latest release)
[vlc] / modules / codec / ffmpeg / video.c
index 939ea0b9c014e77f095457fbd900592ddf408a11..aa4f0b57a99179643da42cc3c529a57b4d952996 100644 (file)
@@ -2,7 +2,7 @@
  * video.c: video decoder using the ffmpeg library
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: video.c,v 1.50 2003/11/23 13:15:27 gbazin Exp $
+ * $Id: video.c,v 1.55 2003/11/29 18:06:12 fenrir Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@netcourrier.com>
@@ -76,6 +76,8 @@ struct decoder_sys_t
 
     /* Postprocessing handle */
     void *p_pp;
+    vlc_bool_t b_pp;
+    vlc_bool_t b_pp_async;
     vlc_bool_t b_pp_init;
 };
 
@@ -161,7 +163,7 @@ static inline picture_t *ffmpeg_NewPictBuf( decoder_t *p_dec,
     p_pic = p_dec->pf_vout_buffer_new( p_dec );
 
 #ifdef LIBAVCODEC_PP
-    if( p_sys->p_pp && !p_sys->b_pp_init )
+    if( p_sys->p_pp && p_sys->b_pp && !p_sys->b_pp_init )
     {
         E_(InitPostproc)( p_dec, p_sys->p_pp, p_context->width,
                           p_context->height, p_context->pix_fmt );
@@ -182,9 +184,13 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
                       AVCodec *p_codec, int i_codec_id, char *psz_namecodec )
 {
     decoder_sys_t *p_sys;
+    vlc_value_t lockval;
     vlc_value_t val;
     int i_tmp;
 
+
+    var_Get( p_dec->p_libvlc, "avcodec", &lockval );
+
     /* Allocate the memory needed to store the decoder's structure */
     if( ( p_dec->p_sys = p_sys =
           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
@@ -215,22 +221,9 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
     if( val.b_bool ) p_sys->p_context->flags |= CODEC_FLAG_GRAY;
 
     /* Decide if we set CODEC_FLAG_TRUNCATED */
-#if LIBAVCODEC_BUILD >= 4662
     var_Create( p_dec, "ffmpeg-truncated", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
     var_Get( p_dec, "ffmpeg-truncated", &val );
     if( val.i_int > 0 ) p_sys->p_context->flags |= CODEC_FLAG_TRUNCATED;
-#endif
-
-    /* ***** Open the codec ***** */
-    if( avcodec_open( p_sys->p_context, p_sys->p_codec ) < 0 )
-    {
-        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
-        return VLC_EGENERIC;
-    }
-    else
-    {
-        msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );
-    }
 
     /* ***** ffmpeg frame skipping ***** */
     var_Create( p_dec, "ffmpeg-hurry-up", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
@@ -254,16 +247,12 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
 
 #ifdef LIBAVCODEC_PP
     p_sys->p_pp = NULL;
-    p_dec->p_sys->b_pp_init = VLC_FALSE;
-    if( E_(OpenPostproc)( p_dec, &p_sys->p_pp ) == VLC_SUCCESS )
-    {
-        /* for now we cannot do postproc and dr */
-        p_sys->b_direct_rendering = 0;
-    }
+    p_sys->b_pp = p_sys->b_pp_async = p_sys->b_pp_init = VLC_FALSE;
+    p_sys->p_pp = E_(OpenPostproc)( p_dec, &p_sys->b_pp_async );
 #endif
 
     /* ffmpeg doesn't properly release old pictures when frames are skipped */
-    if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = 0;
+    //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = 0;
     if( p_sys->b_direct_rendering )
     {
         msg_Dbg( p_dec, "using direct rendering" );
@@ -279,21 +268,9 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
     /* ***** init this codec with special data ***** */
     if( p_dec->fmt_in.i_extra )
     {
-        int b_gotpicture;
         int i_size = p_dec->fmt_in.i_extra;
 
-        if( p_sys->i_codec_id == CODEC_ID_MPEG4 )
-        {
-            uint8_t *p_vol = malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
-            memcpy( p_vol, p_dec->fmt_in.p_extra, i_size );
-            memset( &p_vol[i_size], 0, FF_INPUT_BUFFER_PADDING_SIZE );
-
-            avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
-                                  &b_gotpicture, p_vol, i_size );
-            free( p_vol );
-        }
-#if LIBAVCODEC_BUILD >= 4666
-        else if( p_sys->i_codec_id == CODEC_ID_SVQ3 )
+        if( p_sys->i_codec_id == CODEC_ID_SVQ3 )
         {
             uint8_t *p;
 
@@ -305,7 +282,6 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
             memset( &p[4], 0, 8 );
             memcpy( &p[12], p_dec->fmt_in.p_extra, i_size );
         }
-#endif
         else
         {
             p_sys->p_context->extradata_size = i_size;
@@ -331,6 +307,18 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
     p_dec->fmt_out.i_cat = VIDEO_ES;
     p_dec->fmt_out.i_codec = ffmpeg_PixFmtToChroma( p_context->pix_fmt );
 
+    /* ***** Open the codec ***** */
+    vlc_mutex_lock( lockval.p_address );
+    if( avcodec_open( p_sys->p_context, p_sys->p_codec ) < 0 )
+    {
+        vlc_mutex_unlock( lockval.p_address );
+        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
+        return VLC_EGENERIC;
+    }
+    vlc_mutex_unlock( lockval.p_address );
+    msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );
+
+
     return VLC_SUCCESS;
 }
 
@@ -347,6 +335,15 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
 
     p_block = *pp_block;
 
+    if( p_block->b_discontinuity )
+    {
+        p_sys->i_buffer = 0;
+        p_sys->i_pts = 0; /* To make sure we recover properly */
+
+        block_Release( p_block );
+        return NULL;
+    }
+
     if( p_block->i_pts > 0 || p_block->i_dts > 0 )
     {
         p_sys->input_pts = p_block->i_pts;
@@ -390,7 +387,7 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
         block_Release( p_block );
         p_sys->i_pts = 0; /* To make sure we recover properly */
         p_sys->i_late_frames--;
-        return VLC_SUCCESS;
+        return NULL;
     }
 
     if( p_sys->p_context->width <= 0 || p_sys->p_context->height <= 0 )
@@ -402,6 +399,9 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
      * Do the actual decoding now
      */
 
+    /* Check if post-processing was enabled */
+    p_sys->b_pp = p_sys->b_pp_async;
+
     /* Don't forget that ffmpeg requires a little more bytes
      * that the real frame size */
     if( p_block->i_buffer > 0 )
@@ -470,7 +470,7 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
             continue;
         }
 
-        if( !p_sys->b_direct_rendering )
+        if( !p_sys->b_direct_rendering || p_sys->b_pp )
         {
             /* Get a new picture */
             p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );
@@ -558,7 +558,7 @@ static void ffmpeg_CopyPicture( decoder_t *p_dec,
         int i_src_stride, i_dst_stride;
 
 #ifdef LIBAVCODEC_PP
-        if( p_sys->p_pp )
+        if( p_sys->p_pp && p_sys->b_pp )
             E_(PostprocPict)( p_dec, p_sys->p_pp, p_pic, p_ff_pic );
         else
 #endif
@@ -642,7 +642,7 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
     p_sys->input_pts = p_sys->input_dts = 0;
 
     /* Not much to do in indirect rendering mode */
-    if( !p_sys->b_direct_rendering )
+    if( !p_sys->b_direct_rendering || p_sys->b_pp )
     {
         return avcodec_default_get_buffer( p_context, p_ff_pic );
     }
@@ -681,7 +681,7 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
 
     if( p_ff_pic->reference != 0 )
     {
-      //vout_LinkPicture( p_sys->p_vout, p_pic );
+        p_dec->pf_picture_link( p_dec, p_pic );
     }
 
     /* FIXME what is that, should give good value */
@@ -711,6 +711,6 @@ static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
 
     if( p_ff_pic->reference != 0 )
     {
-      //vout_UnlinkPicture( p_sys->p_vout, p_pic );
+        p_dec->pf_picture_unlink( p_dec, p_pic );
     }
 }