On Sun, Sep 30, 2018 at 11:14 AM Zhong Li <zhong...@intel.com> wrote:
> Libmfx requires 16 bytes aligned input/output for uploading. > Currently only output is 16 byte aligned and assigning same width/height to > input with smaller buffer size actually, thus definitely will cause > segment fault. > > Can reproduce with any 1080p nv12 rawvideo input: > ffmpeg -init_hw_device qsv=qsv:hw -hwaccel qsv -filter_hw_device qsv -f > rawvideo -pix_fmt nv12 -s:v 1920x1080 > -i 1080p_nv12.yuv -vf > 'format=nv12,hwupload=extra_hw_frames=16,hwdownload,format=nv12' -an -y > out_nv12.yuv > > It can fix #7418 > > Signed-off-by: Zhong Li <zhong...@intel.com> > --- > libavutil/hwcontext_qsv.c | 31 +++++++++++++++++++++++++++++-- > 1 file changed, 29 insertions(+), 2 deletions(-) > > diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c > index 33e121b..3039cfa 100644 > --- a/libavutil/hwcontext_qsv.c > +++ b/libavutil/hwcontext_qsv.c > @@ -862,6 +862,10 @@ static int qsv_transfer_data_to(AVHWFramesContext > *ctx, AVFrame *dst, > mfxSyncPoint sync = NULL; > mfxStatus err; > int ret = 0; > + /* make a copy if the input is not padded as libmfx requires */ > + AVFrame tmp_frame, *src_frame; > + int realigned = 0; > + > > while (!s->session_upload_init && !s->session_upload && !ret) { > #if HAVE_PTHREADS > @@ -887,16 +891,36 @@ static int qsv_transfer_data_to(AVHWFramesContext > *ctx, AVFrame *dst, > if (ret < 0) > return ret; > > + > + if (src->height & 16 || src->linesize[0] & 16) { > + realigned = 1; > + memset(&tmp_frame, 0, sizeof(tmp_frame)); > + tmp_frame.format = src->format; > + tmp_frame.width = FFALIGN(src->width, 16); > + tmp_frame.height = FFALIGN(src->height, 16); > + ret = av_frame_get_buffer(&tmp_frame, 32); > + if (ret < 0) > + return ret; > + > + ret = av_frame_copy(&tmp_frame, src); > + if (ret < 0) { > + av_frame_unref(&tmp_frame); > + return ret; > + } > + } > + > + src_frame = realigned ? &tmp_frame : src; > + > if (!s->session_upload) { > if (s->child_frames_ref) > - return qsv_transfer_data_child(ctx, dst, src); > + return qsv_transfer_data_child(ctx, dst, src_frame); > > av_log(ctx, AV_LOG_ERROR, "Surface upload not possible\n"); > return AVERROR(ENOSYS); > } > > in.Info = out->Info; > - map_frame_to_surface(src, &in); > + map_frame_to_surface(src_frame, &in); > > do { > err = MFXVideoVPP_RunFrameVPPAsync(s->session_upload, &in, out, > NULL, &sync); > @@ -917,6 +941,9 @@ static int qsv_transfer_data_to(AVHWFramesContext > *ctx, AVFrame *dst, > return AVERROR_UNKNOWN; > } > > + if (realigned) > + av_frame_unref(&tmp_frame); > + > return 0; > } > > -- > 2.7.4 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel LGTM regards Max _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel