Signed-off-by: Paul B Mahol <onemda@gmail.com>
Paul B Mahol authored on 2017/04/22 20:07:33... | ... |
@@ -14659,12 +14659,15 @@ Default is digital. |
14659 | 14659 |
Set background opacity. |
14660 | 14660 |
@end table |
14661 | 14661 |
|
14662 |
-@section weave |
|
14662 |
+@section weave, doubleweave |
|
14663 | 14663 |
|
14664 | 14664 |
The @code{weave} takes a field-based video input and join |
14665 | 14665 |
each two sequential fields into single frame, producing a new double |
14666 | 14666 |
height clip with half the frame rate and half the frame count. |
14667 | 14667 |
|
14668 |
+The @code{doubleweave} works same as @code{weave} but without |
|
14669 |
+halving frame rate and frame count. |
|
14670 |
+ |
|
14668 | 14671 |
It accepts the following option: |
14669 | 14672 |
|
14670 | 14673 |
@table @option |
... | ... |
@@ -164,6 +164,7 @@ OBJS-$(CONFIG_DESHAKE_FILTER) += vf_deshake.o |
164 | 164 |
OBJS-$(CONFIG_DETELECINE_FILTER) += vf_detelecine.o |
165 | 165 |
OBJS-$(CONFIG_DILATION_FILTER) += vf_neighbor.o |
166 | 166 |
OBJS-$(CONFIG_DISPLACE_FILTER) += vf_displace.o framesync.o |
167 |
+OBJS-$(CONFIG_DOUBLEWEAVE_FILTER) += vf_weave.o |
|
167 | 168 |
OBJS-$(CONFIG_DRAWBOX_FILTER) += vf_drawbox.o |
168 | 169 |
OBJS-$(CONFIG_DRAWGRAPH_FILTER) += f_drawgraph.o |
169 | 170 |
OBJS-$(CONFIG_DRAWGRID_FILTER) += vf_drawbox.o |
... | ... |
@@ -175,6 +175,7 @@ static void register_all(void) |
175 | 175 |
REGISTER_FILTER(DETELECINE, detelecine, vf); |
176 | 176 |
REGISTER_FILTER(DILATION, dilation, vf); |
177 | 177 |
REGISTER_FILTER(DISPLACE, displace, vf); |
178 |
+ REGISTER_FILTER(DOUBLEWEAVE, doubleweave, vf); |
|
178 | 179 |
REGISTER_FILTER(DRAWBOX, drawbox, vf); |
179 | 180 |
REGISTER_FILTER(DRAWGRAPH, drawgraph, vf); |
180 | 181 |
REGISTER_FILTER(DRAWGRID, drawgrid, vf); |
... | ... |
@@ -30,7 +30,7 @@ |
30 | 30 |
#include "libavutil/version.h" |
31 | 31 |
|
32 | 32 |
#define LIBAVFILTER_VERSION_MAJOR 6 |
33 |
-#define LIBAVFILTER_VERSION_MINOR 85 |
|
33 |
+#define LIBAVFILTER_VERSION_MINOR 86 |
|
34 | 34 |
#define LIBAVFILTER_VERSION_MICRO 100 |
35 | 35 |
|
36 | 36 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
... | ... |
@@ -27,6 +27,7 @@ |
27 | 27 |
typedef struct WeaveContext { |
28 | 28 |
const AVClass *class; |
29 | 29 |
int first_field; |
30 |
+ int double_weave; |
|
30 | 31 |
int nb_planes; |
31 | 32 |
int planeheight[4]; |
32 | 33 |
int linesize[4]; |
... | ... |
@@ -56,10 +57,12 @@ static int config_props_output(AVFilterLink *outlink) |
56 | 56 |
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); |
57 | 57 |
int ret; |
58 | 58 |
|
59 |
- outlink->time_base.num = inlink->time_base.num * 2; |
|
60 |
- outlink->time_base.den = inlink->time_base.den; |
|
61 |
- outlink->frame_rate.num = inlink->frame_rate.num; |
|
62 |
- outlink->frame_rate.den = inlink->frame_rate.den * 2; |
|
59 |
+ if (!s->double_weave) { |
|
60 |
+ outlink->time_base.num = inlink->time_base.num * 2; |
|
61 |
+ outlink->time_base.den = inlink->time_base.den; |
|
62 |
+ outlink->frame_rate.num = inlink->frame_rate.num; |
|
63 |
+ outlink->frame_rate.den = inlink->frame_rate.den * 2; |
|
64 |
+ } |
|
63 | 65 |
outlink->w = inlink->w; |
64 | 66 |
outlink->h = inlink->h * 2; |
65 | 67 |
|
... | ... |
@@ -96,22 +99,36 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) |
96 | 96 |
av_frame_copy_props(out, in); |
97 | 97 |
|
98 | 98 |
for (i = 0; i < s->nb_planes; i++) { |
99 |
- av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field, |
|
100 |
- out->linesize[i] * 2, |
|
101 |
- in->data[i], in->linesize[i], |
|
102 |
- s->linesize[i], s->planeheight[i]); |
|
103 |
- av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field, |
|
104 |
- out->linesize[i] * 2, |
|
105 |
- s->prev->data[i], s->prev->linesize[i], |
|
106 |
- s->linesize[i], s->planeheight[i]); |
|
99 |
+ if (s->double_weave && !(inlink->frame_count_out & 1)) { |
|
100 |
+ av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field, |
|
101 |
+ out->linesize[i] * 2, |
|
102 |
+ in->data[i], in->linesize[i], |
|
103 |
+ s->linesize[i], s->planeheight[i]); |
|
104 |
+ av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field, |
|
105 |
+ out->linesize[i] * 2, |
|
106 |
+ s->prev->data[i], s->prev->linesize[i], |
|
107 |
+ s->linesize[i], s->planeheight[i]); |
|
108 |
+ } else { |
|
109 |
+ av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field, |
|
110 |
+ out->linesize[i] * 2, |
|
111 |
+ in->data[i], in->linesize[i], |
|
112 |
+ s->linesize[i], s->planeheight[i]); |
|
113 |
+ av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field, |
|
114 |
+ out->linesize[i] * 2, |
|
115 |
+ s->prev->data[i], s->prev->linesize[i], |
|
116 |
+ s->linesize[i], s->planeheight[i]); |
|
117 |
+ } |
|
107 | 118 |
} |
108 | 119 |
|
109 |
- out->pts = in->pts / 2; |
|
120 |
+ out->pts = s->double_weave ? s->prev->pts : in->pts / 2; |
|
110 | 121 |
out->interlaced_frame = 1; |
111 | 122 |
out->top_field_first = !s->first_field; |
112 | 123 |
|
113 |
- av_frame_free(&in); |
|
124 |
+ if (!s->double_weave) |
|
125 |
+ av_frame_free(&in); |
|
114 | 126 |
av_frame_free(&s->prev); |
127 |
+ if (s->double_weave) |
|
128 |
+ s->prev = in; |
|
115 | 129 |
return ff_filter_frame(outlink, out); |
116 | 130 |
} |
117 | 131 |
|
... | ... |
@@ -149,3 +166,27 @@ AVFilter ff_vf_weave = { |
149 | 149 |
.inputs = weave_inputs, |
150 | 150 |
.outputs = weave_outputs, |
151 | 151 |
}; |
152 |
+ |
|
153 |
+static av_cold int init(AVFilterContext *ctx) |
|
154 |
+{ |
|
155 |
+ WeaveContext *s = ctx->priv; |
|
156 |
+ |
|
157 |
+ if (!strcmp(ctx->filter->name, "doubleweave")) |
|
158 |
+ s->double_weave = 1; |
|
159 |
+ |
|
160 |
+ return 0; |
|
161 |
+} |
|
162 |
+ |
|
163 |
+#define doubleweave_options weave_options |
|
164 |
+AVFILTER_DEFINE_CLASS(doubleweave); |
|
165 |
+ |
|
166 |
+AVFilter ff_vf_doubleweave = { |
|
167 |
+ .name = "doubleweave", |
|
168 |
+ .description = NULL_IF_CONFIG_SMALL("Weave input video fields into double number of frames."), |
|
169 |
+ .priv_size = sizeof(WeaveContext), |
|
170 |
+ .priv_class = &doubleweave_class, |
|
171 |
+ .init = init, |
|
172 |
+ .uninit = uninit, |
|
173 |
+ .inputs = weave_inputs, |
|
174 |
+ .outputs = weave_outputs, |
|
175 |
+}; |