This repository has been archived by the owner on Feb 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path0019-lavf-vf_deinterlace_vaapi-flush-queued-frame-for-fie.patch
132 lines (115 loc) · 4.68 KB
/
0019-lavf-vf_deinterlace_vaapi-flush-queued-frame-for-fie.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
From 51e07bc21cdac063f2bc3e00311a03cde5eac402 Mon Sep 17 00:00:00 2001
From: Linjie Fu <[email protected]>
Date: Fri, 2 Aug 2019 16:11:38 +0800
Subject: [PATCH 19/28] lavf/vf_deinterlace_vaapi: flush queued frame for field
in DeinterlacingBob
For DeinterlacingBob mode with rate=field, the frame number of output
should equal 2x input total since only intra deinterlace is used.
Currently, the first frame is queued in filed mode and won't be
outputed. Due to the async without flush, frame number of output is
[expected_number - 2].
Specifically, if the input only has 1 frame, the output will be empty.
Add deint_vaapi_request_frame for deinterlace_vaapi, send NULL frame
to flush the queued frame.
For 1 frame input in Bob mode with rate=field,
before patch: 0 frame;
after patch: 2 frames;
ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -v verbose -c:v
h264 -i ./input.h264 -vf 'format=nv12|vaapi,hwupload,
deinterlace_vaapi=mode=bob:rate=field,hwdownload,format=nv12'
-pix_fmt yuv420p -f rawvideo -vsync passthrough -y dump.yuv
Signed-off-by: Linjie Fu <[email protected]>
---
libavfilter/vf_deinterlace_vaapi.c | 44 ++++++++++++++++++++++++++++++++------
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/libavfilter/vf_deinterlace_vaapi.c b/libavfilter/vf_deinterlace_vaapi.c
index 71809eb..34f31c0 100644
--- a/libavfilter/vf_deinterlace_vaapi.c
+++ b/libavfilter/vf_deinterlace_vaapi.c
@@ -48,6 +48,9 @@ typedef struct DeintVAAPIContext {
int queue_count;
AVFrame *frame_queue[MAX_REFERENCES];
int extra_delay_for_timestamps;
+
+ int eof;
+ int prev_pts;
} DeintVAAPIContext;
static const char *deint_vaapi_mode_name(int mode)
@@ -190,9 +193,11 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
void *filter_params_addr = NULL;
int err, i, field, current_frame_index;
- av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
- av_get_pix_fmt_name(input_frame->format),
- input_frame->width, input_frame->height, input_frame->pts);
+ // NULL frame is used to flush the queue in field mode
+ if (input_frame)
+ av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
+ av_get_pix_fmt_name(input_frame->format),
+ input_frame->width, input_frame->height, input_frame->pts);
if (ctx->queue_count < ctx->queue_depth) {
ctx->frame_queue[ctx->queue_count++] = input_frame;
@@ -210,6 +215,9 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
current_frame_index = ctx->pipeline_caps.num_forward_references;
input_frame = ctx->frame_queue[current_frame_index];
+ if (!input_frame)
+ return 0;
+
input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3];
for (i = 0; i < ctx->pipeline_caps.num_forward_references; i++)
forward_references[i] = (VASurfaceID)(uintptr_t)
@@ -291,6 +299,8 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
if (ctx->field_rate == 2) {
if (field == 0)
output_frame->pts = 2 * input_frame->pts;
+ else if (ctx->eof)
+ output_frame->pts = 3 * input_frame->pts - ctx->prev_pts;
else
output_frame->pts = input_frame->pts +
ctx->frame_queue[current_frame_index + 1]->pts;
@@ -306,6 +316,8 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
break;
}
+ ctx->prev_pts = input_frame->pts;
+
return err;
fail:
@@ -315,6 +327,25 @@ fail:
return err;
}
+static int deint_vaapi_request_frame(AVFilterLink *link)
+{
+ AVFilterContext *avctx = link->src;
+ DeintVAAPIContext *ctx = avctx->priv;
+ int ret;
+
+ if (ctx->eof)
+ return AVERROR_EOF;
+
+ ret = ff_request_frame(link->src->inputs[0]);
+ if (ret == AVERROR_EOF) {
+ ctx->eof = 1;
+ deint_vaapi_filter_frame(link->src->inputs[0], NULL);
+ } else if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static av_cold int deint_vaapi_init(AVFilterContext *avctx)
{
VAAPIVPPContext *vpp_ctx = avctx->priv;
@@ -376,9 +407,10 @@ static const AVFilterPad deint_vaapi_inputs[] = {
static const AVFilterPad deint_vaapi_outputs[] = {
{
- .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .config_props = &deint_vaapi_config_output,
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .request_frame = &deint_vaapi_request_frame,
+ .config_props = &deint_vaapi_config_output,
},
{ NULL }
};
--
2.7.4