This allows to use drm hwaccels that require a hwdevice.
Tested with v4l2request hwaccel and cedrus driver on an allwinner device
running mpv with --vo=gpu --gpu-context=drm --hwdec=drm.
At first, this code used only 1 plane, so the compatibility stuff was
sufficient. But then use of planes 1 and 2 was added, without extending
the compatibility stuff.
I think I've seen a case recently where this broke the build and caused
users to apply invalid fixes, but I don't remember where.
It's possible that I didn't get all defines that are needed.
I think I was wrong about having to reset the stats when mpv stops
producing frames, eg. when it's paused. As long as the swapchain doesn't
underflow, last_queue_display_time will still be accurate, because the
next frame produced should still be presented one vsync after the
last one in the swapchain.
If the swapchain underflows (which is the common case for when mpv is
paused for more than 150ms,) the next predicted frame time should be in
the past. It should be fine to leave last_queue_display_time unset in
this case, since vo.c will use the current time instead, which is a
decent guess (though it doesn't take vsync phase into account.)
last_sync_refresh_count and last_sync_qpc_time should be kept on
swapchain underflow as well. Assuming the display refresh rate doesn't
change while mpv is paused, they'll only provide a more accurate guess
of the vsync duration when mpv starts playing again. Also,
vsync_duration_qpc never needs to get reset. It will get overwritten
immediately in most cases, and when it doesn't, it's still a better
guess of the vsync duration than nothing.
That's just a single one. It used to be more, when FFmpeg still required
using pointless accessors for tons of fields, which historically broke
compatibility with Libav. (I think I wrote the patch to deprecate that
crap and to allow direct access myself.)
There may be more exceptions, but I forgot about them. Another point is
that we don't really trust FFmpeg ABI stability, though.
In spdif mode, there are hacks that try to cut audio on frame boundaries
(blame spdif, which is a hack in itself). The "alignment" is used in a
bunch of places, but --end does not respect it. This leads to some audio
that can't be pushed because the alignment is off (I don't know why, not
do I care), which puts audio into an underrun state forever.
Fix this by discarding unusable extra samples if no new data can be
expected.
Fixes: #6935
The C11 situation is complicated. For example, MinGW doesn't seem to
have a full C11 implementation, but we pretty much rely on C11 atomics.
Regarding "#pragma once": they say it's not standard because of unsolved
(admittedly valid) issues. Btu still, fuck writing include guards, I
just can't be bothered with this crap.
(Does anyone even read this document?)
I think a popular libmpv application did exactly this: enabling advanced
control, and then receiving deadlocks. I didn't confirm it, though. In
any case, the API docs should avoid tricking users into making this easy
mistake.
The render API (vo_libmpv) had potential deadlock problems with
MPV_RENDER_PARAM_ADVANCED_CONTROL. This required vd-lavc-dr to be
enabled (the default). I never observed these deadlocks in the wild
(doesn't mean they didn't happen), although I could specifically provoke
them with some code changes.
The problem was mostly about DR (direct rendering, letting the video
decoder write to OpenGL buffer memory). Allocating/freeing a DR image
needs to be done on the OpenGL thread, even though _lots_ of threads are
involved with handling images. Freeing a DR image is a special case that
can happen any time. dr_helper.c does most of the evil magic of
achieving this. Unfortunately, there was a (sort of) circular lock
dependency: freeing an image while certain internal locks are held would
trigger the user's context update callback, which in turn would call
mpv_render_context_update(), which processed all pending free requests,
and then acquire an internal lock - which the caller might not release
until a further DR image could be freed.
"Solve" this by making freeing DR images asynchronous. This is slightly
risky, but actually not much. The DR images will be free'd eventually.
The biggest disadvantage is probably that debugging might get trickier.
Any solution to this problem will probably add images to free to some
sort of queue, and then process it later. I considered making this more
explicit (so there'd be a point where the caller forcibly waits for all
queued items to be free'd), but discarded these ideas as this probably
would only increase complexity.
Another consequence is that freeing DR images on the GL thread is not
synchronous anymore. Instead, it mpv_render_context_update() will do it
with a delay. This seems roundabout, but doesn't actually change
anything, and avoids additional code.
This also fixes that the render API required the render API user to
remain on the same thread, even though this wasn't documented. As such,
it was a bug. OpenGL essentially forces you to do all GL usage on a
single thread, but in theory the API user could for example move the GL
context to another thread.
The API bump is because I think you can't make enough noise about this.
Since we don't backport fixes to old versions, I'm specifically stating
that old versions are broken, and I'm supplying workarounds.
Internally, dr_helper_create() does not use pthread_self() anymore, thus
the vo.c change. I think it's better to make binding to the current
thread as explicit as possible.
Of course it's not sure that this fixes all deadlocks (probably not).
When the (float) bitrate is returned, it is implicitely converted to an
int64 value, merely discarding the fractional part.
However the bitrate of a CBR track can vary a bit due to timestamp
precision loss after clock conversion (this can affect MPEG-TS audio
tracks). So a bitrate like 191999.999... results in 191999 when
being returned - instead of 192000.
To fix this, apply proper rounding, as already done for the "old" case.
Hereby refactoring the "old" case to also use `llrint`.
libass had an API to configure this since 2013. mpv always used
ASS_FONTPROVIDER_AUTODETECT, because usually there's little reason to
use anything else. The intention of the now added option is to allow
users to disable use of system fonts.
I didn't consider it worth the trouble to add the coretext and
directwrite enum items from ASS_DefaultFontProvider. The "auto" choice
will have the same effect if they're available. Also, the part of the
code which defines the option does not necessarily have libass available
(it's still optional!), so defining all enum items as choices is icky. I
still added fontconfig, since that may be nice to emulate a nostalgic
2010 feeling of mpv freezing on fontconfig.
The option for OSD is even less useful. (But you get it for free, and
why pass up a chance to add yet another useless option?)
This is not quite what was requested in #6947, but as close as it gets.
in->eof is used as an indicator whether reading packets still makes
sense. (Without this, the prefetcher would obviously burn CPU by
retrying reading even though everything has been read.)
This was not reset properly after seeks were performed. It led to
getting stuck in at least one corner case: when enabling a track, the
demuxer would seek backwards to get new packets from the current
playback position ("refresh seeks"). But if playback was paused, and EOF
was previously reached, it would not try to read packers again due to
in->eof being false. There was not anything else that would make it
retry reading, so it was stuck in a weird underrun/buffering state.
Fixes: #6986
This was a leftover from commit b2752321 which fixed#6522 but after
the recent demux refactoring this fix is superseded by commit 0f6cda4ab.
Remove the redundant update call.
This detected the first packet demuxed after a seek as timestamp
discontinuity. Obviously this is non-sense. Since the OGG radio streams
for which this feature was introduced are normally unseekable, it's
simple to fix this: simply disable it (if in auto mode, the default) as
soon as a seek is performed. This code is never called if the stream is
considered unseekable, unless the user forced it.
There's still a chance this linearization is performed before a seek
happens. This will be a bit awkward, but no worse than without this
feature, since seeking with timestamp resets is inherently broken in
both mpv and libavformat.
Fixes: #6974
Fixes: 27fcd4d
since the loading order of rpaths is system wide lib path, dev tool path
and then bundle lib path it's possible for the xcode swift libs to be
incompatible with the libs the bundle was build with. this leads to
possible segfaults. if we distribute the bundle we don't want to load
the libs from the dev tools anyway.
in xcode 11 the dynamic swift libraries were moved to a separated
versioned swift folder, which can't be used for linking and only for
distribution. additional to the std dynamic swift lib folder the system
wide folder is needed for linking too.
First we shift the values up to the actual amount of bits in draw_ass,
so that they will be drawn correctly when using formats with more than
8 bpc. (draw_rgba is already correct w.r.t. RGB formats with 9 or more
bpc)
Then, in scale_sb_rgba, by setting the amount of bits per channel used
for planar RGB formats (formats are always planar at this point in
draw_bmp) to be the same as the source from 9 to 16 bpc (in effect all
the various GBRP formats) we manage to fit the special case that does
not require any conversion in chroma_up and chroma_down when handling
these formats (as long as the source itself is a planar format),
instead writing directly to the combined dst/src buffer. This in turn
works around a bug (incorrect colors) in libswscale when scaling
between GBRP formats with 9 or more bpc. Additionally this should be
more efficient, since we skip up- and down-conversion and temporary
buffers.
We default to EGL instead of GLX now, which means vdpau only works
if we explicitly specify that we want a GLX context, as vdpau lacks
interop for EGL.
Update the hwdec documentation to reflect this.
Concerns #6980.
This adds vsync reporting to the D3D11 backend using the presentation
feedback provided by DXGI, which is pretty similar to what's provided by
GLX_OML_sync_control in the GLX backend. In DirectX, PresentCount is the
SBC, PresentRefreshCount and SyncRefreshCount are kind of like the MSC
and SyncQPCTime is the UST.
Unlike GLX, the DXGI API makes it possible for PresentCount and
SyncQPCTime to refer to different physical vsyncs, in which case
PresentRefreshCount and SyncRefreshCount will be different. The code
supports this possibility, even though it's not clear whether it can
happen when using flip-model presentation. The docs say for flip-model
apps, PresentRefreshCount is equal to SyncRefreshCount "when the app
presents on every vsync," but on my hardware, they're always equal, even
when mpv misses a vsync. They can definitely be different in exclusive
fullscreen bitblt mode, though, which mpv doesn't support now, but might
support in future.
Another difference to GLX is that, at least on my hardware,
PresentRefreshCount and SyncRefreshCount always refer to the last
physical vsync on which mpv presented a frame, but glxGetSyncValues can
apparently return a MSC and UST from the most recent physical vsync,
even if mpv didn't present a new frame on it. This might result in
different behaviour between the two backends after dropped frames or
brief pauses.
Also note, the docs for the DXGI presentation feedback APIs are pretty
awful, even by Microsoft standards. In particular the docs for
DXGI_FRAME_STATISTICS are misleading (PresentCount really is the number
of times Present() has been called for that frame, not "the running
total count of times that an image was presented to the monitor since
the computer booted.")
For good documentation, try these:
https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/dxgi-flip-modelhttps://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dpresentstatshttps://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/d3dkmthk/ns-d3dkmthk-_d3dkmt_present_stats
(Yeah, the docs for the D3D9Ex and even the kernel-mode version of this
structure are better than the DXGI ones. It seems possible that they're
all rewordings of the same internal Microsoft docs, but whoever wrote
the DXGI one didn't really understand it.)
The question came up on how a client would figure out where
screenshot-directory saved its screenshots if it contained
mpv-specific expansions. This command should remedy the situation
by providing a way for the client to ask mpv to do an expansion.
Previously the options were tested by compiling a test program with the
option, and support was "detected" if the compilation didn't fail.
However, both gcc and clang only issue a warning on unknown warning option,
hence it never failed and all the warn options were detected as supported.
Now the tested option is used together with -Werror, which makes it fail
if it warns that the warning option is unknown.
Fixes clang unknown option warnings -Wno-format-truncation since 4a6b56f .
Certain mpv config options require wl->current_output to be created
before the video can actually start rendering. Just always create it
here if the current_output doesn't exist (the one exception being the
--fs option with no --fs-screen flag). Incidentally, this also fixes
--fs-screen not working on wayland.
This test requires libavutil headers but there is no avutil
dependency for it to use. So let's add one, and also reorder the
ffmpeg tests ahead of the video tests so that the avutil dependency
can be used.
../misc/linked_list.h:71:34: warning: the address of ‘e6’ will always
evaluate as ‘true’ [-Waddress]
No shit, e6 is on the stack. But the macro argument is also allowed to
be NULL. Add some dumb nonsense to shut up the useless warning. (It's
probably useful in other contexts though, so don't disable it
completely.)
Just use cmocka's function. It takes an epsilon argument, which we now
provide directly.
There's no assert_double_equal() in cmocka (and the float variant
actually forces a conversion to the float type), but fortunately we
didn't use it.
(At first I left this intentionally, because the temporarily disabled
stream ctrl code used it, but there's actually no reason to annoy
everyone with the warning.)
Use `private-code` instead of `code` here. Also this bumps up the
required wayland-client/wayland-cursor version to 1.15 which is still
pretty old anyway.
reinit_audio_filters_and_output() can fully shutdown the audio chain on
failure. Specifically, it will deallocate mpctx->ao_chain. The value of
that field was cached in ao_c. The code after the call did not account
that the audio chain can be shutdown, and used the stale ao_c value.
Fixes: #6808
During initial testing with US closed captions, ARIB captions,
timed text in MP4 or the specific external SRT files I tested with
there were no hints that this flag would be needed for seeking to
work.
Unfortunately, that result seems to have been incorrect.
Fixes#6970
If a file format supports PTS resets, get_current_pos_ratio calculates
the ratio using the stored filepos in the demuxer struct instead of a
standard query of the current time in the stream and its total length.
This seems like a reasonable way to avoid weird PTS values, but in
reality this just causes problems and results in inaccurate ratio
values that can affect other parts of the player (most notably the osc
seekbar).
For libavformat formats, demux->filepos is obtained from the
demux_lavf_fill_buffer function which is called on the next packet. The
problem is that there is a slight delay between packets and in some
cases, this delay can be relatively large. That means the obtained
demuxer->filepos value will be very inaccurate since it obtains the pos
from the end of the upcoming packet and not its actual current position.
This is especially noticeable at the very beginning of playback where
get_current_pos_ratio sometimes returns a value of well over 2% despite
less than a second passing in the stream. Another telltale sign is to
simply watch the osc seekbar as a stream progresses and observe how it
loads in staggered steps as every packet is decoded. In contrast, the
seekbar progresses smoothly on the playback of a format that does not
support PTS resets. The simple solution is to instead use the query of
the current time and length of a stream and calculate the ratio that
way.
get_current_pos_ratio will still fallback on using the byte stream
position if the previous queries fail. However, get_current_time will
be more accurate in the vast majority of cases and should be the
preferred method of calculating the position ratio.