From: Niklas Haas <g...@haasn.dev> Flipping can already be accomplished by setting the crop_w/h expressions to their negative values, so together these options can implement any of the common frame orientations. --- doc/filters.texi | 10 ++++++++++ libavfilter/avfilter.c | 3 ++- libavfilter/vf_libplacebo.c | 23 +++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/doc/filters.texi b/doc/filters.texi index 679b71f290..434fdec109 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -16259,6 +16259,16 @@ and @code{(oh-ph)/2}. Set the output placement width/height expressions, default values are @code{ow} and @code{oh}. +@item rotate +Rotate the input frame clockwise by the specified angle. + +@table @samp +@item 0, 360 +@item 90 +@item 180 +@item 270 +@end table + @item fps Set the output frame rate. This can be rational, e.g. @code{60000/1001}. If set to the special string @code{none} (the default), input timestamps will diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 64c1075c40..f113b6a186 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -1062,7 +1062,8 @@ int ff_filter_frame(AVFilterLink *link, AVFrame *frame) strcmp(link->dst->filter->name, "format") && strcmp(link->dst->filter->name, "idet") && strcmp(link->dst->filter->name, "null") && - strcmp(link->dst->filter->name, "scale")) { + strcmp(link->dst->filter->name, "scale") && + strcmp(link->dst->filter->name, "libplacebo")) { av_assert1(frame->format == link->format); av_assert1(frame->width == link->w); av_assert1(frame->height == link->h); diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c index 86e1f43dea..7accf8ead9 100644 --- a/libavfilter/vf_libplacebo.c +++ b/libavfilter/vf_libplacebo.c @@ -193,6 +193,7 @@ typedef struct LibplaceboContext { int color_range; int color_primaries; int color_trc; + int rotation; AVDictionary *extra_opts; int have_hwdevice; @@ -802,6 +803,13 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in, image->crop.y0 = av_expr_eval(s->crop_y_pexpr, s->var_values, NULL); image->crop.x1 = image->crop.x0 + s->var_values[VAR_CROP_W]; image->crop.y1 = image->crop.y0 + s->var_values[VAR_CROP_H]; + image->rotation = s->rotation; + if (s->rotation % PL_ROTATION_180 == PL_ROTATION_90) { + /* Libplacebo expects the input crop relative to the actual frame + * dimensions, so un-transpose them here */ + FFSWAP(float, image->crop.x0, image->crop.y0); + FFSWAP(float, image->crop.x1, image->crop.y1); + } if (src == ref) { /* Only update the target crop once, for the 'reference' frame */ @@ -1198,6 +1206,14 @@ static int libplacebo_config_input(AVFilterLink *inlink) AVFilterContext *avctx = inlink->dst; LibplaceboContext *s = avctx->priv; + if (s->rotation % PL_ROTATION_180 == PL_ROTATION_90) { + /* Swap width and height for 90 degree rotations to make the size and + * scaling calculations work out correctly */ + FFSWAP(int, inlink->w, inlink->h); + if (inlink->sample_aspect_ratio.num) + inlink->sample_aspect_ratio = av_inv_q(inlink->sample_aspect_ratio); + } + if (inlink->format == AV_PIX_FMT_VULKAN) return ff_vk_filter_config_input(inlink); @@ -1386,6 +1402,13 @@ static const AVOption libplacebo_options[] = { {"smpte2084", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE2084}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"}, {"arib-std-b67", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_ARIB_STD_B67}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"}, + {"rotate", "rotate the input clockwise", OFFSET(rotation), AV_OPT_TYPE_INT, {.i64=PL_ROTATION_0}, PL_ROTATION_0, PL_ROTATION_360, DYNAMIC, .unit = "rotation"}, + {"0", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_0}, .flags = STATIC, .unit = "rotation"}, + {"90", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_90}, .flags = STATIC, .unit = "rotation"}, + {"180", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_180}, .flags = STATIC, .unit = "rotation"}, + {"270", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_270}, .flags = STATIC, .unit = "rotation"}, + {"360", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_360}, .flags = STATIC, .unit = "rotation"}, + { "upscaler", "Upscaler function", OFFSET(upscaler), AV_OPT_TYPE_STRING, {.str = "spline36"}, .flags = DYNAMIC }, { "downscaler", "Downscaler function", OFFSET(downscaler), AV_OPT_TYPE_STRING, {.str = "mitchell"}, .flags = DYNAMIC }, { "frame_mixer", "Frame mixing function", OFFSET(frame_mixer), AV_OPT_TYPE_STRING, {.str = "none"}, .flags = DYNAMIC }, -- 2.49.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".