Message ID | 20220208030549.340748-1-wenbin.chen@intel.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,V3,1/3] libavcodec/vaapi_encode: Add new API adaption to vaapi_encode | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
andriy/make_ppc | success | Make finished |
andriy/make_fate_ppc | success | Make fate finished |
On Tue, 2022-02-08 at 11:05 +0800, Wenbin Chen wrote: > Add vaSyncBuffer to VAAPI encoder. Old version API vaSyncSurface wait > surface to complete. When surface is used for multiple operation, it > waits all operations to finish. vaSyncBuffer only wait one channel to > finish. > > Add wait param to vaapi_encode_wait() to prepare for the async_depth > option. "wait=1" means wait until operation ready. "wait=0" means > query operation's status. If it is ready return 0, if it is still > in progress return EAGAIN. > > Signed-off-by: Wenbin Chen <wenbin.chen@intel.com> > --- > libavcodec/vaapi_encode.c | 47 +++++++++++++++++++++++++++++++++------ > 1 file changed, 40 insertions(+), 7 deletions(-) > > diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c > index 3bf379b1a0..b87b58a42b 100644 > --- a/libavcodec/vaapi_encode.c > +++ b/libavcodec/vaapi_encode.c > @@ -134,7 +134,8 @@ static int > vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx, > } > > static int vaapi_encode_wait(AVCodecContext *avctx, > - VAAPIEncodePicture *pic) > + VAAPIEncodePicture *pic, > + uint8_t wait) > { > VAAPIEncodeContext *ctx = avctx->priv_data; > VAStatus vas; > @@ -150,11 +151,43 @@ static int vaapi_encode_wait(AVCodecContext *avctx, > "(input surface %#x).\n", pic->display_order, > pic->encode_order, pic->input_surface); > > - vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface); > - if (vas != VA_STATUS_SUCCESS) { > - av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: " > - "%d (%s).\n", vas, vaErrorStr(vas)); > +#if VA_CHECK_VERSION(1, 9, 0) > + // Try vaSyncBuffer. > + vas = vaSyncBuffer(ctx->hwctx->display, > + pic->output_buffer, > + wait ? VA_TIMEOUT_INFINITE : 0); > + if (vas == VA_STATUS_ERROR_TIMEDOUT) { > + return AVERROR(EAGAIN); > + } else if (vas != VA_STATUS_SUCCESS && vas != > VA_STATUS_ERROR_UNIMPLEMENTED) { > + av_log(avctx, AV_LOG_ERROR, "Failed to sync to output buffer > completion: " > + "%d (%s).\n", vas, vaErrorStr(vas)); > return AVERROR(EIO); We may add has_sync_buffer_func flag in this patch, and run the above code when ctx->has_sync_buffer_func is true. If so, we needn't check whether vaSyncBuffer is implemented again. Thanks Haihao > + } else if (vas == VA_STATUS_ERROR_UNIMPLEMENTED) > + // If vaSyncBuffer is not implemented, try old version API. > +#endif > + { > + if (!wait) { > + VASurfaceStatus surface_status; > + vas = vaQuerySurfaceStatus(ctx->hwctx->display, > + pic->input_surface, > + &surface_status); > + if (vas == VA_STATUS_SUCCESS && > + surface_status != VASurfaceReady && > + surface_status != VASurfaceSkipped) { > + return AVERROR(EAGAIN); > + } else if (vas != VA_STATUS_SUCCESS) { > + av_log(avctx, AV_LOG_ERROR, "Failed to query surface status: > " > + "%d (%s).\n", vas, vaErrorStr(vas)); > + return AVERROR(EIO); > + } > + } else { > + vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface); > + if (vas != VA_STATUS_SUCCESS) { > + av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture > completion: " > + "%d (%s).\n", vas, vaErrorStr(vas)); > + return AVERROR(EIO); > + } > + } > } > > // Input is definitely finished with now. > @@ -633,7 +666,7 @@ static int vaapi_encode_output(AVCodecContext *avctx, > uint8_t *ptr; > int err; > > - err = vaapi_encode_wait(avctx, pic); > + err = vaapi_encode_wait(avctx, pic, 1); > if (err < 0) > return err; > > @@ -695,7 +728,7 @@ fail: > static int vaapi_encode_discard(AVCodecContext *avctx, > VAAPIEncodePicture *pic) > { > - vaapi_encode_wait(avctx, pic); > + vaapi_encode_wait(avctx, pic, 1); > > if (pic->output_buffer_ref) { > av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
> On Tue, 2022-02-08 at 11:05 +0800, Wenbin Chen wrote: > > Add vaSyncBuffer to VAAPI encoder. Old version API vaSyncSurface wait > > surface to complete. When surface is used for multiple operation, it > > waits all operations to finish. vaSyncBuffer only wait one channel to > > finish. > > > > Add wait param to vaapi_encode_wait() to prepare for the async_depth > > option. "wait=1" means wait until operation ready. "wait=0" means > > query operation's status. If it is ready return 0, if it is still > > in progress return EAGAIN. > > > > Signed-off-by: Wenbin Chen <wenbin.chen@intel.com> > > --- > > libavcodec/vaapi_encode.c | 47 +++++++++++++++++++++++++++++++++--- > --- > > 1 file changed, 40 insertions(+), 7 deletions(-) > > > > diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c > > index 3bf379b1a0..b87b58a42b 100644 > > --- a/libavcodec/vaapi_encode.c > > +++ b/libavcodec/vaapi_encode.c > > @@ -134,7 +134,8 @@ static int > > vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx, > > } > > > > static int vaapi_encode_wait(AVCodecContext *avctx, > > - VAAPIEncodePicture *pic) > > + VAAPIEncodePicture *pic, > > + uint8_t wait) > > { > > VAAPIEncodeContext *ctx = avctx->priv_data; > > VAStatus vas; > > @@ -150,11 +151,43 @@ static int vaapi_encode_wait(AVCodecContext > *avctx, > > "(input surface %#x).\n", pic->display_order, > > pic->encode_order, pic->input_surface); > > > > - vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface); > > - if (vas != VA_STATUS_SUCCESS) { > > - av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: " > > - "%d (%s).\n", vas, vaErrorStr(vas)); > > +#if VA_CHECK_VERSION(1, 9, 0) > > + // Try vaSyncBuffer. > > + vas = vaSyncBuffer(ctx->hwctx->display, > > + pic->output_buffer, > > + wait ? VA_TIMEOUT_INFINITE : 0); > > + if (vas == VA_STATUS_ERROR_TIMEDOUT) { > > + return AVERROR(EAGAIN); > > + } else if (vas != VA_STATUS_SUCCESS && vas != > > VA_STATUS_ERROR_UNIMPLEMENTED) { > > + av_log(avctx, AV_LOG_ERROR, "Failed to sync to output buffer > > completion: " > > + "%d (%s).\n", vas, vaErrorStr(vas)); > > return AVERROR(EIO); > > We may add has_sync_buffer_func flag in this patch, and run the above code > when > ctx->has_sync_buffer_func is true. If so, we needn't check whether > vaSyncBuffer > is implemented again. > > Thanks > Haihao Thanks for your review. I will update the patchset. Thanks Wenbin > > > > + } else if (vas == VA_STATUS_ERROR_UNIMPLEMENTED) > > + // If vaSyncBuffer is not implemented, try old version API. > > +#endif > > + { > > + if (!wait) { > > + VASurfaceStatus surface_status; > > + vas = vaQuerySurfaceStatus(ctx->hwctx->display, > > + pic->input_surface, > > + &surface_status); > > + if (vas == VA_STATUS_SUCCESS && > > + surface_status != VASurfaceReady && > > + surface_status != VASurfaceSkipped) { > > + return AVERROR(EAGAIN); > > + } else if (vas != VA_STATUS_SUCCESS) { > > + av_log(avctx, AV_LOG_ERROR, "Failed to query surface status: > > " > > + "%d (%s).\n", vas, vaErrorStr(vas)); > > + return AVERROR(EIO); > > + } > > + } else { > > + vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface); > > + if (vas != VA_STATUS_SUCCESS) { > > + av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture > > completion: " > > + "%d (%s).\n", vas, vaErrorStr(vas)); > > + return AVERROR(EIO); > > + } > > + } > > } > > > > // Input is definitely finished with now. > > @@ -633,7 +666,7 @@ static int vaapi_encode_output(AVCodecContext > *avctx, > > uint8_t *ptr; > > int err; > > > > - err = vaapi_encode_wait(avctx, pic); > > + err = vaapi_encode_wait(avctx, pic, 1); > > if (err < 0) > > return err; > > > > @@ -695,7 +728,7 @@ fail: > > static int vaapi_encode_discard(AVCodecContext *avctx, > > VAAPIEncodePicture *pic) > > { > > - vaapi_encode_wait(avctx, pic); > > + vaapi_encode_wait(avctx, pic, 1); > > > > if (pic->output_buffer_ref) { > > av_log(avctx, AV_LOG_DEBUG, "Discard output for pic " > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 3bf379b1a0..b87b58a42b 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -134,7 +134,8 @@ static int vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx, } static int vaapi_encode_wait(AVCodecContext *avctx, - VAAPIEncodePicture *pic) + VAAPIEncodePicture *pic, + uint8_t wait) { VAAPIEncodeContext *ctx = avctx->priv_data; VAStatus vas; @@ -150,11 +151,43 @@ static int vaapi_encode_wait(AVCodecContext *avctx, "(input surface %#x).\n", pic->display_order, pic->encode_order, pic->input_surface); - vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface); - if (vas != VA_STATUS_SUCCESS) { - av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: " - "%d (%s).\n", vas, vaErrorStr(vas)); +#if VA_CHECK_VERSION(1, 9, 0) + // Try vaSyncBuffer. + vas = vaSyncBuffer(ctx->hwctx->display, + pic->output_buffer, + wait ? VA_TIMEOUT_INFINITE : 0); + if (vas == VA_STATUS_ERROR_TIMEDOUT) { + return AVERROR(EAGAIN); + } else if (vas != VA_STATUS_SUCCESS && vas != VA_STATUS_ERROR_UNIMPLEMENTED) { + av_log(avctx, AV_LOG_ERROR, "Failed to sync to output buffer completion: " + "%d (%s).\n", vas, vaErrorStr(vas)); return AVERROR(EIO); + } else if (vas == VA_STATUS_ERROR_UNIMPLEMENTED) + // If vaSyncBuffer is not implemented, try old version API. +#endif + { + if (!wait) { + VASurfaceStatus surface_status; + vas = vaQuerySurfaceStatus(ctx->hwctx->display, + pic->input_surface, + &surface_status); + if (vas == VA_STATUS_SUCCESS && + surface_status != VASurfaceReady && + surface_status != VASurfaceSkipped) { + return AVERROR(EAGAIN); + } else if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query surface status: " + "%d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + } else { + vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: " + "%d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + } } // Input is definitely finished with now. @@ -633,7 +666,7 @@ static int vaapi_encode_output(AVCodecContext *avctx, uint8_t *ptr; int err; - err = vaapi_encode_wait(avctx, pic); + err = vaapi_encode_wait(avctx, pic, 1); if (err < 0) return err; @@ -695,7 +728,7 @@ fail: static int vaapi_encode_discard(AVCodecContext *avctx, VAAPIEncodePicture *pic) { - vaapi_encode_wait(avctx, pic); + vaapi_encode_wait(avctx, pic, 1); if (pic->output_buffer_ref) { av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
Add vaSyncBuffer to VAAPI encoder. Old version API vaSyncSurface wait surface to complete. When surface is used for multiple operation, it waits all operations to finish. vaSyncBuffer only wait one channel to finish. Add wait param to vaapi_encode_wait() to prepare for the async_depth option. "wait=1" means wait until operation ready. "wait=0" means query operation's status. If it is ready return 0, if it is still in progress return EAGAIN. Signed-off-by: Wenbin Chen <wenbin.chen@intel.com> --- libavcodec/vaapi_encode.c | 47 +++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 7 deletions(-)