]> git.sesse.net Git - vlc/blobdiff - modules/codec/ffmpeg/video.c
Use the new block_Fifo functions
[vlc] / modules / codec / ffmpeg / video.c
index f22163376af31c366d4441e6de7631e6545619bb..8c3b3a8f17fb42d886f5ff871b722debd771d7cf 100644 (file)
  *****************************************************************************/
 struct decoder_sys_t
 {
-    /* Common part between video and audio decoder */
-    int i_cat;
-    int i_codec_id;
-    const char *psz_namecodec;
-
-    AVCodecContext      *p_context;
-    AVCodec             *p_codec;
+    FFMPEG_COMMON_MEMBERS
 
     /* Video decoder specific part */
     mtime_t input_pts;
@@ -62,7 +56,8 @@ struct decoder_sys_t
 
     /* for frame skipping algo */
     int b_hurry_up;
-    int i_frame_skip;
+    enum AVDiscard i_skip_frame;
+    enum AVDiscard i_skip_idct;
 
     /* how many decoded frames are late */
     int     i_late_frames;
@@ -220,18 +215,20 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
                       AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
 {
     decoder_sys_t *p_sys;
-    vlc_value_t lockval;
+    vlc_mutex_t *lock = var_GetGlobalMutex( "avcodec" );
     vlc_value_t val;
 
-    var_Get( p_dec->p_libvlc_global, "avcodec", &lockval );
+    if( lock == NULL )
+        return VLC_EGENERIC;
 
     /* 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 )
     {
         msg_Err( p_dec, "out of memory" );
-        return VLC_EGENERIC;
+        return VLC_ENOMEM;
     }
+    memset( p_sys, 0, sizeof(decoder_sys_t) );
 
     p_dec->p_sys->p_context = p_context;
     p_dec->p_sys->p_codec = p_codec;
@@ -276,6 +273,56 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
     var_Get( p_dec, "ffmpeg-hurry-up", &val );
     p_sys->b_hurry_up = val.b_bool;
 
+    var_Create( p_dec, "ffmpeg-skip-frame", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
+    var_Get( p_dec, "ffmpeg-skip-frame", &val );
+    switch( val.i_int )
+    {
+        case -1:
+            p_sys->p_context->skip_frame = AVDISCARD_NONE;
+            break;
+        case 0:
+            p_sys->p_context->skip_frame = AVDISCARD_DEFAULT;
+            break;
+        case 1:
+            p_sys->p_context->skip_frame = AVDISCARD_BIDIR;
+            break;
+        case 2:
+            p_sys->p_context->skip_frame = AVDISCARD_NONKEY;
+            break;
+        case 3:
+            p_sys->p_context->skip_frame = AVDISCARD_ALL;
+            break;
+        default:
+            p_sys->p_context->skip_frame = AVDISCARD_NONE;
+            break;
+    }
+    p_sys->i_skip_frame = p_sys->p_context->skip_frame;
+
+    var_Create( p_dec, "ffmpeg-skip-idct",  VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
+    var_Get( p_dec, "ffmpeg-skip-idct", &val );
+    switch( val.i_int )
+    {
+        case -1:
+            p_sys->p_context->skip_idct = AVDISCARD_NONE;
+            break;
+        case 0:
+            p_sys->p_context->skip_idct = AVDISCARD_DEFAULT;
+            break;
+        case 1:
+            p_sys->p_context->skip_idct = AVDISCARD_BIDIR;
+            break;
+        case 2:
+            p_sys->p_context->skip_idct = AVDISCARD_NONKEY;
+            break;
+        case 3:
+            p_sys->p_context->skip_idct = AVDISCARD_ALL;
+            break;
+        default:
+            p_sys->p_context->skip_idct = AVDISCARD_NONE;
+            break;
+    }
+    p_sys->i_skip_idct = p_sys->p_context->skip_idct;
+
     /* ***** ffmpeg direct rendering ***** */
     p_sys->b_direct_rendering = 0;
     var_Create( p_dec, "ffmpeg-dr", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
@@ -335,15 +382,15 @@ int E_(InitVideoDec)( decoder_t *p_dec, AVCodecContext *p_context,
         p_sys->p_context->palctrl = &palette_control;
 
     /* ***** Open the codec ***** */
-    vlc_mutex_lock( lockval.p_address );
+    vlc_mutex_lock( lock );
     if( avcodec_open( p_sys->p_context, p_sys->p_codec ) < 0 )
     {
-        vlc_mutex_unlock( lockval.p_address );
+        vlc_mutex_unlock( lock );
         msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
         free( p_sys );
         return VLC_EGENERIC;
     }
-    vlc_mutex_unlock( lockval.p_address );
+    vlc_mutex_unlock( lock );
     msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );
 
 
@@ -390,8 +437,8 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
         p_sys->i_late_frames = 0;
     }
 
-    if( !p_dec->b_pace_control && p_sys->i_late_frames > 0 &&
-        mdate() - p_sys->i_late_frames_start > I64C(5000000) )
+    if( !p_dec->b_pace_control && (p_sys->i_late_frames > 0) &&
+        (mdate() - p_sys->i_late_frames_start > I64C(5000000)) )
     {
         if( p_sys->i_pts )
         {
@@ -413,21 +460,20 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
         p_block->i_pts = p_block->i_dts = 0;
     }
 
-    /* TODO implement it in a better way */
     /* A good idea could be to decode all I pictures and see for the other */
     if( !p_dec->b_pace_control &&
-        p_sys->b_hurry_up && p_sys->i_late_frames > 4 )
+        p_sys->b_hurry_up &&
+        (p_sys->i_late_frames > 4) )
     {
         b_drawpicture = 0;
         if( p_sys->i_late_frames < 8 )
         {
-            p_sys->p_context->hurry_up = 2;
+            p_sys->p_context->skip_frame = AVDISCARD_NONKEY;
         }
         else
         {
             /* picture too late, won't decode
              * but break picture until a new I, and for mpeg4 ...*/
-
             p_sys->i_late_frames--; /* needed else it will never be decrease */
             block_Release( p_block );
             p_sys->i_buffer = 0;
@@ -436,17 +482,18 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
     }
     else
     {
-        p_sys->p_context->hurry_up = 0;
+        if( p_sys->b_hurry_up )
+            p_sys->p_context->skip_frame = p_sys->i_skip_frame;
         if( !(p_block->i_flags & BLOCK_FLAG_PREROLL) )
             b_drawpicture = 1;
         else
             b_drawpicture = 0;
     }
 
-
     if( p_sys->p_context->width <= 0 || p_sys->p_context->height <= 0 )
     {
-        p_sys->p_context->hurry_up = 5;
+        if( p_sys->b_hurry_up )
+            p_sys->p_context->skip_frame = p_sys->i_skip_frame;
         b_null_size = VLC_TRUE;
     }
 
@@ -493,7 +540,8 @@ picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block )
         {
             /* Reparse it to not drop the I frame */
             b_null_size = VLC_FALSE;
-            p_sys->p_context->hurry_up = 0;
+            if( p_sys->b_hurry_up )
+                p_sys->p_context->skip_frame = p_sys->i_skip_frame;
             i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
                                            &b_gotpicture,
                                            (uint8_t*)p_sys->p_buffer, p_sys->i_buffer );