History

avfilter/vf_libplacebo: implement rotation option

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.

Niklas Haas committed 1 year ago

Commit 4f623b41 parent a79720e3 files · +35 −1Browse files

Unified · Split

3 files
  1. doc/filters.texi +10 −0
  2. libavfilter/avfilter.c +2 −1
  3. libavfilter/vf_libplacebo.c +23 −0
doc/filters.texi+10−0
@@ -16259,6 +16259,16 @@ and @code{(oh-ph)/2}. · 16258 unmodified lines
1625916259 Set the output placement width/height expressions, default values are @code{ow}
1626016260 and @code{oh}.
1626116261
16262+@item rotate
16263+Rotate the input frame clockwise by the specified angle.
16264+
16265+@table @samp
16266+@item 0, 360
16267+@item 90
16268+@item 180
16269+@item 270
16270+@end table
16271+
1626216272 @item fps
1626316273 Set the output frame rate. This can be rational, e.g. @code{60000/1001}. If
1626416274 set to the special string @code{none} (the default), input timestamps will
libavfilter/avfilter.c+2−1
@@ -1071,7 +1071,8 @@ int ff_filter_frame(AVFilterLink *link, AVFrame *frame) · 1070 unmodified lines
10711071 strcmp(link->dst->filter->name, "format") &&
10721072 strcmp(link->dst->filter->name, "idet") &&
10731073 strcmp(link->dst->filter->name, "null") &&
1074− strcmp(link->dst->filter->name, "scale")) {
1074+ strcmp(link->dst->filter->name, "scale") &&
1075+ strcmp(link->dst->filter->name, "libplacebo")) {
10751076 av_assert1(frame->format == link->format);
10761077 av_assert1(frame->width == link->w);
10771078 av_assert1(frame->height == link->h);
libavfilter/vf_libplacebo.c+23−0
@@ -193,6 +193,7 @@ typedef struct LibplaceboContext { · 192 unmodified lines
193193 int color_range;
194194 int color_primaries;
195195 int color_trc;
196+ int rotation;
196197 AVDictionary *extra_opts;
197198
198199 int have_hwdevice;
@@ -802,6 +803,13 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in, · 603 unmodified lines
802803 image->crop.y0 = av_expr_eval(s->crop_y_pexpr, s->var_values, NULL);
803804 image->crop.x1 = image->crop.x0 + s->var_values[VAR_CROP_W];
804805 image->crop.y1 = image->crop.y0 + s->var_values[VAR_CROP_H];
806+ image->rotation = s->rotation;
807+ if (s->rotation % PL_ROTATION_180 == PL_ROTATION_90) {
808+ /* Libplacebo expects the input crop relative to the actual frame
809+ * dimensions, so un-transpose them here */
810+ FFSWAP(float, image->crop.x0, image->crop.y0);
811+ FFSWAP(float, image->crop.x1, image->crop.y1);
812+ }
805813
806814 if (src == ref) {
807815 /* Only update the target crop once, for the 'reference' frame */
@@ -1198,6 +1206,14 @@ static int libplacebo_config_input(AVFilterLink *inlink) · 390 unmodified lines
11981206 AVFilterContext *avctx = inlink->dst;
11991207 LibplaceboContext *s = avctx->priv;
12001208
1209+ if (s->rotation % PL_ROTATION_180 == PL_ROTATION_90) {
1210+ /* Swap width and height for 90 degree rotations to make the size and
1211+ * scaling calculations work out correctly */
1212+ FFSWAP(int, inlink->w, inlink->h);
1213+ if (inlink->sample_aspect_ratio.num)
1214+ inlink->sample_aspect_ratio = av_inv_q(inlink->sample_aspect_ratio);
1215+ }
1216+
12011217 if (inlink->format == AV_PIX_FMT_VULKAN)
12021218 return ff_vk_filter_config_input(inlink);
12031219
@@ -1386,6 +1402,13 @@ static const AVOption libplacebo_options[] = { · 182 unmodified lines
13861402 {"smpte2084", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_SMPTE2084}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
13871403 {"arib-std-b67", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_ARIB_STD_B67}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
13881404
1405+ {"rotate", "rotate the input clockwise", OFFSET(rotation), AV_OPT_TYPE_INT, {.i64=PL_ROTATION_0}, PL_ROTATION_0, PL_ROTATION_360, DYNAMIC, .unit = "rotation"},
1406+ {"0", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_0}, .flags = STATIC, .unit = "rotation"},
1407+ {"90", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_90}, .flags = STATIC, .unit = "rotation"},
1408+ {"180", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_180}, .flags = STATIC, .unit = "rotation"},
1409+ {"270", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_270}, .flags = STATIC, .unit = "rotation"},
1410+ {"360", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_360}, .flags = STATIC, .unit = "rotation"},
1411+
13891412 { "upscaler", "Upscaler function", OFFSET(upscaler), AV_OPT_TYPE_STRING, {.str = "spline36"}, .flags = DYNAMIC },
13901413 { "downscaler", "Downscaler function", OFFSET(downscaler), AV_OPT_TYPE_STRING, {.str = "mitchell"}, .flags = DYNAMIC },
13911414 { "frame_mixer", "Frame mixing function", OFFSET(frame_mixer), AV_OPT_TYPE_STRING, {.str = "none"}, .flags = DYNAMIC },

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t