diff options
author | Yayoi <yayoi.ukai@gmail.com> | 2015-03-10 08:01:47 +0300 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-03-12 05:45:42 +0300 |
commit | d5232d4717ec815b5ccb1baf3bc758f1e063010a (patch) | |
tree | d8f8bd25c35df70c4cb1abbfc5461783eb04f6c6 /libavfilter | |
parent | 26d81b5703ea3b100d5138c0a6359076de2a1e0d (diff) |
avfilter/colormatrix:add slice threading
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavfilter')
-rw-r--r-- | libavfilter/vf_colormatrix.c | 146 |
1 files changed, 94 insertions, 52 deletions
diff --git a/libavfilter/vf_colormatrix.c b/libavfilter/vf_colormatrix.c index daba16e152..f5835cbf4b 100644 --- a/libavfilter/vf_colormatrix.c +++ b/libavfilter/vf_colormatrix.c @@ -73,6 +73,17 @@ typedef struct { int hsub, vsub; } ColorMatrixContext; +typedef struct ThreadData { + AVFrame *dst; + const AVFrame *src; + int c2; + int c3; + int c4; + int c5; + int c6; + int c7; +} ThreadData; + #define OFFSET(x) offsetof(ColorMatrixContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM @@ -179,24 +190,28 @@ static av_cold int init(AVFilterContext *ctx) return 0; } -static void process_frame_uyvy422(ColorMatrixContext *color, - AVFrame *dst, AVFrame *src) +static int process_slice_uyvy422(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - const unsigned char *srcp = src->data[0]; - const int src_pitch = src->linesize[0]; + const ThreadData *td = arg; + const AVFrame *src = td->src; + AVFrame *dst = td->dst; const int height = src->height; const int width = src->width*2; - unsigned char *dstp = dst->data[0]; + const int src_pitch = src->linesize[0]; const int dst_pitch = dst->linesize[0]; - const int c2 = color->yuv_convert[color->mode][0][1]; - const int c3 = color->yuv_convert[color->mode][0][2]; - const int c4 = color->yuv_convert[color->mode][1][1]; - const int c5 = color->yuv_convert[color->mode][1][2]; - const int c6 = color->yuv_convert[color->mode][2][1]; - const int c7 = color->yuv_convert[color->mode][2][2]; + const int slice_start = (height * jobnr ) / nb_jobs; + const int slice_end = (height * (jobnr+1)) / nb_jobs; + const unsigned char *srcp = src->data[0] + slice_start * src_pitch; + unsigned char *dstp = dst->data[0] + slice_start * dst_pitch; + const int c2 = td->c2; + const int c3 = td->c3; + const int c4 = td->c4; + const int c5 = td->c5; + const int c6 = td->c6; + const int c7 = td->c7; int x, y; - for (y = 0; y < height; y++) { + for (y = slice_start; y < slice_end; y++) { for (x = 0; x < width; x += 4) { const int u = srcp[x + 0] - 128; const int v = srcp[x + 2] - 128; @@ -209,32 +224,38 @@ static void process_frame_uyvy422(ColorMatrixContext *color, srcp += src_pitch; dstp += dst_pitch; } + + return 0; } -static void process_frame_yuv422p(ColorMatrixContext *color, - AVFrame *dst, AVFrame *src) +static int process_slice_yuv422p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - const unsigned char *srcpU = src->data[1]; - const unsigned char *srcpV = src->data[2]; - const unsigned char *srcpY = src->data[0]; - const int src_pitchY = src->linesize[0]; - const int src_pitchUV = src->linesize[1]; + const ThreadData *td = arg; + const AVFrame *src = td->src; + AVFrame *dst = td->dst; const int height = src->height; const int width = src->width; - unsigned char *dstpU = dst->data[1]; - unsigned char *dstpV = dst->data[2]; - unsigned char *dstpY = dst->data[0]; + const int slice_start = (height * jobnr ) / nb_jobs; + const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int src_pitchY = src->linesize[0]; + const int src_pitchUV = src->linesize[1]; + const unsigned char *srcpU = src->data[1] + slice_start * src_pitchUV; + const unsigned char *srcpV = src->data[2] + slice_start * src_pitchUV; + const unsigned char *srcpY = src->data[0] + slice_start * src_pitchY; const int dst_pitchY = dst->linesize[0]; const int dst_pitchUV = dst->linesize[1]; - const int c2 = color->yuv_convert[color->mode][0][1]; - const int c3 = color->yuv_convert[color->mode][0][2]; - const int c4 = color->yuv_convert[color->mode][1][1]; - const int c5 = color->yuv_convert[color->mode][1][2]; - const int c6 = color->yuv_convert[color->mode][2][1]; - const int c7 = color->yuv_convert[color->mode][2][2]; + unsigned char *dstpU = dst->data[1] + slice_start * dst_pitchUV; + unsigned char *dstpV = dst->data[2] + slice_start * dst_pitchUV; + unsigned char *dstpY = dst->data[0] + slice_start * dst_pitchY; + const int c2 = td->c2; + const int c3 = td->c3; + const int c4 = td->c4; + const int c5 = td->c5; + const int c6 = td->c6; + const int c7 = td->c7; int x, y; - for (y = 0; y < height; y++) { + for (y = slice_start; y < slice_end; y++) { for (x = 0; x < width; x += 2) { const int u = srcpU[x >> 1] - 128; const int v = srcpV[x >> 1] - 128; @@ -251,34 +272,40 @@ static void process_frame_yuv422p(ColorMatrixContext *color, dstpU += dst_pitchUV; dstpV += dst_pitchUV; } + + return 0; } -static void process_frame_yuv420p(ColorMatrixContext *color, - AVFrame *dst, AVFrame *src) +static int process_slice_yuv420p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - const unsigned char *srcpU = src->data[1]; - const unsigned char *srcpV = src->data[2]; - const unsigned char *srcpY = src->data[0]; - const unsigned char *srcpN = src->data[0] + src->linesize[0]; - const int src_pitchY = src->linesize[0]; - const int src_pitchUV = src->linesize[1]; + const ThreadData *td = arg; + const AVFrame *src = td->src; + AVFrame *dst = td->dst; const int height = src->height; const int width = src->width; - unsigned char *dstpU = dst->data[1]; - unsigned char *dstpV = dst->data[2]; - unsigned char *dstpY = dst->data[0]; - unsigned char *dstpN = dst->data[0] + dst->linesize[0]; + const int slice_start = (height * jobnr ) / nb_jobs; + const int slice_end = (height * (jobnr+1)) / nb_jobs; + const int src_pitchY = src->linesize[0]; + const int src_pitchUV = src->linesize[1]; const int dst_pitchY = dst->linesize[0]; const int dst_pitchUV = dst->linesize[1]; - const int c2 = color->yuv_convert[color->mode][0][1]; - const int c3 = color->yuv_convert[color->mode][0][2]; - const int c4 = color->yuv_convert[color->mode][1][1]; - const int c5 = color->yuv_convert[color->mode][1][2]; - const int c6 = color->yuv_convert[color->mode][2][1]; - const int c7 = color->yuv_convert[color->mode][2][2]; + const unsigned char *srcpY = src->data[0] + src_pitchY * slice_start; + const unsigned char *srcpU = src->data[1] + src_pitchUV * (slice_start >> 1); + const unsigned char *srcpV = src->data[2] + src_pitchUV * (slice_start >> 1); + const unsigned char *srcpN = src->data[0] + src_pitchY * (slice_start + 1); + unsigned char *dstpU = dst->data[1] + dst_pitchUV * (slice_start >> 1); + unsigned char *dstpV = dst->data[2] + dst_pitchUV * (slice_start >> 1); + unsigned char *dstpY = dst->data[0] + dst_pitchY * slice_start; + unsigned char *dstpN = dst->data[0] + dst_pitchY * (slice_start + 1); + const int c2 = td->c2; + const int c3 = td->c3; + const int c4 = td->c4; + const int c5 = td->c5; + const int c6 = td->c6; + const int c7 = td->c7; int x, y; - for (y = 0; y < height; y += 2) { + for (y = slice_start; y < slice_end; y += 2) { for (x = 0; x < width; x += 2) { const int u = srcpU[x >> 1] - 128; const int v = srcpV[x >> 1] - 128; @@ -299,6 +326,8 @@ static void process_frame_yuv420p(ColorMatrixContext *color, dstpU += dst_pitchUV; dstpV += dst_pitchUV; } + + return 0; } static int config_input(AVFilterLink *inlink) @@ -336,6 +365,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) ColorMatrixContext *color = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; AVFrame *out; + ThreadData td = {0}; out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { @@ -372,12 +402,24 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) calc_coefficients(ctx); + td.src = in; + td.dst = out; + td.c2 = color->yuv_convert[color->mode][0][1]; + td.c3 = color->yuv_convert[color->mode][0][2]; + td.c4 = color->yuv_convert[color->mode][1][1]; + td.c5 = color->yuv_convert[color->mode][1][2]; + td.c6 = color->yuv_convert[color->mode][2][1]; + td.c7 = color->yuv_convert[color->mode][2][2]; + if (in->format == AV_PIX_FMT_YUV422P) - process_frame_yuv422p(color, out, in); + ctx->internal->execute(ctx, process_slice_yuv422p, &td, NULL, + FFMIN(in->height, ctx->graph->nb_threads)); else if (in->format == AV_PIX_FMT_YUV420P) - process_frame_yuv420p(color, out, in); + ctx->internal->execute(ctx, process_slice_yuv420p, &td, NULL, + FFMIN(in->height, ctx->graph->nb_threads)); else - process_frame_uyvy422(color, out, in); + ctx->internal->execute(ctx, process_slice_uyvy422, &td, NULL, + FFMIN(in->height, ctx->graph->nb_threads)); av_frame_free(&in); return ff_filter_frame(outlink, out); @@ -410,5 +452,5 @@ AVFilter ff_vf_colormatrix = { .inputs = colormatrix_inputs, .outputs = colormatrix_outputs, .priv_class = &colormatrix_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, }; |