[vlc-commits] avcodec: use a reference-counted frame

Rémi Denis-Courmont git at videolan.org
Wed Apr 22 20:46:12 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Apr 22 20:16:16 2015 +0300| [9cd84c8409be110fc946911a88a05572ec2886f1] | committer: Rémi Denis-Courmont

avcodec: use a reference-counted frame

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9cd84c8409be110fc946911a88a05572ec2886f1
---

 modules/codec/avcodec/avcommon_compat.h |    5 +++
 modules/codec/avcodec/video.c           |   73 +++++++++++++++----------------
 2 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/modules/codec/avcodec/avcommon_compat.h b/modules/codec/avcodec/avcommon_compat.h
index 77ca979..d58f5b1 100644
--- a/modules/codec/avcodec/avcommon_compat.h
+++ b/modules/codec/avcodec/avcommon_compat.h
@@ -51,6 +51,11 @@ static inline void avcodec_free_context( AVCodecContext **ctx )
 }
 #endif
 
+#if !LIBAVCODEC_VERSION_CHECK( 55, 28, 1, 45, 101 )
+# define av_frame_alloc avcodec_alloc_frame
+# define av_frame_free avcodec_free_frame
+#endif
+
 #endif /* HAVE_LIBAVCODEC_AVCODEC_H */
 
 #ifdef HAVE_LIBAVUTIL_AVUTIL_H
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 7ee0eb8..e34819d 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -52,8 +52,6 @@ struct decoder_sys_t
     /* Video decoder specific part */
     mtime_t i_pts;
 
-    AVFrame          *p_ff_pic;
-
     /* for frame skipping algo */
     bool b_hurry_up;
     enum AVDiscard i_skip_frame;
@@ -321,7 +319,6 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
 
     p_sys->p_context = p_context;
     p_sys->p_codec = p_codec;
-    p_sys->p_ff_pic = avcodec_alloc_frame();
     p_sys->b_delayed_open = true;
     p_sys->p_va = NULL;
     vlc_sem_init( &p_sys->sem_mt, 0 );
@@ -402,6 +399,7 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
     /* Always use our get_buffer wrapper so we can calculate the
      * PTS correctly */
     p_context->get_buffer2 = lavc_GetFrame;
+    p_context->refcounted_frames = true;
     p_context->opaque = p_dec;
 
 #ifdef HAVE_AVCODEC_MT
@@ -491,7 +489,6 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
     /* ***** Open the codec ***** */
     if( OpenVideoCodec( p_dec ) < 0 )
     {
-        avcodec_free_frame( &p_sys->p_ff_pic );
         vlc_sem_destroy( &p_sys->sem_mt );
         free( p_sys );
         return VLC_EGENERIC;
@@ -650,6 +647,13 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         int i_used, b_gotpicture;
         AVPacket pkt;
 
+        AVFrame *frame = av_frame_alloc();
+        if (unlikely(frame == NULL))
+        {
+            p_dec->b_error = true;
+            break;
+        }
+
         post_mt( p_sys );
 
         av_init_packet( &pkt );
@@ -683,8 +687,8 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
             p_block->i_dts = VLC_TS_INVALID;
         }
 
-        i_used = avcodec_decode_video2( p_context, p_sys->p_ff_pic,
-                                       &b_gotpicture, &pkt );
+        i_used = avcodec_decode_video2( p_context, frame, &b_gotpicture,
+                                        &pkt );
         av_free_packet( &pkt );
 
         wait_mt( p_sys );
@@ -699,6 +703,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
 
             if( i_used < 0 )
             {
+                av_frame_unref(frame);
                 if( b_drawpicture )
                     msg_Warn( p_dec, "cannot decode one frame (%zu bytes)",
                             p_block->i_buffer );
@@ -719,21 +724,21 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         /* Nothing to display */
         if( !b_gotpicture )
         {
+            av_frame_unref(frame);
             if( i_used == 0 ) break;
             continue;
         }
 
         /* Sanity check (seems to be needed for some streams) */
-        if( p_sys->p_ff_pic->pict_type == AV_PICTURE_TYPE_B)
+        if( frame->pict_type == AV_PICTURE_TYPE_B)
         {
             p_sys->b_has_b_frames = true;
         }
 
         /* Compute the PTS */
-        mtime_t i_pts =
-                    p_sys->p_ff_pic->pkt_pts;
+        mtime_t i_pts = frame->pkt_pts;
         if (i_pts <= VLC_TS_INVALID)
-            i_pts = p_sys->p_ff_pic->pkt_dts;
+            i_pts = frame->pkt_dts;
 
         if( i_pts <= VLC_TS_INVALID )
             i_pts = p_sys->i_pts;
@@ -747,8 +752,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
             if( p_dec->fmt_in.video.i_frame_rate > 0 &&
                 p_dec->fmt_in.video.i_frame_rate_base > 0 )
             {
-                p_sys->i_pts += CLOCK_FREQ *
-                    (2 + p_sys->p_ff_pic->repeat_pict) *
+                p_sys->i_pts += CLOCK_FREQ * (2 + frame->repeat_pict) *
                     p_dec->fmt_in.video.i_frame_rate_base /
                     (2 * p_dec->fmt_in.video.i_frame_rate);
             }
@@ -758,8 +762,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
                 if( i_tick <= 0 )
                     i_tick = 1;
 
-                p_sys->i_pts += CLOCK_FREQ *
-                    (2 + p_sys->p_ff_pic->repeat_pict) *
+                p_sys->i_pts += CLOCK_FREQ * (2 + frame->repeat_pict) *
                     i_tick * p_context->time_base.num /
                     (2 * p_context->time_base.den);
             }
@@ -781,10 +784,13 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
             p_sys->i_late_frames = 0;
         }
 
-        if( !b_drawpicture || ( !p_sys->p_va && !p_sys->p_ff_pic->linesize[0] ) )
+        if( !b_drawpicture || ( !p_sys->p_va && !frame->linesize[0] ) )
+        {
+            av_frame_unref(frame);
             continue;
+        }
 
-        picture_t *p_pic = p_sys->p_ff_pic->opaque;
+        picture_t *p_pic = frame->opaque;
         if( p_pic == NULL )
         {
             /* Get a new picture */
@@ -792,18 +798,19 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
                 p_pic = ffmpeg_NewPictBuf( p_dec, p_context );
             if( !p_pic )
             {
+                av_frame_unref(frame);
                 if( p_block )
                     block_Release( p_block );
                 return NULL;
             }
 
             /* Fill picture_t from AVFrame */
-            lavc_CopyPicture(p_dec, p_pic, p_sys->p_ff_pic);
+            lavc_CopyPicture(p_dec, p_pic, frame);
         }
         else
         {
             if( p_sys->p_va != NULL )
-                vlc_va_Extract( p_sys->p_va, p_pic, p_sys->p_ff_pic->data[3] );
+                vlc_va_Extract( p_sys->p_va, p_pic, frame->data[3] );
             picture_Hold( p_pic );
         }
 
@@ -822,28 +829,23 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
             }
         }
 
-        /* Send decoded frame to vout */
-        if( i_pts > VLC_TS_INVALID)
-        {
-            p_pic->date = i_pts;
+        p_pic->date = i_pts;
+        /* Hack to force display of still pictures */
+        p_pic->b_force = p_sys->b_first_frame;
+        p_pic->i_nb_fields = 2 + frame->repeat_pict;
+        p_pic->b_progressive = !frame->interlaced_frame;
+        p_pic->b_top_field_first = frame->top_field_first;
 
-            if( p_sys->b_first_frame )
-            {
-                /* Hack to force display of still pictures */
-                p_sys->b_first_frame = false;
-                p_pic->b_force = true;
-            }
-
-            p_pic->i_nb_fields = 2 + p_sys->p_ff_pic->repeat_pict;
-            p_pic->b_progressive = !p_sys->p_ff_pic->interlaced_frame;
-            p_pic->b_top_field_first = p_sys->p_ff_pic->top_field_first;
+        av_frame_unref(frame);
 
+        /* Send decoded frame to vout */
+        if (i_pts > VLC_TS_INVALID)
+        {
+            p_sys->b_first_frame = false;
             return p_pic;
         }
         else
-        {
             picture_Release( p_pic );
-        }
     }
 
     if( p_block )
@@ -871,9 +873,6 @@ void EndVideoDec( decoder_t *p_dec )
 
     ffmpeg_CloseCodec( p_dec );
 
-    if( p_sys->p_ff_pic )
-        avcodec_free_frame( &p_sys->p_ff_pic );
-
     if( p_sys->p_va )
         vlc_va_Delete( p_sys->p_va, p_sys->p_context );
 



More information about the vlc-commits mailing list