Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 24 May 2013 12:38:29 +0000 (14:38 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 24 May 2013 13:24:22 +0000 (15:24 +0200)
* qatar/master:
  vf_fade: support slice threading
  vf_yadif: support slice threading

Conflicts:
libavfilter/vf_fade.c
libavfilter/vf_yadif.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavfilter/vf_fade.c
libavfilter/vf_yadif.c

@@@ -139,115 -92,77 +139,153 @@@ static int config_props(AVFilterLink *i
      return 0;
  }
  
- static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 +static void fade_plane(int y, int h, int w,
 +                       int fade_factor, int black_level, int black_level_scaled,
 +                       uint8_t offset, uint8_t step, int bytes_per_plane,
 +                       uint8_t *data, int line_size)
 +{
 +    uint8_t *p;
 +    int i, j;
 +
 +    /* luma, alpha or rgb plane */
 +    for (i = 0; i < h; i++) {
 +        p = data + offset + (y+i) * line_size;
 +        for (j = 0; j < w * bytes_per_plane; j++) {
 +            /* s->factor is using 16 lower-order bits for decimal places. */
 +            *p = ((*p - black_level) * fade_factor + black_level_scaled) >> 16;
 +            p+=step;
 +        }
 +    }
 +}
 +
+ static int filter_slice_luma(AVFilterContext *ctx, void *arg, int jobnr,
+                              int nb_jobs)
  {
-     FadeContext *s = inlink->dst->priv;
-     uint8_t *p;
+     FadeContext *s = ctx->priv;
+     AVFrame *frame = arg;
+     int slice_h     = frame->height / nb_jobs;
+     int slice_start = jobnr * slice_h;
+     int slice_end   = (jobnr == nb_jobs - 1) ? frame->height : (jobnr + 1) * slice_h;
+     int i, j;
+     for (i = slice_start; i < slice_end; i++) {
+         uint8_t *p = frame->data[0] + i * frame->linesize[0];
+         for (j = 0; j < frame->width * s->bpp; j++) {
+             /* s->factor is using 16 lower-order bits for decimal
+              * places. 32768 = 1 << 15, it is an integer representation
+              * of 0.5 and is for rounding. */
 -            *p = (*p * s->factor + 32768) >> 16;
++            *p = ((*p - s->black_level) * s->factor + s->black_level_scaled) >> 16;
+             p++;
+         }
+     }
+     return 0;
+ }
+ static int filter_slice_chroma(AVFilterContext *ctx, void *arg, int jobnr,
+                                int nb_jobs)
+ {
+     FadeContext *s = ctx->priv;
+     AVFrame *frame = arg;
+     int slice_h     = FFALIGN(frame->height / nb_jobs, 1 << s->vsub);
+     int slice_start = jobnr * slice_h;
+     int slice_end   = (jobnr == nb_jobs - 1) ? frame->height : (jobnr + 1) * slice_h;
      int i, j, plane;
 -            for (j = 0; j < frame->width >> s->hsub; j++) {
++    const int width = FF_CEIL_RSHIFT(frame->width, s->hsub);
+     for (plane = 1; plane < 3; plane++) {
+         for (i = slice_start; i < slice_end; i++) {
+             uint8_t *p = frame->data[plane] + (i >> s->vsub) * frame->linesize[plane];
++            for (j = 0; j < width; j++) {
+                 /* 8421367 = ((128 << 1) + 1) << 15. It is an integer
+                  * representation of 128.5. The .5 is for rounding
+                  * purposes. */
+                 *p = ((*p - 128) * s->factor + 8421367) >> 16;
+                 p++;
+             }
+         }
+     }
+     return 0;
+ }
+ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
+ {
+     AVFilterContext *ctx = inlink->dst;
+     FadeContext *s       = ctx->priv;
 +    double frame_timestamp = frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base);
  
 -    if (s->factor < UINT16_MAX) {
 -        /* luma or rgb plane */
 -        ctx->internal->execute(ctx, filter_slice_luma, frame, NULL,
 -                               FFMIN(frame->height, ctx->graph->nb_threads));
 -
 -        if (frame->data[1] && frame->data[2]) {
 -            /* chroma planes */
 -            ctx->internal->execute(ctx, filter_slice_chroma, frame, NULL,
 -                                   FFMIN(frame->height, ctx->graph->nb_threads));
 +    // Calculate Fade assuming this is a Fade In
 +    if (s->fade_state == VF_FADE_WAITING) {
 +        s->factor=0;
 +        if ((frame_timestamp >= (s->start_time/(double)AV_TIME_BASE))
 +            && (s->frame_index >= s->start_frame)) {
 +            // Time to start fading
 +            s->fade_state = VF_FADE_FADING;
 +
 +            // Save start time in case we are starting based on frames and fading based on time
 +            if ((s->start_time == 0) && (s->start_frame != 0)) {
 +                s->start_time = frame_timestamp*(double)AV_TIME_BASE;
 +            }
 +
 +            // Save start frame in case we are starting based on time and fading based on frames
 +            if ((s->start_time != 0) && (s->start_frame == 0)) {
 +                s->start_frame = s->frame_index;
 +            }
 +        }
 +    }
 +    if (s->fade_state == VF_FADE_FADING) {
 +        if (s->duration == 0) {
 +            // Fading based on frame count
 +            s->factor = (s->frame_index - s->start_frame) * s->fade_per_frame;
 +            if (s->frame_index > (s->start_frame + s->nb_frames)) {
 +                s->fade_state = VF_FADE_DONE;
 +            }
 +
 +        } else {
 +            // Fading based on duration
 +            s->factor = (frame_timestamp - (s->start_time/(double)AV_TIME_BASE))
 +                            * (float) UINT16_MAX / (s->duration/(double)AV_TIME_BASE);
 +            if (frame_timestamp > ((s->start_time/(double)AV_TIME_BASE)
 +                                    + (s->duration/(double)AV_TIME_BASE))) {
 +                s->fade_state = VF_FADE_DONE;
 +            }
          }
      }
 +    if (s->fade_state == VF_FADE_DONE) {
 +        s->factor=UINT16_MAX;
 +    }
  
 -    if (s->frame_index >= s->start_frame &&
 -        s->frame_index <= s->stop_frame)
 -        s->factor += s->fade_per_frame;
      s->factor = av_clip_uint16(s->factor);
-             plane = s->is_packed_rgb ? 0 : A; // alpha is on plane 0 for packed formats
 +
 +    // Invert fade_factor if Fading Out
 +    if (s->type == 1) {
 +        s->factor=UINT16_MAX-s->factor;
 +    }
 +
 +    if (s->factor < UINT16_MAX) {
 +        if (s->alpha) {
 +            // alpha only
-             fade_plane(0, frame->height, inlink->w,
-                        s->factor, s->black_level, s->black_level_scaled,
-                        0, 1, // offset & pixstep for Y plane or RGB packed format
-                        s->bpp, frame->data[0], frame->linesize[0]);
++            int plane = s->is_packed_rgb ? 0 : A; // alpha is on plane 0 for packed formats
 +                                                 // or plane 3 for planar formats
 +            fade_plane(0, frame->height, inlink->w,
 +                       s->factor, s->black_level, s->black_level_scaled,
 +                       s->is_packed_rgb ? s->rgba_map[A] : 0, // alpha offset for packed formats
 +                       s->is_packed_rgb ? 4 : 1,                 // pixstep for 8 bit packed formats
 +                       1, frame->data[plane], frame->linesize[plane]);
 +        } else {
 +            /* luma or rgb plane */
-                 for (plane = 1; plane < 3; plane++) {
-                     for (i = 0; i < frame->height; i++) {
-                         const int width = FF_CEIL_RSHIFT(inlink->w, s->hsub);
-                         p = frame->data[plane] + (i >> s->vsub) * frame->linesize[plane];
-                         for (j = 0; j < width; j++) {
-                             /* 8421367 = ((128 << 1) + 1) << 15. It is an integer
-                              * representation of 128.5. The .5 is for rounding
-                              * purposes. */
-                             *p = ((*p - 128) * s->factor + 8421367) >> 16;
-                             p++;
-                         }
-                     }
-                 }
++            ctx->internal->execute(ctx, filter_slice_luma, frame, NULL,
++                                FFMIN(frame->height, ctx->graph->nb_threads));
++
 +            if (frame->data[1] && frame->data[2]) {
 +                /* chroma planes */
++                ctx->internal->execute(ctx, filter_slice_chroma, frame, NULL,
++                                    FFMIN(frame->height, ctx->graph->nb_threads));
 +            }
 +        }
 +    }
 +
      s->frame_index++;
  
      return ff_filter_frame(inlink->dst->outputs[0], frame);
@@@ -181,41 -230,18 +229,18 @@@ static void filter(AVFilterContext *ctx
      for (i = 0; i < yadif->csp->nb_components; i++) {
          int w = dstpic->width;
          int h = dstpic->height;
-         int refs = yadif->cur->linesize[i];
-         int df = (yadif->csp->comp[i].depth_minus1 + 8) / 8;
-         int pix_3 = 3 * df;
  
          if (i == 1 || i == 2) {
-         /* Why is this not part of the per-plane description thing? */
 -            w >>= yadif->csp->log2_chroma_w;
 -            h >>= yadif->csp->log2_chroma_h;
 +            w = FF_CEIL_RSHIFT(w, yadif->csp->log2_chroma_w);
 +            h = FF_CEIL_RSHIFT(h, yadif->csp->log2_chroma_h);
          }
  
-         /* filtering reads 3 pixels to the left/right; to avoid invalid reads,
-          * we need to call the c variant which avoids this for border pixels
-          */
-         for (y = 0; y < h; y++) {
-             if ((y ^ parity) & 1) {
-                 uint8_t *prev = &yadif->prev->data[i][y * refs];
-                 uint8_t *cur  = &yadif->cur ->data[i][y * refs];
-                 uint8_t *next = &yadif->next->data[i][y * refs];
-                 uint8_t *dst  = &dstpic->data[i][y * dstpic->linesize[i]];
-                 int     mode  = y == 1 || y + 2 == h ? 2 : yadif->mode;
-                 yadif->filter_line(dst + pix_3, prev + pix_3, cur + pix_3,
-                                    next + pix_3, w - 6,
-                                    y + 1 < h ? refs : -refs,
-                                    y ? -refs : refs,
-                                    parity ^ tff, mode);
-                 yadif->filter_edges(dst, prev, cur, next, w,
-                                     y + 1 < h ? refs : -refs,
-                                     y ? -refs : refs,
-                                     parity ^ tff, mode);
-             } else {
-                 memcpy(&dstpic->data[i][y * dstpic->linesize[i]],
-                        &yadif->cur->data[i][y * refs], w * df);
-             }
-         }
+         td.w       = w;
+         td.h       = h;
+         td.plane   = i;
+         ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(h, ctx->graph->nb_threads));
      }
  
      emms_c();
@@@ -483,6 -527,8 +508,6 @@@ AVFilter avfilter_vf_yadif = 
      .query_formats = query_formats,
  
      .inputs    = avfilter_vf_yadif_inputs,
 -
      .outputs   = avfilter_vf_yadif_outputs,
-     .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 -
 -    .flags     = AVFILTER_FLAG_SLICE_THREADS,
++    .flags     = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
  };