]> git.sesse.net Git - vlc/blobdiff - modules/codec/avcodec/video.c
avcodec: adjust MT contention scope
[vlc] / modules / codec / avcodec / video.c
index 98a568504c567ec58765426e46c35b088fa3e8d3..7d7a2fcfa27e5e721473dc74c75e66aa72e2d6cc 100644 (file)
@@ -767,13 +767,12 @@ void EndVideoDec( decoder_t *p_dec )
 
     wait_mt( p_sys );
 
-    if( p_sys->p_ff_pic ) av_free( p_sys->p_ff_pic );
+    if( p_sys->p_ff_pic )
+        av_free( p_sys->p_ff_pic );
 
     if( p_sys->p_va )
-    {
         vlc_va_Delete( p_sys->p_va );
-        p_sys->p_va = NULL;
-    }
+
     vlc_sem_destroy( &p_sys->sem_mt );
 }
 
@@ -911,34 +910,11 @@ static int ffmpeg_va_GetFrameBuf( struct AVCodecContext *p_context, AVFrame *p_f
     return 0;
 }
 
-/*****************************************************************************
- * ffmpeg_GetFrameBuf: callback used by ffmpeg to get a frame buffer.
- *****************************************************************************
- * It is used for direct rendering as well as to get the right PTS for each
- * decoded picture (even in indirect rendering mode).
- *****************************************************************************/
-static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
-                               AVFrame *p_ff_pic )
+static picture_t *ffmpeg_dr_GetFrameBuf(struct AVCodecContext *p_context)
 {
     decoder_t *p_dec = (decoder_t *)p_context->opaque;
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    /* */
-    p_ff_pic->opaque = NULL;
-#if LIBAVCODEC_VERSION_MAJOR < 54
-    p_ff_pic->age = 256*256*256*64;
-#endif
-
-    if( p_sys->p_va )
-        return ffmpeg_va_GetFrameBuf(p_context, p_ff_pic);
-
-    if( !p_sys->b_direct_rendering )
-        return avcodec_default_get_buffer( p_context, p_ff_pic );
-
-    wait_mt( p_sys );
-    /* Some codecs set pix_fmt only after the 1st frame has been decoded,
-     * so we need to check for direct rendering again. */
-
     int i_width = p_context->width;
     int i_height = p_context->height;
     avcodec_align_dimensions( p_context, &i_width, &i_height );
@@ -989,13 +965,65 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
             goto no_dr;
     }
 
-    if( p_sys->i_direct_rendering_used != 1 )
-    {
+    return p_pic;
+
+no_dr:
+    if (p_pic)
+        decoder_DeletePicture( p_dec, p_pic );
+
+    return NULL;
+}
+
+/*****************************************************************************
+ * ffmpeg_GetFrameBuf: callback used by ffmpeg to get a frame buffer.
+ *****************************************************************************
+ * It is used for direct rendering as well as to get the right PTS for each
+ * decoded picture (even in indirect rendering mode).
+ *****************************************************************************/
+static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
+                               AVFrame *p_ff_pic )
+{
+    decoder_t *p_dec = (decoder_t *)p_context->opaque;
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    /* */
+    p_ff_pic->opaque = NULL;
+#if ! LIBAVCODEC_VERSION_CHECK(54, 34, 0, 79, 101)
+    p_ff_pic->pkt_pts = p_context->pkt ? p_context->pkt->pts : AV_NOPTS_VALUE;
+#endif
+#if LIBAVCODEC_VERSION_MAJOR < 54
+    p_ff_pic->age = 256*256*256*64;
+#endif
+
+    if( p_sys->p_va )
+        return ffmpeg_va_GetFrameBuf(p_context, p_ff_pic);
+
+    if( !p_sys->b_direct_rendering )
+        return avcodec_default_get_buffer( p_context, p_ff_pic );
+
+    wait_mt( p_sys );
+    /* Some codecs set pix_fmt only after the 1st frame has been decoded,
+     * so we need to check for direct rendering again. */
+
+    picture_t *p_pic = ffmpeg_dr_GetFrameBuf(p_context);
+    if (!p_pic) {
+        if( p_sys->i_direct_rendering_used != 0 )
+        {
+            msg_Warn( p_dec, "disabling direct rendering" );
+            p_sys->i_direct_rendering_used = 0;
+        }
+
+        post_mt( p_sys );
+        return avcodec_default_get_buffer( p_context, p_ff_pic );
+    }
+
+    if( p_sys->i_direct_rendering_used != 1 ) {
         msg_Dbg( p_dec, "using direct rendering" );
         p_sys->i_direct_rendering_used = 1;
     }
 
     p_context->draw_horiz_band = NULL;
+    post_mt( p_sys );
 
     p_ff_pic->opaque = (void*)p_pic;
     p_ff_pic->type = FF_BUFFER_TYPE_USER;
@@ -1009,20 +1037,7 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
     p_ff_pic->linesize[2] = p_pic->p[2].i_pitch;
     p_ff_pic->linesize[3] = 0;
 
-    post_mt( p_sys );
     return 0;
-
-no_dr:
-    if (p_pic)
-        decoder_DeletePicture( p_dec, p_pic );
-
-    if( p_sys->i_direct_rendering_used != 0 )
-    {
-        msg_Warn( p_dec, "disabling direct rendering" );
-        p_sys->i_direct_rendering_used = 0;
-    }
-    post_mt( p_sys );
-    return avcodec_default_get_buffer( p_context, p_ff_pic );
 }
 
 static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,