Compare commits

..
1167 Commits
Author SHA1 Message Date
Martin Herkt 10a005df0c Release 0.23.0 2016-12-25 14:12:38 +01:00
Martin Herkt b3d670a3e1 Merge branch 'master' into release/current 2016-12-25 13:28:05 +01:00
wm4 1c761bd6f5 options: deprecate some other complex --ad/--vd features
Who even needs those?

Once these deprecations are gone, --ad/--vd are simple lists without any
kind of complex matching.
2016-12-23 18:18:17 +01:00
wm4 1d5e95783e options: explicitly deprecate --ad-spdif-dtshd
Has been less formally deprecated for a longer time.
2016-12-23 18:12:54 +01:00
wm4 9d21f2503f options: deprecate codec family selection in --vd/--ad
Useless now, so get rid of it. Also affects some user-visible display
things (like reported codec in use).
2016-12-23 18:12:29 +01:00
wm4 c560f6ff0a audio: change how spdif codecs are selected
Remove ad_spdif from the normal codec list, and select it explicitly.

One goal was to decouple this from the normal codec selection, so
they're less entangled and the decoder selection code can be simplified
in the far future. This means spdif codec selection is now done
explicitly via select_spdif_codec(). We can also remove the weird
requirements on "dts" and "dts-hd" for the --audio-spdif option, and it
can just do the right thing.

Now both video and audio codecs consist of a single codec family each,
vd_lavc and ad_lavc.
2016-12-23 18:10:07 +01:00
wm4 17d6ba7f77 vd_lavc: use AVFrame fields directly instead of AVCodecContext
Conceptually cleaner, although the API claims this is equivalent.

Originally, AVCodecContext fields were used, because not all supported
libavcodec/libavutil versions had the AVFrame fields.

This is not done for chroma_sample_location - it has no AVFrame field.
2016-12-22 18:40:32 +01:00
wm4 b1c0bbe8b8 video: use demuxer-signaled duration for last video frame
Helps with gif, probably does unwanted things with other formats.

This doesn't handle --end quite correctly, but this could be added
later.

Fixes #3924.
2016-12-21 18:18:24 +01:00
Dario Russo 1ba3525816 Fix mistakes in spelling and grammar 2016-12-21 17:47:57 +01:00
wm4 99a4be4127 demux_mkv: trust keyframe flags for TrueHD
TrueHD is a fucked up audio codec with extremely small frame sizes. Some
of these frames start with full headers, which are usually marked as
keyframes, and from which decoding can be started (or at least that's
what you'd expect).

So for such tracks we should probably trust the keyframe flags. Doesn't
really improve seek behavior, though.
2016-12-20 14:28:29 +01:00
wm4 3b5777d86a demux_mkv: fix seeking in some broken files
Some files have audio tracks with packets that do not have a keyframe
flag set at all. I don't think there's any audio codec which actually
needs keyframe flags, so always assume an audio packet is a keyframe
(which, in Matroska terminology, means it can start decoding from that
packet).

The file in question had these set:

| + Multiplexing application: Lavf57.56.100 at 313
| + Writing application: Lavf57.56.100 at 329

Garbage produced by garbage...

There are other such files produced by mkvmerge, though. It's not
perfectly sure whether these have been produced by FFmpeg as well
(mkvmerge often trusts the information in the source file, even if it's
wrong - so other samples could have been remuxed from FFmpeg).

Fixes #3920.
2016-12-19 21:29:46 +01:00
wm4 e57037dc95 ad_lavc, vd_lavc: don't set AVCodecContext.refcounted_frames
This field is (or should be) deprecated, and there's no need to set it
with the new API.
2016-12-18 12:28:09 +01:00
Rudolf Polzer 4bfec4279f mpv_identify.sh: add "duration" property to the list. 2016-12-17 15:59:31 -05:00
wm4 1ef9876b7d TOOLS/matroska.py: format file dumper output slightly nicer 2016-12-17 17:30:13 +01:00
wm4 a61eb81141 TOOLS/matroska.py: allow using as module
Don't force CLI usage. It can be imported, and generate_C_header() and
generate_C_definitions() can be called with a file argument instead of
writing to stdout always.
2016-12-17 16:05:51 +01:00
wm4 ff9f5e06ff Revert "Port several python scripts to Perl"
This reverts commit fae7307931.

Before the waf build system was used, we had a configure script written
in shell. To drop the build dependency on Python, someone rewrote the
Python scripts we had to Perl. Now the shell configure script is gone,
and it makes no sense to have a build dependency on both Perl and
Python.

This isn't just a straight revert. It adds the new Matroska EBML
elements to the old Python scripts, adjusts the waf build system, and of
course doesn't add anything back needed by the old build system.

It would be better if this used matroska.py/file2string.py directly by
importing them as modules, instead of calling them via "python". But for
now this is simpler.
2016-12-17 15:43:15 +01:00
Akemi 2b8b17402e cocoa: cosmetic fixes 2016-12-16 16:32:26 +01:00
wm4 aab98776f6 options: change --h=... behavior
Does not match a shell pattern anymore. Instead, a simple sub-string
search is done.
2016-12-16 16:09:10 +01:00
Akemi a8347eb9ba cocoa: fullscreen refactoring
this replaces the old fullscreen with the native
macOS fullscreen. additional the
--fs-black-out-screens was removed since the new
API doesn't support it in a way the old one did.
it can possibly be re-added if done manually.

Fixes #2857 #3272 #1352 #2062 #3864
2016-12-15 20:55:16 +01:00
Zhiming Wang 870a6a11d9 manpage: add table of contents to the HTML version
The reST contents directive is added to mpv.rst.

In wscript_build.py, the --strip-elements-with-class=contents option is
needed for the rst2man call in order to prevent the TOC from appearing
in mpv.1.
2016-12-14 21:43:30 +01:00
pavelxdd 544110bf43 win32: change the log level of 'move window' msg
It does more harm than good, since it spams terminal a lot
2016-12-14 20:45:58 +01:00
Akemi a6035439a9 cocoa: fix dropping of certain urls on the window
the 'path' of an youtube url (youtube.com/watch?v=x)
would just be '/watch'. obviously this fails to
load.
2016-12-14 00:34:16 +01:00
Akemi 3bb06155c9 cocoa: support append file to paylist on drop
When dropping a file on mpv, either on the window
or the App bundle icon, while holding the shift
key the dropped files will be appended to the
playlist.

Fixes #2166
2016-12-14 00:34:16 +01:00
pavelxdd bf5727a60f win32: window styles improvements
Allow minimizing the borderless/fullscreen window by clicking on the
taskbar button or pressing Win+Down hotkey.

Also fixes #2229 and probably fixes #2451
2016-12-12 22:22:43 +11:00
wm4 765a7228d1 manpage: document current and legacy option syntax better
I thought it ewas already documented, but I'm not seeing it anywhere.
Maybe it did exist, but was deleted.

See #3899.
2016-12-12 12:10:10 +01:00
wm4 6b6789a47a manpage: clarify --loop option
Fixes #3899.
2016-12-12 12:10:10 +01:00
Akemi ed7e650d3a osx: update the menu and remove conflicting item
Remove 'Quit mpv & remember playback position'
from the menu because it conflicts with the global
logout shortcut. add separator between 'Hide' and
'Quit' for consistency with other Apps.
also rename the 'Movie' menu to 'Video'. it's a
bit more generic.

Fixes #3865
2016-12-12 12:10:10 +01:00
pavelxdd 4399be5b62 win32: update winapi functions names
According to MSDN, GetWindowLong and SetWindowLong have been
superseded by GetWindowLongPtr and SetWindowLongPtr.
It's a cosmetic code change in this case.
2016-12-12 21:17:58 +11:00
wm4 c21c68edd4 bstr: change to LGPL
Was started by Uoti Urpala in commit 5f631d1c. Although it was made part
of demux_mkv.c, it's quite obvious that it's not based on any
pre-existing demux_mkv.c code (or ebml.c/.h for that matter). Anyone
else who has touched this code every since has already agreed to LGPL
relicensing.
2016-12-11 18:09:44 +01:00
Michael Forney 2d9b6ff7cd ad_spdif: Fix crash when spdif muxer is not available
Currently, if init_filter fails after lavf_ctx is allocated, uninit is called
which frees lavf_ctx, but doesn't clear the pointer in spdif_ctx. So, on the
next call of decode_packet, it thinks it is already initialized and uses it,
resulting in a crash on my system.
2016-12-11 14:20:58 +01:00
shinchiro 0aa9b2a469 wscript_build: rst2pdf: increase section break level
This fix broken pdf build and hopefully less fragile in future
2016-12-11 14:20:48 +01:00
wm4 82855bec50 client API: allow passing NULL to mpv_opengl_cb_uninit_gl()
In which case it does nothing.
2016-12-09 21:31:45 +01:00
wm4 c324bfab59 charset_conv: simplify and change --sub-codepage option
As documented in interface-changes.rst. This makes it much easier to
follow what the heck is going on.

Whether this is adequate for real-world use is unknown.
2016-12-09 19:51:29 +01:00
wm4 0eb87e1baf charset_conv: drop enca and libguess support
Enca is dead. libguess is relatively useless due to not having an
universal detection mode. On the other hand, libuchardet is actively
developed.

Manpages changes in the following commit.
2016-12-09 19:48:59 +01:00
Douglas Christman 2aebf3e482 manpage: replace -vo with --vo 2016-12-08 18:30:50 +01:00
Akemi 736cd7336a manpage: remove mention of window alpha (OSX)
This is not implemented and i don't even know if
it ever was. Also remove a trailing whitespace.

Fixes #3866
2016-12-08 18:30:36 +01:00
wm4 a8b8295f8d options: remove weird RPI-only fullscreen default
As announced by interface-changes.rst.
2016-12-08 12:39:49 +01:00
wm4 51fd8f6fe1 vo_rpi: partially undeprecate
Using vo_opengl + MMAL overlay didn't quite work out.
2016-12-08 11:00:14 +01:00
wm4 3eceac2eab Remove compatibility things
Possible with bumped FFmpeg/Libav.

These are just the simple cases.
2016-12-07 19:53:11 +01:00
wm4 a660e15c9b build: bump required minimum versions to FFmpeg 3.2.2 and Libav 12
Fixes the build with Libav 11 (not).
2016-12-07 19:13:14 +01:00
wm4 2b1d150a53 manpage: move the --opengl-dumb-mode option down
It's horribly obscure - why would it be the first option to be listed?

Also might fix the --scale option formatting/anchor in the HTML
rendering.
2016-12-07 13:26:30 +01:00
wm4 42799005dc ao_alsa: print certain ALSA errors as string instead as number 2016-12-07 12:51:17 +01:00
Ricardo Constantino b60817f9dd TOOLS/autoload: allow disabling through script-opts
This allows leaving autoload in auto-loaded scripts and to be used
in a special profile like "pseudo-gui" without being troublesome
to disable the behavior in profiles that get applied after
pseudo-gui.

Ex:
[someprofile]
script-opts=autoload-disabled=yes
2016-12-05 21:09:28 +00:00
wm4 ceb2e1026d demux, stream: add option to prevent opening referenced files
Quite irresponsibly hacked together. Sue me.
2016-12-04 23:15:31 +01:00
Philip Langdale 83c5f704e7 vo_opengl: hwdec_cuda: Don't include hwcontext headers
After various simplifications, these includes simply aren't needed
now.
2016-12-04 20:41:42 +01:00
wm4 47f974a395 demux_lavf: blacklist ffm (ffserver) 2016-12-04 13:18:48 +01:00
pavelxdd f53b2952eb osc: replace length property with duration
Length property is deprecated and no longer works. This fixes
a bug when the total file duration wasn't visible if the
option to display milliseconds was activated.
2016-12-04 13:18:19 +01:00
shinchiro 5544ffecd9 wscript: add ANGLE_EXPORT definition
It always needed when linking ANGLE libs
2016-12-04 13:18:12 +01:00
Ricardo Constantino 796b48b2a3 osc: don't hide playlist buttons, just disable
Having empty space before the title in layout=*bar looks worse
than the floating buttons in layout=box.

Also disable both playlist buttons selectively according to the
current position.
2016-12-02 16:59:40 +00:00
Ricardo Constantino a7a919f93f osc: topbar: use same styles as bottombar 2016-12-02 16:59:32 +00:00
wm4 a89785f297 vdpau: fix vaapi probing if libvdpau-va-gl1 is present
Needs explicit logic. Fixes a pretty bad regression which prefers
vdpau-copy over native vaapi with direct rendering (with --hwdec=auto)
if libvdpau-va-gl1 is present. The reason is that vdpau-copy is above
vaapi, simply because all vdpau hwdecs are grouped and happened to be
listed before vaapi.

Although this is not that bad for copy-mode (unlike the case described
above), it's still a good idea to use our native vaapi code instead.
2016-12-02 16:09:51 +01:00
wm4 09238a9bb5 vo_opengl: don't rely on viewport to contain window dimensions
Apparently we don't always set the viewport to window dimensions
anymore, e.g. if nothing is actually rendered. This means the viewport
can contain old values.

The window screenshot code uses the viewport values to guess the default
framebuffer dimensions. With --force-window --idle --no-osc (which draws
nothing and issues a glClear() command only), taking a screenshot would
yield an image with the wrong size and possibly garbage in it. Fix this
by explicitly passing the currently known window dimensions. Abusing the
values stored in the viewport was questionable anyway.
2016-12-02 15:26:45 +01:00
wm4 ec74a79e12 ao_wasapi: log return code when probing audio formats
We log a large number of formats, but we rarely log the result of the
probing. Change this.

The logic in try_format_exclusive() changes slightly, but should be
equivalent. EXIT_ON_ERROR() checks for FAILED(), which should be
exclusive to SUCCEEDED().
2016-11-30 17:56:33 +01:00
wm4 20f02229cd player: don't print format detection error when aborting loading
The way playback/loading is stopped on the demuxer layer makes it report
an error to the higher levels of the player. But if playback/loading was
explicitly aborted, printing such an error is confusing and misleading.
This was probably just an oversight anyway. Fix it by using the libmpv
API reported error field instead, which handles this better.
2016-11-29 17:16:22 +01:00
wm4 4958c1a556 options: some simplifications
Remove more stuff that was needed only for legacy suboptions.

One user-visible change is that parent-options like --tv are now not
visible anymore. They lead to a special error message when used before,
but now they're simply not part of the option list anymore.
2016-11-29 17:10:06 +01:00
pavelxdd 3203d6003c ao_wasapi_utils: remove unused variable
Introduced in 1a2319f3e4
Produced a warning during compilation on Windows.
2016-11-27 20:32:33 +01:00
Emmanuel Gil Peyrot 89837523b5 wayland: destroy input before closing the display connection.
Fixes a segfault introduced in libwayland
e8ad23266f36521215dcd7cfcc524e0ef67d66dd, where a poison value has been
introduced to catch this kind of use-after-free bug.
2016-11-27 02:01:14 +00:00
wm4 1a2319f3e4 options: remove deprecated sub-option handling for --vo and --ao
Long planned. Leads to some sanity.

There still are some rather gross things. Especially g_groups is ugly,
and a hack that can hopefully be removed. (There is a plan for it, but
whether it's implemented depends on how much energy is left.)
2016-11-25 21:17:25 +01:00
pavelxdd 98a257b3a8 angle_dynamic: silence warnings during compilation
If Angle is statically linked there were some warnings during compilation.

Fixes #3834
2016-11-25 09:49:49 +01:00
wm4 c03a67c37c audio/out/push: play silence on --audio-stream-silence
Until now, this was only implemented for ao_alsa and AOs not using
push.c. ao_alsa.c relied on enabling funny underrun semantics for
avoiding resets on lower levels, while other AOs using push.c didn't do
anything.

Change this and at least make push.c copy silent data to the AO. This
still isn't perfect as keeping track of how much silence was played when
seems complex, so we don't do it. The consequence is that frame-stepping
will essentially randomize the A/V offset (it'll recover immediately
when unpausing, but still ugly). Also, in order to empty the currently
buffered audio on seeks etc., we still call ao_driver->reset and so on,
so the AO driver will still need to handle this specially.

The intent is to make behavior with ALSA less weird (for one we can
remove the code in ao_alsa.c that tries to trigger an initial
underflow). Also might help with #3754.
2016-11-24 20:52:15 +01:00
Philip Langdale 48a7c4be3a vo_opengl: hwdec_cuda: Prefix cuda symbols to avoid collisions
We want to avoid causing problems if libmpv is used in an application
that links cuda, or if the libav* libraries are linked with cuda,
as might happen if the scale_npp filter is used.
2016-11-24 20:15:57 +01:00
wm4 5aab17f833 vo_opengl: hwdec_cuda: make some init errors verbose
Improves autoprobe behavior. This is equivalent to other hwdec interop
wrappers. If CUDA is just not available, it should remain silent.
2016-11-24 18:14:55 +01:00
pavelxdd e89382f5f6 vo_opengl: hwdec_cuda: fix crash when trying to use hwdec=cuda if cuda SDK is not present
If CUDA SDK wasn't installed, mpv crashed immediately with the message "Failed to load CUDA symbols"
2016-11-24 14:42:30 +01:00
Philip Langdale 7eacaf51f8 vo_opengl/cuda_dynamic: Use explicit cast to silence warnings on windows
Fixes #3834
2016-11-24 11:40:52 +01:00
Philip Langdale 3abb6f1fef wscript: Fix cuda test to actually work when cuda SDK is not present
The test ended up failing if cuda.h wasn't present, even if cuda.h
isn't used during the actual build.

This test is attempting to establish if the ffmpeg being built
against has dynlink_cuda support. While it might theoretically be
possible to build against the older normally-linked-cuda version
of ffmpeg, it seems more trouble than it's worth.
2016-11-23 20:48:26 +01:00
wm4 755e9fad29 command: warn against deprecated properties in all cases
For some reason, some types of accesses didn't warn, for example when
using mp.observe_property() in Lua. This was because the deprecation
handling code explicitly checks certain accesses. I'm not quite certain
why it was done this way. Just make it warn always.

This could be backported to the current release, if we cared.
2016-11-23 17:30:46 +01:00
wm4 f696975fe3 angle_dynamic: minor simplification
Remove the inverted condition by swapping if branches.
2016-11-23 16:02:28 +01:00
wm4 79d99bd264 demux_mkv: distinguish mp2 and mp3
demux_mkv.c has returned mp3 for mp2 since the initial commit. Normally
not a problem.
2016-11-23 15:57:35 +01:00
Martin Herkt f9668f5596 Support linking ANGLE 2016-11-23 04:09:16 +01:00
Martin Herkt 535e180b9e DOCS/compile-windows: be more specific about the D3D compiler DLL
Also provide a more useful link to _43 and _47.
2016-11-23 01:23:12 +01:00
wm4 6b3d682f4e vo_opengl: hwdec_d3d11egl: fix ANGLE fallback define
This was a typo in the extensiuon spec and was probably always broken.
Could have led to broken builds when used with ancient ANGLE headers
(or possibly generic EGL headers).
2016-11-23 01:09:19 +01:00
Philip Langdale f5e82d5ed3 vo_opengl: hwdec_cuda: Use dynamic loading for cuda functions
This change applies the pattern used in ffmpeg to dynamically load
cuda, to avoid requiring the CUDA SDK at build time.
2016-11-23 01:07:26 +01:00
Ricardo Constantino ebd9ce9fca osc: fix use of deprecated idle property
Fixes regression since 7201fd7d
2016-11-22 21:00:04 +00:00
Philip Langdale 585c5c34f1 vo_opengl: hwdec_cuda: Support P016 output surfaces
The latest 375.xx nvidia drivers add support for P016 output
surfaces. In combination with an ffmpeg change to return those
surfaces, we can display them.

The bulk of the work is related to knowing which format you're
dealing with at the right time. Once you know, it's straight forward.
2016-11-22 20:19:58 +01:00
wm4 5087816a74 options: remove legacy global sub-option syntax
A bit of sanity, although a very small one.

--vo sub-options are not affected by this yet.
2016-11-22 15:55:13 +01:00
wm4 7201fd7d08 command: redefine some deprecated properties
As threatened by the API changes document.

We can actually keep the deprecated --playlist-pos and --cache options,
since they are aliases and not used by the corresponding properties.
They are inconsistent, but do no harm. Keep them for now for the sake of
the command line user.

mpv_identify.sh partially stopped working, because it was never updated.
The shell magic can't deal with property names that contain "/", so we
can't replace "samplerate" with "audio-params/samplerate" - just remove
these properties. (How about you use ffprobe?)
2016-11-22 15:54:45 +01:00
wm4 78f76bdddd tv: fix option type
It appears this makes it actually compatible with the property. It was
an ancient MPlayer artifact all along.
2016-11-22 15:54:45 +01:00
wm4 c731513efa wscript: fix typo 2016-11-22 15:54:44 +01:00
wm4 07b6969ba4 vf_vdpaurb: remove this filter
Was deprecated, superseded by --hwdec=vdpau-copy.
2016-11-22 15:54:44 +01:00
wm4 f30c5d09f4 client API: turn mpv_suspend() and mpv_resume() into stubs
As threatened by the API changes document.

This commit also removes or stubs equivalent calls in IPC and Lua
scripting.

The stubs are left to maintain ABI compatibility. The semantics of the
API functions have been close enough to doing nothing that this probably
won't even break existing API users. Probably.
2016-11-22 15:54:44 +01:00
James Ross-Gowan 745862131f d3d11va: unconditionally load D3D DLLs
At least with Nvidia drivers, some thread tries to access D3D11 objects
after ANGLE unloads d3d11.dll. Fix this by holding a reference to
d3d11.dll ourselves.

Might fix the crash in #3348. (I wish I knew why though.)
2016-11-23 01:18:44 +11:00
wm4 f843ae9983 Fix some future release version numbers
Since the recent release was named 0.22.0 instead of 0.21.1, bump all
mentions of 0.22.0 to 0.23.0. These were planned removals of deprecated
versions, which obviously didn't happen in 0.22.0.
2016-11-21 20:17:41 +01:00
wm4 de37c5b1cb audio: fix --audio-stream-silence with ao_wasapi
Seems like wasapi will restart the HDMI stream if resume is called
during playback.
2016-11-21 19:35:06 +01:00
wm4 fcba41e2e4 audio: fix --audio-stream-silence with ao_alsa
ao_alsa.c calls this before the common code sets ao->sstride.

Other than this, I'm still not sure whether this works. Seems like no,
or depends.
2016-11-21 19:35:06 +01:00
Ricardo Constantino b39a7fddb5 osc: fix possible race condition in right timecode 2016-11-21 18:20:53 +00:00
Martin Herkt 1d4273cfb5 Release 0.22.0 2016-11-20 18:16:02 +01:00
Martin Herkt 8700700de8 Merge branch 'master' into release/current 2016-11-20 18:15:08 +01:00
Martin Herkt eafc273d2c DOCS: update interface changes 2016-11-20 18:14:41 +01:00
wm4 bb48f09532 options: clarify --softvol deprecation message and manpage entry
People seem to think that the softvol behavior is deprecated, but what
is deprecated is actually disabling softvol.
2016-11-19 01:19:14 +01:00
wm4 5a011c5c06 player: removing last playlist entry while looping should not stop
Run "playlist-remove current" while the last playlist entry is being
played stopped playback. Fix this and return to the first entry instead.

Fixes #3808.
2016-11-18 13:46:34 +01:00
wm4 c4d6fcbb02 player: make sure non-video subtitle rendering is reset if video resumes
If video reaches EOF, subtitle timing will be switched to timing without
video frames. This means it calls osd_set_force_video_pts() and
overrides the PTS of whatever video frame is current (since the video
frame's PTS has nothing to do with the current playback position
anymore).

This was not reset when seeking back into video. Subtitles wouldn't show
up, or if there was a subtitle displayed, it would get stuck with it. In
particular, this could happen even if EOF was only temporary (such as
with --keep-open).

Fix this by clearing the override PTS whenever a video frame is shown.

Fixes #3770.
2016-11-18 13:02:03 +01:00
Stefano Pigozzi 6250007bca travis: fix ffmpeg-git build 2016-11-17 15:07:54 +01:00
James Ross-Gowan 803e2c5f87 win32: fix some Clang warnings
- win32-console-wrapper.c was inconsistently using the explicit Unicode
  versions of some Windows API functions and structures.
- vo.c should use llabs for int64_t, since long is 32-bit on Windows.
- vo_direct3d.c had a potential use of an uninitialized variable if it
  took the first goto error_exit.
2016-11-17 23:34:20 +11:00
James Ross-Gowan 40b626fd9b build: fix compilation with mingw-w64/Clang
This fixes the build in mingw-w64/Clang on MSYS2. It also disables the
use of gnu_printf in Clang, which was what was causing most of the
warnings. The Clang-compiled mpv binary appears to work, but there are
no guarantees yet, since until now mpv has only been tested with
mingw-w64/GCC on Windows.

Fixes #3800
2016-11-17 23:34:20 +11:00
Ricardo Constantino a3c27786c6 wscript: move install dirs setting to after C compiler check
This fixes waf setting the wrong LIBDIR for DEST_OS=win32 in
waflib/Tools/c_config.py:get_cc_version()

Any scripts assuming the implib and pkgconfig are in the wrong
place should be changed to move the .dll instead.
2016-11-16 17:29:22 +00:00
Ricardo Constantino 03ea61c895 ytdl_hook: sort chapters by time
mpv doesn't work well with unordered chapters.
ex: https://youtu.be/DIKPUL6b4N8
2016-11-15 22:58:43 +00:00
wm4 274c6f36f5 DOCS/client-api-changes.rst: fix typo 2016-11-15 23:49:36 +01:00
wm4 79efe248a5 DOCS/interface-changes.rst: reword a line
Try to make it sound a bit less weird. Probably still sounds weird,
so feel free to propose further changes.
2016-11-15 23:47:06 +01:00
wm4 106f607ef7 README: add links to various changelogs
We're too lazy to maintain a full changelog, but there are still a bunch
of places which document specific changes. A user really should check
them on each update, even if there are transition periods (including
printing warnings etc.) for most changes. It's a good idea to give them
more exposure by adding them to the README.
2016-11-15 23:42:33 +01:00
wm4 c1ae1def85 ao_alsa: explicitly add default device manually
The "default" entry (which is and always was mpv/mplayer's default) does
not have a description set in the ALSA API. (While "sysdefault"
strangely has.)

Instead of an empty description, this should show something nice, so
reuse the ao.c code for naming default devices (see previous commit).

It's still a bit ugly that audio-device-list will have a default entry
for "Autoselect device" and "Default (alsa)", but then again we probably
want to allow the user to force ALSA (i.e. prevent fallbacks to other
AOs) just because ALSA is so flaky and makes this a legitimate feature.
2016-11-14 13:42:49 +01:00
wm4 a2b93e0c27 audio: make empty device ID mean default device
This will make it easier for AOs to add explicit default device entries.
(See next commit.)

Hopefully this change doesn't lead accidentally to bogus "Default"
entries to appear, but then it can only happen if the device ID is
empty, which would mean the underlying audio API returned bogus entries.
2016-11-14 13:42:41 +01:00
wm4 84513ba58b audio: avoid returning audio-device-list entries without description
Use the device name as fallback. This is ugly, but still better than
skipping the description entirely. This can be an issue on ALSA, where
the API can return entries without proper description.
2016-11-14 13:33:53 +01:00
Philip Sequeira cf85191cb7 vo_opengl: blend against background color for --alpha=blend
Do it after color management, etc. so that it matches the color drawn in
the margins.
2016-11-13 18:21:27 +01:00
Stefano Pigozzi 19c9347e47 docs: remove trailing spaces
Some slipped in with previous commit.
2016-11-11 21:44:27 +01:00
Akemi aceeeaf9bb cocoa: option to scale window by HiDPI scale factor
Deactivating this options makes it possible to
circumvent the default OS X behavior of using
points. Windows on HiDPI resolutions won't open
in double the size anymore and videos are display
in their native resolution when windowed.

Fixes #3716
2016-11-11 21:37:04 +01:00
wm4 98e7b4e538 av_common: always make sure to return a valid timebase
av_reduce(&num, &den, 1, 14112000, 1000000) can return num=0, den=1.
This means a 1/14112000 timebase (as used by the mp3 demuxer) would
become invalid.

The intention of mp_get_codec_timebase() is to always return a valid
timebase. av_reduce() probably does the logically correct thing - so add
a fallback to the safe default timebase.

Also, increase the av_reduce() parameter to INT_MAX. Let's just pray
this doesn't cause any actual problems. libavformat does the same, but
might be in a different position due to using av_rescale() etc., while
we convert between fractional timestamps and floats.
2016-11-10 12:06:17 +01:00
wm4 ca175871cd vdpau: fix hwdec uninit
This is a bit unintuitiv, but it appears hwdec backends have to unset
hwdec_priv manually in their uninit function. Normally with this idiom
you'd expect the common code to do this (and maybe even freeing the priv
struct). Since other hwdec backends do this quite consistently, just fix
vdpau for now.

Also add an assert to detect similar bugs sooner.

Fixes #3788.
2016-11-10 08:39:09 +01:00
wm4 fc1017c335 dec_video: don't spam missing PTS warnings
Only print at most 2. Just because with some decoders, we will always
hit this code path, such as playing avi of vfw-muxed mkv on RPI.
2016-11-09 17:51:19 +01:00
wm4 67467103e8 dec_video, dec_audio: avoid full reinit on switches to the same segment
Same deal as with the previous commit.

(Unfortunately, this code is still duplicated.)
2016-11-09 16:44:06 +01:00
wm4 a55e8ff31c dec_sub: avoid full reinit on switches to the same segment
The previous commit means subtitles were reinitialized on every seek
(even within a segment). This commit restores the old behavior.

To check whether the segment changed at all, we don't reset the current
start/end values. This assumes the decoder wrapper is always fed by a
stream which doesn't mix segment and non-segment packets, which is
currently always true.
2016-11-09 16:44:06 +01:00
wm4 b787a4121a demux_timeline: always signal new segment after a seek
This is needed to put the decoders into the correct state. In
particular, decoders will not initialize the current segment without
this flag. The intention of not setting the flag for seeks within the
segments were to avoid costly decoder reinits, but it seems this is
better handled explicitly in the decoder wrappers.
2016-11-09 16:44:06 +01:00
Ricardo Constantino adf65634d8 osc: add seekbarstyle=knob
Most code from @leiserfg in #2365.
Closes #2365

Cut guides to the center of the knob. This makes the knob
knob look more like IRL knob sliders.
2016-11-09 05:51:20 +00:00
Ricardo Constantino 5beb230690 osc: fix crashes when dragging seekbar across file changes
Fixes #3210
2016-11-08 21:18:53 +00:00
Avi Halachmi (:avih) 616ecd9365 options: fnmatch: check existence instead of posix 2016-11-08 19:16:35 +01:00
Niklas Haas c676c31815 demux: expose demuxer colorimetry metadata to player
Implementation-wise, the values from the demuxer/codec header are merged
with the values from the decoder such that the former are used only
where the latter are unknown (0/auto).
2016-11-08 19:16:26 +01:00
Niklas Haas 81ceb7b6a5 demux_mkv: parse colorimetry metadata
Matroska actually has lots of colorimetry metadata that video tracks can
use, including mastering metadata (HDR signal peak) etc.

This commit adds the EBML definitions and parses the most basic fields.
Note that nothing uses these fields yet, this commit is just adding the
necessary parsing and infrastructure.
2016-11-08 19:16:24 +01:00
wm4 33012b4141 ao_alsa: fill unused ALSA channels with silence
This happens when ALSA gives us more channels than we asked for, for
whatever reasons. It looks like this wasn't handled correctly. The mpv
and ALSA channel counts could mismatch, which would lead to UB.

I couldn't actually trigger this case, though. I'm fairly sure that
drivers or plugins exist that do it anyway. (Inofficial ALSA motto: if
it can be broken, then why not break it?)
2016-11-08 17:49:40 +01:00
wm4 1d51dc20ea ao_alsa: strictly disable chmap use for mono/stereo
If the input is already mono or stereo, or if channel map selection
results in mono or stereo, then disable further use of the champ ALSA
API (or rather, stop trusting its results). Then we behave like a simple
application that only wants to output mono or stereo.

See #3045 and #2905. I couldn't actually test these cases, but this
commit is supposed to fix them.
2016-11-08 17:49:13 +01:00
wm4 2e113a7391 ao_alsa: _really_ disable chmap API use in cases where we should
set_chmap() skipped _setting_ the ALSA chmap if chmap use was requested
to be disabled by setting dev_chmap.num=0 by the caller, but it still
queried the current ALSA channel map. We don't trust it that much, so
disable that as well.

But we still query and log it, because that could be helpful for
debugging. Otherwise we could skip the entire set_chmap() call in these
cases.
2016-11-08 17:48:40 +01:00
wm4 2b71bef2ba ao_alsa: slightly better debug logging
Try to make it more compact, and also always list the reordered layout,
but only if it's actually different.

Should be the same functionally.
2016-11-08 16:59:12 +01:00
wm4 8f1ec91b45 mp_image: dump all mp_colorspace members in verbose logging
Also extend the default buffer size for formatting this string, because
it can get too damn long.
2016-11-08 14:19:26 +01:00
Ricardo Constantino 8b7f23129d osc: slimbox: fix clipping with seekbarstyle=bar
Fixes #3737
2016-11-07 22:00:17 +00:00
wm4 6a06e6002b vo_opengl: fix --blend-subtitles handling
The intention was that if --blend-subtitles is enabled, the frame should
always be re-rendered instead of using e.g. a cached scaled frame. The
reason is that subtitles can change anyway, e.g. if you pause and change
subtitle size and such.

On the other hand, if the frame is marked as repeated, it should always
use the cached copy. Actually "simplify" this and drop the cache only if
playback is paused (which frame->still indicates indirectly).

Also see PR #3773.
2016-11-07 22:49:24 +01:00
wm4 de72cb2c33 vo_opengl: fix redrawing with hardware decoding
unmap_current_image() is called after rendering. This essentially
invalidates the textures, so we can't assume that the image is still
present.

Also see PR #3773.
2016-11-07 22:49:16 +01:00
Emmanuel Gil Peyrot 4914e688cf manpage: rename drm-egl to drm. 2016-11-07 18:42:27 +01:00
Douglas Christman 932ecbfe9e man/options.rst: fix typo 2016-11-06 04:53:55 +01:00
Nils Maier 7c9f32620f Apply autofit-larger after autofit-smaller
This prevents the window scaling beyond screen dimensions

Fixes #3753
2016-11-03 21:30:25 +01:00
Aman Gupta 3f5b41dfa3 audio/out: add AudioUnit output driver for iOS 2016-11-01 16:25:40 +01:00
Niklas Haas 0dc1fe3269 manpage: explicitly document all scaling options
Enumerate all of the scaling-related options, even for the ``--cscale``
/ ``--tscale`` etc. variants. Unfortunately this breaks 80col quite
severely, but there's nothing I can do about it due to a bug in rst2man
preventing definition list labels from spanning multiple lines.

Also reorder some of the scaling-related options to be closer together
and in a more consistent order (for a top-to-bottom reading flow).
2016-11-01 16:25:40 +01:00
Niklas Haas 654721c27b filter_kernels: add ability to taper kernels/windows
This allows us to define the tukey window (and other tapered windows).

Also add a missing option definition for `wblur` while we're at it, to
make testing out window-related stuff easier.
2016-11-01 16:25:40 +01:00
wm4 5838322975 demux: improve buffer estimation in a corner case
This deals with the estimation of buffered packets, which is used mostly
for display, but also things like pausing on low buffer levels.

If a stream is fully EOF (no more packets), we don't want to include it
in the total buffer amount. This also means we should make ds->eof less
flaky and more stable, so don't reset it in ds_get_packets() (this
function reset ds->eof just to retrigger a packet read attempt - we can
have this slightly simpler). This somewhat fixes buffering display when
e.g. issuing a refresh seek after re-enabling audio/video when playing
with subtitles only.
2016-11-01 16:25:40 +01:00
wm4 8dff51e06c vo: clear frame repeat flag when redrawing
This makes no sense, as the flag is supposed to be used for vsync
purposes only (when literally outputting the screen again with no
changes at all), and redrawing is often used for OSD updates.
2016-11-01 16:25:40 +01:00
wm4 17733bd5b8 vo_opengl: make frame reupload logic more robust
It's not that easy to decide whether a frame needs to be
reuploaded/rerendered. Using unique frame IDs for input makes it
slightly easier and more robust. This also removes the use of video PTS
in the interpolation path.

This should also avoid reuploading the video frame if it's just redrawn
in paused mode, or when using OSD/subtitles in cover art mode.
2016-11-01 16:25:40 +01:00
Ricardo Constantino eedda59a69 osc: add alpha animation to tooltip
Fixes lingering tooltip with full alpha if mouse leaves window
with OSC still active.
2016-10-31 16:57:32 +00:00
wm4 8fad4b8eab player: enable no-video subtitle display on coverart too
Coverart mode has the same issue as no-video mode, except that the video
chain is fully active. It shows only 1 frame at the start, which would
normally mean that only the subtitle at timestamp 0 is shown. Use the
no-video subtitle rendering mode in this case instead.

(This still doesn't handle subtitle display when playing cover-art
without audio, or playing a single image. This is because there's
nothing that will advance playback_pts.)
2016-10-31 13:55:32 +01:00
wm4 bc77565838 vo_opengl_cb: fix a race condition
When pthread_cond_timedwait(), the condition we are checking for could
be true or false. This code assumed it was always false.

This should be an extremely obscure race condition, since it can happen
only if timeout and the condition changing sort of happen at the same
time, or the lock is held for a longer time (which it normally isn't).
But I could observe it a few times.
2016-10-30 18:29:24 +01:00
wm4 b0ef3dd4fb vo_opengl_cb: fix inverted condition
Commit e6291697 got this wrong.
2016-10-30 12:16:24 +01:00
wm4 1ff6d8ae2e player: don't try updating subtitles while playback PTS doesn't progress
This code would just keep it busy while e.g. being paused. Even if it's
not paused, it couldn't help with anything since we obviously still lock
display to the externally updated PTS.
2016-10-30 12:03:46 +01:00
wm4 1afc0c8b55 vo_opengl_cb: update current frame if a frame is dropped
Even if a frame is dropped due to the libmpv API user not drawing a
frame, it should be set as current frame. This avoids dropping a frame
forever in certain circumstances such as cover art of the API user was
stuck at initialization or such.
2016-10-30 12:00:33 +01:00
Ricardo Constantino a1801da717 man/osc: remove extra indentation from 3adc6071 2016-10-30 10:28:42 +00:00
Ricardo Constantino eac977b12f osc: top/bottombar: rescale layout to same size with scale=1
Basically, there's two less values to revert to previous defaults and
top/bottombar now look at scale=1 like they looked with scale=1.5.
2016-10-29 18:14:32 +01:00
Ricardo Constantino 3adc6071b6 man/osc: Fix hard wrapping in man files 2016-10-29 18:14:30 +01:00
Ricardo Constantino 0c3e4b13ac osc: top/bottombar: scale title if too large like box 2016-10-29 18:14:30 +01:00
Ricardo Constantino 22133f8efc osc: compromise on default deadzonesize
This way people can still use the mouse to quickly check the elapsed time
without moving it all the way to the bottom while still having half the screen
to ignore mouse movement.
2016-10-29 18:14:29 +01:00
Ricardo Constantino 4abd23bd95 osc: don't wrap the title 2016-10-29 18:14:28 +01:00
Ricardo Constantino 993466fc30 osc: top/bottombar: also scale when min-width is reached
Same behavior as box/slimbox.
2016-10-29 18:14:19 +01:00
Ricardo Constantino ad819b5458 osc: top/bottombar: dynamically size timecodes according to timems 2016-10-29 18:14:04 +01:00
Ricardo Constantino 894dbcd1b7 osc: fix missing chapter ticks with seekbarstyle=bar 2016-10-29 18:14:02 +01:00
wm4 90b968a67a player: show subtitles on VO if --force-window is used
If a VO is created, but no video is playing (i.e. --force-window is
used), then until now no subtitles were shown. This is because VO
subtitle display normally depends on video frame timing. If there are no
video frames, there can be no subtitles.

Change this and add some code to handle this situation specifically. Set
a subtitle PTS manually and request VO redrawing manually, which gets
the subtitles rendered somehow.

This is kind of shaky. The subtitles are essentially sampled at
arbitrary times (such as when new audio data is decoded and pushed to
the AO, or on user interaction). To make a it slightly more consistent,
force a completely arbitrary minimum FPS of 10.

Other solutions (such as creating fake video) would be more intrusive or
would require VO-level API changes.

Fixes #3684.
2016-10-26 20:44:05 +02:00
wm4 fc4318d23e player: consistently initialize screensaver state with --force-window
Whether this is a good or a bad thing, make sure it's consistent.
2016-10-26 20:35:12 +02:00
Ricardo Constantino 65c06511bf osc: fix crash with no chapters
Also, chapter position which wasn't changed to work with 1-based.
2016-10-25 15:42:40 +01:00
wm4 ee4bed25a8 command: if window-scale can't be set properly, set it as option
Kind of sketchy, but happens to fix #3724.
2016-10-25 16:05:46 +02:00
Miroslav Koskar 6953a1ca2f osc: Fix and simplify limited_list
* Fixes: when on the end of playlist only half of entries are displayed.
* Simplifies the logic of limited_list so it's easy to follow.
* limited_list's pos parameter is now 1 based which seem more natural.
* Few changes to comply with code style thorough the file.
* Small format change:

  "Playlist: (%d/%d):"  -> "Playlist [%d/%d]:"
  "Chapters: (%d/%d):"  -> "Chapters [%d/%d]:"
2016-10-25 14:09:48 +01:00
Ricardo Constantino c8e3ee494c osc: add script message handlers for chapter/track/playlists
These can be used in input.conf for pretty formatting of lists as
with shift+clicking the OSC buttons.

Ex:
z   script-message osc-playlist
Z   script-message osc-chapterlist
x   script-message osc-tracklist
2016-10-24 19:03:07 +01:00
Avi Halachmi (:avih) 363982c774 vo_tct: support also 256 colors output 2016-10-25 00:03:01 +11:00
Avi Halachmi (:avih) 02d2c2cc97 vo_tct: optional custom size, support non-posix with 80x25 default
Also, replace the UTF8 half block char at the source code with C escape.
2016-10-25 00:03:01 +11:00
Ricardo Constantino 6e143ffec3 man/osc: reorder a few options for better visibility
Also document pre-0.21.0 defaults.
2016-10-23 17:23:25 +01:00
wm4 61ff2408e3 manpage: document ytdl:// 2016-10-23 17:38:58 +02:00
Aman Gupta d0b997d528 player: make --start-time work with --rebase-start-time=no 2016-10-22 18:48:27 +02:00
Uoti Urpala 18681a7dd2 demux_mkv: fix ordered chapter sources with ordered editions
Commit f72a900892 (and others) added support for ordered editions that
recursively refer to other ordered editions. However, this recursion
code incorrectly activated if the source files had ordered chapters
even if the main file only wanted to use them as raw video, resulting
in broken timeline info overall.

Ordered chapters can specify a ChapterSegmentEditionUID value if they
want to use a specific edition from a source file. Otherwise the
source is supposed to be used as a raw video file. The code checked
demuxer->matroska_data.num_ordered_chapters for an opened source file
to see whether it was using a recursive ordered edition, but demux_mkv
could enable a default ordered edition for the file using the normal
playback rules even if the main file had not specified any
ChapterSegmentEditionUID. Thus this incorrectly enabled recursion if a
source file had a default edition using ordered chapters. Check
demuxer->matroska_data.uid.edition instead, and ensure it's never set
if a file is opened without ChapterSegmentEditionUID.

Also fix what seems like a memory leak in demux_mkv.c.

Signed-off-by: wm4 <wm4@nowhere>
2016-10-22 18:45:06 +02:00
wm4 3a78eefc88 demux_mkv: don't recursively resolve timeline for opened reference files
Instead, resolve all references and so on in the top-level timeline.
2016-10-22 17:17:04 +02:00
wm4 1bf474e19a options: make --load-scripts runtime changeable
Just that actually changing it at runtime won't do anything.

This deals with a nasty initialization order issue with encoding.
Encoding is initialized after options have initialized, but before
--load-scripts is checked and executed. Encoding initialization accesses
FFmpeg API, thus it has to run after FFmpeg is initialized (which also
implies it's initialized after options/logging init). On the other hand,
it sets the encoding builtin profile, which possibly sets --load-scripts
to "no". That failed at this point because --load-scripts was marked as
fixed.

Just marking it as not fixed gets rid of the headache, even if it's not
perfectly orthodox.
2016-10-22 16:39:24 +02:00
wm4 bf5c4c42fa command: silence deprecation warnings with --reset-on-next-file=all
--reset-on-next-file=all triggers m_config_backup_all_opts(), which
backups all options (even deprecated ones). Later, when the option
values are reset with m_config_restore_backups(), mp_on_set_option() is
called, which in turn calls mp_property_do_silent(), which in turn will
call mp_property_generic_option() and m_config_get_co(), which triggers
the deprecation message.

Unfortunately there's no good way to determine whether an option has
actually changed (there's no option value compare operation), so the
deprecated options have to be set no matter what. On the other hand, we
can't pass through additional flags through the property layer. So we
add a dumb global flag to silence the deprecation warnings in these
cases.

Fortunately m_config_get_co_raw() works to silence the warnings.
m_config_get_co() also resolves aliases (deprecated and non-deprecated),
but aliased options are handled differently by the option-property
bridge, so we don't need to do that here, so the only purpose of it is
to trigger a warning for deprecated (non-alias) options.
2016-10-22 16:02:52 +02:00
wm4 11b8cbcce7 command: fix reset-on-next-file=all and tv-freq option
The tv-freq options and properties use different types, thus must be
treated as incompatible. Fixes an assertion with reset-on-next-file=all,
which tries to set the option.

Fixes #3708.
2016-10-22 15:34:15 +02:00
wm4 082340b467 options: handle legacy no-* sub-options
These accidentally did nothing. They must be handled explicitly.

Example: --vo=vdpau:no-composite-detect

(Can't wait to get rid of this crap.)
2016-10-21 19:09:15 +02:00
wm4 5f544c1081 manpage: fix a renamed option name 2016-10-21 18:50:40 +02:00
wm4 9ea9bdf130 vo_opengl: context_rpi: fix stdatomic usage
atomic_bool is not supported with e.g. atomic_fetch_and.

Fixes #3699. Untested.
2016-10-21 17:35:48 +02:00
wm4 202f695398 vo_opengl: partially re-enable glFlush() calls
It turns out the glFlush() call really helps in some cases, though only
in audio timing mode (where we render, then wait for a while, then
display the frame). Add a --opengl-early-flush=auto mode, which does
exactly that.

It's unclear whether this is fine on OSX (strange things going on
there), but it should be.

See #3670.
2016-10-21 17:23:26 +02:00
wm4 f64de3ea66 player: don't leave buffering during underflow
Don't leave the buffering state while the demuxer is still marked as
having underflowed. It's unclear why this hasn't been done before - with
the logic being complicated as it is, maybe there was a reason for this.

This is actually still not very reliable, but should be better than what
was before: on stream switching decoders can read packets all while the
demuxer is executing a refresh seek, which creates the underrun
situation - but nothing really totally guarantees that the underrun
state remains stable when the demuxer is back at the current demuxer
position. Anyway, it's an improvement.

The rest of the touched condition is not changed, just moved around for
cosmetic reasons.
2016-10-21 17:11:26 +02:00
wm4 61a51c57a9 demux: don't try to refresh unselected streams
This could cause nonsensical queue overflow warnings, but was otherwise
probably harmless.
2016-10-21 17:11:26 +02:00
Rodger Combs b8b3163b85 wscript: rebuild on library header changes
In particular, libav<x>/version.h changing should trigger a rebuild
2016-10-21 17:11:26 +02:00
Thomas Nagy d38baa65ca build: Set a default error message for #3692
This change will prevent annoying exceptions from
appearing when error messages are missing.
2016-10-21 17:11:26 +02:00
Aman Gupta 8b00d82b79 player: guard against MPSEEK_RELATIVE when current pts is unknown
in very rare circumstances, doing a relative seek like +1s will end up
doing an absolute seek to 00:01. this guards against that possibility.

so far i've only ever seen this issue when using --ad=lavc:ac3_at and
doing several relative seeks in quick succession. this is likely either
a bug in the audiotoolbox decoder in ffmpeg, or simply due to inherent
latency in that hardware decoder which causes brief periods of time
where the current audio pts is unknown.
2016-10-21 17:11:26 +02:00
Aman Gupta 7cd32ec29e audio: force pts_reset only when pts jumps forward more than 5s
i've seen several mpegts samples where pts jumps backwards and repeats
itself. this usually happens on live tv streams from cable providers,
particularly when the stream switches from one advertisement to another.
2016-10-21 17:11:26 +02:00
Aman Gupta 183af9d72e player: speed up audio/video re-sync when there is a huge delay
when there is a huge delay between audio/video sync, it can take a
really long time to converge back. this speeds up the resync time by
increasing the max_change allowed per iteration.

Signed-off-by: wm4 <wm4@nowhere>
2016-10-21 17:11:26 +02:00
Ricardo Constantino ea03ae157f TOOLS/appveyor-install: install uchardet release instead 2016-10-21 15:25:18 +01:00
Ricardo Constantino a6da4faac5 osc: fix crash after reaching a certain position in limited lists
Don't try to display more items than there are in the chapter/playlist.
Fixes #3691
2016-10-20 19:07:35 +01:00
wm4 773d52162e build: add required failure message for libavfilter check
If req==True, a fmsg must be set (apparently).

Fixes #3692, probably.
2016-10-20 19:54:06 +02:00
wm4 cc9e8e7e3d vo: vo_tct is now available on non-POSIX
Fixes Windows build.
2016-10-20 18:30:47 +02:00
Dmitrij D. Czarkoff ee2ba599e7 build: don't rely on "__thread" being always available with GCC
Thread-local storage in GCC is platform-specific, and some platforms that
are otherwise perfectly capable of running mpv may lack TLS support in GCC.

This change adds a test for GCC variant of TLS and relies on its result
instead of assumption.

Provided that LLVM's `__thread` support is similar to GCC, the test is
called "GCC/LLVM TLS".

Signed-off-by: wm4 <wm4@nowhere>
2016-10-20 17:51:57 +02:00
Aman Gupta 26458419a7 wscript: videotoolbox is available on iOS even though IOSurface is not 2016-10-20 17:45:27 +02:00
Aman Gupta 4bd3e51fbe opengl: compile against iOS OpenGLES implementation 2016-10-20 17:45:25 +02:00
wm4 5da510b5fc vf_vdpaurb: deprecate this filter 2016-10-20 16:45:48 +02:00
wm4 6b18d4dba5 video: add --hwdec=vdpau-copy mode
At this point, all other hwaccels provide -copy modes, and vdpau is the
exception with not having one. Although there is vf_vdpaurb, it's less
convenient in certain situations, and exposes some issues with the
filter chain code as well.
2016-10-20 16:43:02 +02:00
rr- dd02369c32 vo_tct: introduce modern caca alternative 2016-10-20 14:59:54 +02:00
Aman Gupta 7684483052 demux_lavf: set title on hearing and visual impaired tracks 2016-10-20 14:56:00 +02:00
Martin Herkt e6b85c9170 Release 0.21.0 2016-10-19 23:10:13 +02:00
Martin Herkt 5d74fa7dc0 Merge branch 'master' into release/current 2016-10-19 19:09:00 +02:00
wm4 a2fa0d0b68 demux_lavf: don't accidentally enable edit list crap on Libav
You really don't get a break from all the multiple bullshit.
2016-10-18 19:14:15 +02:00
wm4 b86a2316df demux_lavf: "support" mov edit lists and log errors if used
FFmpeg recently got "support" for mov edit lists. This is a terrible
hack that will fail completely at least with some decoders (in
particular wrappers for hardware decoding might be affected). As such it
makes no point to pretend they are supported, even if we assume that the
"intended" functionality works, that there are no implementation bugs
(good luck with all that messy code added to the already huge mov
demuxer), and that it covers enough of the mov edit list feature to be
of value.

So log an error if the FFmpeg code for mov edit lists appears to be
active - AV_PKT_FLAG_DISCARD is used only for "clipping" edit list
segments on non-key frame boundaries.

In the first place, FFmpeg committed this only because Google wanted it
in, and patch review did not even pick up obvious issues. (Just look how
there was no lavc version bump when AV_PKT_FLAG_DISCARD was added.)

We still pass the new packet flag to the decoders (av_common.c change),
which means we "support" FFmpeg's edit list code now. (Until it breaks
due to FFmpeg not caring about all the details.)
2016-10-18 16:57:02 +02:00
Ricardo Constantino 912d668ea8 osc: use the same characters as track list for playlist/chapter
Had only tested with luajit which supports the \xHH syntax added
in Lua 5.2.

The arrow is troublesome to use since the ideal way to use it, as
the OSD code uses it, needs \alpha&H00<arrow>\r to work, which
does not in OSC's way of showing messages.
2016-10-17 19:00:17 +01:00
Ben Boeckel c398ab7520 ISSUE_TEMPLATE: minor grammar update 2016-10-17 19:23:23 +02:00
schnusch 68839e4e77 stream_bluray: check title index/playlist range
Blu-ray title index/playlist must be in the range 0-99999, otherwise
an error will be returned
2016-10-17 19:23:11 +02:00
schnusch 51dbb5607e stream_bluray: select title by playlist
Blu-ray titles can now be selected by playlist number like this:
    bd://mpls/[playlist]
2016-10-17 19:23:07 +02:00
wm4 139f6b5de7 ad_lavc, vd_lavc: fix a recent libavcodec deprecation warning
Both AVFrame.pts and AVFrame.pkt_pts have existed for a long time. Until
now, decoders always returned the pts via the pkt_pts field, while the
pts field was used for encoding and libavfilter only. Recently, pkt_pts
was deprecated, and pts was switched to always carry the pts.

This means we have to be careful not to accidentally use the wrong
field, depending on the libavcodec version. We have to explicitly check
the version numbers. Of course the version numbers are completely
idiotic, because idiotically the pkg-config and library names are the
same for FFmpeg and Libav, so we have to deal with this explicitly as
well.
2016-10-17 19:18:03 +02:00
Ricardo Constantino 118d7a310e man/osc: better explain the values of deadzonesize 2016-10-17 16:01:25 +01:00
Philip Langdale 0a81fe1cf9 vd_lavc: Add hwdec wrapper for crystalhd
This hardware decodes to system memory so it only requires a wrapper.
2016-10-15 17:44:23 +02:00
Ricardo Constantino 8956229ee4 osc: fix chapter/playlist listing if empty 2016-10-15 13:58:52 +01:00
Ricardo Constantino 992bdc9411 osc: show playlist/chapter list on prev/next instead of osd 2016-10-15 12:27:04 +01:00
Ricardo Constantino 5d3657e092 osc: fix listing of chapters and playlist
Fixes regression since 05c398f.

Add helper functions for limiting potentially huge lists of
playlists and chapters and use them.
2016-10-15 12:27:04 +01:00
Ricardo Constantino 06065dc5ef osc: fix display of chapters and playlist scaling
Compensate \fs when using non-default scale(fullscreen|windowed).
2016-10-15 12:27:04 +01:00
Ricardo Constantino 2a99e7ae12 osc: add user-alterable margin for top/bottombar 2016-10-15 12:24:01 +01:00
Ricardo Constantino b99dc17f8e osc: add right-click behavior to playlist and chapter buttons 2016-10-15 12:24:01 +01:00
Ricardo Constantino 8bb57c0387 osc: change default layout to bottombar
Change a few other defaults accordingly:
- seekbarstyle=bar looks better with bottombar.
- Bigger scalewindowed and scalefullscreen make bottom/topbar more readable.
2016-10-15 12:24:01 +01:00
Ricardo Constantino 13259f35c8 ytdl_hook: Add title to playlist items if available 2016-10-15 01:33:27 +01:00
wm4 a049a3240e stream_file: don't use poll() on directories
POSIX leaves poll() behavior on directories unspecified. While on
Linux, it seems to behave the same way as regular files (always
return immediately), this is not guaranteed. At least with OSX
10.12, it seems to wait, which essentially means that opening
directories will "hang".

Fixes #3530 and #3649.
2016-10-14 17:19:47 -06:00
James Ross-Gowan 0af8811b15 terminal-win: support modifier keys in console input
Keyboard input in the console still isn't quite as flexible as it is in
the video window. Ctrl+<letter> and Ctrl+LEFT/RIGHT work, but
Ctrl+Alt+<letter> and Ctrl+<number> do not. Also, in the new Windows 10
console, a bunch of Ctrl keystrokes including Ctrl+UP/DOWN are handled
by the console window and not passed to the application.

Unlike in w32_common.c, we can't really translate keyboaard input
ourselves because the keyboard layout of the console window (in
conhost.exe) doesn't necessarily match the keyboard layout of mpv's
console input thread, however, using ToUnicode as a fallback when the
console doesn't return a unicode value could be a possible future
improvement.

Fixes #3625
2016-10-14 08:44:33 +11:00
James Ross-Gowan 6a8d1cdd49 terminal-win: clean up console input
The original version of this code in getch2-win.c fetched 128 console
events at once. This was probably to maximize the chance of getting a
key event if there were other events in the buffer, because it returned
the value of the first key event it found and ignored all others. Since
that code was written, it has been modified to receive console input in
an event-based way using an input thread, so it is probably not
necessary to fetch so many events at once any more. Also, I'm not sure
what it would have done if there were more than 128 events in the
console input buffer. It's possible that fetching multiple events at a
time also had performance advantages, but I can't find any other
programs that do this. Even libuv just fetches one console event at a
time.

Change read_input() to fetch only one event at a time and to consume all
available events before returning to WaitForMultipleObjects. Also remove
some outdated comments and pass the console handle through to the input
thread instead of calling GetStdHandle multiple times (I think this is
theoretically more correct because it is possible for the handles
returned by GetStdHandle to be changed by other threads.)
2016-10-14 08:44:33 +11:00
wm4 b5357e8ba7 ao_alsa: try to fallback to "hdmi" before "iec958" for spdif
If the "default" device refuses to be opened as spdif device (i.e. it
errors due to the AES0 etc. parameters), we were falling back to the
iec958 device. This is needed on some systems for smooth operation with
PCM vs. spdif.

Now change it to try "hdmi" before "iec958", which supposedly helps in
other situations.

Better suggestions welcome. Apparently kodi does this too, although I
didn't check directly.
2016-10-07 17:21:08 +02:00
Ricardo Constantino 65c75112a7 osc: move tooltip to inside seekbar for top/bottombar
Tooltip border is user-alterable
2016-10-07 00:31:49 +01:00
Ricardo Constantino e41dbc3019 osc: change seekbar background's alpha scaling
This avoids a full transparent seekbar with only boxalpha=115.

No change with default values.
2016-10-07 00:31:48 +01:00
Ricardo Constantino 7022a24542 osc: align text vertically in top/bottombar
Close #2093
2016-10-07 00:24:12 +01:00
rr- 403f489f6c vo_drm: change CLI options + refactors
- Change connector selection to accept human readable names (such as
  eDP-1, HDMI-A-2) rather than arbitrary numbers.
- Change GPU selection to accept GPU number rather than device paths.
- Merge connector and GPU selection into one --drm-connector.
- Add support for --drm-connector=help.
- Add support for --drm-* in EGL backend.
- Refactor KMS; reduce state sharing across drm_common.
2016-10-07 00:22:23 +02:00
Maurycy Skier e9c43258b8 ytdl_hook: add chapters by parsing video's description 2016-10-06 21:18:43 +01:00
Martin Herkt c3ae2ff107 man: fix PDF build
It really doesn’t want to pagebreak that box, so I removed a
useless example.
2016-10-06 21:49:14 +02:00
rr- ea1b183f4c vo_drm: fix segfault when using invalid card 2016-10-06 20:09:37 +02:00
Akemi e543853a7f cocoa: add glFlush() to cocoa backend
The glFlush() call was made optional recently
since it's not needed in most cases. On OSX though
this is needed since we removed kCGLPFADoubleBuffer
from the context creation, so the glFlush() call
was added to the cocoa backend only.
The CGLFlushDrawable() call can be safely removed
since it only does something when a double
buffered context is used. Also fixes a small typo.
Fixes #3627.
2016-10-06 19:50:25 +02:00
wm4 9340f19ba2 TOOLS/stats-conv.py: use different colors for symbols too
Also, not setting pen=None seems to draw horizontal lines for the dots,
which is fine too.
2016-10-06 19:42:18 +02:00
wm4 53798b6465 vo_opengl: apply --opengl-early-flush in dumb mode too
In "dumb mode" (where most features are disabled and which only performs
some basic rendering) we explicitly copy a set of whitelisted options,
and leave all the other options at their default values. Add the new
--opengl-early-flush option to this whitelist. Also remove an option
field accidentally added in the commit adding --opengl-early-flush.
2016-10-05 20:35:00 +02:00
wm4 d7e587acc9 options: handle --audio-device changes like the other options
Don't require special property code for handling updates, and simply use
the UPDATE_AUDIO flag instead. Also make runtime changes to
--audio-client-name take effect.
2016-10-05 16:45:04 +02:00
wm4 6fb12a5fda audio: move some fallback handling to common AO reload function
Now a reload requested by an AO behaves in exactly the same way as
changing an AO-related options (like --audio-channels or
--audio-exclusive). This is good for testing and uniform behavior. (You
could go as far as saying it's a necessity, because the spotty and
obscure AO reload behavior is hard to reproduce and thus hard to test at
all.)
2016-10-05 16:42:43 +02:00
wm4 3825dc63b2 command: flush and uninitialize audio output first on option changes
This affects changing audio configuration options. Explicitly flush and
uninitialize the audio output first before doing the rest. This should
ensure all state attached to the audio output is discarded and not used
during the reconfiguration.

Also add a comment to the reinit_audio_filters() call. It doesn't
necessarily restore the audio chain fully, but makes sure a seek is
issued if the amnount of buffered audio discarded was huge enough to
cause "problems".
2016-10-05 16:06:37 +02:00
wm4 e6291697e3 vo_opengl_cb: don't wait for redrawn frames
This also removes some extra waiting if no video is active, at least in
theory.

Also clarify the vo_frame flag comments for redraw/repeat.
2016-10-05 12:34:47 +02:00
wm4 6789f9b094 vo_opengl: disable glFlush() by default, and add an option to enable it
It seems this can cause issues with certain platforms, so better to
disable it by default. The original reason for this isn't overly
justified, and display-sync mode should get rid of the need for it
anyway.

The new option is meant for testing, and will probably be removed if
nobody comes up and reports that enabling the option actually improves
anything.
2016-10-05 12:21:34 +02:00
Kevin Mitchell 387f501278 audio: make setting audio-exclusive update the audio chain
This is required since exclusive mode requires entirely different
initializaiton.
2016-10-04 12:48:26 -07:00
wm4 39f515cb6a audio/out: prevent underruns with spdif under certain conditions
The player tries to avoid splitting frames with spdif (sample alignment
stuff). This can in certain corner cases with certain drivers lead to
the situation that ao_get_space() returns a number higher than 0 and
lower than the audio frame size. The playloop will round this down to 0
bytes and do nothing, leading to a missed wakeup. This can lead to
underruns or playback completely getting stuck.

It can be reproduced by playing AC3 passthrough with no video and:

    --ao=null --ao-null-buffer=0.256 --ao-null-outburst=6100

This commit attempts to fix it by allowing the playloop to write some
additional data (to get a complete frame), that will be buffered within
the AO ringbuffer even if the audio device doesn't want it.
2016-10-04 19:31:17 +02:00
wm4 13dcf82a96 manpage: fix closing quote 2016-10-04 16:52:36 +02:00
wm4 202f14aa29 vo_opengl: hwdec_rpi: fix NULL pointer deref in certain cases
If a client API user provides the MPGetNativeDisplay callback, but
returns NULL for "MPV_RPI_WINDOW", this would crash.
2016-10-04 16:36:20 +02:00
wm4 75cab315ea command: include deprecated/aliased options in property bridge
If we really want client API users to use mpv_set_property() instead of
mpv_set_option(), then compatibility handling of deprecated options
should be included. Otherwise, there's the danger that client API users
either break too early (and without a warning), or mpv_set_option() will
continue to have a reason to exist.
2016-10-04 13:23:11 +02:00
rr- ba3f6f3779 vo_drm: fix tiny memory leak 2016-10-04 13:23:11 +02:00
rr- 1648ff8a0f vo_drm: refactor getting display fps
Reduces code duplication between OpenGL backend and DRM VO.

(The control() for OpenGL backend isn't sufficiently similar to the
VO's control() to consider merging it as a whole - I extracted only the
FPS code.)
2016-10-04 13:23:11 +02:00
wm4 abbc8fc84a player: fix previous commit
...
2016-10-03 17:16:02 +02:00
Dan Oscarsson 7debdde9b9 options: rename subtitle options
Rename the text subtitle options from --sub-text- to --sub-
and --ass- options to --sub-ass-.
The intention is to common sub options to prefixed --sub-
and special ASS option be seen as a special version of sub options.
The OSD options that work like the --sub- options are still named
--osd-.
Man page updated including a short note about renamed --sub-text-*
and --ass-* options to --sub-* and --sub-ass-*.
2016-10-03 16:57:04 +02:00
wm4 81d125efd8 DOCS/interface-changes.rst: mention seek command change
This is potentially incompatible if a program used negative timestamps
to deal with timestamp resets, which would potentially lead to mpv
producing and using negative timestamps.
2016-10-03 15:49:53 +02:00
Philip Sequeira ff531b71e3 command: allow absolute seeks relative to end of stream
"seek -10 absolute" will seek to 10 seconds before the end. This more or less
matches the --start option and negative seeks were otherwise useless (they just
clipped to 0).
2016-10-02 18:01:52 +02:00
wm4 3a5cbf3907 audio: fix late audio start
Regression since commit bbcd0b6a. This code is just cursed, because it's
a fragile state machine with no proper tests, and which could be done in
a much simpler way. Without doubt this change will cause a regression in
some ridiculous corner case as well.

Fixes #3610 (the cause of it, not the behavior it resulted in).
2016-10-02 13:47:25 +02:00
wm4 6f4d918cb7 audio: dump timestamp difference
Can help to analyze timestamp jitter or seeing completely bogus
timestamps.
2016-10-02 12:55:22 +02:00
Bernhard Frauendienst 8d29d5b5d7 vaapi: support drm devices when running in vaapi-copy mode
When the vaapi decoder is used in copy mode, it creates a dummy
display to render to. In theory, this should support hardware
decoding on on a separate GPU that is not actually connected to
any output (like an iGPU which supports more formats than the
external GPU to which the monitor is connected).

However, before this change, only X11 displays were supported as
dummy displays. This caused some graphics drivers (namely
intel-driver) to core dump when they were not actually used as X11
module.
This change introduces support for drm libav displays, which
allows vaapi-copy to run on such cards which are not actually
rendering the X11 output.
2016-10-02 12:38:33 +02:00
wm4 39fc5e1deb player: make --stop-screensaver runtime-changeable
Move the screensaver enable/disable determination to a central place,
and call it if the stop-screensaver property is changed.

Also, do not stop the screensaver when in idle mode (i.e. no file is
loaded).

Fixes #3615.
2016-10-02 12:33:34 +02:00
wm4 e3a57272a7 stream_libarchive: add some more points at which reading can be stopped 2016-10-01 18:19:57 +02:00
wm4 486b3ce6f8 vo_opengl: minor simplification
The extra gl_transform_trans() has no apparent use.
2016-10-01 16:12:03 +02:00
wm4 82231fd74d vo_opengl: attempt to fix chroma offset under rotation and flipping
Other than being overly convoluted, this seems to make sense to me.
Except that to get the "rot" transform I have to set flip=true, which
makes no sense at all to me.
2016-10-01 16:07:51 +02:00
wm4 052584c9e2 vo_opengl: add debugging options for testing with padded textures 2016-10-01 12:09:18 +02:00
wm4 52fea2f909 vo_opengl: partially fix dumb-mode cropping with rotation
Combining rotation and cropping didn't work. It was just completely
broken.

I'm still not sure if this is correct. Chroma positioning seems to be
broken on rotation. There might also be a problem with non-mod-2 frame
sizes. Still, strictly an improvement for both rotated and non-rotated
rendering modes.

Also, this could probably be written in a more elegant way.
2016-09-30 22:19:01 +02:00
wm4 026cccaddf csputils: add note that mp_invert_cmat() is LGPL too
Commit aa1047a3 originally added this as:

+    // this is from the DarkPlaces engine, reduces to 3x3. Original code
+    // released under GPL2 or any later version.

According to Rudolf Polzer, the original author (a certain LH) was
actually asked whether it would be ok to put this code under LGPL, and
the author gave his agreement. This code is not from id Software either
(on which large parts of DarkPlaces is based on), which is the main
reason why DarkPlaces is under GPL.

So this note is just confusing, and always has been LGPL. Fix it.
2016-09-30 17:08:24 +02:00
wm4 ea50f6fdef msg: flush after every message for --log-file
We'd like to get log messages on the output as soon as possible in the
output. I also feel like using fflush() is nicer than using setvbuf().
Who knows how the latter behaves on win32.
2016-09-30 14:55:59 +02:00
wm4 33c24b07e4 vo_opengl: vaegl: log more debugging infos 2016-09-30 14:36:42 +02:00
wm4 5f547e57e3 vo_opengl: rpi: remove dumb comment
It's not even true anymore.
2016-09-30 14:28:55 +02:00
wm4 51f10c512e vo_opengl: rpi: fix glaring memory leak
This was in previously inactive code (uploading yuv420p), so it did not
matter.
2016-09-30 13:53:12 +02:00
wm4 ab07caf39d vo_opengl: rpi: use overlay for yuv420p too
The video code can deal fine with feeding software image formats to
hwdec interop drivers. In RPI's case, this is preferable for
performance, working around OpenGL bugs (see RPI firmware issue #666),
and because OpenGL rendering doesn't bring too many advantages due to
RPI supporting GLES 2.0 only.

Maybe a way to force the normal video path is needed later. But
currently, this can be tested by just not loading the hwdec interop
driver.

If you run command-line mpv and set --hwdec to something that does
not load the RPI interop layer, you'll even have to use --hwdec-preload
manually to get it enabled.
2016-09-30 13:49:49 +02:00
wm4 2aba6972cf vo_opengl: allow hwdec interops to support multiple image formats 2016-09-30 13:46:27 +02:00
wm4 2f1af04745 vo_opengl: egl: print EGL errors only if not probing
Avoids printing an error when trying to create a GLES 3.x context on a
device which can do GLES 2.0 only.
2016-09-30 13:06:31 +02:00
wm4 d3111ee777 vo_opengl: rpi: raise the video layer
Was intended to put the GL layer above the standard console. (But
actually that was done already, and the oddness I'm seeing seems to
be an unrelated bug.)
2016-09-30 13:05:58 +02:00
wm4 1d385b0dae vd_lavc: log if hw decoding selects a different underlying decoder
Less confusing to see what's going on. I think there were more than one
users who got tricked by this, including myself.
2016-09-30 13:05:39 +02:00
wm4 7e6456f43a rpi: add --hwdec=rpi-copy
This means it can be used with normal video filters.

Might help out with #3604.
2016-09-30 13:05:30 +02:00
wm4 b6920372c2 ipc: log when listening to IPC socket
Fixes #3598.
2016-09-29 16:47:19 +02:00
wm4 86ab4b8a9f path: default ~~ paths to home directory
The code for expanding the ~~ prefix used mp_find_config_file(), which
strictly looks for _existing_ files in any config path (e.g. not just
the user-local one, but also system-wide config). If no such file
exists, it simply returns NULL, which makes the code below just return
the literal, unexpanded path.

Change this so that it'll resolve the path to the user-local config
directory instead.

Requested in #3591.
2016-09-29 16:44:01 +02:00
wm4 b81ae52f50 player: enable reading from stdin after loading input.conf
Someone requested this.
2016-09-29 16:26:54 +02:00
wm4 c245d04c37 mp_image: fix clearing to black with p010 format
Using vf_expand (which uses mp_image_clear()) with p010 cleared chroma
to green instead.
2016-09-29 16:12:58 +02:00
James Ross-Gowan f549cec0ac w32_common: implement VOCTRL_GET_DISPLAY_NAMES
This should make display-names usable on Windows. It returns a list of
GDI monitor names like "\\.\DISPLAY1". Since it may be useful to get the
monitor that Windows considers associated with the window (with
MonitorFromWindow,) this will always be returned as the first argument.
This monitor is the one used for display-fps and icc-profile-auto.
2016-09-29 23:49:36 +10:00
Ricardo Constantino 6487ba4864 ytdl_hook: Set aspect ratio for anamorphic video 2016-09-28 21:16:40 +02:00
Philip Langdale 1557ca6712 cuda: initialize hwframes format
In retrospect, this seems obvious, but ffmpeg didn't complain until
a recent update.
2016-09-28 21:10:15 +02:00
wm4 b344da22ae client API: "priority" option is now runtime settable
So it doesn't have to be in the list of options that can be set before
mpv_initialize() only.
2016-09-28 15:26:24 +02:00
wm4 ef2bbd5a7a msg: make --log-file and --dump-stats accept config path expansion
Seems like a valid use-case. Not sure if I like it calling back into the
config code. Care has to be taken for not letting the config path
resolving code dead-lock (which is why locking details in the msg.c code
are changed).

Fixes #3591.
2016-09-28 15:04:38 +02:00
wm4 73a5bde518 img_format: remove some unneeded format definitions
They're still supported, just that they have no IMGFMT_ alias.
2016-09-28 14:21:32 +02:00
James Ross-Gowan b712095d89 win32: make --priority runtime-settable
I'm not sure if this option affects anything or if it's a placebo,
especially since the VO thread is now registered with MMCSS. Still, I
think --priority=high may have helped back when I used mplayer2 on a
netbook. It's also possible that encoding-mode users would want to set
--priority=idle.

Anyway, it was one of the last M_OPT_FIXED options, so fix that.
2016-09-28 21:47:30 +10:00
James Ross-Gowan 3751065f97 win32: build with -DINITGUID
We always want to use __declspec(selectany) to declare GUIDs, but
manually including <initguid.h> in every file that used GUIDs was
error-prone. Since all <initguid.h> does is define INITGUID and include
<guiddef.h>, we can remove all references to <initguid.h> and just
compile with -DINITGUID to get the same effect.

Also, this partially reverts 622bcb0 by re-adding libuuid.a to the
build, since apparently some GUIDs (such as GUID_NULL) are not declared
in the source file, even when INITGUID is set.
2016-09-28 21:38:52 +10:00
wm4 c239b7de7e vo_opengl: deprecate 'drm-egl' backend and introduce 'drm' instead
Just a name change. Requested.
2016-09-27 16:29:22 +02:00
wm4 45c97aea78 stream_lavf: check seekable flag correctly
AVIOContext.seekable is actually a bitfield. Currently, it has only
AVIO_SEEKABLE_NORMAL defined, but it might be extended with a hint for
non-byte seekability. Thus we should check it correctly.
2016-09-27 15:51:34 +02:00
wm4 b6cbf74518 command: fix inverted condition in sub-reload command
Fixes #3586 (probably). Untested.
2016-09-26 20:12:59 +02:00
rr- 0fe3e9ca5e vo_drm: provide display fps 2016-09-26 19:26:31 +02:00
Akemi 9f30cd8292 cocoa: fix fullscreen regression on 10.11 and newer
Fixes #3364.
2016-09-26 19:25:50 +02:00
Ricardo Constantino f0ab9f05f1 player: allow opts in pseudo-gui set by the user to override user's default
This should still allow user-set default options to override built-in
pseudo-gui while respecting user-set pseudo-gui options.

Pros:
- user option in default profile overrides built-in pseudo-gui's options
  Ex: screenshot-directory overrides built-in pseudo-gui's
- user can "fix" pseudo-gui if some option like "force-window=no" is set
  in default by setting "force-window=yes" in [pseudo-gui]
- `mpv --profile=pseudo-gui` will work as before

Cons:
- --show-profile=pseudo-gui won't display the built-in's options

Original idea from wm4.

Documentation edits mostly by wm4.

Signed-off-by: wm4 <wm4@nowhere>
2016-09-26 19:25:14 +02:00
wm4 dd339b200b video: trust demuxer framerate on invalid timestamps
If the PTS goes backwards (whether it's a timestamp reset or some other
problem) would just use 0 as frame duration. (At least until the logic
for detecting divergence with the timestamps gets active.)

Trust the demuxer framerate in these cases instead, if it's available. I
think this improves behavior slightly with some broken files.
2016-09-26 17:55:00 +02:00
wm4 e6dedbcc23 qthelper: introduce new convenience functions
(Why the heck is the C++ helper not in a separate repository?)
2016-09-26 16:49:35 +02:00
wm4 a314b1013f scripting: don't attempt to load builtin scripts twice
During init it will first call mp_load_builtin_scripts(), and then again
via mp_load_scripts().

This was harmless (a second attempt won't load it again if the first one
was successful), but it's unnecessary, and also looks confusing if the
scripts failed to load the first time.
2016-09-26 16:49:35 +02:00
wm4 0f110ad0e2 stream_lavf: fix determining seekability
demux_lavf.c forces seek to being determined as supported if
STREAM_CTRL_HAS_AVSEEK is returned as success. But it always succeeds
with current FFmpeg versions. (Seems like Libav commit cae448cf broke
this in early 2016.)

Now we can't determine via private API whether the underlying protocol
supports read_seek anymore. The affected protocols (mostly rtmp) also
set seekable=0, meaning they signal they're not seekable, even though
read_seek would work. (My guess is that this can't be fixed because even
though seekable is in theory a combination of elaborate flags [of which
only 1 is defined, AVIO_SEEKABLE_NORMAL], a seekable!=0 always means
it's byte-seekable in some way.)

So the FFmpeg API is being garbage _again_, and all what we can do is
determining this via protocol name and a whitelist.

Should fix the behavior reported in #1701.
2016-09-26 16:49:35 +02:00
Kevin Mitchell 41002c46f5 DOCS/compile-windows.md: update msys2 instructions again
they keep changing things. . .
2016-09-25 17:29:45 -07:00
Ricardo Constantino 29d74ca2f5 osc: Fix scaling issues when toggling fullscreen
Fixes #3429
2016-09-25 16:10:48 +02:00
wm4 077dd27df2 sd_ass: fix top alignment of secondary subtitles
Secondary subtitle streams (to be shown on the top of the screen along
main subtitle stream) were shown with normal alignment. This is because
we tell libass to override the alignment style (a relatively recent
change, see commit 2f1eb49e). This would behave differently with old
libass versions too.

To escape the mess, just set the alignment explicitly with an override
tag instead of modifying the style.
2016-09-25 01:03:59 +02:00
wm4 cad6fb038b lua: complain loudly if Lua state creation fails
This should normally happen only if memory allocation for the state
happens, which should be extremely rare. But with Luajit on OSX, it can
happen if the magic compiler flags required by Luajit were not passed to
mpv compilation. Print an error to reduce confusion.
2016-09-25 01:00:20 +02:00
wm4 733218b233 options: do not mark --profile/--include as M_OPT_FIXED
The intention of M_OPT_FIXED is to make options not runtime-changeable,
so trying to set them at runtime will always error. This is not wanted
for --profile and --include, for which there is no reason to block them
at runtime.

Fixes #3581.
2016-09-24 20:41:07 +02:00
wm4 88f10ec84f player: fix instant subtitle refresh on track switches
When switching a subtitle track, the subtitle wasn't necessarily
updated, especially when playback was paused.

Some awfully subtle and complex interactions here.

First off (and not so subtle), the subtitle decoder will read packets
only on explicit update_subtitles() calls, which, if video is active, is
called only when a new video frame is shown. (A simply video frame
redraw doesn't trigger this.) So call it explicitly. But only if
playback is "initialized", i.e. not when it does initial track selection
and decoder init, during which no packets should be read.

The second issue is that the demuxer thread simply will not read new
packets just because a track was switched, especially if playback is
paused. That's fine, but if a refresh seek is to be done, it really
should do this. So if there's either 1. a refresh seek requested, or 2.
a refresh seek ongoing, then read more packets.

Note that it's entirely possible that we overflow the packet queue with
this in unpredicated weird corner cases, but the queue limit will still
be enforced, so this shouldn't make the situation worse.
2016-09-24 19:57:19 +02:00
wm4 2361ec35aa lua: fix array detection
This was dumb and could return something like "{name=123}" as an array.

Also, fix the error message if a key is not a string. lua_typename()
takes a type directly, not a stack item.
2016-09-24 17:52:36 +02:00
wm4 68d2903cb1 command: some minor corrections to previous commit
The last commit was fine - just making some enhancements.

Rename the function to parse_node_chapters(), since it really has not
much to do with Lua.

Don't use len<0 as check whether it makes sense to set chapters, and
instead check for mpctx->demuxer (that includes the possibility to set
chapters e.g. within a preload hook, but after chapters are initialized
from the demuxer).

Return M_PROPERTY_ERROR instead of M_PROPERTY_OK if the mpv_node has the
wrong type.

It's ok if a chapter has no title, so change the checks accordingly.

Remove a Yoda condition.

Notify that chapter metadata might have changed with mp_notify() (the
chapter list itself is already taken care by generic code).

Fix leaking the metadata allocations of the new chapter list.
2016-09-24 17:51:23 +02:00
Maurycy Skier e2e9a7faa8 command: make it possible to set chapters via lua plugins 2016-09-24 17:17:49 +02:00
Philip Langdale 343da8d73d vo_opengl: hwdec_cuda: get the cuda device from the GL context
Obviously, in the vast majority of cases, there's only one device
in the system, but doing this means we're more likely to get a
usable device in the multi-device case.

cuda would support decoding on one device and displaying on another
but the peer memory handling is not transparent and I have no way
to test it so I can't really write it.
2016-09-24 17:11:09 +02:00
Philip Langdale 441febfcba vo_opengl: hwdec_cuda: directly map GL textures and skip using PBOs
The documentation around this stuff is poor, but I found an nvidia
sample that demonstrates how to use the interop API most efficiently.

(https://github.com/nvpro-samples/gl_cuda_interop_pingpong_st)

Key lessons are:
1) you can register the texture itself and have cuda write to it,
   thereby skipping an additional copy through the PBO.
2) You don't have to be mapped when you do the copy - once you get a
   mapped pointer, it remains valid. Magic!

This lets us throw out the PBOs as well as much of the explicit
alignment and stride handling.

CPU usage is slightly (~3%) lower for 4K content in one test case,
so it makes a detectable difference, and presumably saves memory.
2016-09-24 17:11:06 +02:00
Philip Langdale cb46f73cbb manpage: hwdec_cuda: update docs to say 10bit hevc is supported
Now that ffmpeg bundles working headers, this no longer relies
on a custom ffmpeg build with a hacked up header file.
2016-09-24 17:11:04 +02:00
wm4 1500c84226 player: fix intended pseudo-gui behavior
It's still supposed to be possible to customize the pseudo-gui section.
2016-09-23 22:35:54 +02:00
wm4 9eef41dec1 player: do not let pseudo-gui override user config settings
Seems like this confused users quite often.

Instead of --profile=pseudo-gui, --player-operation-mode=pseudo-gui now
has to be used to invoke pseudo GUI mode. The old way still works, and
still behaves in the old way.
2016-09-23 21:24:50 +02:00
wm4 f0fd663320 m_config, command: remove some minor code duplication
I would have been fine with this, but now I want to add another flag,
and the duplication would become more messy than having a strange
function for deduplication.
2016-09-23 21:04:20 +02:00
wm4 b9153ee177 TOOLS/lua/observe-all: explicitly observe all options 2016-09-23 20:49:23 +02:00
wm4 f4db6b8479 command: make most options observable
The property observation mechanism turns properties into integer IDs for
fast comparison. This means if two properties get the same ID, they will
receive the same notifications. Use this to make properties under
options/ receive notifications. The option-property bridge marks
top-level properties with the same name as the options.

This still might not work in cases the C code sets values on options
structs directly.
2016-09-23 20:49:08 +02:00
wm4 5f2822d502 vo_opengl: hwdec_rpi: remove copy&paste error 2016-09-23 19:45:16 +02:00
wm4 9664bc23d5 vo: log framedrops
Seems useful. (This was possibly added ages ago and then removed.)
2016-09-23 19:44:46 +02:00
wm4 6f6c4a57ec command: fix potential UB
Pointed out by quilloss on github.
2016-09-23 15:21:59 +02:00
wm4 caa14e3d45 x11: fix external fullscreen update
On x11, you can change the fullscreen via the window manager and without
mpv's involvement. In these cases, the internal fullscreen flag has to
be updated.

The hack used for this didn't really work properly. Change it
accordingly. The important thing is that the shadow copy of the option
is updated. This is still not really ideal.

Fixes #3570.
2016-09-23 12:09:48 +02:00
Niklas Haas 3a43682355 aspect: use nominal width instead of actual width for video-unscaled
The documentation claims that --video-unscaled will still perform
anamorphic adjustments, and it rightfully should. The current reality is
that it does not, because the video-unscaled size was based on the wrong
set of variables. (encoded width/height instead of nominal display
width/height)
2016-09-22 21:24:56 +02:00
wm4 075edc6fee player: make audio-channels etc. runtime settable
If one of the audio output format options is set, brually reinit the
audio chain.

Since the audio-channels property is still mapped to the deprecated
read-only property, "options/audio-channels" currently has to be used,
e.g. "cycle-values options/audio-channels 2 7.1".
2016-09-22 20:57:06 +02:00
wm4 2ac74977c5 command: add a load-script command
The intention is to give libmpv users as much flexibility to load
scripts as using mpv from CLI, but without restricting libmpv users from
having to decide everything on creation time, or having to go through
hacks like recreating the libmpv context to update state.
2016-09-22 20:57:06 +02:00
wm4 01e95468f9 player: remove some explicit options accesses when saving resume file
Basically, make use of all the new code.

Unfortunately, the new code and it's "compromise semantics" with the old
behavior before the options/properties merge bites back: this
vid/aid/sid, deinterlace, and video-aspect properties have neutral
default settings (such as "auto"), but return the current value during
playback, so we would unnecessarily force this value when playback is
resumed. So leave those as they are.

Also, the colormatrix options were removed a long time ago.
2016-09-22 20:57:06 +02:00
wm4 efbfc00741 command: fix missing update notifications in some cases 2016-09-22 20:57:06 +02:00
wm4 6fe83fdc33 player: some M_SETOPT_RUNTIME cleanups
Add this flag where needed. You shouldn't be able to set e.g. config-dir
in these situations.

Remove the mpctx->initialized check from the property/option bridge,
since it's in use strictly only after initialization. Likewise, the
apply-profile command doesn't need to check this.
2016-09-22 20:57:05 +02:00
Ricardo Constantino 6ba2bbd090 ytdl_hook: temporarily force disable dash segments formats 2016-09-22 20:34:42 +02:00
wm4 9179e8ed21 vo: add a unique frame_id to vo_frame
We think that this allows simpler logic than using the redraw and repeat
fields. Not used yet.
2016-09-22 20:16:44 +02:00
wm4 c296b6204f vo_opengl: apply 90° rotation to chroma texture size
When we rotate the inmage by 90° or 270°, chroma width and height need
to be swapped.

Fixes #3568.

But is the chroma sub location correct? Who the hell knows...
2016-09-22 15:16:53 +02:00
Philip Langdale e300bfcf3a hwdec/cuda: Document how to activate cuda deinterlacing
The latest changes to the decoder in ffmpeg enable frame doubled
deinterlacing so that it's actually useful. Let's document how to
use it.
2016-09-22 13:46:27 +02:00
Akemi 9df797575f cocoa: fix macOS 10.12 deprecation warnings 2016-09-22 13:46:27 +02:00
David Logie 78b3852f7e player: add --watch-later-directory option
This option allows the user to set the directory where "watch later"
files are stored.

Signed-off-by: wm4 <wm4@nowhere>
2016-09-22 13:46:19 +02:00
wm4 7783f0b7d7 client API: more or less deprecate mpv_set_option()
With the merging of options and properties, the mpv_set_option()
function is close to being useless, and mpv_set_property() can be used
for everything instead. There are certain conflicts remaining, which are
explained in depth in the docs. For now, none of this should affect
existing code using the client API.

Make mpv_set_property() redirect to mpv_set_option() before
initialization.

Remove some options marked as M_OPT_FIXED. The "pause" and "speed"
options cannot be written anymore without the playloop being notified by
it, so the M_OPT_FIXED does nothing. For "vo-mmcss-profile", the problem
was lack of synchronization, which has been added. I'm not sure what the
problem was with "frames" - I think it was only marked as M_OPT_FIXED
because changing it during playback will have no effect. Except for
pause/speed, these changes are needed to make them writable as
properties after mpv_initialize().

Also replace all remaining uses of CONF_GLOBAL with M_OPT_FIXED.
2016-09-21 17:35:00 +02:00
wm4 75d12c174f options: make input options generally runtime-settable 2016-09-21 17:35:00 +02:00
wm4 14c232bdbf client API: fix init/destruction race conditions
mp_new_client() blatantly accessed some mutex-protected state outside of
the mutex.

The destruction code is in theory OK, but with changes in the following
commits it'll be a bit hard to guarantee that it stays this way. Add a
simple flag that makes adding new clients impossible, so that having no
clients after shutdown_clients() remains guaranteed.
2016-09-21 17:34:55 +02:00
wm4 47f3cc7e6b lua: add API for registering idle handlers
This is only a functionality the Lua event dispatcher provides, rather
than the libmpv client API.
2016-09-21 15:47:52 +02:00
wm4 b521f15ae9 lua: run timers only after draining the event queue
Instead of rechecking the timers every time after an event is read, do
it only once the event queue is empty. This is probably slightly more
efficient, and facilitates the next commit.
2016-09-21 15:47:51 +02:00
wm4 33598182a0 manpage: lua: mention recent deprecations
These are listed in interface-changes.rst, but the documentation in the
manpage wasn't updated.
2016-09-21 12:45:27 +02:00
rr- f66f0b34c8 lua: expose subprocess_detached 2016-09-21 12:43:21 +02:00
Josh de Kock af6126adbe ao_openal: enable building on OSX
Signed-off-by: Josh de Kock <josh@itanimul.li>
2016-09-21 12:43:14 +02:00
wm4 d080851a30 command: make bitrate properties observable 2016-09-21 11:49:00 +02:00
wm4 41d9f2f058 client API: revert unintended mpv_wait_event() behavior change
Commit bf385e11 accidentally added some testing changes that were not
intended to be committed.
2016-09-21 11:47:54 +02:00
wm4 89674854ce command: add a video-dec-params property
This is the actual decoder output, with no overrides applied. (Maybe
video-params shouldn't contain the overrides in the first place, but
damage done.)
2016-09-20 15:44:26 +02:00
wm4 23639e5b0e video: handle override video parameters in a better place
This really shouldn't be in vd_lavc.c - move it to dec_video.c, where it
also applies aspect overrides. This makes all overrides in one place.
The previous commit contains some required changes for resetting the
image parameters change detection (i.e. it's not done only on video
aspect override changes).
2016-09-20 15:44:23 +02:00
wm4 e13eb3fede command: change update handling of some video-related properties
Use the new mechanism, instead of wrapped properties. As usual, extend
the update handling to some options that were forgotten/neglected
before. Rename video_reset_aspect() to video_reset_params() to make it
more "general" (and we can amazingly include write access to
video-aspect as well in this).
2016-09-20 15:44:16 +02:00
wm4 bf385e1140 player: kill associated OSD and key bindings when removing a script
The former was done already for Lua scripts, but move it to the generic
code.
2016-09-20 15:44:11 +02:00
wm4 fe872f5688 osd: fix OSD redrawing after removing external overlays 2016-09-20 15:44:06 +02:00
Kranky K. Krackpot 6b5e5b6843 man/options.rst: fix typo and layout
Signed-off-by: wm4 <wm4@nowhere>
2016-09-20 15:20:28 +02:00
Kevin Mitchell 5fca497698 audio: fix segfault when yanking USB DAC
The ao_c pointer was stale after the mpctx entry was freed / NULLed.
This prevented the correct early exit from fill_audio_out_buffers.
2016-09-20 14:46:36 +02:00
wm4 995962291a options: fix window-scale property
A recent change merged the window-scaler option and property, but forgot
that the option is float for some reason, while the property uses
double. This led to undefined behavior. Fix it by changing the option
to double too.
2016-09-20 01:25:50 +02:00
wm4 b6ba87af4b m_option: resort M_OPT_ flag values
Remove the gaps that have been added over time.
2016-09-20 01:25:10 +02:00
wm4 fb67db8b72 player: make --osc/--ytdl settable during playback
Setting the osc or ytdl properties will now load/unload the associated
scripts. (For ytdl this does not mean the currently played URL will be
reloaded.)

Also add a changelog entry for this, which also covers the preceding
work for --terminal.
2016-09-20 01:24:27 +02:00
wm4 bf5c97a6c3 options, command: simplify some option updates
Remove wrapper properties for OSD and video position updates, use the
new mechanism for them. We can mark the options directly. Update
behavior will work for more options (since I've casually marked more
affected options than the old less direct mechanism covered).
2016-09-19 20:16:44 +02:00
wm4 df85c76b7f client API: revert some relaxations about calling mpv_initialize()
My original idea was making mpv_initialize() a no-op, but it seems this
can't happen after all. The problem is especially with subtle
interactions in option parsing (basically all pre-parse options).

Instead, I might go into the opposite direction, and add a new API
function that takes over the role of mpv_create+mpv_initialize, and
which will take a list of options. This list will be for the purpose
of setting options that can be set only at initialization time (such
as config-dir). This would also make it more uniform with the command-
line player initialization.

Maybe.

In any case, for now revert parts of commit 453fea87 to remove the
initialization-related freedoms it added. Fortunately, this wasn't
released yet, so we remove it from the API as if it never happened.

(The rest of that commit is still fine, just not the additional
freedom.)
2016-09-19 20:02:53 +02:00
wm4 44a7cb7f0e player: minor changes in init code
Move the MPV_LEAK_REPORT env query to mp_create(), where it will also be
used by the client API (it might be helpful, so why not). The same
applies to MPV_VERBOSE.

The prepare_playlist() call doesn't need to be in mp_initialize() and
can just be in mp_play_files() to reduce the size of mp_initialize().

Also, remove wakeup_playloop(), which is 100% redundant with
mp_wakeup_core_cb().
2016-09-19 19:57:31 +02:00
wm4 ce65ea3345 player: make --log-file and --dump-stats freely settable at runtime
Same deal as with the previous commit. We use the file paths to decide
when we should attempt to reopen them.
2016-09-19 19:56:40 +02:00
wm4 b62634c051 player: make --terminal freetly settable at runtime
So client API users don't have to care about whether to set this before
or after mpv_initialize().

We still don't enable terminal at any point before mpv_initialize(),
because reasons.

This also subtly changes some behavior how terminal options are applied
while parsing. This essentially reverts the behavior as it was reported
in issue #2588. Originally, I was hoping to get rid of the pre-parse
option pass, but it seems this is absolutely not possible due to the way
config and command line parsing are entangled. Command line options take
priority over configfile options, so they have to be applied later - but
we also want to apply logging and terminal options as specified on the
command-line, but _before_ parsing the config files. It has to be this
way to see config file error messages on the terminal, or to hide them
if --no-terminal is used. libmpv considerations also factor into this.
2016-09-19 19:54:54 +02:00
wm4 75fe626aa6 terminal-unix: don't send quit command on terminal_uninit()
Until now, the terminal thread always sent a quit command if the
terminal thread was torn down (whether it happened via terminal_uninit()
or a quit signal). This is not so good if we want to enable toggling
terminal use at runtime, since disabling the terminal would always make
the player quit. So we want terminal_uninit() not to send quit.

This can be easily fixed by using the "death byte" sent to the pipe used
for thread tear-down to indicate whether it was caused by a signal or
terminal_uninit().
2016-09-19 19:53:08 +02:00
wm4 fe7db61035 options: slightly better option update mechanism
Extend the flag-based notification mechanism that was used via
M_OPT_TERM. Make the vo_opengl update mechanism use this (which, btw.,
also fixes compilation with OpenGL renderers forcibly disabled).

While this adds a 3rd mechanism and just seems to further the chaos, I'd
rather have a very simple mechanism now, than actually furthering the
mess by mixing old and new update mechanisms. In particular, we'll be
able to remove quite some property implementations, and replace them
with much simpler update handling. The new update mechanism can also
more easily refactored once we have a final mechanism that handles
everything in an uniform way.
2016-09-19 19:51:26 +02:00
wm4 32f235bcef options: remove some M_OPT_FIXED flags
--quiet can be always set - the playloop checks it whenever rendering
the status line. Nothing special about it.

The ytdl- options are simply refetched by the Lua script every time a
stream is opened, so it makes sense to be able to change them at runtime
as well.

The VO options don't have a real reason to be marked with it anymore.
2016-09-19 19:50:41 +02:00
Hector Martin a802afb206 command: add audio-pts property to get the audio pts
For audio files, this is identical to time-pos (except read-only).
For audio-video files, this returns the audio position. Unlike
time-pos, this is not quantized to a video frame.
For video-only files, this property is unavailable.
2016-09-19 19:45:24 +02:00
Hector Martin 297f9f1bec af_pan: fix typo
This was in the parser code all along. As far as I can tell, *cp was
intended. There is no need to check cp for NULL (nor does it make any
sense to do so every time around the loop) for AF_CONTROL_COMMAND.

However, s->matrixstr can be NULL, so checking for that separately is in
order.
2016-09-19 19:01:52 +02:00
Hector Martin f504661852 af_rubberband: default to channels=together
For stereo and typical L/R-first channel arrangements, this avoids
undesirable phasing artifacts, especially obvious when speed is changed
and then reset. Without this, there is a very audible change in the
stereo field even when librubberband is no longer actually making any
speed changes.
2016-09-19 18:59:42 +02:00
Hector Martin 57eca14a45 af_rubberband: add af-command and option to change the pitch
This allows both fixed and dynamic control over the audio pitch using
librubberband, which was previously not exposed to the user.
2016-09-19 18:56:14 +02:00
Hector Martin ed8540c38e af_pan: add af-command support to change the matrix
This allows for seamless changes in the downmixing matrix without having
to reinitialize the filter chain.
2016-09-19 14:55:58 +02:00
Hector Martin 0525f5fa93 af_pan: coding style fixes 2016-09-19 14:55:55 +02:00
wm4 08432fcbd1 command: fix "cycle"/"add" not working on most properties
Oops, this is kind of important, isn't it?

Stopped working for properties which don't implement
M_PROPERTY_GET_CONSTRICTED_TYPE directly, as do_action() goes to the
property directly, while m_property_do() does a fallback.
2016-09-18 17:55:27 +02:00
wm4 2415b69572 player: more option/property consistency fixes
Some properties had a different type from their equivalent options (such
as mute, volume, deinterlace, edition). This wasn't really sane, as raw
option values should be always within their bounds. On the other hand,
these properties use a different type to reflect runtime limits (such as
range of available editions), or simply to improve the "UI" (you don't
want to cycle throuhg the completely useless "auto" value when cycling
the "mute" property).

Handle this by making them always return the option type, but also
allowing them to provide a "constricted" type, which is used for UI
purposes. All M_PROPERTY_GET_CONSTRICTED_TYPE changes are related to
this.

One consequence is that you can set the volume property to arbitrary
high values just like with the --volume option, but using the "add"
command it still restricts it to the --volume-max range.

Also deprecate --chapter, as it is grossly incompatible to the chapter
property. We pondered renaming it to --chapters, or introducing a more
powerful --range option, but concluded that --start --end is actually
enough.

These changes appear to take care of the last gross property/option
incompatibilities, although there might still be a few lurking.
2016-09-18 16:08:21 +02:00
wm4 3ecc6d0a79 command: fix window-scale option/property inconsistencies
For some odd reason, value ranges for the window-scale option and
property are different, and the property has a more narrow range. Change
it to the option range.

Also store the window-scale value into the option value when setting the
property, so it will be persistent if the window is closed and reopened.
2016-09-18 16:08:21 +02:00
wm4 9e972ed7d2 options: rename/deprecate --playlist-pos
Conflicts with the "playlist-pos" property. They're really a bit too
different, and since the --playlist-pos option is relatively new and
obscure, just rename it to get this out of the way.
2016-09-18 16:08:21 +02:00
wm4 62d4a3891a command: minor fixes to video-aspect property
Make the option type exactly the same as the underlying option's one. I
think this has no user-visible consequences, but makes more sense for
the option-property bridge.
2016-09-18 16:08:21 +02:00
wm4 79e20ff485 options: actually deprecate --mute=auto
Also, make it internally actually an alias to "no".
2016-09-18 16:08:21 +02:00
wm4 74c342c6d3 command: fix --quiet, --really-quiet options
These are not mapped as property, so the option-property bridge has to
skip them. Do this automatically if a property is not found. I know that
this affects --quiet and --really-quiet, but in theory there could be
more.
2016-09-18 16:08:21 +02:00
James Ross-Gowan f8659d0013 displayconfig: treat a refresh rate of 1 as invalid
Found in Windows 8.1/VirtualBox.
2016-09-18 22:15:25 +10:00
RiCON 554c3a1bda stream/stream_lavf: user-agent option is deprecated
There was both user-agent and user_agent options, the former is deprecated in FFmpeg/FFmpeg@27714b462 master.
Libav uses both forms.

This avoids constant `[ffmpeg] http: the user-agent option is deprecated, please use user_agent option` warnings using ytdl_hook.
2016-09-18 11:31:11 +02:00
wm4 cb604d5412 command: add an apply-profile command
This will actually update all associated options (which is trivial now
with the recent changes).
2016-09-17 21:01:59 +02:00
wm4 a3e8ff624c options: take care of propertly updating options on runtime changes
All option write accesses are now put through the property interface,
which means runtime option value verification and runtime updates are
applied. This is done even for command line arguments and config files.

This has many subtle and not-so-subtle consequences. The potential for
unintended and intended subtle or not-subtle behavior changes is very
large.

Architecturally, this is us literally jumping through hoops. It really
should work the other way around, with options being able to have
callbacks for value verification and applying runtime updates. But this
would require rewriting the entirety of command.c. This change is more
practical, and if anything will at least allow incremental changes.

Some options are too incompatible for this to work - these are excluded
with an explicit blacklist.

This change fixes many issues caused by the mismatch between properties
and options. For example, this fixes #3281.
2016-09-17 20:48:22 +02:00
wm4 2d34171bec options: fix pseudo-options like -v
Some pseudo-options do not have associated storage, which made
m_config_set_option_raw() return failure.

Regression due to commit d1d5e9dd.
2016-09-17 20:34:00 +02:00
wm4 ffc9aa8104 manpage: document some more property/options inconsistencies 2016-09-17 19:08:35 +02:00
wm4 b44d075164 command: make window-scale redirect to option if no window created
For consistency with other properties that mirror options.
2016-09-17 19:08:17 +02:00
RiCON b7d5cbd375 DOCS: vo/ao auto profiles are deprecated
Leftovers from removal of references to ao/vo auto profiles.
2016-09-17 18:31:10 +02:00
wm4 dc48893630 options: simplify M_OPT_EXIT
There were multiple values under M_OPT_EXIT (M_OPT_EXIT-n for n>=0).
Somehow M_OPT_EXIT-n either meant error code n (with n==0 no error?), or
the number of option valus consumed (0 or 1). The latter is MPlayer
legacy, which left it to the option type parsers to determine whether an
option took a value or not. All of this was changed in mpv, by requiring
the user to use explicit syntax ("--opt=val" instead of "-opt val").

In any case, the n value wasn't even used (anymore), so rip this all
out. Now M_OPT_EXIT-1 doesn't mean anything, and could be used by a new
error code.
2016-09-17 18:07:40 +02:00
wm4 d1d5e9dda4 m_config: make option setting always call m_config_set_option_raw()
This makes m_config_set_option_raw() the function that is always called
on the lowest level (as leaf function for all other functions).

To do this, m_config_parse_option() has to do something special to deal
with "impure" options like --vf-add, which work on the previous option
value, instead of fully replacing it. m_config_set_option_raw() itself
always completely replaced the previous value.
2016-09-17 17:47:22 +02:00
wm4 7fa26bfd9c options: kill M_OPT_GLOBAL flag
This meant "cannot be used as per-file option" (wrt. playlist items).
Doesn't make too much sense anymore, especially given how obscure
per-file options are.
2016-09-17 17:04:13 +02:00
wm4 4395a4f837 player: don't enter playloop for client API requests
This _actually_ does what commit 8716c2e8 promised, and gives a slight
performance improvement for client API users which make a lot of
requests (like reading properties).

The main issue was that mp_dispatch_lock() (which client.c uses to get
exclusive access to the core) still called the wakeup callback, which
made mp_dispatch_queue_process() exit. So the playloop got executed
again, and since it does a lot of stuff, performance could be reduced.
2016-09-16 20:24:52 +02:00
wm4 56616b0b01 osd: fix OSD getting stuck with --blend-subtitles=yes
If --blend-subtitles=yes is given, vo_opengl will call osd_draw()
multiple times, once for subtitles, and once for OSD. This meant that
the want_redraw flag was reset before the OSD was rendered, which in
turn meant that update_osd() was never called. It seems like removing
the per-OSD object want_redraw wasn't such a good idea. Fix it by
reintroducing such a flag for OSDTYPE_OSD only.

Also, the want_redraw flag is now unused, so kill it.

Another regression caused by commit 9c9cf125. Fixes #3535.
2016-09-16 17:17:32 +02:00
wm4 17e3e800e1 dispatch: fix a race condition triggering an assert()
If we were waiting, and then exiting due to timeout, we still have to
recheck the condition protected by the condition variable/mutex in order
to get back to a consistent state. In this case, the queue was locked
with mp_dispatch_lock(), and mp_dispatch_queue_process() got to return
without waiting for unlock.

Also caused commit 8716c2e8. Probably an argument for replacing the
dispatch queue by a simple mutex.
2016-09-16 16:11:33 +02:00
wm4 ccf3458f8a player: fix a missed wakeup
ytdl.lua stopped working after commit 8716c2e8, because finishing the
hook did not wakeup the playloop correctly.
2016-09-16 15:51:56 +02:00
wm4 c47ae06ed8 vo_opengl: don't pass negative height to overlay_adjust()
Negative height is used to signal a flipped framebuffer. There's
absolutely no reason to pass this down to overlay_adjust(), and only
requires implementers to deal with an additional special-case.
2016-09-16 14:50:05 +02:00
wm4 8716c2e88f player: use better way to wait for input and dispatching commands
Instead of using input_ctx for waiting, use the dispatch queue directly.
One big change is that the dispatch queue will just process commands
that come in (e.g. from client API) without returning. This should
reduce unnecessary playloop excutions (which is good since the playloop
got a bit fat from rechecking a lot of conditions every iteration).

Since this doesn't force a new playloop iteration on every access, this
has to be enforced manually in some cases.

Normal input (via terminal or VO window) still wakes up the playloop
every time, though that's not too important. It makes testing this
harder, though. If there are missing wakeup calls, it will be noticed
only when using the client API in some form.

At this point we could probably use a normal lock instead of the
dispatch queue stuff.
2016-09-16 14:49:23 +02:00
wm4 15baf2789c client API: declare mpv_suspend/mpv_resume deprecated
They're useless, and I have no idea what they're actually supposed to do
(wrt. pending input processing changes).

Also remove their implicit uses from the IPC handlers.
2016-09-16 14:39:47 +02:00
wm4 03fec24e19 player: litter code with explicit wakeup calls
This does 3 kinds of changes:
- change sleeptime=x to mp_set_timeout()
- change sleeptime=0 to mp_wakeup_core() calls (to be more explicit)
- change commands etc. to call mp_wakeup_core() if they do changes that
  require the playloop to be rerun

This is preparation for the following changes. The goal is to process
client API requests without having to rerun the playloop every time. As
of this commit, the changes should not change behavior. In particular,
the playloop is still implicitly woken up on every command.
2016-09-16 14:39:45 +02:00
wm4 b8ade7c99b player, ao, vo: don't call mp_input_wakeup() directly
Currently, calling mp_input_wakeup() will wake up the core thread (also
called the playloop). This seems odd, but currently the core indeed
calls mp_input_wait() when it has nothing more to do. It's done this way
because MPlayer used input_ctx as central "mainloop".

This is probably going to change. Remove direct calls to this function,
and replace it with mp_wakeup_core() calls. ao and vo are changed to use
opaque callbacks and not use input_ctx for this purpose. Other code
already uses opaque callbacks, or has legitimate reasons to use
input_ctx directly (such as sending actual user input).
2016-09-16 14:37:48 +02:00
wm4 f845f64c2a osd: fix subtitle/overlay update problems
This could in theory lead to missed updates if subtitles were switched
or external OSD overlays (via overlay-add) were updated. While the
change IDs of each of those were consistent, switching between two
separate OSD sources is not, and we have to explicitly trigger a change.

Regression since commit 9c9cf125. The new code is actually better,
because we do exactly what is needed, and don't just mess with the
update ID for libass-based OSD.
2016-09-16 14:26:30 +02:00
Philip Langdale b83bfea05d hwdec_cuda: Rename config variable to be more consistent
'cuda-gl' isn't right - you can turn this on without any GL and
get some non-zero benefit (with the cuda-copy hwaccel). So
'cuda-hwaccel' seems more consistent with everything else.
2016-09-16 14:26:30 +02:00
wm4 cf5c3fc31a vo_opengl: rpi: cosmetic change
I almost feel sorry wasting a commit on this.
2016-09-15 14:50:38 +02:00
wm4 8bfcae748c audio: fix missed wakeup when changing audio output device
When playing audio-only, and changing the audio output device, playback
froze until the next time the playback core happened to wakeup (like
moving the mouse, or OSD redrawing). This is probably because of the
awful statemachine in fill_audio_out_buffers() - just make it recreate
the AO directly instead.
2016-09-15 14:50:38 +02:00
wm4 9c9cf125ad osd: slightly simplify update logic
Remove the per-part force_redraw flags, and instead make the difference
between flagging dirty state and returning it to the player frontend
more explicit. The big issue is that 1. the OSD needs to know the dirty
state, and it should be cleared strictly when it is re-rendered
(force_redraw flag), and 2. the player core needs to be notified once,
and the notification must be reset (want_redraw flag).

The call in loadfile.c is replaced by making osd_set_sub() set the
change flag. Increasing the change flag on dirty state (the force_redraw
check in render_object()) should not be needed, because OSD part
renderers set it correctly (at least now).

Doing this just because someone pointed this out.
2016-09-15 14:50:38 +02:00
wm4 5968a307d5 options: add --hwdec=yes as alias for --hwdec=auto
This also lets you just do "mpv --hwdec file.mkv", with the minor caveat
that the legacy syntax "--hwdec val" or "-hwdec val" (without "=") does
not work as expected anymore.
2016-09-15 14:50:38 +02:00
wm4 d1f5b926ac etc/builtin.conf: minor edits
The previous commit merely copied the profile string to a file (plus
changing how RPI-specific defaults are initialized), now make some
changes on top of it. In particular, remove the --input-lirc option,
which was removed a long time ago, but forgotten from the libmpv
profile.
2016-09-15 14:50:38 +02:00
wm4 2b0c620b22 player: move builtin profiles to a separate file
Move the embedded string with the builtin profiles to a separate
builtin.conf file. This makes it easier to read and edit, and you can
also check it for errors with --include=etc/builtin.conf. (Normally
errors are hidden intentionally, because there's no way to output error
messages this early, and because some options might not be present on
all platforms or with all configurations.)
2016-09-15 14:50:38 +02:00
wm4 98f1b5fb98 player: remove unintended !mingw ifdef for IPC uninit
Just wow. This function is implemented in ipc-win.c, and was surely be
meant to be called. But it wasn't called. This could in theory cause
crashes during exit if IPC clients were active.

Untested whether it really works.
2016-09-15 13:17:07 +02:00
wm4 1b5b23b948 client API: remove SIGPIPE overriding code
This workaround prevented that libmpv users could accidentally crash
when the SIGPIPE signal was triggered by FFmpeg's OpenSSL/GnuTLS usage.
But it also modifies the global signal handler state, so remove it now
that this workaround is not required anymore.
2016-09-15 13:13:23 +02:00
wm4 f143665864 manpage: explain "speed-adjusted" FPS for --interpolation-threshold
Fixes #3528.
2016-09-15 10:11:44 +02:00
wm4 30d147687f vo_opengl: fix OSD with icc-profile after previous commit
This happened to break because the texture unit wasn't reset to 0, which
some code expects. The OSD code in particular set the OSD texture on the
wrong texture unit, with the result that OSD/OSC was not visible.
2016-09-14 22:49:08 +02:00
wm4 88a07c5f53 vo_opengl: dynamically manage texture units
A minor cleanup that makes the code simpler, and guarantees that we
cleanup the GL state properly at any point.

We do this by reusing the uniform caching, and assigning each sampler
uniform its own texture unit by incrementing a counter. This has various
subtle consequences for the GL driver, which hopefully don't matter. For
example, it will bind fewer textures at a time, but also rebind them
more often.

For some reason we keep TEXUNIT_VIDEO_NUM, because it limits the number
of hook passes that can be bound at the same time.

OSD rendering is an exception: we do many passes with the same shader,
and rebinding the texture each pass. For now, this is handled in an
unclean way, and we make the shader cache reserve texture unit 0 for the
OSD texture. At a later point, we should allocate that one dynamically
too, and just pass the texture unit to the OSD rendering code. Right now
I feel like vo_rpi.c (may it rot in hell) is in the way.
2016-09-14 20:46:45 +02:00
wm4 e24ba8fa7f vo_opengl: require explicit reset on shader cache after rendering
The caller now has to call gl_sc_reset(), and _after_ rendering. This
way we can unset OpenGL state that was setup for rendering. This affects
the shader program, for example. The next commit uses this to
automatically manage texture units via the shader cache.

vo_rpi.c changes untested.
2016-09-14 20:24:06 +02:00
wm4 ffbc85cde9 vo_opengl: remove a redundant glActiveTexture() call
This bound video textures to individual texture units - this is how it
used to work long ago, but now is pointless, and maybe even dangerous.
2016-09-14 18:51:32 +02:00
Niklas Haas 8f1a889f75 vo_opengl: make the number of PBOs tunable
Also set the number of PBOs from 2 to 3, which should be better for
pipelining. This makes it easier to add more in the future.
2016-09-14 14:07:21 +02:00
wm4 9b6c93e904 vo_opengl: drm: use new EGL context creation code 2016-09-14 11:00:17 +02:00
wm4 c56f5f0681 vo_opengl: wayland: use new EGL context creation code 2016-09-14 10:46:52 +02:00
wm4 215268ea34 vo_opengl: EGL: dump some version info 2016-09-14 10:38:37 +02:00
wm4 d2e8bc4499 vo_opengl: EGL: better desktop-GL context creation
Stops Mesa from restricting us to OpenGL 3.0. It also tries to create
GLES 3 contexts for drivers which do not just return a higher context
when requesting GLES 2.

I don't know whether this code is a good or bad idea. A not-so-good
aspect is that we don't check for EGL 1.5 (or 1.4 extensions) for some
of the more advanced context attributes. But EGL implementations should
be able to tolerate it and return an error, and then we'd use the
fallback.
2016-09-14 10:19:09 +02:00
wm4 c48bd0ef18 vo_opengl: EGL: silence eglBindAPI() error message
It's not helpful and will be printed with EGL implementations that don't
support OpenGL at all. Just shut it up.
2016-09-13 20:38:05 +02:00
wm4 9def3682d1 vo_rpi, vo_opengl: separate RPI/EGL-specific code for both VOs
This used to be shared, but since vo_rpi is going to be removed,
untangle them. There was barely any actual code shared since the recent
changes anyway.

As a subtle change, we also stop opening libGLESv2.so explicitly in the
vo_opengl backend, and use RTLD_DEFAULT instead.
2016-09-13 20:35:53 +02:00
wm4 5819a4e301 vo_opengl: rpi: use new egl context creation helper function
Only for the "new" vo_opengl backend code.
2016-09-13 20:16:45 +02:00
wm4 060599ac6a vo_x11: fix some ifdeffery
This failed to compile when xext was not available.
2016-09-13 18:26:06 +02:00
wm4 0ccceecdc6 vo_opengl: mali fbdev support
Minimal support just for testing.

Only the window surface creation (including size determination) is
really platform specific, so this could be some generic thing with
platform-specific support as some sort of sub-driver, but on the other
hand I don't see much of a need for such a thing.

While most of the fbdev usage is done by the EGL driver, using this
fbdev ioctl is apparently the only way to get the display resolution.
2016-09-13 18:26:06 +02:00
wm4 6dc9280b58 vo_opengl: factor some EGL context creation code
Add a function to egl_helpers.c for creating an EGL context and make
context_x11egl.c use it. This is meant to be generic, and should work
with other windowing APIs as well. The other EGL-using code in mpv can
be switched to it.
2016-09-13 18:03:43 +02:00
wm4 3905c46f9a DOCS/interface-changes.rst: minor cleanup
Edit the 0.21.0 section: remove the redundant vo_opengl items, move some
up. Move the additions (which are less important and which aren't
documented completely anyway) below the incompatible
changes/deprecations.
2016-09-13 10:02:27 +02:00
wm4 5c0c0e469b manpage: vo_rpi -> vo_opengl 2016-09-13 09:24:17 +02:00
Niklas Haas f7471b7ff4 vo_opengl: fix typo in bt.601 auto-guessing logic
The wrong enum got copied here, so it was essentially using the transfer
characteristics as the primaries (instead of the primaries), which
accidentally worked fine most of the time (since the two usually
coincided), but broke on weird/mistagged files.
2016-09-13 09:23:47 +02:00
Vladimir Panteleev 6a0df47d94 player: Save sub-speed value when resuming playback 2016-09-13 09:23:28 +02:00
Vladimir Panteleev fb8f2a812e player: Improve OSD formatting of sub-speed option 2016-09-13 09:23:26 +02:00
Vladimir Panteleev 00f8ee573b player: Apply new sub-speed values during playback 2016-09-13 09:23:22 +02:00
Vladimir Panteleev 08cbac311d sub: Add SD_CTRL_UPDATE_SPEED 2016-09-13 09:23:19 +02:00
Ricardo Constantino 60a0815b4c ytdl_hook: don't bother adding subtitles if duration isn't known
EDL doesn't work with subtitles with unknown length.
2016-09-13 09:23:00 +02:00
Ricardo Constantino 5edd6a8caa ytdl_hook: Support playlist entries without subtitles
Fixes missing subtitle tracks if the first entry didn't have any.

Previously it just checked for the first entry in the playlist for
requested languages and if that entry happened to not have subtitles
they also wouldn't show up for the other entries.

It will skip languages if the first entry with subs has less or
different languages than the others.

Unrelated to http_dash_segments.
2016-09-13 09:22:55 +02:00
wm4 0e72f64ff4 vo_rpi: deprecate this VO 2016-09-12 20:05:48 +02:00
wm4 876ec446f3 vo: change defines to an enum
(They're flags, so it still doesn't make sense to actually name the enum
and use it as a type.)
2016-09-12 20:05:48 +02:00
wm4 8c39c6903b vo_opengl: fix non-C11 TLS fallback for gcc
The consequence of this was that e.g. hardware decoding with VAAPI-EGL
could sometimes not work if the compiler didn't support C11. (Although I
found this one on RPI, which also uses this mechanism.)
2016-09-12 20:05:48 +02:00
wm4 e8cdc22245 vo_opengl: better behavior in GL error corner cases
If the shader fails to compile, and assertion could trigger in
gl_sc_gen_shader_and_reset() due to the code trying to recreate the
shader every time, and re-appending the uniforms every time. Just reset
the uniform array to fix this.

Some disturbed GL drivers might not return anything for glGetShaderiv()
if the GL state got "lost", so initialize variables just for additional
robustness.
2016-09-12 20:05:43 +02:00
wm4 b261e1e782 vo_opengl: rpi: merge vo_rpi features
Since vo_rpi is going to be deprecated, better port its features to the
vo_opengl backend.

The most tricky part is the fact that recreating dispmanx elements will
conflict with the GL context. Fortunately, RPI's EGL support is
reasonably compliant, and we can transplant the context to newly created
dispmanx elements, making this much easier. This means unlike vo_rpi,
the GL state will actually not be recreated.
2016-09-12 20:03:55 +02:00
wm4 9a873cc53b vo_opengl: redirect window screenshot requests to backend
If the glReadPixels method is not available, let the backend do it.

Useful for the next commit.
2016-09-12 19:58:58 +02:00
wm4 274e71ee8b vo_opengl: add hw overlay support and use it for RPI
This overlay support specifically skips the OpenGL rendering chain, and
uses GL rendering only for OSD/subtitles. This is for devices which
don't have performant GL support.

hwdec_rpi.c contains code ported from vo_rpi.c. vo_rpi.c is going to be
deprecated. I left in the code for uploading sw surfaces (as it might
be slightly more efficient for rendering sw decoded video), although
it's dead code for now.
2016-09-12 19:58:58 +02:00
shinchiro 343f5ca24b man: fix building pdf 2016-09-12 13:15:36 +02:00
wm4 043512045e command: don't log "ignore" command with -v verbosity
It's damn annoying because the mouse move input event is mapped to this
by default.
2016-09-11 19:45:11 +02:00
James Ross-Gowan 6ac0ef78c5 client API: don't miss property changes after updates
When update_prop() successfully fetches a changed property value, it
sets prop->changed to true. mark_property_changed() only sets
prop->need_new_value if prop->changed is false, so this had the effect
of ignoring new property values until prop->changed was set back to
false in the next call to gen_property_change_event(). This meant that
when a property change event was generated for a property that was not
observed with MPV_FORMAT_NONE, it would contain the value associated
with the earliest property change, rather than the most recent, and the
property change event for the most recent change would never be
generated.

To fix this, mark_property_changed() should unconditionally set
prop->changed and prop->need_new_value, which will cause the property
value to be re-fetched and a property change event to be generated for
the most recent value.
2016-09-11 23:58:23 +10:00
Philip Langdale 3f7e43c2e2 hwdec_cuda: Add trivial cuda-copy wrapper
The cuvid decoder already knows how to copy back to system memory
if NV12 frames are requested, and this will happen if the decoder
is used without the hwdec.

For convenience, let's add a wrapper hwdec so people don't have
to explicitly pick the cuvid decoder if they want this behaviour.
2016-09-11 10:46:22 +02:00
wm4 71681e04ee options: fix another minor regression
vf_scale's "h" sub-option was interpreted as "--h".
2016-09-11 00:04:49 +02:00
Philip Langdale 440e0a98ab hwdec_cuda: Implement download_image for screenshots
Data has to be copied to system memory for screenshots.
2016-09-10 23:17:47 +02:00
Philip Sequeira 1e684e3cca build: recompile zsh completion if zsh.pl changes 2016-09-10 21:46:03 +02:00
Philip Sequeira eec7660274 TOOLS/zsh.pl: don't filter files by extension
Closes #2273. See that issue for explanation/discussion.

I'll add examples on how to filter in your own config to the wiki soon:
https://github.com/mpv-player/mpv/wiki/Zsh-completion-customization
2016-09-10 21:46:03 +02:00
Philip Sequeira defcb9047e TOOLS/zsh.pl: die if we can't parse main options
This will catch cases where mpv runs without error, but the
--list-options output isn't what we expect. Otherwise, we'll make a
broken completion file that will result in cryptic errors when pressing
tab, like:

_mpv:18: command not found: *:files:->mfiles

That's been the case for most of the zsh completion issues we've had
reported, that I can remember.

Also make uninitialized variable access fatal so that failures to parse
other options will also make the script die eventually, albeit with a
less nice message.
2016-09-10 21:46:01 +02:00
wm4 fc1c004cd8 options: fix --list-options after previous commit
Fixes #3509.
2016-09-10 20:49:10 +02:00
wm4 484328fe04 options: make --h list options according to a pattern passed to it
Useless feature, but I want it.

Won't work on Windows due to missing fnmatch().
2016-09-10 16:29:24 +02:00
wm4 ebc04333d2 m_config: remove another unused leftover 2016-09-10 16:01:05 +02:00
wm4 5ca654301b stream_cb: don't add "*://" to protocol list
--list-protocol was printing a *:// entry, which looked strange at best.
The "*" protocol was used to always match everything, so stream_cb.c
could hook in custom protocols with a prefix chosen by the API user.

Change it instead so that an empty protocol list means "match all",
which also gets rid of the special-cased "*" entry.
2016-09-10 15:35:22 +02:00
wm4 7383b45682 command: do not call mp_switch_track() before proper initialization
This is an awful corner-case party, because we've started to allow the
user to send track-switching related commands before stream selection is
done in the loading stage. If mp_switch_track() is called before this
stream selection, it can behave inconsistently. So if we're in the
pre-loading phase, we must set the stream selection options to get
streams selected later, instead of calling this function. There seem to
be some annoying circumstances that exclude mp_switch_track() from
handling this logic too, so do it at all call-sites.
2016-09-10 13:51:17 +02:00
bugdone fdc5388f8c man: fix typo 2016-09-10 13:15:44 +02:00
Philip Langdale 76818e3dc7 hwdec_cuda: Use the non-deprecated CUDA-GL interop API
The nvidia examples use the old (as in CUDA 3.x) interop API which
is deprecated, and I think not even functional on recent versions
of CUDA for windows. As I was following the examples, I used this
old API.

So, let's update to the new API, and hopefully, it'll start working
on windows too.
2016-09-10 13:15:27 +02:00
sda89ha9 d054a7181f player: fix average frame duration calculation 2016-09-09 19:18:08 +02:00
wm4 04320d26eb stream, demux, config: remove some dead/unneeded option-related code
This has all been made unnecessary recently. The change not to copy the
global option struct in particular can be made because now nothing
accesses the global options anymore in the demux and stream layers.

Some code that was accidentally added/changed in commit 5e30e7a0 is also
removed, because it was simply committed accidentally, and was never
used.
2016-09-09 17:54:57 +02:00
wm4 c157641019 stream_cdda: remove weird option parsing stuff
Mostly untested.

This is not compatible. It removes the URL fields for track range and
cdrom speed (what did this even do). The device is not not to be
prefixed with an additional "/" if it's put into the URL. I can't be
bothered to keep these things compatible, just rip your damn CDs
instead.
2016-09-09 17:54:35 +02:00
wm4 5324fb731f tv: remove weird option parsing stuff
Mostly untested.
2016-09-09 17:54:35 +02:00
wm4 9213db0d49 stream_dvb: remove weird option parsing stuff
Mostly untested.
2016-09-09 17:54:35 +02:00
Philip Langdale d66f2a679b man/options: Document cuda hwdec. 2016-09-09 17:54:35 +02:00
wm4 27e3f04de7 client API: fix error code string
Said "audio" instead of "video".
2016-09-09 12:28:03 +02:00
wm4 ea94b01e6b client API: make mpv_opengl_cb_uninit_gl() behavior slightly nicer
Instead of deselecting the video stream plainly, use the slightly more
robust error_on_track() function. Also give it an error code (although
I'm not sure if this one is confusing, it's better than the one before).
2016-09-09 12:27:41 +02:00
wm4 5e30e7a041 stream_dvd, stream_dvdnav: remove weird option parsing stuff
Same deal as with stream_bluray.

Untested because I don't give a fuck about your shitty DVDs.
2016-09-08 21:46:48 +02:00
wm4 35e8b6c1e6 options: drop unreferenced --bluray-angle option
Uh, what? It wasn't used at all. It was probably accidentally dropped at
one point, or it was never used at all. Whatever, who cares.
2016-09-08 21:02:31 +02:00
wm4 ca55a32922 stream_bluray: fix a minor memory leak 2016-09-08 20:59:24 +02:00
wm4 c8cc1f401b stream_bluray: remove weird option parsing stuff
Instead, parse manually. This is to get rid of the option API usages,
which seem unnecessary and shoehorned. (Just look at the URL pseudo
parsing and the dumb url_options map. They were pretty much artifacts
from refactoring old mplayer code.)
2016-09-08 20:59:13 +02:00
wm4 7177ef3e1c vo: remove unused VOCTRL_GET_PANSCAN
It was used to determine whether the VO supports VOCTRL_SET_PANSCAN.
With all those changes to property semantics this became unnecessary,
and its only use was dropped at some point.
2016-09-08 18:59:21 +02:00
wm4 a2fce5ba26 vo: don't access global options unsynchronized
And since there's no proper fine-grained option change notification
mechanism yet, intercept updates to "framedrop" manually.
2016-09-08 18:53:20 +02:00
wm4 c3097422f2 vo_opengl: use dedicated image unref function in config case
Just another corner-caseish potential issue. Unlike unreffing the image
manually, unref_current_image() also takes care of properly unmapping
hwdec frames. (The corner-case part of this is that it's probably never
mapped at this point, but it's apparently not entirely guaranteed.)
2016-09-08 16:06:12 +02:00
wm4 8bb9632e27 vo_opengl: simplify a condition
The " || vimg->mpi" part virtually never seems to trigger, but on the
other hand could possibly create unintended corner cases (for example by
trying to upload a NULL image, which would then be marked as an error
and render a blue screen).

I guess it's a leftover from over times, where a NULL image meant
"redraw the current frame". This is now handled by actually passing
along the current frame.
2016-09-08 16:06:12 +02:00
Philip Langdale 2048ad2b8a hwdec/opengl: Add support for CUDA and cuvid/NvDecode
Nvidia's "NvDecode" API (up until recently called "cuvid" is a cross
platform, but nvidia proprietary API that exposes their hardware
video decoding capabilities. It is analogous to their DXVA or VDPAU
support on Windows or Linux but without using platform specific API
calls.

As a rule, you'd rather use DXVA or VDPAU as these are more mature
and well supported APIs, but on Linux, VDPAU is falling behind the
hardware capabilities, and there's no sign that nvidia are making
the investments to update it.

Most concretely, this means that there is no VP8/9 or HEVC Main10
support in VDPAU. On the other hand, NvDecode does export vp8/9 and
partial support for HEVC Main10 (more on that below).

ffmpeg already has support in the form of the "cuvid" family of
decoders. Due to the design of the API, it is best exposed as a full
decoder rather than an hwaccel. As such, there are decoders like
h264_cuvid, hevc_cuvid, etc.

These decoders support two output paths today - in both cases, NV12
frames are returned, either in CUDA device memory or regular system
memory.

In the case of the system memory path, the decoders can be used
as-is in mpv today with a command line like:

mpv --vd=lavc:h264_cuvid foobar.mp4

Doing this will take advantage of hardware decoding, but the cost
of the memcpy to system memory adds up, especially for high
resolution video (4K etc).

To avoid that, we need an hwdec that takes advantage of CUDA's
OpenGL interop to copy from device memory into OpenGL textures.

That is what this change implements.

The process is relatively simple as only basic device context
aquisition needs to be done by us - the CUDA buffer pool is managed
by the decoder - thankfully.

The hwdec looks a bit like the vdpau interop one - the hwdec
maintains a single set of plane textures and each output frame
is repeatedly mapped into these textures to pass on.

The frames are always in NV12 format, at least until 10bit output
supports emerges.

The only slightly interesting part of the copying process is that
CUDA works by associating PBOs, so we need to define these for
each of the textures.

TODO Items:
* I need to add a download_image function for screenshots. This
  would do the same copy to system memory that the decoder's
  system memory output does.
* There are items to investigate on the ffmpeg side. There appears
  to be a problem with timestamps for some content.

Final note: I mentioned HEVC Main10. While there is no 10bit output
support, NvDecode can return dithered 8bit NV12 so you can take
advantage of the hardware acceleration.

This particular mode requires compiling ffmpeg with a modified
header (or possibly the CUDA 8 RC) and is not upstream in ffmpeg
yet.

Usage:

You will need to specify vo=opengl and hwdec=cuda.

Note that hwdec=auto will probably not work as it will try to use
vdpau first.

mpv --hwdec=cuda --vo=opengl foobar.mp4

If you want to use filters that require frames in system memory,
just use the decoder directly without the hwdec, as documented
above.
2016-09-08 16:06:12 +02:00
wm4 622f9cf1aa vo_opengl: fix incorrect video rendering after vdpau preemption recovery
This could also trigger in certain other cases, whenever it falls back
to dumb mode.
2016-09-07 18:48:24 +02:00
wm4 4552ee286b vo_opengl: fix another potential vdpau preemption issue
reinit() will change the image params fields, so give it a copy.

Will fix potential crashes if preemption happens more than once.
2016-09-07 18:23:14 +02:00
wm4 062423381d ao_rsound: fix compilation
Probably fixes #3501.
2016-09-07 18:10:12 +02:00
wm4 2372b0a6f6 sub: fix previous commit with older libass releases 2016-09-07 14:11:56 +02:00
wm4 2f1eb49e9f sub: actually apply text alignment options to non-ASS subtitles
This is a bug fix, and the text alignment functionality probably got
lost sometime along the way.

For ASS subtitles, this could have unintended consequences, so it's hard
to get right - thus it's not applied to ASS subtitles.

For other text subtitles, this should be fine, though. It still works on
ASS subtitles as promised by the manpage if --no-sub-ass is used.
2016-09-07 13:42:55 +02:00
wm4 355361e1e3 manpage: remove more references to deprecated sub-option syntax
Fixes #3497.
2016-09-07 12:55:21 +02:00
wm4 5a7b1ff4c0 ao_pcm: remove some useless messages
The first one is printed even if the user disabled video (or there's no
video), so just remove it. The second one uses deprecated sub-option
syntax, so remove that as well.
2016-09-07 12:54:33 +02:00
wm4 591e21a2eb osdep: rename atomics.h to atomic.h
The standard header is stdatomic.h, so the extra "s" freaks me out every
time I look at it.
2016-09-07 11:26:25 +02:00
wm4 c6b7a4dace atomics: readd some emulation
This time it's emulation that's supposed to work (not just dummied out).
Unlike the previous emulation, no mpv code has to be disabled, and
everything should work (albeit possibly a bit slowly). On the other
hand, it's not possible to implement this kind of emulation without
compiler support. We use GNU statement expressions and __typeof__ in
this case.

This code is inactive if stdatomic.h is available.
2016-09-06 20:15:07 +02:00
wm4 2a4e7dcaad DOCS/interface-changes.rst: list exact sub-option replacements
Actually, only link to a wiki page doing that, because these are too
many options.
2016-09-06 20:10:05 +02:00
wm4 d4d8b3a4fc demux: do not access global options
Don't access MPOpts directly, and always use the new m_config.h
functions for accessing them in a thread-safe way.

The goal is eventually removing the mpv_global.opts field, and the
demuxer/stream-layer specific hack that copies MPOpts to deal with
thread-safety issues.

This moves around a lot of options. For one, we often change the
physical storage location of options to make them more localized,
but these changes are not user-visible (or should not be). For
shared options on the other hand it's better to do messy direct
access, which is worrying as in that somehow renaming an option
or changing its type would break code reading them manually,
without causing a compilation error.
2016-09-06 20:09:56 +02:00
wm4 9f0e7bb998 input, demux_tv: remove some older option access methods 2016-09-06 20:09:44 +02:00
wm4 e66c098228 demux_mkv: don't crash if --ordered-chapters-files fails
It just crashed.
2016-09-06 20:09:18 +02:00
wm4 618d7f59b0 vo_vdpau: rename some sub-options
Since the sub-options have been deprecated very recently, and are
redirected to global options, we don't need to document this change.
2016-09-06 20:08:44 +02:00
wm4 723e3ec8d9 common: use char array for version string
Use a char array instead of a pointer, which allows using the version
variables in a constant context.
2016-09-06 20:08:44 +02:00
wm4 9ab0f60d44 vo_opengl: simplify option handling
Instead of copying the options around... just don't. video.c now has
full control over when options are updated. (It still gets notified from
outside, but it decides when the updated options are copied: when
m_config_cache_update() is called.) So there's no need for tricky
stuff, and it can be simplified a bit.

Also change lcms.c. We could do it like video.c, and get the options
from the global config store. But it seems simpler to just provide a
pointer to an option struct, which is arbitrarily mutated from the
outside (from the perspective of lcms.c).
2016-09-06 11:11:36 +02:00
wm4 e5cefa346d vo_opengl: fix --icc-profile initial behavior
Setting --icc-profile had no effect, until a vo_opengl option was
changed at runtime. We must initialize the renderer for the initial
option state too.

For some reason, the ICC profile gets loaded twice. The next commit
happens to fix this.
2016-09-06 11:11:23 +02:00
pavelxdd c36aaeeb2a wscript: fix typo 2016-09-06 09:43:59 +02:00
wm4 c4e01cc00d m_config: avoid accidentally causing deprecation warnings
It has to copy each option, whether it's deprecated or not. This would
print a warning on every deprecated sub-option, even if it's not used.
Yep, this is very stupid.

At least m_config_get_co() gets actually slightly cleaner, because it
separates the search and the deprecation handling.
2016-09-05 21:26:39 +02:00
wm4 1d9032f011 audio/out: deprecate "exclusive" sub-options
And introduce a global option which does this. Or more precisely, this
deprecates the global wasapi and coreaudio options, and adds a new one
that merges their functionality. (Due to the way the sub-option
deprecation mechanism works, this is simpler.)
2016-09-05 21:26:39 +02:00
wm4 13786dc643 audio/out: deprecate device sub-options
We have --audio-device, which can force the device. Also add something
describing to this extent to the manpage.
2016-09-05 21:26:39 +02:00
wm4 69283bc0f8 options: deprecate suboptions for the remaining AO/VOs 2016-09-05 21:26:39 +02:00
wm4 633eb30cbe options: add automagic hack for handling sub-option deprecations
I decided that it's too much work to convert all the VO/AOs to the new
option system manually at once. So here's a shitty hack instead, which
achieves almost the same thing. (The only user-visible difference is
that e.g. --vo=name:help will list the sub-options normally, instead of
showing them as deprecation placeholders. Also, the sub-option parser
will verify each option normally, instead of deferring to the global
option parser.)

Another advantage is that once we drop the deprecated options,
converting the remaining things will be easier, because we obviously
don't need to add the compatibility hacks.

Using this mechanism is separate in the next commit to keep the diff
noise down.
2016-09-05 21:26:39 +02:00
wm4 327cb2a06c vo_direct3d: deprecate direct3d_shaders alias
And remove the difference between the aliases. This is needed to make
the sub-option changes less painful.
2016-09-05 21:26:39 +02:00
wm4 9e6b9d8a98 vo_image: move to global options
This is a bit "special", because the config tree wants unique
m_sub_options pointers in the whole thing.
2016-09-05 21:04:55 +02:00
wm4 726ef35aa8 ao_jack: move to global options 2016-09-05 21:04:41 +02:00
wm4 4ab860cddc options: add a mechanism to make sub-option replacement slightly easier
Instead of requiring each VO or AO to manually add members to MPOpts and
the global option table, make it possible to register them automatically
via vo_driver/ao_driver.global_opts members. This avoids modifying
options.c/options.h every time, including having to duplicate the exact
ifdeffery used to enable a driver.
2016-09-05 21:04:17 +02:00
wm4 cc813647d5 m_config: move parts of m_config_add_option into its own function
Preparation for the next commit.
2016-09-05 21:03:46 +02:00
wm4 6cd80e972e dispatch: improve recent locking changes slightly
Instead of adding a lock_frame to the list when mp_dispatch_lock() is
called, just set a simple flag. This uses the fact that the lock is not
recursive, and can happen once per mp_dispatch_queue_process(). It
avoids the dynamic allocation, and makes error checking slightly
stricter.

Again, this is actually redundant and exists only for error-checking.
It'd actually need only a counter, because the actual locking is done by
"parking" the target thread in mp_dispatch_queue_process() and then
setting queue->idling=false. Only when mp_dispatch_unlock() sets it to
true again other work can proceed again. Document this too.
2016-09-05 20:58:45 +02:00
wm4 3878a59e2c dispatch: redo locking, and allow reentrant processing
A deadlock bug was reported with the following test program:

	mpv_handle *mpv = mpv_create();
	mpv_set_option_string(mpv, "ytdl", "yes");
	mpv_initialize(mpv);
	mpv_terminate_destroy(mpv);

The cause of this is loading the ytdl.lua script, which triggers a
certain code path that calls mp_dispatch_queue_process() recursively. It
does so to wait until the script is loaded, and we want to keep that.

Reentrancy was not supported by mp_dispatch, which leads to the
deadlock. Rewrite the locking so that it does. We mainly get rid of the
"exclusive_lock" mutex. Instead we use the existing lock/condition
variable to wait until we can grab a logical lock.

Note that the lock_frame business can be replaced with a simple counter.
Instead of checking the lock_frame address, it'd simply increment and
store the counter when entering mp_dispatch_queue_process(), and then
compare the counter to decide whether or not to wait. But I think the
additional error checking done by the lock_frame list is valuable.

Fixes #3489.
2016-09-04 18:05:36 +02:00
wm4 2619d8eff4 client API: implement mpv_suspend/resume slightly differently
Why do these API calls even still exist? I don't know, and maybe they
don't make any sense anymore. But whether they should be removed or not
is not a decision I want to make now. I want to get rid of
mp_dispatch_suspend/resume(), though. So implement the client APIs
slightly differently.
2016-09-04 18:05:36 +02:00
Ricardo Constantino d889d1fbaa travis: trigger website rebuild only on docs changes 2016-09-04 18:05:36 +02:00
Stefano Pigozzi e955ae9000 travis: rebuild website for updated docs on push 2016-09-04 13:29:11 +02:00
wm4 4236321835 client API: more option/property updates 2016-09-03 17:14:04 +02:00
wm4 4f263dce34 sd_lavc: enable teletext
Whitelisting supported codecs is (probably) still better than just
allowing everything, given the weird FFmpeg API. I'm also assuming
Libav doesn't even have the codec ID, but I didn't check.

Also add a --teletext-page option, since otherwise it decodes every
teletext page and shows them in succession.

And yes, we can't use av_opt_set_int() - instead we have to set it as
string. Because FFmpeg's option system is terrible.
2016-09-03 17:12:53 +02:00
wm4 590caeb2bd command: try selecting the next track if track switching fails
This affects the "cycle" command. If we switched to the next track, and
it failed to initialize, we just deselected everything.

Change it so that if initialization fails early (typically decoder
selection), we try to continue with the track after that. (Even if
nothing can be selected, the loop will terminate when trying to select
nothing.

Fixes #3446.
2016-09-03 17:12:29 +02:00
wm4 0c2c059826 player: remove opengl-es=no flag from opengl-hq profile
This was mistakenly added. It was removed from the vo_opengl_hq defaults
at an earlier time, but the documentation was not updated, which is why
it made it back into the profile.

Fixes #3485.
2016-09-03 13:07:58 +02:00
wm4 9bc39b352e manpage: document another option/property inconsistence 2016-09-03 13:05:19 +02:00
wm4 ece86d1061 config: deprecate ao and vo auto-profiles
These never made any sense. They checked the --vo/--ao option, and
applied the profile corresponding to the first entry. So the only way to
get any use of those was to use the --ao or --vo option explicitly. You
can get the same functionality by making a manual profile, making these
force the ao/vo, and then using --profile on command line instead of
--vo/--ao.
2016-09-03 12:46:32 +02:00
wm4 c92450d7fb manpage: mention how to apply/view opengl-hq profile 2016-09-02 21:35:40 +02:00
wm4 a85eecfe40 ao_alsa: change sub-options to global options
Same deal as with vo_opengl.

Also edit the outdated information about multichannel output a little.
2016-09-02 21:21:47 +02:00
wm4 eb14b18a33 config: allow profile forward-references in default profile
This works by first parsing a config file into the default profile, and
applying it once parsing the whole file is finished.

This won't work across config files (not even if you include other
config files via "include=file.conf").
2016-09-02 21:21:47 +02:00
wm4 9770ce6c44 m_config: make sure profile values are never NULL
Apparently this was supposed to be handled - but badly at best. Make
unset values always have the value "" instead of NULL to avoid
special-cases.

In particular, this fixes passing NULL to a %s format specifier to
printf in show_profile(). Glibc prints this as "(null)", but it's
undefined behavior, and other libcs can crash.
2016-09-02 21:21:47 +02:00
wm4 b92d3b6d44 w32_common: initialize playback status as soon as possible
On a VOCTRL_UPDATE_PLAYBACK_STATE store the state, and use it to
initialize the next time the task list becomes available.

This actually fixes #3482. Revert commit f2e25e9e because it's not
needed anymore.
2016-09-02 21:21:47 +02:00
wm4 cd7c7d0841 command: remove vo-cmdline
With the recent vo_opengl changes it doesn't do anything anymore.
I don't think a deprecation period is necessary, because the command
was always marked as experimental.
2016-09-02 21:21:47 +02:00
wm4 b2c84a91b6 options: deprecate --vo-defaults
With the conversion from sub-options to global options, this becomes
useless. This change also comes slightly too soon, because not all VOs
have been changed yet.
2016-09-02 21:21:47 +02:00
wm4 849480d0c9 vo_opengl: deprecate sub-options, add them as global options
vo_opengl sub-option were always rather annoying to handle. It seems
better to make them global options instead. This is simpler and easier
to use. The only disadvantage we are aware of is that it's not clear
that many/all of these new global options work with vo_opengl only.

--vo=opengl-hq is also deprecated.

There is extensive compatibility with the old behavior. One exception is
that --vo-defaults will not apply to opengl-hq (though with opengl it
still works). vo-cmdline is also dysfunctional and will be removed in a
following commit.

These changes also affect opengl-cb.

The update mechanism is still rather inefficient: it requires syncing
with the VO after each option change, rather than batching updates.
There's also no granularity (video.c just updates "everything", and if
auto-ICC profiles are enabled, vo_opengl.c will fetch them on each
update).

Most of the manpage changes were done by Niklas Haas <git@haasn.xyz>.
2016-09-02 21:21:47 +02:00
wm4 a07dae57e3 vo_opengl: rename 3dlut-size to icc-3dlut-size
Not documenting this yet, because a later commit will change all the
options anyway.
2016-09-02 15:58:40 +02:00
wm4 72c6bf1345 m_config: add some convenience functions
To be used by the following commits.
2016-09-02 15:58:15 +02:00
wm4 2c917219cf vo: use new option update mechanism
This is still rather basic.

run_reconfig() and run_control() update the options because it's needed
for panscan (and other video scaling options), and fullscreen, border,
ontop updates. In the old model, these options could be accessed only
while both playback thread and VO threads were locked  (i.e. during
synchronous calls like vo_control()), so this should be sufficient in
order not to miss any updates. In the future, a more fine-grained update
mechanism could be added to handle these updates "exactly".

x11_common.c contains an evil hack, as I see no reasonable way to handle
this properly. The VO thread can't "lock" the main thread, so this is
not simple.
2016-09-02 15:50:54 +02:00
wm4 423e53ba0b m_config: introduce basic mechanism to synchronize global option updates
The way option runtime changes are handled is pretty bad in the current
codebase. There's a big option struct (MPOpts), which contains almost
everything, and for which no synchronization mechanism exists. This was
handled by either making some options read-only after initialization,
duplicating the option struct, using sub-options (in the VO), and so on.

Introduce a mechanism that creates a copy of the global options (or
parts of it), and provides a well-defined way to update them in a
thread-safe way.

Most code can remain the same, just that all the component glue code has
to explicitly make use of it first.

There is still lots of room for improvement. For example, the update
mechanism could be better.
2016-09-02 15:50:40 +02:00
wm4 f2e25e9e1f player: don't send win32 taskbar update before window is created
If the win32 taskbar progress update is sent before the VO window is
created, then w32_common.c will ignore it because the actual taskbar
object was not created yet. (At least this is what I suspect happens.
The window is already created at this point, but not mapped.)

Hopefully fix this is fixed by creating until after the window is
created, i.e. the VO has been configured at least once.

Untested (who wants to boot into Windows just to wait until it has
applied all of its stupid updates).

Also not explicit is whether update_vo_playback_state() will actually be
called soon enough in all cases. It probably is.

Probably fixes #3482.
2016-09-02 15:01:09 +02:00
wm4 b2657814c9 vo_opengl: minor renderer option access refactor
Reduce accesses to the renderer opts in vo_opengl.c, and instead add
accessors for them to video.c.

I suppose gamma and maybe icc-auto could be moved to vo_opengl.c
options. Also, the output colorspace could probably be adjusted to what
is really used, not just the options (although it's possible that this
commit changes this, due to video.c mutating its own copy of the options
according to actual renderer capapbilities).

But don't deal with this now.
2016-09-02 14:50:03 +02:00
wm4 4fa6bcbb90 m_config: add helper function for initializing af/ao/vf/vo suboptions
Normally I'd prefer a bunch of smaller functions with fewer parameters
over a single function with a lot of parameters. But future changes will
require messing with the parameters in a slightly more complex way, so a
combined function will be needed anyway. The now-unused "global"
parameter is required for later as well.
2016-09-02 14:49:34 +02:00
Jeong Woon Choi 875aeb0f5c charset_conv: Use CP949 instead of EUC-KR
iconv distinguishes between euc-kr and cp949, while libguess
and libuchardet doesn't (only returns euc-kr). EILSEQ occurs
when the input encoding of iconv is set to euc-kr and if the subs
contain letters not included in euc-kr. Since cp949 is a extension
of euc-kr, choose cp949 instead.

Signed-off-by: wm4 <wm4@nowhere>
2016-09-02 14:46:11 +02:00
wm4 c72df80460 DOCS: move libmpv stub to manpage
And replace the sort-of duplicated explanations.

(It's a bit funny to use weblinks to the generated web version of itself
instead of proper RST links, but I think I don't care.)
2016-09-02 09:53:11 +02:00
wm4 907bf83297 manpage: mention the client API/interface change logs
Also, I'm seeing that we still have mplayer-changes.rst - add a warning
that it's outdated.
2016-09-02 09:48:35 +02:00
wm4 3659f9e416 command: deprecate "cache" property, replace with "cache-percent"
The --cache option and cache property conflict, so one of them has to be
renamed. The option is probably used frequently, so initiate
deprecation/rename of the property.
2016-09-02 09:42:19 +02:00
Niklas Haas ce05413a87 vo_opengl: remove pre/post/scale-shaders
Deprecated in favor of user-shaders, which are functionally equivalent
but superior. (Except in the case of scaler-shader, which has no direct
replacement, but it turned out to be a very unpopular feature either way
- most custom scalers don't fit into the mpv kernel infrastructure and
are therefore implemented as user shaders either way)

Signed-off-by: wm4 <wm4@nowhere>
2016-09-02 09:29:16 +02:00
wm4 453fea87fa client API: create core thread at an earlier time
Create the core thread right in mpv_create(), and reduce what
mpv_initialize() does further. This is simpler, and allows the API user
to do more before calling mpv_initialize(). The latter is not the real
goal, rather we'd like mpv_intialize() reduced to do almost nothing. It
still does a lot, but nothing truly special anymore that is absolutely
required for basic mpv workings.

One thing we want the user to be able to do is changing properties
before mpv_initialize() to reduce the special status of
mpv_set_option().
2016-09-01 21:55:21 +02:00
wm4 1393d79417 command: fix or document some property/option consistency issues
Make some existing properties behave more like options. This mostly
means they don't deny access if the associated component is not active,
but redirects to the option.

One kind of fishy change is that we apply --brightness etc. only if
they're not set to the default value. This won't necessarily work with
--vo=xv, but affects only cases where 1. the Xv adapter has been changed
to non-defaults, and 2. the user tries to reset them with mpv by passing
e.g. --brightness=0. We don't care about Xv, and the noted use-case is
dumb, so this change is acceptable.
2016-09-01 20:57:33 +02:00
wm4 192a7344d9 command: remove 2 deprecated properties
They were delcared to be removed in mpv 0.20.0, and the next release
will be 0.21.0.
2016-09-01 20:01:29 +02:00
wm4 e4e1dc3c79 command: rename/deprecate some conflicting property names
These conflict with options of the same name, and prevent a "full"
unification. Not addressed is the "cache" property, and possibly a few
properties that behave differently from their equivalent options.
2016-09-01 20:01:02 +02:00
wm4 d32bee5f01 command: add options to property list
Now options are accessible through the property list as well, which
unifies them to a degree.

Not all options support runtime changes (meaning affected components
need to be restarted for the options to take effects). Remove from the
manpage those properties which are cleanly mapped to options anyway.
From the user-perspective they're just options available through the
property interface.
2016-09-01 20:00:43 +02:00
wm4 17dbb39dec m_config: fix "no-" option handling with sub-options
E.g. --vf=scale=no-arnd didn't work, because it didn't recognize no-arnd
as flag option.

The top-level command line parser is not affected by this, because it
uses the result of m_config_option_requires_param() differently and
assumes unknown parameters do not necessarily require a parameter. (The
suboption parser can't do this.)
2016-09-01 14:29:08 +02:00
wm4 6b4f560f3c vo, ao: disable positional parameter suboptions
Positional parameters cause problems because they can be ambiguous with
flag options. If a flag option is removed or turned into a non-flag
option, it'll usually be interpreted as value for the first sub-option
(as positional parameter), resulting in very confusing error messages.
This changes it into a simple "option not found" error.

I don't expect that anyone really used positional parameters with --vo
or --ao. Although the docs for --ao=pulse seem to encourage positional
parameters for the host/sink options, which means it could possibly
annoy some PulseAudio users.

--vf and --af are still mostly used with positional parameters, so this
must be a configurable option in the option parser.
2016-09-01 14:21:32 +02:00
wm4 ec3c428e5f stream_cb: remove broken cast
seek_fn is supposed to return the new file offset, or a negative error
code. Our code doesn't use the offset, and only wants to know if any
errors happened. The int cast is completely broken and might treat a
successful seek as failed depending on whether the sign bit will be set.
2016-08-31 22:25:06 +02:00
wm4 e22ae2cba0 m_config: remove an unused function
Well, almost unused.
2016-08-31 22:22:21 +02:00
quilloss aae47146a7 vo: update w32_common left out by 4d75514 2016-08-31 22:19:55 +02:00
wm4 7539928c1c m_config: remove some aliasing checks
We strictly assume no aliasing (the previous commit removed the last
case), so remove the checks.
2016-08-31 22:17:24 +02:00
wm4 c55d859920 m_option: replace --no-video-aspect alias
Instead, add a hacky OPT_ASPECT option type, which only exists to accept
a "no" parameter, which in combination with the "--no-..." handling code
makes --no-video-aspect work again.

We can also remove the code in m_config.c, which only existed to make
"--no-aspect" (a deprecated alias) to work.
2016-08-31 22:17:21 +02:00
wm4 2057209057 m_config: deprecate top-level suboptions
This is a really old weird MPlayer feature. While the MPlayer requires
you to use the sub-option syntax in these cases, mpv "flattens" them to
normal options. The still-supported alternate sub-option syntax remains
a weird artifact that hopefully nobody uses.

For example you can do "-sub-text font=Foo:color=0.5" instead of using
"--sub-text-font=Foo --sub-text-color=0.5". For --sub-text this is an
accidental feature, but it used to be documented for
--demuxer-rawaudio and some others.

This should just be removed, but for now only print a warning to preempt
complaints from weird users wanting this feature back.
2016-08-31 22:16:43 +02:00
wm4 b10dcecf7d client API: deprecate "no-..." option handling
The client API can do this (and there are apparently some libmpv using
projects which rely on this). But it's just unnecessary bloat as it
requires a separate code path from the option parser. It would be better
to remove this code. Formally deprecate it, including API bump and
warning in the API changes file to make it really clear.
2016-08-31 22:16:43 +02:00
wm4 7dde096d8a m_config: introduce and use OPT_ALIAS for some options
OPT_ALIAS redirects the options at a higher level, instead of
introducing "duplicate" options with different name but same backing
storage. This uses the OPT_REPLACED mechanisms - only the deprecation
warning had to be made conditional. Note that e.g. --no-video still
works, because the "--no-..." redirection and OPT_ALIAS are orthogonal.

The deprecated --sub -> --sub-file alias had to be dropped, because it
essentially conflicts with --no-sub. If anyone complains, this could
probably still be undone by letting m_config_find_negation_opt do a
special mapping for --no-sub. (Which would be dumb, but simple and
effective.)
2016-08-31 22:16:19 +02:00
wm4 e024906408 m_config: handle --no-... options differently
Instead of adding "no-"-prefixed aliases to the internal option list,
which will act like normal options, do it in the parsing stage. This
turns out to be simpler (and cheaper), and avoids adding aliased
options.
2016-08-31 16:45:58 +02:00
wm4 ce8dae3f0d m_property: remove pointless explicitly clamping
This is basically dead code, and even the commit that added this code 4
years ago said that this should be for debugging only.

(Though it is possible that the clamp callback was used for something
else, and then unused again. Also, some of the clamping code remains and
is used for internal checking, e.g. clamp_double().)
2016-08-31 15:31:51 +02:00
wm4 f519887fe7 input: use OPT_REPLACED for an old option alias 2016-08-31 14:46:21 +02:00
wm4 7614f2b3a6 vo_xv: remove an aliased option
Trying to get rid of them, and no-colorkey is an instance of it. Kill
it.
2016-08-31 13:38:14 +02:00
wm4 4d75514321 vo: change messy handling of fullscreen and other flags
Before this commit, all VOs had to toggle the option flag themselves,
now command.c does it.

I can't really comprehend why it required every VO to do this manually.
Maybe it was for rejecting the property/option change if the VO didn't
support a specific capability. But then it could have checked the VOCTRL
result. In any case, I don't care, and successfully changing the
property without doing anything (With some VOs) is fine too. Many things
work this way now, and it's simpler overall.

This change will be useful for cleaning up VO option handling.
2016-08-30 23:52:16 +02:00
wm4 af1379c43d options: make mp_vo_opts options an actual sub-option group
Just a minor refactor along the planned option change. This commit will
make it easier to update (i.e. copy) the VO options without copying
_all_ options. For now, behavior should be equivalent, though.

(The VO options were put into a separate struct quite early - when all
global variables were removed from the source code. It wasn't clear
whether the separate struct would have any actual purpose, but it seems
it will now. Awesome, huh.)
2016-08-30 23:50:57 +02:00
wm4 e65a8d7b61 m_config: pass parent option in m_config_add_option()
Instead of just the parent name. This is a minor refactor as preparation
for other things.
2016-08-30 23:48:42 +02:00
wm4 5f88e6a0db m_config: rename is_generated to is_hidden
More appropriate. Originally it really was for automatically added
options, but now it even needed some stupid comments to indicate that
it was used for simply hiding options.
2016-08-30 23:47:09 +02:00
wm4 3bb134969e m_option: remove M_OPT_TYPE_DYNAMIC flag
It's actually redundant with whether m_option_type.free is set. Some
option types were flagged inconsistently. Its only use was for running
an additional sanity check without any real functionality.
2016-08-30 23:45:58 +02:00
wm4 6f6d2eb770 command: cosmetics: fix some minor whitespace mistakes 2016-08-30 23:45:20 +02:00
wm4 f3b3702025 player: make --force-window work with opengl-cb
No reason not to? This probably avoids surprises if someone really tries
to combine them.
2016-08-30 23:44:28 +02:00
wm4 d223959cda player: slightly adjust framerate guessing heuristic
Some files not only use rounded timestamps, but they also do it
incorrectly. They may jitter between up to 4 specific frame durations.
In this case, I found a file that mostly used 41ms and 42ms, but also
had 40ms and 43ms outliers (often but not always following each other).

This breaks the assumption of the framerate estimation code that the
frame duration can deviate up to 1ms. If it jitters around 4 possible
frame durations, the maximum deviation is 3ms. Increase it accordingly.

The change might make playback of "true VFR" video via display-sync mode
worse, but it's not like it was particularly good in the first place.

Also, the check whether to usen the container FPS needs to be stricter.
In the worst case, num_dur is 1, which doesn't really indicate any
evidence that the framerate is correct. Only if there are "enough"
frames the deviation check will become meaningful. 16 is an arbitrary
value that has been designated "enough" by myself.

Also otuput the frame duration values for --dump-stats.
2016-08-29 17:15:06 +02:00
Rostislav Pehlivanov ae3bbc4f63 Merge pull request #3467 from atomnuker/master
wayland: reject resize events with either dimension being 0
2016-08-29 13:40:55 +01:00
Rostislav Pehlivanov cb2cb540f4 wayland: reject resize events with either dimension being 0
Newer versions of mutter/gnome now ask mpv to resize to 0 by 0 pixels.
2016-08-29 13:21:54 +01:00
wm4 3e0d4de988 vo_opengl: explicitly check for GL errors around framebuffer depth check
It seems like many GL implementations (including Mesa) choke on this,
while others are fine. We still think that this use of the GL API is
allowed by the standard (at least in the Mesa case), so to reduce
confusion, explicitly check the "controversial" calls, and use an
appropriate error message.
2016-08-29 14:02:24 +02:00
wm4 251ecf6e4b sd_lavc: always set decoder timebase
Like it's done for audio and video. Just to be uniform.

I'm sorry for deleting the anti-ffmpeg vitriol. It's still all true, but
since we decided to always set the timebase, the crappiness is isolated
to FFmpeg internals.
2016-08-29 13:15:54 +02:00
wm4 edbb8f6286 vd_lavc: always force milliseconds for MMAL
This libavcodec wrapper should rescale the API timestamps to whatever
it internally needs, but it doesn't yet. So restore this code.
2016-08-29 13:15:44 +02:00
wm4 0110b738d5 vd_lavc, ad_lavc: set pkt_timebase, not time_base
These are different AVCodecContext fields. pkt_timebase is the correct
one for identifying the unit of packet/frame timestamps when decoding,
while time_base is for encoding. Some decoders also overwrite the
time_base field with some unrelated codec metadata.

pkt_timebase does not exist in Libav, so an #if is required.
2016-08-29 12:46:12 +02:00
wm4 bda614bfd8 m_config: profile option values can be NULL
Sigh.
2016-08-29 09:30:39 +02:00
wm4 f42e4374d5 command: export profile list as a property
Targeted at scripts, which can do whatever they want with it. This comes
with the promise that they could get randomly broken any time.

See #977.
2016-08-28 19:46:54 +02:00
wm4 a9a55ea7f2 misc: add some annoying mpv_node helpers
Sigh.

Some parts of mpv essentially duplicate this code (with varrying levels
of triviality) - this can be fixed "later".
2016-08-28 19:39:05 +02:00
wm4 5e56c07417 common: add assert.h include
Because why not.
2016-08-28 19:33:04 +02:00
wm4 5086b2d456 player: add option to disable video OSD
Normally, OSD can be disabled with --osd-level=0. But this also disables
terminal OSD, and some users want _only_ the terminal OSD. Add
--video-osd=no, which essentially disables the video OSD.

Ideally, it should probably be possible to control terminal and video
OSD levels independently, but that would require separate OSD timers
(and other state) for both components, so don't do it. But because the
current situation isn't too ideal, add a threat to the manpage that
might be changed in the future.

Fixes #3387.
2016-08-28 18:26:59 +02:00
wm4 7af6e64db7 command: add property for current subtitle text
Requested by someone. Reuses the code for terminal subtitle display.
2016-08-27 21:14:41 +02:00
James Cowgill eed99d3609 player: fix minor spelling mistake in osc.lua
Lintain (https://lintian.debian.org/) complains about this particular spelling
mistake.
2016-08-27 09:02:11 +02:00
wgmk a05f20ea1e TOOLS/zsh.pl: add m4a to zsh completion filetype list 2016-08-26 21:17:24 +02:00
wm4 ed62f56a40 player: avoid some redundant terminal status updates
Run term_osd_update() just once per update, instead of twice (once for
the status line, and once for the terminal OSD messafe).
2016-08-26 20:38:05 +02:00
wm4 37d6604d70 x11, wayland: always round up wait times
If wait_us is >0 and <500, the wait time gets rounded down 0,
effectively turning this into busy waiting. Round it up instead.
2016-08-26 20:22:33 +02:00
wm4 872b7a2654 vo: remove redundant wakeup
Shouldn't matter. Was pointed out by someone. The change should help
avoiding extra unneeded wakeups on the VO thread.
2016-08-26 20:19:39 +02:00
Martin Herkt c226bc7616 Release 0.20.0 2016-08-26 19:40:58 +02:00
Martin Herkt e60a36bd4e Merge branch 'master' into release/current 2016-08-26 19:15:57 +02:00
wm4 bc97d60542 demux: close underlying stream if it's fully read anyway
This is for text subtitles. libavformat currently always reads text
subtitles completely on init. This means the underlying stream is
useless and will consume resources for various reasons (network
connection, file handles, cache memory).

Take care of this by closing the underlying stream if we think the
demuxer has read everything. Since libavformat doesn't export whether it
did (or whether it may access the stream again in the future), we rely
on a whitelist. Also, instead of setting the stream to NULL or so, set
it to an empty dummy stream. This way we don't have to litter the code
with NULL checks.

demux_lavf.c needs extra changes, because it tries to do clever things
for the sake of subtitle charset conversion.

The main reason we keep the demuxer etc. open is because we fell for
libavformat being so generic, and we tried to remove corresponding
special-cases in the higher-level player code. Some of this is forced
due to ass/srt mkv/mp4 demuxing being very similar to external text
files. In the future it might be better to do this in a more
straight-forward way, such as reading text subtitles into libass and
then discarding the demuxer entirely, but for aforementioned reasons
this could be more of a mess than the solution introduced by this
commit.

Probably fixes #3456.
2016-08-26 13:34:52 +02:00
wm4 4121016689 player: don't directly access demuxer->stream
Cleaner and makes it easier to change the underlying stream.

mp_property_stream_capture() still directly accesses it directly via
demux_run_on_thread(). This is evil, but still somewhat sane and is not
getting into the way here.

Not sure if I got all field accesses.
2016-08-26 13:33:38 +02:00
wm4 b636b19058 cache: don't use a backbuffer if the cache is as large as the file
It's just wasted memory.

One corner case is when a file grows during playback, but this is rare
and usually happens on-disk only. The cache size was generally limited
before this change already, so no reason to care.

As an unrelated change, move the cache size info to the resize_cache()
function. There's really no reason not to do this, and it's slightly
more informative if the user changes the cache size at runtime.
2016-08-26 13:33:38 +02:00
wm4 cb9b60ef19 stream_memory: disable stream cache
Obviously makes no sense and just wastes resources.
2016-08-26 13:33:38 +02:00
James Ross-Gowan 31f28da0f3 w32_common: use hooks to detect parent window resize
Because VOCTRL_CHECK_EVENTS is processed asynchronously (as of 088a007,)
the GUI thread no longer gets regular wakeups, so the old check that
made sure the video window matched the parent window's size in --wid
embedding mode did not run very often. This made --wid embedding not
very usable.

Instead of polling for window size changes, use Windows hooks to react
to them when they happen. When the parent window is owned by the same
process as the video window, use a WH_CALLWNDPROC hook. When the parent
window is not owned by the same process, WinEvents must be used, which
are not as smooth, but still work for this purpose.

Since neither SetWindowsHookEx nor SetWinEventHook take a context
parameter to send data to the hook function, the hook functions must
find the child window by its class instead, so there are a few changes
to ensure this is fast and the class is unique.

This also fixes up the logic to handle window destruction. When a parent
window is destroyed, its children are also destroyed, so this gives us a
way to react to parent window destruction without polling.
2016-08-26 20:02:58 +10:00
Avi Halachmi (:avih) ef0b2e33b1 vo_opengl: angle: new opengl flag to control DirectComposition
On some systems DirectComposition might behave poorly. Add an opengl
suboption flag 'dcomposition' (default=yes) which can disable it.
2016-08-25 23:47:37 +10:00
wm4 2a5b61244f x11: work around mutter fullscreen issue
If the video has the same size as the screen, starting with --fs and
then leaving fullscreen doesn't actually leave fullscreen.

The reason is that mpv tries to restore the previous window size if
necessary (otherwise, you'd end up with a Window of nearly the same size
as the screen with some WMs). It will typically restore with the
rectangle set exactly to the screen if no other position or size is
forced. This triggers pre-EWMH fullscreen mode, which WMs detect using
various heuristics.

Apparently we triggered this with mutter (but strangely no other WMs).
It's possible that pre-EWMH fullscreen mode actually requires removing
decorations, and mutter either ignores this. But this is speculation and
I haven't checked.

Work this around by reducing the requested size by 1 pixel if it
happens.

This was observed with mutter 3.18.2.

Fixes #2072.
2016-08-25 14:16:10 +02:00
wm4 c4ba600832 audio: avoid missed wakeups with ab-loops
Could get "stuck".
2016-08-24 12:14:48 +02:00
wm4 c218d9e960 vd_lavc: minor simplification
The timebase is now always valid.
2016-08-23 12:07:46 +02:00
wm4 a47d849df7 ad_lavc: actually tell decoder about the timebase
Essentially forgotten in commit 05e4df3f.
2016-08-23 12:06:47 +02:00
wm4 6980575e15 ao_alsa: log if retrieving supported channel maps fails
It's a sign that the driver doesn't implement the channel map API.
2016-08-22 20:05:34 +02:00
wm4 724f60bf9a audio: do not apply --audio-channels if spdif passthrough is in use
If spdif is enabled, the channel layout has no meaning other than
setting the number of channels. The number of channels must be fixed to
achieve the exact bitrate required.

Fixes #3445.
2016-08-22 12:12:10 +02:00
wm4 74d4073771 demux: demote packet queue overflow to a warning
It doesn't necessarily have to mean anything bad.

We're still too lazy to provide any more detailed information (e.g.
whether this happened to likely bad interleaving, excessive amount of
packets like with some ASS subs, or that the readahead user option is
limitted by the packet queue size).
2016-08-22 12:10:55 +02:00
wm4 93104142f4 player: log if video is considered an image
It's a heristic that can fail, so better log it.
2016-08-21 12:27:48 +02:00
wm4 9a5e062a04 manpage: fix typo 2016-08-20 18:15:24 +02:00
wm4 6b676d82fd vo: be more trusting to estimated display FPS
This should actually be rather safe - we already check whether the
estimated value jitters less than the (possibly untrustworthy) nominal
one. Remove a "safety" check that disabled this code for small
deviations, and make it trigger sooner into playback. Also lower the log
level of messages about using the estimated display FPS down to verbose.

Normally there's another mechanism for smoothing out minor estimation
differences, but that is not good enough here.

This possibly improves behavior as reported in #3433, which can be
reproduced with --vo=null:fps=48.426 --display-fps=48 (though it doesn't
consider the jitter introduced by a real VO).
2016-08-20 18:15:17 +02:00
wm4 af103aebd7 player: update Windows playback state asynchronously
Doing this required synchronizing with the VO thread, which could lead
to audio dropouts if the VO was frozen (which can happen in practice if
e.g. an opengl_cb user is not doing what the API demands).

Add a way to send asynchronous VOCTRLs, and use that for the playback
state. In theory, it would be better to make this status update a
several function and to "merge" several queued update, but that would be
slightly more effort/code, and the update is so infrequent that the
merging would never happen anyway.

The change to vo_destroy() is to make sure all queued asynchronous
reuqests are finished before making the vo_thread exit.

Even though it's only used on MS Windows, it's run on any platform with
any VO, which makes this worse.
2016-08-20 14:46:38 +02:00
wm4 969c011522 ta: add a helper macro 2016-08-20 14:41:12 +02:00
wm4 1a8af89b7d vo: fix mismatching types in pointer operation
run_control() dereferences an uint32_t as int. Whether this is allowed
depends on what uint32_t is typedefed to (dereferencing an unsigned int
as int should be fine). Fix it by always using int. The uint32_t type
never really made sense.
2016-08-20 14:11:35 +02:00
Paul B Mahol e057629493 af_lavrresample: better swr reinitialization 2016-08-20 11:37:06 +02:00
rr- cb31e72589 manpage: info about --panscan vs. --video-unscaled 2016-08-19 22:53:17 +02:00
rr- ed644b0d33 aspect: add --video-unscaled=downscale-big 2016-08-19 22:51:46 +02:00
wm4 23993e91f3 af_lavrresample: fix error if resampler could not be recreated
There are situations where the resampler is destroyed and recreated
during playback. If recreating the resampler unexpectedly fails, the
filter function is supposed to return an error. This wasn't done
correctly, because get_out_samples() accessed the resampler before the
check. Move the check up to fix this.
2016-08-19 22:27:15 +02:00
James Ross-Gowan 68dc869d6a command: prevent O(n^2) behaviour for playlist property
When fetching the playlist property, playlist_entry_from_index would be
called for each playlist entry, which traversed a linked list to get the
entry corresponding to the specified index. This was very slow for large
playlists. Since get_playlist_entry is called for each index in order,
it can avoid a full traversal of the linked list by using the next
pointer on the previously requested entry.
2016-08-20 00:07:32 +10:00
wm4 e5f61c2bd5 vd_lavc: remove unnecessary initialization
This is already the default value.
2016-08-19 15:00:58 +02:00
wm4 2fbd1d3610 demux: change fps field to double
Because why not.
2016-08-19 15:00:58 +02:00
wm4 05e4df3f0c video/audio: always provide "proper" timestamps to libavcodec
Instead of passing through double float timestamps opaquely, pass real
timestamps. Do so by always setting a valid timebase on the
AVCodecContext for audio and video decoding.

Specifically try not to round timestamps to a too coarse timebase, which
could round off small adjustments to timestamps (such as for start time
rebasing or demux_timeline). If the timebase is considered too coarse,
make it finer.

This gets rid of the need to do this specifically for some hardware
decoding wrapper. The old method of passing through double timestamps
was also a bit questionable. While libavcodec is not supposed to
interpret timestamps at all if no timebase is provided, it was
needlessly tricky. Also, it actually does compare them with
AV_NOPTS_VALUE. This change will probably also reduce confusion in the
future.
2016-08-19 14:59:30 +02:00
wm4 4aaa83339c av_common: improve rounding for float->int timestamp conversions 2016-08-19 14:11:32 +02:00
wm4 5d2dfbdfca player: refresh very low framerate video on filter changes
Limit the max. time the refresh is delayed. Make it refresh at all if
image mode is enabled.

Fixes #3435.
2016-08-19 09:38:45 +02:00
wm4 4e3663a2da vf_rotate: allow arbitrary rotation
vf_rotate selects the correct filter for 90° rotation, but it can be
extended to use lavfi's vf_rotate as fallback.

See #3434.
2016-08-19 09:37:52 +02:00
wm4 e6952c7053 github: fix typo 2016-08-18 21:17:25 +02:00
wm4 0f83caf96a github: encourage bug reports
Word this sentence slightly more positively because we are a positive
project.
2016-08-18 21:05:20 +02:00
wm4 1e53fc3a15 demux_lavf: don't report start time for ogg
Better with ogg shoutcast streams. These have PTS resets on each
playlist item, so the PTS would usually reset to some negative value.
2016-08-18 21:03:01 +02:00
wm4 a1dec6f54a player: make looping slightly more seamless
This affects A-B loops and --loop-file, and audio. Instead of dropping
audio by resetting the AO, try to make it seamless by not sending data
after the loop point, and after the seek send new data without a reset.
2016-08-18 20:40:23 +02:00
wm4 bbcd0b6a03 audio: improve aspects of EOF handling
The code actually kept going out of EOF mode into resync mode back into
EOF mode when the playloop had to wait after an audio EOF caused by the
endpts. This would break seamless looping (as added by the next commit).

Apply endpts earlier, to ensure the filter_audio() function always
returns AD_EOF in this case.

The idiotic ao_buffer makes this an amazing pain in the ass.
2016-08-18 20:38:09 +02:00
wm4 7bba97b301 video: don't discard video frames after endpts
Instead of letting it keep decoding by trying to find a new frame,
"plug" the frame queue by not removing it. (Or actually, by putting
it back instead of discarding it.)

Matters for seamless looping (following commits), and possibly some
other corner cases.

The added function vf_unread_output_frame() is a bit of a sin, but still
reasonable, since its implementation is trivial.
2016-08-18 20:37:25 +02:00
wm4 0a0967f48b build: make avutil-mastering-metadata check slightly more robust
Fixes the specific scenario of compiling against a local Libav build,
while the system has FFmpeg installed.
2016-08-18 14:55:43 +02:00
jaseg e02cb674ce manpage: input: fix define-section syntax
Source says "force", manpage said "forced". Now both say "force".
2016-08-17 23:33:20 +02:00
wm4 f5bbb5aed2 player: add option to control duration of image display
The --image-display-duration option controls how long an image is
displayed. It's also possible to display the image forever (until manual
user interaction stops playback).

With this, the core drops the old method to "drain" video (i.e. waiting
for the last frame duration on end of playback). Instead, we reuse
MPContext.time_frame. The old mechanism was disabled for non-images
anyway.

Fixes #3425.
2016-08-17 22:46:48 +02:00
wm4 07f8b64754 m_option: add mechanism to allow inf/-inf float options
Used by the next commit.
2016-08-17 21:48:56 +02:00
wm4 3a7e86ff6e m_option: simplify float value range handling
Use clamp_double() to handle all value restriction/verification. The
error messages become a bit less nice, but they were kind of incomplete
before.
2016-08-17 21:44:05 +02:00
wm4 12e251c29e demux: fix undefined behavior with ogg metadata update
When an ogg track upodates metadata, we have to perform a complicated
runtime update due to the demux.c architecture. A detail was broken and
an array was allocated with the previous number of streams, which
usually led to invalid memory write accesses at least on the first
update.

See github commit comment on commit b9ba9a89.
2016-08-16 10:48:54 +02:00
wm4 814dacdd7d af_lavrresample: work around libswresample misbehavior
The touched code is for seek resets and such - we simply want to reset
the entire resample state. But I noticed after a seek a tiny bit of
audio is missing (mpv's audio sync code inserted silence to compensate).

It turns out swr_drop_output() either does not reset some internal state
as we expect, or it's designed to drop not only buffered samples, but
also future samples.

On the other hand, libavresample's avresample_read(), does not have this
problem. (It is also pretty explicit in what it does - return/skip
buffered data, nothing else.)

Is the libswresample behavior a bug? Or a feature? Does nobody even
know? Who cares - use the hammer to unfuck the situation. Destroy and
deallocate the libswresample context and recreate it. On every seek.
2016-08-16 00:05:34 +02:00
wm4 86fa1e6129 player: allow passing flags to queue_seek()
Change the last parameter from a bool to an int, which is supposed to
take bit-flags. The at this point only flag is MPSEEK_FLAG_DELAY, which
replaces the previous bool parameter. The old false parameter becomes 0,
the old true parameter becomes MPSEEK_FLAG_DELAY.

Since the old "immediate" parameter is now essentially inverted, two
coalesced immediate and delayed seeks end up as delayed instead of
immediate. This change doesn't matter, since there are no relative
immediate seeks anyway.
2016-08-15 21:07:32 +02:00
Martin Herkt 795b65b2ff DOCS: Update version 2016-08-15 16:16:17 +02:00
Martin Herkt ef2d6ed125 Release 0.19.0 2016-08-15 16:10:59 +02:00
Martin Herkt fd1bc95b48 Merge branch 'master' into release/current 2016-08-15 15:19:29 +02:00
Paul B Mahol d7a7e9a8c8 vo_direct3d: add missing header
Fixes build under cygwin.

Signed-off-by: wm4 <wm4@nowhere>
2016-08-14 21:51:59 +02:00
wm4 4a8647b6b8 sub: don't potentially discard too many subtitles on seek
The accepts_packet packet callback is supposed to deal with subtitle
decoders which have only a small queue of current subtitle events (i.e.
sd_lavc.c), in case feeding it too many packets would discard events
that are still needed.

Normally, the number of subtitles that need to be preserved is estimated
by the rendering pts (get_bitmaps() argument). Rendering lags behind
decoding, so normally the rendering pts is smaller than the next video
frame pts, and we simply discard all subtitle events until the rendering
pts.

This breaks down in some annoying corner cases. One of them is seeking
backwards: the VO will still try to render the old PTS during seeks,
which passes a high PTS to the subtitle renderer, which in turn would
discard more subtitles than it should. There is a similar issue with
forward seeks. Add hacks to deal with those issues.

There should be a better way to deal with the essentially unknown
"rendering position", which is made worse by screenshots or rendering
with vf_sub. At the very least, we could handle seeks better, and e.g.
either force the VO not to re-render subs after seeks (ugly), or
introduce seek sequence numbers to distinguish attempts to render
earlier subtitles when a seek is done.
2016-08-14 20:27:37 +02:00
wm4 4b5de33e89 command: add replaygain information properties to track-list 2016-08-13 15:21:09 +02:00
wm4 9d2bcd2ef9 demux: minor cleanup to replaygain error handling
If the PEAK tag is invalid, return an error.

Make the error signalling conventions more uniform by strictly returning
a negative value on error, and treating >=0 as success.
2016-08-13 15:09:03 +02:00
wm4 e392d6610d demux: make ALBUM replaygain tags optional
IF they're missing, use the TRACK ones instead. See #3405.
2016-08-13 15:06:45 +02:00
wm4 78d808c5bd audio: log replaygain values in af_volume instead demuxer
The demuxer layer usually doesn't log per-stream information, and even
the replaygain information was logged only if it came from tags.

So log it in af_volume instead.
2016-08-13 15:06:07 +02:00
wm4 b9ba9a898a demux: add per-track metadata
...and ignore it. The main purpose is for retrieving per-track
replaygain tags. Other than that per-track tags are not used or accessed
by the playback core yet.

The demuxer infrastructure is still not really good with that whole
synchronization thing (at least in part due to being inherited from
mplayer's single-threaded architecture). A convoluted mechanism is
needed to transport the tags from demuxer thread to user thread. Two
factors contribute to the complexity: tags can change during playback,
and tracks (i.e. struct sh_stream) are not duplicated per thread.

In particular, we update the way replaygain tags are retrieved. We first
try to use per-track tags (common in Matroska) and global tags
(effectively formats like mp3). This part fixes #3405.
2016-08-12 21:39:32 +02:00
Paul B Mahol e2a54bb1ca audio/filter: remove delay audio filter
Similar filter is available in libavfilter.
2016-08-12 19:45:39 +02:00
wm4 ec4a8bdb3d github: encourage providing sample files
Also, try to save users from trying to use the github file upload
function. While we're at it, also make the sprunge.us hint a link.
2016-08-11 22:55:36 +02:00
wm4 dc6f8d4a0a command: add a property that returns filename without extension
Requested. Fixes #3404.
2016-08-11 22:40:00 +02:00
wm4 9024cb1685 manpage: remove the word "slave"
It's discriminatory or something.
2016-08-11 22:29:18 +02:00
Ricardo Constantino 5d74ba98ce stream/stream_bluray: display list of available titles on verbose
Based on similar code on FFmpeg and libbluray's list_titles example.
2016-08-11 10:02:46 +02:00
wm4 87190969a7 player: add --no-autoload-files option
Allt his auto-loading is getting annoying especially for testing.
2016-08-10 22:22:50 +02:00
wm4 367e9fb7f1 ao_alsa: make pause state more robust, reduce minor code duplication
With the previous commit, ao_alsa.c now has 3 possible ways to pause
playback. Actually all 3 of them need get_delay() to fake its return
value, so don't duplicate that code.

Also much of the code looks a bit questionable when considering
inconsistent pause/resume calls from outside, so ignore redundant calls.
2016-08-09 17:09:29 +02:00
wm4 2ded41d2be ao_alsa: handle --audio-stream-silence
push.c does not handle this automatically, and AOs using push.c have to
handle it themselves. Also, ALSA is low-level enough that it needs
explicit support in user code. At least I haven't found any option that
does this.

We still can get away relatively cheaply by abusing underflow-handling
for this. ao_alsa.c already configures ALSA to handle underflows by
playing silence. So we purposely induce an underflow when opening the
device, as well as when pausing or resetting the device.

This introduces minor misbehavior: it doesn't account for the additional
delay the initial silence adds, unless the device has fully played the
fragment of silence when the player starts sending data to it. But
nobody cares.
2016-08-09 17:09:29 +02:00
wm4 062349ff5b player: add --audio-wait-open options
Complements the option added in the previous commit.
2016-08-09 17:09:29 +02:00
wm4 eab92cec60 player: add --audio-stream-silence
Completely insane that this has to be done. Crap for compensating HDMI
crap.
2016-08-09 17:09:29 +02:00
wm4 3759a3f40b ao_coreaudio: actually use stop callback
The .pause callback is never used for pull.c-based AOs.

This means this always streamed silence instead of deactivating audio.
2016-08-09 17:09:29 +02:00
wm4 d81b5690df af_lavcac3enc: allow passing options to libavcodec 2016-08-09 17:09:29 +02:00
Thomas Petazzoni 8c2e299b84 wscript: improve stdatomic check
The current stdatomic check verifies the availability of the function by
calling atomic_load(). It also uses this test to check if linking
against libatomic is needed or not.

Unfortunately, on specific architectures (namely SPARC), using
atomic_load() does *not* require linking against libatomic, while other
atomic operations do. Due to this, mpv's wscript concludes that
stdatomic is available, and that linking against libatomic is not
needed, causing the following link failure:

[190/190] Linking build/mpv
audio/out/ao.c.13.o: In function `ao_query_and_reset_events':
/home/peko/autobuild/instance-0/output/build/mpv-0.18.1/build/../audio/out/ao.c:399: undefined reference to `__atomic_fetch_and_4'

In order to fix this, the stdatomic check is adjusted to call
atomic_fetch_add() instead, which does require libatomic. Thanks to
this, the wscript realizes that linking against libatomic is needed, and
the build works fine.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
2016-08-09 17:09:29 +02:00
wm4 469666b75b stream: fix double-free if cache init fails
If the normal stream cache init fails, and a file cache was initialized
before, we free the file cache as well. But since the file cache is
chained to the real stream, the real stream will also be freed. This has
to be prevented by clearing the pointer to the original stream in the
uncached_stream field.

This could in particular be triggered by using --cache-initial=1000 and
aborting playback during loading. (Without that option, stream cache
init failure is far less likely.)
2016-08-08 11:32:55 +02:00
wm4 896a97c2e2 demux: do not add packets between refresh seek requested and done
Could cause strange issues on seeks or track switches, was only visible
as race condition.
2016-08-08 11:13:43 +02:00
wm4 56c52bd2e1 stream_cb: fix stale comment
Oops.
2016-08-08 10:34:12 +02:00
wm4 355a145a48 DOCS/release-policy.md: reminder to update certain version numbers 2016-08-07 19:43:57 +02:00
wm4 3a21d71ad0 client API: bump API for stream_cb
Forgotten in previous commit.

Also minor semi-related change: remove the extra "," from the
mpv_sub_api enum, which I accidentally added in the previous commit.
(C99 is fine with trailing ",", C89 strictly speaking not. So do
this for maximum compatibility.)
2016-08-07 19:42:20 +02:00
Aman Gupta 7ca4a453e0 client API: add stream_cb API for user-defined stream implementations
Based on #2630. Some heavy changes by committer.

Signed-off-by: wm4 <wm4@nowhere>
2016-08-07 19:33:20 +02:00
wm4 52a0cbe456 client API: fix indentation 2016-08-07 19:33:20 +02:00
wm4 5640ceb838 client API: add MPV_ERROR_GENERIC
Because why not.
2016-08-07 19:33:20 +02:00
wm4 cfed84af2b w32_common: update window size on resize events
Fixes a regression introduced by commit 088a0075.

Fixes #3400.
2016-08-07 19:33:20 +02:00
wm4 259f219438 player: gross hack to improve non-hr seeking with external audio tracks
Relative seeks backwards with external audio tracks does not always work
well: it tends to happen that video seek back further than audio, so
audio will remain silent until the audio's after-seek position is
reached. This happens because we strictly seek both video and audio
demuxer to the approximate desirted target PTS, and then start decoding
from that.

Commit 81358380 removes an older method that was supposed to deal with
this. It was sort of bad, because it could lead to the playback core
freezing by waiting on network.

Ideally, the demuxer layer would probably somehow deal with such seeks,
and do them in a way the audio is seeked after video. Currently this is
infeasible, because the demuxer layer assumes a single demuxer, and
external tracks simply use separate demuxer layers. (MPlayer actually
had a pseudo-demuxer that joined external tracks into a single demuxer,
but this is not flexible enough - and also, the demuxer layer as it
currently exists can't deal with dynamically removing external tracks
either. Maybe some time in the future.)

Instead, add a gross hack, that essentially reseeks the audio if it
detects that it's too far off. The result is actually not too bad,
because we can reuse the mechanism that is used for instant track
switching. This way we can make sure of the right position, without
having to care about certain other issues.

It should be noted that if the audio demuxer is used for other tracks
too, and the demuxer does not support refresh seeking, audio will
probably be off by even a higher amount. But this should be rare.
2016-08-07 16:29:13 +02:00
wm4 c7b73edc65 player: fix mid-stream audio sync condition
This code is for resyncing audio-only streams (e.g. switching between
audio tracks if no video track is active). This must not be run if the
video PTS just isn't known yet. (Although the case in which this changes
anything is probably very obscure, if it can even happen. Still, it's a
bit more correct.)

This is a correction to commit 91a3bda6.
2016-08-07 16:00:14 +02:00
wm4 32cc190a55 player: fix display-sync timing if audio take long on resume
In display-sync mode, the very first video frame is idiotically fully
timed, even though audio has not been synced yet at this point, and the
video frame is more like a "preview" frame. But since it's fully timed,
an underflow is detected if audio takes longer than the display time of
the frame (we send the second frame only after audio is done).

The timing code will try to compensate for the determined desync, but it
really shouldn't. So explicitly discard the timing info in this specific
case. On the other hand, if the first frame still hasn't finished
display, we can pretend everything is ok.

This is a hack - ideally, we either would send a frame without timing
info (and then send it again or so when playback starts properly), or we
would add real pause support to the VO, and pause it during syncing.
2016-08-07 14:14:32 +02:00
wm4 39ae261cc5 demux_timeline: enable refresh seeks in some situations
Play a trick to make the packet pos field monotonically increasing over
segment boundaries if the source demuxers return monotonically
increasing pos values. This allows the demuxer to uniquely identify
packets with the pos field, and can do refresh seeks using that.

Normally, the packet pos field is used as a fallback for determining the
playback position if the demuxer returns no proper duration. But
demux_timeline.c always will, and the packet pos fields usually make no
sense in relation to the returned file size anyway if the timeline
source demuxers originate from separate streams.
2016-08-07 13:53:34 +02:00
wm4 78bcbe289e demux: make refresh seek handling more generic
Remove the explicit whitelisting of formats for refresh seeks. Instead,
check whether the packet position is somewhat reliable during demuxing.
If there are packets without position, or the packet position is not
monotonically increasing, then do not use them for refresh seeks.

This does not make sure of some requirements, such as deterministic
seeks. If that happens, mpv will mess up a bit on stream switching.

Also, add another method that uses DTS to identify packets, and prefer
it to the packet position method. Even if there's a demuxer which
randomizes packet positions, it hardly can do that with DTS. The DTS
method is not always available either, though. Some formats do not have
a DTS, and others are not always strictly monotonic (possibly due to
libavformat codec parsing and timestamp determination issues).
2016-08-06 19:28:41 +02:00
wm4 91a3bda6f5 player: sync audio as well when enabling it mid-stream
If an audio track is enabled during playback, then make it resume at the
exact "current position", instead of playing audio before that position.
This was already done for video.
2016-08-06 17:48:45 +02:00
wm4 7fd3dbcd52 demux: fix a minor race condition
If the packet read function returns, and EOF was detected, and a seek
was issued in the meantime, then don't use the EOF result. The seek will
be processed later, and reset the EOF state anyway.

The main effect is probably that we don't return EOF to the decoders
(which the playback core resets before issuing the seek), and that we
won't log an EOF message.

Not important, but slightly more correct.
2016-08-06 17:48:45 +02:00
wm4 d41f0a54b0 player: improve instant track switching
When switching tracks, we normally have the problem that data gets lost
due to readahead buffering. (Which in turn is because we're stubborn and
instruct the demuxers to discard data on unselected streams.) The
demuxer layer has a hack that re-reads discarded buffered data if a
stream is enabled mid-stream, so track switching will seem instant.

A somewhat similar problem is when all tracks of an external files were
disabled - when enabling the first track, we have to seek to the target
position.

Handle these with the same mechanism. Pass the "current time" to the
demuxer's stream switch function, and let the demuxer figure out what to
do. The demuxer will issue a refresh seek (if possible) to update the
new stream, or will issue a "normal" seek if there was no active stream
yet.

One case that changes is when a video/audio stream is enabled on an
external file with only a subtitle stream active, and the demuxer does
not support rrefresh seeks. This is a fuzzy case, because subtitles are
sparse, and the demuxer might have skipped large amounts of data. We
used to seek (and send the subtitle decoder some subtitle packets
twice). This case is sort of obscure and insane, and the fix would be
questionable, so we simply don't care.

Should mostly fix #3392.
2016-08-06 15:47:04 +02:00
wm4 d4ee5e5a8a build: always require atomics
Always require them, instead of just for some components which have hard
requirements on correct atomic semantics. They should be widely
available, and are supported by all recent gcc and clang compiler
versions. We even have the fallbacks builtins, which should keep this
working on very old gcc releases.

In particular, w32_common.c recently added a hard requirement on
atomics, but checking this properly in the build system would have been
messy. This commit makes sure it always works.

The fallback where weak atomic semantics are always fine is in theory
rather questionable as well.
2016-08-05 17:10:22 +02:00
wm4 b2e5eb13bc ao_wasapi: in exclusive mode do not output multichannel by default
Exactly the same situation as with ao_alsa in commit 0b144eac (except
that we can detect the situation better under wasapi).

Essentially, wasapi will allow us to output any sample format, and not
just the one configured by the user in the audio system settings.
2016-08-05 16:11:42 +02:00
wm4 088a0075c5 w32_common: don't wait for GUI thread when polling for events
VOCTRL_CHECK_EVENTS is called on every frame. This is by design, and is
supposed to check the event queue of the windowing API.

With the decoupled GUI thread in w32_common.c this doesn't make too much
sense, and the purpose of VOCTRL_CHECK_EVENTS is really reduced to
checking event flags. Even worse, waiting on the GUI thread can
interfere with playback, since win32 sometimes blocks the event loop
(e.g. clicking the window title bar).

Change the code such that we really only query the event flags. Use
atomics to avoid having to add a new mutex. (We assume we always have
real atomics available. The build system doesn't check this properly,
and it could fall back to dummy atomics, which are not atomic.)

Should help with #3393. Doesn't help if the core happens to send a
synchronous request, most commonly via VOCTRL_SET_CURSOR_VISIBILITY or
VOCTRL_UPDATE_PLAYBACK_STATE.
2016-08-05 16:04:57 +02:00
wm4 9f70117233 ao_null: use channel list option type for channel-layouts suboption 2016-08-05 12:23:42 +02:00
wm4 eccabeb81c options: fix channels options copy/free operations
For some fucked up reason the arguments can be NULL. Makes no sense to
me, but ok.
2016-08-05 12:23:15 +02:00
Ben Boeckel 0c4a73fa21 tvi_v4l2: fix style in the uninit function 2016-08-05 10:08:57 +02:00
Ben Boeckel fa7beaad1f tvi_v4l2: explicitly brace the code
It's fine either way, but this code is weirdly formatted. Make it more
explicit.
2016-08-05 10:08:52 +02:00
wm4 00091411ec github: discourage bug reports 2016-08-05 00:41:08 +02:00
wm4 0b144eac39 audio: use --audio-channels=auto behavior, except on ALSA
This commit adds an --audio-channel=auto-safe mode, and makes it the
default. This mode behaves like "auto" with most AOs, except with
ao_alsa. The intention is to allow multichannel output by default on
sane APIs. ALSA is not sane as in it's so low level that it will e.g.
configure any layout over HDMI, even if the connected A/V receiver does
not support it. The HDMI fuckup is of course not ALSA's fault, but other
audio APIs normally isolate applications from dealing with this and
require the user to globally configure the correct output layout.

This will help with other AOs too. ao_lavc (encoding) is changed to the
new semantics as well, because it used to force stereo (perhaps because
encoding mode is supposed to produce safe files for crap devices?).
Exclusive mode output on Windows might need to be adjusted accordingly,
as it grants the same kind of low level access as ALSA (requires more
research).

In addition to the things mentioned above, the --audio-channels option
is extended to accept a set of channel layouts. This is supposed to be
the correct way to configure mpv ALSA multichannel output. You need to
put a list of channel layouts that your A/V receiver supports.
2016-08-04 20:49:20 +02:00
wm4 c30aa23401 player: remove special-case for DL/DR speakers
Pointless anyway. With superficial checking I couldn't find any decoder
which actually outputs this, and AO chmap negotiation would properly
ignore them anyway in most cases.
2016-08-04 19:14:35 +02:00
wm4 efa9fe8edf options: un-restrict --audio-delay
Not a real reason to restrict its value range.
2016-08-04 11:27:15 +02:00
wm4 3c3361217c player: offset demuxer on start/seek properly with audio/sub delay
Assume you use a large value like --audio-delay=20. Then until now the
player would just have seeked normally to a "too late" position, and
played silence for about 20 seconds until audio in the correct time
range is coming again.

Change this by offsetting seeks by the right amount. This works for both
external and muxed files. If a seek isn't precise, then it works only
for external files.

This might cause issues with very large delay options. Hr-seek skipping
could take a lot of time (especially because it affects video too), the
demuxer queue could overflow, and other weird corner cases could appear.
But we just try this on best-effort basis, and if the user uses extreme
values we don't guarantee good behavior.
2016-08-04 11:26:57 +02:00
wm4 356e703510 vo_opengl_cb: log better error message if OpenGL not initialized by user
Otherwise opengl/video.c would confusingly complain about a wrong
version, which in this case makes no sense.
2016-08-03 19:18:00 +02:00
wm4 f3c35d8108 af_lavcac3enc: skip output if there was no input frame
Unrealistic corner case: drainning was initiated right after a seek.
2016-08-02 22:06:22 +02:00
Rostislav Pehlivanov dea738a245 wayland_common: check for NULL current_output on fs switching
Prevents segfaults when a fullscreen switch is issued before fully
initializing the VO.
Doesn't change anything since the schedule_resize is only there to
resize in case the image size switches, which happens long after init.
2016-08-01 22:16:40 +02:00
wm4 251299da4f af_lavcac3enc: fix buffering timestamps calculations
In theory, an encoder could buffer some data.
2016-08-01 19:59:59 +02:00
wm4 2e3db648b5 af_lavcac3enc: fix memory leak
A major one. Oops.
2016-08-01 17:59:37 +02:00
Rostislav Pehlivanov 08a4af5e6e wayland_common: provide the real scaled window resolution
It makes more sense to completely abstract this scaling inside the
backend so that internally the player only works with real actual
drawn pixels.
2016-08-01 00:31:34 +02:00
wm4 0432ab8f09 af_lavcac3enc: fix a debug message 2016-07-31 18:51:10 +02:00
wm4 0a1c87464b af_lavcac3enc: error out properly if encoding fails 2016-07-31 18:51:08 +02:00
wm4 48f60e182a af_lavcac3enc: fix aspects of AVFrame handling
We send a refcounted frame to the encoder, but then disrespect
refcounting rules and write to the frame data without making sure the
buffer is really writeable.

In theory this can lead to reallocation on every frame is the encoder
really keeps a reference. If we really cared, we could fix this by
providing a buffer pool. But then again, we don't care.
2016-07-31 18:51:05 +02:00
wm4 98af572484 audio: make mp_audio_realloc[_min] ensure frame is writeable
This is logical: the function makes sense only in situations where you
are going to write to the audio data. To make it worse,
av_buffer_realloc() also handles this situation, but only if the buffer
size changes (simply because it can't realloc memory in use), so we have
to explicitly force reallocation by unreffing the buffers first.
2016-07-31 18:51:02 +02:00
Ricardo Constantino 5bcb22beea ytdl: Error out with http_dash_segments
Unsupported for now.
2016-07-30 19:02:39 +02:00
wm4 546f7472fb options: add vp9 to --hwdec-codecs 2016-07-30 15:47:51 +02:00
Rostislav Pehlivanov 45687c17f7 wayland_common: fix fullscreen image switching bug
The problem was that when in fullscreen, switching between images did
not issue a resize event, causing none of the images to be rendered
correctly.
This fixes the problem by issuing a resize event with the screen width
and height.
This commit also moves the zeroing of the events field to when it gets
retrieved by mpv rather than randomly after a resize in the vo/backend
code.
2016-07-30 15:33:00 +02:00
Rostislav Pehlivanov 2f986a5980 wayland_common: prevent black bars on most non-native aspect ratios
ssurface_handle_configure()'s width and height are just hints given by
the compositor, the application's free to not respect those strictly and
to compensate for e.g. aspect ratio.
This prevents crazy scenarios in which pictures with portrait aspect
ratios have a huge black area to make them 16:9 or whatever the
compositor feels like.
2016-07-30 15:32:57 +02:00
Eric Toombs 27b59e1940 demux_raw: s16be support was missing due to small typo
Signed-off-by: wm4 <wm4@nowhere>
2016-07-30 00:05:40 +02:00
Jan Ekström aaf6e3b58d wscript: add proper non-version'd SONAME for Android
This seems to have become a requirement since API target 23+, and
matches what FFmpeg does.
2016-07-30 00:02:40 +02:00
Chris Mayo f95cde60ff build: add --htmldir option
Defaults to docdir but makes it possible to install html documentation
separately.
2016-07-30 00:02:40 +02:00
Rostislav Pehlivanov 3fe5ff99c6 wayland_common: clip window size to the display output size
With X11 it was usually left up to the window manager to prevent huge
windows from being out of range, but no Wayland compositor will do
this right now.

Hugely improves usability when using mpv as an image viewer.
2016-07-30 00:02:40 +02:00
Rostislav Pehlivanov f918ec4b2b wayland_common: flush wakeup_pipe on a wakeup
Missed during the recent changes.
Also simplify error checking code and check for POLLNVAL
as well (the display fd was never actually checked to be valid).
2016-07-30 00:02:39 +02:00
Rostislav Pehlivanov c3e11f7b7c osdep/io: introduce mp_flush_wakeup_pipe()
Makes a fairly common occurence with wakeup_pipes easier to handle.
2016-07-30 00:02:39 +02:00
Rostislav Pehlivanov f3f4e048d8 wayland_common: remove untested/unusable wayland dnd code
Not worth keeping 200 lines of untestable as of today code which might
be broken, if it hasn't been already.
2016-07-30 00:02:39 +02:00
Niklas Haas 46b60a3e72 vo_opengl: remove the 3dlut-size npot2 restriction
This requires changing the pixel upload alignment because the odd sizes
might not be aligned to multiples of 4.

Anyway, the restriction has no real benefit and the sizes in between 32
and 64 might be worth using, so just drop it.
2016-07-25 12:50:11 +02:00
Niklas Haas f127869037 vo_opengl: reduce default 3dlut-size to 64x64x64
Following testing after ebe798a, this is a more than sufficient size to
cover our use case.

The old default was a drop of about 58 dB PSNR using the old code, and
this new default is about 65 dB PSNR, so it's actually an improvement
despite resulting in a smaller size.

There was no outlier whatsoever when comparing sizes around the 64
neighbourhood (with every step corresponding to a PSNR drop of about
0.07 dB), so I picked this since it's a power of two and requires no
change to the current 3dlut-size parsing logic.

I also tested smaller sizes such as 32x32x32 which performed almost as
well on colorful samples, but this results in noticeable black boost in
the dark regions, which is pretty undesirable. Therefore, we should
avoid going much further below 64x64x64.

Either way, this new size is so fast to compute that the 3dlut cache is
almost useless on my end. In fact, it might even be slower to load the
profile from the cache than to recompute it from scratch. (For caches on
a disk. For cache on a tmpfs, it makes no difference)
2016-07-25 12:50:04 +02:00
wm4 cb4342dda4 x11: do not accidentally discard event flags
It seems vo_x11_check_events() was supposed to return the currently
flagged events and reset them. But there are many places where
vo_x11_check_events() is called without checking its return value. This
could lead to forgotten events.

Change the code such that they can't get lost.
2016-07-25 11:28:06 +02:00
Niklas Haas ebe798a333 vo_opengl: increase 3DLUT accuracy at lower LUT sizes
This code had the exact same texture indexing bug that the original
scaler code had before the introduction of the LUT_POS macro to fix it.

We can re-use this same macro here, and the performance drop is
virtually entirely negligible. The benefit is greatly improved LUT
accuracy as the 3DLUT size decreases - in particular, the old LUT
started introducing more and more black crush the lower your LUT size is
(because the error was essentially an over-contrast bias, with a
magnitude linearly related to the lut size).

The new code improves black stability as the LUT size decreases, and
only at very low values (16 and below) do black levels start noticeably
getting affected (due to crude linearization of the nonlinear response
curve).

The default value of 3dlut-size is definitely generous enough for this
to make no difference out of the box, but it also causes no performance
drop at all on my machine so I see no harm in improving the logic.
Furthermore, this means we could easily decrease the default 3dlut size
in a future commit, perhaps even down to 64x64x64 as a default. (But
more testing is warranted here)
2016-07-25 10:26:45 +02:00
wm4 dcfde2934d audio: use idiotic FFmpeg ABI rules for public-except-not-public fields
The FFmpeg API is incredibly weird and inconsistent about this. This is
also a FFmpeg-only issue and nothing like this is in Libav - which
doesn't really show FFmpeg in a very positive light.

(To make it even worse: this is a full-blown Libav API incompatibility,
even though this crap was added for Libav ABI-compatibility. It's
absurd.)

Quoting the FFmpeg header for the AVFrame.channels field:

    /**
     * number of audio channels, only used for audio.
     * Code outside libavutil should access this field using:
     * av_frame_get_channels(frame)
     * - encoding: unused
     * - decoding: Read by user.
     */
    int channels;

It says "should" not must, and it doesn't even mention
av_frame_set_channels(). It's also in the section for public fields (not
below a marker that indicates private fields in a public struct, like
it's done e.g. in AVCodecContext).

But not using the accessor will cause silent failures on ABI changes.
The failure that happened due to this code didn't even make it apparent
what was wrong. So just use the idiotic accessor.

Also harmonize the FFmpeg-cursing in the code. (It's fully justified.)

Fixes #3295.

Note that mpv will still check the exact library version numbers, and
reject mismatches - to protect itself from such issues in the future.
2016-07-24 19:33:20 +02:00
wm4 6bb48a10db player: disable DS with spdif transcoding too
Otherwise it behaves dumb. (Although you could argue it shouldn't try to
guess whether speed changes work, but instead simply disable DS if they
don't work.)
2016-07-24 19:19:24 +02:00
wm4 3623cec7d2 af_lavcac3enc: use common code for AVFrame setup 2016-07-24 19:06:00 +02:00
wm4 d60db967bd demux_lavf: remove subtitle seeking special-case
It used not to work - but now it apparently does. Not sure when that got
fixed in FFmpeg, but there's no longer a reason to keep this hack.

This also gets rid of the check for the read_seek2 field, which is not
part of the public API.
2016-07-24 18:41:55 +02:00
wm4 99d9921f39 vo_opengl: glctx can be NULL during init
This fixes a crash that can happen with the Cocoa backend: it calls
vo_wakeup() during init, which calls vo_opengl.c/wakeup().

Fixes #3360.
2016-07-21 16:07:15 +02:00
wm4 16d276308a x11, wayland: do not accidentally close FD 0
Both backends have code to close each FD of their wakeup_pipe array.
This array is default-initialized with 0, which means if the backends
exit before the wakeup pipe is created (e.g. when probing), they would
close FD 0.

Initialize the FDs with -1. Then we call close(-1) in these situations,
which is perfectly allowed and has no bad consequences.
2016-07-21 15:18:32 +02:00
wm4 b4acfcc8aa vo: remove now unused event_fd handling 2016-07-21 14:48:30 +02:00
Rostislav Pehlivanov c6b83fec7d wayland_common: make function declaration consistent
Half the code had a space before the arguments and half didn't.
2016-07-21 14:45:40 +02:00
Rostislav Pehlivanov c0ef3cf9c2 wayland: port to the new wakeup/wait_events framework
This fits natively into the vo/backend and allows to simplify the
polling code.
One new change is the fact that surface_handle_enter flags VO_EVENT_WIN_STATE
and VO_EVENT_RESIZE instead of only VO_EVENT_WIN_STATE. Before this, the code
hackily relied on the timeout and the loop in the wait_frame function to track
and set the scaling factor. Instead, this triggers mpv to run a schedule_resize
and adjust the new VO output dimensions immediately. This is also more accurate
since surface_handle_enter() gets called when a surface is created, moved and
resized, which is exactly what the rest of the player might be interested in.
2016-07-21 14:45:38 +02:00
wm4 8f51418ca4 manpage: not-document tscale=linear 2016-07-21 12:26:05 +02:00
Niklas Haas 7d01a16f64 vo_opengl: add a tscale=linear direct implementation
This uses GLSL mix() instead of going through an indirect texture
access. Easy to implement and might require less resources on some
devices, since the oversample code was already essentially just a
special case of this.

Could be made the new default (as per issue #2685), but that should be
done in a separate commit.
2016-07-21 11:26:19 +02:00
Akemi f53c7f1a78 cocoa: remove unused icc profile variables 2016-07-21 08:48:45 +02:00
Akemi 7531275f62 cocoa: update screen fps only if necessary
we don't need to update the display refresh rate
when going fullscreen or updating the colour profile
2016-07-21 08:48:37 +02:00
wm4 fde784129f x11: stop using vo.event_fd
Instead let it do its own event loop wakeup handling.
2016-07-20 20:52:08 +02:00
wm4 bd9c0a10e5 vo_opengl: allow backends to provide callbacks for custom event loops
Until now, this has been either handled over vo.event_fd (which should
go away), or by putting event handling on a separate thread. The
backends which do the latter do it for a reason and won't need this, but
X11 and Wayland will, in order to get rid of event_fd.
2016-07-20 20:42:30 +02:00
Rostislav Pehlivanov e11a20a812 vo_wayland: fix high CPU usage due to busy polling
There's no need to call wl_display_flush() since all the client-side
buffered data has already been flushed prior to polling the fd.
Instead only check for POLLIN and the usual ERR+HUP.
2016-07-19 10:01:51 +02:00
wm4 64cd0f4292 x11: skip ICC update on every window move
Don't just cause vo_opengl to update the ICC profile every time the
window is moved. Instead, explicitly check if the screen was changed.

Mostly untested.
2016-07-18 13:06:38 +02:00
wm4 510c6a1be4 libarchive: sanitize non-UTF8 archive entries
Some client API users simply don't like such filenames. For their sake,
don't return them, but return a dummy filename instead. (Returning a
latin1-ized version would work too, but is slightly more work.)

Also remove the "\n" from the replacement dummy filename. This was
accidental.
2016-07-18 12:52:59 +02:00
wm4 fb8deb69a6 libarchive: unify entry iteration between stream/demux layers
No really good reason to duplicate this.
2016-07-18 12:44:56 +02:00
wm4 77e1e8e38e audio: refactor mixer code and delete mixer.c
mixer.c didn't really deserve to be separate anymore, as half of its
contents were unnecessary glue code after recent changes. It also
created a weird split between audio.c and af.c due to the fact that
mixer.c could insert audio filters. With the code being in audio.c
directly, together with other code that unserts filters during runtime,
it will be possible to cleanup this code a bit and make it work like the
video filter code.

As part of this change, make the balance code work like the volume code,
and add an option to back the current balance value. Also, since the
balance semantics are unexpected for most users (panning between the
audio channels, instead of just changing the relative volume), and there
are some other volumes, formally deprecate both the old property and the
new option.
2016-07-17 19:21:28 +02:00
wm4 79974e7ad9 audio: fix crashes due to broken uninit check
Since mixer->ao is always NULL now (it was really just forgotten to be
removed), the uninit call never actually cleared the af field, leaving
a dangling pointer that could be accessed by volume control.
2016-07-15 23:11:25 +02:00
wm4 ea18cb99ba vf_vavpp: get rid of mp_refqueue_is_interlaced()
This makes the difference between passing VA_FRAME_PICTURE or
VA_BOTTOM_FIELD for progressive frames (that should be force-
deinterlaced) to VAProcPipelineParameterBuffer.flags. VA-VPP doesn't
really seem to care, and we can get rid of mp_refqueue_is_interlaced()
entirely. It could be argued it's better to pass field flags instead of
the progressive flag.
2016-07-15 20:37:46 +02:00
wm4 c5361d12d8 vf_d3d11vpp: fix interlaced-only=no mode
"Real" frame flag vs. what we pretend it to be. It always used the real
flag, and thus never deinterlaced unflagged frames, even if the
suboption was set to "no".
2016-07-15 20:21:03 +02:00
wm4 358932a109 vf_d3d11vpp: add video processor selection
Unfortunately completely useless. I still don't know how to force a
video processor to use a specific algorithm, if it's even possible.
2016-07-15 19:48:58 +02:00
wm4 831fc4f012 player: do not cut off terminal status line if it contains newlines
Just a heuristic to preserve the status line in odd corner cases.
Probably a crap idea.

Fixes #3340.
2016-07-15 18:58:36 +02:00
wm4 f29bba1123 af: avoid rebuilding filter chain in another minor case
No need to create additional noise of we can trivially see that
rebuiding the chain won't change anything.
2016-07-15 13:04:17 +02:00
wm4 48f9ea7104 videotoolbox: add yuv420p to --videotoolbox-format 2016-07-15 13:04:17 +02:00
wm4 ae94f329a9 vo_opengl: hwdec: reset hw_subfmt field
In theory, mp_image_params with hw_subfmt set to non-0 if imgfmt is not
a hwaccel format is invalid. (It worked fine because nothing checks this
yet.)
2016-07-15 13:04:17 +02:00
wm4 85488f6892 video: change hw_subfmt meaning
The hw_subfmt field roughly corresponds to the field
AVHWFramesContext.sw_format in ffmpeg. The ffmpeg one is of the type
AVPixelFormat (instead of the underlying hardware format), so it's a
good idea to switch to this too for preparation.

Now the hw_subfmt field is an mp_imgfmt instead of an opaque/API-
specific number. VDPAU and Direct3D11 already used mp_imgfmt, but
Videotoolbox and VAAPI had to be switched.

One somewhat user-visible change is that the verbose log will now always
show the hw_subfmt as image format, instead of as nonsensical number.

(In the end it would be good if we could switch to AVHWFramesContext
completely, but the upstream API is incomplete and doesn't cover
Direct3D11 and Videotoolbox.)
2016-07-15 13:04:17 +02:00
Martin Herkt 4a4a9f3302 man: fix PDF build error
ReportLab really doesn’t like breaking inline literals, so insert an
explicit line break.

Fixes #3338
2016-07-15 12:59:26 +02:00
Aman Gupta 588b2f48e5 videotoolbox: add --hwdec=videotoolbox-copy for h/w accelerated decoding with video filters 2016-07-15 01:01:17 +02:00
wm4 e656889624 DOCS/compile-windows.md: MSVC DLL usage instructions 2016-07-14 22:40:10 +02:00
Timotej Lazar 91a1b17104 Use - as command-name separator everywhere
Old-style commands using _ as separator (e.g. show_progress) were still
used in some places, including documentation and configuration files.
This commit updates all such instances to the new style (show-progress)
so that commands are easier to find in the manual.
2016-07-14 22:37:42 +02:00
wm4 6e45e1de77 demux_timeline: restore mkv edition switching 2016-07-14 18:26:58 +02:00
wm4 d191d76e52 ao_pulse: fix some volume control rounding issues
Volume could get easily "stuck" or making too huge steps when doing
things like "add ao-volume 1".
2016-07-14 18:11:14 +02:00
wm4 f53d73b9dc ao_creoaudio: print OSStatus as decimal signed integer too
OSStatus is quite inconsistent. Sometimes it's a FourCC, sometimes it
reads as decimal signed number.
2016-07-13 17:07:06 +02:00
wm4 79f48500e2 ao_coreaudio: use correct free function on errors 2016-07-13 16:34:00 +02:00
wm4 b5bc93d009 manpage: add some missing color management related sub-properties 2016-07-13 11:05:27 +02:00
Niklas Haas a14f9249c4 command: add properties for HDR metadata
Since it turns out that knowing what exactly a file was tagged with can
be useful for debugging purposes, expose this as a property so I can
check it more easily.

This is mostly useful for sig-peak (since nom-peak is currently entirely
calculated by us), but I added both for consistency.
2016-07-13 11:03:42 +02:00
wm4 8b47e5daa4 video: respect --deinterlace=auto
--deinterlace=auto is the default, and has the obscure semantics that
deinterlacing is disabled, unless the user has manually inserted a
deinterlacing filter.

While in software decoding this doesn't matter, and we will happily
insert 2 yadif filters (if the user has already added one), or not
remove the yadif filter (if deinterlacing is disabled, but the user has
added the filter manually), this is different with hardware deinterlacer
filters. These support VFCTRL_SET_DEINTERLACE for toggling deinterlacing
filtering at runtime. It exists mainly for legacy reasons, and possibly
because it makes switching deinterlacing modes more efficient. It might
also gives us an entry-point for VO deinterlacing, maybe. For whatever
reasons this mechanism exists, we still support and use it.

This commit fixes that video.c always used VFCTRL_SET_DEINTERLACE to
disable deinterlacing, even if --deinterlace=auto was set. Fix this by
checking the value of the option directly.
2016-07-12 19:37:09 +02:00
James Ross-Gowan bf2e2bf3e8 win32: mpv.rc: re-add version info
For some reason, the lack of version info was preventing mpv from
appearing in the Default Programs dialog. Re-add it, but don't set the
string version numbers from version.h, because that's what was causing
trouble when the version info was removed. Like the binary version
numbers, these are now hardcoded to 2.0.0.0, which probably doesn't
matter.

The new version info block is also slightly different to the old one. It
fills out all the binary VERSIONINFO fields and makes better use of
macros. It also removes the \000 line terminators from the string
version info, since as far as I can tell, this was just cargo-culting
for an old broken version of the Microsoft resource compiler, and
binutils' windres terminates the strings properly without them.
2016-07-12 21:05:33 +10:00
James Ross-Gowan 43e811cb4b vo_opengl: angle: use WARP if there are no hw adapters
This should get mpv working on Windows 7 machines without hardware
accelerated graphics adapters. It already worked on Windows 8 and up
because those systems would silently fall back to WARP if there was no
graphics hardware installed.

The normal MPGL_CAP_SW flag is not set, so unlike other opengl backends,
this will choose a software adapter even if opengl:sw is not specified.
The reason for this is, unlike on Linux, where vo_xv and vo_x11 can be
used, mpv on Windows does not have any VO to fall back on when hardware
acceleration isn't available, so if software adapters are rejected, the
user won't see any video output when using the default settings. WARP
seems to perform quite well, so it should be used in this case.
2016-07-12 20:26:41 +10:00
wm4 2d44dfaba9 cache: minor simplification
Every cache_wakeup_and_wait() caller has to deal with asynchronous
stream abort, so why not make it somehow part of the function.
2016-07-11 22:20:23 +02:00
wm4 f4d62dc4a0 cache: fix previous commit
The cache reader thread actually unlocks the mutex protecting the
underlying stream while reading from it. That's why other code goes out
of its way to run certain stream operations on the cache thread. Do the
same.

We could have this simpler by creating a mechanism that would "park" the
cache thread and make it wait for the lock (while we have it) in order
to gain exclusive access. This could be done in the future.
2016-07-11 22:16:06 +02:00
wm4 374600cec0 cache: propagate seek failures
Eagerly execute seeks to the underlying stream in the cache seek
entrypoint itself. While asynchronous execution is a goal of the cache,
it doesn't matter too much for seeks. They always were executed within
the lock, so the reader was blocked anyway. It's not necessary to ensure
async. execution here either, because seeks are relatively rare, and the
demuxer can just stay blocked for a while.

Fixes: mpv http://samples.mplayerhq.hu/V-codecs/DIV5/ayaneshk-test.avi
2016-07-11 20:52:30 +02:00
James Ross-Gowan 5a6ba2a4fd vo_opengl: angle: try D3D9 when D3D11 fails eglInitialize
This will happen when D3D11 is present on the machine but the supported
feature level is too low.
2016-07-11 22:07:13 +10:00
wm4 e246c3f060 audio: fix code for adjusting conversion filters
This code was supposed to adjust existing conversion filters (to make
them output a different format). But the code was just broken,
apparently a refactoring accident. It accessed af instead of af->prev.

The bug tended to add new conversion filters, even if an existing one
could have been used. (Can be tested by inserting a dummy lavrresample
filter followed by a format filter which forces conversion.)

In addition, it's probably better to return the actual error code if
reinitializing the filter fails. It would then respect an AF_FALSE
return value, which means format negotiation failed, instead of a
generic error.
2016-07-11 12:23:32 +02:00
wm4 61afe3820a af_volume: don't let softvol overwrite af_volume volumedb sub-option
af_volume has a volumedb sub-option, which allows the user to set an
explicit volume. Until recently, the player read back this value and
used it as initial softvol volume. But now it just overwrites it.

Instead of overwriting it, multiply the different gain values. Above
all, this will do the right thing if only softvol is used, or if the
user only adds the af_volume filter manually.
2016-07-11 11:03:36 +02:00
wm4 60048b7eb9 audio: add heuristic to move auto-downmixing before other filters
Normally, you want downmixing to happen first thing in the filter chain.
This is reflected in codec downmixing, which feeds the filter chain
downmixed audio in the first place. Doing this has the advantage of
needing less data to process. But the main motivation is that if there
is a drc filter in the chain, you want to process it the downmixed
audio.

Add an idiotic heuristic to achieve this. It tries to detect whether the
audio was indeed automatically downmixed (or upmixed). To detect what
the output format is going to be, it builds the filter chain normally,
and then retries with the heuristic applied (and for extra paranoia,
retries without the heuristic again if it fails to successfully rebuild
the filter chain for unknown reasons). This is simple and will work in
almost all cases.

Doing it in a more complete way is rather hard, because filters are so
generic. For example, we know absolutely nothing about the behavior of
af_lavfi, which creates an opaque filter graph with libavfilter. We
don't know why a filter would e.g. change the channel layout on its
output. (Our heuristic bails out in this case.) We're also slave to the
lowest common denominator of how our format negotiation works, and how
libavfilter's works.

In theory, we could make this mechanism explicit by introducing a
special dummy filter. The filter chain would then try to convert between
input and output formats at the dummy filter, which would give the user
more control over how downmix happens. On the other hand, the user could
just insert explicit conversion filters instead, so this would probably
have questionable value.
2016-07-10 19:53:53 +02:00
wm4 7be98ef1b2 audio: add auto-inserted flag to filter list logging
Like the video filter chain.
2016-07-10 19:51:09 +02:00
wm4 2eac58eaa9 audio: cleanup audio filter format negotiation
The algorithm and functionality is the same, but the code becomes much
simpler and easier to follow.

The assumption that there is only 1 conversion filter (lavrresample)
helps with the simplification, but the main change is to use the same
code for format/channels/rate. Get rid of the different AF_CONTROL_SET_*
controls, and change the af->data parameters directly. (af->data is
badly named, but essentially is a placeholder for the output format.)

Also, instead of trying to use the af_reinit() loop to init inserted
conversion filters or filters with changed output formats, do it inline,
and move the common code to a filter_reinit() function. This gets rid of
the awful retry variable.

In general, this should not change any runtime behavior.
2016-07-10 19:51:09 +02:00
wm4 065bb635d9 manpage: minor fix
Also fix some other type in interface-changes.rst.
2016-07-10 19:51:09 +02:00
Uros Vampl c5827387fd audio: show an osd bar when changing ao-volume
also, make the osd msg prettier
2016-07-10 19:49:28 +02:00
Martin Herkt 1e00bcc14c Release 0.18.1 2016-07-10 02:20:08 +02:00
Martin Herkt 7635438592 Merge branch 'master' into release/current 2016-07-10 01:06:17 +02:00
wm4 e518bf2c72 audio: insert audio-inserted filters at end of chain
This happens to be better for the af_volume filter (for softvol), and
saves some code too. It's "better" because you want to affect the
final filtered audio, such as after a manually inserted drc filter.
2016-07-09 20:23:15 +02:00
wm4 d47b708f00 audio: don't crash when changing volume if no audio is initialized
Oversight.
2016-07-09 19:34:45 +02:00
wm4 2fb2f9b93a man: fix typo 2016-07-09 18:55:14 +02:00
wm4 995c47da9a audio: drop --softvol=no and --softvol=auto
Drop the code for switching the volume options and properties between
af_volume and AO volume controls. interface-changes.rst mentions the
changes in detail.

Do this because this was exceedingly complex and had other problems as
well. It was also very hard to test. It's just not worth the trouble.

Some leftovers like AOCONTROL_HAS_PER_APP_VOLUME will be removed at a
later point.

Fixes #3322.
2016-07-09 18:31:18 +02:00
Jakub Wilk da9590d368 man: fix typos 2016-07-09 16:27:42 +02:00
Jakub Wilk 34a33ebd4d vo_xv, vo_x11: fix typos in warnings 2016-07-09 14:35:41 +02:00
wm4 e58ecc3630 man: fix botched sentence
Fixes #3323.
2016-07-08 19:34:52 +02:00
wm4 6d83455a95 vd_d3d11vpp: remove nonsensical flush call
I made this call up because I sort of thought this makes senssssse. I'm
now convinced that it does not, and even is actively harmful. I'm still
quite in the dark how the DirectD 11 video API is supposed to work with
synchronization, but at least for normal graphics this call would not
make much sense.
2016-07-08 19:34:24 +02:00
wm4 35be389031 x11: add missing FocusChangeMask
So we actually get FocusOut events. Disables key repeat when losing
focus while a key is down.
2016-07-08 16:36:53 +02:00
wm4 885e991312 ao_coreaudio: error out when selecting invalid device
When selecting a device that simply doesn't exist with --audio-device,
AudioUnit will still initialize and start playback without complaining.
But it will never call the audio render callback, which leads to audio
playback simply not progressing.

I couldn't find a way to get AudioUnit to report an error at all, so
here's a crappy hack that takes care of this in most cases. We assume
that all devices have a kAudioDevicePropertyDeviceIsAlive property.
Invalid devices will error when querying the property (with 'obj!' as
status code).

This is not the correct fix, because we try to double-guess AudioUnit's
behavior by accessing a lower label API. Suggestions welcome.
2016-07-08 16:11:03 +02:00
wm4 26b6873ffd client API: remove "status" log level from mpv_request_event docs
Although it appears to be accepted by the function, MSGL_STATUS messages
are never passed to the client API. Consequently "status" has the same
meaning as "v" and is useless.
2016-07-08 16:10:57 +02:00
wm4 71a8aa2e9a command: don't delay progress updates to next video frame 2016-07-08 13:46:15 +02:00
wm4 16b48a429d video: fix midstream video configuration changes
Commit 771a8bf5 added code to avoid unnecessary vf_reconfig() calls for
unrelated reasons, but forget to consider that it has to be called at
least once if the input format changes. As a consequence it got "stuck"
due to not being able to decode more frames.
2016-07-08 08:22:51 +02:00
wm4 f2110f582d vo_vdpau: minor simplification
Remove some indirections that aren't needed anymore.
2016-07-07 16:10:53 +02:00
wm4 8660b4c9f0 video: limit number of frames sent to VO to the VO requested amount
vo_frame can have more than 1 frame - the extra frames are future
references, which are sometimes useful for filtering (vo_opengl
interpolation). There's no harm in reducing the number of frames sent to
the VO requested amount of future frames, so do that.

Doesn't actually reduce the number of concurrently in use frames in
practice.
2016-07-07 16:10:13 +02:00
wm4 ab6fac43b4 player: cut off status line on terminal width
If the status line is wider than the reported terminal size, then cut it
off instead of causing the terminal to scroll down for the next line.

This is done in the most primitive way possible, assuming ASCII.

This was actually done in the past as far as I'm aware; do it again.
(Probably differently.)
2016-07-06 19:52:09 +02:00
wm4 5d2f1da7c5 vf, af: print filter labels in verbose mode 2016-07-06 14:13:03 +02:00
wm4 771a8bf5c6 video: fix deinterlace filter handling for VFCTRL_SET_DEINTERLACE filters
Some filters support VFCTRL_SET_DEINTERLACE. This affects most hardware
deinterlace filters. They can be inserted by the user manually, or auto-
inserted by vf.c itself as conversion filter (vf_d3d11vpp). In these
cases, we shouldn't insert or remove filters outselves, and instead
VFCTRL_SET_DEINTERLACE should be invoked to switch the mode.

This wasn't done correctly in the recently refactored code and could
have broken with --deinterlace. (The refactor only considered switching
via property in this case.) Fix it by making it a proper part of the
filter_reconfig() function, and making set_deinterlacing() (which is
called by the property handler) merely call filter_reconfig() in all
cases to do the real work.

We can even avoid rebuilding the filter chain - though only if no other
auto-filters are inserted. It probably also provides a slightly cleaner
way to implement functionality in the VO while still inserting video
filter fallbacks correctly if required.
2016-07-06 14:08:47 +02:00
wm4 08cd50b84b vf: mark filter chain as uninitialized when mutating it
Sounds fair. Can be used to determine if the filter chain was mutated at
all, and avoiding unconditional reinit if it wasn't.
2016-07-06 13:47:58 +02:00
wm4 0b1ef81498 video: fix deinterlace filter handling on pixel format changes
The test scenario at hand was hardware decoding a file with d3d11 and
with deinterlacing enabled. The file switches to a non-hardware
dedocdeable format mid-stream. This failed, because it tried to call
vf_reconfig() with the old filters inserted, with was fatal due to
vf_d3d11vpp accepting only hardware input formats.

Fix this by always strictly removing all auto-inserted filters
(including the deinterlacing one), and reconfiguring only after that.

Note that this change is good for other situations too, because we
generally don't want to use a hardware deinterlacer for software
decoding by default. They're not necessarily optimal, and VAAPI VPP even
has incomprehensible deinterlacer bugs specifically with software frames
not coming from a hardware decoder.
2016-07-06 13:38:43 +02:00
wm4 fc76966d9e vf: don't clobber input params on reconfigure failure
I think this is more robust, and future commits will rely on it.
2016-07-06 13:27:20 +02:00
wm4 0fe62bc1d2 player: it's not --force-seeking but --force-seekable
Oops. Fuck.
2016-07-06 00:11:57 +02:00
wm4 d72bcc8041 player: rewrite deinterlace filter auto-insertion
Instead of using the "vf" command code (which changes filters at runtime
on user input), use the general filter-insertion code. The latter was
added later, and is more suitable for automatically inserted filters.

The old code failed in particular when using watch-later saving, which
stored the filter list in the resume config file. If a user changed the
hardware decoding mode via command line, the stored filter chain was out
of date and could cause failure due to not working with hardware or
software decoding mode. Storing the deinterlace filter in the filter
list was unavoidable, because it was part of the user state. (The new
code only edits the actually instantiated filters.)
2016-07-05 21:10:26 +02:00
Niklas Haas 329a7147d0 csp: document deviations from the references where they occur
These mostly happen in situations where the correct behavior is
relatively new and not found in the wild (therefore not worth
implementing) and/or extremely complicated (and thus not worth worrying
about the potential edge cases and UI changes).

Still, it's best to document these where they happen to guide the poor
souls maintaining these files in the future.
2016-07-05 19:16:49 +02:00
Ben Boeckel 4f4eea6b44 x11_common: silence xdg-screensaver
Some screen lockers have a habit of dumping output to the terminal when
their output is reset. Ignore its output to keep the TTY output clean.
2016-07-05 19:16:01 +02:00
Ben Boeckel 33e72ed451 subprocess: add a callback to ignore output
This callback is equivalent to shoving data into /dev/null.
2016-07-05 19:15:59 +02:00
James Ross-Gowan 6a3da439cd vo_opengl: angle: update the swapchain on resize
This uses eglPostSubBufferNV to trigger ANGLE to check the window size
and update the size of the swapchain to match, which is recommended
here: https://groups.google.com/d/msg/angleproject/RvyVkjRCQGU/gfKfT64IAgAJ

With the D3D11 backend, using eglPostSubBufferNV with a 0-sized update
region will even skip the Present() call, meaning it won't block for a
vsync period. Hopefully ANGLE will have a less hacky way of doing this
in future. See the relevant ANGLE issue: http://anglebug.com/1438

Fixes #3301
2016-07-04 22:04:37 +10:00
wm4 f98e1b0b96 vo_opengl: error out gracefully when trying to use FBOs without FBO API
This can for example happen with vo_opengl_cb, if it is used with a GL
implementation that does not supports FBOs. (mpv itself should never
attempt to use FBOs if they're not available.)

Without this check it would trigger an assert() in our dummy
glBindFramebuffer wrapper.

Suspected cause of #3308, although it's still unlikely.
2016-07-04 13:34:31 +02:00
wm4 7cd1a3c766 vf_d3d11vpp: fix output image format if not doing any filtering
For example it should be set to IMGFMT_D3D11NV12 if it isn't already.
Otherwise, an assertion in vf.c could trigger.

This probably couldn't be provoked yet.
2016-07-04 11:54:02 +02:00
wm4 46f1ce1e2f input: remove redundant log message 2016-07-04 10:50:00 +02:00
Niklas Haas be230d16e5 vo_opengl: move eval_szexpr to user_shaders.c
This moves some of the bulky user-shader specific logic into the file
dedicated to it. Rather than expose video.c state, variable lookup is
now done via a simulated closure.
2016-07-03 19:42:52 +02:00
Niklas Haas 5b6cce2b73 vd_lavc: expose mastering display side data reference peak
This greatly improves the result when decoding typical (ST.2084) HDR
content, since the job of tone mapping gets significantly easier when
you're only mapping from 1000 to 250, rather than 10000 to 250.

The difference is so drastic that we can now even reasonably use
`hdr-tone-mapping=linear` and get a very perceptually uniform result
that is only slightly darker than normal. (To compensate for the extra
dynamic range)

Due to weird implementation details, this only seems to be present on
keyframes (or something like that), so we have to cache the last seen
value for the frames in between.

Also, in some files the metadata is just completely broken /
nonsensical, so I decided to apply a simple heuristic to detect
completely broken metadata.
2016-07-03 19:42:52 +02:00
Niklas Haas 923e3c7b20 vo_opengl: generalize HDR tone mapping mechanism
This involves multiple changes:

1. Brightness metadata is split into nominal peak and signal peak.

For a quick and dirty explanation: nominal peak is the brightest value
that your color space can represent (i.e. the brightness of an encoded
1.0), and signal peak is the brightest value that actually occurs in
the video (i.e. the brightest thing that's displayed).

2. vo_opengl uses a new decision logic to figure out the right nom_peak
and sig_peak for all situations. It also does a better job of picking
the right target gamut/colorspace to use for the OSD. (Which still is
and still should be treated as sRGB). This change in logic also
fixes #3293 en passant.

3. Since it was growing rapidly, the logic for auto-guessing / inferring
the right colorimetry configuration (in pass_colormanage) was split from
the logic for actually performing the adaptation (now pass_color_map).

Right now, the new logic doesn't do a whole lot since HDR metadata is
still ignored (but not for long).
2016-07-03 19:42:52 +02:00
Niklas Haas d81fb97f45 mp_image: split colorimetry metadata into its own struct
This has two reasons:

1. I tend to add new fields to this metadata, and every time I've done
so I've consistently forgotten to update all of the dozens of places in
which this colorimetry metadata might end up getting used. While most
usages don't really care about most of the metadata, sometimes the
intend was simply to “copy” the colorimetry metadata from one struct to
another. With this being inside a substruct, those lines of code can now
simply read a.color = b.color without having to care about added or
removed fields.

2. It makes the type definitions nicer for upcoming refactors.

In going through all of the usages, I also expanded a few where I felt
that omitting the “young” fields was a bug.
2016-07-03 19:42:52 +02:00
Niklas Haas 3abf9c9204 vo_opengl: don't constantly resize the output FBO
Commit 883d3114 seems to have (accidentally?) dropped the FBOTEX_FUZZY
from the output_fbo resize, which means that current master will keep
resizing and resizing the FBO as you change the window size, introducing
severe memory leaking after a while. (Not sure why that would cause
memory leaks, but I blame nvidia)

Either way, it's bad for performance too, so it's worth fixing.
2016-07-03 19:42:52 +02:00
wm4 ea23a86f49 sub: remove unused sub_bitmaps.scaled field 2016-07-03 19:32:43 +02:00
wm4 8ed32e90c9 sub: move RGBA scaling to vo_vaapi
vo_vaapi is the only thing which can't scale RGBA on the GPU. (Other
cases of RGBA scaling are handled in draw_bmp.c for some reason.)

Move this code and get rid of the osd_conv_cache thing.

Functionally, nothing changes.
2016-07-03 19:32:43 +02:00
wm4 37cf92c07a sub: change how libass output is converted to RGBA in some cases
This affects VOs (or other code which render OSD) which does not support
the LIBASS format, but only RGBA. Instead of having a converter stage in
osd.c, make mp_ass_packer_pack() output directly in RGBA.

In general, this is work towards refcounted subtitle images.

Although we could keep the "converter" design, doing it this way seems
simpler, at least considering the current situation with only 2 OSD
formats. It also prevents copying & packing the data twice, which will
lead to better performance. (Although I guess this case is not important
at all.)

It also fixes --force-rgba-osd-rendering when used with vo_opengl,
vo_vdpau, and vo_direct3d.
2016-07-03 19:32:31 +02:00
wm4 59972fbfe1 sub: move around some code
Put the packing code into separate functions. Preparation for the
following commit.
2016-07-03 19:32:00 +02:00
wm4 f110552898 sub: pass preferred OSD format to subtitle renderers
The intention is to let mp_ass_packer_pack() produce different output
for the RGBA and LIBASS formats. VOs (or whatever generates the OSD)
currently do not signal a preferred format, and this mechanism just
exists to switch between RGBA and LIBASS formats correctly, preferring
LIBASS if the VO supports it.
2016-07-03 19:31:56 +02:00
wm4 315e2e3da8 vo_opengl: remove caching GL_MAX_TEXTURE_SIZE value
No real need to cache this, and we need fewer fields in the OSD part
struct.

Also add logging for when the OSD texture is reallocated.
2016-07-03 17:33:59 +02:00
wm4 b57debe5b3 vo_opengl: use ringbuffer of PBOs
This is how PBOs are normally supposed to be used.

Unfortunately I can't see an any absolute improvement on nVidia binary
drivers and playing 4K material. Compared to the "old" PBO path with 1
buffer, the measured GL time decreases significantly, though.
2016-07-03 16:34:32 +02:00
wm4 8c7f9dc1a8 vo_opengl: support inconsistent negative strides per plane
GL generally does not support flipping the image on upload, meaning
negative strides are not supported. vo_opengl handles this by flipping
rendering if the stride is inverted, and gl_pbo_upload() "ignores"
negative strides by uploading without flipping the image.

If individual planes had strides with different signs, this broke. The
flipping affected the entire image, and only the sign of the first plane
was respected.

This is just a crazy corner case that will never happen, but it turns
out this is quite simple to support, and actually improves the code
somewhat.
2016-07-03 16:34:32 +02:00
wm4 823c353faa vo_opengl: move PBO upload handling to shared code
This introduces a gl_pbo_upload_tex() function, which works almost like
our gl_upload_tex() glTexSubImage2D() wrapper, except it takes a struct
which caches the PBO handles. It also takes the full texture size (to
make allocating an ideal buffer size easier), and a parameter to disable
PBOs (so that the caller doesn't have to duplicate the gl_upload_tex()
call if PBOs are disabled or unavailable).

This also removes warnings and fallbacks on PBO failure. We just
silently try using PBOs on every frame, and if that fails at some point,
revert to normal texture uploads. Probably doesn't matter.
2016-07-03 16:34:32 +02:00
James Ross-Gowan 06219c7f88 w32_common: make WM_NCHITTEST simpler and more accurate
This makes the geometry of the sizing borders more like the ones in
Windows 10. It also fixes an off-by-one error that made the right and
bottom borders thinner than the left and top borders, which made it
difficult to resize the window when using the Windows 7 classic theme
(because it has pretty thin sizing borders to begin with.)
2016-07-03 21:58:29 +10:00
wm4 5d47f9a565 manpage: document confusing "vf clr" command usage 2016-07-03 13:45:18 +02:00
wm4 1298c29dc7 player: add missing space to error message 2016-07-02 18:26:55 +02:00
Ben Boeckel 76a73a0a5d vd_lavc: hide structs behind platform flags
Otherwise, warnings about them being unused appear.
2016-07-01 19:12:34 -04:00
Ben Boeckel b2ce00ed56 readme: fix typo 2016-07-01 19:12:26 -04:00
wm4 d057e7a142 player: fatal error if linked and compiled FFmpeg versions mismatch
We don't support this anymore.

This tries to exit in a controlled way after command line options are
applied in order to honor logging options and, in case of libmpv, not to
kill the host. Not sure if it would be better to just vomit text to
stderr and call abort().
2016-07-01 20:56:59 +02:00
wm4 3738bfb451 bitmap_packer: remove some unused functions 2016-07-01 20:29:45 +02:00
wm4 8523e1fd95 sub: set ASS sub bitmap data to correct pointer
Point it to the copied data. Doesn't really matter at this point, but
later it might have left dangling pointers.
2016-07-01 20:28:49 +02:00
wm4 fd5098a409 vo_direct3d: remove bitmap packer
See previous comments.
2016-07-01 20:28:49 +02:00
wm4 c0f272fcd1 vo_vdpau: remove bitmap packer use
See previous commit.
2016-07-01 20:28:49 +02:00
wm4 1b71cfccba vo_opengl: remove OSD bitmap packing
It's packed in the OSD common layer already.
2016-07-01 20:28:49 +02:00
wm4 549a9ea6fa command: pack sub image data in overlay-add command
Working towards refcounted sub images, and also for removing bitmap
packers from VOs.

I'm not sure why we even have this overlay-add command. It was sort of
"needed" before opengl-cb was introduced, and before Lua scripts could
put ASS drawings on OSD without conflicting with the OSC. But now trying
to use it doesn't make too much sense anymore.

Still keep it because we're trying to be nice, but throw performance out
of the window. Now image data is copied 2 more times before displaying
it. This also makes using the command a bit simpler.
2016-07-01 20:22:09 +02:00
wm4 614efea3e6 ad_lavc: work around braindead ffmpeg behavior
The libavcodec wmapro decoder will skip some bytes at the start of the
first packet and return each time. It will not return any audio data in
this state.

Our own code as well as libavcodec's new API handling
(avcodec_send_packet() etc.) discard the PTS on the first return, which
means the PTS is never known for the first packet. This results in a
"Failed audio resync." message.

Fixy it by remember the PTS in next_pts. This field is used only if the
decoder outputs no PTS, and is updated after each frame - and thus
should be safe to set.

(Possibly this should be fixed in libavcodec new API handling by not
setting the PTS to NOPTS as long as no real data has been output. It
could even interpolate the PTS if the timebase is known.)

Fixes the failure message seen in #3297.
2016-07-01 15:51:34 +02:00
wm4 c57304a591 sub: pack libass bitmaps directly in sd_ass.c and osd_libass.c
Change all producer of libass images to packing the bitmaps into a
single larger bitmap directly when they're output. This is supposed to
help working towards refcounted sub bitmaps.

This will reduce performance for VOs like vo_xv, but not for vo_opengl.
vo_opengl simply will pick up the pre-packed sub bitmaps, and skip
packing them again. vo_xv will copy and pack the sub bitmaps
unnecessarily - but if we want sub bitmap refcounting, they'd have to be
copied anyway.

The packing code cannot be removed yet from vo_opengl, because there are
certain corner cases that still produce unpackad other sub bitmaps.
Actual refcounting will also require more work.
2016-06-30 21:38:50 +02:00
wm4 2d6da37b6b README: declare that we do not respect FFmpeg ABI rules 2016-06-29 21:16:42 +02:00
wm4 e40851ea22 options: deprecate --heartbeat-cmd
It's useless. --heartbeat-interval is also considered deprecated, but
this is not made explicit.
2016-06-29 18:10:15 +02:00
wm4 9ed5dae480 options: add a deprecation warning printing mechanism
We have a warning mechanism for removed and for replaced options, but
none yet for options which have been simply deprecated.

For the following commit.

(Fun fact: just adding the m_option field increases binary size by
14KB.)
2016-06-29 18:09:30 +02:00
wm4 c6953bfa8c ao_oss: do not add an entry to audio-device-list if device file missing
This effectively makes it go away on Linux (unless you have OSS
emulation loaded).
2016-06-29 17:40:04 +02:00
wm4 deb1c3c7a8 audio: don't add default entry to audio-device-list if AO support listing
In such cases there isn't really a reason to do so, and using such an
entry would probably fail anyway.

Also convenient for the following commit.
2016-06-29 17:38:57 +02:00
wm4 9ca1592f3f d3d: implement screenshots for --hwdec=d3d11va
No method of taking a screenshot was implemented at all. vo_opengl
lacked window screenshotting, because ANGLE doesn't allow reading the
frontbuffer. There was no way to read back from a D3D11 texture either.

Implement reading image data from D3D11 textures. This is a low-quality
effort to get basic screenshots done. Eventually there will be a better
implementation: once we use AVHWFramesContext natively, the readback
implementation will be in libavcodec, and will be able to cache the
staging texture correctly. Hopefully. (For now it doesn't even have a
AVHWFramesContext for D3D11 yet. But the abstraction is more appropriate
for this purpose.)
2016-06-28 20:38:53 +02:00
wm4 17c5738cb4 d3d: merge angle_common.h into d3d.h
OK, this was dumb. The file didn't have much to do with ANGLE, and the
functionality can simply be moved to d3d.c. That file contains helpers
for decoding, but can always be present (on Windows) since it doesn't
access any D3D specific libavcodec APIs. Thus it doesn't need to be
conditionally built like the actual hwaccel wrappers.
2016-06-28 20:07:56 +02:00
Muhammad Faiz d5615102d5 vo_opengl: add output_size uniform to custom shader
logically, scaler should know its input and output size

Signed-off-by: wm4 <wm4@nowhere>
2016-06-28 19:52:55 +02:00
wm4 40c9b38023 vo_opengl: minor typo and coding style fixes 2016-06-28 19:48:29 +02:00
Niklas Haas dc9a5cbfd7 vo_opengl: revise the transfer curve logic
Instead of hard-coding a big list, move some of the functionality
to csputils. Affects both the auto-guess blacklist and the peak
estimation.

Also update the comments.
2016-06-28 19:48:29 +02:00
Niklas Haas 65499d863a csputils: adjust whitespace
All these blank lines felt sort of weird, especially since the functions
were semantically related.
2016-06-28 19:48:29 +02:00
Niklas Haas 6e6c32ed6c vo_opengl: revise the logic for picking the default color space
Too many "exceptions" these days, it's easier to just hard-code a
whitelist instead of a blacklist. And besides, it only really makes
sense to avoid adaptation for BT.601 specifically, since that's the one
we auto-guess based on the resolution.
2016-06-28 19:48:29 +02:00
Niklas Haas f9fe5d06ad vo_opengl: use image_params instead of *_src for autoconfig
I'm not even sure why we ever consulted *_src to begin with, since that
just describes the current image format - and not the original metadata.
(And in fact, we specifically had logic to work around the impliciations
this had on linear scaling)

image_params is *the* authoritative source on the intended (i.e.
reference) image metadata, whereas *_src may be changed by previous
passes already. So only consult image_params for picking auto-generated
values.

Also, add some more missing "wide gamut" and "non-gamma" curves to the
autoconfig blacklist. (Maybe it would make sense to move this list to
csputils in the future? Or perhaps even auto-detect it based on the
associated primaries)
2016-06-28 19:48:29 +02:00
Niklas Haas f3b6966d14 vo_opengl: implement the Panasonic V-Log function
User request and not that hard. Closes #3157.

Note that FFmpeg doesn't support this and there's no signalling in HEVC
etc., so the only way users can access it is by using vf_format
manually.

Mind: This encoding uses full range values, not TV range.
2016-06-28 19:48:29 +02:00
Niklas Haas 740fdc139f manpage: add missing documentation for vf_format:gamma=dci-p3 2016-06-28 19:48:29 +02:00
Niklas Haas 247ec0cb84 csputils: add Panasonic V-Gamut primaries
This is actually not entirely trivial since it involves negative Yxy
coordinates, so the CMM has to be capable of full floating point
operation. Fortunately, LittleCMS is, so we can just blindly implement
it.
2016-06-28 19:48:29 +02:00
Niklas Haas 13a63331b6 manpage: warn about the use of HDR functions for target-trc
Most devices seems to require special signalling (e.g. via HDMI
metadata) to actually decode HDR signals and treat them as such, so it's
probably worth warning the potential user about the fact that mpv pretty
definitely does *not* set any of this metadata signalling.
2016-06-28 19:48:29 +02:00
Niklas Haas 9278ce98f7 vo_opengl: implement ARIB STD-B68 (HLG) HDR TRC
This HDR function is unique in that it's still display-referred, it just
allows for values above the reference peak (super-highlights). The
official standard doesn't actually document this very well, but the
nominal peak turns out to be exactly 12.0 - so we normalize to this
value internally in mpv. (This lets us preserve the property that the
textures are encoded in the range [0,1], preventing clipping and making
the best use of an integer texture's range)

This was grouped together with SMPTE ST2084 when checking libavutil
compatibility since they were added in the same release window, in a
similar timeframe.
2016-06-28 19:48:29 +02:00
wm4 4ce53025cb audio: add a helper for getting frame end PTS
Although I don't see any use for it yet, why not.
2016-06-27 15:12:21 +02:00
wm4 3e58ce96ac dec_audio: fix segment boudnary switching
Some bugs in this code are exposed by e.g. playing lossless audio files
with --ad-lavc-threads=16. (libavcodec doesn't really support threaded
audio decoding, except for lossless files.) In these cases, a major
amount of audio can be buffered, which makes incorrect handling of this
buffering obvious.

For one, draining the decoder can take a while, so if there's a new
segment, we shouldn't read audio.

The segment end check was completely wrong, and used the start value.
2016-06-27 15:12:21 +02:00
Rudolf Polzer acb74236ac ao_lavc, vo_lavc: Migrate to new encoding API.
Also marked some places for possible later refactoring, as they became
quite similar in this commit.
2016-06-27 08:33:12 -04:00
stepshal c5094206ce Fix misspellings 2016-06-26 13:47:21 +02:00
quilloss 24478a8a72 vo_opengl utils: use gl->main_fb when reading window content
The main framebuffer is not the default framebuffer for the dxinterop
backend. Bind the main framebuffer and use the appropriate attachment
when reading the window content.

Fix #3284
2016-06-26 13:17:39 +02:00
wm4 e081e46950 manpage: fix typo 2016-06-26 12:33:16 +02:00
wm4 22c76e85db vo_xv: fix behavior with odd sizes
The size check introduced in commit d941a57b did not consider that Xv
can round up the image size to the next chroma boundary. Doing that
makes sense, so it can't certainly be considered server misbehavior.

Do 2 things against this: allow if the server returns a larger image (we
just crop it then), and also allocate a properly aligned image in the
first place.
2016-06-25 12:44:42 +02:00
wm4 d1d864546c DOCS: change version references from 0.17.1 to 0.18.0
0.17.1 was never released, so the actual 0.18.0 release takes its place.
2016-06-25 12:39:08 +02:00
Martin Herkt 69e7b0d3ea Release 0.18.0 2016-06-25 03:23:40 +02:00
Martin Herkt ad56f2c46a Merge branch 'master' into release/current 2016-06-25 02:25:44 +02:00
wm4 393bb2a565 image_writer: port to new encode API 2016-06-24 18:20:36 +02:00
wm4 ea098d3462 ass_mp.h: remove conditional inclusion guards
This file is only used when libass is enabled. (It used to be different,
when code was more entangled.)
2016-06-24 18:05:34 +02:00
wm4 1c3bbd9318 af_lavcac3enc: use av_err2str() call (fixes Libav build)
I added this call because I thought it'd be nice, but Libav doesn't have
this function (macro, actually).
2016-06-23 12:41:41 +02:00
wm4 e911e208b8 af_lavcac3enc: make encoder configurable 2016-06-23 12:14:45 +02:00
wm4 5c74da4503 af_lavcac3enc: implement flushing on seek
There's a lot of data that could have been buffered, and which has to be
discarded.
2016-06-23 12:07:05 +02:00
wm4 c071c30bcd af_lavcac3enc: port to new encode API 2016-06-23 12:04:04 +02:00
wm4 b01855714b af_lavcac3enc: automatically configure most encoder parameters
Instead of hardcoding what the libavcodec ac3 encoder expects, configure
it based on the AVCodec fields.

Unfortunately, it doesn't export the list of sample rates, so that is
done manually. This commit actually fixes the rate always to 48Khz. I
don't even know whether the other rates worked. (Possibly did, but
they'd still change the spdif parameters, and would work differently
from ad_spdif.c.)
2016-06-23 12:02:36 +02:00
wm4 5a60f594e5 af_lavcac3enc: drop log message prefixes
MPlayer leftover. They're already added by the logging code.
2016-06-23 10:45:56 +02:00
wm4 31b73d5ca0 af_lavcac3enc: fix custom bitrates
Probably has been broken for ages.

(Not sure why anyone would use this feature, though.)
2016-06-23 10:43:54 +02:00
wm4 b753c229f7 vo_opengl: improve missing function warning
Mostly a cosmetic change. Handling bultin and extension functions
separaterly makes more sense here too.
2016-06-22 21:55:00 +02:00
wm4 7ea22fe889 ad_lavc: resume from mid-stream EOF conditions with new decode API
Workaround for an awful corner-case. The new decode API "locks" the
decoder into the EOF state once a drain packet has been sent. The
problem starts with a file containing a 0-sized packet, which is
interpreted as drain packet.

This should probably be changed in libavcodec (not treating 0-sized
packets as drain packets with the new API) or in libavformat (discard
0-sized packets as invalid), but efforts to do so have been fruitless.

Note that vd_lavc.c already does something similar, but originally for
other reasons.

Fixes #3106.
2016-06-22 21:37:36 +02:00
dirb 9d0af06811 vo_opengl: add scaler name to the 'Disabling scaler' message
Print to the user the name of the scaler that gets disabled rather than
just printing its number.
2016-06-22 18:16:43 +02:00
wm4 6f9973618c vf_vdpaurb: use new common nv12 download code
See previous commit. (The mixing case was never supported, so this has
equivalent functionality.)

This also implicitly fixes a bug: the old code allocated image data for
the cropped surface size only, which means the
video_surface_get_bits_y_cb_cr call could write beyond the allocated
image memory.
2016-06-21 21:44:13 +02:00
wm4 b40d8fdfa3 vdpau: get surface data as nv12 if possible
For now, this affects taking screenshots only.

If the video mixer is actually needed, we want to go through the video
mixer for screenshots too - which is why this function simply always
used the video mixer, and then copied the surface to RAM as RGBA.

Add reading the surface as nv12 if possible. If the format is correct,
and no special video processing (like deinterlacing) is used, then it's
read directly without going through the video mixer.

There's no particular reason for doing this, other than avoiding the
video mixer (like vo_opengl can do it now). Also, the next commit will
make use of this in vf_vdpaurb.c.
2016-06-21 21:31:58 +02:00
wm4 22291a2587 command: improve playlist* properties change notifications
Until now, only the "playlist" property itself had proper change
notification. Extend it to all other properties as well.

Fixes #3267 (hopefully).
2016-06-20 21:35:59 +02:00
wm4 fc50f3772c github: move "reproduction steps" before behavior sections 2016-06-20 20:06:54 +02:00
Floens 65280e47cd vo_opengl: manually add the GL_BACK_LEFT constant for GLES
GLES doesn't have this constant. It's not used on GLES.
I'm starting to think we need some better way to do this.
2016-06-20 19:24:42 +02:00
Floens 30adf280fd vo_opengl: GL_ARB_timer_query compile fix for GLES
The GL_ARB_timer_query extension and thus the GL_TIME_ELAPSED constant
don't exist for GLES.
For ES the EXT_disjoint_timer_query is used so take the constant from
that else provide the constant manually.
See pr #3216 which introduced this error.
2016-06-20 19:24:42 +02:00
wm4 9bac0ea421 vf_vdpaurb: fix operation
The hw_subfmt field remained set, while it has to be unset for non-hwdec
formats.
2016-06-20 19:10:58 +02:00
wm4 761eeacf54 vo_opengl: unmap hwdec images once rendering is done
Instead of keeping them for a while. While keeping the mapping was
perfectly ok, nothing speaks against reducing the time they're mapped.
2016-06-20 13:57:46 +02:00
wm4 7be37337f4 vo_opengl: vdpau interop without RGB conversion
Until now, we've always converted vdpau video surfaces to RGB, and then
mapped the resulting RGB texture. Change this so that the surface is
mapped as NV12 plane textures.

The reason this wasn't done until now is because vdpau surfaces are
mapped in an "interlaced" way as separate fields, even for progressive
video. This requires messy reinterleraving. It turns out that even
though it's an extra processing step, the result can be faster than
going through the video mixer for RGB conversion.

Other than some potential speed-gain, doing this has multiple other
advantages. We can apply our own color conversion, which is important in
more complex cases. We can correctly apply debanding and potentially
other processing that requires chroma-specific or in-YUV handling.

If deinterlacing is enabled, this switches back to the old RGB
conversion method. Until we have at least a primitive deinterlacer in
vo_opengl, this will stay this way. The d3d11 and vaapi code paths are
similar. (Of course these don't require any crazy field reinterleaving.)
2016-06-19 19:58:40 +02:00
wm4 754ad1d730 refqueue: free referenced images on free
Otherwise stale references will survive forever. Could leak hardware
video surfaces.

In particular, the mpv vdpau code crashed with an assertion when exiting
after toggling deinterlacing, because not all references were released.
2016-06-19 19:52:49 +02:00
wm4 0cf187caca bitmap_packet: let max=0 mean unlimited
And remove the strange PACKER_MAX_WH define. This is more convenient for
users which don't care about limits, such as sd_lavc.c.
2016-06-18 19:31:23 +02:00
wm4 07c11656e3 sd_lavc: fix sub-bitmap alignment
Ooops.
2016-06-18 19:30:38 +02:00
Bin Jin 67a6203ce0 vo_opengl: remove prescaling framework with superxbr prescaler
Signed-off-by: wm4 <wm4@nowhere>
2016-06-18 19:17:28 +02:00
Bin Jin 3df95ee57a vo_opengl: remove uniform buffer object routines 2016-06-18 19:16:31 +02:00
Bin Jin 61bc96518a vo_opengl: remove nnedi3 prescaler 2016-06-18 19:16:27 +02:00
Akemi 47d9fbd133 cocoa: fix display refresh rate retrieval on multi monitor setups
1. this basically reverts commit de4c74e5a4.
even with CVDisplayLinkCreateWithActiveCGDisplays and
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext we still have to
explicitly set the current display ID, otherwise it will just always
choose the display with the lowest refresh rate. another weird thing is,
we still have to set the display ID another time with
CVDisplayLinkSetCurrentCGDisplay after the link was started. otherwise
the display period is 0 and the fallback will be used.
if we ever use the callback method for something useful it's probably
better to use CVDisplayLinkCreateWithActiveCGDisplays since we will need
to keep the display link around instead of releasing it at the end.
in that case we have to call CVDisplayLinkSetCurrentCGDisplay two times,
once before and once after LinkStart.
2. add windowDidChangeScreen delegate to update the display refresh rate
when mpv is moved to a different screen.
2016-06-18 19:15:36 +02:00
Akemi fb7c5804bb cocoa: fix actual display refresh rate retrieval
We have two problems here.
1. CVDisplayLinkGetActualOutputVideoRefreshPeriod, like the name suggests,
returns a frame period and not a refresh rate. using this as screen_fps
just leads to a slideshow. why didn't this break video playback on OS X
completely? the answer to this leads us to the second problem.
2. it seems that CVDisplayLinkGetActualOutputVideoRefreshPeriod always
returns 0 if used without CVDisplayLinkSetOutputCallback and hence always
fell back to CVDisplayLinkGetNominalOutputVideoRefreshPeriod. adding a
callback to CVDisplayLink solves this problem. the callback function at
this moment doesn't do anything but could possibly used in the future.
2016-06-18 19:15:34 +02:00
James Ross-Gowan 0fd5a24ecb vo_opengl: dxinterop: render to gl->main_fb
This can also remove all the stuff for lazily attaching the texture. It
doesn't matter if the dxinterop backend changes the bound framebuffer
during a VOCTRL, since the renderer does not rely on the GL state being
preserved.
2016-06-18 23:51:57 +10:00
wm4 4a15bc6d73 vo_opengl: add ability to render to an arbitrary backing framebuffer
Most of the functionality already exists for the sake of vo_opengl_cb.
We only have to use it.

This will be used by dxinterop in the following commit.
2016-06-18 15:16:29 +02:00
wm4 9215a9e598 sd_lavc: align sub-bitmaps for the sake of libswscale
Since there are not many sub-rectangles, this doesn't cost too much. On
the other hand, it avoids frequent warnings with vo_xv.

Also, the second copy in mp_blur_rgba_sub_bitmap() can be dropped.
2016-06-18 12:08:17 +02:00
wm4 689cf04571 sd_lavc: fix typo 2016-06-18 10:49:41 +02:00
wm4 8e6704acdb sub, vo_opengl: use packed sub-bitmaps directly if available
The previous few commits changed sd_lavc.c's output to packed RGB sub-
images. In particular, this means all sub-bitmaps are part of a larger,
single bitmap. Change the vo_opengl OSD code such that it can make use
of this, and upload the pre-packed image, instead of packing and copying
them again.

This complicates the upload code a bit (4 code paths due to messy PBO
handling). The plan is to make sub-bitmaps always packed, but some more
work is required to reach this point. The plan is to pack libass images
as well. Since this implies a copy, this will make it easy to refcount
the result.

(This is all targeted towards vo_opengl. Other VOs, vo_xv, vo_x11, and
vo_wayland in particular, will become less efficient. Although at least
vo_vdpau and vo_direct3d could be switched to the new method as well.)
2016-06-17 23:15:50 +02:00
wm4 28c7dec157 sd_lavc: change hack against vobsubs with wrong resolution
The sub-bitmaps get extended by --sub-gauss, so we have to compute the
bounding box on the original subs. Not sure if this is really
eqauivalent to what the code did before, and I don't have the sample
anymore. (But this approach sure is a _shitty_ hack.)
2016-06-17 23:15:39 +02:00
wm4 56058a95e5 sub: fix --sub-gauss
Implement it directly in sd_lavc.c as well. Blurring requires extending
the size of the sub-images by the blur radius. Since we now want
sub_bitmaps to be packed into a single image, and we don't want to
repack for blurring, we add some extra padding to each sub-bitmap in the
initial packing, and then extend their size later. This relies on the
previous bitmap_packer commit, which always adds the padding in all
cases.

Since blurring is now done on parts of a large bitmap, the data pointers
can become unaligned, depending on their position. To avoid shitty
libswscale printing a dumb warning, allocate an extra image, so that the
blurring pass is done on two newly allocated images. (I don't find this
feature important enough to waste more time on it.)

The previous refactor accidentally broke this feature due to a logic bug
in osd.c. It didn't matter before it happened to break, and doesn't
matter now since the code paths are different.
2016-06-17 23:14:26 +02:00
wm4 f72eb5b394 sub: move paletted image handling completely to sd_lavc.c
Until now, subtitle renderers could export SUBBITMAP_INDEXED, which is a
8 bit per pixel with palette format. sd_lavc.c was the only renderer
doing this, and the result was converted to RGBA in every use-case
(except maybe when the subtitles were hidden.)

Change it so that sd_lavc.c converts to RGBA on its own. This simplifies
everything a bit, and the palette handling can be removed from the
common code.

This is also preparation for making subtitle images refcounted. The
"caching" in img_convert.c is a PITA in this respect, and needs to be
redone. So getting rid of some img_convert.c code is a positive side-
effect. Also related to refcounted subtitles is packing them into a
single mp_image. Fewer objects to refcount is easier, and for the libass
format the same will be done. The plan is to remove manual packing from
the VOs which need single images entirely.
2016-06-17 23:13:14 +02:00
wm4 454fff39ad bitmap_packer: make manual use slightly more convenient
Apply the padding internally to each input bitmap, instead of requiring
this for the semi-public API.

Right now, everything still uses packer_pack_from_subbitmaps() to fill
the input bitmap sizes, but that's going to change with the following
commit. Since bitmap_packer.in is mutated during packing anyway, it's
more convenient to add the padding automatically.

Also, guarantee that every sub-bitmap has a padding border around it.
Don't let the padding overlap. Add padding even on the containing
borders.

This is simpler, doesn't cost much in memory usage, and is convenient
for one of the following commits.
2016-06-17 23:12:43 +02:00
wm4 8986b37fe7 sd_lavc: move AVSubtitle bitmap setup code into its own function
No functional changes.
2016-06-17 23:12:34 +02:00
wm4 d0bd39eb90 Add github issue and pull request templates
I do not understand why github requires adding this crap to source code
repositories themselves, instead of making them part of the repository
configuration. Remove CONTRIBUTING.md to compensate for github crap
accumulating.
2016-06-17 16:16:03 +02:00
wm4 7ecac3ae6f d3d11va: remove unused d3d11va_surface.subindex field
This is now stored within the AVFrame/mp_image.
2016-06-16 18:13:46 +02:00
wm4 a6074a3375 vf_d3d11vpp: flush device context only when using shared textures
Reduces interference with pass-through case, where this is not needed.
2016-06-16 17:29:53 +02:00
wm4 36f8d41702 vf_d3d11vpp: make missing deinterlacing caps non-fatal
Instead, warn.
2016-06-16 17:17:54 +02:00
wm4 1878a4655d vf_d3d11vpp: log some video processor creation parameters 2016-06-16 16:34:51 +02:00
James Ross-Gowan 5700da4a8f vo_opengl: use EXT_disjoint_timer_query for timers
This is the ES equivalent to ARB_timer_query. It enables the performance
timers on ANGLE. All the added functions should be identical in
semantics to their desktop GL equivalents.
2016-06-15 20:32:47 +10:00
wm4 43e964e2d6 vo_opengl: fix framebuffer object name
The OpenGL 3.0+ and ES specs are quite clear on what values are
accepted for the attachment object name parameter. And there's no
overlap for the default framebuffer. Sigh.

Probably fixes Mesa raising an error in this case and might fix #3251.
Regression by the previous vo_opengl change.
2016-06-15 00:55:27 +02:00
wm4 a30e727266 demux_mkv: support Matroska webvtt
They're different from the Google/WebM subtitle types, and use a new
codec ID.

Fixes #3247.
2016-06-14 16:43:07 +02:00
wm4 788929e4e0 vo_opengl: use standard functions to retrieve display depth
Until now, we've used system-specific API (GLX, EGL, etc.) to retrieve
the depth of the default framebuffer. (We equal this to display depth
and use the determined depth for dithering.)

We can actually retrieve this value through standard GL API, and it
works everywhere (except GLES 2 of course). This simplifies everything a
great deal.

egl_helpers.c is empty now. But I expect that some EGL boilerplate will
be moved to it, so don't remove it yet.
2016-06-14 10:35:43 +02:00
wm4 3682df2dd5 vo_opengl: hwdec_d3d11egl: remove ES2 swizzle special-case
This was somehow done under the assumption that ANGLE would somehow
always use RG in ES2 mode. But there's no basis for this. Even if ANGLE
supports NV12 textures with drivers that do not allow for texture_rg,
this cas eis too obscure to worry about. So do the robust and correct
thing instead, and disable this code if texture_rg is not available.
2016-06-13 16:15:57 +02:00
Gusar321 81ec9cf596 vo_rpi: fix destroying overlays
Commit 74e3d11 resulted in the background overlay not getting destroyed
when mpv quits. Add back a piece of code that was removed in that commit
to restore correct functionality.

Fixes issue #3100
2016-06-13 14:48:11 +02:00
wm4 b00eab525a audio: apply an upper bound timeout when draining
This helps with shitty APIs and even shittier drivers (I'm looking at
you, ALSA). Sometimes they won't send proper wakeups. This can be fine
during playback, when for example playing video, because mpv still will
wakeup the AO outside of its own wakeup mechanisms when sending new data
to it. But when draining, it entirely relies on the driver's wakeup
mechanism. So when the driver wakeup mechanism didn't work, it could
hard freeze while waiting for the audio thread to play the rest of the
data.

Avoid this by waiting for an upper bound. We set this upper bound at the
total mpv audio buffer size plus 1 second. We don't use the get_delay
value, because the audio API could return crap for it, and we're being
paranoid here. I couldn't confirm whether this works correctly, because
my driver issue fixed itself.

(In the case that happened to me, the driver somehow stopped getting
interrupts. aplay froze instead of playing audio, and playing audio-only
files resulted in a chop party. Video worked, for reasons mentioned
above, but drainign froze hard. The driver problem was solved when
closing all audio output streams in the system. Might have been a dmix
related problem too.)
2016-06-12 21:05:10 +02:00
wm4 972ea9ca59 audio: do not wake up core during EOF
When we're draining, don't wakeup the core on every buffer fill, since
unlike during normal playback, we won't actually get more data. The
wakeup here conceptually works like wakeups with condition variables, so
redundant wakeups do not hurt, so this is just a minor change and
nothing of consequence.

(Final EOF also requires waking up the core, but there is separate code
to send this notification.)

Also dump the p->still_playing field in trace logging.
2016-06-12 20:59:11 +02:00
Bin Jin 3d844cddf8 vo_opengl: make size of OUTPUT available to user shaders 2016-06-12 17:51:50 +02:00
wm4 0b082b2086 player: fix previous commit
Of course we can't just skip updating the OSD if the playloop was woken
up for the purpose of removing OSD after an OSD timer expired.

Fixes e.g. OSD bars sometimes sticking along when seeking while paused.
2016-06-12 12:52:35 +02:00
wm4 bb9aad097a player: do not update OSD all the time when paused
Normally, OSD is updated every time the playloop is run. This has to be
done, because the OSD may implicitly reference various properties,
without knowing whether they really need to be updated or not. (There's
a property update mechanism, but it's mostly unavailable, because OSD is
special-cased and can not use the client API mechanism properly.)

Normally, these updates are no problem, because the OSD is only actually
printed when the OSD text actually changes.

But commit d23ffd24 added a rate-limiting mechanism, which tries to
limit OSD updates at most every 50ms (or the next video frame). Since it
can't know in advance whether the OSD is going to change or not, this
simply waked up the player every 50ms.

Change this so that the player is updated only as part of general
updates determined through mp_notify(). (This function also notifies the
client API of changed properties.) The desired result is that the player
will not wake up at all in normal idle mode, but still update properties
that can change when paused, such as the cache.

This is mostly a cosmetic change (in the sense of making runtime
behavior just slightly better). It has the slightly more negative
consequence that properties which update implicitly (such as "clock")
will not update periodically anymore.
2016-06-11 18:40:08 +02:00
James Ross-Gowan 9fcc517cee win32: use HINST_THISCOMPONENT
This is a common idiom used in MSDN docs and Raymond Chen's example
programs to get a HINSTANCE for the current module, regardless of
whether it's an .exe or a .dll. Using GetModuleHandle(NULL) for this is
technically incorrect, since it always gets a handle to the .exe, even
when the executing code (in libmpv) is running in a .dll. In this case,
using the wrong HINSTANCE could cause namespace issues with window
classes, since CreateWindowEx uses the HINSTANCE to search for the
matching window class name.

See:
https://blogs.msdn.microsoft.com/oldnewthing/20050418-59/?p=35873
https://blogs.msdn.microsoft.com/oldnewthing/20041025-00/?p=37483
2016-06-11 15:35:17 +02:00
Stefano Pigozzi de4c74e5a4 cocoa: use displaylink without manually tracking the display id
Maybe it partially helps with #2392 (on dual display setups). Either way, it
makes the code simpler.
2016-06-11 11:58:07 +02:00
Rudolf Polzer 9cc5507079 vo_sdl: fix pixel formats.
There were two mistakes:

- SDL's RGB565 is always equivalent to ffmpeg's RGB565 (both are packed 16bit
  native-endian integers in RGB=565 form) - this was wrongly reversed on
  big endian platforms.
- SDL's RGB888 doesn't actually mean RGB24, but XRGB8888 (i.e. 32bit
  packed integer, top 8 bits unused).
- Use RGB0 not RGBA when there is no alpha.
2016-06-10 16:30:12 -04:00
wm4 bea2e39721 vo_opengl: request core profile on X11/EGL too
Avoids that some OpenGL implementation will pin it to 3.0.
2016-06-10 20:31:28 +02:00
Bin Jin 2b1656b1ac vo_opengl: increase the size limit for cached file
This is mainly for the nnedi3 user shader. With all whose NN weights
hardcoded into the shader source code, the shader file could be as
large as 300 kB.
2016-06-10 17:08:54 +02:00
wm4 1c5fd2d901 Revert "wscript: Require recent FFmpeg by default"
This reverts commit b51957fab5.

Breaks big time. It appears to ignore explicitly configured paths within
the libav* .pc files, which for example breaks mpv-build.
2016-06-09 21:05:33 +02:00
wm4 d38d26057a vo_opengl: hwdec_d3d11eglrgb: remove some more unused fields
Not sure what/if I was thinking there.
2016-06-09 18:43:40 +02:00
wm4 262ceca731 vo_opengl: fix d3d11 hardware decoding probing on Windows 7
Although D3D11 video decoding is unuspported on Windows 7, the
associated APIs almost work. Where they fail is texture creation, where
we try to create D3D11_BIND_DECODER surfaces. So specifically try to
detect this situation.

One issue is that once the hwdec interop is created, the damage is done,
and it can't use another backend (because currently only 1 hwdec backend
is supported). So that's where we prevent attempts to use it.

It still can fail when trying to use d3d11va-copy (since that doesn't
require an interop backend), but at that point we don't care anymore -
dxva2(-copy) is tried before that anyway.
2016-06-09 11:18:36 +02:00
wm4 6fd7f5a111 vo_opengl: hwdec_d3d11eglrgb: remove unused fields
Leftovers.
2016-06-09 10:51:04 +02:00
Martin Herkt b51957fab5 wscript: Require recent FFmpeg by default
Distros and users alike should be made aware of the fact that old
FFmpeg versions are bad. When users come to us with FFmpeg-related
trouble, the answer is “update FFmpeg” more often than not
(and no further support will be provided until they have done so),
so instead we just nag them about it here.
2016-06-09 01:41:53 +02:00
wm4 4123c9642d vo_opengl: hwdec_vdpau: remove minor code duplication
Move unmap() to the top of the function, and replace some duplicated
code with a call to it.
2016-06-08 22:16:32 +02:00
Niklas Haas ff37d7efec vo_opengl: refactor performance data properties
Instead of having 9 different properties, requiring 18 different
VOCTRLs to read them all, they are now exposed as a single property.
This is not only cleaner (since they're all together) but also allows
querying all 9 of them with only a single VOCTRL (by using
mp.get_property_native).

(The extra factor of 2 was due to an extra query being needed to get the
type, which is now also unnecessary)

This makes it much easier to access performance metrics from within a
lua script, and also makes it easier to just show a readable, formatted
version via show-text.
2016-06-08 22:11:38 +02:00
Niklas Haas 54c48bd801 vo_opengl: make user hook passes optional
User hooks can now use an extra WHEN expression to specify when the
shader should be run. For example, this can be used to only run a chroma
scaling shader `WHEN CHROMA.w LUMA.w <`.

There's a slight semantics change to user shaders: When trying to bind a
texture that does not exist, a shader will now be silently skipped
(similar to when the condition is false) instead of generating an error.

This allows shader stages to depend on an optional earlier stage without
having to copy/paste the same condition everywhere.

(In other words: there's an implicit condition on all of the bound
textures existing)
2016-06-08 20:50:19 +02:00
wm4 a15181e5df vo_opengl: do not leak previous FBO when reallocating it
WTF of the day.
2016-06-08 17:49:23 +02:00
James Ross-Gowan b906eb37ed hwdec_d3d11eglrgb: reduce log level when probing
When using --hwdec=auto, systems that don't provide
D3D11_CREATE_DEVICE_VIDEO_SUPPORT, which probably includes all Windows
Vista and 7 systems, will print an error message. Reduce the log level
to verbose when probing and skip the error message entirely if d3d11.dll
is not present.

This commit is in a similar spirit to 991af7d.
2016-06-09 00:24:49 +10:00
wm4 7373158703 vo_opengl: hwdec_d3d11egl: remove broken code on error path
If ID3D11Device_QueryInterface fails, "multithread" will be set to NULL.
The _Release would just make it crash with a null pointer deref.
2016-06-08 12:57:14 +02:00
wm4 69d5be1ee9 player: remove unused return value 2016-06-08 12:04:56 +02:00
wm4 bd9bba40ee player: tell user about --force-seeking if demuxer is not seekable
This comes up often, see e.g. #3220. The issue is that if the stream
input is not seekable, the demuxer is marked as not seekable. But if the
stream cache is enabled, the file still _might_ be seekable to a degree.
We recently disabled seeking in this mode because it can cause very
weird issues, mostly because if stream-layer seeking fails, the demuxers
will arbitrarily misbehave. On the other hand, it can work if the seek
is within the cached range, which is why the user can still enable it
with --force-seeking. There is a weird trade-off between allowing this
and not crapping up too easily, so just informing the user about the
possibility seems best.
2016-06-08 12:02:06 +02:00
wm4 aeb3df0e2c demux_lavf: assume fully read files (subtitles) are always seekable
Since the libavformat API is crap, we have to apply tons of heuristics
to check whether seeking will work. (No, checking it at seek time isn't
going to work either, because if a seek fails, the demuxer will be in an
undefined state. Because the libavformat API is crap.)
2016-06-08 12:02:06 +02:00
stepshal 9c286d7472 waftools: remove trailing newline 2016-06-08 12:01:57 +02:00
wm4 68796fbdf5 demux: fix memory leak when loading of ordered chapter file is aborted 2016-06-07 21:56:09 +02:00
Niklas Haas 5b5db336e9 build: silence -Wunused-result
For clang, it's enough to just put (void) around usages we are
intentionally ignoring the result of.

Since GCC does not seem to want to respect this decision, we are forced
to disable the warning globally.
2016-06-07 14:12:33 +02:00
Niklas Haas 38ac5d5e7b vo_opengl: avoid outputting ultra-wide-gamut by default
The default behavior of vo_opengl has pretty much always been 'show the
source colors as-is, without caring to adapt it to the target device'.
This decision is mostly based on the fact that if we do anything else,
lots of people will complain.

With the rise of content like BT.2020, however, it turns out more people
complain about this content being very desaturated than people complain
about this content not matching VLC - so let's just map ultra-wide gamut
content back down to standard gamut by default.
2016-06-07 12:18:39 +02:00
Niklas Haas 9bd886f449 vo_opengl: also collect upload perfdata for hwdec
Instead of measuring the actual upload time, this instead measures the
time needed to render + map the texture via vdpau. These numbers are
still useful, since they're part of the critical path.
2016-06-07 12:18:05 +02:00
Niklas Haas 393a069112 vo_opengl: expose performance timers as properties
This is plumbed through a new VOCTRL, VOCTRL_PERFORMANCE_DATA, and
exposed as properties render-time-last, render-time-avg etc.

All of these numbers are in microseconds, which gives a good precision
range when just outputting them via show-text. (Lua scripts can
obviously still do their own formatting etc.)

Signed-off-by: wm4 <wm4@nowhere>
2016-06-07 12:17:25 +02:00
Niklas Haas 8ceb935bd8 vo_opengl: add time queries
To avoid blocking the CPU, we use 8 time objects and rotate through
them, only blocking until the last possible moment (before we need
access to them on the next iteration through the ring buffer). I tested
it out on my machine and 4 query objects were enough to guarantee
block-free querying, but the extra margin shouldn't hurt.

Frame render times are just output at the end of each frame, via MP_DBG.
This might be improved in the future. (In particular, I want to expose
these numbers as properties so that users get some more visible feedback
about render times)

Currently, we measure pass_render_frame and pass_draw_to_screen
separately because the former might be called multiple times due to
interpolation. Doing it this way gives more faithful numbers. Same goes
for frame upload times.
2016-06-07 12:16:15 +02:00
James Ross-Gowan 88b584656d dxva2: remove dead code in failure case
This was made unnecessary by a02d77b, since the only way the function
could fail was by failing to add a reference to the DirectX DLLs.
2016-06-07 18:53:05 +10:00
James Ross-Gowan a9150a49d7 vo_opengl: angle: prevent DXGI hooking Alt+Enter
When ANGLE is using D3D11 and not running in DirectComposition mode,
DXGI will hook the video window's message loop and override Alt+Enter to
trigger a transition to exclusive fullscreen mode (which doesn't even
work with mpv's renderer for some reason.) This behaviour can be
disabled by getting a pointer to the IDXGIFactory associated with the
D3D11 device and calling MakeWindowAssociation with the appropriate
flags.
2016-06-07 18:41:47 +10:00
Kevin Mitchell b3e74f652b ao_wasapi: initialize COM in main thread with MTA
Since the main thread is shared by other things in the player, using STA (single
threaded aparement) may have caused problems. Instead initialize in MTA
(multithreaded apartment).
2016-06-05 16:31:03 -07:00
wm4 c1cb04b6a3 vo_opengl: apply vo-cmdline command incrementally
Instead of implicitly resetting the options to defaults and then
applying the options, they're always applied on top of the current
options (in the same way adding new options to the CLI command line
will).

This does not apply to vo_opengl_cb, because that has an even worse mess
which I refuse to deal with.
2016-06-05 16:56:34 +02:00
wm4 ee337b47be vo_opengl_cb: icc-profile-auto does not and will not work
In theory we could probably make icc-profile-auto a vo_opengl-specific
option, but I won't bother with this. Logging an error is simpler.
2016-06-05 15:00:07 +02:00
wm4 b3a3ed00f0 vo_opengl: possibly update icc profile after changing options
Changing the options can enable icc-profile-auto, and in this case the
profile has to be reteieved again from the system.
2016-06-05 12:21:47 +02:00
wm4 65f5fbc5d4 vo_opengl: somewhat simplify suboption handling mess
Enable m_sub_options_copy() to copy nested sub-options, and also enable
it to create an option struct from defaults. We can get rid of most of
the crap in assign_options() now.

Calling handle_scaler_opt() to get a static allocation for scaler name
is still needed. It's moved to reinit_scaler(), which seems to be a
better place for it. Without it, dangling pointers could be created when
options are changed. (And in fact, this fixes possible dangling pointers
for window.name.) In theory we could create a dynamic copy, but that
seemed even more messy.

Chance of regressions.
2016-06-04 20:48:56 +02:00
wm4 352904fd03 vo_opengl: cleanup icc + runtime option changing behavior
Commit 026b75e7 actually enabled changing icc options at runtime (via
vo_cmdline), but it didn't quite work. In particular, changing the icc-
profile option just kept the old profile, because it was cached
accordingly.

As part of this, change gl_lcms.opts from a struct to a pointer to a
struct. We properly copy it, instead of allowing possibly dangling
strings, like it was done in a working but unclean way before.

Also, reinit the whole rendering chain when the auto icc profile
changes, just like it's done when icc options are changed.
2016-06-04 17:52:10 +02:00
wm4 2dfea67f3b vo_opengl: minor simplification to gl_lcms_set_memory_profile()
Passing the bstr thing as pointer makes no sense. Everywhere else bstr
structs are passed by value because they're so small. Only when it's
supposed to receive a return value they're not.
2016-06-04 14:50:32 +02:00
wm4 a9ffe38aa1 vo_opengl: remove pointless NULL-check
It's never NULL.
2016-06-04 13:44:46 +02:00
wm4 026b75e7f5 vo_opengl: move all icc handling from vo_opengl.c to video.c
Originally, video.c did not access any CMS things (other than lut3d
being set on it), but this has changed. In practice, almost all accesses
to it have moved to video.c. vo_opengl only created it, and set the auto
icc profile path.

Complete the move.

Some things wrt. option handling are a bit fishy. (But when is this not
the case.)

icc-profile-auto was not tested, but the distributed human CI will take
care of it.
2016-06-03 20:35:22 +02:00
wm4 2179879172 vo_opengl: move struct lut3d definition
This was dumb. Also, lcms.h has actually no need to include video.h
besides this and csputils.h (makes it slightly less entangled).
2016-06-03 20:06:29 +02:00
wm4 2d76c145c3 vo_opengl: fix giant memory leaks with icc profiles
Well this was dumb.
2016-06-03 20:03:49 +02:00
wm4 645a0d7791 client API: fully document opengl-cb hardware decoding interop
Document it exhaustively. Most of these issues were basically burried in
the code.
2016-06-01 22:33:36 +02:00
wm4 62acbd795f manpage: update --hwdec=d3d11va remarks 2016-05-31 18:32:06 +02:00
Rostislav Pehlivanov e44882d792 wayland: mark existing dnd entry print as debug rather than an error
It gets printed on every alt+tab or desktop switch under mutter and
weston, and offers no useful information since it's handled by
destroying the previous entry.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2016-05-31 11:22:57 +02:00
Rostislav Pehlivanov 29ea6e5e4a wayland: correctly report display refresh rate
This commit will cause the wayland backend and vo to correctly report
the display frame rate. This didn't work as VOCTRL_GET_DISPLAY_FPS was
received way too early, before the window was created (and thus
current_output set).

The VO will now signal VO_EVENT_WIN_STATE after window initialization
and upon a resize.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2016-05-31 11:22:55 +02:00
Niklas Haas 68c77d955f vo_opengl: default hdr-tone-mapping to hable
This algorithm works really well. Setting it is a much better
"out-of-the-box" experience than just clipping, which will always look
ugly.

In other words, with this default, users of mpv will just be able to
play HDR content without even realizing it's HDR (pretty much).
2016-05-30 20:17:35 +02:00
Niklas Haas 45c3e0f0d0 vo_opengl: refactor HDR mechanism
Instead of doing HDR tone mapping on an ad-hoc basis inside
pass_colormanage, the reference peak of an image is now part of the
image params (alongside colorspace, gamma, etc.) and tone mapping is
done whenever peak_src != peak_dst.

To get sensible behavior when mixing HDR and SDR content and displays,
target-brightness is a generic filler for "the assumed brightness of SDR
content".

This gets rid of the weird display_scaled hack, sets the framework
for multiple HDR functions with difference reference peaks, and allows
us to (in a future commit) autodetect the right source peak from
the HDR metadata.

(Apart from metadata, the source peak can also be controlled via
vf_format. For HDR content this adjusts the overall image brightness,
for SDR content it's like simulating a different exposure)
2016-05-30 20:17:33 +02:00
Rostislav Pehlivanov 098ff4174c wayland: implement HIDPI support
The wayland protocol exposes scaling done by the compositor to
compensate for small window sizes on small high DPI displays. If the
program ignores the scaling done, what'll happen is the compositor is
going to ask the program to be scaled down by N times the window size and
then it'll upscale the program's surface by N times. The scaling
algorithm seems to be bilinear so the scaling is quite obvious.

This commit sets up callbacks to listen for the scaling factor of each
output and, on rescale events, notifies the compositor that the
surface's scale is what the compositor asked for and changes the
player's surface to the appropriate size, causing no scaling to be done
by the compositor.

Compositors not supporting this interface will ignore the callbacks and do
nothing, keeping program behaviour the same. For compositors supporting
and using this interface (mutter), this will fix the rendering to be pixel
precise as it should be.

Both the opengl wayland backend and the wayland vo have been fixed to support
this. Verified to not break either on weston and mutter.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2016-05-30 20:17:26 +02:00
wm4 9009601c2d vf: fix filter auto-insertion
Commit 0348cd08 was too naive/simple, and always inserted the d3d11vpp
filter if any d3d11 output image formats were supported, even if it
makes no sense. For example --vf=format=rgb8 already breaks it.

It needs to take the set of supported input formats into account. the
weird format negotiation makes this hard. As a simple and cheap
solution, make some assumptions about the supported formats of a filter.

I hope to simplify this one day by using another format negotiation
algorithm, but this can probably wait.
2016-05-30 20:03:01 +02:00
wm4 4853eca8c6 mp_image: properly communicate aspect ratio through AVFrame
No idea why this wasn't done before. In particular, this fixes playing
anamorphic video through --lavfi-complex.
2016-05-30 19:12:41 +02:00
wm4 079f67268f mp_image: don't reset pixel aspect with mp_image_set_size()
No reason to do so. See also commit 240ba92b.

Since now many mp_images will never have a pixel aspect ratio set,
redefine a 0/0 aspect ratio to "undefined" instead invalid. This also
brings it more in line with how decoder vs. container aspect ratios are
handled.

Most callers seem to be fine with the new behavior.

mp_image_params_valid() in particular has to be adjusted, or some things
stop working due to mp_images not becoming valid after setting size and
format.
2016-05-30 19:07:22 +02:00
Niklas Haas 15bb05d2fe vo_opengl: add hable tone-mapping algorithm
Developed by John Hable for use in Uncharted 2. Also used by Frictional
Games in SOMA. Originally inspired by a filmic tone mapping algorithm
created by Kodak.

From http://frictionalgames.blogspot.de/2012/09/tech-feature-hdr-lightning.html
2016-05-30 16:58:25 +02:00
Niklas Haas 48015009b7 vo_opengl: rename tone-mapping=simple to reinhard
This is the canonical name for the algorithm. I simply didn't know it
before.
2016-05-30 16:58:22 +02:00
maniak1349 899d3e55b3 w32_common: center window on original window center on video resize
Position the window around the original window center on video size change
(when switching to the next file with different resolution, for example)
instead of keeping the position of its top-left corner fixed.
2016-05-30 16:58:07 +02:00
Ricardo Constantino 256d9d2b89 ytdl: fix brightcove urls 2016-05-30 16:57:43 +02:00
Ilya Tumaykin b1dd3beda9 build: don't install tests, only build them
Considering tests are usually executed right after a successful build,
there's no reason to keep them around for later.
2016-05-29 20:02:47 +02:00
wm4 240ba92bed mp_image: don't lose pixel aspect ratio when setting format
This is quite unexpected. It's caused by mp_image_set_size(), which is
used to update certain fields which can be format-dependent, but which
is actually also supposed to reset the pixel aspect ratio.
2016-05-29 19:00:55 +02:00
wm4 0348cd080f video: remove d3d11 video processor use from OpenGL interop
We now have a video filter that uses the d3d11 video processor, so it
makes no sense to have one in the VO interop code. The VO uses it for
formats not directly supported by ANGLE (so the video data is converted
to a RGB texture, which ANGLE can take in).

Change this so that the video filter is automatically inserted if
needed. Move the code that maps RGB surfaces to its own inteorp backend.
Add a bunch of new image formats, which are used to enforce the new
constraints, and to automatically insert the filter only when needed.

The added vf mechanism to auto-insert the d3d11vpp filter is very dumb
and primitive, and will work only for this specific purpose. The format
negotiation mechanism in the filter chain is generally not very pretty,
and mostly broken as well. (libavfilter has a different mechanism, and
these mechanisms don't match well, so vf_lavfi uses some sort of hack.
It only works because hwaccel and non-hwaccel formats are strictly
separated.)

The RGB interop is now only used with older ANGLE versions. The only
reason I'm keeping it is because it's relatively isolated (uses only
existing mechanisms and adds no new concepts), and because I want to be
able to compare the behavior of the old code with the new one for
testing. It will be removed eventually.

If ANGLE has NV12 interop, P010 is now handled by converting to NV12
with the video processor, instead of converting it to RGB and using the
old mechanism to import that as a texture.
2016-05-29 19:00:55 +02:00
wm4 49f73eaf7b vf_d3d11vpp: add a D3D11 video processor filter
Main use: deinterlacing.

I'm not sure how to select the deinterlacing mode at all. You can
enumate the available video processors, but at least on Intel, all of
them either signal support for all deinterlacers, or none (the latter is
apparently used for IVTC). I haven't found anything that actually tells
the processor _which_ algorithm to use.

Another strange detail is how to select top/bottom fields and field
dominance. At least I'm getting quite similar results to vavpp on Linux,
so I'm content with it for now.

Future plans include removing the D3D11 video processor use from the
ANGLE interop code.
2016-05-28 19:28:08 +02:00
James Ross-Gowan 9eccedf447 vo_opengl: angle: enable DirectComposition
This avoids a copy of the video image and lowers vsync jitter. Since
there are now two options to add to the window_attribs list, it has been
made dynamic.
2016-05-29 01:55:10 +10:00
wm4 9f42760538 vf_vdpaupp: use refqueue helper
This makes vf_vdpaupp use the deinterlacer helper code already used by
vf_vavpp. I nice side-effect is that this also removes some traces of
code originating from vo_vdpau.c, so we can switch it to LGPL.

Extend the refqueue helper with a deint setting. If not set,
mp_refqueue_should_deint() always returns false, which slightly
simplifies vf_vdpaupp. It's of no consequence to vf_vavpp (other than it
has to set it to get expected behavior).
2016-05-27 17:03:00 +02:00
Niklas Haas f8df0528b5 vo_opengl: skip junk before first user shader pass
A lot of real-world shaders start off with comments explaining the usage
or license, generating lots of "empty" passes. This simply change allows
us to skip them, which silences the warning spam and prevents us from
having to store and copy around these empty passes.

It also adds a more useful failure check: Attempting to use a user
shader that doesn't define any passes at all.
2016-05-27 17:03:00 +02:00
Yen Chi Hsuan 72e94941c9 TOOLS/zsh.pl: add .f4v extension in zsh completions 2016-05-27 17:03:00 +02:00
James Ross-Gowan 84fba1df21 vo_opengl: enable color management on GLES
This requires the GL_EXT_texture_norm16 extension and works in ANGLE.
A default precision had to be set for sampler3Ds, otherwise the shaders
would fail to compile.
2016-05-27 23:02:26 +10:00
wm4 ca87e623b5 command: add playlist-pos-1 property
This has often been requested for use on OSD. I don't really like having
such "special" properties, but whatever. Hopefully this will be the only
case.

Untested because I'm too damn lazy.

Fixes #2828.
2016-05-26 18:44:01 +02:00
wm4 306c554376 vo_opengl: fix superxbr shader compilation on ES
ES shaders do not allow implicit conversion from int to float, which
is the most annoying ES anti-feature ever.
2016-05-26 08:21:10 +02:00
wm4 e5f49d9685 vo_opengl: always autoselect ANGLE as backend if available
Remove the opengl-hq option default that caused it not to autoselect
ANGLE (unlike --vo=opengl). Details see commit d5df90a2.

Back then the intention was to use ANGLE by default, since it integrates
much nicer with the Windows compositor (instead of native OpenGL, which
tends to cause crazy glitches). On the other hand, many opengl-hq
capabilities are not available with older ANGLE builds, so it didn't
make any sense to autoselect ANGLE for it.

With the GL_EXT_texture_norm16 extension recently added to ANGLE, it has
essentially reached feature parity to desktop GL for the subset we are
using. (Even the integer texture hack for high bit depth input could be
dropped now.)

It (probably) still does not support nnedi3, due to the weird way the NN
coefficients are imported. Also, it uses half-floats instead of 16 bit
fixed-point textures for technical reasons, which implies about 5 bits
of precision loss. If anyone actually manages to distinguish the two
dithering texture formats in a double-blind test, I will fix it.
2016-05-26 00:07:10 +02:00
wm4 5c9f164caf vf_vavpp: make refqueue logic field-based
Abstracts the annoying framerate-doubling behavior.

Same deal as with refqueue introduction: the code size blows up, but at
least it can be reused for other filters.
2016-05-25 23:51:24 +02:00
wm4 fc18e1df62 vf_vavpp: minor simplification 2016-05-25 23:51:24 +02:00
wm4 68191fdca7 vf_vavpp: simplify update_pipeline() usage
Calling this right at start of filter_ext() also fixes a small
regression from previous commit. The change in reference surfaces due to
the first update_pipeline() with deinterlacing enabled changed behavior
of mp_refqueue_next() and mp_refqueue_has_output(). Since
update_pipeline() was called between those, the frame output logic got
inconsistent, and the first deinterlaced frame was duplicated from the
previous non-deinterlaced frame.

Also reset the number of ref-frames when switching back to non-deint
mode.
2016-05-25 23:51:24 +02:00
wm4 5353571de0 vf_vavpp: use future instead of past PTS to determine field duration
If the deinterlacer separates fields, the framerate must be doubled.
Since we have no stable and reliably framerate anywhere, we've been
calculating it by taking the time halfway to the next frame.

vf_vavpp actually used the past frame to calculate the frame duration,
which is sort of ok, but will skip the 2nd field in a stream (since the
first frame has no past PTS). This is annoying for testing, so use the
future frame PTS instead, which means the last field of the stream will
be dropped instead.
2016-05-25 23:51:24 +02:00
wm4 15a5d33b79 vf_vavpp: move frame handling to separate file
Move the handling of the future/past frames and the associated dataflow
rules to a separate source file.

While this on its own seems rather questionable and just inflates the
code, I intend to reuse it for other filters. The logic is annoying
enough that it shouldn't be duplicated a bunch of times.

(I considered other ways of sharing this logic, such as an uber-
deinterlace filter, which would access the hardware deinterlacer via a
different API. Although that sounds like kind of the right approach,
this would have other problems, so let's not, at least for now.)
2016-05-25 23:51:24 +02:00
wm4 b9cc33de58 win32: pthread: use SRW locks by default
SRW locks are available since Windows Vista. They work essentially like
Linux futexes. In particular, they can be statically initialized, and do
not require deinitialization. This makes them ideal for implementing
PTHREAD_MUTEX_INITIALIZER.

We still need CRITICAL_SECTION for recursive mutexes.
2016-05-24 19:02:22 +02:00
wm4 8ff96f0216 hwdec_d3d11egl: call ID3D11DeviceContext::Flush
This must be called if a texture shared between D3D devices is updated.

Often enough, the shared devices will be the same device, but ANGLE
forces using shared surfaces. I suppose there is no guarantee the driver
will do the expected thing. Internally, the driver could for example not
insert the required barriers before the shared texture is used.
2016-05-24 14:30:15 +02:00
dequis d941a57bd3 vo_xv: Handle incorrect size returned by Xv(Shm)CreateImage
Fixes #320 (which is closed as 'not our problem' but eh)

Relevant xorg bug: https://bugs.freedesktop.org/show_bug.cgi?id=70931

For me this happened when (accidentally) trying to play a 8460x2812 jpg
file with mpv. Like the referenced bug, xvinfo reports "maximum XvImage
size: 8192 x 8192". So the returned XvImage is 8192x2812 and memory
corruption happens.

Only after handling this BadShmSeg X11 errors are shown.
2016-05-24 10:25:39 +02:00
wm4 6bd021e4ee manpage: adjust dxva2 description 2016-05-23 23:46:58 +02:00
wm4 e293e411b5 etc/mpv.conf: add missing comment
The config file is an example, and is not supposed to actually define
anything by default.
2016-05-23 23:41:58 +02:00
wm4 335278b86e manpage: document how hardware decoding might cause quality loss 2016-05-23 22:55:30 +02:00
wm4 c4707cdee6 vo_opengl: fix other minor namespace issues
See previous commit.
2016-05-23 21:27:18 +02:00
wm4 e76aa7e8db vo_opengl: rename glUploadTex, drop unused parameter
Rename it to get out of OpenGL's namespace. The gl_ prefix is used by
other mpv functions, but no OpenGL ones.

The "slice" parameter was never actually used, and all callers passed 0
for it.
2016-05-23 21:27:18 +02:00
wm4 66079048ea vo_opengl: unify PBO and normal OSD texture upload path
The main change is actually that e first copy to a "staging" memory
frame, and then upload this at once. The old non-PBO code called
glTexsubImage2D for each OSD sub-bitmap.

The new non-PBO code path is a bit faster now if there are many small
sub-bitmaps (on Linux/nVidia). It's also a bit simpler, so this is a
win.

(Although I don't particularly appreciate the mixed normal/PBO texture
code.)
2016-05-23 21:27:18 +02:00
wm4 049e3ccb65 vo_opengl: make ES float texture format checks stricter
Some of these checks became pointless after dropping ES 2.0 support for
extended filtering.

GL_EXT_texture_rg is part of core in ES 3.0, and we already check for
this version, so testing for the extension is redundant.

GL_OES_texture_half_float_linear is also always available, at least as
far as our needs go.

The functionality we need from GL_EXT_color_buffer_half_float is always
available in ES 3.2, and we explicitly check for ES 3.2, so reject this
extension if the ES version is new enough.
2016-05-23 21:27:18 +02:00
wm4 80d702dce8 vo_opengl: make PBOs work on GLES 3.x
For some reason, GLES has no glMapBuffer, only glMapBufferRange.

GLES 2 has no buffer mapping at all, and GL 2.1 does not always have
glMapBufferRange. On those PBOs remain unsupported (there's no reason to
care about GL 2.1 without the extension).

This doesn't actually work on ANGLE, and I have no idea why. (There are
artifacts on OSD, as if parts of the OSD data weren't copied.) It works
on desktop OpenGL and at least 1 other ES 3 implementation. Don't enable
it on ANGLE, I guess.
2016-05-23 21:27:18 +02:00
Ben Boeckel afcef4c25b docs: fix some typos 2016-05-23 21:27:18 +02:00
wm4 75f373cc46 vo_opengl: remove unused glDrawBuffer 2016-05-23 21:27:18 +02:00
wm4 cc72a4e8c3 vo_opengl: support framebuffer invalidation
Not sure how much can be gained with this, as we can't use it properly
yet. For now, this is used only before rendering, which probably does
overwhelmingly nothing.

In the future, this should be used after temporary passes, which could
possibly reduce memory usage and even memory bandwidth usage, depending
on the drivers.
2016-05-23 21:27:18 +02:00
wm4 cc4a0571fa vo_opengl: slightly improve logging of loaded extensions
Only log when actual extensions are loaded, never log anything about
builtins.
2016-05-23 21:27:18 +02:00
wm4 c06a92e09e demux_edl: adjust warnings and variable names
Don't warn against unknown sourve length if the segment length is
explicitly provided.

Rename "len" to "end_time", because that's what it actually is.
2016-05-23 15:23:27 +02:00
Ricardo Constantino 4ff2a60632 ytdl_hook: support multi-arc subtitles
While at it, pass durations of segments from ytdl if available.
2016-05-23 15:14:14 +02:00
Josh de Kock 4aa017e301 ao_opensles: remove 32bit audio
It's unsupported by android, and can cause problems when trying to play 32bit audio. Removing 32bit fixes it by forcing 16 bit or 8 bit audio.
2016-05-22 14:31:37 +02:00
maniak1349 c4e8c36071 options: --geometry: center window position after applying size
Center window position after applying W and H parameters of the --geometry
option. Passing valid X and Y values will still override the position.

Fixes #2397.
2016-05-22 14:31:37 +02:00
maniak1349 5a3c299ca1 w32_common: make VOCTRL_SET_UNFS_WINDOW_SIZE resize the window around its center
Before that position of the window top-left corner was remaining the same
when the window was scaled.

Right now VOCTRL_SET_UNFS_WINDOW_SIZE is called only by window-scale. This
change will not affect resizes made by the user (dragging window edge).

Fixes #3164.
2016-05-22 14:31:37 +02:00
maniak1349 364af7c630 w32_common: center window on original window center on resize to fit screen
Center the window on the original window center instead of the screen center
when the window has been resized due to requested window size exceeding the
size of the screen.

If user moved the window, he probably did it for the reason and he probably
don't want it to get back to the center of the screen when he is resizing it
(with window-scale for example).
2016-05-22 14:31:37 +02:00
maniak1349 981048e041 w32_common: update stored client area size on window resize
Properly update stored client area size when the window is resized in
reinit_window_state due to window size exceeding the size of the screen.

This was causing wrong behavior with window-scale - when window size was
becoming too big the window was resized but the video was not.
2016-05-22 14:31:37 +02:00
wm4 035297212a demux_mkv: better resync behavior for broken google-created webms
I've got a broken webm that fails to seek correctly with "--start=0".
The problem is that every index entry points to 1 byte before cluster
start (!!!). demux_mkv tries to resync to the next cluster, but since it
already has read 2 bytes with ebml_read_id(), it doesn't get the first
cluster, but the following one. Actually, it can be any amount of bytes
from 1-4, whatever happens to look valid at this essentially random byte
position.

Improve this by resyncing from the original position, instead of the one
after the EBML element ID has been attempted to be read.

The file shows the following headers:

| + Muxing application: google at 177
| + Writing application: google at 186

Indeed, the file was downloaded with youtube-dl. I can only guess that
Google got it completely wrong.
2016-05-21 16:39:44 +02:00
wm4 79afa347cc vo_opengl: remove non-working rgb/rgba FBO formats
Following commit 84ccebd9, the internal helpers don't allow GL_RGB and
GL_RGBA as internal formats for FBO attachments anymore.

While OpenGL itself is perfectly fine with it, I don't see much of a
reason to bother, and mixing sized and unsized internal formats is
confusing anyway.

Just remove these formats.
2016-05-20 23:21:43 +02:00
wm4 3deedef195 stream: separate posix/win32 cancellation code
This code evolved into an ifdef mess as support for cancellation on
Windows was added. Make the Windows-specific code completely separate.
It looks cleaner, and it also means that some of the posix code is not
uselessly enabled on Windows. The latter made msvcrt.dll output warnings
because it does not like -1 passed as FD to read/write. (The same would
be harmless on POSIX.)
2016-05-20 15:51:50 +02:00
Quentin Glidic f0d7437412 build: Do not link to libGL for egl-drm
Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
2016-05-20 14:15:44 +02:00
wm4 e431a7bbfd vf_crop: support opaque hardware decoding formats
Cropping usually happens by adjusting the plane start pointers and the
image size. The former is obviously not possible for opaque hwaccel
formats, but the latter must work.

Since the code already takes care of aligning the top/left crop origin
to chroma alignment, simply set the crop origin to 0/0 in the hwaccel
case. Also add a message if such an adjustment happens.

Supporting this isn't worth much; the main usefulness is with debugging.
2016-05-19 22:56:11 +02:00
wm4 05b3a8cd14 vo_opengl: require at least ES 3.0 for float textures
ES 2.0 has this weird rule that not the internalformat parameter
determines the internal format, but the combination of all texture
parameters. GL_OES_texture_half_float thus does not specify e.g. a
GL_RGBA16F format, but requires passing GL_RGBA as format and
GL_HALF_FLOAT_OES as type. We won't bother with this, since ES 2.0 is a
lost cause anyway.

This also removes the OpenGL error when the code is trying to create a
f16 FBO for testing whether FBOs work.
2016-05-19 17:52:09 +02:00
wm4 561630cb01 vo_opengl: change error state handling and fix hwdec crashes on errors
gl_video_upload_image() can fail in the hardware decoding case. In this
case rendering continued "normally", which meant that pass_get_img_tex()
would kill the process with an assertion failure.

Fix this by allowing gl_video_upload_image() to fail, and exit rendering
early enough to skip code which requires an image to be present. (Maybe
this is still a bit too subtle, but better than before.)

Set an error flag, and render the blue screen we introduced for shader
errors. (For this purpose also move the rendering of it to final output,
to ensure it's visible at all.) The error flag is temporary, because the
associated failure might also be temporary, unlike shader compilation
errors.
2016-05-19 12:18:48 +02:00
wm4 4e5f1ec00e vo_opengl: d3d11egl: enable "required" GLSL extensions
ANGLE doesn't handle this very strictly. But if they change this in the
future, it shouldn't brick us.

Not quite happy with this glsl_extensions fields, but it is quite
unintrusive after all.
2016-05-19 12:02:08 +02:00
wm4 b0d3c2ede7 vo_opengl: make gl_sc_enable_extension() permanent/idempotent
No reason not to, and makes the following commit slightly simpler.

In fact, this makes the shaders more correct too. Normally, "#extension"
must come before any normal shader text, including the "precision"
directive. Not sure why this worked before. (Probably didn't.)
2016-05-19 12:01:59 +02:00
wm4 b46eaa3b43 vo_opengl: d3d11egl: enable direct nv12 sampling on ES 3.x
ANGLE was missing texture() overloads in the shader compiler for
GL_TEXTURE_EXTERNAL_OES textures. Support has been added upstream,
so we can use it now.
2016-05-19 10:43:57 +02:00
wm4 5f7bd411fb vo_opengl: remove unused field 2016-05-18 18:22:27 +02:00
wm4 0b911792ca vo_opengl: fix/simplify reinitialization on dynamic reconfiguration
With the new hooks mechanism, user shaders and such are actually loaded
before rendering starts, instead of being loaded during rendering. This
is used to cache them (instead of e.g. reparsing them every frame).

The cached state wasn't cleared correctly in some situations. Namely,
resizing didn't correctly enable/disable prescale hooks.

Reorganize how these reinitializations are handled. Get rid of
reinit_rendering(), whose meaning was pretty unclear. Call the required
functions to reset or recreate state directly wherever they are needed.
2016-05-18 17:47:10 +02:00
wm4 26b6d74484 demux_playlist: recognize m3u8 as playlist extension
Whatever. As mentioned in #3154.
2016-05-17 18:18:00 +02:00
wm4 a02d77ba0d d3d: simplify DLL loading
For some reason, the d3d9/dxva2/d3d11 DLLs are still optional. But we
don't need to try so hard to keep exact references. In fact, there's no
reason to unload them at all.

So load them once in a central place. For simplicity, the d3d9/d3d11
backends both load all DLLs. (They will error out only if the required
DLLs could not be loaded.)

In theory, we could just call LoadLibrary multiple times (without
calling FreeLibrary), but I'm slightly worried that this could be
detected as a "bug", or that the reference count could even have a low
static limit that could be hit soon.
2016-05-17 11:59:54 +02:00
wm4 39b64fb176 video: merge dxva2 source files
video/dxva2.c exported only 2 functions, both used only by
video/decode/dxva2.c.

The same was already done for d3d11.
2016-05-17 11:05:51 +02:00
wm4 9b56bbecdf vo_opengl: hwdec: remove build-dependency on dxva2
wscript builds hwdec_dxva2gldx.c if gl-dxinterop is enabled, while
video/dxva2.c depends on d3d-hwaccel. If d3d-hwaccel is disabled, then
hwdec_dxva2gldx.c will fail to link, because it uses
d3d9_surface_in_mp_image(), defined in dxva2.c.

Fix this by removing the use of this function. It has barely any value
at this point anyway. Just use the libavcodec documented way to get the
surface directly.

Fixes #3150.
2016-05-17 10:59:11 +02:00
wm4 b18a598444 ta: remove old and redundant macro 2016-05-17 10:53:14 +02:00
wm4 a2d58d9986 vo_opengl: move UT_buffer to switch handling
No reason to make it a special case.
2016-05-17 10:48:05 +02:00
wm4 f00040b9fc vo_opengl: make number of cached shaders/uniform dynamic
Use dynamic memory allocation, as the static allocation is starting to
get annoying.

Currently, SC_MAX_ENTRIES is essentially still a static upper limit on
the number of shaders. But in future we could try a more clever cache
replacement strategy, which does not keep stale entries forever if the
maximum happens not to be reached.
2016-05-17 10:45:01 +02:00
wm4 09763bef83 vo_opengl: move cached uniforms to a separate struct 2016-05-17 10:33:45 +02:00
Niklas Haas 8262a4dd52 vo_opengl: increase shader limits
The new uniforms introduced by 362015c have exceeded the uniform limit
when using high-radius tscale. In addition, the SC limit of 32 entries
might be pushing it with user shaders.

Just make these value a bigger to delay the onset of this same failure
mode. Maybe in the future it should be reworked to grow dynamically?
Either way, we *can* always predict a static upper bound on the number
of uniforms and shader cache entries, it's just that we forgot to do so.

Fixes #3151
2016-05-17 10:09:01 +02:00
Niklas Haas ca09cd68c8 DOCS/mplayer-changes: document HDR support
Marketing told me to do so.
2016-05-16 19:29:15 +02:00
Niklas Haas e73c83d3df vo_opengl: skip tonemapping if the output trc is HDR
This makes it so that users with actual HDR displays can just set their
config to target-trc=st2084 and get native HDR output. This will look a
bit silly for SDR content (everything will be really bright), but for
lack of a better tone mapping situation (including reverse tone mapping)
this is the easiest thing to do for now.

Ideally the brightness metadata should be part of the colorspace struct
or something (with mpv always adapting where necessary), but it depends
on the TRC and not the primaries so it's a bit more complicated than
that.
2016-05-16 14:42:45 +02:00
Niklas Haas e6f6ae94f3 vo_opengl: copy over HDR parameters to dumb_mode
Since dumb mode is affected by tone mapping (which I'll call a feature,
not a bug), we need to copy over the configuration - in particular, the
defaults. (To prevent a render failure)
2016-05-16 14:20:48 +02:00
Niklas Haas 3bdbf6274c vo_opengl: fall back to gamma2.2 by default for HDR content
Since HDR content is now auto-detected as such, we should probably do
something smarter in the "no configuration" case, such as outputting
gamma 2.2 instead.

This decision will affect the majority of users of stock configurations
who just play back appropriately tagged HDR files, so having a good
default behavior is important. "Output the HDR content as-is" is
definitely not likely to give the user a good result.
2016-05-16 14:07:39 +02:00
Niklas Haas b6c40953cb csputils: add AVCOL_TRC_SMPTEST2084 support
This now lets us auto-detect appropriately tagged HDR content using
FFmpeg's new TRC entries (when available).

Hidden behind an #if because Libav stable doesn't have it yet.
2016-05-16 13:59:57 +02:00
wm4 887b2cc30f vo_opengl: remove unnecessary casts 2016-05-16 12:58:09 +02:00
wm4 1bc902336a vo_opengl: remove another unneeded allocation 2016-05-16 12:54:45 +02:00
wm4 51307e9f18 vo_opengl: remove possibly undefined behavior 2016-05-16 12:53:45 +02:00
wm4 70df6aa375 vo_opengl: free to-be-added hook on hook array overflow
Seems sensible.

Untested.
2016-05-16 12:51:36 +02:00
wm4 155857dbe6 vo_opengl: never clear file cache
Make it dynamic and never remove entries from it.

For now, this is better than possibly creating dangling pointers all
over the place in the gl_user_shader struct.

Untested.
2016-05-16 12:51:26 +02:00
wm4 0c40eee479 vo_opengl: use proper include statement 2016-05-16 12:44:12 +02:00
wm4 dd99c1e3b4 vo_opengl: remove unnecessary allocation 2016-05-16 12:42:08 +02:00
wm4 56ed5bf1c7 vo_opengl: remove unused global variable
?
2016-05-16 12:41:55 +02:00
wm4 320627d600 manpage: declare user-shader syntax for not stable 2016-05-16 12:41:08 +02:00
wm4 51603e472d vo_opengl: fix bicubic_fast in ES mode
GLES shaders disallow implicit conversion from int to float.

This has been broken for quite a while.
2016-05-16 12:10:47 +02:00
Niklas Haas e047cc0931 vo_opengl: implement more HDR tonemapping algorithms
This is now a configurable option, with tunable parameters.

I got inspiration for these algorithms off wikipedia. "simple" seems to
work pretty well, but not well enough to make it a reasonable default.

Some other notable candidates:

- Local functions (e.g. based on local contrast or gradient)
- Clamp with soft knee (linear up to a point)
- Mapping in CIE L*Ch. Map L smoothly, clamp C and h.
- Color appearance models

These will have to be implemented some other time.

Note that the parameter "peak_src" to pass_tone_map should, in
principle, be auto-detected from the SEI information of the source file
where available. This will also have to be implemented in a later
commit.
2016-05-16 02:49:49 +02:00
Niklas Haas 3cfe98c684 vo_opengl: avoid redundant double-gamma conversion
Due to the way color management in mpv worked historically, the subtitle
blending function was written to preserve the linearity of the input.
(In the past, the 3DLUT function required linear inputs)

Since the 3DLUT was refactored to accept the video color directly, the
re-linearization after blending is now virtually always redundant.
(Notably, it's also redundant when CMS is turned off, so this way of
writing the code stopped making sense a long time ago. It is a remnant
from before the pass_colormanage function was as flexible as it is now)
2016-05-16 02:45:39 +02:00
Niklas Haas f81f486c68 vo_opengl: implement HDR (SMPTE ST2084)
Currently, this relies on the user manually entering their display
brightness (since we have no way to detect this at runtime or from ICC
metadata). The default value of 250 was picked by looking at ~10 reviews
on tftcentral.co.uk and realizing they all come with around 250 cd/m^2
out of the box. (In addition, ITU-R Rec. BT.2022 supports this)

Since there is no metadata in FFmpeg to indicate usage of this TRC, the
only way to actually play HDR content currently is to set
``--vf=format=gamma=st2084``. (It could be guessed based on SEI, but
this is not implemented yet)

Incidentally, since SEI is ignored, it's currently assumed that all
content is scaled to 10,000 cd/m^2 (and hard-clipped where out of
range). I don't see this assumption changing much, though.

As an unfortunate consequence of the fact that we don't know the display
brightness, mixed with the fact that LittleCMS' parametric tone curves
are not flexible enough to support PQ, we have to build the 3DLUT
against gamma 2.2 if it's used. This might be a good thing, though,
consdering the PQ source space is probably not fantastic for
interpolation either way.

Partially addresses #2572.
2016-05-16 02:45:39 +02:00
Niklas Haas 965031ccd5 vo_opengl: use enums for choice options internally
This is much more readable than hard-coding magic IDs all over the file,
and removes the need for all the explanatory comments that were a direct
result of this.
2016-05-16 02:45:39 +02:00
Niklas Haas 362015cd77 vo_opengl: abstract hook texture access behind macro
This macro takes care of rotation, swizzling, integer conversion and
normalization automatically. I found the performance impact to be
nonexistant for superxbr and debanding, although rotation *did* have an
impact due to the extra matrix multiplication. (So it gets skipped where
possible)

All of the internal hooks have been rewritten to use this new mechanism,
and the prescaler hooks have finally been separated from each other.
This also means the prescale FBO kludge is no longer required.

This fixes image corruption for image formats like 0bgr, and also fixes
prescaling under rotation. (As well as other user hooks that have
orientation-dependent access)

The "raw" attributes (tex, tex_pos, pixel_size) are still un-rotated, in
case something needs them, but ideally the hooks should be rewritten to
use the new API as much as possible. The hooked texture has been renamed
from just NAME to NAME_raw to make script authors notice the change (and
also deemphasize direct texture access).

This is also a step towards getting rid of the use_integer pass.
2016-05-15 20:42:08 +02:00
Niklas Haas dfc7b59909 vo_opengl: make the screen blue on shader errors
This helps visually signify that somthing went wrong, and prevents
confusing shader compilation errors with other types of bugs.
2016-05-15 20:42:02 +02:00
Niklas Haas 034faaa9d8 vo_opengl: use RPN expressions for user hook sizes
This replaces the previous TRANSFORM by WIDTH, HEIGHT and OFFSET where
WIDTH and HEIGHT are RPN expressions. This allows for more fine-grained
control over the output size, and also makes sure that overwriting
existing textures works more cleanly.

(Also add some more useful bstr functions)
2016-05-15 20:42:02 +02:00
Niklas Haas 7c3d78fd82 vo_opengl: support external user hooks
This allows users to add their own near-arbitrary hooks to the vo_opengl
processing pipeline, greatly enhancing the flexibility of user shaders.
This enables, among other things, user shaders such as CrossBilateral,
SuperRes, LumaSharpen and many more.

To make parsing the user shaders easier, shaders are now loaded as
bstrs, and the hooks are set up during video reconfig instead of on
every single frame.
2016-05-15 20:42:02 +02:00
Niklas Haas d53142f9ba vo_opengl: add optional hook points
These are "sequence points" where the image could be rendered out to an
FBO, hooked, and re-loaded if any such hook exists. This is perfect for
things like the current user shaders system, as well as optional effects
like unsharp masking.

Note that since we have to pick *some* FBO to store the optionally
hooked texture, we just store it in an array indexed by an increasing
counter. Since we only ever store as many as MAX_TEXTURE_HOOKS + all
internal hook points entries, this is guaranteed to be enough space.

This commit also removes some of the now unused FBOs.
2016-05-15 20:42:02 +02:00
Niklas Haas 070edd7300 vo_opengl: add hooks and rework pass_read_video
The hook mechanism allows arbitrary processing stages to get dispatched
whenever certain named textures have been "finalized" by the code.

This is mostly meant to serve as a change that opens up the internal
processing in pass_read_video to user scripts, but as a side benefit all
of the code dealing with offsets and plane alignment and other such
confusing things has been rewritten.

This hook mechanism is powerful enough to cover the needs of both
debanding and prescaling (and more), so as a result they can be removed
from pass_read_video entirely and implemented through hooks.

Some avenues for optimization:

- The prescale hook is currently somewhat distributed code-wise. It might be
  cleaner to split it into superxbr and NNEDI3 hooks which can each be
  self-contained.

- It might be possible to move a large part of the hook code out to an
  external file (including the hook definitions for debanding and
  prescaling), which would be very much desired.

- Currently, some stages (chroma merging, integer conversion) will
  *always* run even if unnecessary. I'm planning another series of
  refactors (deferred img_tex) to allow dropping unnecessary shader
  stages like these, but that's probably some ways away. In the meantime
  it would be doable to re-add some of the logic to skip these stages if
  we know we don't need them.

- More hook locations could be added (?)
2016-05-15 20:42:02 +02:00
Niklas Haas 3d4889e91e vo_opengl: minor change to scaler_resizes_only
Instead of rounding down, we round to the nearest float. This reduces
the maximum possible error introduced by this rounding operation. Also
clarify the comment.
2016-05-15 20:42:02 +02:00
wm4 32c10956e0 vaapi: avoid forward declaration of variable
Why is everything so horrible.
2016-05-15 18:37:51 +02:00
Julian 6ae7a555bf lua: add timer:is_enabled() function
Allows to query if some timer is currently running or was
stopped/killed.
2016-05-14 20:49:28 +02:00
wm4 449b948ee8 vo_opengl: remove some pointless compatibility
Remove non-texture_rg compatibility from LUT sampling. OpenGL without
texture_rg support will always trigger dumb-mode, and dumb-mode does not
use LUTs. It used not to, and that was when this made sense.
2016-05-14 12:02:02 +02:00
Ricardo Constantino 77d50cb3cf ytdl_hook: Just check if protocol is rtmp
Partial fix to #3090
2016-05-14 11:22:25 +02:00
wm4 3858d37b61 vo_opengl: partially fix 0bgr format support
Fixes broken colors with --vf=format=0bgr (but only if deband is
disabled).

0bgr means the first byte is padding, while the following three bytes
are bgr. From the vo_opengl perspective, it has 4 physical components
with 3 logical components. copy_img_tex() simply copied 3 components
from the physical representation, which means the last component (r) was
sliced off.

Fix this by not using p->color_swizzle for packed formats, and instead
let packed formats set the per-plane swizzle in texplane.swizzle. The
latter applies the swizzle as part of operation in copy_img_tex(), which
essentially moves physical to logical representations.

Unfortunately, debanding (and thus with opengl-hq defaults) is still
broken.
2016-05-13 22:35:42 +02:00
wm4 09e07e92c5 vo_opengl: drop duplicate LUMINANCE_ALPHA handling
This was supposed to handle the absence of GL_ARB_texture_rg. But it's
already handled elsewhere. (init_format() sets texplane.swizzle
accordingly.)
2016-05-13 22:07:25 +02:00
wm4 7d2c6d60da vo_opengl: minor simplification
Make the find_plane_format function take a bit count.

This also makes the function's comment true for the first time the
function and its comment exist. (It was commented as taking bits, but
always took bytes.)
2016-05-13 21:46:08 +02:00
wm4 c9d8bc088c vo_opengl: restrict ES2 FBO formats
Only a few very low bit depth internal formats can be rendered to in
pure ES2 (GL_RGB565 is the "best" one).

Seems like the only potentially reasonable renderable formats in ES2
could be provided via GL_OES_rgb8_rgba8, or half-floats, so don't
bother with this at all.
2016-05-13 18:50:38 +02:00
wm4 f7c81c03b2 vo_opengl: angle: log extension string 2016-05-13 15:39:11 +02:00
wm4 5bd6b76f5c cache: simplify speed calculations
Remove the attempted cleverness; keep it dumb.

This strictly calculates the average speed over an at least 1 second
window (longer if I/O blocks it).

Since this doesn't reset the speed anymore when reading stops by going
idle, the results might actually be more accurate now.
2016-05-12 22:37:45 +02:00
wm4 ee85473d4a travis: move travis-deps script to TOOLS
Don't let it clutter the top level directory.
2016-05-12 21:24:32 +02:00
wm4 a228bf54c8 vo_opengl: slightly better FBO format check
Now that we know in advance whether an implementation should support a
specific format, we have more flexibility when determining which format
to use.

In particular, we can drop the roundabout ES logic.

I'm not sure if actually trying to create the FBO for probing still has
any value. But it might, so leave it for now.
2016-05-12 21:22:28 +02:00
wm4 0cd217b039 vo_opengl: disable scalers on ES2
Even if everything else is available, the need for first class arrays
breaks it. In theory we could fix this since we don't strictly need
them, but I guess it's not worth bothering.

Also give the misnamed have_mix variable a slightly better name.
2016-05-12 21:22:28 +02:00
wm4 bd41a3ab62 vo_opengl: add detection for the ES texture_rg extension 2016-05-12 21:22:28 +02:00
wm4 84ccebd9b9 vo_opengl: reorganize texture format handling
This merges all knowledge about texture format into a central table.

Most of the work done here is actually identifying which formats exactly
are supported by OpenGL(ES) under which circumstances, and keeping this
information in the format table in a somewhat declarative way. (Although
only to the extend needed by mpv.) In particular, ES and float formats
are a horrible mess.

Again this is a big refactor that might cause regression on "obscure"
configurations.
2016-05-12 21:22:28 +02:00
wm4 e68b510a94 vo_opengl: correctly disable interpolation if tscale can't be used
It'll fail with an assertion in the interpolation code otherwise.
2016-05-12 21:22:28 +02:00
James Ross-Gowan c160e5f31d Add Appveyor CI integration for Windows builds 2016-05-12 23:34:06 +10:00
wm4 d4712af5af vo_opengl: angle: dump translated shaders
Helpful for debugging and such.
2016-05-12 11:17:49 +02:00
wm4 809d235208 manpage: document missing sub-properties
This is the client-API part; the normal descriptions are present in the
text above.
2016-05-11 19:14:31 +02:00
wm4 01d04b100f vo_opengl: don't use dumb-mode with 10 bit integer texture hack
Recent regression. Caused it to use dumb-mode with integer textures,
which on ANGLE leads to nearest scaling.
2016-05-11 17:41:00 +02:00
wm4 fe540f4477 vo_opengl: fix NULL deref on certain init failures 2016-05-11 17:12:59 +02:00
wm4 70b3561270 video: add --hwdec=auto-copy mode
This uses the normal autoprobing rules like "auto", but rejects anything
that isn't flagged as copying data back to system memory.

The chunk in command.c was dead code, so remove it instead of updating
it.
2016-05-11 16:20:13 +02:00
wm4 2ec26b8396 manpage: unmark d3d11va as "experimental"
Also add missing mediacodec entry.
2016-05-11 16:18:05 +02:00
wm4 cb694ffd8e vo_opengl: d3d11egl: support full range YUV
MSDN documents this as "Introduced in Windows 8.1.". I assume on Windows
7 this field will simply be ignored. Too bad for Windows 7 users.

Also, I'm not using D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_16_235 and
D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_0_255, because these are apparently
completely missing from the MinGW headers. (Such a damn pain.)
2016-05-11 15:40:31 +02:00
wm4 7983cda5bf vo_opengl: d3d11egl: don't require EGL_EXT_device_query
Older ANGLE builds don't export this.

This change is really only for convenience, and I might revert it at
some later point.
2016-05-11 15:40:31 +02:00
wm4 fd82e14888 build: merge d3d11va and dxva2 hwaccel checks
We don't have any reason to disable either. Both are loaded dynamically
at runtime anyway. There is also no reason why dxva2 would disappear
from libavcodec any time soon.
2016-05-11 15:40:31 +02:00
wm4 fde20d10bc vo_opengl: angle: dynamically load ANGLE
ANGLE is _really_ annoying to build. (Requires special toolchain and a
recent MSVC version.) This results in various issues with people
having trouble to build mpv against ANGLE (apparently linking it
against a prebuilt binary doesn't count, or using binaries from
potentially untrusted sources is not wanted).

Dynamically loading ANGLE is going to be a huge convenience. This commit
implements this, with special focus on keeping it source compatible to
a normal build with ANGLE linked at build-time.
2016-05-11 15:39:29 +02:00
q66 bea7675307 build: also use the iconv check on freebsd
This is necessary to make mpv build out of box on FreeBSD.
2016-05-10 23:03:53 +02:00
wm4 1f6e71c7fa vo_opengl: fix passing along swizzle from hwdec interop
In theory this was needed for the previous commit (but wasn't in
practice, since for hwdec the LUMINANCE_ALPHA mangling is not applied
anymore, and ANGLE uses RG textures in absence of GL_ARB_texture_rg for
whatever crazy reasons).

In practice this caused funky colors on OSX with the uyvy422 format,
which is also fixed in this commit.
2016-05-10 21:12:57 +02:00
wm4 a3d416c3d3 vo_opengl: d3d11egl: native NV12 sampling support
This uses EGL_ANGLE_stream_producer_d3d_texture_nv12 and related
extensions to map the D3D textures coming from the hardware decoder
directly in GL.

In theory this would be trivial to achieve, but unfortunately ANGLE does
not have a mechanism to "import" D3D textures as GL textures. Instead,
an awkward mechanism via EGL_KHR_stream was implemented, which involves
at least 5 extensions and a lot of glue code. (Even worse than VAAPI EGL
interop, and very far from the simplicity you get on OSX.)

The ANGLE mechanism so far supports only the NV12 texture format, which
means 10 bit won't work. It also does not work in ES3 mode yet. For
these reasons, the "old" ID3D11VideoProcessor code is kept and used as a
fallback.
2016-05-10 21:06:34 +02:00
wm4 4b3faf9dc1 vo_opengl: add an angle-es2 backend
It forces es2 mode on ANGLE. Only useful for testing. Since the normal
"angle" backend already falls back to es2 if es3 does not work, this new
backend always exit when autoprobing it.
2016-05-10 20:19:25 +02:00
wm4 12ae19c449 vo_opengl: cosmetics: rename variables
"p" is used for the private context everywhere in the source file, but
renaming it also requires renaming some local variables.
2016-05-10 18:49:49 +02:00
wm4 b0b01aa250 vo_opengl: refactor how hwdec interop exports textures
Rename gl_hwdec_driver.map_image to map_frame, and let it fill out a
struct gl_hwdec_frame describing the exact texture layout. This gives
more flexibility to what the hwdec interop can export. In particular, it
can export strange component orders/permutations and textures with
padded size. (The latter originating from cropped video.)

The way gl_hwdec_frame works is in the spirit of the rest of the
vo_opengl video processing code, which tends to put as much information
in immediate state (as part of the dataflow), instead of declaring it
globally. To some degree this duplicates the texplane and img_tex
structs, but until we somehow unify those, it's better to give the hwdec
state its own struct. The fact that changing the hwdec struct would
require changes and testing on at least 4 platform/GPU combinations
makes duplicating it almost a requirement to avoid pain later.

Make gl_hwdec_driver.reinit set the new image format and remove the
gl_hwdec.converted_imgfmt field.

Likewise, gl_hwdec.gl_texture_target is replaced with
gl_hwdec_plane.gl_target.

Split out a init_image_desc function from init_format. The latter is not
called in the hwdec case at all anymore. Setting up most of struct
texplane is also completely separate in the hwdec and normal cases.

video.c does not check whether the hwdec "mapped" image format is
supported. This should not really happen anyway, and if it does, the
hwdec interop backend must fail at creation time, so this is not an
issue.
2016-05-10 18:42:42 +02:00
wm4 7e6e47b8c4 sd_lavc: work around bug in older ffmpeg releases
Older ffmpeg releases don't have ffmpeg git commit
50401f5fb7d778583b03a13bc4440f71063d319d, which fixes ffmpeg's
pkt_timebase check to reject its default "unset" timebase as invalid.
The consequence was that all non-PGS bitmap subtitle timestamps were
forced to 0.

Of course this hit _only_ shitty distros using outdated/badly maintained
ffmpeg releases, so this is not worth working around. I've already
wasted a lot of time on analyzing this dumb issue, and it could be
useful for bisecting, so don't drop pre-3.0 ffmpeg just yet.

Fixes #3109.
2016-05-10 11:48:43 +02:00
wm4 013d63b081 stream_cdda: enable cache by default
Requested.
2016-05-10 11:17:52 +02:00
wm4 5d8d8618c4 manpage: document -- and some issues passing filenames 2016-05-10 11:15:45 +02:00
Richard H Lee da0bf27930 ass_process_chunk: Use llrint, not lrint
libass's ass_process_chunk expects long long int for the timecode and
durations arguments, thus should use llrint instead of lrint.

This does not cause any problems on most platforms, but on cygwin, it
causes strange subtitle behaviour, like subtitles not showing, getting
stuck or old subtitles showing at the same time as new subtitles.
2016-05-10 00:41:57 +02:00
wm4 af0a8d7478 player: restore usual seeking behavior
Commit 786f37ae accidentally changed seeking behavior such that
continuous seeking (holding the seek button down) would use the previous
seek target timestamp, instead of the new video timestamp. (This is for
the default mode, seeking to keyframes.)

The result is that the movement on the seekbar is smooth, but the way
the video updates is awkward. Some might actually prefer the new
behavior (and some players effectively show similar bahavior), but I
don't. So restore the old behavior.

This is done in two steps:

First: strictly wait for the entire seek process to finish, which will
effectively make the seeking code pick up the new video timestamp
correctly.

This would play audio immediately, which would result in noise during
continuous seeking, which leads to second: explicitly abort the playback
restarting process if this case is detected, and never play audio.
2016-05-09 22:54:49 +02:00
Mantas Mikulėnas 00c9bdf3f7 x11: tell GNOME to use dark window decorations 2016-05-09 20:39:59 +02:00
wm4 73aa7484f2 manpage: fix some script_message references to preferred name 2016-05-09 20:39:33 +02:00
wm4 46fff8d31a video: refactor how VO exports hwdec device handles
The main change is with video/hwdec.h. mp_hwdec_info is made opaque (and
renamed to mp_hwdec_devices). Its accessors are mainly thread-safe (or
documented where not), which makes the whole thing saner and cleaner. In
particular, thread-safety rules become less subtle and more obvious.

The new internal API makes it easier to support multiple OpenGL interop
backends. (Although this is not done yet, and it's not clear whether it
ever will.)

This also removes all the API-specific fields from mp_hwdec_ctx and
replaces them with a "ctx" field. For d3d in particular, we drop the
mp_d3d_ctx struct completely, and pass the interfaces directly.

Remove the emulation checks from vaapi.c and vdpau.c; they are
pointless, and the checks that matter are done on the VO layer.

The d3d hardware decoders might slightly change behavior: dxva2-copy
will not use the VO device anymore if the VO supports proper interop.
This pretty much assumes that any in such cases the VO will not use any
form of exclusive mode, which makes using the VO device in copy mode
unnecessary.

This is a big refactor. Some things may be untested and could be broken.
2016-05-09 20:03:22 +02:00
wm4 ee4c00698f vo_direct3d: remove passing device to decoder
This was never really used anyway. Removing it for the sake of the
following commit.
2016-05-09 18:59:10 +02:00
Emmanuel Gil Peyrot f99e48ae6a wayland: use the advertised size in fullscreen
When we receive the wl_shell_surface::configure event, it makes sense
to respect the aspect ratio of the video in windowed mode, but in
fullscreen it forces compositing and wastes resources (until atomic
modesetting is available everywhere and we can stop having
desynchronised planes).

Weston mitigates a resolution mismatch by creating black surfaces and
compositing them around the fullscreen surface, placed at the middle,
while GNOME puts it at the top-left and leaves the rest of the desktop
composited below, both of them producing a subpar experience.

Fixes #3021, #2657.
2016-05-08 19:47:08 +02:00
maniak1349 7d9eab15f0 win32: make taskbar progress indication optional
Add --taskbar-progress command line option and property which controls taskbar
progress indication rendering in Windows 7+. This option is on by default and
can be toggled during playback.

This option does not affect the creation process of ITaskbarList3. When the
option is turned off the progress bar is just hidden with TBPF_NOPROGRESS.

Closes #2535
2016-05-08 17:05:20 +02:00
wm4 2f8b4dd480 demux_lavf: fix a minor memory leak 2016-05-08 13:24:22 +02:00
wm4 ababfcbfe3 manpage: document --x11-bypass-compositor=no
Requested.
2016-05-08 11:05:01 +02:00
wm4 8fe33a11e2 x11: slightly safer X11 error handler behavior
The X11 error handler is global, and not per-display. If another Xlib
user exists in the process, they can conflict. In theory, it might
happen that e.g. another library sets an error handler (overwriting the
mpv one), and some time after mpv closes its display, restores the error
handler to mpv's one. To mitigate this, check if the error log instance
is actually set, instead of possibly crashing.

The change in vo_x11_uninit() is mostly cosmetic.
2016-05-08 11:04:44 +02:00
Rahul Kalkani 11406b9215 manpage: change gnome-screensaver-command example
Correct options to deactivate is -d or --deactivate.

Signed-off-by: wm4 <wm4@nowhere>
2016-05-07 12:17:28 +02:00
wm4 062493fa7e x11: rename inappropriate --x11-bypass-compositor=never option
This obviously made no sense.
2016-05-07 12:14:56 +02:00
wm4 55846641ea x11: add --x11-bypass-compositor=always
Also add missing documentation for fs-only, and correct the default.
2016-05-06 19:57:17 +02:00
Niklas Haas 7c5188c27e DOCS: update documentation related to color management
Some of this documentation was left woefully inaccurate as color
management in mpv evolved. This commit updates all of the wording and
adds notes and comments where appropriate.
2016-05-06 18:09:17 +02:00
wm4 a93fb460cd ao_alsa: add more shitty workarounds
This reportedly makes it work on ODROID-C2. The idea for this hack is
taken from kodi; they unconditionally set some or all of those flags.
I don't trust ALSA enough to hope that setting these flags couldn't
break something else, so we try without them first.

It's not clear whether this is a driver bug or a bug in the ALSA libs.
There is no ALSA bug tracker (the ALSA website has had a dead link to
a deleted bug tracker fo years). There's not much we can do other than
piling up ridiculous hacks. At least I think that at this point invalid
API usage by mpv can be excluded as a cause.

ALSA might be the worst audio API ever.
2016-05-06 17:20:02 +02:00
wm4 eef271c8f4 manpage: minor fixes to --lavfi-complex 2016-05-06 10:15:33 +02:00
wm4 7a75e7c002 vo_opengl: angle: avoid fullscreen FBO copy for flipping
In order to honor the differences between OpenGL and Direct3D coordinate
systems, ANGLE uses a full FBO copy merely to flip the final frame
vertically. This can be avoided with the EGL_ANGLE_surface_orientation
extension.
2016-05-05 18:44:41 +02:00
wm4 605dd928d3 vo_opengl: angle: call eglTerminate()
I hope that this does what we expect it does: destroy the EGLDisplay
specific to our HDC. (Some implementations will terminate all EGL
contexts in the whole process.)

eglReleaseThread() merely calls eglMakeCurrent(0, 0, 0, 0), which is
not enough.

This commit also fixes the problem fixed with the previous commit,
but I think both changes are needed to make our API usage clean.
2016-05-05 13:46:18 +02:00
wm4 f56555b514 vo_opengl: EGL: fix hwdec probing
If ANGLE was probed before (but rejected), the ANGLE API can remain
"initialized", and eglGetCurrentDisplay() will return a non-NULL
EGLDisplay. Then if a native GL context is used, the ANGLE/EGL API will
then (apparently) keep working alongside native OpenGL API. Since GL
objects are just numbers, they'll simply fail to interact, and OpenGL
will get invalid textures. For some reason this will result in black
textures.

With VAAPI-EGL, something similar could happen in theory, but didn't in
practice.
2016-05-05 13:38:08 +02:00
wm4 e5e1088c92 command: use NBSP for spacing after current marker for OSD lists
Requested. Will prevent odd layout for playlists with URLs longer than
the screen.
2016-05-04 21:51:35 +02:00
wm4 b2646911a9 client API: access choices as flags if appropriate
Options/properties that are choices, and which include "yes" or "no"
values (or both) can now be read and written as MPV_FORMAT_FLAG.

For write access, rejecting flags in these cases was obnoxiously
unintuitive and inconvenient.

For read access, the value of this is less convincing, and actually it's
a major API change. At this point I probably have to admit that the
finer details of the client API are very unstable.
2016-05-04 17:37:54 +02:00
wm4 833375f88d command: change some hwdec properties
Introduce hwdec-current and hwdec-interop properties.

Deprecate hwdec-detected, which never made a lot of sense, and which is
replaced by the new properties. hwdec-active also becomes useless, as
hwdec-current is a superset, so it's deprecated too (for now).
2016-05-04 16:55:26 +02:00
Niklas Haas 86b5f1463c lcms: don't warn/error on 3dlut cache misses
Cache misses are a normal and expected part of the operation of a cache.
It doesn't really make sense to show a user-visible warning for them.

To work-around this, just skip trying to open the cache if it doesn't
exist yet.
2016-05-04 12:10:55 +02:00
Niklas Haas 9054460bba lcms: improve black point handling (especially BT.1886)
First of all, black point compensation is now on by default. This is
really rather harmless and only improves the result (where "improvement"
means "less black clipping").

Second, this adds an option to limit the ICC profile's contrast, which
helps for untagged matrix profiles that are implicitly black scaled even
in colorimetric intent. (Note that this relies on BPC being enabled to
work properly, which is why the two changes are tied together)

Third, this uses the LittleCMS built in black point estimator instead of
relying on the presence of accurate A2B tables. This also checks tags
and does some amounts of noise elimination.

If the option is unspecified and the profile is missing black point
information, print a warning instructing the user to set the option, and
fall back to 1000 otherwise.
2016-05-04 12:10:45 +02:00
wm4 05c398fb6c command: slightly nicer OSD list formatting
For "current" markers on OSD properties like chapter-list. The marker is
now an actual arrow instead of "> ", and non-current entries will have
the same indentation as the current entry.

While I'm not entirely sure about the new look of those lists, it's a
bit better than the visual mess that was before.
2016-05-03 22:41:53 +02:00
wm4 485ae095f7 osd: make osd_ass_0/1 defines
So we can concatenate them with strings at compile time.
2016-05-03 22:29:12 +02:00
wm4 5be40f035b d3d: DXVA2_ModeMPEG2_VLD supports all profiles
Fixes hardware decoding of most mpeg2 things.
2016-05-03 15:46:16 +02:00
wm4 eefe7ad28b vo_opengl: vdpau: fix certain cases of preemption recovery failures
The vdpau_mixer could fail to be recreated properly if preemption
occured at some point before playback initialization (like when using
--hwdec-preload and the opengl-cb API).

Normally, the vdpau_mixer was supposed to be marked invalid when the
components using it detect a preemption, e.g. in hwdec_vdpau.c. This one
didn't mark the vdpau_mixer as invalid if preemption was detected in
reinit(), only in map_image().

It's cleaner to detect preemption directly in the vdpau_mixer, which
ensures it's always recreated correctly.
2016-05-03 13:56:11 +02:00
wm4 51e4c065ff ao_alsa: log final hwparams too
snd_pcm_hw_params() updates them.
2016-05-03 11:24:47 +02:00
wm4 8a26e139af x11: extend --x11-bypass-compositor with fs-only option
The "fs-only" choice sets the _NET_WM_BYPASS_COMPOSITOR to 1 if the
window is fullscreened, and 0 otherwise. (0 is specified to be the
implicit default - i.e. no change is requested in windowed mode.)

In particular, change the default to "fs-only".

Fixes #2582.
2016-05-02 21:21:53 +02:00
wm4 f54e555d27 wscript: make at least 1 OpenGL output mandatory
You have to explicitly disable it if you really want to compile without
it (like with libass).
2016-05-01 20:15:53 +02:00
wm4 3ff3749b7d av_log: readd ffmpeg library runtime version mismatch warning
It just happens far too often.
2016-05-01 20:11:15 +02:00
James Ross-Gowan 622bcb0e37 win32: replace libuuid.a usage with initguid.h
Including initguid.h at the top of a file that uses references to GUIDs
causes the GUIDs to be declared globally with __declspec(selectany). The
'selectany' attribute tells the linker to consolidate multiple
definitions of each GUID, which would be great except that, in Cygwin
and MinGW GCC 6.1, this method of linking makes the GUIDs conflict with
the ones declared in libuuid.a.

Since initguid.h obsoletes libuuid.a in modern compilers that support
__declspec(selectany), add initguid.h to all files that use GUIDs and
remove libuuid.a from the build.

Fixes #3097
2016-05-01 21:10:24 +10:00
Vaidas Kascėnas 9fda504d18 manpage: fix typo
Signed-off-by: wm4 <wm4@nowhere>
2016-04-30 18:58:34 +02:00
Nyx0uf ed695ce689 os x: handle multiple dropped files on the window
Should fix #3076 (partially).

Signed-off-by: wm4 <wm4@nowhere>
2016-04-30 18:58:06 +02:00
maniak1349 949247d6e6 w32_common: respect --fit-border on size check
Fit whole window or just a client area in accord with value of --fit-border option.

Fixes #2935.
2016-04-30 18:55:09 +02:00
maniak1349 70f64f3ca9 options: add --fit-border video option
Flag that is set by default. Reseting it will result in mpv trying to fit
client area with video instead of the whole window with border and
decorations on the screen.
Marked as (Windows only) for now until it's implemented on other platforms.
2016-04-30 18:55:09 +02:00
maniak1349 5c90352ae6 w32_common: fix size calculations for window resize
Substraction of 1 is not necessary due to .right and .bottom values of RECT
struct describing a point one pixel outside of the rectangle.

Fixes #2935. (2.b)
2016-04-30 18:55:09 +02:00
wm4 0826b78bc5 sd_ass: minor consistency adjustment 2016-04-30 14:26:08 +02:00
wm4 3a8058658d sd_add: replace --sub-ass=no with --ass-style-override=strip
--sub-ass=no / --ass=no still work, but --ass-style-override=strip is
preferred now. With this change, --ass-style-override can control all
the types of style overriding.
2016-04-30 14:25:23 +02:00
Kevin Mitchell 8d51f08010 d3d11va: fix invalid deref on decoder init failure
fixes #3092
2016-04-29 23:36:01 -07:00
wm4 64f9e48bf1 d3d11va, dxva2: return the format struct directly
Slight simplification, IMHO.
2016-04-29 23:30:01 +02:00
wm4 016eab2209 d3d11va, dxva2: simplify decoder selection
In particular, this moves the depth test to common code.

Should be functionally equivalent, except that for DXVA2, the
IDirectXVideoDecoderService_GetDecoderRenderTargets API is called
more often potentially.
2016-04-29 23:24:28 +02:00
wm4 bda111018c video: add IMGFMT_P010 alias
Gets rid of some silliness, and might be useful in the future.
2016-04-29 22:38:54 +02:00
wm4 0ed206abd9 command: don't seek immediately when setting a-b loop when paused
Because it's annoying and feels unnatural.

If the B point is set while paused, don't seek. If not paused, it should
properly loop immediately.

In theory there's a chance that it will show at least 1 frame after the
loop point when setting the B point. But let's not care about that.
2016-04-28 22:46:49 +02:00
wm4 d30634b104 ao_alsa: log hwparams while restricting them
They can sometimes fail, so I want logging to determine what's going on.

Most of them are at debug log-level, except the final hwparams.
2016-04-28 13:31:13 +02:00
wm4 304d9d58dd vo_opengl: fix build with GLES3 headers
Legacy desktop GL only symbols. Broken by the previous commit.
2016-04-27 20:26:08 +02:00
wm4 9d16837c99 vo_opengl: support GL_EXT_texture_norm16 on GLES
This gives us 16 bit fixed-point integer texture formats, including
ability to sample from them with linear filtering, and using them as FBO
attachments.

The integer texture format path is still there for the sake of ANGLE,
which does not support GL_EXT_texture_norm16 yet.

The change to pass_dither() is needed, because the code path using
GL_R16 for the dither texture relies on glTexImage2D being able to
convert from GL_FLOAT to GL_R16. GLES does not allow this. This could be
trivially fixed by doing the conversion ourselves, but I'm too lazy to
do this now.
2016-04-27 19:19:56 +02:00
wm4 757c8baf8c vo_opengl: always use sized internal formats
This shouldn't make much of a difference, but should make the following
commit simpler.
2016-04-27 19:02:04 +02:00
wm4 5df4ee55f1 player: strictly wait until done when backstepping
This fixes backstepping getting "stuck" when e.g. holding down a key
bound to the backstep command. The reason is that even if the backstep
itself is finished, the next backstep might not take the new video PTS
as reference if the hr-seek itself isn't finished yet.

The intention of not waiting for the hr-seek to finish was faster
backstepping by possibly skipping audio decoding. But it probably
doesn't matter enough to make the rest of the code more complex.
2016-04-27 17:02:00 +02:00
wm4 9cb036f297 vo_opengl: d3d11egl: minor simplification
This should be ok. eglBindTexImage() just associates the texture, and
does not make a copy (not even a conceptual one).
2016-04-27 14:35:24 +02:00
wm4 0b1ba577b1 vo_opengl: d3d11egl: print warning on unsupported colorspaces
Not much we can do about. If there are many complaints, a mechanism to
automatically disable interop in such cases could be added.
2016-04-27 14:34:46 +02:00
wm4 dff33893f2 d3d11va: store texture/subindex in IMGFMT_D3D11VA plane pointers
Basically this gets rid of the need for the accessors in d3d11va.h, and
the code can be cleaned up a little bit.

Note that libavcodec only defines a ID3D11VideoDecoderOutputView pointer
in the last plane pointers, but it tolerates/passes through the other
plane pointers we set.
2016-04-27 14:06:50 +02:00
wm4 9896994688 vd_lavc: adjust D3D11VA autoprobe order
We want to prefer d3d11va over dxva2 anything. But since dxva2 copyback
is more efficient than d3d11va's currently, d3d11va-copy should come
last.
2016-04-27 13:54:20 +02:00
wm4 3706918311 vo_opengl: D3D11VA + ANGLE interop
This uses ID3D11VideoProcessor to convert the video to a RGBA surface,
which is then bound to ANGLE. Currently ANGLE does not provide any way
to bind nv12 surfaces directly, so this will have to do.

ID3D11VideoContext1 would give us slightly more control about the
colorspace conversion, though it's still not good, and not available
in MinGW headers yet.

The video processor is created lazily, because we need to have the coded
frame size, of which AVFrame and mp_image have no concept of. Doing the
creation lazily is less of a pain than somehow hacking the coded frame
size into mp_image.

I'm not really sure how ID3D11VideoProcessorInputView is supposed to
work. We recreate it on every frame, which is simple and hopefully
doesn't affect performance.
2016-04-27 13:49:47 +02:00
wm4 cf9b415173 hwdec: remove numbers from enum
They don't actually mean anything.

Just HWDEC_NONE should remain 0, because it's the default init value for
structs etc.
2016-04-27 13:37:55 +02:00
wm4 d3a26272cd vo_opengl: print error if opengl hwdec interop fails 2016-04-27 13:32:49 +02:00
wm4 0c6c62cb17 lavfi: shut up false positive compiler warnings
As a positive side-effect, this also errors out gracefully for the
extremely unlikely but possible case certain builtin filters are not
available. (This could happen only with crippled libavfilter builds that
can't be used by anything using its public API.)
2016-04-26 19:38:51 +02:00
wm4 da59726776 vd_lavc: hack against videotoolbox crash on failure
I guess this won't ever be fixed properly in FFmpeg. Too hairy, and the
alternative (using VideoToolbox as "full decoder") is too attractive.
2016-04-26 18:53:58 +02:00
wm4 66a958bb4f ao_coreaudio: remove detected_device
Setting this here is a race condition. It's called from a CoreAudio
callbacks, and there are no locks. It's a string, so this can be
potentially severe.

It's hard to fix and only CoreAudio supported it, so remove it.

This causes the "audio-out-detected-device" property to return nothing
on all platforms.
2016-04-26 18:35:37 +02:00
wm4 dfe40f770d vo_rpi: rename mutex/cond variables
They're now used for the TV callback too, not just vsync.
2016-04-26 17:12:01 +02:00
wm4 6798525251 vo_rpi: wait for vsync with a timeout
Sucks, but better than freezing forever given the (to me) unpredictable
RPI behavior. This will be good enough to drop out of vsync timing mode,
or to abort playback.
2016-04-26 17:11:16 +02:00
wm4 74e3d11f21 vo_rpi: attempt to survive display mode changes
Recreate all dispmanx objects after mode changes signalled by the TV
callback. This is needed since dispmanx objects are marked as invalid
and cease working.

One important point is that the vsync callbacks will stop coming when
this happens, so restoring the callback is important.

Note that the MMAL renderer itself does not get trashed by the firmware
on such events, but we completely reconfigure it anyway when it happens.
2016-04-26 16:47:53 +02:00
wm4 dfa88271a2 vp_rpi: fix indentation
This also moves the p->background check into the top if (the code
effectively didn't do anything when this false).
2016-04-26 13:59:06 +02:00
wm4 8ffd2f1dd4 vd_lavc: simplify some unneeded ifdeffery
These were for ancient libavcodec versions.
2016-04-25 19:11:16 +02:00
wm4 6a1814dfb8 vd_lavc: make image_format hwdec field optional
For Mediacodec in particular we don't care about the format. It can just
decode to whatever it wants. The only case we would care about is it not
returning an opaque format if we don't have proper interop, but
libavcodec always returns non-opaque formats by default.
2016-04-25 12:23:38 +02:00
wm4 7e3d8e7134 vd_lavc: simplify RPI and Mediacodec wrappers
Use the recently added lavc_suffix mechanism to select the wrapper
decoder.

With all hwdec callbacks being optional, and RPI/Mediacodec having only
dummy callbacks, all the callbacks can be removed as well.

The result is that the vd_lavc_hwdec struct for both of them is tiny.
It's better to move them to vd_lavc.c directly, because they are so
trivial and small.
2016-04-25 12:23:38 +02:00
wm4 46e49a37be vd_lavc: make all hwdec callbacks optional 2016-04-25 12:23:37 +02:00
wm4 bb17df1f07 vd_lavc: set AVCodecContext.time_base to forced time base
This is a bit sketchy, as there isn't a truly standard way to
communicate the timebase.
2016-04-25 12:23:37 +02:00
wm4 4f5509e1dd vd_lavc: better hwdec wrapper decoder selection
This is intended for cases when --hwdec needs to override the decoder
implementation in use, like for example on the RPI.

It does two things:
1. Allow the hwdec to indicate a decoder suffix. libavcodec by
   convention adds a suffix to all wrapper decoders, and here we start
   relying on it. While not necessarily the best idea, it's the only
   thing we got. libavcodec's hwaccel list is useless, because it only
   has the codec ID, not the associated decoder's name.
2. Make --hwdec=auto work properly. It shouldn't fail anymore, and hwdec
   probing should reliably work, even if a different decoder is selected
   with --vd. The semantics of --hwdec should dictate that it overrides
   the default decoder.
2016-04-25 12:13:12 +02:00
wm4 85416bc36a vd_lavc: allow process_image() to return NULL
In case of errors or whatever.
2016-04-25 11:30:07 +02:00
wm4 021cb2c387 mp_image: allow passing NULL to mp_image_new_custom_ref()
A minor simplification. Most callers don't need this, and there's no
good reason why the caller should provide an "initializer" like this.
(This function calls mp_image_new_dummy_ref(), which has no reason
for an initializer either.)
2016-04-25 11:28:49 +02:00
trUSTssc e232f1a731 player: fix memleak when using video-frame-info 2016-04-24 20:44:01 +02:00
wm4 5800d1845f player: always show the first frame in DS mode
Fixes bogus frame drop counter in cover art mode.
2016-04-24 20:14:51 +02:00
wm4 5f97bd4223 player: assume video forwards timestamps jumps only with some formats
Another crappy fix for timestamp reset issues. This time, we try to fix
files which have very weird but legitimate frame durations, such as
cdgraphics. It can have many short frames, but once in a while there are
potentially very long frames.

Fixes #3027.
2016-04-24 18:24:46 +02:00
wm4 649e155938 manpage: fix --autofit example
Fixes #3069.
2016-04-24 17:58:39 +02:00
wm4 47e7676e7e player: force VO reconfig when unselecting video track
Switches to a black window if --force-window is used while coverart
"video" is playing.
2016-04-23 18:55:24 +02:00
wm4 786f37ae1c player: cleaner determination of current playback PTS
In particular, this won't overwrite the playback PTS in coverart mode,
which actually fixes relative seeks.
2016-04-23 18:55:24 +02:00
wm4 abb3f80998 player: eagerly redraw OSD when seeking with coverart 2016-04-23 16:39:46 +02:00
wm4 b1a8e8dba6 vd_lavc: fix hwdec fallback if hwdec pre-initialization fails
Damn.
2016-04-22 15:52:16 +02:00
wm4 244eff9201 vo_opengl: always reset some GL state when leaving renderer
The active texture and some pixelstore parameters are now always reset
to defaults when entering and leaving the renderer. Could be important
for libmpv.
2016-04-22 12:08:21 +02:00
wm4 2b4123f078 player: fix OSD bar chapter marks
Truly dumb bug introduced with the previous commit.
2016-04-22 09:31:21 +02:00
wm4 1944a34c23 command: if only ab-loop-b is set, loop from start of file
Commit 382bafcb changed the behavior for ab-loop-a. This commit changes
ab-loop-b so that the behavior is symmetric.

Adjust the OSD rendering accordingly to the two changes.

Also fix mentions of the "ab_loop" command to the now preferred
"ab-loop".
2016-04-21 22:15:36 +02:00
wm4 78346e9c9a ad_spdif: take care of deprecated libavcodec API usage 2016-04-20 19:37:45 +02:00
wm4 60664bc00b stream_memory: add hex:// protocol
Completely useless, expect for some special purposes.
2016-04-20 18:00:20 +02:00
wm4 834a236514 player: force wakeup on playback restart
Just a theoretical issue, most likely.
2016-04-20 13:11:11 +02:00
wm4 cd9ee1a853 player: really start audio only once video is ready
The check whether video is ready yet was done only in STATUS_FILLING.
But it also switched to STATUS_READY, which means the next time
fill_audio_out_buffers() was called, audio would actually be started
before video.

In most situations, this bug didn't show up, because it was only
triggered if the demuxer didn't provide video packets quickly enough,
but did for audio packets.

Also log when audio is started.

(I hate fill_audio_out_buffers(), why did I write it?)
2016-04-20 13:08:06 +02:00
wm4 61ac156d47 player: reduce some timer calls 2016-04-20 10:50:22 +02:00
wm4 8dbc93a94c player: minor simplification to buffering property updates
Strictly schedule an update in regular intervals as long as either
stream cache or demuxer are prefetching. Don't update just always
because the stream cache is enabled ("idle != -1") or cache-related
properties are observed (mp_client_event_is_registered()).

Also, the "idle" variable was awkard; get rid of it with equivalent
code.
2016-04-20 10:41:09 +02:00
wm4 8db9206c54 player: simplify an aspect of buffering determination
Calculate the buffering percentage in the same code which determines
whether the player is or should be buffering. In particular it can't
happen that percentage and buffering state are slightly out of sync due
to calling DEMUXER_CTRL_GET_READER_STATE and reusing it with the
previously determined buffering state.

Now it's also easier to guarantee that the buffering state is updated
properly.

Add some more verbose output as well.

(Damn I hate this code, why did I write it?)
2016-04-19 22:01:30 +02:00
wm4 503dada42f demux_playlist: read directories recursive
demux_playlist.c recognizes if the source stream points to a directory,
and adds its directory entries. Until now, only 1 level was added.
During playback, further directory entries could be resolved as
directory paths were "played".

While this worked fine, it lead to frequent user confusion, because
playlist resuming and other things didn't work as expected. So just
recursively scan everything.

I'm unsure whether it's a good fix, but at least it gets rid of the
complaints. (And probably will add others.)
2016-04-18 22:08:44 +02:00
wm4 382bafcb13 player: loop on end of file if ab-loop-b is unset
Possibly slightly more useful/intuitive.
2016-04-18 21:33:19 +02:00
Kevin Mitchell ce153bdb42 d3dva: move Intel_H264_NoFGT_ClearVideo to lower priority
This seems to cause problems, so only use it if H264_E is not available.

fixes #3059
2016-04-18 02:00:50 -07:00
Kevin Mitchell 2f5c7af914 dxva2: fix missing newline in error message 2016-04-18 01:58:18 -07:00
Kevin Mitchell 611594e7e8 d3dva: include selected decoder and format in verbose output 2016-04-17 18:28:14 -07:00
Philip Sequeira 1f1117d0dd input: fix parsing multiple input command prefixes 2016-04-17 12:53:30 +02:00
Philip Sequeira d797f7def9 TOOLS/zsh.pl: complete --audio-device 2016-04-16 18:47:15 +02:00
wm4 44644e69f0 vo_opengl: fix an outdated comment
This wasn't updated over multiple iterations.
2016-04-16 16:16:50 +02:00
wm4 8e96e04999 command: fix cycling certain properties
Commit a9bd4535 generally changed properties are set to string values.
This actually broke the fallback for non-string properties, because the
set string action was redirected directly to the property, instead of
the generic handler and its fallback code.
2016-04-15 22:10:19 +02:00
wm4 9db1b7a001 vo_lavc: fix build on Libav
OF COURSE Libav doesn't have AV_PICTURE_TYPE_NONE. Why the fuck would
it?
2016-04-15 19:35:29 +02:00
wm4 050b17ca9c mp_image: make mp_image_copy_fields_* private
Future code should always use mp_image_{to,from}_av_frame(). Everything
else is way too messy and fragile.
2016-04-15 15:48:02 +02:00
wm4 a77cbc504a vo_lavc: unsupport deprecated AVFMT_RAWPICTURE
As of ffmpeg git master, only the libavdevice decklink wrapper supports
this. Everything else has dropped support.

You're now supposed to use AV_CODEC_ID_WRAPPED_AVFRAME, which works a
bit differently. Normal AVFrames should still work for these encoders.
2016-04-15 15:45:38 +02:00
wm4 798188cb33 vo_lavc: send refcounted AVFrame to encoder
This potentially makes it more efficient, and actually makes it simpler.

Yes, AV_PICTURE_TYPE_NONE is the default for pict_type.
2016-04-15 15:43:46 +02:00
wm4 d04aa5ef4e mp_image: add mp_image_to_av_frame()
What mp_image_to_av_frame_and_unref() should have been. (The _unref
variant is still useful though.)
2016-04-15 15:33:53 +02:00
wm4 e6cdfdfa74 mp_image: simplify mp_image_steal_data()
Why was this so complex.
2016-04-15 15:31:23 +02:00
wm4 bbaedfd0c5 mp_image: pass through AVHWFramesContext
In both directions.
2016-04-15 15:07:02 +02:00
wm4 607ba5f235 ao_coreaudio_exclusive: list formats when searching substream
Should help debug problems with AC3 passthrough not working.
2016-04-15 14:19:22 +02:00
wm4 1aa943d8ab ao_coreaudio: remove unused function 2016-04-15 14:14:42 +02:00
wm4 b735c0e207 lcms: include math.h
Fixes #3053.
2016-04-15 13:58:41 +02:00
wm4 fbb5da0010 command: log property set calls
And remove the same thing from the client API code.

The command.c code has to deal with many specialized M_PROPERTY_SET_*
actions, and we bother with a subset only.
2016-04-15 13:20:05 +02:00
wm4 177f5d9e9c command: allow setting panscan etc. properties if no video is active
In that case, it merely changes the underlying option value.
2016-04-15 11:32:40 +02:00
wm4 a9bd4535d2 client API: improve mpv_set_property() handling of MPV_FORMAT_NODE
If a mpv_node wrapped a string, the behavior was different from calling
mpv_set_property() with MPV_FORMAT_STRING directly. Change this.

The original intention was to be strict about types if MPV_FORMAT_NODE
is used. But I think the result was less than ideal, and the same change
towards less strict behavior was made to mpv_set_option() ages ago.
2016-04-15 11:32:40 +02:00
wm4 8c02c92ab9 vo_opengl: rpi: don't include x11 header file
Copy & paste bug.
2016-04-15 09:45:15 +02:00
wm4 4ebac1e936 player: fix use-after-free with --screenshot-directory
Probably fixes #3049.
2016-04-14 22:48:12 +02:00
wm4 e13cc25a2c build: add check for AVHWFramesContext API
It's not used yet anywhere. Pushing this now so switching between
branches is less bothersome.
2016-04-14 18:20:13 +02:00
wm4 0467f5287d m_option: slightly improve --msg-level=help output
In particular get rid of the semi-deprecated ":" separator.
2016-04-13 22:25:51 +02:00
wm4 9a4120f21f m_option: add string conversion for --audio-channels
Requested in #3040.
2016-04-13 22:22:53 +02:00
Niklas Haas e3e03d0f34 vo_opengl: simplify and improve up scale=oversample
Since what we're doing is a linear blend of the four colors, we can just
do it for free by using GPU sampling.

This requires significantly fewer texture fetches and calculations to
compute the final color, making it much more efficient. The code is also
much shorter and simpler.
2016-04-12 16:26:53 +02:00
wm4 f4142ab9ad demux_mkv: fix seeking with files that miss the first index entry
Now it will always be able to seek back to the start, even if the index
is sparse or misses the first entry.

This can be achieved by reusing the logic for incremental index
generation (for files with no index), and start time probing (for making
sure the first block is always indexed).
2016-04-12 15:41:44 +02:00
wm4 837b865c7f vf_vavpp: reindent 2016-04-11 22:03:26 +02:00
wm4 f5ff2656e0 vaapi: determine surface format in decoder, not in renderer
Until now, we have made the assumption that a driver will use only 1
hardware surface format. the format is dictated by the driver (you
don't create surfaces with a specific format - you just pass a
rt_format and get a surface that will be in a specific driver-chosen
format).

In particular, the renderer created a dummy surface to probe the format,
and hoped the decoder would produce the same format. Due to a driver
bug this required a workaround to actually get the same format as the
driver did.

Change this so that the format is determined in the decoder. The format
is then passed down as hw_subfmt, which allows the renderer to configure
itself with the correct format. If the hardware surface changes its
format midstream, the renderer can be reconfigured using the normal
mechanisms.

This calls va_surface_init_subformat() each time after the decoder
returns a surface. Since libavcodec/AVFrame has no concept of sub-
formats, this is unavoidable. It creates and destroys a derived
VAImage, but this shouldn't have any bad performance effects (at
least I didn't notice any measurable effects).

Note that vaDeriveImage() failures are silently ignored as some
drivers (the vdpau wrapper) support neither vaDeriveImage, nor EGL
interop. In addition, we still probe whether we can map an image
in the EGL interop code. This is important as it's the only way
to determine whether EGL interop is supported at all. With respect
to the driver bug mentioned above, it doesn't matter which format
the test surface has.

In vf_vavpp, also remove the rt_format guessing business. I think the
existing logic was a bit meaningless anyway. It's not even a given
that vavpp produces the same rt_format for output.
2016-04-11 22:03:26 +02:00
Rudolf Polzer 49431626cb Revert "build: disable encoding mode by default"
Reverting because the use of deprecated API has been fixed.

This reverts commit d0238711dc.
2016-04-11 14:59:33 -04:00
Rudolf Polzer 160497b8ff encode_lavc: Migrate to codecpar API. 2016-04-11 14:57:20 -04:00
400 changed files with 25115 additions and 15502 deletions

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
### mpv version and platform
If you're not using git master or the latest release, update.
### Reproduction steps
### Expected behavior
### Actual behavior
### Log file
Make a log file made with -v or --log-file=output.txt, paste it to
http://sprunge.us or a similar site, and replace this text with a link to it.
Providing a log file is strongly encouraged. It is very helpful for reproducing
bugs or getting important technical context. Without a log it might not be
possible to analyze and fix certain bugs.
### Sample files
Sample files needed to reproduce this issue can be uploaded to https://0x0.st/
or similar sites. (Only needed if the issue cannot be reproduced without it.)
+7
View File
@@ -0,0 +1,7 @@
Ideally, you shouldn't need enter any text here, and your commit messages should
explain your changes sufficiently (especially why they are needed). Read
https://github.com/mpv-player/mpv/blob/master/DOCS/contribute.md for coding
style and development conventions. Remove this text block, but if you haven't
agreed to it before, leave the following sentence in place:
I agree that my changes can be relicensed to LGPL 2.1 or later.
+1 -1
View File
@@ -15,11 +15,11 @@
/tags
/TAGS
/video/out/x11_icon.inc
/video/out/opengl/nnedi3_weights.inc
/demux/ebml_defs.c
/demux/ebml_types.h
/sub/osd_font.h
/player/lua/*.inc
/player/builtin_conf.inc
/DOCS/man/mpv.1
/DOCS/man/mpv.aux
/DOCS/man/mpv.log
+4 -1
View File
@@ -12,6 +12,8 @@ env:
global:
# Coverity token
- secure: "H21mSRlMhk4BKS0xHZvCFGJxteCP0hRVUxTuNfM2Z9HBsyutuLEYMtViLO86VtM+Tqla3xXPzUdS4ozLwI72Ax/5ZUDXACROj73yW6QhFB5D6rLut12+FjqC7M33Qv2hl0xwgNBmR5dsm1ToP37+Wn+ecJQNvN8fkTXF+HVzOEw="
# Travis token for mpv.io
- secure: "nlTVLJK6kRhtXvhKCoJ3YdFGHuKaq/eHowfPw25hqRWuBOZd+HjHY5KIYjV7SxuKFDpJE4GpNcvA3Q31nsqomxpkLYgrwjg6TSazN7ZP+x85ZgV1QGFebrPfGm2n5UR5CAPAwFoeF3pZheLi4bajVzwq1fWW+x3grS188P9OZso="
compiler:
- clang
- gcc
@@ -37,11 +39,12 @@ matrix:
- os: linux
compiler: clang
before_install: ./travis-deps libass-stable $LIBAV
before_install: TOOLS/travis-deps libass-stable $LIBAV
script:
- ./bootstrap.py
- ./waf configure
- ./waf build
after_script: TOOLS/travis-rebuild-website
notifications:
email: false
-32
View File
@@ -1,32 +0,0 @@
Reporting bugs
==============
- State your platform and mpv version.
- Make sure you're actually using the latest mpv release. Linux distributions
in particular love redistributing ancient and unmaintained mpv releases.
- Attach a log file made with ``-v`` or ``--log-file=output.txt``.
- Avoid attaching text files packed in archive files (zip/rar/...), unless
explicitly asked so. There are better means, such as using http://sprunge.us
- If you think this is file specific, upload a sample file and link it.
- Don't report multiple unrelated/barely related bugs in one issue.
- If you don't get a reply after days, be sure to post a new message to the
issue - it could have been overlooked or forgotten.
- Read: https://mpv.io/bug-reports/
Asking questions
================
Preferably, asking questions should be done via IRC (#mpv on irc.freenode.net),
but asking questions by opening a github issue is also barely tolerated.
When asking on IRC (#mpv on irc.freenode.net), don't ask to ask, just state
your problem. Stay long enough until someone gets a chance to reply. Sometimes
it can take hours.
Sending patches
===============
See: https://github.com/mpv-player/mpv/blob/master/DOCS/contribute.md
In particular, be aware that all changes to GPL code must come with the
implicit agreement that they might be LGPLv2.1+ relicensed at a later point.
-3
View File
@@ -12,9 +12,6 @@ the code to LGPLv2.1+ at a later point without asking the contributor. (This
is a safeguard for making potential relicensing of the project to LGPLv2.1+
easier.) Using a more liberal license compatible to LGPLv2.1+ is also ok.
Some GPLv3 or LGPLv3 code in mpv can be enabled by building with --enable-gpl3,
and in this case, the resulting binaries must be distributed under GPLv3.
For information about authors and contributors, consult the git log, which
contains the complete SVN and CVS history as well.
+46
View File
@@ -32,6 +32,52 @@ API changes
::
--- mpv 0.23.0 ---
1.24 - the deprecated mpv_suspend() and mpv_resume() APIs now do nothing.
--- mpv 0.22.0 ---
1.23 - deprecate setting "no-" options via mpv_set_option*(). For example,
instead of "no-video=" you should set "video=no".
- do not override the SIGPIPE signal handler anymore. This was done as
workaround for the FFmpeg TLS code, which has been fixed long ago.
- deprecate mpv_suspend() and mpv_resume(). They will be stubbed out
in mpv 0.23.0.
- make mpv_set_property() work to some degree before mpv_initialize().
It can now be used instead of mpv_set_option().
- semi-deprecate mpv_set_option()/mpv_set_option_string(). You should
use mpv_set_property() instead. There are some deprecated properties
which conflict with some options (see client.h remarks on
mpv_set_option()), for which mpv_set_option() might still be required.
In future mpv releases, the conflicting deprecated options/properties
will be removed, and mpv_set_option() will internally translate API
calls to mpv_set_property().
- qthelper.hpp: deprecate get_property_variant, set_property_variant,
set_option_variant, command_variant, and replace them with
get_property, set_property, command.
--- mpv 0.19.0 ---
1.22 - add stream_cb API for custom protocols
--- mpv 0.18.1 ---
---- - remove "status" log level from mpv_request_log_messages() docs. This
is 100% equivalent to "v". The behavior is still the same, thus no
actual API change.
--- mpv 0.18.0 ---
1.21 - mpv_set_property() changes behavior with MPV_FORMAT_NODE. Before this
change it rejected mpv_nodes with format==MPV_FORMAT_STRING if the
property was not a string or did not have special mechanisms in place
the function failed. Now it always invokes the option string parser,
and mpv_node with a basic data type works exactly as if the function
is invoked with that type directly. This new behavior is equivalent
to mpv_set_option().
This also affects the mp.set_property_native() Lua function.
- generally, setting choice options/properties with "yes"/"no" options
can now be set as MPV_FORMAT_FLAG
- reading a choice property as MPV_FORMAT_NODE will now return a
MPV_FORMAT_FLAG value if the choice is "yes" (true) or "no" (false)
This implicitly affects Lua and JSON IPC interfaces as well.
- big changes to vo-cmdline on vo_opengl and vo_opengl_hq (but not
vo_opengl_cb): options are now normally not reset, but applied on top
of the current options. The special undocumented value "-" still
works, but now resets all options to before any vo-cmdline command
has been called.
--- mpv 0.12.0 ---
1.20 - deprecate "GL_MP_D3D_interfaces"/"glMPGetD3DInterface", and introduce
"GL_MP_MPGetNativeDisplay"/"glMPGetNativeDisplay" (this is a
+29 -15
View File
@@ -104,10 +104,10 @@ Installing MSYS2
It doesn't matter whether the i686 or the x86_64 version is used. Both can
build 32-bit and 64-bit binaries when running on a 64-bit version of Windows.
2. Start a MinGW-w64 shell (``mingw64_shell.bat``). Note that this is different
2. Start a MinGW-w64 shell (``mingw64.exe``). Note that this is different
from the MSYS2 shell that is started from the final installation dialog.
For a 32-bit build, use ``mingw32_shell.bat``.
For a 32-bit build, use ``mingw32.exe``.
Updating MSYS2
--------------
@@ -118,7 +118,7 @@ separately.
```bash
# Check for core updates. If instructed, close the shell window and reopen it
# before continuing.
update-core
pacman -Syu
# Update everything else
pacman -Su
@@ -166,13 +166,28 @@ Or, compile and install both libmpv and mpv:
./waf configure CC=gcc.exe --check-c-compiler=gcc --enable-libmpv-shared --prefix=/mingw64
./waf install
# waf installs libmpv to the wrong directory, so fix it up
mv -f /mingw64/bin/pkgconfig/mpv.pc /mingw64/lib/pkgconfig/
mv -f /mingw64/bin/libmpv.dll.a /mingw64/lib/
sed -i 's_/mingw64/bin_/mingw64/lib_' /mingw64/lib/pkgconfig/mpv.pc
rmdir /mingw64/bin/pkgconfig
# waf installs libmpv dll to the wrong directory, so fix it up
mv -f /mingw64/lib/mpv-1.dll /mingw64/bin/
```
Linking libmpv with MSVC programs
---------------------------------
You can build C++ programs in Visual Studio and link them with libmpv. To do
this, you need a Visual Studio which supports ``stdint.h`` (recent ones do),
and you need to create a import library for the mpv DLL:
```bash
lib /def:mpv.def /name:mpv-1.dll /out:mpv.lib /MACHINE:X64
```
The string in the ``/name:`` parameter must match the filename of the DLL (this
is simply the filename the MSVC linker will use). The ``mpv.def`` can be
retrieved from the mpv build directory, or can be produced by MingGW's
gendef.exe helper from the mpv DLL.
Static linking is not possible.
Running mpv
-----------
@@ -190,11 +205,10 @@ DLLs in that folder. The simplest solution is to add ``C:\msys64\mingw64\bin``
to the windows system ``%PATH%``. Beware though that this can cause problems or
confusion in Cygwin if that is also installed on the machine.
Use of the ANGLE OpenGL backend requires a copy of ``d3dcompiler_43.dll`` (yes,
exactly 43) in the path or in the same folder as mpv. It must be of the same
architecture (x86_64 / i686) as the mpv you compiled. You can find a copy in the
official mpv builds:
Use of the ANGLE OpenGL backend requires a copy of the D3D compiler DLL that
matches the version of the D3D SDK that ANGLE was built with
(``d3dcompiler_43.dll`` in case of MinGW-built ANGLE) in the path or in the
same folder as mpv. It must be of the same architecture (x86_64 / i686) as the
mpv you compiled. You can find copies here:
https://mpv.srsfckn.biz/mpv-x86_64-20160118.7z
https://mpv.srsfckn.biz/mpv-i686-20160118.7z
https://mpv.srsfckn.biz/d3dcompiler.7z
+156
View File
@@ -19,6 +19,162 @@ Interface changes
::
--- mpv 0.23.0 ---
- remove deprecated vf_vdpaurb (use "--hwdec=vdpau-copy" instead)
- the following properties now have new semantics:
- "demuxer" (use "current-demuxer")
- "fps" (use "container-fps")
- "idle" (use "idle-active")
- "cache" (use "cache-percent")
- "audio-samplerate" (use "audio-params/samplerate")
- "audio-channels" (use "audio-params/channel-count")
- "audio-format" (use "audio-codec-name")
(the properties equivalent to the old semantics are in parentheses)
- remove deprecated --vo and --ao sub-options (like --vo=opengl:...), and
replace them with global options. A somewhat complete list can be found
here: https://github.com/mpv-player/mpv/wiki/Option-replacement-list#mpv-0210
- remove --vo-defaults and --ao-defaults as well
- remove deprecated global sub-options (like -demuxer-rawaudio format=...),
use flat options (like --demuxer-rawaudio-format=...)
- the --sub-codepage option changes in incompatible ways:
- detector-selection and fallback syntax is deprecated
- enca/libguess are removed and deprecated (behaves as if they hadn't
been compiled-in)
- --sub-codepage=<codepage> does not force the codepage anymore
(this requires different and new syntax)
- remove --fs-black-out-screens option for macOS
- change how spdif codecs are selected. You can't enable spdif passthrough
with --ad anymore. This was deprecated; use --audio-spdif instead.
- deprecate the "family" selection with --ad/--vd
forcing/excluding codecs with "+", "-", "-" is deprecated as well
- explicitly mark --ad-spdif-dtshd as deprecated (it was done so a long time
ago, but it didn't complain when using the option)
--- mpv 0.22.0 ---
- the "audio-device-list" property now sets empty device description to the
device name as a fallback
- add --hidpi-window-scale option for macOS
- add audiounit audio output for iOS
- make --start-time work with --rebase-start-time=no
- add --opengl-early-flush=auto mode
- add --hwdec=vdpau-copy, deprecate vf_vdpaurb
- add tct video output for true-color and 256-color terminals
--- mpv 0.21.0 ---
- unlike in older versions, setting options at runtime will now take effect
immediately (see for example issue #3281). On the other hand, it will also
do runtime verification and reject option changes that do not work
(example: setting the "vf" option to a filter during playback, which fails
to initialize - the option value will remain at its old value). In general,
"set name value" should be mostly equivalent to "set options/name value"
in cases where the "name" property is not deprecated and "options/name"
exists - deviations from this are either bugs, or documented as caveats
in the "Inconsistencies between options and properties" manpage section.
- deprecate _all_ --vo and --ao suboptions. Generally, all suboptions are
replaced by global options, which do exactly the same. For example,
"--vo=opengl:scale=nearest" turns into "--scale=nearest". In some cases,
the global option is prefixed, e.g. "--vo=opengl:pbo" turns into
"--opengl-pbo".
Most of the exact replacements are documented here:
https://github.com/mpv-player/mpv/wiki/Option-replacement-list
- remove --vo=opengl-hq. Set --profile=opengl-hq instead. Note that this
profile does not force the VO. This means if you use the --vo option to
set another VO, it won't work. But this also means it can be used with
opengl-cb.
- remove the --vo=opengl "pre-shaders", "post-shaders" and "scale-shader"
sub-options: they were deprecated in favor of "user-shaders"
- deprecate --vo-defaults (no replacement)
- remove the vo-cmdline command. You can set OpenGL renderer options
directly via properties instead.
- deprecate the device/sink options on all AOs. Use --audio-device instead.
- deprecate "--ao=wasapi:exclusive" and "--ao=coreaudio:exclusive",
use --audio-exclusive instead.
- subtle changes in how "--no-..." options are treated mean that they are
not accessible under "options/..." anymore (instead, these are resolved
at parsing time). This does not affect options which start with "--no-",
but do not use the mechanism for negation options.
(Also see client API change for API version 1.23.)
- rename the following properties
- "demuxer" -> "current-demuxer"
- "fps" -> "container-fps"
- "idle" -> "idle-active"
- "cache" -> "cache-percent"
the old names are deprecated and will change behavior in mpv 0.23.0.
- remove deprecated "hwdec-active" and "hwdec-detected" properties
- deprecate the ao and vo auto-profiles (they never made any sense)
- deprecate "--vo=direct3d_shaders" - use "--vo=direct3d" instead.
Change "--vo=direct3d" to always use shaders by default.
- deprecate --playlist-pos option, renamed to --playlist-start
- deprecate the --chapter option, as it is redundant with --start/--end,
and conflicts with the semantics of the "chapter" property
- rename --sub-text-* to --sub-* and --ass-* to --sub-ass-* (old options
deprecated)
- incompatible change to cdda:// protocol options: the part after cdda://
now always sets the device, not the span or speed to be played. No
separating extra "/" is needed. The hidden --cdda-device options is also
deleted (it was redundant with the documented --cdrom-device).
- deprecate --vo=rpi. It will be removed in mpv 0.23.0. Its functionality
was folded into --vo=opengl, which now uses RPI hardware decoding by
treating it as a hardware overlay (without applying GL filtering). Also
to be changed in 0.23.0: the --fs flag will be reset to "no" by default
(like on the other platforms).
- deprecate --mute=auto (informally has been since 0.18.1)
- deprecate "resume" and "suspend" IPC commands. They will be completely
removed in 0.23.0.
- deprecate mp.suspend(), mp.resume(), mp.resume_all() Lua scripting
commands, as well as setting mp.use_suspend. They will be completely
removed in 0.23.0.
- the "seek" command's absolute seek mode will now interpret negative
seek times as relative from the end of the file (and clamps seeks that
still go before 0)
- add almost all options to the property list, meaning you can change
options without adding "options/" to the property name (a new section
has been added to the manpage describing some conflicting behavior
between options and properties)
- implement changing sub-speed during playback
- make many previously fixed options changeable at runtime (for example
--terminal, --osc, --ytdl, can all be enable/disabled after
mpv_initialize() - this can be extended to other still fixed options
on user requests)
--- mpv 0.20.0 ---
- add --image-display-duration option - this also means that image duration
is not influenced by --mf-fps anymore in the general case (this is an
incompatible change)
--- mpv 0.19.0 ---
- deprecate "balance" option/property (no replacement)
--- mpv 0.18.1 ---
- deprecate --heartbeat-cmd
- remove --softvol=no capability:
- deprecate --softvol, it now does nothing
- --volume, --mute, and the corresponding properties now always control
softvol, and behave as expected without surprises (e.g. you can set
them normally while no audio is initialized)
- rename --softvol-max to --volume-max (deprecated alias is added)
- the --volume-restore-data option and property are removed without
replacement. They were _always_ internal, and used for watch-later
resume/restore. Now --volume/--mute are saved directly instead.
- the previous point means resuming files with older watch-later configs
will print an error about missing --volume-restore-data (which you can
ignore), and will not restore the previous value
- as a consequence, volume controls will no longer control PulseAudio
per-application value, or use the system mixer's per-application
volume processing
- system or per-application volume can still be controlled with the
ao-volume and ao-mute properties (there are no command line options)
--- mpv 0.18.0 ---
- now ab-loops are active even if one of the "ab-loop-a"/"-b" properties is
unset ("no"), in which case the start of the file is used if the A loop
point is unset, and the end of the file for an unset B loop point
- deprecate --sub-ass=no option by --ass-style-override=strip
(also needs --embeddedfonts=no)
- add "hwdec-interop" and "hwdec-current" properties
- deprecated "hwdec-active" and "hwdec-detected" properties (to be removed
in mpv 0.20.0)
- choice option/property values that are "yes" or "no" will now be returned
as booleans when using the mpv_node functions in the client API, the
"native" property accessors in Lua, and the JSON API. They can be set as
such as well.
- the VO opengl fbo-format sub-option does not accept "rgb" or "rgba"
anymore
- all VO opengl prescalers have been removed (replaced by user scripts)
--- mpv 0.17.0 ---
- deprecate "track-list/N/audio-channels" property (use
"track-list/N/demux-channel-count" instead)
-14
View File
@@ -1,14 +0,0 @@
Client API (libmpv) documentation and examples
==============================================
libmpv lets you embed mpv as a library. It is meant to enable development of
GUI frontends.
Since libmpv merely allows access to underlying mechanisms that can control
mpv, documentation is spread over a few places:
- https://github.com/mpv-player/mpv/blob/master/libmpv/client.h
- http://mpv.io/manual/master/#options
- http://mpv.io/manual/master/#list-of-input-commands
- http://mpv.io/manual/master/#properties
- https://github.com/mpv-player/mpv-examples/tree/master/libmpv
+23 -33
View File
@@ -70,7 +70,7 @@ Available filters are:
Set AVOptions on the SwrContext or AVAudioResampleContext. These should
be documented by FFmpeg or Libav.
``lavcac3enc[=tospdif[:bitrate[:minch]]]``
``lavcac3enc[=options]``
Encode multi-channel audio to AC-3 at runtime using libavcodec. Supports
16-bit native-endian input format, maximum 6 channels. The output is
big-endian when outputting a raw AC-3 stream, native-endian when
@@ -103,6 +103,10 @@ Available filters are:
If the input channel number is less than ``<minch>``, the filter will
detach itself (default: 3).
``encoder=<name>``
Select the libavcodec encoder used. Currently, this should be an AC-3
encoder, and using another codec will fail horribly.
``equalizer=g1:g2:g3:...:g10``
10 octave band graphic equalizer, implemented using 10 IIR band-pass
filters. This means that it works regardless of what type of audio is
@@ -308,33 +312,12 @@ Available filters are:
``mpv '--af=format=channels=5.1' '--audio-channels=5.1'`` would always force
remixing audio to 5.1 and output it like this.
``delay[=[ch1,ch2,...]]``
Delays the sound to the loudspeakers such that the sound from the
different channels arrives at the listening position simultaneously. It is
only useful if you have more than 2 loudspeakers.
This filter supports the following ``af-command`` commands:
``[ch1,ch2,...]``
The delay in ms that should be imposed on each channel (floating point
number between 0 and 1000).
To calculate the required delay for the different channels, do as follows:
1. Measure the distance to the loudspeakers in meters in relation to your
listening position, giving you the distances s1 to s5 (for a 5.1
system). There is no point in compensating for the subwoofer (you will
not hear the difference anyway).
2. Subtract the distances s1 to s5 from the maximum distance, i.e.
``s[i] = max(s) - s[i]; i = 1...5``.
3. Calculate the required delays in ms as ``d[i] = 1000*s[i]/342; i =
1...5``.
.. admonition:: Example
``mpv --af=delay=[10.5,10.5,0,0,7,0] media.avi``
Would delay front left and right by 10.5 ms, the two rear channels
and the subwoofer by 0 ms and the center channel by 7 ms.
``set-matrix``
Set the ``<matrix>`` argument dynamically. This can be used to change
the mixing matrix at runtime, without reinitializing the entire filter
chain.
``drc[=method:target]``
Applies dynamic range compression. This maximizes the volume by compressing
@@ -418,10 +401,6 @@ Available filters are:
``mpv --af=scaletempo=stride=30:overlap=.50:search=10 media.ogg``
Would tweak the quality and performance parameters.
``mpv --af=format=float,scaletempo media.ogg``
Would make scaletempo use float code. Maybe faster on some
platforms.
``mpv --af=scaletempo=scale=1.2:speed=pitch audio.ogg``
Would play media at 1.2x normal speed, with audio at normal pitch.
Changing playback speed would change pitch, leaving audio tempo at
@@ -430,9 +409,13 @@ Available filters are:
``rubberband``
High quality pitch correction with librubberband. This can be used in place
of ``scaletempo``, and will be used to adjust audio pitch when playing
at speed different from normal.
at speed different from normal. It can also be used to adjust audio pitch
without changing playback speed.
This filter has a number of sub-options. You can list them with
``<pitch-scale>``
Sets the pitch scaling factor. Frequencies are multiplied by this value.
This filter has a number of additional sub-options. You can list them with
``mpv --af=rubberband=help``. This will also show the default values
for each option. The options are not documented here, because they are
merely passed to librubberband. Look at the librubberband documentation
@@ -441,6 +424,13 @@ Available filters are:
(The mapping of the mpv rubberband filter sub-option names and values to
those of librubberband follows a simple pattern: ``"Option" + Name + Value``.)
This filter supports the following ``af-command`` commands:
``set-pitch``
Set the ``<pitch-scale>`` argument dynamically. This can be used to
change the playback pitch at runtime. Note that speed is controlled
using the standard ``speed`` property, not ``af-command``.
``lavfi=graph``
Filter audio using FFmpeg's libavfilter.
+72 -120
View File
@@ -4,17 +4,11 @@ AUDIO OUTPUT DRIVERS
Audio output drivers are interfaces to different audio output facilities. The
syntax is:
``--ao=<driver1[:suboption1[=value]:...],driver2,...[,]>``
``--ao=<driver1,driver2,...[,]>``
Specify a priority list of audio output drivers to be used.
If the list has a trailing ',', mpv will fall back on drivers not contained
in the list. Suboptions are optional and can mostly be omitted.
You can also set defaults for each driver. The defaults are applied before the
normal driver parameters.
``--ao-defaults=<driver1[:parameter1:parameter2:...],driver2,...>``
Set defaults for each driver.
in the list.
.. note::
@@ -23,87 +17,19 @@ normal driver parameters.
where PulseAudio is used. On BSD systems, ``--ao=oss`` or ``--ao=sndio``
may work (the latter being experimental).
.. admonition:: Examples
- ``--ao=alsa,oss,`` Try the ALSA driver, then the OSS driver, then others.
- ``--ao=alsa:resample=yes:device=[plughw:0,3]`` Lets ALSA resample and
sets the device-name as first card, fourth device.
Available audio output drivers are:
``alsa`` (Linux only)
ALSA audio output driver
``device=<device>``
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
"spdif" device, unless you really know how to set it correctly.
``resample=yes``
Enable ALSA resampling plugin. (This is disabled by default, because
some drivers report incorrect audio delay in some cases.)
``mixer-device=<device>``
Set the mixer device used with ``--no-softvol`` (default: ``default``).
``mixer-name=<name>``
Set the name of the mixer element (default: ``Master``). This is for
example ``PCM`` or ``Master``.
``mixer-index=<number>``
Set the index of the mixer channel (default: 0). Consider the output of
"``amixer scontrols``", then the index is the number that follows the
name of the element.
``non-interleaved``
Allow output of non-interleaved formats (if the audio decoder uses
this format). Currently disabled by default, because some popular
ALSA plugins are utterly broken with non-interleaved formats.
``ignore-chmap``
Don't read or set the channel map of the ALSA device - only request the
required number of channels, and then pass the audio as-is to it. This
option most likely should not be used. It can be useful for debugging,
or for static setups with a specially engineered ALSA configuration (in
this case you should always force the same layout with ``--audio-channels``,
or it will work only for files which use the layout implicit to your
ALSA device).
.. note::
MPlayer and mplayer2 required you to replace any ',' with '.' and
any ':' with '=' in the ALSA device name. mpv does not do this anymore.
Instead, quote the device name:
``--ao=alsa:device=[plug:surround50]``
Note that the ``[`` and ``]`` simply quote the device name. With some
shells (like zsh), you have to quote the option string to prevent the
shell from interpreting the brackets instead of passing them to mpv.
Actually, you should use the ``--audio-device`` option, instead of
setting the device directly.
See `ALSA audio output options`_ for options specific to this AO.
.. warning::
Handling of multichannel/surround audio changed in mpv 0.8.0 from the
behavior in MPlayer/mplayer2 and older versions of mpv.
The old behavior is that the player always downmixed to stereo by
default. The ``--audio-channels`` (or ``--channels`` before that) option
had to be set to get multichannel audio. Then playing stereo would
use the ``default`` device (which typically allows multiple programs
to play audio at the same time via dmix), while playing anything with
more channels would open one of the hardware devices, e.g. via the
``surround51`` alias (typically with exclusive access). Whether the
player would use exclusive access or not would depend on the file
being played.
The new behavior since mpv 0.8.0 always enables multichannel audio,
i.e. ``--audio-channels=auto`` is the default. However, since ALSA
provides no good way to play multichannel audio in a non-exclusive
way (without blocking other applications from using audio), the player
is restricted to the capabilities of the ``default`` device by default,
which means it supports only stereo and mono (at least with current
typical ALSA configurations). But if a hardware device is selected,
then multichannel audio will typically work.
The short story is: if you want multichannel audio with ALSA, use
``--audio-device`` to select the device (use ``--audio-device=help``
to get a list of all devices and their mpv name).
To get multichannel/surround audio, use ``--audio-channels=auto``. The
default for this option is ``auto-safe``, which makes this audio otuput
explicitly reject multichannel output, as there is no way to detect
whether a certain channel layout is actually supported.
You can also try `using the upmix plugin <http://git.io/vfuAy>`_.
This setup enables multichannel audio on the ``default`` device
@@ -113,31 +39,36 @@ Available audio output drivers are:
``oss``
OSS audio output driver
``<dsp-device>``
The following global options are supported by this audio output:
``--oss-device``
Sets the audio output device (default: ``/dev/dsp``).
``<mixer-device>``
Deprecated, use ``--audio-device``.
``--oss-mixer-device``
Sets the audio mixer device (default: ``/dev/mixer``).
``<mixer-channel>``
``--oss-mixer-channel``
Sets the audio mixer channel (default: ``pcm``). Other valid values
include **vol, pcm, line**. For a complete list of options look for
``SOUND_DEVICE_NAMES`` in ``/usr/include/linux/soundcard.h``.
``jack``
JACK (Jack Audio Connection Kit) audio output driver
JACK (Jack Audio Connection Kit) audio output driver.
``port=<name>``
The following global options are supported by this audio output:
``--jack-port=<name>``
Connects to the ports with the given name (default: physical ports).
``name=<client>``
``--jack-name=<client>``
Client name that is passed to JACK (default: ``mpv``). Useful
if you want to have certain connections established automatically.
``(no-)autostart``
``--jack-autostart=<yes|no>``
Automatically start jackd if necessary (default: disabled). Note that
this tends to be unreliable and will flood stdout with server messages.
``(no-)connect``
``--jack-connect=<yes|no>``
Automatically create connections to output ports (default: enabled).
When enabled, the maximum number of output channels will be limited to
the number of available output ports.
``std-channel-layout=waveext|any``
``--jack-std-channel-layout=<waveext|any>``
Select the standard channel layout (default: waveext). JACK itself has no
notion of channel layouts (i.e. assigning which speaker a given
channel is supposed to map to) - it just takes whatever the application
@@ -157,7 +88,9 @@ Available audio output drivers are:
Automatically redirects to ``coreaudio_exclusive`` when playing compressed
formats.
``change-physical-format=<yes|no>``
The following global options are supported by this audio output:
``--coreaudio-change-physical-format=<yes|no>``
Change the physical format to one similar to the requested audio format
(default: no). This has the advantage that multichannel audio output
will actually work. The disadvantage is that it will change the
@@ -165,11 +98,13 @@ Available audio output drivers are:
setting in the ``Audio Devices`` dialog in the ``Audio MIDI Setup``
utility. Note that this does not affect the selected speaker setup.
``exclusive``
``--coreaudio-exclusive``
Deprecated, use ``--audio-exclusive``.
Use exclusive mode access. This merely redirects to
``coreaudio_exclusive``, but should be preferred over using that AO
directly.
``coreaudio_exclusive`` (Mac OS X only)
Native Mac OS X audio output driver using direct device access and
exclusive mode (bypasses the sound server).
@@ -183,18 +118,21 @@ Available audio output drivers are:
``pulse``
PulseAudio audio output driver
``[<host>][:<output sink>]``
The following global options are supported by this audio output:
``--pulse-host=<host>``, ``--pulse-sink=<sink>``
Specify the host and optionally output sink to use. An empty <host>
string uses a local connection, "localhost" uses network transfer
(most likely not what you want).
Deprecated, use ``--audio-device``.
``buffer=<1-2000|native>``
``--pulse-buffer=<1-2000|native>``
Set the audio buffer size in milliseconds. A higher value buffers
more data, and has a lower probability of buffer underruns. A smaller
value makes the audio stream react faster, e.g. to playback speed
changes. Default: 250.
``latency-hacks=<yes|no>``
``--pulse-latency-hacks=<yes|no>``
Enable hacks to workaround PulseAudio timing bugs (default: no). If
enabled, mpv will do elaborate latency calculations on its own. If
disabled, it will use PulseAudio automatically updated timing
@@ -214,61 +152,67 @@ Available audio output drivers are:
environments, such as systems where none of the other drivers
are available.
``buflen=<length>``
The following global options are supported by this audio output:
``--sdl-buflen=<length>``
Sets the audio buffer length in seconds. Is used only as a hint by the
sound system. Playing a file with ``-v`` will show the requested and
obtained exact buffer size. A value of 0 selects the sound system
default.
``bufcnt=<count>``
``--sdl-bufcnt=<count>``
Sets the number of extra audio buffers in mpv. Usually needs not be
changed.
``null``
Produces no audio output but maintains video playback speed. Use
``--ao=null:untimed`` for benchmarking.
Produces no audio output but maintains video playback speed. You can use
``--ao=null --ao-null-untimed`` for benchmarking.
``untimed``
The following global options are supported by this audio output:
``--ao-null-untimed``
Do not simulate timing of a perfect audio device. This means audio
decoding will go as fast as possible, instead of timing it to the
system clock.
``buffer``
``--ao-null-buffer``
Simulated buffer length in seconds.
``outburst``
``--ao-null-outburst``
Simulated chunk size in samples.
``speed``
``--ao-null-speed``
Simulated audio playback speed as a multiplier. Usually, a real audio
device will not go exactly as fast as the system clock. It will deviate
just a little, and this option helps to simulate this.
``latency``
``--ao-null-latency``
Simulated device latency. This is additional to EOF.
``broken-eof``
``--ao-null-broken-eof``
Simulate broken audio drivers, which always add the fixed device
latency to the reported audio playback position.
``broken-delay``
``--ao-null-broken-delay``
Simulate broken audio drivers, which don't report latency correctly.
``channel-layouts``
``--ao-null-channel-layouts``
If not empty, this is a ``,`` separated list of channel layouts the
AO allows. This can be used to test channel layout selection.
``pcm``
Raw PCM/WAVE file writer audio output
``(no-)waveheader``
The following global options are supported by this audio output:
``--ao-pcm-waveheader=<yes|no>``
Include or do not include the WAVE header (default: included). When
not included, raw PCM will be generated.
``file=<filename>``
``--ao-pcm-file=<filename>``
Write the sound to ``<filename>`` instead of the default
``audiodump.wav``. If ``no-waveheader`` is specified, the default is
``audiodump.pcm``.
``(no-)append``
``--ao-pcm-append=<yes|no>``
Append to the file, instead of overwriting it. Always use this with the
``no-waveheader`` option - with ``waveheader`` it's broken, because
it will write a WAVE header every time the file is opened.
@@ -280,14 +224,19 @@ Available audio output drivers are:
confused with RoarAudio, which is something completely
different.
``host=<name/path>``
The following global options are supported by this audio output:
``--rsound-host=<name/path>``
Set the address of the server (default: localhost). Can be either a
network hostname for TCP connections or a Unix domain socket path
starting with '/'.
``port=<number>``
``--rsound-port=<number>``
Set the TCP port used for connecting to the server (default: 12345).
Not used if connecting to a Unix domain socket.
These options are deprecated. If anyone cares enough, their functionality
can be added back using ``--audio-device``.
``sndio``
Audio output to the OpenBSD sndio sound system
@@ -296,16 +245,24 @@ Available audio output drivers are:
(Note: only supports mono, stereo, 4.0, 5.1 and 7.1 channel
layouts.)
``device=<device>``
The following global options are supported by this audio output:
``--ao-sndio-device=<device>``
sndio device to use (default: ``$AUDIODEVICE``, resp. ``snd0``).
Deprecated, use ``--audio-device``.
``wasapi``
Audio output to the Windows Audio Session API.
``exclusive``
The following global options are supported by this audio output:
``--ao-wasapi-exclusive``
Deprecated, use ``--audio-exclusive``.
Requests exclusive, direct hardware access. By definition prevents
sound playback of any other program until mpv exits.
``device=<id>``
``--ao-wasapi-device=<id>``
Deprecated, use ``--audio-device``.
Uses the requested endpoint instead of the system's default audio
endpoint. Both an ordinal number (0,1,2,...) and the GUID
String are valid; the GUID string is guaranteed to not change
@@ -313,8 +270,3 @@ Available audio output drivers are:
Also supports searching active devices by human-readable name. If more
than one device matches the name, refuses loading it.
This option is mostly deprecated in favour of the more general
``--audio-device`` option. That said, ``--audio-device=help`` will give
a list of valid device GUIDs (prefixed with ``wasapi/``), as well as
their human readable names, which should work here.
+6 -1
View File
@@ -8,6 +8,11 @@ There is no real changelog, but you can look at the following things:
https://github.com/mpv-player/mpv/releases
* The git log, which is the "real" changelog
* The files ``client-api-changes.rst`` and ``interface-changes.rst`` in the
``DOCS`` sub directoryon the git repository, which document API and user
interface changes (the latter usually documents breaking changes only, rather
than additions).
* The file ``mplayer-changes.rst`` in the ``DOCS`` sub directory on the git
repository, which used to be in place of this section. It documents some
changes that happened since mplayer2 forked off MPlayer.
changes that happened since mplayer2 forked off MPlayer. (Not updated
anymore.)
+264 -221
View File
@@ -95,7 +95,7 @@ List of Input Commands
relative (default)
Seek relative to current position (a negative value seeks backwards).
absolute
Seek to a given time.
Seek to a given time (a negative value starts from the end of the file).
absolute-percent
Seek to a given percent position.
relative-percent
@@ -459,6 +459,8 @@ Input Commands that are Possibly Subject to Change
Remove all filters. Note that like the other sub-commands, this does
not control automatically inserted filters.
The argument is always needed. E.g. in case of ``clr`` use ``vf clr ""``.
You can assign labels to filter by prefixing them with ``@name:`` (where
``name`` is a user-chosen arbitrary identifier). Labels can be used to
refer to filters by name in all of the filter chain modification commands.
@@ -524,7 +526,7 @@ Input Commands that are Possibly Subject to Change
``disable-section "<section>"``
Disable the named input section. Undoes ``enable-section``.
``define-section "<section>" "<contents>" [default|forced]``
``define-section "<section>" "<contents>" [default|force]``
Create a named input section, or replace the contents of an already existing
input section. The ``contents`` parameter uses the same syntax as the
``input.conf`` file (except that using the section syntax in it is not
@@ -542,7 +544,7 @@ Input Commands that are Possibly Subject to Change
<default> (also used if parameter omitted)
Use a key binding defined by this section only if the user hasn't
already bound this key to a command.
<forced>
<force>
Always bind a key. (The input section that was made active most recently
wins if there are ambiguities.)
@@ -561,29 +563,20 @@ Input Commands that are Possibly Subject to Change
the resolution is reduced to that of the video's. You can read the
``osd-width`` and ``osd-height`` properties. At least with ``--vo-xv`` and
anamorphic video (such as DVD), ``osd-par`` should be read as well, and the
overlay should be aspect-compensated. (Future directions: maybe mpv should
take care of some of these things automatically, but it's hard to tell
where to draw the line.)
overlay should be aspect-compensated.
``id`` is an integer between 0 and 63 identifying the overlay element. The
ID can be used to add multiple overlay parts, update a part by using this
command with an already existing ID, or to remove a part with
``overlay-remove``. Using a previously unused ID will add a new overlay,
while reusing an ID will update it. (Future directions: there should be
something to ensure different programs wanting to create overlays don't
conflict with each others, should that ever be needed.)
while reusing an ID will update it.
``x`` and ``y`` specify the position where the OSD should be displayed.
``file`` specifies the file the raw image data is read from. It can be
either a numeric UNIX file descriptor prefixed with ``@`` (e.g. ``@4``),
or a filename. The file will be mapped into memory with ``mmap()``. Some VOs
will pass the mapped pointer directly to display APIs (e.g. opengl or
vdpau), so no actual copying is involved. Truncating the source file while
the overlay is active will crash the player. You shouldn't change the data
while the overlay is active, because the data is essentially accessed at
random points. Instead, call ``overlay-add`` again (preferably with a
different memory region to prevent tearing).
or a filename. The file will be mapped into memory with ``mmap()``,
copied, and unmapped before the command returns (changed in mpv 0.18.1).
It is also possible to pass a raw memory address for use as bitmap memory
by passing a memory address as integer prefixed with an ``&`` character.
@@ -616,15 +609,14 @@ Input Commands that are Possibly Subject to Change
(Technically, the minimum size would be ``stride * (h - 1) + w * 4``, but
for simplicity, the player will access all ``stride * h`` bytes.)
.. admonition:: Warning
.. note::
When updating the overlay, you should prepare a second shared memory
region (e.g. make use of the offset parameter) and add this as overlay,
instead of reusing the same memory every time. Otherwise, you might
get the equivalent of tearing, when your application and mpv write/read
the buffer at the same time. Also, keep in mind that mpv might access
an overlay's memory at random times whenever it feels the need to do
so, for example when redrawing the screen.
Before mpv 0.18.1, you had to do manual "double buffering" when updating
an overlay by replacing it with a different memory buffer. Since mpv
0.18.1, the memory is simply copied and doesn't reference any of the
memory indicated by the command's arguments after the commend returns.
If you want to use this command before mpv 0.18.1, reads the old docs
to see how to handle this correctly.
``overlay-remove <id>``
Remove an overlay added with ``overlay-add`` and the same ID. Does nothing
@@ -634,10 +626,10 @@ Input Commands that are Possibly Subject to Change
Send a message to all clients, and pass it the following list of arguments.
What this message means, how many arguments it takes, and what the arguments
mean is fully up to the receiver and the sender. Every client receives the
message, so be careful about name clashes (or use ``script_message_to``).
message, so be careful about name clashes (or use ``script-message-to``).
``script-message-to "<target>" "<arg1>" "<arg2>" ...``
Same as ``script_message``, but send it only to the client named
Same as ``script-message``, but send it only to the client named
``<target>``. Each client (scripts etc.) has a unique name. For example,
Lua scripts can get their name via ``mp.get_script_name()``.
@@ -648,11 +640,11 @@ Input Commands that are Possibly Subject to Change
The argument is the name of the binding.
It can optionally be prefixed with the name of the script, using ``/`` as
separator, e.g. ``script_binding scriptname/bindingname``.
separator, e.g. ``script-binding scriptname/bindingname``.
For completeness, here is how this command works internally. The details
could change any time. On any matching key event, ``script_message_to``
or ``script_message`` is called (depending on whether the script name is
could change any time. On any matching key event, ``script-message-to``
or ``script-message`` is called (depending on whether the script name is
included), with the following arguments:
1. The string ``key-binding``.
@@ -673,13 +665,6 @@ Input Commands that are Possibly Subject to Change
(the ``ab-loop-a`` property); the second the ``B`` point, and the third
will clear both points.
``vo-cmdline "<args>"``
Reset the sub-option of the current VO. Currently works with ``opengl``
(including ``opengl-hq``). The argument is the sub-option string usually
passed to the VO on the command line. Not all sub-options can be set, but
those which can will be reset even if they don't appear in the argument.
This command might be changed or removed in the future.
``drop-buffers``
Drop audio/video/demuxer buffers, and restart from fresh. Might help with
unseekable streams that are going out of sync.
@@ -706,6 +691,17 @@ Input Commands that are Possibly Subject to Change
``af-command "<label>" "<cmd>" "<args>"``
Same as ``vf-command``, but for audio filters.
``apply-profile "<name>"``
Apply the contents of a named profile. This is like using ``profile=name``
in a config file, except you can map it to a key binding to change it at
runtime.
There is no such thing as "unapplying" a profile - applying a profile
merely sets all option values listed within the profile.
``load-script "<path>"``
Load a script, similar to the ``--script`` option.
Undocumented commands: ``tv-last-channel`` (TV/DVB only),
``ao-reload`` (experimental/internal).
@@ -817,7 +813,7 @@ Input sections group a set of bindings, and enable or disable them at once.
In ``input.conf``, each key binding is assigned to an input section, rather
than actually having explicit text sections.
See also: ``enable_section`` and ``disable_section`` commands.
See also: ``enable-section`` and ``disable-section`` commands.
Predefined bindings:
@@ -846,20 +842,12 @@ an option at runtime.
Property list
-------------
``osd-level`` (RW)
See ``--osd-level``.
.. note::
``osd-scale`` (RW)
OSD font size multiplier, see ``--osd-scale``.
``loop`` (RW)
See ``--loop``.
``loop-file`` (RW)
See ``--loop-file`` (uses ``yes``/``no``).
``speed`` (RW)
See ``--speed``.
Most options can be set as runtime via properties as well. Just remove the
leading ``--`` from the option name. These are not documented. Only
properties which do not exist as option with the same name, or which have
very different behavior from the options are documented below.
``audio-speed-correction``, ``video-speed-correction``
Factor multiplied with ``speed`` at which the player attempts to play the
@@ -877,6 +865,12 @@ Property list
looks better for display purposes. Use the ``path`` property to get an
unmodified filename.)
This has a sub-property:
``filename/no-ext``
Like the ``filename`` property, but if the text contains a ``.``, strip
all text after the last ``.``. Usually this removes the file extension.
``file-size``
Length in bytes of the source file/stream. (This is the same as
``${stream-end}``. For ordered chapters and such, the
@@ -913,9 +907,11 @@ Property list
list of format names, e.g. mp4 is ``mov,mp4,m4a,3gp,3g2,mj2`` (the list
may grow in the future for any format).
``demuxer``
``current-demuxer``
Name of the current demuxer. (This is useless.)
(Renamed from ``demuxer``.)
``stream-path``
Filename (full path) of the stream layer filename. (This is probably
useless. It looks like this can be different from ``path`` only when
@@ -991,6 +987,12 @@ Property list
Remaining length of the file in seconds. Note that the file duration is not
always exactly known, so this is an estimate.
``audio-pts`` (R)
Current audio playback position in current file in seconds. Unlike time-pos,
this updates more often than once per frame. For audio-only files, it is
mostly equivalent to time-pos, while for video-only files this property is
not available.
``playtime-remaining``
``time-remaining`` scaled by the current ``speed``.
@@ -1080,10 +1082,6 @@ Property list
"title" MPV_FORMAT_STRING
"default" MPV_FORMAT_FLAG
``ab-loop-a``, ``ab-loop-b`` (RW)
Set/get A-B loop points. See corresponding options and ``ab_loop`` command.
The special value ``no`` on either of these properties disables looping.
``angle`` (RW)
Current DVD angle.
@@ -1156,13 +1154,12 @@ Property list
``af-metadata/<filter-label>``
Equivalent to ``vf-metadata/<filter-label>``, but for audio filters.
``pause`` (RW)
Pause status. This is usually ``yes`` or ``no``. See ``--pause``.
``idle``
``idle-active``
Return ``yes`` if no file is loaded, but the player is staying around
because of the ``--idle`` option.
(Renamed from ``idle``.)
``core-idle``
Return ``yes`` if the playback core is paused, otherwise ``no``. This can
be different ``pause`` in special situations, such as when the player
@@ -1238,36 +1235,22 @@ Property list
is loaded, or when switching ordered chapter segments. This is because
the same underlying code is used for seeking and resyncing.)
``hr-seek`` (RW)
See ``--hr-seek``.
``mixer-active``
Return ``yes`` if the audio mixer is active, ``no`` otherwise. This has
implications for ``--softvol=no`` mode: if the mixer is inactive, changing
``volume`` doesn't actually change anything on the system mixer. If the
``--volume`` or ``--mute`` option are used, these might not be applied
properly until the mixer becomes active either. (The options, if set, will
just overwrite the mixer state at audio initialization.)
Return ``yes`` if the audio mixer is active, ``no`` otherwise.
While the behavior with ``mixer-active==yes`` is relatively well-defined,
the ``no`` case will provide possibly wrong or insignificant values.
This option is relatively useless. Before mpv 0.18.1, it could be used to
infer behavior of the ``volume`` property.
Note that an active mixer does not necessarily imply active audio output,
although this is implied in the current implementation.
``ao-volume`` (RW)
System volume. This property is available only if mpv audio output is
currently active, and only if the underlying implementation supports volume
control. What this option does depends on the API. For example, on ALSA
this usually changes system-wide audio, while with PulseAudio this controls
per-application volume.
``volume`` (RW)
Current volume (see ``--volume`` for details). Also see ``mixer-active``
property.
``volume-max``
Current maximum value the volume property can be set to. (This may depend
on the ``--softvol-max`` option.)
``mute`` (RW)
Current mute status (``yes``/``no``). Also see ``mixer-active`` property.
``audio-delay`` (RW)
See ``--audio-delay``.
``ao-mute`` (RW)
Similar to ``ao-volume``, but controls the mute state. May be unimplemented
even if ``ao-volume`` works.
``audio-codec``
Audio codec selected for decoding.
@@ -1316,26 +1299,6 @@ Property list
Same as ``audio-params``, but the format of the data written to the audio
API.
``aid`` (RW)
Current audio track (similar to ``--aid``).
``audio`` (RW)
Alias for ``aid``.
``balance`` (RW)
Audio channel balance. (The implementation of this feature is rather odd.
It doesn't change the volumes of each channel, but instead sets up a pan
matrix to mix the left and right channels.)
``fullscreen`` (RW)
See ``--fullscreen``.
``deinterlace`` (RW)
See ``--deinterlace``.
``field-dominance`` (RW)
See ``--field-dominance``
``colormatrix`` (R)
Redirects to ``video-params/colormatrix``. This parameter (as well as
similar ones) can be overridden with the ``format`` video filter.
@@ -1343,39 +1306,9 @@ Property list
``colormatrix-input-range`` (R)
See ``colormatrix``.
``video-output-levels`` (RW)
See ``--video-output-levels``,
``colormatrix-primaries`` (R)
See ``colormatrix``.
``ontop`` (RW)
See ``--ontop``.
``border`` (RW)
See ``--border``.
``on-all-workspaces`` (RW)
See ``--on-all-workspaces``. Unsetting may not work on all WMs.
``framedrop`` (RW)
See ``--framedrop``.
``gamma`` (RW)
See ``--gamma``.
``brightness`` (RW)
See ``--brightness``.
``contrast`` (RW)
See ``--contrast``.
``saturation`` (RW)
See ``--saturation``.
``hue`` (RW)
See ``--hue``.
``hwdec`` (RW)
Reflects the ``--hwdec`` option.
@@ -1385,24 +1318,28 @@ Property list
properties to see whether this was successful.
Unlike in mpv 0.9.x and before, this does not return the currently active
hardware decoder.
hardware decoder. Since mpv 0.18.0, ``hwdec-current`` is available for
this purpose.
``hwdec-active``
Return ``yes`` or ``no``, depending on whether any type of hardware decoding
is actually in use.
``hwdec-current``
Return the current hardware decoding in use. If decoding is active, return
one of the values used by the ``hwdec`` option/property. ``no`` indicates
software decoding. If no decoder is loaded, the property is unavailable.
``hwdec-detected``
If software decoding is active, this returns the hardware decoder in use.
Otherwise, it returns either ``no``, or if applicable, the currently loaded
hardware decoding API. This is known only once the VO has opened (and
possibly later). With some VOs (like ``opengl``), this is never known in
advance, but only when the decoder attempted to create the hw decoder
successfully. Also, hw decoders with ``-copy`` suffix will return ``no``
while no video is being decoded. All this reflects how detecting hw decoders
are detected and used internally in mpv.
``hwdec-interop``
This returns the currently loaded hardware decoding/output interop driver.
This is known only once the VO has opened (and possibly later). With some
VOs (like ``opengl``), this might be never known in advance, but only when
the decoder attempted to create the hw decoder successfully. (Using
``--hwdec-preload`` can load it eagerly.) If there are multiple drivers
loaded, they will be separated by ``,``.
``panscan`` (RW)
See ``--panscan``.
If no VO is active or no interop driver is known, this property is
unavailable.
This does not necessarily use the same values as ``hwdec``. There can be
multiple interop drivers for the same hardware decoder, depending on
platform and VO.
``video-format``
Video format as string.
@@ -1457,6 +1394,12 @@ Property list
``video-params/gamma``
The gamma function in use as string. (Exact values subject to change.)
``video-params/nom-peak``
The video encoding's nominal peak brightness as float.
``video-params/sig-peak``
The video file's tagged signal peak as float.
``video-params/chroma-location``
Chroma location as string. (Exact values subject to change.)
@@ -1483,6 +1426,9 @@ Property list
"colormatrix" MPV_FORMAT_STRING
"colorlevels" MPV_FORMAT_STRING
"primaries" MPV_FORMAT_STRING
"gamma" MPV_FORMAT_STRING
"nom-peak" MPV_FORMAT_DOUBLE
"sig-peak" MPV_FORMAT_DOUBLE
"chroma-location" MPV_FORMAT_STRING
"rotate" MPV_FORMAT_INT64
"stereo-in" MPV_FORMAT_STRING
@@ -1495,6 +1441,9 @@ Property list
These have the same values as ``video-out-params/dw`` and
``video-out-params/dh``.
``video-dec-params``
Exactly like ``video-params``, but no overrides applied.
``video-out-params``
Same as ``video-params``, but after video filters have been applied. If
there are no video filters in use, this will contain the same values as
@@ -1517,10 +1466,12 @@ Property list
``video-frame-info/tff``
``video-frame-info/repeat``
``fps``
``container-fps``
Container FPS. This can easily contain bogus values. For videos that use
modern container formats or video codecs, this will often be incorrect.
(Renamed from ``fps``.)
``estimated-vf-fps``
Estimated/measured FPS of the video filter chain output. (If no filters
are used, this corresponds to decoder output.) This uses the average of
@@ -1541,7 +1492,10 @@ Property list
``display-names``
Names of the displays that the mpv window covers. On X11, these
are the xrandr names (LVDS1, HDMI1, DP1, VGA1, etc.).
are the xrandr names (LVDS1, HDMI1, DP1, VGA1, etc.). On Windows, these
are the GDI names (\\.\DISPLAY1, \\.\DISPLAY2, etc.) and the first display
in the list will be the one that Windows considers associated with the
window (as determined by the MonitorFromWindow API.)
``display-fps`` (RW)
The refresh rate of the current display. Currently, this is the lowest FPS
@@ -1561,79 +1515,35 @@ Property list
``video-aspect`` (RW)
Video aspect, see ``--video-aspect``.
If video is active, this reports the effective aspect value, instead of
the value of the ``--video-aspect`` option.
``osd-width``, ``osd-height``
Last known OSD width (can be 0). This is needed if you want to use the
``overlay_add`` command. It gives you the actual OSD size, which can be
``overlay-add`` command. It gives you the actual OSD size, which can be
different from the window size in some cases.
``osd-par``
Last known OSD display pixel aspect (can be 0).
``vid`` (RW)
Current video track (similar to ``--vid``).
``video`` (RW)
Alias for ``vid``.
``video-align-x``, ``video-align-y`` (RW)
See ``--video-align-x`` and ``--video-align-y``.
``video-pan-x``, ``video-pan-y`` (RW)
See ``--video-pan-x`` and ``--video-pan-y``.
``video-zoom`` (RW)
See ``--video-zoom``.
``video-unscaled`` (W)
See ``--video-unscaled``.
``program`` (W)
Switch TS program (write-only).
``dvb-channel`` (W)
Pair of integers: card,channel of current DVB stream.
Can be switched to switch to another channel on the same card.
Can be switched to switch to another channel on the same card.
``dvb-channel-name`` (RW)
Name of current DVB program.
On write, a channel-switch to the named channel on the same
card is performed. Can also be used for channel switching.
card is performed. Can also be used for channel switching.
``sid`` (RW)
Current subtitle track (similar to ``--sid``).
``sub-text``
Return the current subtitle text. Formatting is stripped. If a subtitle
is selected, but no text is currently visible, or the subtitle is not
text-based (i.e. DVD/BD subtitles), an empty string is returned.
``secondary-sid`` (RW)
Secondary subtitle track (see ``--secondary-sid``).
``sub`` (RW)
Alias for ``sid``.
``sub-delay`` (RW)
See ``--sub-delay``.
``sub-pos`` (RW)
See ``--sub-pos``.
``sub-visibility`` (RW)
See ``--sub-visibility``.
``sub-forced-only`` (RW)
See ``--sub-forced-only``.
``sub-scale`` (RW)
Subtitle font size multiplier.
``ass-force-margins`` (RW)
See ``--ass-force-margins``.
``sub-use-margins`` (RW)
See ``--sub-use-margins``.
``ass-vsfilter-aspect-compat`` (RW)
See ``--ass-vsfilter-aspect-compat``.
``ass-style-override`` (RW)
See ``--ass-style-override``.
This property is experimental and might be removed in the future.
``stream-capture`` (RW)
A filename, see ``--stream-capture``. Setting this will start capture using
@@ -1646,6 +1556,9 @@ Property list
Current position on playlist. The first entry is on position 0. Writing
to the property will restart playback at the written entry.
``playlist-pos-1`` (RW)
Same as ``playlist-pos``, but 1-based.
``playlist-count``
Number of total playlist entries.
@@ -1771,6 +1684,16 @@ Property list
``track-list/N/audio-channels`` (deprecated)
Deprecated alias for ``track-list/N/demux-channel-count``.
``track-list/N/replaygain-track-peak``, ``track-list/N/replaygain-track-gain``
Per-track replaygain values. Only available for audio tracks with
corresponding information stored in the source file.
``track-list/N/replaygain-album-peak``, ``track-list/N/replaygain-album-gain``
Per-album replaygain values. If the file has per-track but no per-album
information, the per-album values will be copied from the per-track
values currently. It's possible that future mpv versions will make
these properties unavailable instead in this case.
When querying the property with the client API using ``MPV_FORMAT_NODE``,
or with Lua ``mp.get_property_native``, this will return a mpv_node with
the following contents:
@@ -1787,9 +1710,11 @@ Property list
"albumart" MPV_FORMAT_FLAG
"default" MPV_FORMAT_FLAG
"forced" MPV_FORMAT_FLAG
"selected" MPV_FORMAT_FLAG
"external" MPV_FORMAT_FLAG
"external-filename" MPV_FORMAT_STRING
"codec" MPV_FORMAT_STRING
"ff-index" MPV_FORMAT_INT64
"decoder-desc" MPV_FORMAT_STRING
"demux-w" MPV_FORMAT_INT64
"demux-h" MPV_FORMAT_INT64
@@ -1798,6 +1723,10 @@ Property list
"demux-samplerate" MPV_FORMAT_INT64
"demux-fps" MPV_FORMAT_DOUBLE
"audio-channels" MPV_FORMAT_INT64
"replaygain-track-peak" MPV_FORMAT_DOUBLE
"replaygain-track-gain" MPV_FORMAT_DOUBLE
"replaygain-album-peak" MPV_FORMAT_DOUBLE
"replaygain-album-gain" MPV_FORMAT_DOUBLE
``chapter-list``
List of chapters, current entry marked. Currently, the raw property value
@@ -1826,11 +1755,8 @@ Property list
"title" MPV_FORMAT_STRING
"time" MPV_FORMAT_DOUBLE
``af`` (RW)
See ``--af`` and the ``af`` command.
``vf`` (RW)
See ``--vf`` and the ``vf`` command.
``af``, ``vf`` (RW)
See ``--vf``/``--af`` and the ``vf``/``af`` command.
When querying the property with the client API using ``MPV_FORMAT_NODE``,
or with Lua ``mp.get_property_native``, this will return a mpv_node with
@@ -1848,12 +1774,6 @@ Property list
It's also possible to write the property using this format.
``video-rotate`` (RW)
See ``--video-rotate`` option.
``video-stereo-mode`` (RW)
See ``--video-stereo-mode`` option.
``seekable``
Return whether it's generally possible to seek in the current file.
@@ -1904,6 +1824,44 @@ Property list
whether the video window is visible. If the ``--force-window`` option is
used, this is usually always returns ``yes``.
``vo-performance``
Some video output performance metrics. Not implemented by all VOs. This has
a number of sup-properties, of the form ``vo-performance/<metric>-<value>``,
all of them in milliseconds.
``<metric>`` refers to one of:
``upload``
Time needed to make the frame available to the GPU (if necessary).
``render``
Time needed to perform all necessary video postprocessing and rendering
passes (if necessary).
``present``
Time needed to present a rendered frame on-screen.
When a step is unnecessary or skipped, it will have the value 0.
``<value>`` refers to one of:
``last``
Last measured value.
``avg``
Average over a fixed number of past samples. (The exact timeframe
varies, but it should generally be a handful of seconds)
``peak``
The peak (highest value) within this averaging range.
When querying the property with the client API using ``MPV_FORMAT_NODE``,
or with Lua ``mp.get_property_native``, this will return a mpv_node with
the following contents:
::
MPV_FORMAT_NODE_MAP
"<metric>-<value>" MPV_FORMAT_INT64
(One entry for each ``<metric>`` and ``<value>`` combination)
``video-bitrate``, ``audio-bitrate``, ``sub-bitrate``
Bitrate values calculated on the packet level. This works by dividing the
bit size of all packets between two keyframes by their presentation
@@ -1954,8 +1912,9 @@ Property list
The ``name`` is what is to be passed to the ``--audio-device`` option (and
often a rather cryptic audio API-specific ID), while ``description`` is
human readable free form text. The description is an empty string if none
was received.
human readable free form text. The description is set to the device name
(minus mpv-specific ``<driver>/`` prefix) if no description is available
or the description would have been an empty string.
The special entry with the name set to ``auto`` selects the default audio
output driver and the default device.
@@ -2055,6 +2014,10 @@ Property list
require reloading the file for changes to take effect. If there is an
equivalent property, prefer setting the property instead.
There shouldn't be any reason to access ``options/<name>`` instead of
``<name>``, except in situations in which the properties have different
behavior or conflicting semantics.
``file-local-options/<name>``
Similar to ``options/<name>``, but when setting an option through this
property, the option is reset to its old value once the current file has
@@ -2063,7 +2026,7 @@ Property list
(Note that if an option is marked as file-local, even ``options/`` will
access the local value, and the ``old`` value, which will be restored on
end of playback, can not be read or written until end of playback.)
end of playback, cannot be read or written until end of playback.)
``option-info/<name>``
Additional per-option information.
@@ -2108,6 +2071,86 @@ Property list
``property-list``
Return the list of top-level properties.
``profile-list``
Return the list of profiles and their contents. This is highly
implementation-specific, and may change any time. Currently, it returns
an array of options for each profile. Each option has a name and a value,
with the value currently always being a string. Note that the options array
is not a map, as order matters and duplicate entries are possible. Recursive
profiles are not expanded, and show up as special ``profile`` options.
Inconsistencies between options and properties
----------------------------------------------
You can access (almost) all options as properties, though there are some
caveats with some properties (due to historical reasons):
``vid``, ``aid``, ``sid``
While playback is active, you can set existing tracks only. (The option
allows setting any track ID, and which tracks to enable is chosen at
loading time.)
Option changes at runtime are affected by this as well.
``deinterlace``
While video is active, this behaves differently from the option. It will
never return the ``auto`` value (but the state as observed by the video
chain). If you set ``auto``, the property will set this as the option value,
and will return the actual video chain state as observed instead of auto.
``video-aspect``
While video is active, always returns the effective aspect ratio. Setting
a special value (like ``no``, values ``<= 0``) will make the property
set this as option, and return whatever actual aspect was derived from the
option setting.
``brightness`` (and other color options)
If ``--vo=xv`` is used, these properties may return the adapter's current
values instead of the option values.
``display-fps``
If a VO is created, this will return either the actual display FPS, or
an invalid value, instead of the option value.
``vf``, ``af``
If you set the properties during playback, and the filter chain fails to
reinitialize, the new value will be rejected. Setting the option or
setting the property outside of playback will always succeed/fail in the
same way. Also, there are no ``vf-add`` etc. properties, but you can use
the ``vf``/``af`` group of commands to achieve the same.
Option changes at runtime are affected by this as well.
``edition``
While a file is loaded, the property will always return the effective
edition, and setting the ``auto`` value will show somewhat strange behavior
(the property eventually switching to whatever is the default edition).
``playlist``
The property is read-only and returns the current internal playlist. The
option is for loading playlist during command line parsing. For client API
uses, you should use the ``loadlist`` command instead.
``window-scale``
Might verify the set value when setting while a window is created.
``audio-file``, ``sub-file``, ``external-file``
These options/properties are actually lists of filenames. To make the
command-line interface easier, each ``--audio-file=...`` option appends
the full string to the internal list. However, when used as properties,
every time you set the property as a string the internal list will be
replaced with a single entry containing the string you set. ``,`` or other
separators are never used. You have to use ``MPV_FORMAT_NODE_ARRAY`` (or
corresponding API, e.g. ``mp.set_property_native()`` with a table in Lua)
to set multiple entries.
Strictly speaking, option access via API (e.g. ``mpv_set_option_string()``)
has the same problem, and it's only a difference between CLI/API.
``playlist-pos``, ``chapter``
These properties behave different from the deprecated options with the same
names.
Property Expansion
------------------
+2 -12
View File
@@ -41,7 +41,7 @@ It's also possible to send input.conf style text-only commands:
::
> echo 'show_text ${playback-time}' | socat - /tmp/mpvsocket
> echo 'show-text ${playback-time}' | socat - /tmp/mpvsocket
But you won't get a reply over the socket. (This particular command shows the
playback time on the player's OSD.)
@@ -65,7 +65,7 @@ You can send commands from a command prompt:
::
echo show_text ${playback-time} >\\.\pipe\mpvsocket
echo show-text ${playback-time} >\\.\pipe\mpvsocket
To be able to simultaneously read and write from the IPC pipe, like on Linux,
it's necessary to write an external program that uses overlapped file I/O (or
@@ -241,16 +241,6 @@ extra commands can also be used as part of the protocol:
By default, most events are enabled, and there is not much use for this
command.
``suspend``
Suspend the mpv main loop. There is a long-winded explanation of this in
the C API function ``mpv_suspend()``. In short, this prevents the player
from displaying the next video frame, so that you don't get blocked when
trying to access the player.
``resume``
Undo one ``suspend`` call. ``suspend`` increments an internal counter, and
``resume`` decrements it. When 0 is reached, the player is actually resumed.
``get_version``
Returns the client API version the C API of the remote mpv instance
provides.
+16
View File
@@ -0,0 +1,16 @@
EMBEDDING INTO OTHER PROGRAMS (LIBMPV)
======================================
mpv can be embedded into other programs as video/audio playback backend. The
recommended way to do so is using libmpv. See ``libmpv/client.h`` in the mpv
source code repository. This provides a C API. Bindings for other languages
might be available (see wiki).
Since libmpv merely allows access to underlying mechanisms that can control
mpv, further documentation is spread over a few places:
- https://github.com/mpv-player/mpv/blob/master/libmpv/client.h
- http://mpv.io/manual/master/#options
- http://mpv.io/manual/master/#list-of-input-commands
- http://mpv.io/manual/master/#properties
- https://github.com/mpv-player/mpv-examples/tree/master/libmpv
+35 -21
View File
@@ -43,9 +43,8 @@ timers added with ``mp.add_timeout`` or similar.
When the player quits, all scripts will be asked to terminate. This happens via
a ``shutdown`` event, which by default will make the event loop return. If your
script got into an endless loop, mpv will probably behave fine during playback
(unless the player is suspended, see ``mp.suspend``), but it won't terminate
when quitting, because it's waiting on your script.
script got into an endless loop, mpv will probably behave fine during playback,
but it won't terminate when quitting, because it's waiting on your script.
Internally, the C code will call the Lua function ``mp_event_loop`` after
loading a Lua script. This function is normally defined by the default prelude
@@ -175,7 +174,7 @@ The ``mp`` module is preloaded, although it can be loaded manually with
Similar to ``mp.set_property``, but set the given property using its native
type.
Since there are several data types which can not represented natively in
Since there are several data types which cannot represented natively in
Lua, this might not always work as expected. For example, while the Lua
wrapper can do some guesswork to decide whether a Lua table is an array
or a map, this would fail with empty tables. Also, there are not many
@@ -350,6 +349,10 @@ The ``mp`` module is preloaded, although it can be loaded manually with
with ``add_timeout()``), this starts the timer from the beginning,
using the initially configured timeout.
``is_enabled()``
Whether the timer is currently enabled or was previously disabled
(e.g. by ``stop()`` or ``kill()``).
``timeout`` (RW)
This field contains the current timeout period. This value is not
updated as time progresses. It's only used to calculate when the
@@ -408,21 +411,16 @@ These also live in the ``mp`` module, but are documented separately as they
are useful only in special situations.
``mp.suspend()``
Suspend the mpv main loop. There is a long-winded explanation of this in
the C API function ``mpv_suspend()``. In short, this prevents the player
from displaying the next video frame, so that you don't get blocked when
trying to access the player.
Before mpv 0.17.0, this was automatically called by the event handler.
This function has been deprecated in mpv 0.21.0 and does nothing starting
with mpv 0.23.0 (no replacement).
``mp.resume()``
Undo one ``mp.suspend()`` call. ``mp.suspend()`` increments an internal
counter, and ``mp.resume()`` decrements it. When 0 is reached, the player
is actually resumed.
This function has been deprecated in mpv 0.21.0 and does nothing starting
with mpv 0.23.0 (no replacement).
``mp.resume_all()``
This resets the internal suspend counter and resumes the player. (It's
like calling ``mp.resume()`` until the player is actually resumed.)
This function has been deprecated in mpv 0.21.0 and does nothing starting
with mpv 0.23.0 (no replacement).
``mp.get_wakeup_pipe()``
Calls ``mpv_get_wakeup_pipe()`` and returns the read end of the wakeup
@@ -446,6 +444,13 @@ are useful only in special situations.
``mp.get_wakeup_pipe()`` if you're interested in properly working
notification of new events and working timers.
``mp.register_idle(fn)``
Register an event loop idle handler. Idle handlers are called before the
script goes to sleep after handling all new events. This can be used for
example to delay processing of property change events: if you're observing
multiple properties at once, you might not want to act on each property
change, but only when all change notifications have been received.
``mp.enable_messages(level)``
Set the minimum log level of which mpv message output to receive. These
messages are normally printed to the terminal. By calling this function,
@@ -454,9 +459,9 @@ are useful only in special situations.
The level is a string, see ``msg.log`` for allowed log levels.
``mp.register_script_message(name, fn)``
This is a helper to dispatch ``script_message`` or ``script_message_to``
invocations to Lua functions. ``fn`` is called if ``script_message`` or
``script_message_to`` (with this script as destination) is run
This is a helper to dispatch ``script-message`` or ``script-message-to``
invocations to Lua functions. ``fn`` is called if ``script-message`` or
``script-message-to`` (with this script as destination) is run
with ``name`` as first parameter. The other parameters are passed to ``fn``.
If a message with the given name is already registered, it's overwritten.
@@ -537,8 +542,8 @@ Example command-line::
--script-opts=myscript-optionA=TEST,myscript-optionB=0,myscript-optionC=yes
mp.utils options
----------------
mp.utils functions
------------------
This built-in module provides generic helper functions for Lua, and have
strictly speaking nothing to do with mpv or video/audio playback. They are
@@ -629,7 +634,16 @@ strictly part of the guaranteed API.
Set to ``true`` if the process has been killed by mpv as a result
of ``cancellable`` being set to ``true``.
In all cases, ``mp.resume_all()`` is implicitly called.
``utils.subprocess_detached(t)``
Runs an external process and detaches it from mpv's control.
The parameter ``t`` is a table. The function reads the following entries:
``args``
Array of strings of the same semantics as the ``args`` used in the
``subprocess`` function.
The function returns ``nil``.
``utils.parse_json(str [, trail])``
Parses the given string argument as JSON, and returns it as a Lua table. On
+89 -45
View File
@@ -9,6 +9,8 @@ a media player
:Manual section: 1
:Manual group: multimedia
.. contents:: Table of Contents
SYNOPSIS
========
@@ -143,11 +145,11 @@ Ctrl + and Ctrl -
u
Switch between applying no style overrides to SSA/ASS subtitles, and
overriding them almost completely with the normal subtitle style. See
``--ass-style-override`` for more info.
``--sub-ass-style-override`` for more info.
V
Toggle subtitle VSFilter aspect compatibility mode. See
``--ass-vsfilter-aspect-compat`` for more info.
``--sub-ass-vsfilter-aspect-compat`` for more info.
r and t
Move subtitles up/down.
@@ -208,9 +210,6 @@ Alt+2 (and command+2 on OSX)
command + f (OSX only)
Toggle fullscreen (see also ``--fs``).
command + [ and command + ] (OSX only)
Set video window alpha.
(The following keys are valid if you have a keyboard with multimedia keys.)
PAUSE
@@ -244,6 +243,16 @@ button 5 and button 6
USAGE
=====
Command line arguments starting with ``-`` are interpreted as options,
everything else as filenames or URLs. All options except *flag* options (or
choice options which include ``yes``) require a parameter in the form
``--option=value``.
One exception is the lone ``-`` (without anything else), which means media data
will be read from stdin. Also, ``--`` (without anything else) will make the
player interpret all following arguments as filenames, even if they start with
``-``. (To play a file named ``-``, you need to use ``./-``.)
Every *flag* option has a *no-flag* counterpart, e.g. the opposite of the
``--fs`` option is ``--no-fs``. ``--fs=yes`` is same as ``--fs``, ``--fs=no``
is the same as ``--no-fs``.
@@ -251,6 +260,24 @@ is the same as ``--no-fs``.
If an option is marked as *(XXX only)*, it will only work in combination with
the *XXX* option or if *XXX* is compiled in.
Legacy option syntax
--------------------
The ``--option=value`` syntax is not strictly enforced, and the alternative
legacy syntax ``-option value`` and ``--option value`` will also work. This is
mostly for compatibility with MPlayer. Using these should be avoided. Their
semantics can change any time in the future.
For example, the alternative syntax will consider an argument following the
option a filename. ``mpv -fs no`` will attempt to play a file named ``no``,
because ``--fs`` is a flag option that requires no parameter. If an option
changes and its parameter becomes optional, then a command line using the
alternative syntax will break.
Currently, the parser makes no difference whether an option starts with ``--``
or a single ``-``. This might also change in the future, and ``--option value``
might always interpret ``value`` as filename in order to reduce ambiguities.
Escaping spaces and other special characters
--------------------------------------------
@@ -268,15 +295,16 @@ command line.
The suboption parser can quote strings with ``"`` and ``[...]``.
Additionally, there is a special form of quoting with ``%n%`` described below.
For example, the ``opengl`` VO can take multiple options:
For example, assume the hypothetical ``foo`` filter can take multiple options:
``mpv test.mkv --vo=opengl:scale=lanczos:icc-profile=file.icc,xv``
``mpv test.mkv --vf=foo:option1=value1:option2:option3=value3,bar``
This passes ``scale=lanczos`` and ``icc-profile=file.icc`` to ``opengl``,
and also specifies ``xv`` as fallback VO. If the icc-profile path contains
spaces or characters like ``,`` or ``:``, you need to quote them:
This passes ``option1`` and ``option3`` to the ``foo`` filter, with ``option2``
as flag (implicitly ``option2=yes``), and adds a ``bar`` filter after that. If
an option contains spaces or characters like ``,`` or ``:``, you need to quote
them:
``mpv '--vo=opengl:icc-profile="file with spaces.icc",xv'``
``mpv '--vf=foo:option1="option value with spaces",bar'``
Shells may actually strip some quotes from the string passed to the commandline,
so the example quotes the string twice, ensuring that mpv receives the ``"``
@@ -297,11 +325,11 @@ It is started with ``%`` and has the following format::
.. admonition:: Examples
``mpv --ao=pcm:file=%10%C:test.wav test.avi``
``mpv '--vf=foo:option1=%11%quoted text' test.avi``
Or in a script:
``mpv --ao=pcm:file=%`expr length "$NAME"`%"$NAME" test.avi``
``mpv --vf=foo:option1=%`expr length "$NAME"`%"$NAME" test.avi``
Suboptions passed to the client API are also subject to escaping. Using
``mpv_set_option_string()`` is exactly like passing ``--name=data`` to the
@@ -309,8 +337,7 @@ command line (but without shell processing of the string). Some options
support passing values in a more structured way instead of flat strings, and
can avoid the suboption parsing mess. For example, ``--vf`` supports
``MPV_FORMAT_NODE``, which lets you pass suboptions as a nested data structure
of maps and arrays. (``--vo`` supports this in the same way, although this
fact is undocumented.)
of maps and arrays.
Paths
-----
@@ -320,11 +347,22 @@ example, paths starting with ``-`` will be interpreted as options. Likewise,
if a path contains the sequence ``://``, the string before that might be
interpreted as protocol prefix, even though ``://`` can be part of a legal
UNIX path. To avoid problems with arbitrary paths, you should be sure that
absolute paths passed to mpv start with ``/``, and relative paths with ``./``.
absolute paths passed to mpv start with ``/``, and prefix relative paths with
``./``.
Using the ``file://`` pseudo-protocol is discouraged, because it involves
strange URL unescaping rules.
The name ``-`` itself is interpreted as stdin, and will cause mpv to disable
console controls. (Which makes it suitable for playing data piped to stdin.)
The special argument ``--`` can be used to stop mpv from interpreting the
following arguments as options.
When using the client API, you should strictly avoid using ``mpv_command_string``
for invoking the ``loadfile`` command, and instead prefer e.g. ``mpv_command``
to avoid the need for filename escaping.
For paths passed to suboptions, the situation is further complicated by the
need to escape special characters. To work this around, the path can be
additionally wrapped in the fixed-length syntax, e.g. ``%n%string_of_length_n``
@@ -420,7 +458,7 @@ tree and play the longest title.
a bitmap video stream which can be superimposed over the main
movie. mpv's subtitle styling and positioning options and keyboard
shortcuts generally do not work with image-based subtitles.
Exceptions include options like ``--stretch-dvd-subs`` and
Exceptions include options like ``--stretch-dvd-subs`` and
``--stretch-image-subs-to-screen``.
@@ -517,7 +555,8 @@ profile name ``default`` to continue with normal options.
[slow]
profile-desc="some profile name"
vo=opengl:scale=ewa_lanczos:scale-radius=16
# reference a builtin profile
profile=opengl-hq
[fast]
vo=vdpau
@@ -538,10 +577,6 @@ Some profiles are loaded automatically. The following example demonstrates this:
::
[vo.vdpau]
# Use hardware decoding
hwdec=vdpau
[protocol.dvd]
profile-desc="profile for dvd:// streams"
alang=en
@@ -550,11 +585,7 @@ Some profiles are loaded automatically. The following example demonstrates this:
profile-desc="profile for .flv files"
vf=flip
[ao.alsa]
device=spdif
The profile name follows the schema ``type.name``, where type can be ``vo``
to match the value the ``--vo`` option is set to, ``ao`` for ``--ao``,
The profile name follows the schema ``type.name``, where type can be
``protocol`` for the input/output protocol in use (see ``--list-protocols``),
and ``extension`` for the extension of the path of the currently played file
(*not* the file format).
@@ -642,6 +673,15 @@ PROTOCOLS
either aliases to documented protocols, or are just redirections to
protocols implemented and documented in FFmpeg.
``ytdl://...``
By default, the youtube-dl hook script (enabled by default for mpv CLI)
only looks at http URLs. Prefixing an URL with ``ytdl://`` forces it to
be always processed by the script. This can also be used to invoke special
youtube-dl functionality like playing a video by ID or invoking search.
Keep in mind that you can't pass youtube-dl command line options by this,
and you have to use ``--ytdl-raw-options`` instead.
``-``
Play data from stdin.
@@ -677,7 +717,7 @@ PROTOCOLS
``mf://[filemask|@listfile]`` ``--mf-...``
Play a series of images as video.
``cdda://track[-endtrack][:speed][/device]`` ``--cdrom-device=PATH`` ``--cdda-...``
``cdda://[device]`` ``--cdrom-device=PATH`` ``--cdda-...``
Play CD.
``lavf://...``
@@ -715,6 +755,9 @@ PROTOCOLS
``memory://data``
Use the ``data`` part as source data.
``hex://data``
Like ``memory://``, but the string is interpreted as hexdump.
PSEUDO GUI MODE
===============
@@ -729,24 +772,32 @@ Currently this happens only in the following cases:
or file associations provided by desktop environments)
- if started from explorer.exe on Windows (technically, if it was started on
Windows, and all of the stdout/stderr/stdin handles are unset)
- manually adding ``--profile=pseudo-gui`` to the command line
- started out of the bundle on OSX
- if you manually use ``--player-operation-mode=pseudo-gui`` on the command line
This mode implicitly adds ``--profile=pseudo-gui`` to the command line, with
the ``pseudo-gui`` profile being predefined with the following contents:
This mode applies options from the builtin profile ``builtin-pseudo-gui``, but
only if these haven't been set in the user's config file or on the command line.
Also, for compatibility with the old pseudo-gui behavior, the options in the
``pseudo-gui`` profile are applied unconditionally. In addition, the profile
makes sure to enable the pseudo-GUI mode, so that ``--profile=pseudo-gui``
works like in older mpv releases. The profiles are currently defined as follows:
::
[pseudo-gui]
[builtin-pseudo-gui]
terminal=no
force-window=yes
idle=once
screenshot-directory=~~desktop/
[pseudo-gui]
player-operation-mode=pseudo-gui
This follows the mpv config file format. To customize pseudo-GUI mode, you can
put your own ``pseudo-gui`` profile into your ``mpv.conf``. This profile will
enhance the default profile, rather than overwrite it.
.. warning::
The profile always overrides other settings in ``mpv.conf``.
Currently, you can extend the ``pseudo-gui`` profile in the config file the
normal way. This is deprecated. In future mpv releases, the behavior might
change, and not apply your additional settings, and/or use a different
profile name.
.. include:: options.rst
@@ -771,14 +822,7 @@ The profile always overrides other settings in ``mpv.conf``.
.. include:: changes.rst
EMBEDDING INTO OTHER PROGRAMS (LIBMPV)
======================================
mpv can be embedded into other programs as video/audio playback backend. The
recommended way to do so is using libmpv. See ``libmpv/client.h`` in the mpv
source code repository. This provides a C API. Bindings for other languages
might be available (see wiki).
.. include:: libmpv.rst
ENVIRONMENT VARIABLES
=====================
@@ -932,7 +976,7 @@ For Windows-specifics, see `FILES ON WINDOWS`_ section.
``~/.config/mpv/watch_later/``
Contains temporary config files needed for resuming playback of files with
the watch later feature. See for example the ``Q`` key binding, or the
``quit_watch_later`` input command.
``quit-watch-later`` input command.
Each file is a small config file which is loaded if the corresponding media
file is loaded. It contains the playback position and some (not necessarily
+1505 -317
View File
File diff suppressed because it is too large. Load diff
+144 -128
View File
@@ -20,22 +20,25 @@ The Interface
::
+------------------+-----------+--------------------+
| playlist prev | title | playlist next |
+-------+------+---+--+------+-+----+------+--------+
| audio | skip | seek | | seek | skip | full |
+-------+ back | back | play | frwd | frwd | screen |
| sub | | | | | | |
+-------+------+------+------+------+------+--------+
| seekbar |
+----------------+--------------+-------------------+
| time passed | cache status | time remaining |
+----------------+--------------+-------------------+
+---------+----------+----------------------------+-------------+
| pl prev | pl next | title | cache |
+------+--+---+------+---------+-----------+------+-------+-----+
| play | skip | skip | time | seekbar | time | audio | sub |
| | back | frwd | elapsed | | left | | |
+------+------+------+---------+-----------+------+-------+-----+
playlist prev
pl prev
============= ================================================
left-click play previous file in playlist
right-click show playlist
shift+L-click show playlist
============= ================================================
pl next
============= ================================================
left-click play next file in playlist
right-click show playlist
shift+L-click show playlist
============= ================================================
@@ -47,55 +50,33 @@ title
right-click show filename
============= ================================================
playlist next
============= ================================================
left-click play next file in playlist
shift+L-click show playlist
============= ================================================
audio and sub
| Displays selected track and amount of available tracks
============= ================================================
left-click cycle audio/sub tracks forward
right-click cycle audio/sub tracks backwards
shift+L-click show available audio/sub tracks
============= ================================================
skip back
============= ================================================
left-click go to beginning of chapter / previous chapter
shift+L-click show chapters
============= ================================================
seek back
============= ================================================
left-click skip back 5 seconds
right-click skip back 30 seconds
shift-L-click skip back 1 frame
============= ================================================
cache
| Shows current cache fill status
play
============= ================================================
left-click toggle play/pause
============= ================================================
seek frwd
skip back
============= ================================================
left-click skip forward 10 seconds
right-click skip forward 60 seconds
shift-L-click skip forward 1 frame
left-click go to beginning of chapter / previous chapter
right-click show chapters
shift+L-click show chapters
============= ================================================
skip frwd
============= ================================================
left-click go to next chapter
right-click show chapters
shift+L-click show chapters
============= ================================================
fullscreen
time elapsed
| Shows current playback position timestamp
============= ================================================
left-click toggle fullscreen
left-click toggle displaying timecodes with milliseconds
============= ================================================
seekbar
@@ -105,23 +86,22 @@ seekbar
left-click seek to position
============= ================================================
time passed
| Shows current playback position timestamp
============= ================================================
left-click toggle displaying timecodes with milliseconds
============= ================================================
cache status
| Shows current cache fill status (only visible when below 45%)
time remaining
time left
| Shows remaining playback time timestamp
============= ================================================
left-click toggle between total and remaining time
============= ================================================
audio and sub
| Displays selected track and amount of available tracks
============= ================================================
left-click cycle audio/sub tracks forward
right-click cycle audio/sub tracks backwards
shift+L-click show available audio/sub tracks
============= ================================================
Key Bindings
~~~~~~~~~~~~
@@ -167,85 +147,117 @@ Example::
Configurable Options
~~~~~~~~~~~~~~~~~~~~
``showwindowed``
| Default: yes
| Enable the OSC when windowed
``showfullscreen``
| Default: yes
| Enable the OSC when fullscreen
``scalewindowed``
| Default: 1.0
| Scale factor of the OSC when windowed
``scalefullscreen``
| Default: 1.0
| Scale factor of the OSC when fullscreen
``scaleforcedwindow``
| Default: 2.0
| Scale factor of the OSC when rendered on a forced (dummy) window
``vidscale``
| Default: yes
| Scale the OSC with the video
| ``no`` tries to keep the OSC size constant as much as the window size allows
``valign``
| Default: 0.8
| Vertical alignment, -1 (top) to 1 (bottom)
``halign``
| Default: 0.0
| Horizontal alignment, -1 (left) to 1 (right)
``boxalpha``
| Default: 80
| Alpha of the background box, 0 (opaque) to 255 (fully transparent)
``hidetimeout``
| Default: 500
| Duration in ms until the OSC hides if no mouse movement, must not be
negative
``fadeduration``
| Default: 200
| Duration of fade out in ms, 0 = no fade
``deadzonesize``
| Default: 0
| Size of the deadzone. The deadzone is an area that makes the mouse act
like leaving the window. Movement there won't make the OSC show up and
it will hide immediately if the mouse enters it. The deadzone starts
at the window border opposite to the OSC and the size controls how much
of the window it will span. Values between 0 and 1.
``minmousemove``
| Default: 3
| Minimum amount of pixels the mouse has to move between ticks to make
the OSC show up
``layout``
| Default: box
| The layout for the OSC. Currently available are: box, slimbox,
bottombar and topbar.
Default: bottombar
The layout for the OSC. Currently available are: box, slimbox,
bottombar and topbar. Default pre-0.21.0 was 'box'.
``seekbarstyle``
| Default: slider
| Sets the style of the seekbar, slider (diamond marker) or bar (fill)
Default: bar
Sets the style of the seekbar, slider (diamond marker), knob (circle
marker with guide), or bar (fill).
Default pre-0.21.0 was 'slider'.
``deadzonesize``
Default: 0.5
Size of the deadzone. The deadzone is an area that makes the mouse act
like leaving the window. Movement there won't make the OSC show up and
it will hide immediately if the mouse enters it. The deadzone starts
at the window border opposite to the OSC and the size controls how much
of the window it will span. Values between 0.0 and 1.0, where 0 means the
OSC will always popup with mouse movement in the window, and 1 means the
OSC will only show up when the mouse hovers it. Default pre-0.21.0 was 0.
``minmousemove``
Default: 0
Minimum amount of pixels the mouse has to move between ticks to make
the OSC show up. Default pre-0.21.0 was 3.
``showwindowed``
Default: yes
Enable the OSC when windowed
``showfullscreen``
Default: yes
Enable the OSC when fullscreen
``scalewindowed``
Default: 1.0
Scale factor of the OSC when windowed.
``scalefullscreen``
Default: 1.0
Scale factor of the OSC when fullscreen
``scaleforcedwindow``
Default: 2.0
Scale factor of the OSC when rendered on a forced (dummy) window
``vidscale``
Default: yes
Scale the OSC with the video
``no`` tries to keep the OSC size constant as much as the window size allows
``valign``
Default: 0.8
Vertical alignment, -1 (top) to 1 (bottom)
``halign``
Default: 0.0
Horizontal alignment, -1 (left) to 1 (right)
``barmargin``
Default: 0
Margin from bottom (bottombar) or top (topbar), in pixels
``boxalpha``
Default: 80
Alpha of the background box, 0 (opaque) to 255 (fully transparent)
``hidetimeout``
Default: 500
Duration in ms until the OSC hides if no mouse movement, must not be
negative
``fadeduration``
Default: 200
Duration of fade out in ms, 0 = no fade
``tooltipborder``
Default: 1
Size of the tooltip outline when using bottombar or topbar layouts
``timetotal``
| Default: no
| Show total time instead of time remaining
Default: no
Show total time instead of time remaining
``timems``
| Default: no
| Display timecodes with milliseconds
Default: no
Display timecodes with milliseconds
``visibility``
| Default: auto (auto hide/show on mouse move)
| Also supports ``never`` and ``always``
Default: auto (auto hide/show on mouse move)
Also supports ``never`` and ``always``
Script Commands
~~~~~~~~~~~~~~~
@@ -266,6 +278,10 @@ Example
You could put this into ``input.conf`` to hide the OSC with the ``a`` key and
to set auto mode (the default) with ``b``::
a script_message osc-visibility never
b script_message osc-visibility auto
a script-message osc-visibility never
b script-message osc-visibility auto
``osc-playlist``, ``osc-chapterlist``, ``osc-tracklist``
Shows a limited view of the respective type of list using the OSC. First
argument is duration in seconds.
+29 -8
View File
@@ -214,7 +214,7 @@ Available filters are:
Format name, e.g. rgb15, bgr24, 420p, etc. (default: don't change).
``<outfmt>``
Format name that should be substituted for the output. If they do not
have the same bytes per pixel and chroma subsamplimg, it will fail.
have the same bytes per pixel and chroma subsampling, it will fail.
``<colormatrix>``
Controls the YUV to RGB color space conversion when playing video. There
are various standards. Normally, BT.601 should be used for SD video, and
@@ -288,6 +288,8 @@ Available filters are:
:adobe: Adobe RGB (1998)
:prophoto: ProPhoto RGB (ROMM)
:cie1931: CIE 1931 RGB
:dci-p3: DCI-P3 (Digital Cinema)
:v-gamut: Panasonic V-Gamut primaries
``<gamma>``
Gamma function the source file was encoded with. Normally this should be set
@@ -303,13 +305,24 @@ Available filters are:
Available gamma functions are:
:auto: automatic selection (default)
:bt.1886: ITU-R BT.1886 (approximation of BT.601/BT.709/BT.2020 curve)
:bt.1886: ITU-R BT.1886 (EOTF corresponding to BT.601/BT.709/BT.2020)
:srgb: IEC 61966-2-4 (sRGB)
:linear: Linear light
:gamma1.8: Pure power curve (gamma 1.8)
:gamma2.2: Pure power curve (gamma 2.2)
:gamma2.8: Pure power curve (gamma 2.8)
:prophoto: ProPhoto RGB (ROMM) curve
:st2084: SMPTE ST2084 (HDR) curve
:std-b67: ARIB STD-B67 (Hybrid Log-gamma) curve
:v-log: Panasonic V-Log transfer curve
``<peak>``
Reference peak illumination for the video file. This is mostly
interesting for HDR, but it can also be used tone map SDR content
to a darker or brighter exposure.
The default of 0.0 will default to the display's reference brightness
for SDR and the source's reference brightness for HDR.
``<stereo-in>``
Set the stereo mode the video is assumed to be encoded in. Takes the
@@ -793,12 +806,20 @@ Available filters are:
1-9
Apply high quality VDPAU scaling (needs capable hardware).
``vdpaurb``
VDPAU video read back. Works with ``--vo=vdpau`` and ``--vo=opengl`` only.
This filter will read back frames decoded by VDPAU so that other filters,
which are not normally compatible with VDPAU, can be used like normal.
This filter must be specified before ``vdpaupp`` in the filter chain if
``vdpaupp`` is used.
``d3d11vpp``
Direct3D 11 video post processing. Currently requires D3D11 hardware
decoding for use.
``deint=<yes|no>``
Whether deinterlacing is enabled (default: no).
``interlaced-only=<yes|no>``
If ``yes`` (default), only deinterlace frames marked as interlaced.
``mode=<blend|bob|adaptive|mocomp|ivctc|none>``
Tries to select a video processor with the given processing capability.
If a video processor supports multiple capabilities, it is not clear
which algorithm is actually selected. ``none`` always falls back. On
most if not all hardware, this option will probably do nothing, because
a video processor usually supports all modes or none.
``buffer=<num>``
Buffer ``<num>`` frames in the filter chain. This filter is probably pretty
+139 -801
View File
File diff suppressed because it is too large. Load diff
+13 -11
View File
@@ -7,8 +7,8 @@ large part of which is incompatible or completely changes how the player
behaves. Although there are still many similarities to its ancestors, **mpv**
should generally be treated as a completely different program.
.. note::
These lists are incomplete.
.. admonition:: Warning
This document is not updated anymore, and is incomplete and outdated.
General Changes from MPlayer to mpv
-----------------------------------
@@ -30,7 +30,7 @@ Player
* Slave mode compatibility broken (see below).
* Re-enable screensaver while the player is paused.
* Allow resuming playback at a later point with ``Shift+q``, also see the
``quit_watch_later`` input command.
``quit-watch-later`` input command.
* ``--keep-open`` option to stop the player from closing the window and
exiting after playback ends.
* A client API, that allows embedding **mpv** into applications
@@ -79,7 +79,8 @@ Video
using most of FFmpeg's filters, which improve greatly on the old MPlayer
filters in features, performance, and correctness.
* More correct color reproduction (color matrix generation), including support
for BT.2020 (Ultra HD) and linear XYZ (Digital Cinema) inputs.
for BT.2020 (Ultra HD). linear XYZ (Digital Cinema) and SMPTE ST2084 (HDR)
inputs.
* Support for color managed displays, via ICC profiles.
* High-quality image resamplers (see the ``opengl`` ``scale`` suboption).
* Support for scaling in (sigmoidized) linear light.
@@ -261,13 +262,14 @@ Command Line Switches
``-ssf <sub>`` ``--sws-...``
``-stop-xscreensaver`` ``--stop-screensaver``
``-sub-fuzziness`` ``--sub-auto``
``-sub-text-*`` ``--sub-*``
``-sub`` ``--sub-file``
``-subcp`` ``--sub-codepage``
``-subdelay`` ``--sub-delay``
``-subfile`` ``--sub-file``
``-subfont-*`` ``--sub-text-*``, ``--osd-*``
``-subfont-*`` ``--sub-*``, ``--osd-*``
``-subfont-text-scale`` ``--sub-scale``
``-subfont`` ``--sub-text-font``
``-subfont`` ``--sub-font``
``-subfps`` ``--sub-fps``
``-subpos`` ``--sub-pos``
``-sws`` ``--sws-scaler``
@@ -311,11 +313,11 @@ input.conf and Slave Commands
+--------------------------------+----------------------------------------+
| Old | New |
+================================+========================================+
| ``pt_step 1 [0|1]`` | ``playlist_next [weak|force]`` |
| ``pt_step 1 [0|1]`` | ``playlist-next [weak|force]`` |
| | (translation layer cannot deal with |
| | whitespace) |
+--------------------------------+----------------------------------------+
| ``pt_step -1 [0|1]`` | ``playlist_prev [weak|force] (same)`` |
| ``pt_step -1 [0|1]`` | ``playlist-prev [weak|force] (same)`` |
+--------------------------------+----------------------------------------+
| ``switch_ratio [<ratio>]`` | ``set video-aspect <ratio>`` |
| | |
@@ -330,7 +332,7 @@ input.conf and Slave Commands
| ``<step> <dir>`` | ``no-osd``: ``no-osd cycle <prop>`` |
| | ``<step>`` |
+--------------------------------+----------------------------------------+
| ``osd_show_property_text`` | ``show_text <text>`` |
| ``osd_show_property_text`` | ``show-text <text>`` |
| ``<text>`` | The property expansion format string |
| | syntax slightly changed. |
+--------------------------------+----------------------------------------+
@@ -339,9 +341,9 @@ input.conf and Slave Commands
| | ``raw`` prefix to disable property |
| | expansion. |
+--------------------------------+----------------------------------------+
| ``show_tracks`` | ``show_text ${track-list}`` |
| ``show_tracks`` | ``show-text ${track-list}`` |
+--------------------------------+----------------------------------------+
| ``show_chapters`` | ``show_text ${chapter-list}`` |
| ``show_chapters`` | ``show-text ${chapter-list}`` |
+--------------------------------+----------------------------------------+
| ``af_switch``, ``af_add``, ... | ``af set|add|...`` |
+--------------------------------+----------------------------------------+
+2 -1
View File
@@ -25,7 +25,8 @@ Release procedure
- Create and/or update the `VERSION` file.
- Update `DOCS/client-api-changes.rst` (on major releases).
- Update `DOCS/client-api-changes.rst` and `DOCS/interface-changes.rst`
(in particular, update the last version numbers if necessary)
- Create tag v0.X.Y.
+1 -1
View File
@@ -123,7 +123,7 @@ options/options.h, options/options.c
parser-mpcmd.c, and uses the option table in options.c.
input/input.c:
This translates keyboard input comming from VOs and other sources (such
This translates keyboard input coming from VOs and other sources (such
as remote control devices like Apple IR or client API commands) to the
key bindings listed in the user's (or the builtin) input.conf and turns
them into items of type struct mp_cmd. These commands are queued, and read
+35 -2
View File
@@ -7,6 +7,7 @@
* [Overview](#overview)
* [Downloads](#downloads)
* [Changelog](#changelog)
* [Compilation](#compilation)
* [FFmpeg vs. Libav](#ffmpeg-vs-libav)
* [Release cycle](#release-cycle)
@@ -14,6 +15,7 @@
* [Contributing](#contributing)
* [Relation to MPlayer and mplayer2](#relation-to-mplayer-and-mplayer2)
* [Wiki](https://github.com/mpv-player/mpv/wiki)
* [FAQ](https://github.com/mpv-player/mpv/wiki/FAQ)
* [Man pages](http://mpv.io/manual/master/)
* [Contact](#contact)
* [License](#license)
@@ -47,6 +49,20 @@ Releases can be found on the [release list][releases].
For semi-official builds and third-party packages please see
[mpv.io](http://mpv.io/installation/).
## Changelog
There is no completely changelog, however changes to the player core interface
are listed in the [interface changelog][interface-changes].
Changes to the C API are documented in the [client API changelog][api-changes].
The [release list][releases] has a summary of most of the important changes
on every release.
Changes to the default key bindings are inidcated in
[restore-old-bindings.conf][restore-old-bindings].
## Compilation
@@ -79,7 +95,7 @@ Essential dependencies (incomplete list):
- Audio output development headers (libasound/ALSA, pulseaudio)
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavfilter
and either libswresample or libavresample)
At least FFmpeg 2.4.0 or Libav 11 is required.
At least FFmpeg 3.2.2 or Libav 12 is required.
- zlib
- iconv (normally provided by the system libc)
- libass (OSD, OSC, text subtitles)
@@ -137,6 +153,20 @@ most likely the best maintenance out of all stable releases. Older releases
are for distros, and at best receive basic changes like fixing critical security
issues or build fixes, and at worst are completely abandoned.
## FFmpeg ABI compatibility
mpv does not support linking against FFmpeg versions it was not built with, even
if the linked version is supposedly ABI-compatible with the version it was
compiled against. Expect malfunctions, crashes, and security issues if you
do it anyway.
The reason for not supporting this is because it creates far too much complexity
with little to no benefit, coupled with absurd and unusable FFmpeg API
artifacts.
Newer mpv versions will refuse to start if runtime and compile time FFmpeg
library versions mismatch.
## Release cycle
Every other month, an arbitrary git snapshot is made, and is assigned
@@ -183,7 +213,7 @@ In general, mpv should be considered a completely new program, rather than a
MPlayer drop-in replacement.
If you are wondering what's different from mplayer2 and MPlayer, an incomplete
list of changes is located [here][mplayer-changes].
and now unmaintained list of changes is located [here][mplayer-changes].
## Contact
@@ -206,6 +236,9 @@ only if discretion is required.
[release-policy]: https://github.com/mpv-player/mpv/blob/master/DOCS/release-policy.md
[windows_compilation]: https://github.com/mpv-player/mpv/blob/master/DOCS/compile-windows.md
[mplayer-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/mplayer-changes.rst
[interface-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/interface-changes.rst
[api-changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/client-api-changes.rst
[restore-old-bindings]: https://github.com/mpv-player/mpv/blob/master/etc/restore-old-bindings.conf
## License
+723
View File
@@ -1,3 +1,726 @@
Release 0.23.0
==============
Now requires at least FFmpeg 3.2.2.
Features
--------
- vo_rpi: partially undeprecate
Added
~~~~~
- vo_opengl: hwdec_cuda: Support P016 output surfaces
Removed
~~~~~~~
- charset_conv: drop enca and libguess support in favor of uchardet
- vf_vdpaurb: remove this filter in favor of --hwdec=vdpau-copy
Options and Commands
--------------------
Added
~~~~~
- TOOLS/autoload: allow disabling through script-opts
- demux, stream: add --access-references to prevent opening referenced files
Deprecated
~~~~~~~~~~
- options: deprecate codec family selection in --vd/--ad
Removed
~~~~~~~
- macOS: remove --fs-black-out-screens
- options: remove deprecated sub-option handling for --vo and --ao
Fixes and Minor Enhancements
----------------------------
- Windows: window styles improvements (allow minimizing borderless/fullscreen window) (#2229, #2451)
- ad_spdif: Fix crash when spdif muxer is not available
- audio: fix --audio-stream-silence with ao_alsa
- audio: fix --audio-stream-silence with ao_wasapi
- build: drop build-time dependency on Perl
- build: support linking ANGLE (previously loaded dynamically)
- d3d11va: unconditionally load D3D DLLs (#3348)
- demux_mkv: fix seeking in some broken files (#3920)
- hwdec_cuda: allow building without CUDA SDK (load CUDA dynamically)
- macOS: fix dropping of URLs containing query strings on the window
- macOS: fullscreen refactoring (#2857, #3272, #1352, #2062, #3864)
- macOS: support append file to paylist on drop (#2166)
- macOS: update the menu and remove conflicting “Quit & remember position” item (#3865)
- osc: don't hide playlist buttons, just disable
- osc: fix possible race condition in right timecode
- osc: topbar: use same styles as bottombar
- player: don't print format detection error when aborting loading
- vdpau: fix vaapi probing if libvdpau-va-gl1 is present
- video: use demuxer-signaled duration for last video frame (#3924)
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.22.0..v0.23.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.22.0...v0.23.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.22.0..v0.23.0
Release 0.22.0
==============
Features
--------
Added
~~~~~
- audio/out: add AudioUnit output driver for iOS
- demux_mkv: parse Matroska colorimetry metadata
- filter_kernels: add ability to taper kernels/windows, add tukey window
- osc: add seekbarstyle=knob (#2365)
- video/out: add tct as modern caca alternative for true-color and 256-color terminals
- video: add --hwdec=vdpau-copy mode
Deprecated
~~~~~~~~~~
- vf_vdpaurb: deprecated in favor of --hwdec=vdpau-copy
Options and Commands
--------------------
Added
~~~~~
- --opengl-early-flush=auto
- --scale-taper, --scale-wtaper
- --scale-wblur
- macOS: --hidpi-window-scale (#3716)
- osc: add script message handlers for chapter/track/playlists
Fixes and Minor Enhancements
----------------------------
- Apply --autofit-larger after --autofit-smaller (#3753)
- Set subtitle track title to indicate hearing/visual impaired tracks
- ao_alsa: disable chmap API use for mono/stereo (#2905, #3045)
- build: add required failure message for libavfilter check (#3692)
- build: fix compilation with mingw-w64/Clang (#3800)
- build: make VideoToolbox available on iOS
- command: fix reset-on-next-file=all and tv-freq option (#3708)
- command: if window-scale can't be set properly, set it as option (#3724)
- demux_mkv: don't recursively resolve timeline for opened reference files
- demux_mkv: fix ordered chapter sources with ordered editions
- opengl: compile against iOS OpenGLES implementation
- options: handle legacy no-* sub-options
- osc: add alpha animation to tooltip (fix lingering tooltip)
- osc: change default deadzonesize to 0.5
- osc: don't wrap the title
- osc: fix crash after reaching a certain position in limited lists (#3691)
- osc: fix crash with no chapters
- osc: fix crashes when dragging seekbar across file changes (#3210)
- osc: fix displaying only half of the entries when at the end of a list
- osc: fix missing chapter ticks with seekbarstyle=bar
- osc: slimbox: fix clipping with seekbarstyle=bar (#3737)
- osc: top/bottombar: also scale when min-width is reached to match box/slimbox behavior
- osc: top/bottombar: dynamically size timecodes according to timems
- osc: top/bottombar: rescale layout to same size with scale=1
- osc: top/bottombar: scale title if too large like box
- player: consistently initialize screensaver state with --force-window
- player: enable no-video subtitle display on coverart too
- player: make --start-time work with --rebase-start-time=no
- player: make sure non-video subtitle rendering is reset if video resumes (#3770)
- player: removing last playlist entry while looping should not stop (#3808)
- player: show subtitles on VO if --force-window is used (#3684)
- player: speed up audio/video re-sync when there is a huge delay
- vdpau: fix hwdec uninit (#3788)
- vo_opengl: blend against background color for --alpha=blend
- vo_opengl: context_rpi: fix stdatomic usage (#3699)
- vo_opengl: fix --blend-subtitles handling (#3773)
- vo_opengl: fix redrawing with hardware decoding (#3773)
- vo_opengl: partially re-enable glFlush() calls (#3670)
- ytdl_hook: sort chapters by time
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.21.0..v0.22.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.21.0...v0.22.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.21.0..v0.22.0
Release 0.21.0
==============
Features
--------
Added
~~~~~
- config: allow profile forward-references in default profile
- demux_lavf: "support" mov edit lists and log errors if used (FFmpeg only)
- hwdec: Add support for CUDA and cuvid/NvDecode (mostly useful on Linux where VDPAU still lacks HEVC Main 10 support; keep using DXVA2 on Windows)
- osc: add right-click behavior to playlist and chapter buttons
- osc: add user-alterable margin for top/bottombar
- rpi: add --hwdec=rpi-copy (#3604)
- sd_lavc: enable teletext
- vaapi: support drm devices when running in vaapi-copy mode
- vd_lavc: Add hwdec wrapper for crystalhd
- vo_opengl: add hw overlay support and use it for RPI
- vo_opengl: basic mali fbdev support
- vo_opengl: rpi: merge vo_rpi features
Removed
~~~~~~~
- vo_opengl: remove pre/post/scale-shaders in favor of user-shaders
Deprecated
~~~~~~~~~~
- config: deprecate ao and vo auto-profiles
- vo_rpi: deprecate this VO
Options and Commands
--------------------
Added
~~~~~
- add --teletext-page option
- af_pan: add af-command support to change the matrix
- af_rubberband: add af-command and option to change the pitch
- command: add a load-script command
- command: add a video-dec-params property
- command: add an apply-profile command
- command: add audio-pts property to get the audio pts
- command: add options to property list
- command: add sub-text property for current subtitle text
- command: export profile list as a property (#977)
- options: add --hwdec=yes as alias for --hwdec=auto
- player: add --player-operation-mode=pseudo-gui
- player: add --video-osd=no option to disable video OSD (#3387)
- player: add --watch-later-directory option
- stream_bluray: select title by playlist (bd://mpls/[playlist])
- vo_opengl: disable glFlush() by default, and add an option to enable it for testing
Changed
~~~~~~~
- af_rubberband: default to channels=together
- command: allow absolute seeks relative to end of stream
- command: make bitrate properties observable
- command: make most options observable
- msg: make --log-file and --dump-stats accept config path expansion (#3591)
- options: deprecate --playlist-pos to --playlist-start
- options: make input options generally runtime-settable
- options: rename subtitle options (--sub-text- → --sub; --ass- → --sub-ass-)
- osc: change default layout to bottombar, seekbarstyle to bar, use larger scalewindowed and scalefullscreen
- player: make --terminal, --log-file, --dump-stats, --osc, --ytdl, --audio-*, --priority, --stop-screensaver (#3615) settable at runtime
- vo_drm: change CLI options
- Change connector selection to accept human readable names (such as eDP-1, HDMI-A-2) rather than arbitrary numbers.
- Change GPU selection to accept GPU number rather than device paths.
- Merge connector and GPU selection into one --drm-connector.
- Add support for --drm-connector=help.
- Add support for --drm-* in EGL backend.
- vo_opengl: rename 3dlut-size to icc-3dlut-size
Removed
~~~~~~~
- command: remove hwdec-active and hwdec-detected properties
- command: remove vo-cmdline
- options: drop unreferenced --bluray-angle option
- vo, ao: disable positional parameter suboptions
- vo_xv: replace no-colorkey with ck-method=none
Deprecated
~~~~~~~~~~
- all VOs and AOs: deprecate sub-options, add them as global options
- command: deprecate "cache" property, replace with "cache-percent"
- deprecate --vo-defaults
- deprecate --vo=opengl-hq alias in favor of opengl-hq profile
- options: deprecate --mute=auto
- vo_direct3d: deprecate direct3d_shaders alias, use shaders by default
- vo_opengl: deprecate 'drm-egl' backend and introduce 'drm' instead
Fixes and Minor Enhancements
----------------------------
- TOOLS/zsh.pl: die if we can't parse main options
- TOOLS/zsh.pl: don't filter files by extension (#2273)
- ao_alsa: try to fallback to "hdmi" before "iec958" for spdif
- ao_rsound: fix compilation (#3501)
- aspect: use nominal width instead of actual width for video-unscaled
- audio/out: prevent underruns with spdif under certain conditions
- audio: fix late audio start (#3610)
- audio: fix missed wakeup when changing audio output device
- audio: fix segfault when yanking USB DAC
- charset_conv: Use CP949 instead of EUC-KR
- command: don't log "ignore" command with -v verbosity
- command: try selecting the next track if track switching fails (#3446)
- demux_mkv: don't crash if --ordered-chapters-files fails
- displayconfig: treat a refresh rate of 1 as invalid
- ipc: log when listening to IPC socket (#3598)
- macOS: fix fullscreen regression on 10.11 and newer (#3364)
- mp_image: fix clearing to black with p010 format
- osc: Fix scaling issues when toggling fullscreen (#3429)
- osc: align text vertically in top/bottombar (#2093)
- osc: change seekbar background's alpha scaling
- osc: fix display of chapters and playlist scaling
- osc: move tooltip to inside seekbar for top/bottombar
- osc: show playlist/chapter list on prev/next instead of osd
- path: default ~~ paths to home directory (#3591)
- player: do not let pseudo-gui override user config settings
- player: enable reading from stdin after loading input.conf
- player: fix instant subtitle refresh on track switches
- player: make --force-window work with opengl-cb
- stream_file: don't use poll() on directories (would hang on macOS; #3530, #3649)
- stream_lavf: fix determining seekability (#1701)
- sub: actually apply text alignment options to non-ASS subtitles
- terminal-win: support modifier keys in console input (#3625)
- vo_drm: fix segfault when using invalid card
- vo_opengl: apply 90° rotation to chroma texture size (#3568)
- vo_opengl: fix incorrect video rendering after vdpau preemption recovery
- vo_opengl: partially fix dumb-mode cropping with rotation
- vo_opengl: rpi: use overlay for yuv420p too
- w32_common: initialize playback status as soon as possible (#3482)
- wayland: reject resize events with either dimension being 0 (#3679)
- x11: fix external fullscreen update (#3570)
- ytdl_hook: Add title to playlist items if available
- ytdl_hook: Set aspect ratio for anamorphic video
- ytdl_hook: Support playlist entries without subtitles
- ytdl_hook: add chapters by parsing video's description
- ytdl_hook: don't add subtitles with unknown duration
- ytdl_hook: temporarily force disable dash segments formats
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.20.0..v0.21.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.20.0...v0.21.0 or
https://git.srsfckn.biz/mpv/log/?qt=range&q=v0.20.0..v0.21.0
Release 0.20.0
==============
Options and Commands
--------------------
Added
~~~~~
- aspect: add --video-unscaled=downscale-big
- player: add --image-display-duration option to control duration of image display (#3425)
- vo_opengl: angle: new flag (dcomposition) to control DirectComposition
- command: add sub-speed property
Fixes and Minor Enhancements
----------------------------
- af_lavrresample: fix error if resampler could not be recreated
- audio: avoid missed wakeups with ab-loops
- audio: do not apply --audio-channels if spdif passthrough is in use (#3445)
- cache: don't use a backbuffer if the cache is as large as the file
- command: prevent O(n^2) behaviour for playlist property
- demux: close underlying stream if it's fully read anyway (#3456)
- demux: fix undefined behavior with ogg metadata update (#3451)
- player: make looping slightly more seamless
- player: refresh very low framerate video on filter changes (#3435)
- stream_memory: disable stream cache
- vf_rotate: allow arbitrary rotation (#3434)
- vo: be more trusting to estimated display FPS (#3433)
- w32_common: use hooks to detect parent window resize
- x11: work around mutter fullscreen issue (#2072)
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.19.0..v0.20.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.19.0...v0.20.0 or
http://git.srsfckn.biz/mpv/log/?qt=range&q=v0.19.0..v0.20.0
Release 0.19.0
==============
Build System Changes
--------------------
- build: add --htmldir option
- build: always require atomics
- wscript: add proper unversioned SONAME for Android
Features
--------
New
~~~
- client API: add stream_cb API for user-defined stream implementations (bumps client API version to 1.22)
- vf_d3d11vpp: add video processor selection
- videotoolbox: add --hwdec=videotoolbox-copy for h/w accelerated decoding with video filters
- vo_opengl: add a tscale=linear direct implementation
Removed
~~~~~~~
- audio/filter: remove delay audio filter
Options and Commands
--------------------
Added
~~~~~
- command: add filename/no-ext sub-property that returns filename without extension (#3404)
- command: add properties for HDR metadata
- command: add replaygain information properties to track-list
- options: add vp9 to --hwdec-codecs
- player: add --audio-stream-silence
- player: add --audio-wait-open
- player: add --no-autoload-files
- videotoolbox: add yuv420p to --videotoolbox-format
Changed
~~~~~~~
- options: un-restrict --audio-delay
- use - as command-name separator everywhere
- vo_opengl: reduce default 3dlut-size to 64x64x64 (since accuracy is improved)
Deprecated
~~~~~~~~~~
- deprecate "balance" option/property (no replacement)
Fixes and Minor Enhancements
----------------------------
- Windows: don't wait for GUI thread when polling for events (#3393)
- af_lavcac3enc: error out properly if encoding fails
- af_volume: don't let softvol overwrite af_volume volumedb sub-option
- ao_pulse: fix some volume control rounding issues
- ao_wasapi: in exclusive mode, do not output multichannel by default
- audio: add heuristic to move auto-downmixing before other filters
- audio: show an osd bar when changing ao-volume
- demux: make ALBUM replaygain tags optional (#3405)
- demux_raw: fix small typo to add s16be support
- demux_timeline: restore mkv edition switching
- libarchive: sanitize non-UTF8 archive entries
- macOS/vo_opengl: fix crash when glctx is NULL during init (#3360)
- player: disable display-sync with spdif transcoding
- player: do not cut off terminal status line if it contains newlines (#3340)
- player: fix display-sync timing if audio resumes slowly
- player: improve instant track switching (#3392)
- player: improve non-hr seeking with external audio tracks
- player: offset demuxer on start/seek properly with audio/sub delay
- player: sync audio as well when enabling it mid-stream
- stream/stream_bluray: display list of available titles in verbose mode
- sub: don't potentially discard too many subtitles on seek
- video: respect --deinterlace=auto
- vo_direct3d: add missing header (fixes Cygwin build)
- vo_opengl: angle: try D3D9 when D3D11 fails eglInitialize
- vo_opengl: angle: use WARP if there are no hw adapters (makes it work on Windows 7 without hardware-accelerated graphics)
- vo_opengl: increase 3DLUT accuracy at smaller LUT sizes
- vo_opengl: remove the 3dlut-size npot2 restriction
- vo_wayland: fix high CPU usage due to busy polling
- wayland_common: clip window size to the display output size
- wayland_common: fix crashes when switching to fullscreen before the video output is fully initialized
- wayland_common: fix fullscreen image switching bug
- wayland_common: prevent black bars on most non-native aspect ratios
- wayland_common: remove untested/unusable wayland dnd code
- win32: mpv.rc: re-add version info
- x11: skip ICC update on every window move
- ytdl: Error out with http_dash_segments (unsupported for now)
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.18.1..v0.19.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.18.1...v0.19.0 or
http://git.srsfckn.biz/mpv/log/?qt=range&q=v0.18.1..v0.19.0
Release 0.18.1
==============
Note: Running mpv with different versions of the FFmpeg/Libav libraries than
it was compiled with is no longer supported. Even supposedly ABI-compatible
versions have been a source of trouble, and it creates far too much
complexity with little to no benefit, coupled with absurd and unusable FFmpeg
API artifacts.
Instead, mpv will exit with an error when such a situation is detected.
This simply means that mpv needs to be rebuilt whenever FFmpeg libraries change.
Features
--------
New
~~~
- d3d: implement screenshots for --hwdec=d3d11va
- vo_opengl: add output_size uniform to custom shader
- vo_opengl: implement the Panasonic V-Log function (#3157)
- vo_opengl: implement ARIB STD-B68 (HLG) HDR TRC
Options and Commands
--------------------
Changed
~~~~~~~
- command: pack sub image data in overlay-add command
Deprecated
~~~~~~~~~~
- options: deprecate --heartbeat-cmd
- audio: deprecate --softvol
Removed
~~~~~~~
- audio: drop --softvol=no and --softvol=auto (#3322)
Fixes and Minor Enhancements
----------------------------
- video: fix deinterlace filter handling on pixel format changes
- x11: silence xdg-screensaver
- vo_opengl: angle: update the swapchain on resize (#3301)
- vo_opengl: error out gracefully when trying to use FBOs without FBO API
- vd_lavc: expose mastering display side data reference peak (improves results with HDR content)
- vo_opengl: generalize HDR tone mapping mechanism (#3293)
- vo_opengl: don't constantly resize the output FBO
- vo_opengl: use ringbuffer of PBOs
- Windows: make WM_NCHITTEST simpler and more accurate
- ao_oss: do not add an entry to audio-device-list if device file missing
- dec_audio: fix segment boudnary switching
- ao_lavc, vo_lavc: Migrate to new FFmpeg encoding API
- vo_opengl: explicitly use main framebuffer when reading window content (#3284)
- vo_xv: fix behavior with odd sizes
- audio: insert auto-inserted filters at end of chain
- x11: add missing FocusChangeMask (disables key repeat when losing focus while a key is down)
- ao_coreaudio: error out when selecting invalid device
- ad_lavc: work around misbehavior of some FFmpeg decoders like wmapro (#3297)
- player: cut off status line on terminal width
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.18.0..v0.18.1`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.18.0...v0.18.1 or
http://git.srsfckn.biz/mpv/log/?qt=range&q=v0.18.0..v0.18.1
Release 0.18.0
==============
Build System Changes
--------------------
- build: Do not link to libGL for egl-drm
- build: also use the iconv check on FreeBSD
- build: don't install tests, only build them
- build: re-enable encoding mode by default
- vo_opengl: hwdec: remove build-dependency on dxva2 (#3150)
- wscript: make at least 1 OpenGL output mandatory
Features
--------
New
~~~
- csputils: add SMPTE ST2084 support
- demux_mkv: support Matroska webvtt (#3247)
- demux_playlist: read directories recursively
- stream_memory: add hex:// protocol
- vf_crop: support opaque hardware decoding formats
- vf_d3d11vpp: add a D3D11 video processor filter
- vo_opengl: D3D11VA + ANGLE interop
- vo_opengl: add an angle-es2 backend
- vo_opengl: angle: dynamically load ANGLE
- vo_opengl: d3d11egl: native NV12 sampling support
- vo_opengl: enable color management on GLES
- vo_opengl: implement HDR (SMPTE ST2084)
- vo_opengl: implement tone mapping algorithms
- vo_opengl: make PBOs work on GLES 3.x
- vo_opengl: support external user hooks, enhancing the flexibility of user shaders
- vo_opengl: vdpau interop without RGB conversion
- wayland: implement HIDPI support
Removed
~~~~~~~
- vo_opengl: remove nnedi3 prescaler (replaced by user shaders)
- vo_opengl: remove prescaling framework with superxbr prescaler (replaced by user shaders)
Options and Commands
--------------------
Added
~~~~~
- Windows: make taskbar progress indication optional (#2535)
- af_lavcac3enc: make encoder configurable
- command: add playlist-pos-1 property (#2828)
- command: introduce hwdec-current and hwdec-interop properties.
- options: add --fit-border video option (currently Windows only)
- video: add --hwdec=auto-copy mode
- vo_opengl: always autoselect ANGLE as backend if available
- vo_opengl: expose performance timers as properties
- x11: add --x11-bypass-compositor=never
- x11: extend --x11-bypass-compositor with fs-only option (#2582)
Changed
~~~~~~~
- command: allow setting panscan etc. properties if no video is active
- command: don't seek immediately when setting a-b loop while paused
- command: if only ab-loop-b is set, loop from start of file
- options: --geometry: center window position after applying size (#2397)
- player: loop on end of file if ab-loop-b is unset
- sd_add: replace --sub-ass=no with --ass-style-override=strip
Removed
~~~~~~~
- vo_opengl: remove non-working rgb/rgba FBO formats
Fixes and Minor Enhancements
----------------------------
- TOOLS/zsh.pl: add .f4v extension in zsh completions
- TOOLS/zsh.pl: complete --audio-device
- Windows: center window on original window center on resize to fit screen
- Windows: fix size calculations for window resize (#2935)
- Windows: fix wrong behavior with window-scale when window size exceeds screen size
- Windows: make VOCTRL_SET_UNFS_WINDOW_SIZE resize the window around its center (#3164)
- af_lavcac3enc: fix custom bitrates
- ao_alsa: add more workarounds for hardware with broken drivers (e.g. ODROID-C2)
- ao_opensles: remove 32-bit audio formats (not supported by Android)
- cocoa: fix actual display refresh rate retrieval
- cocoa: use displaylink without manually tracking the display id (#2392)
- command: improve playlist* properties change notifications (#3267)
- command: slightly nicer OSD list formatting
- compatibility with recent FFmpeg APIs
- d3d: fix hardware decoding of most MPEG2 things
- d3dva: move Intel_H264_NoFGT_ClearVideo to lower priority (#3059)
- demux_mkv: better resync behavior for broken google-created webms
- demux_mkv: fix seeking with files that miss the first index entry
- demux_playlist: recognize m3u8 as playlist extension (#3154)
- input: fix parsing multiple input command prefixes
- lcms: don't warn/error on 3dlut cache misses
- lcms: improve black point handling (especially BT.1886)
- macOS: handle multiple dropped files on the window (#3076)
- player: always show the first frame in DS mode
- player: assume video forwards timestamps jumps only with some formats (#3027)
- player: do not update OSD all the time when paused
- player: eagerly redraw OSD when seeking with coverart
- player: fix use-after-free with --screenshot-directory (#3049)
- player: force VO reconfig when unselecting video track
- player: really start audio only once video is ready
- sd_lavc: work around bug in older FFmpeg releases (#3109)
- stream_cdda: enable cache by default
- sub: fix --sub-gauss
- vd_lavc: better hwdec wrapper decoder selection
- vo_opengl: EGL: fix hwdec probing
- vo_opengl: angle: avoid fullscreen FBO copy for flipping
- vo_opengl: angle: enable DirectComposition (lowers vsync jitter)
- vo_opengl: angle: prevent DXGI hooking Alt+Enter
- vo_opengl: avoid outputting ultra-wide-gamut by default
- vo_opengl: correctly disable interpolation if tscale can't be used
- vo_opengl: fix bicubic_fast in ES mode
- vo_opengl: fix d3d11 hardware decoding probing on Windows 7
- vo_opengl: improve scale=oversample performance
- vo_opengl: make the screen blue on shader errors
- vo_opengl: partially fix 0bgr format support
- vo_opengl: possibly update icc profile after changing options
- vo_opengl: request core profile on X11/EGL too
- vo_opengl: require at least ES 3.0 for float textures
- vo_opengl: vdpau: fix certain cases of preemption recovery failures
- vo_rpi: attempt to survive display mode changes
- vo_rpi: fix destroying overlays (#3100)
- vo_rpi: wait for vsync with a timeout
- vo_sdl: fix pixel formats.
- vo_xv: Handle incorrect size returned by Xv(Shm)CreateImage (#320)
- wayland: correctly report display refresh rate
- wayland: use the advertised size in fullscreen (#3021, #2657)
- x11: tell GNOME to use dark window decorations
- ytdl_hook: fix brightcove urls
- ytdl_hook: just check if protocol is rtmp (#3090)
- ytdl_hook: support multi-arc subtitles
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API, and DOCS/interface-changes.rst for a history
of changes to other user-visible interfaces.
A complete changelog can be seen by running `git log v0.17.0..v0.18.0`
in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.17.0...v0.18.0 or
http://git.srsfckn.biz/mpv/log/?qt=range&q=v0.17.0..v0.18.0
Release 0.17.0
==============
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/bash
set -e
export DEST_OS=win32
export CC=gcc
export PKG_CONFIG=/usr/bin/pkg-config
export PERL=/usr/bin/perl
export PYTHON=/usr/bin/python3
"$PYTHON" bootstrap.py
"$PYTHON" waf configure \
--check-c-compiler=gcc \
--disable-cdda \
--enable-egl-angle \
--enable-jpeg \
--enable-lcms2 \
--enable-libarchive \
--enable-libass \
--enable-lua \
--enable-rubberband \
--enable-uchardet
"$PYTHON" waf build
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/bash
set -e
case $MSYSTEM in
MINGW32)
export MINGW_PACKAGE_PREFIX=mingw-w64-i686
;;
MINGW64)
export MINGW_PACKAGE_PREFIX=mingw-w64-x86_64
;;
esac
# Write an empty fonts.conf to speed up fc-cache
export FONTCONFIG_FILE=/dummy-fonts.conf
cat >"$FONTCONFIG_FILE" <<EOF
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig></fontconfig>
EOF
# Install build dependencies for mpv
pacman -S --noconfirm --needed \
$MINGW_PACKAGE_PREFIX-gcc \
$MINGW_PACKAGE_PREFIX-angleproject-git \
$MINGW_PACKAGE_PREFIX-ffmpeg \
$MINGW_PACKAGE_PREFIX-lcms2 \
$MINGW_PACKAGE_PREFIX-libarchive \
$MINGW_PACKAGE_PREFIX-libass \
$MINGW_PACKAGE_PREFIX-libjpeg-turbo \
$MINGW_PACKAGE_PREFIX-lua51 \
$MINGW_PACKAGE_PREFIX-rubberband \
$MINGW_PACKAGE_PREFIX-uchardet
# Delete unused packages to reduce space used in the Appveyor cache
pacman -Sc --noconfirm
-24
View File
@@ -1,24 +0,0 @@
#! /usr/bin/env perl
use strict;
use warnings;
# Convert the contents of a file into a C string constant.
# Note that the compiler will implicitly add an extra 0 byte at the end
# of every string, so code using the string may need to remove that to get
# the exact contents of the original file.
# FIXME: why not a char array?
# treat only alphanumeric and punctuations (excluding " and ?) as safe
my $unsafe_chars = qr{[^][A-Za-z0-9!#%&'()*+,./:;<=>^_{|}~ -]};
for my $file (@ARGV) {
open my $fh, '<:raw', $file or next;
print "/* Generated from $file */\n";
while (<$fh>) {
# replace unsafe chars with their equivalent octal escapes
s/($unsafe_chars)/\\@{[sprintf '%03o', ord($1)]}/gos;
print "\"$_\"\n"
}
close $fh;
}
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env python
# Convert the contents of a file into a C string constant.
# Note that the compiler will implicitly add an extra 0 byte at the end
# of every string, so code using the string may need to remove that to get
# the exact contents of the original file.
import sys
# Indexing a byte string yields int on Python 3.x, and a str on Python 2.x
def pord(c):
return ord(c) if type(c) == str else c
def main(infile):
conv = ['\\' + ("%03o" % c) for c in range(256)]
safe_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" \
"0123456789!#%&'()*+,-./:;<=>?[]^_{|}~ "
for c in safe_chars:
conv[ord(c)] = c
for c, esc in ("\nn", "\tt", r"\\", '""'):
conv[ord(c)] = '\\' + esc
for line in infile:
sys.stdout.write('"' + ''.join(conv[pord(c)] for c in line) + '"\n')
with open(sys.argv[1], 'rb') as infile:
sys.stdout.write("// Generated from %s\n\n" % sys.argv[1])
main(infile)
-30
View File
@@ -1,30 +0,0 @@
use 5.008;
use strict;
use warnings;
# ABSTRACT: Module collection to parse Matroska files.
package Parse::Matroska;
=head1 DESCRIPTION
C<use>s L<Parse::Matroska::Reader>. See the documentation
of the modules mentioned in L</"SEE ALSO"> for more information
in how to use this module.
It's intended for this module to contain high-level interfaces
to the other modules in the distribution.
=head1 SOURCE CODE
L<https://github.com/Kovensky/Parse-Matroska>
=head1 SEE ALSO
L<Parse::Matroska::Reader>, L<Parse::Matroska::Element>,
L<Parse::Matroska::Definitions>.
=cut
use Parse::Matroska::Reader;
1;
-357
View File
@@ -1,357 +0,0 @@
use 5.008;
use strict;
use warnings;
# ABSTRACT: internal EBML grammar definitions
package Parse::Matroska::Definitions;
use Parse::Matroska::Utils qw{uniq uncamelize};
use Exporter;
our @ISA = qw{Exporter};
our @EXPORT_OK = qw{elem_by_hexid %EBML_DEFINITION %MATROSKA_DEFINITION};
=head1 SYNOPSIS
use Parse::Matroska::Definitions qw{elem_by_hexid};
my $ebml_id = elem_by_hexid('1a45dfa3');
print "EBML ID $ebml_id->{elid}'s name: $ebml_id->{name}";
=head1 DESCRIPTION
Contains the definition of the EBML grammar as expected in
Matroska files. This module is meant mostly for internal use.
As this was extended from a script in mpv-player, some data
generated is apparently useless for regular module users
but is still relevant to the mpv-player script. Such data
is annotated as being for mpv compatibility.
=head1 NOTE
The API of this module is not yet considered stable.
=head1 GLOBALS
These global variables are considered B<immutable>.
=head2 @Parse::Matroska::Definitions::global_elem_list
A global list of known matroska elements. Useful for
mpv's matroska script, used for generating C headers
that parse matroska.
=head2 %Parse::Matroska::Definitions::global_elem_dict
A global hash of known matroska elements. Used internally
by L</elem_by_hexid($id)>.
=cut
@Parse::Matroska::Definitions::global_elem_list = ();
%Parse::Matroska::Definitions::global_elem_dict = ();
=head2 %EBML_DEFINITION
Optionally-importable hash of known EBML IDs belonging
to the EBML generic grammar.
=head2 %MATROSKA_DEFINITION
Optionally-importable hash of known EBML IDs belonging
to the Matroska-specific grammar.
=cut
our %EBML_DEFINITION = define_ebml();
our %MATROSKA_DEFINITION = define_matroska();
=method elem_by_hexid($id)
Returns an EBML Element Definition corresponding to the provided
hexadecimal string. Returns C<undef> if the element is unknown.
=cut
sub elem_by_hexid {
my ($elid) = @_;
return $Parse::Matroska::Definitions::global_elem_dict{$elid};
}
################################################
### Helper functions for document definition ###
################################################
# used by elem when setting the 'valname' key
use constant TYPE_MAP => {
uint => 'uint64_t',
str => 'char *',
binary => 'struct bstr',
ebml_id => 'uint32_t',
float => 'double',
sint => 'int64_t',
};
# this will be localized to "MATROSKA" or "EBML" on the elem declarations
our $ELEM_DEFINE_TYPE = undef;
=method elem($name,$elid,$valtype)
NOTE: never call this function yourself; it changes data structures
that are considered immutable outside of this package.
Internal API function that generates the EBML Element Definitions.
This API function returns an array which first element is C<$elid>
and the second is a generated hash. The generated hash is stored
in the @global_elem_list and %global_elem_dict.
The generated hash contains:
=for :list
= name
The EBML Element's name, given through C<$name>.
= elid
The EBML Element's hex id, given through C<$elid>. Used for lookups by L</elem_by_hexid($id)>.
= valtype
The EBML Element's type, given through C<$valtype>, except when C<$valtype> is an arrayref.
= multiple
If C<$name> ends with a C<*>, this is set as true and strips the C<*> from L</name>. Used to
mark elements that may be repeated.
= subelements
An arrayref of elements that may be children of this element, given through C<$valtype> if it
is an arrayref. Sets L</valtype> to C<sub> if there are subelements.
= subids
An arrayref listing all the L</elid>s of subelements, C<uniq>ified.
The following elements are for mpv compatibility:
=for :list
= definename
Name used for generating C #defines.
= fieldname
Name used for generating C struct fields.
= structname
Name used for generating C struct names.
= ebmltype
A pre-#defined constant to describe the element's type.
= valname
Typename used when declaring a struct field referring to this element.
=cut
sub elem {
my %e = (name => shift, elid => shift, valtype => shift);
# strip * from name, set 'multiple' if there was one
$e{multiple} = scalar $e{name} =~ s/\*$//;
# ELEM_DEFINE_TYPE is either MATROSKA or EBML
$e{definename} = "${ELEM_DEFINE_TYPE}_ID_".uc($e{name});
$e{fieldname} = uncamelize $e{name};
$e{structname} = "ebml_$e{fieldname}";
if (ref $e{valtype} eq 'HASH') {
$e{subelements} = $e{valtype};
$e{subids} = uniq map { $_->{elid} } values %{$e{subelements}};
$e{valtype} = 'sub';
$e{ebmltype} = 'EBML_TYPE_SUBELEMENTS';
$e{valname} = "struct $e{structname}";
} else {
$e{ebmltype} = "EBML_TYPE_\U$e{valtype}";
die "Unrecognized value type $e{valtype}" unless
defined ($e{valname} = TYPE_MAP->{$e{valtype}});
}
my $e = \%e;
push @Parse::Matroska::Definitions::global_elem_list, $e;
$Parse::Matroska::Definitions::global_elem_dict{$e{elid}} = $e;
return ($e{elid}, $e);
}
#############################################
### EBML and Matroska document definitons ###
#############################################
=method define_ebml
Internal function that defines the EBML generic grammar.
Must not be called from outside the package.
=cut
sub define_ebml {
local $ELEM_DEFINE_TYPE = 'EBML';
return (
elem('EBML', '1a45dfa3', {
elem('EBMLVersion', '4286', 'uint'),
elem('EBMLReadVersion', '42f7', 'uint'),
elem('EBMLMaxIDLength', '42f2', 'uint'),
elem('EBMLMaxSizeLength', '42f3', 'uint'),
elem('DocType', '4282', 'str'),
elem('DocTypeVersion', '4287', 'uint'),
elem('DocTypeReadVersion', '4285', 'uint'),
}),
elem('CRC32', 'bf', 'binary'),
elem('Void', 'ec', 'binary'),
);
}
=method define_matroska
Internal function that defines the Matroska-specific EBML grammar.
Must not be called from outside the package.
=cut
sub define_matroska {
local $ELEM_DEFINE_TYPE = 'MATROSKA';
return (
elem('Segment', '18538067', {
elem('SeekHead*', '114d9b74', {
elem('Seek*', '4dbb', {
elem('SeekID', '53ab', 'ebml_id'),
elem('SeekPosition', '53ac', 'uint'),
}),
}),
elem('Info*', '1549a966', {
elem('SegmentUID', '73a4', 'binary'),
elem('PrevUID', '3cb923', 'binary'),
elem('NextUID', '3eb923', 'binary'),
elem('TimecodeScale', '2ad7b1', 'uint'),
elem('DateUTC', '4461', 'sint'),
elem('Title', '7ba9', 'str'),
elem('MuxingApp', '4d80', 'str'),
elem('WritingApp', '5741', 'str'),
elem('Duration', '4489', 'float'),
}),
elem('Cluster*', '1f43b675', {
elem('Timecode', 'e7', 'uint'),
elem('BlockGroup*', 'a0', {
elem('Block', 'a1', 'binary'),
elem('BlockDuration', '9b', 'uint'),
elem('ReferenceBlock*', 'fb', 'sint'),
elem('DiscardPadding', '75A2', 'sint'),
}),
elem('SimpleBlock*', 'a3', 'binary'),
}),
elem('Tracks*', '1654ae6b', {
elem('TrackEntry*', 'ae', {
elem('TrackNumber', 'd7', 'uint'),
elem('TrackUID', '73c5', 'uint'),
elem('TrackType', '83', 'uint'),
elem('FlagEnabled', 'b9', 'uint'),
elem('FlagDefault', '88', 'uint'),
elem('FlagForced', '55aa', 'uint'),
elem('FlagLacing', '9c', 'uint'),
elem('MinCache', '6de7', 'uint'),
elem('MaxCache', '6df8', 'uint'),
elem('DefaultDuration', '23e383', 'uint'),
elem('TrackTimecodeScale', '23314f', 'float'),
elem('MaxBlockAdditionID', '55ee', 'uint'),
elem('Name', '536e', 'str'),
elem('Language', '22b59c', 'str'),
elem('CodecID', '86', 'str'),
elem('CodecPrivate', '63a2', 'binary'),
elem('CodecName', '258688', 'str'),
elem('CodecDecodeAll', 'aa', 'uint'),
elem('CodecDelay', '56AA', 'uint'),
elem('SeekPreRoll', '56BB', 'uint'),
elem('Video', 'e0', {
elem('FlagInterlaced', '9a', 'uint'),
elem('PixelWidth', 'b0', 'uint'),
elem('PixelHeight', 'ba', 'uint'),
elem('DisplayWidth', '54b0', 'uint'),
elem('DisplayHeight', '54ba', 'uint'),
elem('DisplayUnit', '54b2', 'uint'),
elem('FrameRate', '2383e3', 'float'),
elem('ColourSpace', '2eb524', 'binary'),
elem('StereoMode', '53b8', 'uint'),
}),
elem('Audio', 'e1', {
elem('SamplingFrequency', 'b5', 'float'),
elem('OutputSamplingFrequency', '78b5', 'float'),
elem('Channels', '9f', 'uint'),
elem('BitDepth', '6264', 'uint'),
}),
elem('ContentEncodings', '6d80', {
elem('ContentEncoding*', '6240', {
elem('ContentEncodingOrder', '5031', 'uint'),
elem('ContentEncodingScope', '5032', 'uint'),
elem('ContentEncodingType', '5033', 'uint'),
elem('ContentCompression', '5034', {
elem('ContentCompAlgo', '4254', 'uint'),
elem('ContentCompSettings', '4255', 'binary'),
}),
}),
}),
}),
}),
elem('Cues', '1c53bb6b', {
elem('CuePoint*', 'bb', {
elem('CueTime', 'b3', 'uint'),
elem('CueTrackPositions*', 'b7', {
elem('CueTrack', 'f7', 'uint'),
elem('CueClusterPosition', 'f1', 'uint'),
elem('CueRelativePosition','f0', 'uint'),
elem('CueDuration', 'b2', 'uint'),
}),
}),
}),
elem('Attachments', '1941a469', {
elem('AttachedFile*', '61a7', {
elem('FileDescription', '467e', 'str'),
elem('FileName', '466e', 'str'),
elem('FileMimeType', '4660', 'str'),
elem('FileData', '465c', 'binary'),
elem('FileUID', '46ae', 'uint'),
}),
}),
elem('Chapters', '1043a770', {
elem('EditionEntry*', '45b9', {
elem('EditionUID', '45bc', 'uint'),
elem('EditionFlagHidden', '45bd', 'uint'),
elem('EditionFlagDefault', '45db', 'uint'),
elem('EditionFlagOrdered', '45dd', 'uint'),
elem('ChapterAtom*', 'b6', {
elem('ChapterUID', '73c4', 'uint'),
elem('ChapterTimeStart', '91', 'uint'),
elem('ChapterTimeEnd', '92', 'uint'),
elem('ChapterFlagHidden', '98', 'uint'),
elem('ChapterFlagEnabled', '4598', 'uint'),
elem('ChapterSegmentUID', '6e67', 'binary'),
elem('ChapterSegmentEditionUID', '6ebc', 'uint'),
elem('ChapterDisplay*', '80', {
elem('ChapString', '85', 'str'),
elem('ChapLanguage*', '437c', 'str'),
elem('ChapCountry*', '437e', 'str'),
}),
}),
}),
}),
elem('Tags*', '1254c367', {
elem('Tag*', '7373', {
elem('Targets', '63c0', {
elem('TargetTypeValue', '68ca', 'uint'),
elem('TargetTrackUID', '63c5', 'uint'),
elem('TargetEditionUID', '63c9', 'uint'),
elem('TargetChapterUID', '63c4', 'uint'),
elem('TargetAttachmentUID', '63c6', 'uint'),
}),
elem('SimpleTag*', '67c8', {
elem('TagName', '45a3', 'str'),
elem('TagLanguage', '447a', 'str'),
elem('TagString', '4487', 'str'),
}),
}),
}),
}),
);
}
1;
-331
View File
@@ -1,331 +0,0 @@
use 5.008;
use strict;
use warnings;
# ABSTRACT: a mid-level representation of an EBML element
package Parse::Matroska::Element;
use Carp;
use List::Util qw{first};
=head1 SYNOPSIS
use Parse::Matroska::Reader;
my $reader = Parse::Matroska::Reader->new($path);
my $elem = $reader->read_element;
print "ID: $elem->{elid}\n";
print "Name: $elem->{name}\n";
print "Length: $elem->{content_len}\n";
print "Type: $elem->{type}\n";
print "Child count: ", scalar(@{$elem->all_children}), "\n";
if ($elem->{type} eq 'sub') {
while (my $chld = $elem->next_child) {
print "Child Name: $chld->{name}\n";
}
} else {
print "Value: ", $elem->get_value, "\n";
}
=head1 DESCRIPTION
Represents a single Matroska element as decoded by
L<Parse::Matroska::Reader>. This is essentially a hash
augmented with functions for delay-loading of binary
values and children elements.
=head1 NOTE
The API of this module is not yet considered stable.
=attr elid
The EBML Element ID, suitable for passing to
L<Parse::Matroska::Definitions/elem_by_hexid>.
=attr name
The EBML Element's name.
=attr type
The EBML Element's type. Can be C<uint>, C<sint>,
C<float>, C<ebml_id>, C<str> or C<binary>. See L</value>
for details.
Equivalent to
C<elem_by_hexid($elem-E<gt>{value})-E<gt>{valtype}>.
=attr value
The EBML Element's value. Should be obtained through
L</get_value>.
Is an unicode string if the L</type> is C<str>, that is,
the string has already been decoded by L<Encode/decode>.
Is C<undef> if the L</type> is C<binary> and the contents
were delay-loaded and not yet read. L</get_value> will
do the delayed load if needed.
Is an arrayref if the L</type> is C<sub>, containing
the children nodes that were already loaded.
Is a hashref if the L</type> is C<ebml_id>, containing
the referred element's information as defined in
L<Parse::Matroska::Definitions>. Calling
C<elem_by_hexid($elem-E<gt>{value}-E<gt>{elid})> will
return the same object as $elem->{value}.
=attr full_len
The entire length of this EBML Element, including
the header's.
=attr size_len
The length of the size marker. Used when calculating
L</full_len> from L</content_len>
=attr content_len
The length of the contents of this EBML Element,
which excludes the header.
=attr reader
A weakened reference to the associated
L<Parse::Matroska::Reader>.
=method new(%hash)
Creates a new Element initialized with the hash
given as argument.
=cut
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$self->initialize(@_);
return $self;
}
=method initialize(%hash)
Called by L</new> on initialization.
=cut
sub initialize {
my ($self, %args) = @_;
for (keys %args) {
$self->{$_} = $args{$_};
}
$self->{depth} = 0 unless $self->{depth};
}
=method skip
Called by the user to ignore the contents of this EBML node.
Needed when ignoring the children of a node.
=cut
sub skip {
my ($self) = @_;
my $reader = $self->{reader};
return unless $reader; # we don't have to skip if there's no reader
my $pos = $reader->getpos;
croak "Too late to skip, reads were already done"
if $pos ne $self->{data_pos};
$reader->skip($self->{content_len});
}
=method get_value($keep_bin)
Returns the value contained by this EBML element.
If the element has children, returns an arrayref to
the children elements that were already encountered.
If the element's type is C<binary> and the value was
delay-loaded, does the reading now.
If $keep_bin is true, the delay-loaded data is kept
as the L</value>, otherwise, further calls to
C<get_value> will reread the data from the L</reader>.
=cut
sub get_value {
my ($self, $keep_bin) = @_;
return undef if $self->{type} eq 'skip';
return $self->{value} if $self->{value};
my $reader = $self->{reader} or
croak "The associated Reader has been deleted";
# delay-loaded 'binary'
if ($self->{type} eq 'binary') {
croak "Cannot seek in the current Reader" unless $self->{data_pos};
# seek to the data position...
$reader->setpos($self->{data_pos});
# read the data, keeping it in value if requested
if ($keep_bin) {
$self->{value} = $reader->readlen($self->{content_len});
return $self->{value};
} else {
return $reader->readlen($self->{content_len});
}
}
}
=method next_child($read_bin)
Builtin iterator; reads and returns the next child element.
Always returns undef if the type isn't C<sub>.
Returns undef at the end of the iterator and resets itself to
point to the first element; so calling L</next_child($read_bin)>
after the iterator returned C<undef> will return the first child.
The optional C<$read_bin> parameter has the children elements
not delay-load their value if their type is C<binary>.
If all children elements have already been read, return
each element in-order as would be given by
L</all_children($recurse,$read_bin)>.
=cut
sub next_child {
my ($self, $read_bin) = @_;
return unless $self->{type} eq 'sub';
if ($self->{_all_children_read}) {
my $idx = $self->{_last_child} ||= 0;
if ($idx == @{$self->{value}}) {
# reset the iterator, returning undef once
$self->{_last_child} = 0;
return;
}
my $ret = $self->{value}->[$idx];
++$idx;
$self->{_last_child} = $idx;
return $ret;
}
my $len = defined $self->{remaining_len}
? $self->{remaining_len}
: $self->{content_len};
if ($len == 0) {
# we've read all children; switch into $self->{value} iteration mode
$self->{_all_children_read} = 1;
# return undef since the iterator will reset
return;
}
$self->{pos_offset} ||= 0;
my $pos = $self->{data_pos};
my $reader = $self->{reader} or croak "The associated reader has been deleted";
$reader->setpos($pos);
$reader->{fh}->seek($self->{pos_offset}, 1) if $pos;
my $chld = $reader->read_element($read_bin);
return undef unless defined $chld;
$self->{pos_offset} += $chld->{full_len};
$self->{remaining_len} = $len - $chld->{full_len};
if ($self->{remaining_len} < 0) {
croak "Child elements consumed $self->{remaining_len} more bytes than parent $self->{name} contained";
}
$chld->{depth} = $self->{depth} + 1;
$self->{value} ||= [];
push @{$self->{value}}, $chld;
return $chld;
}
=method all_children($recurse,$read_bin)
Calls L</populate_children($recurse,$read_bin)> on self
and returns an arrayref with the children nodes.
Both C<$recurse> and C<$read_bin> are optional and default
to false.
=cut
sub all_children {
my ($self, $recurse, $read_bin) = @_;
$self->populate_children($recurse, $read_bin);
return $self->{value};
}
=method children_by_name($name)
Searches in the already read children elements for all
elements with the EBML name C<$name>. Returns an array
containing all found elements. On scalar context,
returns only the first element found.
Croaks if the element's C<type> isn't C<sub>.
=cut
sub children_by_name {
my ($self, $name) = @_;
return unless defined wantarray; # don't do work if work isn't wanted
croak "Element can't have children" unless $self->{type} eq 'sub';
my @found = grep { $_->{name} eq $name } @{$self->{value}};
return @found if wantarray; # list
return shift @found if defined wantarray; # scalar
}
=method populate_children($recurse,$read_bin)
Populates the internal array of children elements, that is,
requests that the associated L<Matroska::Parser::Reader> reads
all children elements. Returns itself.
Returns false if the element's C<type> isn't C<sub>.
If C<$recurse> is provided and is true, the method will call
itself in the children elements with the same parameters it
received; this will build a full EBML tree.
If C<$read_bin> is provided and is true, disables delay-loading
of the contents of C<binary>-type nodes, reading the contents
to memory.
If both C<$recurse> and C<$read_bin> are true, entire EBML trees
can be loaded without requiring seeks, thus behaving correctly
on unseekable streams. If C<$read_bin> is false, the entire EBML
tree is still loaded, but calling L</get_value> on C<binary>-type
nodes will produce an error on unseekable streams.
=cut
sub populate_children {
my ($self, $recurse, $read_bin) = @_;
return unless $self->{type} eq 'sub';
if (@{$self->{value}} && $recurse) {
# only recurse
foreach (@{$self->{value}}) {
$_->populate_children($recurse, $read_bin);
}
return $self;
}
while (my $chld = $self->next_child($read_bin)) {
$chld->populate_children($recurse, $read_bin) if $recurse;
}
return $self;
}
1;
-426
View File
@@ -1,426 +0,0 @@
use 5.008;
use strict;
use warnings;
# ABSTRACT: a low-level reader for EBML files
package Parse::Matroska::Reader;
use Parse::Matroska::Definitions qw{elem_by_hexid};
use Parse::Matroska::Element;
use Carp;
use Scalar::Util qw{openhandle weaken};
use IO::Handle;
use IO::File;
use List::Util qw{first};
use Encode;
use constant BIGINT_TRY => 'Pari,GMP,FastCalc';
use Math::BigInt try => BIGINT_TRY;
use Math::BigRat try => BIGINT_TRY;
=head1 SYNOPSIS
use Parse::Matroska::Reader;
my $reader = Parse::Matroska::Reader->new($path);
$reader->close;
$reader->open(\$string_with_matroska_data);
my $elem = $reader->read_element;
print "Element ID: $elem->{elid}\n";
print "Element name: $elem->{name}\n";
if ($elem->{type} ne 'sub') {
print "Element value: $elem->get_value\n";
} else {
while (my $child = $elem->next_child) {
print "Child element: $child->{name}\n";
}
}
$reader->close;
=head1 DESCRIPTION
Reads EBML data, which is used in Matroska files.
This is a low-level reader which is meant to be used as a backend
for higher level readers. TODO: write the high level readers :)
=head1 NOTE
The API of this module is not yet considered stable.
=method new
Creates a new reader.
Calls L</open($arg)> with its arguments if provided.
=cut
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
$self->open(@_) if @_;
return $self;
}
=method open($arg)
Creates the internal filehandle. The argument can be:
=for :list
* An open filehandle or L<IO::Handle> object.
The filehandle is not C<dup()>ed, so calling L</close> in this
object will close the given filehandle as well.
* A scalar containing a path to a file.
* On perl v5.14 or newer, a scalarref pointing to EBML data.
For similar functionality in older perls, give an L<IO::String> object
or the handle to an already C<open>ed scalarref.
=cut
sub open {
my ($self, $arg) = @_;
$self->{fh} = openhandle($arg) || IO::File->new($arg, "<:raw")
or croak "Can't open $arg: $!";
}
=method close
Closes the internal filehandle.
=cut
sub close {
my ($self) = @_;
$self->{fh}->close;
delete $self->{fh};
}
# equivalent to $self->readlen(1), possibly faster
sub _getc {
my ($self) = @_;
my $c = $self->{fh}->getc;
croak "Can't do read of length 1: $!" if !defined $c && $!;
return $c;
}
=method readlen($length)
Reads C<$length> bytes from the internal filehandle.
=cut
sub readlen {
my ($self, $len) = @_;
my $data;
my $readlen = $self->{fh}->read($data, $len);
croak "Can't do read of length $len: $!"
unless defined $readlen;
return $data;
}
# converts a byte string into an integer
# we do so by converting the integer into a hex string (big-endian)
# and then reading the hex-string into an integer
sub _bin2int($) {
my ($bin) = @_;
# if the length is larger than 3
# the resulting integer might be larger than INT_MAX
if (length($bin) > 3) {
return Math::BigInt->from_hex(unpack("H*", $bin));
}
return hex(unpack("H*", $bin));
}
# creates a floating-point number with the given mantissa and exponent
sub _ldexp {
my ($mantissa, $exponent) = @_;
my $r = new Math::BigRat($mantissa);
return $r * Math::BigRat->new(2)**$exponent;
}
# NOTE: the read_* functions are hard to read because they're ports
# of even harder to read python functions.
# TODO: make them readable
=method read_id
Reads an EBML ID atom in hexadecimal string format, suitable
for passing to L<Parse::Matroska::Definitions/elem_by_hexid($id)>.
=cut
sub read_id {
my ($self) = @_;
my $t = $self->_getc;
return undef unless defined $t;
my $i = 0;
my $mask = 1<<7;
if (ord($t) == 0) {
croak "Matroska Syntax error: first byte of ID was \\0"
}
until (ord($t) & $mask) {
++$i;
$mask >>= 1;
}
# return hex string of the bytes we just read
return unpack "H*", ($t . $self->readlen($i));
}
=method read_size
Reads an EBML Data Size atom, which immediately follows
an EBML ID atom.
This returns an array consisting of:
=for :list
0. The length of the Data Size atom.
1. The value encoded in the Data Size atom, which is the length of all the data following it.
=cut
sub read_size {
my ($self) = @_;
my $t = $self->_getc;
my $i = 0;
my $mask = 1<<7;
if (ord($t) == 0) {
croak "Matroska Syntax error: first byte of data size was \\0"
}
until (ord($t) & $mask) {
++$i;
$mask >>= 1;
}
$t = $t & chr($mask-1); # strip length bits (keep only significant bits)
return ($i+1, _bin2int $t . $self->readlen($i));
}
=method read_str($length)
Reads a string of length C<$length> bytes from the internal filehandle.
The string is already L<Encode/decode>d from C<UTF-8>, which is the
standard Matroska string encoding.
=cut
{
my $utf8 = find_encoding("UTF-8");
sub read_str {
my ($self, $length) = @_;
return $utf8->decode($self->readlen($length));
}
}
=method read_uint($length)
Reads an unsigned integer of length C<$length> bytes
from the internal filehandle.
Returns a L<Math::BigInt> object if C<$length> is greater
than 4.
=cut
sub read_uint {
my ($self, $length) = @_;
return _bin2int $self->readlen($length);
}
=method read_sint($length)
Reads a signed integer of length C<$length> bytes
from the internal filehandle.
Returns a L<Math::BigInt> object if C<$length> is greater
than 4.
=cut
sub read_sint {
my ($self, $length) = @_;
my $i = $self->read_uint($length);
# Apply 2's complement to the unsigned int
my $mask = int(2 ** ($length * 8 - 1));
# if the most significant bit is set...
if ($i & $mask) {
# subtract the MSB twice
$i -= 2 * $mask;
}
return $i;
}
=method read_float($length)
Reads an IEEE floating point number of length C<$length>
bytes from the internal filehandle.
Only lengths C<4> and C<8> are supported (C C<float> and C<double>).
=cut
{
my $b1 = new Math::BigInt 1;
sub read_float {
my ($self, $length) = @_;
my $i = new Math::BigInt $self->read_uint($length)->bstr;
my $f;
# These evil expressions reinterpret an unsigned int as IEEE binary floats
if ($length == 4) {
$f = _ldexp(($i & ((1<<23) - 1)) + (1<<23), ($i>>23 & ((1<<8) - 1)) - 150);
$f = -$f if $i & ($b1<<31);
} elsif ($length == 8) {
$f = _ldexp(($i & (($b1<<52) - 1)) + ($b1<<52), ($i>>52 & ((1<<12) - 1)) - 1075);
$f = -$f if $i & ($b1<<63);
} else {
croak "Matroska Syntax error: unsupported IEEE float byte size $length";
}
return $f;
}
}
=method read_ebml_id($length)
Reads an EBML ID when it's encoded as the data inside another
EBML element, that is, when the enclosing element's C<type> is
C<ebml_id>.
This returns a hashref with the EBML element description as
defined in L<Parse::Matroska::Definitions>.
=cut
sub read_ebml_id {
my ($self, $length) = @_;
return elem_by_hexid(unpack("H*", $self->readlen($length)));
}
=method skip($length)
Skips C<$length> bytes in the internal filehandle.
=cut
sub skip {
my ($self, $len) = @_;
return if $self->{fh}->can('seek') && $self->{fh}->seek($len, 1);
$self->readlen($len);
return;
}
=method getpos
Wrapper for L<IO::Seekable/$io-E<gt>getpos> in the internal filehandle.
Returns undef if the internal filehandle can't C<getpos>.
=cut
sub getpos {
my ($self) = @_;
return undef unless $self->{fh}->can('getpos');
return $self->{fh}->getpos;
}
=method setpos($pos)
Wrapper for L<IO::Seekable/$io-E<gt>setpos> in the internal filehandle.
Returns C<undef> if the internal filehandle can't C<setpos>.
Croaks if C<setpos> does not seek to the requested position,
that is, if calling C<getpos> does not yield the same object
as the C<$pos> argument.
=cut
sub setpos {
my ($self, $pos) = @_;
return undef unless $pos && $self->{fh}->can('setpos');
my $ret = $self->{fh}->setpos($pos);
croak "Cannot seek to correct position"
unless $self->getpos eq $pos;
return $ret;
}
=method read_element($read_bin)
Reads a full EBML element from the internal filehandle.
Returns a L<Parse::Matroska::Element> object initialized with
the read data. If C<read_bin> is not present or is false, will
delay-load the contents of C<binary> type elements, that is,
they will only be loaded when calling C<get_value> on the
returned L<Parse::Matroska::Element> object.
Does not read the children of the element if its type is
C<sub>. Look into the L<Parse::Matroska::Element> interface
for details in how to read children elements.
Pass a true C<$read_bin> if the stream being read is not
seekable (C<getpos> is undef) and the contents of C<binary>
elements is desired, otherwise seeking errors or internal
filehandle corruption might occur.
=cut
sub read_element {
my ($self, $read_bin) = @_;
return undef if $self->{fh}->eof;
my $elem_pos = $self->getpos;
my $elid = $self->read_id;
my $elem_def = elem_by_hexid($elid);
my ($size_len, $content_len) = $self->read_size;
my $full_len = length($elid)/2 + $size_len + $content_len;
my $elem = Parse::Matroska::Element->new(
elid => $elid,
name => $elem_def && $elem_def->{name},
type => $elem_def && $elem_def->{valtype},
size_len => $size_len,
content_len => $content_len,
full_len => $full_len,
reader => $self,
elem_pos => $elem_pos,
data_pos => $self->getpos,
);
weaken($elem->{reader});
if (defined $elem_def) {
if ($elem->{type} eq 'sub') {
$elem->{value} = [];
} elsif ($elem->{type} eq 'str') {
$elem->{value} = $self->read_str($content_len);
} elsif ($elem->{type} eq 'ebml_id') {
$elem->{value} = $self->read_ebml_id($content_len);
} elsif ($elem->{type} eq 'uint') {
$elem->{value} = $self->read_uint($content_len);
} elsif ($elem->{type} eq 'sint') {
$elem->{value} = $self->read_sint($content_len);
} elsif ($elem->{type} eq 'float') {
$elem->{value} = $self->read_float($content_len);
} elsif ($elem->{type} eq 'skip') {
$self->skip($content_len);
} elsif ($elem->{type} eq 'binary') {
if ($read_bin) {
$elem->{value} = $self->readlen($content_len);
} else {
$self->skip($content_len);
}
} else {
die "Matroska Definition error: type $elem->{valtype} unknown"
}
} else {
$self->skip($content_len);
}
return $elem;
}
1;
=head1 CAVEATS
Children elements have to be processed as soon as an element
with children is found, or their children ignored with
L<Parse::Matroska::Element/skip>. Not doing so doesn't cause
errors but results in an invalid structure, with constant C<0>
depth.
To work correctly in unseekable streams, either the contents
of C<binary>-type elements has to be ignored or the C<read_bin>
flag to C<read_element> has to be true.
-37
View File
@@ -1,37 +0,0 @@
use strict;
use warnings;
# ABSTRACT: internally-used helper functions
package Parse::Matroska::Utils;
use Exporter;
our @ISA = qw{Exporter};
our @EXPORT_OK = qw{uniq uncamelize};
=method uniq(@array)
The same as L<List::MoreUtils/"uniq LIST">.
Included to avoid depending on it since it's
not a core module.
=cut
sub uniq(@) {
my %seen;
return grep { !$seen{$_}++ } @_;
}
=method uncamelize($string)
Converts a "StringLikeTHIS" into a
"string_like_this".
=cut
sub uncamelize($) {
local $_ = shift;
# lc followed by UC: lc_UC
s/(?<=[a-z])([A-Z])/_\L$1/g;
# UC followed by two lc: _UClclc
s/([A-Z])(?=[a-z]{2})/_\L$1/g;
# strip leading _ that the second regexp might add; lowercase all
s/^_//; lc
}
+9 -2
View File
@@ -7,6 +7,13 @@
-- Add at most 5000 * 2 files when starting a file (before + after).
MAXENTRIES = 5000
local options = require 'mp.options'
o = {
disabled = false
}
options.read_options(o)
function Set (t)
local set = {}
for _, v in pairs(t) do set[v] = true end
@@ -25,7 +32,7 @@ function add_files_at(index, files)
local oldcount = mp.get_property_number("playlist-count", 1)
for i = 1, #files do
mp.commandv("loadfile", files[i], "append")
mp.commandv("playlist_move", oldcount + i - 1, index + i - 1)
mp.commandv("playlist-move", oldcount + i - 1, index + i - 1)
end
end
@@ -49,7 +56,7 @@ end
function find_and_add_entries()
local path = mp.get_property("path", "")
local dir, filename = mputils.split_path(path)
if #dir == 0 then
if o.disabled or #dir == 0 then
return
end
local pl_count = mp.get_property_number("playlist-count", 1)
+9 -1
View File
@@ -6,9 +6,17 @@
local utils = require("mp.utils")
for i,name in ipairs(mp.get_property_native("property-list")) do
function observe(name)
mp.observe_property(name, "native", function(name, val)
print("property '" .. name .. "' changed to '" ..
utils.to_string(val) .. "'")
end)
end
for i,name in ipairs(mp.get_property_native("property-list")) do
observe(name)
end
for i,name in ipairs(mp.get_property_native("options")) do
observe("options/" .. name)
end
-169
View File
@@ -1,169 +0,0 @@
#! /usr/bin/env perl
# Generate C definitions for parsing Matroska files.
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/lib";
use Parse::Matroska::Definitions;
use Parse::Matroska::Reader;
use Getopt::Long;
use List::Util qw{max};
my @global_elem_list = @Parse::Matroska::Definitions::global_elem_list;
Getopt::Long::Configure(qw{auto_version auto_help});
my %opt;
GetOptions(\%opt,
"generate-header",
"generate-definitions",
"full",
);
if ($opt{"generate-header"}) {
generate_c_header();
} elsif ($opt{"generate-definitions"}) {
generate_c_definitions();
} else {
for (@ARGV) {
my $reader = Parse::Matroska::Reader->new($_ eq '-' ? \*STDIN : $_) or die $!;
while (my $elem = $reader->read_element($_ eq '-')) {
process_elem($elem, $_ eq '-');
}
}
}
# Generate declarations for libmpdemux/ebml_types.h
sub generate_c_header {
print "/* Generated by TOOLS/matroska.pl, do not edit manually */\n\n";
# Write a #define for the ElementID of each known element
for my $el (@global_elem_list) {
printf "#define %-40s 0x%s\n", $el->{definename}, $el->{elid};
}
print "\n";
# Define a struct for each ElementID that has child elements
for my $el (@global_elem_list) {
next unless $el->{subelements};
print "\nstruct $el->{structname} {\n";
# Figure out the length of the longest variable name
# Used for pretty-printing in the next step
my $l = max(map { length $_->{valname} } values %{$el->{subelements}});
# Output each variable, with pointers for array (multiple) elements
for my $subel (sort { $a->{definename} cmp $b->{definename} } values %{$el->{subelements}}) {
printf " %-${l}s %s%s;\n",
$subel->{valname}, $subel->{multiple}?'*':' ', $subel->{fieldname};
}
print "\n";
# Output a counter variable for each element
# (presence/absence for scalars, item count for arrays)
for my $subel (sort values %{$el->{subelements}}) {
print " int n_$subel->{fieldname};\n"
}
print "};\n";
}
print "\n";
# Output extern references for ebml_elem_desc structs for each of the elements
# These are defined by generate_c_definitions
for my $el (@global_elem_list) {
next unless $el->{subelements};
print "extern const struct ebml_elem_desc $el->{structname}_desc;\n";
}
print "\n";
# Output the max number of sub-elements a known element might have
printf "#define MAX_EBML_SUBELEMENTS %d\n",
max(map { scalar keys %{$_->{subelements}} }
grep { $_->{subelements} } @global_elem_list);
}
# Generate definitions for libmpdemux/ebml_defs.c
sub generate_c_definitions {
print "/* Generated by TOOLS/matroska.pl, do not edit manually */\n\n";
# ebml_defs.c uses macros declared in ebml.c
for my $el (@global_elem_list) {
print "\n";
if ($el->{subelements}) {
# set N for the next macros
print "#define N $el->{fieldname}\n";
# define a struct ebml_$N_desc and gets ready to define fields
# this secretly opens two scopes; hence the }}; at the end
print "E_S(\"$el->{name}\", ".scalar(keys %{$el->{subelements}}).")\n";
# define a field for each subelement
# also does lots of macro magic, but doesn't open a scope
for my $subel (sort { $a->{definename} cmp $b->{definename} } values %{$el->{subelements}}) {
print "F($subel->{definename}, $subel->{fieldname}, ".
($subel->{multiple}?'1':'0').")\n";
}
# close the struct
print "}};\n";
# unset N since we've used it
print "#undef N\n";
} else {
print "E(\"$el->{name}\", $el->{fieldname}, $el->{ebmltype})\n";
}
}
}
sub repr {
my @ret;
foreach (@_) {
if (/'/) {
s/"/\\"/g;
push @ret, "\"$_\"";
} else {
push @ret, "'$_'";
}
}
return @ret if wantarray;
return pop @ret if defined wantarray;
return;
}
sub process_elem {
my ($elem, $read_bin) = @_;
unless ($opt{full}) {
if ($elem->{name} eq 'Cluster' || $elem->{name} eq 'Cues') {
$elem->skip;
return;
}
}
die unless $elem;
if ($elem->{type} ne 'skip') {
print "$elem->{depth} $elem->{elid} $elem->{name} size: $elem->{content_len} value: ";
}
if ($elem->{type} eq 'sub') {
print "subelements:\n";
while (my $chld = $elem->next_child($read_bin)) {
process_elem($chld);
}
} elsif ($elem->{type} eq 'binary') {
my $t = "<skipped $elem->{content_len} bytes>";
if ($elem->{content_len} < 20) {
$t = unpack "H*", $elem->get_value;
}
print "binary $t\n";
delete $elem->{value};
} elsif ($elem->{type} eq 'ebml_id') {
print "binary $elem->{value}->{elid} (".($elem->{value}->{name}||"UNKNOWN").")\n";
} elsif ($elem->{type} eq 'skip') {
# skip
} elsif ($elem->{type} eq 'str') {
print "string ". repr($elem->get_value) . "\n";
} else {
print "$elem->{type} ". $elem->get_value ."\n";
}
}
+466
View File
@@ -0,0 +1,466 @@
#!/usr/bin/env python
"""
Generate C definitions for parsing Matroska files.
Can also be used to directly parse Matroska files and display their contents.
"""
#
# This file is part of MPlayer.
#
# MPlayer is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# MPlayer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with MPlayer; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# for compatibility with Python 2.x
from __future__ import print_function
elements_ebml = (
'EBML, 1a45dfa3, sub', (
'EBMLVersion, 4286, uint',
'EBMLReadVersion, 42f7, uint',
'EBMLMaxIDLength, 42f2, uint',
'EBMLMaxSizeLength, 42f3, uint',
'DocType, 4282, str',
'DocTypeVersion, 4287, uint',
'DocTypeReadVersion, 4285, uint',
),
'CRC32, bf, binary',
'Void, ec, binary',
)
elements_matroska = (
'Segment, 18538067, sub', (
'SeekHead*, 114d9b74, sub', (
'Seek*, 4dbb, sub', (
'SeekID, 53ab, ebml_id',
'SeekPosition, 53ac, uint',
),
),
'Info*, 1549a966, sub', (
'SegmentUID, 73a4, binary',
'PrevUID, 3cb923, binary',
'NextUID, 3eb923, binary',
'TimecodeScale, 2ad7b1, uint',
'DateUTC, 4461, sint',
'Title, 7ba9, str',
'MuxingApp, 4d80, str',
'WritingApp, 5741, str',
'Duration, 4489, float',
),
'Cluster*, 1f43b675, sub', (
'Timecode, e7, uint',
'BlockGroup*, a0, sub', (
'Block, a1, binary',
'BlockDuration, 9b, uint',
'ReferenceBlock*, fb, sint',
'DiscardPadding, 75A2, sint',
),
'SimpleBlock*, a3, binary',
),
'Tracks*, 1654ae6b, sub', (
'TrackEntry*, ae, sub', (
'TrackNumber, d7, uint',
'TrackUID, 73c5, uint',
'TrackType, 83, uint',
'FlagEnabled, b9, uint',
'FlagDefault, 88, uint',
'FlagForced, 55aa, uint',
'FlagLacing, 9c, uint',
'MinCache, 6de7, uint',
'MaxCache, 6df8, uint',
'DefaultDuration, 23e383, uint',
'TrackTimecodeScale, 23314f, float',
'MaxBlockAdditionID, 55ee, uint',
'Name, 536e, str',
'Language, 22b59c, str',
'CodecID, 86, str',
'CodecPrivate, 63a2, binary',
'CodecName, 258688, str',
'CodecDecodeAll, aa, uint',
'CodecDelay, 56aa, uint',
'SeekPreRoll, 56bb, uint',
'Video, e0, sub', (
'FlagInterlaced, 9a, uint',
'PixelWidth, b0, uint',
'PixelHeight, ba, uint',
'DisplayWidth, 54b0, uint',
'DisplayHeight, 54ba, uint',
'DisplayUnit, 54b2, uint',
'FrameRate, 2383e3, float',
'ColourSpace, 2eb524, binary',
'StereoMode, 53b8, uint',
'Colour, 55b0, sub', (
'MatrixCoefficients, 55B1, uint',
'BitsPerChannel, 55B2, uint',
'ChromaSubsamplingHorz, 55B3, uint',
'ChromaSubsamplingVert, 55B4, uint',
'CbSubsamplingHorz, 55B5, uint',
'CbSubsamplingVert, 55B6, uint',
'ChromaSitingHorz, 55B7, uint',
'ChromaSitingVert, 55B8, uint',
'Range, 55B9, uint',
'TransferCharacteristics, 55BA, uint',
'Primaries, 55BB, uint',
'MaxCLL, 55BC, uint',
'MaxFALL, 55BD, uint',
'MasteringMetadata, 55D0, sub', (
'PrimaryRChromaticityX, 55D1, float',
'PrimaryRChromaticityY, 55D2, float',
'PrimaryGChromaticityX, 55D3, float',
'PrimaryGChromaticityY, 55D4, float',
'PrimaryBChromaticityX, 55D5, float',
'PrimaryBChromaticityY, 55D6, float',
'WhitePointChromaticityX, 55D7, float',
'WhitePointChromaticityY, 55D8, float',
'LuminanceMax, 55D9, float',
'LuminanceMin, 55DA, float',
),
),
),
'Audio, e1, sub', (
'SamplingFrequency, b5, float',
'OutputSamplingFrequency, 78b5, float',
'Channels, 9f, uint',
'BitDepth, 6264, uint',
),
'ContentEncodings, 6d80, sub', (
'ContentEncoding*, 6240, sub', (
'ContentEncodingOrder, 5031, uint',
'ContentEncodingScope, 5032, uint',
'ContentEncodingType, 5033, uint',
'ContentCompression, 5034, sub', (
'ContentCompAlgo, 4254, uint',
'ContentCompSettings, 4255, binary',
),
),
),
),
),
'Cues, 1c53bb6b, sub', (
'CuePoint*, bb, sub', (
'CueTime, b3, uint',
'CueTrackPositions*, b7, sub', (
'CueTrack, f7, uint',
'CueClusterPosition, f1, uint',
'CueRelativePosition, f0, uint',
'CueDuration, b2, uint',
),
),
),
'Attachments, 1941a469, sub', (
'AttachedFile*, 61a7, sub', (
'FileDescription, 467e, str',
'FileName, 466e, str',
'FileMimeType, 4660, str',
'FileData, 465c, binary',
'FileUID, 46ae, uint',
),
),
'Chapters, 1043a770, sub', (
'EditionEntry*, 45b9, sub', (
'EditionUID, 45bc, uint',
'EditionFlagHidden, 45bd, uint',
'EditionFlagDefault, 45db, uint',
'EditionFlagOrdered, 45dd, uint',
'ChapterAtom*, b6, sub', (
'ChapterUID, 73c4, uint',
'ChapterTimeStart, 91, uint',
'ChapterTimeEnd, 92, uint',
'ChapterFlagHidden, 98, uint',
'ChapterFlagEnabled, 4598, uint',
'ChapterSegmentUID, 6e67, binary',
'ChapterSegmentEditionUID, 6ebc, uint',
'ChapterDisplay*, 80, sub', (
'ChapString, 85, str',
'ChapLanguage*, 437c, str',
'ChapCountry*, 437e, str',
),
),
),
),
'Tags*, 1254c367, sub', (
'Tag*, 7373, sub', (
'Targets, 63c0, sub', (
'TargetTypeValue, 68ca, uint',
'TargetTrackUID, 63c5, uint',
'TargetEditionUID, 63c9, uint',
'TargetChapterUID, 63c4, uint',
'TargetAttachmentUID, 63c6, uint',
),
'SimpleTag*, 67c8, sub', (
'TagName, 45a3, str',
'TagLanguage, 447a, str',
'TagString, 4487, str'
),
),
),
),
)
import sys
from math import ldexp
from binascii import hexlify
def byte2num(s):
return int(hexlify(s), 16)
class EOF(Exception): pass
def camelcase_to_words(name):
parts = []
start = 0
for i in range(1, len(name)):
if name[i].isupper() and (name[i-1].islower() or
name[i+1:i+2].islower()):
parts.append(name[start:i])
start = i
parts.append(name[start:])
return '_'.join(parts).lower()
class MatroskaElement(object):
def __init__(self, name, elid, valtype, namespace):
self.name = name
self.definename = '{0}_ID_{1}'.format(namespace, name.upper())
self.fieldname = camelcase_to_words(name)
self.structname = 'ebml_' + self.fieldname
self.elid = elid
self.valtype = valtype
if valtype == 'sub':
self.ebmltype = 'EBML_TYPE_SUBELEMENTS'
self.valname = 'struct ' + self.structname
else:
self.ebmltype = 'EBML_TYPE_' + valtype.upper()
try:
self.valname = {'uint': 'uint64_t', 'str': 'char *',
'binary': 'bstr', 'ebml_id': 'uint32_t',
'float': 'double', 'sint': 'int64_t',
}[valtype]
except KeyError:
raise SyntaxError('Unrecognized value type ' + valtype)
self.subelements = ()
def add_subelements(self, subelements):
self.subelements = subelements
self.subids = set(x[0].elid for x in subelements)
elementd = {}
elementlist = []
def parse_elems(l, namespace):
subelements = []
for el in l:
if isinstance(el, str):
name, hexid, eltype = [x.strip() for x in el.split(',')]
multiple = name.endswith('*')
name = name.strip('*')
new = MatroskaElement(name, hexid, eltype, namespace)
elementd[hexid] = new
elementlist.append(new)
subelements.append((new, multiple))
else:
new.add_subelements(parse_elems(el, namespace))
return subelements
parse_elems(elements_ebml, 'EBML')
parse_elems(elements_matroska, 'MATROSKA')
def printf(out, *args):
out.write(' '.join([str(x) for x in args]))
out.write('\n')
def generate_C_header(out):
printf(out, '// Generated by TOOLS/matroska.py, do not edit manually')
printf(out)
for el in elementlist:
printf(out, '#define {0.definename:40} 0x{0.elid}'.format(el))
printf(out)
for el in reversed(elementlist):
if not el.subelements:
continue
printf(out)
printf(out, 'struct {0.structname} {{'.format(el))
l = max(len(subel.valname) for subel, multiple in el.subelements)+1
for subel, multiple in el.subelements:
printf(out, ' {e.valname:{l}} {star}{e.fieldname};'.format(
e=subel, l=l, star=' *'[multiple]))
printf(out)
for subel, multiple in el.subelements:
printf(out, ' int n_{0.fieldname};'.format(subel))
printf(out, '};')
for el in elementlist:
if not el.subelements:
continue
printf(out, 'extern const struct ebml_elem_desc {0.structname}_desc;'.format(el))
printf(out)
printf(out, '#define MAX_EBML_SUBELEMENTS', max(len(el.subelements)
for el in elementlist))
def generate_C_definitions(out):
printf(out, '// Generated by TOOLS/matroska.py, do not edit manually')
printf(out)
for el in reversed(elementlist):
printf(out)
if el.subelements:
printf(out, '#define N', el.fieldname)
printf(out, 'E_S("{0}", {1})'.format(el.name, len(el.subelements)))
for subel, multiple in el.subelements:
printf(out, 'F({0.definename}, {0.fieldname}, {1})'.format(
subel, int(multiple)))
printf(out, '}};')
printf(out, '#undef N')
else:
printf(out, 'E("{0.name}", {0.fieldname}, {0.ebmltype})'.format(el))
def read(s, length):
t = s.read(length)
if len(t) != length:
raise EOF
return t
def read_id(s):
t = read(s, 1)
i = 0
mask = 128
if ord(t) == 0:
raise SyntaxError
while not ord(t) & mask:
i += 1
mask >>= 1
t += read(s, i)
return t
def read_vint(s):
t = read(s, 1)
i = 0
mask = 128
if ord(t) == 0:
raise SyntaxError
while not ord(t) & mask:
i += 1
mask >>= 1
t = bytes((ord(t) & (mask - 1),))
t += read(s, i)
return i+1, byte2num(t)
def read_str(s, length):
return read(s, length)
def read_uint(s, length):
t = read(s, length)
return byte2num(t)
def read_sint(s, length):
i = read_uint(s, length)
mask = 1 << (length * 8 - 1)
if i & mask:
i -= 2 * mask
return i
def read_float(s, length):
t = read(s, length)
i = byte2num(t)
if length == 4:
f = ldexp((i & 0x7fffff) + (1 << 23), (i >> 23 & 0xff) - 150)
if i & (1 << 31):
f = -f
elif length == 8:
f = ldexp((i & ((1 << 52) - 1)) + (1 << 52), (i >> 52 & 0x7ff) - 1075)
if i & (1 << 63):
f = -f
else:
raise SyntaxError
return f
def parse_one(s, depth, parent, maxlen):
elid = hexlify(read_id(s)).decode('ascii')
elem = elementd.get(elid)
if parent is not None and elid not in parent.subids and elid not in ('ec', 'bf'):
print('Unexpected:', elid)
if 1:
raise NotImplementedError
size, length = read_vint(s)
this_length = len(elid) / 2 + size + length
if elem is not None:
if elem.valtype != 'skip':
print(" " * depth, '[' + elid + ']', elem.name, 'size:', length, 'value:', end=' ')
if elem.valtype == 'sub':
print('subelements:')
while length > 0:
length -= parse_one(s, depth + 1, elem, length)
if length < 0:
raise SyntaxError
elif elem.valtype == 'str':
print('string', repr(read_str(s, length).decode('utf8', 'replace')))
elif elem.valtype in ('binary', 'ebml_id'):
t = read_str(s, length)
dec = ''
if elem.valtype == 'ebml_id':
idelem = elementd.get(hexlify(t).decode('ascii'))
if idelem is None:
dec = '(UNKNOWN)'
else:
dec = '({0.name})'.format(idelem)
if len(t) < 20:
t = hexlify(t).decode('ascii')
else:
t = '<{0} bytes>'.format(len(t))
print('binary', t, dec)
elif elem.valtype == 'uint':
print('uint', read_uint(s, length))
elif elem.valtype == 'sint':
print('sint', read_sint(s, length))
elif elem.valtype == 'float':
print('float', read_float(s, length))
elif elem.valtype == 'skip':
read(s, length)
else:
raise NotImplementedError
else:
print(depth, 'Unknown element:', elid, 'size:', length)
read(s, length)
return this_length
if __name__ == "__main__":
def parse_toplevel(s):
parse_one(s, 0, None, 1 << 63)
if sys.argv[1] == '--generate-header':
generate_C_header(sys.stdout)
elif sys.argv[1] == '--generate-definitions':
generate_C_definitions(sys.stdout)
else:
s = open(sys.argv[1], "rb")
while 1:
start = s.tell()
try:
parse_toplevel(s)
except EOF:
if s.tell() != start:
raise Exception("Unexpected end of file")
break
+2 -3
View File
@@ -67,13 +67,12 @@ EOF
chapters
editions
titles
duration
audio
audio-bitrate
audio-codec
audio-format
channels
samplerate
audio-codec-name
video
angle
@@ -1 +1 @@
profile=pseudo-gui
player-operation-mode=pseudo-gui
+6 -5
View File
@@ -151,15 +151,16 @@ for cur in ax:
cur.addLegend(offset = (-1, 1))
for e in G.sevents:
cur = ax[1 if e.type == "value" else 0]
if not cur in G.curveno:
G.curveno[cur] = 0
args = {'name': e.name,'antialias':True}
color = mkColor(colors[G.curveno[cur] % len(colors)])
if e.type == "event-signal":
args['symbol'] = e.marker
args['pen'] = None
args['symbolBrush'] = pg.mkBrush(color, width=0)
else:
if not cur in G.curveno:
G.curveno[cur] = 0
args['pen'] = pg.mkPen(mkColor(colors[G.curveno[cur] % len(colors)]), width=0)
G.curveno[cur] += 1
args['pen'] = pg.mkPen(color, width=0)
G.curveno[cur] += 1
n = cur.plot([x for x,y in e.vals], [y for x,y in e.vals], **args)
QtGui.QApplication.instance().exec_()
+3 -3
View File
@@ -89,7 +89,7 @@ class Libav < TravisDepsBuilder
{
"libav-stable" => {
:action => :stable,
:url => 'http://libav.org/releases/libav-11.tar.gz'
:url => 'http://libav.org/releases/libav-12.tar.gz'
},
"libav-git" => {
:action => :git,
@@ -97,7 +97,7 @@ class Libav < TravisDepsBuilder
},
"ffmpeg-stable" => {
:action => :stable,
:url => 'http://www.ffmpeg.org/releases/ffmpeg-2.4.tar.gz'
:url => 'http://www.ffmpeg.org/releases/ffmpeg-3.2.2.tar.gz'
},
"ffmpeg-git" => {
:action => :git,
@@ -107,7 +107,7 @@ class Libav < TravisDepsBuilder
end
def configure
[super, "--cc=#{ENV['CC']}"].join(" ")
[super, "--cc=#{ENV['CC']} --disable-asm"].join(" ")
end
end
+29
View File
@@ -0,0 +1,29 @@
#!/bin/sh
if [ "x$LIBAV" != "xffmpeg-git" ] || [ "x$TRAVIS_OS_NAME" != "xlinux" ]; then
# trigger build only on one of the matrix nodes
exit;
fi
if [ "x$TRAVIS_BRANCH" != "xmaster" ]; then
# only rebuild website with pushes to master
exit;
fi
TRAVIS_COMMIT_RANGE=${TRAVIS_COMMIT_RANGE:-HEAD^..}
if git diff --quiet --name-only --exit-code "$TRAVIS_COMMIT_RANGE" DOCS/; then
exit;
fi
body='{
"request": {
"branch":"master"
}}'
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Travis-API-Version: 3" \
-H "Authorization: token $WEBSITE_TRAVIS_TOKEN" \
-d "$body" \
https://api.travis-ci.org/repo/mpv-player%2Fmpv.io/requests
+26 -8
View File
@@ -4,11 +4,14 @@
use strict;
use warnings;
use warnings FATAL => 'uninitialized';
my $mpv = $ARGV[0] || 'mpv';
my @opts = parse_main_opts('--list-options', '^ (\-\-[^\s\*]*)\*?\s*(.*)');
die "Couldn't find any options" unless (@opts);
my @ao = parse_opts('--ao=help', '^ ([^\s\:]*)\s*: (.*)');
my @vo = parse_opts('--vo=help', '^ ([^\s\:]*)\s*: (.*)');
@@ -36,7 +39,8 @@ chomp $vf_str;
$protos_str = join(' ', @protos);
my $profile_comp = <<'EOS';
my $runtime_completions = <<'EOS';
profile|show-profile)
local -a profiles
local current
for current in "${(@f)$($words[1] --profile=help)}"; do
@@ -63,8 +67,25 @@ my $profile_comp = <<'EOS';
profiles=($profiles 'help[list profiles]')
_values -s , 'profile(s)' $profiles && rc=0
fi
;;
audio-device)
local -a audio_devices
local current
for current in "${(@f)$($words[1] --audio-device=help)}"; do
current=${current//\*/\\\*}
current=${current//\:/\\\:}
current=${current//\[/\\\[}
current=${current//\]/\\\]}
if [[ $current =~ ' '\'([^\']*)\'' \('(.*)'\)' ]]; then
audio_devices=($audio_devices "$match[1][$match[2]]")
fi
done
audio_devices=($audio_devices 'help[list audio devices]')
_values 'audio device' $audio_devices && rc=0
;;
EOS
chomp $profile_comp;
chomp $runtime_completions;
my $tmpl = <<"EOS";
#compdef mpv
@@ -111,9 +132,7 @@ $vf_str
&& rc=0
;;
profile|show-profile)
$profile_comp
;;
$runtime_completions
files)
compset -P '*,'
@@ -125,8 +144,7 @@ $profile_comp
local expl
_tags files urls
while _tags; do
_requested files expl 'media file' _files -g \\
"*.(#i)(asf|asx|avi|flac|flv|m1v|m2p|m2v|m4v|mjpg|mka|mkv|mov|mp3|mp4|mpe|mpeg|mpg|ogg|ogm|ogv|opus|qt|rm|ts|vob|wav|webm|wma|wmv|wv)(-.)" && rc=0
_requested files expl 'media file' _files && rc=0
if _requested urls; then
while _next_label urls expl URL; do
_urls "\$expl[@]" && rc=0
@@ -189,7 +207,7 @@ sub parse_main_opts {
}
} elsif ($line =~ /\[file\]/) {
$entry .= '->files';
} elsif ($name =~ /^--(ao|vo|af|vf|profile|show-profile)$/) {
} elsif ($name =~ /^--(ao|vo|af|vf|profile|show-profile|audio-device)$/) {
$entry .= "->$1";
}
push @list, $entry;
+1 -1
View File
@@ -1 +1 @@
0.17.0
0.23.0
+29
View File
@@ -0,0 +1,29 @@
branches:
only:
- master
- appveyor
environment:
matrix:
- MSYSTEM: MINGW64
- MSYSTEM: MINGW32
shallow_clone: true
test: off
install:
# Update core packages
- C:\msys64\usr\bin\pacman -Syyuu --noconfirm
# Update non-core packages
- C:\msys64\usr\bin\pacman -Suu --noconfirm
# Install required MSYS2 packages
- C:\msys64\usr\bin\pacman -S --noconfirm --needed perl python pkg-config
# Now MSYS2 is up to date, do the rest of the install from a bash script
- C:\msys64\usr\bin\bash -lc "cd \"$APPVEYOR_BUILD_FOLDER\" && exec ./TOOLS/appveyor-install.sh"
build_script:
- C:\msys64\usr\bin\bash -lc "cd \"$APPVEYOR_BUILD_FOLDER\" && exec ./TOOLS/appveyor-build.sh"
on_failure:
- type "%APPVEYOR_BUILD_FOLDER%\build\config.log"
cache:
- C:\msys64\var\cache\pacman\pkg
+44 -13
View File
@@ -138,6 +138,9 @@ static void mp_audio_destructor(void *ptr)
* available on every plane. The previous data is kept (for the smallest
* common number of samples before/after resize).
*
* This also makes sure the resulting buffer is writable (even in the case
* the buffer has the correct size).
*
* mpa->samples is not set or used.
*
* This function is flexible enough to handle format and channel layout
@@ -153,6 +156,12 @@ void mp_audio_realloc(struct mp_audio *mpa, int samples)
int size = get_plane_size(mpa, samples);
if (size < 0)
abort(); // oom or invalid parameters
if (!mp_audio_is_writeable(mpa)) {
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
av_buffer_unref(&mpa->allocated[n]);
mpa->planes[n] = NULL;
}
}
for (int n = 0; n < mpa->num_planes; n++) {
if (!mpa->allocated[n] || size != mpa->allocated[n]->size) {
if (av_buffer_realloc(&mpa->allocated[n], size) < 0)
@@ -171,7 +180,7 @@ void mp_audio_realloc(struct mp_audio *mpa, int samples)
// If the buffer is reallocated, also preallocate.
void mp_audio_realloc_min(struct mp_audio *mpa, int samples)
{
if (samples > mp_audio_get_allocated_size(mpa)) {
if (samples > mp_audio_get_allocated_size(mpa) || !mp_audio_is_writeable(mpa)) {
size_t alloc = ta_calc_prealloc_elems(samples);
if (alloc > INT_MAX)
abort(); // oom
@@ -257,13 +266,21 @@ void mp_audio_skip_samples(struct mp_audio *data, int samples)
data->pts += samples / (double)data->rate;
}
// Return the timestamp of the sample just after the end of this frame.
double mp_audio_end_pts(struct mp_audio *f)
{
if (f->pts == MP_NOPTS_VALUE || f->rate < 1)
return MP_NOPTS_VALUE;
return f->pts + f->samples / (double)f->rate;
}
// Clip the given frame to the given timestamp range. Adjusts the frame size
// and timestamp.
void mp_audio_clip_timestamps(struct mp_audio *f, double start, double end)
{
if (f->pts == MP_NOPTS_VALUE || f->rate < 1)
double f_end = mp_audio_end_pts(f);
if (f_end == MP_NOPTS_VALUE)
return;
double f_end = f->pts + f->samples / (double)f->rate;
if (end != MP_NOPTS_VALUE) {
if (f_end >= end) {
if (f->pts >= end) {
@@ -339,9 +356,9 @@ struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe)
mp_chmap_from_lavc(&lavc_chmap, avframe->channel_layout);
#if LIBAVUTIL_VERSION_MICRO >= 100
// FFmpeg being special again
if (lavc_chmap.num != avframe->channels)
mp_chmap_from_channels(&lavc_chmap, avframe->channels);
// FFmpeg being stupid POS again
if (lavc_chmap.num != av_frame_get_channels(avframe))
mp_chmap_from_channels(&lavc_chmap, av_frame_get_channels(avframe));
#endif
new->rate = avframe->sample_rate;
@@ -386,12 +403,9 @@ fail:
return NULL;
}
// Returns NULL on failure. The input is always unreffed.
struct AVFrame *mp_audio_to_avframe_and_unref(struct mp_audio *frame)
int mp_audio_to_avframe(struct mp_audio *frame, struct AVFrame *avframe)
{
struct AVFrame *avframe = av_frame_alloc();
if (!avframe)
goto fail;
av_frame_unref(avframe);
avframe->nb_samples = frame->samples;
avframe->format = af_to_avformat(frame->format);
@@ -402,8 +416,8 @@ struct AVFrame *mp_audio_to_avframe_and_unref(struct mp_audio *frame)
if (!avframe->channel_layout)
goto fail;
#if LIBAVUTIL_VERSION_MICRO >= 100
// FFmpeg being a stupid POS (but I respect it)
avframe->channels = frame->channels.num;
// FFmpeg being a stupid POS again
av_frame_set_channels(avframe, frame->channels.num);
#endif
avframe->sample_rate = frame->rate;
@@ -449,6 +463,23 @@ struct AVFrame *mp_audio_to_avframe_and_unref(struct mp_audio *frame)
avframe = tmp;
}
return 0;
fail:
av_frame_unref(avframe);
return -1;
}
// Returns NULL on failure. The input is always unreffed.
struct AVFrame *mp_audio_to_avframe_and_unref(struct mp_audio *frame)
{
struct AVFrame *avframe = av_frame_alloc();
if (!avframe)
goto fail;
if (mp_audio_to_avframe(frame, avframe) < 0)
goto fail;
talloc_free(frame);
return avframe;
+2
View File
@@ -73,6 +73,7 @@ void mp_audio_copy(struct mp_audio *dst, int dst_offset,
void mp_audio_copy_attributes(struct mp_audio *dst, struct mp_audio *src);
void mp_audio_skip_samples(struct mp_audio *data, int samples);
void mp_audio_clip_timestamps(struct mp_audio *f, double start, double end);
double mp_audio_end_pts(struct mp_audio *data);
bool mp_audio_is_writeable(struct mp_audio *data);
int mp_audio_make_writeable(struct mp_audio *data);
@@ -80,6 +81,7 @@ int mp_audio_make_writeable(struct mp_audio *data);
struct AVFrame;
struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe);
struct AVFrame *mp_audio_to_avframe_and_unref(struct mp_audio *frame);
int mp_audio_to_avframe(struct mp_audio *frame, struct AVFrame *avframe);
struct mp_audio_pool;
struct mp_audio_pool *mp_audio_pool_create(void *ta_parent);
-38
View File
@@ -230,44 +230,6 @@ void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels)
}
}
// Return channel index of the given speaker, or -1.
static int mp_chmap_find_speaker(const struct mp_chmap *map, int speaker)
{
for (int n = 0; n < map->num; n++) {
if (map->speaker[n] == speaker)
return n;
}
return -1;
}
static void mp_chmap_remove_speaker(struct mp_chmap *map, int speaker)
{
int index = mp_chmap_find_speaker(map, speaker);
if (index >= 0) {
for (int n = index; n < map->num - 1; n++)
map->speaker[n] = map->speaker[n + 1];
map->num--;
}
}
// Some decoders output additional, redundant channels, which are usually
// useless and will mess up proper audio output channel handling.
// map: channel map from which the channels should be removed
// requested: if not NULL, and if it contains any of the "useless" channels,
// don't remove them (this is for convenience)
void mp_chmap_remove_useless_channels(struct mp_chmap *map,
const struct mp_chmap *requested)
{
if (requested &&
mp_chmap_find_speaker(requested, MP_SPEAKER_ID_DL) >= 0)
return;
if (map->num > 2) {
mp_chmap_remove_speaker(map, MP_SPEAKER_ID_DL);
mp_chmap_remove_speaker(map, MP_SPEAKER_ID_DR);
}
}
// Return the ffmpeg/libav channel layout as in <libavutil/channel_layout.h>.
// Speakers not representable by ffmpeg/libav are dropped.
// Warning: this ignores the order of the channels, and will return a channel
-3
View File
@@ -109,9 +109,6 @@ void mp_chmap_fill_na(struct mp_chmap *map, int num);
void mp_chmap_from_channels(struct mp_chmap *dst, int num_channels);
void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels);
void mp_chmap_remove_useless_channels(struct mp_chmap *map,
const struct mp_chmap *requested);
uint64_t mp_chmap_to_lavc(const struct mp_chmap *src);
uint64_t mp_chmap_to_lavc_unchecked(const struct mp_chmap *src);
void mp_chmap_from_lavc(struct mp_chmap *dst, uint64_t src);
+13
View File
@@ -374,3 +374,16 @@ void mp_chmal_sel_log(const struct mp_chmap_sel *s, struct mp_log *log, int lev)
if (s->allow_any)
mp_msg(log, lev, " - anything\n");
}
// Select a channel map from the given list that fits best to c. Don't change
// *c if there's no match, or the list is empty.
void mp_chmap_sel_list(struct mp_chmap *c, struct mp_chmap *maps, int num_maps)
{
// This is a separate function to keep messing with mp_chmap_sel internals
// within this source file.
struct mp_chmap_sel sel = {
.chmaps = maps,
.num_chmaps = num_maps,
};
mp_chmap_sel_fallback(&sel, c);
}
+2
View File
@@ -47,4 +47,6 @@ bool mp_chmap_sel_get_def(const struct mp_chmap_sel *s, struct mp_chmap *map,
struct mp_log;
void mp_chmal_sel_log(const struct mp_chmap_sel *s, struct mp_log *log, int lev);
void mp_chmap_sel_list(struct mp_chmap *c, struct mp_chmap *maps, int num_maps);
#endif
+21 -24
View File
@@ -45,6 +45,7 @@ struct priv {
uint32_t skip_samples, trim_samples;
bool preroll_done;
double next_pts;
bool needs_reset;
AVRational codec_timebase;
};
@@ -85,7 +86,7 @@ static int init(struct dec_audio *da, const char *decoder)
struct priv *ctx = talloc_zero(NULL, struct priv);
da->priv = ctx;
ctx->codec_timebase = (AVRational){0};
ctx->codec_timebase = mp_get_codec_timebase(da->codec);
ctx->force_channel_map = c->force_channels;
@@ -99,13 +100,16 @@ static int init(struct dec_audio *da, const char *decoder)
lavc_context = avcodec_alloc_context3(lavc_codec);
ctx->avctx = lavc_context;
ctx->avframe = av_frame_alloc();
lavc_context->refcounted_frames = 1;
lavc_context->codec_type = AVMEDIA_TYPE_AUDIO;
lavc_context->codec_id = lavc_codec->id;
if (opts->downmix) {
#if LIBAVCODEC_VERSION_MICRO >= 100
lavc_context->pkt_timebase = ctx->codec_timebase;
#endif
if (opts->downmix && mpopts->audio_output_channels.num_chmaps == 1) {
lavc_context->request_channel_layout =
mp_chmap_to_lavc(&mpopts->audio_output_channels);
mp_chmap_to_lavc(&mpopts->audio_output_channels.chmaps[0]);
}
// Always try to set - option only exists for AC3 at the moment
@@ -173,6 +177,7 @@ static int control(struct dec_audio *da, int cmd, void *arg)
ctx->trim_samples = 0;
ctx->preroll_done = false;
ctx->next_pts = MP_NOPTS_VALUE;
ctx->needs_reset = false;
return CONTROL_TRUE;
}
return CONTROL_UNKNOWN;
@@ -184,6 +189,12 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt,
struct priv *priv = da->priv;
AVCodecContext *avctx = priv->avctx;
// If the decoder discards the timestamp for some reason, we use the
// interpolated PTS. Initialize it so that it works for the initial
// packet as well.
if (mpkt && priv->next_pts == MP_NOPTS_VALUE)
priv->next_pts = mpkt->pts;
int in_len = mpkt ? mpkt->len : 0;
AVPacket pkt;
@@ -192,7 +203,9 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt,
int got_frame = 0;
av_frame_unref(priv->avframe);
#if HAVE_AVCODEC_NEW_CODEC_API
if (priv->needs_reset)
control(da, ADCTRL_RESET, NULL);
int ret = avcodec_send_packet(avctx, &pkt);
if (ret >= 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
if (ret >= 0 && mpkt)
@@ -200,27 +213,11 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt,
ret = avcodec_receive_frame(avctx, priv->avframe);
if (ret >= 0)
got_frame = 1;
if (ret == AVERROR_EOF)
priv->needs_reset = true;
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
ret = 0;
}
#else
int ret = avcodec_decode_audio4(avctx, priv->avframe, &got_frame, &pkt);
if (mpkt) {
// At least "shorten" decodes sub-frames, instead of the whole packet.
// At least "mpc8" can return 0 and wants the packet again next time.
if (ret >= 0) {
ret = FFMIN(ret, mpkt->len); // sanity check against decoder overreads
mpkt->buffer += ret;
mpkt->len -= ret;
mpkt->pts = MP_NOPTS_VALUE; // don't reset PTS next time
}
// LATM may need many packets to find mux info
if (ret == AVERROR(EAGAIN)) {
mpkt->len = 0;
return 0;
}
}
#endif
if (ret < 0) {
MP_ERR(da, "Error decoding audio.\n");
return -1;
@@ -228,7 +225,7 @@ static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt,
if (!got_frame)
return 0;
double out_pts = mp_pts_from_av(priv->avframe->pkt_pts, &priv->codec_timebase);
double out_pts = mp_pts_from_av(priv->avframe->pts, &priv->codec_timebase);
struct mp_audio *mpframe = mp_audio_from_avframe(priv->avframe);
if (!mpframe)
+43 -16
View File
@@ -71,6 +71,7 @@ static void uninit(struct dec_audio *da)
av_freep(&lavf_ctx->pb->buffer);
av_freep(&lavf_ctx->pb);
avformat_free_context(lavf_ctx);
spdif_ctx->lavf_ctx = NULL;
}
}
@@ -82,12 +83,10 @@ static int init(struct dec_audio *da, const char *decoder)
spdif_ctx->use_dts_hd = da->opts->dtshd;
spdif_ctx->pool = mp_audio_pool_create(spdif_ctx);
if (strcmp(decoder, "dts-hd") == 0) {
decoder = "dts";
if (strcmp(decoder, "spdif_dts_hd") == 0)
spdif_ctx->use_dts_hd = true;
}
spdif_ctx->codec_id = mp_codec_to_av_codec_id(decoder);
spdif_ctx->codec_id = mp_codec_to_av_codec_id(da->codec->codec);
return spdif_ctx->codec_id != AV_CODEC_ID_NONE;
}
@@ -116,8 +115,9 @@ static int determine_codec_profile(struct dec_audio *da, AVPacket *pkt)
goto done;
}
int got_frame = 0;
if (avcodec_decode_audio4(ctx, frame, &got_frame, pkt) < 1 || !got_frame)
if (avcodec_send_packet(ctx, pkt) < 0)
goto done;
if (avcodec_receive_frame(ctx, frame) < 0)
goto done;
profile = ctx->profile;
@@ -171,11 +171,7 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt)
if (!stream)
goto fail;
#if HAVE_AVCODEC_HAS_CODECPAR
stream->codecpar->codec_id = spdif_ctx->codec_id;
#else
stream->codec->codec_id = spdif_ctx->codec_id;
#endif
AVDictionary *format_opts = NULL;
@@ -298,22 +294,53 @@ static const int codecs[] = {
AV_CODEC_ID_NONE
};
static void add_decoders(struct mp_decoder_list *list)
static bool find_codec(const char *name)
{
for (int n = 0; codecs[n] != AV_CODEC_ID_NONE; n++) {
const char *format = mp_codec_from_av_codec_id(codecs[n]);
if (format) {
mp_add_decoder(list, "spdif", format, format,
"libavformat/spdifenc audio pass-through decoder");
if (format && name && strcmp(format, name) == 0)
return true;
}
return false;
}
// codec is the libavcodec name of the source audio codec.
// pref is a ","-separated list of names, some of them which do not match with
// libavcodec names (like dts-hd).
struct mp_decoder_list *select_spdif_codec(const char *codec, const char *pref)
{
struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list);
if (!find_codec(codec))
return list;
bool spdif_allowed = false, dts_hd_allowed = false;
bstr sel = bstr0(pref);
while (sel.len) {
bstr decoder;
bstr_split_tok(sel, ",", &decoder, &sel);
if (decoder.len) {
if (bstr_equals0(decoder, codec))
spdif_allowed = true;
if (bstr_equals0(decoder, "dts-hd") && strcmp(codec, "dts") == 0)
spdif_allowed = dts_hd_allowed = true;
}
}
mp_add_decoder(list, "spdif", "dts", "dts-hd",
if (!spdif_allowed)
return list;
const char *suffix_name = dts_hd_allowed ? "dts_hd" : codec;
char name[80];
snprintf(name, sizeof(name), "spdif_%s", suffix_name);
mp_add_decoder(list, "spdif", codec, name,
"libavformat/spdifenc audio pass-through decoder");
return list;
}
const struct ad_functions ad_spdif = {
.name = "spdif",
.add_decoders = add_decoders,
.add_decoders = NULL,
.init = init,
.uninit = uninit,
.control = control,
+30 -20
View File
@@ -43,11 +43,12 @@
#include "audio/filter/af.h"
extern const struct ad_functions ad_lavc;
// Not a real codec - specially treated.
extern const struct ad_functions ad_spdif;
static const struct ad_functions * const ad_drivers[] = {
&ad_lavc,
&ad_spdif,
NULL
};
@@ -90,10 +91,10 @@ static struct mp_decoder_list *audio_select_decoders(struct dec_audio *d_audio)
struct mp_decoder_list *list = audio_decoder_list();
struct mp_decoder_list *new =
mp_select_decoders(list, codec, opts->audio_decoders);
if (d_audio->try_spdif) {
mp_select_decoders(d_audio->log, list, codec, opts->audio_decoders);
if (d_audio->try_spdif && codec) {
struct mp_decoder_list *spdif =
mp_select_decoder_list(list, codec, "spdif", opts->audio_spdif);
select_spdif_codec(codec, opts->audio_spdif);
mp_append_decoders(spdif, new);
talloc_free(new);
new = spdif;
@@ -108,6 +109,8 @@ static const struct ad_functions *find_driver(const char *name)
if (strcmp(ad_drivers[i]->name, name) == 0)
return ad_drivers[i];
}
if (strcmp(name, "spdif") == 0)
return &ad_spdif;
return NULL;
}
@@ -126,21 +129,18 @@ int audio_init_best_codec(struct dec_audio *d_audio)
const struct ad_functions *driver = find_driver(sel->family);
if (!driver)
continue;
MP_VERBOSE(d_audio, "Opening audio decoder %s:%s\n",
sel->family, sel->decoder);
MP_VERBOSE(d_audio, "Opening audio decoder %s\n", sel->decoder);
d_audio->ad_driver = driver;
if (init_audio_codec(d_audio, sel->decoder)) {
decoder = sel;
break;
}
MP_WARN(d_audio, "Audio decoder init failed for "
"%s:%s\n", sel->family, sel->decoder);
MP_WARN(d_audio, "Audio decoder init failed for %s\n", sel->decoder);
}
if (d_audio->ad_driver) {
d_audio->decoder_desc =
talloc_asprintf(d_audio, "%s [%s:%s]", decoder->desc, decoder->family,
decoder->decoder);
talloc_asprintf(d_audio, "%s (%s)", decoder->decoder, decoder->desc);
MP_VERBOSE(d_audio, "Selected audio codec: %s\n", d_audio->decoder_desc);
} else {
MP_ERR(d_audio, "Failed to initialize an audio decoder for codec '%s'.\n",
@@ -180,10 +180,14 @@ static void fix_audio_pts(struct dec_audio *da)
if (da->current_frame->pts != MP_NOPTS_VALUE) {
double newpts = da->current_frame->pts;
if (da->pts != MP_NOPTS_VALUE)
MP_STATS(da, "value %f audio-pts-err", da->pts - newpts);
// Keep the interpolated timestamp if it doesn't deviate more
// than 1 ms from the real one. (MKV rounded timestamps.)
if (da->pts == MP_NOPTS_VALUE || fabs(da->pts - newpts) > 0.001)
da->pts = da->current_frame->pts;
da->pts = newpts;
}
if (da->pts == MP_NOPTS_VALUE && da->header->missing_timestamps)
@@ -200,7 +204,9 @@ void audio_work(struct dec_audio *da)
if (da->current_frame)
return;
if (!da->packet && demux_read_packet_async(da->header, &da->packet) == 0) {
if (!da->packet && !da->new_segment &&
demux_read_packet_async(da->header, &da->packet) == 0)
{
da->current_state = DATA_WAIT;
return;
}
@@ -211,6 +217,7 @@ void audio_work(struct dec_audio *da)
da->packet = NULL;
}
bool had_input_packet = !!da->packet;
bool had_packet = da->packet || da->new_segment;
int ret = da->ad_driver->decode_packet(da, da->packet, &da->current_frame);
@@ -233,12 +240,12 @@ void audio_work(struct dec_audio *da)
fix_audio_pts(da);
bool segment_end = true;
bool segment_end = !da->current_frame && !had_input_packet;
if (da->current_frame) {
mp_audio_clip_timestamps(da->current_frame, da->start, da->end);
if (da->current_frame->pts != MP_NOPTS_VALUE && da->start != MP_NOPTS_VALUE)
segment_end = da->current_frame->pts >= da->start;
segment_end = da->current_frame->pts >= da->end;
if (da->current_frame->samples == 0) {
talloc_free(da->current_frame);
da->current_frame = NULL;
@@ -250,12 +257,15 @@ void audio_work(struct dec_audio *da)
struct demux_packet *new_segment = da->new_segment;
da->new_segment = NULL;
// Could avoid decoder reinit; would still need flush.
da->codec = new_segment->codec;
if (da->ad_driver)
da->ad_driver->uninit(da);
da->ad_driver = NULL;
audio_init_best_codec(da);
if (da->codec == new_segment->codec) {
audio_reset_decoding(da);
} else {
da->codec = new_segment->codec;
if (da->ad_driver)
da->ad_driver->uninit(da);
da->ad_driver = NULL;
audio_init_best_codec(da);
}
da->start = new_segment->start;
da->end = new_segment->end;
+3
View File
@@ -59,4 +59,7 @@ int audio_get_frame(struct dec_audio *d_audio, struct mp_audio **out_frame);
void audio_reset_decoding(struct dec_audio *d_audio);
// ad_spdif.c
struct mp_decoder_list *select_spdif_codec(const char *codec, const char *pref);
#endif /* MPLAYER_DEC_AUDIO_H */
+155 -178
View File
@@ -31,7 +31,6 @@
#include "af.h"
// Static list of filters
extern const struct af_info af_info_delay;
extern const struct af_info af_info_channels;
extern const struct af_info af_info_format;
extern const struct af_info af_info_volume;
@@ -46,7 +45,6 @@ extern const struct af_info af_info_lavfi;
extern const struct af_info af_info_rubberband;
static const struct af_info *const filter_list[] = {
&af_info_delay,
&af_info_channels,
&af_info_format,
&af_info_volume,
@@ -168,10 +166,10 @@ static struct af_instance *af_create(struct af_stream *s, char *name,
.replaygain_data = s->replaygain_data,
.out_pool = mp_audio_pool_create(af),
};
struct m_config *config = m_config_from_obj_desc(af, s->log, &desc);
if (m_config_apply_defaults(config, name, s->opts->af_defs) < 0)
goto error;
if (m_config_set_obj_params(config, args) < 0)
struct m_config *config =
m_config_from_obj_desc_and_args(af, s->log, NULL, &desc,
name, s->opts->af_defs, args);
if (!config)
goto error;
af->priv = config->optstruct;
@@ -210,29 +208,6 @@ static struct af_instance *af_prepend(struct af_stream *s,
return new;
}
/* Create and insert a new filter of type name after the filter in the
argument. This function can be called during runtime, the return
value is the new filter */
static struct af_instance *af_append(struct af_stream *s,
struct af_instance *af,
char *name, char **args)
{
if (!af)
af = s->first;
if (af == s->last)
af = s->last->prev;
// Create the new filter and make sure it is OK
struct af_instance *new = af_create(s, name, args);
if (!new)
return NULL;
// Update pointers
new->prev = af;
new->next = af->next;
af->next = new;
new->next->prev = new;
return new;
}
// Uninit and remove the filter "af"
static void af_remove(struct af_stream *s, struct af_instance *af)
{
@@ -275,8 +250,12 @@ static void af_print_filter_chain(struct af_stream *s, struct af_instance *at,
while (af) {
char b[128] = {0};
mp_snprintf_cat(b, sizeof(b), " [%s] ", af->info->name);
if (af->label)
mp_snprintf_cat(b, sizeof(b), "\"%s\" ", af->label);
if (af->data)
mp_snprintf_cat(b, sizeof(b), "%s", mp_audio_config_to_str(af->data));
if (af->auto_inserted)
mp_snprintf_cat(b, sizeof(b), " [a]");
if (af == at)
mp_snprintf_cat(b, sizeof(b), " <-");
MP_MSG(s, msg_level, "%s\n", b);
@@ -287,169 +266,156 @@ static void af_print_filter_chain(struct af_stream *s, struct af_instance *at,
MP_MSG(s, msg_level, " [ao] %s\n", mp_audio_config_to_str(&s->output));
}
static bool af_is_conversion_filter(struct af_instance *af)
{
return af && strcmp(af->info->name, "lavrresample") == 0;
}
// in is what af can take as input - insert a conversion filter if the actual
// input format doesn't match what af expects.
// Returns:
// AF_OK: must call af_reinit() or equivalent, format matches (or is closer)
// AF_FALSE: nothing was changed, format matches
// else: error
static int af_fix_format_conversion(struct af_stream *s,
struct af_instance **p_af,
struct mp_audio in)
{
int rv;
struct af_instance *af = *p_af;
struct af_instance *prev = af->prev;
struct mp_audio actual = *prev->data;
if (actual.format == in.format)
return AF_FALSE;
int dstfmt = in.format;
char *filter = "lavrresample";
if (!af_lavrresample_test_conversion(actual.format, dstfmt))
return AF_ERROR;
if (strcmp(filter, prev->info->name) == 0) {
if (prev->control(prev, AF_CONTROL_SET_FORMAT, &dstfmt) == AF_OK) {
*p_af = prev;
return AF_OK;
}
return AF_ERROR;
}
struct af_instance *new = af_prepend(s, af, filter, NULL);
if (new == NULL)
return AF_ERROR;
new->auto_inserted = true;
if (AF_OK != (rv = new->control(new, AF_CONTROL_SET_FORMAT, &dstfmt))) {
af_remove(s, new);
return rv;
}
*p_af = new;
return AF_OK;
}
// same as af_fix_format_conversion - only wrt. channels
static int af_fix_channels(struct af_stream *s, struct af_instance **p_af,
struct mp_audio in)
{
int rv;
struct af_instance *af = *p_af;
struct af_instance *prev = af->prev;
struct mp_audio actual = *prev->data;
if (mp_chmap_equals(&actual.channels, &in.channels))
return AF_FALSE;
if (prev->control(prev, AF_CONTROL_SET_CHANNELS, &in.channels) == AF_OK) {
*p_af = prev;
return AF_OK;
}
char *filter = "lavrresample";
struct af_instance *new = af_prepend(s, af, filter, NULL);
if (new == NULL)
return AF_ERROR;
new->auto_inserted = true;
if (AF_OK != (rv = new->control(new, AF_CONTROL_SET_CHANNELS, &in.channels)))
return rv;
*p_af = new;
return AF_OK;
}
static int af_fix_rate(struct af_stream *s, struct af_instance **p_af,
struct mp_audio in)
{
int rv;
struct af_instance *af = *p_af;
struct af_instance *prev = af->prev;
struct mp_audio actual = *prev->data;
if (actual.rate == in.rate)
return AF_FALSE;
if (prev->control(prev, AF_CONTROL_SET_RESAMPLE_RATE, &in.rate) == AF_OK) {
*p_af = prev;
return AF_OK;
}
char *filter = "lavrresample";
struct af_instance *new = af_prepend(s, af, filter, NULL);
if (new == NULL)
return AF_ERROR;
new->auto_inserted = true;
if (AF_OK != (rv = new->control(new, AF_CONTROL_SET_RESAMPLE_RATE, &in.rate)))
return rv;
*p_af = new;
return AF_OK;
}
static void reset_formats(struct af_stream *s)
{
struct mp_audio none = {0};
for (struct af_instance *af = s->first; af; af = af->next) {
af->control(af, AF_CONTROL_SET_RESAMPLE_RATE, &(int){0});
af->control(af, AF_CONTROL_SET_CHANNELS, &(struct mp_chmap){0});
af->control(af, AF_CONTROL_SET_FORMAT, &(int){0});
if (af != s->first && af != s->last)
mp_audio_copy_config(af->data, &none);
}
}
static int filter_reinit(struct af_instance *af)
{
struct af_instance *prev = af->prev;
assert(prev);
// Check if this is the first filter
struct mp_audio in = *prev->data;
// Reset just in case...
mp_audio_set_null_data(&in);
if (!mp_audio_config_valid(&in))
return AF_ERROR;
af->fmt_in = in;
int rv = af->control(af, AF_CONTROL_REINIT, &in);
if (rv == AF_OK && !mp_audio_config_equals(&in, prev->data))
rv = AF_FALSE; // conversion filter needed
if (rv == AF_FALSE)
af->fmt_in = in;
if (rv == AF_OK) {
if (!mp_audio_config_valid(af->data))
return AF_ERROR;
af->fmt_out = *af->data;
}
return rv;
}
static int filter_reinit_with_conversion(struct af_stream *s, struct af_instance *af)
{
int rv = filter_reinit(af);
// Conversion filter is needed
if (rv == AF_FALSE) {
// First try if we can change the output format of the previous
// filter to the input format the current filter is expecting.
struct mp_audio in = af->fmt_in;
if (af->prev != s->first && !mp_audio_config_equals(af->prev->data, &in)) {
// This should have been successful (because it succeeded
// before), even if just reverting to the old output format.
mp_audio_copy_config(af->prev->data, &in);
rv = filter_reinit(af->prev);
if (rv != AF_OK)
return rv;
}
if (!mp_audio_config_equals(af->prev->data, &in)) {
// Retry with conversion filter added.
struct af_instance *new =
af_prepend(s, af, "lavrresample", NULL);
if (!new)
return AF_ERROR;
new->auto_inserted = true;
mp_audio_copy_config(new->data, &in);
rv = filter_reinit(new);
if (rv != AF_OK)
af_remove(s, new);
}
if (rv == AF_OK)
rv = filter_reinit(af);
}
return rv;
}
static int af_find_output_conversion(struct af_stream *s, struct mp_audio *cfg)
{
assert(mp_audio_config_valid(&s->output));
assert(s->initialized > 0);
if (mp_chmap_equals_reordered(&s->input.channels, &s->output.channels))
return AF_ERROR;
// Heuristic to detect point of conversion. If it looks like something
// more complicated is going on, better bail out.
// We expect that the last filter converts channels.
struct af_instance *conv = s->last->prev;
if (!conv->auto_inserted)
return AF_ERROR;
if (!(mp_chmap_equals_reordered(&conv->fmt_in.channels, &s->input.channels) &&
mp_chmap_equals_reordered(&conv->fmt_out.channels, &s->output.channels)))
return AF_ERROR;
// Also, should be the only one which does auto conversion.
for (struct af_instance *af = s->first->next; af != s->last; af = af->next)
{
if (af != conv && af->auto_inserted &&
!mp_chmap_equals_reordered(&af->fmt_in.channels, &af->fmt_out.channels))
return AF_ERROR;
}
// And not if it's the only filter.
if (conv->prev == s->first && conv->next == s->last)
return AF_ERROR;
*cfg = s->output;
return AF_OK;
}
// Return AF_OK on success or AF_ERROR on failure.
// Warning:
// A failed af_reinit() leaves the audio chain behind in a useless, broken
// state (for example, format filters that were tentatively inserted stay
// inserted).
// In that case, you should always rebuild the filter chain, or abort.
static int af_reinit(struct af_stream *s)
static int af_do_reinit(struct af_stream *s, bool second_pass)
{
struct mp_audio convert_early = {0};
if (second_pass) {
// If a channel conversion happens, and it is done by an auto-inserted
// filter, then insert a filter to convert it early. Otherwise, do
// nothing and return immediately.
if (af_find_output_conversion(s, &convert_early) != AF_OK)
return AF_OK;
}
remove_auto_inserted_filters(s);
af_chain_forget_frames(s);
reset_formats(s);
s->first->fmt_in = s->first->fmt_out = s->input;
if (mp_audio_config_valid(&convert_early)) {
struct af_instance *new = af_prepend(s, s->first, "lavrresample", NULL);
if (!new)
return AF_ERROR;
new->auto_inserted = true;
mp_audio_copy_config(new->data, &convert_early);
int rv = filter_reinit(new);
if (rv != AF_DETACH && rv != AF_OK)
return AF_ERROR;
MP_VERBOSE(s, "Moving up output conversion.\n");
}
// Start with the second filter, as the first filter is the special input
// filter which needs no initialization.
struct af_instance *af = s->first->next;
// Up to 4 retries per filter (channel, rate, format conversions)
int max_retry = 4;
int retry = 0;
while (af) {
if (retry >= max_retry)
goto negotiate_error;
int rv = filter_reinit_with_conversion(s, af);
// Check if this is the first filter
struct mp_audio in = *af->prev->data;
// Reset just in case...
mp_audio_set_null_data(&in);
if (!mp_audio_config_valid(&in))
goto error;
af->fmt_in = in;
int rv = af->control(af, AF_CONTROL_REINIT, &in);
if (rv == AF_OK && !mp_audio_config_equals(&in, af->prev->data))
rv = AF_FALSE; // conversion filter needed
switch (rv) {
case AF_OK:
if (!mp_audio_config_valid(af->data))
goto error;
af->fmt_out = *af->data;
af = af->next;
break;
case AF_FALSE: { // Configuration filter is needed
if (af_fix_channels(s, &af, in) == AF_OK) {
retry++;
continue;
}
if (af_fix_rate(s, &af, in) == AF_OK) {
retry++;
continue;
}
// Do this last, to prevent "format->lavrresample" being added to
// the filter chain when output formats not supported by
// af_lavrresample are in use.
if (af_fix_format_conversion(s, &af, in) == AF_OK) {
retry++;
continue;
}
case AF_FALSE: {
// If the format conversion is (probably) caused by spdif, then
// (as a feature) drop the filter, instead of failing hard.
int fmt_in1 = af->prev->data->format;
int fmt_in2 = in.format;
int fmt_in2 = af->fmt_in.format;
if (af_fmt_is_valid(fmt_in1) && af_fmt_is_valid(fmt_in2)) {
bool spd1 = af_fmt_is_spdif(fmt_in1);
bool spd2 = af_fmt_is_spdif(fmt_in2);
@@ -460,7 +426,6 @@ static int af_reinit(struct af_stream *s)
struct af_instance *aft = af->prev;
af_remove(s, af);
af = aft->next;
retry++;
continue;
}
}
@@ -478,8 +443,6 @@ static int af_reinit(struct af_stream *s)
af->info->name, rv);
goto error;
}
if (af && !af->auto_inserted)
retry = 0;
}
/* Set previously unset fields in s->output to those of the filter chain
@@ -503,6 +466,19 @@ error:
return AF_ERROR;
}
static int af_reinit(struct af_stream *s)
{
int r = af_do_reinit(s, false);
if (r == AF_OK && mp_audio_config_valid(&s->output)) {
r = af_do_reinit(s, true);
if (r != AF_OK) {
MP_ERR(s, "Failed second pass filter negotiation.\n");
r = af_do_reinit(s, false);
}
}
return r;
}
// Uninit and remove all filters
void af_uninit(struct af_stream *s)
{
@@ -557,7 +533,7 @@ void af_destroy(struct af_stream *s)
format of the preferred output respectively. The function is
reentrant i.e. if called with an already initialized stream the
stream will be reinitialized.
If one of the prefered output parameters is 0 the one that needs
If one of the preferred output parameters is 0 the one that needs
no conversion is used (i.e. the output format in the last filter).
The return value is 0 if success and -1 if failure */
int af_init(struct af_stream *s)
@@ -602,12 +578,7 @@ struct af_instance *af_add(struct af_stream *s, char *name, char *label,
if (af_find_by_label(s, label))
return NULL;
struct af_instance *new;
// Insert the filter somewhere nice
if (af_is_conversion_filter(s->first->next))
new = af_append(s, s->first->next, name, args);
else
new = af_prepend(s, s->first->next, name, args);
struct af_instance *new = af_prepend(s, s->last, name, args);
if (!new)
return NULL;
new->label = talloc_strdup(new, label);
@@ -808,6 +779,12 @@ struct mp_audio *af_read_output_frame(struct af_stream *s)
return af_dequeue_output_frame(s->last);
}
void af_unread_output_frame(struct af_stream *s, struct mp_audio *frame)
{
struct af_instance *af = s->last;
MP_TARRAY_INSERT_AT(af, af->out_queued, af->num_out_queued, 0, frame);
}
// Make sure the caller can change data referenced by the frame.
// Return negative error code on failure (i.e. you can't write).
int af_make_writeable(struct af_instance *af, struct mp_audio *frame)
+1 -5
View File
@@ -112,9 +112,6 @@ struct af_stream {
enum af_control {
AF_CONTROL_REINIT = 1,
AF_CONTROL_RESET,
AF_CONTROL_SET_RESAMPLE_RATE,
AF_CONTROL_SET_FORMAT,
AF_CONTROL_SET_CHANNELS,
AF_CONTROL_SET_VOLUME,
AF_CONTROL_GET_VOLUME,
AF_CONTROL_SET_PAN_LEVEL,
@@ -151,6 +148,7 @@ void af_add_output_frame(struct af_instance *af, struct mp_audio *frame);
int af_filter_frame(struct af_stream *s, struct mp_audio *frame);
int af_output_frame(struct af_stream *s, bool eof);
struct mp_audio *af_read_output_frame(struct af_stream *s);
void af_unread_output_frame(struct af_stream *s, struct mp_audio *frame);
int af_make_writeable(struct af_instance *af, struct mp_audio *frame);
double af_calc_delay(struct af_stream *s);
@@ -160,6 +158,4 @@ int af_test_output(struct af_instance *af, struct mp_audio *out);
int af_from_ms(int n, float *in, int *out, int rate, float mi, float ma);
float af_softclip(float a);
bool af_lavrresample_test_conversion(int src_format, int dst_format);
#endif /* MPLAYER_AF_H */
-194
View File
@@ -1,194 +0,0 @@
/*
* This audio filter delays the output signal for the different
* channels and can be used for simple position panning.
* An extension for this filter would be a reverb.
*
* Original author: Anders
*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "common/common.h"
#include "af.h"
#define L 65536
#define UPDATEQI(qi) qi=(qi+1)&(L-1)
// Data for specific instances of this filter
typedef struct af_delay_s
{
void* q[AF_NCH]; // Circular queues used for delaying audio signal
int wi[AF_NCH]; // Write index
int ri; // Read index
float d[AF_NCH]; // Delay [ms]
char *delaystr;
}af_delay_t;
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
af_delay_t* s = af->priv;
switch(cmd){
case AF_CONTROL_REINIT:{
int i;
struct mp_audio *in = arg;
if (in->bps != 1 && in->bps != 2 && in->bps != 4) {
MP_FATAL(af, "Sample format not supported\n");
return AF_ERROR;
}
// Free prevous delay queues
for(i=0;i<af->data->nch;i++)
free(s->q[i]);
mp_audio_force_interleaved_format(in);
mp_audio_copy_config(af->data, in);
// Allocate new delay queues
for(i=0;i<af->data->nch;i++){
s->q[i] = calloc(L,af->data->bps);
if(NULL == s->q[i])
MP_FATAL(af, "Out of memory\n");
}
if(AF_OK != af_from_ms(AF_NCH, s->d, s->wi, af->data->rate, 0.0, 1000.0))
return AF_ERROR;
s->ri = 0;
for(i=0;i<AF_NCH;i++){
MP_DBG(af, "Channel %i delayed by %0.3fms\n",
i,MPCLAMP(s->d[i],0.0,1000.0));
MP_TRACE(af, "Channel %i delayed by %i samples\n",
i,s->wi[i]);
}
return AF_OK;
}
}
return AF_UNKNOWN;
}
// Deallocate memory
static void uninit(struct af_instance* af)
{
int i;
for(i=0;i<AF_NCH;i++)
free(((af_delay_t*)(af->priv))->q[i]);
}
static int filter_frame(struct af_instance *af, struct mp_audio *c)
{
if (!c)
return 0;
af_delay_t* s = af->priv; // Setup for this instance
int nch = c->nch; // Number of channels
int len = mp_audio_psize(c)/c->bps; // Number of sample in data chunk
int ri = 0;
int ch,i;
if (af_make_writeable(af, c) < 0) {
talloc_free(c);
return -1;
}
for(ch=0;ch<nch;ch++){
switch(c->bps){
case 1:{
int8_t* a = c->planes[0];
int8_t* q = s->q[ch];
int wi = s->wi[ch];
ri = s->ri;
for(i=ch;i<len;i+=nch){
q[wi] = a[i];
a[i] = q[ri];
UPDATEQI(wi);
UPDATEQI(ri);
}
s->wi[ch] = wi;
break;
}
case 2:{
int16_t* a = c->planes[0];
int16_t* q = s->q[ch];
int wi = s->wi[ch];
ri = s->ri;
for(i=ch;i<len;i+=nch){
q[wi] = a[i];
a[i] = q[ri];
UPDATEQI(wi);
UPDATEQI(ri);
}
s->wi[ch] = wi;
break;
}
case 4:{
int32_t* a = c->planes[0];
int32_t* q = s->q[ch];
int wi = s->wi[ch];
ri = s->ri;
for(i=ch;i<len;i+=nch){
q[wi] = a[i];
a[i] = q[ri];
UPDATEQI(wi);
UPDATEQI(ri);
}
s->wi[ch] = wi;
break;
}
}
}
s->ri = ri;
af_add_output_frame(af, c);
return 0;
}
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
af->control=control;
af->uninit=uninit;
af->filter_frame = filter_frame;
af_delay_t *s = af->priv;
int n = 1;
int i = 0;
char* cl = s->delaystr;
while(cl && n && i < AF_NCH ){
sscanf(cl,"%f%n",&s->d[i],&n);
if(n==0 || cl[n-1] == '\0')
break;
cl=&cl[n];
if (*cl != ',')
break;
cl++;
i++;
}
return AF_OK;
}
#define OPT_BASE_STRUCT af_delay_t
const struct af_info af_info_delay = {
.info = "Delay audio filter",
.name = "delay",
.open = af_open,
.priv_size = sizeof(af_delay_t),
.options = (const struct m_option[]) {
OPT_STRING("delays", delaystr, 0),
{0}
},
};
+8 -8
View File
@@ -29,10 +29,10 @@ struct priv {
int in_format;
int in_srate;
struct mp_chmap in_channels;
struct m_channels in_channels;
int out_format;
int out_srate;
struct mp_chmap out_channels;
struct m_channels out_channels;
int fail;
};
@@ -44,8 +44,8 @@ static void force_in_params(struct af_instance *af, struct mp_audio *in)
if (priv->in_format != AF_FORMAT_UNKNOWN)
mp_audio_set_format(in, priv->in_format);
if (priv->in_channels.num)
mp_audio_set_channels(in, &priv->in_channels);
if (priv->in_channels.num_chmaps > 0)
mp_audio_set_channels(in, &priv->in_channels.chmaps[0]);
if (priv->in_srate)
in->rate = priv->in_srate;
@@ -58,8 +58,8 @@ static void force_out_params(struct af_instance *af, struct mp_audio *out)
if (priv->out_format != AF_FORMAT_UNKNOWN)
mp_audio_set_format(out, priv->out_format);
if (priv->out_channels.num)
mp_audio_set_channels(out, &priv->out_channels);
if (priv->out_channels.num_chmaps > 0)
mp_audio_set_channels(out, &priv->out_channels.chmaps[0]);
if (priv->out_srate)
out->rate = priv->out_srate;
@@ -124,10 +124,10 @@ const struct af_info af_info_format = {
.options = (const struct m_option[]) {
OPT_AUDIOFORMAT("format", in_format, 0),
OPT_INTRANGE("srate", in_srate, 0, 1000, 8*48000),
OPT_CHMAP("channels", in_channels, CONF_MIN, .min = 0),
OPT_CHANNELS("channels", in_channels, 0, .min = 1),
OPT_AUDIOFORMAT("out-format", out_format, 0),
OPT_INTRANGE("out-srate", out_srate, 0, 1000, 8*48000),
OPT_CHMAP("out-channels", out_channels, CONF_MIN, .min = 0),
OPT_CHANNELS("out-channels", out_channels, 0, .min = 1),
OPT_FLAG("fail", fail, 0),
{0}
},
+140 -58
View File
@@ -31,9 +31,13 @@
#include <libavutil/bswap.h>
#include <libavutil/mem.h>
#include "config.h"
#include "common/av_common.h"
#include "common/common.h"
#include "af.h"
#include "audio/audio_buffer.h"
#include "audio/chmap_sel.h"
#include "audio/fmt-conversion.h"
@@ -54,13 +58,52 @@ typedef struct af_ac3enc_s {
struct mp_audio *pending; // unconsumed input data
int in_samples; // samples of input per AC3 frame
int out_samples; // upper bound on encoded output per AC3 frame
int in_sampleformat;
int64_t encoder_buffered;
int cfg_add_iec61937_header;
int cfg_bit_rate;
int cfg_min_channel_num;
char *cfg_encoder;
char **cfg_avopts;
} af_ac3enc_t;
// fmt carries the input format. Change it to the best next-possible format
// the encoder likely accepts.
static void select_encode_format(AVCodecContext *c, struct mp_audio *fmt)
{
int formats[AF_FORMAT_COUNT];
af_get_best_sample_formats(fmt->format, formats);
for (int n = 0; formats[n]; n++) {
const enum AVSampleFormat *lf = c->codec->sample_fmts;
for (int i = 0; lf && lf[i] != AV_SAMPLE_FMT_NONE; i++) {
int mpfmt = af_from_avformat(lf[i]);
if (mpfmt && mpfmt == formats[n]) {
mp_audio_set_format(fmt, mpfmt);
goto done_fmt;
}
}
}
done_fmt: ;
int rate =
af_select_best_samplerate(fmt->rate, c->codec->supported_samplerates);
if (rate > 0)
fmt->rate = rate;
struct mp_chmap_sel sel = {0};
const uint64_t *lch = c->codec->channel_layouts;
for (int n = 0; lch && lch[n]; n++) {
struct mp_chmap chmap = {0};
mp_chmap_from_lavc(&chmap, lch[n]);
mp_chmap_sel_add_map(&sel, &chmap);
}
struct mp_chmap res = fmt->channels;
mp_chmap_sel_adjust(&sel, &res);
if (!mp_chmap_is_empty(&res))
mp_audio_set_channels(fmt, &res);
}
// Initialization and runtime control
static int control(struct af_instance *af, int cmd, void *arg)
{
@@ -76,23 +119,17 @@ static int control(struct af_instance *af, int cmd, void *arg)
if (!af_fmt_is_pcm(in->format) || in->nch < s->cfg_min_channel_num)
return AF_DETACH;
mp_audio_set_format(in, s->in_sampleformat);
// At least currently, the AC3 encoder doesn't export sample rates.
in->rate = 48000;
select_encode_format(s->lavc_actx, in);
if (in->rate != 48000 && in->rate != 44100 && in->rate != 32000)
in->rate = 48000;
af->data->rate = in->rate;
mp_chmap_reorder_to_lavc(&in->channels);
if (in->nch > AC3_MAX_CHANNELS)
mp_audio_set_num_channels(in, AC3_MAX_CHANNELS);
mp_audio_set_format(af->data, AF_FORMAT_S_AC3);
mp_audio_set_num_channels(af->data, 2);
if (!mp_audio_config_equals(in, &orig_in))
return AF_FALSE;
s->in_samples = AC3_FRAME_SIZE;
if (s->cfg_add_iec61937_header) {
s->out_samples = AC3_FRAME_SIZE;
} else {
@@ -100,14 +137,11 @@ static int control(struct af_instance *af, int cmd, void *arg)
}
mp_audio_copy_config(s->input, in);
mp_audio_realloc(s->input, s->in_samples);
s->input->samples = 0;
talloc_free(s->pending);
s->pending = NULL;
MP_DBG(af, "af_lavcac3enc reinit: %d, %d, %d.\n",
in->nch, in->rate, s->in_samples);
MP_DBG(af, "reinit: %d, %d, %d.\n", in->nch, in->rate, s->in_samples);
int bit_rate = s->bit_rate ? s->bit_rate : default_bit_rate[in->nch];
@@ -118,6 +152,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
avcodec_close(s->lavc_actx);
// Put sample parameters
s->lavc_actx->sample_fmt = af_to_avformat(in->format);
s->lavc_actx->channels = in->nch;
s->lavc_actx->channel_layout = mp_chmap_to_lavc(&in->channels);
s->lavc_actx->sample_rate = in->rate;
@@ -127,14 +162,26 @@ static int control(struct af_instance *af, int cmd, void *arg)
MP_ERR(af, "Couldn't open codec %s, br=%d.\n", "ac3", bit_rate);
return AF_ERROR;
}
if (s->lavc_actx->frame_size < 1) {
MP_ERR(af, "encoder didn't specify input frame size\n");
return AF_ERROR;
}
}
if (s->lavc_actx->frame_size != AC3_FRAME_SIZE) {
MP_ERR(af, "lavcac3enc: unexpected ac3 "
"encoder frame size %d\n", s->lavc_actx->frame_size);
return AF_ERROR;
}
s->in_samples = s->lavc_actx->frame_size;
mp_audio_realloc(s->input, s->in_samples);
s->input->samples = 0;
s->encoder_buffered = 0;
return AF_OK;
}
case AF_CONTROL_RESET:
if (avcodec_is_open(s->lavc_actx))
avcodec_flush_buffers(s->lavc_actx);
talloc_free(s->pending);
s->pending = NULL;
s->input->samples = 0;
s->encoder_buffered = 0;
return AF_OK;
}
return AF_UNKNOWN;
}
@@ -156,8 +203,8 @@ static void uninit(struct af_instance* af)
static void update_delay(struct af_instance *af)
{
af_ac3enc_t *s = af->priv;
af->delay = ((s->pending ? s->pending->samples : 0) + s->input->samples) /
(double)s->input->rate;
af->delay = ((s->pending ? s->pending->samples : 0) + s->input->samples +
s->encoder_buffered) / (double)s->input->rate;
}
static int filter_frame(struct af_instance *af, struct mp_audio *audio)
@@ -190,6 +237,9 @@ static bool fill_buffer(struct af_instance *af)
af->delay = 0;
if (s->pending) {
if (!mp_audio_is_writeable(s->input))
assert(s->input->samples == 0); // we can't have sent a partial frame
mp_audio_realloc_min(s->input, s->in_samples);
int copy = MPMIN(s->in_samples - s->input->samples, s->pending->samples);
s->input->samples += copy;
mp_audio_copy(s->input, s->input->samples - copy, s->pending, 0, copy);
@@ -199,12 +249,27 @@ static bool fill_buffer(struct af_instance *af)
return s->input->samples >= s->in_samples;
}
static int filter_out(struct af_instance *af)
// Return <0 on error, 0 on need more input, 1 on success (and *frame set).
// To actually advance the read pointer, set s->input->samples=0 afterwards.
static int read_input_frame(struct af_instance *af, AVFrame *frame)
{
af_ac3enc_t *s = af->priv;
if (!fill_buffer(af))
return 0; // need more input
if (mp_audio_to_avframe(s->input, frame) < 0)
return -1;
return 1;
}
static int filter_out(struct af_instance *af)
{
af_ac3enc_t *s = af->priv;
if (!s->pending)
return 0;
AVFrame *frame = av_frame_alloc();
if (!frame) {
MP_FATAL(af, "Could not allocate memory \n");
@@ -212,29 +277,43 @@ static int filter_out(struct af_instance *af)
}
int err = -1;
frame->nb_samples = s->in_samples;
frame->format = s->lavc_actx->sample_fmt;
frame->channel_layout = s->lavc_actx->channel_layout;
assert(s->input->num_planes <= AV_NUM_DATA_POINTERS);
frame->extended_data = frame->data;
for (int n = 0; n < s->input->num_planes; n++)
frame->data[n] = s->input->planes[n];
frame->linesize[0] = s->input->samples * s->input->sstride;
AVPacket pkt = {0};
av_init_packet(&pkt);
int ok;
int lavc_ret = avcodec_encode_audio2(s->lavc_actx, &pkt, frame, &ok);
av_frame_free(&frame);
s->input->samples = 0;
if (lavc_ret < 0 || !ok) {
// Send input as long as it wants.
while (1) {
err = read_input_frame(af, frame);
if (err < 0)
goto done;
if (err == 0)
break;
err = -1;
int lavc_ret = avcodec_send_frame(s->lavc_actx, frame);
// On EAGAIN, we're supposed to read remaining output.
if (lavc_ret == AVERROR(EAGAIN))
break;
if (lavc_ret < 0) {
MP_FATAL(af, "Encode failed.\n");
goto done;
}
s->encoder_buffered += s->input->samples;
s->input->samples = 0;
}
int lavc_ret = avcodec_receive_packet(s->lavc_actx, &pkt);
if (lavc_ret == AVERROR(EAGAIN)) {
// Need to buffer more input.
err = 0;
goto done;
}
if (lavc_ret < 0) {
MP_FATAL(af, "Encode failed.\n");
goto done;
}
MP_DBG(af, "avcodec_encode_audio got %d, pending %d.\n",
pkt.size, s->pending->samples);
pkt.size, s->pending->samples + s->input->samples);
s->encoder_buffered -= AC3_FRAME_SIZE;
struct mp_audio *out =
mp_audio_pool_get(af->out_pool, af->data, s->out_samples);
@@ -271,11 +350,12 @@ static int filter_out(struct af_instance *af)
swap_16((uint16_t *)(buf + header_len), pkt.size / 2);
out->samples = frame_size / out->sstride;
af_add_output_frame(af, out);
update_delay(af);
err = 0;
done:
av_packet_unref(&pkt);
av_frame_free(&frame);
update_delay(af);
return err;
}
@@ -287,9 +367,9 @@ static int af_open(struct af_instance* af){
af->filter_frame = filter_frame;
af->filter_out = filter_out;
s->lavc_acodec = avcodec_find_encoder_by_name("ac3");
s->lavc_acodec = avcodec_find_encoder_by_name(s->cfg_encoder);
if (!s->lavc_acodec) {
MP_ERR(af, "Audio LAVC, couldn't find encoder for codec %s.\n", "ac3");
MP_ERR(af, "Couldn't find encoder %s.\n", s->cfg_encoder);
return AF_ERROR;
}
@@ -298,35 +378,34 @@ static int af_open(struct af_instance* af){
MP_ERR(af, "Audio LAVC, couldn't allocate context!\n");
return AF_ERROR;
}
const enum AVSampleFormat *fmts = s->lavc_acodec->sample_fmts;
for (int i = 0; fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
s->in_sampleformat = af_from_avformat(fmts[i]);
if (s->in_sampleformat) {
s->lavc_actx->sample_fmt = fmts[i];
break;
}
}
if (!s->in_sampleformat) {
MP_ERR(af, "Audio LAVC, encoder doesn't "
"support expected sample formats!\n");
if (mp_set_avopts(af->log, s->lavc_actx, s->cfg_avopts) < 0)
return AF_ERROR;
// For this one, we require the decoder to expert lists of all supported
// parameters. (Not all decoders do that, but the ones we're interested
// in do.)
if (!s->lavc_acodec->sample_fmts ||
!s->lavc_acodec->channel_layouts)
{
MP_ERR(af, "Audio encoder doesn't list supported parameters.\n");
return AF_ERROR;
}
MP_VERBOSE(af, "[af_lavcac3enc]: in sample format: %s\n",
af_fmt_to_str(s->in_sampleformat));
s->input = talloc_zero(s, struct mp_audio);
if (s->cfg_bit_rate) {
int i;
for (i = 0; i < 19; i++) {
if (ac3_bitrate_tab[i] == s->cfg_bit_rate)
if (ac3_bitrate_tab[i] == s->cfg_bit_rate) {
s->bit_rate = ac3_bitrate_tab[i] * 1000;
break;
}
}
if (i >= 19) {
MP_WARN(af, "af_lavcac3enc unable set unsupported "
"bitrate %d, use default bitrate (check manpage to see "
"supported bitrates).\n", s->cfg_bit_rate);
s->cfg_bit_rate = 0;
MP_WARN(af, "unable set unsupported bitrate %d, use default "
"bitrate (check manpage to see supported bitrates).\n",
s->cfg_bit_rate);
}
}
@@ -344,12 +423,15 @@ const struct af_info af_info_lavcac3enc = {
.cfg_add_iec61937_header = 1,
.cfg_bit_rate = 640,
.cfg_min_channel_num = 3,
.cfg_encoder = "ac3",
},
.options = (const struct m_option[]) {
OPT_FLAG("tospdif", cfg_add_iec61937_header, 0),
OPT_CHOICE_OR_INT("bitrate", cfg_bit_rate, 0, 32, 640,
({"auto", 0}, {"default", 0})),
OPT_INTRANGE("minch", cfg_min_channel_num, 0, 2, 6),
OPT_STRING("encoder", cfg_encoder, 0),
OPT_KEYVALUELIST("o", cfg_avopts, 0),
{0}
},
};
+16 -40
View File
@@ -99,10 +99,6 @@ static double get_delay(struct af_resample *s)
return avresample_get_delay(s->avrctx) / (double)s->in_rate +
avresample_available(s->avrctx) / (double)s->out_rate;
}
static void drop_all_output(struct af_resample *s)
{
while (avresample_read(s->avrctx, NULL, 1000) > 0) {}
}
static int get_out_samples(struct af_resample *s, int in_samples)
{
return avresample_get_out_samples(s->avrctx, in_samples);
@@ -113,18 +109,9 @@ static double get_delay(struct af_resample *s)
int64_t base = s->in_rate * (int64_t)s->out_rate;
return swr_get_delay(s->avrctx, base) / (double)base;
}
static void drop_all_output(struct af_resample *s)
{
while (swr_drop_output(s->avrctx, 1000) > 0) {}
}
static int get_out_samples(struct af_resample *s, int in_samples)
{
#if LIBSWRESAMPLE_VERSION_MAJOR > 1 || LIBSWRESAMPLE_VERSION_MINOR >= 2
return swr_get_out_samples(s->avrctx, in_samples);
#else
return av_rescale_rnd(in_samples, s->out_rate, s->in_rate, AV_ROUND_UP)
+ swr_get_delay(s->avrctx, s->out_rate);
#endif
}
#endif
@@ -173,12 +160,6 @@ static int check_output_conversion(int mp_format)
return af_to_avformat(mp_format);
}
bool af_lavrresample_test_conversion(int src_format, int dst_format)
{
return af_to_avformat(src_format) != AV_SAMPLE_FMT_NONE &&
check_output_conversion(dst_format) != AV_SAMPLE_FMT_NONE;
}
static struct mp_chmap fudge_pairs[][2] = {
{MP_CHMAP2(BL, BR), MP_CHMAP2(SL, SR)},
{MP_CHMAP2(SL, SR), MP_CHMAP2(BL, BR)},
@@ -407,28 +388,22 @@ static int control(struct af_instance *af, int cmd, void *arg)
r = configure_lavrr(af, in, out, true);
return r;
}
case AF_CONTROL_SET_FORMAT: {
int format = *(int *)arg;
if (format && check_output_conversion(format) == AV_SAMPLE_FMT_NONE)
return AF_FALSE;
mp_audio_set_format(af->data, format);
return AF_OK;
}
case AF_CONTROL_SET_CHANNELS: {
mp_audio_set_channels(af->data, (struct mp_chmap *)arg);
return AF_OK;
}
case AF_CONTROL_SET_RESAMPLE_RATE:
af->data->rate = *(int *)arg;
return AF_OK;
case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: {
s->playback_speed = *(double *)arg;
return AF_OK;
}
case AF_CONTROL_RESET:
if (s->avrctx)
drop_all_output(s);
if (s->avrctx) {
#if HAVE_LIBSWRESAMPLE
swr_close(s->avrctx);
if (swr_init(s->avrctx) < 0) {
close_lavrr(af);
return AF_ERROR;
}
#else
while (avresample_read(s->avrctx, NULL, 1000) > 0) {}
#endif
}
return AF_OK;
}
return AF_UNKNOWN;
@@ -500,19 +475,20 @@ static void reorder_planes(struct mp_audio *mpa, int *reorder,
static int filter_resample(struct af_instance *af, struct mp_audio *in)
{
struct af_resample *s = af->priv;
struct mp_audio *out = NULL;
if (!s->avrctx)
goto error;
int samples = get_out_samples(s, in ? in->samples : 0);
struct mp_audio out_format = s->pool_fmt;
struct mp_audio *out = mp_audio_pool_get(af->out_pool, &out_format, samples);
out = mp_audio_pool_get(af->out_pool, &out_format, samples);
if (!out)
goto error;
if (in)
mp_audio_copy_attributes(out, in);
if (!s->avrctx)
goto error;
if (out->samples) {
out->samples = resample_frame(s->avrctx, out, in);
if (out->samples < 0)
+138 -124
View File
@@ -28,12 +28,11 @@
#include "af.h"
// Data for specific instances of this filter
typedef struct af_pan_s
{
int nch; // Number of output channels; zero means same as input
float level[AF_NCH][AF_NCH]; // Gain level for each channel
char *matrixstr;
}af_pan_t;
typedef struct af_pan_s {
int nch; // Number of output channels; zero means same as input
float level[AF_NCH][AF_NCH]; // Gain level for each channel
char *matrixstr;
} af_pan_t;
static void set_channels(struct mp_audio *mpa, int num)
{
@@ -44,129 +43,17 @@ static void set_channels(struct mp_audio *mpa, int num)
mp_audio_set_channels(mpa, &map);
}
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
static void parse_matrix(struct af_instance *af, const char *cp)
{
af_pan_t* s = af->priv;
switch(cmd){
case AF_CONTROL_REINIT:
// Sanity check
if(!arg) return AF_ERROR;
af->data->rate = ((struct mp_audio*)arg)->rate;
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
set_channels(af->data, s->nch ? s->nch: ((struct mp_audio*)arg)->nch);
if((af->data->format != ((struct mp_audio*)arg)->format) ||
(af->data->bps != ((struct mp_audio*)arg)->bps)){
mp_audio_set_format((struct mp_audio*)arg, af->data->format);
return AF_FALSE;
}
return AF_OK;
case AF_CONTROL_SET_PAN_LEVEL:{
int i;
int ch = ((af_control_ext_t*)arg)->ch;
float* level = ((af_control_ext_t*)arg)->arg;
if (ch >= AF_NCH)
return AF_FALSE;
for(i=0;i<AF_NCH;i++)
s->level[ch][i] = level[i];
return AF_OK;
}
case AF_CONTROL_SET_PAN_NOUT:
// Reinit must be called after this function has been called
// Sanity check
if(((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH){
MP_ERR(af, "The number of output channels must be"
" between 1 and %i. Current value is %i\n",AF_NCH,((int*)arg)[0]);
return AF_ERROR;
}
s->nch=((int*)arg)[0];
return AF_OK;
case AF_CONTROL_SET_PAN_BALANCE:{
float val = *(float*)arg;
if (s->nch)
return AF_ERROR;
if (af->data->nch >= 2) {
s->level[0][0] = MPMIN(1.f, 1.f - val);
s->level[0][1] = MPMAX(0.f, val);
s->level[1][0] = MPMAX(0.f, -val);
s->level[1][1] = MPMIN(1.f, 1.f + val);
}
return AF_OK;
}
case AF_CONTROL_GET_PAN_BALANCE:
if (s->nch)
return AF_ERROR;
*(float*)arg = s->level[0][1] - s->level[1][0];
return AF_OK;
}
return AF_UNKNOWN;
}
static int filter_frame(struct af_instance *af, struct mp_audio *c)
{
if (!c)
return 0;
struct mp_audio *l = mp_audio_pool_get(af->out_pool, &af->fmt_out, c->samples);
if (!l) {
talloc_free(c);
return -1;
}
mp_audio_copy_attributes(l, c);
af_pan_t* s = af->priv; // Setup for this instance
float* in = c->planes[0]; // Input audio data
float* out = NULL; // Output audio data
float* end = in+c->samples*c->nch; // End of loop
int nchi = c->nch; // Number of input channels
int ncho = l->nch; // Number of output channels
register int j,k;
out = l->planes[0];
// Execute panning
// FIXME: Too slow
while(in < end){
for(j=0;j<ncho;j++){
register float x = 0.0;
register float* tin = in;
for(k=0;k<nchi;k++)
x += tin[k] * s->level[j][k];
out[j] = x;
}
out+= ncho;
in+= nchi;
}
talloc_free(c);
af_add_output_frame(af, l);
return 0;
}
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
af->control=control;
af->filter_frame = filter_frame;
af_pan_t *s = af->priv;
int n = 0;
int j,k;
int nch = s->nch;
if(nch && AF_OK != control(af,AF_CONTROL_SET_PAN_NOUT, &nch))
return AF_ERROR;
// Read pan values
char *cp = s->matrixstr;
j = 0; k = 0;
while(cp && k < AF_NCH){
int j = 0, k = 0, n;
while (*cp && k < AF_NCH) {
sscanf(cp, "%f%n" , &s->level[j][k], &n);
MP_VERBOSE(af, "Pan level from channel %i to"
" channel %i = %f\n",k,j,s->level[j][k]);
cp =&cp[n];
" channel %i = %f\n", k, j, s->level[j][k]);
cp = &cp[n];
j++;
if(j>=nch){
if (j >= s->nch) {
j = 0;
k++;
}
@@ -174,6 +61,133 @@ static int af_open(struct af_instance* af){
break;
cp++;
}
}
// Initialization and runtime control
static int control(struct af_instance *af, int cmd, void *arg)
{
af_pan_t* s = af->priv;
switch(cmd){
case AF_CONTROL_REINIT:
// Sanity check
if (!arg)
return AF_ERROR;
af->data->rate = ((struct mp_audio*)arg)->rate;
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
set_channels(af->data, s->nch ? s->nch : ((struct mp_audio*)arg)->nch);
if ((af->data->format != ((struct mp_audio*)arg)->format) ||
(af->data->bps != ((struct mp_audio*)arg)->bps)) {
mp_audio_set_format((struct mp_audio*)arg, af->data->format);
return AF_FALSE;
}
return AF_OK;
case AF_CONTROL_SET_PAN_LEVEL: {
int i;
int ch = ((af_control_ext_t*)arg)->ch;
float *level = ((af_control_ext_t*)arg)->arg;
if (ch >= AF_NCH)
return AF_FALSE;
for (i = 0; i < AF_NCH; i++)
s->level[ch][i] = level[i];
return AF_OK;
}
case AF_CONTROL_SET_PAN_NOUT:
// Reinit must be called after this function has been called
// Sanity check
if (((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH) {
MP_ERR(af, "The number of output channels must be"
" between 1 and %i. Current value is %i\n",
AF_NCH, ((int*)arg)[0]);
return AF_ERROR;
}
s->nch = ((int*)arg)[0];
return AF_OK;
case AF_CONTROL_SET_PAN_BALANCE: {
float val = *(float*)arg;
if (s->nch)
return AF_ERROR;
if (af->data->nch >= 2) {
s->level[0][0] = MPMIN(1.f, 1.f - val);
s->level[0][1] = MPMAX(0.f, val);
s->level[1][0] = MPMAX(0.f, -val);
s->level[1][1] = MPMIN(1.f, 1.f + val);
}
return AF_OK;
}
case AF_CONTROL_GET_PAN_BALANCE:
if (s->nch)
return AF_ERROR;
*(float*)arg = s->level[0][1] - s->level[1][0];
return AF_OK;
case AF_CONTROL_COMMAND: {
char **args = arg;
if (!strcmp(args[0], "set-matrix")) {
parse_matrix(af, args[1]);
return CONTROL_OK;
} else {
return CONTROL_ERROR;
}
}
}
return AF_UNKNOWN;
}
static int filter_frame(struct af_instance *af, struct mp_audio *c)
{
if (!c)
return 0;
struct mp_audio *l = mp_audio_pool_get(af->out_pool, &af->fmt_out, c->samples);
if (!l) {
talloc_free(c);
return -1;
}
mp_audio_copy_attributes(l, c);
af_pan_t* s = af->priv; // Setup for this instance
float *in = c->planes[0]; // Input audio data
float *out = NULL; // Output audio data
float *end = in+c->samples * c->nch; // End of loop
int nchi = c->nch; // Number of input channels
int ncho = l->nch; // Number of output channels
register int j, k;
out = l->planes[0];
// Execute panning
// FIXME: Too slow
while (in < end) {
for (j = 0; j < ncho; j++) {
register float x = 0.0;
register float *tin = in;
for (k = 0; k < nchi; k++)
x += tin[k] * s->level[j][k];
out[j] = x;
}
out += ncho;
in += nchi;
}
talloc_free(c);
af_add_output_frame(af, l);
return 0;
}
// Allocate memory and set function pointers
static int af_open(struct af_instance *af)
{
af->control = control;
af->filter_frame = filter_frame;
af_pan_t *s = af->priv;
int nch = s->nch;
if (nch && AF_OK != control(af, AF_CONTROL_SET_PAN_NOUT, &nch))
return AF_ERROR;
// Read pan values
if (s->matrixstr)
parse_matrix(af, s->matrixstr);
return AF_OK;
}
+26
View File
@@ -26,6 +26,7 @@
struct priv {
RubberBandState rubber;
double speed;
double pitch;
struct mp_audio *pending;
bool needs_reset;
// Estimate how much librubberband has buffered internally.
@@ -44,6 +45,14 @@ static void update_speed(struct af_instance *af, double new_speed)
rubberband_set_time_ratio(p->rubber, 1.0 / p->speed);
}
static void update_pitch(struct af_instance *af, double new_pitch)
{
struct priv *p = af->priv;
p->pitch = new_pitch;
rubberband_set_pitch_scale(p->rubber, p->pitch);
}
static int control(struct af_instance *af, int cmd, void *arg)
{
struct priv *p = af->priv;
@@ -72,6 +81,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
}
update_speed(af, p->speed);
update_pitch(af, p->pitch);
control(af, AF_CONTROL_RESET, NULL);
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
@@ -87,6 +97,19 @@ static int control(struct af_instance *af, int cmd, void *arg)
p->pending = NULL;
p->rubber_delay = 0;
return AF_OK;
case AF_CONTROL_COMMAND: {
char **args = arg;
if (!strcmp(args[0], "set-pitch")) {
char *endptr;
double pitch = strtod(args[1], &endptr);
if (*endptr || pitch < 0.01 || pitch > 100.0)
return CONTROL_ERROR;
update_pitch(af, pitch);
return CONTROL_OK;
} else {
return CONTROL_ERROR;
}
}
}
return AF_UNKNOWN;
}
@@ -187,9 +210,11 @@ const struct af_info af_info_rubberband = {
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {
.speed = 1.0,
.pitch = 1.0,
.opt_pitch = RubberBandOptionPitchHighConsistency,
.opt_transients = RubberBandOptionTransientsMixed,
.opt_formant = RubberBandOptionFormantPreserved,
.opt_channels = RubberBandOptionChannelsTogether,
},
.options = (const struct m_option[]) {
OPT_CHOICE("transients", opt_transients, 0,
@@ -220,6 +245,7 @@ const struct af_info af_info_rubberband = {
OPT_CHOICE("channels", opt_channels, 0,
({"apart", RubberBandOptionChannelsApart},
{"together", RubberBandOptionChannelsTogether})),
OPT_DOUBLE("pitch-scale", pitch, M_OPT_RANGE, .min = 0.01, .max = 100),
{0}
},
};
+12 -8
View File
@@ -71,15 +71,19 @@ static int control(struct af_instance *af, int cmd, void *arg)
if (af_fmt_is_planar(in->format))
mp_audio_set_format(af->data, af_fmt_to_planar(af->data->format));
s->rgain = 1.0;
if ((s->rgain_track || s->rgain_album) && af->replaygain_data) {
float gain, peak;
struct replaygain_data *rg = af->replaygain_data;
if ((s->rgain_track || s->rgain_album) && rg) {
MP_VERBOSE(af, "Replaygain: Track=%f/%f Album=%f/%f\n",
rg->track_gain, rg->track_peak,
rg->album_gain, rg->album_peak);
float gain, peak;
if (s->rgain_track) {
gain = af->replaygain_data->track_gain;
peak = af->replaygain_data->track_peak;
gain = rg->track_gain;
peak = rg->track_peak;
} else {
gain = af->replaygain_data->album_gain;
peak = af->replaygain_data->album_peak;
gain = rg->album_gain;
peak = rg->album_peak;
}
gain += s->rgain_preamp;
@@ -115,7 +119,7 @@ static void filter_plane(struct af_instance *af, struct mp_audio *data, int p)
{
struct priv *s = af->priv;
float level = s->level * s->rgain;
float level = s->level * s->rgain * from_dB(s->cfg_volume, 20.0, -200.0, 60.0);
int num_samples = data->samples * data->spf;
if (af_fmt_from_planar(af->data->format) == AF_FORMAT_S16) {
@@ -158,7 +162,7 @@ static int af_open(struct af_instance *af)
struct priv *s = af->priv;
af->control = control;
af->filter_frame = filter;
s->level = from_dB(s->cfg_volume, 20.0, -200.0, 60.0);
s->level = 1.0;
return AF_OK;
}
-403
View File
@@ -1,403 +0,0 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <libavutil/common.h>
#include "config.h"
#include "audio/out/ao.h"
#include "audio/filter/af.h"
#include "common/global.h"
#include "common/msg.h"
#include "mpv_talloc.h"
#include "mixer.h"
struct mixer {
struct mp_log *log;
struct MPOpts *opts;
struct ao *ao;
struct af_stream *af;
// Static, dependent on ao/softvol settings
bool softvol; // use AO (false) or af_volume (true)
bool persistent_volume; // volume does not need to be restored
bool emulate_mute; // if true, emulate mute with volume=0
// Last known values (possibly out of sync with reality)
float vol_l, vol_r;
bool muted;
// Used to decide whether we should unmute on uninit
bool muted_by_us;
/* Contains ao driver name or "softvol" if volume is not persistent
* and needs to be restored after the driver is reinitialized. */
const char *driver;
// Other stuff
float balance;
};
struct mixer *mixer_init(void *talloc_ctx, struct mpv_global *global)
{
struct mixer *mixer = talloc_ptrtype(talloc_ctx, mixer);
*mixer = (struct mixer) {
.log = mp_log_new(mixer, global->log, "mixer"),
.opts = global->opts,
.vol_l = 100,
.vol_r = 100,
.driver = "",
};
return mixer;
}
bool mixer_audio_initialized(struct mixer *mixer)
{
return !!mixer->ao;
}
float mixer_getmaxvolume(struct mixer *mixer)
{
// gain == 1
return mixer->softvol ? mixer->opts->softvol_max : 100;
}
static void checkvolume(struct mixer *mixer)
{
if (!mixer->ao)
return;
ao_control_vol_t vol = {mixer->vol_l, mixer->vol_r};
if (mixer->softvol) {
float gain;
if (!af_control_any_rev(mixer->af, AF_CONTROL_GET_VOLUME, &gain))
gain = 1.0;
vol.left = gain * 100.0;
vol.right = gain * 100.0;
} else {
MP_DBG(mixer, "Reading volume from AO.\n");
// Rely on the values not changing if the query is not supported
ao_control(mixer->ao, AOCONTROL_GET_VOLUME, &vol);
ao_control(mixer->ao, AOCONTROL_GET_MUTE, &mixer->muted);
}
float l = mixer->vol_l;
float r = mixer->vol_r;
if (mixer->emulate_mute && mixer->muted)
l = r = 0;
/* Try to detect cases where the volume has been changed by some external
* action (such as something else changing a shared system-wide volume).
* We don't test for exact equality, as some AOs may round the value
* we last set to some nearby supported value. 3 has been the default
* volume step for increase/decrease keys, and is apparently big enough
* to step to the next possible value in most setups.
*/
if (FFABS(vol.left - l) >= 3 || FFABS(vol.right - r) >= 3) {
mixer->vol_l = vol.left;
mixer->vol_r = vol.right;
if (mixer->emulate_mute)
mixer->muted = false;
}
mixer->muted_by_us &= mixer->muted;
}
void mixer_getvolume(struct mixer *mixer, float *l, float *r)
{
checkvolume(mixer);
*l = mixer->vol_l;
*r = mixer->vol_r;
}
static void setvolume_internal(struct mixer *mixer)
{
float l = mixer->vol_l, r = mixer->vol_r;
if (mixer->emulate_mute && mixer->muted)
l = r = 0;
if (!mixer->softvol) {
MP_DBG(mixer, "Setting volume on AO.\n");
struct ao_control_vol vol = {.left = l, .right = r};
if (ao_control(mixer->ao, AOCONTROL_SET_VOLUME, &vol) != CONTROL_OK)
MP_ERR(mixer, "Failed to change audio output volume.\n");
return;
}
float gain = (l + r) / 2.0 / 100.0;
if (!af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)) {
if (gain == 1.0)
return;
MP_VERBOSE(mixer, "Inserting volume filter.\n");
if (!(af_add(mixer->af, "volume", "softvol", NULL)
&& af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)))
MP_ERR(mixer, "No volume control available.\n");
}
}
void mixer_setvolume(struct mixer *mixer, float l, float r)
{
checkvolume(mixer); // to check mute status
float max = mixer_getmaxvolume(mixer);
mixer->vol_l = MPCLAMP(l, 0, max);
mixer->vol_r = MPCLAMP(r, 0, max);
if (mixer->ao)
setvolume_internal(mixer);
}
void mixer_getbothvolume(struct mixer *mixer, float *b)
{
float mixer_l, mixer_r;
mixer_getvolume(mixer, &mixer_l, &mixer_r);
*b = (mixer_l + mixer_r) / 2;
}
void mixer_setmute(struct mixer *mixer, bool mute)
{
checkvolume(mixer);
if (mute == mixer->muted)
return;
if (mixer->ao) {
mixer->muted = mute;
mixer->muted_by_us = mute;
if (mixer->emulate_mute) {
setvolume_internal(mixer);
} else {
ao_control(mixer->ao, AOCONTROL_SET_MUTE, &mute);
}
checkvolume(mixer);
} else {
mixer->muted = mute;
mixer->muted_by_us = mute;
}
}
bool mixer_getmute(struct mixer *mixer)
{
checkvolume(mixer);
return mixer->muted;
}
void mixer_addvolume(struct mixer *mixer, float step)
{
float vol_l, vol_r;
mixer_getvolume(mixer, &vol_l, &vol_r);
mixer_setvolume(mixer, vol_l + step, vol_r + step);
}
void mixer_getbalance(struct mixer *mixer, float *val)
{
if (mixer->af)
af_control_any_rev(mixer->af, AF_CONTROL_GET_PAN_BALANCE, &mixer->balance);
*val = mixer->balance;
}
/* NOTE: Currently the balance code is seriously buggy: it always changes
* the af_pan mapping between the first two input channels and first two
* output channels to particular values. These values make sense for an
* af_pan instance that was automatically inserted for balance control
* only and is otherwise an identity transform, but if the filter was
* there for another reason, then ignoring and overriding the original
* values is completely wrong.
*/
void mixer_setbalance(struct mixer *mixer, float val)
{
struct af_instance *af_pan_balance;
mixer->balance = val;
if (!mixer->af)
return;
if (af_control_any_rev(mixer->af, AF_CONTROL_SET_PAN_BALANCE, &val))
return;
if (val == 0)
return;
if (!(af_pan_balance = af_add(mixer->af, "pan", "autopan", NULL))) {
MP_ERR(mixer, "No balance control available.\n");
return;
}
/* make all other channels pass through since by default pan blocks all */
for (int i = 2; i < AF_NCH; i++) {
float level[AF_NCH] = {0};
level[i] = 1.f;
af_control_ext_t arg_ext = { .ch = i, .arg = level };
af_pan_balance->control(af_pan_balance, AF_CONTROL_SET_PAN_LEVEL,
&arg_ext);
}
af_pan_balance->control(af_pan_balance, AF_CONTROL_SET_PAN_BALANCE, &val);
}
char *mixer_get_volume_restore_data(struct mixer *mixer)
{
if (!mixer->driver[0])
return NULL;
return talloc_asprintf(NULL, "%s:%f:%f:%d", mixer->driver, mixer->vol_l,
mixer->vol_r, mixer->muted_by_us);
}
static void probe_softvol(struct mixer *mixer)
{
bool ao_perapp = ao_control(mixer->ao, AOCONTROL_HAS_PER_APP_VOLUME, 0) == 1;
bool ao_softvol = ao_control(mixer->ao, AOCONTROL_HAS_SOFT_VOLUME, 0) == 1;
assert(!(ao_perapp && ao_softvol));
mixer->persistent_volume = !ao_softvol;
if (mixer->opts->softvol == SOFTVOL_AUTO) {
// No system-wide volume => fine with AO volume control.
mixer->softvol = !ao_softvol && !ao_perapp;
} else {
mixer->softvol = mixer->opts->softvol == SOFTVOL_YES;
}
if (mixer->softvol)
mixer->persistent_volume = false;
MP_DBG(mixer, "Will use af_volume: %s\n", mixer->softvol ? "yes" : "no");
// If we can't use real volume control => force softvol.
if (!mixer->softvol) {
ao_control_vol_t vol;
if (ao_control(mixer->ao, AOCONTROL_GET_VOLUME, &vol) != CONTROL_OK) {
mixer->softvol = true;
MP_WARN(mixer, "Hardware volume control unavailable.\n");
}
}
// Probe native mute support.
mixer->emulate_mute = true;
if (!mixer->softvol) {
if (ao_control(mixer->ao, AOCONTROL_GET_MUTE, &(bool){0}) == CONTROL_OK)
mixer->emulate_mute = false;
}
}
static void restore_volume(struct mixer *mixer)
{
struct MPOpts *opts = mixer->opts;
struct ao *ao = mixer->ao;
float force_vol_l = -1, force_vol_r = -1;
int force_mute = -1;
const char *prev_driver = mixer->driver;
mixer->driver = mixer->softvol ? "softvol" : ao_get_name(ao);
if (!prev_driver[0])
prev_driver = mixer->driver;
// Restore old parameters if volume won't survive reinitialization.
// But not if volume scale is possibly different.
if (!mixer->persistent_volume && strcmp(mixer->driver, prev_driver) == 0) {
force_vol_l = mixer->vol_l;
force_vol_r = mixer->vol_r;
}
// Set mute if we disabled it on uninit last time.
if (mixer->muted_by_us)
force_mute = 1;
// Set parameters from command line.
if (opts->mixer_init_volume >= 0)
force_vol_l = force_vol_r = opts->mixer_init_volume;
if (opts->mixer_init_mute >= 0)
force_mute = opts->mixer_init_mute;
// Set parameters from playback resume.
char *data = mixer->opts->mixer_restore_volume_data;
if (!mixer->persistent_volume && data && data[0]) {
char drv[40];
float v_l, v_r;
int m;
if (sscanf(data, "%39[^:]:%f:%f:%d", drv, &v_l, &v_r, &m) == 4) {
if (strcmp(mixer->driver, drv) == 0) {
force_vol_l = v_l;
force_vol_r = v_r;
force_mute = !!m;
MP_DBG(mixer, "Restoring volume from resume config.\n");
}
}
talloc_free(mixer->opts->mixer_restore_volume_data);
mixer->opts->mixer_restore_volume_data = NULL;
}
// Using --volume should not reset the volume on every file (i.e. reinit),
// OTOH mpv --{ --volume 10 f1.mkv --} --{ --volume 20 f2.mkv --} must work.
// Resetting the option volumes to "auto" (-1) is easiest. If file local
// options (as shown above) are used, the option handler code will reset
// them to other values, and force the volume to be reset as well.
opts->mixer_init_volume = -1;
opts->mixer_init_mute = -1;
checkvolume(mixer);
if (force_vol_l >= 0 && force_vol_r >= 0) {
MP_DBG(mixer, "Restoring previous volume.\n");
mixer_setvolume(mixer, force_vol_l, force_vol_r);
}
if (force_mute >= 0) {
MP_DBG(mixer, "Restoring previous mute toggle.\n");
mixer_setmute(mixer, force_mute);
}
}
// Called after the audio filter chain is built or rebuilt.
// (Can be called multiple times, even without mixer_uninit() in-between.)
void mixer_reinit_audio(struct mixer *mixer, struct ao *ao, struct af_stream *af)
{
if (!ao || !af)
return;
mixer->ao = ao;
mixer->af = af;
MP_DBG(mixer, "Reinit...\n");
probe_softvol(mixer);
restore_volume(mixer);
if (mixer->balance != 0)
mixer_setbalance(mixer, mixer->balance);
}
/* Called before uninitializing the audio filter chain. The main purpose is to
* turn off mute, in case it's a global/persistent setting which might
* otherwise be left enabled even after this player instance exits.
*/
void mixer_uninit_audio(struct mixer *mixer)
{
if (!mixer->ao)
return;
MP_DBG(mixer, "Uninit...\n");
checkvolume(mixer);
if (mixer->muted_by_us && mixer->persistent_volume) {
MP_DBG(mixer, "Draining.\n");
/* Current audio output API combines playing the remaining buffered
* audio and uninitializing the AO into one operation, even though
* ideally unmute would happen between those two steps. We can't do
* volume changes after uninitialization, but we don't want the
* remaining audio to play at full volume either. Thus this
* workaround to drop remaining audio first. */
ao_reset(mixer->ao);
mixer_setmute(mixer, false);
/* We remember mute status and re-enable it if we play more audio
* in the same process. */
mixer->muted_by_us = true;
}
mixer->ao = NULL;
mixer->af = NULL;
mixer->softvol = false;
}
-50
View File
@@ -1,50 +0,0 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MPLAYER_MIXER_H
#define MPLAYER_MIXER_H
#include <stdbool.h>
// Values of MPOpts.softvol
enum {
SOFTVOL_NO = 0,
SOFTVOL_YES = 1,
SOFTVOL_AUTO = 2,
};
struct mpv_global;
struct ao;
struct af_stream;
struct mixer;
struct mixer *mixer_init(void *talloc_ctx, struct mpv_global *global);
void mixer_reinit_audio(struct mixer *mixer, struct ao *ao, struct af_stream *af);
void mixer_uninit_audio(struct mixer *mixer);
bool mixer_audio_initialized(struct mixer *mixer);
void mixer_getvolume(struct mixer *mixer, float *l, float *r);
void mixer_setvolume(struct mixer *mixer, float l, float r);
void mixer_addvolume(struct mixer *mixer, float step);
void mixer_getbothvolume(struct mixer *mixer, float *b);
void mixer_setmute(struct mixer *mixer, bool mute);
bool mixer_getmute(struct mixer *mixer);
void mixer_getbalance(struct mixer *mixer, float *bal);
void mixer_setbalance(struct mixer *mixer, float bal);
float mixer_getmaxvolume(struct mixer *mixer);
char *mixer_get_volume_restore_data(struct mixer *mixer);
#endif /* MPLAYER_MIXER_H */
+85 -36
View File
@@ -28,7 +28,6 @@
#include "audio/format.h"
#include "audio/audio.h"
#include "input/input.h"
#include "options/options.h"
#include "options/m_config.h"
#include "common/msg.h"
@@ -36,6 +35,7 @@
#include "common/global.h"
extern const struct ao_driver audio_out_oss;
extern const struct ao_driver audio_out_audiounit;
extern const struct ao_driver audio_out_coreaudio;
extern const struct ao_driver audio_out_coreaudio_exclusive;
extern const struct ao_driver audio_out_rsound;
@@ -53,6 +53,9 @@ extern const struct ao_driver audio_out_sdl;
static const struct ao_driver * const audio_out_drivers[] = {
// native:
#if HAVE_AUDIOUNIT
&audio_out_audiounit,
#endif
#if HAVE_COREAUDIO
&audio_out_coreaudio,
#endif
@@ -109,6 +112,8 @@ static bool get_desc(struct m_obj_desc *dst, int index)
.priv_size = ao->priv_size,
.priv_defaults = ao->priv_defaults,
.options = ao->options,
.options_prefix = ao->options_prefix,
.global_opts = ao->global_opts,
.hidden = ao->encode,
.p = ao,
};
@@ -121,11 +126,16 @@ const struct m_obj_list ao_obj_list = {
.description = "audio outputs",
.allow_unknown_entries = true,
.allow_trailer = true,
.disallow_positional_parameters = true,
.use_global_options = true,
};
static struct ao *ao_alloc(bool probing, struct mpv_global *global,
struct input_ctx *input_ctx, char *name, char **args)
void (*wakeup_cb)(void *ctx), void *wakeup_ctx,
char *name)
{
assert(wakeup_cb);
struct MPOpts *opts = global->opts;
struct mp_log *log = mp_log_new(NULL, global->log, "ao");
struct m_obj_desc desc;
@@ -139,17 +149,16 @@ static struct ao *ao_alloc(bool probing, struct mpv_global *global,
*ao = (struct ao) {
.driver = desc.p,
.probing = probing,
.input_ctx = input_ctx,
.global = global,
.wakeup_cb = wakeup_cb,
.wakeup_ctx = wakeup_ctx,
.log = mp_log_new(ao, log, name),
.def_buffer = opts->audio_buffer,
.client_name = talloc_strdup(ao, opts->audio_client_name),
};
struct m_config *config = m_config_from_obj_desc(ao, ao->log, &desc);
if (m_config_apply_defaults(config, name, opts->ao_defs) < 0)
ao->priv = m_config_group_from_desc(ao, ao->log, global, &desc, name);
if (!ao->priv)
goto error;
if (m_config_set_obj_params(config, args) < 0)
goto error;
ao->priv = config->optstruct;
return ao;
error:
talloc_free(ao);
@@ -157,18 +166,19 @@ error:
}
static struct ao *ao_init(bool probing, struct mpv_global *global,
struct input_ctx *input_ctx,
struct encode_lavc_context *encode_lavc_ctx,
void (*wakeup_cb)(void *ctx), void *wakeup_ctx,
struct encode_lavc_context *encode_lavc_ctx, int flags,
int samplerate, int format, struct mp_chmap channels,
char *dev, char *name, char **args)
char *dev, char *name)
{
struct ao *ao = ao_alloc(probing, global, input_ctx, name, args);
struct ao *ao = ao_alloc(probing, global, wakeup_cb, wakeup_ctx, name);
if (!ao)
return NULL;
ao->samplerate = samplerate;
ao->channels = channels;
ao->format = format;
ao->encode_lavc_ctx = encode_lavc_ctx;
ao->init_flags = flags;
if (ao->driver->encode != !!ao->encode_lavc_ctx)
goto fail;
@@ -182,6 +192,8 @@ static struct ao *ao_init(bool probing, struct mpv_global *global,
ao->api_priv = talloc_zero_size(ao, ao->api->priv_size);
assert(!ao->api->priv_defaults && !ao->api->options);
ao->stream_silence = flags & AO_INIT_STREAM_SILENCE;
int r = ao->driver->init(ao);
if (r < 0) {
// Silly exception for coreaudio spdif redirection
@@ -190,8 +202,9 @@ static struct ao *ao_init(bool probing, struct mpv_global *global,
snprintf(redirect, sizeof(redirect), "%s", ao->redirect);
snprintf(rdevice, sizeof(rdevice), "%s", ao->device ? ao->device : "");
talloc_free(ao);
return ao_init(probing, global, input_ctx, encode_lavc_ctx,
samplerate, format, channels, rdevice, redirect, NULL);
return ao_init(probing, global, wakeup_cb, wakeup_ctx,
encode_lavc_ctx, flags, samplerate, format, channels,
rdevice, redirect);
}
goto fail;
}
@@ -240,8 +253,8 @@ static void split_ao_device(void *tmp, char *opt, char **out_ao, char **out_dev)
}
struct ao *ao_init_best(struct mpv_global *global,
bool ao_null_fallback,
struct input_ctx *input_ctx,
int init_flags,
void (*wakeup_cb)(void *ctx), void *wakeup_ctx,
struct encode_lavc_context *encode_lavc_ctx,
int samplerate, int format, struct mp_chmap channels)
{
@@ -283,7 +296,7 @@ struct ao *ao_init_best(struct mpv_global *global,
}
}
if (ao_null_fallback) {
if (init_flags & AO_INIT_NULL_FALLBACK) {
MP_TARRAY_APPEND(tmp, ao_list, ao_num,
(struct m_obj_settings){.name = "null"});
}
@@ -297,9 +310,8 @@ struct ao *ao_init_best(struct mpv_global *global,
dev = pref_dev;
mp_verbose(log, "Using preferred device '%s'\n", dev);
}
ao = ao_init(probing, global, input_ctx, encode_lavc_ctx,
samplerate, format, channels, dev,
entry->name, entry->attribs);
ao = ao_init(probing, global, wakeup_cb, wakeup_ctx, encode_lavc_ctx,
init_flags, samplerate, format, channels, dev, entry->name);
if (ao)
break;
if (!probing)
@@ -402,8 +414,7 @@ int ao_query_and_reset_events(struct ao *ao, int events)
static void ao_add_events(struct ao *ao, int events)
{
atomic_fetch_or(&ao->events_, events);
if (ao->input_ctx)
mp_input_wakeup(ao->input_ctx);
ao->wakeup_cb(ao->wakeup_ctx);
}
// Request that the player core destroys and recreates the AO. Fully thread-safe.
@@ -429,6 +440,29 @@ bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
return r;
}
// safe_multichannel=true behaves like ao_chmap_sel_adjust.
// safe_multichannel=false is a helper for callers which do not support safe
// handling of arbitrary channel layouts. If the multichannel layouts are not
// considered "always safe" (e.g. HDMI), then allow only stereo or mono, if
// they are part of the list in *s.
bool ao_chmap_sel_adjust2(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map, bool safe_multichannel)
{
if (!safe_multichannel && (ao->init_flags & AO_INIT_SAFE_MULTICHANNEL_ONLY)) {
struct mp_chmap res = *map;
if (mp_chmap_sel_adjust(s, &res)) {
if (!mp_chmap_equals(&res, &(struct mp_chmap)MP_CHMAP_INIT_MONO) &&
!mp_chmap_equals(&res, &(struct mp_chmap)MP_CHMAP_INIT_STEREO))
{
MP_WARN(ao, "Disabling multichannel output.\n");
*map = (struct mp_chmap)MP_CHMAP_INIT_STEREO;
}
}
}
return ao_chmap_sel_adjust(ao, s, map);
}
bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map, int num)
{
@@ -464,7 +498,8 @@ bool ao_untimed(struct ao *ao)
struct ao_hotplug {
struct mpv_global *global;
struct input_ctx *input_ctx;
void (*wakeup_cb)(void *ctx);
void *wakeup_ctx;
// A single AO instance is used to listen to hotplug events. It wouldn't
// make much sense to allow multiple AO drivers; all sane platforms have
// a single such audio API.
@@ -476,12 +511,14 @@ struct ao_hotplug {
};
struct ao_hotplug *ao_hotplug_create(struct mpv_global *global,
struct input_ctx *input_ctx)
void (*wakeup_cb)(void *ctx),
void *wakeup_ctx)
{
struct ao_hotplug *hp = talloc_ptrtype(NULL, hp);
*hp = (struct ao_hotplug){
.global = global,
.input_ctx = input_ctx,
.wakeup_cb = wakeup_cb,
.wakeup_ctx = wakeup_ctx,
.needs_update = true,
};
return hp;
@@ -489,15 +526,10 @@ struct ao_hotplug *ao_hotplug_create(struct mpv_global *global,
static void get_devices(struct ao *ao, struct ao_device_list *list)
{
int num = list->num_devices;
if (ao->driver->list_devs)
if (ao->driver->list_devs) {
ao->driver->list_devs(ao, list);
// Add at least a default entry
if (list->num_devices == num) {
char name[80] = "Default";
if (num > 1)
mp_snprintf_cat(name, sizeof(name), " (%s)", ao->driver->name);
ao_device_list_add(list, ao, &(struct ao_device_desc){"", name});
} else {
ao_device_list_add(list, ao, &(struct ao_device_desc){"", ""});
}
}
@@ -535,8 +567,8 @@ struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp)
if (d == &audio_out_null)
break; // don't add unsafe/special entries
struct ao *ao = ao_alloc(true, hp->global, hp->input_ctx,
(char *)d->name, NULL);
struct ao *ao = ao_alloc(true, hp->global, hp->wakeup_cb, hp->wakeup_ctx,
(char *)d->name);
if (!ao)
continue;
@@ -560,6 +592,19 @@ void ao_device_list_add(struct ao_device_list *list, struct ao *ao,
{
struct ao_device_desc c = *e;
const char *dname = ao->driver->name;
char buf[80];
if (!c.desc || !c.desc[0]) {
if (c.name && c.name[0]) {
c.desc = c.name;
} else if (list->num_devices) {
// Assume this is the default device.
snprintf(buf, sizeof(buf), "Default (%s)", dname);
c.desc = buf;
} else {
// First default device (and maybe the only one).
c.desc = "Default";
}
}
c.name = c.name[0] ? talloc_asprintf(list, "%s/%s", dname, c.name)
: talloc_strdup(list, dname);
c.desc = talloc_strdup(list, c.desc);
@@ -576,9 +621,13 @@ void ao_hotplug_destroy(struct ao_hotplug *hp)
talloc_free(hp);
}
static void dummy_wakeup(void *ctx)
{
}
void ao_print_devices(struct mpv_global *global, struct mp_log *log)
{
struct ao_hotplug *hp = ao_hotplug_create(global, NULL);
struct ao_hotplug *hp = ao_hotplug_create(global, dummy_wakeup, NULL);
struct ao_device_list *list = ao_hotplug_get_device_list(hp);
mp_info(log, "List of detected audio devices:\n");
for (int n = 0; n < list->num_devices; n++) {
+16 -3
View File
@@ -50,6 +50,18 @@ enum {
AO_EVENT_HOTPLUG = 2,
};
enum {
// Allow falling back to ao_null if nothing else works.
AO_INIT_NULL_FALLBACK = 1 << 0,
// Only accept multichannel configurations that are guaranteed to work
// (i.e. not sending arbitrary layouts over HDMI).
AO_INIT_SAFE_MULTICHANNEL_ONLY = 1 << 1,
// Stream silence as long as no audio is playing.
AO_INIT_STREAM_SILENCE = 1 << 2,
// Force exclusive mode, i.e. lock out the system mixer.
AO_INIT_EXCLUSIVE = 1 << 3,
};
typedef struct ao_control_vol {
float left;
float right;
@@ -72,8 +84,8 @@ struct encode_lavc_context;
struct mp_audio;
struct ao *ao_init_best(struct mpv_global *global,
bool ao_null_fallback,
struct input_ctx *input_ctx,
int init_flags,
void (*wakeup_cb)(void *ctx), void *wakeup_ctx,
struct encode_lavc_context *encode_lavc_ctx,
int samplerate, int format, struct mp_chmap channels);
void ao_uninit(struct ao *ao);
@@ -96,7 +108,8 @@ void ao_hotplug_event(struct ao *ao);
struct ao_hotplug;
struct ao_hotplug *ao_hotplug_create(struct mpv_global *global,
struct input_ctx *input_ctx);
void (*wakeup_cb)(void *ctx),
void *wakeup_ctx);
void ao_hotplug_destroy(struct ao_hotplug *hp);
bool ao_hotplug_check_update(struct ao_hotplug *hp);
const char *ao_hotplug_get_detected_device(struct ao_hotplug *hp);
+229 -85
View File
@@ -35,6 +35,7 @@
#include "config.h"
#include "options/options.h"
#include "options/m_config.h"
#include "options/m_option.h"
#include "common/msg.h"
#include "osdep/endian.h"
@@ -48,23 +49,51 @@
#include "internal.h"
#include "audio/format.h"
struct ao_alsa_opts {
char *device;
char *mixer_device;
char *mixer_name;
int mixer_index;
int resample;
int ni;
int ignore_chmap;
};
#define OPT_BASE_STRUCT struct ao_alsa_opts
static const struct m_sub_options ao_alsa_conf = {
.opts = (const struct m_option[]) {
OPT_STRING("alsa-device", device, 0, DEVICE_OPT_DEPRECATION),
OPT_FLAG("alsa-resample", resample, 0),
OPT_STRING("alsa-mixer-device", mixer_device, 0),
OPT_STRING("alsa-mixer-name", mixer_name, 0),
OPT_INTRANGE("alsa-mixer-index", mixer_index, 0, 0, 99),
OPT_FLAG("alsa-non-interleaved", ni, 0),
OPT_FLAG("alsa-ignore-chmap", ignore_chmap, 0),
{0}
},
.defaults = &(const struct ao_alsa_opts) {
.mixer_device = "default",
.mixer_name = "Master",
.mixer_index = 0,
.ni = 0,
},
.size = sizeof(struct ao_alsa_opts),
};
struct priv {
snd_pcm_t *alsa;
bool device_lost;
snd_pcm_format_t alsa_fmt;
bool can_pause;
bool paused;
snd_pcm_sframes_t prepause_frames;
double delay_before_pause;
snd_pcm_uframes_t buffersize;
snd_pcm_uframes_t outburst;
char *cfg_device;
char *cfg_mixer_device;
char *cfg_mixer_name;
int cfg_mixer_index;
int cfg_resample;
int cfg_ni;
int cfg_ignore_chmap;
snd_output_t *output;
struct ao_alsa_opts *opts;
};
#define BUFFER_TIME 250000 // 250ms
@@ -122,13 +151,13 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_id_set_index(sid, p->cfg_mixer_index);
snd_mixer_selem_id_set_name(sid, p->cfg_mixer_name);
snd_mixer_selem_id_set_index(sid, p->opts->mixer_index);
snd_mixer_selem_id_set_name(sid, p->opts->mixer_name);
err = snd_mixer_open(&handle, 0);
CHECK_ALSA_ERROR("Mixer open error");
err = snd_mixer_attach(handle, p->cfg_mixer_device);
err = snd_mixer_attach(handle, p->opts->mixer_device);
CHECK_ALSA_ERROR("Mixer attach error");
err = snd_mixer_selem_register(handle, NULL, NULL);
@@ -334,8 +363,10 @@ static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
struct mp_chmap_sel chmap_sel = {.tmp = p};
snd_pcm_chmap_query_t **maps = snd_pcm_query_chmaps(p->alsa);
if (!maps)
if (!maps) {
MP_VERBOSE(ao, "snd_pcm_query_chmaps() returned NULL\n");
return false;
}
for (int i = 0; maps[i] != NULL; i++) {
char aname[128];
@@ -345,12 +376,18 @@ static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
struct mp_chmap entry;
if (mp_chmap_from_alsa(&entry, &maps[i]->map)) {
struct mp_chmap reorder = entry;
if (maps[i]->type == SND_CHMAP_TYPE_VAR)
mp_chmap_reorder_norm(&reorder);
MP_DBG(ao, "Got supported channel map: %s (type %s) -> %s -> %s\n",
aname, snd_pcm_chmap_type_name(maps[i]->type),
mp_chmap_to_str(&entry), mp_chmap_to_str(&reorder));
mp_chmap_sel_add_map(&chmap_sel, &reorder);
mp_chmap_reorder_norm(&reorder);
MP_DBG(ao, "got ALSA chmap: %s (%s) -> %s", aname,
snd_pcm_chmap_type_name(maps[i]->type),
mp_chmap_to_str(&entry));
if (!mp_chmap_equals(&entry, &reorder))
MP_DBG(ao, " -> %s", mp_chmap_to_str(&reorder));
MP_DBG(ao, "\n");
struct mp_chmap final =
maps[i]->type == SND_CHMAP_TYPE_VAR ? reorder : entry;
mp_chmap_sel_add_map(&chmap_sel, &final);
} else {
MP_VERBOSE(ao, "skipping unknown ALSA channel map: %s\n", aname);
}
@@ -358,7 +395,7 @@ static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
snd_pcm_free_chmaps(maps);
return ao_chmap_sel_adjust(ao, &chmap_sel, chmap);
return ao_chmap_sel_adjust2(ao, &chmap_sel, chmap, false);
}
// Map back our selected channel layout to an ALSA one. This is done this way so
@@ -442,7 +479,7 @@ static int set_chmap(struct ao *ao, struct mp_chmap *dev_chmap, int num_channels
MP_VERBOSE(ao, "which we understand as: %s\n", mp_chmap_to_str(&chmap));
if (p->cfg_ignore_chmap) {
if (p->opts->ignore_chmap) {
MP_VERBOSE(ao, "user set ignore-chmap; ignoring the channel map.\n");
} else if (af_fmt_is_spdif(ao->format)) {
MP_VERBOSE(ao, "using spdif passthrough; ignoring the channel map.\n");
@@ -451,10 +488,14 @@ static int set_chmap(struct ao *ao, struct mp_chmap *dev_chmap, int num_channels
} else if (chmap.num != num_channels) {
MP_WARN(ao, "ALSA channel map conflicts with channel count!\n");
} else {
MP_VERBOSE(ao, "using the ALSA channel map.\n");
if (mp_chmap_equals(&chmap, &ao->channels))
if (mp_chmap_equals(&chmap, &ao->channels)) {
MP_VERBOSE(ao, "which is what we requested.\n");
ao->channels = chmap;
} else if (!mp_chmap_is_valid(dev_chmap)) {
MP_VERBOSE(ao, "ignoring the ALSA channel map.\n");
} else {
MP_VERBOSE(ao, "using the ALSA channel map.\n");
ao->channels = chmap;
}
}
free(alsa_chmap);
@@ -477,6 +518,22 @@ static int set_chmap(struct ao *ao, struct mp_chmap *dev_chmap, int num_channels
#endif /* else HAVE_CHMAP_API */
static void dump_hw_params(struct ao *ao, int msglevel, const char *msg,
snd_pcm_hw_params_t *hw_params)
{
struct priv *p = ao->priv;
int err;
err = snd_pcm_hw_params_dump(hw_params, p->output);
CHECK_ALSA_WARN("Dump hwparams error");
char *tmp = NULL;
size_t tmp_s = snd_output_buffer_string(p->output, &tmp);
if (tmp)
mp_msg(ao->log, msglevel, "%s---\n%.*s---\n", msg, (int)tmp_s, tmp);
snd_output_flush(p->output);
}
static int map_iec958_srate(int srate)
{
switch (srate) {
@@ -520,7 +577,7 @@ static char *append_params(void *ta_parent, const char *device, const char *p)
abort();
}
static int try_open_device(struct ao *ao, const char *device)
static int try_open_device(struct ao *ao, const char *device, int mode)
{
struct priv *p = ao->priv;
int err;
@@ -534,7 +591,7 @@ static int try_open_device(struct ao *ao, const char *device)
map_iec958_srate(ao->samplerate));
const char *ac3_device = append_params(tmp, device, params);
MP_VERBOSE(ao, "opening device '%s' => '%s'\n", device, ac3_device);
err = snd_pcm_open(&p->alsa, ac3_device, SND_PCM_STREAM_PLAYBACK, 0);
err = snd_pcm_open(&p->alsa, ac3_device, SND_PCM_STREAM_PLAYBACK, mode);
if (err < 0) {
// Some spdif-capable devices do not accept the AES0 parameter,
// and instead require the iec958 pseudo-device (they will play
@@ -543,17 +600,22 @@ static int try_open_device(struct ao *ao, const char *device)
bstr dev;
bstr_split_tok(bstr0(device), ":", &dev, &(bstr){0});
if (bstr_equals0(dev, "default")) {
ac3_device = append_params(tmp, "iec958", params);
MP_VERBOSE(ao, "got error %d; opening iec fallback device '%s'\n",
err, ac3_device);
err = snd_pcm_open
(&p->alsa, ac3_device, SND_PCM_STREAM_PLAYBACK, 0);
const char *const fallbacks[] = {"hdmi", "iec958", NULL};
for (int n = 0; fallbacks[n]; n++) {
char *ndev = append_params(tmp, fallbacks[n], params);
MP_VERBOSE(ao, "got error '%s'; opening iec fallback "
"device '%s'\n", snd_strerror(err), ndev);
err = snd_pcm_open
(&p->alsa, ndev, SND_PCM_STREAM_PLAYBACK, mode);
if (err >= 0)
break;
}
}
}
talloc_free(tmp);
} else {
MP_VERBOSE(ao, "opening device '%s'\n", device);
err = snd_pcm_open(&p->alsa, device, SND_PCM_STREAM_PLAYBACK, 0);
err = snd_pcm_open(&p->alsa, device, SND_PCM_STREAM_PLAYBACK, mode);
}
return err;
@@ -563,6 +625,10 @@ static void uninit(struct ao *ao)
{
struct priv *p = ao->priv;
if (p->output)
snd_output_close(p->output);
p->output = NULL;
if (p->alsa) {
int err;
@@ -574,20 +640,35 @@ static void uninit(struct ao *ao)
alsa_error: ;
}
static int init_device(struct ao *ao)
#define INIT_DEVICE_ERR_GENERIC -1
#define INIT_DEVICE_ERR_HWPARAMS -2
static int init_device(struct ao *ao, int mode)
{
struct priv *p = ao->priv;
int ret = INIT_DEVICE_ERR_GENERIC;
char *tmp;
size_t tmp_s;
int err;
err = snd_output_buffer_open(&p->output);
CHECK_ALSA_ERROR("Unable to create output buffer");
const char *device = "default";
if (ao->device)
device = ao->device;
if (p->cfg_device && p->cfg_device[0])
device = p->cfg_device;
if (p->opts->device && p->opts->device[0])
device = p->opts->device;
err = try_open_device(ao, device);
err = try_open_device(ao, device, mode);
CHECK_ALSA_ERROR("Playback open error");
err = snd_pcm_dump(p->alsa, p->output);
CHECK_ALSA_WARN("Dump PCM error");
tmp_s = snd_output_buffer_string(p->output, &tmp);
if (tmp)
MP_DBG(ao, "PCM setup:\n---\n%.*s---\n", (int)tmp_s, tmp);
snd_output_flush(p->output);
err = snd_pcm_nonblock(p->alsa, 0);
CHECK_ALSA_WARN("Unable to set blocking mode");
@@ -597,12 +678,15 @@ static int init_device(struct ao *ao)
err = snd_pcm_hw_params_any(p->alsa, alsa_hwparams);
CHECK_ALSA_ERROR("Unable to get initial parameters");
dump_hw_params(ao, MSGL_DEBUG, "Start HW params:\n", alsa_hwparams);
// Some ALSA drivers have broken delay reporting, so disable the ALSA
// resampling plugin by default.
if (!p->cfg_resample) {
if (!p->opts->resample) {
err = snd_pcm_hw_params_set_rate_resample(p->alsa, alsa_hwparams, 0);
CHECK_ALSA_ERROR("Unable to disable resampling");
}
dump_hw_params(ao, MSGL_DEBUG, "HW params after rate:\n", alsa_hwparams);
snd_pcm_access_t access = af_fmt_is_planar(ao->format)
? SND_PCM_ACCESS_RW_NONINTERLEAVED
@@ -614,6 +698,7 @@ static int init_device(struct ao *ao)
err = snd_pcm_hw_params_set_access(p->alsa, alsa_hwparams, access);
}
CHECK_ALSA_ERROR("Unable to set access type");
dump_hw_params(ao, MSGL_DEBUG, "HW params after access:\n", alsa_hwparams);
bool found_format = false;
int try_formats[AF_FORMAT_COUNT];
@@ -637,25 +722,36 @@ static int init_device(struct ao *ao)
err = snd_pcm_hw_params_set_format(p->alsa, alsa_hwparams, p->alsa_fmt);
CHECK_ALSA_ERROR("Unable to set format");
dump_hw_params(ao, MSGL_DEBUG, "HW params after format:\n", alsa_hwparams);
struct mp_chmap dev_chmap = ao->channels;
if (af_fmt_is_spdif(ao->format) || p->cfg_ignore_chmap) {
dev_chmap.num = 0; // disable chmap API
} else if (dev_chmap.num == 1 && dev_chmap.speaker[0] == MP_SPEAKER_ID_FC) {
// As yet another ALSA API inconsistency, mono is not reported correctly.
dev_chmap.num = 0;
} else if (query_chmaps(ao, &dev_chmap)) {
ao->channels = dev_chmap;
} else {
// Assume only stereo and mono are supported.
mp_chmap_from_channels(&ao->channels, MPMIN(2, dev_chmap.num));
dev_chmap.num = 0;
// Stereo, or mono if input is 1 channel.
struct mp_chmap reduced;
mp_chmap_from_channels(&reduced, MPMIN(2, ao->channels.num));
struct mp_chmap dev_chmap = {0};
if (!af_fmt_is_spdif(ao->format) && !p->opts->ignore_chmap &&
!mp_chmap_equals(&ao->channels, &reduced))
{
struct mp_chmap res = ao->channels;
if (query_chmaps(ao, &res))
dev_chmap = res;
// Whatever it is, we dumb it down to mono or stereo. Some drivers may
// return things like bl-br, but the user (probably) still wants stereo.
// This also handles the failure case (dev_chmap.num==0).
if (dev_chmap.num <= 2) {
dev_chmap.num = 0;
ao->channels = reduced;
} else if (dev_chmap.num) {
ao->channels = dev_chmap;
}
}
int num_channels = ao->channels.num;
err = snd_pcm_hw_params_set_channels_near
(p->alsa, alsa_hwparams, &num_channels);
CHECK_ALSA_ERROR("Unable to set channels");
dump_hw_params(ao, MSGL_DEBUG, "HW params after channels:\n", alsa_hwparams);
if (num_channels > MP_NUM_CHANNELS) {
MP_FATAL(ao, "Too many audio channels (%d).\n", num_channels);
@@ -665,6 +761,7 @@ static int init_device(struct ao *ao)
err = snd_pcm_hw_params_set_rate_near
(p->alsa, alsa_hwparams, &ao->samplerate, NULL);
CHECK_ALSA_ERROR("Unable to set samplerate-2");
dump_hw_params(ao, MSGL_DEBUG, "HW params after rate-2:\n", alsa_hwparams);
snd_pcm_hw_params_t *hwparams_backup;
snd_pcm_hw_params_alloca(&hwparams_backup);
@@ -682,9 +779,14 @@ static int init_device(struct ao *ao)
if (err < 0)
snd_pcm_hw_params_copy(alsa_hwparams, hwparams_backup);
dump_hw_params(ao, MSGL_V, "Going to set final HW params:\n", alsa_hwparams);
/* finally install hardware parameters */
err = snd_pcm_hw_params(p->alsa, alsa_hwparams);
ret = INIT_DEVICE_ERR_HWPARAMS;
CHECK_ALSA_ERROR("Unable to set hw-parameters");
ret = INIT_DEVICE_ERR_GENERIC;
dump_hw_params(ao, MSGL_DEBUG, "Final HW params:\n", alsa_hwparams);
if (set_chmap(ao, &dev_chmap, num_channels) < 0)
goto alsa_error;
@@ -692,8 +794,13 @@ static int init_device(struct ao *ao)
if (num_channels != ao->channels.num) {
int req = ao->channels.num;
mp_chmap_from_channels(&ao->channels, MPMIN(2, num_channels));
mp_chmap_fill_na(&ao->channels, num_channels);
MP_ERR(ao, "Asked for %d channels, got %d - fallback to %s.\n", req,
num_channels, mp_chmap_to_str(&ao->channels));
if (num_channels != ao->channels.num) {
MP_FATAL(ao, "mismatching channel counts.\n");
goto alsa_error;
}
}
err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams, &p->buffersize);
@@ -736,22 +843,37 @@ static int init_device(struct ao *ao)
MP_VERBOSE(ao, "buffersize: %d samples\n", (int)p->buffersize);
MP_VERBOSE(ao, "period size: %d samples\n", (int)p->outburst);
ao->device_buffer = p->buffersize;
return 0;
alsa_error:
uninit(ao);
return -1;
return ret;
}
static int init(struct ao *ao)
{
struct priv *p = ao->priv;
if (!p->cfg_ni)
p->opts = mp_get_config_group(ao, ao->global, &ao_alsa_conf);
if (!p->opts->ni)
ao->format = af_fmt_from_planar(ao->format);
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
int r = init_device(ao);
int mode = 0;
int r = init_device(ao, mode);
if (r == INIT_DEVICE_ERR_HWPARAMS) {
// With some drivers, ALSA appears to be unable to set valid hwparams,
// but they work if at least SND_PCM_NO_AUTO_FORMAT is set. Also, it
// appears you can set this flag only on opening a device, thus there
// is the need to retry opening the device.
MP_WARN(ao, "Attempting to work around even more ALSA bugs...\n");
mode |= SND_PCM_NO_AUTO_CHANNELS | SND_PCM_NO_AUTO_FORMAT |
SND_PCM_NO_AUTO_RESAMPLE;
r = init_device(ao, mode);
}
// Sometimes, ALSA will advertise certain chmaps, but it's not possible to
// set them. This can happen with dmix: as of alsa 1.0.29, dmix can do
@@ -773,7 +895,7 @@ static int init(struct ao *ao)
MP_VERBOSE(ao, "Working around braindead dmix multichannel behavior.\n");
uninit(ao);
ao->channels = without_na;
r = init_device(ao);
r = init_device(ao, mode);
}
}
@@ -814,7 +936,7 @@ static double get_delay(struct ao *ao)
struct priv *p = ao->priv;
snd_pcm_sframes_t delay;
if (snd_pcm_state(p->alsa) == SND_PCM_STATE_PAUSED)
if (p->paused)
return p->delay_before_pause;
if (snd_pcm_delay(p->alsa, &delay) < 0)
@@ -828,27 +950,47 @@ static double get_delay(struct ao *ao)
return delay / (double)ao->samplerate;
}
// For stream-silence mode: replace remaining buffer with silence.
// Tries to cause an instant buffer underrun.
static void soft_reset(struct ao *ao)
{
struct priv *p = ao->priv;
snd_pcm_sframes_t frames = snd_pcm_rewindable(p->alsa);
if (frames > 0 && snd_pcm_state(p->alsa) == SND_PCM_STATE_RUNNING) {
frames = snd_pcm_rewind(p->alsa, frames);
if (frames < 0) {
int err = frames;
CHECK_ALSA_WARN("pcm rewind error");
}
}
}
static void audio_pause(struct ao *ao)
{
struct priv *p = ao->priv;
int err;
if (p->can_pause) {
if (p->paused)
return;
p->delay_before_pause = get_delay(ao);
p->prepause_frames = p->delay_before_pause * ao->samplerate;
if (ao->stream_silence) {
soft_reset(ao);
} else if (p->can_pause) {
if (snd_pcm_state(p->alsa) == SND_PCM_STATE_RUNNING) {
p->delay_before_pause = get_delay(ao);
err = snd_pcm_pause(p->alsa, 1);
CHECK_ALSA_ERROR("pcm pause error");
p->prepause_frames = 0;
}
} else {
if (snd_pcm_delay(p->alsa, &p->prepause_frames) < 0
|| p->prepause_frames < 0)
p->prepause_frames = 0;
p->delay_before_pause = p->prepause_frames / (double)ao->samplerate;
err = snd_pcm_drop(p->alsa);
CHECK_ALSA_ERROR("pcm drop error");
}
p->paused = true;
alsa_error: ;
}
@@ -870,9 +1012,15 @@ static void audio_resume(struct ao *ao)
struct priv *p = ao->priv;
int err;
if (!p->paused)
return;
resume_device(ao);
if (p->can_pause) {
if (ao->stream_silence) {
p->paused = false;
get_delay(ao); // recovers from underrun (as a side-effect)
} else if (p->can_pause) {
if (snd_pcm_state(p->alsa) == SND_PCM_STATE_PAUSED) {
err = snd_pcm_pause(p->alsa, 0);
CHECK_ALSA_ERROR("pcm resume error");
@@ -881,11 +1029,13 @@ static void audio_resume(struct ao *ao)
MP_VERBOSE(ao, "resume not supported by hardware\n");
err = snd_pcm_prepare(p->alsa);
CHECK_ALSA_ERROR("pcm prepare error");
if (p->prepause_frames)
ao_play_silence(ao, p->prepause_frames);
}
if (p->prepause_frames)
ao_play_silence(ao, p->prepause_frames);
alsa_error: ;
p->paused = false;
}
static void reset(struct ao *ao)
@@ -893,12 +1043,18 @@ static void reset(struct ao *ao)
struct priv *p = ao->priv;
int err;
p->paused = false;
p->prepause_frames = 0;
p->delay_before_pause = 0;
err = snd_pcm_drop(p->alsa);
CHECK_ALSA_ERROR("pcm prepare error");
err = snd_pcm_prepare(p->alsa);
CHECK_ALSA_ERROR("pcm prepare error");
if (ao->stream_silence) {
soft_reset(ao);
} else {
err = snd_pcm_drop(p->alsa);
CHECK_ALSA_ERROR("pcm prepare error");
err = snd_pcm_prepare(p->alsa);
CHECK_ALSA_ERROR("pcm prepare error");
}
alsa_error: ;
}
@@ -937,6 +1093,8 @@ static int play(struct ao *ao, void **data, int samples, int flags)
}
} while (res == 0);
p->paused = false;
return res < 0 ? -1 : res;
alsa_error:
@@ -981,7 +1139,8 @@ static bool is_useless_device(char *name)
{
char *crap[] = {"front", "rear", "center_lfe", "side", "surround21",
"surround40", "surround41", "surround50", "surround51", "surround71",
"sysdefault", "pulse", "null", "dsnoop", "dmix", "hw", "iec958"};
"sysdefault", "pulse", "null", "dsnoop", "dmix", "hw", "iec958",
"default"};
for (int i = 0; i < MP_ARRAY_SIZE(crap); i++) {
int l = strlen(crap[i]);
if (name && strncmp(name, crap[i], l) == 0 &&
@@ -997,6 +1156,8 @@ static void list_devs(struct ao *ao, struct ao_device_list *list)
if (snd_device_name_hint(-1, "pcm", &hints) < 0)
return;
ao_device_list_add(list, ao, &(struct ao_device_desc){"", ""});
for (int n = 0; hints[n]; n++) {
char *name = snd_device_name_get_hint(hints[n], "NAME");
char *desc = snd_device_name_get_hint(hints[n], "DESC");
@@ -1018,8 +1179,6 @@ static void list_devs(struct ao *ao, struct ao_device_list *list)
snd_device_name_free_hint(hints);
}
#define OPT_BASE_STRUCT struct priv
const struct ao_driver audio_out_alsa = {
.description = "ALSA audio output",
.name = "alsa",
@@ -1037,20 +1196,5 @@ const struct ao_driver audio_out_alsa = {
.wakeup = ao_wakeup_poll,
.list_devs = list_devs,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {
.cfg_mixer_device = "default",
.cfg_mixer_name = "Master",
.cfg_mixer_index = 0,
.cfg_ni = 0,
},
.options = (const struct m_option[]) {
OPT_STRING("device", cfg_device, 0),
OPT_FLAG("resample", cfg_resample, 0),
OPT_STRING("mixer-device", cfg_mixer_device, 0),
OPT_STRING("mixer-name", cfg_mixer_name, 0),
OPT_INTRANGE("mixer-index", cfg_mixer_index, 0, 0, 99),
OPT_FLAG("non-interleaved", cfg_ni, 0),
OPT_FLAG("ignore-chmap", cfg_ignore_chmap, 0),
{0}
},
.global_opts = &ao_alsa_conf,
};
+198
View File
@@ -0,0 +1,198 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "ao.h"
#include "internal.h"
#include "audio/format.h"
#include "osdep/timer.h"
#include "options/m_option.h"
#include "misc/ring.h"
#include "common/msg.h"
#include "ao_coreaudio_utils.h"
#include "ao_coreaudio_chmap.h"
#import <AudioUnit/AudioUnit.h>
#import <CoreAudio/CoreAudioTypes.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import <mach/mach_time.h>
struct priv {
AudioUnit audio_unit;
double device_latency;
};
static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags,
const AudioTimeStamp *ts, UInt32 bus,
UInt32 frames, AudioBufferList *buffer_list)
{
struct ao *ao = ctx;
struct priv *p = ao->priv;
void *planes[MP_NUM_CHANNELS] = {0};
for (int n = 0; n < ao->num_planes; n++)
planes[n] = buffer_list->mBuffers[n].mData;
int64_t end = mp_time_us();
end += ca_frames_to_us(ao, frames);
end += p->device_latency * 1e6;
ao_read_data(ao, planes, frames, end);
return noErr;
}
static bool init_audiounit(struct ao *ao)
{
AudioStreamBasicDescription asbd;
OSStatus err;
uint32_t size;
struct priv *p = ao->priv;
AVAudioSession *instance = AVAudioSession.sharedInstance;
AVAudioSessionPortDescription *port = nil;
NSInteger maxChannels = instance.maximumOutputNumberOfChannels;
NSInteger prefChannels = MIN(maxChannels, ao->channels.num);
[instance setCategory:AVAudioSessionCategoryPlayback error:nil];
[instance setMode:AVAudioSessionModeMoviePlayback error:nil];
[instance setActive:YES error:nil];
[instance setPreferredOutputNumberOfChannels:prefChannels error:nil];
AudioComponentDescription desc = (AudioComponentDescription) {
.componentType = kAudioUnitType_Output,
.componentSubType = kAudioUnitSubType_RemoteIO,
.componentManufacturer = kAudioUnitManufacturer_Apple,
.componentFlags = 0,
.componentFlagsMask = 0,
};
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
if (comp == NULL) {
MP_ERR(ao, "unable to find audio component\n");
goto coreaudio_error;
}
err = AudioComponentInstanceNew(comp, &(p->audio_unit));
CHECK_CA_ERROR("unable to open audio component");
err = AudioUnitInitialize(p->audio_unit);
CHECK_CA_ERROR_L(coreaudio_error_component,
"unable to initialize audio unit");
if (af_fmt_is_spdif(ao->format) || instance.outputNumberOfChannels <= 2) {
ao->channels = (struct mp_chmap)MP_CHMAP_INIT_STEREO;
} else {
port = instance.currentRoute.outputs.firstObject;
if (port.channels.count == 2 &&
port.channels[0].channelLabel == kAudioChannelLabel_Unknown) {
// Special case when using an HDMI adapter. The iOS device will
// perform SPDIF conversion for us, so send all available channels
// using the AC3 mapping.
ao->channels = (struct mp_chmap)MP_CHMAP6(FL, FC, FR, SL, SR, LFE);
} else {
ao->channels.num = (uint8_t)port.channels.count;
for (AVAudioSessionChannelDescription *ch in port.channels) {
ao->channels.speaker[ch.channelNumber - 1] =
ca_label_to_mp_speaker_id(ch.channelLabel);
}
}
}
ca_fill_asbd(ao, &asbd);
size = sizeof(AudioStreamBasicDescription);
err = AudioUnitSetProperty(p->audio_unit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, 0, &asbd, size);
CHECK_CA_ERROR_L(coreaudio_error_audiounit,
"unable to set the input format on the audio unit");
AURenderCallbackStruct render_cb = (AURenderCallbackStruct) {
.inputProc = render_cb_lpcm,
.inputProcRefCon = ao,
};
err = AudioUnitSetProperty(p->audio_unit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input, 0, &render_cb,
sizeof(AURenderCallbackStruct));
CHECK_CA_ERROR_L(coreaudio_error_audiounit,
"unable to set render callback on audio unit");
return true;
coreaudio_error_audiounit:
AudioUnitUninitialize(p->audio_unit);
coreaudio_error_component:
AudioComponentInstanceDispose(p->audio_unit);
coreaudio_error:
return false;
}
static void stop(struct ao *ao)
{
struct priv *p = ao->priv;
OSStatus err = AudioOutputUnitStop(p->audio_unit);
CHECK_CA_WARN("can't stop audio unit");
}
static void start(struct ao *ao)
{
struct priv *p = ao->priv;
AVAudioSession *instance = AVAudioSession.sharedInstance;
p->device_latency = [instance outputLatency];
OSStatus err = AudioOutputUnitStart(p->audio_unit);
CHECK_CA_WARN("can't start audio unit");
}
static void uninit(struct ao *ao)
{
struct priv *p = ao->priv;
AudioOutputUnitStop(p->audio_unit);
AudioUnitUninitialize(p->audio_unit);
AudioComponentInstanceDispose(p->audio_unit);
[AVAudioSession.sharedInstance
setActive:NO
withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
error:nil];
}
static int init(struct ao *ao)
{
if (!init_audiounit(ao))
goto coreaudio_error;
return CONTROL_OK;
coreaudio_error:
return CONTROL_ERROR;
}
#define OPT_BASE_STRUCT struct priv
const struct ao_driver audio_out_audiounit = {
.description = "AudioUnit (iOS)",
.name = "audiounit",
.uninit = uninit,
.init = init,
.pause = stop,
.resume = start,
.priv_size = sizeof(struct priv),
};
+3 -9
View File
@@ -39,7 +39,6 @@ struct priv {
AudioStreamID original_asbd_stream;
int change_physical_format;
int exclusive;
};
static int64_t ca_get_hardware_latency(struct ao *ao) {
@@ -133,11 +132,6 @@ static bool reinit_device(struct ao *ao) {
OSStatus err = ca_select_device(ao, ao->device, &p->device);
CHECK_CA_ERROR("failed to select device");
char *uid;
err = CA_GET_STR(p->device, kAudioDevicePropertyDeviceUID, &uid);
CHECK_CA_ERROR("failed to get device UID");
ao->detected_device = talloc_steal(ao, uid);
return true;
coreaudio_error:
@@ -148,7 +142,7 @@ static int init(struct ao *ao)
{
struct priv *p = ao->priv;
if (!af_fmt_is_pcm(ao->format) || p->exclusive) {
if (!af_fmt_is_pcm(ao->format) || (ao->init_flags & AO_INIT_EXCLUSIVE)) {
MP_VERBOSE(ao, "redirecting to coreaudio_exclusive\n");
ao->redirect = "coreaudio_exclusive";
return CONTROL_ERROR;
@@ -424,7 +418,7 @@ const struct ao_driver audio_out_coreaudio = {
.uninit = uninit,
.init = init,
.control = control,
.pause = stop,
.reset = stop,
.resume = start,
.hotplug_init = hotplug_init,
.hotplug_uninit = hotplug_uninit,
@@ -432,7 +426,7 @@ const struct ao_driver audio_out_coreaudio = {
.priv_size = sizeof(struct priv),
.options = (const struct m_option[]){
OPT_FLAG("change-physical-format", change_physical_format, 0),
OPT_FLAG("exclusive", exclusive, 0),
{0}
},
.options_prefix = "coreaudio",
};
+3 -1
View File
@@ -56,7 +56,7 @@ static const int speaker_map[][2] = {
{ 0, -1 },
};
static int ca_label_to_mp_speaker_id(AudioChannelLabel label)
int ca_label_to_mp_speaker_id(AudioChannelLabel label)
{
for (int i = 0; speaker_map[i][1] >= 0; i++)
if (speaker_map[i][0] == label)
@@ -64,6 +64,7 @@ static int ca_label_to_mp_speaker_id(AudioChannelLabel label)
return -1;
}
#if HAVE_COREAUDIO
static void ca_log_layout(struct ao *ao, int l, AudioChannelLayout *layout)
{
if (!mp_msg_test(ao->log, l))
@@ -327,3 +328,4 @@ void ca_get_active_chmap(struct ao *ao, AudioDeviceID device, int channel_count,
MP_WARN(ao, "mismatching channels - falling back to %s\n",
mp_chmap_to_str(out_map));
}
#endif
+4
View File
@@ -22,8 +22,12 @@
struct mp_chmap;
int ca_label_to_mp_speaker_id(AudioChannelLabel label);
#if HAVE_COREAUDIO
bool ca_init_chmap(struct ao *ao, AudioDeviceID device);
void ca_get_active_chmap(struct ao *ao, AudioDeviceID device, int channel_count,
struct mp_chmap *out_map);
#endif
#endif
+2 -2
View File
@@ -41,7 +41,7 @@
#include "internal.h"
#include "audio/format.h"
#include "osdep/timer.h"
#include "osdep/atomics.h"
#include "osdep/atomic.h"
#include "options/m_option.h"
#include "common/msg.h"
#include "audio/out/ao_coreaudio_chmap.h"
@@ -399,7 +399,7 @@ const struct ao_driver audio_out_coreaudio_exclusive = {
.name = "coreaudio_exclusive",
.uninit = uninit,
.init = init,
.pause = audio_pause,
.reset = audio_pause,
.resume = audio_resume,
.list_devs = ca_get_device_list,
.priv_size = sizeof(struct priv),
+1 -1
View File
@@ -70,7 +70,7 @@ OSStatus ca_get_ary(AudioObjectID id, ca_scope scope, ca_sel selector,
return err;
coreaudio_error_free:
free(*data);
talloc_free(*data);
coreaudio_error:
return err;
}
+20 -29
View File
@@ -22,15 +22,17 @@
* on CoreAudio but not the AUHAL (such as using AudioQueue services).
*/
#include <CoreAudio/HostTime.h>
#include "audio/out/ao_coreaudio_utils.h"
#include "audio/out/ao_coreaudio_properties.h"
#include "osdep/timer.h"
#include "osdep/endian.h"
#include "osdep/semaphore.h"
#include "audio/format.h"
#if HAVE_COREAUDIO
#include "audio/out/ao_coreaudio_properties.h"
#include <CoreAudio/HostTime.h>
#endif
CFStringRef cfstr_from_cstr(char *str)
{
return CFStringCreateWithCString(NULL, str, CA_CFSTR_ENCODING);
@@ -46,6 +48,7 @@ char *cfstr_get_cstr(CFStringRef cfstr)
return buffer;
}
#if HAVE_COREAUDIO
static bool ca_is_output_device(struct ao *ao, AudioDeviceID dev)
{
size_t n_buffers;
@@ -114,6 +117,13 @@ OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device)
kAudioObjectSystemObject, &p_addr, 0, 0, &size, &v);
CFRelease(uid);
CHECK_CA_ERROR("unable to query for device UID");
uint32_t is_alive = 1;
err = CA_GET(*device, kAudioDevicePropertyDeviceIsAlive, &is_alive);
CHECK_CA_ERROR("could not check whether device is alive (invalid device?)");
if (!is_alive)
MP_WARN(ao, "device is not alive!\n");
} else {
// device not set by user, get the default one
err = CA_GET(kAudioObjectSystemObject,
@@ -135,12 +145,13 @@ OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device)
coreaudio_error:
return err;
}
#endif
bool check_ca_st(struct ao *ao, int level, OSStatus code, const char *message)
{
if (code == noErr) return true;
mp_msg(ao->log, level, "%s (%s)\n", message, mp_tag_str(code));
mp_msg(ao->log, level, "%s (%s/%d)\n", message, mp_tag_str(code), (int)code);
return false;
}
@@ -299,6 +310,7 @@ int64_t ca_frames_to_us(struct ao *ao, uint32_t frames)
return frames / (float) ao->samplerate * 1e6;
}
#if HAVE_COREAUDIO
int64_t ca_get_latency(const AudioTimeStamp *ts)
{
uint64_t out = AudioConvertHostTimeToNanos(ts->mHostTime);
@@ -323,6 +335,9 @@ bool ca_stream_supports_compressed(struct ao *ao, AudioStreamID stream)
for (int i = 0; i < n_formats; i++) {
AudioStreamBasicDescription asbd = formats[i].mFormat;
ca_print_asbd(ao, "- ", &asbd);
if (ca_formatid_is_compressed(asbd.mFormatID)) {
talloc_free(formats);
return true;
@@ -334,30 +349,6 @@ coreaudio_error:
return false;
}
bool ca_device_supports_compressed(struct ao *ao, AudioDeviceID device)
{
AudioStreamID *streams = NULL;
size_t n_streams;
/* Retrieve all the output streams. */
OSStatus err =
CA_GET_ARY_O(device, kAudioDevicePropertyStreams, &streams, &n_streams);
CHECK_CA_ERROR("could not get number of streams.");
for (int i = 0; i < n_streams; i++) {
if (ca_stream_supports_compressed(ao, streams[i])) {
talloc_free(streams);
return true;
}
}
talloc_free(streams);
coreaudio_error:
return false;
}
OSStatus ca_lock_device(AudioDeviceID device, pid_t *pid)
{
*pid = getpid();
@@ -536,4 +527,4 @@ coreaudio_error:
sem_destroy(&wakeup);
return format_set;
}
#endif
+6 -1
View File
@@ -49,7 +49,9 @@ bool check_ca_st(struct ao *ao, int level, OSStatus code, const char *message);
} while (0)
void ca_get_device_list(struct ao *ao, struct ao_device_list *list);
#if HAVE_COREAUDIO
OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device);
#endif
bool ca_formatid_is_compressed(uint32_t formatid);
void ca_fill_asbd(struct ao *ao, AudioStreamBasicDescription *asbd);
@@ -63,9 +65,11 @@ bool ca_asbd_is_better(AudioStreamBasicDescription *req,
AudioStreamBasicDescription *new);
int64_t ca_frames_to_us(struct ao *ao, uint32_t frames);
#if HAVE_COREAUDIO
int64_t ca_get_latency(const AudioTimeStamp *ts);
#endif
bool ca_device_supports_compressed(struct ao *ao, AudioDeviceID device);
#if HAVE_COREAUDIO
bool ca_stream_supports_compressed(struct ao *ao, AudioStreamID stream);
OSStatus ca_lock_device(AudioDeviceID device, pid_t *pid);
OSStatus ca_unlock_device(AudioDeviceID device, pid_t *pid);
@@ -74,5 +78,6 @@ OSStatus ca_enable_mixing(struct ao *ao, AudioDeviceID device, bool changed);
int64_t ca_get_device_latency_us(struct ao *ao, AudioDeviceID device);
bool ca_change_physical_format_sync(struct ao *ao, AudioStreamID stream,
AudioStreamBasicDescription change_format);
#endif
#endif /* MPV_COREAUDIO_UTILS_H */
+37 -25
View File
@@ -34,24 +34,48 @@
#include "internal.h"
#include "audio/format.h"
#include "osdep/timer.h"
#include "options/m_config.h"
#include "options/m_option.h"
#include <jack/jack.h>
struct priv {
jack_client_t *client;
float jack_latency;
char *cfg_port;
char *cfg_client_name;
struct jack_opts {
char *port;
char *client_name;
int connect;
int autostart;
int stdlayout;
};
#define OPT_BASE_STRUCT struct jack_opts
static const struct m_sub_options ao_jack_conf = {
.opts = (const struct m_option[]){
OPT_STRING("jack-port", port, 0),
OPT_STRING("jack-name", client_name, 0),
OPT_FLAG("jack-autostart", autostart, 0),
OPT_FLAG("jack-connect", connect, 0),
OPT_CHOICE("jack-std-channel-layout", stdlayout, 0,
({"waveext", 0}, {"any", 1})),
{0}
},
.defaults = &(const struct jack_opts) {
.client_name = "mpv",
.connect = 1,
},
.size = sizeof(struct jack_opts),
};
struct priv {
jack_client_t *client;
float jack_latency;
int last_chunk;
int num_ports;
jack_port_t *ports[MP_NUM_CHANNELS];
int activated;
struct jack_opts *opts;
};
static int process(jack_nframes_t nframes, void *arg)
@@ -77,7 +101,7 @@ connect_to_outports(struct ao *ao)
{
struct priv *p = ao->priv;
char *port_name = (p->cfg_port && p->cfg_port[0]) ? p->cfg_port : NULL;
char *port_name = (p->opts->port && p->opts->port[0]) ? p->opts->port : NULL;
const char **matching_ports = NULL;
int port_flags = JackPortIsInput;
int i;
@@ -144,7 +168,7 @@ static void resume(struct ao *ao)
if (jack_activate(p->client))
MP_FATAL(ao, "activate failed\n");
if (p->connect)
if (p->opts->connect)
connect_to_outports(ao);
}
}
@@ -155,9 +179,11 @@ static int init(struct ao *ao)
struct mp_chmap_sel sel = {0};
jack_options_t open_options;
p->opts = mp_get_config_group(ao, ao->global, &ao_jack_conf);
ao->format = AF_FORMAT_FLOATP;
switch (p->stdlayout) {
switch (p->opts->stdlayout) {
case 0:
mp_chmap_sel_add_waveext(&sel);
break;
@@ -170,10 +196,10 @@ static int init(struct ao *ao)
goto err_chmap;
open_options = JackNullOption;
if (!p->autostart)
if (!p->opts->autostart)
open_options |= JackNoStartServer;
p->client = jack_client_open(p->cfg_client_name, open_options, NULL);
p->client = jack_client_open(p->opts->client_name, open_options, NULL);
if (!p->client) {
MP_FATAL(ao, "cannot open server\n");
goto err_client_open;
@@ -213,8 +239,6 @@ static void uninit(struct ao *ao)
jack_client_close(p->client);
}
#define OPT_BASE_STRUCT struct priv
const struct ao_driver audio_out_jack = {
.description = "JACK audio output",
.name = "jack",
@@ -222,17 +246,5 @@ const struct ao_driver audio_out_jack = {
.uninit = uninit,
.resume = resume,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {
.cfg_client_name = "mpv",
.connect = 1,
},
.options = (const struct m_option[]) {
OPT_STRING("port", cfg_port, 0),
OPT_STRING("name", cfg_client_name, 0),
OPT_FLAG("autostart", autostart, 0),
OPT_FLAG("connect", connect, 0),
OPT_CHOICE("std-channel-layout", stdlayout, 0,
({"waveext", 0}, {"any", 1})),
{0}
},
.global_opts = &ao_jack_conf,
};
+133 -111
View File
@@ -39,9 +39,8 @@
#include "common/encode_lavc.h"
struct priv {
uint8_t *buffer;
size_t buffer_size;
AVStream *stream;
AVCodecContext *codec;
int pcmhack;
int aframesize;
int aframecount;
@@ -98,15 +97,14 @@ static int init(struct ao *ao)
pthread_mutex_lock(&ao->encode_lavc_ctx->lock);
ac->stream = encode_lavc_alloc_stream(ao->encode_lavc_ctx,
AVMEDIA_TYPE_AUDIO);
if (!ac->stream) {
MP_ERR(ao, "could not get a new audio stream\n");
goto fail;
if (encode_lavc_alloc_stream(ao->encode_lavc_ctx,
AVMEDIA_TYPE_AUDIO,
&ac->stream, &ac->codec) < 0) {
MP_ERR(ao, "could not get a new audio stream\n");
goto fail;
}
codec = encode_lavc_get_codec(ao->encode_lavc_ctx, ac->stream);
codec = ao->encode_lavc_ctx->ac;
int samplerate = af_select_best_samplerate(ao->samplerate,
codec->supported_samplerates);
@@ -118,46 +116,38 @@ static int init(struct ao *ao)
// Using codec->time_bvase is deprecated, but needed for older lavf.
ac->stream->time_base.num = 1;
ac->stream->time_base.den = ao->samplerate;
ac->stream->codec->time_base.num = 1;
ac->stream->codec->time_base.den = ao->samplerate;
ac->codec->time_base.num = 1;
ac->codec->time_base.den = ao->samplerate;
ac->stream->codec->sample_rate = ao->samplerate;
ac->codec->sample_rate = ao->samplerate;
struct mp_chmap_sel sel = {0};
mp_chmap_sel_add_any(&sel);
if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
if (!ao_chmap_sel_adjust2(ao, &sel, &ao->channels, false))
goto fail;
mp_chmap_reorder_to_lavc(&ao->channels);
ac->stream->codec->channels = ao->channels.num;
ac->stream->codec->channel_layout = mp_chmap_to_lavc(&ao->channels);
ac->codec->channels = ao->channels.num;
ac->codec->channel_layout = mp_chmap_to_lavc(&ao->channels);
ac->stream->codec->sample_fmt = AV_SAMPLE_FMT_NONE;
ac->codec->sample_fmt = AV_SAMPLE_FMT_NONE;
select_format(ao, codec);
ac->sample_size = af_fmt_to_bytes(ao->format);
ac->stream->codec->sample_fmt = af_to_avformat(ao->format);
ac->stream->codec->bits_per_raw_sample = ac->sample_size * 8;
ac->codec->sample_fmt = af_to_avformat(ao->format);
ac->codec->bits_per_raw_sample = ac->sample_size * 8;
if (encode_lavc_open_codec(ao->encode_lavc_ctx, ac->stream) < 0)
if (encode_lavc_open_codec(ao->encode_lavc_ctx, ac->codec) < 0)
goto fail;
ac->pcmhack = 0;
if (ac->stream->codec->frame_size <= 1)
ac->pcmhack = av_get_bits_per_sample(ac->stream->codec->codec_id) / 8;
if (ac->codec->frame_size <= 1)
ac->pcmhack = av_get_bits_per_sample(ac->codec->codec_id) / 8;
if (ac->pcmhack) {
if (ac->pcmhack)
ac->aframesize = 16384; // "enough"
ac->buffer_size =
ac->aframesize * ac->pcmhack * ao->channels.num * 2 + 200;
} else {
ac->aframesize = ac->stream->codec->frame_size;
ac->buffer_size =
ac->aframesize * ac->sample_size * ao->channels.num * 2 + 200;
}
if (ac->buffer_size < FF_MIN_BUFFER_SIZE)
ac->buffer_size = FF_MIN_BUFFER_SIZE;
ac->buffer = talloc_size(ac, ac->buffer_size);
else
ac->aframesize = ac->codec->frame_size;
// enough frames for at least 0.25 seconds
ac->framecount = ceil(ao->samplerate * 0.25 / ac->aframesize);
@@ -182,7 +172,7 @@ fail:
}
// close audio device
static int encode(struct ao *ao, double apts, void **data);
static void encode(struct ao *ao, double apts, void **data);
static void uninit(struct ao *ao)
{
struct priv *ac = ao->priv;
@@ -199,12 +189,12 @@ static void uninit(struct ao *ao)
return;
}
if (ac->buffer) {
if (ac->stream) {
double outpts = ac->expected_next_pts;
if (!ectx->options->rawts && ectx->options->copyts)
outpts += ectx->discontinuity_pts_offset;
outpts += encode_lavc_getoffset(ectx, ac->stream);
while (encode(ao, outpts, NULL) > 0) ;
outpts += encode_lavc_getoffset(ectx, ac->codec);
encode(ao, outpts, NULL);
}
pthread_mutex_unlock(&ectx->lock);
@@ -220,24 +210,107 @@ static int get_space(struct ao *ao)
return ac->aframesize * ac->framecount;
}
static void write_packet(struct ao *ao, AVPacket *packet)
{
// TODO: Can we unify this with the equivalent video code path?
struct priv *ac = ao->priv;
packet->stream_index = ac->stream->index;
if (packet->pts != AV_NOPTS_VALUE) {
packet->pts = av_rescale_q(packet->pts,
ac->codec->time_base,
ac->stream->time_base);
} else {
// Do we need this at all? Better be safe than sorry...
MP_WARN(ao, "encoder lost pts, why?\n");
if (ac->savepts != MP_NOPTS_VALUE) {
packet->pts = av_rescale_q(ac->savepts,
ac->codec->time_base,
ac->stream->time_base);
}
}
if (packet->dts != AV_NOPTS_VALUE) {
packet->dts = av_rescale_q(packet->dts,
ac->codec->time_base,
ac->stream->time_base);
}
if (packet->duration > 0) {
packet->duration = av_rescale_q(packet->duration,
ac->codec->time_base,
ac->stream->time_base);
}
ac->savepts = AV_NOPTS_VALUE;
if (encode_lavc_write_frame(ao->encode_lavc_ctx,
ac->stream, packet) < 0) {
MP_ERR(ao, "error writing at %d %d/%d\n",
(int) packet->pts,
ac->stream->time_base.num,
ac->stream->time_base.den);
return;
}
}
static void encode_audio_and_write(struct ao *ao, AVFrame *frame)
{
// TODO: Can we unify this with the equivalent video code path?
struct priv *ac = ao->priv;
AVPacket packet = {0};
int status = avcodec_send_frame(ac->codec, frame);
if (status < 0) {
MP_ERR(ao, "error encoding at %d %d/%d\n",
frame ? (int) frame->pts : -1,
ac->codec->time_base.num,
ac->codec->time_base.den);
return;
}
for (;;) {
av_init_packet(&packet);
status = avcodec_receive_packet(ac->codec, &packet);
if (status == AVERROR(EAGAIN)) { // No more packets for now.
if (frame == NULL) {
MP_ERR(ao, "sent flush frame, got EAGAIN");
}
break;
}
if (status == AVERROR_EOF) { // No more packets, ever.
if (frame != NULL) {
MP_ERR(ao, "sent audio frame, got EOF");
}
break;
}
if (status < 0) {
MP_ERR(ao, "error encoding at %d %d/%d\n",
frame ? (int) frame->pts : -1,
ac->codec->time_base.num,
ac->codec->time_base.den);
break;
}
if (frame) {
if (ac->savepts == AV_NOPTS_VALUE)
ac->savepts = frame->pts;
}
encode_lavc_write_stats(ao->encode_lavc_ctx, ac->codec);
write_packet(ao, &packet);
av_packet_unref(&packet);
}
}
// must get exactly ac->aframesize amount of data
static int encode(struct ao *ao, double apts, void **data)
static void encode(struct ao *ao, double apts, void **data)
{
AVPacket packet;
struct priv *ac = ao->priv;
struct encode_lavc_context *ectx = ao->encode_lavc_ctx;
double realapts = ac->aframecount * (double) ac->aframesize /
ao->samplerate;
int status, gotpacket;
ac->aframecount++;
if (data)
ectx->audio_pts_offset = realapts - apts;
av_init_packet(&packet);
packet.data = ac->buffer;
packet.size = ac->buffer_size;
if(data) {
AVFrame *frame = av_frame_alloc();
frame->format = af_to_avformat(ao->format);
@@ -252,82 +325,29 @@ static int encode(struct ao *ao, double apts, void **data)
if (ectx->options->rawts || ectx->options->copyts) {
// real audio pts
frame->pts = floor(apts * ac->stream->codec->time_base.den / ac->stream->codec->time_base.num + 0.5);
frame->pts = floor(apts * ac->codec->time_base.den / ac->codec->time_base.num + 0.5);
} else {
// audio playback time
frame->pts = floor(realapts * ac->stream->codec->time_base.den / ac->stream->codec->time_base.num + 0.5);
frame->pts = floor(realapts * ac->codec->time_base.den / ac->codec->time_base.num + 0.5);
}
int64_t frame_pts = av_rescale_q(frame->pts, ac->stream->codec->time_base, ac->worst_time_base);
int64_t frame_pts = av_rescale_q(frame->pts, ac->codec->time_base, ac->worst_time_base);
if (ac->lastpts != AV_NOPTS_VALUE && frame_pts <= ac->lastpts) {
// this indicates broken video
// (video pts failing to increase fast enough to match audio)
MP_WARN(ao, "audio frame pts went backwards (%d <- %d), autofixed\n",
(int)frame->pts, (int)ac->lastpts);
frame_pts = ac->lastpts + 1;
frame->pts = av_rescale_q(frame_pts, ac->worst_time_base, ac->stream->codec->time_base);
frame->pts = av_rescale_q(frame_pts, ac->worst_time_base, ac->codec->time_base);
}
ac->lastpts = frame_pts;
frame->quality = ac->stream->codec->global_quality;
status = avcodec_encode_audio2(ac->stream->codec, &packet, frame, &gotpacket);
if (!status) {
if (ac->savepts == AV_NOPTS_VALUE)
ac->savepts = frame->pts;
}
frame->quality = ac->codec->global_quality;
encode_audio_and_write(ao, frame);
av_frame_free(&frame);
}
else
{
status = avcodec_encode_audio2(ac->stream->codec, &packet, NULL, &gotpacket);
}
if(status) {
MP_ERR(ao, "error encoding\n");
return -1;
}
if(!gotpacket)
return 0;
MP_DBG(ao, "got pts %f (playback time: %f); out size: %d\n",
apts, realapts, packet.size);
encode_lavc_write_stats(ao->encode_lavc_ctx, ac->stream);
packet.stream_index = ac->stream->index;
// Do we need this at all? Better be safe than sorry...
if (packet.pts == AV_NOPTS_VALUE) {
MP_WARN(ao, "encoder lost pts, why?\n");
if (ac->savepts != MP_NOPTS_VALUE)
packet.pts = ac->savepts;
}
if (packet.pts != AV_NOPTS_VALUE)
packet.pts = av_rescale_q(packet.pts, ac->stream->codec->time_base,
ac->stream->time_base);
if (packet.dts != AV_NOPTS_VALUE)
packet.dts = av_rescale_q(packet.dts, ac->stream->codec->time_base,
ac->stream->time_base);
if(packet.duration > 0)
packet.duration = av_rescale_q(packet.duration, ac->stream->codec->time_base,
ac->stream->time_base);
ac->savepts = AV_NOPTS_VALUE;
if (encode_lavc_write_frame(ao->encode_lavc_ctx, &packet) < 0) {
MP_ERR(ao, "error writing at %f %f/%f\n",
realapts, (double) ac->stream->time_base.num,
(double) ac->stream->time_base.den);
return -1;
}
return packet.size;
encode_audio_and_write(ao, NULL);
}
// this should round samples down to frame sizes
@@ -377,22 +397,22 @@ static int play(struct ao *ao, void **data, int samples, int flags)
}
if (ac->worst_time_base.den == 0) {
//if (ac->stream->codec->time_base.num / ac->stream->codec->time_base.den >= ac->stream->time_base.num / ac->stream->time_base.den)
if (ac->stream->codec->time_base.num * (double) ac->stream->time_base.den >=
ac->stream->time_base.num * (double) ac->stream->codec->time_base.den) {
//if (ac->codec->time_base.num / ac->codec->time_base.den >= ac->stream->time_base.num / ac->stream->time_base.den)
if (ac->codec->time_base.num * (double) ac->stream->time_base.den >=
ac->stream->time_base.num * (double) ac->codec->time_base.den) {
MP_VERBOSE(ao, "NOTE: using codec time base (%d/%d) for pts "
"adjustment; the stream base (%d/%d) is not worse.\n",
(int)ac->stream->codec->time_base.num,
(int)ac->stream->codec->time_base.den,
(int)ac->codec->time_base.num,
(int)ac->codec->time_base.den,
(int)ac->stream->time_base.num,
(int)ac->stream->time_base.den);
ac->worst_time_base = ac->stream->codec->time_base;
ac->worst_time_base = ac->codec->time_base;
ac->worst_time_base_is_stream = 0;
} else {
MP_WARN(ao, "NOTE: not using codec time base (%d/%d) for pts "
"adjustment; the stream base (%d/%d) is worse.\n",
(int)ac->stream->codec->time_base.num,
(int)ac->stream->codec->time_base.den,
(int)ac->codec->time_base.num,
(int)ac->codec->time_base.den,
(int)ac->stream->time_base.num,
(int)ac->stream->time_base.den);
ac->worst_time_base = ac->stream->time_base;
@@ -437,7 +457,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
}
// Shift pts by the pts offset first.
outpts += encode_lavc_getoffset(ectx, ac->stream);
outpts += encode_lavc_getoffset(ectx, ac->codec);
while (samples - bufpos >= ac->aframesize) {
void *start[MP_NUM_CHANNELS] = {0};
@@ -492,3 +512,5 @@ const struct ao_driver audio_out_lavc = {
.play = play,
.drain = drain,
};
// vim: sw=4 ts=4 et tw=80
+6 -11
View File
@@ -57,7 +57,7 @@ struct priv {
// (This is not needed by the AO API, but many AOs behave this way.)
int outburst; // samples
char **channel_layouts;
struct m_channels channel_layouts;
};
static void drain(struct ao *ao)
@@ -91,15 +91,9 @@ static int init(struct ao *ao)
ao->untimed = priv->untimed;
struct mp_chmap_sel sel = {.tmp = ao};
if (priv->channel_layouts) {
for (int n = 0; priv->channel_layouts[n]; n++) {
struct mp_chmap map = {0};
if (!mp_chmap_from_str(&map, bstr0(priv->channel_layouts[n]))) {
MP_FATAL(ao, "Invalid channel map in option.\n");
return -1;
}
mp_chmap_sel_add_map(&sel, &map);
}
if (priv->channel_layouts.num_chmaps) {
for (int n = 0; n < priv->channel_layouts.num_chmaps; n++)
mp_chmap_sel_add_map(&sel, &priv->channel_layouts.chmaps[n]);
} else {
mp_chmap_sel_add_any(&sel);
}
@@ -244,7 +238,8 @@ const struct ao_driver audio_out_null = {
OPT_FLOATRANGE("latency", latency_sec, 0, 0, 100),
OPT_FLAG("broken-eof", broken_eof, 0),
OPT_FLAG("broken-delay", broken_delay, 0),
OPT_STRINGLIST("channel-layouts", channel_layouts, 0),
OPT_CHANNELS("channel-layouts", channel_layouts, 0),
{0}
},
.options_prefix = "ao-null",
};
+18 -2
View File
@@ -24,6 +24,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#ifdef __APPLE__
#ifndef AL_FORMAT_MONO_FLOAT32
#define AL_FORMAT_MONO_FLOAT32 0x10010
#endif
#ifndef AL_FORMAT_STEREO_FLOAT32
#define AL_FORMAT_STEREO_FLOAT32 0x10011
#endif
#ifndef AL_FORMAT_MONO_DOUBLE_EXT
#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012
#endif
#include <OpenAL/MacOSX_OALExtensions.h>
#else
#ifdef OPENAL_AL_H
#include <OpenAL/alc.h>
#include <OpenAL/al.h>
@@ -33,6 +46,7 @@
#include <AL/al.h>
#include <AL/alext.h>
#endif
#endif // __APPLE__
#include "common/msg.h"
@@ -96,7 +110,7 @@ static int validate_device_opt(struct mp_log *log, const m_option_t *opt,
mp_info(log, " '%s'\n", list);
list = list + strlen(list) + 1;
}
return M_OPT_EXIT - 1;
return M_OPT_EXIT;
}
return 0;
}
@@ -356,7 +370,9 @@ const struct ao_driver audio_out_openal = {
.list_devs = list_devs,
.priv_size = sizeof(struct priv),
.options = (const struct m_option[]) {
OPT_STRING_VALIDATE("device", cfg_device, 0, validate_device_opt),
OPT_STRING_VALIDATE("device", cfg_device, 0, validate_device_opt,
DEVICE_OPT_DEPRECATION),
{0}
},
.options_prefix = "ao-openal",
};
+1 -1
View File
@@ -46,7 +46,6 @@ struct priv {
static const int fmtmap[][2] = {
{ AF_FORMAT_U8, SL_PCMSAMPLEFORMAT_FIXED_8 },
{ AF_FORMAT_S16, SL_PCMSAMPLEFORMAT_FIXED_16 },
{ AF_FORMAT_S32, SL_PCMSAMPLEFORMAT_FIXED_32 },
{ 0 }
};
@@ -247,4 +246,5 @@ const struct ao_driver audio_out_opensles = {
OPT_INTRANGE("sample-rate", cfg_sample_rate, 0, 1000, 100000),
{0}
},
.options_prefix = "opensles",
};
+10 -2
View File
@@ -462,7 +462,7 @@ static int init(struct ao *ao)
p->buffersize = 0;
memset(data, 0, p->outburst);
while (p->buffersize < 0x40000 && device_writable(ao) > 0) {
write(p->audio_fd, data, p->outburst);
(void)write(p->audio_fd, data, p->outburst);
p->buffersize += p->outburst;
}
free(data);
@@ -612,6 +612,12 @@ static int audio_wait(struct ao *ao, pthread_mutex_t *lock)
return r;
}
static void list_devs(struct ao *ao, struct ao_device_list *list)
{
if (stat(PATH_DEV_DSP, &(struct stat){0}) == 0)
ao_device_list_add(list, ao, &(struct ao_device_desc){"", "Default"});
}
#define OPT_BASE_STRUCT struct priv
const struct ao_driver audio_out_oss = {
@@ -629,6 +635,7 @@ const struct ao_driver audio_out_oss = {
.drain = drain,
.wait = audio_wait,
.wakeup = ao_wakeup_poll,
.list_devs = list_devs,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {
.audio_fd = -1,
@@ -641,9 +648,10 @@ const struct ao_driver audio_out_oss = {
.oss_mixer_device = PATH_DEV_MIXER,
},
.options = (const struct m_option[]) {
OPT_STRING("device", dsp, 0),
OPT_STRING("device", dsp, 0, DEVICE_OPT_DEPRECATION),
OPT_STRING("mixer-device", oss_mixer_device, 0),
OPT_STRING("mixer-channel", cfg_oss_mixer_channel, 0),
{0}
},
.options_prefix = "oss",
};
+1 -2
View File
@@ -152,8 +152,6 @@ static int init(struct ao *ao)
priv->outputfilename,
priv->waveheader ? "WAVE" : "RAW PCM", ao->samplerate,
ao->channels.num, af_fmt_to_str(ao->format));
MP_INFO(ao, "Info: Faster dumping is achieved with --no-video\n");
MP_INFO(ao, "Info: To write WAVE files use --ao=pcm:waveheader (default).\n");
priv->fp = fopen(priv->outputfilename, priv->append ? "ab" : "wb");
if (!priv->fp) {
@@ -226,4 +224,5 @@ const struct ao_driver audio_out_pcm = {
OPT_FLAG("append", append, 0),
{0}
},
.options_prefix = "ao-pcm",
};
+5 -3
View File
@@ -23,6 +23,7 @@
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include <math.h>
#include <pthread.h>
#include <pulse/pulseaudio.h>
@@ -34,8 +35,8 @@
#include "ao.h"
#include "internal.h"
#define VOL_PA2MP(v) ((v) * 100 / PA_VOLUME_NORM)
#define VOL_MP2PA(v) ((v) * PA_VOLUME_NORM / 100)
#define VOL_PA2MP(v) ((v) * 100.0 / PA_VOLUME_NORM)
#define VOL_MP2PA(v) lrint((v) * PA_VOLUME_NORM / 100)
struct priv {
// PulseAudio playback stream object
@@ -835,9 +836,10 @@ const struct ao_driver audio_out_pulse = {
},
.options = (const struct m_option[]) {
OPT_STRING("host", cfg_host, 0),
OPT_STRING("sink", cfg_sink, 0),
OPT_STRING("sink", cfg_sink, 0, DEVICE_OPT_DEPRECATION),
OPT_CHOICE_OR_INT("buffer", cfg_buffer, 0, 1, 2000, ({"native", 0})),
OPT_FLAG("latency-hacks", cfg_latency_hacks, 0),
{0}
},
.options_prefix = "pulse",
};
+5 -2
View File
@@ -156,9 +156,12 @@ const struct ao_driver audio_out_rsound = {
.resume = audio_resume,
.priv_size = sizeof(struct priv),
.options = (const struct m_option[]) {
OPT_STRING("host", host, 0),
OPT_STRING("port", port, 0),
OPT_STRING("host", host, 0,
.deprecation_message = "request --audio-device support on issue tracker"),
OPT_STRING("port", port, 0,
.deprecation_message = "request --audio-device support on issue tracker"),
{0}
},
.options_prefix = "rsound",
};
+1
View File
@@ -212,4 +212,5 @@ const struct ao_driver audio_out_sdl = {
OPT_FLOAT("buflen", buflen, 0),
{0}
},
.options_prefix = "sdl",
};
+3 -1
View File
@@ -320,7 +320,9 @@ const struct ao_driver audio_out_sndio = {
.reset = reset,
.priv_size = sizeof(struct priv),
.options = (const struct m_option[]) {
OPT_STRING("device", dev, 0, OPTDEF_STR(SIO_DEVANY)),
OPT_STRING("device", dev, 0, OPTDEF_STR(SIO_DEVANY),
DEVICE_OPT_DEPRECATION),
{0}
},
.options_prefix = "ao-sndio",
};
+5 -8
View File
@@ -132,7 +132,7 @@ static bool thread_feed(struct ao *ao)
mp_time_us() + (int64_t)llrint(delay_us));
// note, we can't use ao_read_data return value here since we already
// commited to frame_count above in the GetBuffer call
// committed to frame_count above in the GetBuffer call
hr = IAudioRenderClient_ReleaseBuffer(state->pRenderClient,
frame_count, 0);
EXIT_ON_ERROR(hr);
@@ -270,11 +270,13 @@ static void uninit(struct ao *ao)
static int init(struct ao *ao)
{
MP_DBG(ao, "Init wasapi\n");
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CoInitializeEx(NULL, COINIT_MULTITHREADED);
struct wasapi_state *state = ao->priv;
state->log = ao->log;
state->opt_exclusive |= ao->init_flags & AO_INIT_EXCLUSIVE;
state->deviceID = wasapi_find_deviceID(ao);
if (!state->deviceID) {
uninit(ao);
@@ -469,7 +471,7 @@ static int hotplug_init(struct ao *ao)
MP_DBG(ao, "Hotplug init\n");
struct wasapi_state *state = ao->priv;
state->log = ao->log;
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CoInitializeEx(NULL, COINIT_MULTITHREADED);
HRESULT hr = wasapi_change_init(ao, true);
EXIT_ON_ERROR(hr);
@@ -494,9 +496,4 @@ const struct ao_driver audio_out_wasapi = {
.hotplug_init = hotplug_init,
.hotplug_uninit = hotplug_uninit,
.priv_size = sizeof(wasapi_state),
.options = (const struct m_option[]) {
OPT_FLAG("exclusive", opt_exclusive, 0),
OPT_STRING("device", opt_device, 0),
{NULL},
},
};
+5 -3
View File
@@ -29,7 +29,7 @@
#include <endpointvolume.h>
#include "common/msg.h"
#include "osdep/atomics.h"
#include "osdep/atomic.h"
#include "osdep/windows_utils.h"
#include "internal.h"
#include "ao.h"
@@ -50,6 +50,10 @@ void wasapi_change_uninit(struct ao* ao);
#define SAFE_RELEASE(unk, release) \
do { if ((unk) != NULL) { release; (unk) = NULL; } } while(0)
#define mp_format_res_str(hres) \
(SUCCEEDED(hres) ? "ok" : ((hres) == AUDCLNT_E_UNSUPPORTED_FORMAT) \
? "unsupported" : mp_HRESULT_to_str(hres))
enum wasapi_thread_state {
WASAPI_THREAD_FEED = 0,
WASAPI_THREAD_RESUME,
@@ -92,8 +96,6 @@ typedef struct wasapi_state {
// ao options
int opt_exclusive;
int opt_list;
char *opt_device;
// format info
WAVEFORMATEXTENSIBLE format;
+1 -1
View File
@@ -94,7 +94,7 @@ static HRESULT STDMETHODCALLTYPE sIMMNotificationClient_OnDeviceAdded(
return S_OK;
}
// maybe MPV can go over to the prefered device once it is plugged in?
// maybe MPV can go over to the preferred device once it is plugged in?
static HRESULT STDMETHODCALLTYPE sIMMNotificationClient_OnDeviceRemoved(
IMMNotificationClient *This,
LPCWSTR pwstrDeviceId)
+7 -20
View File
@@ -20,7 +20,6 @@
#include <math.h>
#include <wchar.h>
#include <windows.h>
#include <initguid.h>
#include <errors.h>
#include <ksguid.h>
#include <ksmedia.h>
@@ -290,18 +289,12 @@ static bool set_ao_format(struct ao *ao, WAVEFORMATEX *wf,
static bool try_format_exclusive(struct ao *ao, WAVEFORMATEXTENSIBLE *wformat)
{
struct wasapi_state *state = ao->priv;
MP_VERBOSE(ao, "Trying %s (exclusive)\n",
waveformat_to_str(&wformat->Format));
HRESULT hr = IAudioClient_IsFormatSupported(state->pAudioClient,
AUDCLNT_SHAREMODE_EXCLUSIVE,
&wformat->Format, NULL);
if (hr != AUDCLNT_E_UNSUPPORTED_FORMAT)
EXIT_ON_ERROR(hr);
MP_VERBOSE(ao, "Trying %s (exclusive) -> %s\n",
waveformat_to_str(&wformat->Format), mp_format_res_str(hr));
return SUCCEEDED(hr);
exit_label:
MP_ERR(state, "Error testing exclusive format: %s\n", mp_HRESULT_to_str(hr));
return false;
}
// This works like try_format_exclusive(), but will try to fallback to the AC3
@@ -394,11 +387,8 @@ static bool search_channels(struct ao *ao, WAVEFORMATEXTENSIBLE *wformat)
for (int j = 0; channel_layouts[j]; j++) {
mp_chmap_from_str(&entry, bstr0(channel_layouts[j]));
if (!wformat->Format.nSamplesPerSec) {
if (search_samplerates(ao, wformat, &entry)) {
if (search_samplerates(ao, wformat, &entry))
mp_chmap_sel_add_map(&chmap_sel, &entry);
MP_VERBOSE(ao, "%s is supported\n",
waveformat_to_str(&wformat->Format));
}
} else {
change_waveformat_channels(wformat, &entry);
if (try_format_exclusive(ao, wformat))
@@ -407,7 +397,7 @@ static bool search_channels(struct ao *ao, WAVEFORMATEXTENSIBLE *wformat)
}
entry = ao->channels;
if (ao_chmap_sel_adjust(ao, &chmap_sel, &entry)){
if (ao_chmap_sel_adjust2(ao, &chmap_sel, &entry, !state->opt_exclusive)){
change_waveformat_channels(wformat, &entry);
return true;
}
@@ -443,11 +433,12 @@ static bool find_formats_shared(struct ao *ao)
WAVEFORMATEXTENSIBLE wformat;
set_waveformat_with_ao(&wformat, ao);
MP_VERBOSE(ao, "Trying %s (shared)\n", waveformat_to_str(&wformat.Format));
WAVEFORMATEX *closestMatch;
HRESULT hr = IAudioClient_IsFormatSupported(state->pAudioClient,
AUDCLNT_SHAREMODE_SHARED,
&wformat.Format, &closestMatch);
MP_VERBOSE(ao, "Trying %s (shared) -> %s\n",
waveformat_to_str(&wformat.Format), mp_format_res_str(hr));
if (hr != AUDCLNT_E_UNSUPPORTED_FORMAT)
EXIT_ON_ERROR(hr);
@@ -858,11 +849,7 @@ static LPWSTR select_device(struct mp_log *l, struct device_desc *d)
bstr wasapi_get_specified_device_string(struct ao *ao)
{
struct wasapi_state *state = ao->priv;
bstr device = bstr_strip(bstr0(state->opt_device));
if (!device.len)
device = bstr_strip(bstr0(ao->device));
return device;
return bstr_strip(bstr0(ao->device));
}
LPWSTR wasapi_find_deviceID(struct ao *ao)
+13 -2
View File
@@ -21,7 +21,7 @@
#include <stdbool.h>
#include <pthread.h>
#include "osdep/atomics.h"
#include "osdep/atomic.h"
#include "audio/out/ao.h"
/* global data used by ao.c and ao drivers */
@@ -40,9 +40,13 @@ struct ao {
const struct ao_driver *api; // entrypoints to the wrapper (push.c/pull.c)
const struct ao_driver *driver;
void *priv;
struct mpv_global *global;
struct encode_lavc_context *encode_lavc_ctx;
struct input_ctx *input_ctx;
void (*wakeup_cb)(void *ctx);
void *wakeup_ctx;
struct mp_log *log; // Using e.g. "[ao/coreaudio]" as prefix
int init_flags; // AO_INIT_* flags
bool stream_silence; // if audio inactive, just play silence
// The device as selected by the user, usually using ao_device_desc.name
// from an entry from the list returned by driver->list_devices. If the
@@ -178,6 +182,8 @@ struct ao_driver {
int priv_size;
const void *priv_defaults;
const struct m_option *options;
const char *options_prefix;
const struct m_sub_options *global_opts;
};
// These functions can be called by AOs.
@@ -191,6 +197,8 @@ void ao_wakeup_poll(struct ao *ao);
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map);
bool ao_chmap_sel_adjust2(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map, bool safe_multichannel);
bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map, int num);
@@ -199,4 +207,7 @@ bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
void ao_device_list_add(struct ao_device_list *list, struct ao *ao,
struct ao_device_desc *e);
#define DEVICE_OPT_DEPRECATION \
.deprecation_message = "use --audio-device instead"
#endif
+12 -6
View File
@@ -30,7 +30,7 @@
#include "osdep/timer.h"
#include "osdep/threads.h"
#include "osdep/atomics.h"
#include "osdep/atomic.h"
#include "misc/ring.h"
/*
@@ -101,7 +101,8 @@ static int play(struct ao *ao, void **data, int samples, int flags)
int state = atomic_load(&p->state);
if (!IS_PLAYING(state)) {
set_state(ao, AO_STATE_PLAY);
ao->driver->resume(ao);
if (!ao->stream_silence)
ao->driver->resume(ao);
}
return write_samples;
@@ -151,7 +152,7 @@ int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_us)
end:
if (need_wakeup)
mp_input_wakeup_nolock(ao->input_ctx);
ao->wakeup_cb(ao->wakeup_ctx);
// pad with silence (underflow/paused/eof)
for (int n = 0; n < ao->num_planes; n++)
@@ -185,7 +186,7 @@ static double get_delay(struct ao *ao)
static void reset(struct ao *ao)
{
struct ao_pull_state *p = ao->api_priv;
if (ao->driver->reset)
if (!ao->stream_silence && ao->driver->reset)
ao->driver->reset(ao); // assumes the audio callback thread is stopped
set_state(ao, AO_STATE_NONE);
for (int n = 0; n < ao->num_planes; n++)
@@ -195,7 +196,7 @@ static void reset(struct ao *ao)
static void pause(struct ao *ao)
{
if (ao->driver->reset)
if (!ao->stream_silence && ao->driver->reset)
ao->driver->reset(ao);
set_state(ao, AO_STATE_NONE);
}
@@ -203,7 +204,8 @@ static void pause(struct ao *ao)
static void resume(struct ao *ao)
{
set_state(ao, AO_STATE_PLAY);
ao->driver->resume(ao);
if (!ao->stream_silence)
ao->driver->resume(ao);
}
static bool get_eof(struct ao *ao)
@@ -244,6 +246,10 @@ static int init(struct ao *ao)
p->buffers[n] = mp_ring_new(ao, ao->buffer * ao->sstride);
atomic_store(&p->state, AO_STATE_NONE);
assert(ao->driver->resume);
if (ao->stream_silence)
ao->driver->resume(ao);
return 0;
}
+62 -23
View File
@@ -35,7 +35,7 @@
#include "osdep/threads.h"
#include "osdep/timer.h"
#include "osdep/atomics.h"
#include "osdep/atomic.h"
#include "audio/audio.h"
#include "audio/audio_buffer.h"
@@ -49,6 +49,8 @@ struct ao_push_state {
struct mp_audio_buffer *buffer;
struct mp_audio *silence;
bool terminate;
bool wait_on_ao;
bool still_playing;
@@ -142,6 +144,7 @@ static void resume(struct ao *ao)
static void drain(struct ao *ao)
{
struct ao_push_state *p = ao->api_priv;
double maxbuffer = ao->buffer / (double)ao->samplerate + 1;
MP_VERBOSE(ao, "draining...\n");
@@ -151,14 +154,23 @@ static void drain(struct ao *ao)
p->final_chunk = true;
wakeup_playthread(ao);
while (p->still_playing && mp_audio_buffer_samples(p->buffer) > 0)
pthread_cond_wait(&p->wakeup, &p->lock);
// Wait until everything is done. Since the audio API (especially ALSA)
// can't be trusted to do this right, and we're hard-blocking here, apply
// an upper bound timeout.
struct timespec until = mp_rel_time_to_timespec(maxbuffer);
while (p->still_playing && mp_audio_buffer_samples(p->buffer) > 0) {
if (pthread_cond_timedwait(&p->wakeup, &p->lock, &until)) {
MP_WARN(ao, "Draining is taking too long, aborting.\n");
goto done;
}
}
if (ao->driver->drain) {
ao->driver->drain(ao);
} else {
double time = unlocked_get_delay(ao);
mp_sleep_us(MPMIN(time, ao->buffer / (double)ao->samplerate + 1) * 1e6);
mp_sleep_us(MPMIN(time, maxbuffer) * 1e6);
}
done:
@@ -172,6 +184,7 @@ static int unlocked_get_space(struct ao *ao)
struct ao_push_state *p = ao->api_priv;
int space = mp_audio_buffer_get_write_available(p->buffer);
if (ao->driver->get_space) {
int align = af_format_sample_alignment(ao->format);
// The following code attempts to keep the total buffered audio to
// ao->buffer in order to improve latency.
int device_space = ao->driver->get_space(ao);
@@ -181,6 +194,7 @@ static int unlocked_get_space(struct ao *ao)
// byte based and doesn't do proper chunked processing.
int min_buffer = ao->buffer + 64;
int missing = min_buffer - device_buffered - soft_buffered;
missing = (missing + align - 1) / align * align;
// But always keep the device's buffer filled as much as we can.
int device_missing = device_space - soft_buffered;
missing = MPMAX(missing, device_missing);
@@ -247,15 +261,38 @@ static int play(struct ao *ao, void **data, int samples, int flags)
return write_samples;
}
static void ao_get_silence(struct ao *ao, struct mp_audio *data, int size)
{
struct ao_push_state *p = ao->api_priv;
if (!p->silence) {
p->silence = talloc_zero(p, struct mp_audio);
mp_audio_set_format(p->silence, ao->format);
mp_audio_set_channels(p->silence, &ao->channels);
p->silence->rate = ao->samplerate;
}
if (p->silence->samples < size) {
mp_audio_realloc_min(p->silence, size);
p->silence->samples = size;
mp_audio_fill_silence(p->silence, 0, size);
}
*data = *p->silence;
data->samples = size;
}
// called locked
static void ao_play_data(struct ao *ao)
{
struct ao_push_state *p = ao->api_priv;
struct mp_audio data;
mp_audio_buffer_peek(p->buffer, &data);
int max = data.samples;
int space = ao->driver->get_space(ao);
bool play_silence = p->paused || (ao->stream_silence && !p->still_playing);
space = MPMAX(space, 0);
struct mp_audio data;
if (play_silence) {
ao_get_silence(ao, &data, space);
} else {
mp_audio_buffer_peek(p->buffer, &data);
}
int max = data.samples;
if (data.samples > space)
data.samples = space;
int flags = 0;
@@ -277,7 +314,8 @@ static void ao_play_data(struct ao *ao)
MP_ERR(ao, "Audio output driver seems to ignore AOPLAY_FINAL_CHUNK.\n");
r = max;
}
mp_audio_buffer_skip(p->buffer, r);
if (!play_silence)
mp_audio_buffer_skip(p->buffer, r);
if (r > 0)
p->expected_end_time = 0;
// Nothing written, but more input data than space - this must mean the
@@ -288,15 +326,16 @@ static void ao_play_data(struct ao *ao)
// Wait until space becomes available. Also wait if we actually wrote data,
// so the AO wakes us up properly if it needs more data.
p->wait_on_ao = space == 0 || r > 0 || stuck;
p->still_playing |= r > 0;
p->still_playing |= r > 0 && !play_silence;
// If we just filled the AO completely (r == space), don't refill for a
// while. Prevents wakeup feedback with byte-granular AOs.
int needed = unlocked_get_space(ao);
bool more = needed >= (r == space ? ao->device_buffer / 4 : 1) && !stuck;
bool more = needed >= (r == space ? ao->device_buffer / 4 : 1) && !stuck &&
!(flags & AOPLAY_FINAL_CHUNK);
if (more)
mp_input_wakeup(ao->input_ctx); // request more data
MP_TRACE(ao, "in=%d flags=%d space=%d r=%d wa=%d needed=%d more=%d\n",
max, flags, space, r, p->wait_on_ao, needed, more);
ao->wakeup_cb(ao->wakeup_ctx); // request more data
MP_TRACE(ao, "in=%d flags=%d space=%d r=%d wa/pl=%d/%d needed=%d more=%d\n",
max, flags, space, r, p->wait_on_ao, p->still_playing, needed, more);
}
static void *playthread(void *arg)
@@ -306,12 +345,13 @@ static void *playthread(void *arg)
mpthread_set_name("ao");
pthread_mutex_lock(&p->lock);
while (!p->terminate) {
if (!p->paused)
bool playing = !p->paused || ao->stream_silence;
if (playing)
ao_play_data(ao);
if (!p->need_wakeup) {
MP_STATS(ao, "start audio wait");
if (!p->wait_on_ao || p->paused) {
if (!p->wait_on_ao || !playing) {
// Avoid busy waiting, because the audio API will still report
// that it needs new data, even if we're not ready yet, or if
// get_space() decides that the amount of audio buffered in the
@@ -336,7 +376,7 @@ static void *playthread(void *arg)
}
if (was_playing && !p->still_playing)
mp_input_wakeup(ao->input_ctx);
ao->wakeup_cb(ao->wakeup_ctx);
pthread_cond_signal(&p->wakeup); // for draining
if (p->still_playing && timeout > 0) {
@@ -440,8 +480,9 @@ int ao_play_silence(struct ao *ao, int samples)
assert(ao->api == &ao_api_push);
if (samples <= 0 || !af_fmt_is_pcm(ao->format) || !ao->driver->play)
return 0;
char *p = talloc_size(NULL, samples * ao->sstride);
af_fill_silence(p, samples * ao->sstride, ao->format);
int bytes = af_fmt_to_bytes(ao->format) * samples * ao->channels.num;
char *p = talloc_size(NULL, bytes);
af_fill_silence(p, bytes, ao->format);
void *tmp[MP_NUM_CHANNELS];
for (int n = 0; n < MP_NUM_CHANNELS; n++)
tmp[n] = p;
@@ -486,10 +527,8 @@ int ao_wait_poll(struct ao *ao, struct pollfd *fds, int num_fds,
bool wakeup = false;
if (p_fds[num_fds].revents & POLLIN) {
wakeup = true;
// flush the wakeup pipe contents - might "drown" some wakeups, but
// that's ok for our use-case
char buf[100];
read(p->wakeup_pipe[0], buf, sizeof(buf));
// might "drown" some wakeups, but that's ok for our use-case
mp_flush_wakeup_pipe(p->wakeup_pipe[0]);
}
return (r >= 0 || r == -EINTR) ? wakeup : -1;
}
@@ -499,7 +538,7 @@ void ao_wakeup_poll(struct ao *ao)
assert(ao->api == &ao_api_push);
struct ao_push_state *p = ao->api_priv;
write(p->wakeup_pipe[1], &(char){0}, 1);
(void)write(p->wakeup_pipe[1], &(char){0}, 1);
}
#endif
+34 -7
View File
@@ -16,6 +16,8 @@
*/
#include <assert.h>
#include <math.h>
#include <limits.h>
#include <libavutil/common.h>
#include <libavutil/log.h>
@@ -75,13 +77,35 @@ void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st)
// other demuxers must be handled manually.
void mp_set_lav_codec_headers(AVCodecContext *avctx, struct mp_codec_params *c)
{
#if HAVE_AVCODEC_HAS_CODECPAR
if (c->lav_codecpar)
avcodec_parameters_to_context(avctx, c->lav_codecpar);
#else
if (c->lav_headers)
mp_copy_lav_codec_headers(avctx, c->lav_headers);
#endif
}
// Pick a "good" timebase, which will be used to convert double timestamps
// back to fractions for passing them through libavcodec.
AVRational mp_get_codec_timebase(struct mp_codec_params *c)
{
AVRational tb = {c->native_tb_num, c->native_tb_den};
if (tb.num < 1 || tb.den < 1) {
if (c->reliable_fps)
tb = av_inv_q(av_d2q(c->fps, 1000000));
if (tb.num < 1 || tb.den < 1)
tb = AV_TIME_BASE_Q;
}
// If the timebase is too coarse, raise its precision, or small adjustments
// to timestamps done between decoder and demuxer could be lost.
if (av_q2d(tb) > 0.001) {
AVRational r = av_div_q(tb, (AVRational){1, 1000});
tb.den *= (r.num + r.den - 1) / r.den;
}
av_reduce(&tb.num, &tb.den, tb.num, tb.den, INT_MAX);
if (tb.num < 1 || tb.den < 1)
tb = AV_TIME_BASE_Q;
return tb;
}
// We merely pass-through our PTS/DTS as an int64_t; libavcodec won't use it.
@@ -97,8 +121,10 @@ union pts { int64_t i; double d; };
int64_t mp_pts_to_av(double mp_pts, AVRational *tb)
{
assert(sizeof(int64_t) >= sizeof(double));
if (tb && tb->num > 0 && tb->den > 0)
return mp_pts == MP_NOPTS_VALUE ? AV_NOPTS_VALUE : mp_pts / av_q2d(*tb);
if (tb && tb->num > 0 && tb->den > 0) {
return mp_pts == MP_NOPTS_VALUE ?
AV_NOPTS_VALUE : llrint(mp_pts / av_q2d(*tb));
}
// The + 0.0 is to squash possible negative zero mp_pts, which would
// happen to end up as AV_NOPTS_VALUE.
return (union pts){.d = mp_pts + 0.0}.i;
@@ -133,6 +159,7 @@ void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt, AVRational *tb)
dst->side_data_elems = mpkt->avpacket->side_data_elems;
if (dst->data == mpkt->avpacket->data)
dst->buf = mpkt->avpacket->buf;
dst->flags |= mpkt->avpacket->flags;
}
if (mpkt && tb && tb->num > 0 && tb->den > 0)
dst->duration = mpkt->duration / av_q2d(*tb);
+1
View File
@@ -33,6 +33,7 @@ struct mp_log;
int mp_lavc_set_extradata(AVCodecContext *avctx, void *ptr, int size);
void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st);
void mp_set_lav_codec_headers(AVCodecContext *avctx, struct mp_codec_params *c);
AVRational mp_get_codec_timebase(struct mp_codec_params *c);
void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt, AVRational *tb);
int64_t mp_pts_to_av(double mp_pts, AVRational *tb);
double mp_pts_from_av(int64_t av_pts, AVRational *tb);
Loaded 100 of 400 files, more files were not shown because too many files have changed in this diff. Show more