[FFmpeg-devel] [PATCH] lavc/phtread_frame: update hwaccel_priv_data in time for multithread

Fu, Linjie linjie.fu at intel.com
Wed Jul 24 16:07:22 EEST 2019


> -----Original Message-----
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces at ffmpeg.org] On Behalf
> Of Fu, Linjie
> Sent: Saturday, July 20, 2019 00:32
> To: FFmpeg development discussions and patches <ffmpeg-
> devel at ffmpeg.org>
> Subject: Re: [FFmpeg-devel] [PATCH] lavc/phtread_frame: update
> hwaccel_priv_data in time for multithread
> 
> > -----Original Message-----
> > From: Fu, Linjie
> > Sent: Friday, July 19, 2019 05:35
> > To: ffmpeg-devel at ffmpeg.org
> > Cc: Fu, Linjie <linjie.fu at intel.com>
> > Subject: [PATCH] lavc/phtread_frame: update hwaccel_priv_data in time
> for
> > multithread
> >
> > When resolution/format changes, hwaccel_uninit/hwaccel_init will
> > be called to destroy and re-create the hwaccel_priv_data. When output
> > frame number meets the constraints for vframes, the hwaccel_priv_data
> > modified in decoding thread won't be update to user-thread due to the
> > delay mechanism. It will lead to:
> >     1. memory leak in child-thread.
> >     2. double free in user-thread while calling avcodec_close().
> >
> > Can be reproduced with a resolution change case, and use -vframes
> > to terminate the decode during dynamic resolution changing:
> >
> > ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -v verbose
> > -i ./reinit-large_420_8-to-small_420_8.h264 -pix_fmt nv12 -f rawvideo
> > -vsync passthrough -vframes 45 -y out.yuv
> >
> > The root cause is the conflict between delay mechanism and -vframes.
> > FFmpeg won't output a frame if it's still receiving the initial packets,
> > so there is async between decode process and output. hwaccel_priv_data
> > in user thread won't be updated until the resolution changing
> > frame is output.
> >
> > As user context should reflect the state of the last frame that
> > was output to the user, hwaccel_priv_data should be updated
> > separately from decoding thread in time.
> >
> > Signed-off-by: Linjie Fu <linjie.fu at intel.com>
> > ---
> >  libavcodec/pthread_frame.c | 11 +++++++++--
> >  1 file changed, 9 insertions(+), 2 deletions(-)
> >
> > diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
> > index 36ac0ac..cf7a575 100644
> > --- a/libavcodec/pthread_frame.c
> > +++ b/libavcodec/pthread_frame.c
> > @@ -282,7 +282,6 @@ static int
> > update_context_from_thread(AVCodecContext *dst, AVCodecContext
> *src,
> >          dst->sample_rate    = src->sample_rate;
> >          dst->sample_fmt     = src->sample_fmt;
> >          dst->channel_layout = src->channel_layout;
> > -        dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data;
> >
> >          if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
> >              (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src-
> > >hw_frames_ctx->data)) {
> > @@ -410,6 +409,7 @@ static int submit_packet(PerThreadContext *p,
> > AVCodecContext *user_avctx,
> >              pthread_mutex_unlock(&prev_thread->progress_mutex);
> >          }
> >
> > +        p->avctx->internal->hwaccel_priv_data = prev_thread->avctx-
> > >internal->hwaccel_priv_data;
> >          err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
> >          if (err) {
> >              pthread_mutex_unlock(&p->mutex);
> > @@ -476,7 +476,7 @@ int ff_thread_decode_frame(AVCodecContext
> > *avctx,
> >      FrameThreadContext *fctx = avctx->internal->thread_ctx;
> >      int finished = fctx->next_finished;
> >      PerThreadContext *p;
> > -    int err;
> > +    int err, cur_decoding;
> >
> >      /* release the async lock, permitting blocked hwaccel threads to
> >       * go forward while we are in this function */
> > @@ -544,6 +544,13 @@ int ff_thread_decode_frame(AVCodecContext
> > *avctx,
> >
> >      if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding =
> 0;
> >
> > +    /* update hwaccel_priv_data from decoding thread */
> > +    cur_decoding = fctx->next_decoding - 1;
> > +    if (cur_decoding < 0) cur_decoding += avctx->thread_count;
> > +
> > +    p = &fctx->threads[cur_decoding];
> > +    avctx->internal->hwaccel_priv_data = p->avctx->internal-
> > >hwaccel_priv_data;
> > +
> >      fctx->next_finished = finished;
> >
> >      /* return the size of the consumed packet if no error occurred */
> > --
> > 2.7.4
> 
> 
> Since previous concerns in https://patchwork.ffmpeg.org/patch/13723/
> could be  addressed in this version, ping for comments.
> 
A kind ping, comments are welcome.

-linjie


More information about the ffmpeg-devel mailing list