Involve detection of software renderers in the probing properly. Other
VOs could handle probing also more gracefully, and e.g. produce less
noise if an API is unavailable. (Although other than the OpenGL VOs,
only vo_wayland will.)
Now the "sw" suboption for vo_opengl[_old] is strictly speaking not
needed anymore. Doing "--vo=opengl" disables the probing logic, and will
always force it, if possible.
Includes some simplifications as well.
Because of the icc-profile-auto option (which was added at a later
point), supporting this would probably be slightly messy: the ICC
profile can spontaneously update, and then it would overwrite the
previously set options.
Don't make icc-profile-auto fatal if unsupported. The "auto" indicates
that it will use whatever it finds, even if it's nothing.
Also add a warning; before this commit, it just refused to initialize
without explanation.
As a mostly unrelated cosmetic change, remove redundant parameters which
had no point anymore.
Probably fixes#1359 (or rather works it around by disallowing it).
Obscure feature, and I've never heard of anyone using it.
The anaglyph effects can be reproduced with vf_stereo3d. The only thing
that can't be reproduced with it is "quadbuffer", which requires special
and expensive hardware.
This adds API to libmpv that lets host applications use the mpv opengl
renderer. This is a more flexible (and possibly more portable) option to
foreign window embedding (via --wid).
This assumes that methods like context sharing and multithreaded OpenGL
rendering are infeasible, and that a way is needed to integrate it with
an application that uses a single thread to render everything.
Add an example that does this with QtQuick/qml. The example is
relatively lazy, but still shows how relatively simple the integration
is. The FBO indirection could probably be avoided, but would require
more work (and would probably lead to worse QtQuick integration, because
it would have to ignore transformations like rotation).
Because this makes mpv directly use the host application's OpenGL
context, there is no platform specific code involved in mpv, except
for hw decoding interop.
main.qml is derived from some Qt example.
The following things are still missing:
- a way to do better video timing
- expose GL renderer options, allow changing them at runtime
- support for color equalizer controls
- support for screenshots
This wasn't done before because there was no advantage in "abstracting"
it. This changed, and putting this into its own files is better than
messing it into gl_common.c/h.
Same as with the previous commits.
In theory, vdpau/x11 GL interop doesn't assume GLX. It could use EGL as
well. But since it's always GLX in practice, so we're fine with this.
Remove the gl_hwdec.mpgl field - it's unused now.
Basically, don't access the vo field.
There's also no reason anymore to access MPGLContext. We still need to
access loaded GL functions though, so add a field for that to gl_hwdec.
Untested.
Always set the viewport on entry. The way the viewport is tracked is a
bit complicated in my opinion, and in fact it doesn't even reduce the
number of GL calls. Setting it on entry is actually redundant if video
covers the screen fully, because the handle_pass() unconditionally sets
it anyway, but avoiding it would complicate the cases gl->Clear() is
actually needed.
Add a fbo argument to gl_video_render_frame(). This allows you to render
into a FBO rather than the default framebuffer. It will be useful for
providing an API to render on an external GL context. (If that will
actually be added.)
Always create the context in mpgl_init(), instead of doing it when
mpgl_config_window() is called the first time. This is a small step
towards cleaning up the GL backend interface, and adding other things
like perhaps GLES support, or a callback-driven backend for libmpv.
This silences the warning:
video/out/gl_video.c:1091:51: runtime error: division by zero
when running with clang -fsanitize=undefined. Division by zero is legal
according to IEEE, but I guess clang doesn't care about standard. While
triggering this warning isn't actually avoided in all cases, it's
avoided in the common case and also makes people shut up about it.
Add a generic mechanism to the VO to relay "extra" events from VO to
player. Use it to notify the core of window resizes, which in turn will
be used to mark all affected properties ("window-scale" in this case) as
changed.
(I refrained from hacking this as internal command into input_ctx, or to
poll the state change, etc. - but in the end, maybe it would be best to
actually pass the client API context directly to the places where events
can happen.)
After removing synchronous libdispatch calls, this looks like it doesn't
deadlock anymore. I also experimented with pthread_mutex_trylock liek wm4
suggested, but it leads to some annoying black flickering. I will fallback to
that only if some new deadlocks are discovered.
Unfortunately using dispatch_sync for synchronization turned out to be really
bad for us. It caused a wide array of race conditions, deadlocks, etc.
Moving to a very simple mutex. It's not clear to me how to do liveresizing
with this, for now it just flickers with is unacceptable (maybe I'll draw
black instead).
This should fix all the threading cocoa bugs. Reopen if it's not the case!
Fixes#751Fixes#1129
bstr.c doesn't really deserve its own directory, and compat had just
a few files, most of which may as well be in osdep. There isn't really
any justification for these extra directories, so get rid of them.
The compat/libav.h was empty - just delete it. We changed our approach
to API compatibility, and will likely not need it anymore.
This uses glXGetVideoSyncSGI() to check how many vsyncs happened since
the last flip_page() call. It allows checking a pattern of vsync
increments of at most 2 elements. For example, to check ~24 fps playback
on a ~60 Hz monitor, this can be used:
--vo=opengl:check-pattern=[3-2]:waitvsync
Whether the reported results are accurate or just plain wrong may depend
on the driver and if the waitvsync sub-option is used. There are no
guarantees.
This option is undocumented, and may be removed again in the near or
distant future.
I'm not sure about the merit, though it does print nice numbers if debug
output is enabled.
Basically, this tries to achieve similar results as the glFinish()
business, but again it entirely depends on the drivers whether this
does anything meaningful, or whether it's actively harmful.
It seems that at least on nvidia systems with composting disabled, we
can get it to block deterministically on the actual vsync event, which
should improve framedropping.
The VO is run inside its own thread. It also does most of video timing.
The playloop hands the image data and a realtime timestamp to the VO,
and the VO does the rest.
In particular, this allows the playloop to do other things, instead of
blocking for video redraw. But if anything accesses the VO during video
timing, it will block.
This also fixes vo_sdl.c event handling; but that is only a side-effect,
since reimplementing the broken way would require more effort.
Also drop --softsleep. In theory, this option helps if the kernel's
sleeping mechanism is too inaccurate for video timing. In practice, I
haven't ever encountered a situation where it helps, and it just burns
CPU cycles. On the other hand it's probably actively harmful, because
it prevents the libavcodec decoder threads from doing real work.
Side note:
Originally, I intended that multiple frames can be queued to the VO. But
this is not done, due to problems with OSD and other certain features.
OSD in particular is simply designed in a way that it can be neither
timed nor copied, so you do have to render it into the video frame
before you can draw the next frame. (Subtitles have no such restriction.
sd_lavc was even updated to fix this.) It seems the right solution to
queuing multiple VO frames is rendering on VO-backed framebuffers, like
vo_vdpau.c does. This requires VO driver support, and is out of scope
of this commit.
As consequence, the VO has a queue size of 1. The existing video queue
is just needed to compute frame duration, and will be moved out in the
next commit.
OSD used to be not thread-safe at all, so a track was used to get it
redrawn. This mostly reverts commit 6a2a8880, because OSD not being
thread-safe was the non-trivial part of it.
Mostly untested, because this code path is used on OSX only, and I don't
have OSX.
Let the VOs draw the OSD on their own, instead of making OSD drawing a
separate VO driver call. Further, let it be the VOs responsibility to
request subtitles with the correct PTS. We also basically allow the VO
to request OSD/subtitles at any time.
OSX changes untested.
This turned out much more complicated than I thought. It's not just a
matter of adjusting the texture coordinates, but you also have to
consider separated scaling and panscan clipping, which make everything
complicated.
This actually still doesn't clip 100% correctly, but the bug is only
visible when rotating (or flipping with --vf=flip), and using something
like --video-pan-x/y at the same time.
This commit adds support for automatic selection of color profiles based on
the display where mpv is initialized, and automatically changes the color
profile when display is changed or the profile itself is changed from
System Preferences.
@UliZappe was responsible with the testing and implementation of a lot of this
commit, including the original implementation of `cocoa_get_icc_profile_path`
(See #594).
Fixes#594
Reduce most dependencies on struct mp_csp_details, which was a bad first
attempt at dealing with colorspace stuff. Instead, consistently use
mp_image_params.
Code which retrieves colorspace matrices from csputils.c still uses this
type, though.
Always pass around mp_log contexts in the option parser code. This of
course affects all users of this API as well.
In stream.c, pass a mp_null_log, because we can't do it properly yet.
This will be fixed later.
Since m_option.h and options.h are extremely often included, a lot of
files have to be changed.
Moving path.c/h to options/ is a bit questionable, but since this is
mainly about access to config files (which are also handled in
options/), it's probably ok.
The --flip option flipped the image upside-down, by trying to use VO
support, or if not available, by inserting a video filter. I'm not sure
why it existed. Maybe it was important in ancient times when VfW based
decoders output an image this way (but even then, flipping an image is a
free operation by negating the stride).
One nice thing about this is that it provided a possible path for
implementing video orientation, which is a feature we should probably
support eventually. The important part is that it would be for free for
VOs that support it, and would work even with hardware decoding.
But for now get rid of it. It's useless, trivial, stands in the way, and
supporting video orientation would require solving other problems first.
This allows vo_opengl to use GL_TEXTURE_RECTANGLE textures, either by
enabling it with the 'rectangle-textures' sub-option, or by having a
hwdec backend force it. By default it's off.
The _only_ reason we're adding this is because VDA can export rectangle
textures only.
This means most code accessing this struct must now include hwdec.h
instead of dec_video.h. I just put it into dec_video.h at first because
I thought a separate file would be a waste, but it's more proper to do
it this way, as there are too many files which include dec_video.h only
to get the mp_hwdec_info definition.
This initialized only the load_api and load_api_ctx fields, and left the
other fields as they were. This failed with vf_vavpp, which assumed all
fields are initialized.
Most hardware decoding APIs provide some OpenGL interop. This allows
using vo_opengl, without having to read the video data back from GPU.
This requires adding a backend for each hardware decoding API. (Each
backend is an entry in gl_hwdec_vaglx[].) The backends expose video data
as a set of OpenGL textures.
Add infrastructure to support this. The next commit will add support for
VA-API.
Keep track of the default values directly, instead of creating a new
instance of the option struct just to get the defaults.
Also get rid of the special handling of m_obj_desc.init_options.
Instead, handle it purely by the option parser. Originally, I wanted to
handle --vo=opengl-hq and --vo=direct3d_shaders with this (by making
them aliases to the real VOs with a different preset), but since --vo
=opengl-hq=help prints the wrong values (as consequence of the
simplification), I'm not doing that, and instead use something
different.
Improves display of images and video with alpha channel, especially if
the transparent regions contain (supposed to be invisible) garbage
color values.
Until now, video output levels (obscure feature, like using TV screens
that require RGB output in limited range, similar to YUY) still required
handling of VOCTRL_SET_YUV_COLORSPACE. Simplify this, and use the new
mp_image_params code. This gets rid of some code. VOCTRL_SET_YUV_COLORSPACE
is not needed at all anymore in VOs that use the reconfig callback. The
result of VOCTRL_GET_YUV_COLORSPACE is now used only used for the
colormatrix related properties (basically, for display on OSD). For
other VOs, VOCTRL_SET_YUV_COLORSPACE will be sent only once after config
instead of twice.
Change how m_config is initialized. Make it more uniform; now all
m_config structs are intialized in exactly the same way. Make sure
there's only a single m_option[] array defining the options, and keep
around the pointer to the optstruct default value, and the optstruct
size as well. This will allow reconstructing the option default values
in the following commit.
In particular, stop pretending that the handling of some special options
(like --profile, --v, and some others) is in any way elegant, and make
them explicit hacks. This is really more readable and easier to
understand than what was before, and simplifies the code.
Nothing should change from user perspective.
mpv --vo=opengl:help now works.
Remove the vo_opengl inline help text. The new code can list option
names for you, but that's it. Refer to the manpage if you have trouble.
The filter chain and the video ouputs have config() functions. They are
strictly limited to transfering the video size and format. Other
parameters (like color levels) have to be transferred separately.
Improve upon this by introducing a separate set of reconfig() functions,
which use mp_image_params to carry format parameters. This struct
contains all image format related parameters from config(), plus
additional parameters such as colorspace.
Change vf_rotate to use it, as well as vo_opengl. vf_rotate is just
an example/test case, but vo_opengl will need it later.
The intention is also to get rid of VOCTRL_SET_YUV_COLORSPACE. This
information is now handed to the VOs via reconfig(). The getter,
VOCTRL_GET_YUV_COLORSPACE, will still be needed though.
There's no point duplicating all the text that is already in the man
pages, and synchronizing them is a pain. Place a link to the github
generated pages instead.
Unfortunately, the anchor '#vo-opengl' does not work. Maybe github's
rst converter just sucks, as the actually generated HTML contains
links using that anchor too, but does not generate the anchor itself.
Too bad.
Instead of having separate callbacks for each backend-handled feature
(like MPGLContext.fullscreen, MPGLContext.border, etc.), pass the
VOCTRL responsible for this directly to the backend. This allows
removing a bunch of callbacks, that currently must be set even for
optional/lesser features (like VOCTRL_BORDER).
This requires changes to all VOs using gl_common, as well as all
backends that support gl_common.
Also introduce VOCTRL_CHECK_EVENTS. vo.check_events is now optional.
VO backends can use VOCTRL_CHECK_EVENTS instead to implementing
check_events. This has the advantage that the event handling code in
VOs doesn't have to be duplicated if vo_control() is used.
This commit is a followup on the previous one and uses a solution I like more
since it totally decouples the Cocoa code from mpv's core and tries to emulate
a generic Cocoa application's lifecycle as much as possible without fighting
the framework.
mpv's main is executed in a pthread while the main thread runs the native cocoa
event loop.
All of the thread safety is mainly accomplished with additional logic in
cocoa_common as to not increase complexity on the crossplatform parts of the
code.
To simplify things, we just assume that all OpenGL calls as well as
all calls into gl_video must be locked. Currently, also assume that
anything GUI related must be locked as well (stuff like VOCTRL_BORDER).
In its current state, this commit does nothing, but it will allow us to
move the Cocoa GUI out of the playloop, as well as possibly implementing
better framedropping.
Allows playing video with alpha information on X11, as long as the video
contains alpha and the window manager does compositing. See vo.rst.
Whether a window can be transparent is decided by the choice of the X
Visual used for window creation. Unfortunately, there's no direct way to
request such a Visual through the GLX or the X API, and use of the
XRender extension is required to find out whether a Visual implies a
framebuffer with alpha used by XRender (see for example [1]). Instead of
depending on the XRender wrapper library (which would require annoying
configure checks, even though XRender is virtually always supported),
use a simple heuristics to find out whether a Visual has alpha. Since
getting it wrong just means an optional feature will not work as
expected, we consider this ok.
[1] http://stackoverflow.com/questions/4052940/how-to-make-an-opengl-rendering-context-with-transparent-background/9215724#9215724
gl_video.c contains all rendering code, gl_lcms.c the .icc loader and
creation of 3D LUT (and all LittleCMS specific code). vo_opengl.c is
reduced to interfacing between the various parts.
Do this instead of stuffing all x11/cocoa/win32/wayland specific code
into gl_common.c. The cocoa specific parts could probably go directly
into cocoa_common.m, possibly same with wayland.
Also redo how the list of backends is managed. Get rid of the GLTYPE_
constants. Instead of having a big switch() on GLTYPE_, each backend
entry has a function pointer to setup the MPGLContext callback (e.g.
mpgl_set_backend_x11()).
Latest nvidia drivers ignore the application setting, so this switch
makes even less sense than before. It's still possible to control this
with VO specific suboptions.
Separate the video output options from the big MPOpts structure and also only
pass the new mp_vo_opts structure to the vo backend.
Move video_driver_list into mp_vo_opts
Removes almost every global variabel in vo.h and puts them in a special struct
in MPOpts for video output related options.
Also we completly remove the options/globals pts and refresh rate because
they were unused.
This was done so because the X11 code had a hard to track down issue
with some window managers, and caused the VO window to be placed
incorrectly. This was fixed in the previous commit. Consequently, we can
remove this bad hack.
It was once used for vo_sdl (the old one based on SDL 1.2), since SDL
apparently lost the GL state when switching to fullscreen. The new
vo_sdl (using SDL 1.3) doesn't use or need this. It's dead code, so
get rid of it.
VFCAP_OSD was used to determine at runtime whether the VO supports OSD
rendering. This was mostly unused. vo_direct3d had an option to disable
OSD (was supposed to allow to force auto-insertion of vf_ass, but we
removed that anyway). vo_opengl_old could disable OSD rendering when a
very old OpenGL version was detected, and had an option to explicitly
disable it as well.
Remove VFCAP_OSD from everything (and some associated logic). Now the
vo_driver.draw_osd callback can be set to NULL to indicate missing OSD
support (important so that vo_null etc. don't single-step on OSD
redraw), and if OSD support depends on runtime support, the VO's
draw_osd should just do nothing if OSD is not available.
Also, do not access vo->want_redraw directly. Change the want_redraw
reset logic for this purpose, too. (Probably unneeded, vo_flip_page
resets it already.)
All wayland only specific routines are placed in wayland_common.
This makes it easier to write other video outputs.
The EGL specific parts, as well as opengl context creation, are in gl_common.
This backend works for:
* opengl-old
* opengl
* opengl-hq
To use it just specify the opengl backend
--vo=opengl:backend=wayland
or disable the x11 build.
Don't forget to set EGL_PLATFORM to wayland.
Co-Author: Scott Moreau
(Sorry I lost the old commit history due to the file structure changes)
create_window is really bad naming, because this function can be called
multiple times, while the name implies that it always creates a new
window. At least the name config_window is not actively misleading.
Dithering was disabled if the input bit depth was not larger than the
output bit depth of the screen framebuffer. But since scaling, RGB
conversion, and other filters change the number of significant bits
anyway, dithering could still benefit image quality even in these
cases. Always do dithering, unless dithering is completely disabled.
The original intention of this mechanism was not to change the image
needlessly when playing video that matches the native bit depth of the
screen.
This also means the option is verified on program start, not when the VO
is created. The actual code becomes a bit more complex, because the
screen width/height is not available at program start.
The actual parsing code is still the same, with its unusual sscanf()
usage.
Remove the strange things the old mp_image_setfmt() code did to the
image format parameters. This includes setting chroma shift to 31 for
gray (Y8) formats and more.
Y8 + vo_opengl_old didn't actually work for unknown reasons (regression
in this branch). Fix this. The difference is that Y8 is now interpreted
as gray RGB (LUMINANCE texture) instead of involving YUV (and levels)
conversion.
Get rid of distinguishing RGB and BGR. There wasn't really any good
reason for this.
Remove mp_get_chroma_shift() and IMGFMT_IS_YUVP16*(). mp_imgfmt_desc
gives the same information and more.
mplayer's video chain traditionally used FourCCs for pixel formats. For
example, it used IMGFMT_YV12 for 4:2:0 YUV, which was defined to the
string 'YV12' interpreted as unsigned int. Additionally, it used to
encode information into the numeric values of some formats. The RGB
formats had their bit depth and endian encoded into the least
significant byte. Extended planar formats (420P10 etc.) had chroma
shift, endian, and component bit depth encoded. (This has been removed
in recent commits.)
Replace the FourCC mess with a simple enum. Remove all the redundant
formats like YV12/I420/IYUV. Replace some image format names by
something more intuitive, most importantly IMGFMT_YV12 -> IMGFMT_420P.
Add img_fourcc.h, which contains the old IDs for code that actually uses
FourCCs. Change the way demuxers, that output raw video, identify the
video format: they set either MP_FOURCC_RAWVIDEO or MP_FOURCC_IMGFMT to
request the rawvideo decoder, and sh_video->imgfmt specifies the pixel
format. Like the previous hack, this is supposed to avoid the need for
a complete codecs.cfg entry per format, or other lookup tables. (Note
that the RGB raw video FourCCs mostly rely on ffmpeg's mappings for NUT
raw video, but this is still considered better than adding a raw video
decoder - even if trivial, it would be full of annoying lookup tables.)
The TV code has not been tested.
Some corrective changes regarding endian and other image format flags
creep in.
Remove mp_image.width/height. The w/h members are the ones to use.
width/height were used internally by vf_get_image(), and sometimes for
other purposes.
Remove some image flags, most of which are now useless or completely
unused. This includes VFCAP_ACCEPT_STRIDE: the vf_expand insertion in
vf.c does nothing.
Remove some other unused mp_image fields.
Some rather messy changes in vo_opengl[_old] to get rid of legacy
mp_image flags and fields. This is left from when vo_gl supported DR.
Setting the size of a mp_image must be done with mp_image_set_size()
now. Do this to guarantee that the redundant fields (like chroma_width)
are updated consistently. Replacing the redundant fields by function
calls would probably be better, but there are too many uses of them,
and is a bit less convenient.
Most code actually called mp_image_setfmt(), which did this as well.
This commit just makes things a bit more explicit.
Warning: the video filter chain still sets up mp_images manually,
and vf_get_image() is not updated.
Slices allowed filtering or drawing video in horizontal bands or
blocks. This allowed working on the video in smaller units. In theory,
this could bring a performance win by lowering cache pressure, as you
didn't have to keep the whole video frame in cache while filtering,
only the slice.
In practice, the slice code path was barely used for the following
reasons:
- Multithreaded decoding with ffmpeg didn't use slices. The ffmpeg
slice callback was disabled, because it can be called from another
thread, and the mplayer video chain is not thread-safe.
- There was nothing that would turn "full" images into appropriate
slices, so slices were rarely used.
- Most filters didn't actually support slices.
On the other hand, supporting slices lead to code duplication and more
complex code in general. I made some experiments and didn't find any
actual measurable performance improvements when using slices. Even
ffmpeg removed slices based filtering from libavfilter in favor of
simpler code.
The most broken thing about the slices code path is that slices can't
be queued, like it is done for images in vo.c.
Remove VOCTRL_DRAW_IMAGE and always set vo_driver.draw_image in VOs.
Make draw_image mandatory: change some VOs (like vo_x11) to support it,
and remove the image-to-slices fallback in vf_vo.
Remove vo_driver.is_new. This member indicated whether draw_image is
supported unconditionally, which is now always the case.
draw_image_pts is a hack until the video filter chain is changed to
include the PTS as field in mp_image. Then vo_vdpau and vo_lavc will
be changed to use draw_image.
Change from gamma 2.2 to the slightly more precise 1/0.45 as per BT.709.
https://www.itu.int/rec/R-REC-BT.709-5-200204-I/en mentions a value of
γ=0.45 for the conceptual non-linear precorrection of video signals.
This is approximately the inverse of 2.22, and not 2.20 as the code had
been using until now.
This wasn't actually used since the old gray-alpha OSD rendering has
been removed. Removing the documentation for the vo_opengl_old osdcolor
suboption was forgotten as well.
The -zoom option enabled scaling with vo_x11. Remove the -zoom option,
and make its behavior default. Since vo_x11 has to use libswscale for
colorspace conversion anyway, which doesn't do actual extra scaling when
vo_x11 is run in windowed mode, there should be no speed difference with
this change.
The code removed from vf_scale attempted to scale the video to d_width/
d_height, which matters for anamorphic video and the --xy option only.
vo_x11 can handle these natively. The only case for which the removed
vf_scale code could matter is encoding with vo_lavc, but since that
didn't set VOFLAG_SWSCALE, nothing actually changes.
Finish renaming directories and moving files. Adjust all include
statements to make the previous commit compile.
The two commits are separate, because git is bad at tracking renames
and content changes at the same time.
Also take this as an opportunity to remove the separation between
"common" and "mplayer" sources in the Makefile. ("common" used to be
shared between mplayer and mencoder.)
Tis drops the silly lib prefixes, and attempts to organize the tree in
a more logical way. Make the top-level directory less cluttered as
well.
Renames the following directories:
libaf -> audio/filter
libao2 -> audio/out
libvo -> video/out
libmpdemux -> demux
Split libmpcodecs:
vf* -> video/filter
vd*, dec_video.* -> video/decode
mp_image*, img_format*, ... -> video/
ad*, dec_audio.* -> audio/decode
libaf/format.* is moved to audio/ - this is similar to how mp_image.*
is located in video/.
Move most top-level .c/.h files to core. (talloc.c/.h is left on top-
level, because it's external.) Park some of the more annoying files
in compat/. Some of these are relicts from the time mplayer used
ffmpeg internals.
sub/ is not split, because it's too much of a mess (subtitle code is
mixed with OSD display and rendering).
Maybe the organization of core is not ideal: it mixes playback core
(like mplayer.c) and utility helpers (like bstr.c/h). Should the need
arise, the playback core will be moved somewhere else, while core
contains all helper and common code.