[FFmpeg-devel] [PATCH] added slicing yuv, rgb

Yayoi yayoi.ukai at gmail.com
Wed Dec 17 07:44:27 CET 2014


---
 libavfilter/allfilters.c |   2 +-
 libavfilter/vf_lut.c     | 119 ++++++++++++++++++++++++++++++++++-------------
 2 files changed, 88 insertions(+), 33 deletions(-)

diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index adb86be..76341bd 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -218,7 +218,7 @@ void avfilter_register_all(void)
     REGISTER_FILTER(YADIF,          yadif,          vf);
     REGISTER_FILTER(ZMQ,            zmq,            vf);
     REGISTER_FILTER(ZOOMPAN,        zoompan,        vf);
-
+    
     REGISTER_FILTER(CELLAUTO,       cellauto,       vsrc);
     REGISTER_FILTER(COLOR,          color,          vsrc);
     REGISTER_FILTER(FREI0R,         frei0r_src,     vsrc);
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
index 0b7a2ca..3ab7f40 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -69,6 +69,13 @@ typedef struct LutContext {
     int negate_alpha; /* only used by negate */
 } LutContext;
 
+typedef struct ThreadData {
+    AVFrame *in, *out;
+    int plane;
+    int h,w;
+    AVFilterLink *inlink;
+} ThreadData;
+
 #define Y 0
 #define U 1
 #define V 2
@@ -276,14 +283,76 @@ static int config_props(AVFilterLink *inlink)
     return 0;
 }
 
+static int process_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    int x, y;
+    LutContext *s = ctx->priv;
+    const ThreadData *td = arg;
+    const AVFrame *in = td->in;
+    const AVFrame *out = td->out;
+    const int step = s->step;
+    const uint8_t (*tab)[256] = (const uint8_t (*)[256])s->lut;
+
+
+    const int slice_start = (in->height *  jobnr   ) / nb_jobs;
+    const int slice_end   = (in->height * (jobnr+1)) / nb_jobs;
+    uint8_t       *outrow = out->data[0] + slice_start * out->linesize[0];
+    const uint8_t *inrow =  in->data[0] + slice_start *  in->linesize[0];
+    int w = td->w;
+    for (y = slice_start; y < slice_end; y++) {  
+
+        for (x = 0; x < w; x++) {
+            switch (step) {
+            case 4:  outrow[3] = tab[3][inrow[3]]; // Fall-through
+            case 3:  outrow[2] = tab[2][inrow[2]]; // Fall-through
+            case 2:  outrow[1] = tab[1][inrow[1]]; // Fall-through
+            default: outrow[0] = tab[0][inrow[0]];
+            }
+            outrow += step;
+            inrow  += step;
+        }
+    }
+    return 0;
+
+}
+
+
+
+static int process_slice_yuv(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    int x, y;
+    LutContext *s = ctx->priv;
+    const ThreadData *td = arg;
+    int plane = td->plane;
+    int h = td->h;
+    int w = td->w; 
+
+    const AVFrame *in = td->in;
+    const AVFrame *out = td->out;
+    int slice_start = (h *  jobnr   ) / nb_jobs;
+    int slice_end   = (h * (jobnr+1)) / nb_jobs;
+    uint8_t       *outrow = out->data[plane] + slice_start * out->linesize[plane];
+    const uint8_t *inrow =  in->data[plane] + slice_start *  in->linesize[plane];
+
+    for (y = slice_start; y < slice_end; y++) {
+        const uint8_t *tab = s->lut[plane];
+        for (x = 0; x < w; x++)
+            outrow[x] = tab[inrow[x]];
+        inrow  += in ->linesize[plane];
+        outrow += out->linesize[plane];
+    }
+    return 0;
+
+}
+
 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext *ctx = inlink->dst;
     LutContext *s = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
     AVFrame *out;
-    uint8_t *inrow, *outrow, *inrow0, *outrow0;
-    int i, j, plane, direct = 0;
+    ThreadData td; 
+    int plane, direct = 0;
 
     if (av_frame_is_writable(in)) {
         direct = 1;
@@ -297,47 +366,33 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
         av_frame_copy_props(out, in);
     }
 
+    td.in  = in;
+    td.out = out;
+    td.inlink = inlink;
+
+
     if (s->is_rgb) {
         /* packed */
-        inrow0  = in ->data[0];
-        outrow0 = out->data[0];
-
-        for (i = 0; i < in->height; i ++) {
-            int w = inlink->w;
-            const uint8_t (*tab)[256] = (const uint8_t (*)[256])s->lut;
-            inrow  = inrow0;
-            outrow = outrow0;
-            for (j = 0; j < w; j++) {
-                switch (s->step) {
-                case 4:  outrow[3] = tab[3][inrow[3]]; // Fall-through
-                case 3:  outrow[2] = tab[2][inrow[2]]; // Fall-through
-                case 2:  outrow[1] = tab[1][inrow[1]]; // Fall-through
-                default: outrow[0] = tab[0][inrow[0]];
-                }
-                outrow += s->step;
-                inrow  += s->step;
-            }
-            inrow0  += in ->linesize[0];
-            outrow0 += out->linesize[0];
-        }
+
+        int w = inlink->w;
+        td.w = w;
+        ctx->internal->execute(ctx, process_slice_rgb, &td, NULL, FFMIN(outlink->h, ctx->graph->nb_threads));
+
     } else {
         /* planar */
+        
         for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
             int vsub = plane == 1 || plane == 2 ? s->vsub : 0;
             int hsub = plane == 1 || plane == 2 ? s->hsub : 0;
             int h = FF_CEIL_RSHIFT(inlink->h, vsub);
             int w = FF_CEIL_RSHIFT(inlink->w, hsub);
 
-            inrow  = in ->data[plane];
-            outrow = out->data[plane];
+            td.plane = plane;
+            td.h = h;
+            td.w = w;
+
+            ctx->internal->execute(ctx, process_slice_yuv, &td, NULL, FFMIN(h, ctx->graph->nb_threads));
 
-            for (i = 0; i < h; i++) {
-                const uint8_t *tab = s->lut[plane];
-                for (j = 0; j < w; j++)
-                    outrow[j] = tab[inrow[j]];
-                inrow  += in ->linesize[plane];
-                outrow += out->linesize[plane];
-            }
         }
     }
 
-- 
1.8.3.4 (Apple Git-47)



More information about the ffmpeg-devel mailing list