This allows choosing whether the `fit_mode` merely controls the placement
of the image within the output resolution, or whether the output resolution
is also adjusted according to the given `fit_mode`.
The semantics of these keywords are well-defined by the CSS 'object-fit'
property. This is arguably more user-friendly and less obtuse than the
existing `normalize_sar` and `pad_crop_ratio` options. Additionally, this
comes with two new (useful) behaviors, `none` and `scale_down`, neither of
which map elegantly to the existing options.
One additional benefit of this option is that, unlike `normalize_sar`, it
does *not* also imply `reset_sar`; meaning that users can now choose to
have an anamorphic base layer and still have the overlay images scaled to fit
on top of it according to the chosen strategy.
See-Also: https://drafts.csswg.org/css-images/#the-object-fit
Blending onto independent alpha framebuffers is not possible under the
constraints of the supported blend operators. While we could handle
blending premul-onto-premul, this would break if the base layer is YUV,
since premultiplied alpha does not survive the (nonlinear) YUV conversion.
Fortunately, blending independent-onto-premul is just as easy, and works in
all cases. So just force this mode when using a linear intermediate blend
texture, which is always RGBA.
Instead of directly mutating `opts->params`. Avoids any possible leak of
overriden params between invocations of this function, as well as the later
`pl_render_image` during the linear output pass.
Chooses the desired output alpha mode. Note that this depends on
an upstream version of libplacebo new enough to respect the corresponding
AVFrame field in pl_map_avframe_ex.
In constant FPS mode, it's possible for there no be *no* input active at
the current timestamp, even though there would be active inputs later in
the timeline (nb_active > 0). This would previously hit the AVERROR_BUG case.
With this change, we can instead output an empty frame.
Instead of having a single s->status field to track the most recently
EOF'd stream, track the number of active streams directly and only query
the most recent status at the end.
The reason this worked before is because we implicitly relied on the
assumption that `ok` would always be true until all streams are EOF, but
because it's possible to have gaps in the timeline when mixing multiple
streams, this is not always the case in principle.
In practice, this fixes a bug where the filter would early-exit (EOF)
too soon, when any input reached EOF and there is a gap in the timeline.
When using libplacebo to composite multiple streams with complex PTS
values, it's possible for there to be a "hole" in the output stream; in
particular in constant FPS mode. This commit refactors output_frame() to
allow it to handle the case of there being no active input.
pl_frame_mix_current() will return NULL if all frames are in the future,
but when libplacebo is using a frame mixer with a radius greater than 1,
future frames are expected to already be partially renderered. Instead, use
pl_frame_mix_nearest(), which is guaranteed to give us a valid frame for any
nonempty frame mix.
Fixes: 3091bca3ed
Instead of undconditionally using the first input. This covers the case of
one layer fully obscuring another layer, in which case that should become
the new "base" layer.
This prevents leaking stale metadata from previous frames, for example if
an overlay temporarily obscures this input and then un-obscures it again. It
is worth pointing out that this does change the semantics subtly, because of
the smoothing period on detected HDR metadata, but I argue that the new
behavior is an improvement, as it will avoid leaking past metadata that is
definitely no longer relevant after an image is unobscured.
Sometimes, one input fully obscures another. In this case, we can skip
actually rendering any input below the obscuring one.
The reason I don't simply start the main render loop at `idx_start` will
become apparent in the following commit.
We can't use pl_frame_is_cropped() on this dummy frame, but we need to
determine the reference frame before we can map the real output, so to
resolve this conflict, we just reimplement the crop detection logic using
the output link dimensions.
It is possible for pl_queue_update() to return PL_QUEUE_OK, but to generate
an empty frame mix. This happens if the first frame of that input is in the
future.
In this case, we should skip an input as not active, similar to inputs that
have already reached EOF.
Instead of copying over the entire target and changing a few fields,
set the entire struct to a whitelist of safe properties that we want to
persist on the intermediate texture.
In particular, this avoids leaking irrelevant state related to the
acquire/release callbacks, e.g., which can otherwise cause deadlocks
when the same vulkan frame is attempted to be acquired twice.
This gives vastly improved blending results than when blending directly in
the desired output colorspace. Overridable by the existing "disable_linear"
option.
This is functionally similar to combining multiple "libplacebo" filters,
but does not rely on the existence of a Vulkan filter link, so it can be used
without performance penalty in all circumstances. It's also enabled by
default, without requiring special action from the user.
This was requested by users of `vf_libplacebo`, to mirror the existing
option on the other `vf_scale_*` family of filters. While we have
`vf_normalize`, it was not as useful in the event that the content
stretching was actually desired.
Bridges an important usability gap between `vf_scale` and `vf_libplacebo`
that made mixing and matching the filters needlessly difficult.
This aligns the behavior of vf_libplacebo with other filters in the
vf_scale family, that forward any change in the SAR as a result of
changing the output resolution to the output frame / link, and updates
the ff_scale_adjust_dimensions() call to continue working as intended.
The new behavior reflects the documentation of vf_libplacebo, which
described this behavior despite that not being the way the filter worked
up to this point.
As an aside, also fixes a bug where the AVFrame SAR was inconsistent
with the AVFilterLink SAR when the s->nb_inputs > 1 condition was met.
Under normal circumstances, this change does not affect anything, as the vast
majority of filters either support only vulkan or only software formats.
However, when a filter supports both (such as vf_libplacebo itself, and
possibly vf_scale in the future), linking together two such filter instances
without an explicit format will default matching the input format, resulting
in a redundant round trip through host RAM.
This change bumps up AV_PIX_FMT_VULKAN to the first entry in the format list,
ensuring that it gets preferred whenever possible.
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.
While technically not specifiad as valid by the AVFilterLink documentation,
it is currently possible to get an FPS of zero from various sources inside
libavfilter (notably vf_buffersrc).
Avoid a division by zero and resulting infinity when this happens.
&pl_alpha_overlay expects straight alpha, but the alpha output may be
premultiplied as a result of the target alpha mode (or in the absence of an
alpha channel). Fix it by requesting independent alpha explicitly when
blending.
There is no reason to only do this on the first input. It doesn't actually
matter for now given that we don't constrain the color space list, but it
may matter when that changes.
Signed-off-by: Niklas Haas <git@haasn.dev>
Each input is entirely independent and can have varying pixel formats,
color spaces, etc. To accomplish this, we need to make a full copy of the
format list for each subsequent input, rather than sharing the same ref.
Signed-off-by: Niklas Haas <git@haasn.dev>
Sponsored-by: nxtedition
Fixes a deprecation warning, and also fixes a bug where the depredated
skip_target_clearing option was not correctly mapped to the new API inside
libplacebo upstream.
Signed-off-by: Niklas Haas <git@haasn.dev>
Sponsored-by: nxtedition
These were introduced in libplacebo API version 220. We actually already
map the field by default, but deinterlacing was never enabled unless the user
explicitly forced it using extra_ops.
For anamorphic videos, enabling this option leads to adjustment of
output dimensions to obtain square pixels when the user requests
proportional scaling through either of the w/h expressions or
force_original_aspect_ratio.
Output SAR is always reset to 1.
Option added to scale, scale_cuda, scale_npp & scale_vaapi.
libplacebo already has a similar option with different semantics,
scale_vt and scale_vulkan don't implement force_oar, so for these
three filters, I've made minimal changes needed to not break building
or change output.
This patch is analogous to 20f9727018:
It hides the internal part of AVFilter by adding a new internal
structure FFFilter (declared in filters.h) that has an AVFilter
as its first member; the internal part of AVFilter is moved to
this new structure.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Switches to av_frame_side_data_remove_by_props(), covering a number of
cases that we previously ignored. Additionally, stop stripping metadata
when merely changing colorspace or color range, since these do not
affect the actual color volume of the image data, only the encoding.
Setting it was broken in 8160178dfc, since
links are not yet set up during init. It is also redundant, as the
struct also stores the input index.
Reported-By: llyyr <llyyr.public@gmail.com>
avfilter API requires all the filter parameters, including hw context
(if present) to be available during init, so that is the proper place to
perform such setup.