History

lavfi/colorlevels: Add slice threading support

Add slice threading support, use the command like: ./ffmpeg -i input -vf colorlevels -f null /dev/null with 1080p h264 clip, the fps from 39 fps to 79 fps in the local(Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz)

Jun Zhao committed 7 years ago

Commit 360bee81 parent 468f0031 file · +91 −19Browse files

Unified · Split

libavfilter/vf_colorlevels.c+91−19
@@ -105,6 +105,68 @@ static int config_input(AVFilterLink *inlink) · 104 unmodified lines
105105 return 0;
106106 }
107107
108+struct thread_data {
109+ const uint8_t *srcrow;
110+ uint8_t *dstrow;
111+ int dst_linesize;
112+ int src_linesize;
113+
114+ double coeff;
115+ uint8_t offset;
116+
117+ int h;
118+
119+ int imin;
120+ int omin;
121+};
122+
123+#define LOAD_COMMON\
124+ ColorLevelsContext *s = ctx->priv;\
125+ const struct thread_data *td = arg;\
126+\
127+ int process_h = td->h;\
128+ const int slice_start = (process_h * jobnr ) / nb_jobs;\
129+ const int slice_end = (process_h * (jobnr+1)) / nb_jobs;\
130+ int x, y;\
131+ const uint8_t *srcrow = td->srcrow;\
132+ uint8_t *dstrow = td->dstrow;\
133+ const int step = s->step;\
134+ const uint8_t offset = td->offset;\
135+\
136+ int imin = td->imin;\
137+ int omin = td->omin;\
138+ double coeff = td->coeff;\
139+
140+static int colorlevel_slice_8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
141+{
142+ LOAD_COMMON
143+
144+ for (y = slice_start; y < slice_end; y++) {
145+ const uint8_t *src = srcrow + y * td->src_linesize;
146+ uint8_t *dst = dstrow + y * td->dst_linesize;
147+
148+ for (x = 0; x < s->linesize; x += step)
149+ dst[x + offset] = av_clip_uint8((src[x + offset] - imin) * coeff + omin);
150+ }
151+
152+ return 0;
153+}
154+
155+static int colorlevel_slice_16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
156+{
157+ LOAD_COMMON
158+
159+ for (y = slice_start; y < slice_end; y++) {
160+ const uint16_t *src = (const uint16_t *)(srcrow + y * td->src_linesize);
161+ uint16_t *dst = (uint16_t *)(dstrow + y * td->dst_linesize);
162+
163+ for (x = 0; x < s->linesize; x += step)
164+ dst[x + offset] = av_clip_uint16((src[x + offset] - imin) * coeff + omin);
165+ }
166+
167+ return 0;
168+}
169+
108170 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
109171 {
110172 AVFilterContext *ctx = inlink->dst;
@@ -137,6 +199,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 26 unmodified lines
137199 int omin = lrint(r->out_min * UINT8_MAX);
138200 int omax = lrint(r->out_max * UINT8_MAX);
139201 double coeff;
202+ struct thread_data td;
140203
141204 if (imin < 0) {
142205 imin = UINT8_MAX;
@@ -162,15 +225,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 19 unmodified lines
162225
163226 srcrow = in->data[0];
164227 coeff = (omax - omin) / (double)(imax - imin);
165− for (y = 0; y < inlink->h; y++) {
166− const uint8_t *src = srcrow;
167− uint8_t *dst = dstrow;
168−
169− for (x = 0; x < s->linesize; x += step)
170− dst[x + offset] = av_clip_uint8((src[x + offset] - imin) * coeff + omin);
171− dstrow += out->linesize[0];
172− srcrow += in->linesize[0];
173− }
228+
229+ td.srcrow = srcrow;
230+ td.dstrow = dstrow;
231+ td.dst_linesize = out->linesize[0];
232+ td.src_linesize = in->linesize[0];
233+ td.coeff = coeff;
234+ td.offset = offset;
235+ td.h = inlink->h;
236+ td.imin = imin;
237+ td.omin = omin;
238+
239+ ctx->internal->execute(ctx, colorlevel_slice_8, &td, NULL,
240+ FFMIN(inlink->h, ff_filter_get_nb_threads(ctx)));
174241 }
175242 break;
176243 case 2:
@@ -184,6 +251,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 7 unmodified lines
184251 int omin = lrint(r->out_min * UINT16_MAX);
185252 int omax = lrint(r->out_max * UINT16_MAX);
186253 double coeff;
254+ struct thread_data td;
187255
188256 if (imin < 0) {
189257 imin = UINT16_MAX;
@@ -209,15 +277,19 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 19 unmodified lines
209277
210278 srcrow = in->data[0];
211279 coeff = (omax - omin) / (double)(imax - imin);
212− for (y = 0; y < inlink->h; y++) {
213− const uint16_t *src = (const uint16_t*)srcrow;
214− uint16_t *dst = (uint16_t *)dstrow;
215−
216− for (x = 0; x < s->linesize; x += step)
217− dst[x + offset] = av_clip_uint16((src[x + offset] - imin) * coeff + omin);
218− dstrow += out->linesize[0];
219− srcrow += in->linesize[0];
220− }
280+
281+ td.srcrow = srcrow;
282+ td.dstrow = dstrow;
283+ td.dst_linesize = out->linesize[0];
284+ td.src_linesize = in->linesize[0];
285+ td.coeff = coeff;
286+ td.offset = offset;
287+ td.h = inlink->h;
288+ td.imin = imin;
289+ td.omin = omin;
290+
291+ ctx->internal->execute(ctx, colorlevel_slice_16, &td, NULL,
292+ FFMIN(inlink->h, ff_filter_get_nb_threads(ctx)));
221293 }
222294 }
223295
@@ -252,5 +324,5 @@ AVFilter ff_vf_colorlevels = { · 28 unmodified lines
252324 .query_formats = query_formats,
253325 .inputs = colorlevels_inputs,
254326 .outputs = colorlevels_outputs,
255− .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
327+ .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
256328 };

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t