X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_framerate.c;h=f5085705a4afa0add950199516bf881e720c47c3;hb=d40bb518b50561db60ef71ab0e37eb7f3fb9043b;hp=06e463e4d77d8d4bc00546cef93fb36b83ec029b;hpb=94346ab593f3fc0822f11d3e3f378f9944ad2d40;p=ffmpeg diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c index 06e463e4d77..f5085705a4a 100644 --- a/libavfilter/vf_framerate.c +++ b/libavfilter/vf_framerate.c @@ -51,7 +51,7 @@ static const AVOption framerate_options[] = { {"interp_start", "point to start linear interpolation", OFFSET(interp_start), AV_OPT_TYPE_INT, {.i64=15}, 0, 255, V|F }, {"interp_end", "point to end linear interpolation", OFFSET(interp_end), AV_OPT_TYPE_INT, {.i64=240}, 0, 255, V|F }, - {"scene", "scene change level", OFFSET(scene_score), AV_OPT_TYPE_DOUBLE, {.dbl=8.2}, 0, INT_MAX, V|F }, + {"scene", "scene change level", OFFSET(scene_score), AV_OPT_TYPE_DOUBLE, {.dbl=8.2}, 0, 100., V|F }, {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64=1}, 0, INT_MAX, V|F, "flags" }, {"scene_change_detect", "enable scene change detection", 0, AV_OPT_TYPE_CONST, {.i64=FRAMERATE_FLAG_SCD}, INT_MIN, INT_MAX, V|F, "flags" }, @@ -95,29 +95,22 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) { FrameRateContext *s = ctx->priv; ThreadData *td = arg; + AVFrame *work = s->work; + AVFrame *src1 = td->copy_src1; + AVFrame *src2 = td->copy_src2; uint16_t src1_factor = td->src1_factor; uint16_t src2_factor = td->src2_factor; int plane; - for (plane = 0; plane < 4 && td->copy_src1->data[plane] && td->copy_src2->data[plane]; plane++) { - int cpy_line_width = s->line_size[plane]; - uint8_t *cpy_src1_data = td->copy_src1->data[plane]; - int cpy_src1_line_size = td->copy_src1->linesize[plane]; - uint8_t *cpy_src2_data = td->copy_src2->data[plane]; - int cpy_src2_line_size = td->copy_src2->linesize[plane]; - int cpy_src_h = (plane > 0 && plane < 3) ? (td->copy_src1->height >> s->vsub) : (td->copy_src1->height); - uint8_t *cpy_dst_data = s->work->data[plane]; - int cpy_dst_line_size = s->work->linesize[plane]; - const int start = (cpy_src_h * job ) / nb_jobs; - const int end = (cpy_src_h * (job+1)) / nb_jobs; - cpy_src1_data += start * cpy_src1_line_size; - cpy_src2_data += start * cpy_src2_line_size; - cpy_dst_data += start * cpy_dst_line_size; - - s->blend(cpy_src1_data, cpy_src1_line_size, - cpy_src2_data, cpy_src2_line_size, - cpy_dst_data, cpy_dst_line_size, - cpy_line_width, end - start, + for (plane = 0; plane < 4 && src1->data[plane] && src2->data[plane]; plane++) { + const int start = (s->height[plane] * job ) / nb_jobs; + const int end = (s->height[plane] * (job+1)) / nb_jobs; + uint8_t *src1_data = src1->data[plane] + start * src1->linesize[plane]; + uint8_t *src2_data = src2->data[plane] + start * src2->linesize[plane]; + uint8_t *dst_data = work->data[plane] + start * work->linesize[plane]; + + s->blend(src1_data, src1->linesize[plane], src2_data, src2->linesize[plane], + dst_data, work->linesize[plane], s->line_size[plane], end - start, src1_factor, src2_factor, s->blend_factor_max >> 1); } @@ -177,7 +170,9 @@ static int process_work_frame(AVFilterContext *ctx) return 0; if (!s->f0) { - s->work = av_frame_clone(s->f1); + av_assert1(s->flush); + s->work = s->f1; + s->f1 = NULL; } else { if (work_pts >= s->pts1 + s->delta && s->flush) return 0; @@ -242,44 +237,38 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } -static void blend_frames_c(BLEND_FUNC_PARAMS) -{ - int line, pixel; - for (line = 0; line < height; line++) { - for (pixel = 0; pixel < width; pixel++) - dst[pixel] = ((src1[pixel] * factor1) + (src2[pixel] * factor2) + half) >> BLEND_FACTOR_DEPTH8; - src1 += src1_linesize; - src2 += src2_linesize; - dst += dst_linesize; - } -} - -static void blend_frames16_c(BLEND_FUNC_PARAMS) -{ - int line, pixel; - uint16_t *dstw = (uint16_t *)dst; - uint16_t *src1w = (uint16_t *)src1; - uint16_t *src2w = (uint16_t *)src2; - width /= 2; - src1_linesize /= 2; - src2_linesize /= 2; - dst_linesize /= 2; - for (line = 0; line < height; line++) { - for (pixel = 0; pixel < width; pixel++) - dstw[pixel] = ((src1w[pixel] * factor1) + (src2w[pixel] * factor2) + half) >> BLEND_FACTOR_DEPTH16; - src1w += src1_linesize; - src2w += src2_linesize; - dstw += dst_linesize; - } +#define BLEND_FRAME_FUNC(nbits) \ +static void blend_frames##nbits##_c(BLEND_FUNC_PARAMS) \ +{ \ + int line, pixel; \ + uint##nbits##_t *dstw = (uint##nbits##_t *)dst; \ + uint##nbits##_t *src1w = (uint##nbits##_t *)src1; \ + uint##nbits##_t *src2w = (uint##nbits##_t *)src2; \ + int bytes = nbits / 8; \ + width /= bytes; \ + src1_linesize /= bytes; \ + src2_linesize /= bytes; \ + dst_linesize /= bytes; \ + for (line = 0; line < height; line++) { \ + for (pixel = 0; pixel < width; pixel++) \ + dstw[pixel] = ((src1w[pixel] * factor1) + \ + (src2w[pixel] * factor2) + half) \ + >> BLEND_FACTOR_DEPTH(nbits); \ + src1w += src1_linesize; \ + src2w += src2_linesize; \ + dstw += dst_linesize; \ + } \ } +BLEND_FRAME_FUNC(8) +BLEND_FRAME_FUNC(16) void ff_framerate_init(FrameRateContext *s) { if (s->bitdepth == 8) { - s->blend_factor_max = 1 << BLEND_FACTOR_DEPTH8; - s->blend = blend_frames_c; + s->blend_factor_max = 1 << BLEND_FACTOR_DEPTH(8); + s->blend = blend_frames8_c; } else { - s->blend_factor_max = 1 << BLEND_FACTOR_DEPTH16; + s->blend_factor_max = 1 << BLEND_FACTOR_DEPTH(16); s->blend = blend_frames16_c; } if (ARCH_X86) @@ -293,13 +282,13 @@ static int config_input(AVFilterLink *inlink) const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); int plane; + s->vsub = pix_desc->log2_chroma_h; for (plane = 0; plane < 4; plane++) { - s->line_size[plane] = av_image_get_linesize(inlink->format, inlink->w, - plane); + s->line_size[plane] = av_image_get_linesize(inlink->format, inlink->w, plane); + s->height[plane] = inlink->h >> ((plane == 1 || plane == 2) ? s->vsub : 0); } s->bitdepth = pix_desc->comp[0].depth; - s->vsub = pix_desc->log2_chroma_h; s->sad = ff_scene_sad_get_fn(s->bitdepth == 8 ? 8 : 16); if (!s->sad)