This will help with things like livestreams.
As a minor detail, subtitles are excluded, because they sometimes have
"unused" events after video and audio ends. To avoid this annoying
corner case, just ignore them.
Before this change and before the seekable stream cache became a thing,
we could possibly seek using the stream cache. But we couldn't know
whether the seek would succeed. We knew the available byte range, but
could in general not tell whether a demuxer would stay within the range
when trying to seek to a specific time position. We preferred to have
safe defaults, so seeking in streams that were detected as unseekable
were not honored. We allowed overriding this via --force-seekable=yes,
in which case it depended on your luck whether the seek would work, or
the player crapped its pants.
With the demuxer packet cache, we can tell exactly whether a seek will
work (at least if there's only 1 seek range). We can just let seeks go
through. Everything to allow this is already in place, and this commit
just moves around some minor things.
Note that the demux_seek() return value was not used before, because low
level (i.e. network level) seeks are usually asynchronous, and if they
fail, the state is pretty much undefined. We simply repurpose the return
value to signal whether cache seeking worked. If it didn't, we can just
resume playback normally, because demuxing continues unaffected, and no
decoder are reset.
This should be particularly helpful to people who for some reason stream
data into stdin via streamlink and such.
In commit 1199c1e3, we added checks to every libarchive API call to make
sure the archive was closed on ARCHIVE_FATAL - otherwise, libarchive
could endow us with free CVEs (such as it apparently happens when you
continue reading a rar archive that uses features not yet supported by
libarchive).
This broke the fallback for seeking in unseekable archive formats. Of
course libarchive won't tell us directly whether a format implementation
has seek support or not - and OF COURSE it returns ARCHIVE_FATAL if it
has no seek support. (The error string, which you can retrieve via API,
is actually more detailed, and also claims it's an "internal error". I
don't think so, libarchive.) Returning ARCHIVE_FATAL means we have to
assume free CVEs are ahead, and we have to close the archive. Which
breaks the fallback in a dumb way (we have no way of telling which of
those cases happened anyway).
Fix this by assuming that all seek errors are potentially due to lack of
seek support. If the seek call fails, reopen the archive, and set a flag
so the seek API is never tried again. (This means we can still skip
ahead for forward seeks, which is more efficient than skipping from the
start of the archive entry.)
Also fix an old typo in an error message.
Caused by the relatively recent change to packet parsing. This time it
was probably triggered by lace type 0, which reduces the byte length of
a 0 sized packet to 3 (timestamp + flag) instead of 4 (lace count for
other lace types). The thing about laces is just my guess why it worked
for other 0 sized packets, though.
Also remove the redundant and now incorrect check below.
Fixes#5271.
This log line tells us why the demuxer is trying to read more, which us
useful when debugging queue overflows. Probably barely useful, but I
think keeping that flag separately also makes the code slightly easier
to understand.
Same as previous commit, but for the OSC.
(A bit of a waste to request demuxer-cache-state at least twice per
frame, but the OSC queries so many properties it probably doesn't matter
anymore.)
I don't want to add another field to display stream and demuxer cache
separately, so just add them up. This strangely makes sense, since the
forward buffered stream cache amount consists of data not read by the
demuxer yet. (If the demuxer cache has buffered the full stream, the
forward buffered stream cache amount is 0.)
Reduce it from 75MB in both directions (forward/backwards) to 10MB each.
The stream cache is kind of becoming useless in favor of the demuxer
cache. Using both doesn't make much sense, because they will contain
duplicated data for no reason.
Still leave it at 10MB, which may help with mp4 a bit. libavformat's mp4
demuxer tends to seek too much, so we try to avoid triggering network
level seeks by having some caching in the stream layer.
This fixes weird behavior in the following case:
- open a file
- make sure the max. demuxer forward cache is smaller than the
file's video track
- make sure the max. readahead duration is larger than the file's
duration
- disable the audio track
- seek to the beginning of the file
- once the cache has filled enable the audio track
- a queue overflow warning should appear
(- looking at the seek ranges is also interesting)
The queue overflow warning happens because the packed queue for the
video track will use up the full quota set by --demuxer-max-bytes. When
the audio track is enabled, reading an audio packet would technically
overflow the packet cache by the size of whatever packet is read next.
This means the demuxer signals EOF to the decoder, and once playback has
consumed enough video packets so that audio packets can be read again,
the decoder resumes from EOF. This interacts badly with A/V
synchronization and the whole thing can randomly crap itself until audio
has fully recovered.
We didn't care about this so far, but we want to raise the readahead
duration to something very high, so that the demuxer cache is fully
used. This means this case can be hit quite quickly by switching audio
or subtitle tracks, and is not really an obscure corner case anymore.
Fix this by always losing all cache. Since the cache can't be used
anyway until the newly selected track has been read, this is not much of
a disadvantage. The only thing that could be brought up is that
unselecting the track again could resume operation normally. (Maybe this
would be useful if network died completely without chance of recovery.
Then you could watch the already buffered video anyway by deselecting
the audio track again.) But given the headaches, this seems like the
better solution.
Unfortunately this requires adding new new strange fields and strangely
fragmenting state management functions again. I'm sure whoever works on
this in the future will hate me. Currently it seems like the lesser
evil, and much simpler and robust than the other potential solutions.
In case this needs to be revisited, here is a reminder for readers from
the future what alternative solutions were considered, without those
disadvantages:
A first attempted solution allowed the demuxer to buffer some additional
packets on track switching. This would allow it to read enough data to
feed the decoder at least. But it was still awkward, as it didn't allow
the demuxer to continue prefetching the newly selected track. It also
barely worked, because you could make the forward buffer "over full" by
seeking back with seekable cache enabled, and then it couldn't read
packets anyway.
As alternative solution, we could always demux and cache all tracks,
even if they're deselected. This would also not require a network-level
seek for the "refresh" logic (it's the thing that lets the video decoder
continue as if nothing happened, while actually seeking back in the
stream to get the missing audio packets, in the case of enabling a
previously disabled audio track). But it would also possibly waste
network and memory resources, depending on what the user actually wants.
A second solution would just account the queue sizes for each stream
separately. We could freely fill up the audio packet queue, even if the
video queue is full. Since the demuxer API returns interleaved packets
and doesn't let you predict which packet type comes next, this is not as
simple as it sounds, but it'd probably tie in nicely with the "refresh"
logic.
A third solution would be removing buffered video packets from the end
of the packet queue. Since the "refresh" logic gets these anyway, there
is no reason to keep them if they prevent the audio packet queue from
catching up with the video one. But this would require additional logic,
would interact badly with a bunch of other corner cases. And as far as
the code goes, it's rather complex, because all the logic is written
with FIFO behavior in mind (including the fact that the packet queue is
a singly linked list with no backwards links, making removal from the
end harder).
Some old crap which nobody needs and which probably nobody uses.
This relies on a GCC extension: using "## __VA_ARGS__" to remove the
comma from the argument list if the va args are empty. It's supported
by clang, and there's some chance newer standards will introduce a
proper way to do this. (Even if it breaks somewhere, it will be a
problem only for 1 release, since I want to drop the deprecated
properties immediately.)
Libav has been broken due to the hwdec changes. This was always a
temporary situation (depended on pending patches to be merged), although
it took a bit longer. This also restores the travis config.
One code change is needed in vd_lavc.c, because it checks the AV_PIX_FMT
for videotoolbox (as opposed to the mpv format identifier), which is not
available in Libav. Add an ifdef; the affected code is for a deprecated
option anyway.
This hack was part of a solution to VSync judder in desktop OpenGL on
Windows. Rather than using blocking-SwapBuffers(), mpv could use
DwmFlush() to wait for the image to be presented by the compositor.
Since this would only work while the compositor was running, and the
compositor was silently disabled when OpenGL entered exclusive
fullscreen mode, mpv needed a way to detect exclusive fullscreen mode.
The code that is being removed could detect exclusive fullscreen mode by
checking the state of an undocumented mutex using undocumented native
API functions, but because of how fragile it was, it was always meant to
be removed when a better solution for accurate VSync in OpenGL was
found. Since then, mpv got the dxinterop backend, which uses desktop
OpenGL but has accurate VSync. It also got a native Direct3D 11 backend,
which is a viable alternative to OpenGL on Windows.
For people who are still using desktop OpenGL with WGL, there shouldn't
be much of a difference, since mpv can use other API functions to detect
exclusive fullscreen.
Refactored and split the `reinit_window_state` code into four
separate functions:
- `update_window_style` used to update window styles without
modifying the window rect.
- `fit_window_on_screen` used to adjust the window size when it is
larger than the screen size. Added a helper function `fit_rect` to
fit one rect on another without using any data from w32 struct.
- `update_fullscreen_state` used to calculate the new fullscreen
state and adjust the window rect accordingly.
- `update_window_state` used to display the window on screen with
new size, position and ontop state.
This commit fixes three issues:
- fixed#4753 by skipping `fit_window_on_screen` for a maximized
window, since maximized window should already fit on the screen.
It should be noted that this bug was only reproducible with
`--fit-border` option which is enabled by default. The cause of the
bug is that after calling the `add_window_borders` for a maximized
window, the rect in result is slightly larger than the screen rect,
which is okay, `SetWindowPos` will interpret it as a maximized state
later, so no auto-fitting to screen size is needed here.
- fixed#5215 by skipping `fit_window_on_screen` when leaving fullscreen.
On a multi-monitor system if the mpv window was stretched to cover
multiple monitors, its size was reset after switching back from
fullscreen to fit the size of the active monitor. Also, when changing
`--ontop` and `--border` options, now only the
`update_window_style` and `update_window_state` functions are used,
so `fit_window_on_screen` is not used for them too.
- fixed#2451 by moving the `ITaskbarList2_MarkFullscreenWindow`
below the `SetWindowPos`. If the taskbar is notified about fullscreen
state before the window is shown on screen, the taskbar button could
be missing until Alt-TAB is pressed, usually it was reproducible on
Windows 8.
Other changes:
- In `update_fullscreen_state` the `reset window bounds` debug
message now reports client area size and position, instead of window area
size and position. This is done for consistency with debug messages
in handling fullscreen state above in this function, since they also print
window bounds of the client area.
- Refactored `gui_thread_reconfig`. Added a new window flag `fit_on_screen`
to fit the window on screen even when leaving fullscreen. This is needed
for the case when the new video opened while the window is still in the
fullscreen state.
- Moved parent and fullscreen state checks out from the WM_MOVING to
`snap_to_screen_edges` function for consistency with other functions.
There's no point in keeping these checks out of the function body.
When window and screen size and position are stored in RECT, it's
much easier to modify them using WinAPI functions.
Added two macros to get width and height of the rect.
This was off for mpv CLI, but on for libmpv. The motivation behind this
was that it would be confusing for applications if libmpv continued
playback in a severely "degraded" way (without either audio or video),
and that it would be better to fail early.
In reality the behavior was just a confusing difference to mpv CLI, and
has confused actual users as well. Get rid of it.
Not bothering with a version bump, since this is so minor, and it's easy
to ensure compatibility in affected applications by just setting the
option explicitly.
(Also adding the missing next-release-marker in client-api-changes.rst.)
I've decided that MP_TRACE means “noisy spam per frame”, whereas
MP_DBG just means “more verbose debugging messages than MSGL_V”.
Basically, MSGL_DBG shouldn't create spam per frame like it currently
does, and MSGL_V should make sense to the end-user and provide mostly
additional informational output.
MP_DBG is basically what I want to make the new default for --log-file,
so the cut-off point for MP_DBG is if we probably want to know if for
debugging purposes but the user most likely doesn't care about on the
terminal.
Also, the debug callbacks for libass and ffmpeg got bumped in their
verbosity levels slightly, because being external components they're a
bit less relevant to mpv debugging, and a bit too over-eager in what
they consider to be relevant information.
I exclusively used the "try it on my machine and remove messages from
MSGL_* until it does what I want it to" approach of refactoring, so
YMMV.
Annoying exception that makes no sense to keep. Normally, users or
client applications will either use --hwdec=auto, or not set the option
at all, which both leads to the expected result.
By default the CreateProcess changes the mouse cursor to
IDC_APPSTARTING. The new flag added to STARTUPINFOEXW prevents
changing the cursor from default arrow on creating a new process.
This commit introduces mp.utils.file_info() for querying information
on file paths, implemented for both Lua and Javascript.
The function takes a file path as an argument and returns a Lua table /
JS object upon success. The table/object will contain the values:
mode, size, atime, mtime, ctime and the convenience booleans is_file, is_dir.
On error, the Lua side will return `nil, error` and the Javascript side
will return `undefined` (and mark the last error).
This feature utilizes the already existing cross-platform `mp_stat()`
function.
The OpenType Font File specification recommends that "Collection fonts
that use CFF or CFF2 outlines should have an .OTC extension." mpv
should accept .otc as a fallback extension for font detection should
the mimetype detection fail.
IETF RFC8081 added the "font" top-level media type,
including font/ttf, font/otf, font/sfnt, and also
font/collection. These font formats are all supported
by mpv/libass but they are not accepted as valid
Matroska mime types. mpv can load them via file extension
and they work as expected, so files using the new types
should not trigger a warning from mpv.
Full range YUV causes problems everywhere. For example it's usually the
wrong choice when using encoding mode, and libswscale sometimes messes
up when converting to full range too. (In this partricular case, we
found that converting rgba->yuv420p16 full range actually seems to
output limited range.)
This actually restores a similar heueristic from the late vf_scale.c.
When autoprobing the hwdec interops (which now happens to all compiled
interops if hardware decoding is used), failure to load an interop
should not print an error in the normal case. So hide it.
(We could make the log level conditional on whether autoprobing is used,
but directly loading it without autoprobing is obscure, and most other
interops don't do this either.)
For METHOD_INTERNAL hwdecs (non-copy cases), make sure the VO interops
are always loaded, because those decoders will output hardware pixel
formats, which will need special support in vo_gpu. Otherwise,
initialization will fail, complaining that it can't convert the output
format to something the VO supports.
It seems like there's nothing stopping from sub-demuxers from keeping
packets in the cache, even if it's completely pointless. The top-most
demuxer (demux_timeline) already takes care of caching, so sub-demuxers
only waste space and time with this.
Add a function that can disable the packet cache even at runtime and
after packets are read. (It's not clear whether it really can happen
that packets are read before demux_timeline gets the sub-demuxers, but
there's no reason to make it too fragile.) Call it on all sub-demuxers.
For this to work, it seems we have to move the code for setting the
seekable_cache flag to before demux_timeline is potentially initialized,
because otherwise the cache would be reenabled if the demuxer triggering
timeline support is a timeline segment itself (e.g. ordered chapters).
This fixes missing audio when cycling through audio tracks with anything
that uses nested demuxers, such as demux_timeline, which us used for
EDL, --merge-files, ordered chapters, and youtube-dl pseudo DASH
support. When this bug happened, reenabling an audio track would lead to
silence for the duration of the readahead amount.
The underlying reason is the incorrectly updated buffered range on track
switch. It accidentally included the amount covered by the deselected
stream. But the cause of the observed effect was that demux_timeline
issued a refresh seek to the underlying slave demuxer, which in turn
thought it could do a cache seek, because the seek range still included
everything.
update_stream_selection_state() calls update_seek_ranges() to update the
seek ranges after a track switch. When reenabling the track, ds->eager
was set to false during update_seek_ranges(), which made it think the
stream was sparse, and thus it didn't restrict the current seek range
(making later code think everything was buffered). Fix this by moving
some code, so we first update the ds->eager flag, then the seek ranges.
Also verbose log the low level stream selection calls.
Calling do_deactivate_getch2 before joining the terminal thread could
lead to breakage if the terminal thread got another interation in before
it was signaled to stop.
This also addresses a minor error with the order in which things are
initialized - getch2_poll would previously call tcgetpgrp(tty_in) before
tty_in was initialized, which did not lead to broken behavior, but was
not correct either.
Fixes#5195
This implements a poll-compatible interface, backed by select on macOS,
suitable for polling on device files - which are not supported by
macOS's implementation of poll. This is a (long-standing) bug in macOS,
so hopefully we can eventually remove this shim.
'help' is a valid value for a lot of mpv options, such as `hwdec`
or `vo` for printing available values, so this change makes the
output of OPT_CHOICE options like `--video-sync=help` more
consistent by not reporting an error about invalid value 'help'.
update_subtitles() makes sure all subtitle packets at/before the given
PTS have been read and processed. Normally, this function is only called
before sending a frame to the VO. This is too late for vf_sub, which
expects the subtitles to be updated before feeding a frame to the
filters.
Apparently this was specifically a problem for the first frame.
Subsequent frames might have been ok due to general prefetching.
(This will fail anyway, should a filter dare to add an offset to the
timestamps of the filered frames before they pass to vf_sub.)
Fixes#5194.
POSIX permits select() to modify the timeout, which can happen on the
Linux implementation. This can reset the timeout, which spins this into
a tight loop. A timeout isn't necessary in the first place, so just use
NULL instead.
This was a bit confused, and I bet nobody understood whether to use
--sub-file or --sub-files, and what the difference is. Explicitly
mention that both variants exist, and how they are related.
Until now, using --sub-file would add only subtitle tracks from the
given file. (E.g. if you passed a video file, only the subtitle tracks
from it were added, not the video or audio tracks.)
This is slightly messy (because streams are hidden), and users don't
even want it, as shown by #5132. Change it to always add all streams.
But if there's no stream of the wanted type, we still report an error
and do not add any streams. It's also made sure none of the other track
types are autoselected.
Also adjust the error messages on load failure slightly.
Fixes#5132.
It appears libavformat never sets the file start time for subtitles, so
this special check is not needed. The original idea was probably that
_if_ the demuxer set the start time to the first subtitle packet, the
subtitles would be shifted incorrectly.
* Distinguish between the window being moved or not.
* Skip trying to snap if currently in full screen or an embedded
window.
* Exit snapped state if the size changed when the window was being
moved.
Check the expected width and height against up-to-date
window placement. If they do not match, we will consider snapping
to have happened on Windows' side.
Previously when using a libmpv instance to play multiple videos,
once --start was set there was no clear way to unset it. You could
use --start=0, but 0 does not always mean the beginning of the file
(especially when using --rebase-start-time=no). Looking up the start
timestamp and passing that in also does not always work, particularly
when the first timestamp is negative (since negative values to --start
have a special meaning).
This commit adds a new "none" value which maps to the internal
REL_TIME_NONE, matching the default value of the play_start option.
Fixes display-sync (though if you change virtual desktops you'll need to seek
to re-enable display-sync) partially under wayland.
As an advantage, rendering is completely disabled if you change desktops or
alt+tab so you lose no performance if you leave mpv running elsewhere as long
as it isn't visible.
This could also be ported to other VOs which supports it.
Most options that change the playback endpoint coexist and playback
stops when it reaches any of them. (e.g. --ab-loop-b, --end, or
--chapter). This patch extends that behavior to --length so it isn't
automatically trumped by --end if both are present. These two will
interact now as the other options do.
This change is also documented in DOCS/man/options.rst.
Using --loop-file should now seek to the position denoted by --start
or equivalent option, rather than always seeking to the beginning as
it had done before. --loop-playlist already behaves this way, so
this brings --loop-file in line for added consistency.
If --ab-loop-b is present, then ab-looping will be enabled and will
attempt to seek to the beginning of the file. This patch changes it
so it will instead seek to the start of playback, either via --start
or some equivalent, rather than always to the beginning of the file.
Added a get_play_start_pts function to coincide with the
already-existing get_play_end_pts. This prevents code duplication
and also serves to make it so code that probes the start time
(such as get_current_pos_ratio) will work correctly with chapters.
Included is a bug fix for misc.c/rel_time_to_abs that makes it work
correctly with chapters when --rebase-start-time=no is set.
We need to support hardware/drivers which do not support ARGB8888 in
their primary plane.
We also use p->primary_plane_format when creating the gbm surface, to
make sure it always matches (in actuality there should be little
difference).
Passing in an invalid DRM overlay id with the --drm-overlay option would
cause drmplane to be freed twice: once in the for-loop and once at the
error-handler label fail.
Solve by setting drmpanel to NULL after freeing it.
Also the 'return false' statement after the error handler label should
probably be 'return NULL', given that the return type of
drm_atomic_create_context returns a pointer.
vo_x11 and vo_xv need this. According to the Linux manpage, all involved
functions are POSIX-2001 anyway. (I just assumed they were not, because
they're mostly System V UNIX legacy garbage.)
If the codec uses AV_CODEC_HW_CONFIG_METHOD_INTERNAL, and we're using
the -copy method, then don't request the native pix_fmt. It might not
have a AVFrame.hw_frames_ctx set, and we couldn't read back at all. On
top of that, most of those decoders probably don't provide read-back
when using such opaque formats anyway, while providing separate decoding
modes to decode to RAM.
Finally get rid of all the HWDEC_* things, and instead rely on the
libavutil equivalents. vdpau still uses a shitty hack, but fuck the
vdpau code.
Remove all the now unneeded remains. The vdpau preemption thing was not
unused anymore; if someone cares this could probably be restored.
This code is for trying to avoid using an emulation layer when using
auto probing, so that we end up using the actual API the drivers
provide. It was destroyed in the recent refactor.
With the recent changes, mpv's internal mechanisms got synced to
libavcodec's once more. Some things are still needed for filters (until
the mechanism gets replaced), but there's no need to require other hwdec
methods to use these fields. So remove them where they are unnecessary.
Also fix some minor leaks in the dxva2 backends, and set the driver_name
field in the Apple ones. Untested on Apple crap.
Otherwise, if e.g. "nvdec" didn't work, but "nvdec-copy" did, it would
never try "vdpau", which is actually the next non-copy mode on the
autprobe list. It's really expected that it selects "vdpau". Fix this by
sorting the -copy modes to the end of the final hwdec list.
But we still don't want preferred -copy modes like "nvdec-copy" to be
sorted after fragile non-preferred modes like "cuda", and --hwdec=auto
should prefer "nvdec-copy" over it, so make sure the copying mode does
not get precedence over preferred vs. non-preferred mode.
Also simplify the existing auto_pos sorting condition, and fix the
fallback sort order (although that doesn't matter too much).
This is never updated after the AO inits, so there are several cases
where the volume would stay at 100%, even if it shouldn't. This affects
initial volume as well as track switching or switching between files.
dlopen() and dlsym() can fail in various ways, and we can find out
how it failed by calling dlerror(). This is particularly useful if
you typo the filename of a script when explicitly passing it with
--script, and dlopen actually tells you that the file doesn't exist
instead of leading you down a rabbit hole of disassembling your
shared object file to figure out why the thing won't load.
Change it from explicit metadata about every hwaccel method to trying to
get it from libavcodec. As shown by add_all_hwdec_methods(), this is a
quite bumpy road, and a bit worse than expected.
This will probably cause a bunch of regressions. In particular I didn't
check all the strange decoder wrappers, which all cause some sort of
special cases each. You're volunteering for beta testing by using this
commit.
One interesting thing is that we completely get rid of mp_hwdec_ctx in
vd_lavc.c, and that HWDEC_* mostly goes away (some filters still use it,
and the VO hwdec interops still have a lot of code to set it up, so it's
not going away completely for now).
Seems like they finally got rid of this. It was the first lavc vdpau
API, and mpv stopped supporting it in favor of newer APIs a long time
ago, causing confusion to users who tried to enable vdpau decoding by
forcing the decoders (MPlayer style).
The libavcodec mediacodec support does not conform to the new hwaccel
APIs yet. It has been agreed uppon that this glue code can be deleted
for now, and support for it will be restored at a later point.
Readding would require that it supports the AVCodecContext.hw_device_ctx
API. The hw_device_ctx would then contain the surface ID.
vo_mediacodec_embed would actually perform the task of creating
vo.hwdec_devs and adding a mp_hwdec_ctx, whose av_device_ref is a
AVHWDeviceContext containing the android surface.
It makes more sense to have it in the general video directory (along
with vdpau.c and vaapi.c), since the decoder source files don't even
access it anymore.
Like with all hwaccels, there's little that is actually specific to
decoding (which has been moved away anyway), and what is left are
declarations (which will also go away soon).
Lots of shit code for nothing. We probably could just use libavutil's
code for all of this. But for now go with this, since it tends to
prevent stupid terminal messages during probing (libavutil has no
mechanism to selectively suppress errors specifically during probing).
Ignores the "emulated" API flag (for avoiding vaapi/vdpau wrappers), but
it doesn't matter that much for -copy anyway.
This leaked 2 unreffed AVFrame structs (roughly 1KB) per decoded frame.
Can I blame the FFmpeg API and the weird difference between freeing and
unreffing an AVFrame?
The idea is to get rid of vd_lavc_hwdec, so special functionality like
this has to go somewhere else. At this point, hwframes_refine is only
needed for d3d11, and it doesn't do much, so for now the new callback
has no context. In can be made more fancy if really needed.
The testing_only field is not referenced anymore with vaglx removed and
the previous commit dropping all uses.
The ra_hwdec_driver.api field became unused with the previous commit,
but all hwdec interop drivers still initialized it.
Since this touches highly OS-specific code, build regressions are
possible (plus the previous commit might break hw decoding at runtime).
At least hwdec_cuda.c still used the .api field, other than initializing
it.
Make the VO<->decoder interface capable of supporting multiple hwdec
APIs at once. The main gain is that this simplifies autoprobing a lot.
Before this change, it could happen that the VO loaded the "wrong" hwdec
API, and the decoder was stuck with the choice (breaking hw decoding).
With the change applied, the VO simply loads all available APIs, so
autoprobing trickery is left entirely to the decoder.
In the past, we were quite careful about not accidentally loading the
wrong interop drivers. This was in part to make sure autoprobing works,
but also because libva had this obnoxious bug of dumping garbage to
stderr when using the API. libva was fixed, so this is not a problem
anymore.
The --opengl-hwdec-interop option is changed in various ways (again...),
and renamed to --gpu-hwdec-interop. It does not have much use anymore,
other than debugging. It's notable that the order in the hwdec interop
array ra_hwdec_drivers[] still matters if multiple drivers support the
same image formats, so the option can explicitly force one, if that
should ever be necessary, or more likely, for debugging. One example are
the ra_hwdec_d3d11egl and ra_hwdec_d3d11eglrgb drivers, which both
support d3d11 input.
vo_gpu now always loads the interop lazily by default, but when it does,
it loads them all. vo_opengl_cb now always loads them when the GL
context handle is initialized. I don't expect that this causes any
problems.
It's now possible to do things like changing between vdpau and nvdec
decoding at runtime.
This is also preparation for cleaning up vd_lavc.c hwdec autoprobing.
It's another reason why hwdec_devices_request_all() does not take a
hwdec type anymore.
nvdec aka cuvid aka cuda should work much better than vdpau, and support
newer codecs (such as vp9), and more advanced surface formats (like 10
bit).
This requires moving the d3d hwaccels in the autoprobe order, since on
Windows, d3d decoding should be preferred over nvidia proprietary stuff.
Users of older drivers will need to force --hwdec=vdpau, since it could
happen that the vo_gpu cuda hwdec interop loads (so the vdpau interop is
not loaded), but the hwdec itself doesn't work.
I expect this does not break AMD (which still needs vdpau for vo_gpu
interop, until libva is fixed so it can fully support AMD).
This has stopped being useful a long time ago, and it's the only GPL
source file in the vo_gpu source directories. Recently it wasn't even
loaded at all, unless you forced loading it.
stdatomic.h defines no atomic_float typedef. We can't just use _Atomic
unconditionally, because we support compilers without C11 atomics. So
just create a custom atomic_float typedef in the wrapper, which uses
_Atomic in the C11 code path.
This does what af_volume used to do. Since we couldn't relicense it,
just rewrite it. Since we don't have a new filter mechanism yet, and the
libavfilter is too inconvenient, do applying the volume gain in ao.c
directly. This is done before handling the audio data to the driver.
Since push.c runs a separate thread, and pull.c is called asynchronously
from the audio driver's thread, the volume value needs to be
synchronized. There's no existing central mutex, so do some shit with
atomics. Since there's no atomic_float type predefined (which is at
least needed when using the legacy wrapper), do some nonsense about
reinterpret casting the float value to an int for the purpose of atomic
access. Not sure if using memcpy() is undefined behavior, but for now I
don't care.
The advantage of not using a filter is lower complexity (no filter auto
insertion), and lower latency (gain processing is done after our
internal audio buffer of at least 200ms).
Disavdantages include inability to use native volume control _before_
other filters with custom filter chains, and the need to add new
processing for each new sample type.
Since this doesn't reuse any of the old GPL code, nor does indirectly
rely on it, volume and replaygain handling now works in LGPL mode.
How to process the gain is inspired by libavfilter's af_volume (LGPL).
In particular, we use exactly the same rounding, and we quantize
processing for integer sample types by 256 steps. Some of libavfilter's
copyright may or may not apply, but I think not, and it's the same
license anyway.
Oops. This is part of the TV code, for which we didn't make any effort
to relicense. But files were always built, because they didn't depend on
the common TV code. (The HAVE_GPL in the source file exposed this by
making the build fail.)
These couldn't be relicensed, and won't survive the LGPL transition. The
other existing filters are mostly LGPL (except libaf glue code).
This remove the deprecated pan option. I guess it could be restored by
inserting a libavfilter filter (if there's one), but for now let it be
gone.
This temporarily breaks volume control (and things related to it, like
replaygain).
The internal stereo3d filter was removed due to being GPL only, and due
to being a mess that somehow used libavfilter's filter. Without this
filter, it's hard to remove our internal stereo3d image attribute, so
even using libavfilter's stereo3d filter would not work too well (unless
someone fixes it and makes it able to use AVFrame metadata, which we
then could mirror in mp_image).
This was never well thought-through anyway, so just drop it. I think
some "downsampling" support would still make sense, maybe that can be
readded later.
Now using libavfilter filters directly.
The rotation case is a bit lazy, because it uses the slow vf_rotate
filter in all cases, instead of using special filters for 90° step
rotations.
This was marked GPL, because the implementation in command.c (which is
shared with the subtitle code) was marked as GPL. This has been changed,
so this is unnecessary. The original commands for external audio tracks
have been added to mpv by someone who agreed with the relicensing.
They were added to the "to deleted" list and never relicensed, because I
thought I'd delete them early. But it's possible that they'll stay in
mpv for a longer time, so relicense them. Still leaving them as
deprecated and scheduled for removal, so they can still be dropped once
there is a better way to deal with them, if they get annoying, or if a
better mechanism is found that makes them unnecessary.
All contributors agreed. There are some minor changes by people who did
not agree, but these are all not relevant or have been removed.
Almost all of them had their guts removed and replaced by libavfilter
long ago, but remove them anyway. They're pointless and have been
scheduled for deprecation.
Still leave vf_format (because we need it in some form) and vf_sub (not
sure).
This will break some builtin functionality: lavfi yadif defaults are
different, auto rotation and stereo3d downconversion are broken. These
might be fixed later.
We want to drop vf_scale, but we still need a way to auto convert
between imgfmts. In particular, vf.c will auto insert the "scale" filter
if the VO doesn't support a pixfmt.
To avoid chaos, create a new vf_convert.c filter, based on vf_scale.c,
but without the unrelicensed code parts. In particular, this filter does
not do scaling and has no options. It merely converts from one imgfmt to
another, if needed.
Apparently a relatively widespread convention, and almost as strict as
the old "exact" semantics. (So it's not going to auto load radically
unrelated files.)
There has been no new developments or agreements, but I was uncertain
about the copyright status of them. Thus this part of code was marked as
being potentially GPL, and was not built in LGPL mode. Now I've taken a
close look again, and decided that these can be relicensed using the
existing relicensing agreements.
OSD level 3 was introduced in commit 8d190244, with the author being
unreachable. As I decided in commit 6ddd95fd, OSD level 3 itself can
be kept, but the "osd" command had to go, and the "rendering" of OSD
level 3 (the HAVE_GPL code in osd.c) was uncertain. But the code for
this was rewritten: instead of duplicating the time/percent formatting
code, it was changed to use common code, and some weird extra logic was
removed. The code inside of the "if" is exactly the same as the code
that formats the OSD status line (covered by LGPL relicensing).
The current commands for adding/removing sub/audio tracks more or less
originated from commit 2f376d1b39, with the author being unreachable.
But the original code was very different, mostly due to MPlayer's
incredibly messy handling of subtitles in general. Nothing of this
remains in the current code. Even the command declarations were
rewritten. The commands (as seen from the user side) are rather similar
in naming and semantics, but we don't consider this copyrightable. So it
doesn't look like anything copyrightable is left.
The add/cycle commands were more or less based on step_property,
introduced in commit 7a71da01d6, with the patch author disagreeing with
the LGPL relicensing. But all code original to the patch has been
replaced in later mpv changes, and the original code was mostly copied
from MP_CMD_SET_PROPERTY anyway. The underlying property interface was
completely changed, the error handling was redone, and all of this is
very similar to the changes that were done on SET_PROPERTY. The command
declarations are completely different in the first place, because the
semantic change from step to add/cycle. The commit also seems to have
been co-authored by reimar to some degree. He also had the idea to
change the original patch from making the command modify a specific
property to making it generic.
(The error message line, especially with its %g formatting, might
contain some level of originality, so change that just to be sure.
This commit Copies and adapts the error message for SET_PROPERTY.)
Although I'm a bit on the fence with all the above things, it really
doesn't look like there's anything substantial that would cause issues.
I thus claim that there is no problem with changing the license to LGPL
for the above things. It's probably still slightly below the standard
that was usually applied in the code relicensing in mpv, but probably
still far above to the usual in open source relicensing (and above
commercial standards as well, if you look what certain tech giants do).
Always display the duration as "unknown" if the duration is known. Also
fix that at least demux_lavf reported unknown duration as 0 (fix by
setting the default to unknown in demux.c).
Remove the dumb _u formatter function, and use a different approach to
avoiding displaying "unknown" as playback time on playback start (set
last_seek_pts for that).
Looks like this is covered by LGPL relicensing agreements now.
Notes about contributors who could not be reached or who didn't agree:
Commit 7fccb6486e has tons of mp_msg changes look like they are not
copyrightable (even if they were, all mp_msg calls were rewritten in
mpv times again). The additional play() change looks suspicious, but
the function was rewritten several times anyway (first time after that
commit in 4f40ec312).
Commit 89ed1748ae was rewritten in commit 325311af3 and then again
several times after that. Basically all this code is unnecessary in
modern mpv and has been removed.
No code survived from the following commits: 4d31c3c53, 61ecf838f2,
d38968bd, 4deb67c3f. At least two cosmetic typo fixes are not
considered as well.
Commit 22bb046ad is reverted (this wasn't a valid warning anyway, just
a C++-ism icc applied to C). Using the constants is nicer, but at least
I don't have to decide whether that change was copyrightable.
The D3D11_CREATE_DEVICE_BGRA_SUPPORT flag doesn't enable support for
BGRA textures. BGRA textures will be supported whether or not the flag
is passed. The flag just fails device creation if they are not supported
as an API convenience for programs that need BGRA textures, such as
programs that use D2D or D3D9 interop. We can handle devices without
BGRA support fine, so don't bother with the flag.
This sliences some warnings about unused values and statements with no
effect, but it also fixes a logic error with freelocale(), since
previously it would not work as expected when used in the body of an if
statement without braces.
Uses real functions, because with macros, I don't think there is a way
to silence the "statement with no effect" warnings in the case where the
return value of uselocale() is ignored.
As for replacing the these functions with working implementations, I
don't think this is possible for mpv's use-case, since MSVCRT does not
support UTF-8 locales, or any locale with multibyte characters that are
three or more bytes long. See:
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale
For consistency with already implemented shcore.dll
function loading in w32->api:
Moved loading of imm32.dll to w32_api_load, and declare
pImmDisableIME function pointer in the w32->api struct.
Removed unloading of imm32.dll.
This gives the filename or URL to the libavformat probing logic, which
might use the file extension as a "help" to decide which format the file
is. This helps with mp3 files that have large id3v2 tags and prevents
the idiotic ffmpeg probing logic to think that a mp3 file is amr.
(What we really want is knowing whether we _really_ need to feed more
data to libavformat to detect the format. And without having to pre-read
excessive amounts of data for relatively normal streams.)
Fix that libarchive fails to return filenames for UTF-8/UTF-16 entries.
The reason is that it uses locales and all that garbage, and mpv does
not set a locale.
Both C locales and wchar_t are shitfucked retarded legacy braindeath. If
the C/POSIX standard committee had actually competent members, these
would have been deprecated or removed long ago. (I mean, they managed to
remove gets().) To justify this emotional outbreak potentially insulting
to unknown persons, I will write a lot of text. Those not comfortable
with toxic language should pretend this is a religious text.
C locales are supposed to be a way to support certain languages and
cultures easier. One example are character codepages. Back when UTF-8
was not invented yet, there were only 255 possible characters, which is
not enough for anything but English and some european languages. So they
decided to make the meaning of a character dependent on the current
codepage. The locale (LC_CTYPE specifically) determines what character
encoding is currently used.
Of course nowadays, this is legacy nonsense. Everything uses UTF-8 for
"char", and what doesn't is broken and terrible anyway. But the old ways
stayed with us, and the stupidity of it as well.
C locales were utterly moronic even when they were invented. The locale
(via setlocale()) is global state, and global state is not a reasonable
way to do anything. It will break libraries, or well modularized code.
(The latter would be forced to strictly guard all entrypoints set
set/restore locales, assuming a single threaded world.)
On top of that, setting a locale randomly changes the semantics of a
bunch of standard functions. If a function respects locale, you suddenly
can't rely on it to behave the same on all systems. Some behavior can
come as a surprise, and of course it will be dependent on the region of
the user (it doesn't help that most software is US-centric, and the US
locale is almost like the C locale, i.e. almost what you expect).
Idiotically, locales were not just used to define the current character
encoding, but the concept was used for a whole lot of things, like e. g.
whether numbers should use "," or "." as decimal separaror. The latter
issue is actually much worse, because it breaks basic string conversion
or parsing of numbers for the purpose of interacting with file formats
and such.
Much can be said about how retarded locales are, even beyond what I just
wrote, or will wrote below. They are so hilariously misdesigned and
insufficient, I can't even fathom how this shit was _standardized_. (In
any case, that meant everyone was forced to implement it.) Many C
functions can't even do it correctly. For example, the character set
encoding can be a multibyte encoding (not just UTF-8, but awful garbage
like Shift JIS (sometimes called SHIT JIZZ), yet functions like
toupper() can return only 1 byte. Or just take the fact that the locale
API tries to define standard paper sizes (LC_PAPER) or telephone number
formatting (LC_TELEPHONE). Who the fuck uses this, or would ever use
this?
But the badness doesn't stop here. At some point, they invented threads.
And they put absolutely no thought into how threads should interact with
locales. So they kept locales as global state. Because obviously, you
want to be able to change the semantics of basic string processing
functions _while_ they're running, right? (Any thread can call
setlocale() at any time, and it's supposed to change the locale of all
other threads.)
At this point, how the fuck are you supposed to do anything correctly?
You can't even temporarily switch the locale with setlocale(), because
it would asynchronously fuckup the other threads. All you can do is to
enforce a convention not to set anything but the C local (this is what
mpv does), or to duplicate standard functions using code that doesn't
query locale (this is what e.g. libass does, a close dependency of mpv).
Imagine they had done this for certain other things. Like errno, with
all the brokenness of the locale API. This simply wouldn't have worked,
shit would just have been too broken. So they didn't. But locales give a
delicious sweet spot of brokenness, where things are broken enough to
cause neverending pain, but not broken enough that enough effort would
have spent to fix it completely.
On that note, standard C11 actually can't stringify an error value. It
does define strerror(), but it's not thread safe, even though C11
supports threads. The idiots could just have defined it to be thread
safe. Even if your libc is horrible enough that it can't return string
literals, it could just just some thread local buffer. Because C11 does
define thread local variables. But hey, why care about details, if you
can just create a shitty standard?
(POSIX defines strerror_r(), which "solves" this problem, while still
not making strerror() thread safe.)
Anyway, back to threads. The interaction of locales and threads makes no
sense. Why would you make locales process global? Who even wanted it to
work this way? Who decided that it should keep working this way, despite
being so broken (and certainly causing implementation difficulties in
libc)? Was it just a fucked up psychopath?
Several decades later, the moronic standard committees noticed that this
was (still is) kind of a bad situation. Instead of fixing the situation,
they added more garbage on top of it. (Probably for the sake of
"compatibility"). Now there is a set of new functions, which allow you
to override the locale for the current thread. This means you can
temporarily override and restore the local on all entrypoints of your
code (like you could with setlocale(), before threads were invented).
And of course not all operating systems or libcs implement this. For
example, I'm pretty sure Microsoft doesn't. (Microsoft got to fuck it up
as usual, and only provides _configthreadlocale(). This is shitfucked on
its own, because it's GLOBAL STATE to configure that GLOBAL STATE should
not be GLOBAL STATE, i.e. completely broken garbage, because it requires
agreement over all modules/libraries what behavior should be used. I
mean, sure, makign setlocale() affect only the current thread would have
been the reasonable behavior. Making this behavior configurable isn't,
because you can't rely on what behavior is active.)
POSIX showed some minor decency by at least introducing some variations
of standard functions, which have a locale argument (e.g. toupper_l()).
You just pass the locale which you want to be used, and don't have to do
the set locale/call function/restore locale nonense. But OF COURSE they
fucked this up too. In no less than 2 ways:
- There is no statically available handle for the C locale, so you have
to initialize and store it somewhere, which makes it harder to make
utility functions safe, that call locale-affected standard functions
and expect C semantics. The easy solution, using pthread_once() and a
global variable with the created locale, will not be easily accepted
by pedantic assholes, because they'll worry about allocation failure,
or leaking the locale when using this in library code (and then
unloading the library). Or you could have complicated library
init/uninit functions, which bring a big load of their own mess.
Same for automagic DLL constructors/destructors.
- Not all functions have a variant that takes a locale argument, and
they missed even some important ones, like snprintf() or strtod() WHAT
THE FUCK WHAT THE FUCK WHAT THE FUCK WHAT THE FUCK WHAT THE FUCK WHAT
THE FUCK WHAT THE FUCK WHAT THE FUCK WHAT THE FUCK
I would like to know why it took so long to standardize a half-assed
solution, that, apart from being conceptually half-assed, is even
incomplete and insufficient. The obvious way to fix this would have
been:
- deprecate the entire locale API and their use, and make it a NOP
- make UTF-8 the standard character type
- make the C locale behavior the default
- add new APIs that explicitly take locale objects
- provide an emulation layer, that can be used to transparently build
legacy code without breaking them
But this wouldn't have been "compatible", and the apparently incompetent
standard committees would have never accepted this. As if anyone
actually used this legacy garbage, except other legacy garbage. Oh yeah,
and let's care a lot about legacy compatibility, and let's not care at
all about modern code that either has to suffer from this, or subtly
breaks when the wrong locales are active.
Last but not least, the UTF-8 locale name is apparently not even
standardized. At the moment I'm trying to use "C.UTF-8", which is
apparently glibc _and_ Debian specific. Got to use every opportunity to
make correct usage of UTF-8 harder. What luck that this commit is only
for some optional relatively obscure mpv feature.
Why is the C locale not UTF-8? Why did POSIX not standardize an UTF-8
locale? Well, according to something I heard a few years ago, they're
considering disallowing UTF-8 as locale, because UTF-8 would violate
certain ivnariants expected by C or POSIX. (But I'm not sure if I
remember this correctly - probably better not to rage about it.)
Now, on to libarchive.
libarchive intentionally uses the locale API and all the broken crap
around it to "convert" UTF-8 or UTF-16 (as contained in reasonably sane
archive formats) to "char*". This is a good start!
Since glibc does not think that the C locale uses UTF-8, this fails for
mpv. So trying to use archive_entry_pathname() to get the archive entry
name fails if the name contains non-ASCII characters.
Maybe use archive_entry_pathname_utf8()? Surely that should return
UTF-8, since its name seems to indicate that it returns UTF-8. But of
fucking course it doesn't! libarchive's horribly convoluted code (that
is full of locale API usage and other legacy shit, as well as ifdefs and
OS specific code, including Windows and fucking Cygwin) somehow fucks up
and fails if the locale is not set to UTF-8. I made a PR fixing this in
libarchive almost 2 years ago, but it was ignored.
So, would archive_entry_pathname_w() as fallback work? No, why would it?
Of course this _also_ involves shitfucked code that calls shitfucked
standard functions (or OS specific ifdeffed shitfuck). The truth is that
at least glibc changes the meaning of wchar_t depending on the locale.
Unlike most people think, wchar_t is not standardized to be an UTF
variant (or even unicode) - it's an encoding that uses basic units that
can be larger than 8 bit. It's an implementation defined thing. Windows
defines it to 2 bytes and UTF-16, and glibc defines it to 4 bytes and
UTF-32, but only if an UTF-8 locale is set (apparently).
Yes. Every libarchive function dealing with strings has 3 variants:
plain, _utf8, and _w. And none of these work if the locale is not set.
I cannot fathom why they even have a wchar_t variant, because it's
redundant and fucking useless for any modern code.
Writing a UTF-16 to UTF-8 conversion routine is maybe 3 pages of code,
or a few lines if you use iconv. But libarchive uses all this glorious
bullshit, and ends up with 3 not working API functions, and with over
4000 lines of its own string abstraction code with gratuitous amounts of
ifdefs and OS dependent code that breaks in a fairly common use case.
So what we do is:
- Use the idiotic POSIX 2008 API (uselocale() etc.) (Too bad for users
who try to build this on a system that doesn't have these - hopefully
none are left in 2017. But if there are, torturing them with obscure
build errors is probably justified. Might be bad for Windows though,
which is a very popular platform except on phones.)
- Use the "C.UTF-8" locale, which is probably not 100% standards
compliant, but works on my system, so it's fine.
- Guard every libarchive call with uselocale() + restoring the locale.
- Be lazy and skip some libarchive calls. Look forward to the unlikely
and astonishingly stupid bugs this could produce.
We could also just set a C UTF-8 local in main (since that would have no
known negative effects on the rest of the code), but this won't work for
libmpv.
We assume that uselocale() never fails. In an unexplainable stroke of
luck, POSIX made the semantics of uselocale() nice enough that user code
can fail failures without introducing crash or security bugs, even if
there should be an implementation fucked up enough where it's actually
possible that uselocale() fails even with valid input.
With all this shitty ugliness added, it finally works, without fucking
up other parts of the player. This is still less bad than that time when
libquivi fucked up OpenGL rendering, because calling a libquvi function
would load some proxy abstraction library, which in turn loaded a KDE
plugin (even if KDE was not used), which in turn called setlocale()
because Qt does this, and consequently made the mpv GLSL shader
generation code emit "," instead of "." for numbers, and of course only
for users who had that KDE plugin installed, and lived in a part of the
world where "." is not used as decimal separator.
All in all, I believe this proves that software developers as a whole
and as a culture produce worse results than drug addicted butt fucked
monkeys randomly hacking on typewriters while inhaling the fumes of a
radioactive dumpster fire fueled by chinese platsic toys for children
and Elton John/Justin Bieber crossover CDs for all eternity.
If the backbuffer is much larger than the forward buffer, and if you
join a small range with a large range (larger than the forward buffer),
then the seek issues to the end of the range after joining will overflow
the queue.
Normally, read_more will be false when the forward buffer is full, but
the resume seek after joining will set need_refresh to true, which
forces more reading and thus triggers the overfloe warning.
Attempt to fix this by not setting read_more to true on refresh seeks.
Set prefetch_more instead. read_more will still be set if an A/V stream
has no data.
This doesn't help with the following problems related to using refresh
seeks for track switching:
- If the forward buffer is full, then enabling another track will
obviously immediately overflow the queue, and immediately lead to
marking the new track as having no more data (i.e. EOF). We could cut
down the forward buffer or so, but there's no simple way to implement
it. Another possibility would be dropping all buffers and trying to
resume again, but this would likely be complex as well.
- Subtitle tracks will not even show a warning (because they are sparse,
and we have no way of telling whether a packet is missing, or there's
just no packet near the current position). Before this commit,
enabling an empty subtitle track would probably have overflown the
queue, because ds->refreshing was never set to true. Possibly this
could be solved by determining a demuxer read position, which would
reflect until which PTS all subtitle packets should have been demuxed.
The forward buffer limit was intended as a last safeguard to avoid
excessive memory usage against badly interleaved files or decoders going
crazy (up to reading the whole into memory and OOM'ing the user's
system). It's not good at all to limit prefetch. Possibly solutions
include having another smaller limit for prefetch, or maybe having only
a total buffer limit, and discarding back buffer if more data has to be
read. The current solution is making the forward buffer larger than the
forward duration (--cache-secs) would require, but of course this
depends on the stream's bitrate.
The option for enabling it has now an "auto" choice, which is the
default, and which will enable it if the media is thought to be via
network or if the stream cache is enabled (same logic as --cache-secs).
Also bump the --cache-secs default from 10 to 120.
Some back buffer is required to make the immediate forward range
seekable. This is because the back buffer limit is strictly enforced.
Just set a rather high back buffer by default. It's not use if
--demuxer-seekable-cache is disabled, so this is without risk.
Limit the number of cached ranges to MAX_SEEK_RANGES, which is the same
number of maximally exported seek ranges. It makes no sense to keep
them, as the user won't see them anyway. Remove the smallest ones to
enforce the limit if the number grows too high.
Helps a little bit, I guess. But in general, t(h)rashing the cache kills
us anyway.
This has a fixed number of index entries. Entries are added/removed as
packets go through the packet queue. Only keyframes after index_distance
seconds are added. If there are too many keyframe packets, the existing
index is reduced by half, and index_distance is doubled. This should
provide somewhat even spacing between the entries.
The packet queue is sorted, so we can stop the search if we have found a
packet, and the next packet in the queue has a higher PTS than the seek
PTS (for the sake of SEEK_FORWARD, we still consider the first packet
with a higher PTS).
Also, as a mostly cosmetic change, but which might be "faster", check
target for NULL, instead of target_diff for a magic float value.
Subtitle streams are sparse, and no overlap is required to correctly
join two cached ranges. This was not correctly handled iff the two
ranges had different subtitle packets close to the join point.
demux_add_packet() must completely ignore any packets that are added
while a queued seek is not initiated yet.
The main issue is that after setting in->seeking==true, the central lock
is released, and it can take "a while" until it's reacquired on the
demux thread and the seek is actually initiated. During that time,
packets could be read and added, that have nothing to do with the new
state.
Seems like the last refactor to this code broke playing flipped images,
at least with --opengl-pbo --gpu-api=opengl.
Flipping is rather a shitmess. The main problem is that OpenGL does not
support flipped uploading. The original vo_gl implementation considered
it important to handle the flipped case efficiently, so instead of
uploading the image line by line backwards, it uploaded it flipped, and
then flipped it in the renderer (basically the upload path ignored the
flipping). The ra code and backends probably have an insane and
inconsistent mix of semantics, so fix this by never passing it flipped
images in the first place.
In the future, the backends should probably support flipped images
directly.
Fixes#5097.
If subtitles are part of the stream, determining the seekable range
becomes harder. Subtitles are sparse, and can have packets in irregular
intervals, or even completely lack packets. The usual logic of computing
the seek range by the min/max packet timestamps fails.
Solve this by making the only assumption we can make: subtitle packets
are implicitly demuxed along with other packets. We also assume perfect
interleaving for this, but you really can't do anything with sparse
packets that makes sense without this assumption.
One special case is if we prune sparse packets within the current
seekable range. Obviously this should limit the seekable range to after
the pruned packet.
Instead of weirdly deciding this on every packet read and having the
code far away from where it's actually needed, just run it where it's
actually needed.
A typical idiom for calling functions that remove something from the
array being iterated, but it's not needed here. I have no idea why this
was ever done.
Setting ds->refreshing for unselected streams could lead to a
nonsensical queue overflow warning, because read_packet() took it as a
reason to continue reading.
Also add some more information to the queue overflow warning (even if
that one doesn't have anything to do with this bug - it was for
unselected streams only).
This fixes an endless loop with threading disabled, such as for example
when playing a file with an external subtitle file, and seeking to the
beginning. Something will set in->seeking, but the seek is never
executed, which made demux_read_packet() loop endlessly. (External
subtitles will use non-threaded mode for whatever reasons.)
Fix this by by making the unthreaded code to execute the worker thread
body, which reduces the difference in logic.
Until now, the demuxer cache was limited to a single range. Extend this
to multiple range. Should be useful for slow network streams.
This commit changes a lot in the internal demuxer cache logic, so
there's a lot of room for bugs and regressions. The logic without
demuxer cache is mostly untouched, but also involved with the code
changes. Or in other words, this commit probably fucks up shit.
There are two things which makes multiple cached ranges rather hard:
1. the need to resume the demuxer at the end of a cached range when
seeking to it
2. joining two adjacent ranges when the lowe range "grows" into it (and
resuming the demuxer at the end of the new joined range)
"Resuming" the demuxer means that we perform a low level seek to the end
of a cached range, and properly append new packets to it, without adding
packets multiple times or creating holes due to missing packets.
Since audio and video never line up exactly, there is no clean "cut"
possible, at which you could resume the demuxer cleanly (for 1.) or
which you could use to detect that two ranges are perfectly adjacent
(for 2.). The way how the demuxer interleaves multiple streams is also
unpredictable. Typically you will have to expect that it randomly allows
one of the streams to be ahead by a bit, and so on.
To deal with this, we have heuristics in place to detect when one packet
equals or is "behind" a packet that was demuxed earlier. We reuse the
refresh seek logic (used to "reread" packets into the demuxer cache when
enabling a track), which checks for certain packet invariants.
Currently, it observes whether either the raw packet position, or the
packet DTS is strictly monotonically increasing. If none of them are
true, we discard old ranges when creating a new one.
This heavily depends on the file format and the demuxer behavior. For
example, not all file formats have DTS, and the packet position can be
unset due to libavformat not always setting it (e.g. when parsers are
used).
At the same time, we must deal with all the complicated state used to
track prefetching and seek ranges. In some complicated corner cases, we
just give up and discard other seek ranges, even if the previously
mentioned packet invariants are fulfilled.
To handle joining, we're being particularly dumb, and require a small
overlap to be confident that two ranges join perfectly. (This could be
done incrementally with as little overlap as 1 packet, but corner cases
would eat us: each stream needs to be joined separately, and the cache
pruning logic could remove overlapping packets for other streams again.)
Another restriction is that switching the cached range will always
trigger an asynchronous low level seek to resume demuxing at the new
range. Some users might find this annoying.
Dealing with interleaved subtitles is not fully handled yet. It will
clamp the seekable range to where subtitle packets are.
Build ffmpeg-mpv, shaderc and crossc from source, since they are not
packaged in MSYS2. Also, add some more explicit --enable flags to the
mpv build to make sure things like D3D11, D3D11VA hwaccels and Vulkan
are auto-detected.
Like the manual says, this is technically undefined behaviour. See:
https://msdn.microsoft.com/en-us/library/windows/desktop/ff476085.aspx
In particular, MSDN says texture arrays created with the BIND_DECODER
flag cannot be used with CreateShaderResourceView, which means they
can't be sampled through SRVs like normal Direct3D textures. However,
some programs (Google Chrome included) do this anyway for performance
and power-usage reasons, and it appears to work with most drivers.
Older AMD drivers had a "bug" with zero-copy decoding, but this appears
to have been fixed. See #3255, #3464 and http://crbug.com/623029.
The shader cache in ra_d3d11 caches the result of shaderc, crossc and
the D3DCompiler DLL, so it should be invalidated when any of those
components are updated. This should make the cache more reliable, which
makes it safer to enable gpu-shader-cache-dir. Shader compilation is
slow with D3D11, so gpu-shader-cache-dir is highly necessary
Some shaders take a _long_ time to compile with the Direct3D compiler.
The ANGLE backend had this problem too, to a certain extent. Logging
should help identify which shaders cause long stalls and could also help
with benchmarking ways of reducing compile times.
ra_d3d11 uses the SPIR-V compiler to translate GLSL to SPIR-V, which is
then translated to HLSL. This means it always exposes the same GLSL
version that the SPIR-V compiler supports (4.50 for shaderc/glslang.)
Despite claiming to support GLSL 4.50, some features that are tied to
the GLSL version in OpenGL are not supported by ra_d3d11 when targeting
legacy Direct3D feature levels.
This includes two features that mpv relies on:
- Reading from gl_FragCoord in the fragment shader (requires FL 10_0)
- textureGather from any texture component (requires FL 11_0)
These features have been exposed as new RA caps.
This is a new RA/vo_gpu backend that uses Direct3D 11. The GLSL
generated by vo_gpu is cross-compiled to HLSL with SPIRV-Cross.
What works:
- All of mpv's internal shaders should work, including compute shaders.
- Some external shaders have been tested and work, including RAVU and
adaptive-sharpen.
- Non-dumb mode works, even on very old hardware. Most features work at
feature level 9_3 and all features work at feature level 10_0. Some
features also work at feature level 9_1 and 9_2, but without high-bit-
depth FBOs, it's not very useful. (Hardware this old is probably not
fast enough for advanced features anyway.)
Note: This is more compatible than ANGLE, which requires 9_3 to work
at all (GLES 2.0,) and 10_1 for non-dumb-mode (GLES 3.0.)
- Hardware decoding with D3D11VA, including decoding of 10-bit formats
without truncation to 8-bit.
What doesn't work / can be improved:
- PBO upload and direct rendering does not work yet. Direct rendering
requires persistent-mapped PBOs because the decoder needs to be able
to read data from images that have already been decoded and uploaded.
Unfortunately, it seems like persistent-mapped PBOs are fundamentally
incompatible with D3D11, which requires all resources to use driver-
managed memory and requires memory to be unmapped (and hence pointers
to be invalidated) when a resource is used in a draw or copy
operation.
However it might be possible to use D3D11's limited multithreading
capabilities to emulate some features of PBOs, like asynchronous
texture uploading.
- The blit() and clear() operations don't have equivalents in the D3D11
API that handle all cases, so in most cases, they have to be emulated
with a shader. This is currently done inside ra_d3d11, but ideally it
would be done in generic code, so it can take advantage of mpv's
shader generation utilities.
- SPIRV-Cross is used through a NIH C-compatible wrapper library, since
it does not expose a C interface itself.
The library is available here: https://github.com/rossy/crossc
- The D3D11 context could be made to support more modern DXGI features
in future. For example, it should be possible to add support for
high-bit-depth and HDR output with DXGI 1.5/1.6.
Backported from @haasn's change to libplacebo, except in the current RA,
there's nothing to indicate an ra_format can be bound as a storage
image, so there's no way to force all of these formats to have a
glsl_format. Instead, the layout qualifier will be removed if
glsl_format is NULL.
This is needed for the upcoming ra_d3d11 backend. In Direct3D 11, while
loading float values from unorm images often works as expected, it's
technically undefined behaviour, and in Windows 10, it will cause the
debug layer to spam the log with error messages. Also, apparently in
GLSL, the format name must match the image's format exactly (but in
Direct3D, it just has to have the same component type.)
Backported from @haasn's change to libplacebo. More flexible than the
previous "shared || non-shared" distinction. The extra flexibility is
needed for Direct3D 11, but it also doesn't hurt code-wise.
For some reason vo_lavc's draw_image can buffer the frame and encode it
only later. Also, there is logic for rendering the OSD (i.e. subtitles)
only when needed.
In theory this can lead to subtitles being pruned before it tries to
render them (as the subtitle logic doesn't know that the VO still needs
them later), although this probably never happens in reality.
The worse issue, that actually happened, is that if the last frame gets
buffered, it attempts to render subtitles in the uninit callback. At
this point, the subtitle decoder is already torn down and all subtitles
removed, thus it will draw nothing. This didn't always happen. I'm not
sure why - potentially in the working cases, the frame wasn't buffered.
Since this logic doesn't have much worth, except a minor performance
advantage if frames with subtitles are dropped, just remove it.
Hopefully fixes#4689.
libavcodec can't deal with them, because its API doesn't distinguish
between 0 sized packets and sending EOF. As such, keeping them doesn't
do any good, ever. This actually fixes some obscure mkv sample (see
previous commit).
Fixes some obscure sample that uses fixed size laces with 0-sized lace
size. Some broken shit. (Maybe the decoder wouldn't care about these
packets, but the demuxer attempted to resync after these packet reading
errors, even though they were perfectly recoverable. But I don't care
enough about this.)
Sample link: https://samples.ffmpeg.org/Matroska/switzler084d_dl.mkv
This directly reads individual mkv sub-packets (block laces) into a
dedicated AVBufferRefs, which can be directly used for creating packets
without a additional copy of the packet data. This also means we switch
parsing of block header fields and lacing metadata to read directly from
the stream, instead of a memory buffer.
This could have been much easier if libavcodec didn't require padding
the packet data with zero bytes. We could just have each packet
reference a slice of the block data. But as it is, the only way to get
padding without a copy is to read the laces into individually allocated
(and padded) memory block, which required a larger rewrite.
This probably makes recovering from broken mkv files slightly worse if
the transport is unseekable. We just read, and then check if we've
overread. But I think that shouldn't be a real concern.
No actual measureable performance change. Potential for some
regressions, as this is quite intrusive, and touches weird obscure shit
like mkv lacing. Still keeping it because I like how it removes some
redundant EBML parsing functions.
This adds a bunch of stuff (mostly unused or redundant) as preparation
for supporting multiple seek ranges. Actual support is probably still
far away.
One change that messes deeper with the actual code is that we account
for total buffered bytes instead of just the backwards bytes now. This
way, prune_old_packets() doesn't have to iterate over all seek ranges to
determine whether something needs pruning.
The main purpose of this commit is avoiding any hidden O(n^2) algorithms
in the code for pruning the demuxer cache, and for determining the
seekable boundaries of the cache. The old code could loop over the whole
packet queue on every packet pruned in certain corner cases.
There are two ways how to reach the goal:
1) commit a cardinal sin
2) do everything incrementally
The cardinal sin is adding an extra field to demux_packet, which caches
the determined seekable range for a keyframe range. demux_packet is a
rather general data structure and thus shouldn't have any fields that
are not inherent to its use, and are only needed as an implementation
detail of code using it. But what are you gonna do, sue me?
In the future, demux.c might have its own packet struct though. Then the
other existing cardinal sin (the "next" field, from MPlayer times) could
be removed as well.
This commit also changes slightly how the seek end is determined. There
is a note on the manpage in case anyone finds the new behavior
confusing. It's somewhat cleaner and might be needed for supporting
multiple ranges (although that's unclear).
The demuxer cache seeking mechanism looks at keyframe ranges to
determine the earlierst PTS of a packet. Instead of looping over all
packets twice (once to find the next keyframe, a second time to find the
seek PTS), do it in one go.
For that basically turn recompute_keyframe_target_pts() into an
iteration functionn. Functionality should be unchanged with this commit.
The base_ts field is used to guess the decoder position, and when set to
NOPTS, it just read ahead arbitrarily. Also demux_add_packet() sets
base_ts to the new timestamp when appending a packet, which would also
make it readahead by a too large amount.
Fix this by setting base_ts after a seek. This assumes that normally, a
cached seek target will always have the timestamp set. This is actually
not quite clear (as it calls recompute_keyframe_target_pts(), which
looks at multiple packets), but maybe it works well enough.
Don't do any of the extra work related to pruning the backbuffer if
demuxer cache seeking is disabled.
As a small extra, always prune packets with no timestamps immediately,
or queue heads that are not keyframes. (Both of them would be pruned
from the backbuffer by the normal logic anyway.)
If fulfilling --demuxer-readahead-secs requires more memory than allowed
by --demuxer-max-bytes, the queue obviously overflows. But the warning
is normally only for the case when trying to find the next video or
audio packet fails, and decoding can't continue.
Use a separate variable for determining whether to prefetch, and if the
queue has overflown, skip the message. In fact, skip the EOF setting and
waking up the decoder thread as well, because the EOF flag should not be
(have been) set in this situation, and waking up the reader thread helps
only if the EOF state changed.
Repeating frames (for display-sync) is not supposed to render the entire
frame again. When using hardware decoding, it unfortunately did: the
renderer uses the frame ID to check whether the frame data changed, and
unmapping the hwdec frame clears it.
Essentially reverts commit 761eeacf54. Back then I probably
thought it would be a good idea to release the hwdec image quickly in
order to return it to the decoder, but they're referenced anyway.
This should increase the performance and reduce GPU work.
In a shit show of subtle corner case interactions, making the demuxer
cache buffer the entire file can display a small buffered time if
subtitles are enabled. The reason is that some subtitle decoders may
read in advance infinitely, i.e. they read the entire subtitle stream.
Then, since the other streams (audio/video) have logically reached EOF,
and the subtitle stream is set to ds->active==true. This will have to be
fixed properly later to account buffering for subtitle-only files
(another corner case) correctly, but for now this is less annoying.
We don't hope to auto-detect them at load time, as that would be too
much of a pain - even FFmpeg requires fetching and parsing of video
packets, and exposes the information only via deprecated API.
But there still needs to be a way to select them by default. This is
also needed to get the first CC packet at all (without seeking back).
This commit also attempts to clean up locking a bit, which is a PITA,
but it's better be careful & clean.
Normally such code is didsabled by have_mglsl==false in
check_gl_features(), but apparently not this one.
Just fix it. Seems also more readable.
Fixes#5069.
Apparently this is required, but it doesn't check for it. To be fair,
this was tested by creating a compatibility context and pretending it's
GL 2.1. GL_ARB_shader_storage_buffer_object actually requires GL 4.0 or
up, but GL_ARB_uniform_buffer_object requires only GL 2.0.
According to
https://github.com/libarchive/libarchive/pull/773#issuecomment-334892291
we're not allowed to "continue reading" (post above) or performing "more
operations" (comments in archive.h header), whatever that means. Assume
closing and freeing the archive is still ok.
Since the codec already includes logic for closing and reopening the
archive for seeking in unseekable archives, this probably isn't too bad.
Untested due to lack of crashing sample (I lost my original test case,
and as recently user-provided one didn't crash).
Apparently some people want this. Actually making it compile is still
their problem, though, and I expect that build with FFmpeg upstream will
occasionally be broken (as it is right now). This is because mpv also
relies on API provided by Libav, and if FFmpeg hasn't merged that yet,
it's not our problem - we provide a version of FFmpeg upstream with
those changes merged, and it's called ffmpeg-mpv.
Also adjust the README which still talked about FFmpeg releases.
vo_gpu.c will call gl_video_icc_auto_enabled() to check whether it
should retrieve the ICC profile. But the value returned by this function
will be outdated, because gl_video_update_options() is not called yet.
Change the order of function calls so that this is done after updating
the options.
(This is fairly chaotic, but I guess this code will be refactored a
dozen of times anyway in the future.)
All this code used to be required by the old variants of the libavcodec
hw decoding APIs. Almost all of that is gone, although the mediacodec
API unfortunately still pulls in some old stuff (but not all of it).
(mediacodec build/functionality is untested, but should work.)
All of this was dead code and completely unused.
get_buffer2_hwdec() is the biggest chunk. One unfortunate thing about it
is that, while it was active, it could perform a software fallback much
faster, because it didn't have to wait until a full frame is decoded (it
actually decoded a full frame, but the current code has to decode many
more frames due to the codec delay, because the current code waits until
the API returns a decoded frame.) We should probably restore the latter,
although since it's an optional optimization, and the current behavior
doesn't change with the removal of this code, don't actually do anything
about it.
This is where it should be. It only wasn't because of an old libavcodec
bug, that returned the side data only on every IDR. This required some
sort of caching, which is now dropped. (mp_image wouldn't have been able
to do this kind of caching, because this code is stateless.) We don't
support these old libavcodec versions anymore, which is why this is not
needed anymore.
Also move initialization of rotation/stereo stuff to dec_video.c.
This simply didn't work. Unlike cuda-copy, this is a true hwaccel, and
obviously we need to provide it a device.
Implement this in a relatively generic way, which can probably reused
directly by videotoolbox (not doing this yet because it would require
testing on OSX).
Like with cuda-copy, --cuda-decode-device is ignored. We might be able
to provide a more general way to select devices at some later point.
This is just a dumb consequence of HWDEC_ types somehow being part of
both decoder and VO. Obviously, the VO should only care about supporting
specific hardware surface types or providing specific device types, but
until they are separated, stupid unintuitive mismatches will occur.
Somewhat useful for debugging. Unfortunately libass (or something else)
strips leading whitespace, making it look slightly more ugly than
necessary. Still an improvement.
Even though only 1 seek range is supported at the time.
Other than preparation for possibly future features, the main gain is
actually that we finally separate the reporting for the buffering, and
the seek ranges. These can be subtly different, so it's good to have a
clear separation.
This commit also fixes that the ts_reader wasn't rebased to the start
time, which could make the player show "???" for buffered cache amount
in some .ts files and others (especially at the end, when ts_reader
could become higher than ts_max). It also fixes writing the cache-end
field in the demuxer-cache-state property: it checked ts_start against
NOPTS, which makes no sense.
ts_start was never used (except for the bug mentioned above), so get rid
of it completely. This also makes it convenient to move the segment
check for last_ts to the demux_add_packet() function.
The current invocation of bstr_cut is as good as no cutting at all.
Almost the entire header is reread in every iteration of the loop.
I don't know how many styles libavcodec tends to generate, but if
(now or in the future) it generates many, then this loop is slow
for no good reason. If anything, the code would be more clear and
have the same performance if it didn't call bstr_cut at all.
The intention here (and the sensible thing regardless) seems to be
to skip the part of the string that bstr_find has already looked
through and found nothing. This commit additionally skips the whole
substring, because overlapping matches are impossible.
See manpage additions.
(In ffmpeg-mpv and Libav, this is still called "cuvid". Libav won't work
yet, because it has no frame params support yet, but this could get
fixed soon.)
It isn't all that reliable, and improving it would make startup slower
and require more complexity. There isn't even a good reason to do this
(other than semi-broken mkv files), so don't do it. Also see previous
commit.
In some cases, demux_mkv will detect a start time slightly above 0, but
there might still be a subtitle starting at exactly 0. When the player
rebases the timestamps to assumed start time, the subtitle will have a
slightly negative timestamp in the end. libavcodec's subtitle converter
turns this into a larger number due to underflow. Fix by clamping
subtitles always to 0, which may or may not be what you want.
At least it fixes#5047.
This is required now. Can't have FFmpeg upstream randomly break us and
then not fix it (like this recent EOF issue).
Upstream FFmpeg is of course still supported, but you will need to edit
the build scripts. Official support is only with the master branch of
our own repo.
This removes the need for codec- and API-specific knowledge in the
libavcodec hardware acceleration API user. For mpv, this removes the
need for vd_lavc_hwdec.pixfmt_map and a few other things. (For now, we
still keep the "old" parts for the sake of supporting older Libav, and
FFgarbage.)
params->rc was ignored in the calculation for the buffer size. I fucking
hate this stupid ra_tex_upload signature where *rc is randomly relevant
or not.
Coverity complains about this, but it's probably a false positive.
Anyway, rewrite it in a slightly more readable way. Now it's more
obvious that it is correct.
I _think_ this confuses Coverity and it thinks there is uninitialized
data to be read. Initialize the array to change/remove the warning, or
if there's a real problem, to make it easier to detect. (Basically apply
defensive coding.)
Even if the demuxer cache does not multiple ranges yet. This is to
reduce the pain should caching of multiple ranges ever be implemented.
Also change it from the sub properties stuff to return a mpv_node
directly, which is less roundabout. Sub-property access won't work
anymore, though.
Remove the seekable-start/-end fields as well, as they're redundant with
the ranges.
All this would normally be considered an API change, but since it's been
only a few days with no known users, change it immediately.
This adds some node.c helpers as well, as the code would be too damn
fugly otherwise.
Should speed up seeks.
(Unfortunately it's useless for backstepping. Backstepping is like
precise seeking, except we're unable to drop frames, as we can't know
the previous frame if we drop it.)
Comparing mpv's implementation against the ACES ODR reference samples
and algorithms, it seems like they're happy desaturating highlights
_way_ more aggressively than mpv currently does. And indeed, looking at
some example clips like The Redwoods (which is actually well-mastered),
the current desaturation produces unnatural-looking brightness fringes
where the sky meets the treeline.
Adjust the algorithm to make it apply to a much larger, more gradual
brightness region; and change the interpretation of the parameter. As a
bonus, the new parameter is actually sanely scaled (higher values = more
desaturation). Also, make it scale based on the signal level instead of
the luminance, to avoid under-desaturating bright blues.
Avoids that cache seeking is not possible with files that have audio
frames with no timestamps (such as avi, sometimes mkv sub-packets from
lacing). These would set back_pts (first seekable PTS) to NOPTS, and
thus disable cache seeking completely. Instead, prune such packets until
we find one with timestamps.
One corner case is that the new next good packet might be in the forward
cache. In this case we defer dropping until the next time this code is
run, and the reader position has possibly moved past the drop point.
In theory, start/ts_min could be set to NOPTS, in which case
"pts < start" for a valid pts would always evaluate to false.
Also remove the redundant "in-cache seek is possible.." message, as
there's always another message when cache seeks are done.
The seek range computation ignored streams with no timestamps. For
things like buffer estimation this is OK and wanted, but the seek range
needs to be conservative.
Which parts of the queue are considered forward or backward cache
depends on ds->reader_header. The packet at ds->reader_head, as well as
all packets following it (via the ->next field) are considered forward.
The fw_packs/fw_bytes/bw_bytes must be updated accordingly.
This broke in demux_add_packet(), when ds->reader_head was _not_ set on
the first packet (or before). This could happen since commit
05ae571241, which can require skipping packets (so they immediately end
up in the backbuffer).
With the timeline code, a packet at the start or end of a segment can
refer to an invisible frame. So it doesn't extend the seek range, and
the timestamp should be clipped to the actual segment range.
Also restructure recompute_keyframe_target_pts() to be hopefully less
confusing.
Restores some behavior from before the demuxer cache changes, though
affects mostly just OSD display. The unknown queue state is reserved for
streams with missing or messed up timestamps.
Fully fixes behavior of the files mentioned in the previous commit. Will
probably lead to worse behavior if someone tries to fix real video and
cover art tracks, but that's a broken fringe case anyway.
This fixes .cue files with audio files that contain attached pictures to
some degree. demux_timeline.c just discarded packets with unset index,
so the picture was never fed to the decoder.
Directory-opening never worked on Windows because MSVCRT's open()
doesn't open directories and its fstat() doesn't recognise directory
handles. These are just MSVCRT restrictions, and the Windows API itself
has no problem with opening directories as file objects, so reimplement
mpv's mp_open and mp_stat to use the Windows API directly. This should
fix directory playback.
This also populates the st_dev and st_ino fields of struct stat, so
filesystem loop checking in demux_playlist.c should now work on Windows.
Fixes#4711
The new_segment field was used to track the decoder data flow handler of
timeline boundaries, which are used for ordered chapters etc. (anything
that sets demuxer_desc.load_timeline). This broke seeking with the
demuxer cache enabled. The demuxer is expected to set the new_segment
field after every seek or segment boundary switch, so the cached packets
basically contained incorrect values for this, and the decoders were not
initialized correctly.
Fix this by getting rid of the flag completely. Let the decoders instead
compare the segment information by content, which is hopefully enough.
(In theory, two segments with same information could perhaps appear in
broken-ish corner cases, or in an attempt to simulate looping, and such.
I preferred the simple solution over others, such as generating unique
and stable segment IDs.)
We still add a "segmented" field to make it explicit whether segments
are used, instead of doing something silly like testing arbitrary other
segment fields for validity.
Cached seeking with timeline stuff is still slightly broken even with
this commit: the seek logic is not aware of the overlap that segments
can have, and the timestamp clamping that needs to be performed in
theory to account for the fact that a packet might contain a frame that
is always clipped off by segment handling. This can be fixed later.
Needed for a failed thing, leaving it anyway because it causes no harm
and might be less awkward if struct virtual_stream is possibly extended
anyway in the future.
This commit allows to use the AV_PIX_FMT_DRM_PRIME newly introduced
format in ffmpeg that allows decoders to provide an AVDRMFrameDescriptor
struct.
That struct holds dmabuf fds and information allowing zerocopy rendering
using KMS / DRM Atomic.
This has been tested on RockChip ROCK64 device.
Although seeking past the cached range will trigger a low level seek, a
seek into the region between cache end and last video key frame would
simply seek to the video key frame. This meant that you could get
"stuck" at the end of the file instead of terminating playback when
trying to seek past the end.
One change is that we fix this by _actually_ allowing SEEK_FORWARD to
seek past the last video keyframe in find_seek_target().
In that case, or otherwise seeking to cache buffer end, it could happen
that we set ds->reader_head=NULL if the seek target is after the current
packet. We allow this, because the end of the cached region is defined
by the existence of "any" packet, not necessarily a key frame. Seeking
there still makes sense, because we know that there is going to be more
packets (or EOF) that satisfy the seek target.
The problem is that just resuming demuxing with reader_head==NULL will
simply return any packets that come its way, even non-keyframe ones.
Some decoders will produce ugly soup in this case. (In practice, this
was not a problem, because seeking at the end of the cached region was
rare before this commit, and also some decoders like h264 will skip
broken frames by default anyway.)
So the other change of this commit is to enable key frame skipping.
As a nasty implementation detail, we use a separate flag, instead of
setting reader_head to the first key frame encounted (reader_head being
NULL can happen after a normal seek or on playback start, and then we
want to mirror the underlying demuxer behavior, for better or worse).
This change is relatively untested, so you get to keep the pieces for
yourself.
Seems like most code dealing with this was for setting it in redundant
cases. Now SEEK_BACKWARD is redundant, and SEEK_FORWARD is the odd one
out.
Also fix that SEEK_FORWARD was not correctly unset in try_seek_cache().
In demux_mkv_seek(), make the arbitrary decision that a video stream is
not required for the subtitle prefetch logic to be active. We might want
subtitles with long duration even with audio only playback, or if the
file is used as external subtitle.
If a packet uses segmentation, the codec field must be set. Copying the
codec field was forgotten as an oversight, which is why this just
crashes. This showed up only now, because demux_copy_packet() was not
used before in the main demux path until recently.
Fixes#5027.
Since we divide by it in a couple of places and compositors can be crazy,
its better to be safe than sorry.
Also checks cursor spawn durinig init (pointless since it does again on
cursor entry but its more correct).
It seems the cursor hadn't had its position properly adjusted when scaled.
Hence, bring back correct buffer scaling to make the cursor look fine.
Also the cursor surface now gets created sooner so that's better.
This improves upon the previous commit, and partially rewrites it (and
other code). It does:
- disable the seeking within cache by default, and add an option to
control it
- mess with the buffer estimation reporting code, which will most likely
lead to funny regressions even if the new features are not enabled
- add a back buffer to the packet cache
- enhance the seek code so you can seek into the back buffer
- unnecessarily change a bunch of other stuff for no reason
- fuck up everything and vomit ponies and rainbows
This should actually be pretty usable. One thing we should add are some
properties to report the proper buffer state. Then the OSC could show a
nice buffer range. Also configuration of the buffers could be made
simpler. Once this has been tested enough, it can be enabled by default,
and might replace the stream cache's byte ringbuffer.
In addition it may or may not be possible to keep other buffer ranges
when seeking outside of the current range, but that would be much more
complex.
More the ignore_eof field to the internal demux_stream struct. This is
relatively messy, because the internal struct exists only once the
stream is created, and after that setting the ignore_eof flag is a race
condition. We could bother with adding demux_add_sh_stream() parameters
for this, but let's not. So in theory a tiny race condition is
introduced, which can never be triggered since all demux API functions
are called by the playback thread only anyway.
Fix that ts_offset is accessed without log (this was introduced much
earlier by myself).
Introduce an alternative way of avoiding the annoying EOF reached
messages by not resetting the EOF flags for CC streams when a CC packet
is added. This makes the second commit in the PR which added the
original fix unnecessary.
As another cosmetic change merge the check in cached_demux_control()
into a single if().
In the future, the CC pseudo-stream should probably be replaced with an
entire pseudo-demuxer or such, which would avoid some of the messiness
(or maybe not, we don't know yet).
In the extreme case, reading 1 byte would wake up the cache to make the
cache thread read 1 byte. This would be extremely inefficient. This will
not normally happen in our cache implementation, but it's still present
to some lesser degree. Normally you'd set a predefined "cache too low"
boundary, after which you would restart reading. For some reason
something like this is already present using a hardcoded value
(FILL_LIMIT - I don't even know the deeper reason why this exists). So
use that to reduce wakeups.
This doesn't fix redundant wakeups on EOFs, which is especially visible
should something keep retrying reading on EOF (like in an endless loop).
Regression since ec6e8a31e0. Removal of the explicit else case
always applies the conversion to premultiplied alpha in the else branch.
We want to scale with multiplied alpha, but we don't want to multiply
with alpha again on top of it.
Fixes#4983, hopefully.
This should be functionally identical to rgba16f, since the formats only
differ in their representation on the CPU, but it could be useful for RA
backends that don't expose rgba16f, like Vulkan. It's definitely useful
for the WIP D3D11 backend.
With video paused, changing the brightness controls (or similar) would
sometimes not rerender the video frame. So the OSD would redraw, but the
video wouldn't change. This is caused by output caching, and a redraw
request is free to return the cached frame. Change it such to invalidate
the cached frame if any of the options or the equalizer change.
In theory, gl_video_reset_surfaces() could be called if the equalizer
changes - this would apparently force interpolatzion to redraw all
frames. But this looks kind of crappy when changing the equalizer during
playback. It'll "eventually" use the correct settings anyway, and when
paused interpolation is off.
This was phased out, and was used only by vdpau by now. Drop the
mechanism and the vdpau special code, which means screenshots won't
include the vf_vdpaupp processing anymore. (I don't care enough about
vdpau, it's on its way out.)
The mechanism introduced in b135af6842 assumed AVHWFramesContext would
be enough. Apparently it's not - the intended use with Rockchip (not
Rokchip btw.) requires accessing actual frame data in order to access
the AVDRMFrameDescriptor struct.
Just pass the entire mp_image to the new function. This is more
flexible, although it slightly worries me that it will be less reusable
for things which require setting up mp_image_params before any real
frames are processed (such as filters).
The same should happen with any other side data that matters to mpv,
otherwise filters will drop it.
(No, don't try to argue that mpv should use AVFrame. That won't work.)
ffmpeg_garbage() is copy&paste from frame_new_side_data() in FFmpeg
(roughly feed201849b8f91), because it's not public API. The name
reflects my opinion about FFmpeg's API.
In mp_image_to_av_frame(), change the too-fragile
*new_ref = (struct mp_image){0};
into explicitly zeroing out the fields that are "transferred" to the
created AVFrame.
Merge mp_image_copy_fields_to_av_frame() into mp_image_from_av_frame(),
same for the other direction.
There isn't any good reason to keep them separate, and the refcounting
handling makes it only more awkward.
It seems this will be useful for Rokchip DRM hwcontext integration.
DRM hwcontexts have additional internal structure which can be different
depending on the decoder, and which is not part of the generic hwcontext
API. Rockchip has 1 layer, which EGL interop happens to translate to a
RGB texture, while VAAPI (mapped as DRM hwcontext) will use multiple
layers. Both will use sw_format=nv12, and thus are indistinguishable on
the mp_image_params level. But this is needed to initialize the EGL
mapping and the vo_gpu video renderer correctly.
We hope that the layer count is enough to tell whether EGL will
translate the data to a RGB texture (vs. 2 texture resembling raw nv12
data). For that we introduce MP_IMAGE_HW_FLAG_OPAQUE.
This commit adds the flag, infrastructure to set it, and an "example"
for D3D11.
The D3D11 addition is quite useless at this point. But later we want to
get rid of d3d11_update_image_attribs() anyway, while we still need a
way to force d3d11vpp filter insertion, so maybe it has some
justification (who knows). In any case it makes testing this easier.
Obviously it also adds some basic support for triggering the opaque
format for decoding, which will use a driver-specific format, but which
is not supported in shaders. The opaque flag is not used to determine
whether d3d11vpp needs to be inserted, though.
Mostly an obscure option for testing. But --videotoolbox-format can be
deprecated, as it becomes redundant.
We rely on the libavutil hwcontext implementation to reject invalid
pixfmts, or not to blow up if they are incompatible.
This was confusing at best. Change it to output the actual choices.
(Seems like in the end it's always me who has to clean up other people's
bullshit.)
Context names were not unique - but they should be, so fix it. The whole
point of the original --opengl-backend option was to side-step the
tricky auto-detection, so you know exactly what you get. The goal of
this commit is to make --gpu-context work the same way. Fix the
non-unique names by appending "vk" to the names.
Keep in mind that this was not suitable for slecting the "UI" backend
anyway, since "x11" would force GLX, whereas people on not-NVIDIA
actually want "x11egl". Users trying to use --gpu-context=x11 to force
the X11 backend would always end up with GLX, which would at least break
VAAPI hardware decoding for them. Basically the idea that this option
could select the "UI" type is completely broken - it selects an
implementation, which implies a UI. Selecting the UI type This would
require a separate mechanism. (Although in theory this separate
mechanism could be part of the --gpu-context option - in any case,
someone would have to implement it.)
To achieve help output that can actually be understood, just duplicate
the code. Most of that code is duplicated anyway, and trying to share
just the list code with the result of making the output unreadable
doesn't make too much sense. If we wanted to save code/effort, we could
just remove the help output altogether.
--gpu-api has non-unique entries, and it would be nice to group them
(e.g. list all OpenGL capable contexts with "opengl"), but C makes this
simple idea too much of a pain, so don't do it.
Also remove a stray tab from the android entry on the manpage.
If the chroma location is missing, vo_gpu will use centered chroma.
Select a better chroma location by default: normally, it will always be
MPEG video chroma location. If full levels are used, use JPEG chroma
location, because that sort of sounds like it could make sense as it
might coincide with JPEG being decoded.
See e.g. #4804.
Unfortunately I'm also adding the full text of the LGPL license text,
because the GPL one was already present in this repository, and I don't
want to imply that the GPL somehow has priority.
Every compositor (including toy compositors) has had support for wl_output v2
since forever, so there's little point in supporting degraded output for 5 year
old releases (especially considering we require zxdg6 which is far more recent).
This adds symbol information to the generated SPIR-V, which shows up in
the SPIR-V assembly dump. It's also useful for potential RA backends
that use SPIRV-Cross, since the symbol information is used in the
generated shader source.
Rename --enable-preliminary-lgpl2 to --enable-gpl. This concludes the
relicensing. Some things are still to do (relicensing some still-GPL
optional code), but we consider the code included by --enable-gpl to be
fully relicensed.
The relicensing was performed by asking every known author for
permission for relicensing it to LGPL version 2.1 "or later". If an
author could not be contacted or permission could not be obtained, and
the contribution was considered relevant for copyright purposes, the
affected code was either excluded from LGPL mode (not built), or removed
or rewritten. This is the standard in open source relicensing processes.
Keep in mind that using LGPL mode is still on the user's own risk. Even
though I claim that the relicensing was pretty clean and thorough
(measured on the standards of the open source community¹), and I
followed the advice of some actual experts, there is still a residual
uncertainty due to the fact that I'm not an all-knowing entity (authors
could have taken someone else's code and pretend it's their own) nor a
lawyer (meaning I might lack associated authority or expertise), and the
fact that the judicial system is far from deterministic. The relicensing
was performed merely to the best of my knowledge. I reject all
responsibility outside of that.
This commit also cleans up the "Copyright" file to reflect the finalized
relicensing process.
¹ Not to imply that the standards of commercial companies are much
higher. Some major tech companies get away with stuff I would not
consider clean.
See #2033.
This should actually cover all of them, if you take into account that
some unchanged GPL source files include header files with such checks.
Also this was done already for the libaf derived code.
This is only for "safety" and to avoid misunderstandings.
It turns out compositors which do scaling scale the cursor as well,
so every single surface needs to get scaled too.
Also, 32 corresponds to the default size for both GTK+ and KDE.
This new interface in libva2 offers a cleaner way to export surfaces
which can then be imported to EGL. In particular, this works with
the Mesa driver, so we can have proper playback without a pointless
download and upload on AMD cards.
This change does nothing with libva1, and will fall back to the
libva1 interface (vaDeriveImage() + vaAcquireBufferHandle()) if
vaExportSurfaceHandle() is not present.
Signed-off-by: wm4 <wm4@nowhere>
Rename --stats to --load-stats-overlay and add an entry to options.rst
over the original commit.
Signed-off-by: wm4 <wm4@nowhere>
Previously multiple timers were used to realize oneshot, toggling
(redrawing) and page keybindings. The oneshot case in particular also
relied on mp.osd_message to display text only for a given duration.
This was changed to only use one timer in total now. Because now each
case has a defined "start" and "end" point (including oneshot)
mp.set_osd_ass() can be used to print stats as well. This is currently
optional and has to be activated using the config option
persistent_overlay=true.
One shortcoming: oneshot and toggling are mutual exclusive right now.
Previously you could enter toggling while oneshot stats were shown,
this is not possible anymore to reduce the number of cases to be
considered. This can be added later on if desired.
It used a bad heuristic that got even worse/less reliable with recent
changes in mpv. In fact, it's not reliable at all.
Watch out for dropped frames instead. That's a useful indicator.
Previously I could trigger a bug with intense button mashing, however,
was unable to reproduce it and therefore debug it.
This change now seems to be resilient against button mashing, let's hope
it really is.
Please note that the latest version of this script needs a very recent
version of mpv (from yesterday, to be precise, see the readme).
For older versions, please go to "releases".
HOW IT WORKS:
While the stats are visible (i.e. text is printed to the OSD) a
subsequent click on a numeric key (1, 2, ...) will display the
corresponding "page".
This works no matter if the stats are toggled or just shown as a single
invocation. In case of a single invocation, the newly displayed page
will be shown for the full duration again.
The selected page will be remembered (not persistantly though).
So far, only 3 pages are available.
1: the default page, stats as they used to be
2: extensive VO performance stats (to be redesigned/changed soon)
3: dummy
In the future, many more pages are possible.
Implementation is likely to change again (functionality will stay
the same). A new timer had to be introduced to remove the forced
keybindings in the oneshot case. The toggle case can remove them without
a timer. Ensuring that each mode won't remove timers of the other mode
didn't really turn out neat.
Therefore, I intend to change this again, maybe by merging the
oneshot case into the toggle case.
Due to the large amount of per-pass data, the function takes a parameter
indicating whether or not to print a simplified view instead.
The overall intent is to print the simplified view for now, but supposed
printing the full view on a dedicated "tab" (or extra view type), and as
such, `o.print_perfdata_passes` will go away again. I've only introduced
it for now so users can play around with this functionality if they want
to, until Argon- gets around to implementing stats "tabs".
Previously, we used a property and when it was unavailable we assumed it
doesn't exist before assuming it really is just unavailable. This lead
to unnecessarily falling back to deprecated properties which made mpv
print deprecation warnings.
Now we can really check if a property is not known to mpv.
The alternative would've been to check the error part of mp.get_property
and perform string comparisons on the returned error message.
Not sure if supporting old mpv versions is actually worth it though.
Fixes#37#36
Both come with graphs enabled by default.
They can be disabled using the options plot_vsync_ratio and
plot_vsync_jitter (see the readme regarding customization).
In case both graphs are deactivated the ratio and jitter properties will
be printed on the same line to save some space.
One more user-visible/noticeable change: the maximum used to scale the
values for each graph is no longer calculated each time the stats are
shown but instead when collecting the data. This means the maximum
can actually be higher than all values currently present in a graph's
data buffer. This makes it easier to judge a graph's values, especially
since as we have no axis labels.
To prevent high values staying max forever graph data buffers are
cleared when toggling (can be disabled). It was never useful to
keep old data and simply append newer data (with a time skip) anyway.
This used to be the case, I'm not sure when it changed.
The current way of 'hiding' it in case of 0 is not exactly
good and relies on the OSD representation. It could be done
better by querying the video-sync-active property but that would
require querying yet one more thing...
Added to mpv in commit a14f9249. Simply shown after the gamma curve if
available, since it's semantically attached to it.
Also regroup some of the colorimetry options to make this fit (and for
them to make more sense)
Display an additional line with the sum of all three timing values.
Disabled by default.
I didn't see the necessity to also create a graph for this line
Add a yellow highlight to the existing red highlight.
Red is still used once the available time is exhausted, yellow is
supposed to be a warning when the headroom is getting small.
The threshold is configurable.
Graphs are now aligned. This required a change in the layout of
performance data. Reason is a wrong (but intended) calculation
of vector drawing sizes in libass to maintain compatibility.
This essentially prevents text following the graph.
To achieve alignment only monospaced text can precede the graph.
This led to the layout changing slightly when graphs are shown.
Instead of creating new strings with the content of the previous
one followed by some new content we now write all content into
tables that are concatenated in the end.
This is unlikely to improve performance but at least it will
cut down on all these temporary, growing strings polluting memory.
Major changes:
- graphs are only drawn when in toggled mode
- performance data is retrieved every ith frame (default: 5)
- highlighting of performance data (numbers): add a highlight
when the summed numbers (last/avg/peak) exceed 1/display-fps
Display various performance data about frames and their
display/rendering. Additionally plot graphs for this data.
This is experimental and pretty much just a test at this point and by
far not final.
Previously the delay was slightly shortened but a user explicitly
setting a specific delay most likely expects the stats to refresh
in exactly the frequency he desired.
You can now either show the stats once or toggle their display. Both are
using different key bindings which are additionally configurable now.
Please bear in mind that "toggling" means "redraw every x seconds for x
seconds". Therefore, this approach is prone to problems especially when
something else is printing text to the OSD as well as every of these
calls will overwrite each other. This is currently a limitation of mpv.
Fixes#18
This simply prints ASCII codes to display any text marked as bold in the
terminal. Supported by every sane terminal since 1986. For those insane,
there's a check. The check has been copied from the ansicolors.lua
script floating around and it checks if the directory path uses "\"
instead of "/", and in case it does, it checks whether ANSICON env
variable has been set (which is used to indicate the Windows terminal
supports ACII escape sequences).
Unify both append_property* functions and greatly refactor them.
Instead of thousands of arguments we now use a table.
While this is in theory cleaner it does not exactly look like it.
However, it's way more flexible and extendable this way.
Also, since the new append_property() might look a bit confusing
I felt the need to add a comment.
Previously, the script would throw garbage (ASS tags) at the terminal
when the bound key was pressed. This changes the behaviour to _not_
print any ASS tags (and replace those which can be interpreted by the
terminal) if there's no video.
I cleaned the patch up since you mentioned you were busy. As I said
before, there is absolutely no problem with calling mpv to display
strings to the OSD without any video. They'll just go straight to the
terminal just as they would with an active VO.
ATSC is a mix of terrestrial and cable,
and depending on modulation is actually using
DVBC_ANNEX_B. Thus, we need to override the delivery
system depending on the modulation, channel by channel.
Signed-off-by: Oliver Freyermuth <o.freyermuth@googlemail.com>
These values are kept with a different unit in VDR style config
for all delivery systems, not only for DVB-S / DVB-S2.
Signed-off-by: Oliver Freyermuth <o.freyermuth@googlemail.com>
Dump the complete raw tuning commands to allow for debugging
on low level.
Also, remove code duplication and some variable shadowing.
Signed-off-by: Oliver Freyermuth <o.freyermuth@googlemail.com>
Also, in case tuning fails with timeout even though the ioctl
was accepted by the device, fall back to DVBv3 tuning.
This may go wrong for multi-delivery-system cards,
so issue an error message in that case.
Signed-off-by: Oliver Freyermuth <o.freyermuth@googlemail.com>
At the moment, rendering on Android requires ``--vo=opengl-cb`` and
a lot of java<->c++ bridging code to receive the receive and react to
the render callback in java. Performance also suffers with opengl-cb,
due to the overhead of context switching in JNI.
With this patch, Android can render using ``--vo=gpu --gpu-context=android``
(after setting ``--wid`` to point to an android.view.Surface on-screen).
MediaCodec uses a fixed number of output buffers to hold frames, and
expects that output buffers will be released as soon as possible. Once
rendered, the underlying frame is automatically released and cannot be
reused or rerendered.
The new VO_CAP_NOREDRAW forces mpv to release frames immediately after
they are rendered or dropped, to ensure that MediaCodec decoder does not
run out of buffers and stall out.
This partiular format is not marked as AV_PIX_FMT_FLAG_RGB in FFmpeg's
pixdesc table, so mpv assumed it's a YUV format.
This is a regression, since the old code in mp_imgfmt_get_desc() also
treated this format specially to avoid this problem. Another format
which was special-cased in the old code was AV_PIX_FMT_MONOBLACK, so
make an exception for it as well.
Maybe this problem could be avoided by mp_image_params_guess_csp() not
forcing certain colorimetric parameters by the implied colorspace, but
certainly that would cause other problems. At least there are mistagged
files out there that would break. (Do we actually care?)
Fixes#4965.
This commit:
- Implements output tracking (e.g. monitor plug/unplug)
- Creates the surface during registry (no other dependencies)
- Queues the callback immediately after surface creation
- Cleaner and better event handling (functions return directly)
- Better reconfigure handling (resizes reduced to 1 during init)
- Don't unnecessarily resize (if dimensions match)
Apart from that fixes 2 potential memory leaks (mime type and window
title), 2 string ownership issues (output name and make need to be
dup'd), fixes some style issues (switches were indented) and finally
adds messages when disabling/enabling idle inhibition.
The callback setter function was removed in preparation for the commit
which will use the frame event cb because it was unnecessary.
The VO code resets each flag individually, and it doesn't do it for this one.
Also make the prints use the struct names rather than the hardcoded ones,
forgot to add those to the last wayland_common commit.
iive agreed to relicense things that are still in mpv to LGPLv2.1. So
change the licenses of the affected files, and rename the configure
switch for LGPL mode to --enable-preliminary-lgpl2.
(The "preliminary" part will probably be removed from the configure
switch soon as well.)
Also player/main.c hasn't had GPL parts since a few commits ago.
But --msg-level can only raise the log level used for --log-file,
because the original idea with --log-file was that it'd log verbose
messages to disk even if terminal logging is lower than -v or fully
disabled.
Seems absurd to keep this under GPL, since it's only a tiny code
fragment (that would always look the same, no matter if you rewrote it
independently), but now I got proper permission from the original author
anyway.
The wayland code was written more than 4 years ago when wayland wasn't
even at version 1.0. This commit rewrites everything in a more modern way,
switches to using the new xdg v6 shell interface which solves a lot of bugs
and makes mpv tiling-friedly, adds support for drag and drop, adds support
for touchscreens, adds support for KDE's server decorations protocol,
and finally adds support for the new idle-inhibitor protocol.
It does not yet use the frame callback as a main rendering loop driver,
this will happen with a later commit.
with the previous commit we removed the ability of loading the standard
shell environment. this exact behaviour can only be re-added by either
invoking the standard shell in a background process and reading it's
environment vars or by manually reading all the various shell configs.
both ways are kinda dirty and the former was already rejected before.
for now we will just add some commonly used paths, when started from the
bundle, so it can find the binaries used by mpv again. for example the
youtube-dl one for our youtube-dl hook.
Apple slightly changed the App bundle mechanism which broke wrapper
scripts that invoke the actual binary. it caused the bundle to always
open a new instance of mpv instead of reusing the currently running one.
just removing the wrapper script would lead to several regressions, so
it was replaced with a symlink to the bundle binary. detection if mpv
was started from the bundle was replaced by comparing the execution name
of the binary, eg the name of the symlink "mpv-bundle". additionally,
because we load a standard config from the Resources folder of the
bundle again, we prevent that config from being loaded if mpv wasn't
started via the bundle. the psn argument has to be removed manually
again.
the ability of loading your standard shell environment has been removed
with the wrapper. a substitution will be added with another commit. as a
side effect this fixes an issues when zsh was used with common NodeJS
configuration scripts.
Fixes#4926#4866
The existing code in check_ext() avoided false positive due to
sub-strings, but allowed false negatives. Fix this with slightly better
search code, and make it available as function to other source files.
(There are some cases of strstr() still around.)
- Don't recommend libdvdnav, since DVD support isn't compiled by default
anymore.
- Take advantage of the new $MINGW_PACKAGE_PREFIX and $MSYSTEM_PREFIX
variables to make the build commands independent from the mingw-w64
build environment being used.
- Invoke /usr/bin/python3 directly, since I've heard some packages have
started to depend on mingw-w64 versions of Python, but our build
scripts only work with the MSYS2 version.
- Reword the MSYS2 install instructions to try to prevent common errors.
Unless FBOs are unsupported, this works. In particular, it's required to
get ICC profiles working in voluntary dumb mode. So instead of
blanket-disabling it, only disable it in the !have_fbo false case.
We allowed any input format that was generally supported by libva, but
this is probably nonsense, as the actual surface format was always fixed
to nv12. We would have to check whether libva can upload a given pixel
format to a nv12 surface. Or we would have to use a separate frame pool
for input surfaces with the exact sw_format - but then we'd also need to
check whether the vaapi VideoProc supports the surface type.
Hardcode nv12 and yuv420p as input formats, which we know can be
uploaded to nv12 surfaces. In theory we could get a list of supported
upload formats from libavutil, but that also require allocating a dummy
hw frames context just for the query.
Add a comment to the upload code why we can allocate an output surface
for input.
In the long run, we'll probably want to use libavfilter's vaapi
deinterlacer, but for now this would break at least user options.
The current check_va_status() function could probably be argued to be
derived from the original VAAPI's patch check_status() function, thus
GPL-only. While I have my doubts that it applies to an idiom on this
level, it's better to replace it. Similar idea, different expression
equals no copyright association.
An earlier commit message promised this, but it was forgotten.
Changed the reference from --gpu-gamma to --gamma-factor,
and changed the reference from --post-shader to --glsl-shaders,
in order to reflect actual changes to the option names.
Originally mpv vaapi support was based on the MPlayer-vaapi patches.
These were never merged in upstream MPlayer. The license headers
indicated they were GPL-only. Although the actual author agreed to
relicensing, the company employing him to write this code did not, so
the original code is unusable to us.
Fortunately, vaapi support was refactored and rewritten several times,
meaning little code is actually left. The previous commits removed or
moved that to GPL-only code. Namely, vo_vaapi.c remains GPL-only. The
other code went away or became unnecessary mainly because libavcodec
itself gained the ability to manage the hw decoder, and libavutil
provides code to manage vaapi surfaces. We also changed to mainly using
EGL interop, making any of the old rendering code unnecessary.
hwdec_vaglx.c is still GPL. It's possibly relicensable, because much of
it was changed, but I'm not too sure and further investigation would be
required. Also, this has been disabled by default for a while now, so
bothering with this is a waste of time. This commit simply disables it
at compile time as well in LGPL mode.
Done for license reasons. vo_vaapi.c is turned into some kind of
dumpster fire, and we'll remove it as soon as I'm mentally ready for
unkind users to complain about removal of this old POS.
This is for relicensing. Some of this code is loosely based on
vo_vaapi.c from the original MPlayer-vaapi patches. Most of the code has
changed, and only the initialization code and check_status() look
remotely similar. The initialization code is changed to be like Libav's
(hwcontext_vaapi.c). check_va_status() is just a C idiom, but to play it
safe, we'll either drop it from LGPL code (or recreate it).
vaapi.c still contains plenty of code from the original patches, but the
next commits will move them out of the LGPL code paths.
Seems to be fixed upstream in the nvidia driver, so it's probably a good
idea to 1. force the layout and 2. remove the warning, as it now
actually works. Users with older drivers would run into errors, but they
can still use shaderc as a replacement. (And it's not like the old
status quo was any better)
This was always set to the length of the VAO, but it should have been
set to the number of vertex attribs actually in use for this frame. No
idea how that managed to survive the test framework on nvidia/linux, but
ANGLE caught it.
This has several advantages:
1. no more redundant texcoords when we don't need them
2. no more arbitrary limit on how many textures we can bind
3. (that extends to user shaders as well)
4. no more arbitrary limits on tscale radius
To realize this, the VAO was moved from a hacky stateful approach
(gl_sc_set_vertex_attribs) - which always bothered me since it was
required for compute shaders as well even though they ignored it - to be
a proper parameter of gl_sc_dispatch_draw, and internally plumbed into
gl_sc_generate, which will make a (properly mangled) deep copy into
params.vertex_attribs.
Apparently this filter is broken in a weird way, which even makes some
libavfilter functions segfault in certain conditions. Don't waste time
with it and just remove the examples.
Also adjust the "life" example description (certainly this filter is
100% worthless, but the example does demonstrate how to use source
filters without any available input).
The case at hand was 5.1 -> fl-fr-fc-lfe-na-na (apparently triggered by
ALSA). That means only the NA channels have to be cleared, but the
result was actually that fc and lfe were cleared. This is due to a
simple regression in the reorder code, which quite obviously got the
index of the first NA channel wrong.
FlagBits is just the name of the enum. The actual data type representing
a combination of these flags follows the *Flags convention. (The
relevant difference is that the latter is defined to be uint32_t instead
of left implicit)
For consistency, use *Flags everywhere instead of randomly switching
between *Flags and *FlagBits.
Also fix a wrong type name on `stageFlags`, pointed out by @atomnuker
Using renderpass layout transitions is more optimal and doesn't require
a redundant pipeline barrier.
Since our render passes are static and don't change throughout the
lifetime of a ra_renderpass, we unfortunately don't have much
flexibility here - so just hard-code SHADER_READ_ONLY_OPTIMAL as the
output format as this will be the most common case.
We also can't short-circuit the transition when we need to preserve the
framebuffer contents, since that depends on the current layout; so we
still use an explicit tex_barrier in this case. (Most optimal for this
scenario would be an input attachment anyway)
auto-copy selects more modes than the ones listed. It will always be
outdated anyway.
The GLX vaapi backend is never selected anymore, because it sucks.
Now you need FFmpeg git, or something.
This also gets rid of the last real use of gpu_memcpy(). libavutil does
that itself. (vaapi.c still used it, but it was essentially unused,
because the code path isn't really in use anymore. It wasn't even
included due to the d3d-hwaccel dependency in wscript.)
This is apparently required to get storage images working on
windows/vulkan, and probably good practice either way. Not entirely sure
if it's the best idea to be always storing the value as 32-bit float,
but it should hardly matter in practice (since we're only writing one
sample per thread).
(Leaving them implicit requires the shaderStorageImageWriteWithoutFormat
feature to be enabled, which the windows nvidia vulkan driver doesn't
support, at least not for a GTX 670)
This makes the radeon driver shut up about frequently updating
STATIC_DRAW UBOs (--opengl-debug), and also reduces the amount of
synchronization necessary for vulkan uniform buffers.
Also add some extra debugging/tracing code paths. I went with a
flags-based approach in case we ever want to extend this.
In addition to the built-in nvidia compiler, we now also support a
backend based on libshaderc. shaderc is sort of like glslang except it
has a C API and is available as a dynamic library.
The generated SPIR-V is now cached alongside the VkPipeline in the
cached_program. We use a special cache header to ensure validity of this
cache before passing it blindly to the vulkan implementation, since
passing invalid SPIR-V can cause all sorts of nasty things. It's also
designed to self-invalidate if the compiler gets better, by offering a
catch-all `int compiler_version` that implementations can use as a cache
invalidation marker.
This time based on ra/vo_gpu. 2017 is the year of the vulkan desktop!
Current problems / limitations / improvement opportunities:
1. The swapchain/flipping code violates the vulkan spec, by assuming
that the presentation queue will be bounded (in cases where rendering
is significantly faster than vsync). But apparently, there's simply
no better way to do this right now, to the point where even the
stupid cube.c examples from LunarG etc. do it wrong.
(cf. https://github.com/KhronosGroup/Vulkan-Docs/issues/370)
2. The memory allocator could be improved. (This is a universal
constant)
3. Could explore using push descriptors instead of descriptor sets,
especially since we expect to switch descriptors semi-often for some
passes (like interpolation). Probably won't make a difference, but
the synchronization overhead might be a factor. Who knows.
4. Parallelism across frames / async transfer is not well-defined, we
either need to use a better semaphore / command buffer strategy or a
resource pooling layer to safely handle cross-frame parallelism.
(That said, I gave resource pooling a try and was not happy with the
result at all - so I'm still exploring the semaphore strategy)
5. We aggressively use pipeline barriers where events would offer a much
more fine-grained synchronization mechanism. As a result of this, we
might be suffering from GPU bubbles due to too-short dependencies on
objects. (That said, I'm also exploring the use of semaphores as a an
ordering tactic which would allow cross-frame time slicing in theory)
Some minor changes to the vo_gpu and infrastructure, but nothing
consequential.
NOTE: For safety, all use of asynchronous commands / multiple command
pools is currently disabled completely. There are some left-over relics
of this in the code (e.g. the distinction between dev_poll and
pool_poll), but that is kept in place mostly because this will be
re-extended in the future (vulkan rev 2).
The queue count is also currently capped to 1, because of the lack of
cross-frame semaphores means we need the implicit synchronization from
the same-queue semantics to guarantee a correct result.
Under some conditions, hide_osc() was calling render(), which then called
hide_osc() again, and so forth, until the stack overflows.
Tracking the exact conditions where this happens (and then managing them
to prevent it) is an excercise in futility.
Remove the osc directly - instead of going through the entire rendering
procedure just to end up rendering nothing.
Fixes#4900 .
Also implicitly fixes memory leak when mp.set_property_native was used,
because the cleanup did not expect more allocations from the accidental
use of mpv_get_property.
Tested by making the ra_tex_resize function always fail (apart from the
initial FBO check). This required a few changes:
1. reset shaders on failed dispatch
2. reset cleanup binds on failed dispatch
3. fall back to initializing the struct image to 1x1 on failure
4. handle output_fbo_valid gracefully
This was sort of grating by default and made it really hard to actually
read e.g. text on top of a transparent background. I decided to approach
the problem from both directions, making the whites darker and the grays
lighter. This brings it closer to the dynamic range of e.g. the
wikipedia transparent svg preview.
Due to the plethora of historical baggage from different eras getting
confusing, I decided to simplify and unify the struct organization and
naming scheme.
Structs that got renamed:
1. fbodst -> ra_fbo (and moved to gpu/context.h)
2. fbotex -> removed (redundant after 2af2fa7a)
3. fbosurface -> surface
4. img_tex -> image
In addition to these structs being renamed, all of the names have been
made consistent. The new scheme is as follows:
struct image img;
struct ra_tex *tex;
struct ra_fbo fbo;
This also affects derived names, e.g. indirect_fbo -> indirect_tex.
Notably also, finish_pass_fbo -> finish_pass_tex and finish_pass_direct
-> finish_pass_fbo.
The new equivalent of fbotex_change() is called ra_tex_resize().
This commit (should) contain no logic changes, just renaming a bunch of
crap.
I've observed the garbage pixels in more scenarios. They also were never
really needed to begin with, originally being a discovered work-around
for bug that we fixed since then anyway. Doesn't really seem to even
help resizing, since the OpenGL drivers are all smart enough to pool
resources internally anyway.
Fixes#1814
Enabling double buffering fixed some graphical glitches when entering
fullscreen, but it also caused a fullscreen performance regression. We
decided that the glitches were preferable to the performance regression.
This reverts commit cee764849e.
The code used ra_ctx_destroy even though ra_ctx_create was never called
(since it's just a dummy ctx), which led to a conflict of assumptions.
The proper fix is to only use ra_gl_ctx_uninit (mirroring the
ra_gl_ctx_init) and free the dummy ctx manually.
Fixes https://github.com/cmdrkotori/mpc-qt/issues/129
We want e.g. --opengl-shaders-append=foo to resolve to the new option,
all while printing an option name. --opengl-shader is a similar case.
These options are special, because they apply "actions" on actual
options by specifying a suffix. So the alias/deprecation handling has to
be part of resolving the actual option from prefix and suffix.
Turns out the option code apparently tries to directly talloc_free() the
allocated strings, instead of going through a tactx wrapper or
something. So we can't directly overwrite it. Do something else
instead..
Almost as fast as the old code, but more general. Notably, glslang
doesn't support nested arrays.
(cf. https://github.com/KhronosGroup/glslang/issues/1057)
Also much cleaner code-wise, so I think I'll keep it even if glslang
implements array_of_arrays.
This never really made sense since the BT.1886 changes. It should get
*brighter* for bright rooms, not darker for dark rooms. Picked some new
values that seemed reasonable-ish.
This causes a performance regression on 10.11 and newer, but the single
buffered method was broken and could cause partially rendered frames to
be presented to the screen.
This reverts 9f30cd8292 and
e543853a7f.
This is done in several steps:
1. refactor MPGLContext -> struct ra_ctx
2. move GL-specific stuff in vo_opengl into opengl/context.c
3. generalize context creation to support other APIs, and add --gpu-api
4. rename all of the --opengl- options that are no longer opengl-specific
5. move all of the stuff from opengl/* that isn't GL-specific into gpu/
(note: opengl/gl_utils.h became opengl/utils.h)
6. rename vo_opengl to vo_gpu
7. to handle window screenshots, the short-term approach was to just add
it to ra_swchain_fns. Long term (and for vulkan) this has to be moved to
ra itself (and vo_gpu altered to compensate), but this was a stop-gap
measure to prevent this commit from getting too big
8. move ra->fns->flush to ra_gl_ctx instead
9. some other minor changes that I've probably already forgotten
Note: This is one half of a major refactor, the other half of which is
provided by rossy's following commit. This commit enables support for
all linux platforms, while his version enables support for all non-linux
platforms.
Note 2: vo_opengl_cb.c also re-uses ra_gl_ctx so it benefits from the
--opengl- options like --opengl-early-flush, --opengl-finish etc. Should
be a strict superset of the old functionality.
Disclaimer: Since I have no way of compiling mpv on all platforms, some
of these ports were done blindly. Specifically, the blind ports included
context_mali_fbdev.c and context_rpi.c. Since they're both based on
egl_helpers, the port should have gone smoothly without any major
changes required. But if somebody complains about a compile error on
those platforms (assuming anybody actually uses them), you know where to
complain.
Let's blame FFmpeg for just overwriting the samplerate in
av_frame_copy_props(). Can't fully hide my own brain damage though,
since mp_aframe_config_copy() expected that the rate is copied (that
function also copies format and channel layout).
See "Copyright" file for caveats.
This changes the remaining "almost LGPL" files to LGPL, because we think
that the conditions the author set for these was finally fulfilled.
This code could not be relicensed. The intention was to write new filter
code (which could handle both audio and video), but that's a bit of
work. Write some code that can do audio conversion (resampling,
downmixing, etc.) without the old audio filter chain code in order to
speed up the LGPL relicensing.
If you build with --disable-libaf, nothing in audio/filter/* is compiled
in. It breaks a few features, such as --volume, --af, pitch correction
on speed changes, replaygain.
Most likely this adds some bugs, even if --disable-libaf is not used.
(How the fuck does EOF notification work again anyway?)
Move it from af_lavrresample.c to a new aconverter.c file, which is
independent from the filter chain code. It also doesn't use mp_audio,
and thus has no GPL dependencies.
Preparation for later commits. Not particularly well tested, so have
fun.
Just reimplement it in some way, as mp_audio is GPL-only.
Actually I wanted to get rid of audio_buffer.c completely (and instead
have a list of mp_aframes), but to do so would require rewriting some
more player core audio code. So to get this LGPL relicensing over
quickly, just do some extra work.
This is "wrong", because you might want mp_image_copy_attributes() to
preserve the information that the colorspace parameters are unknown.
This is important for hwdec -copy modes, which call this function before
fix_image_params() and mp_colorspace_merge() are called.
Instead, just wipe the colorspace attributes if the pixel format changes
in an apparently incompatible way. Use mp_image_params_guess_csp() logic
for this and factor that into its own function.
mp_image_set_attributes() attempts to do something similar, so change
that in the same way. Also, mp_image_params_guess_csp() just returned if
the imgfmt was invalid or unset - just remove that part, because it
annoyingly doesn't fit into the new code, and had little reason to exist
to begin with. (Probably.)
I see no reason not to do this. I think the check comes from the time
when mp_image stored the image aspect ratio, instead of the pixel aspect
ratio, where the logic might have made more sense.
It was noticed that -copy hwdec modes typically dropped the
chroma_location field. This happened because the attributes on hw
download are copied with mp_image_copy_attributes(), which tries to copy
these parameters only if src and dst were both YUV (in an attempt to
copy parameters only if it makes sense).
But hardware formats did not have the YUV flag set (anymore?), and code
shouldn't attempt to check the flag in this way anyway. Drop the check,
and always copy the whole color metadata struct. There is a call to
mp_image_params_guess_csp() below, which tries to unset nonsense
metadata if it was copied from a YUV format to RGB. This function would
also do the right thing for hw formats (although for the cited bug only
the software case matters).
Fixes#4804.
This reverts commit 96462040ec.
I guess the autoprobing is still too primitive to handle this well. What
it really should be trying is initializing the wrapper decoder, and if
that doesn't work, try another method. This is complicated by hwaccels
initializing in a delayed way, so there is no easy solution yet.
Probably fixes#4865.
This mechanism uses system() and shouldn't even exist. x11_common.c has
its own solution for the original problem (disabling Linux DE
screensavers without MPlayer/mpv having to link a dbus lib). If that is
not sufficient, you can create a simple Lua script.
Incidentally fixes#4888.
Instead of "deps", "deps_neg", and "deps_any" fields, just have a single
"deps" field, which changes from an array to a string. The string is now
an expression, which can contain the operators &&, ||, !, and allows
grouping with ( ).
It's probably overkill. If it gets a maintenance burden, we can switch
to specifiying the dep expressions as ASTs (or maybe eval()-able Python
expressions), and we could simplify the code that determines the reason
why a dependency is not fulfilled. The latter involves a complicated
conversion of the expression AST to DNF.
The parser is actually pretty simple, and pretty much follows:
https://en.wikipedia.org/wiki/Shunting_yard_algorithm
This fixes >2GiB files with at least API level 21.
See: https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md
for the gritty details.
* Based on libavformat's things, except we do not care about API
versions or NDKs without unistd.h, which contains all sorts of
things that we utilize.
* Redefines lseek to always point to the 64bit version.
* Redefines fseeko to always point towards an inlined static
implementation that utilizes the 64bit version of lseek underneath.
The first one (line 140) comes from 69650851f8 and is the correct one.
The second one (line 731) comes from 72a8120daa and slipped in with the
revert commit.
Remove the second one.
This overrides the use of GLX_SGI_swap_control, because apparently
GLX_SGI_swap_control doesn't support SwapInterval(0), but the
GLX_MESA_swap_interval does.
Of course, everybody except mesa just accepts SwapInterval(0) even for
GLX_SGI_swap_control, but mesa needs to be the special snowflake here
and reject it, forcing us to load their stupid named extension instead.
Meanwhile khronos has done nothing except spit out GLX_EXT_swap_control
(not to be confused with GL_EXT_swap_control, which is exported by
WGL_EXT_swap_control), that doesn't fix the problem because mesa doesn't
implement it anyway.
What a fucking mess.
Loaded 100 of 331 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.