[FFmpeg-devel] [PATCH v2] lavfi/qsvvpp: support async depth
Linjie Fu
linjie.justin.fu at gmail.com
Sun Mar 21 12:10:10 EET 2021
Hi Fei,
On Mon, Mar 15, 2021 at 1:13 PM Fei Wang <fei.w.wang at intel.com> wrote:
>
> Async depth will allow qsv filter cache few frames, and avoid force
> switch and end filter task frame by frame. This change will improve
> performance for some multi-task case, for example 1:N transcode(
> decode + vpp + encode) with all QSV plugins.
Async depth support for qsv vpp is valuable for the performance of
whole qsv pipeline, since both decoding/encoding have already
supported the async_depth.
Hence, would you please help to elaborate more about the details about
the performance improvement for the whole pipeline?
(For examples, before/after this patch, cmdline, platform and the fps ...)
> Signed-off-by: Fei Wang <fei.w.wang at intel.com>
> ---
> Change: combine used and queued into queued in QSVFrame.
>
> libavfilter/qsvvpp.c | 153 ++++++++++++++++++-------------
> libavfilter/qsvvpp.h | 41 ++++++++-
> libavfilter/vf_deinterlace_qsv.c | 14 +--
> libavfilter/vf_vpp_qsv.c | 75 ++++++++++++---
> 4 files changed, 193 insertions(+), 90 deletions(-)
>
> diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
> index f216b3f248..e7c7a12cfa 100644
> --- a/libavfilter/qsvvpp.c
> +++ b/libavfilter/qsvvpp.c
> @@ -27,6 +27,7 @@
> #include "libavutil/hwcontext_qsv.h"
> #include "libavutil/time.h"
> #include "libavutil/pixdesc.h"
> +#include "libavutil/fifo.h"
This seems to be redundant, since you're adding fifo.h in qsvvpp.h as well.
> #include "internal.h"
> #include "qsvvpp.h"
> @@ -37,37 +38,6 @@
> #define IS_OPAQUE_MEMORY(mode) (mode & MFX_MEMTYPE_OPAQUE_FRAME)
> #define IS_SYSTEM_MEMORY(mode) (mode & MFX_MEMTYPE_SYSTEM_MEMORY)
>
> -typedef struct QSVFrame {
> - AVFrame *frame;
> - mfxFrameSurface1 *surface;
> - mfxFrameSurface1 surface_internal; /* for system memory */
> - struct QSVFrame *next;
> -} QSVFrame;
> -
> -/* abstract struct for all QSV filters */
> -struct QSVVPPContext {
> - mfxSession session;
> - int (*filter_frame) (AVFilterLink *outlink, AVFrame *frame);/* callback */
> - enum AVPixelFormat out_sw_format; /* Real output format */
> - mfxVideoParam vpp_param;
> - mfxFrameInfo *frame_infos; /* frame info for each input */
> -
> - /* members related to the input/output surface */
> - int in_mem_mode;
> - int out_mem_mode;
> - QSVFrame *in_frame_list;
> - QSVFrame *out_frame_list;
> - int nb_surface_ptrs_in;
> - int nb_surface_ptrs_out;
> - mfxFrameSurface1 **surface_ptrs_in;
> - mfxFrameSurface1 **surface_ptrs_out;
> -
> - /* MFXVPP extern parameters */
> - mfxExtOpaqueSurfaceAlloc opaque_alloc;
> - mfxExtBuffer **ext_buffers;
> - int nb_ext_buffers;
> -};
> -
> static const mfxHandleType handle_types[] = {
> MFX_HANDLE_VA_DISPLAY,
> MFX_HANDLE_D3D9_DEVICE_MANAGER,
> @@ -336,9 +306,11 @@ static int fill_frameinfo_by_link(mfxFrameInfo *frameinfo, AVFilterLink *link)
> static void clear_unused_frames(QSVFrame *list)
> {
> while (list) {
> - if (list->surface && !list->surface->Data.Locked) {
> - list->surface = NULL;
> + /* list->queued==1 means the frame is not cached in VPP
> + * process any more, it can be released to pool. */
> + if ((list->queued == 1) && !list->surface.Data.Locked) {
> av_frame_free(&list->frame);
> + list->queued = 0;
> }
> list = list->next;
> }
> @@ -361,8 +333,10 @@ static QSVFrame *get_free_frame(QSVFrame **list)
> QSVFrame *out = *list;
>
> for (; out; out = out->next) {
> - if (!out->surface)
> + if (!out->queued) {
> + out->queued = 1;
> break;
> + }
> }
>
> if (!out) {
> @@ -371,8 +345,9 @@ static QSVFrame *get_free_frame(QSVFrame **list)
> av_log(NULL, AV_LOG_ERROR, "Can't alloc new output frame.\n");
> return NULL;
> }
> - out->next = *list;
> - *list = out;
> + out->queued = 1;
> + out->next = *list;
> + *list = out;
> }
>
> return out;
> @@ -402,7 +377,7 @@ static QSVFrame *submit_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *p
> return NULL;
> }
> qsv_frame->frame = av_frame_clone(picref);
> - qsv_frame->surface = (mfxFrameSurface1 *)qsv_frame->frame->data[3];
> + qsv_frame->surface = *(mfxFrameSurface1 *)qsv_frame->frame->data[3];
The type of surface in struct QSVFrame would be changed fron
*mfxFrameSurface1 to mfxFrameSurface1, and surface_internal would be
removed.
IMO separating the related changes for the structures into a single
commit would make it more explicit, since it's not closely related
with the implemetation of async fifo.
- linjie
More information about the ffmpeg-devel
mailing list