Commit Graph

4388 Commits

Author SHA1 Message Date
wm4 257534ed18 vo: remove unused equalizer control remains
Equalizer control was redone in 03cf150ff3 (over 2 years
ago). Ever since, the equalizer control structs and the GET voctrl have
been unused. Only the SET voctrl is still used as notification mechanism
(actually a bad hack to avoid some further option change handling
complexity).

Remove the unused parts.
2019-09-20 00:45:17 +02:00
wm4 8e5cd62dca oml_sync: fix typo in comment
I think... Also reword another part of the text.
2019-09-20 00:32:29 +02:00
wm4 7000d91cf8 vf_fingerprint: use aligned_alloc instead of posix_memalign
I was assuming posix_memalign was the most portable function to use, but
MinGW does not provide it for some reason. Switch to C11 aligned_alloc()
which someone suggested was provided by MinGW (but actually isn't,
someone probably confused it with the incompatible _aligned_malloc),
and add a configure check.

Even though it turned out that MinGW doesn't provide it, the function
is slightly more elegant than posix_memalign(), so stay with it.
2019-09-19 23:09:02 +02:00
wm4 9cfeafa89e video: add vf_fingerprint and a skip-logo script
skip-logo.lua is just what I wanted to have. Explanations are on the top
of that file. As usual, all documentation threatens to remove this stuff
all the time, since this stuff is just for me, and unlike a normal user
I can afford the luxuary of hacking the shit directly into the player.

vf_fingerprint is needed to support this script. It needs to scale down
video frames as part of its operation. For that, it uses zimg. zimg is
much faster than libswscale and generates more correct output. (The
filter includes a runtime fallback, but it doesn't even work because
libswscale fucks up and can't do YUV->Gray with range adjustment.)

Note on the algorithm: seems almost too simple, but was suggested to me.
It seems to be pretty effective, although long time experience with
false positives is missing. At first I wanted to use dHash [1][2], which
is also pretty simple and effective, but might actually be worse than
the implemented mechanism. dHash has the advantage that the fingerprint
is smaller. But exact matching is too unreliable, and you'd still need
to determine the number of different bits for fuzzier comparison. So
there wasn't really a reason to use it.

[1] https://pypi.org/project/dhash/
[2] http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html
2019-09-19 20:37:05 +02:00
wm4 e1157cb6e8 video: generally try to align image data on 64 bytes
Generally, using x86 SIMD efficiently (or crash-free) requires aligning
all data on boundaries of 16, 32, or 64 (depending on instruction set
used). 64 bytes is needed or AVX-512, 32 for old AVX, 16 for SSE. Both
FFmpeg and zimg usually require aligned data for this reason.

FFmpeg is very unclear about alignment. Yes, it requires you to align
data pointers and strides. No, it doesn't tell you how much, except
sometimes (libavcodec has a legacy-looking avcodec_align_dimensions2()
API function, that requires a heavy-weight AVCodecContext as argument).

Sometimes, FFmpeg will take a shit on YOUR and ITS OWN alignment. For
example, vf_crop will randomly reduce alignment of data pointers,
depending on the crop parameters. On the other hand, some libavfilter
filters or libavcodec encoders may randomly crash if they get the wrong
alignment. I have no idea how this thing works at all.

FFmpeg usually doesn't seem to signal alignment internal anywhere, and
usually leaves it to av_malloc() etc. to allocate with proper alignment.
libavutil/mem.c currently has a ALIGN define, which is set to 64 if
FFmpeg is built with AVX-512 support, or as low as 16 if built without
any AVX support. The really funny thing is that a normal FFmpeg build
will e.g. align tiny string allocations to 64 bytes, even if the machine
does not support AVX at all.

For zimg use (in a later commit), we also want guaranteed alignment.
Modern x86 should actually not be much slower at unaligned accesses, but
that doesn't help. zimg's dumb intrinsic code apparently randomly
chooses between aligned or unaligned accesses (depending on compiler, I
guess), and on some CPUs these can even cause crashes. So just treat the
requirement to align as a fact of life.

All this means that we should probably make sure our own allocations are
64 bit aligned. This still doesn't guarantee alignment in all cases, but
it's slightly better than before.

This also makes me wonder whether we should always override libavcodec's
buffer pool, just so we have a guaranteed alignment. Currently, we only
do that if --vd-lavc-dr is used (and if that actually works). On the
other hand, it always uses DR on my machine, so who cares.
2019-09-19 20:37:05 +02:00
wm4 e265c07547 vo: fix missed option updates under rare circumstances
Dear diary,

today I fixed a shitty bug that was all my fault because I made a
horrible mess. (Except it was a horrible mess before I even touched
this shit, but let's not blame others.)

Sometimes, updates to VO option that control video sizing (like panscan)
didn't update the screen correctly. They were delayed until the next
option change or so.

It turns out that if the option update happens at the "same" time as a
VOCTRL, update_opts() doesn't actually notify the vo_driver of the
change. This in turn happened because run_control() called
m_config_cache_update(). The latter function returns true if the options
changed since the last call, and update_opts() also calls it (on the
same config cache) for the same purpose. The update_opts() call, which
is triggered by a third mechanism, comes later, but the cache update
call will return false (as it should). Basically, given the config API,
you can't act differently on multiple update calls and expect it to
work. The skipped handling in update_opts() meant that the notification
required to apply the changed option wasn't run.

Fix this by simply calling update_opts() directly instead. Now there's
only 1 m_config_cache_update() call on this specific instance. Fix the
call in run_reconfig() too, so the previous sentence isn't a lie (but it
probably doesn't make a difference in practice due to certain details).

I'm not sure how I even ran into this sort-of race condition. The VOCTRL
that messed up the option update was VOCTRL_UPDATE_PLAYBACK_STATE, which
happens semi-regularly.

Why this config cache shit and all the other shit? Rediscovering this
crap wasn't pleasant. It's a bunch of hacks that became necessary when
the ancient MPlayer architecture made it hard to move the VO to a
separate thread.

All the VO code typically accesses vo->opts (whose fields all used to be
global variables in MPlayer). The frontend changes these on user input.
Putting locking around all the options would be a nightmare, and keeping
a copy of the options in the thread was much simpler. You need a way to
propagate option changes, notify the thread, and update the local copy
too. And the result of these thoughts was the config cache mechanism.

In this specific case, the relevant cache update call in update_opts()
triggers a VOCTRL_SET_PANSCAN to the VO driver, which isn't related to
its former function anymore. Instead, it causes the VO driver to update
the video sizing/placing options, which the generic VO code can't do.
(Mostly because the VO driver includes the windowing stuff and is
responsible for resizing etc. itself.)

VOCTRLs sent by the frontend are even worse. MPlayer had no real runtime
option change mechanism. Some options were vaguely duplicated by
properties, so you could effectively change those options at runtime.
Each of these options had its own VOCTRL, which still exist today, e.g.
VOCTRL_FULLSCREEN, or VOCTRL_ONTOP. I tried to make all options runtime
changeable, and to unify properties with options. But I couldn't be
bothered with updating all VO drivers to listen to option changes
directly, because that would be pretty tedious. So the property code is
still all there and sends the old VOCTRLs. But of course you need to
sync up the options, which is why the run_control() code did that.

(Unrelated: VO_EVENT_FULLSCREEN_STATE is the worst shithack of them all.
Currently, only the frontend can actually write to options (for awful
reasons), so if the fullscreen state changes due to outside interaction,
the VO driver can't update the corresponding option fields. So the VO
notifies the frontend with said VO_EVENT_, and the frontend then sends
VOCTRL_GET_FULLSCREEN, and updates the global copy of the option with
the value returned by that. I still like to think the situation is not
that bad considering the monstrous effort of converting single-threaded
code that had hundreds of options in global variables to multi-threaded
code with no global variables at all.)
2019-09-19 20:37:05 +02:00
wm4 9e1945d307 win_state: silence a valgrind warning
m_geometry_apply() will read and modify the dummy variable. It's not
actually used for anything, but valgrind will still warn against
uninitialized data. I'm not sure whether this was UB, but in any case
it's annoying when running valgrind.
2019-09-19 20:37:05 +02:00
wm4 a8be8fe4f4 vd_lavc: put vaapi before vdpau in autoprobe order
--hwdec=auto-copy was preferring vdpau over vaapi. In the HEVC 10 bit
case, this also led to hardware decoding not being enabled. (Probably
because the probing can't start over after enabling hw decoding fails at
runtime, or something like that.)

Possible that this subtly breaks on some setups. You can't always win.
2019-09-19 20:37:05 +02:00
wm4 a17337910c vo_gpu: hwdec_vaegl: silence confusing message during probing
During probing on a system with AMD GPU, mpv used to output the
following messages if hardware decoding was enabled:

[ffmpeg] AVHWFramesContext: Failed to create surface: 2 (resource
allocation failed).
[ffmpeg] AVHWFramesContext: Unable to allocate a surface from internal
buffer pool.

This commit removed the message, with hopefully no other side effects.
Long explanations follow, better don't read them, it's just tedious
drivel about the details. People should learn to write concise commit
messages, not drone on and on endlessly all while they have no fucking
point.

The code probes supported hardware pixel format, and checks whether they
can be mapped as textures. av_hwdevice_get_hwframe_constraints() returns
a list of hardware pixel formats in the valid_sw_formats field (the "sw"
means software, but they're still hardware pixel formats, makes sense).
This contained the format yuv420p, even though this is not a valid
hardware format. Trying to create a surface of this type results in VA
surface creation failure, upon which FFmpeg prints the error messages
above. We'd be fine with this, except FFmpeg has a global log callback,
and there's no way to suppress these messages without creating other
issues.

It turns out that FFmpeg's vaapi implementation returns all formats from
vaQueryImageFormats() if no "hwconfig" is provided. This list includes
yuv420p, which is probably supported for surface upload/download, but
not as native format. Following FFmpeg's logic, it should not appear in
the valid_sw_formats list, because formats for transfers are returned by
another roundabout API.

Idiotically, there doesn't seem to be any vaapi call that determines
whether a format is a valid surface format. All mechanisms to do this
are bound to a VAConfigID (= video codec or video processor), all while
the actual surface creation API strangely does not take a VAConfigID (a
big WTF).

Also, calling the vaCreateSurfaces() API ourselves for probing is out of
the question, because that functions is utterly and idiotically complex.
Look at the FFmpeg code and how much effort it requires to setup a
complete set of attributes - we can't duplicate this.

So the only way left to do this is the most idiotic and tedious way:
enumerating all VAProfile (and VAEntrypoints) to create all possible
VAConfigIDs. Each of the VAConfigIDs is associated with a list of
formats, which FFmpeg can return (by passing the ID along with the
"hwconfig"), and which is probed separately.

Note that VAConfigID actually refers to a dynamic instance of something,
and creating a VAConfigID takes not only the VAProfile and the
VAEntrypoint, but also an arbitrary attribute array. In theory, this
means our attempt to get to know all possible configurations cannot
work, but in practice this attribute array seems to be pointless for
decoding and video processing, and FFmpeg doesn't use it (though the
encoding path does use it). This probably just makes it _barely_ OK to
do it this way.

Could we discard all this probing shit, and somehow do it another way?
Probably not. The EGL API for mapping surfaces doesn't even seem to
provide a way to enumerate supported formats, we may not even know
whether DRM/dmabuf interop is actually supported (AFAIR the EGL
extensions are present even if they don't work), nor do we know whether
the VAAPI driver supports this interop (not sure). So actually trying is
the only way.

Further, mpv initializes the decoder on a another thread, where you
can't just access OpenGL state. This suckage is mostly to be blamed on
OpenGL itself and its crazy thread boundedness. In theory, this could be
done anyway (see how software decoding "direct rendering" tries to get
around this). But to make it worse, the decoder never cares about the
list of supported formats determined by this code; instead,
f_autoconvert.c tries to deal with it and insert a video processor
(well, good luck with this crap, I bet it doesn't even work). So this
whole endeavor might be pointless, other than the fact that failed
probing can disable use of vaapi (which is correct and necessary). But
if you have a shovel, you don't use it to smash the flat end on the heap
of shit that's piled up before you, or do you?

While this method probably works, it's still orgasmically tedious. It
was tedious before: we had to create a real surface, create a GL
texture, map the surface with it, then destroy everything again. But the
added code is tedious on its own. Highlights include the need to malloc
a FFmpeg struct just to pass a single damn integer, the need to
enumerate "entrypoints" for each VA profile, even though all profiles
have exactly 1 entrypoint, and the kind of obnoxious way how vaapi
requires you to preallocate arrays for returned things, even they could
for example reasonably be returned as immutable arrays or have some
other simpler API.

The main grand fuckup is of course that vaapi requires a VAConfigID to
query surface properties, but not for creating surfaces. This
awkwardness even affected the FFmpeg API design, which has a "hwconfig"
concept that is only used by vaapi (vaapi is only 1 out of 10 hardware
decoding APIs supported by the FFmpeg hwcontext stuff). Maybe I'm just
missing something. It's as if vaapi required setting radioactive shit on
fire. Look how clean the native D3D11 code is instead. (Even the ANGLE
code manages to avoid being this fucked up. Or the VDPAU code, despite
supporting multiple mapping methods.)

Another only barely related change is that the valid_sw_formats field
can be NULL, and the API explicitly documents this. Technically, the mpv
code was buggy for not checking this, although until now the FFmpeg
implementation so far could not return it when we still passed NULL for
the hwconfig parameter.
2019-09-19 20:37:05 +02:00
wm4 c42a21c9fa vo_gpu: hwdec_vaegl: refactor format probing
No functional changes, just preparation for the next commit. Split the
probing into multiple functions. Prepare for the yet unused possibility
to pass AVVAAPIHWConfig to probing. try_format_pixfmt() now assumes it
can be called multiple times with the same format, so it filters the
format.

The format probing is now something like O(n^2) for n formats, but n
will most likely remain something under 50 or so.
2019-09-19 20:37:05 +02:00
wm4 fb8d240c4d vf_vapourynth: remove Lua backend
I once created this because someone wanted to use vapoursynth without
the Python dependency. No idea if anyone ever actually used it. It's
sort of icky (it calls itself "lazy" to preempt complaints about how
much it sucks), and complicates the build process. Kill it.

It seems much more promising to have something like this:

https://github.com/vapoursynth/vapoursynth/issues/386

This would either solve the build distribution problem by relaxing the
Python dependency, and/or allow a Lua backend to be included without
pain.
2019-09-19 20:37:05 +02:00
wm4 c6773692ad vo_gpu: remove vdpau/GLX backend
Useless garbage.

This was once added to test whether vdpau presentation feedback could be
used. Results were always unsatisfactory, and now vdpau is dead.
2019-09-19 20:37:05 +02:00
wm4 83d7123dc3 vo_gpu: remove mali-fbdev
Useless at this point, I don't even know if it still works, or how to
test it.
2019-09-19 20:37:05 +02:00
wm4 0b4790f23f aspect: add video margin options
Semantics a bit questionable. This is done for the OSC (next commit),
and a comment added the manpage explicitly states this. Meaning this is
probably garbage and needs to revisit when the OSC changes and/or
someone wants to use this margin feature for something else.

Not sure about the subtitle thing. It's imaginable that someone uses
these options to create empty borders for subtitles on the bottom, so
subtitles should be located there. On the other hand, this gives a
rather unpolished user experience when using the (later added) OSC
feature to not overlap with the video. There's not much of a point if
the OSC still overlaps the video. However, I'm too lazy to think about
this, so it stays like it is.
2019-09-19 20:37:05 +02:00
wm4 e1c8069b68 aspect: fix some UB problems in corner cases
--video-margin-ratio-left=0.2 --video-margin-ratio-right=0.9 (added in
the the next commit) will set f_w to inf, resulting in some garbage
being propagated. Later, the OSD margins are computed from values before
various sanity clamping is applied, which makes libass suffer from
bullshit values.

I'm very sure it's OK and more correct to compute the OSD margins using
the later values, but I'm not sure about that.
2019-09-19 20:37:05 +02:00
wm4 165799157d vd_lavc: add --hwdec-extra-frames option
Surprised this didn't exist before.
2019-09-19 20:37:05 +02:00
wm4 b9d351f02a Implement backwards playback
See manpage additions. This is a huge hack. You can bet there are shit
tons of bugs. It's literally forcing square pegs into round holes.
Hopefully, the manpage wall of text makes it clear enough that the whole
shit can easily crash and burn. (Although it shouldn't literally crash.
That would be a bug. It possibly _could_ start a fire by entering some
sort of endless loop, not a literal one, just something where it tries
to do work without making progress.)

(Some obvious bugs I simply ignored for this initial version, but
there's a number of potential bugs I can't even imagine. Normal playback
should remain completely unaffected, though.)

How this works is also described in the manpage. Basically, we demux in
reverse, then we decode in reverse, then we render in reverse.

The decoding part is the simplest: just reorder the decoder output. This
weirdly integrates with the timeline/ordered chapter code, which also
has special requirements on feeding the packets to the decoder in a
non-straightforward way (it doesn't conflict, although a bugmessmass
breaks correct slicing of segments, so EDL/ordered chapter playback is
broken in backward direction).

Backward demuxing is pretty involved. In theory, it could be much
easier: simply iterating the usual demuxer output backward. But this
just doesn't fit into our code, so there's a cthulhu nightmare of shit.
To be specific, each stream (audio, video) is reversed separately. At
least this means we can do backward playback within cached content (for
example, you could play backwards in a live stream; on that note, it
disables prefetching, which would lead to losing new live video, but
this could be avoided).

The fuckmess also meant that I didn't bother trying to support
subtitles. Subtitles are a problem because they're "sparse" streams.
They need to be "passively" demuxed: you don't try to read a subtitle
packet, you demux audio and video, and then look whether there was a
subtitle packet. This means to get subtitles for a time range, you need
to know that you demuxed video and audio over this range, which becomes
pretty messy when you demux audio and video backwards separately.

Backward display is the most weird (and potentially buggy) part. To
avoid that we need to touch a LOT of timing code, we negate all
timestamps. The basic idea is that due to the navigation, all
comparisons and subtractions of timestamps keep working, and you don't
need to touch every single of them to "reverse" them.

E.g.:

    bool before = pts_a < pts_b;

would need to be:

    bool before = forward
        ? pts_a < pts_b
        : pts_a > pts_b;

or:

    bool before = pts_a * dir < pts_b * dir;

or if you, as it's implemented now, just do this after decoding:

    pts_a *= dir;
    pts_b *= dir;

and then in the normal timing/renderer code:

    bool before = pts_a < pts_b;

Consequently, we don't need many changes in the latter code. But some
assumptions inhererently true for forward playback may have been broken
anyway. What is mainly needed is fixing places where values are passed
between positive and negative "domains". For example, seeking and
timestamp user display always uses positive timestamps. The main mess is
that it's not obvious which domain a given variable should or does use.

Well, in my tests with a single file, it suddenly started to work when I
did this. I'm honestly surprised that it did, and that I didn't have to
change a single line in the timing code past decoder (just something
minor to make external/cached text subtitles display). I committed it
immediately while avoiding thinking about it. But there really likely
are subtle problems of all sorts.

As far as I'm aware, gstreamer also supports backward playback. When I
looked at this years ago, I couldn't find a way to actually try this,
and I didn't revisit it now. Back then I also read talk slides from the
person who implemented it, and I'm not sure if and which ideas I might
have taken from it. It's possible that the timestamp reversal is
inspired by it, but I didn't check. (I think it claimed that it could
avoid large changes by changing a sign?)

VapourSynth has some sort of reverse function, which provides a backward
view on a video. The function itself is trivial to implement, as
VapourSynth aims to provide random access to video by frame numbers (so
you just request decreasing frame numbers). From what I remember, it
wasn't exactly fluid, but it worked. It's implemented by creating an
index, and seeking to the target on demand, and a bunch of caching. mpv
could use it, but it would either require using VapourSynth as demuxer
and decoder for everything, or replacing the current file every time
something is supposed to be played backwards.

FFmpeg's libavfilter has reversal filters for audio and video. These
require buffering the entire media data of the file, and don't really
fit into mpv's architecture. It could be used by playing a libavfilter
graph that also demuxes, but that's like VapourSynth but worse.
2019-09-19 20:37:04 +02:00
dudemanguy 80c4aaa2a4 wayland: fix wl_proxy leak
This one is probably not terribly obvious from just the valgrind log,
but a wayland dev explained it to me just a second ago. Whenever mpv
sends events to the screen with wl_display_dispatch, wayland internally
allocates memory to a struct wl_proxy object if a new id is found. Quite
a few more things happen to that proxy object, but eventually mpv stores
the data on the client-side in a wrapper type of struct (struct
wl_data_offer). mpv's data_device_listener keeps track of those proxies
and frees the memory when appropriate. Of course, mpv is constantly
sending events to the screen and does so until the user quits the
player. What happens here is that one final wl_display_dispatch is called
right before the user quits the player and before mpv's
data_device_listener can handle that object. So the result is that you
always have one extra dangling proxy that doesn't get properly freed.
The solution is to just simply call wl_data_offer_destroy before closing
the wl_display to free that final dangling wl_proxy.
2019-09-19 00:00:19 +03:00
Anton Kindestam e08f235578 drm: fix libmpv ABI breakage introduced in 351c083487
Extending the client-allocated mpv_opengl_drm_params struct
constituted a break of ABI that could cause UB.

Create a clean break by deprecating "drm_params" and related structs
and enum values, and replacing it with "drm_params_v2".

Also fix some comments and code that wrongly assumed that open could
return any other negative number than -1 for failure.

This commit updates the libmpv version to 1.104
2019-09-18 23:59:32 +03:00
Philip Langdale fa0a905ea0 vo_gpu: hwdec_vaapi: Refactor Vulkan and OpenGL interops for VAAPI
Like hwdec_cuda, you get a big #ifdef mess if you try and keep the
OpenGL and Vulkan interops in the same file. So, I've refactored
them into separate files in a similar way.
2019-09-15 17:51:47 -07:00
Philip Langdale 237f5fa1b7 vo_gpu: hwdec_cuda: Improve interop selection mechanism
This change updates the interop selection to match what I did for
VAAPI, by iterating through an array of init functions until one
of them works.
2019-09-15 17:51:47 -07:00
wm4 0abe34ed21 vo_gpu: x11: remove special vdpau probing, use EGL by default
Originally, vo_gpu/vo_opengl considered the case of Nvidia proprietary
drivers, which required vdpau/GLX, and Intel open source drivers, which
require vaapi/EGL. Since window creation and GPU context creation are
inseparable in mpv's internal API, it had to pick the correct API very
early, or hardware decoding wouldn't work. "x11probe" was introduced for
this reason. It created a GLX context (without showing the window yet),
and checked whether vdpau was available. If yes, it used GLX, if not, it
continued probing x11/EGL. (Obviously it couldn't always fail on GLX
without vdpau, which is why it was a separate "probe" backend.)

Years passed, and now the situation is different. Vdpau is dead. Nvidia
drivers and libavcodec now provide CUDA interop, which requires EGL, and
fixes some of the vdpau problems. AMD drivers now provide vaapi, which
generally works better than vdpau. Intel didn't change.

In particular, vaapi provides working HEVC Main10 support. In theory, it
should work on vdpau too, with quality reduction (no 10 bit surfaces),
but I couldn't get it to work.

So always prefer EGL. And suddenly hardware decoding works. This is
actually rather important, because HEVC is unfortunately on the rise,
despite shitty encoders and unoptimized decoders. The latter may mean
that hardware decoding works better than libavcodec.

This should have been done a long, long time ago.
2019-09-15 20:00:52 +03:00
wm4 6385a5fd1b vf_vavpp: disable this filter
Might be unreasonable, but I'm angry at the shit driver freezing my
machine.
2019-09-15 17:59:25 +02:00
Niklas Haas a416b3f084 vo_gpu: correctly normalize src.sig_peak
In some cases, src.sig_peak remains undefined as 0, which was definitely
the case when using the OSD, since it never got passed through the usual
color space normalization process. Most robust work-around is to simply
force the normalization at the site where it's needed. This ensures this
value is always valid and defined, to make the peak-dependent logic in
these two functions always work.

Fixes 4b25ec3a9d
Fixes #6917
Fixes #6918
2019-09-15 01:33:27 +02:00
sfan5 ee0f4444f9 image_writer: add webp-compression option 2019-09-14 23:02:39 +02:00
sfan5 0f79444c6d image_writer: add WebP support (lossy or lossless) 2019-09-14 23:02:39 +02:00
sfan5 8925f10962 image_writer: move convert_image() to player/screenshot.c 2019-09-14 23:02:39 +02:00
sfan5 5c313f1f59 vo: add warning message to vo_vaapi and vo_vdpau
These are a common source of bug reports, due to misconceptions that
they are required to make use of hardware decoding.
2019-09-14 13:50:10 +02:00
Hui Jin fda45f4537 vo_d3d11/context: fix crash due to ctx->ra is null pointer access
'ctx->ra' is null pointer when d3d11 init failed before call 'ra_d3d11_create' in 'd3d11_init'.
2019-09-14 21:35:49 +10:00
Hui Jin 191737b9c9 vo_d3d11/hwdec_dxva2dxgi: fix memory leak that 'ctx11' be not release
'ctx11' be not release when d3d11 hwdec be uninit with 'mapper_uninit' method.
2019-09-14 21:35:49 +10:00
wm4 10a1b98082 vo_gpu: x11egl: support Mesa OML sync extension
Mesa supports the EGL_CHROMIUM_sync_control extension, and it's
available out of the box with AMD drivers. In practice, this is exactly
the same as GLX_OML_sync_control, but for EGL. The extension
specification is separate from the GLX one though, and buried somewhere
in the Chromium code.

This appears to work, although I don't know if it really works.

In theory, this could be useful for other EGL targets. Support code for
it could have been added to egl_helpers.c to avoid some minor duplicated
glue code if another EGL target were to provide this extension. I didn't
bother with that. ANGLE on Windows can't support it, because the
extension spec. explicitly requires POSIX timers. ANGLE on Linux/OSX is
actively harmful for mpv and hopefully won't ever use it. Wayland uses
EGL, but has its own fancy presentation feedback stuff (and besides, I
don't think basic video player functionality works on Wayland at all).
context_drm_egl maybe? But I think DRM has its own stuff.
2019-09-08 23:23:43 +10:00
wm4 8d7960f6ef vo_gpu: glx: move OML sync code to an independent file
So the next commit can make EGL use it. EGL has a quite similar
function, that practically works the same. Although it's relatively
trivial, it's still tricky, and probably shouldn't end up as duplicated
code.

There are no functional changes, except initialization, and how failure
of the glXGetSyncValues call is handled. Also, some comments mention the
EGL extension.

Note that there's no intention for this code to handle anything else
than the very specific OML sync extension (and its EGL equivalent). This
is just too weirdly specific to the weird idiosyncrasies of the
extension, and it makes no sense to extend it to handle anything else.
(Such as Wayland or DXGI presentation feedback.)
2019-09-08 23:23:43 +10:00
Niklas Haas 4b25ec3a9d vo/gpu: fix check on src/dst peak mismatch
In the past, src peak was always equal to or higher than dst peak. But
since `--target-peak` got introduced, this could no longer be the case.
This leads to an incorrect result (scaling for peak mismatch in gamma
light) unless some other option (CMS, --linear-scaling, etc.) forces the
linearization.

Fixes #6533
2019-09-05 19:13:44 +03:00
der richter c8a911f35f cocoa-cb: remove an unused variable 2019-09-02 00:39:36 +03:00
Philip Langdale b539eb222b vo/gpu: vulkan: Pass the device name option through to libplacebo
We collect a 'vulkan-device' option today but then don't actually
pass it on, so it's useless. Once that's fixed, it can be used
to select a specific vulkan device by name.

Tested with the new nvidia offload feature to select between the
nvidia and intel GPUs.
2019-08-24 18:38:27 +02:00
James Ross-Gowan 80552ab28e vo_gpu: d3d11: fix storage lifetime of compound literals
Somehow I got the idea that compound literals had function-scoped
lifetime. Instead, like all other objects with automatic storage
duration, compound literals are block-scoped, so they become invalid
after exiting the block they were declared in. It seems like a recent
change to GCC actually reuses the memory that the compound literals
used to occupy, which was causing a few bugs.

The pattern of conditionally assigning a pointer to a compound literal
was used in a few places in ra_d3d11 where the Direct3D API expects
either a pointer to an initialised struct or NULL. Change these to
ensure the lifetime of the struct includes the API call.

Should fix #6775.
2019-08-20 18:12:21 +10:00
wnoun ae8cb39ab2 vo_gpu: fix taking screenshots of rotated videos 2019-08-14 21:54:14 +02:00
Philip Langdale 639ee55df7 vo_gpu: hwdec_vaapi: Synchronise after exporting VA surface
This is documented as required (although we did not do it in
the old GL codepath, with no visible problems) and I have seen
transient artifacts after seeking which _appear_ to have gone
away after introducing this.
2019-08-07 10:51:43 +02:00
der richter a8c2e29868 cocoa-cb: migrate to swift 5 with swift 4 fallback
this migrates our current swift code to version 5 and 4. building is
support from 10.12.6 and xcode 9.1 onwards.

dynamic linking is the new default, since Apple removed static libs
from their new toolchains and it's the recommended way.

additionally the found macOS SDK version is printed since it's an
important information for finding possible errors now.

Fixes #6470
2019-07-21 18:13:07 +03:00
der richter 0602f082cb cocoa-cb: fix optional cases on macOS 10.12 2019-07-21 18:13:07 +03:00
der richter c540ac8485 cocoa-cb: conditional compilation for Dark Mode and Material features
Fixes #6621
2019-07-21 18:13:07 +03:00
Philip Langdale b5b0350371 vo_gpu: hwdec_vaapi: Count planes rather than layers in Vulkan interop
We saw a segfault when trying to use the intel-media-driver (iHD)
rather than the normal intel va driver. This happened because the
iHD driver reports P010 (and maybe other formats) with multiple
layers to represent the interleaved UV plane. The normal va driver
reports one UV layer to match the plane.

This threw off my logic which assumed that the number of layers
could not exceed the number of planes.

There's a way one could fix this in a fully generalised form, but
I'm just going to do what the EGL path does and assume that:
 * Layer 'n' is on Plane 'n' for n < total number of planes
 * These layers always start at offset 0 on the plane

You can imagine ways that these assumptions are violated, but at
least the failure will look the same for both EGL and Vulkan
paths.
2019-07-08 01:57:02 +02:00
Philip Langdale b33ced193e vo_gpu: hwdec_vaapi: Suppress format errors when probing
Today, we normally see a format error when probing because yuyv422
cannot be used, but it's in the normal set of probed formats.

This error is distracting and confusing, so only log probing errors
at the VERBOSE level.

Fixes #6411
2019-07-08 01:57:02 +02:00
Philip Langdale b70ed35ba4 vo_gpu: hwdec_vaapi: Add Vulkan interop
This change introduces a vulkan interop path for the vaapi hwdec.
The basic principles are mostly the same as for EGL, with the
exported dma_buf being imported by Vukan. The biggest difference
is that we cannot reuse the texture as we do with OpenGL - there's
no way to rebind a VkImage to a different piece of memory, as far
as I can see. So, a new texture is created on each map call.

I did not bother implementing a code path for the old libva API as
I think it's safe to assume any system with a working vulkan driver
will have access to a newer libva.

Note that we are using separate layers for the vaapi surface, just
as is done for EGL. This is because libplacebo doesn't support
multiplane images.

This change does not include format negotiation because no driver
implements the vk_ext_image_drm_format_modifier extension that
would be required to do that. In practice, the two formats we care
about (nv12, p010) work correctly, so we are not blocked. A separate
change had to be made in libplacebo to filter out non-fatal validation
errors related to surface sizes due to the lack of format negotiation.
2019-07-08 01:57:02 +02:00
Philip Langdale 6842755feb vo_gpu: hwdec_vaegl: Rename and move to hwdec_vaapi
In preparation for adding Vulkan interop support, let's rename
to remove the egl reference and move to an api neutral location.
2019-07-08 01:57:02 +02:00
Chainik 7f0f1a1b72 vf_vapoursynth: allow multithreaded writing of source frames 2019-07-08 01:53:22 +02:00
Chainik 5907bc023c vf_vapoursynth: allow multithreaded reading of returned frames 2019-07-08 01:53:22 +02:00
Philip Langdale 1638fa7b46 vo/gpu: hwdec_vdpau: Support direct mode for 4:4:4 content
New releases of VDPAU support decoding 4:4:4 content, and that comes
back as NV24 when using 'direct mode' in OpenGL Interop. That means we
need to be a little bit smarter about how we set up the OpenGL
textures.
2019-07-08 01:11:27 +02:00
Michael Forney 13e14d95e1 opengl/context_wayland: Fix crash on configure before initial reconfig
If the compositor sends a configure event before the surface is initially
mapped, resize gets called before the egl_window gets created, resulting
in a crash in wl_egl_window_resize.

This was fixed back in 618361c697, but was reintroduced when the wayland
code was rewritten in 68f9ee7e0b.
2019-07-08 01:00:01 +02:00
Philip Langdale e2976e662d video/out/gpu: Add a `storable` flag to ra_format
While `ra` supports the concept of a texture as a storage
destination, it does not support the concept of a texture format
being usable for a storage texture. This can lead to us attempting
to create a texture from an incompatible format, with undefined
results.

So, let's introduce an explicit format flag for storage and use
it. In `ra_pl` we can simply reflect the `storable` flag. For
GL and D3D, we'll need to write some new code to do the compatibility
checks. I'm not going to do it here because it's not a regression;
we were already implicitly assuming all formats were storable.

Fixes #6657
2019-07-08 00:59:28 +02:00