X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_deinterlace_qsv.c;h=3c2d87c7c84bb822828e1f374e8967c05f82b98b;hb=a04ad248a05e7b613abe09b3bb067f555108d794;hp=c9e76c6056a1a8157fc87ba8e48a2749563ebf46;hpb=b4ca32414ea28ad29b4bd387c298f5a676dace2a;p=ffmpeg diff --git a/libavfilter/vf_deinterlace_qsv.c b/libavfilter/vf_deinterlace_qsv.c index c9e76c6056a..3c2d87c7c84 100644 --- a/libavfilter/vf_deinterlace_qsv.c +++ b/libavfilter/vf_deinterlace_qsv.c @@ -47,14 +47,6 @@ enum { QSVDEINT_MORE_INPUT, }; -typedef struct QSVFrame { - AVFrame *frame; - mfxFrameSurface1 surface; - int used; - - struct QSVFrame *next; -} QSVFrame; - typedef struct QSVDeintContext { const AVClass *class; @@ -83,7 +75,7 @@ typedef struct QSVDeintContext { int mode; } QSVDeintContext; -static void qsvdeint_uninit(AVFilterContext *ctx) +static av_cold void qsvdeint_uninit(AVFilterContext *ctx) { QSVDeintContext *s = ctx->priv; QSVFrame *cur; @@ -202,11 +194,20 @@ static int init_out_session(AVFilterContext *ctx) } } + if (err < 0) + return ff_qsvvpp_print_error(ctx, err, "Error getting the session handle"); + else if (err > 0) { + ff_qsvvpp_print_warning(ctx, err, "Warning in getting the session handle"); + return AVERROR_UNKNOWN; + } + /* create a "slave" session with those same properties, to be used for * actual deinterlacing */ err = MFXInit(impl, &ver, &s->session); - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error initializing a session for deinterlacing\n"); + if (err < 0) + return ff_qsvvpp_print_error(ctx, err, "Error initializing a session for deinterlacing"); + else if (err > 0) { + ff_qsvvpp_print_warning(ctx, err, "Warning in session initialization"); return AVERROR_UNKNOWN; } @@ -304,9 +305,17 @@ static int init_out_session(AVFilterContext *ctx) par.vpp.Out.FrameRateExtD = ctx->outputs[0]->time_base.den; } + /* Print input memory mode */ + ff_qsvvpp_print_iopattern(ctx, par.IOPattern & 0x0F, "VPP"); + /* Print output memory mode */ + ff_qsvvpp_print_iopattern(ctx, par.IOPattern & 0xF0, "VPP"); err = MFXVideoVPP_Init(s->session, &par); - if (err != MFX_ERR_NONE) { - av_log(ctx, AV_LOG_ERROR, "Error opening the VPP for deinterlacing: %d\n", err); + if (err < 0) + return ff_qsvvpp_print_error(ctx, err, + "Error opening the VPP for deinterlacing"); + else if (err > 0) { + ff_qsvvpp_print_warning(ctx, err, + "Warning in VPP initialization"); return AVERROR_UNKNOWN; } @@ -359,7 +368,7 @@ static void clear_unused_frames(QSVDeintContext *s) while (cur) { if (!cur->surface.Data.Locked) { av_frame_free(&cur->frame); - cur->used = 0; + cur->queued = 0; } cur = cur->next; } @@ -374,7 +383,7 @@ static int get_free_frame(QSVDeintContext *s, QSVFrame **f) frame = s->work_frames; last = &s->work_frames; while (frame) { - if (!frame->used) { + if (!frame->queued) { *f = frame; return 0; } @@ -414,9 +423,11 @@ static int submit_frame(AVFilterContext *ctx, AVFrame *frame, qf->surface.Info.PicStruct = !qf->frame->interlaced_frame ? MFX_PICSTRUCT_PROGRESSIVE : (qf->frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF : MFX_PICSTRUCT_FIELD_BFF); - if (qf->frame->repeat_pict == 1) + if (qf->frame->repeat_pict == 1) { qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FIELD_REPEATED; - else if (qf->frame->repeat_pict == 2) + qf->surface.Info.PicStruct |= qf->frame->top_field_first ? MFX_PICSTRUCT_FIELD_TFF : + MFX_PICSTRUCT_FIELD_BFF; + } else if (qf->frame->repeat_pict == 2) qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING; else if (qf->frame->repeat_pict == 4) qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING; @@ -434,7 +445,7 @@ static int submit_frame(AVFilterContext *ctx, AVFrame *frame, (AVRational){1, 90000}); *surface = &qf->surface; - qf->used = 1; + qf->queued = 1; return 0; } @@ -475,8 +486,13 @@ static int process_frame(AVFilterContext *ctx, const AVFrame *in, return QSVDEINT_MORE_INPUT; } - if ((err < 0 && err != MFX_ERR_MORE_SURFACE) || !sync) { - av_log(ctx, AV_LOG_ERROR, "Error during deinterlacing: %d\n", err); + if (err < 0 && err != MFX_ERR_MORE_SURFACE) { + ret = ff_qsvvpp_print_error(ctx, err, "Error during deinterlacing"); + goto fail; + } + + if (!sync) { + av_log(ctx, AV_LOG_ERROR, "No sync during deinterlacing\n"); ret = AVERROR_UNKNOWN; goto fail; } @@ -487,8 +503,7 @@ static int process_frame(AVFilterContext *ctx, const AVFrame *in, err = MFXVideoCORE_SyncOperation(s->session, sync, 1000); } while (err == MFX_WRN_IN_EXECUTION); if (err < 0) { - av_log(ctx, AV_LOG_ERROR, "Error synchronizing the operation: %d\n", err); - ret = AVERROR_UNKNOWN; + ret = ff_qsvvpp_print_error(ctx, err, "Error synchronizing the operation"); goto fail; } @@ -579,7 +594,7 @@ static const AVFilterPad qsvdeint_outputs[] = { { NULL } }; -AVFilter ff_vf_deinterlace_qsv = { +const AVFilter ff_vf_deinterlace_qsv = { .name = "deinterlace_qsv", .description = NULL_IF_CONFIG_SMALL("QuickSync video deinterlacing"),