Compare commits

..
1316 Commits
Author SHA1 Message Date
Martin Herkt e1993d5ad2 Release 0.14.0 2015-12-11 19:20:29 +01:00
Martin Herkt 0607dcebff Merge branch 'master' into release/current 2015-12-11 18:33:38 +01:00
James Ross-Gowan 3d12312806 vo_opengl: add dxinterop backend
WGL_NV_DX_interop is widely supported by Nvidia and AMD drivers. It
allows a texture to be shared between Direct3D and WGL, so that
rendering can be done with WGL and presentation can be done with
Direct3D. This should allow us to work around some persistent WGL
issues, such as dropped frames with some driver/OS combos, drivers that
buffer frames to increase performance at the cost of latency, and the
inability to disable exclusive fullscreen mode when using WGL to render
to a fullscreen window.

The addition of a DX_interop backend might also enable some cool
Direct3D-specific enhancements in the future, such as using the
GetPresentStatistics API to get accurate frame presentation timestamps.

Note that due to a driver bug, this backend is currently broken on
Intel. It will appear to work as long as the window is not resized too
often, but after a few changes of size it will be unable to share the
newly created renderbuffer with GL. See:
https://software.intel.com/en-us/forums/graphics-driver-bug-reporting/topic/562051
2015-12-11 18:29:18 +01:00
wm4 a6521f3941 demux: remove old subtitle parser
All of these are supported by FFmpeg now. It was disabled by default
too (with FFmpeg).

If compiled against Libav, mpv will lose the ability to read some
subtitle formats (but the most important ones, srt and ass, still should
work).
2015-12-10 22:53:37 +01:00
wm4 475fe453cc stream: drop PVR support
This is only for specific Hauppage cards. According to the comments in
who is actively using this feature. Get it out of the way.

Anyone who still wants to use this should complain. Keeping this code
would not cause terribly much additional work, and it could be restored
again. (But not if the request comes months later.)
2015-12-10 22:53:02 +01:00
wm4 3da91a673a player: init playback speed correctly
Usually not a problem, but could not be initialized early enough in some
corner cases.
2015-12-10 22:53:02 +01:00
wm4 47e6ef0bdf vo_opengl: remove one more XYZ special-case
The XYZ colorspace on XYZ pixfmt is enforced in some sanitation routine.
2015-12-09 17:10:38 +01:00
Bin Jin 6d36c432ab vo_opengl: fix precision loss of fruit dithering matrix
With default setting, the matrix for fruit dithering requires 12 bits
precision (values from 0/4096 to 4095/4096). But 16-bit float
provides only 10 bits. In addition, when `dither-size-fruit=8` is
set, 16 bits are required from the texture format.

Fix this by attempting to use 16 bit integer texture first. This is
still not precise, but should be better than using a half float.
2015-12-09 00:36:48 +01:00
wm4 45ae0716be csputils: rename "yuv2rgb" functions
They're not necessarily restricted to YUV aka YCbCr.

vo_direct3d.c and demux_disc.c (DVD specific code) changes untested.
2015-12-09 00:23:36 +01:00
wm4 c5c7b239b6 csputils, vo_opengl: remove XYZ special case in color matrix retrieval
This just seems unnecessary. Refactor it a bit. There should be no
functional changes.
2015-12-09 00:16:51 +01:00
wm4 c2d0d7818f csputils: remove obscure int_bits matrix scaling
This has no reason to be there. Put the functionality into another
function instead. While we're at it, also adjust for possible accuracy
issues with high bit depth YUV (matters for rendering subtitles into
screenshots only).
2015-12-09 00:08:00 +01:00
wm4 0d7d935e88 vo_opengl: fix shader compilation regression
The recent LUT adjustment changes broke interpolation.

The concatenation of the shader stages is a bit messy, and it seems like
sampler_prelude is not a good place to add this macro. Always add the
macro to every shader instead. (While this doesn't seem too elegant,
this isn't too inelegant either, and goes these problems out of the
way.)
2015-12-08 03:18:47 +01:00
wm4 3d66a5d14e sub: increase gap/overlap fixing threshold to 210ms
Don't ask why.
2015-12-07 23:48:59 +01:00
wm4 c138505813 vo_opengl: enable colormatrix even for RGB input
Enables brightness/contrast controls, and handles gbrp10 correctly.
2015-12-07 23:48:59 +01:00
wm4 663415b914 vo_opengl: fix issues with some obscure pixel formats
The computation of the tex_mul variable was broken in multiple ways.
This variable is used e.g. by debanding for moving expansion of 10 bit
fixed-point input to normalized range to another stage of processing.

One obvious bug was that the rgb555 pixel format was broken. This format
has component_bits=5, but obviously it's already sampled in normalized
range, and does not need expansion. The tex_mul-free code path avoids
this by not using the colormatrix. (The code was originally designed to
work around dealing with the generally complicated pixel formats by only
using the colormatrix in the YUV case.)

Another possible bug was with 10 bit input. It expanded the input by
bringing the [0,2^10) range to [0,1], and then treating the expanded
input as 16 bit input. I didn't bother to check what this actually
computed, but it's somewhat likely it was wrong anyway. Now it uses
mp_get_csp_mul(), and disables expansion when computing the YUV matrix.
2015-12-07 23:48:59 +01:00
Bin Jin c569d4f6ed vo_opengl: decrease default lookup texture size to 64
It turns out that with accurate lookup we can decrease the
default size of texture now. Do it to compensate the performance
loss introduced by the LUT_POS macro.
2015-12-07 23:48:40 +01:00
Bin Jin e6058d3dc3 vo_opengl: make LOOKUP_TEXTURE_SIZE configurable 2015-12-07 23:48:18 +01:00
Bin Jin c1a96de41c vo_opengl: Fix minor LUT sampling error
Define a macro to correct the coordinate for lookup texture. Cache
the corrected coordinate for 1D filter and use mix() to minimize the
performance impact.
2015-12-07 23:48:15 +01:00
Bin Jin 18fe6e6dc8 filter_kernels: add warnings for potential LUT sampling error 2015-12-07 23:48:12 +01:00
wm4 aaa64b879e cocoa: fix recent regression
Commit 9db50c67 changed it so that the window title can now be a NULL
string.

Completely untested. Probably fixes #2570.
2015-12-07 00:49:36 +01:00
wm4 159eb3f962 win32: add option to set VO MMCSS profile
This was requested.
2015-12-06 19:20:23 +01:00
wm4 9db50c6760 vo: get rid of vo_get_window_title()
It always was a weird artifact - VOCTRLs are meant _not_ to require
special handling in the code that passes them through (like in vo.c).
Removing it is also interesting to further reduce the dependency of
backends on struct vo. Just get rid of it.

Removing it is somewhat inconvenient, because in many situations the UI
window is created after the first VOCTRL_UPDATE_WINDOW_TITLE. This means
these backends have to store it in a new field in their own context.
2015-12-06 18:41:31 +01:00
wm4 970606e491 sd_ass: slightly better heuristic for applying --sub-fix-timing
Fixes a reported sample, that has a sign interrupted by a few frames
(for which --sub-fix-timing would remove the wanted gap).

The list of tags in has_overrides() is taken from libass. It has a
similar function (which even checks whether the tag are within the { }
delimiters). Unfortunately, this function is not public, so we just have
a simpler one which does roughly the same. It doesn't matter that this
function sometimes returns false positives.
2015-12-06 18:22:30 +01:00
wm4 7d7ea72854 sub: another minor simplification 2015-12-06 18:17:14 +01:00
wm4 0262295c4b manpage: reflect recent subtitle changes 2015-12-06 01:15:08 +01:00
wm4 48ed48f7b8 sub: minor simplifications
The awkward "preprocess" step of putting the subtitles through single
filters before doing something else was made unnecessary by the recent
changes.

(Fun fact: I originally planned to move these extra things, like fixing
subtitle gaps/overlaps, to filters - but this would suffer from various
complications, and moving them to the renderers seems much simpler.)
2015-12-05 23:56:53 +01:00
wm4 94c062d0d2 sub: move subtitle FPS adjustment to sd_ass.c
I feel like it's better there. Note that there is no reduced
functionality, as bitmaps subs (i.e. not handled by sd_ass.c) were never
fully read on init, and thus never went through sub_read_all_packets().

On the other hand, this might lead to confusion, as --sub-fps etc. will
now also affect muxed subtitles (which makes not much sense).
2015-12-05 23:56:28 +01:00
wm4 04934e86dd sub: move --sub-fix-timing handling to renderer
Instead of messing with the subtitle packet timestamps, do it on output.
We work on the libass event list. If there is an unwanted gap or
overlap, we render the timestamp at another position where there is no
gap or overlap.

This is somewhat more robust, and even works with demuxed subs (to some
degree - depends whether the subs are prefected soon enough).

It's active even for native ASS subs. I wonder if this is a problem with
extended type setting. If it is, the heuristic that tries to avoid
interrupting such cases has to be improved.

While it probably would be ideal to do this after the subtitle decoder,
certain aspects are at least currently handled better in this place.
2015-12-05 23:56:07 +01:00
wm4 ff1eaea3e7 sd_lavc: remove small gaps between subtitles
Just like with text subtitles. Move the magic constants to a common
place too.
2015-12-05 23:55:56 +01:00
wm4 9a240dc82e sd_lavc: discard empty subtitles and improve sub_seek behavior
Image subtitles often use a "signaling" packet to set the end time of
the previous subtitle. As far as the libavcodec API is concerned, such
packets decode to empty AVSubtitles. Discard these after the end time of
the previous subtitle has been set.

Keep track of the per-subtitle end time better. This is for the sake of
improving sub_step/sub_seek. Without this, it would seek to the sub
before the previous sub, if the current sub has ended displaying.
2015-12-05 23:55:35 +01:00
wm4 a7cf091519 sd_lavc: implement sub_step/sub_seek
Works roughly the same as the one in sd_ass for text subtitles. While
sub_step is very uninteresting, it comes for free with the support for
sub_seek.

The implementation is taken from ass_step_sub() from libass, with some
modifications
2015-12-05 23:55:22 +01:00
wm4 a2e7642d3c sub: allow feeding bitmap subs in advance
Until now, feeding packets to the decoder in advance was done for text
subtitles only. This was possible because libass buffers all subtitle
data anyway (in ASS_Track). sd_lavc, responsible for bitmap subs, does
not do this. But it can buffer a small number of subtitle frames ahead.
Enable this.

Repurpose the sub_accept_packets_in_advance(). Instead of "can take all
packets" it means "can take 1 packet" now. (The old meaning is still
needed locally in dec_sub.c; keep it there.) It asks the decoder whether
there is place for at least 1 subtitle packet. sd_lavc implements it and
returns true if its internal fixed-size subtitle queue still has a free
slot. (The implementation of this in dec_sub.c isn't entirely clean.
For one, decode_chain() ignores this mechanism, so it's implied that
bitmap subtitles do not use the subtitle filter chain in any advanced
way.)

Also fix 2 bugs in the sd_lavc queue handling. Subtitles must be checked
in reverse, because the first entry will often have endpts==NOPTS, which
would always match. alloc_sub() must cycle the queue buffer, because it
reuses memory allocations (like sub.imgs) by design.
2015-12-05 23:54:00 +01:00
wm4 565efeeada vd_lavc: fix avctx NULL checks
If reinit after a fallback from hardware fails, this field can be NULL.
The check in control() was broken due to a typo (found by Coverity), and
decode() lacked the check entirely.
2015-12-05 23:53:55 +01:00
wm4 c46106d633 player: remove redundant check
Found by Coverity.
2015-12-05 23:53:48 +01:00
wm4 63204eda5d vo_opengl_cb: avoid NULL pointer deref in corner cases
Found by Coverity.
2015-12-05 23:53:41 +01:00
wm4 791228f2ab msg: remove redundant condition
Found by Coverity.
2015-12-05 23:53:24 +01:00
Bin Jin 19b0b1df51 vo_opengl: improve boundary check for polar filters
If the sampling point is placed diagonally, the radius difference
could be as large as sqrt(2.0). And a loosened check with (radius - 1)
would potentially include pixels out of the range.

Fix the check to handle those corner case properly to avoid
unnecessary texture lookup and improve the performance a bit.
2015-12-05 23:53:17 +01:00
James Ross-Gowan 30bbcd6452 win32: fix console output with raw stdio functions
reopen_console_handle() was never properly tested because mpv overrides
printf in most source files. Turns out that when there's no console on
startup, the CRT sets the fds of stdout and stderr to -2, so the old
method of using dup2 to manipulate these fds didn't work. As far as I
can tell, the only way to give stdout and stderr valid fds is to use
freopen, so this uses freopen to set them both to the console output.
This also uses dup2 to change STDOUT_FILENO and STDERR_FILENO, so low-
level functions like isatty still work.

Note that this means fileno(stdout) != STDOUT_FILENO. I don't think this
will cause any problems.

This should fix MPV_LEAK_REPORT on the Windows console.
2015-12-06 02:37:38 +11:00
wm4 832cb56f2d player: don't make display-sync panic on timestamp discontinuities 2015-12-04 17:07:50 +01:00
wm4 68c6da69f7 player: resync audio only on larger timestamp discontinuities
Helps with files that have occasional broken timestamps. For larger
discontinuities, e.g. caused by actual timestamp resets, we still want
to realign audio.

(I guess in general, this should be removed and replaced by a more
general resync-on-desync logic, but not now.)
2015-12-04 16:55:55 +01:00
wm4 f626bef7c8 win32: enable internal pthreads wrapper by default 2015-12-04 16:32:31 +01:00
wm4 81746a1798 win32: remove dwmapi.dll dynamic loading
All Windows versions we support have this API.
2015-12-04 16:30:53 +01:00
Bin Jin 01c418f9df filter_kernels: remove redundant corner case check
Actually, the original code would bypass some code path below.
2015-12-04 15:35:20 +01:00
commander kotori 3b6c7275bc examples/qt_opengl: Use fbo of the widget and not the thread context
Sometimes QOpenGLWidget may be redirecting it's output to a framebuffer
object rather than the frontbuffer, in which case the current thread's
context render fbo is different from the widget's.  Use the widget's
desired fbo instead.
2015-12-03 10:41:49 +01:00
commander kotori 6562d4a562 examples/qt_opengl: remove redundant time-start property fetch
Time-start is not a real property since 70df1608d.

Fixes #2529.
2015-12-03 10:41:49 +01:00
wm4 17507b5935 vo_opengl: require --enable-gpl3 for nnedi
There are claims that nnedi3.c doesn't constitute its own new
implementation, but is derived from existing HLSL or OpenCL shaders
distributed under the LGPLv3 license.

Until these are resolved, do the "correct" thing and require
--enable-gpl3 to build nnedi.
2015-12-03 09:32:40 +01:00
wm4 57e691b901 client API: disallow masking MPV_EVENT_SHUTDOWN
This makes no sense, because the client is obligated to react to this
event.

This also happens to fix a deadlock with JSON IPC clients sending
"disable_event all", because MPV_EVENT_SHUTDOWN was used to stop the
thread driving the socket connection (fixes #2558).
2015-12-02 23:08:43 +01:00
wm4 344d44681e video: readd codec delay estimation
Approximately reverts commit 3ccac74d. This failed with some avi files,
which do pseudo-VFR by sending packets with empty frames (or repeat
frames, depending on point of view). Specifically, these packets are not
0 bytes, so they don't get skipped by libavformat, as with the usual VFR
avi hack. Instead, the packet contains a VOP with vop_coded=0, so
libavcodec will just return no frame. We could probably distinguish such
skipped frames and delayed frames by explicitly measuring the codec
delay by counting how long it takes to get the very first frame (and
then treat skips as explicit drops), but we may as well simply reinstate
the old code.

To appease to at least one semi-broken case, do not enable this logic on
the RPI, as the FFmpeg MMAL wrapper has arbitrary buffering (and MMAL
itself is asynchronous).
2015-12-02 14:38:47 +01:00
wm4 03d311823d vo_opengl: fix backend=x11 on Intel
"backend=x11" was resolved to x11_probe, which is unintentional.
2015-12-02 14:19:17 +01:00
Bin Jin 9cb7646071 vo_opengl: add credits to NNEDI3 shader
Add credits to several existing implementation of NNEDI3 shader.
2015-12-02 12:32:17 +01:00
Bin Jin 42a0f4d87b vo_opengl: enable NNEDI3 prescaler on OpenGL ES 3.0
It turns out that both UBO and intBitsToFloat() are supported in
OpenGL ES 3.0[1][2], enable them so that NNEDI3 prescaler can be used
in a wider range of backends.

Also fixes some implicit int-to-float conversions so that the shader
actually compiles on GLES.

Tested on Linux desktop (nvidia 358.16) with "es" sub-option.

[1]: https://www.khronos.org/opengles/sdk/docs/man3/html/glGetUniformBlockIndex.xhtml
[2]: https://www.khronos.org/opengles/sdk/docs/manglsl/docbook4/xhtml/intBitsToFloat.xml
2015-12-02 12:32:02 +01:00
lzmths 69cc002c92 path: cosmetics
Avoiding conditional directives that split up parts of statements.

Signed-off-by: wm4 <wm4@nowhere>
2015-12-02 12:31:48 +01:00
wm4 b325ed1105 manpage: fix a command name
Using "-" as separator is preferred now.
2015-12-01 22:53:26 +01:00
Christian Hesse 30f18b8dc7 build: install scalable svg icon as well 2015-12-01 10:58:35 +01:00
wm4 e1d414c992 manpage: ' can't be used for quoting 2015-11-30 22:22:09 +01:00
wm4 7f3cf75c5a vo_opengl_cb: pass mpv_global to gl_video
I guess gl_video->global was originally meant to be optional, but now it
crashes in some newer code with vo_opengl_cb, which tries to init it
with this field set to NULL (because normally it's not needed).

Probably fixes #2542.
2015-11-30 00:03:14 +01:00
wm4 ece794d905 manpage: explain behavior of "path" property
This seems to confuse users pretty often, but I'm not going to change
its behavior.

See e.g. #2541.
2015-11-29 17:56:08 +01:00
wm4 3fa76c84be osd: do not let OSD messages overwrite --osd-msgN text
Requested. Don't overwrite permanent OSD text set with e.g. --osd-msg1.
Instead, append the OSD message to it (on the next line).

Note that with --osd-msg1, seeking will still overwrite the OSD with the
playback status for a while. If you do not want this, use --osd-msg3
--osd-level=3 instead.
2015-11-29 17:56:08 +01:00
wm4 66d93c711b vo: cosmetics: split function
Split two huge chunks from the update_vsync_timing_after_swap()
function. There should be no functional changes.
2015-11-29 17:56:08 +01:00
wm4 03a81a9d85 vo: make using estimated FPS more conservative
Don't use the average FPS if there are likely skipped vsyncs. Note that
we don't use the normal skip detection, as it is unreliable if the real
and assumed display FPS differ too much. The normal skip detection is
still in place as it's more reliable in the case when vsync jitters
much, but the display FPS is relatively exact.

Further improvement over commit 41f2c653.
2015-11-29 17:56:08 +01:00
wm4 e2c0e7f5c2 vo: remove redundant and broken code
This was stupid.
2015-11-29 17:55:58 +01:00
wm4 8bf34950c1 sub: remove unused function, move another one
mp_ass_default_track() was not used by anything anymore (commit 5a89150a
got rid of it). mp_ass_add_default_styles() is used by sd_ass.c only.
2015-11-29 17:55:02 +01:00
wm4 2b990ac810 osd: fix and cleanup font style management
Commit 2b07d3eb merged progbar and OSD text renderer into one ASS_Track,
but it confused the styles. Specifically, if both progbar and OSD are
visible, the create_ass_track() call made by the progbar code will reset
the style adjusted by the OSD text code.

Change create_ass_track() not to add any styles. Instead let the caller
manage the styles. They are now referenced by name, and lazily added if
they don't exist yet. This is also much cleaner.
2015-11-29 17:55:02 +01:00
wm4 005f03d99f DOCS/interface-changes: add some recent changes 2015-11-29 17:55:02 +01:00
wm4 6ff1cd5502 vo_opengl: make tscale=mitchell:tscale-clamp the default
Looks better than "oversample". tscale-clamp suggested by haasn.
2015-11-29 17:55:01 +01:00
wm4 9fc74d5acd vo_opengl: warn if interpolation is enabled, but not display-sync
Try to avoid user confusion.

Reading the global options in this place is a pretty disgusting hack,
but it's still the most robust way.
2015-11-28 20:10:01 +01:00
wm4 2b07d3eb47 osd: use the same ASS_Renderer for OSD text and progbar
Reduces memory usage and startup times. The implementation is a bit
weird, because both OSD parts have conflicting requirements on the used
ASS styles.
2015-11-28 19:24:31 +01:00
wm4 73e0d545ce vo: report when switching back to system-reported FPS too
Instead of just when switching away from it.

Further improvement over commit 41f2c653.
2015-11-28 18:41:11 +01:00
wm4 50d43a1db4 vo: wait longer before abandoning system-reported display-fps
Further improvement over commit 41f2c653.
2015-11-28 18:40:25 +01:00
wm4 318e9801f2 vo_opengl: fix interpolation with display-sync
At least I hope so.

Deriving the duration from the pts was not really correct. It doesn't
include speed adjustments, and becomes completely wrong of the user e.g.
changes the playback speed by a huge amount. Pass through the accurate
duration value by adding a new vo_frame field.

The value for vsync_offset was not correct either. We don't need the
error for the next frame, but the error for the current one. This wasn't
noticed because it makes no difference in symmetric cases, like 24 fps
on 60 Hz.

I'm still not entirely confident in the correctness of this, but it sure
is an improvement.

Also, remove the MP_STATS() calls - they're not really useful to debug
anything anymore.
2015-11-28 15:45:49 +01:00
wm4 ea1caa474a player: fix commit 50bb209a
Well, this was stupid.
2015-11-28 02:24:03 +01:00
wm4 7023c383b2 vo: change vo_frame field units
This was just converting back and forth between int64_t/microseconds and
double/seconds. Remove this stupidity. The pts/duration fields are still
in microseconds, but they have no meaning in the display-sync case (also
drop printing the pts field from opengl/video.c - it's always 0).
2015-11-27 22:04:44 +01:00
wm4 2bee47fd27 vo: switch back to system-reported display FPS if possible
If we switched away from the system FPS, we were remaining in this mode
ssentially forever. There's no reason to do so; switch back if the
estimated FPS gets worse again. Improvement over commit 41f2c653.
2015-11-27 21:56:29 +01:00
wm4 c8e0e35709 vo: factor redundant timer calls
Call it once instead of 3 times.
2015-11-27 21:52:06 +01:00
wm4 9afd62bfcd vo: fix audio-timing framedrop regressions
Commit 12eb8b2d accidentally disabled framedropping in the audio timing
case. It tried to replace the last_flip field with the prev_vsync one,
which didn't work because prev_sync is reset to 0 if the timing code is
used. Fix it by always setting it properly. This field must (or should)
be reinitialized to something sensible when switching to display sync
timing mode; since prev_vsync is not reset anymore, the check when to
reinitialize this field has to be adjusted as well.

It's a bit weird that update_vsync_timing_after_swap() now does some
minor work for timing mode too, but I guess it's ok, if only to avoid
additional fields and timer calls.
2015-11-27 21:50:59 +01:00
wm4 eec844a06e ao: disambiguate default device list entries
If there were many AO drivers without device selection, this added a
"Default" entry for each AO. These entries were not distinguishable, as
the device list feature is meant not to require to display the "raw"
device name in GUIs.

Disambiguate them by adding the driver name. If the AO is the first, the
name will remain just "Default". (The condition checks "num > 1",
because the very first entry is the dummy for AO autoselection.)
2015-11-27 14:42:10 +01:00
wm4 50bb209a80 player: always disable display-sync on desyncs
Instead of periodically trying to enable it again. There are two cases
that can happen:

1. A random discontinuity messed everything up,
2. Things are just broken and will desync all the time

Until now, it tried to deal with case 1 - but maybe this is really rare,
and we don't really need to care about it. On the other hand, case 2 is
kind of hard to diagnose if the user doesn't use the terminal.

Seeking will reenable display-sync, so you can fix playback if case 1
happens, but still get predictable behavior in case 2.
2015-11-27 14:40:52 +01:00
wm4 41f2c653e2 vo: disregard system-reported display FPS if it's too imprecise
If the system-reported display FPS (returned by the VO backends, or
forced with --display-fps) is too imprecise (deviating frame duration by
more than 1%). This works if the display FPS is off by almost 1 (typical
for old/bad/broken OS APIs). Actually it even works if the FPs is
completely wrong.

Is it a good idea? Probably not. It might be better to only output a
warning message. But unless there are reports about it going terribly
wrong, I'll go with this for now.
2015-11-27 14:40:37 +01:00
wm4 85498a0797 vo: improve vsync delay detection
Actually I'm not content with the detection added in commit 44376d2d. It
triggers too often if vsync is very jittery. It's easy to avoid this: we
add more samples to the detection by reusing the drift computation loop.
If there's a significant step in the drift, we consider it a drop.
2015-11-27 14:35:08 +01:00
wm4 b250c19a38 player: make display-vdrop mode do what the manpage claims
Don't change video speed in this mode, which is closer to the claim on
the manpage that it's close to the behavior of the "audio" mode.
2015-11-26 18:53:32 +01:00
James Ross-Gowan 69ba4f776f w32_common: implement icc-profile-auto
This adds basic support for ICC profiles. Per-monitor profiles are
supported. WCS profiles are not supported, but there is an API for
converting WCS profiles to ICC, so they might be supported in future.
I'm just not sure if anyone actually uses them.

Reloading the ICC profile when it's changed in the control panel is also
not supported. This might be possible by using the WCS APIs and watching
the registry for changes, but there is no official API for it, and as
far as I can tell, no other Windows programs can do it.
2015-11-26 23:04:50 +11:00
wm4 4c111fbcde af_lavrresample: fix build on Libav
Of course, only FFmpeg has av_clipd(), while Libav does not. (Nevermind
that it doesn't do much more than the mpv MPCLAMP() macro. Supposedly,
libavutil can provide optimized platform-specific versions for av_clip*,
but of course nothing actually does for av_clipf() or av_clipd().)
2015-11-26 00:25:28 +01:00
wm4 12eb8b2de8 vo: smooth out reported vsync time
Return the estimated/ideal flip time to the timing logic (meaning
vo_get_delay() returns a smoothed out time). In addition to this add
some lame but working drift compensation. (Useful especially if the
display FPS is wrong by a factor such as 1.001.)

Also remove some older leftovers. The vsync_interval_approx and
last_flip fields are redundant or unneeded.
2015-11-25 23:30:52 +01:00
wm4 44376d2d9b vo: add new frame drop detection
For the vo-delayed-frame-count property.

Slightly less dumb than the previous one (which was removed earlier),
but still pretty dumb. But this also seems to be relatively robust, even
with strong vsync jittering.
2015-11-25 22:11:30 +01:00
wm4 b8bcf0f466 vo: do not use display FPS for framedrop
This logic was kind of questionable anyway, and --display-sync should
give much better results. (I would even go as far as saying that the
FPS-dependent framedrop code made things worse in some situations. Not
all, though.)
2015-11-25 22:11:14 +01:00
wm4 1fe64c61be vo_opengl: disable interpolation without display-sync
Without display-sync mode, our guesses wrt. vsync phase etc. are much
worse, and I see no reason to keep the complicated "vsync_timed" code.
2015-11-25 22:10:55 +01:00
wm4 772961f0ce command, vo: add estimated-display-fps property
This is simply the average refresh rate. Including "bad" samples is
actually an advantage, because the property exists only for
informational purposes, and will reflect problems such as the driver
skipping a vsync.

Also export the standard deviation of the vsync frame duration
(normalized to the range 0-1) as vsync-jitter property.
2015-11-25 22:07:56 +01:00
wm4 5bc9b273b3 player: log some more display-sync information 2015-11-25 22:07:47 +01:00
wm4 0425741754 af_lavrresample: clamp float output to range
libswresample doesn't do it - although it should, but the patch is stuck
in limbo.

Probably reduces problems with artifacts on downmixing in some cases.
2015-11-25 22:07:18 +01:00
wm4 19c1a208ec vo_rpi: set aspect ratio
Otherwise, the MMAL output component will letter-box the video within
the specified dest_rect while keeping square pixels.
2015-11-25 22:06:58 +01:00
wm4 422ed42817 vo_rpi: log subtitle render time 2015-11-25 22:06:50 +01:00
wm4 fa2fdaab0a vo_rpi: add an option to disable OSD
The OSD takes up an entire fullscreen dispmanx layer. Although the GPU
should be able to handle it (possibly even without any disadvantages),
it'll still be useful for debugging performance issues.
2015-11-25 22:06:17 +01:00
James Ross-Gowan b7d614aa0d vo_opengl: win32: test for exclusive mode
This is a hack, but unfortunately the DwmGetCompositionTimingInfo
heuristic does not work in all cases (with multiple-monitors on Windows
8.1 and even with a single monitor in Windows 10.) See the comment in
mp_w32_is_in_exclusive_mode() for more details.

It should go without saying that if any better method of doing this
reveals itself, this hack should be dropped.
2015-11-26 00:38:03 +11:00
James Ross-Gowan dab2e909af vo_opengl: angle: don't load libGLESv2.dll
ANGLE has EGL_KHR_get_all_proc_addresses, so all GLES core functions can
be queried with eglGetProcAddress.
2015-11-26 00:35:48 +11:00
wm4 06df54a111 ao_alsa: filter audio device list
Remove known useless device entries from the --audio-device list (and
corresponding property). Do this because the list is supposed to be a
high level list of devices the user can select. ALSA does not provide
such a list (in an useable manner), and ao_alsa.c is still in the best
position to improve the situation somewhat.
2015-11-24 19:47:58 +01:00
wm4 ef918b239e ao_alsa: list bidirectional devices too
The ALSA doxygen says:

    IOID - input / output identification ("Input" or "Output"), NULL
    means both

This bug was blatantly introduced with commit cf94fce4.
2015-11-24 19:21:41 +01:00
Kevin Mitchell 00b7fb3023 ao_wasapi: get rid of Vistablob hack
This was required to work around XP linking issues and is no longer
required.
2015-11-24 04:42:37 -08:00
Kevin Mitchell 4f103b2093 manpage: deinterlace is now the lowercase d
there were a few places that that used an upper case D
and one that still actually said Shift+D
2015-11-23 15:18:52 -08:00
wm4 2e401201ad vo: remove VOCTRL_GET_RECENT_FLIP_TIME
It doesn't have any real purpose anymore. Up until now, it was still
implemented by vo_wayland, but since we changed how the frame callbacks
work, even that appears to be pointless.

Originally, the plan was to somehow extend this mechanism to all
backends and to magically fix frame scheduling, but since we can't hope
for proper mechanisms even on wayland, this idea looks way less
interesting.
2015-11-23 16:54:53 +01:00
wm4 b2e8d5749b demux: fix seeking in .ts
.ts files (and some other raw streams) are the only files that enable
the SEEK_FACTOR code path, which was broken since commit 70df1608.
2015-11-23 16:20:44 +01:00
wm4 52af1f72e2 dxva2: reject 10 bit HEVC
10 bit HEVC would require DXVA2_ModeHEVC_VLD_Main10, and most a
different surface type (judging by lavfsplitter source code, both
P010 and P016 would work). Since I'm unable to test this stuff,
exclude 10 bit for now.

See #2516.
2015-11-23 12:38:06 +01:00
wm4 c9d1aa1d3c manpage: clarify correct-downscaling description
Someone complained about the wording.
2015-11-23 09:55:39 +01:00
James Ross-Gowan 718807b78b win32: don't show progress indicator in idle mode 2015-11-23 19:50:13 +11:00
wm4 d2efa56d48 sd_ass: fix secondary subtitle mode
If a second subtitle is shown, it should be forced to display on top
of the screen. This was working only if --no-ass was passed, because
otherwise the subtitle was rendered normally (i.e. usually on the
bottom).
2015-11-22 22:06:56 +01:00
wm4 01a2af6c7c command: export some per-video-frame information
Utterly useless, but requested. Fixes #2444.
2015-11-22 18:54:22 +01:00
wm4 b38094ad91 README: add something about system requirements
This is actually all bullshit. There are many factors that can ruin the
video playback experience (and most outside of our or the user's
control).

One thing that makes sense is that this declares incompatibility with
Windows XP (fixes #2473).
2015-11-22 18:19:35 +01:00
wm4 9817473163 vo_opengl: fix superxbr on GLES
Well, not that anyone does or should care.
2015-11-21 20:45:08 +01:00
wm4 c5a4fd9bee vo_opengl: angle: allow using D3D9 backend
The D3D9 backend does not support GLES 3, which makes it pretty useless.
But it still might be a legitimate replacement of vo_direct3d.c on
Windows 7 machines.

Note that we could just use:

    eglGetDisplay(EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE)

But for now I'll leave the old code. Maybe this can exclude use of
software rendering backends (EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE).
Since I'm not sure, I won't touch it.
2015-11-21 20:30:50 +01:00
wm4 d5df90a295 vo_opengl: use ANGLE by default if available (except for "hq" preset)
Running mpv with default config will now pick up ANGLE by default. Since
some think ANGLE is still not good enough for hq features, extend the
"es" option to reject GLES backends, and add to to the opengl-hq preset.

One consequence is that mpv will by default use libswscale to convert
10 bit video to 8 bit, before it reaches the VO.
2015-11-21 18:17:14 +01:00
wm4 3245b7f275 old-configure: add a missing config.h entry
Yes, the old build system still exists in-tree.
2015-11-19 21:25:15 +01:00
wm4 59eb489425 vo_opengl: enable dumb-mode automatically if possible
I decided that I actually can't stand how vo_opengl unnecessarily puts
the video through 3 shader stages (instead of 1). Thus, what was meant
to be a fallback for weak OpenGL implementations, the dumb-mode, now
becomes default if the user settings allow it.

The code required to check for the settings isn't so wild, so I guess
it's manageable. I still hope that one day, our rendering logic can
generate ideal shader stages for this case too.

Note that in theory, dumb-mode could be reenabled at runtime due to a
color management 3D LUT being set, so a separate dumb_mode field is
required. The dumb-mode option can't just be overwritten.
2015-11-19 21:22:24 +01:00
wm4 4fd0cd4a73 vo_opengl: support 3D textures on ANGLE
Unfortunately, color management can still not work, because no GLES
version specified so far support fixed-point 16 bit textures. Maybe
we could use integer textures, but these don't support filtering.
Using float textures would be another possibility.
2015-11-19 21:21:04 +01:00
wm4 6df3fa2ec1 vo_opengl: switch FBO format on GLES
GL_RGB10_A2 is the best fixed-point format we can get on GLES/ANGLE for
now. (Unless we somehow switch to non-normalized integer textures.)
2015-11-19 21:20:50 +01:00
wm4 1a8b06f67e vo_opengl: make 1D textures completely optional
Polar scalers use 1D textures, because they're slightly faster on some
GPUs than 2D textures. But 2D textures work too, so add support for
them.

Allows using these scalers with ANGLE.
2015-11-19 21:20:40 +01:00
wm4 92d06f43fa vo_opengl: fix some more GLES shader issues
Just like commit f9a2fc59. There are probably some more such cases.
The vec2 constructor calls are probably fine, but don't bother with
confusing inconsistencies.
2015-11-19 21:19:04 +01:00
wm4 23f3b99003 vo_opengl: create FBOs in a more GLES conformant way
While desktop GL's glTexImage2D() essentially accepts anything, GLES is
much stricter. The combination of allowed formats/types/internal formats
is exactly specified. The GLES 3.0.4 specification lists them in
table 3.2. (The ANGLE API validation code references this table.)

The table could probably be extended into a general declarative table
about GL formats covering other uses, but this would be a big
non-trivial project, so don't bother and accept a minor degree
of duplication with other tables.

Note that the format and type do (or should) not matter here, because
no image data is transferred to the GPU.
2015-11-19 21:17:57 +01:00
wm4 b86a59aa4f vo_opengl: better check for float texture support
We don't only need float textures for advanced scaling - we also need
them to be filterable with GL_LINEAR. On GLES, this is not supported
until GLES 3.1, but some implementation expose them with extensions.
2015-11-19 21:17:45 +01:00
Kevin Mitchell 368431f57c vo_opengl: check shader string before sscanfing it 2015-11-19 08:14:06 -08:00
Kevin Mitchell 94147762fc vo_opengl: add missing log newline 2015-11-19 08:11:35 -08:00
Kevin Mitchell e10727baa7 ao_wasapi: only report per-app volume in shared mode
otherwise we were incorrectly adjusting the hardware master volume
in exclusive mode with softvol=auto
2015-11-19 07:14:50 -08:00
wm4 a6fb80baa4 vo_opengl: add RGBA8 framebuffer format, enable non-dumb mode for ES 3.0
This makes advanced scaling sort-of work for GLES 3.0 (on ANGLE). It's
still not very advisable, as 8 bits might not be enough to avoid
debanding. (Ironically, the debanding filter can be enabled, and does
not raise any GL errors - but probably doesn't do anything useful.)
2015-11-19 14:45:06 +01:00
wm4 f9a2fc592f vo_opengl: don't mix floats and integers in dither shader
Some GLSL dialects (GLSL ES 3.00) do not have such implicit conversions.
They have to be made floats for the sake of the shader compiler.
2015-11-19 14:41:49 +01:00
James Ross-Gowan 76e4374d06 vo_opengl: fix ANGLE GLES3 mode
Turns out glGetTexLevelParameter, which is missing in ANGLE, is a
GLES3.1 function. Removing it from the list of core GLES3 functions
makes ANGLE work in GLES3 mode.
2015-11-19 20:37:30 +11:00
wm4 7e285a6f71 ao_wasapi: work around DTS passthrough failure
Apparently, some audio drivers do not support the DTS subtype, but
passthrough works anyway if the AC3 subtype is set. Just retry with
AC3 if the proper format doesn't work. The audio device which
exposed this behavior reported itself as
"M601d-A3/A3R (Intel(R) Display Audio)".

xbmc/kodi even always passes DTS as AC3.
2015-11-19 00:08:07 +01:00
wm4 516e7d19da x11: request bypassing compositor
Maybe this is a good idea. Also add an option to disable it again, for
the sake of testing.

Fixes #2502.
2015-11-18 21:48:29 +01:00
wm4 58caf577f1 player: replace mistimed-frame-count with vsync-ratio on status line
I think this is much more informative. Maybe.
2015-11-18 21:21:57 +01:00
wm4 76fcef618b player: make timeline switching slightly nicer
But not much.
2015-11-18 20:58:07 +01:00
wm4 74c862c68e .gitignore: add nnedi3_weights.inc 2015-11-18 20:34:30 +01:00
Kevin Mitchell 9f858cc759 ao_openal: fix sign of speaker angle in comment 2015-11-18 08:27:47 -08:00
Justas Lavišius ca77bcd543 ao_openal: fix virtual speaker positioning
Place speakers in standard positions equidistant from the listener.

use standard coordinate system
2015-11-18 08:26:07 -08:00
Ellis Berner e086d40486 manpage: fix typo in vd-lavc-o example
`--vd--lavc-o becomes --vd-lavc-o`
2015-11-18 13:33:42 +01:00
wm4 eda518f558 manpage: fix a typo 2015-11-18 13:33:37 +01:00
James Ross-Gowan e76ec2c963 vo_opengl: add initial ANGLE support
ANGLE is a GLES2 implementation for Windows that uses Direct3D 11 for
rendering, enabling vo_opengl to work on systems with poor OpenGL
drivers and bypassing some of the problems with native GL, such as VSync
in fullscreen mode.

Unfortunately, using GLES2 means that most of vo_opengl's advanced
features will not work, however ANGLE is under rapid development and
GLES3 support is supposed to be coming soon.
2015-11-18 23:07:33 +11:00
wm4 a3195381d1 input.conf: add default bindings for changing window scale
These are very much inspired by the hardcoded Cocoa bindings on OSX.

Fixes #2500.
2015-11-17 21:49:30 +01:00
wm4 8ff2058681 demux_mkv: fix incremental indexing with single-keyframe files
This is another regression of the recently added start time probing. If
a seek is executed after opening the file (but before reading any
packets), the first block is discarded instead of indexed. If there are
no other keyframes in the file, seeking will fail completely.

Fix it by seeking to the cluster start if there aren't any index entries
yet. This will read the skipped packet again.

Fixes #2498.
2015-11-17 21:43:35 +01:00
wm4 0ec35fa111 videotoolbox: make decoder format customizable
Because apparently there's no ideal universally working format.

The weird OpenGL texture format for kCVPixelFormatType_32BGRA is from:

http://stackoverflow.com/questions/22077544/draw-an-iosurface-to-an-opengl-context

(Which apparently got it from the linked Apple example code.)
2015-11-17 21:21:19 +01:00
wm4 25fe9e89e7 vo_opengl: osx: error out if there is no IOSurface 2015-11-17 15:22:47 +01:00
Kevin Mitchell 0e0f07bbef ao_openal: accommodate more sample formats
Try and and choose the closest sample format to the one requested.

fixes #2494
2015-11-17 01:54:38 -08:00
Kevin Mitchell c7a39b8521 ao_openal: move uninit before init
the next commit will use uninit within init
2015-11-17 01:32:48 -08:00
wm4 5a89150a46 player: remove OSD subtitle render path
This was used with --no-sub-ass (aka --no-ass). This option (which is
not yet removed) strips all styling from the subtitles, and renders them
as plaintext only. For some reason, it originally seemed convenient to
reuse all the OSD text rendering code (osd_libass.c). While this was
indeed simple, it had a bad influence on the rest of the code. For
example, it had to decide whether to go through the OSD code path, or
the proper subtitle renderer in sd_ass.c.

Kill the OSD subtitle renderer. Reimplement --no-sub-ass and also
"secondary" subtitles in sd_ass.c. fill_plaintext() contains some rather
minor code duplication with osd_libass.c for setting up a dummy
ASS_Event and escaping the stripped text. Since sd_ass.c already has to
handle "normal" text subtitles, and has code for stripping ASS tags,
this remains all relatively simple.

Remove all the unnecessary crap from the rest of the code.
2015-11-17 01:56:23 +01:00
wm4 85450d06a1 player: use demuxer ts offset to simplify timeline ts handling
Use the demux_set_ts_offset() added in the previous commit to base each
timeline segment to use timestamps according to its relative position
within the overall timeline. As a consequence we don't need to care
about these timestamps anymore, and everything becomes simpler.

(Another minor but delicious nugget of sanity.)
2015-11-16 23:17:33 +01:00
wm4 70df1608d6 player: handle rebasing start time differently
Most of this is explained in the DOCS additions.

This gives us slightly more sanity, because there is less interaction
between the various parts. The goal is getting rid of the video_offset
entirely.

The simplification extends to the user API. In particular, we don't need
to fix missing parts in the API, such as the lack for a seek command
that seeks relatively to the start time. All these things are now
transparent.

(If someone really wants to know the real timestamps/start time, new
properties would have to be added.)
2015-11-16 22:47:17 +01:00
wm4 e24e0ccd68 vo_opengl: force dumb mode if RG textures are not available
Something goes wrong somewhere. Don't bother, it's only needed for
compatibility with our absolute baseline (GL 2.1/GLES 2).

On the other hand, we can process nv12 formats just fine.
2015-11-16 20:09:15 +01:00
wm4 514f5d760e README: suggest uchardet instead of Enca as dependency
Enca is dead, uchardet is better (in half of all cases; on others it's
worse).
2015-11-16 16:24:26 +01:00
wm4 05be95c8ce sub: remove an unneeded old hack for MicroDVD
This happens to be handled in a better way in another place now.
2015-11-16 16:23:28 +01:00
wm4 6b22b21651 vo_opengl: attempt to improve GLX vs. EGL backend detection
For the sake of vaapi interop, we want to use EGL, but on the other
hand, but because driver developers are full of shit, vdpau interop will
not work on EGL (even if the driver supports EGL). The latter happens
with both nvidia and AMD Mesa drivers.

Additionally, EGL vaapi interop support can apparently only detected at
runtime by actually using it. While hwdec_vaegl.c already does this, it
would require initializing libva on _every_ system, which will cause
libav to print an unpreventable bullshit message to the terminal.

Try to counter these huge loads of bullshit by adding more fucking
bullshit.
2015-11-16 16:22:23 +01:00
wm4 07c546b2b4 vo_opengl: fix backend autoprobing
We want the following behavior:
- VO probed, backend probed: only accept non-sw, fail completely
otherwise
- VO forced, backend probed: use the first non-sw, or if none is found,
fall back to the first working sw backend
- VO probed, backend forced: (I don't care about this case)
- VO forced, backend forced: just use that backend

Also, on backend probe failure the vo->probed field was left in its old
state.
2015-11-16 16:15:07 +01:00
Martin Herkt bf0b178e71 win32: support taskbar button progress indicator
This adds support for the progress indicator taskbar extension
that was introduced with Windows 7 and Windows Server 2008 R2.

I don’t like this solution because it keeps its own state and
introduces another VOCTRL, but I couldn’t come up with anything
less messy.

closes #2399
2015-11-15 23:18:24 +01:00
wm4 883d311413 vo_opengl: use glBlitFramebuffer to draw repeated frames
In the display-sync, non-interpolation case, and if the display refresh
rate is higher than the video framerate, we duplicate display frames by
rendering exactly the same screen again. The redrawing is cached with a
FBO to speed up the repeat.

Use glBlitFramebuffer() instead of another shader pass. It should be
faster.

For some reason, post-process was run again on each display refresh.
Stop doing this, which should also be slightly faster. The only
disadvantage is that temporal dithering will be run only once per video
frame, but I can live with this.

One aspect is messy: clearing the background is done at the start on the
target framebuffer, so to avoid clearing twice and duplicating the code,
only copy the part of the framebuffer that contains the rendered video.
(Which also gets slightly messy - needs to compensate for coordinate
system flipping.)
2015-11-15 18:30:54 +01:00
wm4 c7d82dd25c vo: fix unpausing with display-sync
Currently, vo.c will always continue to render the currently queued
frame, which sets last_flip, which in turn confuses vo_get_delay(),
which in turn will show a bogus A/V desync message on unpause. So just
reset it again on unpause.
2015-11-15 13:17:54 +01:00
wm4 cf3b34f17a vo: fix dropping frames with display-sync
I guess the removed code is an old leftover, and makes no sense anymore.
Should fix weird A/V diff dropouts when frames are being dropped with
display-sync.
2015-11-14 21:49:48 +01:00
wm4 a790009a63 player: account for minor VO underruns
If the player sends a frame with duration==0 to the VO, it can trivially
underrun. Don't panic, but keep the correct time.

Also, returning the absolute time from vo_get_next_frame_start_time()
just to turn it into a float with relative time was silly. Rename it and
make it return what the caller needs.
2015-11-14 21:49:48 +01:00
wm4 542d88472f player: remove unused field 2015-11-14 21:42:55 +01:00
wm4 9f43778eb2 player: fix audio drift computation at different playback speeds
This computed nonsense if the user set a playback speed other than 1
(in addition to the display-sync speed change).
2015-11-14 21:42:25 +01:00
wm4 0f3dedebb4 player: stricter framedrop threshold
80ms allowable desync was a bit too much. It'd allow for a range of
160ms, which everyone can notice. It might also be a bother to apply
compensation resampling speed for that long.
2015-11-13 22:53:38 +01:00
wm4 70d46a9fb8 player: try to compensate actual audio drift
We always let audio slowly desync until a threshold is reached, and then
pushed it back by applying a maximum compensation speed. Refine what
comes afterwards: instead of playing with the nominal video speed, use
the actual required audio speed for keeping sync as measured by the A/V
difference. (The "actual" speed is the ideal speed with A/V differences
added.)

Although this works in theory, it's somewhat questionable how much this
works in practice. The ideal time value is actually not exact, but is
the time at which the frame is scheduled (could be compensated by using
the time_left calculations in handle_display_sync_frame()). It doesn't
account for speed changes or catastrophic discontinuities. It uses only
10 past frames.
2015-11-13 22:51:39 +01:00
wm4 c362c3d7ae player: change display-sync audio speed only if needed
As long as it's within the desync tolerance, do not change the audio
speed at all for resampling. This reduces speed changes which might be
caused by jittering timestamps and similar cases.

(While in theory you could just not care and change speed every single
frame, I'm afraid that such changes could possibly cause audio
artifacts. So better just avoid it in the first place.)
2015-11-13 22:50:58 +01:00
wm4 07b8abbd62 player: remove display_sync_disable_counter
We can implement it differently and drop a tiny bit of state.
2015-11-13 22:49:50 +01:00
wm4 d5981924fe command: add vsync-ratio property
This is very "illustrative", unlike the video-speed-correction
property, and thus useful. It can also be used to observe scheduling
errors, which are not detected by the core. (These happen due to
rounding errors; possibly not evne our fault, but coming from
files with rounded timestamps and so on.)
2015-11-13 22:48:32 +01:00
wm4 62b386c2fd player: compute required display-sync speed change differently
Instead of looking at the current frame duration for the intended
speedup, look at all past frames, and find a good average speed. This
ties in with not wanting to average _all_ frame durations, which
doesn't make sense in VFR situations.

This is currently done in the most naive way possible, but already sort
of works for VFR which switches between frame durations that are
integer multiples of a base rate. Certainly more improvements could
be made, such as trying to adjust directly on FPS changes, instead of
averaging everything, but for now this is not needed at all.
2015-11-13 22:47:14 +01:00
wm4 fad254562b player: smooth out frame durations by averaging them
Helps somewhat with muxer-rounded timestamps.

There is some danger that this introduces a timestamp drift. But since
they are averaged values (unlike as when using an incorrect container
framerate hint), any potential drift shouldn't be too brutal, or
compensate itself soon. So I won't bother yet with comparing the results
with the real timestamp, unless we run into actual problems.

Of course we still prefer potentially real timestamps over the
approximated ones. But unless the timestamps match the container FPS,
we can't know whether they are (no, checking whether the they have
microsecond components would be cheating). Perhaps in future, we could
let the demuxer export the timebase - if the timebase is not 1000 (or
divisible by it), we know that millisecond-rounded timestamps won't
happen.
2015-11-13 22:46:55 +01:00
wm4 d32c4c75ef player: refactor display-sync frame duration calculations
Get rid of get_past_frame_durations(), which was a bit too messy. Add
a past_frames array, which contains the same information in a more
reasonable way. This also means that we can get the exact current and
past frame durations without going through awful stuff. (The main
problem is that vo_pts_history contains future frames as well, which is
needed for frame backstepping etc., but gets in the way here.)

Also disable the automatic disabling of display-sync if the frame
duration changes, and extend the frame durations allowed for display
sync. To allow arbitrarily high durations, vo.c needs to be changed
to pause and potentially redraw OSD while showing a single frame, so
they're still limited.

In an attempt to deal with VFR, calculate the overall speed using the
average FPS. The frame scheduling itself does not use the average FPS,
but the duration of the current frame. This does not work too well,
but provides a good base for further improvements.

Where this commit actually helps a lot is dealing with rounded
timestamps, e.g. if the container framerate is wrong or unknown, or
if the muxer wrote incorrectly rounded timestamps. While the rounding
errors apparently can't be get rid of completely in the general case,
this is still much better than e.g. disabling display-sync completely
just because some frame durations go out of bounds.
2015-11-13 22:45:40 +01:00
wm4 624c9e46ce player: always require a future frame with display-sync enabled
We need a frame duration even on start, because the number of vsyncs
the frame is shown is predetermined. (vo_opengl actually makes use of
this property in certain cases.)
2015-11-13 22:42:42 +01:00
wm4 f0feea5591 command: rename vo-missed-frame-count property
"Missed" implies the frame was dropped, but what really happens is that
the following frame will be shown later than intended (due to the
current frame skipping a vsync).

(As of this commit, this property is still inactive and always
returns 0. See git blame for details.)
2015-11-13 22:41:41 +01:00
Martin Herkt def87f1e5f win32: avoid detection as exclusive fullscreen window
Apparently Windows treats windows that use OpenGL, cover an entire
screen and have the WS_POPUP style set or are topmost windows as
exclusive fullscreen windows that bypass DWM and cannot be covered
by other windows.
This means we can’t use dwmflush in fullscreen mode, and it also
means that no other window can cover mpv, and it makes the screen
flicker when switching to fullscreen mode.

This can be avoided by not setting the WS_POPUP flag.
Users can still access the old behavior by enabling stay-on-top
(which IMO at least makes sense—now we just need to get dwmflush
autodetection right to avoid nasty surprises).

fixes #2177
2015-11-13 12:41:59 +01:00
wm4 b726fefe5d vo_opengl_cb: do not block on flipping when redrawing
Gives slightly better behavior when used with Qt. (Which tends not to
flip buffers when the window is not visible.)
2015-11-12 22:44:05 +01:00
wm4 49a41bf4df build: make vaapi-wayland depend on gl-wayland
Wayland without GL isn't enough. Specifically, we need to make sure the
EGL libs are included. (That's one tricky dependency tree.)

Fixes #2476.
2015-11-12 11:38:03 +01:00
wm4 384b13c5fd demux_libass: remove this demuxer
This loaded external .ass files via libass. libavformat's .ass reader is
now good enough, so use that instead.

Apparently libavformat still doesn't support fonts embedded into text
.ass files, but support for this has been accidentally broken in mpv for
a while anyway. (And only 1 person complained.)
2015-11-11 21:28:20 +01:00
wm4 977869a804 demux_lavf: mark ASS tracks as always UTF-8
Stops mpv from trying to run a subtitle charset detector on .ass files
loaded by libavformat.
2015-11-11 21:25:08 +01:00
wm4 7c4fe02d01 player: less naive rounding 2015-11-11 19:52:35 +01:00
rr- b7398cbdd8 drm: fix setting up connectors
Fixes regression from 67caea357c.
2015-11-11 19:40:13 +01:00
wm4 9774be0d15 af_lavrresample: simplify set_compensation usage
Just set the ratio directly by working around the intended semantics of
the API function. The silly rounding stuff we had isn't needed anymore
(and not entirely correct anyway).

Note that since the compensation is virtually active forever, we need to
reset if it's not needed. So always run this code to be sure to reset
it.

Also note that libswresample itself had a precision issue, until it
was fixed in FFmpeg commit 351e625d.
2015-11-11 19:28:37 +01:00
Martin Herkt a33a44cf4e Release 0.13.0 2015-11-10 19:14:14 +01:00
Martin Herkt 273607c1c6 Merge branch 'master' into release/current 2015-11-10 18:45:08 +01:00
wm4 fee45c0170 player: silence sporadic error messages on audio init
When the audio format is not known yet and the audio chain is still
initializing, filter reinit will fail. Normally, attempts to
reinitialize filters at this stage should be rare (e.g. user commands
editing the filter chain). But it sometimes happened with track
switching in combination with the video code calling
update_playback_speed() at arbitrary times.

Get rid of the message by not trying to change the filters for the sake
of playback speed update while decoding is still being initialized.
2015-11-10 17:53:05 +01:00
wm4 9a6ec9de2f vd_lavc: be more careful with flushing the decoder
Until now, we've relied on the following things:

- you can send flush packets to the decoder even if it's fully flushed,
- you can send new packets to a flushed decoder,
- you can send new packers to a partially flushed decoder.

("flushing" refers to sending flush packets to the decoder until the
decoder does not return new pictures, not avcodec_flush_buffers().)

All of these are questionable. The libavcodec API probably doesn't
guarantee that these work well or at all, even though most decoders have
no issue with these. But especially with hardware decoding wrappers
(like MMAL), real problems can be expected. Isolate us from these corner
cases by handling them explicitly.
2015-11-10 16:06:42 +01:00
wm4 4682b0147e vo_opengl: move the glFlush() call to the renderer 2015-11-10 14:36:23 +01:00
wm4 479eb93d9e vo_opengl_cb: better underflow reporting
This applies to unexpected freezes or deadlocks, not e.g. normal
framedrops. The verbose messages also might remind an API user if the
API usage is incorrect, such as not calling mpv_opengl_cb_draw() when a
redraw request was issued.
2015-11-10 14:35:13 +01:00
wm4 9d9f863f55 vo_opengl: limit GLSL to version 3.3
Fixes custom shaders, which define their entrypoint as sample()
function.
2015-11-10 11:51:11 +01:00
Kevin Mitchell dd0c85679b stream_libarchive: make libarchive seek callback lazy
This fixes problems seeking http streams to their end.
2015-11-09 22:41:19 -08:00
Kevin Mitchell 4efadb2808 stream_libarchive: add multivolume support
This commit introduces logic to read other volumes from the same source
as the primary archive. Both .rar formats as well as 7z are supported for now.

It also changes the libarchive callback structure to be per-volume
consistent with the libarchive intenal client data array constructed
with archive_read_append_callback_data.

Added open, close and switch callbacks. Only the latter is strictly
required to make sure that the streams always start at position 0, but
leaving all volumes open can eat a lot of memory for archives with many
parts.
2015-11-09 22:41:19 -08:00
Kevin Mitchell cf5b117553 libarchive: remove redundant log prefix
"libarchive:" is already added by the logging system
2015-11-09 22:41:19 -08:00
Kevin Mitchell 434512827f external_files: deduplicate bstr functions 2015-11-09 22:41:19 -08:00
Bin Jin 03bbaad686 vo_opengl: fix 10-bit video prescaling
The nnedi3 prescaler requires a normalized range to work properly,
but the original implementation did the range normalization after
the first step of the first pass. This could lead to severe quality
degradation when debanding is not enabled for NNEDI3.

Fix this issue by passing `tex_mul` into the shader code.

Fixes #2464
2015-11-09 22:48:40 +01:00
wm4 3dc0f2ecf0 vo_opengl_cb: make operation more similar to normal VOs
vo_opengl_cb is a special case, because we somehow have to render video
asynchronously, all while "trusting" the API user to do it correctly.
This didn't quite work, and a while ago a compromise using a timeout to
prevent theoretically possible deadlocks was added.

Make it even more synchronous. Basically, go all the way, and
synchronize rendering between VO and user renderer thread to the
full extent possible.

This means the silly frame queue is dropped, and we event attempt to
synchronize the GL SwapBuffer call (via mpv_opengl_cb_report_flip()).

The changes introduced with commit dc33eb56 are effectively dropped. I
don't even remember if they mattered.

In the future, we might make all VOs fetch asynchronously from a frame
queue, which would mostly remove the differences between vo_opengl and
vo_opengl_cb, but this will take a while (if it will even be done).
2015-11-09 20:51:57 +01:00
wm4 eeb5f98758 vo_opengl: handle GL_ARB_uniform_buffer_object with low GLSL versions
Why is this stupid crap being so much a pain for no reason.
2015-11-09 16:24:01 +01:00
wm4 caa497ee8a vo_opengl: fix extension name 2015-11-09 14:29:58 +01:00
wm4 930f841589 vo_opengl: simplify GLSL version detection
Pick the correct GLSL version from the GL_SHADING_LANGUAGE_VERSION
string. Might be somewhat questionable, as we expect the minor version
number not to have leading 0s.

Should help with cases when the reported GLSL version is much higher
than the equivalent of the reported GL version. This problem was
observed in combination with GL_ARB_uniform_buffer_object, which
can't be used if the declared GLSL version is too low.
2015-11-09 14:29:09 +01:00
wm4 8baf773d0e command: make display-fps property writable
Has the same function as setting the option.

This commit changes the property in a bunch of other ways. For example
if the VO is not created, it will return the option value.
2015-11-09 13:59:25 +01:00
wm4 11888a9270 vo_opengl: never load vaapi GLX interop by default
Causes more harm than it helps. Will eventually be removed.

Also rename the "reject_emulated" field to "probing" - this is more
appropriate now.
2015-11-09 11:58:38 +01:00
wm4 76e50f6a3d vo_opengl: always preload hwdec interop
Simplifies some auto detection matters.

I _still_ don't want to remove the lazy loading mechanism, because it's
still slightly useful for filters using the hwdec APIs. My main
motivation for not always preloading them is actually that libva prints
random useless crap to the terminal with no way to prevent this.
2015-11-09 11:57:11 +01:00
wm4 7d5282ea5d vo_opengl: rename "drm_egl" to "drm-egl" 2015-11-09 11:21:28 +01:00
rr- f757163058 vo_opengl: disable drm_egl autopickup 2015-11-09 11:19:56 +01:00
wm4 ac64ce71d6 dec_audio: add missing include
Was masked by FFmpeg's terrible headers, but failed with Libav.
2015-11-08 20:01:20 +01:00
wm4 16cd20c46f win32: request MMCSS "Playback" profile 2015-11-08 19:33:38 +01:00
wm4 8f7b12d9ae manpage: remove examples and authors section
The examples demonstrates use with optical media, which is far from
mpv's main purpose.

The authors section is a leftover from MPlayer times. There are enough
other places which reiterate how mpv is based on mplayer2/MPlayer,
copyright statements, and so on.
2015-11-08 19:02:18 +01:00
wm4 66f8e45311 manpage: slightly improve configuration files section
Hint that the linked section contains information for Windows. (Well,
that's a lie, but it has a link to the Windows section.)

Avoid implying that lines in the config file end with ';'. Also, the <>
are probably just confusing.
2015-11-08 18:09:00 +01:00
wm4 0ff3ffb2be audio: interpolate audio timestamps
Deal with jittering Matroska crap timestamps. This reuses the mechanism
that is needed for frames without PTS, and adds a heuristic to it. If
the interpolated timestamp is less than 1ms away from the real one, it
might be due to Matroska timestamp rounding (or other file formats with
such rounding, or files remuxed from Matroska).

While there actually isn't much of a need to do this (audio PTS
jittering by such a low amount doesn't negatively influence much), it
helps with identifying jitter from other sources.
2015-11-08 18:06:24 +01:00
wm4 d91434756b audio: move PTS setting out of the decoder
Instead of requiring the decoder to set the PTS directly on the
dec_audio context (including handling absence of PTS etc.), transfer the
packet PTS to the decoded audio frame. Marginally simpler, and gives
more control to the generic code.
2015-11-08 17:22:56 +01:00
rr- 03013e0fd7 vo_drm: relicense to LGPL
Also removed authorship information (as per convention seen in other
files)
2015-11-08 15:00:15 +01:00
rr- 62f261a7b8 vo_drm: use bool rather than integer return values
Since the errors weren't used for anything other than simple
success/fail checks, I simplified things a bit.
2015-11-08 15:00:15 +01:00
rr- c3f2ef5491 vo_opengl: add DRM EGL backend
Notes:

- Unfortunately the only way to talk to EGL from within DRM I could find
  involves linking with GBM (generic buffer management for Mesa.)
  Because of this, I'm pretty sure it won't work with proprietary NVidia
  drivers, but then again, last time I checked NVidia didn't offer
  proper screen resolution for VT.

- VT switching doesn't seem to work at all. It's worth mentioning that
  using vo_drm before introduction of VT switcher had an anomaly where
  user could switch to another VT and input text to it, while video
  played on top of that VT. However, that isn't the case with drm_egl:
  I can't switch to other VT during playback like this. This makes me
  think that it's either a limitation coming from my firmware or from
  EGL/KMS itself rather than a bug with my code. Nonetheless, I still
  left (untestable) VT switching code in place, in case it's useful to
  someone else.

- The mode_id, connector_id and device_path should be configurable for
  power users and people who wish to watch videos on nonprimary screen.
  Unfortunately I didn't see anything that would allow OpenGL backends
  to register their own set of options. At the same time, adding them to
  global namespace is pointless.

- A few dozens of lines could be shared with vo_drm (setting up VT
  switching, most of code behind page flipping). I don't have any strong
  opinion on this.

- Sometimes I get minor visual glitches. I'm not sure if there's a race
  condition of some sort, unitialized variable (doubtful), or if it's
  buggy driver. (I'm using integrated Intel HD Graphics 4400 with Mesa)

- .config and .control are very minimal.

Signed-off-by: wm4 <wm4@nowhere>
2015-11-08 15:00:15 +01:00
rr- 67caea357c vo_drm: move initialization to drm_common
Makes KMS initialization procedures reusable so that they can be used by
the upcoming DRM EGL adapter.
2015-11-08 14:58:34 +01:00
rr- b1893d2084 vo_opengl: fix typo 2015-11-07 19:46:51 +01:00
wm4 46cee66563 vo_opengl: rename fancy-downscaling to correct-downscaling
The old name was stupid. Very stupid.
2015-11-07 17:49:14 +01:00
Avi Halachmi (:avih) 0062c98dff vo_opengl: fancy-downscaling: enable also for anamorphic clips 2015-11-07 17:44:50 +01:00
wm4 6bbb1e4cf9 x11: print Xlib errors in verbose mode if Xlib messages are silenced
Follow up to commit b984ec52.
2015-11-07 17:43:10 +01:00
wm4 1356755ad4 demux_mkv: remove --demuxer-mkv-fix-timestamps
While it seemed like a pretty good idea at first, it's just a dead end
and works only in the simplest cases. While it may or may not help
slightly with audio sync mode, the display-sync mode already compensates
this in a better way. The main issue is that timestamps at this layer
are not in order, so it can look at single timestamps only.
2015-11-07 17:37:32 +01:00
wm4 2dc18a2f82 chmap: remove MPlayer layouts
Unused; last uses removed with the previous two commits.
2015-11-07 15:22:30 +01:00
wm4 a7f51f8fd4 ao_jack: remove "alsa" std-channel-layout choice
Same deal as with previous commit. "waveext" is less arbitrary and at
least supports 3/7 channels.
2015-11-07 15:20:34 +01:00
wm4 5a7c22a1ac ao_alsa: remove the last bits of legacy channel map fallback
Essentially we'd use something random, just because it's part of the srt
of traditionally used ALSA channel mappings. But each driver can do its
own things.

This doesn't let me sleep at night, so remove it.
2015-11-07 15:18:05 +01:00
wm4 617aff6cda audio: fix af_fmt_change_bytes() with spdif formats
This could accidentally change some spdif formats to AAC (because AAC is
the first on the list and will match first). spdif formats are
inherently uninterchangeable, so treat them as their own class of
formats (like int vs. float).

Might fix some issues with ao_wasapi.c.
2015-11-07 15:07:50 +01:00
wm4 b984ec52aa vo_opengl: x11: silence error messages when using legacy GL context
glXCreateContextAttribsARB() by design can throw some X11 errors. We
ignore these, but we generally still print error messages to the
terminal. This was confusing/annoying users, so silence it. The stupid
part is that the Xlib error handler is global, so we have to be slightly
careful here.
2015-11-06 21:20:23 +01:00
wm4 9693e0f57a Remove some VLAs
They are evil and should be eradicated. Some of these were pretty dumb
anyway.

There are probably some more around in platform specific code or other
code not enabled by default on Linux.
2015-11-06 21:12:20 +01:00
James Ross-Gowan 647b360a0a w32: use DisplayConfig API to retrieve correct monitor refresh rate
This is based on an older patch by James Ross-Gowan. It was rebased and
cleaned up. Also, the DWM API usage present in the older patch was
removed, because DWM reports nonsense rates at least on Windows 8.1
(they are rounded to integers, just like with the old GDI API - except
the GDI API had a good excuse, as it could report only integers).

Signed-off-by: wm4 <wm4@nowhere>
2015-11-06 19:53:18 +01:00
James Ross-Gowan 68ac45e487 w32: always get screenrc from an HMONITOR
This simplifies update_screen_rect a bit. Unless --fs-screen=all is
used, it will always get an HMONITOR and call GetMonitorInfo to
determine its dimensions. This will make it easier for the next few
commits to determine the colour profile and the refresh rate from the
HMONITOR.

There is a slight change in behaviour. When selecting a screen that is
out of range, such as --screen=9 on a machine with only two monitors,
the old code would silently select the last existing monitor. The new
code prints an error message and falls back to the default screen (same
as the Cocoa code.)

Signed-off-by: wm4 <wm4@nowhere>
2015-11-06 19:53:18 +01:00
James Ross-Gowan 9e10cd9fa1 w32: remove Win95 and NT4 monitor code
The call to EnumDisplaySettings seems to be a relic from when MPlayer
ran on systems that didn't have GetMonitorInfo or SM_CX/CYVIRTUALSCREEN.
GetMonitorInfo was loaded dynamically, so it was possible for MPlayer to
run without it and use the values returned by EnumDisplaySettings.

These are always present in modern versions of Windows, so the values
returned from EnumDisplaySettings are always overwritten. Remove the
call to EnumDisplaySettings and assume SM_CX/CYVIRTUALSCREEN is always
present.

Signed-off-by: wm4 <wm4@nowhere>
2015-11-06 19:53:18 +01:00
wm4 b2a3e877c0 video: increase avi pts buffer size
When decoding on RPI/MMAL, the buffering between decoder input and
output can be quite excessive.
2015-11-06 17:06:32 +01:00
wm4 5f89ba707d vo_opengl: simplify function loader slightly
We don't use any functions that have been deprecated in any later GL or
GLES functions. (This is a leftover of vo_opengl_old support.)
2015-11-06 14:01:01 +01:00
wm4 cfa4952f7c vo_opengl: glBindBufferBase is not part of GL 2.1/GLES 2.0
Commit 27dc834f added it as such.

Also remove the check for glUniformBlockBinding() - it's part of an
extension, and the check glGetUniformBlockIndex() already checks whether
the extension is fully available.
2015-11-06 13:59:33 +01:00
wm4 945df57357 demux_mkv: dump mixing/writing app fields in verbose log 2015-11-06 12:48:24 +01:00
wm4 fb193713a3 old-makefile: update with latest source additions
Yes, I'm still using this.
2015-11-05 17:53:05 +01:00
Bin Jin 27dc834f37 vo_opengl: implement NNEDI3 prescaler
Implement NNEDI3, a neural network based deinterlacer.

The shader is reimplemented in GLSL and supports both 8x4 and 8x6
sampling window now. This allows the shader to be licensed
under LGPL2.1 so that it can be used in mpv.

The current implementation supports uploading the NN weights (up to
51kb with placebo setting) in two different way, via uniform buffer
object or hard coding into shader source. UBO requires OpenGL 3.1,
which only guarantee 16kb per block. But I find that 64kb seems to be
a default setting for recent card/driver (which nnedi3 is targeting),
so I think we're fine here (with default nnedi3 setting the size of
weights is 9kb). Hard-coding into shader requires OpenGL 3.3, for the
"intBitsToFloat()" built-in function. This is necessary to precisely
represent these weights in GLSL. I tried several human readable
floating point number format (with really high precision as for
single precision float), but for some reason they are not working
nicely, bad pixels (with NaN value) could be produced with some
weights set.

We could also add support to upload these weights with texture, just
for compatibility reason (etc. upscaling a still image with a low end
graphics card). But as I tested, it's rather slow even with 1D
texture (we probably had to use 2D texture due to dimension size
limitation). Since there is always better choice to do NNEDI3
upscaling for still image (vapoursynth plugin), it's not implemented
in this commit. If this turns out to be a popular demand from the
user, it should be easy to add it later.

For those who wants to optimize the performance a bit further, the
bottleneck seems to be:
1. overhead to upload and access these weights, (in particular,
   the shader code will be regenerated for each frame, it's on CPU
   though).
2. "dot()" performance in the main loop.
3. "exp()" performance in the main loop, there are various fast
   implementation with some bit tricks (probably with the help of the
   intBitsToFloat function).

The code is tested with nvidia card and driver (355.11), on Linux.

Closes #2230
2015-11-05 17:38:20 +01:00
Bin Jin 3f73d63523 file2string: mark question mark as non-safe
Escaping all question marks as well, they can be used to form
trigraph characters which are effective even within string literal.
2015-11-05 17:38:20 +01:00
Bin Jin 4c43c30421 vo_opengl: add Super-xBR filter for upscaling
Add the Super-xBR filter for image doubling, and the prescaling framework
to support it.

The shader code was ported from MPDN extensions project, with
modification to process luma only.

This commit is largely inspired by code from #2266, with
`gl_transform_trans()` authored by @haasn taken directly.
2015-11-05 17:38:20 +01:00
Bin Jin 7438f208c3 vo_opengl: make image size dynamic during rendering
This commit marks the image size variables temporary, and renames them
in order to prevent any potential confusion in the future.
2015-11-05 17:38:20 +01:00
wm4 017f3d0674 options: enable mpeg2 hw decoding by default if hw decoding is requested
We didn't include this codec in the whitelist because of past problems
with vdpau and interlacing. (I can't reproduce any problems anymore.)
2015-11-05 17:31:07 +01:00
wm4 2cf9ee989c rpi: add support for codecs other than h264
FFmpeg now supports h264 and mpeg2. At least vc-1 will probably follow.
2015-11-05 17:24:35 +01:00
wm4 66ed50aa00 vo_vdpau: check VDP_RGBA_FORMAT_A8 support
Apparently not all vdpau drivers in the wild support this format (VDPAU
SUNXI can't). Revert to RGB in these cases.
2015-11-04 21:49:54 +01:00
wm4 179d7317e7 player: use input instead of output format for spdif check
This check disables the display-sync resample method. If the filters
convert PCM to AC3, we can still insert a filter to change speed. This
is because filters are inserted at the beginning of the filter chain.
2015-11-04 21:49:54 +01:00
wm4 3108a3a001 audio: do not require full audio chain reinit for speed changes
Actually, it didn't really require that before (most work was avoided),
but some bits had to be run anyway. Separate the speed change into a
light-weight function, which merely updates already created filters, and
a heavy-weight one which messes with filter insertion.

This also happens to fix the case where the filters would "forget" the
current speed (force resampling, change speed, hit a volume control to
force af_volume insertion - it will reset speed and desync).

Since we now always run the light-weight function, remove the
af_scaletempo verbose message that is printed on speed setting. Other
than that, all setters are cheap.
2015-11-04 21:49:54 +01:00
wm4 8f7cf9443f player: move audio speed adjustment code
Move it (in a cosmetic sense), and also move its invocation to below all
the video handling.

All other changes remain cosmetic, including moving the framedrop
calculation code, and getting rid of the video_speed_correction
variable.
2015-11-04 21:49:54 +01:00
wm4 e3db686e87 af_lavcac3enc: simplify/fix AVPacket handling
For some reason, the encoder didn't like that the AVPacket already had
fields set. I'm not quite sure, but this might just be invalid API
usage. Do it as it's recommended.
2015-11-04 21:49:54 +01:00
wm4 db1fc3628f audio: strictly align audio on spdif frames
We still have a sample-based buffer between filters and audio outputs.
In order to avoid cutting frames into half (which can upset receivers),
we strictly need to align the boundaries on which we cut the audio.
2015-11-04 21:49:54 +01:00
wm4 3ad03f6673 options: handle terminal/logging settings eagerly
Update msg.c state immediately if a terminal or logging setting is set.
Until now, this was delayed until mp[v]_initialize() was called. When
using the client API, you could easily miss logged error messages, even
when logging was initialized early on by calling
mpv_request_log_messages().

(Properties can't be used for this either, because properties do not
work before mpv_initialize().)
2015-11-04 21:49:54 +01:00
wm4 f00edfd9c5 vo_opengl_cb: log some events
The noframe event is logged whenever there is no new frame. This can
happen due to normal redraws, but also due to video frame queue
underflow.

The mpv_opengl_cb_report_flip() API function is currently pretty
useless, because blocking on the video frame queue is more reliable and
simpler. But at least we can log the actual vsync.
2015-11-04 21:49:54 +01:00
wm4 e6a395c297 vo_opengl, vo_opengl_cb: drop unneeded vo_frame fields
next_vsync/prev_vsync was only used to retrieve the vsync duration. We
can get this in a simpler way.

This also removes the vsync duration estimation from vo_opengl_cb.c,
which is probably worthless anyway. (And once interpolation is made
display-sync only, this won't matter at all.)
2015-11-04 21:49:54 +01:00
wm4 be49da72ea ao_alsa: fix 7.1 over HDMI
We need to effectively swap the last channel pair. See commit 4e358a96
and 5a18c5ea for details.

Doing this seems rather strange, as 7.1 just extends 5.1 with 2 new
speakers, and 5.1 doesn't need this change. Going by the HDMI standard
and the Intel HDA sources (cited in the referenced commits), it also
looks like 7.1 should simply append two channels to 5.1 as well. But
swapping them is apparently correct. This is also what XBMC does. (I
didn't find any other applications doing 7.1 PCM using the ALSA channel
map API. VLC seems to ignore the 7.1 case.) Testing reveals that at
least the end result is correct.

"Normal" ALSA 7.1 is unaffected by this, as it reports a different
(and saner) channel layout.
2015-11-04 21:48:37 +01:00
wm4 46f59f25c2 ao_alsa: map mp_chmaps back to ALSA in a different way
Instead of constructing an ALSA channel map from mpv ones from scratch,
try to find the original ALSA channel map again. Th result is that we
need to convert channel maps only in one direction. If we need to map
a mp_chmap to ALSA, we fetch the device's channel map list, convert
each entry to mp_chmap, and find the first one which fits.

This seems helpful for the following commit. For now, this only gets rid
of mapping back the trivial MONO mapping, which alone would still be
acceptable, but with other channel layout mogrifications it gets messy
fast. While we need to do something awkward to keep our channel map
reordering for VAR chmaps (which basically gives nicer output and
possibly slightly better performance), this is still the better
solution.
2015-11-04 21:48:37 +01:00
wm4 0ca8b290a4 ao_alsa: print more chmap info at debug verbosity 2015-11-04 21:48:37 +01:00
wm4 5a18c5ea91 Revert "af_lavrresample: don't drop sl/sr channels for 7.1 on ALSA"
This reverts commit 4e358a9636.

Testing shows the channel pairs must indeed be swapped (details see
commit message of the reverted commit). Making the downmix code move
sl/sr to sdl/sdr is not an appropriate solution anymore, and it's
better to fix the unusual channel layout in ao_alsa.c directly.

(Not reverting the change in chmap.c; this is still correct.)
2015-11-04 21:48:37 +01:00
James Ross-Gowan a9833a71ce TOOLS/gen-x11-icon.sh: fix for recent ImageMagick
Apparently ImageMagick no longer appends a newline to the format. This
also sets the execute bit on the script.
2015-11-04 21:48:27 +01:00
wm4 350d902799 player: fix display-sync adrop speed limiting
Commit 49d94853 worked only at the start of playback.
2015-11-04 10:57:29 +01:00
wm4 e187de7eed vo: do not go to sleep if there's a new frame queued
This affects only the display-sync code path, as for normal timing the
wakeup_pts stuff handles proper wakeup. It's probably mostly a
theoretical issue.
2015-11-03 20:47:15 +01:00
wm4 49d94853b5 player: limit speed change in display-sync adrop mode
Discontinuities (like toggling fullscreen) can cause multiple frames to
be dropped in succession, which sounds very weird. It's better to drop
some video frames instead to compensate for larger desyncs.

We roughly base it on the maximum allowed speed changes (audio change is
"additional" to the video change to account for deviations when playing
at max. video speed change).
2015-11-03 20:29:25 +01:00
wm4 163c6ad862 vd_lavc: make hwdec fallback more tolerant
A hw decoder might fail to decode a frame for multiple reasons, and not
always just because decoding is impossible. We can't generally
distinguish these reasons well. Make it more tolerant by accepting
failures of 3 frames, but not more. The threshold can be adjusted by the
repurposed --vd-lavc-software-fallback option.

(This behavior was suggested much earlier in some PR, but at the time
the "proper" hwdec fallback was indistinguishable from decoding error.
With the current situation, "proper" fallback is still instantious.)
2015-11-03 14:03:02 +01:00
wm4 4058b418bf vo: fix display-sync frame drop accounting again
Commit acd5816a fixed this, except when vo_opengl interpolation was
active. (And again, the old interpolation code path should be removed.)
2015-11-03 13:33:38 +01:00
wm4 4e358a9636 af_lavrresample: don't drop sl/sr channels for 7.1 on ALSA
ao_alsa: attempt to fix 7.1 over HDMI

The last 2 channels of 7.1 (RLC/RRC in ALSA) were exported as sdl/sdr
instead of sl/sr (I don't even know why I chose sdl/sdr, but SL/SR
and RLC/RRC are different in the ALSA API). libsw/avresample do not
move the sl/sr channels to sdl/sdr when rematrixing, so silence was
sent for 2 channels. If my selection of sdl/sdr is essentially API
abuse, there's no reason why they should do this differently.

The mess here is really that ALSa doesn't map the HDMI layouts cleanly.
Most ALSA drivers export 7.1 in a way compatible to our expectations,
but Intel HDA/HDMI does not:

mpv/ffmpeg:   fl-fr-fc-lfe-bl-br-sl-sr
ALSA/generic: FL FR FC LFE RL RR SL  SR  [1]
ALSA/HDMI:    FL FR LFE FC RL RR RLC RRC [2]

The HDMI layout is layout 0x13 (going by CEA-861-B). The comment in
the kernel code has to be correct too. The early standard defines only
1 other layout, which replaces RLC/RRC with FRC/FLC - this probably
corresponds to what we call "7.1(wide)".

So it appears when ALSA requests RLC/RRC, we should feed it sl/sr.

To make it more complicated, Kodi/xbmc apparently also have to deal with
ALSA being special, but instead of sending sl/sr to RLC/RRC, they swap
the last two pairs of the layout, and send sl/sr to RL/RR and bl/br to
RLC/RRC. Or I might have misunderstood their code. I don't have a
7.1-capable A/V receiver, so I can't test this.

For now, go with the simpler solution, and wait until someone tests it.
If the speakers end up swapped, a completely different solution will be
needed.

[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/sound/core/pcm_lib.c?id=refs/tags/v4.3#n2434
[2] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/sound/pci/hda/patch_hdmi.c?id=refs/tags/v4.3#n307
2015-11-03 00:28:00 +01:00
wm4 9d4aff8ac7 ao_alsa: minor cleanups 2015-11-03 00:23:28 +01:00
wm4 e162a5bf04 ao_alsa: simplify dmix non-NA hack
There's really no need to do this deep in the chmap sslection code. This
will setup the device further than before, but that doesn't matter.
2015-11-03 00:23:28 +01:00
wm4 8d415b2e01 ao_alsa: move channel map setting code out of main init function
This grew way too large.
2015-11-03 00:23:28 +01:00
wm4 d634394da6 ao_alsa: make failure of buffer parameter setting non-fatal
These calls actually can leave the ALSA configuration space empty (how
very useful), which is why snd_pcm_hw_params() can fail. An earlier
change intended to make this non-fatal, but it didn't work for this
reason.

Backup the old parameters, so we can retry with the non-empty
configuration space. (It has to be non-empty, because the previous
setters didn't fail.)

Note that the buffer settings are not very important to us. They're
a leftover from MPlayer, which needed to write enough data to the
audio device to not underrun while decoding and displaying a video
frame. In mpv, most of these things happen asynchronously, _and_
there is a dedicated thread just for feeding the audio device, so
we should be pretty imune even against extreme buffer settings. But
I suppose it's still useful to prevent PulseAudio from making the
buffer too large, so still keep this code.
2015-11-03 00:23:28 +01:00
wm4 609de236a9 ao_alsa: disable resampling first thing
Again, this could have bad access, is unlikely, and has no bad
consequences. It's noteworthy that vlc and the ALSA PCM example both do
this first, even if they set the sample rate later.
2015-11-03 00:23:28 +01:00
wm4 3f0d831af0 ao_alsa: set access type before format
I'm worried that not restricting the access type before restricting the
format will cause problems. While it's unlikely, it might prevent
failures in some corner cases. Also, since we by default always use
interleaved access (buggy ALSA plugins), this will have no effects at
all.
2015-11-03 00:23:28 +01:00
wm4 587bb5e811 ao_alsa: handle channel count mismatch safeguard after chmap negotiation
If the API doesn't list padded channel maps, but the final device
channel map is padded, and if unpadded output is not possible (unlike in
the somewhat similar dmix case), then we shouldn't apply the channel
count mismatch fallback in the beginning. Do it after channel map
negotiation instead.
2015-11-03 00:23:28 +01:00
wm4 c2220c526d ao_alsa: apply non-NA fallback only if input is stereo
Doesn't matter much; effectively this prevents just log spam in some
cases where the map is legitimately padded. Normally this is really
only needed for the dmix ALSA case. (See git blame for details.)
2015-11-03 00:23:28 +01:00
wm4 b58e4abc01 ao_alsa: treat SND_CHMAP_UNKNOWN as NA channel too
Apparently required by nVidia HDMI. It should not be, and NA would
definitely be more correct here, so this could be considered a driver
bug. Maybe.
2015-11-03 00:23:28 +01:00
wm4 3fb161ecd2 ao_alsa: remove log message on pausing
This was annoying.
2015-11-03 00:23:27 +01:00
wm4 1d2d649281 vdpau: fix uninit when init fails
The uninit() function was called twice if the uninit() function failed
(once by init(), once by vd_lavc.c code), which caused crashes due to
double-free. (This failure is a corner case, and all other hwdec
backends appear to handle this case gracefully.)

I do not think this code should be able to deal with uninit() being
called other than once. Guarantee that it's called exactly once.
2015-11-01 23:03:02 +01:00
wm4 8e8b420c9d vo_opengl: win32: fix cross-compilation
MXE uses an all-lowercase convention for MS headers.
2015-11-01 21:50:41 +01:00
wm4 9de8730dc9 vo_opengl: win32: always request MMCSS for DWM
Quoting MSDN: "Notifies the Desktop Window Manager (DWM) to opt in to or
out of Multimedia Class Schedule Service (MMCSS) scheduling while the
calling process is alive.". Whatever this means. (An application can
change the scheduling priority of the window manager?)

Does this improve anything? I have no idea. Certainly this is a program
that does multimedia and graphics, so we seem to be a good match for
this.

Is it bad if we enable this even while playback is inactive or paused? I
have no idea either.

Is there a magic cargo cult function that will mark our renderer thread
as multimedia thing? I have no idea. (We use a function to enable MMCSS
for our audio thread in ao_wasapi.)
2015-11-01 20:50:41 +01:00
wm4 30a6106477 vo_opengl: win32: try to enable DwmFlush by default
Enable it by default, but not unconditionally. Add an "auto" mode, which
disable DwmFlush if the compositor is (probably) inactive. Let's see how
this goes.

Since I accidentally enabled DwmFlush always by default (more or less)
in a previous commit touching this code, this is probably mostly just
cargo-culting, and it's uncertain whether it does anything.

Note that I still got bad vsync behavior when fullscreening mpv, and
making another window visible on the same screen. This happens even if
forcing DWM.
2015-11-01 20:47:57 +01:00
wm4 f1e767b6a2 player: another fix to A/V difference calculation in display-sync mode
update_av_diff() works on the timestamps, while time_left is in real
time. When playing at not-1 speed, these are very different, and cause
the A/V difference to jitter. Fix this by scaling the expected A/V
desync to the correct range.
2015-11-01 19:53:48 +01:00
wm4 8581835161 vo: fix no-audio mode with interpolation enabled/display-sync disabled
Commit acd5816a broke this. It was stopping playback occasionally.
Another case where the non-display-sync interpolation mode
(in->vsync_timed==true) is causing a lot of subtle issues and will be
removed soon.
2015-11-01 14:19:22 +01:00
wm4 cdeb0e4c72 video: fix playback of pal8
PAL8 is the only format that is RGB, has only 1 component, is byte-
aligned. It was accidentally detected by the GBRP case as planar RGB.
(It would have been ok if it were gray; what ruins it is that it's
actually paletted, and the color values do not correspond to colors (but
palette entries).

Pseudo-pal formats are ok; in fact AV_PIX_FMT_GRAY is rightfully marked
as MP_IMGFLAG_YUV_P.
2015-11-01 14:11:43 +01:00
wm4 8fd63c8f0c video: fix another A/V difference bug in display-sync mode
This didn't show up with cases where the frame pattern has a cycle of 1
or 2 like it is the case with 24-on-24 fps, or 24-on-60 fps. It did show
up with 25-on-60 fps. (We don't slow down 25 fps video to 24 on default
settings.)

In this case, we must not add the timing error of the next frame to the
A/V difference estimation of the current frame. Use the previous timing
error instead.

This is another bug resulting from the confusion about whether we
calculate parameters for the currently playing frame, or the one we're
about to queue.
2015-10-31 13:21:16 +01:00
wm4 b92fd602ce vo_direct3d: fix operation
Regression since commit 93db4233. I think the bit that was forgotten
here was to remove the vo_w32_config() return value completely. The VO
failed to init because that function always returned 0. This commit
removes these bits and fixes the VO.

Fixes #2434.
2015-10-31 12:52:02 +01:00
Evgeny Kolesnikov 7984d25ceb SVG version of the icon (with symbolic counterpart) 2015-10-30 20:29:55 +01:00
wm4 2b6241a09a vo_opengl: add vsync-fences option
Yet another relatively useless option that tries to make OpenGL's sync
behavior somewhat sane. The results are not too encouraging. With a
value of 1, vsync jitter is gone on nVidia, but there are frame drops
(less than with glfinish). With 2, I get the usual vsync jitter _and_
frame drops.

There's still some hope that it might prevent too deep queuing with some
GPUs, I guess.

The timeout for the wait call is 1 second. The value is pretty
arbitrary; it should just not be too high to freeze the process (if
the GPU is un-nice), and not too low to trigger the timeout in normal
cases, even if the GPU load is very high. So I guess 1 second is ok
as a timeout.

The idea to use fences this way to control the queue depth was stolen
from RetroArch:

https://github.com/libretro/RetroArch/blob/df01279cf318e7ec90ace039d60515296e3de908/gfx/drivers/gl.c#L1856
2015-10-30 20:26:51 +01:00
wm4 93f748e77f vo_opengl: cosmetics: flip the order of 2 functions
draw_frame() is called first, then flip_page(). Order them in the order
they're called.
2015-10-30 20:26:43 +01:00
rr- 7c6d7017bd vo_drm: uninstall signal handlers after quitting 2015-10-30 20:26:37 +01:00
rr- 344b65c4db vo_drm: handle possible errors from sigaction 2015-10-30 20:26:37 +01:00
rr- 03cf69f0a8 vo_drm: check if signal already used 2015-10-30 20:26:37 +01:00
wm4 05e39ec513 stream/audio: fix unchecked strdups
See #2435. It's literally a waste of time trying to fix minor memory
leaks in this old, unused, and crappy code.
2015-10-30 15:51:26 +01:00
wm4 7aba3a5d96 command: add mistimed-frame-count property
Does what the manpage says. This is a replacement incrementing the
dropped frame counter (see previous commit).
2015-10-30 14:05:41 +01:00
wm4 acd5816a6d video: fix framedrop accounting in display-sync mode
Commit a1315c76 broke this slightly. Frame drops got counted multiple
times, and also vo.c was actually trying to "render" the dropped frame
over and over again (normally not a problem, since frames are always
queued "tightly" in display-sync mode, but could have caused 100% CPU
usage in some rare corner cases).

Do not repeat already dropped frames, but still treat new frames with
num_vsyncs==0 as dropped frames. Also, strictly count dropped frames in
the VO. This means we don't count "soft" dropped frames anymore (frames
that are shown, but for fewer vsyncs than intended). This will be
adjusted in the next commit.
2015-10-30 13:26:55 +01:00
wm4 8737732035 vo_opengl: cache frames only in display-sync mode
vo_frame.num_vsyncs can be != 1 in some cases in normal sync mode too.
This is not a very exact fix, but in exchange it's robust. (These
vo_frame flags are way too tricky in combination with redrawing and
such.)
2015-10-30 12:53:43 +01:00
wm4 67aab3a9f6 vo_opengl: do not attempt to cache frames in FBO in dumb-mode
There were occasional shader compilation and rendering failures if FBOs
were unavailable. This is caused by the FBO caching code getting active,
even though FBOs are unavailable (i.e. dumb-mode).

Boken by commit 97fc4f.

Fixes #2432.
2015-10-30 12:49:12 +01:00
wm4 8eb7cb28f9 manpage: briefly mention libmpv 2015-10-30 09:49:16 +01:00
wm4 3dec68ba47 vd_lavc: fix declarations
Fixes linker failure. How did this ever work? Apparently it did most of
the time, but apparently we just got the first case where it didn't.

Fixes #2433.
2015-10-30 09:41:55 +01:00
wm4 d5b8d77a17 manpage: extend profile documentation 2015-10-29 22:17:51 +01:00
wm4 a1315c7644 vo: take normal drop path when dropping in display-sync mode
I hope there wasn't a deeper reason for exiting early.
2015-10-29 22:17:43 +01:00
Paul B Mahol 532f05b83d vo_drm: show osd in audio only mode
Signed-off-by: Paul B Mahol <onemda@gmail.com>
2015-10-29 12:59:13 +01:00
Martin Herkt 5b7d0fbab3 Release 0.12.0 2015-10-29 03:49:43 +01:00
Martin Herkt ec567d8a77 Merge branch 'master' into release/current 2015-10-29 02:56:49 +01:00
wm4 33489feca8 player: raise display sync desync tolerance
Bump it to 80, and 2 vsyncs. This is another measure against vsync
jitter. Admittedly this is a bit simplistic (and we should probably
estimate a stable estimated vsync phase instead), but for now this will
do.
2015-10-28 23:57:27 +01:00
wm4 ce82d88215 player: reset AO stats on pause and other discontinuities
It's annoying.
2015-10-28 23:57:24 +01:00
wm4 d1ad0815fe player: simplify display-adrop mode safeguard
It's not needed, because the additional data is not appended, but is the
total size of the audio buffer. The maximum size is the static audio
drop size (or twice, if the audio is duplicated).
2015-10-28 23:57:24 +01:00
wm4 fc3f1e7c54 player: minor refactor for A/V diff computation
Calculate the A/V difference directly in the display sync code, instead
of the awkward current way, which reuses the fields for audio sync.

We still set time_frame, because it makes falling back to audio sync
somewhat smoother.
2015-10-28 23:57:24 +01:00
wm4 466658ee7e player: fix display sync A/V difference estimation on drops
When dropping or repeating frames, we essentially influence when the
frame after the next frame will be shown, not the next frame. This led
to dropping/repeating frames 2 times, because the A/V difference had a
delay of one frame. Compensate it with the expected value.
2015-10-28 23:57:24 +01:00
wm4 cf18922d19 sub: remove use of semi-deprecated libass field
In newer libass version, this does nothing, and will be removed on the
next API/ABI bump.
2015-10-28 23:49:13 +01:00
wm4 3c081dfd93 Replace deprecated av_free_packet() calls
av_free_packet() got finally deprecated. Use av_packet_unref() instead,
which has almost the same semantics, has existed for a while, and is
available in all FFmpeg and Libav versions we support.
2015-10-28 23:48:56 +01:00
wm4 a135c9cffc demux_mkv: fix cluster skip with duration probing
The start time probing essentially broke it.
2015-10-27 20:57:11 +01:00
wm4 f891b24cb5 vo: kill non-working missed frame detection
This was not very reliable.

In the normal vo_opengl case, this didn't deal well enough with vsync
jitter. Vsync timings can jitter quite extremely, up to a whole vsync
duration, in which case the "missed" frame counter keeps growing, even
though nothing is wrong. This behavior also messes up the A/V difference
calculation, but as long as it's within tolerance, it won't provoke
extra frame dropping/repeating. Real misses are harder to detect, and I
might add such detection later.

In the vo_opengl_cb case, this was additionally broken due to the
asynchronity between renderer and VO threads.
2015-10-27 20:57:04 +01:00
wm4 70aa3b04f8 player: disable total-avsync-change update in display-sync mode
The total-avsync-change property made no sense in display-sync mode (in
addition to making not all that much sense in general).
2015-10-27 20:56:58 +01:00
wm4 c24921d56b player: fix display-sync A/V calculation on high playback speeds
This is all kinds of stupid - update_avsync_after_frame() will multiply
this value with the speed at a later point, and we only update this
field for this function. (This should be refactored.)
2015-10-27 20:56:49 +01:00
wm4 aaec2aba38 player: add audio drop/duplicate mode
Not very robust in the moment.
2015-10-27 20:56:46 +01:00
wm4 3b95dd47d5 player: simplify audio sync pts calculation
This was done for symmetry with adjust_sync(). But mpctx->delay is
always 0 at this point, so prefer slightly simpler code.
2015-10-27 20:56:39 +01:00
wm4 555ecbb70e demux_mkv: fix duration probing for files with non-0 start time
When using --demuxer-mkv-probe-video-duration=full and the file did not
start at timestamp 0, the reported duration was still wrong.
2015-10-26 18:21:31 +01:00
wm4 919707efb7 ao_coreaudio_exclusive: check for maximum channel count
Until recently, the channel layout code happened to catch this, but now
an explicit check is needed. Otherwise, it'd try to pad the missing
channels with NA in the channel map fallback code.
2015-10-26 16:00:24 +01:00
wm4 c1de8cdc38 client API: change error string if playback fails completely
It can print this if AO/VO initialization fails, which makes the wording
a lie. Change it to something more diplomatically safe.
2015-10-26 15:55:40 +01:00
wm4 0cc440f291 ao_coreaudio_exclusive: fallback to stereo on unknown channel layouts
This is intended for the case when CoreAudio returns only unknown
channel layouts, or no channel layout matches the number of channels the
CoreAudio device forces. Assume that outputting stereo or mono to the
first channels is safe, and that it's better than outputting nothing.

It's notable that XBMC/kodi falls back to a static channel layout in
this case. For some messed up reason, the layout it uses happens to
match with the channel order in ALSA's/mpv's "7.1(alsa)" layout.
2015-10-26 15:55:11 +01:00
wm4 0524907c18 ao_coreaudio_chmap: minor refactor
Share some code between ca_init_chmap() and ca_get_active_chmap(), which
also makes it look slightly nicer. No functional changes, other than the
additional log message.
2015-10-26 15:55:01 +01:00
wm4 c971fefd41 ao_coreaudio_chmap: allow stereo as fallback; avoid mono fallback
If no channel layouts were determined (which can actually happen with
some "strange" devices), the selection code was falling back to mono,
because mono is always added as a fallback. This doesn't seem quite
right.

Allow a fallback to stereo too, if no channel layout could be retrieved
at all. So we always assume that mono and stereo work, if no other
layouts are available.

(I still don't know what the CoreAudio stereo layout is supposed to do.
It could be used to swap left and right channels. It could also be used
to pad/move the channels, but I have never seen that. And it can be set
to non-stereo channels, which breaks mpv. Whatever.)
2015-10-26 15:54:45 +01:00
wm4 9ed289ef90 ao_coreaudio: fix another minor memory leak
How stupid, even the cleanup gotos were already there.
2015-10-26 15:54:36 +01:00
wm4 f3a003e550 audio: bump maximum number of channels to 16
The main reason is that ao_coreaudio_exclusive needs this for some OSX
devices. They want packed audio, and special-casing this in the
coreaudio code would be too much of a pain.

The maximum of channels we can support is 64 (because FFmpeg uses 64 bit
masks for channel layouts), but since struct mp_audio can get pretty
big (has static allocations of 2 pointers for each channel for planar
mode), it's less wasteful to stay lower for now.
2015-10-26 15:54:19 +01:00
wm4 48c2e9d67d audio: use AVFrames with more than 8 channels correctly
Requires messy dealing with the extended_ fields.

Don't bother with af_lavfi and ao_lavc for now. There are probably no
valid use-cases for these.
2015-10-26 15:54:00 +01:00
wm4 0ffaf653a2 af_lavrresample: make planarization pass work with >8 channels
av_get_default_channel_layout() fails with channel counts larger than 8.
The channel layout doesn't need to make sense, so pick an arbitrary
fallback.

libswresample also has options for setting the channel counts directly,
but better not introduce new concepts in the code. Also, libavresample
doesn't have these options.
2015-10-26 15:53:47 +01:00
wm4 76d1b430b0 audio: improve mp_chmap_to_lavc_unchecked() unknown chmap behavior
Change it so that it will always return a bitmask with the correct
number of channels set if an unknown channel map is passed. This didn't
work for channel counts larger than 8, as there are not any standard
channel layouts defined with more than 8 channels (both in mpv and
FFmpeg). Instead, it returned 0.

This will help when raising the maximum allowed channel count in mpv.
Some code in af_lavrresample relies on it, more or less.

One change is that unknown channel maps won't result in lavc standard
channel layouts anymore, just a set of random speakers. This should be
fine, as the caller of mp_chmap_to_lavc_unchecked() should handle these
cases. For mp_chmap_reorder_to_lavc() this is not so clear anymore, but
should also be ok.

For normal channel maps, simply dropping NA channels is still the
correct and wanted behavior.

Currently, the mpv maximum channel count is 8. This commit is
preparation for raising this limit.
2015-10-26 15:52:21 +01:00
wm4 ec27d573f4 audio: always log channel maps before determining final map
Until now, this was done only in debug verbosity, while some AOs logged
equivalent information in verbose mode. Clean this up.
2015-10-26 15:52:08 +01:00
wm4 72d3c5ef00 ao_coreaudio: fix potential UB in error cases
mNumberChannelDescriptions being 0 is pretty much an error, but if it
can happen, then the code checking the chmap below will trigger UB, as
chmap is not initialized at all.

Also, simplify the code a little: we never change the number of
channels, so this is just fine.
2015-10-26 15:51:59 +01:00
wm4 81109dcbb6 ao_coreaudio_chmap: add more logging 2015-10-26 15:51:50 +01:00
wm4 fa510bd00c af: prevent endless loop when removing filters due to spdif
This code removes filters which can not take spdif inout. This was made
so that PCM filters are transparently dropped in spdif mode.

This entered an endless loop with:

   --af=lavcac3enc:::2 --audio-channels=5.1

The forced number of output channels is incompatible with spdif. It's
trying to insert af_lavrresample as conversion filter to compensate for
it. Of course this doesn't work, which triggers the PCM filter removal.
Then it goes on normally - since the new state is exactly as before, it
will try the same thing again, forever.

Fix by reusing the retry counter, which is a very dumb but very
effective measure against these cases of filter negotiation failure. We
could try to be more clever (for example, if the removed filter is a
conversion filter, we can be sure this won't work, and error out
immediately). But better keep it simple and robust.
2015-10-26 15:51:26 +01:00
wm4 c21c26472c ao_alsa: log format probing in verbose mode
And also remove a redundant log message. (We can tell from the following
probe or error message whether or not the format test is successful.)
2015-10-25 20:09:38 +01:00
Rodger Combs d6e7190836 vd_lavc: make software decoding fallback an option 2015-10-25 15:21:11 +01:00
wm4 d1a46c2c32 options: remove --use-text-osd 2015-10-24 19:09:35 +02:00
Ricardo Constantino a02f3a5dd4 ytdl: disable --all-subs if "sub-lang" is in raw-options
Defaults stay the same (--all-subs is used if sub-lang wasn't used.)
Don't forget to also add "write-sub=" if using sub-lang or else it won't
work.
2015-10-24 17:30:22 +02:00
Bin Jin 17b4fb02b3 vo_opengl: remove source shader leftover
The source shader was removed after deband was introduced.
2015-10-24 17:11:02 +02:00
wm4 252dcdcc99 sd_lavc: take care of AVPicture deprecation 2015-10-23 20:14:08 +02:00
Niklas Haas 97fc4f4a85 vo_opengl: always cache to an FBO when not interpolating
This speeds up redraws considerably (improving eg. <60 Hz material on a 60 Hz
monitor with display-sync active, or redraws while paused), but slightly
slows down the worst case (eg. video FPS = display FPS).
2015-10-23 19:51:20 +02:00
Niklas Haas ad6e7c31df vo: expose frame->num_vsyncs to the VO backend
It's not clear why this was originally hidden, but the information is
useful for allowing the VO backend to make decisions about caching.
2015-10-23 19:51:20 +02:00
James Ross-Gowan bf6b981367 w32_common: disable IME
The IME is not useful for key-bindings. Handle the base ASCII chars
instead and don't show the IME window. For the sake of libmpv users, the
IME should only be disabled on mpv's GUI thread and not application-
wide.

No IME on the GUI thread should also mean that VK_PROCESSKEY will never
have to be handled, so the logic for that can be removed as well.
2015-10-23 17:55:47 +02:00
wm4 72ded5ccef vo_opengl: wayland: use a more standard symbol
They're the same, but EGL_CONTEXT_MAJOR_VERSION_KHR technically is an
extension, while EGL_CONTEXT_CLIENT_VERSION is the standardized alias.
2015-10-23 16:09:58 +02:00
wm4 0344abd67a vo_opengl: vaapi: fix compilation failure on older systems
Older systems have certain EGL extension definitions missing. We
redefine them to make the build system easier, and because it's trivial.
But we forgot to define the EGL_LINUX_DMA_BUF_EXT identifier. (I hope
it's the only missing one.)
2015-10-23 15:56:17 +02:00
wm4 56fefde7e2 command: make bitrate properties work correctly for external tracks 2015-10-23 14:58:01 +02:00
wm4 955c6843b6 command: do not return 0 for bitrates if unknown
This makes the bitrate properties unavailable, instead of
returning 0 when:

1. No track is selected, or
2. Not enough packets have been read to have a bitrate estimate yet
2015-10-23 14:53:19 +02:00
wm4 d1528e51d5 player: offset chapter display by start time
Some mkv files can have this. The chapter times are still timestamps
(and thus not affected by the start time), but it misplaces the OSD
chapter ticks.
2015-10-23 12:14:17 +02:00
wm4 53c720d412 vo_opengl_cb: fix passing through some video equalizer properties
The equalizer code as it exists in vo_opengl works perfectly fine. The
situation in vo_opengl_cb is pretty different. The playback thread can't
communicate with the renderer thread synchronously (essentially to give
the API user more flexibility). So the equalizer communication has to be
done in an asynchronous way too.

There were two problems. First, the eq capabilities can change with the
pixel format, and the renderer initializes them on config only. This
means equalizers were disabled on the first config run, and options like
--video-output-levels or --brightness would not work. So we just
initialize the caps with a known superset. The player will not correctly
indicate when setting an eq doesn't work, but we're fine with it, as it
is a relatively cosmetic issue.

Second, it copied back the eq settings in the "wrong" moment (what
for?), which overwrote the settings in some cases.

Third, the eq was not reset correctly on vo init. This is needed to make
it behave the same as vo_opengl.
2015-10-23 12:09:14 +02:00
wm4 878f12885b client API: fix typo and wording in a comment 2015-10-22 19:36:38 +02:00
wm4 0a1a5707bf demux: cosmetics: remove indirection
Let's not waste precious lines.
2015-10-22 01:26:34 +02:00
wm4 dd08018e9e sub: adjust behavior on mismatching video/subtitle aspect mismatch
If the aspect ratio of the video resolution and the subtitle resolution
(the implied subtitle coordinate system) mismatch, the subtitles
obviously can't be overlayed over the video perfectly. Either you get
video that can't be covered by subtitles, or the subtitles could go
beyond the video. We don't want to stretch the subtitle to compensate
for the aspect ratio, because it would look terrible.

Until now, mpv used to fit the subtitle rectangle into the video
rectangle (letterboxing/pillarboxing). This looks odd with some sample
files with subtitle canvas being wider than the video. Also, mpc-hc
displays them in a better way. vlc stretches them, which looks bad.
While you probably can't win this game with all those broken files
around, pick the mpc-hc method to handle this.
2015-10-21 23:07:39 +02:00
wm4 56d04c6570 input: rename recently added HALF_SPACE
There was a complaint that the naming is inaccurate. That's probably
right. Just use the official name instead, which is a bit clunky, but
surely correct.
2015-10-21 22:25:30 +02:00
wm4 96eb480299 ao_coreaudio_exclusive: fix build
"Let's apply cosmetic last minute changes without testing them."
2015-10-21 22:18:41 +02:00
wm4 14bb3d06a2 input: add key name for U+3000 IDEOGRAPHIC SPACE
Deserves its own name, because just like SPACE it's a printable
character, but invisible.

Fixes #2349... I think.
2015-10-21 21:57:59 +02:00
wm4 1a1ac76d2a sd_lavc: extend subtitle resolution if images go outside
Helps with broken vobsubs, which have an incorrect resolution header
set.

So we just extend the subtitle resolution to the video size, if the
video size is larger. This helps somewhat with readability, or makes
them visible at all. It should be a pretty safe change, because normally
no sub pictures are supposed to go outside of the area. It should make a
difference with broken files only.

The sample in question had a video resolution of 1888x1072, and a
subtitle resolution of 720x480. Note that always using video resolution
as subtitle resolution would break other files.
2015-10-21 21:33:02 +02:00
wm4 d93a9be656 ao_coreaudio: do not accept unknown channel layouts
Coreaudio gives us a channel map with all entries set to
kAudioChannelLabel_Unknown. This is translated to a mpv channel map with
all channels set to NA, which has special meaning: it's an "unknown"
channel map, which acts as wildcard and can be converted from/to any
channel layout. Not really what we want.

I've got this with USB audio, playing stereo. The multichannel layout
consisted of 2 unknown channels, while the stereo channel map was
stereo (as expected).

Note that channel maps with _some_ NA entries are not affected by this,
and must still work.
2015-10-21 18:57:03 +02:00
wm4 dda16ee1fb ao_coreaudio_exclusive: deal with devices return different channel count
If the device returns an unexpected number of channels instead of the
requested count on init, don't immediately error out. Instead, look if
there's a channel map with the given number of channels.

If there isn't, still error out, because we don't want to guess the
channel layout.
2015-10-21 18:54:48 +02:00
wm4 78112c8582 ao_coreaudio: avoid unnecessary format changes
Not particularly important; just being nice and potentially avoiding
problems caused by format setting.
2015-10-21 18:54:36 +02:00
wm4 ff778f6d68 ao_coreaudio: log current format before setting new format 2015-10-21 18:53:50 +02:00
wm4 cee9aeaf6b ao_coreaudio: fix some minor memory leaks 2015-10-21 18:53:34 +02:00
Niklas Haas eb66038d4f vo_opengl: make the default debanding settings less excessive
It's great that the new algorithm supports multiple placebo iterations
and all, but it's really not necessary and hurts performance in the
general case for the sake of the 0.1% that actually pause the screen
and look for minute differences.

Signed-off-by: wm4 <wm4@nowhere>
2015-10-21 11:32:31 +02:00
Joschka Tillmanns 1ee8ce75f1 options: add support for client certificate authentication
Client certificates are supported by ffmpeg as documented here:

  > https://www.ffmpeg.org/ffmpeg-protocols.html#tls

Signed-off-by: wm4 <wm4@nowhere>
2015-10-20 22:55:27 +02:00
bitingsock 0121d00478 TOOLS/autoload: avoid throwing an error when playing e.g. youtube
Signed-off-by: wm4 <wm4@nowhere>
2015-10-20 12:33:57 +02:00
wm4 e157d005ba ao_coreaudio: raise timeout for change-physical-format
Reportedly fixes operation with "USB connected Parasound ZDAC v.2". (OSX
and USB audio sure is not nice at all.)

This might be perceived as hang by some users, so it's quite possible
that this will have to be adjusted again somehow.

Fixes #2409.
2015-10-20 00:25:34 +02:00
Ricardo Vieira 251107076b Revert "vo_wayland: define opaque region"
This reverts commit c10fb4ce9f.

This is already done in vo_wayland.c:resize,324 doing it here makes the window bigger before the video resizes showing a black area while dragging the border.
2015-10-20 00:15:07 +02:00
wm4 750c29766f player: be slightly less prone to framedrop in display sync mode
1 to 2 frames desync is still tolerable, and will be quickly compensated
(if everything works).
2015-10-19 23:45:43 +02:00
wm4 b0b67cdf5d player: do not use copysign()
Apparently this function caused weird problems to me. I have no idea
why. The usage of the function looks perfectly fine to me, and even
rounding issues can be excluded. In any case, getting rid of this solved
my problem, and makes the code actually more readable.
2015-10-19 23:44:50 +02:00
wm4 50f8548b2f vd_lavc: attempt to fallback from hwdec before anything is decoded
The previous commit moved the av_frame_unref() after the got_picture
check. This accidentally also deferred the software fallback
reinitialization to until a software picture was decoded (instead of the
exact time of the fallback), which is not ideal.

Just rely on the fact that calling av_frame_unref() on a frame is ok
even if nothing was decoded.
2015-10-19 18:19:57 +02:00
wm4 0ab6031d76 vd_lavc: continue decoding properly after decoding failure
Commit 12cd48a8 started setting the hwdec_failed field even if hwdec was
not active, and because it also checked this field even if hwdec was not
active, broke decoding forever.

Fix this, and also avoid a memory leak or API misuse by releasing the
decoded picture. Passing an unreleased frame to the decoder has as far
as I know no defined effects.
2015-10-19 17:49:30 +02:00
wm4 667b968939 demux_lavf: always copy codec headers
If this is not done, libavformat could change the headers while
demuxing, all while the decoder thread reads these fields during
initialization.
2015-10-19 15:27:42 +02:00
wm4 e1128c8b28 video: pass through libavformat has_b_frames field
This fixes initial decoding of some samples. See #1341.

According to Libav devs, this should be considered a libavcodec bug, but
as it's hard to fix, here we go.
2015-10-19 15:00:21 +02:00
wm4 e3de309804 vo_opengl: support all kinds of GBRP formats
Adds support for AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12,
AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP, and
AV_PIX_FMT_GBRAP16.

(Not that it matters, because nobody uses these anyway.)
2015-10-18 18:37:24 +02:00
wm4 9ca312b4b1 demux: remove demux_add_packet() return value 2015-10-17 14:27:55 +02:00
wm4 d27d91715f build: remove explicit checks for VPP
This was once done when old versions of libva without VPP had to be
supported. Some parts of it were removed earlier already.
2015-10-17 14:25:09 +02:00
wm4 0eb45343ca vaapi: drop non-existing FourCC
This VA_FOURCC isn't even defined by latest drivers, so I'm just
assuming it doesn't exist and never existed. For planar 4:2:0,
VA_FOURCC_YV12 is normally preferred, and there's even a VA_FOURCC_IYUV
for 4:2:0 with unswapped planes.
2015-10-17 14:20:53 +02:00
wm4 7e7ef2f01d build: bump required libva version
0.34 and 0.35 don't have the buffer API, such as vaAcquireBufferHandle.
This is only needed for the EGL interop, but why bother staying
compatible for such old things (0.36 was released over a year ago).

We also can drop some minor compatibility ifdeffery.
2015-10-17 14:17:49 +02:00
wm4 76bfd5b4a2 demux_mkv: probe start time
MKV files can very well start with timestamps other than 0. While mpv
has support for such files in general, and demux_lavf enables this
feature, demux_mkv didn't export a start time.

Implement this by simply reading the first cluster timestamp. This in
turn is done by reading 1 block. While we don't need the block for this
prupose at all, it's the easiest way to get the cluster timestamp read
correctly without code duplication. In theory this could be wrong, and
a packet could start at a much later time, but in practice this won't
happen.

This commit also adds an option to disable this feature. It's not
documented because nobody should use it. (But I happen to have a need
for this.)
2015-10-16 17:11:44 +02:00
wm4 8d414e2fe7 command: make time properties unavailable if timestamp is unknown
Let's hope this doesn't confuse client API users too much. It's still
the best solution to get rid of corner cases where it actually return
the wrong timestamp on start, and then suddenly jump.
2015-10-16 16:16:10 +02:00
wm4 2483dab54d TOOLS/stats-conv: rewrite for pygtgraph
matplotlib is pathetically slow, which makes using stats-conv.py to view
dumps longer than a few seconds a huge pain.

pyqtgraph is slightly faster than matplotlib. Other than that, it seems
to be worse in every aspect (at least for plotting), but such is life.
2015-10-15 23:07:03 +02:00
wm4 3a7a2385df vo_opengl_cb: fix pausing and seeking if interpolation is enabled
When seeking, the current frame will have the wrong timestamp, until the
seek is done and a new frame from the seek target is shown. We still use
the "old" frame for redrawing during seeks. This frame has to be
explicitly marked with still=true in order not to confuse the
interpolation queue. If this is not done, it will ignore frames until a
frame with approximately the same timestamp as the "old" frame is
reached. (Does this mean interpolation handles timestamp resets
incorrectly? I have no idea.)

Of course we also have to clear possibly queued frames on seeks.

Also, in pausing, explicitly let the frame redraw.
2015-10-14 20:38:30 +02:00
wm4 3274fabeb3 player: fix an adjustment in display sync mode
This adjustment is supposed to improve the audio speed calculation in
case of unexpected desync. The flipped sign made it actually worse,
although the total impact of this bug was very minor.
2015-10-14 18:53:00 +02:00
wm4 e0f8d79772 af_lavrresample: fix unintended audio drift when setting playback speed
Small adjustments to the playback speed use swr_set_compensation()
to stretch the audio as it is required. But since large adjustments
are now handled by actually reinitializing libswresample, the small
adjustments get rounded off completely with typical frame sizes.

Compensate for this by accounting for the rounding error and keeping
track of fractional samples that should have been output to achieve
the correct ratio.

This fixes display sync mode behavior, which requires these adjustments
to be relatively accurate.
2015-10-14 18:51:12 +02:00
wm4 da496ae2fe msg: remove the useless trailing comment from stats dumping
The origin of the stats line was added as a comment (starting with '#').
It was useless and just blowing up file sizes.
2015-10-14 18:50:58 +02:00
wm4 184426175f player: fix inverted condition
Simple oversight which made it not work at all.

How did this ever work, and if it was never tested, then why did it work
when fixing this oversight?
2015-10-13 22:09:13 +02:00
wm4 1f9c4f19cf vo_opengl: x11egl: fix confused error status codes
This is all kinds of wonderfully stupid.
2015-10-12 22:10:11 +02:00
wm4 8b291aff96 vo_opengl: x11egl: reject nvidia drivers when autoprobing
Newer nVidia drivers support EGL, but they seem to work badly,
apparently don't support some needed features or not in a form we want
(such as swap control), and vdpau interop is not available. Disable it
by default, because I'm tired of explaining this issue.

Can be reverted as soon as nVidia release working drivers.
2015-10-12 21:30:13 +02:00
wm4 8d004f07a4 vd_lavc: work around libavcodec nonsense causing hwdec init failure
The libavcodec h264 decoder contains some idiotic code with unknown
purpose (no sample or explanation known that necessitates its
existence), that causes the AVCodecContext.get_format callback to be
invoked at a time when hwaccels can't be initialized. By definition, the
get_format callback is supposed to initialize hwaccels (another idiotic
thing now part of the API, but different story). This causes hwdec
initialization sometimes to fail (WolfensteinTwitch.mp4): the first
get_format callback will mark it as failed, so the second get_format
(the "proper" normal one) will not bother restoring the state, and hwdec
init fails.

While this should be fixed in libavcodec (good luck with that), it's
quite easy to workaround.
2015-10-12 21:24:25 +02:00
wm4 14a2993796 demux_mkv: do not return subtitle packets that end before seek target
This affects the subtitle preroll mode during seeking. It could matter
somewhat with insane files with ten-thousands of subtitle events, which
now seem to pop up, and will avoid packet queue overflow.
2015-10-12 21:19:43 +02:00
wm4 3804376ccc af_lavrresample: reinit resampler on large speed changes
swr/avresample_set_compensation() was made for small speed adjustments.
Non-documentation says it should be used for changes not larger than 1%,
so reinitialize the sampler if the change is larger than that.
2015-10-12 21:12:05 +02:00
ChrisK2 bddd1e9e3b ytdl: Set a proper label for external audio tracks 2015-10-11 20:52:11 +02:00
wm4 9e7069fde2 vd_lavc: refuse to initialize vaapi with unknown profiles
Bad idea, although I'm not sure how harmful it actually was.

Although this is common code, only the vaapi hwaccel still uses it.
2015-10-11 18:48:02 +02:00
wm4 94b6a1054e cocoa: set application policy before creating window
This fixes a regression since commit f4d62da8. The original code run
vo_cocoa_config_window() once without creating the window, which had the
effect that the last part of the function was run at least once before
the actual window was created. Fix the regression by moving it to before
the window is created.

The regression itself is hard to describe. One test case: start mpv from
a fullscreened terminal window. It should switch to another desktop,
with the mpv window visible. This didn't happen anymore.
2015-10-11 16:19:08 +02:00
wm4 d714c8380a DOCS/client_api_examples/README: add qt_opengl
And also adjust the documentation for the other Qt examples to avoid
redundancy.

While we're at it, move the simple example to the top.
2015-10-11 14:18:52 +02:00
wm4 b7ba2e2c57 DOCS/client_api_examples/qt_opengl: fix uninit
mpv_opengl_cb_uninit_gl() still needs the OpenGL context. It makes calls
to free OpenGL objects. Strictly speaking, this is probably unnecessary,
because the OpenGL context is destroyed afterwards (implicitly freeing
all related objects). But mpv_opengl_cb_uninit_gl() does not require the
destruction of the OpenGL context, and thus has to free resources
manually.

It's also true that OpenGL normally simply ignores API calls (or returns
errors) if no context is set, but doing it properly is cleaner.

That makeCurrent() can be called in the destructor is explicitly allowed
and recommended for freeing GL resources in the Qt docs.

This fixes a mpv error message on exit.
2015-10-11 14:11:12 +02:00
wang-bin 52de5ea6ad DOCS/client_api_examples: add qt widget + opengl-cb example 2015-10-11 13:58:09 +02:00
ChrisK2 78caf6ae86 ytdl: Remove DASH hacks, use DASH by default
Thanks to rcombs, ffmpeg now properly supports DASH and we can
remove our hacks for it and use it by default whenever
available. If you don't like this for whatever reason, you
can get the "normal" streams back with --ytdl-format=best .

Closes #579
Closes #1321
Closes #2359
2015-10-11 00:35:35 +02:00
wm4 46c499d02a DOCS/client_api_examples/README: rewrite
The new one is much more detailed.

Also add part of it to the libmpv doxygen.
2015-10-10 15:44:27 +02:00
wm4 dbbde6161d player: fix missed wakeup on video EOF
If video EOF happens during playback restart, and audio is syncing, and
the demuxer packet queue overflows (i.e. no new packets will be read),
then it could happen that the player accidentally enters sleeping, and
continues playing anything only after e.g. user input wakes it up.
2015-10-09 15:53:02 +02:00
wm4 a62dcdd5f4 manpage: font options do not support fontconfig patterns anymore
libass 0.13.0 breaks this due to removal of fontconfig from its core
(instead, fontconfig is one possible backend, and pattern lookup is
apparently not possible anymore).
2015-10-09 00:03:19 +02:00
wm4 f7124be091 audio: add AO deviation logging
Pretty dumb (and doesn't handle pausing or other discontinuities), but
at least somewhat idiot-proof.
2015-10-08 23:20:33 +02:00
wm4 6499224888 vo: log deviation from ideal vsync interval 2015-10-08 22:06:15 +02:00
wm4 252d5b319a demux_subreader: participate in probing only on Libav
FFmpeg supports all formats the old subreader code does, and is better
at it. On the other hand, subreader.c's probing is bad and can lead to
false positives easily.
2015-10-08 19:59:49 +02:00
wm4 280251656c af_lavrresample: use libswsresample dynamic rate adjustment feature
swr_set_compensation() changes the apparent sample rate on the fly (who
would have guessed). It is thus very well-suited for adjusting audio
speed on the fly during playback (like needed by the display-sync mode).
It skips the relatively slow resampler reinitialization.

If this doesn't work (libswresample soxr backend), then fall back to the
old method.
2015-10-07 21:54:45 +02:00
wm4 aa796c23db vo_xv: fix crash with --wid
Fixes #2386.

Reminder that you should not use this crap-VO.
2015-10-07 13:49:29 +02:00
wm4 0a41c6f0ec audio: make spdif re-probe from normal decoding work
The previous commit handled not falling back to normal decoding if the
AO was reloaded (I think...), and this tries to re-engage spdif pass-
through if it was previously falling back to normal decoding (e.g.
because it temporarily switched to an audio device incapable of
passthrough).
2015-10-06 20:21:29 +02:00
wm4 66aa54d319 audio: re-probe spdif if AO is reloaded
Makes the spdif automagic work better on audio hotplugging.
2015-10-06 19:59:02 +02:00
wm4 288eaacd85 demux: don't attempt to open a demuxer after abort signal was given
demux_open() kept trying to fallback to other demuxers when opening was
cancelled. This was not really a problem, but it was stupid.
2015-10-06 18:19:20 +02:00
wm4 ecb776f88e player: make stop command actually stop
The stop command didn't always stop. In this case, opening a HLS URL and
then sending "stop" during loading would actually make it fallback to
parsing it as a playlist, and then continued to play the playlist items.
(This corner case makes several unfortunate factors come together to
produce this really odd behavior.)

Another issue is that the "stop" was not always explicitly set. This
could be a problem when sending several commands at once. Only the
"quit" command should have priority over the "stop" command, so this is
still checked.
2015-10-06 18:19:20 +02:00
wm4 1c593f1497 README: link to Copyright instead of LICENSE file
The Copyright file explains the whole license mess. The earlier change
was apparently confusing, because the link reading "details" merely
linked to the GPLv2 license instead of explaining anything. In fact, I
meant to link to the Copyright file in the first place.
2015-10-06 18:19:20 +02:00
wm4 b4804a4b26 video: fix base for --no-correct-pts
Use the first encountered packet PTS/DTS as base, instead of the last
one. This does not add the amount of frames buffered in the codec to the
PTS offset, and thus is better.

Also, don't add the frame time if there was no decoded frame yet. The
first frame should obviously have the timestamp of the first packet
(going by this heuristic).
2015-10-06 18:19:20 +02:00
wm4 5015759334 video: increase maximum number of buffered AVI pts samples
While b-frame reordering limits the maximum required number to around
16, the number of additionally buffered frames can be much higher.

Guess when this actually matters? (For the libavcodec MMAL wrapper.)
2015-10-06 18:19:20 +02:00
wm4 3c292395ca video: don't sort AVI pts samples
It's obviously not needed, and only an artifact of the old PTS
determination code.
2015-10-06 18:19:20 +02:00
wm4 8e654d3f78 video: remove user-controllable PTS sorting (--pts-association-mode)
Useless. Sometimes it might be useful to make some extremely broken
files work, but on the other hand --no-correct-pts is sufficient for
these cases.

While we still need some of the code for AVI, the "auto" mode in
particular inflated the size of the code.
2015-10-06 18:19:20 +02:00
wm4 0e245b3752 video: disable framedrop if avi-style timestamps are used
This can't be handled correctly at all. Other cases when the decoder
might drop a frame (such as completely failing to decode a frame) will
shift timestamps by a frame, and it can't be avoided.

While we could maybe find a better way to handle this with libavcodec's
main decoders, this seems to be much harder if it should work with
certain HW decoders, which don't passthrough the DTS field (such as
MMAL). Another problem are .avi files with b-frames. So just leave it
as it is.
2015-10-06 18:18:57 +02:00
ChrisK2 6fb926a560 ytdl: Remove version check and minor cleanup
Closes #2370
2015-10-06 17:06:11 +02:00
Kevin Mitchell 8f33c65fe0 ao_alsa: add debug messages for format search 2015-10-06 02:24:36 -07:00
Kevin Mitchell beae60bcd5 ao_alsa: fix failure to find any sampleformat
Set format to invalid after each failed test. This way the final check
for valid format will actually fail if no formats work.
2015-10-06 02:24:36 -07:00
wm4 29e42b78c0 README: clarify license statement
Fixes #2382.
2015-10-06 09:28:38 +02:00
wm4 54fbda2ba4 audio: add option for falling back to ao_null
The manpage entry explains this.

(Maybe this option could be always enabled and removed. I don't quite
remember what valid use-cases there are for just disabling audio
entirely, other than that this is also needed for audio decoder init
failure.)
2015-10-05 19:12:23 +02:00
wm4 e694d67366 ao: rework audio output driver probing
Make the code a bit more uniform. Always build a "dummy" audio output
list before probing, which means that opening preferred devices and
pure auto-probing is done with the same code. We can drop the second
ao_init() call.

This also makes the next commit easier, which wants to selectively
fallback to ao_null. This could have been implemented by passing a
different requested audio output list (instead of reading it from
MPOptions), but I think it's better if this rather special feature
is handled internally in the AO code. This also makes sure the AO
code can handle its own options (such as the audio output list) in
a self-contained way.
2015-10-05 19:10:22 +02:00
wm4 6890de958d manpage: edit recommended VO remarks 2015-10-04 20:26:12 +02:00
wm4 c855ab5624 player: add wav to list of external audio file extensions
Fixes #2378.
2015-10-04 19:48:58 +02:00
wm4 3ccac74de2 video: remove codec delay estimation
This was used only by the timestamp sorting code, which is a fallback
for avi files (as well as avi-muxed mkv files). This was supposed to
prevent accumulating timestamps in case the decoder consumes more
packets than it outputs frames (i.e. frames are dropped). This didn't
work very well (timestamps could be off by a large amount), the
estimation of the delay was fragile, and the interdependencies with the
decoder were annoying, so kill it.
2015-10-03 22:10:44 +02:00
wm4 ee283843fa video: cosmetics: remove trailing whitespace 2015-10-03 21:21:27 +02:00
wm4 291f301c10 video/out: remove an unused parameter
This parameter has been unused for years (the last flag was removed in
commit d658b115). Get rid of it.

This affects the general VO API, as well as the vo_opengl backend API,
so it touches a lot of files.

The VOFLAGs are still used to control OpenGL context creation, so move
them to the OpenGL backend code.
2015-10-03 18:20:16 +02:00
wm4 e448e10fd7 vo: change some defines to enums
Why not.
2015-10-02 18:49:35 +02:00
wm4 e72ca08554 vo_opengl: drop old backend API 2015-10-02 18:49:35 +02:00
wm4 e87f705497 vo_opengl: rpi: switch to new internal API 2015-10-02 18:33:09 +02:00
wm4 93db4233af win32: cleanup: remove some unneeded things 2015-10-02 18:14:00 +02:00
wm4 fe993a6712 vo_opengl: w32: switch to new internal API 2015-10-02 18:10:58 +02:00
wm4 69bc7e34b9 vo_opengl: refactor DwmFlush crap
Get it out of the way in the common code. MPGLContext.dwm_flush_opt can
be removed as well as soon as the option system gets overhauled.
2015-10-02 17:59:05 +02:00
Emmanuel Gil Peyrot a9ed9e329c vo_opengl: remove leftover variable from vaglx in vaegl
This was preventing compilation on systems without X11 headers.
2015-10-02 03:49:02 +01:00
Emmanuel Gil Peyrot 8a21cb1cd3 vo: fix compilation failure when vaapi is enabled and x11 disabled
This was previously trying to use the video_output_vaapi symbol despite
vo_vaapi.c being guarded by the vaapi-x11 option.
2015-10-02 03:21:51 +01:00
wm4 bd87598af9 vo_opengl: wayland: switch to new internal API 2015-10-01 22:57:02 +02:00
wm4 f4d62da8f0 vo_opengl: cocoa: switch to new internal API 2015-10-01 22:42:25 +02:00
wm4 ae7212963e cue: read more metadata
Make handling of metadata slightly more generic, and add reading of the
"PERFORMER" fields. There are some more fields, but for now let's leave
it at this.

TRACK-specific PERFORMER fields have to be read from the per-chapter
metadata (somewhat obscure).

Fixes #2328.
2015-10-01 21:57:35 +02:00
wm4 24f34c9e8e player: print tags under different log prefix
A minor, but apparently common feature request. Fixes #2360.
2015-10-01 21:10:59 +02:00
wm4 98c4ab6d13 vo_opengl: make sw suboption work without explicit backend selection
You needed to select a GL backend with the backend suboption. This was
confusing.

Fixes #2361.
2015-10-01 20:57:29 +02:00
wm4 4a07205963 vo_opengl: debanding requires GLSL 1.30
We have to disable it, or shader compilation will fail.

Fixes #2362.
2015-10-01 20:44:39 +02:00
wm4 7c5f41ff5f x11: separate window creation and configuration
This gets rid of an old hack, VOFLAG_HIDDEN. Although handling of it has
been sane for a while, it used to cause much pain, and is still
unintuitive and weird even today.

The main reason for this hack is that OpenGL selects a X11 Visual for
you, and you're supposed to use this Visual when creating the X window
for the OpenGL context. Which means the X window can't be created early
in the common X11 init code, but the OpenGL code needs to do something
before that. API-wise you need separate functions for X11 init and X11
window creation. The VOFLAG_HIDDEN hack conflated window creation and
the entrypoint for resizing on video resolution change into one
function, vo_x11_config_vo_window(). This required all platform backends
to handle this flag, even if they didn't need this mechanism.

Wayland still uses this for minor reasons (alpha support?), so the
wayland backend must be changed before the flag can be entirely removed.
2015-09-30 23:31:34 +02:00
wm4 a2a2cdb5bc vo_opengl: cosmetics: coding style 2015-09-30 23:05:42 +02:00
wm4 41bf41e416 vo_opengl: do not reset video queue when changing video equalizer
If interpolation is enabled, then this causes heavy artifacts if done
while unpaused. It's preferable to allow a latency of a few frames for
the change to take full effect instead. If this is done paused, the
frame is fully redrawn anyway.
2015-09-30 22:59:34 +02:00
wm4 ebb43f5176 Revert "vo_x11: remove this video output"
This reverts commit d11184a256.

Unfortunately, there was a lot of unexpected resistance.

Do note that this is still extremely slow, crappy, etc.

Note that vo_x11.c was further edited. Compared to the removed vo_x11.c,
an additional ~200 lines of code was removed in order to simplify it. I
tried to strip it down as much as possible. In particular, support for
odd non-32 bit formats (24, 16, 15, 8 bit) is dropped.

Closes #2300.
2015-09-30 22:52:22 +02:00
wm4 aff6e8e8da stream: minor cleanup to verbose logging
Don't print the URL that is opened twice. stream.c and stream_lavf.c
each printed it once. Remove the logging from stream_lavf.c, and move
the log call to a more interesting point.
2015-09-30 22:51:37 +02:00
ChrisK2 1b7e8ff6c5 ytdl: Don't override user-set format in no-video mode 2015-09-30 22:28:01 +02:00
wm4 739452361f manpage: adjustments to hwdec remarks 2015-09-29 21:14:56 +02:00
wm4 ee63c9c210 video: replace vf_format outputlevels option with global option
The vf_format suboption is replaced with --video-output-levels (a global
option and property). In particular, the parameter is removed from
mp_image_params. The mechanism is moved to the "video equalizer", which
also handles common video output customization like brightness and
contrast controls.

The new code is slightly cleaner, and the top-level option is slightly
more user-friendly than as vf_format sub-option.
2015-09-29 21:12:26 +02:00
wm4 b4491c00c4 Take care of libavcodec convergence_duration deprecation
This AVPacket field was a hack against the fact that the duration field
was merely an int (too small for things like subtitle durations). Newer
libavcodec drops this field and makes duration 64 bit.
2015-09-29 18:43:28 +02:00
wm4 12cd48a8a9 Revert "vd_lavc: do not abort hardware decoding on errors"
This essentially reverts commit 009dfbe3. FFmpeg VideoToolbox support
is being wacky, and can cause major issues, such as not being able
to decode a single frame. (E.g. by playing a .ts file. This should be
fixed in FFmpeg eventually.)

This is not a straight revert of the commit; just a functional one. We
keep the slightly simpler code structure.
2015-09-28 22:31:47 +02:00
wm4 31316e9ca0 vo_opengl: videotoolbox: cleanups
Get rid of the VDA specifics like naming or ancient pixel formats.
2015-09-28 22:11:04 +02:00
wm4 853fe788f8 vo_opengl: rename hwdec_vda.c to hwdec_osx.c
It doesn't deal with VDA at all anymore. Rename it to hwdec_osx.c. Not
using hwdec_videotoolbox.c, because that would give it the longest
source path in this project yet. (Also, this code isn't even
VideoToolox-specific, other than the name of the pixel format used.)
2015-09-28 22:03:14 +02:00
wm4 1dd7b7bddc video: remove VDA support
VideoToolbox is preferred. Now that FFmpeg released 2.8, there's no
reason to support VDA anymore. In fact, we had a bug that made VDA not
useable with older FFmpeg versions in some newer mpv releases.

VideoToolbox is supported even on slightly older OSX versions, and if
not, you still can run mpv without hw decoding.
2015-09-28 22:03:14 +02:00
wm4 15ef9f9ee6 vd_lavc: remove some ancient cargo-culting
Definitely not needed anymore, and fixes a crash in some weird corner-
cases.

The extradata freeing is apparently still needed, though. (Because a
codec context can be opened again, which makes no sense, but ok.)
2015-09-28 22:03:14 +02:00
wm4 ad2ab5893e ao_alsa: improve handling of device disconnection
This can happen with USB audio. There was already code for this, but
something in mpv and ALSA changed - and now the old code is not
necessarily triggered anymore. It probably depends on the exact
situation.
2015-09-28 22:03:14 +02:00
wm4 144571da9b ao_coreaudio_utils: fix error handling in device listing code
This could sometimes cause crashes in hotplug events. (Apparently in
cases when CoreAudio changes its state asynchronously, or such.)

CA_GET_STR() does not set the string if there was an error, so errors
have to be strictly checked before using it.
2015-09-28 22:03:14 +02:00
wm4 8aa8417aa3 vo_opengl: vaapi: add Wayland support
Pretty trivial with the new EGL interop.

Fixes #478.
2015-09-27 21:38:45 +02:00
wm4 1fa674c109 vo_opengl: refactor EGL context information callback
Move the ugliness from x11egl.c to common.c, so that the ugliness
doesn't have to be duplicated in wayland.c.
2015-09-27 21:34:11 +02:00
wm4 710872bc22 vaapi: remove dependency on X11
There are at least 2 ways of using VAAPI without X11 (Wayland, DRM).
Remove the X11 requirement from the decoder part and the EGL interop.
This will be used by a following commit, which adds Wayland support.

The worst about this is the decoder part, which includes a bad hack for
using the decoder without any VO interop (also known as "vaapi-copy"
mode). Separate the X11 parts so that they're self-contained. For the
EGL interop code we do something similar (it's kept slightly simpler,
because it essentially only has to translate between our silly
MPGetNativeDisplay abstraction and the vaGetDisplay...() call).
2015-09-27 21:33:15 +02:00
wm4 1ff32236fa manpage: fix broken example
Fixes #2353.
2015-09-27 19:21:37 +02:00
wm4 2a7811176c vo_opengl: vaapi: provide symbols for missing extensions
We also could just check at build time, but since it's not much, just
redefine them inline if not present.
2015-09-27 16:25:03 +02:00
wm4 2e5df94f0f vo_opengl: vaapi: redo how EGL extensions are loaded
It looks like my hope that we can unconditionally include EGL headers in
the OpenGL code is not coming true, because OSX does not support EGL at
all. So I prefer loading the VAAPI EGL/GL specific extensions manually,
because it's less of a mess. Partially reverts commit d47dff3f.
2015-09-27 16:18:06 +02:00
wm4 0c494c238a vo_opengl: rpi: fix EGL comment
While EGL 1.4 seemed a bit ambiguous about this to me, it actually says
quite clearly that core functions are not supported with
eglGetProcAddress() in the following paragraph.
2015-09-27 16:07:18 +02:00
wm4 375886c777 vo_opengl: probe for EGL by default
Normally, we prefer GLX on X11. But for the VAAPI EGL interop, we
obviously want EGL. Since nvidia does not provide EGL with desktop GL
yet, we can leave it to the autoprobing. Just make sure some failure
messages don't unnecessarily show up in the nvidia case.

This breaks VAAPI GLX interop by default, but I don't care much. If
you use --hwdec=auto (which you should if you want hw decoding), this
should fallback to vaapi-copy instead.
2015-09-26 20:52:10 +02:00
wm4 0aa548457f vo_opengl: x11egl: cleanup uninit path
Get rid of the config_window_x11_egl() indirection.
2015-09-26 20:52:10 +02:00
wm4 e0cb65e8ac vo_opengl: vaapi: probe the surface format
Probe the surface format, and check whether it's really something we
support. This also does a complete check whether the EGL interop works
at all (the only way to find this out is actually running this code).
Also, support YV12. Under some circumstances, vaapi (with Intel
drivers) can be made to use this format.

Unfortunately, the Intel drivers show some very weird behavior, which
is hopefully a bug. insane_hack() provides a very evil workaround (see
comments). A proper solution might be passing the hw format as part of
mp_image_params, but as long as hw surfaces appear to be able to change
the format on the fly, attempting this is probably not worth the extra
complexity and likely fragility. The hack allows us to pretend that
there is sane behavior for now.
2015-09-26 20:52:10 +02:00
wm4 6875e6a779 wscript: add missing entry to help output
Fixes #2344.
2015-09-25 20:50:04 +02:00
wm4 ac5538c7df vaapi: use GPU memcpy for reading back from HW surface
This makes it much faster if the surface is really mapped from GPU
memory. It's slightly slower than system memcpy if used on system
memory. We don't really know definitely in which type of memory
it's located, so we use the GPU memcpy in all cases.

Fixes #2317.
2015-09-25 19:18:16 +02:00
wm4 0ae8aebb89 video: refactor GPU memcpy usage
Make the GPU memcpy from the dxva2 code generally useful to other parts
of the player.

We need to check at configure time whether SSE intrinsics work at all.
(At least in this form, they won't work on clang, for example. It also
won't work on non-x86.)

Introduce a mp_image_copy_gpu(), and make the dxva2 code use it. Do some
awkward stuff to share the existing code used by mp_image_copy(). I'm
hoping that FFmpeg will sooner or later provide a function like this, so
we can remove most of this again. (There is a patch, bit it's stuck in
limbo since forever.)

All this is used by the following commit.
2015-09-25 19:18:16 +02:00
Philip Langdale 361040f9d9 vd_lavc: Fix recovery from vdpau preemption
Flushing buffers, and thereby triggering decoder reinitialisation
needs to happen before attempting, and failing, to decode.
2015-09-25 17:29:44 +02:00
wm4 d2281935b3 vo_rpi, wayland: fix build
Broken by commit d47dff3f. If something is going to include EGL.h,
header_fixes.h has to know. This definitely affected vo_rpi, and
probably affects wayland builds (with x11egl didabled) as well.
2015-09-25 16:02:15 +02:00
wm4 0a6c334b59 vo_opengl: vaapi: undo vaAcquireBufferHandle() correctly on error
Checking and resetting the VAImage.buf field is non-sense, even if it
happened to work out in the normal case. buf is actually freed when
vaDestroyImage() is called (not quite intuitive), and we need an extra
field to know whether vaReleaseBufferHandle() has to be called.
2015-09-25 12:14:19 +02:00
wm4 38b747bb67 vaapi: cosmetics, minor fixes
Printing "Using vaDeriveImage()" every frame is too verbose, so raise
the log level.

mp_image strides are in int and not unsigned int; fix this. It's not
like it actually matters, though.

Finish a comment.
2015-09-25 12:10:43 +02:00
wm4 993bee38ca vo_opengl: vaapi: handle YV12 correctly
This specific FourCC has its planes swapped compared to FFmpeg yuv420p.
2015-09-25 12:07:20 +02:00
wm4 0b87bf9b72 vo_opengl: vaapi: document DRM fourcc upstream defines
Add the upstream symbolic names as comments. Normally, these should be
defined in libdrm's drm_fourcc.h header. But DRM_FORMAT_R8 and
DRM_FORMAT_GR88 are not defined anywhere, except in the kernel userland
headers of Linux 4.3 (!). We don't want mpv to depend on bleeding-edge
Linux kernel headers, so this will have to do.

Also, just for completeness, add fourccs for the 3 and 4 channel
formats. I didn't manage to test them, though.
2015-09-25 12:03:36 +02:00
wm4 456366b63b vo_opengl: vaapi: use dummy image to determine plane layout
Reduces the amount of hardcoded assumptions about the layout
drastically. (Now adding yuv420 support would be just adjusting an if,
if you ignore the other problems, such as determining the hw format at
all early enough.)
2015-09-25 10:22:10 +02:00
wm4 ec356d3efe vo_opengl: vaapi: remove unnecessary loop
Not sure what I was thinking.
2015-09-25 10:03:17 +02:00
wm4 5786d07450 vo_opengl: vaapi: fix cleanup
Don't call eglDestroyImageKHR() on the same ID possibly more than once.

Clear the image reference on termination, or we would leak up to 1 image
per VO recreation.
2015-09-25 10:02:54 +02:00
wm4 8d8a2045bd vo_opengl: support new VAAPI EGL interop
Should work much better than the old GLX interop code. Requires Mesa 11,
and explicitly selecting the X11 EGL backend with:

    --vo=opengl:backend=x11egl

Should it turn out that the new interop works well, we will try to
autodetect EGL by default.

This code still uses some bad assumptions, like expecting surfaces to be
in NV12. (This is probably ok, because virtually all HW will use this
format. But we should at least check this on init or so, instead of
failing to render an image if our assumption doesn't hold up.)

This repo was a lot of help: https://github.com/gbeauchesne/ffvademo
The kodi code was also helpful (the magic FourCC it uses for
EGL_LINUX_DRM_FOURCC_EXT are nowhere documented, and
EGL_IMAGE_INTERNAL_FORMAT_EXT as used in ffvademo does
not actually exist).

(This is the 3rd VAAPI GL interop that was implemented in this player.)
2015-09-25 00:26:19 +02:00
wm4 0e9cfa6b64 vo_opengl: add mechanism to retrieve Display from EGL context
The VAAPI EGL interop code will need access to the X11 Display. While
GLX could return it from the current GLX context, EGL has no such
mechanism. (At least no standard one supported by all implementations.)
So mpv makes up such a mechanism.

For internal purposes, this is very rather awkward solution, but it's
needed for libmpv anyway.
2015-09-25 00:20:11 +02:00
wm4 d47dff3faa vo_opengl: load certain EGL extensions needed for VAAPI EGL interop
These extensions use a bunch of EGL types, so we need to include the EGL
headers in common.h to use our GL function loader with this.

In the future, we should probably require presence of the EGL headers to
reduce the hacks. This might be not so simple at least with OSX, so for
now this has to do.
2015-09-25 00:19:58 +02:00
wm4 b81d9c79a8 vo_opengl: enable X11 EGL backend by default
Originally, this was disabled, because it was useless and I was afraid
it could possibly break autodetection and proper fallback.
2015-09-24 23:56:55 +02:00
wm4 57831d52dc vo_opengl: actually set hardware decoder mapped texture format
Surfaces used by hardware decoding formats can be mapped exactly like a
specific software pixel format, e.g. RGBA or NV12. p->image_params is
supposed to be set to this format, but it wasn't.

(How did this ever work?)

Also, setting params->imgfmt in the hwdec interop drivers is pointless
and redundant. (Change them to asserts, because why not.)
2015-09-24 23:48:57 +02:00
wm4 b14c9eb748 client API: rename GL_MP_D3D_interfaces
This is a pseudo-OpenGL extension for letting libmpv query native
windowing system handles from the API user. (It uses the OpenGL
extension mechanism because I'm lazy. In theory it would be nicer to let
the user pass them with mpv_opengl_cb_init_gl(), but this would require
a more intrusive API change to extend its argument list.)

The naming of the extension and associated function was unnecessarily
Windows specific (using "D3D"), even though it would work just fine for
other platforms. So deprecate the old names and introduce new ones. The
old ones still work.
2015-09-24 21:07:37 +02:00
wm4 cb1c072534 vo_opengl: remove sharpen scalers, add sharpen sub-option
This turns the old scalers (inherited from MPlayer) into a pre-
processing step (after color conversion and before scaling). The code
for the "sharpen5" scaler is reused for this.

The main reason MPlayer implemented this as scalers was perhaps because
FBOs were too expensive, and making it a scaler allowed to implement
this in 1 pass. But unsharp masking is not really a scaler, and I would
guess the result is more like combining bilinear scaling and unsharp
masking.
2015-09-23 22:43:27 +02:00
wm4 c17ff1703a vo_opengl: move deband_opts declaration to where it's used
At least one thing the current option code can do right.
2015-09-23 22:21:59 +02:00
wm4 65ad85790a vo_opengl: remove unsued chroma_location field
This was redundant to forcing the value with vf_format, so the vo_opengl
sub-option was removed. This field is just a leftover.
2015-09-23 22:16:36 +02:00
wm4 17cd6798a6 vo_opengl: move shader file caching to video.c
It's just about loading and cachign small files, not does not
necessarily have anything to do with shaders. Move it to video.c where
it's used.
2015-09-23 22:13:03 +02:00
wm4 d8d4e18835 player: fix another --force-window bug
Will this shit ever actually work?

Fixes #2339.
2015-09-23 22:03:11 +02:00
wm4 009dfbe3b6 vd_lavc: do not abort hardware decoding on errors
Usually, libavcodec ignores errors reported by the hardware decoding
API, so it's not like we can actually escape if the hardware is somehow
acting up.

For normal fallback purposes, or if parts of the hw decoding API which
we actually check fails, we do this by setting and checking the
hwdec_failed flag anyway.
2015-09-23 20:37:47 +02:00
wm4 2ed9370bd6 vf_vavpp: allocate output surfaces with the same size as input
This can happen if the hw decoder allocates padded surfaces (e.g.
mod16), but the VPP output surface was allocated with the exact size.
Apparently VPP requires matching input and output sizes, or it will add
artifacts. In this case, it added mirrored pixels to the bottom few
pixels.

Note that the previous commit should have fixed this. But it didn't
work, while this commit does.

Fixes #2320.
2015-09-23 14:20:50 +02:00
wm4 e0c005cb75 va_vavpp: set input/output processing region
If not set, VPP will use the whole surface. This is a problem if the
surfaces are padded, and especially if the surfaces are padded by
different amounts.

This is an attempt to fix #2320, but it appears to do nothing at all.
2015-09-23 14:20:50 +02:00
wm4 4d6c1be7b6 vd_lavc: minor cleanup to hwdec fallback code
The comment was largely outdated, and described the old situation when
we used a "violent" fallback by making get_buffer2 fail completely.

Also, for the case when the hw decoder initialization succeeded (in
get_format), but get_buffer2 for some reason requests something
unexpected, we also can fallback more gracefully and in the same way.
2015-09-23 14:20:50 +02:00
Martin Herkt f8c57433b9 Release 0.11.0 2015-09-23 01:13:22 +02:00
Martin Herkt ead2933792 Merge branch 'master' into release/current 2015-09-23 01:12:42 +02:00
Martin Herkt 79f8ee2808 DOCS: update client API changes for release 2015-09-23 01:12:15 +02:00
Martin Herkt e3e6c1939f DOCS: update release policy 2015-09-23 01:07:52 +02:00
wm4 4d747400bb win32: allow multiple windows at the same time
Window classes are process-wide (or at least DLL-wide), so you can't
have 2 classes with the same name. Our code attempted to do this when
for example 2 libmpv instances were created within the same process.
This failed, because RegisterWindowEx() fails if the class already
exists.

Fix this by ignoring RegisterWindowEx() errors. If the class can really
not be registered, we will fail on CreateWindowEx() instead. Of course
we also can't unregister the class, as another thread might be using it.
Windows will free the class automatically if the DLL is unloaded or the
process terminates.

Fixes #2319 (hopefully).
2015-09-22 21:54:43 +02:00
wm4 8838c4a5b1 build: allow disabling vapoursynth completely
It's possible to build vf_vapoursynth with either the Python or Lua
backend (or both or none). The check for the vapoursynth core itself was
hidden away and couldn't be disabled, which would link mpv with
vapoursynth even if all backends were disabled.

Rearrange the checks so that the core will be disabled if no backend is
found (or both are disabled). This duplicates the check for
vapoursynth.pc, but since it's trivial, this is not that bad.
2015-09-22 11:46:57 +02:00
wm4 a75e933dac player: fix excessive CPU usage in audio-only mode
Caused by one of the --force-window commits. The unconditional
uninit_video_out() call (which normally should be idempotent) raised
sporadic MPV_EVENT_VIDEO_RECONFIG events. This is ok, except for the
fact that clients (like a Lua script or libmpv users) would cause the
event loop to run again after receiving it, triggering a feedback loop.
Fix it by sending the events really only on a change.
2015-09-22 11:19:39 +02:00
wm4 ab7ac46bcc player: some more --force-window fixes
Sigh... After the recent changes, another regression appeared. This
time, the VO window wasn't cleared when changing from video to a non-
video file (such as audio-only with no cover art). Fix this by properly
taking the handle_force_window() bool parameter into account.

Also, the info message could be printed twice, which is harmless but
ugly. So just remove the message.

Also, do some more minor cleanups (like fixing the comment, which was
completely outdated).
2015-09-21 21:22:20 +02:00
wm4 7a19eb490e player: do not destroy VO prematurely when initializing playback
If --force-window wasn't used, this would destroy the VO while a file
is still being loaded, resulting in flicker and other interruptions
when switching from one playlist entry to another. Recent regression.

The condition used here is pretty tricky, but it boils down to that it
should trigger either in idle mode, or when loading has been fully done
(at these points we definitely know whether the VO will be needed).
2015-09-20 23:13:27 +02:00
wm4 8782354e6d player: rename and move find_subfiles.c
This was in sub/, because the code used to be specific to subtitles. It
was extended to automatically load external audio files too, and moving
the file and renaming it was long overdue.
2015-09-20 18:05:06 +02:00
wm4 f287ccf017 player: add opus to list of external audio file extensions
Fixes #2336.
2015-09-20 18:00:21 +02:00
wm4 2f4e01e772 player: make force-window in auto-profiles actually work
The previous commit was incomplete (and I didn't notice due to a broken
test procedure).

The annoying part is that actually creating the VO was separate; redo
this and merge the code for this into handle_force_window() as well.
This will also make implementing proper reaction to runtime option
changes easier. (Only the part for actually listening to option changes
is missing.)
2015-09-20 17:58:02 +02:00
wm4 9d2bc9a4ac player: make force-window=immediate work in auto-profiles
This is a bad hack; the correct way to handle this would be implementing
profiles differently, and then listen to option changes and act on them
dynamically.
2015-09-20 17:05:14 +02:00
wm4 3586e6ceeb vf_yadif: add hack for Libav compatibility
Libav accepts slightly different options compared to FFmpeg. Sigh...

This was "broken" in 25755f5f. Fixes #2335.
2015-09-20 15:36:52 +02:00
wm4 21e5e4da4b audio/filter: remove reentrancy flag
This flag was used by some filters and made sure none of these filters
were inserted twice. This triggers only if the user explicitly tries to
add multiple filters (and not e.g. due to auto-insertion), so at best
this warned the user from doing something potentially pointless. At
worst, it blocked some (mildly) legitimate use-cases. Get rid of it.

Also see #2322.
2015-09-20 14:44:44 +02:00
Philip Sequeira bad743aed5 TOOLS/zsh.pl: only check the actual exit code when calling mpv
Ignore the other bits of $?. Apparently they can be set even if the
command succeeded.
2015-09-20 14:21:03 +02:00
Philip Langdale 126367bb09 vf_vdpaurb: query_format is still required
I took this out because I thought the filter chain would auto-negotiate
using nv12 without the explicit hint, and it does in the basic case
with no intermediate filter, but once you start adding filters, it
can end up negotiating a different format and then failing.
2015-09-18 07:33:15 -07:00
Philip Langdale 1e53308d65 vf_vdpaurb: Pass through non-hardware-decoded content
Today, vdpaurb will fail if it's used with non-hardware-decoded
content. This created work for the user as they have to explicitly
add or not add it, depending on the content.

As an improvement, we can make vdpaurb pass through any frames
that aren't hardware decoded, so that it can always be present in the
filter chain, if desired.
2015-09-15 21:53:53 -07:00
wm4 fea1e09a9c manpage: add a note about libavfilter 2015-09-11 23:48:47 +02:00
wm4 7020908691 video/filter: remove some vf_lavfi wrappers
I see no point in keeping these around. Keeping wrappers for some select
libavfilter filters just because MPlayer had these filters is not a good
reason.

Ultimately, all real filtering work should go to libavfilter, and users
should get used to using vf_lavfi directly. We might even not require
the awful double-nested syntax for using libavfilter one day.

vf_rotate, vf_yadif, vf_stereo3d are kept because mpv uses them
internally. (They all extend the lavfi filters or change their
defaults.) vf_mirror is kept for symmetry with vf_flip. vf_gradfun and
vf_pullup are probably semi-popular, so I'll remove them not yet - only
after some more discussion.
2015-09-11 23:47:00 +02:00
wm4 876e93d8b7 vf_lavfi: cosmetics: fix coding style 2015-09-11 23:05:14 +02:00
wm4 4e0e24c3c2 af_lavfi: implement af-metadata property
Works like vf-metadata. Unfortunately requires some code duplication
(even though it's not much).

Fixes #2311.
2015-09-11 23:04:02 +02:00
wm4 f095e86b61 af: use generic statuc codes
The reason MPlayer traditionally duplicated them all over the place is
that it wanted every component to be a self-contained library (e.g.
audio filters were in "libaf"). But this is not necessarily helpful, and
this change makes the following commit a bit simpler.
2015-09-11 23:03:04 +02:00
wm4 c2ee824c26 player: prefer logical current directory path
The "PWD" enviornment variable is described by POSIX. We don't go to
length to verify its contents, but just trust it.

This affects the logic for resuming playback.
2015-09-11 23:01:12 +02:00
wm4 d96f6edf49 vf: vf_stereo3d depends on libavfilter 2015-09-11 18:03:16 +02:00
wm4 e76f503fff ao_lavc: minor simplification 2015-09-11 09:01:49 +02:00
Kevin Mitchell 1557d2d470 ao_alsa: use sample format determination code 2015-09-10 23:58:09 -07:00
Kevin Mitchell 7eacfdcd25 ao_alsa: add double to sample format list 2015-09-10 23:58:09 -07:00
Kevin Mitchell 09c61e0a45 ao_alsa: put spdif formats into find_alsa_format 2015-09-10 23:58:09 -07:00
Kevin Mitchell b7144ad8bf audio/format: revise af_format_conversion_score
* (de)planarize -1
* pad 1 byte -8
* truncate 1 byte -1024
* float -> int 1048576 * (8 - dst_bytes)
* int -> float -512

Now the score is negative if and only if the conversion is lossy
(e.g. previously s24 -> float was given a negative (lossy) score),
However, int->float is still considered bad
(s16->float is worse than than s16->s32).

This penalizes any loss of precision more than performance / bandwidth hits.
For example, previously s24->s16p was considered equal to s24->u8.

Finally, we penalize padding more than (de)planarizing as this will
increase the output size for example with ao_lavc.
2015-09-10 23:58:09 -07:00
Kevin Mitchell 269f271b73 video: make --field-dominance set interlaced flag
fixes #2289
2015-09-10 23:46:06 -07:00
wm4 fdf6e5f5aa vo_rpi: fix compilation
The recent OpenGL refactor commits forgot to update this file.
2015-09-11 08:16:17 +02:00
wm4 e9822f6012 ao_oss: use new sample format determination code 2015-09-10 23:39:46 +02:00
wm4 e721660e6d ao_lavc: use new sample format determination code
This is just a refactor, which makes it use the previously introduced
function, and allows us to make af_format_conversion_score() private.

(We drop 2 unlikely warning messages too... who cares.)
2015-09-10 23:38:42 +02:00
wm4 60a617df31 audio/format: add function for determining sample conversion candidates 2015-09-10 23:30:51 +02:00
wm4 e45f469280 audio/format: fix interlaved vs. non-interleaved conversions
This mixed up the returned score for some interleaved/non-interleaved
comparisons. Changing interleaving subtracted 1 point, while extending
sample size by 1 byte also subtracted 1 point.

(This scoring system is not ideal - it'd be much cleaner to do a 3-way
sample format comparison instead, and sort the formats according to the
comparison instead of the score.)
2015-09-10 23:29:31 +02:00
wm4 dc04541ba8 audio/format: actually prefer float over double sample format
...for int->float conversions. This code accidentally inverted the
condition.
2015-09-10 23:25:27 +02:00
wm4 9e04e31906 video: do not use deprecated libavutil pixdesc fields
These were normalized and are saner now. We want to use the new fields,
and also get rid of the deprecation warnings, so use them. There's no
release yet which uses these, so some ifdeffery is unfortunately needed.
2015-09-10 22:13:52 +02:00
wm4 a8eae12af5 vo_opengl: fix shader compilation with debanding and OSX hwdec
2 things are being stupid here: Apple for requiring rectangle textures
with their IOSurface interop for no reason, and OpenGL having a
different sampler type for rectangle textures.
2015-09-10 20:53:47 +02:00
wm4 e2139488ff vo_opengl: move sampler type mapping to a function 2015-09-10 20:52:50 +02:00
wm4 f1205293a7 command: make "add <property> 0" not change the value
The value 0 was treated specially, and effectively forced the increment
to 1. Interestingly, passing 0 or no value also does not include the
scale (from touchpads etc.), but this is probably an accidental behavior
that was never intentionally added.

Simplify it and make the default increment 1. 0 now means what it
should: the value will not be changed. This is not particularly useful,
but on the other hand there is no need for surprising and unintuitive
semantics.

OARG_CYCLEDIR() failed to apply the default value, because
m_option_type_cycle_dir was missing a copy handler - add this too.
2015-09-10 14:15:48 +02:00
wm4 2492b5f119 cache: do not include backbuffer size in total stream cache size
This causes weirdness with the "cache-size" property and option. Only
the read handler of the property included the backbuffer, while all
others did not. Make it consistent, and subtract the backbuffer size
from the cache size.

Fixes #2305.
2015-09-10 14:15:45 +02:00
wm4 d3bd5c9541 DOCS: cleanup API changes version markers
Make it so that they don't need to be edited on release (no change in
tense). Also, move the "stray" changes after client API version 1.19 to
1.19 itself.
2015-09-10 14:08:10 +02:00
wm4 b4abcbd19d vo_opengl: fix deband sub-option handling
This all has to be done manually.
2015-09-09 20:40:04 +02:00
Niklas Haas 97363e176d vo_opengl: implement debanding (and remove source-shader)
The removal of source-shader is a side effect, since this effectively
replaces it - and the video-reading code has been significantly
restructured to make more sense and be more readable.

This means users no longer have to constantly download and maintain a
separate deband.glsl installation alongside mpv, which was the only real
use case for source-shader that we found either way.
2015-09-09 19:19:23 +02:00
wm4 95d5bee832 old-makefile: update for recent OpenGL refactors 2015-09-09 18:21:09 +02:00
Niklas Haas eb56807b41 vo_opengl: move self-contained shader routines to a separate file
This is mostly to cut down somewhat on the amount of code bloat in
video.c by moving out helper functions (including scaler kernels and
color management routines) to a separate file.

It would certainly be possible to move out more functions (eg. dithering
or CMS code) with some extra effort/refactoring, but this is a start.

Signed-off-by: wm4 <wm4@nowhere>
2015-09-09 18:17:44 +02:00
Niklas Haas 7929e36e93 vo_opengl: reduce code duplication for scaler options
This simple refactor cuts down on the immense amount of overhead and
duplication across all of the related scale-* options.
2015-09-09 18:09:40 +02:00
Niklas Haas 44eda2177d vo_opengl: remove gl_ prefixes from files in video/out/opengl
This is a bit redundant with the name of the directory itself, and not
in line with existing naming conventions.
2015-09-09 18:09:31 +02:00
Niklas Haas deebc55014 vo_opengl: move gl_* files to their own subdir
This is mainly just to keep things a bit more organized and separated
inside the codebase.
2015-09-09 18:09:25 +02:00
Niklas Haas 944fa1214a vo_opengl: minor refactor
Just making the argument order for pass_load_fbotex more consistent with
finish_pass_fbo.
2015-09-09 18:09:13 +02:00
Rudolf Polzer 37544e53dc Use setfield, not --field-dominance. See #2297. 2015-09-09 02:57:44 +02:00
wm4 f622f9d3a3 vo_opengl: filter allowed options in dumb-mode
Instead of the other way around of disabling disallowed options. This is
more robust and also slightly simpler, at least conceptually. If new
vo_opengl features are added, they don't need to be explicitly disabled
for dumb-mode just to avoid that it accidentally breaks.
2015-09-08 22:55:01 +02:00
wm4 ab6f6aa61e vo_opengl: move gl_video_opts copying code to separate function
Sigh...

Hopefully this code will be completely unnecessary one day, as it's
only needed due to the sub-option parser craziness.

Move dumb_mode to the top of the struct, so the C universal initializer
doesn't cause warnings with all those broken compilers.
2015-09-08 22:46:47 +02:00
wm4 af0b903afa af_lavrresample: remove unnecessary indirections
Not sure why struct af_resample_opts even exists. It seems useful to
group the fields set by user options. But storing the current format
conversion parameters doesn't seem very elegant, and having a separate
instance in the "ctx" field isn't helpful either.
2015-09-08 22:21:19 +02:00
wm4 4eae4a5da7 af_lavrresample: add normalize suboption 2015-09-08 22:16:30 +02:00
wm4 0eb72d786c vo_opengl: restore single pass optimization as separate code path
The single path optimization, rendering the video in one shader pass and
without FBO indirections, was removed soem commits ago. It didn't have a
place in this code, and caused considerable complexity and maintenance
issues.

On the other hand, it still has some worth, such as for use with
extremely crappy hardware (GLES only or OpenGL 2.1 without FBO
extension). Ideally, these use cases would be handled by a separate VO
(say, vo_gles). While cleaner, this would still cause code duplication
and other complexity.

The third option is making the single-pass optimization a completely
separate code path, with most vo_opengl features disabled. While this
does duplicate some functionality (such as "unpacking" the video data
from textures), it's also relatively unintrusive, and the high quality
code path doesn't need to take it into account at all. On another
positive node, this "dumb-mode" could be forced in other cases where
OpenGL 2.1 is not enough, and where we don't want to care about versions
this old.
2015-09-07 21:18:30 +02:00
wm4 8a9c9e0ede vo_opengl: move video source rectangle computation to a function
Needed for the following commit.
2015-09-07 21:18:30 +02:00
wm4 cd32179627 vo_opengl: comsetics: remove unnecessary line break 2015-09-07 21:18:30 +02:00
Niklas Haas f3b00ec142 vo_opengl: require FBOs and get rid of the single-pass optimization
This change makes vo_opengl slightly less compatible (ancient devices
without FBOs will no longer work) and decreases performance in the
simplest case (vo=opengl), in exchange for significantly reducing code
complexity and making everything easier to reason about.
2015-09-07 21:17:38 +02:00
wm4 7c73f70b89 osd: delay libass initialization as far as possible
Until now, most OSD objects created the associated ASS_Renderer instance
as soon as possible, even if nothing was going to be rendered. Maybe
this was even intentional.

Change this for the sake of lowering resource usage, and strictly
initialize ASS_Renderer only when it's really needed.

For the OSC, initialization has to be forced, because of the insane
mechanism for translating mouse coordinates to OSD coordinates.
2015-09-07 14:26:01 +02:00
wm4 392ae68e5f options: fix --no-config
This was completely broken. It was checked manually in some config
loading paths, so it appeared to work. But the intention was always to
completely disable reading from the normal config dir. This logic was
broken in commit 2263f37d.

The manual checks are actually redundant, and are not needed if
--no-config is implemented properly - remove them.

Additionally, the change to load the libmpv defaults from an embedded
profile also failed to set "config=no". The option is marked as not
being settable by a config file, and the libmpv default profile is
parsed as a config file, so this option was rejected. Fix it by removing
the CONF_NOCFG flag. (Alternatively, m_config_set_profile() could be
changed not to set the "config file" flag by default, but I'm not
bothering with this.)
2015-09-05 15:33:19 +02:00
wm4 a6694b7b96 DOCS/client_api_examples/sdl: make the window resizable 2015-09-04 22:38:19 +02:00
wm4 23f6f3f50c af_lavrresample: add missing include statement
Apparently, this broke compilation with Libav under some circumstances.
Looking at it again, it shouldn't have, but this change doesn't hurt
anyway.
2015-09-04 22:16:13 +02:00
wm4 215afe7a41 vo_opengl: use the correct attribute name for vertex position
This didn't seem entirely sane. It probably worked by accident, because
"position" is always the first attribute, and thus the default value 0
for the location was always correct.
2015-09-04 13:03:35 +02:00
wm4 d04d2380e3 audio/filter: remove af_bs2b too
Some users still use this filter, so the filter was going to be kept.
But I overlooked that libavfilter provides this filter. Remove the
redundant wrapper from mpv. Something like --af=lavfi=bs2b should work
and give exactly the same results.
2015-09-04 00:23:39 +02:00
wm4 091bfa3abf audio/filter: remove some useless filters
All of these filters are considered not useful anymore by us. Some have
replacements in libavfilter (useable through af_lavfi).

af_center, af_extrastereo, af_karaoke, af_sinesuppress, af_sub,
af_surround, af_sweep: pretty simple and useless filters which probably
nobody ever wants.

af_ladspa: has a replacement in libavfilter.

af_hrtf: the algorithm doesn't work properly on most sources, and the
implementation was buggy and complicated. (The filter was inherited from
MPlayer; but even in mpv times we had to apply fixes that fixed major
issues with added noise.) There is a ladspa filter if you still want to
use it.

af_export: I'm not even sure what this is supposed to do. Possibly it
was meant for GUIs rendering audio visualizations, but it couldn't
really work well. For example, the size of the audio depended on the
samplerate (fixed number of samples only), and it couldn't retrieve the
complete audio, only fragments. If this is really needed for GUIs, mpv
should add native visualization, or a proper API for it.
2015-09-03 23:55:36 +02:00
Martin Herkt 181e1377b2 Release 0.10.0 2015-09-03 19:59:59 +02:00
wm4 e1fbd3b790 player: log error code on playback exit
So far, this required using the client API to know it.
2015-09-03 14:45:32 +02:00
wm4 496d53a2f2 ebml: warn if an EBML has unknown length
While unknown lengths are supported in some important cases like
segments and clusters, they are not for small and complex metadata
elements like the track list. Such elements are simply rejected.

This case was caught by the size sanity check below, but the message is
misleading and wrong.

(There are likely no files in the wild which require support for this.
The sample file I've seen was muxed by libavformat, but in a case where
it aborted when writing the header. Clearly a broken file.)
2015-09-03 13:39:00 +02:00
wm4 90efe329b9 manpage: fix typo
Fixes #2279.
2015-09-03 12:01:18 +02:00
wm4 61b902f5a7 vd_lavc: better hwdec log output
Often, we don't know whether hardware decoding will work until we've
tried. (This used to be different, but API changes and improvements in
libavcodec led to this situation.) We will often output that we're going
to use hardware decoding, and then print a fallback warning.

Instead, print the status once we have decoded a frame.

Some of the old messages are turned into verbose messages, which should
be helpful for debugging. Also add some new ones.
2015-09-02 23:33:13 +02:00
wm4 11f44a10f9 vd_lavc: factor all hwdec fallbacks into the same function
The fallback at initialization time was basically duplicated, maybe for
the sake of showing a different error message. This doesn't matter
anymore; not much can fail at initialization anymore. Most meaningful
and common errors happen either at probing or in get_format (when the
actual hw decoder is initialized).
2015-09-02 23:10:39 +02:00
wm4 3f5715a053 vo_opengl: improve robustness against PBO failure
If PBO upload fails, disable PBOs and revert to the normal codepath. In
theory we should retry PBO upload on failure (because OpenGL specifies
that it can sporadically fail), but since it normally doesn't happen,
and the fallback will work, I'm not bothering.

Some restructuring is needed, since glUnmapBuffer needs to be called
earlier. In fact, the old code structure didn't make too much sense, and
is a leftover from MPlayer's direct rendering support, which let the
decoder decode to a PBO-mapped region. This means the buffer_ptr field
can be dropped. Drop buffer_size as well, since it only had 2 possible
values (0 or the size required for the current config).
2015-09-02 22:45:07 +02:00
wm4 418af6f0cb vo_opengl: enable pbo by default with opengl-hq
Can significantly help with very large video resolutions on nvidia
drivers. It doesn't seem to have negative effects on Intel drivers
either. (Although it could have on Intel drivers for older hardware.)

For now, this is only for --vo=opengl-hq. Maybe --vo=opengl should use
it too, but it's still meant to be the crappy, fail-safe default.
2015-09-02 13:17:23 +02:00
wm4 79beb60c54 vo_opengl: slightly simplify plane size determination
Setup a dummy image for the given image params, and get the plane sizes
from that. Admittedly not much of a simplification, but conceptually
it's simpler and less error-prone, as the image layout is guaranteed to
be the same, rather than essentially duplicating the way it is
determined.
2015-09-02 13:17:23 +02:00
wm4 ebf80c07e3 vo_opengl: don't distinguish "real" and texture size
This is from times when we supported padded/non-NPOT textures. The
difference is not useful anymore, and theoretical support for different
sizes is most likely buggy and unmaintained. So remove it.

Also remove the tex_ prefix wherever it appears.
2015-09-02 13:17:23 +02:00
wm4 8ffbb22c27 vo_opengl: simplify PBO copy
Use mp_image_copy() instead of copying manually. (This function checks
whether the destination is regarded writeable, which it is not, because
the destination is the source image with changed pointers, so
refcounting has to be removed from the destination image by resetting
mpi->bufs.)
2015-09-02 13:17:23 +02:00
wm4 4241120363 vo_opengl: rename get_image to map_image 2015-09-02 13:17:23 +02:00
wm4 3a5d769d4a vo_opengl: remove redundant statement in PBO code
This shouldn't be needed anymore. Textures are now always allocated with
the exact size. Any padding (including non-NPOT support) is gone. The
texture sizes will always match the memory plane sizes.

Drop the unused and forgotten "npot" field from the option struct too.
2015-09-02 13:17:22 +02:00
Kevin Mitchell a8e6de90fe screenshot: avoid confusing template error message with no file
Previously, with mpv --force-window=yes --idle=yes --screenshot-template="%f",
mpv would display an error saying that the template was incorrect, which it
isn't, there's just no file to put in the format. In this case, just use the
string "NO_FILE".
2015-09-02 10:34:36 +02:00
wm4 eabc530945 sub: always try to use libavcodec text subtitle converter
Drop the whitelist. It's annoying to maintain. Instead, accept any
subtitle decoder. Since this code path will now also be taken by bitmap
subtitle decoders not whitelisted by sd_lavc.c, add a warning when
bitmap subtitles are decoded. (To reduce or increase potential user
confusion.)

To some degree, a whitelist is needed to distinguish text and bitmap
subtitles. FFmpeg has an API to distinguish them in a generic way to
some degree, but Libav doesn't. So we just stick with this for now.
2015-09-01 23:48:14 +02:00
wm4 62378b394a vo_opengl: remove some leftovers
Forgotten in the previous commit.
2015-09-01 23:21:28 +02:00
wm4 9be10f3bf1 vo_opengl, vda: return to old state
Undo 292266f2. Reapply 3e12e79b.

An additional copy is not really justified, as it could reduce
performance. On the other hand, we can force API users to create
a GL 3.x context.
2015-09-01 15:40:04 +02:00
wm4 d60270ed3d sub: fix --sub-codepage UTF-8 with fallback
Fixes e.g --sub-codepage=utf8:gb18030 if the subtitle us UTF-8.

This was broken in commit e5d31808.

Also log the detected charset in verbose mode.
2015-09-01 13:37:45 +02:00
wm4 e6fd6d6e49 vo_rpi, vo_opengl: do not globally terminate EGL on VO uninit
eglTerminate() affects the EGLDisplay in all threads. Since the RPI
firmware apparently only ever uses EGL_DEFAULT_DISPLAY, this means it
will trash all other contexts on other threads in the same process.

Thus we don't call eglTerminate() at all, at least on RPI. Call
eglReleaseThread() instead (which may or may not be a NOP).
2015-08-31 19:46:02 +02:00
wm4 fb94744595 vo_opengl: fix alpha video in one case
yuva444p worked, yuva420p didn't. This happened because the chroma pass
discards the alpha plane, which is referenced by the alpha blend code
later.

Add a terrible hack to work this around, actually using the same hack as
was used for the Y plane. (A terrible hack for terrible code.)
2015-08-30 23:05:49 +02:00
wm4 82f0d373fb video: make container vs. bitstream aspect ratio configurable
Utterly idiotic bullshit.

Fixes #2259.
2015-08-30 23:04:17 +02:00
Kevin Mitchell 061b947c84 w32: shift drag and drop appends
use the append to playlist functionality if shift is pressed while dropping
2015-08-30 05:55:16 -07:00
Kevin Mitchell 638322f77e x11: drag and drop append with modifier
If the drag and drop action is anything other than
XdndActionCopy, append the dropped files rather than
replacing the existing playlist. With most file managers,
this will mean at least pressing shift while dropping.
2015-08-30 05:28:30 -07:00
Kevin Mitchell c80b7eed53 input: add append argument to file drop event
This puts in place the machinery to merely append dropped file to the playlist
instead of replacing the existing playlist. In this commit, all front-ends
set this to false preserving the existing behaviour.
2015-08-30 05:28:24 -07:00
Kevin Mitchell f14f6fdb31 osc: reinit on playlist changes
This takes care of the corner case where the player is started with a
single playlist entry so that the next/prev arrows are greyed out, but
remain that way even after new elements are added to the playlist.
2015-08-29 02:17:21 -07:00
wm4 2cfa62e651 player: slightly better error reporting when opening file fails
Return MPV_ERROR_LOADING_FAILED instead of MPV_ERROR_NOTHING_TO_PLAY.
2015-08-28 20:51:29 +02:00
wm4 ed0bc8b64f client API: improve an error message
This refers to media played by mpv, and these don't necessarily have to
be files. They can be network resources or entirely abstract URLs too.
2015-08-28 20:50:32 +02:00
torque ef5f4b4d9a osc: exit tick immediately if disabled.
Even after it has been disabled with the `disable-osc` message, the OSC
continues to run the tick function. Completely preventing tick from
being called is impractical since there are several different places
that it's called in the code, so just make it immediately return if the
OSC has been disabled.

This prevents the OSC from continuing the clear the OSD on every tick,
allowing other scripts to disable it so that they may draw to the OSD.
2015-08-28 09:49:52 +02:00
wm4 c61675320b sd_ass: assume negative durations are unknown durations, and handle them
The FFmpeg can officially not distinguish between unknown subtitle
durations, and subtitle durations being 0. (It documents the value 0
meaning unknown duration.)

In practice, at least the LRC demuxer signals unknown subtitle durations
with a negative value.

Assume negative durations mean unknown duration. Show subtitles with
unknown duration forever. Unless there's a subtitle event following it;
then reset the duration so that it ends on the new subtitle event.

Fixes #2244.
2015-08-27 23:45:02 +02:00
ChrisK2 3c86bd2bb5 ytdl: catch bogous extractor info
Some extractors may claim to have extracted subtitles, but then
set the relevant fields to null. Try to catch those cases.

Fixes #2254
2015-08-27 13:42:04 +02:00
wm4 ba384fffca demux_mkv: discard broken index
Add a simplistic heuristic for detecting broken indexes. This includes
indexes with very few elements (apparently libavformat sometimes writes
such indexes, or used to), and indexes with broken timestamps.

The latter was apparently produced by very old HandBrake versions:

| + Muxing application: libmkv 0.6.1.2
| + Writing application: HandBrake 0.9.1

These broken files seem to be common enough that libavformat added a
workaround for them in 2008 (and maybe again in 2015). Apparently all
timestamps are multiplied with the file's tc_scale twice, and FFmpeg
attempts to fix them. We should throw away the whole thing.
2015-08-26 22:47:07 +02:00
wm4 dae464a491 demux_mkv: don't read index twice
Actually, this never happened, because there's logic for ignoring
duplicate header elements (which includes the seek index). This is
mostly for robustness and readability.
2015-08-26 22:42:54 +02:00
wm4 f1778d1f5b video: disable interpolation during framestepping
It just causes annoying artifacts.

Interestingly, this means keeping down the frame stepping key (".") will
play video with interpolation disabled.
2015-08-25 21:48:11 +02:00
wm4 6238491688 vo_opengl: force redraw when framestepping with interpolation
This might fix some problems when framestepping with interpolation
enabled. The problem here is that we want to show the non-interpolated
frame while paused. Framestepping is like unpausing the video for a
frame, and then pausing again. This draws an interpolated frame, and
redrawing on pausing is supposed to take care of this.

This possibly didn't always work, because vo->want_redraw is not checked
by the vo_control() code path. So wake up the VO thread (which takes
care of servicing redraw requests, kind of) explicitly.

The correct solution is getting rid of the public-writable want_redraw
field and replacing it with a new vo_request_redraw() function, but this
can come later.
2015-08-25 21:31:37 +02:00
wm4 cf94fce467 ao_alsa: fix minor memory leak
So snd_device_name_get_hint() return values do in fact have to be freed.

Also, change listing semantics slightly: if io==NULL, skip the entry,
instead of assuming it's an output device.
2015-08-25 15:45:57 +02:00
wm4 1ec1b4186c vd_lavc: bump number of allocated surfaces for hwdec with HEVC 2015-08-24 23:02:40 +02:00
wm4 2172c22ee3 vaapi: add HEVC profile entries
libavcodec does not support HEVC via VAAPI yet, so this won't work.
However, there is ongoing work to add HEVC support to VAAPI, and this
change might help with testing. (Or maybe not - but there is no harm in
this change.)
2015-08-24 23:00:45 +02:00
wm4 a48a8a746e demux_libarchive: don't allow probing to read unlimited data
Instead, allow reading 2KB only. This seems to be sufficient for
libarchive to recognize zip, 7z, rar, tar. Good enough.

This is implemented by creating an in-memory stream with a copy of
the file header. If libarchive succeeds opening this, the actual
stream is opened.

Allowing unlimited reading could break unseekable streams, such as
playing from http servers with no range request support or pipes.

Also, we try not to read too much data in the first probe pass. Some
slow network streams like shoutcast services could make probing much
slower if we allow it to read too much. In the second probing pass,
actually allow 200KB.
2015-08-24 22:26:07 +02:00
wm4 3bbcbc15a5 vda, videotoolbox: guard against unexpected pixel format
Should not happen, but since we don't control decoder video surface
allocation, anything could happen, and the code should be able to deal
with it. Untested.
2015-08-23 21:41:54 +02:00
wm4 63dc0085c8 audio: don't sleep when finishing audio resync
This should avoid unnecessary sleeping when audio playback start resync
has finished and goes into the normal playback state.

This is tricky; see e.g. commit 402fe381.
2015-08-23 21:41:09 +02:00
wm4 fb5368b159 vda, videotoolbox: fix broken condition in screenshot code
Fixes #2237.
2015-08-23 11:32:49 +02:00
wm4 5c3196d20b stream_libarchive: read tar only in "unsafe" mode
As expected, probing with libarchive is a disaster. Both libavformat and
libarchive are too eager to misdetect file formats just because files
"might" be of a specific type. In this case, it's mp3 vs. tar. To be
fair, neither file format has an actual header. I'm not sure why we'd
need tar support, but since libarchive provides it, and idiots on the
internet apparently pack media files in tar sometimes (really, idiots),
keep it for now, and probe tar last.
2015-08-22 22:13:20 +02:00
wm4 602105dbda player: add --playlist-pos option
Oddly often requested.
2015-08-22 22:08:17 +02:00
wm4 1e4113040c vo_opengl: remove dead code
Leftover from 3245bfef.
2015-08-22 21:05:32 +02:00
Ellis Berner 0e2024ef2b docs: correct typo for 'ingore-chmap'
ingore-chmap -> ignore-chmap
2015-08-22 11:50:33 +02:00
wm4 8565073f68 command: make the playback-time property writable
Provides a simplistic way to seek without having to care about weird
situations like timestamp vs. playback time. This is good, because the
seek command is currently timestamp based, so when using the seek
command the user _does_ have to care.
2015-08-21 15:53:24 +02:00
wm4 2e3ce738f5 player: return better guess for playback time during seeks
Always compute the estimated absolute time of the seek target, and
display this as playback time during seeks.

Improves behavior with e.g. .ts files, for which we try to avoid seeks
by timestamp.
2015-08-21 15:37:07 +02:00
Stian Eikeland 8a9fc9398d options: sub-file replaces subfile, instead of sub 2015-08-21 00:15:24 +02:00
Jari Vetoniemi d29e699491 gl_wayland: Wait for frame callbacks
Keep glSwapInterval(0) on to avoid blocking on gl calls, but wait for
frame callbacks so we play nice with compositor.
2015-08-21 00:01:01 +02:00
Jari Vetoniemi e05dc7bfb7 vo_wayland: Wait for frame callbacks
Privdes small api for vo_wayland where one can request frame callback
and then wait for it.

This will make vo_wayland play video smoothly.
2015-08-21 00:01:01 +02:00
Jari Vetoniemi 3245bfefc3 gl_wayland: eglSwapInterval(0) to avoid blocking
This makes mesa not wait for frame callback internally.
2015-08-21 00:01:01 +02:00
Ricardo Constantino b144da63a8 TOOLS/lua/autoload: fix adding more files at end of auto-playlist
Fixes regression in dfd8a5f that made autoload not add more files
at the end of the current playlist if playlist was made by the
script.

This still prevents loading the script if more than one (media or
playlist) file was manually added.
2015-08-20 22:05:03 +02:00
wm4 9cd929bf79 TOOLS/lua/autoload: add all files on start
Or almost. I don't know or care.

Fixes #2219 (maybe, I don't know or care).
2015-08-20 22:04:36 +02:00
wm4 addbf8faae stream_libarchive: disable raw filter
Too many false positives (it accepts things like unspecific text files),
and also relatively useless.
2015-08-20 21:56:44 +02:00
Niklas Haas e1fd80097c vo_opengl: add tscale-clamp option
This significantly reduces the amount of noticeable flashing when using
tscale kernels with negative lobes, by cutting them off completely.

I'm not sure if this has any negative effects. It needs a bit of
subjective testing over a period of time, so I just made it an option.

Fixes #2155.
2015-08-20 21:55:19 +02:00
wm4 96648169e3 vo_rpi: disable background by default
And add an option to enable it.
2015-08-20 19:07:18 +02:00
wm4 147f4956d3 player: deliver IDLE event after uninitializing state
A client API user might count on the fact that audio and video outputs
have already been uninitialized. (They remain uninitialized before
entering idle mode in order to allow smooth transition to the next
playlist entry.) Since event delivery is asynchronous, this has to
happen after actually doing the uninitialization, or the client will
essentially run into a race condition.
2015-08-20 15:25:32 +02:00
wm4 895c8801a2 gl_rpi: destroy the EGLSurface too
Most likely doesn't matter much.
2015-08-20 15:21:01 +02:00
wm4 0d5541af47 vo_rpi: use correct variable for osd layer
This is a cosmetic change, because the value is exactly the same. (The
old code just duplicates the logic, sort of.)
2015-08-20 15:20:20 +02:00
wm4 1b93a7a895 stream_libarchive: fix libarchive callback signature
libarchive uses a quite confusing ifdeffery mess for some of the types
used in callbacks. Currently, archive_read_set_seek_callback() causes a
warning at least on Windows due to mismatching return type. The header
file uses __LA_INT64_T as return type, so I think the user is intended
to use int64_t.

(The ssize_t return type for the read_cb seems correct, on the other
hand.)
2015-08-20 11:08:22 +02:00
wm4 b8fe17f2e6 vo_rpi: fix blackscreen before the first subtitle/OSD is rendered
The OSD overlay wasn't initialized, so it remained solid black until the
first time a subtitle line or an OSD element became visible.
2015-08-20 10:36:32 +02:00
wm4 3bceb37b06 old-configure: avoid a warning 2015-08-19 21:38:47 +02:00
wm4 bffd78748f vd_lavc: remove unneeded hwdec parameters
All hwdec backends now use a single pixel format, and the format is
always checked.

Also, the init_decoder callback is now mandatory.
2015-08-19 21:33:18 +02:00
wm4 cab1f6439c video: don't decode 2 frames ahead with display-sync
This is not needed. It was used only temporarily in a development
branch, and is a leftover from earlier rebasing.
2015-08-19 21:24:56 +02:00
Stefano Pigozzi d0e19b659e build: make sure the HAVE_ key is undefined on failure
Some particular checks can define the HAVE_ key on their own. To make sure
they work correctly when composed (with compose_checks) we force the HAVE_
key to be undefined if a check fails.
2015-08-19 00:15:41 +02:00
Stefano Pigozzi 2dac2efce4 Revert "build: workaround for broken waf crap"
This reverts commit 1b7883a3e5.
2015-08-19 00:12:33 +02:00
wm4 1b7883a3e5 build: workaround for broken waf crap
Even though the rpi check fails, it'll define "HAVE_RPI 1" in config.h.
Why? Who knows...
2015-08-18 23:57:00 +02:00
wm4 4427fa9900 stream_libarchive: restrict number of allowed formats
Most of what is not in this list is extremely obscure, or increases the
file format misdetection rate.
2015-08-18 23:26:40 +02:00
wm4 594071dbf4 manpage: fix typo
Actually, this was unintentionally changed in commit 70e0bc1e.
2015-08-18 23:11:11 +02:00
wm4 5eb6466e54 vo_rpi: redraw subtitles only on change
Since vo_rpi uses MMAL for video output, which is completely
independent from the GLES overlay, we can just not redraw the
GLES screen if subtitles do not change.

(As a furhter optimization, the dispmanx overlay could be removed
if nothing is visible. But I'm not sure if adding and removing the
overlay frequently is a good idea for performance, so this could
just as well go the other way.)
2015-08-18 23:09:37 +02:00
wm4 58ba2a9087 vo_rpi: use EGL to render subtitles
Slightly faster than using the dispmanx mess (perhaps to a large amount
due to the rather stupid C-only unoptimized ASS->RGBA blending code).

Do this by reusing vo_opengl's subtitle renderer, and vo_opengl's RPI
backend.
2015-08-18 23:01:09 +02:00
wm4 c36c596b7b rpi: factor out context creation
To be used by vo_rpi.c. No functional changes.
2015-08-18 23:00:51 +02:00
wm4 da8a9ff589 demux_libarchive: reject 0-sized files
libarchive does strange things with them.
2015-08-18 00:14:37 +02:00
wm4 cf2fa9d3e5 stream: provide a stream_get_size() convenience function
And use it everywhere, instead of retrieving the size manually. Slight
simplification.
2015-08-18 00:10:54 +02:00
wm4 bf5eac8dd3 demux_libarchive: open flat compressed files
Things like .gz etc., which have no real file header. A mixed bag,
because it e.g. tends to misdetect mp3 files as compressed files or
something (of course it has no mp3 support - I don't know as what it
detects them). But requested by someone (or maybe not, I'm not sure
how to interpret that).
2015-08-17 23:59:55 +02:00
wm4 41d7989800 DOCS/client_api_examples/sdl: don't curse the mainloop
Fix a typo, and also reword another comment.
2015-08-17 23:56:56 +02:00
wm4 6894858bf2 video: fix VideoToolbox/VDA autodetection
This affects vo_opengl_cb in particular: it'll most likely auto-load
VDA, and then the VideoToolbox decoder won't work. And everything fails.

This is mainly caused by FFmpeg using separate pixfmts for the _same_
thing (CVPixelBuffers), simply because libavcodec's architecture demands
that hwaccel backends are selected by pixfmts. (Which makes no sense,
but now we have the mess.)

So instead of duplicating FFmpeg's misdesign, just change the format to
our own canonical one on the image output by the decoder. Now the GL
interop code is exactly the same for VDA and VT, and we use the VT name
only.
2015-08-17 23:51:31 +02:00
wm4 2b280f4522 stream: libarchive wrapper for reading compressed archives
This works similar to the existing .rar support, but uses libarchive.
libarchive supports a number of formats, including zip and (most of)
rar.

Unfortunately, seeking does not work too well. Most libarchive readers
do not support seeking, so it's emulated by skipping data until the
target position. On backwards seek, the file is reopened. This works
fine on a local machine (and if the file is not too large), but will
perform not so well over network connection.

This is disabled by default for now. One reason is that we try
libarchive on every file we open, before trying libavformat, and I'm not
sure if I trust libarchive that much yet. Another reason is that this
breaks multivolume rar support. While libarchive supports seeking in
rar, and (probably) supports multivolume archive, our support of
libarchive (probably) does not. I don't care about multivolume rar, but
vocal users do.
2015-08-17 00:55:26 +02:00
wm4 00b60710cf player: actually close files on playback end
Regression since commit 75b1d504.
2015-08-15 16:26:02 +02:00
wm4 a6e33b4290 vo_rpi: fix NULL pointer deref
Can happen in obscure situations and with hw decoding disabled.
2015-08-14 13:20:00 +02:00
wm4 70c990cda5 atomics: cleanup HAVE_ATOMICS define
The waf build system generates this already. No point in redoing it in
the header file.

The legacy build system (which we really should drop) didn't; fix it.
2015-08-13 23:34:14 +02:00
wm4 baeead7181 vo_rpi: simplify background handling
Apparently this is sufficient.
2015-08-13 17:25:15 +02:00
wm4 a6a585d470 vo_rpi: unregister vsync callback
Small bug, much pain.
2015-08-13 17:23:31 +02:00
wm4 0ba44d5fef vo_rpi: skip OSD rendering when repeating frames
It's unnecessary and slow. Doesn't help too much, though.
2015-08-13 12:23:18 +02:00
wm4 ed09e78fb9 DOCS/client_api_examples/sdl: add more explanation comments 2015-08-12 23:04:26 +02:00
wm4 b989bb96d1 client API: change subtle wording to different subtle wording
Make a difference between different mpv_handles pointing to the same mpv
core, or different mpv cores. While we're not explicit about it, at
least avoid that someone could misunderstand when really looking for the
case of mpv_handles pointing to the same core.
2015-08-12 23:04:05 +02:00
wm4 a17d5e4bdd player: use OSD formattin for DS on the terminal status line 2015-08-12 22:26:35 +02:00
wm4 828881816a demux: remove redundant demux_chapter.name field
Instead, force everyone to use the metadata struct and set a "title"
field. This is only a problem for the timeline producers, which set up
chapters manually. (They do this because a timeline is a separate
struct.)

This fixes the behavior of the chapter-metadata property, which never
returned a "title" property for e.g. ordered chapters.
2015-08-12 11:11:23 +02:00
wm4 c7329e5118 vo: fix video EOF with display-sync
We must not use the frame PTS in any case. In this case, it fails
because nothing sets it up to wake up. This typically caused the player
to apparently "pause", until something else waked it up, like moving the
mouse and other events.
2015-08-12 10:46:29 +02:00
wm4 b103a8e113 DOCS/client_api_examples/sdl: don't load file before GL init
Could lead to failure because it's essentially a race condition.
2015-08-11 19:02:25 +02:00
Rodger Combs 533e151feb cocoa: hide cursor using a blank image instead of a system-wide API
Fixes #503
2015-08-11 08:02:58 +02:00
wm4 f6a354e846 DOCS/client_api_examples: add SDL OpenGL example 2015-08-11 01:23:09 +02:00
wm4 2d68a2e55a manpage: fix typo 2015-08-11 00:14:13 +02:00
wm4 266735a7a2 osc: avoid annoying verbose mode log spam
enable_key_bindings()/disable_key_bindings() now prints a log message on
each call, thus we should avoid makign redundant calls.

This could probably be solved more elegantly, but since this is all
legacy/private API, don't bother.
2015-08-10 23:51:01 +02:00
wm4 e77bc570d7 vo_rpi: support display sync
This VO is special because it normally doesn't block on vsync, but can
be made to do so. Supposedly the MMAL video output API merely sets a
"current frame" field when sending an output frame, and the firmware
will pick up whatever frame that field is set to at the time of a
vsync.
2015-08-10 18:48:45 +02:00
wm4 031555fbe6 player: add display sync mode
If this mode is enabled, the player tries to strictly synchronize video
to display refresh. It will adjust playback speed to match the display,
so if you play 23.976 fps video on a 24 Hz screen, playback speed is
increased by approximately 1/1000. Audio wll be resampled to keep up
with playback.

This is different from the default sync mode, which will sync video to
audio, with the consequence that video might skip or repeat a frame once
in a while to make video keep up with audio.

This is still unpolished. There are some major problems as well; in
particular, mkv VFR files won't work well. The reason is that Matroska
is terrible and rounds timestamps to milliseconds. This makes it rather
hard to guess the framerate of a section of video that is playing. We
could probably fix this by just accepting jittery timestamps (instead
of explicitly disabling the sync code in this case), but I'm not ready
to accept such a solution yet.

Another issue is that we are extremely reliant on OS video and audio
APIs working in an expected manner, which of course is not too often
the case. Consequently, the new sync mode is a bit fragile.
2015-08-10 18:48:45 +02:00
wm4 fedaad8250 player: separate controls for user and video controlled speed
For video sync, we want separate playback speed controls for user-
requested speed and the "correction" speed for video timing. Further, we
use this separation to make sure only a resampler is inserted if
playback speed is only changed for video sync correction.

As of this commit, this is basically inactive code. It's just
preparation for the video sync code (the following commit).
2015-08-10 18:40:16 +02:00
wm4 3d1cc17ab2 player: redo estimated-vf-fps calculation
Additionally to taking the average, this tries to use the demuxer FPS to
eliminate jitter, and applies some other heuristics to check if the
result is sane.

This code will also be used for the display sync code (it will actually
make use of the require_exact parameter).

(The value of doing this over keeping the simpler demux_mkv hack is
somewhat questionable. But at least it allows us to deal with other
container formats that use jittery timestamps, such as mp4 remuxed
from mkv.)
2015-08-10 18:38:57 +02:00
wm4 8f2d9db79f demux_mkv: disable timestamp fixup code again
This doesn't work too well if sections of the file change to a different
framerate. It lowers our chances to guess the correct FPS in the display
sync code.

For normal playback, this (probably) doesn't help that much anyway,
except that the "estimated-vf-fps" property will regress in the simplest
mkv case. This will be fixed with the next commit.

The now disabled code will probably be removed; it's not useful anymore.
2015-08-10 18:38:36 +02:00
wm4 5a52fe47a0 TOOLS/stats-conv: allow passing regex via command line 2015-08-10 18:36:10 +02:00
wm4 8d66bd76e2 video: remove old vdpau hwaccel API usage
While the "old" libavcodec vdpau API is not deprecated (only the very-
old API is), it's still relatively complicated code that badly
duplicates the much simpler newer vdpau code. It exists only for the
sake of older FFmpeg releases; get rid of it.
2015-08-10 00:07:35 +02:00
wm4 853ff000c3 command: improve A-B loop OSD messages 2015-08-10 00:07:35 +02:00
Ricardo Constantino dfd8a5ff06 TOOLS/lua/autoload: don't run if playlist is loaded 2015-08-10 00:07:31 +02:00
Ricardo Constantino 91b9dcf800 TOOLS/lua: Add zones.lua
Lua script that enables handling of certain commands depending on where
the mouse pointer is. Mostly useful for mouse-wheel handling via
input.conf.

Example:

MOUSE_BTN3 script-message-to zones commands "*-left: add volume +5"
"default: seek +10"
MOUSE_BTN4 script-message-to zones commands "*-left: add volume -5"
"default: seek -10"

Will changes behavior of Mouse Wheel Up/Down to alter volume if mouse is
in the left zone of the window, but re-adds the default to seek if wheel
is used on other parts.
2015-08-09 23:52:13 +02:00
Niklas Haas e9182c5c7c options: remove the period at the end of "No file."
Since we're on the topic of consistency, I've seen multiple users
complain about the presence of this period, which does not really match
other programs' behavior.
2015-08-09 21:45:37 +02:00
Martin Herkt fbb22039f3 options: move program name to end of window title
Fixes #2188
2015-08-09 20:14:16 +02:00
wm4 27a17be325 manpage: document videotoolbox support 2015-08-08 18:30:41 +02:00
wm4 62aba69e15 av_common: remove deprecated API usage
As the removed comment says, not copying this field may cause problems
on older libav* releases. See also commit 5f7de399.

Remove this, as newer FFmpeg releases are available. As of this commit,
use of mpv with FFmpeg 2.5.x and below, or Libav 11 and below is not
recommended, and may lead to random video decoding issues. (Although the
failure cases are apparently somewhat obscure.)
2015-08-07 15:45:27 +02:00
wm4 dd5c87e1d7 audio: remove unused legacy libavutil header
It was never used, but is a leftover from old times.
2015-08-07 02:41:39 +02:00
wm4 60794e2359 player: raise maximum idle time
No reason to wake up every other minute.
2015-08-07 02:41:02 +02:00
wm4 8c388ce79c build: fix build with --disable-tv --enable-pvr
These share some code (frequencies.c at least), so linking was failing.
Fix by making pvr depend on tv.
2015-08-06 01:03:24 +02:00
wm4 70e0bc1e4a manpage: use - as separator for the remaining commands
See commit 289705da. These manpage parts were just forgotten when
updating the command descriptions.
2015-08-06 00:35:09 +02:00
wm4 d6c99bcda2 lua: implement input_enable_section/input_disable_section via commands
Removes some more internal API calls from the Lua scripting backend.
Which is good, because ideally the scripting backend would use libmpv
functions only.

One awkwardness is that mouse sections are still not supported by the
public commands (and probably will never), so flags like allow-hide-
cursor make no sense to an outside user.

Also, the way flags are passed to the Lua function changes. But that's
ok, because they're only undocumented internal functions, and not
supposed to be used by script users. osc.lua only does due to historical
reasons.
2015-08-06 00:31:47 +02:00
wm4 caebbded67 command: define-section with empty contents removes a section 2015-08-06 00:17:30 +02:00
wm4 9bcc882659 lua: make mp.input_define_section use the define-section command 2015-08-06 00:17:30 +02:00
wm4 d1179f9501 command: add a command for defining input bindings
This was requested. It was more or less present internally already and
used for Lua scripting. Lua will switch to the "public" functions in
the following commits.
2015-08-06 00:16:45 +02:00
wm4 beb4f8316a demux: add options to control maximum queue size
Add --demuxer-max-packets and --demuxer-max-bytes, which control the
maximum size of the packet queue. These can be helpful to avoid
excessive memory usage.

Memory usage is the reason why there's a limit in the first place. If a
file is more or less broken, and audio and video don't line up, the
decoders will fill up the packet queue trying to read more audio or
video, and the maximum sizes are required to avoid unbounded memory
allocation. Being able to override the maximum sizes is useful; either
for restricting memory usage further, or enlarging the sizes when
attempting to play various broken files.
2015-08-05 23:41:29 +02:00
wm4 775d816096 demux: remove options to control minimum packet queue size
Remove --demuxer-readahead-packets and --demuxer-readahead-bytes. These
were a bit useless. They could force a minimum packet queue size, but
controlling the queue size with --demuxer-readahead-secs is much nicer.

It's fairly certain nobody ever used these options.
2015-08-05 23:38:23 +02:00
wm4 410553aaaa old-configure: add dummies for recently added config.h entries
Also add a note that you should not use the old build system. (It's only
kept because of the "asshole maintainer" rule: no matter how broken or
pointless someting is, as long as you're the maintainer and want to keep
it, it stays in the repo.)
2015-08-05 23:11:13 +02:00
wm4 5aae68610e DOCS: document video-aspect behavior change
Forgotten in commit ae2f8fd0.
2015-08-05 21:29:09 +02:00
Philip Langdale 0c23325b3a vf_vdpaurb: Don't segfault if input mpi is null
This will happen when input EOF is reached but output frames remain
to be shown.
2015-08-05 18:56:41 +02:00
wm4 0cd70b2d62 build: fix conditions for building gl_hwdec_vda.c
This contains code for the VT and VDA case, thus must be build if at
least 1 of them is enabled.
2015-08-05 18:14:32 +02:00
Sebastien Zwickert 31b5a211f4 hwdec: add VideoToolbox support
VDA is being deprecated in OS X 10.11 so this is needed to keep hwdec working.
The code needs libavcodec support which was added recently (to FFmpeg git,
libav doesn't support it).

Signed-off-by: Stefano Pigozzi <stefano.pigozzi@gmail.com>
2015-08-05 17:47:30 +02:00
wm4 417e256c21 vo_vdpau: fix frame scheduling if display FPS is unknown
Pretty stupid: vo_get_vsync_interval() returns a negative value if the
display FPS is unknown (e.g. xrandr not compiled), and the comparison
whether the value is below 0 fails later because it's assigned to an
unsigned int.

Regression since commit e3d85ad4.

Also, fix some comments in vo.c.
2015-08-04 19:23:07 +02:00
wm4 e5d3180889 charset_conv: use our own UTF-8 check with ENCA only
Some charsets can look like valid UTF-8, but aren't UTF-8. One example
is ISO-2022-JP. While ENCA apparently likes to get misdetect real UTF-8,
this is not the case with uchardet. uchardet can detect ISO-2022-JP
correctly, but didn't even get to try, because our own UTF-8 check
succeeded. So run the UTF-8 check when using ENCA only.

Fixes #2195.
2015-08-04 18:58:58 +02:00
wm4 3ab6155d21 command: always make video-aspect property accessible
Now it can always be read. Normally returns the value of the video-
aspect option. Writing it sets the option. If the aspect is not forced,
it will attempt to return whatever is the current video aspect.
2015-08-04 18:04:48 +02:00
wm4 ae2f8fd0be command: fix video-aspect property update notification
Fixes #2194.
2015-08-04 18:02:59 +02:00
wm4 fce864acec osc: completely disable if no VO window exists
Fixes relatively excessive CPU usage when paused while playing audio
only.
2015-08-04 17:51:00 +02:00
wm4 2d77818183 command: make auto-deinterlacing output at field rate
This was requested by a user.

The vdpau and vaapi deinterlacers already do this.
2015-08-04 17:51:00 +02:00
wm4 0b1c3e8de2 player: warn against using HLS URLs with --playlist
That just makes no sense, but seems to be a somewhat common user error.

The detection is not perfect. It's conceivable that EXT-X-... headers
are used in normal m3u playlists. After all, HLS playlists are by
definition a compatible extension to m3u playlists, as stupid as it
sounds.
2015-08-04 17:51:00 +02:00
Jehan e7897dfb9b charset_conv: "auto" encoding detection now uses uchardet.
If mpv is not built with uchardet, "enca" is still the fallback default
encoding detection.
2015-08-04 17:51:00 +02:00
wm4 aca591ded3 input.conf: remap d/D keys
Drop d for toggling framedrop. Toggling this is way too special to be at
such a prominent place, and in fact I believe toggling it is pointless.

Remap deinterlacing from D to d. It's relatively useful and non-
destructive.

As suggested in #973 (almost).
2015-08-04 01:04:26 +02:00
wm4 75b1d5043f player: use demux_open_url() to open main files
Instead of opening a stream and then a demuxer, do both at once with
demux_open_url().

This requires some awkward additions to demuxer_params, because there
are some weird features associated with opening the main file. E.g. the
relatively useless --stream-capture features requires enabling capturing
on the stream before the demuxer is opened, but on the other hand
shouldn't be done on secondary files like external subtitles.

Also relatively bad: since demux_open_url() returns just a demuxer
pointer or NULL, additional error reporting is done via demuxer_params.

Still, at least conceptually, it's ok, and simpler than before.
2015-08-04 01:01:09 +02:00
wm4 525ada8c7a stream: remove remaining DVD/BD menu definitions 2015-08-03 23:49:14 +02:00
wm4 c844d57489 stream_bluray: remove menu implementation 2015-08-03 23:49:14 +02:00
wm4 1ef7820e6e stream_dvdnav: rip out lower-level menu implementation
Separate because it might cause regressions.
2015-08-03 23:49:14 +02:00
wm4 f792f56440 player: remove higher-level remains of DVD/BD menu support
Nobody wanted to restore this, so it gets the boot.

If anyone still wants to volunteer to restore menu support, this would
be welcome. (I might even try it myself if I feel masochistic and like
wasting a lot of time for nothing.) But if it does get restored, it
should be done differently. There were many stupid things about how it
was done. For example, it somehow tried to pull mp_nav_events through
all the layers (including needing to "buffer" them in the demuxer),
which was needlessly complicated. It could be done simpler.

This code was already inactive, so this commit actually changes nothing.
Also keep in mind that normal DVD/BD playback still works.
2015-08-03 23:49:14 +02:00
wm4 59d44ecef1 video: unbreak EOF with video-only files that have timestamp resets
Normally when there's a timestamp reset, we make audio resync to make
sure audio and video line up (again). But in video-only mode, just
setting audio to resyncing breaks EOF detection, because there's no code
which would get audio_status out of this bogus state.
2015-08-03 23:09:11 +02:00
wm4 c3803e3254 vo: fix inverted condition
When full_redraw is set, we always need to take the draw_image path. If
it's not set, we can try VOCTRL_REDRAW_FRAME (and fallback to draw_image
if that fails).

Fixes #2184.
2015-08-03 20:21:10 +02:00
wm4 b8591a31e5 audio: fix --end handling (again)
Commit c5818046 fixed one case of audio EOF handling, and caused a new
one. This time, the ao_buffer doesn't actually contain everyting that
should be played - because if --end is used, only a part of it is
played. Of course this is stupid, and it will be changed later. For now,
this smaller change fixes the bug.

Fixes #2189.
2015-08-03 17:02:06 +02:00
wm4 bbbb2d9723 charset_conv: fix switched parameters
Fixes #2186.
2015-08-02 18:21:22 +02:00
wm4 aa0157d9b8 image_writer: don't use jpeg baseline, and remove useless jpeg options
The jpeg-optimize and jpeg-baseline options were undocumented, and
they're also pretty useless. There's no reason to ever change them.

Also, don't write jpeg baseline images. This just makes compression
worse for the sake of rather questionable compatibility with ancient
decoders.
2015-08-02 01:10:18 +02:00
wm4 920cf8971e build: make charset detectors dependent on iconv and group them 2015-08-02 00:12:36 +02:00
wm4 a74914a057 charset_conv: add uchardet support
For now, it needs to be explicitly selected. ENCA is still the default.

This assumes uchardet returns iconv names. This doesn't seem to be
always the case, and the result are lots of iconv errors. So
explicitly check for this situation, and print a warning if it
occurs. It's entirely possible that uchardet support is actually
useless, because names are not necessarily iconv-compatible (but
uchardet doesn't seem to document whether it attempts to return
iconv-compatible names if possible).

Fixes #908.
2015-08-02 00:03:29 +02:00
wm4 11f2be2bcc charset_conv: make it possible to return an allocated string as guess
uchardet is written in C++, and thus doesn't appreciate the value of
using static strings, and internally stores the guessed charset as
allocated std::string. Add a minimal hack to deal with this. (I don't
appreciate that the code is potentially harder to understand by
returning either a static or allocated string, but I do appreciate for
not having to litter the existing code with strdups.)
2015-08-01 23:49:37 +02:00
wm4 17fe9d7c0d audio: remove questionable speed change adjustment
time_frame is when the next video frame should be shown. It's normally
overwritten by the video timing code. This also says something about
"nosound mode" (--no-audio today), but at least these days we don't use
it at all if video is disabled.

Remove it; it likely has no function at all.
2015-08-01 22:18:32 +02:00
wm4 d812599851 video: move frame duration code to a separate function
Minor preparation for something else.
2015-08-01 22:17:09 +02:00
wm4 ee58e7cfe5 vo: correctly account for dropped frames
If the framedrop count happens to be incremented with
vo_increment_drop_count() during rendering, these increments were
counted twice, because these events also set in->dropped_frame.
2015-08-01 22:16:52 +02:00
wm4 63ade8a49c terminal: disable terminal foreground state polling
This was originally done for zsh; but zsh can manage the terminal state
correctly when foregrounding/backgrounding applications if you enable it
with "ttyctl -f". So I see no reason to wake up the mpv process once
every second anymore.
2015-08-01 21:30:16 +02:00
wm4 e0c55cbfea audio: remove af_dummy
Was used internally once; has no function anymore.
2015-08-01 21:20:55 +02:00
wm4 efd7100962 old-configure: some adjustments 2015-08-01 21:14:50 +02:00
wm4 5b14ceb315 vo_opengl: minor simplifications
No functional changes.
2015-08-01 21:11:38 +02:00
wm4 41101c2996 win32: revert wchar_t changes
Revert "win32: more wchar_t -> WCHAR replacements"
Revert "win32: replace wchar_t with WCHAR"

Doing a "partial" port of this makes no sense anymore from my
perspective. Revert the changes, as they're confusing without
context, maintenance, and progress. These changes were a bit
premature anyway, and might actually cause other issues
(locale neutrality etc. as it was pointed out).
2015-08-01 21:09:11 +02:00
wm4 fefac2c941 win32: more wchar_t -> WCHAR replacements
This was essentially missing from commit 0b52ac8a.

Since L"..." string literals have the type wchar_t[], we can't use them
for UTF-16 strings. Use C11 u"..." string literals instead. These have
the type char16_t[], but we simply assume char16_t is the same
underlying type as WCHAR. In practice, they're both unsigned short.

For this reason use -std=c11 on Windows. Since Windows is a "special"
environment (we require either MinGW or Cygwin), we don't need to worry
too much about compiler compatibility.
2015-07-30 21:50:11 +02:00
wm4 c8fab7cc7b vo_direct3d: create multithreaded IDirect3DDevice9
A user complains that it leads to the dxva driver failing, leading to
messages like this:

[ffmpeg/video] h264: Failed to execute: 0x8007000e
[ffmpeg/video] h264: hardware accelerator failed to decode picture

Reportedly, this happens only with vo_direct3d, not with vo_opengl. The
only difference is that vo_direct3d attempts to share the D3D device
with the decoder. Possibly the error is that the device in the VO is not
created with D3DCREATE_MULTITHREADED. Change this.

Probably fixes #2178.
2015-07-30 21:26:42 +02:00
wm4 c6b5645991 TOOLS: remove youtube-starttime.lua
Obsolete due to native youtube-dl start time support.
2015-07-29 13:23:12 +02:00
Ricardo Constantino 81bfe4da8f ytdl: get start_time 2015-07-29 13:20:09 +02:00
Ricardo Constantino 794dbd847a ytdl: print command in debug mode 2015-07-29 13:20:06 +02:00
wm4 15f97f05b9 demux_playlist: skip hidden directories
The user probably doesn't want these. Conveniently, this also skips the
unwanted "." and ".." entries.

(This code is triggered if the input stream is a directory - and it's in
demux_playlist.c because it's convenient.)
2015-07-29 00:13:48 +02:00
wm4 f2bba55e01 command: let track properties return option value in idle mode
In idle mode (no file playing), the track properties such as vid/sid/aid
should return the option setting, instead of the value "no".
2015-07-29 00:09:44 +02:00
wm4 0b52ac8a78 win32: replace wchar_t with WCHAR
WCHAR is more portable. While at least MinGW, Cygwin, and MSVC actually
use 16 bit wchar_t, Midipix will have 32 bit wchar_t. In that context,
using WCHAR instead is more portable.

This affects only non-MinGW parts, so not all uses of wchar_t need to
be changed. For example, terminal-win.c won't be used on Midipix at
all. (Most of io.c won't either, so the search & replace here is more
than necessary, but also not harmful.)

(Midipix is not useable yet, so this is just preparation.)
2015-07-29 00:01:32 +02:00
wm4 7d889fbdd0 video: move up vo_frame setup 2015-07-28 23:54:39 +02:00
wm4 f15e652dd4 vo_opengl: framebuffers work under GLES 2
They are not entirely full-featured in GLES 2, but they appear to
provide all we need. Thus we can enable them.
2015-07-27 23:27:49 +02:00
wm4 2cfd87ab15 vo_opengl: slightly more informative message when disabling scalers 2015-07-27 23:18:19 +02:00
wm4 b3468d53c7 win32: pthread: don't play dirty tricks for mutex init
We used double-checked locking on pthread_mutex_t.requires_init in order
to lazily initialize static mutexes (since CRITICAL_SECTION has no
native way to do this). This was kind of unclean: we relied on MSVC
semantics for volatile (which apparently means all accesses are weakly
atomic), which is not such a good idea since mpv can't even be compiled
with MSVC.

Since it's too much of a pain to get weak atomics, just use INIT_ONCE
for initializing the CRITICAL_SECTION. Microsoft most likely implemented
this in an extremely efficient way. Essentially, it provides a mechanism
for correct double-checked locking without having to deal with the
tricky details. We still use an extra flag to avoid calling it at all
for normal locks.

(To get weak atomics, we could have used stdatomic.h, which modern MinGW
provides just fine. But I don't want this wrapper depend on MinGW
specifics if possible.)
2015-07-27 22:59:38 +02:00
wm4 3452f9aeac win32: add portable config mode
See manpage additions.

The main reason for adding this is that we can't guess whether the user
wants his config in his Windows profile or not. The user basically has
to tell mpv what should be done, and the "portable_config" directory
does this implicitly.

Fixes #2042 (approximately).
2015-07-27 21:48:30 +02:00
wm4 51ca8a4b3e vo_rpi: determine and return display refresh rate
Reverse engineered from tvservice.c.
2015-07-27 21:09:24 +02:00
shdown 5c8dd832bb audio: fix restoring volume
Was broken by 68bbab0e42, which changed
the number of fields to scan, but not the expected return value.
2015-07-27 15:07:51 +02:00
wm4 1e91750c73 video: always decode at least 2 frames in advance
Remove the exception for decoding only 1 frame if VO framedrop is
disabled. This was originally done to be able to test potential
regressions when we enabled VO framedrop and decoding 2 frames by
default. It's not needed anymore.
2015-07-26 21:44:57 +02:00
wm4 77a9265561 Copyright: mention that more liberal licenses are ok too
In fact, some source files do this.
2015-07-26 21:44:57 +02:00
wm4 68d5e7a986 vo_opengl: minor cleanup to hwdec texture setting code
Instead of special-casing hwdec in the place where the video textures
are used, just set the textures in the image upload function. The
renderer code doesn't need to know whether hwdec interop is used at all.
2015-07-26 21:44:57 +02:00
Stefano Pigozzi a3a453b69b build: remove useless class 2015-07-26 15:00:47 +02:00
wm4 616d1510a7 manpage: document --audio-channels=auto caveats
This is an unfortunate fact of life. Maybe making this the default
wasn't such a good idea after all.

Also update etc/example.conf. It used an obsolete alias for "auto".
2015-07-25 22:44:06 +02:00
wm4 95b930f866 Require contributions in LGPLv2.1+
As suggested in #2033.

Additionally, change "LGPLv2+" to "LGPLv2.1+". Since this was always
used with the "and later" phrase, this doesn't require any further
discussion.

Also clarify that the "+" means "or later". This should be clear to
anyone with a brain, but you never know with copyright.
2015-07-24 23:54:51 +02:00
wm4 bdc60daffa vo_opengl: remove legacy GL detection
This detected whether an OpenGL context still provided legacy OpenGL if
the OpenGL version is modern (>= 3.0). This was actually only needed for
vo_opengl_old, because it relied on legacy functions. Since it's gone,
this code isn't needed either.

(Also, the removed comment about OpenGL 3.0 was wrong: you could just
query GL_CONTEXT_FLAGS and see if the forward compatible bit was set.)
2015-07-24 23:34:43 +02:00
wm4 9f65629bd0 audio: remove an unused parameter 2015-07-24 17:27:40 +02:00
wm4 c581804603 audio: fix EOF state with --keep-open
In paused mode, we never entered the audio EOF state. This shows e.g. in
--keep-open mode, which will not set the eof-reached property correctly.

Regression since commit c06cd1b9. This commit was the wrong fix. We need
to respect the buffer state, and pausing has nothing to do with this.

Fixes #2167.
2015-07-24 17:27:04 +02:00
wm4 3cbf68b470 command: add property indicating per-file options
Fixes #2165, more or less.
2015-07-23 22:59:04 +02:00
Niklas Haas 86a60a4dd2 vo_opengl: fix scale=oversample's threshold calculations
This resulted in wrong behavior for values of scale-param1 between 0.0
and 0.5 (not inclusive).
2015-07-23 21:53:03 +02:00
wm4 281c21b7f1 video: don't restrict --vd-lavc-threads to a maximum of 16
Only do it when the number of threads is autodetected, as more than 16
threads are still considered not recommended. (libavcodec prints a
warning.)
2015-07-23 17:17:26 +02:00
wm4 5b47836082 manpage: fix typo 2015-07-23 17:13:37 +02:00
wm4 b492720c7c Revert "vo_opengl: make the size of interpolation textures exact"
This reverts commit fb8d158366.

Reallocating the FBOs on every resize is very slow. It affects resizing
the window, as well as changing the video size itself with e.g.
panscan. Since the original change was done based on a single user
complaint, but the change itself caused a lot of complaints, we decided
to just revert it.
2015-07-22 23:57:09 +02:00
wm4 55879a8c0f cache: make backbuffer size configurable
Allow setting an arbitrary amount, instead of the fixed 50%.

This is nto striclty backwards compatible. The defaults don't change,
but the --cache/--cache-default options now set the readahead portion.
So in practice, users who configured this until now will see the
double amount of cache being used, _plus_ the 75MB default backbuffer
will be in use.
2015-07-22 23:55:10 +02:00
wm4 63d112746d cache: fix backbuffer logic
Currently, this is perfectly equivalent, because back_size is hardcoded
to buffer_size/2. But this fixes the logic for the case the back_size
can be configured freely.
2015-07-22 23:30:05 +02:00
ChrisK2 aeb99f2718 TOOLS: unbreak osxbundle.py
broekn by 739d345d6c
2015-07-21 23:04:06 +02:00
wm4 a357d39369 video: always re-probe auto deint filter on filter reconfig
If filters are disabled or reconfigured, attempt to remove and probe the
deinterlace filter again. This fixes behavior if e.g. a software deint
filter was automatically inserted, and then hardware decoding is enabled
during playback. Without this commit, initializing hw decoding would
fail because of the software filter; with this commit, it'll replace it
with the hw deinterlacer instead.
2015-07-21 21:54:15 +02:00
wm4 e5fac76b3b vf_scale: cleanup log messages
In particular, get rid of the EUSERBROKEN message.
2015-07-20 21:16:37 +02:00
wm4 4a1657da01 vo: minor simplification for queue size handling
Instead of calling it "future frames" and adding or subtracting 1 from
it, always call it "requested frames". This simplifies it a bit.

MPContext.next_frames had 2 added to it; this was mainly to ensure a
minimum size of 2. Drop it and assume VO_MAX_REQ_FRAMES is at least 2;
together with the other changes, this can be the exact size of the
array.
2015-07-20 21:12:46 +02:00
Niklas Haas 6f7d04be21 vo_opengl: add temporal-dither-period option
This was requested multiple times by users, and it's not hard to
implement and/or maintain.
2015-07-20 19:32:58 +02:00
wm4 b11fd7fd2d demux_mkv: remove unnecessary code
This did nothing. It's a leftover from ancient times.
2015-07-20 13:04:06 +02:00
wm4 3252d352c9 demux_mkv: parse FLAC channel layouts
Handle a relatively recently introduced hack, that allows FLAC audio to
have arbitrary channel layouts, instead of just the predefined fixed
ones. This is actually supported by FFmpeg, but since the demuxer
(instead of the decoder) handles this in FFmpeg, we need to add special-
code to our mkv demuxer.

(The way FFmpeg does this seems a bit backwards, since now every demuxer
for a format that can handle FLAC needs to contain this logic as well.)

The FLAC hack is relatively terrible: we need to parse the FLAC headers,
look for a VorbisComment, parse the VorbisComment, and then retrieve
the magic WAVEFORMATEXTENSIBLE_CHANNEL_MASK entry. But the hack is
officially endorsed, as the official FLAC tools use it. (Although I
couldn't find a trace of it in the format specification. Should I be
surprised?)
2015-07-20 12:56:35 +02:00
Niklas Haas b0d1ac93cf vo_opengl: make oversample the default for opengl-hq as well
This was supposed to have changed back when oversample was reintroduced
in 3007250. Fixes #2155.
2015-07-20 09:11:54 +02:00
wm4 253f6f1a95 af_lavrresample: always reinit resampler on filter reinit
This was a minor optimization to potentially avoid resampler
reconfiguration when the filter is reinitialized. But filter
reinitialization is a rare event, and the case when no reconfiguration
is needed is even rarer. As such, this is an unnecessary micro-
optimization and only adds potential for bugs.
2015-07-19 22:54:03 +02:00
wm4 8749900b5f af_lavrresample: don't unnecessarily print remix message
This message bloats verbose log output if e.g. audio speed is frequently
readjusted, such as when syncing audio to video. So don't print the
message if only speed is changed. (This case requires reconfiguration,
but can't change the input/output channel maps.)

Also do not print the message if no remixing is done at all.
2015-07-19 22:50:08 +02:00
Philip Sequeira 2cf019ed70 TOOLS/zsh.pl: die loudly if mpv fails to run 2015-07-19 22:04:45 +02:00
wm4 47a62059a9 vf_vapoursynth: relicense to LGPL 2.1+
This was requested by someone.

All code was written by myself; some minor changes by 2 contributors who
agreed to general LGPL relicensing. 1 line of code is by someone unknown
who possibly wasn't asked (setting the "display_fps" variable), and
which can be reasonably ignored as it makes up only 0.1% of the file.
2015-07-19 00:03:20 +02:00
Stefano Pigozzi 532508823c build: update waf to 1.8.12 2015-07-18 21:37:30 +02:00
deuiore 7984fde8de command: add track-list/N/audio-channels property
Signed-off-by: wm4 <wm4@nowhere>

(With some heavy modifications from the original patch.)
2015-07-18 19:05:25 +02:00
Niklas Haas fb8d158366 vo_opengl: make the size of interpolation textures exact
I still have no idea why this is needed, maybe some weird off-by-one
in some shitty driver? Either way, the difference for a working setup
shouldn't be too major, the most noticeable effect would be somewhat worse
performance when resizing the video during playback with interpolation
enabled using the mouse.

That's a specific enough side effect for me to not care as much about it.

Fixes #1814.
2015-07-18 18:41:12 +02:00
wm4 050c529e9a screenshot: don't write PNG colorspace tags by default
Generates too much discussion and confusion.

Fixes #2051.
2015-07-18 18:33:54 +02:00
wm4 57043d9269 sub: add option for stretching image subtitles to screen
Probably makes users happy who want bitmap subtitles to show up in the
screen margins, and stops them from doing idiotic crap with vf_expand.

Fixes #2098.
2015-07-18 14:36:17 +02:00
wm4 5594333337 av_log: remove dumb shit
It's the user's fault if he/she/it does something that is not
recommended.

Fixes #2110.
2015-07-18 14:21:31 +02:00
wm4 bad3996d85 vo_opengl: cleanup frame reupload logic
There are some situations when redrawing is requested, but the current
frame was deleted. This could happen when switching e.g. hw decoding
mid-stream.

Separate uploading/drawing and fix the condition.
2015-07-17 23:26:06 +02:00
Stefano Pigozzi 7ba403002f build: fix windows compilation after clean
broken since 4730e0aaba
2015-07-17 09:41:09 +02:00
Kevin Mitchell ebdbb4f24c TOOLS: make autodeint detect telecine in parallel
This avoids having to rewind the video for a second telecine detection pass.
2015-07-16 16:14:58 -07:00
wm4 968bd3df3b vo_opengl: refactor queue configuration
Just avoid some code duplication. Also, gl_video_set_options() having a
queue size output parameter is weird at best. While I don't appreciate
that this commit suddenly requires gl_video.c to deal with vo.c directly
in a special case, it's simply the best place to put this function.
2015-07-16 22:43:40 +02:00
wm4 bb9717a630 vo: fix number of future frames
That was 2 too many.

Also fix a documentation comment.
2015-07-16 22:10:08 +02:00
Stefano Pigozzi 4730e0aaba build: make mpv.rc depend on version.h 2015-07-15 15:24:31 +02:00
wm4 15954c36ca vo_opengl: reject future images in different formats
The VO will be provided with future frames even if the format changes
mid-stream. This caused a crash if these frames were actually used (i.e.
interpolation mode was enabled).

Fixes a crash when deinterlacing is toggled during playback, and the
deinterlacer changes the stream format (as it can happen e.g. if the
decoder outputs nv12, which in turn happens with hw decoding).

(On a side note, future frames are always non-NULL. Also, the current
frame is of course always in the correct format.)
2015-07-15 14:59:26 +02:00
wm4 7ef8f457a8 vaapi: destroy derived VAImage after each use
Appears to be required by some hardware. Whatever.
2015-07-15 13:30:32 +02:00
wm4 bc68794acc vo_vaapi: drop unused field 2015-07-15 13:27:38 +02:00
wm4 50bd2807ad vaapi: don't assume vaQueryImageFormats() returns sorted list
vaQueryImageFormats() returns a randomly ordered list - so we shouldn't
assume the first format on the list which works is the best. This
effectively switches to nv12 instead of yuv420p on some drivers.

We handle this by reusing va_to_imgfmt[], and ordering it by preference.
We hardcode that GPUs prefer nv12 pver yuv420p. In theory we could do
complicated probing (allocate dummy surface + use vaDeriveImage on it,
then retrieve the FourCC) - but all things which could break assumption
in the future are not supported yet (like 10 bit or 4:4:4), so this is
fine.
2015-07-15 13:27:25 +02:00
wm4 e3e20f1431 Revert "vaapi: remove vaDeriveImage() code path"
This reverts commit d660e67be9.

Fixes #2123.
2015-07-15 13:15:58 +02:00
wm4 d1c37c0e29 vaapi: allow allocating additional surfaces during decoding
Fixes problems with --vo=opengl:interpolation. The issue here is that
vo_opengl retains more surfaces than what was preallocated for the
decoder. Until now, we just explicitly failed to decode frames for which
no additional surfaces are available. Since modern drivers usually are
fine with not "registering" surfaces before the decoder is created, just
allow allocating additional surfaces if needed.

(We also could probably recreate the HW decoder, since the HW decoder
should be stateless. But let's try to avoid raising the overall
complexity of the code.)
2015-07-15 12:37:28 +02:00
wm4 423a1a0f6c vo_opengl: simplify
After recent changes, there is no reason why gl_video_set_image() should
exist anymore. So merge it back into gl_video_upload_image().
2015-07-15 12:22:49 +02:00
wm4 27708eee81 player: show larger cache sizes in MB on status line 2015-07-14 23:23:23 +02:00
wm4 739d345d6c build: don't make version.sh create version.h by default
You could actually run version.sh, and then the waf build system could
accidentally pick up the generated (and most likely stale) version.h.
2015-07-14 23:11:06 +02:00
Philip Langdale e1ab9b905f vf_vdpaupp: Don't crash when evaluating interlacing of NULL mpi
The interlaced frame test needs to be aware that the input mpi might be
NULL - this happens at the end of a stream when the input frames have
all been submitted but frames still need to be drained from the
decoder.
2015-07-14 11:10:04 +02:00
wm4 f3e8108c78 README: remove dead links to mailing lists
These were deleted due to inactivity.

Fixes #2135.
2015-07-14 00:12:14 +02:00
wm4 176470b906 player: add missing \n to a message 2015-07-13 23:55:26 +02:00
wm4 905d5efded manpage: fix typo
The (...) was closed, but never opened.
2015-07-13 23:52:48 +02:00
wm4 8771838408 sub: call ass_set_fonts() only once
ass_set_fonts() is called by mp_ass_configure_fonts(), which was called
every time a subtitle renderer was initialized. I'm not sure why this
was done - I can't find a good reason, and most likely there's none.

However, it did cause problems with an experimental libass branch. It
crashed some time after switching to a second subtitle track. The branch
will hopefully be merged soon, and it seems unlikely that libass wants
to fix its problems with its ridiculous API (rather it should normalize
its API so that the issue doesn't happen in the first place), so just
apply this change. It makes our code simpler too.
2015-07-13 23:11:54 +02:00
wm4 57efe9089c player: extend --hls-bitrate option
Fixes #2116.
2015-07-13 13:34:58 +02:00
wm4 0d35c78a6c player: put --term-playing-msg in a separate log category
Fixes #1983.
2015-07-13 13:06:09 +02:00
wm4 9b15c99aa1 demux: handle Matroska-style replaygain tags as well
Matroska doesn't follow the usual ReplayGain conventions, and doesn't
distinguish between track/album values.

Fixes #2128.
2015-07-12 19:33:34 +02:00
wm4 f052165dbf demux: refactor replaygain tag handling
For the following commit. Also print the replaygain values in verbose
mode.
2015-07-12 19:31:57 +02:00
Stefano Pigozzi ba525e68c4 bootstrap: change waf primary mirror
Requested by waf's developer. The ftp mirror is going to be closed down in
the short future.
2015-07-12 10:09:50 +02:00
Stefano Pigozzi 78e771554c build: fix version.h creation
Previous code did not retrigger a relink when version.h changed since it
didn't use a waf task.
2015-07-12 10:09:49 +02:00
Philip Sequeira 4a4f788a68 player: use exit code 0 by default for quit, 4 for signals, etc.
Default key bindings in encoding mode also use code 4, because scripts
will probably want to fail if encoding is aborted (leaving an
incomplete file).
2015-07-11 23:46:49 +02:00
wm4 898855cc0d vo_opengl: reduce verbose output
Outputting the detected OpenGL features was useless and redundant with
the extension loading output.

Also, remove MPGL_CAP_3D_TEX from OpenGL(ES) 3.0. This block didn't
include the glTexImage3D function, so that was pointless and couldn't
have worked. The OpenGL 2.1 block does it correctly.
2015-07-11 20:01:28 +02:00
Philip Langdale 5776b0c940 vo_vdpau: Implement rotation support
VDPAU has explicit support for rotating surfaces, and it is far less
expensive than using the normal rotation filter (which would require
reading video frames back into system memory), it is desirable to
implement the VO rotation capability.

To do this, we need to render the video frames to an output surface,
without rotation, and then render from that surface to the final
output surface to apply the rotation. It is important that the
intermediate surface is the same size as the final one (only not
rotated) so that hqscaling can be applied if requested by the user.

(hqscaling is a mixer capability and so takes effect when the video
surface is rendered to an output surface)

Finally, we must remember to explicitly clear the final output
surface as VDPAU only auto-clears output surfaces when rendering video
surfaces.
2015-07-11 20:01:28 +02:00
Niklas Haas 3007250824 vo_opengl: reimplement tscale=oversample
Closes #2102.
2015-07-11 14:00:43 +02:00
Philip Langdale 4b0b9b515b vf_vdpaurb: Add a new filter for reading back vdpau decoded frames
Normally, vdpau decoded frames are passed directly to a suitable
vo (vo_vdpau or vo_opengl) without ever touching system memory. This
is efficient for output purposes, but prevents any of the regular
filters from being used with such frames.

This new filter implements a read-back step to pull the frames back
into system memory where they can be acted on by other filters.
Eventually the frames will be sent to the vo as if they were normal
software-decoded frames.

Note that a vdpau compatible vo must still be used to ensure that
the decoder is properly initialised.

Signed-off-by: wm4 <wm4@nowhere>
2015-07-11 10:44:34 +02:00
wm4 8e82a64f56 player: parse and expose m3u playlist titles
Requested. Closes #2100.
2015-07-10 21:22:35 +02:00
wm4 c2b61876c4 video: don't force video refresh if video is restarting 2015-07-10 18:07:39 +02:00
wm4 59b64ceb79 video: add a way to disable automatic stereo conversion
Fixes #2111.
2015-07-10 18:04:34 +02:00
wm4 140273cdec vf_stereo3d: drop internal implementation
Leave the libavfilter wrapper only.
2015-07-10 18:03:38 +02:00
wm4 01ce203ed7 stream_file: remove an indirection
Remove the "fd" local variable, and always use "p->fd" directly.
2015-07-10 12:47:53 +02:00
wm4 4c04f74a50 stream_file: cosmetics: shorten variable name
Can't be bothered to type this much.
2015-07-10 12:45:49 +02:00
wm4 707fe102b6 gl_hwdec: change wording in verbose message 2015-07-10 12:22:24 +02:00
wm4 4e76782630 player: refactor chapter seek code
mp_seek_chapter() had only 1 caller. Also the code was rather
roundabout; the entire function can be compressed to 5 lines of code.
(The new code is functionally the same - "mpctx->last_chapter_seek =
-2;" was effectively a dead assingment.)
2015-07-10 12:11:14 +02:00
wm4 a46de35abb client API: fix mpv_get_property_async() string case
The logic for this code didn't survive the previous refactor. It always
crashed in async mode.

Fixes #2121.
2015-07-10 11:03:09 +02:00
Ben Boeckel 731fc5b816 stream_file: initialize fd
Use the fd variable and delay assignment to priv->fd to mirror other
branches of the if/else tree.
2015-07-09 23:04:06 +02:00
wm4 f3d06e3e91 demux_mkv: improve video duration detection heuristic
Extend the --demuxer-mkv-probe-video-duration behavior to work with
files that are partial and are missing an index. Do this by finding a
cluster 10MB before the end of the file, and if that fails, just read
the entire file. This is actually pretty trivial to do and requires only
5 lines of code.

Also add a mode that always reads the entire file to estimate the video
duration.
2015-07-09 22:47:41 +02:00
wm4 d23d9dc394 stream_file: add fd:// protocol 2015-07-09 15:51:31 +02:00
wm4 23220db924 player: disable seeking even if the cache is enabled
Until now, if a stream wasn't seekable, but the stream cache was enabled
(--cache), we've enabled seeking anyway. The idea was that at least
short seeks would typically fall within the cache. And if not, the user
was out of luck and terrible things happened. In other words, it was
unreliable.

Be stricter about it and remove this behavior. Effectively, this will
for example disable seeking in piped data.

Instead of trying to be clever, add an --force-seekable option, which
will always enable seeking if the user really wants it.
2015-07-08 22:04:35 +02:00
wm4 15581f2209 player: never overwrite stop_play field
This is a real pain: if a quit command is received, it's set to PT_QUIT.
And then other code could overwrite it, making it not quit. The annoying
bit is that stop_play is written and read in many places. Just not
overwriting it unconditionally seems to be the best course of action.
2015-07-08 21:31:31 +02:00
wm4 0be07e1d86 input: fix exit code for quit-watch-later command
It should have the same default as the "quit" command.
2015-07-08 19:01:56 +02:00
wm4 9aadc0199f command: allow changing deinterlace property any time
Don't require video decoding to be active.
2015-07-08 15:24:34 +02:00
wm4 ef7278b4fd vf_vdpaupp: don't attempt to deinterlace progressive frames 2015-07-08 15:14:38 +02:00
wm4 d2c05cb559 mp_image: fix vf_vdpaupp references
Some code called by vf_vdpaupp.c calls mp_image_new_custom_ref(), but
out of convenience doesn't reset the buffers. Make this behavior ok.
(The assert() was there to catch usage errors, but the same error could
already happen before the refcount changes were made, so the check is
not overly helpful.)

Fixes #2115.
2015-07-08 14:48:17 +02:00
wm4 db2268d5b1 vaapi: drop compatibility crap and vo_vaapi deinterlacer
Drop libva versions below 0.34.0. These are ancient, so I don't care.

Drop the vo_vaapi deinterlacer as well. With 0.34.0, VPP is always
available, and deinterlacing is done with vf_vavpp.

The vaCreateSurfaces() function changes its signature - actually it did
in 0.34.0 or so, and the <va/va_compat.h> defined a macro to make it use
the old signature.
2015-07-08 14:48:11 +02:00
wm4 4781f9e69a vf_vavpp: don't attempt to deinterlace progressive frames 2015-07-08 14:48:11 +02:00
wm4 9620e37d6a vaapi: increase number of additional surfaces
Sometime recently, hardware decoding started to fail if h264 with full
reference frames was decoded, and --vo=vaapi was used. VAAPI requires
registering all surfaces that the decoder will ever use in advance, so
if the playback chain uses more surfaces than originally allocated, we
fail and drop back to software decoding.

I'm not really sure why or when this started happening. Commit 7b9d7265
for one is not the cause - it can be reproduced with earlier commits. It
also seems to be timing dependent. Possibly it has to do with the way
vo.c retains previous surfaces, and the way they can be queued/unqueued
asynchronously.

Increasing the number of reserved additional surfaces by 1 fixes it.

(Though I have no idea where exactly all these surfaces are being used.
Or rather, _when_.)
2015-07-08 12:18:29 +02:00
wm4 0ebf5979d1 command: make deinterlace property use interlaced-only yadif mode 2015-07-07 15:19:40 +02:00
wm4 25755f5fe7 vf_yadif: expose interlaced frame mode
Also remove the enabled suboption, which did nothing. (It was probably
broken at some point.)
2015-07-07 15:18:56 +02:00
wm4 92727e7332 vo_opengl_cb, vo_opengl: add option for preloading hwdec context
See manpage additions. This is mainly useful for vo_opengl_cb, but can
also be applied to vo_opengl.

On a side note, gl_hwdec_load_api() should stop using a name string, and
instead always use the IDs. This should be cleaned up another time.
2015-07-07 15:05:32 +02:00
wm4 1d29177c5c options: cleanup hwdec name mappings
Now there's a "canonical" table for mapping the names, that other code
can use, without having to rely too much on option code magic.

Also, use the central HWDEC constants, instead of magic values. (There
used to be semi-ok reasons to do this, but now it makes no sense
anymore.)
2015-07-07 15:05:32 +02:00
wm4 dc33eb56f4 vo_opengl_cb: drop frames eagerly if frames are not rendered
libmpv users might stop calling the frame render callback for stupid
reasons, at which point video frames would pile up.
2015-07-07 13:59:33 +02:00
wm4 459124f66f af: fix behavior with pathologic filter chains
Some filter chains require a huge number of auto-inserted conversion
filters. There is an overly stupid safeguard against infinite filter
insertions, which counts the number of conversion filters inserted. This
triggered accidentally in this case. Fix by resetting this counter after
a non-conversion filter was successfully configured.
2015-07-07 13:24:11 +02:00
wm4 daf32e2d2d sub: fix srt subs and other cases
Oops.
2015-07-07 01:26:26 +02:00
wm4 782c7acd16 player: add missing include directive 2015-07-06 22:28:28 +02:00
wm4 385febe276 sub: protect ASS_Renderer state
Each subtitle track gets its own decoder instance (sd_ass). But they use
a shared ASS_Renderer. This is done mainly because of fontconfig.
Initializing fontconfig is very slow when using it with memory fonts, so
there's a practical need to cache this memory font state, which is done
by not creating separate ASS_Renderers. This is very dirty and very
evil, but we probably can't get rid of it any time soon.

The shared ASS_Renderer was not properly synchronized. While the program
logic guarantees that only one sd_ass instance is visible at a time,
there are other interactions that require synchronization. In
particular, I suspect concurrent execution of mp_ass_configure_fonts()
and sd_ass.get_bitmaps cause issues in a newer libass development
branch.

So here's a shitty hack that hopefully fixes things, hopefully only
until libass becomes less dependent on fontconfig.
2015-07-06 21:55:37 +02:00
wm4 dcd167ca37 dxva2: fix handling of cropped video
Basically, we need to make sure to allocate enough data for the pretty
dumb copy_nv12 function. (It could be avoided by making the function
less dumb, but this fix is simpler.)
2015-07-06 21:25:07 +02:00
wm4 7c032bde3e ao_coreaudio: fix device latency, share the code
ao_coreaudio (using AudioUnit) accounted only for part of the latency -
move the code in ao_coreaudio_exclusive to utils, and use that for the
AudioUnit code.

(There's still the question why CoreAudio and AudioUnit require you to
jump through hoops this much, but apparently that's how it is.)
2015-07-06 17:49:28 +02:00
wm4 a56a7f3e8c ipc: fix undefined behavior in some error cases
goto jumping over an initialization.
2015-07-06 00:08:29 +02:00
wm4 e4b963e643 ao_coreaudio_exclusive: continue even if setting physical format fails
Makes it work with (apparently) crappy drivers, which refuse to set the
physical format in some cases.
2015-07-06 00:04:20 +02:00
wm4 7b9d726588 video: replace our own refcounting with libavutil's
mpv had refcounted frames before libav*, so we were not using
libavutil's facilities. Change this and drop our own code.

Since AVFrames are not actually refcounted, and only the image data
they reference, the semantics change a bit. This affects mainly
mp_image_pool, which was operating on whole images instead of buffers.
While we could work on AVBufferRefs instead (and use AVBufferPool),
this doesn't work for use with hardware decoding, which doesn't
map cleanly to FFmpeg's reference counting. But it worked out. One
weird consequence is that we still need our custom image data
allocation function (for normal image data), because AVFrame's uses
multiple buffers.

There also seems to be a timing-dependent problem with vaapi (the
pool appears to be "leaking" surfaces). I don't know if this is a new
problem, or whether the code changes just happened to cause it more
often. Raising the number of reserved surfaces seemed to fix it, but
since it appears to be timing dependent, and I couldn't find anything
wrong with the code, I'm just going to assume it's not a new bug.
2015-07-05 23:56:00 +02:00
wm4 34b223d730 mp_image: make image writeable before overwriting palette
This is an obscure but theoretically possible bug.
2015-07-05 23:55:47 +02:00
wm4 95424517a2 vo: free frames before killing VO
This caused issues with hardware decoding. The VOs by definition dictate
the lifetime of the hardware context, so no surface allocations must
survive the VO. Fixes assertions on exit with vdpau.
2015-07-04 17:27:13 +02:00
wm4 a4d5c19355 ao_coreaudio_exclusive: fix some verbose output 2015-07-04 17:25:12 +02:00
wm4 5728295dab timer: fix a corner case on clock changes
It's conceivable that the OS time source is subject to clock changes.
The time could jump back to before when mpv was started, which would
cause mp_time_us() to return values smaller than 1. This is unexpected
by the code and could trigger assertions. If there's no monotonic time
source there's not much we can do anyway, so just sanitize the return
value. It will cause strange behavior until the "lost" time offset has
passed, but if you make such huge changes to the system clock while
everything is running, you're asking for trouble anyway.

(Normally we try to get a monotonic time source, though. This problem
sometimes happened on Windows when compiled without winpthreads, when
the code was falling back to gettimeofday(). This was already fixed by
always using another method.)
2015-07-04 17:24:10 +02:00
James Ross-Gowan f544bcf105 win32: use QueryPerformanceCounter for timing
clock_gettime is implemented in winpthreads, so it's unavailable when
mpv is compiled with its internal pthreads implementation. This makes
mp_raw_time_us fall back to gettimeofday(), which can cause an assert
failure in mp_add_timeout() when the system clock is changed. Use
QueryPerformanceCounter instead.

The clock_gettime(CLOCK_MONOTONIC) implementation in winpthreads uses
QueryPerformanceCounter anyway, so there shouldn't be any change in
behaviour.
2015-07-04 15:54:14 +02:00
Preston Hunt 029da5abce ipc: add request_id to json
If the request contains a "request_id", copy it back into the
response. There is no interpretation of the request_id value by mpv; the
only purpose is to make it easier on the requester by providing an
ability to match up responses with requests.

Because the IPC mechanism sends events continously, it's possible for
the response to a request to arrive several events after the request was
made. This can make it very difficult on the requester to determine
which response goes to which request.
2015-07-03 22:26:54 +02:00
wm4 ed44f21289 manpage: fix dwmflush parameter 2015-07-03 19:40:15 +02:00
wm4 31f2cd03d0 vo: set correct frame parameters on redraw 2015-07-03 19:35:39 +02:00
wm4 fc79fd0474 ao: don't pass along AO arguments when redirecting
Only causes problems.
2015-07-03 19:28:01 +02:00
wm4 514af9fbd1 ao_coreaudio: add exclusive suboption 2015-07-03 19:28:00 +02:00
wm4 e9e323f35d ao_coreaudio_exclusive: support PCM
Until now, this was for AC3 only. For PCM, we used AudioUnit in
ao_coreaudio, and the only reason ao_coreaudio_exclusive exists
is that there is no other way to passthrough AC3.

PCM support is actually rather simple. The most complicated
issue is that modern OS X versions actually do not support
copying through the data; instead everything must go through
float. So we have to deal with virtual and physical format
being different, which causes some complications.

This possibly also doesn't support some other things correctly.
For one, if the device allows non-interleaved output only, we
will probably fail. (I couldn't test it, so I don't even know
what is required. Supporting it would probably be rather
simple, and we already do it with AudioUnit.)
2015-07-03 19:28:00 +02:00
wm4 65e3657bc4 ao_coraudio: reject all non-PCM formats
Currently this is equivalent. On the other hand, all audio code should
reject formats that is not in a category known to it.
2015-07-03 19:28:00 +02:00
wm4 74e2c8a6ef ao_coreaudio_utils: reduce spam 2015-07-03 19:28:00 +02:00
wm4 ae3e151b27 ao_coreaudio_utils: fix format back-mapping
Mapping of spdif formats was imperfect. Since the first format on the
list is somehow AAC, it was returned first, which is confusing, because
CoreAudio calls all spdif formats AC3. Since the spdif formats have some
rather arbitrary, reverse mapping the formats didn"t actually work
either. Fix by explicitly ignoring these when spdif is used.

Also, don't forget to set the samplerate in ca_asbd_to_mpformat(), or it
will work only in some cases.
2015-07-03 19:28:00 +02:00
wm4 d4ab91f016 ao_coreaudio_exclusive: do not set ao->bps
This field is basically deprecated or for convenience only, and
this code doesn't need it.
2015-07-03 19:28:00 +02:00
wm4 597657110f ao_coreaudio_exclusive: dump all latency info in verbose mode 2015-07-03 19:28:00 +02:00
wm4 ec21be498f ao_coreaudio_exclusive: factor format selection 2015-07-03 19:28:00 +02:00
wm4 8a20e5306c ao_coreaudio_exclusive: separate out stream selection 2015-07-03 19:28:00 +02:00
wm4 561416597e client API, dxva2: add a workaround for OpenGL fullscreen issues
This is basically a hack for drivers which prevent the mpv DXVA2 decoder
glue from working if OpenGL is in fullscreen mode.

Since it doesn't add any "hard" new API to the client API, some of the
code would be required for a true zero-copy hw decoding pipeline, and
sine it isn't too much code after all, this is probably acceptable.
2015-07-03 16:38:12 +02:00
wm4 b85321d057 vo_direct3d, dxva2: use the same D3D device
Since we still read-back (and don't have hard plans on changing this),
this doesn't have much of an advantage.
2015-07-03 16:04:42 +02:00
wm4 b6dc11810b dxva2: move device creation code
Preparation for the following commit.
2015-07-03 15:42:52 +02:00
wm4 cc51dafa96 vo_opengl: log some more stuff in verbose mode 2015-07-03 15:12:42 +02:00
wm4 5446637e99 av_log: print FFmpeg version
The individual library versionsd are pretty useless. This will actually
tell us at least the git hash or git tag of the FFmpeg build.
2015-07-03 15:11:29 +02:00
wm4 a609877f00 player: simplify reload logic
Instead of only reloading the demuxer, reopen the stream as well.
2015-07-02 14:38:03 +02:00
wm4 a9bbaa5eb2 player: remove automatic DVB channel advancement on no data
For the sake of removing the separate stream/demuxer loading code.

This could probably be reimplemented in some other way, but I have no
DVB hardware for testing. The most preferred way would be making DVB to
not quit, and just rerun the stream selection.
2015-07-02 14:08:22 +02:00
wm4 899dfa957f player: unentangle --stream-dump
The final goal is making opening the demuxer and opening the stream the
same operation.

Stream dumping is a rather uninteresting feature, but has a small
number of vocal users, and it's easy to keep.
2015-07-02 14:02:37 +02:00
wm4 ff25c0ad7d vo_opengl: fix "freezes" after seeking with interpolation on
When seeking to a different position, and seeking takes long, the OSD
might get redrawn. This means that the VO will receive a request to
redraw an old frame using whatever the previous PTS was. This breaks the
interpolation logic: the old frame will be added to the queue, and then
the next frames (with lower PTS if you seeked backwards) are not drawn
as the logic assumes they're past frames.

Fix this by using the non-interpolation code path when redrawing after a
seek reset, and no "real" frame has been drawn yet.

It's a recent regression caused by the redrawing code simplification.
The old code simply sent a VOCTRL for redrawing the frame, and the VO
had to deal with retaining the old frame on its own.

This is a hack as in there's probably a better solution.

Fixes #2097.
2015-07-02 13:18:06 +02:00
wm4 53845d81f5 vo: reset frame timing when redrawing
bother vo_vdpau.c, which actually uses these times.
2015-07-02 13:03:58 +02:00
wm4 dc2b6ab6b7 vo_opengl: X11: don't leak when GL init fails 2015-07-02 00:30:13 +02:00
wm4 89713808ad vo_opengl: X11 EGL: more detailed error reporting 2015-07-02 00:28:25 +02:00
wm4 c169292902 vo_opengl: update EGL code
Use the newer internal GL backend API.
2015-07-02 00:25:30 +02:00
wm4 99bc049745 vo_opengl: remove unused GL API functions 2015-07-02 00:08:17 +02:00
wm4 6afef5839f x11: move GCs and background clearing to vo_xv
vo_xv.c is the only place where these things are used.
2015-07-01 23:55:10 +02:00
wm4 8dff03560a x11: remove clear on map
Less code, and avoids a black flash on start.

In theory it could happen that we map the window, and then don't have a
frame to draw - but mapping the window is done in the exact moment we
have a new frame to display.
2015-07-01 23:46:34 +02:00
wm4 89f05dc7d1 options: fix conversion of flags to strings
This flags stuff tried to be too clever - if there are overlapping flags
(e.g. exclusive or combined flags), the one matching with most bits has
to be chosen.

This fixes logging of the seek command. E.g. "relative" and "absolute"
overlap to make them exclusive, but "relative" was always printed as it
happened to match first.
2015-07-01 23:05:11 +02:00
wm4 e3d85ad46d vo: better magic value for unknown vsync interval
The value 1 is useful in some contexts, but not such a good choice
otherwise.
2015-07-01 22:38:22 +02:00
wm4 03e062d53e vo_opengl_cb: fix interpolation code path 2015-07-01 22:38:13 +02:00
Niklas Haas 8043063275 vo_opengl: fix framestepping/pausing + interpolation
This is not the most theoretically perfect solution, ideally we could
check to see if the frame in question has already been rendered
somewhere in the queue and then avoid re-rendering it, at the cost of a
few extra lines of code. But I don't think the performance trade-off is
dramatic enough here.
2015-07-01 22:38:06 +02:00
wm4 0739cfc209 vo: change internal API for drawing frames
draw_image_timed is renamed to draw_frame. struct frame_timing is
renamed to vo_frame. flip_page_timed is merged into draw_frame (the
additional parameters are part of struct vo_frame). draw_frame also
deprecates VOCTRL_REDRAW_FRAME, and replaces it with a method that
works for both VOs which can cache the current frame, and VOs which
need to redraw it anyway.

This is preparation to making the interpolation and (work in progress)
display sync code saner.

Lots of other refactoring, and also some simplifications.
2015-07-01 22:38:02 +02:00
Niklas Haas f166d12985 vo_opengl: adjust interpolation code for the new video-sync mechanism
This should make interpolation work much better in general, although
there still might be some side effects for unusual framerates (eg. 35 Hz
or 48 Hz). Most of the common framerates are tested and working fine.
(24 Hz, 30 Hz, 60 Hz)

The new code doesn't have support for oversample yet, so it's been
removed (and will most likely be reimplemented in a cleaner way if
there's enough demand). I would recommend using something like robidoux
or mitchell instead of oversample, though - they're much
smoother for the common cases.
2015-07-01 22:37:55 +02:00
wm4 c5e3613bba video: pass vsync offset to VO
For now, this is trivial (and actually redundant). The future display
sync code will make better use of it. The main point is that the new
internal API pretty much makes this transparent to the vo_opengl
interpolation code.
2015-07-01 22:37:51 +02:00
wm4 41ad9d8924 video: pass future frames to VO
Now the VO can request a number of future frames with the last parameter
of vo_set_queue_params(). This will be helpful to fix the interpolation
code.

Note that the first frame (after playback start or seeking) will usually
not have any future frames (to make seeking fast). Near the end of the
file, the number of future frames will become lower as well.
2015-07-01 22:37:46 +02:00
wm4 7faa80ace8 af_lavrresample: log actual channel layout conversions
With all the reordering etc. that can go on in this filter, it's useful
to see what upmix/downmix it's actually performing.
2015-06-30 22:39:57 +02:00
wm4 c0aba8e25a demux_lavf: check for NAN rotation angles
Yep, the FFmpeg API can return this.
2015-06-30 19:35:19 +02:00
wm4 aa42b6ba35 player: slim down A/V desync warning
I don't think most of these suggestions are overly helpful. Just get rid
of them.
2015-06-30 19:20:52 +02:00
wm4 dbf21467f0 build: always regenerate version hash
Until now, it only used the hash from the previous configure run,
instead of trying to get the latest hash. The "old" build system did
this correctly - we just have to use the existing logic in version.sh.

Since waf supports separate build dirs, extend version.sh with an
argument for setting the path of version.h.
2015-06-30 15:56:26 +02:00
wm4 bf739ca324 manpage: fix copy&paste mistakes
These are definitely not per-track.

(Maybe we should just provide a script or such which pretty-prints
"native" property output.
2015-06-30 12:17:58 +02:00
Martin Herkt 55a7ef9675 input.conf: invert mouse volume control
Scrolling right should increase volume, not decrease it.
2015-06-30 12:04:09 +02:00
wm4 eaf1547afc input: improve wording of key binding messages 2015-06-30 00:43:16 +02:00
wm4 2f8eabe216 ao_coreaudio: restore physical format if it can't be set exactly
May help with (supposedly) bad drivers, which can put the device into
some sort of broken state when trying to set a different physical
format. When the previous format is restored, it apparently recovers.

This might make the change-physical-format suboption more robust.
2015-06-30 00:02:12 +02:00
wm4 302aaddc26 ao_coreaudio: support native mono output
We can be pretty sure that AudioUnit will remix for us.

Before this commit, we usually upmixed to stereo, because the
stereo and multichannel layouts were the only whitelisted ones.
2015-06-29 23:55:03 +02:00
wm4 956b8658fb ao_coreaudio: log hotplug events explicitly 2015-06-29 23:54:18 +02:00
wm4 2e4f106ef8 video: fix panscan in vertical case
If the black bars appeared on the left/right borders, panscan=1 didn't
make the video cover the whole screen.
2015-06-29 23:46:59 +02:00
Daniel Bergmann 8b479d2f66 DOCS/man: fix some grammar errors
Signed-off-by: wm4 <wm4@nowhere>
2015-06-29 19:03:51 +02:00
wm4 a5b96226a0 vaapi: prefer direct display over copy-back
Again. With the old OpenGL interop dropped, this probably works better
than vaapi-copy now. Last time we defaulted to vaapi-copy, because the
OpenGL interop could swap U/V planes and other stupid crap. We'll see.
2015-06-29 15:14:38 +02:00
wm4 ef3d121c9e vaapi: treat cropped decoder output slightly more correctly
Work around that FFmpeg doesn't distinguish between surface and cropped
size. The decoder always aligns the surface size to something
"convenient" (e.g. 16 for h264), and to get to the correct cropped size,
the output image's width/height is reduced. Using the cropped size
instead of the real surface size breaks the libva API in certain cases,
so we simply store and use the original size in our per-surface struct.

(If data is cropped on the left/top borders, hw decoding will simply
display these - FFmpeg doesn't let us do better.)
2015-06-29 15:13:45 +02:00
wm4 e0b1b88e83 vaapi: fix potential NULL deref on memory allocation failure 2015-06-29 15:10:17 +02:00
wm4 d660e67be9 vaapi: remove vaDeriveImage() code path
In theory, this code path avoids a copy. In practice, it never seems
to get enabled at all. But it does have potential for weird bugs or
performance issues (like being mapped from non-cacheable memory),
so kill it.
2015-06-29 15:10:07 +02:00
wm4 d98cd6609d x11: remove trailing spaces 2015-06-29 15:09:28 +02:00
Eduardo Sánchez Muñoz db3d36927d x11: Handle external fullscreen toggles
Some window managers let you change the fullscreen state of any window
using a key combination. For example, on XFWM you can use Alt+F11 and
on Compiz you can configure a key combination with the
"Extra WM actions" plugin.

With this change mpv will handle these fullscreen state changes. So, if
you enter into fullscreen mode using the WM's shortcut and then you use
mpv's fullscreen toggle, you will get back into window mode.

Merges PR #2081.

Signed-off-by: wm4 <wm4@nowhere>
2015-06-28 20:13:57 +02:00
wm4 fccce81d42 demux_mkv: disable ordered chapters if ChapterTimeEnd is missing
If the EditionFlagOrdered is set, chapters without ChapterTimeEnd make
no sense. Ordered chapters will play the chapters in the order they
appear, but will play the ranges the chapters cover. So if the end time
is missing, the range is incomplete and it's not clear what should be
played. If you assume the start of the next chapter as end time, the
ordered flag will have no observable effect, so that's not a useful
assumption.

This fixes playback of a file which (apparently) had the
EditionFlagOrdered set accidentally, with normal chapters.
2015-06-28 18:32:58 +02:00
rr- 745cc7a8cd vo_drm: make VT switching non mandatory 2015-06-28 17:11:51 +02:00
rr- fb1b8f93aa vo_drm: fix missing newlines in error messages 2015-06-28 15:22:11 +02:00
wm4 b2e1c91f40 DOCS: fix recent typos
Pointed out by a certain wiiaboo.
2015-06-28 13:23:16 +02:00
wm4 26f52c5730 demux: export forced flag
At least Matroska files have a "forced" flag (in addition to the
"default" flag). Export this flag. Treat it almost like the default
flag, but with slightly higher priority.
2015-06-27 22:02:24 +02:00
wm4 a8711001c5 demux_mkv: ignore deprecated FrameRate, do not assume PAL
The "FrameRate" element is probably deprecated (it's greyed out in the
"spec", and described as "Informational only" in bold). Normally files
use DefaultDuration. In fact, the FrameRate field was preferred over
DefaultDuration for determining framerate if present. Do not do this and
rely on DefaultDuration only.

Also, if no framerate is set, do not assume PAL (25 FPS). Such a
fallback makes little sense and will cause more problems than it solves.
2015-06-27 21:47:18 +02:00
wm4 dde2a5f0e8 demux_mkv: remove some ASCII art log messages
Some of the ASCII art makes sense (like the lines starting with "|"),
but these do not make any sense to me and just look annoying.
2015-06-27 21:42:19 +02:00
wm4 85b7cbec70 options: improve an error message
"mpv --ao=wasapi:help" on Linux gave "Option ao doesn't exist.".
Completely misleading and stupid.
2015-06-27 21:26:05 +02:00
wm4 1921f40db5 ytdl: don't print failure warning when youtube-dl was killed by us 2015-06-27 21:09:12 +02:00
wm4 03c70a8d81 subprocess, lua: export whether the process was killed by us
We want to distinguish actual errors, and just aborting the program
intentionally.

Also be a bit more careful with handling the wait() exit status: do not
called WEXITSTATUS() without checking WIFEXITED() first.
2015-06-27 21:08:55 +02:00
wm4 6ffb1e2b66 ao_wasapi: fix regression
This probably fixes the regression introduced with commit 6147bcce.
2015-06-27 17:59:27 +02:00
wm4 2a67208f40 terminal-unix: set terminal mode on init
mpv usually sets the terminal to non-canonical mode (which in particular
disables line buffering). But the old mode is restored if the process is
not foregrounded. This is supposed to make mpv behave nicer when it is
backgrounded.

getch2_poll() enables canonical mode. Unfortunately, this was only
called after the poll timeout elapsed, so non-canonical mode is first
enabled after about a second after program start. Fix this by moving the
poll call before the timeout.

(As far as we're aware, there's no event-based way to determine when the
FD's process group changes, thus we're polling.)
2015-06-27 12:20:40 +02:00
wm4 0969502316 chmap_sel: add a mechanism for preferred conversions
And use it for the mono case. This is slightly more formal and will make
it easier to add more such cases.
2015-06-27 12:09:30 +02:00
wm4 e0a7e094bc chmap_sel: remove outdated incomplete comment 2015-06-27 11:13:12 +02:00
wm4 3b3170aedb Disable DVD and BD menu support (to be removed)
DVD/BD menu support never worked right, and are a pain to maintain. In
particular, DVD menus never actually worked correctly, because
highlights were not rendered correctly. Fixing this requires major
effort, which I'm not interested to spend.

Most importantly, the requirement to switch streams without losing the
DVD/BD state caused major weirdness in the playback core. It was
implemented by somehow syncing the playback state to the DVD/BD
implementation (in stream_dvdnav.c etc.), and then reloading the demuxer
without destroying and recreating the stream. This caused a bunch of
special-cases which I'm looking forward to remove.

For now, don't just remove everything related to menu support and just
disable it. If someone volunteers, it can be restored (i.e. rewritten)
in a reasonable way. If nobody volunteers soon, it goes.
2015-06-26 23:37:30 +02:00
wm4 d9b19390ad demux_mkv: use arrays for codec lookup tables
No need to define extra types.
2015-06-26 23:16:25 +02:00
wm4 8a60283309 demux_mkv: minor simplification 2015-06-26 23:09:37 +02:00
wm4 6147bcce35 audio: fix format function consistency issues
Replace all the check macros with function calls. Give them all the
same case and naming schema.

Drop af_fmt2bits(). Only af_fmt2bps() survives as af_fmt_to_bytes().

Introduce af_fmt_is_pcm(), and use it in situations that used
!AF_FORMAT_IS_SPECIAL. Nobody really knew what a "special" format
was. It simply meant "not PCM".
2015-06-26 23:06:37 +02:00
wm4 d6737c5fab audio: replace format name table
Having a big switch() is simpler.
2015-06-26 23:06:21 +02:00
wm4 efb50cabe6 audio: remove bitmask format definition mess
Audio formats used a semi-clever schema to encode the properties of the
PCM encoding as bitfields into the format integer value.

The af_fmt_change_bits() implementation becomes a bit weird, but it's
an improvement to the rest of the code.

(I've always disliked it, so why not get rid of it.)
2015-06-26 23:05:16 +02:00
wm4 554b4217a0 ao_coreaudio_utils: use a macro
This is actually the last line of code outside of format.c/h which still
tries to fiddle with the format bitfields.
2015-06-26 23:04:44 +02:00
wm4 e4e7fade96 ao_sndio: fix comment
So whoever (nobody?) would want to deal with this broken and obscure AO
for an obscure audio API could add support for some more channel
layouts.
2015-06-26 23:03:37 +02:00
rrooij b0176c1d24 DOCS/mplayer-changes: Add removal of X11 vo
The X11 video output was removed recently and is a difference
from mplayer. That's why it should be documented in the
mplayer-changes document.
2015-06-26 23:03:29 +02:00
wm4 d11184a256 vo_x11: remove this video output
It only causes additional maintenance work.

Even if you wanted to have a fallback, it's probably better to use
--vo=sdl or so.
2015-06-26 17:17:34 +02:00
wm4 cd6d846b70 ao_coreaudio: support non-interleaved output
This saves us the trouble of interleaving the audio data for
no reason.
2015-06-26 15:58:11 +02:00
wm4 8134a0601b ao_coreaudio: explicitly skip input streams
This may or may not fix some issues with the format switching
code. Actually, it seems somewhat unlikely, but then checking
the stream type isn't incorrect either, and is probably
something the API user should always be doing.
2015-06-26 15:56:19 +02:00
wm4 3c61e6eb4e ao_coreaudio_utils: compare full AudioStreamBasicDescription
Originally, this was written for comparing the sample format only, but
ca_change_physical_format_sync() actually expects that the full format
is compared. (For all other uses it doesn't matter.)
2015-06-25 20:17:14 +02:00
wm4 5a3cdb8f1e audio: output human-readable channel layouts too
This gets you the "logical" channel layout, instead of the exact thing
we're sending to the AO. (Tired of the cryptic shit ALSA gives me.)
2015-06-25 19:10:24 +02:00
wm4 fd1194de3c audio: fix channel map fallback selection (again)
The speaker replacement nonsense sometimes made blatantly incorrect
decisions. In this case, it prefered a 7.1(rear) upmix over outputting
5.1(side) as 5.1, which makes no sense at all. This happened because 5.1
and 7.1(rear) appeared equivalent to the final selection, as both of
them lose the sl-sr channels. The old code was too stupid to select the
one with the lower number of channels as well.

Redo this. There's really no reason why there should be a separate final
decision, so move the speaker replacement logic into the
mp_chmap_is_better() function.

Improve some other details. For example, we never should compare the
plain number of channels for deciding upmix/downmix, because due to NA
channels this is essentially meaningless. Remove the NA channels when
doing this comparison. Also, explicitly handle exact matches.
Conceptually this is not necessary, but it avoids that we have to
needlessly shuffle audio data around.
2015-06-25 17:32:00 +02:00
wm4 5d71188c99 ao: standardize channel layout name in debug output further 2015-06-25 13:15:32 +02:00
wm4 0906f758d3 vo_sdl: fix glaring memory leak
Who knows when this broke?
2015-06-25 09:55:24 +02:00
wm4 e4c5876f57 player, demux: replace some demux_open() uses with demux_open_url() 2015-06-24 21:26:06 +02:00
wm4 ab2e3cf6f9 demux_lavf: fix chapter titles
Obvious bug added earlier today.
2015-06-24 16:51:19 +02:00
wm4 1b7ce759b1 Revert "win32: add mappings for some special keys"
This reverts commit fc9695e63b.

Users were complaining that both mpv and something else (what? I don't
know) respond to some multimedia keys, such as volume change.
2015-06-24 15:14:38 +02:00
wm4 a70c8105fc DOCS: document some recent interface additions 2015-06-24 14:40:03 +02:00
wm4 ef020c155f demux_mkv: allow integer and float elements with length 0
Integer and float elements are encoded as a sequence of bytes prefixed
by a variable-length encoded length specifier. If the length is 0, then
there is no data. Whether this is valid or not is not really clear, but
some sample files which do this have surfaced. It's not particularly
hard to handle this, so just do it.
2015-06-24 14:34:05 +02:00
wm4 fcd589b123 demux: get rid of some bstr things
Change the demuxer_add_attachment() and demuxer_add_chapter() signatures
to take char* instead of bstr, and everything which depends on it.
2015-06-24 14:18:51 +02:00
wm4 ae2873f72e demux_mkv: don't use byte strings
Use char* for strings instead of bstr (data ptr + length pair). Matroska
actually (probably) allows "padding" strings with \0 bytes, so using
normal C strings instead of byte strings is more appropriate.
2015-06-24 14:02:40 +02:00
c_14 47919bdfc9 manpage: Fix typo. oacopts -> ovcopts 2015-06-23 22:00:57 +02:00
wm4 ff9c597fbf player: increase tick event update frequency
500ms is a bit too high. Change it to 50ms. This improves client API
(and Lua) playback state update frequency.

Updating absolutely every time the audio PTS changes would be possible,
but is not helpful. Audio samplerates are high to trigger a wakeup
feedback loop, so the process would waste CPU time on updating the
playback position all the time.

(If a client application wants to ensure smooth update of the playback
position, it should update the position manually using a timer and by
reading the property - the application can make a much better decision
at how often the playback has to happen.)
2015-06-23 19:23:11 +02:00
wm4 ddd6f5a9d7 manpage: minor fixes 2015-06-23 15:33:07 +02:00
wm4 68e7e89835 command: export stereo 3D tags
Fixes #2066.
2015-06-23 15:20:21 +02:00
wm4 62269871aa af: move af_from_dB() function to af_volume.c
And also simplify it (it certainly had the most awkward API you could
think of for such a simple function).
2015-06-23 15:11:23 +02:00
wm4 4c6a600943 af_volume: add a replaygain fallback option 2015-06-23 15:07:19 +02:00
wm4 e7d5a5e688 af_lavrresample: free and reallocate resample context on reconfig
This avoids keeping "bad" state from previous reconfig calls, such as
the internal_sample_format option (which is set only on the first
reconfig call).

There's no advantage to keeping the resample contexts around anyway.
2015-06-22 17:05:42 +02:00
wm4 cd78e0c5bf af_lavrresample: fix comment
mp_format is not a libavresample input format here, and the comment was
more confusing than it helped.
2015-06-22 16:06:40 +02:00
wm4 3d55340c6d af: restore detaching of PCM filters when using spdif
Basically, af_fix_format_conversion() behaves stupid you insert a
conversion filter that won't work, and adding back the conversion test
function is the simplest fix to it.
2015-06-22 16:03:07 +02:00
wm4 17e8815e37 af_lavrresample: don't flush in uninitialized state
libswresample verbosely complains.
2015-06-22 16:03:03 +02:00
wm4 872b19dfcb ao_alsa: fix a log message
So apparently, this essentially happens when the kernel driver doesn't
implement write accesses in the channel map control. Which doesn't
necessarily mean that the channel map is unsupported, or that there is a
bug - it's just lazyness and a consequence of the terrible ALSA kernel
API for the channel mapping stuff.

In these cases, the channel count implicitly selects the channel map,
and snd_pcm_set_chmap() always fails with ENXIO.

I'm actually not sure what happens if dmix is on top of e.g. HDMI, which
actually lets you change the channel mapping.

I'm also not sure why commit d20e24e5d1614354e9c8195ed0b11fe089c489e4
(alsa-lib git repository) does not take care of this.
2015-06-21 18:32:38 +02:00
wm4 dbbac7b3e1 demux: mime types are case-insensitive
This one is used for demux_mf and for dmeux_mkv image attachments.
2015-06-21 18:21:21 +02:00
wm4 0316f5514e demux_mkv: share some duplicated code
As a side effect, video tracks now actually export some fields
(language, default flag) to the player.
2015-06-21 18:19:10 +02:00
wm4 be882175d8 demux: merge extradata fields
MPlayer traditionally had completely separate sh_ structs for
audio/video/subs, without a good way to share fields. This meant that
fields shared across all these headers had to be duplicated. This commit
deduplicates essentially the last remaining duplicated fields.
2015-06-21 18:06:14 +02:00
wm4 c66be698cd demux_mkv: minor audio extradata cleanup
Always use the already existing extradata[_len] variable, instead of the
awkward switch between manually changed extradata and falling back to
passing through extradata at the end.
2015-06-21 17:49:43 +02:00
wm4 2b64eee8d5 demux: rename sh_stream.format to sh_stream.codec_tag
Why not. "format" sounds too misleading for the actual importance and
meaning of this field.
2015-06-21 16:56:35 +02:00
wm4 991af7dfb1 video: reduce error message when loading hwdec backend fails
When using --hwdec=auto, about half of all systems will print:

    "[vdpau] Error when calling vdp_device_create_x11: 1"

this happens because usually mpv will be linked against both vdpau and
vaapi libs, but the drivers are not necessarily available. Then trying
to load a driver will fail. This is a normal part of probing, but the
error messages were printed anyway. Silence them by explicitly
distinguishing probing.

This pretty much goes through all the layers. We actually consider
loading hw backends for vo_opengl always "auto probed", even if a hw
backend is explicitly requested. In this case vd_lavc will print a
warning message anyway (adjust this message a bit).
2015-06-20 22:26:57 +02:00
wm4 b17b8ff7fe x11: make screensaver failure message slightly more friendly 2015-06-20 21:55:15 +02:00
wm4 23b83c6676 client API: allow using msg-level option for log messages
Client API users can enable log output with mpv_request_log_messages().
But you can enable only a single log level. This is normally enough, but
the --msg-level option (which controls the terminal log level) provides
more flexibility. Due to internal complexity, it would be hard to
provide the same flexibility for each client API handle. But there's a
simple way to achieve basically the same thing: add an option that sends
log messages to the API handle, which would also be printed to the
terminal as by --msg-level.

The only change is that we don't disable this logic if the terminal is
disabled. Instead we check for this before the message is output, which
in theory can lower performance if messages are being spammed. It could
be handled with some more effort, but the gain would be negligible.
2015-06-20 21:40:47 +02:00
wm4 34fce974c6 av_log: skip prefix if unknown
This happens with av_log(NULL, ...) calls. Drop the "?: " fallback
prefix, because it was confusing.

(Of course FFmpeg should not do this at all, but it's a very long way to
making the FFmpeg log callback sane.)
2015-06-20 17:02:56 +02:00
wm4 4e1159c3f2 demux_playlist: make mime type comparison case-insensitive
That's how mime types are.

(This makes redirection with a specific HLS URL work, because some idiot
thought it'd be a great idea to spell the mime type as
"application/x-mpegURL".)
2015-06-20 16:36:22 +02:00
wm4 da9e0988a6 win32: remove a wine hack
No particular reason, but it's still possible that it causes additional
corner cases, and it's not really needed to test this on wine (other
than testing fullscreen stuff, which should be done on a real Windows
anyway).
2015-06-20 14:32:14 +02:00
wm4 91fdfd3880 win32: prefer using internal variable for fullscreen
No particular reason, but since we already have an internal variable,
it's better than using the option struct, which will be redone sooner
or later.
2015-06-20 14:29:17 +02:00
wm4 09eaaf3f2c demux_mkv: do not reset bits_per_coded_sample if not needed 2015-06-19 21:48:19 +02:00
wm4 b789acee21 demux_mkv: do not set block_align for codecs which do not need it
These decoders do not reference it. I suspect this was originally done
for the sake for MPlayer's vfw/dshow wrappers.
2015-06-19 21:47:11 +02:00
wm4 f2cc6ce356 demux_mkv: do not set bitrate fields for codecs which do not need it
The only decoders I could find and which (possibly) require this field
are codecs which can be used via VfW only, and realaudio sipr. For VfW
we still passthrough this field.
2015-06-19 21:46:32 +02:00
wm4 8b44be54e7 demux_mkv: stricter realaudio extradata handling
Verify memory accesses and such. The behavior should be equivalent.

(RealAudio causes pain for everyone even in its grave.)
2015-06-19 21:43:55 +02:00
wm4 fd557a0178 demux_mkv: separate generic and non-VfW audio codec handling parts
Native Matroska codec support has to map the Matroska codec IDs to
libavcodec ones, and also has to undo codec-specific Matroska
strangeness, such as restoring AAC extradata and realaudio handling. The
VfW codec support doesn't need it, because AVI maps well enough to
libavcodec conventions (possibly because AVI was a dominant codec when
libavcodec was created). But there's still some need for generic codec
handling, such as enabling parsers and messing with various codec
parameters.

Separate these two, and move the parts which are guaranteed not to be
needed by VfW to the if-else tree that handles the VfW case
("A_MS/ACM"), making the cases exclusive.

(This should probably be done more radically, since it's very unlikely
that we should or have to mess with the VfW parameters at all - they
should just be passed through to the decoder.)
2015-06-19 21:42:55 +02:00
wm4 f544cd0501 demux_mkv: remove indirection through defines
This is actually more readable. Most of the defines are used only once,
so using a symbol instead of the direct string only obfuscated it.
2015-06-19 21:41:57 +02:00
wm4 0641ec0525 demux_mkv: remove FourCCs from audio codec handling
This removes the last traces of the old MPlayer FourCC-based codec
mapping code. Forcing all codec IDs through a FourCC table and then
back to codec names was confusing at best, so this is a nice cleanup.

Handling of PCM (non-VfW case) is redone to some degree.

Handling of AC3 is moved below realaudio handling, since "A_REAL/DNET"
is apparently AC3, and we must not skip realaudio-specific handling.
(It seems unlikely that anything would actually break, but on the other
hand I don't have any A_REAL/DNET samples for testing.)

Instead of explicitly matching all the specific AAC codec names, just
match them all as prefix.

Some codecs don't need special handling other than their mapping
entries, so they fall away (like Vorbis and Opus).

The prores check in mkv_parse_and_add_packet() is not strictly related
to this, but is done for consistency with the wavpack check above.
2015-06-19 21:39:59 +02:00
Teoh Han Hui aed7c84840 osc: time display configuration options
Total time and ms
2015-06-19 21:33:44 +02:00
wm4 b1a56d11fe player: add some debug output for seeking 2015-06-18 22:31:55 +02:00
wm4 d328b2088c player: actually play video
Broken by e00e9d65.
2015-06-18 20:48:30 +02:00
Marcin Kurczewski 797277a233 Various spelling fixes
Signed-off-by: wm4 <wm4@nowhere>
2015-06-18 19:36:58 +02:00
wm4 0f0e88cbaa DOCS/compile-windows.md: fix Lua package
mingw-w64-x86_64-lua maps to Lua 5.3, which we do not support. Change it
to mingw-w64-x86_64-lua51.
2015-06-18 18:41:09 +02:00
wm4 32955d3529 client API: fix logging memory leak
Very stupid.

Was pointed out in #2056.
2015-06-18 18:40:12 +02:00
wm4 e00e9d651b player: make decoding cover art more robust
When showing cover art, the decoding logic pretends that the source has
an infinite number of frames. This slightly simplifies dealing with
filter data flow. It was done by feeding the same packet repeatedly to
the decoder (each decode run produces new output).

Change this by decoding once at the video initialization. This is easier
to follow, and increases robustness in case of broken images. Usually,
we try to tolerate decoding errors, so decoding normally continues, but
in this case it would just burn the CPU for no reason.

Fixes #2056.
2015-06-18 18:39:46 +02:00
rrooij a87b18aa5a DOCS/manpage: fix typos
Fix some errors in the man pages by spell checking them. Most of them
were typos.

Signed-off-by: wm4 <wm4@nowhere>
2015-06-17 20:13:34 +02:00
wm4 f53135ffea av_log: set default av_log callback on exit
This is slightly "dangerous", because it could overwrite a log callback
another library has set, after we've set our own callback. But it's
probably still slightly better than leaving our own callback, which will
run the fallback code if no mpv instance is set. (Multiple mpv instances
sharing the same global state will safely avoid overwriting each other's
log callback.)

Note that we can't do much better, because the global state in FFmpeg is
obviously insane.
2015-06-17 14:52:31 +02:00
wm4 d4aaf29a05 ao_wasapi: fix crash on hotplug init error
On init error, the mp_msg macros are actually called. They could cause
a crash because state->log was NULL.
2015-06-17 13:42:31 +02:00
wm4 762623cdef af_lavrresample: include osdep/endian.h
The 24 bit conversion code needs the relevant preprocessor symbols.
2015-06-17 13:41:45 +02:00
wm4 72808be6f8 command: do not exit playback if the B point of A-B loop is past EOF
The previous behavior is confusing if the B point is near EOF (consider
B being the duration of the file, which is strictly speaking past the
last video timestamp). The new behavior is fine as well for B being far
past EOF.

Achieve this by checking the EOF state in addition to whether playback
has reached the B point. Also, move the A-B loop code out of
command_event(). It just isn't useful anymore, and obfuscates the code
more than it makes it loop simple.

Fixes #2046.
2015-06-16 23:11:14 +02:00
wm4 dbdc46c97a player: do not exit when a seek gets queued
Seems logical.

Note that if playback otherwise ends while playback is active and a seek
is still queued, we still exit. Otherwise you couldn't end playback by
seeking past the end of the file (which is classic MPlayer and mpv
behavior).
2015-06-16 23:07:46 +02:00
wm4 b2781c11ed af: remove conversion filter search
This attempted to find a minimal filter graph for a format conversion
involving multiple conversion filters. With the last 2 commits it
becomes dead code - remove it.
2015-06-16 22:49:21 +02:00
wm4 552dc0d564 af_convert24: remove this filter 2015-06-16 22:40:37 +02:00
wm4 5a9f817bfd af_lavrresample: integrate 24 bit (3 bytes per sample) output
Now af_lavrresample can output 24 bit samples directly, by doing the
conversion "inline". Luckily, S32->S24 can be done in-place, so this
isn't too much work. But the output conversion logic (which seems to be
adding up) gets slightly more complicated again.

Normally this is done by af_convert24. But having multiple conversion
filters complicates some aspects of the filter chain. S24 output is the
only thing the code for multiple conversion filters is still needed for,
and getting rid of that is preferable.
2015-06-16 22:38:37 +02:00
wm4 8ee9c170be af_lavrresample: always fill reorder
If the code path for additional output conversion is active,
reorder_planes() is always called, even if the reorder_out array wasn't
filled. This is obviously wrong - always fill this array.
2015-06-16 21:40:29 +02:00
wm4 831d7c3c40 audio: remove S8, U16, U24, U32 formats
They are useless. Not only are they actually rarely in use; but
libavcodec doesn't even output them, as libavcodec has no such sample
formats for decoded audio.

Even if it should happen that we actually still need them (e.g. if doing
direct hardware output), there are better solutions. Swapping the sign
is a fast and lossless operation and can be done inplace, so AO actually
needing it could do this directly.

If you wonder why we keep U8 instead of S8: because libavcodec does it.
2015-06-16 21:11:59 +02:00
wm4 488ebdb0d5 DOCS/compile-windows.md: drop unused dependency 2015-06-16 17:34:38 +02:00
wm4 82ff32ffac audio: fix crash on uninit
Shit.
2015-06-15 20:28:05 +02:00
wm4 30f5ba9422 af_lavcac3enc: fix A/V sync
The filter can buffer singificant amounts of audio.

(The proper fix is making the filter chain PTS-aware.)
2015-06-15 14:33:48 +02:00
wm4 74a73752c2 af: fix an aspect of filter chain flushing
Even if we flush the current filter, we have to read the remaining
output from the frame we previously fed to the filter.
2015-06-15 14:33:07 +02:00
wm4 5eae20fc0f audio: remove unused readonly field
Its last use was removed in 433402b5.
2015-06-15 14:32:14 +02:00
wm4 ec72feaba3 win32: use atomics for COM interface refcount 2015-06-14 17:56:24 +02:00
wm4 725d840b73 demux_mkv: always copy video extradata
The existing code avoided doing this for some codecs. I see no point in
this, and it seems the original reason this exists was due to some
cleanup in 2007. libavformat doesn't do this. So just drop it.
2015-06-13 22:34:23 +02:00
wm4 d50e01d0c6 demux_mkv: fix mpeg2 mapping
It's well possible that we've always ended up invoking the
AV_CODEC_ID_MPEG1VIDEO codec, but it's hard to tell. Mangling everything
through FourCCs (and then back) makes it hard to analyze. Also,
libavformat's Matroska demuxer uses AV_CODEC_ID_MPEG2VIDEO here, so it
should be quite safe to do anyway.
2015-06-13 22:34:23 +02:00
wm4 fd88fb70af demux_mkv: remove FourCCs from video codec handling
Inherited from MPlayer times, we used FourCCs to identify video codecs.
This was later changed to libavcodec codec names (which made life a
whole lot simpler). But demux_mkv still uses FourCCs a lot.

Change this for video. It's pretty simple, because some preparation was
done in the past. We just have to replace some "internal" FourCCs with
different handling.

One potentially complicated issue is that there is no natural way to
set the sh->format (AVCodecContext.codec_tag) field anymore. Most
decoders do not need it, though mjpeg is an exception.

Note that the AVI compatibility code still requires codec mappings, but
these are provided by FFmpeg. Also, the audio code is not changed.

For the MKV_V_MPEG2 -> mpeg1video thing see next commit.
2015-06-13 22:34:23 +02:00
wm4 b33ab743e5 demux_mkv: remove a level of indentation
Replace an else block with a nested if with just "else if". No
functional or other changes.
2015-06-13 21:27:00 +02:00
wm4 efa6d0c746 demux_mkv: remove ms_compat code
Reduces the mess slightly.
2015-06-13 21:17:48 +02:00
Marcin Kurczewski 8d6c22def4 vo_drm: fixed crashes with --profile=pseudo-gui 2015-06-13 16:18:11 +02:00
Stefano Pigozzi 63e4cb5163 test: update cmocka version to 1.0 2015-06-13 00:01:58 +02:00
wm4 9909234abe chmap: make up some channel layout names
Going by the existing names, these should make sense. HDMI knows about
these layouts, but does not name them.
2015-06-12 23:57:32 +02:00
wm4 6cc02658fa ao_alsa: if possible, reorder device maps to std layouts
Channel maps reported by the device as SND_CHMAP_TYPE_VAR can be freely
reordered. We don't use this much (out of laziness), but in this case
it's a simple way to reduce necessary reordering (which would be an
extra libavresample invocation), and to make debug output more readable.
2015-06-12 23:15:44 +02:00
wm4 5b269ce696 ao_alsa: make it accept 7.1 over HDMI
SDR/SDL is what lavc outputs for 7.1(rear), while RRC/RLC is what ALSA
uses for some 7.1 layouts, so this makes sense to me.
2015-06-12 23:08:09 +02:00
wm4 afdc060bb3 chmap_sel: improve speaker replacement handling
This didn't really work since the last time the channel map fallback
code was touched. In some cases, quite bad results were selected.
2015-06-12 19:23:46 +02:00
wm4 55624a70ee chmap_sel: do naive speaker replacements last
This prevents that the potentially better pick by
mp_chmap_sel_fallback() is overridden.
2015-06-12 19:21:01 +02:00
wm4 433402b56c audio: fill NA channels with silence
Until now, we didn't do this, because it required some effort, and
didn't seem to be necessary. It probably still isn't, but it sounds
like a good idea not to output arbitrary data on these channels.

The situation is complicated by the fact that just adding new channels
to a planar frame would require messing with buffers. So we would have
to allocate new buffers and add them to the frame. We could have to
maintain an extra buffer pool for this. Avoid this by being "clever",
and just allocate a frame with enough channels in the first place.
libav/swresample won't know about these channels and won't write to
them, but we can grab them in reorder_planes() and use them for the
NA channels.
2015-06-12 17:53:23 +02:00
wm4 c890eeac47 audio: use unknown channel layouts if there is no standard layout
This is just a conceptual issue, since for now every channel count has
an associated standard layout.

But should the max. channel count ever be bumped, some things would stop
function if mp_chmap_from_channels() refused to work for any channel
count within the allowed range.
2015-06-12 17:45:56 +02:00
wm4 11fee81a7a audio: fix messed up channel reordering
Quite a blunder, really.
2015-06-12 17:45:47 +02:00
wm4 627b87b0d8 audio: deal with AVFrame-style buffer assignments
In the AVFrame-style system (which we inreasingly map our internal data
stuctures on), buffers and plane pointers don't necessarily have a 1:1
correspondence. For example, a single buffer could cover 2 or more
planes, all while other planes are covered by a second buffer, and so
on. They don't need to be ordered in the same way.

Change mp_audio_get_allocated_size() to retrieve the maximum size all
planes provide. This also considers the case of planes not pointing to
buffer start.

Change mp_audio_realloc() to reset all planes, even if corresponding
buffers are not reallocated. (The caller has to be careful anyway if it
wants to be sure the contents are preserved on realloc calls.)
2015-06-12 17:44:40 +02:00
wm4 0d2456ae5f lua: support MPV_END_FILE_REASON_REDIRECT
And also add the missing "unknown" entry to the manpage.
2015-06-11 21:42:09 +02:00
wm4 e53cb0890e client API: add MPV_END_FILE_REASON_REDIRECT
Requested. Minor incompatible behavior change, as it was signalling
MPV_END_FILE_REASON_EOF previously.
2015-06-11 21:42:09 +02:00
wm4 87b60ded88 client API: leave mpv_event_end_file.error to 0 on no error
Making sure this is true makes it closer to the libmpv docs, and
possibly less confusing in corner cases.
2015-06-11 21:42:09 +02:00
wm4 ce513dedd8 lua: export end-file event fields 2015-06-11 21:42:09 +02:00
wm4 478ea1d0f3 ao_alsa: change ALSA braindeath heuristic
If you try to play surround with dmix, it will advertise surround and
lets you set more than 2 channels, but will report a stereo channel map,
with the extra channels identified as NA. We could handle this now, but
we don't want to (because it's excessively stupid).

Do it only if the channel map is not what we requested, instead of just
acting if it contains NA entries at all. This avoids that we hurt
ourselves in the unlikely but possible case we actually have to use
channel maps with NA entries.
2015-06-11 21:42:09 +02:00
torque d0fe5e08b9 command: add keypress, keydown, and keyup commands.
These commands are used to simulate keypresses using the key names from
input.conf.
2015-06-11 21:42:09 +02:00
wm4 b655ed5ed0 player: use 4 as process exit code on user quits
So successful playback and user quit can be distinguished, for whatever
reason you may want to do this.

Normally, the "quit" command can be customized, but this does not work
for quit commands sent by the terminal signal handler. One solution
would be introducing something like "ON_SIGNAL" (equivalent to
"CLOSE_WIN"), but considering there are a bunch of possible signals, I'd
rather not get into this. So go with the dumb solution.

Probably fixes #2029.
2015-06-10 23:18:42 +02:00
wm4 a3d561f950 options: make keyvalue list parsing less strict
Affects for example --script-opts. A bunch of characters are now allowed
in them without causing trouble to the user.
2015-06-10 23:06:07 +02:00
wm4 7de2411c47 vo_opengl: fix a small memory leak when loading user shaders
When gl_shader_cache was destroyed, existing user shader entries leaked
the file path string.
2015-06-09 22:42:03 +02:00
wm4 4a90b15f74 vo_opengl: fix dangling pointers with vo_cmdline
gl_video_set_options() does not acquire ownership of the opts parameter
or its contents. In case of vo_cmdline, opts will point to temporary
memory. This memory will be free'd at a later point, and p->opts will
point to free'd memory on the next reinitialization.

The fix is pretty ugly, but it's a quick bug fix. This can probably be
removed once VO sub-options are exposed as properties.

Fixes #2035.
2015-06-09 22:30:32 +02:00
wm4 f51459c077 audio: add some change notifications
We must be sure that every change comes with a notification. Otherwise,
some property changes could possibly be missed.
2015-06-09 18:29:11 +02:00
wm4 b7d833c2a6 ao_coreaudio: change physical stream format synchronously 2015-06-09 18:26:14 +02:00
wm4 211088943c audio/out/pull: avoid dropping some audio when draining
If the audio API takes a while for starting the audio callback, the
current heuristic can be off. In particular, with very short files, it
can happen that the audio callback is not called before playback is
stopped, so no audio is output at all.

Change draining so that it essentially waits for the ringbuffer to
empty. The assumption is that once the audio API has read the data
via the callback, it will always output it, even if the audio API
is stopped right after the callback has returned.
2015-06-09 18:26:14 +02:00
wm4 a2b1c6d3f6 audio/out/pull: correctly pad partial frames with silence
If a frame could only be partially filled with real audio data, the
silence wasn't written at the correct offset. It could have happened
that the remainder of the frame contained garbage.

(This didn't happen in the more common case of playing dummy silence.)
2015-06-09 18:26:14 +02:00
wm4 3399b775b7 command: fix audio-out-detected-device property
Used a wrong condition, and I suppose it could crash in some situations.

Change it to lazily initialize the hotplug stuff, like the
audio-device-list property does.
2015-06-09 18:25:44 +02:00
wm4 bd64763076 command: remove unnecessary event IDs
These were actually not needed for correct function, since individual
property change notifications via mp_notify_property() are used.
2015-06-09 18:21:56 +02:00
wm4 9986593b50 command: make property event mask matching more restrictive
This was matching e.g. both "foo/bar" and "foobar" against "foo", when
only the former should match. This could cause more property
notifications than necessary.
2015-06-09 18:21:56 +02:00
wm4 8653ed2183 ao_alsa: refine channel count mismatch error message
I suspect we need to hand this more gracefully in some cases.
2015-06-09 18:21:56 +02:00
wm4 f72028ddad vaapi: add missing license header
Absence of license header implies LGPL, as mentioned in the "Copyright"
file. But vaapi.h contains some code taken from the mplayer-vaapi
patch, which was under the typical MPlayer license.
2015-06-08 22:14:47 +02:00
wm4 0dfbd29828 gl_osd: fix license header
All vo_gl.c related code has been GPL+LGPL dual-licensed. The OSD code
is no exception and is also derived from vo_gl.c. Thus it should have
the same license (although I think technically speaking sub-licensing
it by removing one of the licenses is ok).
2015-06-08 22:13:00 +02:00
wm4 5dbd22e165 vo: clarify condition
This is (at least currently) redundant, but makes the code more
explicit. (This was discussed on IRC.)
2015-06-08 12:27:40 +02:00
Avi Halachmi (:avih) b694f480fe vo: restore frame-drop logic for high-fps clips
Commits 92b27be and f4ce99d removed high-fps logic to to a bug. That bug was
a missing parenthesis around everything after duration >= 0 && ... at the
removed code.

This patch restores the removed code, fixes the bug and then refactors the
code a bit.
2015-06-07 23:53:37 +02:00
Jaime Marquínez Ferrándiz 69abb48194 ytdl_hook: Support 'multi_video' results
They can be handled by the same codes used for playlists, most of them will use an EDL.
Fixes #2027.
2015-06-07 23:53:13 +02:00
wm4 92b27bec45 Revert "opengl: drop less frames when clip and display have similar fps"
This reverts commit f1746741de.

Together with the other revert, this fixes #2023 (the reason being
broken framedrop handling - it was dropping frames when it shouldn't).
2015-06-07 20:06:42 +02:00
wm4 f4ce99d082 Revert "vo: improve frame drop logic on high playback rate"
This reverts commit ffcad1a72b.
2015-06-07 20:04:49 +02:00
wm4 fb7d0c80cc vo_vdpau: add a NULL check, verify image dimensions
read_output_surface() could fail and return NULL.

Also, make sure we don't set the image to a size larger than the
allocated size. Normally this shouldn't happen, but in theory it could
in corner cases; this is for robustness.
2015-06-06 21:06:54 +02:00
wm4 57048c7393 audio: add --audio-spdif as new method for enabling passthrough
This provides a new method for enabling spdif passthrough. The old
method via --ad (--ad=spdif:ac3 etc.) is deprecated. The deprecated
method will probably stop working at some point.

This also supports PCM fallback. One caveat is that it will lose at
least 1 audio packet in doing so. (I don't care enough to prevent this.)

(This is named after the old S/PDIF connector, because it uses the same
underlying technology as far as the higher level protoco is concerned.
Also, the user should be renamed that passthrough is backwards.)
2015-06-05 22:42:59 +02:00
wm4 14ac4f0bd6 ad_spdif: use a pseudo codec entry to select DTS-HD instead of an option
This deprecates the --ad-spdif-dtshd option, and replaces it with a
pseudo decoder. This means ad_spdif will report two decoders, "dts" and
"dts-hd", of which the second simply enables what the option did.

The --ad-spdif-dtshd option will actually be deprecated in the next
commit.
2015-06-05 22:34:48 +02:00
wm4 68aaffc711 audio: do not allow AO to change passthrough formats
This makes no sense, because the format can't be converted anyway. It
just sets up the filter chain init code, which will vomit a bunch of
useless and confusing messages. So uninit and fail explicitly when this
happens.
2015-06-05 22:34:47 +02:00
wm4 2bf2254248 vo_vdpau: limit output surfaces to allowed maximum dimensions
We can't do much in this case, but at least we can not call the vdpau
API functions with too large sizes. Apparently the API considers this
undefined behavior, and random stuff might happen.
2015-06-05 22:34:16 +02:00
wm4 e0f0f6f3e9 vo_vdpau: directly get surface size from surface for screenshots
The previous code was not wrong, but I'd claim this makes the code more
robust. If a situation could happen in which the passed surface size is
incorrect, we could have passed a too small image, and
VdpOutputSurfaceGetBitsNative could have randomly overwritten memory.
2015-06-05 22:34:16 +02:00
wm4 650469d65b vo_vdpau: shorten 2 variable names
Why should I be required to type so much?
2015-06-05 22:34:16 +02:00
wm4 f30b28de46 video: remove worthless log message
All this information is already output otherwise. Except the FourCC,
which lost most of its importance in mpv.
2015-06-05 18:59:46 +02:00
wm4 54b6389873 vf_sub: minor simplification 2015-06-05 18:59:13 +02:00
Niklas Haas b68627ed2b filter_kernels: distinguish between regular/EWA robidoux
This is because it turns out the regular robidoux is pretty useful for
tscale etc.
2015-06-05 17:08:39 +02:00
wm4 af58bfb62b vo_vdpau: check maximum video size
Check the maximum size of video surfaces, and refuse initialization if
the video is too large for them.

Maybe we could do something more sophisticated, like inserting a
software scaler. On the other hand, this would have a very questionable
benefit, as it would be guaranteed to be too slow.
2015-06-04 22:29:26 +02:00
wm4 c06cd1b993 audio: do not exit when loading small files in paused mode
When starting in paused mode, no audio is written to the device at all,
because writing audio implicitly unpauses the AO. If the file is very
small, and all audio fits within the AO buffer, this accidentally
triggered the EOF condition. (In unpaused mode, it would write all
audio, end playback, and then wait until the AO has everything played.)
2015-06-04 22:05:29 +02:00
wm4 b2d058ef00 ao_alsa: refuse to use spdif if AES flags can't be set
Seems like a good idea to avoid accidentally playing noise by writing
spdif data to pure PCM devices.
2015-06-04 21:54:08 +02:00
wm4 fd96bddca9 af_lavrresample: slightly better computation of total delay
On libavresample, don't ignore the buffered output data.

On libswresample, don't round the total buffer size to the input
samplerate.
2015-06-04 21:23:46 +02:00
wm4 935997d4d6 af_lavrresample: use a new libswresample function if available
It was recently added to libswresample, and it does exactly what we
need.
2015-06-04 19:22:45 +02:00
wm4 2dc46423d6 af_lavrresample: change output samples calculation
This is better, because now we call swr_get_delay() with the output
samplerate, instead of with the input samplerate and then multiplying it
with the ratio and rounding it up.
2015-06-04 19:08:40 +02:00
wm4 c277c17a93 ao_alsa: hack against potential spdif failure 2015-06-04 13:10:33 +02:00
wm4 73401f92ec bootstrap.py: make it work on win32
Apparently, just running ./waf and hoping that it will be run with a
Python interpreter doesn't necessarily work. The workaround is pretty
simple and reliable.
2015-06-04 11:10:02 +02:00
wm4 38c74270c3 inpout.conf: make shift+o toggle between 2 states only
The "osd" command cycles between 4 states (OSD level 0-3), which is
probably confusing and inconvenient. OSD levels 0 and 2 are rarely
needed. I would claim there is normally not much of a need to completely
disable OSD by setting level 0 during playback. Level 2 is just slightly
less information than level 3, and I'm not sure why it exists at all.

Change it so that it toggles between level 3 and 1. Note that this
ignores the default OSD level. If the default is 3, the first use of
this key will set it to 3 again. Just assume 1 is the default. If
someone complains, this could be improved.
2015-06-03 22:02:10 +02:00
wm4 04d5bf4f0b player: print track list when switching tracks 2015-06-03 21:52:32 +02:00
wm4 e14df5c4f4 player: print a message along with track list
Slightly less strange.
2015-06-03 21:50:37 +02:00
wm4 52bd61d698 player: don't print stream list when adding external tracks during load
There's a short time during loading where external commands can add
external streams even before the main file is loaded (like during ytdl
hook execution). The track list is printed every time an external track
is added via commands. This was quite awkward when ytdl was adding
multiple streams, so don't print it in this stage. They are printed
anyway at the end of the loading process.
2015-06-03 21:34:46 +02:00
wm4 e40b663da3 af_lavrresample: use native libavresample function for output size
This also drops the unused get_drain_samples() function.
2015-06-02 22:25:34 +02:00
wm4 5a97ae2715 demux_lavf: fix wrong printf parameter type on 64 bit systems
"f.len - 4" is size_t, not int. Fix by using BSTR_P() (and a bstr
function to adjust the length).
2015-06-02 22:25:34 +02:00
wm4 7556f367d6 ao_coreaudio_exclusive: move generic functions to utils 2015-06-02 22:25:34 +02:00
wm4 7c0d3b9a50 ao_coreaudio_exclusive: react to device removal
Listening to kAudioDevicePropertyDeviceHasChanged does not send any
property change notifications when the device dies. Makes no sense,
but I suppose in CoreAudio logic a dead/removed device can't send
any notifications.

This caused the player to essentially pause playback if the audio
device was removed during playback.

Fix by listening to the kAudioHardwarePropertyDevices property too,
which will actually be sent in this specific case. Then, if
querying the already dead device fails, we know we have to reload.
2015-06-02 22:25:30 +02:00
wm4 87a94a5655 ao_coreaudio_exclusive: make property listeners event-based
In short, instead of letting the coreaudio property listener set atomic
flags (which are then polled), make the property listeners actually
active.

The format change listener used during audio output now simply calls
ao_request_reload() on its own. All code involved is thread-safe, so
there's no need to do it during this audio callback (we assumed the
callback was never run concurrently with itself).

The listener installed temporarily during ca_change_format() is changed
to post a semaphore. Get rid of the weird retry logic and replace it
with a flat loop + timeout. It appears the maximum wait time could be
2500ms; reduce the total timeout to 500ms instead.
2015-06-02 21:04:40 +02:00
wm4 37d505f363 ao: allow ao_uninit(NULL) 2015-06-02 21:03:04 +02:00
wm4 fe8634ea90 af_lavrresample: fix and simplify flushing on playback speed change
This manually retrieved the remaining audio from the resampler. It
subtly missed a conversion which could leave to an unsubtle crash.
This could happen if reorder_planes() was supposed to insert NA
channels, and the resampler/actual output format were different.

Simplify it by reusing the normal drain path. One oddness is that
the filter will add an output frame outside of normal filtering,
but that should be fine.
2015-06-02 20:30:30 +02:00
Rudolf Polzer f14a3df778 idet.sh: Support larger files. 2015-06-02 15:37:41 +02:00
wm4 ed805e16fc osx: add NULL check for input context in a missing case
Fixes a crash on exit under certain circumstances.
2015-06-01 19:36:20 +02:00
wm4 ebc5237c36 vf_vavpp: provide future/past frames to driver
This was missing for extended deinterlacer.

Unfortunately, these deinterlacer still do not work. The provided future
frame (which is all the deinterlacers want) seems to be correct, though.

One minor behavioral change is that this always keeps the previous frame
for PTS computations. This could be avoided (in order to keep exactly
the same behavior as before), but it seems more elegant and should not
do any harm. (Also, if we really cared about reducing hw frame refs,
a more worthy goal is producing the field output incrementally.)
2015-06-01 01:39:30 +02:00
wm4 56c4cdf369 ta: add another array helper macro
Stupid C.
2015-06-01 01:35:56 +02:00
wm4 ebde784fab vf_vavpp: move vaMapBuffer() closer to its use
The mapped data (pointed to by the param variable) is not needed before,
so the call can be moved down. Also, this prevents that the buffer
remains mapped forever if the other vaMapBuffer() call above fails (the
cleanup code forgets to unmap the buffer - this commit makes it
unnecessary).
2015-06-01 01:34:55 +02:00
wm4 8e010a500d vf_vavpp: remove dummy loop, unindent
This used a do-while loop, which runs only once, as replacement for a
cleanup goto. While this is ok, doing a goto directly is easier to
follow and is closer to idiomatic C. But mainly remove it so that the
indentation can be reduced.
2015-06-01 01:34:00 +02:00
wm4 4c20e45561 vf_vavpp: cosmetics
Adjust coding style. Get rid of some useless consts too.
2015-06-01 01:33:37 +02:00
wm4 99bc1df84d vf_vavpp: minor simplification
Slightly easier to follow.
2015-06-01 01:32:52 +02:00
wm4 d91d24ba7e win32: fix window resize logic
Reconfiguring with the same video size should never cause the window to
resize back to the video size (if the user changed its size). This was
broken and it resized anyway.
2015-05-31 17:54:14 +02:00
wm4 a075dfb52c audio: remove an old hack
This was a cosmetic issue. It's handled differently now (clamping the
display time to known duration range).

This reverts commit 33b57f5557.
2015-05-30 22:01:09 +02:00
wm4 3170473003 vo_opengl: output slightly more debugging info on backend probing 2015-05-30 21:25:28 +02:00
wm4 a3f7b38cbc vo: move up vo_wayland in autoprobe list
When running on Wayland, and vo_opengl is not available or rejected for
some reason, it's better to use vo_wayland instead of e.g. vo_x11.
2015-05-30 21:00:37 +02:00
Filip Milivojevic 47d841458d vf_vavpp: fix bob deinterlacing for bottom field first videos
Signed-off-by: wm4 <wm4@nowhere>
2015-05-30 14:56:04 +02:00
wm4 ed925c70c9 vf_vavpp: do not pretend to support references
We do not fill them, so we would pass random IDs to the driver. The code
was originally written to handle bob deinterlacing only, so I guess it
originally passed always 0 anyway, despite having code for reference
surface list allocation.

Also, move down the vaUnmapBuffer() call. This call actually "unmaps"
the param pointer, so accessing it after the unmap call would be
undefined behavior. The "example" in <va/vavpp.h> does this too, but
it's most likely an error.

(Additionally, not even bob deinterlacing worked correctly in my test,
sigh.)
2015-05-29 23:06:22 +02:00
wm4 ad85203d63 vf_vavpp: simplify surface list allocation 2015-05-29 23:01:44 +02:00
wm4 f44725b8d4 player: restore video-aspect on playback resume 2015-05-29 22:34:24 +02:00
wm4 5bea966836 cache: limit readahead size to half the cache size at the beginning
Normally, the cache keeps 50% of the buffer for seeking backwards. Until
now, the cache just used the full buffer size at the beginning of a
file, because the 50% normally reserved for the backbuffer are unused.

This caused a problem: when streaming from http, the player would first
read about 150MB (default cache size), then stop until 75MB of the cache
has been played. (Until the 75MB position, the cache is fully used, so
nothing new can be read. After that, part of the backbuffer starts
getting unreserved, and can be used for readahead.) This long read pause
can cause the server to terminate the connection. Reconnecting may be
possible, but if youtube-dl is used, the media URL may have become
invalid.

Fix this by limiting readahead to 50% even if unnecessary. The only
exception is when the whole file would fit in the cache. In this case,
it won't matter if we can't reconnect, because the cache covers
everything anyway, and hopefully the cache will stay valid.

Likely fixes #2000.
2015-05-29 22:32:10 +02:00
Marcin Kurczewski 20bc56b22d vo_drm: fix not using BUF_COUNT 2015-05-29 18:42:20 +02:00
Marcin Kurczewski 4763718728 vo_drm: fix centering with regard to stride 2015-05-29 18:42:04 +02:00
wm4 d3894290ec vaapi: remove direct mapping non-sense
This must have been some non-sense in the original vaapi mplayer patch.
While I still have no good idea what this "direct mapping" business is
about, it appears to be pretty much pointless. Nothing can hold
additional "real" surface references (due to how the API and mpv/lavc
refcounting work), so removing the additional surfaces won't break
anything. It still could be that this was for achieving additional
buffering (not reusing surfaces as soon), but we buffer some additional
data anyway. Plus, the original intention of the vaapi mplayer code was
probably increasing surface count just by 1 or 2, not actually doubling
it, and/or it was a "trick" to get to the maximum count of 21 when h264
is in use.

gstreamer-vaapi uses "ref_frames + SCRATCH_SURFACES_COUNT" here, with
SCRATCH_SURFACES_COUNT defined to 4. It doesn't appear to check the
overlay attributes at all in the decoder.

In any case, remove this non-sense.
2015-05-29 16:28:55 +02:00
wm4 327b091909 lua: fix options submodule
It polluted the global namespace, instead of exporting the function
properly.

For now, keep it compatible by explicitly keeping the bogus export.

Also fix a mistake in the manpage example.
2015-05-29 15:50:09 +02:00
wm4 9fe6a8c5f5 vd_lavc: fix a hw decoding fallback case
On hw decoder reinit failure we did not actually always return a sw
format, because the first format (fmt[0]) is not always a sw format.
This broke some cases of fallback. We must go through the trouble to
determine the first actual sw format.
2015-05-29 14:17:51 +02:00
wm4 6a5cbe7802 vdpau: do not attempt to allocate surfaces while preempted
This reduces spam while preempted a bit.

The remaining message, "hardware accelerator failed to decode picture"
on every frame, can not be prevented because it's hardcoded in
libavcodec.
2015-05-29 13:48:18 +02:00
wm4 c4757ad17c vo_opengl: avoid broken shader if hwdec fails to provide textures
If gl_hwdec_driver.map_image fails, all textures will be set to 0. This
in turn makes pass_prepare_src_tex() skip generation of the texture
uniforms, which leads to a shader compilation error, as e.g. texture0 is
not defined but expected to exist and accessed.

Set the textures to an invalid non-0 ID instead. OpenGL can deal with
it.
2015-05-28 21:56:45 +02:00
wm4 6f5a10542c vdpau: add support for the "new" libavcodec vdpau API
Yet another of these dozens of hwaccel changes. This time, libavcodec
provides utility functions, which initialize the vdpau decoder and map
codec profiles. So a lot of work the API user had to do falls away.

This also will give us support for high bit depth profiles, and possibly
HEVC once libavcodec supports it.
2015-05-28 21:56:13 +02:00
wm4 0699a6c598 video: rename vdpau.c to vdpau_old.c
vdpau.c will be used for new code.
2015-05-28 21:56:09 +02:00
wm4 a9b1e72ef2 vd_lavc: allocate hw surfaces using the coded size
...instead of relying on the hw decoding API to align it for us. The old
method could in theory have gone wrong if the video is cropped by an
amount large enough to step over several blocks.
2015-05-28 21:55:16 +02:00
wm4 e632e37ab8 vdpau: retrieve mixer parameters directly from the hw surface
Always configure the vdpau mixer based on the current surface sent to
it. Before this, we just hardcoded the chroma type, and the surface size
was essentially a guess.

Calling VdpVideoSurfaceGetParameters() on every surface is a bit
suspicious, but it appears it's a cheap function (just requiring some
locks and a table lookup). This way we avoid creating another
complicated mechanism to carry around the actual surface parameters
with a mp_image/AVFrame.
2015-05-28 21:54:02 +02:00
wm4 939132cbd9 vd_lavc: merge two functions
There's not much of a reason to keep get_surface_hwdec() and
get_buffer2_hwdec() separate. Actually, the way the mpi->AVFrame
referencing is done makes this confusing. The separation is probably
an artifact of the pre-libavcodec-refcounting compatibility glue.
2015-05-28 21:53:37 +02:00
wm4 a2eb0ab076 vd_lavc: make hardware decoding fallback less violent
Most of hardware decoding is initialized lazily. When the first packet
is parsed, libavcodec will call get_format() to check whether hw or sw
decoding is wanted. Until now, we've returned AV_PIX_FMT_NONE from
get_format() if hw decoder initialization failed. This caused the
avcodec_decode_video2() call to fail, which in turn let us trigger the
fallback. We didn't return a sw format from get_format(), because we
didn't want to continue decoding at all. (The reason being that full
reinitialization is more robust when continuing sw decoding.)

This has some disadvantages. libavcodec vomited some unwanted error
messages. Sometimes the failures are more severe, like it happened with
HEVC. In this case, the error code path simply acted up in a way that
was extremely inconvenient (and had to be fixed by myself). In general,
libavcodec is not designed to fallback this way.

Make it a bit less violent from the API usage point of view. Return a sw
format if hw decoder initialization fails. In this case, we let
get_buffer2() call avcodec_default_get_buffer2() as well. libavcodec is
allowed to perform its own sw fallback. But once the decode function
returns, we do the full reinitialization we wanted to do.

The result is that the fallback is more robust, and doesn't trigger any
decoder error codepaths or messages either. Change our own fallback
message to a warning, since there are no other messages with error
severity anymore.
2015-05-28 21:52:04 +02:00
wm4 0949ee347d demux_lavf: do a better job at guessing the vobsub .sub filename
Vobsubs come as .idx/.sub pair of files. The .idx file is the one that
should be opened, but the name of the .sub file is unknown. We can now
make our own guess what the name of that file is. In particular, improve
support with URLs (as these can have the file extension in the middle of
the filename string if there are HTTP parameters).

Note that this works only with newer ffmpeg versions, because the
recently added sub_name demuxer option is used for this.
2015-05-28 21:51:54 +02:00
Marcin Kurczewski ce0bf9692f vo_drm: Expose mode ID option to users 2015-05-28 21:51:49 +02:00
Marcin Kurczewski eea625736f vo_drm: Fix resolution not restored after exiting 2015-05-28 21:51:49 +02:00
Marcin Kurczewski 5a1ef9d8db vo_drm: Fix stride problem for certain devices 2015-05-28 21:51:48 +02:00
wm4 dc2c7371f1 command: remove deprecated get_property command
This command has been deprecated in the 0.8.x and 0.9.x releases - get
rid of it. Its only point ever was MPlayer compatibility, which broke
years ago anyway.
2015-05-27 18:08:02 +02:00
wm4 e8a1d35e9c options: remove --slave-broken
It has been deprecated for ages.
2015-05-27 18:01:26 +02:00
wm4 ac6ebbbcbc player: set cocoa input context at an earlier point
There is not much of a reason to do this later. (Since some time ago,
the input_ctx is created right at the start, so this can be done now.)
2015-05-27 17:57:24 +02:00
wm4 ba45c410d3 player: load scripts at an earlier point
This is about as early as possible.
2015-05-27 17:53:58 +02:00
wm4 acc4102ba2 vo_opengl: rename use_full_range to use_normalized_range
As suggested by haasn. The term "full range" makes it sound like it has
to do with TV vs. PC range, which is not the case at all.
2015-05-27 17:40:58 +02:00
Stefano Pigozzi b50390d5da DOCS: fix wrong libmpv's cocoa example comment
libmpv can be embedded in a cocoa view (without the mpv window). This has been
the case for serveral months, and the comment is just wrong now.
2015-05-27 14:34:42 +02:00
Niklas Haas b65c548b7d vo_opengl: fix source-shader + XYZ input 2015-05-27 11:32:42 +02:00
wm4 ae1ac475ac DOCS: interface-changes: mention recent vo_opengl additions 2015-05-27 11:28:21 +02:00
Niklas Haas 22af0dce0d vo_opengl: CMS no longer implies linear scaling
They're completely orthogonal concepts, merged in the past due to
convenience and ease of implementing it in the old #ifdef hell renderer.

Especially after the CMS stuff was generalized by 634b4a, this was a
trivial change to implement and also means color management will be much
higher quality when enabled with vo=opengl (which had quantization
issues in the past due to the 8 bit FBO format and upscaling), since it
can be done in a single pass now.
2015-05-27 11:24:12 +02:00
Niklas Haas 13d4ee6d1c vo_opengl: icc-profile overrides icc-profile-auto
Signed-off-by: wm4 <wm4@nowhere>
2015-05-27 11:23:16 +02:00
Niklas Haas 4d6b9550fe vo_opengl: add support for custom shaders 2015-05-27 11:09:41 +02:00
wm4 bf4dd877e9 osx: synchronize access to the input_ctx
While all functions of input_ctx are inherently thread-safe, access to
the _inputContext field itself is not. It could be unset any time by
cocoa_set_input_context(). So even trivial input_ctx calls must be under
a lock, so that the input_ctx can not be destroyed while the function
call is "starting". (Even a function call in progress wouldn't be fine,
because mp_input_uninit() requires the caller to "own" the object, i.e.
no other threads can access it at this point.)
2015-05-26 22:48:04 +02:00
wm4 2dd904289d osx: never expose input_ctx from EventsResponder
Keep it internal, so we can synchronize access to it properly.
2015-05-26 22:39:04 +02:00
wm4 39a339c813 input: remove some unneeded things
Wakeup FDs are not needed anymore (this code exists only for libwaio
usage by now), and 2 other functions can be made private.
2015-05-26 22:00:25 +02:00
wm4 51654d2ad5 command: better choice when to allow playback-related commands
For certain reasons, we allow adding external tracks even before the
main file is loaded. This somewhat breaks in old assumption, which uses
mpctx->num_sources to determine whether a command can be applied in the
current state. Use the newer playback_initialized instead, which is a
much better choice for this purpose.
2015-05-26 21:42:34 +02:00
wm4 3c24250c14 command: fix track property when no file is loaded
The previous commit removed this. Although mp_switch_track() can now be
called in all situations, we still don't want it to be called here.
Setting a track property while no file is loaded would simply deselect
the track instead of setting the underlying option to the requested
value.

Likewise, if the "cycle" command (M_PROPERTY_SWITCH) is used, don't just
deselect the track.
2015-05-26 21:33:34 +02:00
wm4 88249baf5b player: fix crashes when adding external tracks before loading main file
Adding an external audio track before loading the main file didn't work
right. For one, mp_switch_track() assumes it is called after the main
file is loaded. (The difference is that decoders are only initialized
once the main file is loaded, and we avoid doing this before that for
whatever reason.)

To avoid further messiness, just allow mp_switch_track() to be called at
any time. Also make it do what mp_mark_user_track_selection() did, since
the latter requires current_track to be set. (One could probably simply
allow current_track to be set at this point, but it'd interfere with
default track selection anyway and thus would be pointless.)

Fixes #1984.
2015-05-26 14:01:23 +02:00
wm4 bdcd25d3c2 demux: don't get stuck on some cases of timestamp resets
In this case, streaming ogg via mpd over icecast made it buffer
infinitely on new tracks.
2015-05-26 12:59:48 +02:00
wm4 302901ddaf ao_alsa: hack back mono output
The ALSA API is inconsistent and doesn't report support. Just requesting
1 channel actually works. Whatever.
2015-05-25 22:10:35 +02:00
wm4 446a10020f TOOLS/lua/status-bar: update use of a deprecated property
Also mention that this code does not reflect the status line of current
mpv.
2015-05-25 22:01:34 +02:00
wm4 289705daaf input: allow - as separator between commands, instead of _
Wnile it seems quite logical to me that commands use _ as word
separator, while properties use -, I can't really explain the
difference, and it tends to confuse users as well. So always
prefer - as separator for everything.

Using _ still works, and will probably forever. Not doing so would
probably create too much chaos and confusion.
2015-05-25 21:59:44 +02:00
wm4 6bfbd4ebdc command: change the hwdec properties
Another very minor step towards property/option unification.

Not bothering with interface compatibility here.
2015-05-25 21:44:48 +02:00
wm4 449cdfc0ff vd_lavc: report actually used hwdec API
Instead of the requested one, which can be just "auto", and which is
rather useless.
2015-05-25 21:43:20 +02:00
wm4 3fc3357d54 vf_dlopen: declare as deprecated
Mostly to see whether someone uses it, and if a better solution can be
worked out. (It's simple enough to be supported forever.)
2015-05-25 21:13:54 +02:00
Stefano Pigozzi 34875413fa cocoa: don't load hardcoded icon if running from bundle
Makes ricers happy.
2015-05-25 08:58:32 +02:00
wm4 05a75d0a76 demux_edl: fix includes
It doesn't need access to the playback core state anymore.
2015-05-24 23:27:23 +02:00
wm4 f3dcd85150 video: do not use MP_NOPTS_VALUE for A/V difference
There's no need for this, it just creates more corner cases.

Also always reset it on seeks etc..
2015-05-24 23:27:23 +02:00
wm4 58e7d0a30b player: add function to compute past frame durations
And use it for the estimated-vf-fps property (it should be doing the
same as before).
2015-05-24 23:27:23 +02:00
wm4 0d0444fed0 vo_null: add framerate emulation 2015-05-24 23:27:18 +02:00
Philip Sequeira 9e77b8f06a manpage: --media-title -> --force-media-title
Missed in 450af053.
2015-05-24 01:16:12 -04:00
torque 36b1b84216 DOCS/client_api_examples/cocoa-openglcb: do initial flush correctly. 2015-05-23 19:21:10 +02:00
wm4 8054c034b8 command: add protocol-list property
Fixes #1972.
2015-05-23 15:26:55 +02:00
wm4 a3f8d45fb6 ytdl: do not use deprecated option
This was missed in commit 450af053.
2015-05-23 15:15:16 +02:00
Niklas Haas fa7b22c687 vo_opengl: switch to new OpenGL backend API for icc-profile-auto
The current code just segfaults.
2015-05-22 21:56:16 +02:00
wm4 f7ca2c83e1 command: allow changing track properties while no file is loaded
Now it simply changes the options, i.e. what will be requested, instead
of returning M_PROPERTY_UNAVAILABLE.

This is another minor step towards unifying options and properties.

Still a bit weird: it will always return "no" if no file is loaded, and
disregards the option value.
2015-05-22 21:05:03 +02:00
wm4 ae46833836 player: use an array for stream ID options and such
This makes the code slightly more generic.
2015-05-22 21:00:24 +02:00
wm4 a7c831f36d command: deprecate audio-samplerate
Also replace their implementation with the recently introduced
properties. One significant difference is that audio-channels using OSD
formatting does not print the channel layout. The user can just use the
replacement property instead.
2015-05-22 20:28:20 +02:00
wm4 f9507fe927 command: add audio-params and audio-out-params properties 2015-05-22 20:23:47 +02:00
wm4 1eaceb5fae command: remove old property deprecation warning mechanism
We don't need two.

This mechanism was basically for MPlayer, and it has expired its
usefulness by now.
2015-05-22 20:08:04 +02:00
wm4 ff0b33ac9d command: rename audio-format property
Clashes with the option.
2015-05-22 20:05:36 +02:00
wm4 450af05338 options: rename --media-title option
Conflicts with the property.
2015-05-22 20:03:14 +02:00
wm4 d26803cba0 command: deprecate the "length" property
It collides with the --length option.
2015-05-22 20:02:47 +02:00
wm4 c2f9e3d2b3 command: add a new property deprecation mechanism
Looks like this will be needed a lot...
2015-05-22 20:02:04 +02:00
wm4 17b3cab983 DOCS: add a changelog for option/command/property changes
All these make up both user interface and API. It's a good idea to
actually keep track of changes to it.
2015-05-22 19:16:42 +02:00
wm4 a165a61415 audio: make softvol scale cubic
This brings the volume control closer to what is percepted as linear
volume change.

Adjust the --softvol-max default to roughly the old maximum (roughly
doubles the gain).
2015-05-22 19:16:42 +02:00
wm4 68bbab0e42 audio: change range of volume option/property
Now --volume takes an absolute volume, meaning it doesn't depend on
--softvol-max. 0 is still silence, and 100 now always means unchanged
volume. The OSD and the "volume" property are changed accordingly.

Also raise the minimum value of --softvol-max. A value below 100 makes
no sense and breaks the OSD.
2015-05-22 18:35:03 +02:00
wm4 eb296d4fde options: --loop without argument means looping forever
Adding a "yes" choice makes the option parser consider this option as a
multi-state flag option, and without argument "yes" is implicitly
selected. "yes" is made an alias for "inf", so it will loop infinitely.

As a negative side effect, the old syntax "-loop inf" does not work
anymore. Since this is ambiguous, the option parser prefers interpreting
the "inf" as filename.

Fixes #1970.
2015-05-22 14:56:26 +02:00
wm4 8c795d7963 command: explicitly show mouse cursor when unfullscreening 2015-05-21 23:11:51 +02:00
wm4 ac879545ad win32: do not call timeEndPeriod(1) on termination
This was called for formal reasons at best. The way it does this is
somewhat dangerous, because if libmpv is unloaded as DLL, this would
attempt to call a dangling function pointer.

(No, we don't want an extra DllMain entrypoint just for win32.)
2015-05-21 22:52:14 +02:00
wm4 cbaa8d65fc DOCS/client_api_examples: cocoa: minor fixes
Cocoa needs to be linked explicitly.

EXIT_SUCCESS is pretty pointless, and the same file uses exit(1) in
other places.
2015-05-21 22:45:56 +02:00
torque 83012fd77a DOCS/client_api_examples: add opengl-cb-based cocoa example.
Contains a basic toggle button that pauses the video.
2015-05-21 22:29:57 +02:00
wm4 7412995c94 chmap: use av_popcount64()
Saves us some code, and also happens to fix #1968.
2015-05-21 20:37:17 +02:00
wm4 292266f268 vo_opengl: vda: make it work anywhere
A rather dumb hack to copy the problematic rectangle textures (mandated
by VDA) into 2D ones.

(This isn't done yet for OpenGL 3.0+. We need to make sure the
performance isn't reduced too much by it.)
2015-05-21 20:27:22 +02:00
wm4 af667643a0 video: do not align source position to 2
vo_direct3d still seems to require this (tested on Windows 8.1 with
Intel graphics). Do it in vo_direct3d instead of messing with all VOs.
2015-05-21 19:27:54 +02:00
wm4 cf023e1f3a vo_opengl: remove npot option
Completely useless.
2015-05-21 19:27:47 +02:00
Robin f07ef6087d DOCS/mplayer-changes: add relative seeking by %
Add relative seeking by percentage to mplayer-changes.rst
2015-05-21 12:10:44 +02:00
wm4 8724e3e2dd vo_xv: make number of buffers configurable 2015-05-20 23:07:47 +02:00
Robin 9bd3ae311f command: refactor if/else statements to switch
The code checking for the type of seeking contained some if else
statements. To improve readability, I decided to refactor those
statements to a switch statement.
2015-05-20 22:59:19 +02:00
wm4 0e78424842 video: force audio resync after video discontinuity 2015-05-20 14:28:02 +02:00
wm4 3e0dae6959 video: better heuristic for timestamp resets
Reduce the default tolerance for timestamp jumps from 60 to 15 seconds.
For .ts files, where ts_resets_possible coming from AVFMT_TS_DISCONT is
set, apply a more sophisticated heuristic. It's clear that such a file
wouldn't have a framerate below, say, 23hz. If the demuxer reports a
lower fps, we allow longer PTS jumps.

This should replace long pauses on discontinuities with .ts files with
at most a short stutter.

Of course, all kinds of things could go wrong anyway if the source is
VFR, or FFmpeg's frame rate detection fails in some other way. I haven't
found such a file yet, though.
2015-05-20 14:24:55 +02:00
wm4 402fe381d7 audio: fix resync issue different
Commit 10915000 attempted to fix wasting CPU when resyncing and no new
data was actually coming from the demuxer. The fix assumed that at this
point it would have reached the sync point, but since the code attempts
weird incremental decoding, this wasn't actually true. So it broke
seeking in addition to removing the CPU waste.

Try something else. This time, we essentially only wakeup again if
data was read (i.e. audio_decode() returned successfully).
2015-05-19 23:23:17 +02:00
rrooij 36529bc6f7 command: change OSD symbol for absolute perc. seek
The OSD symbol for seeking to an absolute percentage was always OSD_FFW,
even when it should be OSD_REW. It uses the correct OSD symbols now, by
checking the current position ratio.

Note: The symbol is still incorrectly given when the absolute percentage
is very close to the current position ratio. Fortunately, that's a rare
use case.
2015-05-19 23:23:04 +02:00
wm4 e57a44c341 manpage: fix syntax
I guess this wasn't meant to be literal syntax, but it implies "," is
used as sub-option separator.
2015-05-19 21:38:19 +02:00
wm4 4d2a01b776 demux: read cue sheets embedded in tags
This reads the "CUESHEET" tag, and attempts to parse it as .cue data. If
any is found, the cue tracks are added as chapters.

This reuses the parser written for demux_cue.c.

Fixes #1957.
2015-05-19 21:36:52 +02:00
wm4 0ed1719e1a demux_cue: move cue parser to a separate file
Preparation for the next commit.
2015-05-19 21:36:21 +02:00
wm4 1919f1e05b ad_spdif: use DTS-HD passthrough only if the audio is really DTS-HD
Apparently some A/V receivers do not behave well if "normal" DTS is
passed through using the high bitrate spdif format normally used for
DTS-HD (other receivers are fine with it).

Parse the first packet passed to ad_spdif by decoding it with libavcodec
in order to get the profile. Ignore the --ad-spdif-dtshd if it's not
DTS-HD. (If the codec profile changes midstream, the user is out of
luck. But this is probably an insignificant corner case.)

I thought about parsing the bitstream, but let's not. While it probably
wouldn't be that much effort, we are trying to keep it down on codec
details here - otherwise we could just do our own spdif framing instead
of using libavformat's spdif pseudo-muxer.

Another possibility, using the codec parameters signalled by
libavformat, is disregarded. Our builtin Matroska decoder doesn't do
this, and also we do not want on the demuxer having to decode some
packets in order to retrieve codec params (as libavformat does).

Fixes #1949.
2015-05-19 21:35:43 +02:00
wm4 a6d3a6919a ad_spdif: set output format lazily
Preparation for the following commit, which looks at the packet data
before deciding what to output.
2015-05-19 21:34:30 +02:00
wm4 10915000fb audio: avoid wasting CPU due to continuous wakeup
Thsi code path happens during seeking. If video is still being decoded
to get to the first video frame, audio has nothing to do, as it is
synchronized against the first video frame. We only want to wake up if
there's an actual state change.

Fixes #1958.
2015-05-19 21:33:48 +02:00
rrooij 0c84f6e820 command: use consistent comment style
Signed-off-by: wm4 <wm4@nowhere>
2015-05-19 21:33:40 +02:00
rrooij e17a8550c4 input: add relative percentage seek
Only absolute percentage seeking was permitted first. It is now also
possible to seek by relative percentage.

MPSEEK_FACTOR is used as seek_type.

Fixes #1950.

Signed-off-by: wm4 <wm4@nowhere>
2015-05-19 21:33:40 +02:00
wm4 be9bf4cc7c x11: never forcefully terminate xdg-screensaver process
It sometimes happens on exit, and it's probably a bad idea. If the
process hangs on exit (possibly due to stupid hardcoded timeouts it's
doing), mpv will also hang now, unfortunately.
2015-05-18 22:25:59 +02:00
Mateusz Łukasik 0d020c5c46 mpv.desktop: shorten polish name
The Polish name was too long and contradicted. One word is enough.

Signed-off-by: wm4 <wm4@nowhere>
2015-05-18 22:03:05 +02:00
wm4 21cb1f7075 sub: add .sup file extension for subtitle autoloading 2015-05-18 10:28:01 +02:00
wm4 f4c412a057 command: add playlist_shuffle command
Fixes #965.
2015-05-17 21:16:10 +02:00
wm4 aa78dff42b input.conf: add CTRL+s key binding for window screenshots 2015-05-17 21:09:21 +02:00
Avi Halachmi (:avih) bc503a0e88 manpage: improve osc help
Signed-off-by: wm4 <wm4@nowhere>
2015-05-16 21:02:11 +02:00
torque 5d2a2c7fc2 DOCS/client_api_examples: Qt: force qmake to use pkg-config. 2015-05-16 20:56:44 +02:00
wm4 f9ff4b59a2 manpage: lua: clarify OSD differences between mp.command/mp.commandv
Conflicts:
	player/audio.c
	player/video.c
2015-05-16 12:32:34 +02:00
wm4 a4f3df5970 x11: attempt to make initial fullscreening more reliable
It appears some WMs have a problem with out method of setting initial
fullscreen mode. We assume that if the window's _NET_WM_STATE includes
_NET_WM_STATE_FULLSCREEN before mapping the window, the WM will show it
as fullscreen at mapped. EWMH doesn't say anything that this should
work, although one could argue that it's implied.

In any case, since it's not standard behavior without at least some
doubt, it's probably a good idea to try the "old" method as well.
Fortunately, it should be idempotent.

See #1937, #1920.
2015-05-15 13:50:44 +02:00
wm4 06bfa9309d vf_vapoursynth: reject unaligned video sizes
Leads to some nice memory corruption otherwise.
2015-05-15 13:41:19 +02:00
wm4 372b85b9d2 vo: remove suspicious line
pts can never be 0 or negative. If there is no frame, some code below
catches this case by checking hasframe.
2015-05-15 13:40:43 +02:00
Michael Vetter 9251fa125f Remove trailing whitespaces 2015-05-15 11:02:44 +02:00
wm4 24f98d1aaf video: add hevc to whitelist of hwdec codecs
This means if --hwdec is used, and hardware decoding is supported for
HEVC, it's actually used.
2015-05-14 20:17:23 +02:00
wm4 a2235b0280 dxva2: support HEVC
This is pretty much copy&pasted from Libav commit
a7e0380497306d9723dec8440a4c52e8bf0263cf.

Note that if FFmpeg was not compiled with HEVC DXVA2 support or your
video drivers do not support HEVC, the player will not fallback and
just fail decoding any video. This is because libavcodec appears not
to return an error in this case. The situation is made worse by the
fact that MSYS2 is on an ancient MinGW-w64 release, which does not
have the required headers for HEVC DXVA2 support.
2015-05-14 17:44:48 +02:00
wm4 bad932e8ed vo_opengl: hardcode rquested GL version in backends
The requested version field didn't make much sense anymore, and was even
partially ignored by some backends.
2015-05-14 13:07:00 +02:00
wm4 fa39dadb05 x11: use new OpenGL backend API 2015-05-14 00:05:54 +02:00
wm4 df97c30e0e vo_opengl: create new API for OpenGL VO backends
An attempt to get rid of the weird mix of callbacks that take either
struct vo or MPGLCopntext as parameter. This is not perfect, and the
API will probably change a bit until all other code is ported to it.
the main question is how to separate struct vo completely from the
windowing code, which actually needs vo for very little.

In the end, the legacy callbacks will be dropped.
2015-05-14 00:05:43 +02:00
wm4 10de9b091a vo_opengl: change user options for requesting GLES
Instead of having separate backends, make use of GLES a flag. This
reduces the number of backends and the resulting annoyances.

Also, nobody cares about using GLES, so there's no backward
compatibility either.
2015-05-14 00:05:39 +02:00
wm4 27da344e6f vo_opengl: merge GL backend creation/initialization
The final goal is to remove the nonsense separation between the 3
backend init/vo_init/GL context creation calls.
2015-05-13 22:56:44 +02:00
wm4 5ab05f61ca vo_opengl: remove mpgl_lock calls
Awkward stuff not needed anymore.
2015-05-13 22:03:24 +02:00
wm4 d89eb74cb7 cocoa: redo synchronization
Before this change, Cocoa state was accessed from both the VO and the
Cocoa main thread. This was probably not a good idea. There was some
locking as well as implicit synchronization using the dispatch
mechanism, but it wasn't watertight.

Change this completely. Now Cocoa things are always accessed from the
main thread only. The old mutex falls away, as well as the
vo_cocoa_set_current_context() function, which implicitly used the lock
to coordinate VO accesses. With the new code, the VO thread generally
has to wait for the main thread, while the main thread never waits for
the VO and rarely accesses it. Fortunately, this is rather straight
forward, and most of this is achieved by making vo_cocoa_control() run
on the main thread. The logic of the code does generally not change.

Some aspects are trickier. Apparently we can't access the
NSOpenGLContext from the VO thread, because this object is not thread-
safe. We use some CGLContextObj functions instead, such as for making
the context current and swapping the buffers.
2015-05-13 22:00:34 +02:00
wm4 7e21f6fd00 vo_opengl: remove some more Cocoa resize leftovers 2015-05-13 21:58:37 +02:00
wm4 0468a4ea47 manpage: explain some property expansion restrictions 2015-05-13 20:44:55 +02:00
wm4 a23a46c6ed manpage: remove stray newline 2015-05-13 20:44:55 +02:00
Stefano Pigozzi 5258c012fe vda: add support for nv12 image formats
The hardware always decodes to nv12 so using this image format causes less cpu
usage than uyvy (which we are currently using, since Apple examples and other
free software use that). The reduction in cpu usage can add up to quite a bit,
especially for 4k or high fps video.

This needs an accompaning commit in libavcodec.
2015-05-13 19:57:39 +02:00
Christian Hesse 5b085fd8b1 build: check for lua52
Arch linux is about to update to lua 5.3.x, but lua 5.2.x will be
provided by package lua52, which contains pkg-config file lua52.pc.

Signed-off-by: wm4 <wm4@nowhere>
2015-05-13 14:59:52 +02:00
wm4 0bdef9979f vo: avoid burning CPU when paused
Some code always calls vo_event(), even with event==0, which leads to
immediate wakeup, which in turn causes the function to be called again.
This would burn CPU, which was especially noticeable when paused.
2015-05-13 09:28:59 +02:00
wm4 fc9695e63b win32: add mappings for some special keys
Untested.
2015-05-12 23:01:32 +02:00
wm4 47d69f366b ipc: avoid SIGPIPE
Until now, we just blocked SIGPIPE globally. Fix it properly to get away
from it.

MSG_NOSIGNAL should be widely available and is part of the POSIX.1-2008
standard. But it's not available on OSX, because Apple is both evil and
retarded. Thus we continue to ignore the problem on such shitty systems.
2015-05-12 22:54:11 +02:00
wm4 29eb764fe0 cocoa: make live-resizing as fast as before
Interrupt video timing. This means the Cocoa event loop does not have
to up to 2 video frame durations until redrawing the frame finally has
finished.

We abuse the VO event flags for this. Eventually this should use
wait_vo() or so in the video timing wait function, but for now the
interaction this would require with the code of other VOs/backends
would cause too much of a mess.
2015-05-12 22:42:06 +02:00
wm4 7735b29732 cocoa: handle live-resizing differently
Instead of requiring a complicated mechanism to share the entire OpenGL
and renderer state between VO and Cocoa thread just to do the redrawing
during live-resize on the Cocoa thread, let the Cocoa thread wait on the
VO thread. This wil allow some major simplifications and cleanups in the
future.

One problem with this is that it can enter a deadlock whenever the VO
tries to sync with the Cocoa thread. To deal with this, the Cocoa thread
waits with a timeout. This can probably be improved later, though in
general this situation can always happen, unless the Cocoa thread waits
in a reentrant way.

Some other details aren't completely clean either. For example,
pending_events should be accessed atomically. This will also be fixed
later.
2015-05-12 22:31:03 +02:00
wm4 434343d634 vo: use pthread_cond_timedwait() for video timing
Will be used to make video waiting interruptible with Cocoa (see the
following commit).

One worry was that this could cause hangs if the system clock jumps
backwards. Normally we don't support such behavior, because it's
almost impossible to handle it reasonably. E.g. we would have to
change the default clock type for condition variables, which in turn
would require a custom function for creating condition variables,
or so. If the OS even supports different clocks.

But it turns out that this is no issue, because other events seem
to wakeup the wait call anyway, and mpv internal absolute times use
a monotonic clock.
2015-05-12 22:30:45 +02:00
wm4 6b7155c05b vo_opengl_cb: add support for interpolation
This uses the OpenGL frame interpolation code, which before could be
used by vo_opengl only.

Some effort was made to make it behave like vo_opengl, for the better or
the worse. As a consequence, there is a minor duplication of code and
mechanism. Hopefully this can all be wiped as soon as the VO frame
queue/timing mechanism is cleaned up.

This also attempts to use mpv_opengl_cb_report_flip() (as called by the
API user) to determine the vsync interval. This might need refinement as
well.

(In general, we simply expect the API user to work in vsync-blocking
manner.)
2015-05-12 22:16:38 +02:00
wm4 ee3de1a063 vo_opengl_cb: add a "block" framedrop mode and make it default
(I have no idea why there are different modes.)

Instead of risking to drop frames too early, give it some margin. Since
there are situations this could deadlock, wait with a timeout. This can
happen if e.g. the API user is refusing to render anything, or if
uninitialization is happening.
2015-05-12 22:16:19 +02:00
wm4 4d9255a5e1 vo_opengl_cb: actually set requested options
Quite an oversight.
2015-05-12 22:16:07 +02:00
wm4 af157db7e5 vo: always call draw_image_timed() if available
Gives the VOs more flexibility.

gl_video.c already ignores the timing info if no interpolation is
active, so this requires no further changes.
2015-05-12 22:15:04 +02:00
wm4 92b9d75d72 threads: use utility+POSIX functions instead of weird wrappers
There is not much of a reason to have these wrappers around. Use POSIX
standard functions directly, and use a separate utility function to take
care of the timespec calculations. (Course POSIX for using this weird
format for time values.)
2015-05-11 23:44:36 +02:00
wm4 ca9964a4fb ao: make better use of atomics
The main reason for this was compatibility; but some associated problems
have been solved in the previous commit.
2015-05-11 23:27:41 +02:00
wm4 cc24ec5b3c atomics: add atomic_fetch_and/atomic_fetch_or
As usual, we prefer plain C11 names and semantics, and have to emulate
them if C11 atomics are not available.

For the non-atomic fallback (which is just there to make code compile in
situations the atomic property is not overly important), we require a
gross hack to make the generic macros work without using compiler-
specific extensions.
2015-05-11 23:20:45 +02:00
wm4 e5573728c7 cocoa: remove unused declaration 2015-05-11 22:56:20 +02:00
wm4 10149f68a5 cocoa: add missing break statements in switch
The first one (for VOCTRL_GET_DISPLAY_FPS) could have led to undefined
behavior if the FPS was unknown. The second is for general symmetry.
2015-05-11 22:56:18 +02:00
wm4 a7ecb11ddd cocoa: remove unused macro 2015-05-11 22:56:15 +02:00
wm4 4858c47e1c Always block SIGPIPE globally
OpenSSL and GnuTLS are still causing this problem (although FFmpeg could
be blamed as well - but not really). In particular, it was happening to
libmpv users and in cases the pseudo-gui profile is used. This was
because all signal handling is in the terminal code, so if terminal is
disabled, it won't be set. This was obviously a questionable shortcut.

Avoid further problems by always blocking the signal. This is done even
for libmpv, despite our policy of not messing with global state.

Explicitly document this in the libmpv docs. It turns out that a version
bump to 1.17 was forgotten for the addition of MPV_FORMAT_BYTE_ARRAY, so
document that change as part of 1.16.
2015-05-11 17:38:35 +02:00
wm4 a5aa58c63c TOOLS/stats-conv.py: add another event type 2015-05-11 17:20:30 +02:00
rrooij 47ee67b8a2 DOCS/man/options.rst: Remove trailing whitespaces 2015-05-10 12:36:55 +02:00
rrooij 5d7468a06e DOCS/man/opions.rst: Elaborate on --no-video
When --no-video is set, the ytdl-format is set to "bestaudio/best". This
wasn't documented in the man page yet.
2015-05-10 12:30:24 +02:00
wm4 9438f811ae ytdl_hook: remove tabs
We don't allow tabs in normal source code.
2015-05-09 21:41:44 +02:00
wm4 27f7489adc build: exclude -Wredundant-decls
It's useless, and creates a bogus warning in subprocess-posix.c.

Since I don't know which compilers might have it by default, just change
it to -Wno-redundant-decls.
2015-05-09 19:59:52 +02:00
wm4 0f063a5011 old-configure: hide
It shouldn't be used, but it's still in the repo because I say so.
2015-05-09 19:55:11 +02:00
wm4 1f389b05fc old-configure: bump libbluray version
Fixes #1927.
2015-05-09 19:50:13 +02:00
wm4 5fe2c19029 player: reuse a function
This has the side-effect that now all encoding-profiles.conf files are
loaded. It's not clear if not doing this was intended or not.
2015-05-09 16:48:08 +02:00
wm4 e9963139da path: improve verbose logging 2015-05-09 16:48:08 +02:00
wm4 6d93dd8969 path: use mp_path_join in one more place 2015-05-09 16:48:08 +02:00
wm4 b6346cd0ba player: make resuming playlists less noisy in verbose mode
mp_find_config_file() will print the filename lookup and its result in
verbose mode. This is wanted, but gets inconvenient when it is done for
every playlist entry (for resuming).

Lookup the watch_later subdir only once and cache the result instead.

This drops the logic for loading the resume file from other locations,
which should generally be unnecessary, though might lead to confusion if
the user has mixed old and new config paths (which the user shouldn't).

Also add a mp_find_user_config_file() function for a more
straightforward and reliable way to get actual local configpaths,
instead of possibly global and unwritable locations.

Also, for symmetry, check the resume option in mp_load_playback_resume()
just like mp_check_playlist_resume() does.
2015-05-09 16:48:05 +02:00
wm4 34ee78f2cb player: avoid undefined behavior when resumign DVD/BD playback
These device options can be NULL, and NULL can't be passed for %s.
2015-05-09 15:37:05 +02:00
wm4 04c02796bd path: make mp_path_join accept normal C strings
Instead of bstr. Most callers of this function do not need bstr. The
bstr version of this function is now mp_path_join_bstr().
2015-05-09 15:26:47 +02:00
wm4 40997b8ae5 lua: remove deprecated "lua" sub directories
The compatibility code and the deprecation warning were at least in
releases 0.8 and 0.9 - time to get rid of them.
2015-05-09 15:04:05 +02:00
wm4 2263f37dfb path: unify the two config file lookup functions
Share most of the implementation of config file lookup between
mp_find_all_config_files() and mp_find_config_file().

Also move the check for config path overrides to mp_get_platform_path()
directly. From the point of view of config file lookup, this is a bit
stupid, but on the other hand increases consistency, as user path
resolution exposes the mp_get_platform_path() functionality directly to
the user.
2015-05-09 13:57:55 +02:00
wm4 5631060569 vo_drm: allow changing video rectangle settings
Now among other things panscan can be changed during playback.

Unfortunately, it flickers. The issue is that reconfig() clears the
framebuffer. Removing the clearing shows that the "unused" parts of
the picture are not cleared - even though OSD could render there. As
such, this is a separate issue.
2015-05-08 22:38:42 +02:00
wm4 859ddc9906 vo_drm: don't mutate the current frame when clamping for panscan
When running with --panscan=1, this could crash - because the current
frame was reduced in size each time the image was redrawn, which would
result in a failed assertion the second time it's drawn.
2015-05-08 22:36:04 +02:00
wm4 51120c9c7f input: filter out redundant mp_input_set_mouse_pos() calls
Prevents the OSC from showing up on start on Cocoa.
2015-05-08 22:00:24 +02:00
wm4 f9e2d5026e player: add --force-window=immediate mode
This creates the window before the first file is loaded. This was
requested a bunch of times, but on the other hand a change to make this
behavior the default was reverted some time ago, because other users
hated it.
2015-05-08 21:47:39 +02:00
wm4 00130651da audio: simplify further
Drop mp_chmap_diff() (which is unused too now), and implement
mp_chmap_diffn() in a slightly simpler way. (Too bad there is no
standard function for counting set bits.)
2015-05-08 21:22:39 +02:00
wm4 8d5924f2c9 audio: remove mp_chmap_contains()
It's unsued now.
2015-05-08 21:14:23 +02:00
wm4 8b7035c8ff ao: log reordered versions of channel maps
Useful for debugging cases when no standard orders are used.
2015-05-08 19:45:16 +02:00
wm4 3560a50029 audio: redo channel map fallback selection
Instead of somehow having 4 different cases with each their own weight,
do it with a single function that decides which channel layout is the
better fallback.

This is simpler, and also introduces new (fixed) semantics. The new test
added to test/chmap_sel.c actually works now. This is a mixed case with
no perfect upmix or downmix, but the better choice is the one which
loses the least channels from the original layout.

One test also changes. If the input is 7.1(wide-side), and the available
layouts are 7.1 and 5.1(side), the latter is now chosen instead of the
former. This makes sense: both layouts contain 6 out of 8 channels from
the original layout, but the 5.1(side) one is smaller. This follows the
general logic. The 7.1 layout has FLC/RLC speakers instead of BL/BR,
and judging by the names, "front left center" is completely different
from "back left". If these should be exchangeable, a separate exception
would have to be added.
2015-05-08 19:33:17 +02:00
wm4 d32b71d52e audio: add chmap utility function 2015-05-08 19:33:08 +02:00
wm4 5142b0e3f3 test: simplify chmap_sel tests 2015-05-08 19:29:46 +02:00
wm4 ad9bce2a5c ao_alsa: log requested numbers of channels if ALSA rejects them 2015-05-08 14:24:20 +02:00
wm4 7b09654c33 audio: fix messed up assert()
This made no sense and always evaluated to true.
2015-05-07 23:26:33 +02:00
wm4 55e777f10b audio: remove UNKNOWN pseudo speakers
Reuse MP_SPEAKER_ID_NA for this. If all mp_chmap entries are set to NA,
the channel layout has special "unknown channel layout" semantics, which
are used to deal with some corner cases.
2015-05-07 23:20:06 +02:00
wm4 b91b4944bd audio: define only a single NA speaker ID
Remove the requirement from mp_chmap that speaker entries must be
unique. Use this to get rid of all the redundant NA speaker IDs.
2015-05-07 23:07:14 +02:00
wm4 3477088741 player: use profiles for libmpv and encoding defaults
The client API (libmpv) and encoding (--o) have slightly different
defaults from the command line player. Instead of doing a bunch of calls
to set the options explicitly, use profiles. This is simpler and has the
advantage that they can be listed on command line (instead of possibly
forcing the user to find and read the code to know all the details).
2015-05-07 21:26:11 +02:00
wm4 036a49478f m_config: make m_config_set_profile() use a name
Is simpler and avoids exposing profile structs to a degree.
2015-05-07 21:03:14 +02:00
wm4 b12ca2b980 DOCS: add a link to LIRC wiki entry 2015-05-07 21:03:06 +02:00
wm4 1bcb82ec93 ao_coreaudio_utils: don't list some formats as "unusable"
While mpv has no internal equivalent representation, they can still be
used as physical CoreAudio formats. Thus this label is confusing.
2015-05-07 20:55:00 +02:00
ChrisK2 6a0a67034d ytdl_hook: Escape EDL URLs
Should prevent the EDL parser from tripping over = and , in the
URL.
2015-05-07 20:41:46 +02:00
wm4 cd5ab98ff9 ao_sndio: add notice about padding channels
(I won't do this, but someone else seeing this might.)
2015-05-06 21:48:40 +02:00
wm4 85fc6b2a05 ao_alsa: use new padding channels support
Sometimes, ALSA will return channel layouts with padded channels (NA
speakers). Use them instead of failing.

This still includes the old "braindeath" code to retry with a layout
without NA channels. This might be helpful for performance, and also the
padded channel layout string looks confusing.

To be fair, I have not encountered a case yet which would really need
this, and for which the old "braindeath" code did not fix it.
2015-05-06 21:48:40 +02:00
wm4 d577872a28 ao_alsa: move ALSA -> mp channel map to a function
One side effect is that the warning about too many channels goes away,
and is replaced with printing the ALSA channel map as "unknown".
2015-05-06 21:48:40 +02:00
wm4 9434aa75b2 manpage: do not use deprecated syntax in example 2015-05-06 21:48:39 +02:00
wm4 f58d3591d9 cocoa: remove an unused parameter 2015-05-06 21:48:39 +02:00
wm4 0ae0e90eb5 ao_coreaudio_exclusive: check new format before waiting for change
It seems if the format was already set, setting the same format will
not cause a property change.
2015-05-06 21:48:39 +02:00
wm4 4444ff48fa ao_coreaudio_exclusive: use atomics instead of volatile
volatile barely means anything.

The polling is kind of bad too, but relatively harmless as device
opening/closing is a rare event, and the format change is not expected
to take long.

Remove the pointless talloc call too (must have been a leftover
from previous refactoring).
2015-05-06 21:48:36 +02:00
wm4 028739932b ao_coreaudio_exclusive: rename "digital" -> "compressed"
PCM is digital too.
2015-05-06 18:54:53 +02:00
wm4 1e1045b13e ao_coreaudio_exclusive: explicitly check for spdif formats 2015-05-06 18:51:31 +02:00
wm4 32bc61ae07 ao_coreaudio_exclusive: merge init_digital() function
No reason to keep them separate. It's an artifact from the old
ao_coreaudio.c, which kept usage of two different APIs in the same file.
Removes a forward reference too.
2015-05-06 18:46:51 +02:00
wm4 e777756301 cocoa: lock cocoa main thread on uninit
This should fix some crashes due to dangling pointers.

The problem was that with_cocoa_lock_on_main_thread() is asynchronous.
It will not wait until it is finished. In the uninit case, this means
the VO could be deallocated and destroyed while cocoa was still running
uninit code.

So simply wait until it is done by using dispatch_sync(). There were
concerns that this could introduce a deadlock by the main thread trying
to wait for something on the VO thread. But from what I can see, this
never happens, and even if it does, it would crash anyway since the VO
is already gone.

One remaining worry is the video_resize_redraw_callback. From what I can
see, it still can mess things up, and will need a more elaborate fix.
2015-05-06 00:36:33 +02:00
wm4 4ffcf2531b ao_coreaudio_utils: decide formats by comparing raw bits
Instead of trying to use af_format_conversion_score() (which tries to be
all kinds of clever), just compare the raw bits as a quality measure. Do
this because otherwise, weird formats like padded 24 bit formats will be
excluded, even though they might be the highest precision formats for
some hardware.

This means that for now, the user would have to check whether the format
is usable at all before calling ca_asbd_is_better(). But since this is
currently only used for ao_coreaudio.c and for the physical format, it
doesn't matter.

If coreaudio-exclusive should get PCM support, the best would be to
revert this change, and to add support for 24 bit formats directly.
2015-05-05 22:10:33 +02:00
wm4 656703e279 ao_coreaudio: log considered physical formats 2015-05-05 22:09:44 +02:00
wm4 86d65c80e1 ao_coreaudio: restore old physical format if format was changed 2015-05-05 22:09:39 +02:00
wm4 0025030cef af: don't attempt to remove last filter for spdif filter removal
Some time ago, a mechanism was added for automatically removing PCM-only
filters if the input format is spdif.

This could cause an infinite loop if the AO did not support spdif, but
was falling back to some PCM format. Then this code tried to remove the
last filter, which is a dummy filter for receiving and queuing filter
output. af_remove() simply fails gracefully in this case, so this
happens over and over again.

Fix by explicitly checking whether the filter to remove is a dummy
filter. (af_remove() also fails only if the dummy filters are attempted
to be removed - checking this directly is simpler.)
2015-05-05 21:47:48 +02:00
wm4 d76f9a484e audio: minor cosmetics
These ( ) were probably not removed when the format constants were
changed from defines to an enum.
2015-05-05 21:47:36 +02:00
wm4 934109a35b ao_coreaudio: move channel mapping code to a separate file
Move all of the channel map retrieval/negotiation code to a separate
file. This will (probably) be helpful when extending
ao_coreaudio_exclusive.c.

Nothing else changes, other than some minor cosmetics and renaming,
and changing some details for decoupling it from the ao_coreaudio.c
internals.
2015-05-05 21:47:19 +02:00
wm4 399267393b ao_coreaudio_utils: don't require talloc for fourcc_repr()
Instead, apply a trick to make the caller allocate enough space on the
stack.
2015-05-05 21:47:04 +02:00
wm4 7a5f5a8adf ao_coreaudio_utils: unbreak default device selection
It appears this is the reason coreaudio-exclusive does not work without
explicitly specifying a device, even if the default device maps to
something passthrough-capable.
2015-05-05 21:46:54 +02:00
wm4 bbedceb467 ao_coreaudio_exclusive: fix latency calculation non-sense
Didn't use the properties it was supposed to use.
2015-05-05 21:46:39 +02:00
wm4 fd6809f98a ao_coreaudio_utils: refine format selection
Instead of always picking a somehow better format over the previous one,
select a format that is equal to or better the requested format, but is
also reasonably close.

Drop the mFormatID comparison - checking the sample format handles this
already.

Make sure to exclude channel counts that can't be used.
2015-05-05 21:46:17 +02:00
wm4 66f4e7cce4 ao_coreaudio: change physical format before channel negotiation
If for example the physical format is set to stereo, the reported
multichannel layout will actually be stereo. It fixes itself only after
the physical format is changed.
2015-05-05 21:45:55 +02:00
wm4 cf210c4ffc vo_opengl: change default FBO format
Reduces (but likely does not remove) the danger of rounding intermediate
values down to 8 bit. This is important for cscale, or any other
processing that might store raw YUV values in framebuffers.

Fixes #1918.
2015-05-05 14:41:33 +02:00
wm4 22455b2961 manpage: fix typo 2015-05-05 14:40:26 +02:00
wm4 8121529a6c ao_coreaudio: add an option for changing the physical format
ao_coreaudio uses AudioUnit - the OSX software mixer. In theory, it
supports multichannel audio just fine. But in practice, this might be
disabled by default, and the user is supposed to select a multichannel
base format in the "Audio MIDI Setup" utility.

This option attempts to change this setting automatically. Some possible
disadvantages and caveats are listed in the manpage additions. It is off
by default, since changing this might be rather bad behavior for a
normal application.
2015-05-05 01:11:16 +02:00
wm4 305a85cc9a ao_coreaudio_utils: add a format negotiation helper function 2015-05-05 01:11:16 +02:00
wm4 f719b8164d af_lavrresample: remove dead undefs 2015-05-05 01:11:16 +02:00
wm4 19ab5f7943 ipc: silence some common info messages
They are not really interesting. At least one user complained about the
noise resulting from use with shell scripts, which connect and
disconnect immediately.
2015-05-05 01:11:16 +02:00
wm4 4d8a7e0394 ao_coreaudio: support padded channel layouts
If for example the audio settings are set to 5.1 output, but the
hardware does 8 channels natively (HDMI), the reported channel
layout will have 2 dummy channels. To avoid falling back to stereo,
we have to write audio in this format to the device.
2015-05-05 01:11:16 +02:00
wm4 06050aed99 audio: introduce support for padding channels
Some audio APIs explicitly require you to add dummy channels. These are
not rendered, and only exist for the sake of the audio API or hardware
strangeness. At least ALSA, Sndio, and CoreAudio seem to have them.

This commit is preparation for using them with ao_coreaudio.

The result is a bit messy. libavresample/libswresample don't have good
API for this; avresample_set_channel_mapping() is pretty useless.
Although in theory you can use it to add and remove channels, you
can't set the channel counts. So we do the ordering ourselves by making
sure the audio data is planar, and by swapping the plane pointers. This
requires lots of messiness to get the conversions in place. Also, the
input reordering is still done with the "old" method, and doesn't
support padded channels - hopefully this will never be needed. (I tried
to come up with cleaner solutions, but compared to my other attempts,
the final commit is not that bad.)
2015-05-05 01:11:16 +02:00
wm4 1b0b094ca2 audio: introduce mp_audio readonly bit
Convenience for the following commit.
2015-05-04 23:57:25 +02:00
wm4 937c8e513f audio: chmap: explicitly drop channels not supported by lavc
Basically as before, but avoid undefined behavior.
2015-05-04 23:56:27 +02:00
wm4 548cd826c2 audio: drop unused function 2015-05-04 23:54:53 +02:00
wm4 eead97f103 ao_coreaudio: fix out of bounds access
ca_label_to_mp_speaker_id() checked whether the last entry was >= 0, but
actually this condition was never true, and MP_SPEAKER_ID_UNKNOWN0 is
not negative.
2015-05-04 23:54:38 +02:00
James Ross-Gowan b6381a0ee3 subprocess-win: use the correct pipe namespace
This was a mistake, it should definitely be using the device namespace
rather than the file namespace. As it says in the docs, all pipe names
must start with \\.\pipe\
2015-05-04 09:24:53 +02:00
Niklas Haas 08d3ef3d9e sws_utils: re-use avcolorspace for sws colorspaces
This lets us avoid having to maintain two separate copies of the
colorspace mapping functions.
2015-05-04 01:34:25 +02:00
wm4 a2da53027b win32: fix desktop directory
The folder argument wasn't used, so it always returned the APPDATA dir.
2015-05-03 19:28:14 +02:00
wm4 e25ecdd09a vo_opengl: gl_lcms: fix cache dir creation with path expansion
Path expansion (like "~/dir/" in config file) was used inconsistently,
so the cache directory wasn't always created correctly. Fix this by
moving the path expansion from load_file() to its callers.
2015-05-03 14:58:18 +02:00
wm4 2ae96f567c path: start special espansion with ~~name instead of ~name
Since commit 7381db60, strings like "~desktop/" were expanded as
platform-specific paths by mpv. Apparently this similarity to standard
Unix shell expansion caused confusion, so change it to "~~desktop/". The
shell doesn't expand this, so it should be better.
2015-05-03 14:52:11 +02:00
wm4 6a03357b71 options: fix typo in variable name 2015-05-03 14:44:42 +02:00
wm4 1982fedca6 options: remove --leak-report
Use the environment variable instead.
2015-05-02 19:03:28 +02:00
wm4 3508a3fbd1 win32: move platform specifics to osdep
This will probably disable this code for Cygwin. I don't know if this
matters, since Cygwin should strictly behave like a Unix anyway.
2015-05-02 18:59:58 +02:00
wm4 1e7831070f build: move main-fn files to osdep
And split the Cocoa and Unix cases. Simplify the Cocoa case slightly by
calling mpv_main directly, instead of passing a function pointer. Also
add a comment explaining why Cocoa needs a special case at all.
2015-05-02 18:59:58 +02:00
wm4 19a5b20752 cocoa: always compile OSX application code with cocoa
This unbreaks compiling command line player and libmpv at the same
time. The problem was that doing so silently disabled the OSX
application thing - but the command line player can not use the
vo_opengl Cocoa backend without it.

The OSX application code is basically dead in libmpv, but it's not
that much code anyway.

If you want a mpv binary that does not create an OSX application
singleton (and creates a menu etc.), you must disable cocoa
completely, as cocoa can't be used anyway in this case.
2015-05-02 18:09:56 +02:00
wm4 d8e92322fa player: handle hotplug events in idle mode too 2015-05-02 18:09:30 +02:00
wm4 15d8cf7fa2 screenshots: create screenshot dir
Minor user convenience.
2015-05-02 16:38:38 +02:00
wm4 f509a2badb vo_opengl: gl_lcms: create cache dir
Minor user convenience.
2015-05-02 16:36:31 +02:00
wm4 dce941b99c vo_opengl: gl_lcms: make sure win32 unicode fopen() wrapper is enabled 2015-05-02 16:35:53 +02:00
wm4 aeea250ab3 vo_opengl: gl_lcms: minor simplification 2015-05-02 16:34:52 +02:00
wm4 ff1b5432e7 vo_opengl: gl_lcms: use mp_path_join()
Maybe this fixes the win32 problems a user had, or maybe not.

Also, check if cache_dir is set at all. An empty string should be
equivalent to "unset".
2015-05-02 16:29:30 +02:00
wm4 a52a494fe4 path: update path descriptions 2015-05-02 16:14:51 +02:00
wm4 dd2c65429f path: fix user path resolution
Forgot to add the remainder to the path.
2015-05-01 22:33:56 +02:00
wm4 fd7bf9c07a manpage: fix typo 2015-05-01 22:17:09 +02:00
wm4 b32a2bf364 osxbundle: remove unnecessary config file entry
This is done via pseudo-gui now.
2015-05-01 21:58:17 +02:00
Niklas Haas 01b793f117 vo_opengl: gl_lcms: make ICC loading less verbose
Especially with the new ICC cache rework, you get a lot of ugly output
messages that don't really contain any meaningful content.
2015-05-01 21:52:08 +02:00
Niklas Haas 1153f13bee vo_opengl: gl_lcms: replace icc-cache by icc-cache-dir
This now stores caches for multiple ICC profiles, potentially all the
user has ever used. The big use case for this is for users with multiple
monitors. The old logic would mandate recomputing the LUT and discarding
the cache whenever dragging mpv from one screen to another.

This also avoids having to save and check the ICC profile itself, since
the file name already uniquely determines it.
2015-05-01 21:52:08 +02:00
Niklas Haas 47d46ec487 vo_opengl: attach target-prim/target-csp to window screenshots
This will essentially make screenshot-tag-colorspace also affect the
"screenshot window" command, where possible.

Unfortunately, it's completely incompatible with icc-profile, due to API
limitations of ffmpeg (we can only give it an enum of well-known
primaries, rather than an actual ICC profile or primaries).
2015-05-01 21:52:07 +02:00
wm4 756991bd4f screenshots: change default directory in pseudo-gui mode to desktop
This should take care of the endless complaints about the default
location for screenshots (and will of course create new ones).

If the screenshot-template is set to an absolute path, the directory
won't be used. So this should be reasonably compatible.
2015-05-01 21:51:10 +02:00
wm4 72373bb5ae screenshots: prefix default template with "mpv-"
So that the user realizes where they come from, or can find them at all.
This was a common complaint, and this is the most lazy solution. Better
suggestions for a default template are welcome.
2015-05-01 21:51:10 +02:00
wm4 8192500716 path: add resolving desktop path to platform-specific paths
win32 has a special function for this.

I'm not sure about OSX - it seems ~/Desktop can be hardcoded, and the
OSX GUI actually localizes the _displayed_ path in its UI.

For Unix, there is not much to be done, or is there.
2015-05-01 21:51:10 +02:00
wm4 7381db60e2 path: expose platform-specific path resolvers 2015-05-01 21:51:10 +02:00
wm4 6814830b9a timer: add "static" to a variable 2015-05-01 21:51:10 +02:00
wm4 d3a3cfe54c path: refactor
Somewhat less ifdeffery, higher flexibility. Now there are 3 separate
config file resolvers for 3 platforms (unix, win, osx), and they can
still interact with each other somewhat. For example, OSX for now uses
most of Unix, but adds the OSX bundle path.

This can be extended to resolve very specific platform paths, such as
location of the desktop.

Most of the Unix specific code moves to path-unix.c.

The behavior should be the same - if not, it is likely a bug.
2015-05-01 21:51:10 +02:00
wm4 60958ddf9b screenshots: add --screenshot-directory option
The plan is to use this to change the screenshot default location in
pseudo-gui mode.
2015-05-01 21:51:09 +02:00
wm4 94a3a76ee3 vo_rpi: update renderer size on display size changes too
(Not sure why it worked without this when I tested the previous
changes.)

Untested, but should be fine. This is equivalent what is done on e.g.
panscan changes.
2015-05-01 19:22:35 +02:00
wm4 e185887ba0 video/out: remove VOFLAG_FLIPPING
I think this used to be quite important, because the ancient VfW support
in MPlayer used to output flipped frames. This code has been dead in mpv
for quite some time (because VfW decoders were removed, and the --flip
option was dropped too), so get rid of it.
2015-05-01 18:47:27 +02:00
wm4 0a7abbda6b vo_opengl: refactor wayland frame skipping
Currently, the wayland backend needs extra work to avoid drawing more
often than the wayland frame callback allows. (This is not ideal, but
will be fixed at a later time.)

Unify this with the start_frame callback added for cocoa. Some details
change for the better. For example, if a frame is dropped, and a redraw
is done afterwards, the actually correct frame is redrawn, instead
whatever was in the textures from before the dropped frame.
2015-05-01 18:44:45 +02:00
wm4 e23e4c7c60 cocoa: don't accidentally drop initial screen drawing
With --idle --force-window, or when started from the bundle, the cocoa
code dropped the first frame. This resulted in a black frame on start
sometimes.

The reason was that the live resizing/redrawing code was invoked, which
simply set skip_swap_buffer to false, blocking redrawing whatever was
going to be rendered next. Normally this is done so that the following
works:

1. vo_opengl draw a frame, releases GL lock
2. live resizing kicks in, redraw the frame
3. vo_opengl wants to call SwapBuffers, drawing a stale buffer
   overwritten by the live resizing code

This is solved by setting skip_swap_buffer in 2., and querying it in 3.

Fix this by resetting the skip_swap_buffer at a known good point: when
vo_opengl starts drawing a new frame.

The start_frame function returns bool, so that it can be merged with
is_active in a following commit.
2015-05-01 18:26:58 +02:00
Avi Halachmi (:avih) ffcad1a72b vo: improve frame drop logic on high playback rate
Commit f1746741de changed the drop
logic to have more slack (drop more frames but less frequent) to prevent
drops due to timing jitter when the clip and screen have similar rates.

However, if the clip has higher rate than the screen (or just higher
playback rate), then that policy hurts smoothness since these "chunked
drops" look worse than one frame drop at a time.

This patch restores the old drop logic when the playback frame rate is
higher than ~5% above the screen refresh rate, and solves this issue.

Fixes #1897
2015-05-01 19:11:44 +03:00
wm4 d01228058b player: properly destroy client context if thread can't be created
Minor leak in an obscure out of memory case.
2015-04-30 21:57:08 +02:00
wm4 8c7f3adb41 vo_rpi: update display size on display mode switches 2015-04-30 21:56:16 +02:00
wm4 6ae66e717f vo_rpi: actually draw a black background
Also factor the display size initialization into a separate function.

For some reason this seems to work, although setting the background
color using this 1x1 pixel bitmap does not work. I blame the RPI
beign a terrible piece of hardware with even worse drivers.
2015-04-30 21:56:13 +02:00
wm4 382434d45a ao_coreaudio_exclusive: check format explicitly on change notifcation
This should for now be equivalent; it's merely more explicit and will
be required if we add PCM support.

Note that the property listeners actually tell you what property
exactly changed, but resolving the current listener mess would be too
hard. So check for changes manually.
2015-04-29 23:10:45 +02:00
wm4 34a5229b23 ao_coreaudio_utils: log mp format with CoreAudio format description
As a consequence, it also logs whether mpv can a this format at all.
2015-04-29 23:07:36 +02:00
wm4 32b835c03b ao_coreaudio_utils: add function for ASBD -> mp format lookup
Useful with some of the following commits.

ca_fill_asbd() should behave exactly as before.

Instead of actually implementing the inverse function of ca_fill_asbd(),
just loop over the (small) list of mpv functions and check if any mpv
equivalent to a given ASBD exists.
2015-04-29 23:06:10 +02:00
wm4 3295ce48ab ao_coreaudio_utils: float is not a signed integer format
kAudioFormatFlagIsSignedInteger implicates that it's only used with
integer formats. The mpv internal flag on the other hand signals the
presence of a sign, and this is set on float formats.

Until now, this probably worked fine, because at least AudioUnit is
ignoring the uncorrect flag.
2015-04-29 22:39:28 +02:00
Niklas Haas 99439f11ea csputils: improve contrast semantics for limited range output
The previous version of this logic resulted in black crush and incorrect
brightness scaling when combined with limited range (TV) output.
2015-04-29 22:09:09 +02:00
wm4 0600d378f9 csputils: apply contrast equalizer in RGB
It's weird that this basically adjusts the contrast between luma and
chroma, and not blackness.

This is more in line with the behavior of libswscale, the vdpau
"procamp" (which mpv doesn't use), and Xv.
2015-04-29 21:32:19 +02:00
wm4 d51dee093f screenshots: add option to prevent 16 bit output
That's what it's usually about (again).
2015-04-29 21:05:04 +02:00
wm4 f07c9b16f9 screenshots: add option to disable JPEG 4:4:4 output
That's what it's usually about.
2015-04-29 21:01:08 +02:00
wm4 38114b6a36 stream: don't print reconnection message if no stream support
This code does not know whether the stream supports reconnecting until
STREAM_CTRL_RECONNECT is called. So the message should be printed after
it. To avoid that reconnects that succeed on the first try go unnoticed,
print a warning on success.
2015-04-29 19:54:46 +02:00
Niklas Haas daf4334697 x11: query ICC profile based on center of window
Right now, the default behavior is to pick the numerically lowest screen
ID that overlaps the window in any way - but this means that mpv will
decide to pick an ICC profile in a pretty arbitrary way even if the
window only overlaps another screen by a single pixel.

The new behavior is to query it based on the center of the window
instead.
2015-04-29 14:01:27 +02:00
wm4 0b72f5e5ad manpage: put explicit links to config file path details
It seems users still have trouble finding the exact paths, especially on
Windows. Maybe this helps.
2015-04-28 22:15:39 +02:00
wm4 8b4ca58062 ao_coreaudio_exclusive: move code for getting original format
Should be almost equivalent, unless there are streams on which this call
does not work for unknown reasons.
2015-04-28 22:11:43 +02:00
wm4 d5e9bf66a1 ao_coreaudio_utils: change audio format logging
Make it easier to distinguish the fields.
2015-04-28 22:11:05 +02:00
wm4 5f86fad2f0 ao_coreaudio_exclusive: account for additional latency
Whether this is correct is unknown. This change tripples the latency
from ~15ms to ~45ms.

XBMC does this, VLC does not from what I could see.
2015-04-28 22:09:51 +02:00
wm4 025cb3b9e3 command: let sub_reload remove the old track first
In the most simple case, this prevents the track ID from changing. One
disadvantage is that if the file fails loading, the track is gone for
good and would have to be re-added explicitly by the user.
2015-04-28 22:06:22 +02:00
wm4 9795216d8a command: change the default action for rescan_external_files
Now the rescan_external_files command will by default reselect the audio
and subtitle streams. This should be more intuitive.

Client API users and Lua scripts might break, but can be fixed in a
backward-compatible way by setting the mode explicitly.
2015-04-28 22:05:07 +02:00
wm4 0c0c8cd44e player: log track list when adding or removing external files
Should help with debugging, and might be slightly more userfriendly.

Note that this is called manually in multiple entry-points, instead of
the functions doing the actual work (like mp_remove_track()). This is
done so that exiting the player or calling the sub_reload command won't
print redundant in-between states.
2015-04-28 22:04:37 +02:00
wm4 0ff93a8357 player: clamp display time to known time range on seeking
During seeking, and there is momemtarily no new data available yet, the
player will display the seek target as current time. Clamp this time to
the known time range as implied by the start time and the duration of
the file.

This improves behavior especially when seeking in audio files, for which
this for some reason triggers rather often. There were some users
complaining about this.

This makes behavior worse for files with timestamp resets, or
incorrectly reported duration. (The latter is relatively common,
e.g. libavformat shortcomings, or incomplete files.)
2015-04-28 22:03:18 +02:00
wm4 c4aa136155 audio: separate fallbacks for upmix and downmix cases
We always want to prefer upmix to downmix, as long as it makes sense.
Even if the upmix is not "perfect" (not just adding channels), we want
to prefer the upmix.

Cleanup for commit d3c7fd9d.
2015-04-28 22:01:55 +02:00
ChrisK2 2fcf0e6183 osc: redo slider position translation
Now done in one place instead of mulitple times all over the code.

Fixes #1876
2015-04-28 21:33:03 +02:00
wm4 f77e3cbf0c json: fix UTF-8 handling
We escape only characters below 32, plus " and \. UTF-8 should be apssed
through verbatim. Since char can be signed (and usually is), the check
broke and happened to escape UTF-8 encoded bytes too. This broke UTF-8
completely.

Note that we don't check for broken or invalid UTF-8, such as described
both in the client API and IPC docs.

Fixes #1874.
2015-04-28 09:58:28 +02:00
wm4 43b6b376dc input.conf: map L to toggle infinite looping 2015-04-27 23:32:59 +02:00
robin 5555f6fc2c ytdl_hook.lua: Change format options when vid is "off"
This will change the format option to "bestaudio/best" instead of
passing the "-x" argument to yt-dl.

Prevents the video still being downloaded in the new mpv versions where
the yt-dl format is set to "best" by default.
2015-04-27 23:32:59 +02:00
wm4 d3c7fd9d7c audio: avoid downmixing in a certain special-case
As indicated by the added test. In this case, fallback and downmix have
the same score, but fallback happens to give better results. So prefer
fallback over downmix.

(This is probably not a correct solution.)
2015-04-27 23:21:58 +02:00
wm4 570f4b136f ao_null: add an option for testing channel layout selection 2015-04-27 23:21:58 +02:00
Niklas Haas d2292c179c manpage: update mpv IRC channels
Moved to #mpv and #mpv-devel, respectively. Travis details were also
updated.
2015-04-27 23:21:58 +02:00
wm4 4d2ed847ce player: fix removing external tracks at runtime
This could make the player crash on exit if the "sub_reload" command was
used successfully. the reason was that the mpctx->sources array could
have dangling pointers to the unloaded demuxers.

Also fix a memory leak by actually always freeing the per-stream
subtitle decoders (which are a hack to make ordered chapters behave
better).
2015-04-27 23:21:58 +02:00
wm4 0c70f94c53 manpage: update colormatrix property description 2015-04-27 17:51:06 +02:00
akemi-san 1e2e504349 vo_drm: zero screen buffers in reconfig function. 2015-04-27 09:22:10 +02:00
Marcin Kurczewski 5f21a68ce9 vo_drm: add window screenshots support 2015-04-26 20:09:26 +02:00
wm4 95a0488ac2 ytdl: force "best" format by default
If the --ytdl-format option is not used, force the "best" format. Do
this because youtube-dl is going to change its default format to one
that will trigger the (partially broken) DASH support in our own code.

Fixes #1867.
2015-04-26 19:52:28 +02:00
wm4 a5ed6e49bf vdpau: always render to cropped size at most
vo_opengl (or gl_hwdec_vdpau.c to be specific) calls
mp_vdpau_mixer_render() with video_rect=NULL, which means to use the
full surface. This is incorrect if the surface is actually cropped, as
it can happen with h264. In this case, it was rendering the parts
outside of the image.

Fix it by making this case use the cropped size instead.

Alternative fix for PR #1863.
2015-04-26 18:56:46 +02:00
wm4 4df8c21f81 DOCS/client-api-changes: fix release marker
The release was pushed back and now actually happened; the marker became
incorrect.
2015-04-25 20:42:35 +02:00
wm4 8998a4b3ed demux_lavf: drop dead code
stream.url can never be NULL, although it probably used to be.
2015-04-25 20:42:02 +02:00
383 changed files with 20869 additions and 19726 deletions

No files matched your search

+1
View File
@@ -15,6 +15,7 @@
/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
+13 -2
View File
@@ -2,9 +2,18 @@ mpv is a fork of mplayer2, which is a fork of MPlayer.
mpv as a whole is licensed as GPL version 2 or later (see LICENSE). Most source
files are GPLv2+, but some files are available under a more liberal license,
such as LGPLv2+, BSD, MIT, ISC, and possibly others. Look at the copyright
such as LGPLv2.1+, BSD, MIT, ISC, and possibly others. Look at the copyright
header of each source file, and grep the sources for "Copyright" if you need
to know details. Files without Copyright notice are licensed as LGPLv2+.
to know details. Files without Copyright notice are licensed as LGPLv2.1+.
All new contributions must be LGPLv2.1+ licensed, or if the changes are done on
GPL code, must come with the implicit agreement that the project can relicense
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.
@@ -17,3 +26,5 @@ MPlayer as a whole is licensed under GPLv2 (incompatible to GPLv3!), because
some files are licensed to GPLv2 (and _not_ any later version of the license).
In particular, this affects the file libmpdemux/demux_ty_osd.c. It is disabled
under mplayer2, and has been removed from mpv.
"v2.1+" in this context means "version 2.1 or later".
+30 -10
View File
@@ -4,9 +4,7 @@ Introduction
This file lists all changes that can cause compatibility issues when using
mpv through the client API (libmpv and ``client.h``). Since the client API
interfaces to input handling (commands, properties) as well as command line
options, this list is interesting for other uses of mpv, such as the Lua
scripting interface, key bindings in ``input.rst``, or plain command line
usage.
options, you should also look at ``interface-changes.rst``.
Normally, changes to the C API that are incompatible to previous iterations
receive a major version bump (i.e. the first version number is increased),
@@ -20,21 +18,43 @@ The version number is the same as used for MPV_CLIENT_API_VERSION (see
Also, read the section ``Compatibility`` in ``client.h``.
Options, commands, properties
=============================
Changes to these are not listed here, but in ``interface-changes.rst``. (Before
client API version 1.17, they were listed here partially.)
This listing includes changes to the bare C API and behavior only, not what
you can access with them.
API changes
===========
::
--- mpv 0.9.0 is released ---
1.17 - add MPV_FORMAT_BYTE_ARRAY
--- mpv 0.12.0 ---
1.20 - deprecate "GL_MP_D3D_interfaces"/"glMPGetD3DInterface", and introduce
"GL_MP_MPGetNativeDisplay"/"glMPGetNativeDisplay" (this is a
backwards-compatible rename)
--- mpv 0.11.0 ---
--- mpv 0.10.0 ---
1.19 - add "GL_MP_D3D_interfaces" pseudo extension to make it possible to
use DXVA2 in OpenGL fullscreen mode in some situations
- mpv_request_log_messages() now accepts "terminal-default" as parameter
1.18 - add MPV_END_FILE_REASON_REDIRECT, and change behavior of
MPV_EVENT_END_FILE accordingly
- a bunch of interface-changes.rst changes
1.17 - mpv_initialize() now blocks SIGPIPE (details see client.h)
--- mpv 0.9.0 ---
1.16 - add mpv_opengl_cb_report_flip()
- introduce mpv_opengl_cb_draw() and deprecate mpv_opengl_cb_render()
- add MPV_FORMAT_BYTE_ARRAY
1.15 - mpv_initialize() will now load config files. This requires setting
the "config" and "config-dir" options. In particular, it will load
mpv.conf.
- minor backwards-compatible change to the "seek" and "screenshot"
commands (new flag syntax, old additional args deprecated)
--- mpv 0.8.0 is released ---
--- mpv 0.8.0 ---
1.14 - add mpv_wait_async_requests()
- the --msg-level option changes its native type from a flat string to
a key-value list (setting/reading the option as string still works)
@@ -47,7 +67,7 @@ API changes
its own and mpv's OpenGL rendering
Warning: this API is not stable yet - anything in opengl_cb.h might
be changed in completely incompatible ways in minor API bumps
--- mpv 0.7.0 is released ---
--- mpv 0.7.0 ---
1.10 - deprecate/disable everything directly related to script_dispatch
(most likely affects nobody)
1.9 - add enum mpv_end_file_reason for mpv_event_end_file.reason
@@ -70,7 +90,7 @@ API changes
1.6 - modify "core-idle" property behavior
- MPV_EVENT_LOG_MESSAGE now always sends complete lines
- introduce numeric log levels (mpv_log_level)
--- mpv 0.6.0 is released ---
--- mpv 0.6.0 ---
1.5 - change in X11 and "--wid" behavior again. The previous change didn't
work as expected, and now the behavior can be explicitly controlled
with the "input-x11-keyboard" option. This is only a temporary
@@ -79,7 +99,7 @@ API changes
although the old option name still works.
1.4 - subtle change in X11 and "--wid" behavior
(this change was added to 0.5.2, and broke some things, see #1090)
--- mpv 0.5.0 is released ---
--- mpv 0.5.0 ---
1.3 - add MPV_MAKE_VERSION()
1.2 - remove "stream-time-pos" property (no replacement)
1.1 - remap dvdnav:// to dvd://
@@ -91,6 +111,6 @@ API changes
insignificant is now significant
- add "cache-free" and "cache-used" properties
- OSX: the "coreaudio" AO spdif code is split into a separate AO
--- mpv 0.4.0 is released ---
--- mpv 0.4.0 ---
1.0 - the API is declared stable
+99 -15
View File
@@ -1,30 +1,114 @@
Client API examples
===================
# Client API examples
All these examples use the mpv client API through libmpv.
cocoa
-----
## Where are the docs?
The libmpv C API is documented directly in the header files (on normal Unix
systems, this is in `/usr/include/mpv/client.h`.
libmpv merely gives you access to mpv's command interface, which is documented
here:
* Options (`mpv_set_option()` and friends): http://mpv.io/manual/master/#options
* Commands (`mpv_command()` and friends): http://mpv.io/manual/master/#list-of-input-commands
* Properties (`mpv_set_property()` and friends): http://mpv.io/manual/master/#properties
Essentially everything is done with them, including loading a file, retrieving
playback progress, and so on.
## Methods of embedding the video window
All of these examples concentrate on how to integrate mpv's video renderers
with your own GUI. This is generally the hardest part. libmpv enforces a
somewhat efficient video output method, rather than e.g. returning a RGBA
surface in memory for each frame. The latter would be prohibitively inefficient,
because it would require conversion on the CPU. The goal is also not requiring
the API users to reinvent their own video rendering/scaling/presentation
mechanisms.
There are currently 2 methods of embedding video.
### Native window embedding
This uses the platform's native method of nesting multiple windows. For example,
Linux/X11 can nest a window from a completely different process. The nested
window can redraw contents on its own, and receive user input if the user
interacts with this window.
libmpv lets you specify a parent window for its own video window via the `wid`
option. Then libmpv will create its window with your window as parent, and
render its video inside of it.
This method is highly OS-dependent. Some behavior is OS-specific. There are
problems with focusing on X11 (the ancient X11 focus policy mismatches with
that of modern UI toolkits - it's normally worked around, but this is not
easily possible with raw window embedding). It seems to have stability problems
on OSX when using the Qt toolkit.
### OpenGL embedding
This method lets you use libmpv's OpenGL renderer directly. You create an
OpenGL context, and then use `mpv_opengl_cb_draw()` to render the video on
each frame.
This is more complicated, because libmpv will work directly on your own OpenGL
state. It's also not possible to have mpv automatically receive user input.
You will have to simulate this with the `mouse`/`keypress`/`keydown`/`keyup`
commands.
You also get much more flexibility. For example, you can actually render your
own OSD on top of the video, something that is not possible with raw window
embedding.
### Which one to use?
Due to the various platform-specific behavior and problems (in particular on
OSX), OpenGL embedding is recommended. If you're not comfortable with requiring
OpenGL, or want to support "direct" video output such as vdpau (which might
win when it comes to performance and energy-saving), you should probably
support both methods if possible.
## List of examples
### simple
Very primitive terminal-only example. Shows some most basic API usage.
### cocoa
Shows how to embed the mpv video window in Objective-C/Cocoa.
qt
--
### cocoa-openglcb
Similar to the cocoa sample, but shows how to integrate mpv's OpenGL renderer
using libmpv's opengl-cb API. Since it does not require complicated interaction
with Cocoa elements from different libraries, it's more robust.
### qt
Shows how to embed the mpv video window in Qt (using normal desktop widgets).
qml
---
### qt_opengl
Shows how to use mpv's OpenGL video renderer in QtQuick2 with QML.
Shows how to use mpv's OpenGL video renderer in Qt. This uses the opengl-cb API
for video. Since it does not rely on embedding "foreign" native Windows, it's
usually more robust, potentially faster, and it's easier to control how your
GUI interacts with the video. You can do your own OpenGL rendering on top of
the video as well.
qml_direct
----------
### qml
Shows how to use mpv's OpenGL video renderer in QtQuick2 with QML. Uses the
opengl-cb API for video. Since the video is a normal QML element, it's trivial
to create OSD overlays with QML-native graphical elements as well.
### qml_direct
Alternative example, which typically avoids a FBO indirection. Might be
slightly faster, but is less flexible and harder to use.
slightly faster, but is less flexible and harder to use. In particular, the
video is not a normal QML element. Uses the opengl-cb API for video.
simple
------
### sdl
Very primitive terminal-only example. Shows some most basic API usage.
Show how to embed the mpv OpenGL renderer in SDL. Uses the opengl-cb API for
video.
@@ -0,0 +1,304 @@
// Plays a video from the command line in an opengl view in its own window.
// Build with: clang -o cocoa-openglcb cocoa-openglcb.m `pkg-config --libs --cflags mpv` -framework Cocoa -framework OpenGL
#import <mpv/client.h>
#import <mpv/opengl_cb.h>
#import <stdio.h>
#import <stdlib.h>
#import <OpenGL/gl.h>
#import <Cocoa/Cocoa.h>
static inline void check_error(int status)
{
if (status < 0) {
printf("mpv API error: %s\n", mpv_error_string(status));
exit(1);
}
}
static void *get_proc_address(void *ctx, const char *name)
{
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
void *addr = CFBundleGetFunctionPointerForName(CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")), symbolName);
CFRelease(symbolName);
return addr;
}
static void glupdate(void *ctx);
@interface MpvClientOGLView : NSOpenGLView
@property mpv_opengl_cb_context *mpvGL;
- (instancetype)initWithFrame:(NSRect)frame;
- (void)drawRect;
- (void)fillBlack;
@end
@implementation MpvClientOGLView
- (instancetype)initWithFrame:(NSRect)frame
{
// make sure the pixel format is double buffered so we can use
// [[self openGLContext] flushBuffer].
NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFADoubleBuffer,
0
};
self = [super initWithFrame:frame
pixelFormat:[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]];
if (self) {
[self setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
// swap on vsyncs
GLint swapInt = 1;
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
[[self openGLContext] makeCurrentContext];
self.mpvGL = nil;
}
return self;
}
- (void)fillBlack
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
}
- (void)drawRect
{
if (self.mpvGL)
mpv_opengl_cb_draw(self.mpvGL, 0, self.bounds.size.width, -self.bounds.size.height);
else
[self fillBlack];
[[self openGLContext] flushBuffer];
}
- (void)drawRect:(NSRect)dirtyRect
{
[self drawRect];
}
@end
@interface CocoaWindow : NSWindow
@property(retain, readonly) MpvClientOGLView *glView;
@property(retain, readonly) NSButton *pauseButton;
@end
@implementation CocoaWindow
- (BOOL)canBecomeMainWindow { return YES; }
- (BOOL)canBecomeKeyWindow { return YES; }
- (void)initOGLView {
NSRect bounds = [[self contentView] bounds];
// window coordinate origin is bottom left
NSRect glFrame = NSMakeRect(bounds.origin.x, bounds.origin.y + 30, bounds.size.width, bounds.size.height - 30);
_glView = [[MpvClientOGLView alloc] initWithFrame:glFrame];
[self.contentView addSubview:_glView];
NSRect buttonFrame = NSMakeRect(bounds.origin.x, bounds.origin.y, 60, 30);
_pauseButton = [[NSButton alloc] initWithFrame:buttonFrame];
_pauseButton.buttonType = NSToggleButton;
// button target has to be the delegate (it holds the mpv context
// pointer), so that's set later.
_pauseButton.action = @selector(togglePause:);
_pauseButton.title = @"Pause";
_pauseButton.alternateTitle = @"Play";
[self.contentView addSubview:_pauseButton];
}
@end
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
mpv_handle *mpv;
dispatch_queue_t queue;
CocoaWindow *window;
}
@end
static void wakeup(void *);
@implementation AppDelegate
- (void)createWindow {
int mask = NSTitledWindowMask|NSClosableWindowMask|
NSMiniaturizableWindowMask|NSResizableWindowMask;
window = [[CocoaWindow alloc]
initWithContentRect:NSMakeRect(0, 0, 1280, 720)
styleMask:mask
backing:NSBackingStoreBuffered
defer:NO];
// force a minimum size to stop opengl from exploding.
[window setMinSize:NSMakeSize(200, 200)];
[window initOGLView];
[window setTitle:@"cocoa-openglcb example"];
[window makeMainWindow];
[window makeKeyAndOrderFront:nil];
NSMenu *m = [[NSMenu alloc] initWithTitle:@"AMainMenu"];
NSMenuItem *item = [m addItemWithTitle:@"Apple" action:nil keyEquivalent:@""];
NSMenu *sm = [[NSMenu alloc] initWithTitle:@"Apple"];
[m setSubmenu:sm forItem:item];
[sm addItemWithTitle: @"quit" action:@selector(terminate:) keyEquivalent:@"q"];
[NSApp setMenu:m];
[NSApp activateIgnoringOtherApps:YES];
}
- (void) applicationDidFinishLaunching:(NSNotification *)notification {
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
atexit_b(^{
// Because activation policy has just been set to behave like a real
// application, that policy must be reset on exit to prevent, among
// other things, the menubar created here from remaining on screen.
[NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];
});
// Read filename
NSArray *args = [NSProcessInfo processInfo].arguments;
if (args.count < 2) {
NSLog(@"Expected filename on command line");
exit(1);
}
NSString *filename = args[1];
[self createWindow];
window.pauseButton.target = self;
mpv = mpv_create();
if (!mpv) {
printf("failed creating context\n");
exit(1);
}
check_error(mpv_set_option_string(mpv, "input-media-keys", "yes"));
// request important errors
check_error(mpv_request_log_messages(mpv, "warn"));
check_error(mpv_initialize(mpv));
check_error(mpv_set_option_string(mpv, "vo", "opengl-cb"));
mpv_opengl_cb_context *mpvGL = mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB);
if (!mpvGL) {
puts("libmpv does not have the opengl-cb sub-API.");
exit(1);
}
// pass the mpvGL context to our view
window.glView.mpvGL = mpvGL;
int r = mpv_opengl_cb_init_gl(mpvGL, NULL, get_proc_address, NULL);
if (r < 0) {
puts("gl init has failed.");
exit(1);
}
mpv_opengl_cb_set_update_callback(mpvGL, glupdate, (__bridge void *)window.glView);
// Deal with MPV in the background.
queue = dispatch_queue_create("mpv", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
// Register to be woken up whenever mpv generates new events.
mpv_set_wakeup_callback(mpv, wakeup, (__bridge void *)self);
// Load the indicated file
const char *cmd[] = {"loadfile", filename.UTF8String, NULL};
check_error(mpv_command(mpv, cmd));
});
}
static void glupdate(void *ctx)
{
MpvClientOGLView *glView = (__bridge MpvClientOGLView *)ctx;
// I'm still not sure what the best way to handle this is, but this
// works.
dispatch_async(dispatch_get_main_queue(), ^{
[glView drawRect];
});
}
- (void) handleEvent:(mpv_event *)event
{
switch (event->event_id) {
case MPV_EVENT_SHUTDOWN: {
mpv_detach_destroy(mpv);
mpv_opengl_cb_uninit_gl(window.glView.mpvGL);
mpv = NULL;
printf("event: shutdown\n");
break;
}
case MPV_EVENT_LOG_MESSAGE: {
struct mpv_event_log_message *msg = (struct mpv_event_log_message *)event->data;
printf("[%s] %s: %s", msg->prefix, msg->level, msg->text);
}
default:
printf("event: %s\n", mpv_event_name(event->event_id));
}
}
- (void)togglePause:(NSButton *)button
{
if (mpv) {
switch (button.state) {
case NSOffState:
{
int pause = 0;
mpv_set_property(mpv, "pause", MPV_FORMAT_FLAG, &pause);
}
break;
case NSOnState:
{
int pause = 1;
mpv_set_property(mpv, "pause", MPV_FORMAT_FLAG, &pause);
}
break;
default:
NSLog(@"This should never happen.");
}
}
}
- (void) readEvents
{
dispatch_async(queue, ^{
while (mpv) {
mpv_event *event = mpv_wait_event(mpv, 0);
if (event->event_id == MPV_EVENT_NONE)
break;
[self handleEvent:event];
}
});
}
static void wakeup(void *context)
{
AppDelegate *a = (__bridge AppDelegate *) context;
[a readEvents];
}
// quit when the window is closed.
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app
{
return YES;
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
NSLog(@"Terminating.");
const char *args[] = {"quit", NULL};
mpv_command(mpv, args);
[window.glView clearGLContext];
return NSTerminateNow;
}
@end
// Delete this if you already have a main.m.
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSApplication *app = [NSApplication sharedApplication];
AppDelegate *delegate = [AppDelegate new];
app.delegate = delegate;
[app run];
}
return 0;
}
+4 -6
View File
@@ -1,9 +1,7 @@
// Plays a video from the command line in a window provided by mpv.
// You likely want to play the video in your own window instead,
// but that's not quite ready yet.
// You may need a basic Info.plist and MainMenu.xib to make this work.
// Plays a video from the command line in a view provided by the client
// application.
// Build with: clang -o cocoabasic cocoabasic.m `pkg-config --libs --cflags mpv`
// Build with: clang -o cocoabasic cocoabasic.m `pkg-config --libs --cflags mpv` -framework cocoa
#include <mpv/client.h>
@@ -207,5 +205,5 @@ int main(int argc, const char * argv[]) {
app.delegate = delegate;
[app run];
}
return EXIT_SUCCESS;
return 0;
}
+1 -1
View File
@@ -50,7 +50,7 @@ Item {
text: "Make video look like on a Smart TV"
onClicked: {
if (checkbox.checked) {
renderer.command(["vo_cmdline", "scale=sharpen3:scale-param1=5.0"])
renderer.command(["vo_cmdline", "sharpen=5.0"])
} else {
renderer.command(["vo_cmdline", ""])
}
@@ -0,0 +1,13 @@
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Qt sets the locale in the QApplication constructor, but libmpv requires
// the LC_NUMERIC category to be set to "C", so change it back.
setlocale(LC_NUMERIC, "C");
MainWindow w;
w.show();
return a.exec();
}
@@ -0,0 +1,52 @@
#include "mainwindow.h"
#include "mpvwidget.h"
#include <QPushButton>
#include <QSlider>
#include <QLayout>
#include <QFileDialog>
MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
{
m_mpv = new MpvWidget(this);
m_slider = new QSlider();
m_slider->setOrientation(Qt::Horizontal);
m_openBtn = new QPushButton("Open");
m_playBtn = new QPushButton("Pause");
QHBoxLayout *hb = new QHBoxLayout();
hb->addWidget(m_openBtn);
hb->addWidget(m_playBtn);
QVBoxLayout *vl = new QVBoxLayout();
vl->addWidget(m_mpv);
vl->addWidget(m_slider);
vl->addLayout(hb);
setLayout(vl);
connect(m_slider, SIGNAL(sliderMoved(int)), SLOT(seek(int)));
connect(m_openBtn, SIGNAL(clicked()), SLOT(openMedia()));
connect(m_playBtn, SIGNAL(clicked()), SLOT(pauseResume()));
connect(m_mpv, SIGNAL(positionChanged(int)), m_slider, SLOT(setValue(int)));
connect(m_mpv, SIGNAL(durationChanged(int)), this, SLOT(setSliderRange(int)));
}
void MainWindow::openMedia()
{
QString file = QFileDialog::getOpenFileName(0, "Open a video");
if (file.isEmpty())
return;
m_mpv->command(QStringList() << "loadfile" << file);
}
void MainWindow::seek(int pos)
{
m_mpv->command(QVariantList() << "seek" << pos << "absolute");
}
void MainWindow::pauseResume()
{
const bool paused = m_mpv->getProperty("pause").toBool();
m_mpv->setProperty("pause", !paused);
}
void MainWindow::setSliderRange(int duration)
{
m_slider->setRange(0, duration);
}
@@ -0,0 +1,27 @@
#ifndef MainWindow_H
#define MainWindow_H
#include <QtWidgets/QWidget>
class MpvWidget;
class QSlider;
class QPushButton;
class MainWindow : public QWidget
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
public Q_SLOTS:
void openMedia();
void seek(int pos);
void pauseResume();
private Q_SLOTS:
void setSliderRange(int duration);
private:
MpvWidget *m_mpv;
QSlider *m_slider;
QPushButton *m_openBtn;
QPushButton *m_playBtn;
};
#endif // MainWindow_H
@@ -0,0 +1,129 @@
#include "mpvwidget.h"
#include <stdexcept>
#include <QtGui/QOpenGLContext>
#include <QtCore/QMetaObject>
static void wakeup(void *ctx)
{
QMetaObject::invokeMethod((MpvWidget*)ctx, "on_mpv_events", Qt::QueuedConnection);
}
static void *get_proc_address(void *ctx, const char *name) {
Q_UNUSED(ctx);
QOpenGLContext *glctx = QOpenGLContext::currentContext();
if (!glctx)
return NULL;
return (void *)glctx->getProcAddress(QByteArray(name));
}
MpvWidget::MpvWidget(QWidget *parent, Qt::WindowFlags f)
: QOpenGLWidget(parent, f)
{
mpv = mpv::qt::Handle::FromRawHandle(mpv_create());
if (!mpv)
throw std::runtime_error("could not create mpv context");
mpv_set_option_string(mpv, "terminal", "yes");
mpv_set_option_string(mpv, "msg-level", "all=v");
if (mpv_initialize(mpv) < 0)
throw std::runtime_error("could not initialize mpv context");
// Make use of the MPV_SUB_API_OPENGL_CB API.
mpv::qt::set_option_variant(mpv, "vo", "opengl-cb");
// Request hw decoding, just for testing.
mpv::qt::set_option_variant(mpv, "hwdec", "auto");
mpv_gl = (mpv_opengl_cb_context *)mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB);
if (!mpv_gl)
throw std::runtime_error("OpenGL not compiled in");
mpv_opengl_cb_set_update_callback(mpv_gl, MpvWidget::on_update, (void *)this);
connect(this, SIGNAL(frameSwapped()), SLOT(swapped()));
mpv_observe_property(mpv, 0, "duration", MPV_FORMAT_DOUBLE);
mpv_observe_property(mpv, 0, "time-pos", MPV_FORMAT_DOUBLE);
mpv_set_wakeup_callback(mpv, wakeup, this);
}
MpvWidget::~MpvWidget()
{
makeCurrent();
if (mpv_gl)
mpv_opengl_cb_set_update_callback(mpv_gl, NULL, NULL);
// Until this call is done, we need to make sure the player remains
// alive. This is done implicitly with the mpv::qt::Handle instance
// in this class.
mpv_opengl_cb_uninit_gl(mpv_gl);
}
void MpvWidget::command(const QVariant& params)
{
mpv::qt::command_variant(mpv, params);
}
void MpvWidget::setProperty(const QString& name, const QVariant& value)
{
mpv::qt::set_property_variant(mpv, name, value);
}
QVariant MpvWidget::getProperty(const QString &name) const
{
return mpv::qt::get_property_variant(mpv, name);
}
void MpvWidget::initializeGL()
{
int r = mpv_opengl_cb_init_gl(mpv_gl, NULL, get_proc_address, NULL);
if (r < 0)
throw std::runtime_error("could not initialize OpenGL");
}
void MpvWidget::paintGL()
{
mpv_opengl_cb_draw(mpv_gl, defaultFramebufferObject(), width(), -height());
}
void MpvWidget::swapped()
{
mpv_opengl_cb_report_flip(mpv_gl, 0);
}
void MpvWidget::on_mpv_events()
{
// Process all events, until the event queue is empty.
while (mpv) {
mpv_event *event = mpv_wait_event(mpv, 0);
if (event->event_id == MPV_EVENT_NONE) {
break;
}
handle_mpv_event(event);
}
}
void MpvWidget::handle_mpv_event(mpv_event *event)
{
switch (event->event_id) {
case MPV_EVENT_PROPERTY_CHANGE: {
mpv_event_property *prop = (mpv_event_property *)event->data;
if (strcmp(prop->name, "time-pos") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double time = *(double *)prop->data;
Q_EMIT positionChanged(time);
}
} else if (strcmp(prop->name, "duration") == 0) {
if (prop->format == MPV_FORMAT_DOUBLE) {
double time = *(double *)prop->data;
Q_EMIT durationChanged(time);
}
}
break;
}
default: ;
// Ignore uninteresting or unknown events.
}
}
void MpvWidget::on_update(void *ctx)
{
QMetaObject::invokeMethod((MpvWidget*)ctx, "update");
}
@@ -0,0 +1,38 @@
#ifndef PLAYERWINDOW_H
#define PLAYERWINDOW_H
#include <QtWidgets/QOpenGLWidget>
#include <mpv/client.h>
#include <mpv/opengl_cb.h>
#include <mpv/qthelper.hpp>
class MpvWidget Q_DECL_FINAL: public QOpenGLWidget
{
Q_OBJECT
public:
MpvWidget(QWidget *parent = 0, Qt::WindowFlags f = 0);
~MpvWidget();
void command(const QVariant& params);
void setProperty(const QString& name, const QVariant& value);
QVariant getProperty(const QString& name) const;
QSize sizeHint() const { return QSize(480, 270);}
Q_SIGNALS:
void durationChanged(int value);
void positionChanged(int value);
protected:
void initializeGL() Q_DECL_OVERRIDE;
void paintGL() Q_DECL_OVERRIDE;
private Q_SLOTS:
void swapped();
void on_mpv_events();
private:
void handle_mpv_event(mpv_event *event);
static void on_update(void *ctx);
mpv::qt::Handle mpv;
mpv_opengl_cb_context *mpv_gl;
};
#endif // PLAYERWINDOW_H
@@ -0,0 +1,13 @@
CONFIG -= app_bundle
QT += widgets
QT_CONFIG -= no-pkg-config
CONFIG += link_pkgconfig debug
PKGCONFIG += mpv
HEADERS = \
mpvwidget.h \
mainwindow.h
SOURCES = main.cpp \
mpvwidget.cpp \
mainwindow.cpp
+158
View File
@@ -0,0 +1,158 @@
// Build with: gcc -o main main.c `pkg-config --libs --cflags mpv sdl2`
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <mpv/client.h>
#include <mpv/opengl_cb.h>
static Uint32 wakeup_on_mpv_redraw, wakeup_on_mpv_events;
static void die(const char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(1);
}
static void *get_proc_address_mpv(void *fn_ctx, const char *name)
{
return SDL_GL_GetProcAddress(name);
}
static void on_mpv_events(void *ctx)
{
SDL_Event event = {.type = wakeup_on_mpv_events};
SDL_PushEvent(&event);
}
static void on_mpv_redraw(void *ctx)
{
SDL_Event event = {.type = wakeup_on_mpv_redraw};
SDL_PushEvent(&event);
}
int main(int argc, char *argv[])
{
if (argc != 2)
die("pass a single media file as argument");
mpv_handle *mpv = mpv_create();
if (!mpv)
die("context init failed");
// Some minor options can only be set before mpv_initialize().
if (mpv_initialize(mpv) < 0)
die("mpv init failed");
if (SDL_Init(SDL_INIT_VIDEO) < 0)
die("SDL init failed");
SDL_Window *window =
SDL_CreateWindow("hi", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
1000, 500, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN |
SDL_WINDOW_RESIZABLE);
if (!window)
die("failed to create SDL window");
// The OpenGL API is somewhat separate from the normal mpv API. This only
// returns NULL if no OpenGL support is compiled.
mpv_opengl_cb_context *mpv_gl = mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB);
if (!mpv_gl)
die("failed to create mpv GL API handle");
SDL_GLContext glcontext = SDL_GL_CreateContext(window);
if (!glcontext)
die("failed to create SDL GL context");
// This makes mpv use the currently set GL context. It will use the callback
// to resolve GL builtin functions, as well as extensions.
if (mpv_opengl_cb_init_gl(mpv_gl, NULL, get_proc_address_mpv, NULL) < 0)
die("failed to initialize mpv GL context");
// Actually using the opengl_cb state has to be explicitly requested.
// Otherwise, mpv will create a separate platform window.
if (mpv_set_option_string(mpv, "vo", "opengl-cb") < 0)
die("failed to set VO");
// We use events for thread-safe notification of the SDL main loop.
// Generally, the wakeup callbacks (set further below) should do as least
// work as possible, and merely wake up another thread to do actual work.
// On SDL, waking up the mainloop is the ideal course of action. SDL's
// SDL_PushEvent() is thread-safe, so we use that.
wakeup_on_mpv_redraw = SDL_RegisterEvents(1);
wakeup_on_mpv_events = SDL_RegisterEvents(1);
if (wakeup_on_mpv_redraw == (Uint32)-1 || wakeup_on_mpv_events == (Uint32)-1)
die("could not register events");
// When normal mpv events are available.
mpv_set_wakeup_callback(mpv, on_mpv_events, NULL);
// When a new frame should be drawn with mpv_opengl_cb_draw().
// (Separate from the normal event handling mechanism for the sake of
// users which run OpenGL on a different thread.)
mpv_opengl_cb_set_update_callback(mpv_gl, on_mpv_redraw, NULL);
// Play this file. Note that this starts playback asynchronously.
const char *cmd[] = {"loadfile", argv[1], NULL};
mpv_command(mpv, cmd);
while (1) {
SDL_Event event;
if (SDL_WaitEvent(&event) != 1)
die("event loop error");
int redraw = 0;
switch (event.type) {
case SDL_QUIT:
goto done;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_EXPOSED)
redraw = 1;
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_SPACE)
mpv_command_string(mpv, "cycle pause");
break;
default:
// Happens when a new video frame should be rendered, or if the
// current frame has to be redrawn e.g. due to OSD changes.
if (event.type == wakeup_on_mpv_redraw)
redraw = 1;
// Happens when at least 1 new event is in the mpv event queue.
if (event.type == wakeup_on_mpv_events) {
// Handle all remaining mpv events.
while (1) {
mpv_event *mp_event = mpv_wait_event(mpv, 0);
if (mp_event->event_id == MPV_EVENT_NONE)
break;
printf("event: %s\n", mpv_event_name(mp_event->event_id));
}
}
}
if (redraw) {
int w, h;
SDL_GetWindowSize(window, &w, &h);
// Note:
// - The 0 is the FBO to use; 0 is the default framebuffer (i.e.
// render to the window directly.
// - The negative height tells mpv to flip the coordinate system.
// - If you do not want the video to cover the whole screen, or want
// to apply any form of fancy transformation, you will have to
// render to a FBO.
// - See opengl_cb.h on what OpenGL environment mpv expects, and
// other API details.
mpv_opengl_cb_draw(mpv_gl, 0, w, -h);
SDL_GL_SwapWindow(window);
}
}
done:
// Destroy the GL renderer and all of the GL objects it allocated. If video
// is still running, the video track will be deselected.
mpv_opengl_cb_uninit_gl(mpv_gl);
mpv_terminate_destroy(mpv);
return 0;
}
+2 -2
View File
@@ -134,10 +134,10 @@ pacman -S git pkg-config python3 mingw-w64-x86_64-gcc
# Install the most important MinGW-w64 dependencies. libass, libbluray and
# lcms2 are also pulled in as dependencies of ffmpeg.
pacman -S mingw-w64-x86_64-ffmpeg mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-lua
pacman -S mingw-w64-x86_64-ffmpeg mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-lua51
# Install additional (optional) dependencies
pacman -S mingw-w64-x86_64-libdvdnav mingw-w64-x86_64-mpg123 mingw-w64-x86_64-libguess
pacman -S mingw-w64-x86_64-libdvdnav mingw-w64-x86_64-libguess
```
For a 32-bit build, install ``mingw-w64-i686-*`` packages instead.
+3
View File
@@ -54,6 +54,9 @@ Sending patches
change in the same commit.
- If you add a new command line option, document it in options.rst. If you
add a new input property, document it in input.rst.
- All new code must be LGPLv2.1+ licensed, or come with the implicit agreement
that it will be relicensed to LGPLv2.1+ later (see ``Copyright`` in the
repository root directory).
Code formatting
---------------
+113
View File
@@ -0,0 +1,113 @@
Introduction
============
mpv provides access to its internal via the following means:
- options
- commands
- properties
- events
All of these are important for interfacing both with end users and API users
(which include Lua scripts, libmpv, and the JSON IPC). As such, they constitute
a large part of the user interface and APIs.
This document lists changes to them. New changes are added to the top.
Interface changes
=================
::
--- mpv 0.14.0 ---
- vo_opengl interpolation now requires --video-sync=display-... to be set
- change some vo_opengl defaults (including changing tscale)
- add "vsync-ratio", "estimated-display-fps" properties
- add --rebase-start-time option
This is a breaking change to start time handling. Instead of making start
time handling an aspect of different options and properties (like
"time-pos" vs. "playback-time"), make it dependent on the new option. For
compatibility, the "time-start" property now always returns 0, so code
which attempted to handle rebasing manually will not break.
--- mpv 0.13.0 ---
- remove VO opengl-cb frame queue suboptions (no replacement)
--- mpv 0.12.0 ---
- remove --use-text-osd (useless; fontconfig isn't a requirement anymore,
and text rendering is also lazily initialized)
- some time properties (at least "playback-time", "time-pos",
"time-remaining", "playtime-remaining") now are unavailable if the time
is unknown, instead of just assuming that the internal playback position
is 0
- add --audio-fallback-to-null option
- replace vf_format outputlevels suboption with "video-output-levels" global
property/option; also remove "colormatrix-output-range" property
- vo_opengl: remove sharpen3/sharpen5 scale filters, add sharpen sub-option
--- mpv 0.11.0 ---
- add "af-metadata" property
--- mpv 0.10.0 ---
- add --video-aspect-method option
- add --playlist-pos option
- add --video-sync* options
"display-sync-active" property
"vo-missed-frame-count" property
"audio-speed-correction" and "video-speed-correction" properties
- remove --demuxer-readahead-packets and --demuxer-readahead-bytes
add --demuxer-max-packets and --demuxer-max-bytes
(the new options are not replacement and have very different semantics)
- change "video-aspect" property: always settable, even if no video is
running; always return the override - if no override is set, return
the video's aspect ratio
- remove disc-nav (DVD, BD) related properties and commands
- add "option-info/<name>/set-locally" property
- add --cache-backbuffer; change --cache-default default to 75MB
the new total cache size is the sum of backbuffer and the cache size
specified by --cache-default or --cache
- add ``track-list/N/audio-channels`` property
- change --screenshot-tag-colorspace default value
- add --stretch-image-subs-to-screen
- add "playlist/N/title" property
- add --video-stereo-mode=no to disable auto-conversions
- add --force-seekable, and change default seekability in some cases
- add vf yadif/vavpp/vdpaupp interlaced-only suboptions
Also, the option is enabled by default (Except vf_yadif, which has
it enabled only if it's inserted by the deinterlace property.)
- add --hwdec-preload
- add ao coreaudio exclusive suboption
- add ``track-list/N/forced`` property
- add audio-params/channel-count and ``audio-params-out/channel-count props.
- add af volume replaygain-fallback suboption
- add video-params/stereo-in property
- add "keypress", "keydown", and "keyup" commands
- deprecate --ad-spdif-dtshd and enabling passthrough via --ad
add --audio-spdif as replacement
- remove "get_property" command
- remove --slave-broken
- add vo opengl custom shader suboptions (source-shader, scale-shader,
pre-shaders, post-shaders)
- completely change how the hwdec properties work:
- "hwdec" now reflects the --hwdec option
- "hwdec-detected" does partially what the old "hwdec" property did
(and also, "detected-hwdec" is removed)
- "hwdec-active" is added
- add protocol-list property
- deprecate audio-samplerate and audio-channels properties
(audio-params sub-properties are the replacement)
- add audio-params and audio-out-params properties
- deprecate "audio-format" property, replaced with "audio-codec-name"
- deprecate --media-title, replaced with --force-media-title
- deprecate "length" property, replaced with "duration"
- change volume property:
- the value 100 is now always "unchanged volume" - with softvol, the
range is 0 to --softvol-max, without it is 0-100
- the minimum value of --softvol-max is raised to 100
- remove vo opengl npot suboption
- add relative seeking by percentage to "seek" command
- add playlist_shuffle command
- add --force-window=immediate
- add ao coreaudio change-physical-format suboption
- remove vo opengl icc-cache suboption, add icc-cache-dir suboption
- add --screenshot-directory
- add --screenshot-high-bit-depth
- add --screenshot-jpeg-source-chroma
- default action for "rescan_external_files" command changes
--- mpv 0.9.0 ---
+16 -188
View File
@@ -11,6 +11,10 @@ syntax is:
To get a full list of available audio filters, see ``--af=help``.
Also, keep in mind that most actual filters are available via the ``lavfi``
wrapper, which gives you access to most of libavfilter's filters. This
includes all filters that have been ported from MPlayer to libavfilter.
You can also set defaults for each filter. The defaults are applied before the
normal filter parameters.
@@ -59,6 +63,13 @@ Available filters are:
(If you just want to set defaults for this filter that will be used
even by automatically inserted lavrresample instances, you should
prefer setting them with ``--af-defaults=lavrresample:...``.)
``normalize=<yes|no>``
Whether to normalize when remixing channel layouts (default: yes). This
is e.g. applied when downmixing surround audio to stereo. The advantage
is that this guarantees that no clipping can happen. Unfortunately,
this can also lead to too low volume levels. Whether you enable or
disable this is essentially a matter of taste, but the default uses
the safer choice.
``o=<string>``
Set AVOptions on the SwrContext or AVAudioResampleContext. These should
be documented by FFmpeg or Libav.
@@ -96,59 +107,6 @@ Available filters are:
If the input channel number is less than ``<minch>``, the filter will
detach itself (default: 3).
``sweep[=speed]``
Produces a sine sweep.
``<0.0-1.0>``
Sine function delta, use very low values to hear the sweep.
``sinesuppress[=freq:decay]``
Remove a sine at the specified frequency. Useful to get rid of the 50/60 Hz
noise on low quality audio equipment. It only works on mono input.
``<freq>``
The frequency of the sine which should be removed (in Hz) (default:
50)
``<decay>``
Controls the adaptivity (a larger value will make the filter adapt to
amplitude and phase changes quicker, a smaller value will make the
adaptation slower) (default: 0.0001). Reasonable values are around
0.001.
``bs2b[=option1:option2:...]``
Bauer stereophonic to binaural transformation using libbs2b. Improves the
headphone listening experience by making the sound similar to that from
loudspeakers, allowing each ear to hear both channels and taking into
account the distance difference and the head shadowing effect. It is
applicable only to 2-channel audio.
``fcut=<300-1000>``
Set cut frequency in Hz.
``feed=<10-150>``
Set feed level for low frequencies in 0.1*dB.
``profile=<value>``
Several profiles are available for convenience:
:default: will be used if nothing else was specified (fcut=700,
feed=45)
:cmoy: Chu Moy circuit implementation (fcut=700, feed=60)
:jmeier: Jan Meier circuit implementation (fcut=650, feed=95)
If ``fcut`` or ``feed`` options are specified together with a profile, they
will be applied on top of the selected profile.
``hrtf[=flag]``
Head-related transfer function: Converts multichannel audio to 2-channel
output for headphones, preserving the spatiality of the sound.
==== ===================================
Flag Meaning
==== ===================================
m matrix decoding of the rear channel
s 2-channel matrix decoding
0 no matrix decoding (default)
==== ===================================
``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
@@ -206,7 +164,7 @@ Available filters are:
.. admonition:: Examples
``mpv --af=channels=4:[0-1,1-0,0-2,1-3] media.avi``
``mpv --af=channels=4:[0-1,1-0,2-2,3-3] media.avi``
Would change the number of channels to 4 and set up 4 routes that
swap channel 0 and channel 1 and leave channel 2 and 3 intact.
Observe that if media containing two channels were played back,
@@ -263,13 +221,6 @@ Available filters are:
used to do conversion itself, unlike this one which lets the filter system
handle the conversion.
``convert24``
Filter for internal use only. Converts between 24-bit and 32-bit sample
formats.
``convertsign``
Filter for internal use only. Converts between signed/unsigned formats.
``volume[=<volumedb>[:...]]``
Implements software volume control. Use this filter with caution since it
can reduce the signal to noise ratio of the sound. In most cases it is
@@ -294,6 +245,10 @@ Available filters are:
``replaygain-clip=yes|no``
Prevent clipping caused by replaygain by automatically lowering the
gain (default). Use ``replaygain-clip=no`` to disable this.
``replaygain-fallback``
Gain in dB to apply if the file has no replay gain tags. This option
is always applied if the replaygain logic is somehow inactive. If this
is applied, no other replaygain options are applied.
``softclip``
Turns soft clipping on. Soft-clipping can make the
sound more smooth if very high volume levels are used. Enable this
@@ -357,64 +312,6 @@ 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.
``sub[=fc:ch]``
Adds a subwoofer channel to the audio stream. The audio data used for
creating the subwoofer channel is an average of the sound in channel 0 and
channel 1. The resulting sound is then low-pass filtered by a 4th order
Butterworth filter with a default cutoff frequency of 60Hz and added to a
separate channel in the audio stream.
.. warning::
Disable this filter when you are playing media with an LFE channel
(e.g. 5.1 surround sound), otherwise this filter will disrupt the sound
to the subwoofer.
``<fc>``
cutoff frequency in Hz for the low-pass filter (20 Hz to 300 Hz)
(default: 60 Hz) For the best result try setting the cutoff frequency
as low as possible. This will improve the stereo or surround sound
experience.
``<ch>``
Determines the channel number in which to insert the sub-channel
audio. Channel number can be between 0 and 7 (default: 5). Observe
that the number of channels will automatically be increased to <ch> if
necessary.
.. admonition:: Example
``mpv --af=sub=100:4 --audio-channels=5 media.avi``
Would add a subwoofer channel with a cutoff frequency of 100 Hz to
output channel 4.
``center``
Creates a center channel from the front channels. May currently be low
quality as it does not implement a high-pass filter for proper extraction
yet, but averages and halves the channels instead.
``<ch>``
Determines the channel number in which to insert the center channel.
Channel number can be between 0 and 7 (default: 5). Observe that the
number of channels will automatically be increased to ``<ch>`` if
necessary.
``surround[=delay]``
Decoder for matrix encoded surround sound like Dolby Surround. Some files
with 2-channel audio actually contain matrix encoded surround sound.
``<delay>``
delay time in ms for the rear speakers (0 to 1000) (default: 20) This
delay should be set as follows: If d1 is the distance from the
listening position to the front speakers and d2 is the distance from
the listening position to the rear speakers, then the delay should be
set to 15ms if d1 <= d2 and to 15 + 5*(d1-d2) if d1 > d2.
.. admonition:: Example
``mpv --af=surround=15 --audio-channels=4 media.avi``
Would add surround sound decoding with 15 ms delay for the sound to
the rear speakers.
``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
@@ -443,36 +340,6 @@ Available filters are:
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.
``export=mmapped_file:nsamples]``
Exports the incoming signal to other processes using memory mapping
(``mmap()``). Memory mapped areas contain a header::
int nch /* number of channels */
int size /* buffer size */
unsigned long long counter /* Used to keep sync, updated every time
new data is exported. */
The rest is payload (non-interleaved) 16-bit data.
``<mmapped_file>``
File to map data to (required)
``<nsamples>``
number of samples per channel (default: 512).
.. admonition:: Example
``mpv --af=export=/tmp/mpv-af_export:1024 media.avi``
Would export 1024 samples per channel to ``/tmp/mpv-af_export``.
``extrastereo[=mul]``
(Linearly) increases the difference between left and right channels which
adds some sort of "live" effect to playback.
``<mul>``
Sets the difference coefficient (default: 2.5). 0.0 means mono sound
(average of both channels), with 1.0 sound will be unchanged, with
-1.0 left and right channels will be swapped.
``drc[=method:target]``
Applies dynamic range compression. This maximizes the volume by compressing
the audio signal's dynamic range. (Formerly called ``volnorm``.)
@@ -496,45 +363,6 @@ Available filters are:
This filter can cause distortion with audio signals that have a very
large dynamic range.
``ladspa=file:label:[<control0>,<control1>,...]``
Load a LADSPA (Linux Audio Developer's Simple Plugin API) plugin. This
filter is reentrant, so multiple LADSPA plugins can be used at once.
``<file>``
Specifies the LADSPA plugin library file.
.. note::
See also the note about the ``LADSPA_PATH`` variable in the
`ENVIRONMENT VARIABLES`_ section.
``<label>``
Specifies the filter within the library. Some libraries contain only
one filter, but others contain many of them. Entering 'help' here
will list all available filters within the specified library, which
eliminates the use of 'listplugins' from the LADSPA SDK.
``[<control0>,<control1>,...]``
Controls are zero or more ``,`` separated floating point values that
determine the behavior of the loaded plugin (for example delay,
threshold or gain).
In verbose mode (add ``-v`` to the mpv command line), all
available controls and their valid ranges are printed. This eliminates
the use of 'analyseplugin' from the LADSPA SDK.
Note that ``,`` is already used by the option parser to separate
filters, so you must quote the list of values with ``[...]`` or
similar.
.. admonition:: Example
``mpv --af=ladspa='/usr/lib/ladspa/delay.so':delay_5s:[0.5,0.2] media.avi``
Does something.
``karaoke``
Simple voice removal filter exploiting the fact that voice is usually
recorded with mono gear and later 'center' mixed onto the final audio
stream. Beware that this filter will turn your signal into mono. Works
well for 2 channel tracks; do not bother trying it on anything but 2
channel stereo.
``scaletempo[=option1:option2:...]``
Scales audio tempo without altering pitch, optionally synced to playback
speed (default).
+21 -9
View File
@@ -55,7 +55,7 @@ Available audio output drivers are:
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.
``ingore-chmap``
``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,
@@ -139,16 +139,13 @@ Available audio output drivers are:
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=alsa|waveext|any``
Select the standard channel layout (default: alsa). JACK itself has no
``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
outputs, and reroutes it to whatever the user defines. This means the
user and the application are in charge of dealing with the channel
layout. ``alsa`` uses the old MPlayer layout, which is inspired by
ALSA's standard layouts. In this mode, ao_jack will refuse to play 3
or 7 channels (because these do not really have a defined meaning in
MPlayer). ``waveext`` uses WAVE_FORMAT_EXTENSIBLE order, which, even
layout. ``waveext`` uses WAVE_FORMAT_EXTENSIBLE order, which, even
though it was defined by Microsoft, is the standard on many systems.
The value ``any`` makes JACK accept whatever comes from the audio
filter chain, regardless of channel layout and without reordering. This
@@ -162,12 +159,23 @@ Available audio output drivers are:
Automatically redirects to ``coreaudio_exclusive`` when playing compressed
formats.
``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
system-wide audio settings. This is equivalent to changing the ``Format``
setting in the ``Audio Devices`` dialog in the ``Audio MIDI Setup``
utility. Note that this does not effect the selected speaker setup.
``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).
Supports only compressed formats (AC3 and DTS).
``openal``
Experimental OpenAL audio output driver
@@ -260,6 +268,10 @@ Available audio output drivers are:
``broken-delay``
Simulate broken audio drivers, which don't report latency correctly.
``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
+1 -1
View File
@@ -111,7 +111,7 @@ You can encode files from one format/codec to another using this facility.
.. admonition:: Examples
``"--ovc=mpeg4 --oacopts=qscale=5"``
``"--ovc=mpeg4 --ovcopts=qscale=5"``
selects constant quantizer scale 5 for MPEG-4 encoding.
``"--ovc=libx264 --ovcopts=crf=23"``
+317 -151
View File
@@ -65,11 +65,11 @@ C-style escaping can be used.
You can bind multiple commands to one key. For example:
| a show_text "command 1" ; show_text "command 2"
| a show-text "command 1" ; show-text "command 2"
It's also possible to bind a command to a sequence of keys:
| a-b-c show_text "command run after a, b, c have been pressed"
| a-b-c show-text "command run after a, b, c have been pressed"
(This is not shown in the general command syntax.)
@@ -86,7 +86,7 @@ List of Input Commands
disabling default bindings, without disabling all bindings with
``--no-input-default-bindings``.
``seek <seconds> [relative|absolute|absolute-percent|exact|keyframes]``
``seek <seconds> [relative|absolute|absolute-percent|relative-percent|exact|keyframes]``
Change the playback position. By default, seeks by a relative amount of
seconds.
@@ -98,6 +98,8 @@ List of Input Commands
Seek to a given time.
absolute-percent
Seek to a given percent position.
relative-percent
Seek relative to current position in percent.
keyframes
Always restart playback at keyframe boundaries (fast).
exact
@@ -112,25 +114,25 @@ List of Input Commands
3rd parameter (essentially using a space instead of ``+``). The 3rd
parameter is still parsed, but is considered deprecated.
``revert_seek [mode]``
``revert-seek [mode]``
Undoes the ``seek`` command, and some other commands that seek (but not
necessarily all of them). Calling this command once will jump to the
playback position before the seek. Calling it a second time undoes the
``revert_seek`` command itself. This only works within a single file.
``revert-seek`` command itself. This only works within a single file.
The first argument is optional, and can change the behavior:
mark
Mark the current time position. The next normal ``revert_seek`` command
Mark the current time position. The next normal ``revert-seek`` command
will seek back to this point, no matter how many seeks happened since
last time.
Using it without any arguments gives you the default behavior.
``frame_step``
``frame-step``
Play one frame, then pause. Does nothing with audio-only playback.
``frame_back_step``
``frame-back-step``
Go back by one frame, then pause. Note that this can be very slow (it tries
to be precise, not fast), and sometimes fails to behave as expected. How
well this works depends on whether precise seeking works correctly (e.g.
@@ -180,7 +182,7 @@ List of Input Commands
frame was dropped. This flag can be combined with the other flags,
e.g. ``video+each-frame``.
``screenshot_to_file "<filename>" [subtitles|video|window]``
``screenshot-to-file "<filename>" [subtitles|video|window]``
Take a screenshot and save it to a given file. The format of the file will
be guessed by the extension (and ``--screenshot-format`` is ignored - the
behavior when the extension is missing or unknown is arbitrary).
@@ -192,7 +194,7 @@ List of Input Commands
Like all input command parameters, the filename is subject to property
expansion as described in `Property Expansion`_.
``playlist_next [weak|force]``
``playlist-next [weak|force]``
Go to the next entry on the playlist.
weak (default)
@@ -200,7 +202,7 @@ List of Input Commands
force
Terminate playback if there are no more files on the playlist.
``playlist_prev [weak|force]``
``playlist-prev [weak|force]``
Go to the previous entry on the playlist.
weak (default)
@@ -230,22 +232,26 @@ List of Input Commands
``loadlist "<playlist>" [replace|append]``
Load the given playlist file (like ``--playlist``).
``playlist_clear``
``playlist-clear``
Clear the playlist, except the currently played file.
``playlist_remove current|<index>``
``playlist-remove current|<index>``
Remove the playlist entry at the given index. Index values start counting
with 0. The special value ``current`` removes the current entry. Note that
removing the current entry also stops playback and starts playing the next
entry.
``playlist_move <index1> <index2>``
``playlist-move <index1> <index2>``
Move the playlist entry at index1, so that it takes the place of the
entry index2. (Paradoxically, the moved playlist entry will not have
the index value index2 after moving if index1 was lower than index2,
because index2 refers to the target entry, not the index the entry
will have after moving.)
``playlist-shuffle``
Shuffle the playlist. This is similar to what is done on start if the
``--shuffle`` option is used.
``run "command" "arg1" "arg2" ...``
Run the given command. Unlike in MPlayer/mplayer2 and earlier versions of
mpv (0.2.x and older), this doesn't call the shell. Instead, the command
@@ -271,12 +277,12 @@ List of Input Commands
``quit [<code>]``
Exit the player. If an argument is given, it's used as process exit code.
``quit_watch_later [<code>]``
``quit-watch-later [<code>]``
Exit player, and store current playback position. Playing that file later
will seek to the previous position on start. The (optional) argument is
exactly as in the ``quit`` command.
``sub_add "<file>" [<flags> [<title> [<lang>]]]``
``sub-add "<file>" [<flags> [<title> [<lang>]]]``
Load the given subtitle file. It is selected as current subtitle after
loading.
@@ -303,39 +309,39 @@ List of Input Commands
The ``lang`` argument sets the track language, and can also influence
stream selection with ``flags`` set to ``auto``.
``sub_remove [<id>]``
``sub-remove [<id>]``
Remove the given subtitle track. If the ``id`` argument is missing, remove
the current track. (Works on external subtitle files only.)
``sub_reload [<id>]``
``sub-reload [<id>]``
Reload the given subtitle tracks. If the ``id`` argument is missing, reload
the current track. (Works on external subtitle files only.)
This works by unloading and re-adding the subtitle track.
``sub_step <skip>``
``sub-step <skip>``
Change subtitle timing such, that the subtitle event after the next
``<skip>`` subtitle events is displayed. ``<skip>`` can be negative to step
backwards.
``sub_seek <skip>``
``sub-seek <skip>``
Seek to the next (skip set to 1) or the previous (skip set to -1) subtitle.
This is similar to ``sub_step``, except that it seeks video and audio
This is similar to ``sub-step``, except that it seeks video and audio
instead of adjusting the subtitle delay.
Like with ``sub_step``, this works with external text subtitles only. For
embedded text subtitles (like with Matroska), this works only with subtitle
events that have already been displayed.
For embedded subtitles (like with Matroska), this works only with subtitle
events that have already been displayed, or are within a short prefetch
range.
``osd [<level>]``
Toggle OSD level. If ``<level>`` is specified, set the OSD mode
(see ``--osd-level`` for valid values).
``print_text "<string>"``
``print-text "<string>"``
Print text to stdout. The string can contain properties (see
`Property Expansion`_).
``show_text "<string>" [<duration>|- [<level>]]``
``show-text "<string>" [<duration>|- [<level>]]``
Show text on the OSD. The string can contain properties, which are expanded
as described in `Property Expansion`_. This can be used to show playback
time, filename, and so on.
@@ -347,24 +353,12 @@ List of Input Commands
<level>
The minimum OSD level to show the text at (see ``--osd-level``).
``show_progress``
``show-progress``
Show the progress bar, the elapsed time and the total duration of the file
on the OSD.
``discnav "<command>"``
Send a menu control command to the DVD/BD menu implementation. The following
commands are defined: ``up``, ``down``, ``left``, ``right``,
``menu`` (request to enter menu), ``prev`` (previous screen),
``select`` (activate current button), ``mouse`` (the mouse was clicked),
``mouse_move`` (the mouse cursor changed position).
``mouse_move`` will use the current mouse position.
Note that while the menu is active, the input section ``discnav-menu`` will
be enabled, so different key bindings can be mapped for menu mode.
``write_watch_later_config``
Write the resume config file that the ``quit_watch_later`` command writes,
``write-watch-later-config``
Write the resume config file that the ``quit-watch-later`` command writes,
but continue playback normally.
``stop``
@@ -389,30 +383,47 @@ List of Input Commands
<double>
The mouse event represents double-click.
``audio_add "<file>" [<flags> [<title> [<lang>]]]``
Load the given audio file. See ``sub_add`` command.
``keypress <key_name>``
Send a key event through mpv's input handler, triggering whatever
behavior is configured to that key. ``key_name`` uses the ``input.conf``
naming scheme for keys and modifiers. Useful for the client API: key events
can be sent to libmpv to handle internally.
``audio_remove [<id>]``
Remove the given audio track. See ``sub_remove`` command.
``keydown <key_name>``
Similar to ``keypress``, but sets the ``KEYDOWN`` flag so that if the key is
bound to a repeatable command, it will be run repeatedly with mpv's key
repeat timing until the ``keyup`` command is called.
``audio_reload [<id>]``
Reload the given audio tracks. See ``sub_reload`` command.
``keyup [<key_name>]``
Set the ``KEYUP`` flag, stopping any repeated behavior that had been
triggered. ``key_name`` is optional. If ``key_name`` is not given or is an
empty string, ``KEYUP`` will be set on all keys. Otherwise, ``KEYUP`` will
only be set on the key specified by ``key_name``.
``rescan_external_files [<mode>]``
``audio-add "<file>" [<flags> [<title> [<lang>]]]``
Load the given audio file. See ``sub-add`` command.
``audio-remove [<id>]``
Remove the given audio track. See ``sub-remove`` command.
``audio-reload [<id>]``
Reload the given audio tracks. See ``sub-reload`` command.
``rescan-external-files [<mode>]``
Rescan external files according to the current ``--sub-auto`` and
``--audio-file-auto`` settings. This can be used to auto-load external
files *after* the file was loaded.
The ``mode`` argument is one of the following:
<keep-selection> (default)
Do not change current track selections.
<reselect>
Select the default audio and video streams, which typically selects
<reselect> (default)
Select the default audio and subtitle streams, which typically selects
external files with highest preference. (The implementation is not
perfect, and could be improved on request.)
<keep-selection>
Do not change current track selections.
Input Commands that are Possibly Subject to Change
--------------------------------------------------
@@ -455,7 +466,7 @@ Input Commands that are Possibly Subject to Change
The ``vf`` command shows the list of requested filters on the OSD after
changing the filter chain. This is roughly equivalent to
``show_text ${vf}``. Note that auto-inserted filters for format conversion
``show-text ${vf}``. Note that auto-inserted filters for format conversion
are not shown on the list, only what was requested by the user.
Normally, the commands will check whether the video chain is recreated
@@ -470,7 +481,7 @@ Input Commands that are Possibly Subject to Change
- ``b vf set ""`` remove all video filters on ``b``
- ``c vf toggle lavfi=gradfun`` toggle debanding on ``c``
``cycle_values ["!reverse"] <property> "<value1>" "<value2>" ...``
``cycle-values ["!reverse"] <property> "<value1>" "<value2>" ...``
Cycle through a list of values. Each invocation of the command will set the
given property to the next value in the list. The command maintains an
internal counter which value to pick next, and which is initially 0. It is
@@ -488,7 +499,7 @@ Input Commands that are Possibly Subject to Change
Note that there is a static limit of (as of this writing) 10 arguments
(this limit could be raised on demand).
``enable_section "<section>" [default|exclusive]``
``enable-section "<section>" [flags]``
Enable all key bindings in the named input section.
The enabled input sections form a stack. Bindings in sections on the top of
@@ -497,14 +508,45 @@ Input Commands that are Possibly Subject to Change
implicitly removed beforehand. (A section cannot be on the stack more than
once.)
If ``exclusive`` is specified as second argument, all sections below the
newly enabled section are disabled. They will be re-enabled as soon as
all exclusive sections above them are removed.
The ``flags`` parameter can be a combination (separated by ``+``) of the
following flags:
``disable_section "<section>"``
Disable the named input section. Undoes ``enable_section``.
<exclusive>
All sections enabled before the newly enabled section are disabled.
They will be re-enabled as soon as all exclusive sections above them
are removed. In other words, the new section shadows all previous
sections.
<allow-hide-cursor>
This feature can't be used through the public API.
<allow-vo-dragging>
Same.
``overlay_add <id> <x> <y> "<file>" <offset> "<fmt>" <w> <h> <stride>``
``disable-section "<section>"``
Disable the named input section. Undoes ``enable-section``.
``define-section "<section>" "<contents>" [default|forced]``
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
allowed), including the need to separate bindings with a newline character.
If the ``contents`` parameter is an empty string, the section is removed.
The section with the name ``default`` is the normal input section.
In general, input sections have to be enabled with the ``enable-section``
command, or they are ignored.
The last parameter has the following meaning:
<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>
Always bind a key. (The input section that was made active most recently
wins if there are ambiguities.)
``overlay-add <id> <x> <y> "<file>" <offset> "<fmt>" <w> <h> <stride>``
Add an OSD overlay sourced from raw data. This might be useful for scripts
and applications controlling mpv, and which want to display things on top
of the video window.
@@ -520,7 +562,7 @@ Input Commands that are Possibly Subject to Change
``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,
``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.)
@@ -534,11 +576,11 @@ Input Commands that are Possibly Subject to Change
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
random points. Instead, call ``overlay-add`` again (preferably with a
different memory region to prevent tearing).
It is also possible to pass a raw memory address for use as bitmap memory
by passing a memory address as integer prefixed with a ``&`` character.
by passing a memory address as integer prefixed with an ``&`` character.
Passing the wrong thing here will crash the player. This mode might be
useful for use with libmpv. The ``offset`` parameter is simply added to the
memory address (since mpv 0.8.0, ignored before).
@@ -578,22 +620,22 @@ Input Commands that are Possibly Subject to Change
an overlay's memory at random times whenever it feels the need to do
so, for example when redrawing the screen.
``overlay_remove <id>``
Remove an overlay added with ``overlay_add`` and the same ID. Does nothing
``overlay-remove <id>``
Remove an overlay added with ``overlay-add`` and the same ID. Does nothing
if no overlay with this ID exists.
``script_message "<arg1>" "<arg2>" ...``
``script-message "<arg1>" "<arg2>" ...``
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``).
``script_message_to "<target>" "<arg1>" "<arg2>" ...``
``script-message-to "<target>" "<arg1>" "<arg2>" ...``
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()``.
``script_binding "<name>"``
``script-binding "<name>"``
Invoke a script-provided key binding. This can be used to remap key
bindings provided by external Lua scripts.
@@ -614,24 +656,24 @@ Input Commands that are Possibly Subject to Change
tracked). The second letter whether the event originates from the mouse,
either ``m`` (mouse button) or ``-`` (something else).
``ab_loop``
``ab-loop``
Cycle through A-B loop states. The first command will set the ``A`` point
(the ``ab-loop-a`` property); the second the ``B`` point, and the third
will clear both points.
``vo_cmdline "<args>"``
``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-buffers``
Drop audio/video/demuxer buffers, and restart from fresh. Might help with
unseekable streams that are going out of sync.
This command might be changed or removed in the future.
``screenshot_raw [subtitles|video|window]``
``screenshot-raw [subtitles|video|window]``
Return a screenshot in memory. This can be used only through the client
API. The MPV_FORMAT_NODE_MAP returned by this command has the ``w``, ``h``,
``stride`` fields set to obvious contents. A ``format`` field is set to
@@ -640,14 +682,14 @@ Input Commands that are Possibly Subject to Change
field is of type MPV_FORMAT_BYTE_ARRAY with the actual image data. The image
is freed as soon as the result node is freed.
Undocumented commands: ``tv_last_channel`` (TV/DVB only),
``get_property`` (deprecated), ``ao_reload`` (experimental/internal).
Undocumented commands: ``tv-last-channel`` (TV/DVB only),
``ao-reload`` (experimental/internal).
Hooks
~~~~~
Hooks are synchronous events between player core and a script or similar. This
applies to the Lua scripting interface and the client API and only. Normally,
applies to client API (including the Lua scripting interface). Normally,
events are supposed to be asynchronous, and the hook API provides an awkward
and obscure way to handle events that require stricter coordination. There are
no API stability guarantees made. Not following the protocol exactly can make
@@ -656,7 +698,7 @@ the player freeze randomly. Basically, nobody should use this API.
There are two special commands involved. Also, the client must listen for
client messages (``MPV_EVENT_CLIENT_MESSAGE`` in the C API).
``hook_add <hook-name> <id> <priority>``
``hook-add <hook-name> <id> <priority>``
Subscribe to the hook identified by the first argument (basically, the
name of event). The ``id`` argument is an arbitrary integer chosen by the
user. ``priority`` is used to sort all hook handlers globally across all
@@ -681,9 +723,9 @@ client messages (``MPV_EVENT_CLIENT_MESSAGE`` in the C API).
typically be stopped.
When the client is done, it must continue the core's hook execution by
running the ``hook_ack`` command.
running the ``hook-ack`` command.
``hook_ack <string>``
``hook-ack <string>``
Run the next hook in the global chain of hooks. The argument is the 3rd
argument of the client message that starts hook execution for the
current client.
@@ -756,7 +798,7 @@ Properties
Properties are used to set mpv options during runtime, or to query arbitrary
information. They can be manipulated with the ``set``/``add``/``cycle``
commands, and retrieved with ``show_text``, or anything else that uses property
commands, and retrieved with ``show-text``, or anything else that uses property
expansion. (See `Property Expansion`_.)
The property name is annotated with RW to indicate whether the property is
@@ -784,6 +826,16 @@ Property list
``speed`` (RW)
See ``--speed``.
``audio-speed-correction``, ``video-speed-correction``
Factor multiplied with ``speed`` at which the player attempts to play the
file. Usually it's exactly 1. (Display sync mode will make this useful.)
OSD formatting will display it in the form of ``+1.23456%``, with the number
being ``(raw - 1) * 100`` for the given raw property value.
``display-sync-active``
Return whether ``--video-sync=display`` is actually active.
``filename``
Currently played file, with path stripped. If this is an URL, try to undo
percent encoding as well. (The result is not necessarily correct, but
@@ -808,7 +860,11 @@ Property list
quantities: fps and possibly rounded timestamps.)
``path``
Full path of the currently played file.
Full path of the currently played file. Usually this is exactly the same
string you pass on the mpv command line or the ``loadfile`` command, even
if it's a relative path. If you expect an absolute path, you will have to
determine it yourself, for example by using the ``working-directory``
property.
``media-title``
If the currently played file has a ``title`` tag, use that.
@@ -836,11 +892,14 @@ Property list
``stream-end``
Raw end position in bytes in source stream.
``length``
Length of the current file in seconds. If the length is unknown, the
``duration``
Duration of the current file in seconds. If the duration is unknown, the
property is unavailable. Note that the file duration is not always exactly
known, so this is an estimate.
This replaces the ``length`` property, which was deprecated after the
mpv 0.9 release. (The semantics are the same.)
``avsync``
Last A/V synchronization difference. Unavailable if audio or video is
disabled.
@@ -858,6 +917,26 @@ Property list
``vo-drop-frame-count``
Frames dropped by VO (when using ``--framedrop=vo``).
``mistimed-frame-count``
Number of video frames that were not timed correctly in display-sync mode
for the sake of keeping A/V sync. This does not include external
circumstances, such as video rendering being too slow or the graphics
driver somehow skipping a vsync. It does not include rounding errors either
(which can happen especially with bad source timestamps). For example,
using the ``display-desync`` mode should never change this value from 0.
``vsync-ratio``
For how many vsyncs a frame is displayed on average. This is available if
display-sync is active only. For 30 FPS video on a 60 Hz screen, this will
be 2. This is the moving average of what actually has been scheduled, so
24 FPS on 60 Hz will never remain exactly on 2.5, but jitter depending on
the last frame displayed.
``vo-delayed-frame-count``
Estimated number of frames delayed due to external circumstances in
display-sync mode. Note that in general, mpv has to guess that this is
happening, and the guess can be inaccurate.
``percent-pos`` (RW)
Position in current file (0-100). The advantage over using this instead of
calculating it out of other properties is that it properly falls back to
@@ -868,18 +947,23 @@ Property list
Position in current file in seconds.
``time-start``
Return the start time of the file. (Usually 0, but some kind of files,
especially transport streams, can have a different start time.)
Deprecated. Always returns 0. Before mpv 0.14, this used to return the start
time of the file (could affect e.g. transport streams). See
``--rebase-start-time`` option.
``time-remaining``
Remaining length of the file in seconds. Note that the file duration is not
always exactly known, so this is an estimate.
``playtime-remaining``
``time-remaining`` scaled by the the current ``speed``.
``time-remaining`` scaled by the current ``speed``.
``playback-time``
Return the playback time, which is the time difference between start PTS and current PTS.
``playback-time`` (RW)
Position in current file in seconds. Unlike ``time-pos``, the time is
clamped to the range of the file. (Inaccurate file durations etc. could
make it go out of range. Also helpful when the user attempts to seek
outside of the file, as the seek target time is considered the current
position during seeking.)
``chapter`` (RW)
Current chapter number. The number of the first chapter is 0.
@@ -922,16 +1006,6 @@ Property list
Current BD/DVD title number. Writing works only for ``dvdnav://`` and
``bd://`` (and aliases for these).
``disc-menu-active``
Return ``yes`` if the BD/DVD menu is active, or ``no`` on normal video
playback. The property is unavailable when playing something that is not
a BD or DVD. Use the ``discnav menu`` command to actually enter or leave
menu mode.
``disc-mouse-on-button``
Return ``yes`` when the mouse cursor is located on a button, or ``no``
when cursor is outside of any button for disc navigation.
``chapters``
Number of chapters.
@@ -1044,6 +1118,9 @@ Property list
An example of these kind of metadata are the cropping parameters
added by ``--vf=lavfi=cropdetect``.
``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``.
@@ -1064,11 +1141,13 @@ Property list
Network cache fill state (0-100.0).
``cache-size`` (RW)
Total network cache size in KB. This is similar to ``--cache``. This allows
Network cache size in KB. This is similar to ``--cache``. This allows
to set the cache size at runtime. Currently, it's not possible to enable
or disable the cache at runtime using this property, just to resize an
existing cache.
This does not include the backbuffer size (changed after mpv 0.10.0).
Note that this tries to keep the cache contents as far as possible. To make
this easier, the cache resizing code will allocate the new cache while the
old cache is still allocated.
@@ -1092,7 +1171,7 @@ Property list
``demuxer-cache-time``
Approximate time of video buffered in the demuxer, in seconds. Same as
``demuxer-cache-duration`` but returns the last timestamp of bufferred
``demuxer-cache-duration`` but returns the last timestamp of buffered
data in demuxer.
``demuxer-cache-idle``
@@ -1119,14 +1198,11 @@ Property list
is loaded, or when switching ordered chapter segments. This is because
the same underlying code is used for seeking and resyncing.)
``pts-association-mode`` (RW)
See ``--pts-association-mode``.
``hr-seek`` (RW)
See ``--hr-seek``.
``volume`` (RW)
Current volume (0-100).
Current volume (see ``--volume`` for details).
``mute`` (RW)
Current mute status (``yes``/``no``).
@@ -1134,18 +1210,52 @@ Property list
``audio-delay`` (RW)
See ``--audio-delay``.
``audio-format``
Audio format as string.
``audio-codec``
Audio codec selected for decoding.
``audio-samplerate``
Audio samplerate.
``audio-codec-name``
Audio codec.
``audio-channels``
Number of audio channels. The OSD value of this property is actually the
channel layout, while the raw value returns the number of channels only.
``audio-params``
Audio format as output by the audio decoder.
This has a number of sub-properties:
``audio-params/format``
The sample format as string. This uses the same names as used in other
places of mpv.
``audio-params/samplerate``
Samplerate.
``audio-params/channels``
The channel layout as a string. This is similar to what the
``--audio-channels`` accepts.
``audio-params/hr-channels``
As ``channels``, but instead of the possibly cryptic actual layout
sent to the audio device, return a hopefully more human readable form.
(Usually only ``audio-out-params/hr-channels`` makes sense.)
``audio-params/channel-count``
Number of audio channels. This is redundant to the ``channels`` field
described above.
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
"format" MPV_FORMAT_STRING
"samplerate" MPV_FORMAT_INT64
"channels" MPV_FORMAT_STRING
"channel-count" MPV_FORMAT_INT64
"hr-channels" MPV_FORMAT_STRING
``audio-out-params``
Same as ``audio-params``, but the format of the data written to the audio
API.
``aid`` (RW)
Current audio track (similar to ``--aid``).
@@ -1156,7 +1266,7 @@ Property list
``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 the left and right channels.)
matrix to mix the left and right channels.)
``fullscreen`` (RW)
See ``--fullscreen``.
@@ -1174,8 +1284,8 @@ Property list
``colormatrix-input-range`` (R)
See ``colormatrix``.
``colormatrix-output-range`` (R)
See ``colormatrix``.
``video-output-levels`` (RW)
See ``--video-output-levels``,
``colormatrix-primaries`` (R)
See ``colormatrix``.
@@ -1208,25 +1318,29 @@ Property list
See ``--hue``.
``hwdec`` (RW)
Return the current hardware decoder that is used. This uses the same values
as the ``--hwdec`` option. If software decoding is active, this returns
``no``. You can write this property. Then the ``--hwdec`` option is set to
the new value, and video decoding will be reinitialized (internally, the
player will perform a seek to refresh the video properly).
Reflects the ``--hwdec`` option.
Note that you don't know the success of the operation immediately after
writing this property. It happens with a delay as video is reinitialized.
Writing to it may change the currently used hardware decoder, if possible.
(Internally, the player may reinitialize the decoder, and will perform a
seek to refresh the video properly.) You can watch the other hwdec
properties to see whether this was successful.
``detected-hwdec``
Return the current hardware decoder that was detected and opened. Returns
the same values as ``hwdec``.
Unlike in mpv 0.9.x and before, this does not return the currently active
hardware decoder.
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 are returned only while hw decoding is active (and
unset afterwards). All this reflects how detecting hw decoders are
detected and used internally in mpv.
``hwdec-active``
Return ``yes`` or ``no``, depending on whether any type of hardware decoding
is actually in use.
``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.
``panscan`` (RW)
See ``--panscan``.
@@ -1290,26 +1404,29 @@ Property list
``video-params/rotate``
Intended display rotation in degrees (clockwise).
``video-params/stereo-in``
Source file stereo 3D mode. (See ``--video-stereo-mode`` option.)
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_ARRAY
MPV_FORMAT_NODE_MAP (for each track)
"pixelformat" MPV_FORMAT_STRING
"w" MPV_FORMAT_INT64
"h" MPV_FORMAT_INT64
"dw" MPV_FORMAT_INT64
"dh" MPV_FORMAT_INT64
"aspect" MPV_FORMAT_DOUBLE
"par" MPV_FORMAT_DOUBLE
"colormatrix" MPV_FORMAT_STRING
"colorlevels" MPV_FORMAT_STRING
"primaries" MPV_FORMAT_STRING
"chroma-location" MPV_FORMAT_STRING
"rotate" MPV_FORMAT_INT64
MPV_FORMAT_NODE_MAP
"pixelformat" MPV_FORMAT_STRING
"w" MPV_FORMAT_INT64
"h" MPV_FORMAT_INT64
"dw" MPV_FORMAT_INT64
"dh" MPV_FORMAT_INT64
"aspect" MPV_FORMAT_DOUBLE
"par" MPV_FORMAT_DOUBLE
"colormatrix" MPV_FORMAT_STRING
"colorlevels" MPV_FORMAT_STRING
"primaries" MPV_FORMAT_STRING
"chroma-location" MPV_FORMAT_STRING
"rotate" MPV_FORMAT_INT64
"stereo-in" MPV_FORMAT_STRING
``dwidth``, ``dheight``
Video display size. This is the video size after filters and aspect scaling
@@ -1328,6 +1445,19 @@ Property list
Has the same sub-properties as ``video-params``.
``video-frame-info``
Approximate information of the current frame. Note that if any of these
are used on OSD, the information might be off by a few frames due to OSD
redrawing and frame display being somewhat disconnected, and you might
have to pause and force a redraw.
Sub-properties:
``video-frame-info/picture-type``
``video-frame-info/interlaced``
``video-frame-info/tff``
``video-frame-info/repeat``
``fps``
Container FPS. This can easily contain bogus values. For videos that use
modern container formats or video codecs, this will often be incorrect.
@@ -1354,13 +1484,21 @@ Property list
Names of the displays that the mpv window covers. On X11, these
are the xrandr names (LVDS1, HDMI1, DP1, VGA1, etc.).
``display-fps``
``display-fps`` (RW)
The refresh rate of the current display. Currently, this is the lowest FPS
of any display covered by the video, as retrieved by the underlying system
APIs (e.g. xrandr on X11). It is not the measured FPS. It's not necessarily
available on all platforms. Note that any of the listed facts may change
any time without a warning.
``estimated-display-fps``
Only available if display-sync mode (as selected by ``--video-sync``) is
active. Returns the actual rate at which display refreshes seem to occur,
measured by system time.
``vsync-jitter``
Estimated deviation factor of the vsync duration.
``video-aspect`` (RW)
Video aspect, see ``--video-aspect``.
@@ -1463,6 +1601,11 @@ Property list
been unloaded yet; in this case, ``current`` refers to the new
selection. (Since mpv 0.7.0.)
``playlist/N/title``
Name of the Nth entry. Only available if the playlist file contains
such fields, and only if mpv's parser supports it for the given
playlist format.
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:
@@ -1474,6 +1617,7 @@ Property list
"filename" MPV_FORMAT_STRING
"current" MPV_FORMAT_FLAG (might be missing; since mpv 0.7.0)
"playing" MPV_FORMAT_FLAG (same)
"title" MPV_FORMAT_STRING (optional)
``track-list``
List of audio/video/sub tracks, current entry marked. Currently, the raw
@@ -1501,6 +1645,10 @@ Property list
``track-list/N/lang``
Track language as identified by the file. Not always available.
``track-list/N/audio-channels``
For audio tracks, the number of audio channels in the audio stream.
Not always accurate (depends on container hints). Not always available.
``track-list/N/albumart``
``yes`` if this is a video track that consists of a single picture,
``no`` or unavailable otherwise. This is used for video tracks that are
@@ -1510,6 +1658,10 @@ Property list
``yes`` if the track has the default flag set in the file, ``no``
otherwise.
``track-list/N/forced``
``yes`` if the track has the forced flag set in the file, ``no``
otherwise.
``track-list/N/codec``
The codec name used by this track, for example ``h264``. Unavailable
in some rare cases.
@@ -1545,8 +1697,10 @@ Property list
"src-id" MPV_FORMAT_INT64
"title" MPV_FORMAT_STRING
"lang" MPV_FORMAT_STRING
"audio-channels" MPV_FORMAT_INT64
"albumart" MPV_FORMAT_FLAG
"default" MPV_FORMAT_FLAG
"forced" MPV_FORMAT_FLAG
"external" MPV_FORMAT_FLAG
"external-filename" MPV_FORMAT_STRING
"codec" MPV_FORMAT_STRING
@@ -1625,7 +1779,7 @@ Property list
``osd-sym-cc``
Inserts the current OSD symbol as opaque OSD control code (cc). This makes
sense only with the ``show_text`` command or options which set OSD messages.
sense only with the ``show-text`` command or options which set OSD messages.
The control code is implementation specific and is useless for anything else.
``osd-ass-cc``
@@ -1633,13 +1787,13 @@ Property list
``${osd-ass-cc/1}`` enables it again. By default, ASS sequences are
escaped to avoid accidental formatting, and this property can disable
this behavior. Note that the properties return an opaque OSD control
code, which only makes sense for the ``show_text`` command or options
code, which only makes sense for the ``show-text`` command or options
which set OSD messages.
.. admonition:: Example
- ``--osd-status-msg='This is ${osd-ass-cc/0}{\\b1}bold text'``
- ``show_text "This is ${osd-ass-cc/0}{\b1}bold text"``
- ``show-text "This is ${osd-ass-cc/0}{\b1}bold text"``
Any ASS override tags as understood by libass can be used.
@@ -1740,6 +1894,12 @@ Property list
Return the working directory of the mpv process. Can be useful for JSON IPC
users, because the command line player usually works with relative paths.
``protocol-list``
List of protocol prefixes potentially recognized by the player. They are
returned without trailing ``://`` suffix (which is still always required).
In some cases, the protocol will not actually be supported (consider
``https`` if ffmpeg is not compiled with TLS support).
``mpv-version``
Return the mpv version/copyright string. Depending on how the binary was
built, it might contain either a release version, or just a git hash.
@@ -1783,6 +1943,12 @@ Property list
``no`` otherwise. What this is set to if the option is e.g. changed
at runtime is left undefined (meaning it could change in the future).
``option-info/<name>/set-locally``
Return ``yes`` if the option was set per-file. This is the case with
automatically loaded profiles, file-dir configs, and other cases. It
means the option value will be restored to the value before playback
start when playback ends.
``option-info/<name>/default-value``
The default value of the option. May not always be available.
@@ -1812,7 +1978,7 @@ command is an exception and not a general rule.)
.. admonition:: Example for input.conf
``i show_text "Filename: ${filename}"``
``i show-text "Filename: ${filename}"``
shows the filename of the current file when pressing the ``i`` key
Within ``input.conf``, property expansion can be inhibited by putting the
+18
View File
@@ -79,6 +79,24 @@ mpv will also send events to clients with JSON messages of the following form:
where ``event_name`` is the name of the event. Additional event-specific fields
can also be present. See `List of events`_ for a list of all supported events.
Because events can occur at any time, it may be difficult at times to determine
which response goes with which command. Commands may optionally include a
``request_id`` which, if provided in the command request, will be copied
verbatim into the response. mpv does not intrepret the ``request_id`` in any
way; it is solely for the use of the requester.
For example, this request:
::
{ "command": ["get_property", "time-pos"], "request_id": 100 }
Would generate this response:
::
{ "error": "success", "data": 1.468135, "request_id": 100 }
All commands, replies, and events are separated from each other with a line
break character (``\n``).
+33 -2
View File
@@ -99,7 +99,7 @@ The ``mp`` module is preloaded, although it can be loaded manually with
functions.
Unlike ``mp.command``, this will not use OSD by default either (except
for some OSd-specific commands).
for some OSD-specific commands).
``mp.command_native(table [,def])``
Similar to ``mp.commandv``, but pass the argument list as table. This has
@@ -519,7 +519,7 @@ Example implementation::
optionC = true,
}
read_options(options, "myscript")
print(option.optionA)
print(options.optionA)
The config file will be stored in ``lua-settings/identifier.conf`` in mpv's user
@@ -630,6 +630,10 @@ strictly part of the guaranteed API.
On Windows, ``killed`` is only returned when the process has been
killed by mpv as a result of ``cancellable`` being set to ``true``.
``killed_by_us``
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.parse_json(str [, trail])``
@@ -690,6 +694,33 @@ List of events
Happens after a file was unloaded. Typically, the player will load the
next file right away, or quit if this was the last file.
The event has the ``reason`` field, which takes one of these values:
``eof``
The file has ended. This can (but doesn't have to) include
incomplete files or broken network connections under
circumstances.
``stop``
Playback was ended by a command.
``quit``
Playback was ended by sending the quit command.
``error``
An error happened. In this case, an ``error`` field is present with
the error string.
``redirect``
Happens with playlists and similar. Details see
``MPV_END_FILE_REASON_REDIRECT`` in the C API.
``unknown``
Unknown. Normally doesn't happen, unless the Lua API is out of sync
with the C API. (Likewise, it could happen that your script gets
reason strings that did not exist yet at the time your script was
written.)
``file-loaded``
Happens after a file was loaded and begins playback.
+109 -78
View File
@@ -116,11 +116,7 @@ o (also P)
Show progression bar, elapsed time and total duration on the OSD.
O
Toggle OSD states: none / seek / seek + timer / seek + timer + total time.
d
Toggle frame dropping states: none / skip display / skip decoding (see
``--framedrop``).
Toggle OSD states between normal and playback time/duration.
v
Toggle subtitle visibility.
@@ -132,7 +128,10 @@ x and z
Adjust subtitle delay by +/- 0.1 seconds.
l
Set/clear A-B loop points. See ``ab_loop`` command for details.
Set/clear A-B loop points. See ``ab-loop`` command for details.
L
Toggle infinite looping.
Ctrl + and Ctrl -
Adjust audio delay by +/- 0.1 seconds.
@@ -156,6 +155,10 @@ S
Take a screenshot, without subtitles. (Whether this works depends on VO
driver support.)
Ctrl s
Take a screenshot, as the window shows it (with subtitles, OSD, and scaled
video).
I
Show filename on the OSD.
@@ -168,7 +171,7 @@ Shift+PGUP and Shift+PGDWN
Seek backward or forward by 10 minutes. (This used to be mapped to
PGUP/PGDWN without Shift.)
D
d
Activate/deactivate deinterlacer.
A
@@ -189,23 +192,19 @@ corresponding adjustment, or the software equalizer (``--vf=eq``).)
7 and 8
Adjust saturation.
(The following keys are valid only on OS X.)
command + 0
Alt+0 (and command+0 on OSX)
Resize video window to half its original size.
(On other platforms, you can bind keys to change the ``window-scale``
property.)
command + 1
Alt+1 (and command+1 on OSX)
Resize video window to its original size.
command + 2
Alt+2 (and command+2 on OSX)
Resize video window to double its original size.
command + f
command + f (OSX only)
Toggle fullscreen (see also ``--fs``).
command + [ and command + ]
command + [ and command + ] (OSX only)
Set video window alpha.
(The following keys are valid if you have a keyboard with multimedia keys.)
@@ -259,7 +258,7 @@ parser puts several options into a single string, and passes them to a
component at once, instead of using multiple options on the level of the
command line.
The suboption parser can quote strings with ``"``, ``'``, and ``[...]``.
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:
@@ -273,7 +272,7 @@ spaces or characters like ``,`` or ``:``, you need to quote them:
``mpv '--vo=opengl:icc-profile="file with spaces.icc",xv'``
Shells may actually strip some quotes from the string passed to the commandline,
so the example quotes the string twice, ensuring that mpv recieves the ``"``
so the example quotes the string twice, ensuring that mpv receives the ``"``
quotes.
The ``[...]`` form of quotes wraps everything between ``[`` and ``]``. It's
@@ -302,7 +301,7 @@ Suboptions passed to the client API are also subject to escaping. Using
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 let's you pass suboptions as a nested data structure
``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.)
@@ -327,7 +326,17 @@ additionally wrapped in the fixed-length syntax, e.g. ``%n%string_of_length_n``
Some mpv options interpret paths starting with ``~``. Currently, the prefix
``~~/`` expands to the mpv configuration directory (usually ``~/.config/mpv/``).
``~/`` expands to the user's home directory. (The trailing ``/`` is always
required.)
required.) There are the following paths as well:
================ ===============================================================
Name Meaning
================ ===============================================================
``~~home/`` same as ``~~/``
``~~global/`` the global config path, if available (not on win32)
``~~osxbundle/`` the OSX bundle resource path (OSX only)
``~~desktop/`` the path to the desktop (win32, OSX)
================ ===============================================================
Per-File Options
----------------
@@ -379,10 +388,11 @@ You can put all of the options in configuration files which will be read every
time mpv is run. The system-wide configuration file 'mpv.conf' is in your
configuration directory (e.g. ``/etc/mpv`` or ``/usr/local/etc/mpv``), the
user-specific one is ``~/.config/mpv/mpv.conf``. For details and platform
specifics see the `FILES`_ section.
specifics (in particular Windows paths) see the `FILES`_ section.
User-specific options override system-wide options and options given on the
command line override either. The syntax of the configuration files is
``option=<value>``; everything after a *#* is considered a comment. Options
``option=value``. Everything after a *#* is considered a comment. Options
that work without values can be enabled by setting them to *yes* and disabled by
setting them to *no*. Even suboptions can be specified in this way.
@@ -400,10 +410,10 @@ Escaping spaces and special characters
This is done like with command line options. The shell is not involved here,
but option values still need to be quoted as a whole if it contains certain
characters like spaces. A config entry can be quoted with ``"`` and ``'``,
characters like spaces. A config entry can be quoted with ``"``,
as well as with the fixed-length syntax (``%n%``) mentioned before. This is like
passing the exact contents of the quoted string as command line option. C-style
escapes are currently _not_ interpreted on this level, although some options to
escapes are currently _not_ interpreted on this level, although some options do
this manually. (This is a mess and should probably be changed at some point.)
Putting Command Line Options into the Configuration File
@@ -447,7 +457,38 @@ description (shown by ``--profile=help``) can be defined with the
``profile-desc`` option. To end the profile, start another one or use the
profile name ``default`` to continue with normal options.
.. admonition:: Example mpv profile
.. admonition:: Example mpv config file with profiles
::
# normal top-level option
fullscreen=yes
# a profile that can be enabled with --profile=big-cache
[big-cache]
cache=123400
demuxer-readahead-secs=20
[slow]
profile-desc="some profile name"
vo=opengl:scale=ewa_lanczos:scale-radius=16
[fast]
vo=vdpau
# using a profile again extends it
[slow]
framedrop=no
# you can also include other profiles
profile=big-cache
Auto profiles
-------------
Some profiles are loaded automatically. The following example demonstrates this:
.. admonition:: Auto profile loading
::
@@ -466,6 +507,13 @@ profile name ``default`` to continue with normal options.
[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``,
``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).
This feature is very limited, and there are no other auto profiles.
TAKING SCREENSHOTS
==================
@@ -513,13 +561,21 @@ listed.
if there is audio "missing", or not enough frames can be dropped. Usually
this will indicate a problem. (``total-avsync-change`` property.)
- Encoding state in ``{...}``, only shown in encoding mode.
- Display sync state. If display sync is active (``display-sync-active``
property), this shows ``DS: 2.500/13``, where the first number is average
number of vsyncs per video frame (e.g. 2.5 when playing 24Hz videos on 60Hz
screens), which might jitter if the ratio doesn't round off, or there are
mistimed frames (``vsync-ratio``), and the second number of estimated number
of vsyncs which took too long (``vo-delayed-frame-count`` property). The
latter is a heuristic, as it's generally not possible to determine this with
certainty.
- Dropped frames, e.g. ``Dropped: 4``. Shows up only if the count is not 0. Can
grow if the video framerate is higher than that of the display, or if video
rendering is too slow. Also can be incremented on "hiccups" and when the video
frame couldn't be displayed on time. (``vo-drop-frame-count`` property.)
If the decoder drops frames, the number of decoder-dropped frames is appended
to the display as well, e.g.: ``Dropped: 4/34``. This happens only if
decoder-framedropping is enabled with the ``--framedrop`` options.
decoder frame dropping is enabled with the ``--framedrop`` options.
(``drop-frame-count`` property.)
- Cache state, e.g. ``Cache: 2s+134KB``. Visible if the stream cache is enabled.
The first value shows the amount of video buffered in the demuxer in seconds,
@@ -550,13 +606,9 @@ PROTOCOLS
you must mount the ISO file as filesystem, and point ``--bluray-device``
to the mounted directory directly.
``bdnav://[title][/device]``
Play a Blu-Ray disc, with navigation features enabled. This feature is
permanently experimental.
``dvd://[title|[starttitle]-endtitle][/device]`` ``--dvd-device=PATH``
Play a DVD. If you want dvdnav menus, use ``dvd://menu``. If no title
is given, the longest title is auto-selected.
Play a DVD. DVD menus are not supported. If no title is given, the longest
title is auto-selected.
``dvdnav://`` is an old alias for ``dvd://`` and does exactly the same
thing.
@@ -601,6 +653,11 @@ PROTOCOLS
``PATH`` itself should start with a third ``/`` to make the path an
absolute path.
``fd://123``
Read data from the given UNIX FD (for example 123). This is similar to
piping data to stdin via ``-``, but can use an arbitrary file descriptor.
Will not work correctly on MS Windows.
``edl://[edl specification as in edl-mpv.rst]``
Stitch together parts of multiple files and play them.
@@ -635,6 +692,7 @@ the ``pseudo-gui`` profile being predefined with the following contents:
terminal=no
force-window=yes
idle=once
screenshot-directory=~~desktop/
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
@@ -665,6 +723,15 @@ 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 to 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).
ENVIRONMENT VARIABLES
=====================
@@ -789,6 +856,8 @@ If errors happen, the following exit codes can be returned:
immediately after initialization.
:3: There were some files that could be played, and some files which
couldn't (using the definition of success from above).
:4: Quit due to a signal, Ctrl+c in a VO window (by default), or from the
default quit key bindings in encoding mode.
Note that quitting the player manually will always lead to exit code 0,
overriding the exit code that would be returned normally. Also, the ``quit``
@@ -860,6 +929,14 @@ Other config files (such as ``input.conf``) are in the same directory. See the
The environment variable ``$MPV_HOME`` completely overrides these, like on
UNIX.
If a directory named ``portable_config`` next to the mpv.exe exists, all
config will be loaded from this directory only. Watch later config files are
written to this directory as well. (This exists on Windows only and is redundant
with ``$MPV_HOME``. However, since Windows is very scripting unfriendly, a
wrapper script just setting ``$MPV_HOME``, like you could do it on other
systems, won't work. ``portable_config`` is provided for convenience to get
around this restriction.)
Config files located in the same directory as ``mpv.exe`` are loaded with
lower priority. Some config files are loaded only once, which means that
e.g. of 2 ``input.conf`` files located in two config directories, only the
@@ -872,49 +949,3 @@ future.
Note that mpv likes to mix ``/`` and ``\`` path separators for simplicity.
kernel32.dll accepts this, but cmd.exe does not.
EXAMPLES OF MPV USAGE
=====================
Blu-ray playback:
- ``mpv bd:////path/to/disc``
- ``mpv bd:// --bluray-device=/path/to/disc``
Play in Japanese with English subtitles:
``mpv dvd://1 --alang=ja --slang=en``
Play only chapters 5, 6, 7:
``mpv dvd://1 --chapter=5-7``
Play only titles 5, 6, 7:
``mpv dvd://5-7``
Play a multi-angle DVD:
``mpv dvd://1 --dvd-angle=2``
Play from a different DVD device:
``mpv dvd://1 --dvd-device=/dev/dvd2``
Play DVD video from a directory with VOB files:
``mpv dvd://1 --dvd-device=/path/to/directory/``
Stream from HTTP:
``mpv http://example.com/example.avi``
Stream using RTSP:
``mpv rtsp://server.example.com/streamName``
Play a libavfilter graph:
``mpv avdevice://lavfi:mandelbrot``
AUTHORS
=======
mpv is a MPlayer fork based on mplayer2, which in turn is a fork of MPlayer.
MPlayer was initially written by Arpad Gereoffy. See the ``AUTHORS`` file for
a list of some of the many other contributors.
MPlayer is (C) 2000-2013 The MPlayer Team
This man page was written mainly by Gabucino, Jonas Jermann and Diego Biurrun.
+385 -215
View File
@@ -69,7 +69,8 @@ Playback Control
The general format for absolute times is ``[[hh:]mm:]ss[.ms]``. If the time
is given with a prefix of ``+`` or ``-``, the seek is relative from the start
or end of the file.
or end of the file. (Since mpv 0.14, the start of the file is always
considered 0.)
``pp%`` seeks to percent position pp (0-100).
@@ -101,6 +102,14 @@ Playback Control
Stop after a given time relative to the start time.
See ``--start`` for valid option values and examples.
``--rebase-start-time=<yes|no>``
Whether to move the file start time to ``00:00:00`` (default: yes). This
is less awkward for files which start at a random timestamp, such as
transport streams. On the other hand, if there are timestamp resets, the
resulting behavior can be rather weird. For this reason, and in case you
are actually interested in the real timestamps, this behavior can be
disabled with ``no``.
``--speed=<0.01-100>``
Slow down or speed up playback by the factor given as parameter.
@@ -129,6 +138,17 @@ Playback Control
Specify which chapter to start playing at. Optionally specify which
chapter to end playing at. Also see ``--start``.
``--playlist-pos=<no|index>``
Set which file on the internal playlist to start playback with. The index
is an integer, with 0 meaning the first file. The value ``no`` means that
the selection of the entry to play is left to the playback resume mechanism
(default). If an entry with the given index doesn't exist, the behavior is
unspecified and might change in future mpv versions. The same applies if
the playlist contains further playlists (don't expect any reasonable
behavior). Passing a playlist file to mpv should work with this option,
though. E.g. ``mpv playlist.m3u --playlist-pos=123`` will work as expected,
as long as ``playlist.m3u`` does not link to further playlists.
``--playlist=<filename>``
Play files according to a playlist file (Supports some common formats. If
no format is detected, it will be treated as list of files, separated by
@@ -348,7 +368,7 @@ Program Behavior
``--idle=<no|yes|once>``
Makes mpv wait idly instead of quitting when there is no file to play.
Mostly useful in slave mode, where mpv can be controlled through input
commands (see also ``--slave-broken``).
commands.
``once`` will only idle at start and let the player close once the
first playlist has finished playing back.
@@ -445,19 +465,16 @@ Program Behavior
If the script can't do anything with an URL, it will do nothing.
(Note: this is the replacement for the now removed libquvi support.)
``--ytdl-format=<best|worst|mp4|webm|...>``
Video format/quality that is directly passed to youtube-dl. The possible
values are specific to the website and the video, for a given url the
available formats can be found with the command
``youtube-dl --list-formats URL``. See youtube-dl's documentation for
available aliases. To use experimental DASH support for youtube, use
``bestvideo+bestaudio``.
(Default: ``best``)
available aliases.
(Default: youtube-dl's default, currently ``bestvideo+bestaudio/best``)
``--ytdl-raw-options=<key>=<value>[,<key>=<value>[,...]]``
Pass arbitraty options to youtube-dl. Parameter and argument should be
Pass arbitrary options to youtube-dl. Parameter and argument should be
passed as a key-value pair. Options without argument must include ``=``.
There is no sanity checking so it's possible to break things (i.e.
@@ -528,7 +545,7 @@ Video
Old, decoder-based framedrop mode. (This is the same as ``--framedrop=yes``
in mpv 0.5.x and before.) This tells the decoder to skip frames (unless
they are needed to decode future frames). May help with slow systems,
but can produce unwatchably choppy output, or even freeze the display
but can produce unwatchable choppy output, or even freeze the display
completely. Not recommended.
The ``--vd-lavc-framedrop`` option controls what frames to drop.
<decoder+vo>
@@ -540,11 +557,10 @@ Video
differences to other VOs are possible.
``--display-fps=<fps>``
Set the maximum assumed display FPS used with ``--framedrop``. By default
a detected value is used (X11 only, not correct on multi-monitor systems),
or infinite display FPS if that fails. Infinite FPS means only frames too
late are dropped. If a correct FPS is provided, frames that are predicted
to be too late are dropped too.
Set the display FPS used with the ``--video-sync=display-*`` modes. By
default a detected value is used (X11 only, not correct on multi-monitor
systems). Keep in mind that setting an incorrect value (even if slightly
incorrect) can ruin video playback.
``--hwdec=<api>``
Specify the hardware video decoding API that should be used if possible.
@@ -556,11 +572,11 @@ Video
:no: always use software decoding (default)
:auto: see below
:vdpau: requires ``--vo=vdpau`` or ``--vo=opengl`` (Linux only)
:vaapi: requires ``--vo=opengl`` or ``--vo=vaapi`` (Linux with Intel GPUs only)
:vaapi: requires ``--vo=opengl`` or ``--vo=vaapi`` (Linux only)
:vaapi-copy: copies video back into system RAM (Linux with Intel GPUs only)
:vda: requires ``--vo=opengl`` (OS X only)
:videotoolbox: requires ``--vo=opengl`` (OS X 10.8 and up only)
:dxva2-copy: copies video back to system RAM (Windows only)
:rpi: requires ``--vo=rpi`` (Raspberry Pi only - default if available)
:rpi: requires ``--vo=rpi`` (Raspberry Pi only - default if available)
``auto`` tries to automatically enable hardware decoding using the first
available method. This still depends what VO you are using. For example,
@@ -569,6 +585,12 @@ Video
work, it will always fall back to software decoding, instead of trying the
next method (might matter on some Linux systems).
The ``vaapi`` mode, if used with ``--vo=opengl``, requires Mesa 11 and most
likely works with Intel GPUs only. It also requires the opengl EGL backend
(automatically used if available). You can also try the old GLX backend by
forcing it with ``--vo=opengl:backend=x11``, but the vaapi/GLX interop is
said to be slower than ``vaapi-copy``.
The ``vaapi-copy`` mode allows you to use vaapi with any VO. Because
this copies the decoded video back to system RAM, it's likely less efficient
than the ``vaapi`` mode.
@@ -579,6 +601,30 @@ Video
codecs. See ``--hwdec-codecs`` to enable hardware decoding for more
codecs.
``--hwdec-preload=<api>``
This is useful for the ``opengl`` and ``opengl-cb`` VOs for creating the
hardware decoding OpenGL interop context, but without actually enabling
hardware decoding itself (like ``--hwdec`` does).
If set to ``no`` (default), the ``--hwdec`` option is used.
For ``opengl``, if set, do not create the interop context on demand, but
when the VO is created.
For ``opengl-cb``, if set, load the interop context as soon as the OpenGL
context is created. Since ``opengl-cb`` has no on-demand loading, this
allows enabling hardware decoding at runtime at all, without having to
to temporarily set the ``hwdec`` option just during OpenGL context
initialization with ``mpv_opengl_cb_init_gl()``.
``--videotoolbox-format=<name>``
Set the internal pixel format used by ``--hwdec=videotoolbox`` on OSX. The
choice of the format can influence performance considerably. On the other
hand, there doesn't appear to be a good way to detect the best format for
the given hardware. ``nv12``, the default, works better on modern hardware,
while ``uyvy422`` appears to be better for old hardware. ``rgb0`` also
works.
``--panscan=<0.0-1.0>``
Enables pan-and-scan functionality (cropping the sides of e.g. a 16:9
video to make it fit a 4:3 display without black bands). The range
@@ -605,6 +651,23 @@ Video
Ignore aspect ratio information from video file and assume the video has
square pixels. See also ``--video-aspect``.
``--video-aspect-method=<hybrid|bitstream|container>``
This sets the default video aspect determination method (if the aspect is
_not_ overridden by the user with ``--video-aspect`` or others).
:hybrid: Prefer the container aspect ratio. If the bitstream aspect
switches mid-stream, switch to preferring the bitstream aspect.
This is the default behavior in mpv and mplayer2.
:container: Strictly prefer the container aspect ratio. This is apparently
the default behavior with VLC, at least with Matroska.
:bitstream: Strictly prefer the bitstream aspect ratio, unless the bitstream
aspect ratio is not set. This is apparently the default behavior
with XBMC/kodi, at least with Matroska.
Normally you should not set this. Try the ``container`` and ``bitstream``
choices if you encounter video that has the wrong aspect ratio in mpv,
but seems to be correct in other players.
``--video-unscaled``
Disable scaling of the video. If the window is larger than the video,
black bars are added. Otherwise, the video is cropped. The video still
@@ -639,17 +702,17 @@ Video
which means the value ``0`` would rotate the video according to the
rotation metadata.)
``--video-stereo-mode=<mode>``
``--video-stereo-mode=<no|mode>``
Set the stereo 3D output mode (default: ``mono``). This is done by inserting
the ``stereo3d`` conversion filter.
The pseudo-mode ``no`` disables automatic conversion completely.
The mode ``mono`` is an alias to ``ml``, which refers to the left frame in
2D. This is the default, which means mpv will try to show 3D movies in 2D,
instead of the mangled 3D image not intended for consumption (such as
showing the left and right frame side by side, etc.).
The pseudo-mode ``none`` disables automatic conversion completely.
Use ``--video-stereo-mode=help`` to list all available modes. Check with
the ``stereo3d`` filter documentation to see what the names mean. Note that
some names refer to modes not supported by ``stereo3d`` - these modes can
@@ -700,7 +763,7 @@ Video
if supported.
This behaves exactly like the ``deinterlace`` input property (usually
mapped to ``Shift+D``).
mapped to ``d``).
``auto`` is a technicality. Strictly speaking, the default for this option
is deinterlacing disabled, but the ``auto`` case is needed if ``yadif`` was
@@ -716,6 +779,10 @@ Video
:top: top field first
:bottom: bottom field first
.. note::
Setting either ``top`` or ``bottom`` will flag all frames as interlaced.
``--frames=<number>``
Play/convert only first ``<number>`` video frames, then quit.
@@ -726,6 +793,26 @@ Video
For audio-only playback, any value greater than 0 will quit playback
immediately after initialization. The value 0 works as with video.
``--video-output-levels=<outputlevels>``
RGB color levels used with YUV to RGB conversion. Normally, output devices
such as PC monitors use full range color levels. However, some TVs and
video monitors expect studio RGB levels. Providing full range output to a
device expecting studio level input results in crushed blacks and whites,
the reverse in dim gray blacks and dim whites.
Not all VOs support this option. Some will silently ignore it.
Available color ranges are:
:auto: automatic selection (equals to full range) (default)
:limited: limited range (16-235 per component), studio levels
:full: full range (0-255 per component), PC levels
.. note::
It is advisable to use your graphics driver's color range option
instead, if available.
``--hwdec-codecs=<codec1,codec2,...|all>``
Allow hardware decoding for a given list of codecs only. The special value
``all`` always allows all codecs.
@@ -733,9 +820,9 @@ Video
You can get the list of allowed codecs with ``mpv --vd=help``. Remove the
prefix, e.g. instead of ``lavc:h264`` use ``h264``.
By default this is set to ``h264,vc1,wmv3``. Note that the hardware
acceleration special codecs like ``h264_vdpau`` are not relevant anymore,
and in fact have been removed from Libav in this form.
By default this is set to ``h264,vc1,wmv3,hevc,mpeg2video``. Note that the
hardware acceleration special codecs like ``h264_vdpau`` are not relevant
anymore, and in fact have been removed from Libav in this form.
This is usually only needed with broken GPUs, where a codec is reported
as supported, but decoding causes more problems than it solves.
@@ -752,6 +839,11 @@ Video
The result is most likely broken decoding, but may also help if the
detected or reported profiles are somehow incorrect.
``--vd-lavc-software-fallback=<yes|no|N>``
Fallback to software decoding if the hardware-accelerated decoder fails
(default: 3). If this is a number, then fallback will be triggered if
N frames fail to decode in a row. 1 is equivalent to ``yes``.
``--vd-lavc-bitexact``
Only use bit-exact algorithms in all decoding steps (for codec testing).
@@ -772,7 +864,7 @@ Video
.. admonition:: Example
``--vd--lavc-o=debug=pict``
``--vd-lavc-o=debug=pict``
``--vd-lavc-show-all=<yes|no>``
Show even broken/corrupt frames (default: no). If this option is set to
@@ -808,10 +900,11 @@ Video
Set framedropping mode used with ``--framedrop`` (see skiploopfilter for
available skip values).
``--vd-lavc-threads=<0-16>``
``--vd-lavc-threads=<N>``
Number of threads to use for decoding. Whether threading is actually
supported depends on codec. 0 means autodetect number of cores on the
machine and use that, up to the maximum of 16 (default: 0).
supported depends on codec (default: 0). 0 means autodetect number of cores
on the machine and use that, up to the maximum of 16. You can set more than
16 threads manually.
@@ -838,10 +931,18 @@ Audio
Note that many AOs have a ``device`` sub-option, which overrides the
device selection of this option (but not the audio output selection).
Likewise, forcing an AO with ``--ao`` will override the audio output
selection of ``--audio-device`` (but not the device selecton).
selection of ``--audio-device`` (but not the device selection).
Currently not implemented for most AOs.
``--audio-fallback-to-null=<yes|no>``
If no audio device can be opened, behave as if ``--ao=null`` was given. This
is useful in combination with ``--audio-device``: instead of causing an
error if the selected device does not exist, the client API user (or a
Lua script) could let playback continue normally, and check the
``current-ao`` and ``audio-device-list`` properties to make high-level
decisions about how to continue.
``--ao=<driver1[:suboption1[=value]:...],driver2,...[,]>``
Specify a priority list of audio output drivers to be used. For
interactive use one would normally specify a single one to use, but in
@@ -855,6 +956,25 @@ Audio
``--af-clr`` exist to modify a previously specified list, but you
should not need these for typical use.
``--audio-spdif=<codecs>``
List of codecs for which compressed audio passthrough should be used. This
works for both classic S/PDIF and HDMI.
Possible codecs are ``ac3``, ``dts``, ``dts-hd``. Multiple codecs can be
specified by separating them with ``,``. ``dts`` refers to low bitrate DTS
core, while ``dts-hd`` refers to DTS MA (receiver and OS support varies).
You should only use either ``dts`` or ``dts-hd`` (if both are specified,
and ``dts`` comes first, only ``dts`` will be used).
In general, all codecs in the ``spdif`` family listed with ``--ad=help``
are supported in theory.
.. admonition:: Warning
There is not much reason to use this. HDMI supports uncompressed
multichannel PCM, and mpv supports lossless DTS-HD decoding via
FFmpeg's libdcadec wrapper.
``--ad=<[+|-]family1:(*|decoder1),[+|-]family2:(*|decoder2),...[-]>``
Specify a priority list of audio decoders to be used, according to their
family and decoder name. Entries like ``family:*`` prioritize all decoders
@@ -882,9 +1002,21 @@ Audio
``--ad=help``
List all available decoders.
``--volume=<-1-100>``
Set the startup volume. A value of -1 (the default) will not change the
volume. See also ``--softvol``.
.. admonition:: Warning
Enabling compressed audio passthrough (AC3 and DTS via SPDIF/HDMI) with
this option is deprecated. Use ``--audio-spdif`` instead.
``--volume=<value>``
Set the startup volume. 0 means silence, 100 means no volume reduction or
amplification. A value of -1 (the default) will not change the volume. See
also ``--softvol``.
.. note::
This was changed after the mpv 0.9 release. Before that, 100 actually
meant maximum volume. At the same time, the volume scale was made cubic,
so the old values won't match up with the new ones anyway.
``--audio-delay=<sec>``
Audio delay in seconds (positive or negative float value). Positive values
@@ -946,17 +1078,12 @@ Audio
welcome. A full list of AVOptions can be found in the FFmpeg manual.
``--ad-spdif-dtshd=<yes|no>``, ``--dtshd``, ``--no-dtshd``
When using DTS pass-through, output any DTS-HD track as-is.
With ``ad-spdif-dtshd=no`` (the default), only the DTS Core parts will be
output.
If DTS is passed through, use DTS-HD.
DTS-HD tracks can be sent over HDMI but not over the original
coax/TOSLINK S/PDIF system.
.. admonition:: Warning
Some receivers don't accept DTS core-only when ``--ad-spdif-dtshd=yes`` is
used, even though they accept DTS-HD.
``--dtshd`` and ``--no-dtshd`` are deprecated aliases.
This and enabling passthrough via ``--ad`` are deprecated in favor of
using ``--audio-spdif=dts-hd``.
``--audio-channels=<number|layout>``
Request a channel layout for audio output (default: auto). This will ask
@@ -985,6 +1112,14 @@ Audio
If the channel layout of the media file (i.e. the decoder) and the AO's
channel layout don't match, mpv will attempt to insert a conversion filter.
.. admonition:: Warning
Using ``auto`` can cause issues when using audio over HDMI. The OS will
typically report all channel layouts that _can_ go over HDMI, even if
the receiver does not support them. If a receiver gets an unsupported
channel layout, random things can happen, such as dropping the
additional channels, or adding noise.
``--audio-display=<no|attachment>``
Setting this option to ``attachment`` (default) will display image
attachments (e.g. album cover art) when playing audio files. It will
@@ -1053,19 +1188,9 @@ Audio
their start timestamps differ, and then video timing is gradually adjusted
if necessary to reach correct synchronization later.
``--softvol-max=<10.0-10000.0>``
Set the maximum amplification level in percent (default: 200). A value of
200 will allow you to adjust the volume up to a maximum of double the
current level. With values below 100 the initial volume (which is 100%)
will be above the maximum, which e.g. the OSD cannot display correctly.
.. admonition:: Note
The maximum value of ``--volume`` as well as the ``volume`` property
is always 100. Likewise, the volume OSD bar always goes from 0 to 100.
This means that with ``--softvol-max=200``, ``--volume=100`` sets
maximum amplification, i.e. amplify by 200%. The default volume (no
change in volume) will be ``50`` in this case.
``--softvol-max=<100.0-1000.0>``
Set the maximum amplification level in percent (default: 130). A value of
130 will allow you to adjust the volume up to about double the normal level.
``--audio-file-auto=<no|exact|fuzzy|all>``, ``--no-audio-file-auto``
Load additional audio files matching the video filename. The parameter
@@ -1140,7 +1265,7 @@ Subtitles
the top of the screen) alongside the normal subtitle, and provides a way
to render two subtitles at once.
there are some caveats associated with this feature. For example, bitmap
There are some caveats associated with this feature. For example, bitmap
subtitles will always be rendered in their usual position, so selecting a
bitmap subtitle as secondary subtitle will result in overlapping subtitles.
Secondary subtitles are never shown on the terminal if video is disabled.
@@ -1209,8 +1334,8 @@ Subtitles
``--sub-speed=<0.1-10.0>``
Multiply the subtitle event timestamps with the given value. Can be used
to fix the playback speed for frame-based subtitle formats. Works for
external text subtitles only.
to fix the playback speed for frame-based subtitle formats. Affects text
subtitles only.
.. admonition:: Example
@@ -1356,6 +1481,18 @@ Subtitles
Disabled by default.
``--stretch-image-subs-to-screen=<yes|no>``
Stretch DVD and other image subtitles to the screen, ignoring the video
margins. This has a similar effect as ``--sub-use-margins`` for text
subtitles, except that the text itself will be stretched, not only just
repositioned. (At least in general it is unavoidable, as an image bitmap
can in theory consist of a single bitmap covering the whole screen, and
the player won't know where exactly the text parts are located.)
This option does not display subtitles correctly. Use with care.
Disabled by default.
``--sub-ass``, ``--no-sub-ass``
Render ASS subtitles natively (enabled by default).
@@ -1385,10 +1522,11 @@ Subtitles
``--sub-codepage=<codepage>``
If your system supports ``iconv(3)``, you can use this option to specify
the subtitle codepage. By default, ENCA will be used to guess the charset.
If mpv is not compiled with ENCA, ``UTF-8:UTF-8-BROKEN`` is the default,
which means it will try to use UTF-8, otherwise the ``UTF-8-BROKEN``
pseudo codepage (see below).
the subtitle codepage. By default, uchardet will be used to guess the
charset. If mpv is not compiled with uchardet, enca will be used.
If mpv is compiled with neither uchardet nor enca, ``UTF-8:UTF-8-BROKEN``
is the default, which means it will try to use UTF-8, otherwise the
``UTF-8-BROKEN`` pseudo codepage (see below).
The default value for this option is ``auto``, whose actual effect depends
on whether ENCA is compiled.
@@ -1438,18 +1576,24 @@ Subtitles
mode. Use ``--sub-codepage=guess:help`` to get a list of
languages subject to the same caveat as with ENCA above.
If the player was compiled with uchardet support you can use it with:
``--sub-codepage=uchardet``
This mode doesn't take language or fallback codepage.
``--sub-fix-timing``, ``--no-sub-fix-timing``
By default, external text subtitles are preprocessed to remove minor gaps
or overlaps between subtitles (if the difference is smaller than 200 ms,
the gap or overlap is removed). This does not affect image subtitles,
subtitles muxed with audio/video, or subtitles in the ASS format.
By default, subtitle timing is adjusted to remove minor gaps or overlaps
between subtitles (if the difference is smaller than 210 ms, the gap or
overlap is removed).
``--sub-forced-only``
Display only forced subtitles for the DVD subtitle stream selected by e.g.
``--slang``.
``--sub-fps=<rate>``
Specify the framerate of the subtitle file (default: video fps).
Specify the framerate of the subtitle file (default: video fps). Affects
text subtitles only.
.. note::
@@ -1590,7 +1734,7 @@ Window
file.mkv normally, then fail to open ``/dev/null``, then exit). (In
mpv 0.8.0, ``always`` was introduced, which restores the old behavior.)
``--force-window``
``--force-window=<yes|no|immediate>``
Create a video output window even if there is no video. This can be useful
when pretending that mpv is a GUI application. Currently, the window
always has the size 640x480, and is subject to ``--geometry``,
@@ -1602,11 +1746,17 @@ Window
window placement still works if the video size is different from the
``--force-window`` default window size). This can be a problem if
initialization doesn't work perfectly, such as when opening URLs with
bad network connection, or opening broken video files.
bad network connection, or opening broken video files. The ``immediate``
mode can be used to create the window always on program start, but this
may cause other issues.
``--ontop``
Makes the player window stay on top of other windows.
On Windows, if combined with fullscreen mode, this causes mpv to be
treated as exclusive fullscreen window that bypasses the Desktop Window
Manager.
``--border``, ``--no-border``
Play video with window border and decorations. Since this is on by
default, use ``--no-border`` to disable the standard window decorations.
@@ -1853,7 +2003,7 @@ Window
``intptr_t``. mpv will create its own window, and set the wid window as
parent, like with X11.
On OSX/Cocoa. the ID is interpreted as ``NSView*``. Pass it as value cast
On OSX/Cocoa, the ID is interpreted as ``NSView*``. Pass it as value cast
to ``intptr_t``. mpv will creates its own sub-view. Because OSX does not
support window embedding of foreign processes, this works only with libmpv,
and will crash when used from the command line.
@@ -1885,6 +2035,10 @@ Window
This option might be removed in the future.
``--x11-bypass-compositor=<yes|no>``
If set to ``yes`` (default), then ask the compositor to unredirect the
mpv window. This uses the ``_NET_WM_BYPASS_COMPOSITOR`` hint.
Disc Devices
------------
@@ -1947,7 +2101,7 @@ Disc Devices
(Never) accept imperfect data reconstruction.
``--cdda-cdtext=<yes|no>``
Print CD text. This is disabled by default, because it ruins perfomance
Print CD text. This is disabled by default, because it ruins performance
with CD-ROM drives for unknown reasons.
``--dvd-speed=<speed>``
@@ -2078,7 +2232,7 @@ Demuxer
seeks only.
You can use the ``--demuxer-mkv-subtitle-preroll-secs`` option to specify
how mach data the demuxer should pre-read at most in order to find subtitle
how much data the demuxer should pre-read at most in order to find subtitle
packets that may overlap. Setting this to 0 will effectively disable this
preroll mechanism. Setting a very large value can make seeking very slow,
and an extremely large value would completely reread the entire file from
@@ -2103,24 +2257,17 @@ Demuxer
``--demuxer-mkv-subtitle-preroll-secs=<value>``
See ``--demuxer-mkv-subtitle-preroll``.
``--demuxer-mkv-probe-video-duration``
``--demuxer-mkv-probe-video-duration=<yes|no|full>``
When opening the file, seek to the end of it, and check what timestamp the
last video packet has, and report that as file duration. This is strictly
for compatibility with Haali only. In this mode, it's possible that opening
will be slower (especially when playing over http), or that behavior with
broken files is much worse. So don't use this option.
``--demuxer-mkv-fix-timestamps=<yes|no>``
Fix rounded Matroska timestamps (enabled by default). Matroska usually
stores timestamps rounded to milliseconds. This means timestamps jitter
by some amount around the intended timestamp. mpv can correct the timestamps
based on the framerate value stored in the file: the timestamp is rounded
to the next frame (according to the framerate), unless the new timestamp
would deviate more than 1ms from the old one. This should undo the rounding
done by the muxer.
(The allowed deviation can be less than 1ms if the file uses a non-standard
timecode scale.)
The ``yes`` mode merely uses the index and reads a small number of blocks
from the end of the file. The ``full`` mode actually traverses the entire
file and can make a reliable estimate even without an index present (such
as partial files).
``--demuxer-rawaudio-channels=<value>``
Number of channels (or channel layout) if ``--demuxer=rawaudio`` is used
@@ -2162,6 +2309,20 @@ Demuxer
``--demuxer-rawvideo-size=<value>``
Frame size in bytes when using ``--demuxer=rawvideo``.
``--demuxer-max-packets=<packets>``, ``--demuxer-max-bytes=<bytes>``
This controls how much the demuxer is allowed to buffer ahead. The demuxer
will normally try to read ahead as much as necessary, or as much is
requested with ``--demuxer-readahead-secs``. The ``--demuxer-max-...``
options can be used to restrict the maximum readahead. This limits excessive
readahead in case of broken files or desynced playback. The demuxer will
stop reading additional packets as soon as one of the limits is reached.
(The limits still can be slightly overstepped due to technical reasons.)
Set these limits highher if you get a packet queue overflow warning, and
you think normal playback would be possible with a larger packet queue.
See ``--list-options`` for defaults and value range.
``--demuxer-thread=<yes|no>``
Run the demuxer in a separate thread, and let it prefetch a certain amount
of packets (default: yes). Having this enabled may lead to smoother
@@ -2180,21 +2341,11 @@ Demuxer
(This value tends to be fuzzy, because many file formats don't store linear
timestamps.)
``--demuxer-readahead-packets=<packets>``
If ``--demuxer-thread`` is enabled, this controls how much the demuxer
should buffer ahead. As long as the number of packets in the packet queue
doesn't exceed ``--demuxer-readahead-packets``, and the total number of
bytes doesn't exceed ``--demuxer-readahead-bytes``, the thread keeps
reading ahead.
Note that if you set these options near the maximum, you might get a
packet queue overflow warning.
See ``--list-options`` for defaults and value range.
``--demuxer-readahead-bytes=<bytes>``
See ``--demuxer-readahead-packets``.
``--force-seekable=<yes|no>``
If the player thinks that the media is not seekable (e.g. playing from a
pipe, or it's a http stream with a server that doesn't support range
requests), seeking will be disabled. This option can forcibly enable it.
For seeks within the cache, there's a good chance of success.
Input
-----
@@ -2251,8 +2402,6 @@ Input
This can also specify a direct file descriptor with ``fd://N`` (UNIX only).
In this case, JSON replies will be written if the FD is writable.
See also ``--slave-broken``.
.. note::
When the given file is a FIFO mpv opens both ends, so you can do several
@@ -2339,14 +2488,14 @@ OSD
``--osd-duration=<time>``
Set the duration of the OSD messages in ms (default: 1000).
``--osd-font=<pattern>``, ``--sub-text-font=<pattern>``
``--osd-font=<name>``, ``--sub-text-font=<name>``
Specify font to use for OSD and for subtitles that do not themselves
specify a particular font. The default is ``sans-serif``.
.. admonition:: Examples
- ``--osd-font='Bitstream Vera Sans'``
- ``--osd-font='Bitstream Vera Sans:style=Bold'`` (fontconfig pattern)
- ``--osd-font='MS Comic Sans'``
.. note::
@@ -2354,6 +2503,9 @@ OSD
options) are ignored when ASS-subtitles are rendered, unless the
``--no-sub-ass`` option is specified.
This used to support fontconfig patterns. Starting with libass 0.13.0,
this stopped working.
``--osd-font-size=<size>``, ``--sub-text-font-size=<size>``
Specify the OSD/sub font size. The unit is the size in scaled pixels at a
window height of 720. The actual pixel size is scaled with the window
@@ -2534,17 +2686,6 @@ OSD
Default: 0.
``--use-text-osd=<yes|no>``
Disable text OSD rendering completely. (This includes the complete OSC as
well.) This is mostly useful for avoiding loading fontconfig in situations
where fontconfig does not behave well, and OSD is unused - this could for
example allow GUI programs using libmpv to workaround fontconfig issues.
Note that selecting subtitles of any kind still initializes fontconfig.
Default: ``no``.
Screenshot
----------
@@ -2566,14 +2707,19 @@ Screenshot
Note that not all formats are supported.
Default: ``yes``.
Default: ``no``.
``--screenshot-high-bit-depth=<yes|no>``
If possible, write screenshots with a bit depth similar to the source
video (default: yes). This is interesting in particular for PNG, as this
sometimes triggers writing 16 bit PNGs with huge file sizes.
``--screenshot-template=<template>``
Specify the filename template used to save screenshots. The template
specifies the filename without file extension, and can contain format
specifiers, which will be substituted when taking a screenshot.
By default the template is ``shot%n``, which results in filenames like
``shot0012.png`` for example.
By default the template is ``mpv-shot%n``, which results in filenames like
``mpv-shot0012.png`` for example.
The template can start with a relative or absolute path, in order to
specify a directory location where screenshots should be saved.
@@ -2616,7 +2762,7 @@ Screenshot
.. note::
This is a simple way for getting unique per-frame timestamps. Frame
This is a simple way for getting unique per-frame timestamps. (Frame
numbers would be more intuitive, but are not easily implementable
because container formats usually use time stamps for identifying
frames.)
@@ -2655,9 +2801,26 @@ Screenshot
``%%``
Replaced with the ``%`` character itself.
``--screenshot-directory=<path>``
Store screenshots in this directory. This path is joined with the filename
generated by ``--screenshot-template``. If the template filename is already
absolute, the directory is ignored.
If the directory does not exist, it is created on the first screenshot. If
it is not a directory, an error is generated when trying to write a
screenshot.
This option is not set by default, and thus will write screenshots to the
directory from which mpv was started. In pseudo-gui mode
(see `PSEUDO GUI MODE`_), this is set to the desktop.
``--screenshot-jpeg-quality=<0-100>``
Set the JPEG quality level. Higher means better quality. The default is 90.
``--screenshot-jpeg-source-chroma=<yes|no>``
Write JPEG files with the same chroma subsampling as the video
(default: yes). If disabled, the libjpeg default is used.
``--screenshot-png-compression=<0-9>``
Set the PNG compression level. Higher means better compression. This will
affect the file size of the written screenshot file and the time it takes
@@ -2988,13 +3151,13 @@ Cache
seeking, such as MP4.
Note that half the cache size will be used to allow fast seeking back. This
is also the reason why a full cache is usually reported as 50% full. The
cache fill display does not include the part of the cache reserved for
seeking back. Likewise, when starting a file the cache will be at 100%,
because no space is reserved for seeking back yet.
is also the reason why a full cache is usually not reported as 100% full.
The cache fill display does not include the part of the cache reserved for
seeking back. The actual maximum percentage will usually be the ratio
between readahead and backbuffer sizes.
``--cache-default=<kBytes|no>``
Set the size of the cache in kilobytes (default: 150000 KB). Using ``no``
Set the size of the cache in kilobytes (default: 75000 KB). Using ``no``
will not automatically enable the cache e.g. when playing from a network
stream. Note that using ``--cache`` will always override this option.
@@ -3014,6 +3177,12 @@ Cache
on the situation, either of these might be slower than the other method.
This option allows control over this.
``--cache-backbuffer=<kBytes>``
Size of the cache back buffer (default: 75000 KB). This will add to the total
cache size, and reserved the amount for seeking back. The reserved amount
will not be used for readahead, and instead preserves already read data to
enable fast seeking back.
``--cache-file=<TMP|path>``
Create a cache file on the filesystem.
@@ -3115,6 +3284,13 @@ Network
Verify peer certificates when using TLS (e.g. with ``https://...``).
(Silently fails with older FFmpeg or Libav versions.)
``--tls-cert-file``
A file containing a certificate to use in the handshake with the
peer.
``--tls-key-file``
A file containing the private key for the certificate.
``--referrer=<string>``
Specify a referrer path or URL for HTTP requests.
@@ -3128,7 +3304,7 @@ Network
network transport when playing ``rtsp://...`` URLs. The value ``lavf``
leaves the decision to libavformat.
``--hls-bitrate=<no|min|max>``
``--hls-bitrate=<no|min|max|<rate>>``
If HLS streams are played, this option controls what streams are selected
by default. The option allows the following parameters:
@@ -3137,6 +3313,9 @@ Network
:min: Pick the streams with the lowest bitrate.
:max: Same, but highest bitrate. (Default.)
Additionally, if the option is a number, the stream with the highest rate
equal or below the option value is selected.
The bitrate as used is sent by the server, and there's no guarantee it's
actually meaningful.
@@ -3174,65 +3353,6 @@ DVB
Default: ``no``
PVR
---
``--pvr-...``
These options tune various encoding properties of the PVR capture module.
It has to be used with any hardware MPEG encoder based card supported by
the V4L2 driver. The Hauppauge WinTV PVR-150/250/350/500 and all IVTV
based cards are known as PVR capture cards. Be aware that only Linux
2.6.18 kernel and above is able to handle MPEG stream through V4L2 layer.
For hardware capture of an MPEG stream and watching it with mpv, use
``pvr://`` as media URL.
``--pvr-aspect=<0-3>``
Specify input aspect ratio:
:0: 1:1
:1: 4:3 (default)
:2: 16:9
:3: 2.21:1
``--pvr-arate=<32000-48000>``
Specify encoding audio rate (default: 48000 Hz, available: 32000,
44100 and 48000 Hz).
``--pvr-alayer=<1-3>``
Specify MPEG audio layer encoding (default: 2).
``--pvr-abitrate=<32-448>``
Specify audio encoding bitrate in kbps (default: 384).
``--pvr-amode=<value>``
Specify audio encoding mode. Available preset values are 'stereo',
'joint_stereo', 'dual' and 'mono' (default: stereo).
``--pvr-vbitrate=<value>``
Specify average video bitrate encoding in Mbps (default: 6).
``--pvr-vmode=<value>``
Specify video encoding mode:
:vbr: Variable Bit Rate (default)
:cbr: Constant Bit Rate
``--pvr-vpeak=<value>``
Specify peak video bitrate encoding in Mbps (only useful for VBR
encoding, default: 9.6).
``--pvr-fmt=<value>``
Choose an MPEG format for encoding:
:ps: MPEG-2 Program Stream (default)
:ts: MPEG-2 Transport Stream
:mpeg1: MPEG-1 System Stream
:vcd: Video CD compatible stream
:svcd: Super Video CD compatible stream
:dvd: DVD compatible stream
Miscellaneous
-------------
@@ -3262,6 +3382,84 @@ Miscellaneous
out. This delay in reaction time to sudden A/V offsets should be the only
side-effect of turning this option on, for all sound drivers.
``--video-sync=<audio|...>``
How the player synchronizes audio and video.
The modes starting with ``display-`` try to output video frames completely
synchronously to the display, using the detected display vertical refresh
rate as a hint how fast frames will be displayed on average. These modes
change video speed slightly to match the display. See ``--video-sync-...``
options for fine tuning. The robustness of this mode is further reduced by
making a some idealized assumptions, which may not always apply in reality.
Behavior can depend on the VO and the system's video and audio drivers.
Media files must use constant framerate. Section-wise VFR might work as well
with some container formats (but not e.g. mkv). If the sync code detects
severe A/V desync, or the framerate cannot be detected, the player
automatically reverts to ``audio`` mode for some time or permanently.
The modes with ``desync`` in their names do not attempt to keep audio/video
in sync. They will slowly (or quickly) desync, until e.g. the next seek
happens. These modes are meant for testing, not serious use.
:audio: Time video frames to audio. This is the most robust
mode, because the player doesn't have to assume anything
about how the display behaves. The disadvantage is that
it can lead to occasional frame drops or repeats. If
audio is disabled, this uses the system clock. This is
the default mode.
:display-resample: Resample audio to match the video. This mode will also
try to adjust audio speed to compensate for other drift.
(This means it will play the audio at a different speed
every once in a while to reduce the A/V difference.)
:display-resample-vdrop: Resample audio to match the video. Drop video
frames to compensate for drift.
:display-resample-desync: Like the previous mode, but no A/V compensation.
:display-vdrop: Drop or repeat video frames to compensate desyncing
video. (Although it should have the same effects as
``audio``, the implementation is very different.)
:display-adrop: Drop or repeat audio data to compensate desyncing
video. See ``--video-sync-adrop-size``. This mode will
cause severe audio artifacts if the real monitor
refresh rate is too different from the reported or
forced rate.
:display-desync: Sync video to display, and let audio play on its own.
:desync: Sync video according to system clock, and let audio play
on its own.
``--video-sync-max-video-change=<value>``
Maximum speed difference in percent that is applied to video with
``--video-sync=display-...`` (default: 1). Display sync mode will be
disabled if the monitor and video refresh way do not match within the
given range. It tries multiples as well: playing 30 fps video on a 60 Hz
screen will duplicate every second frame. Playing 24 fps video on a 60 Hz
screen will play video in a 2-3-2-3-... pattern.
The default settings are not loose enough to speed up 23.976 fps video to
25 fps. We consider the pitch change too extreme to allow this behavior
by default. Set this option to a value of ``5`` to enable it.
Note that in the ``--video-sync=display-resample`` mode, audio speed will
additionally be changed by a small amount if necessary for A/V sync. See
``--video-sync-max-audio-change``.
``--video-sync-max-audio-change=<value>``
Maximum *additional* speed difference in percent that is applied to audio
with ``--video-sync=display-...`` (default: 0.125). Normally, the player
play the audio at the speed of the video. But if the difference between
audio and video position is too high, e.g. due to drift or other timing
errors, it will attempt to speed up or slow down audio by this additional
factor. Too low values could lead to video frame dropping or repeating if
the A/V desync cannot be compensated, too high values could lead to chaotic
frame dropping due to the audio "overshooting" and skipping multiple video
frames before the sync logic can react.
``--video-sync-adrop-size=<value``
For the ``--video-sync=display-adrop`` mode. This mode duplicates/drops
audio data to keep audio in sync with video. To avoid audio artifacts on
jitter (which would add/remove samples all the time), this is done in
relatively large, fixed units, controlled by this option. The unit is
seconds.
``--mf-fps=<value>``
Framerate used when decoding from multiple PNG or JPEG files with ``mf://``
(default: 1).
@@ -3293,6 +3491,10 @@ Miscellaneous
other options such as e.g. user agent are not available with all protocols,
and printing errors for unknown options would end up being too noisy.)
``--vo-mmcss-profile=<name>``
(Windows only.)
Set the MMCSS profile for the video renderer thread (default: ``Playback``).
``--priority=<prio>``
(Windows only.)
Set process priority for mpv according to the predefined priorities
@@ -3303,39 +3505,7 @@ Miscellaneous
.. warning:: Using realtime priority can cause system lockup.
``--pts-association-mode=<decode|sort|auto>``
Select the method used to determine which container packet timestamp
corresponds to a particular output frame from the video decoder. Normally
you should not need to change this option.
:decoder: Use decoder reordering functionality. Unlike in classic MPlayer
and mplayer2, this includes a dTS fallback. (Default.)
:sort: Maintain a buffer of unused pts values and use the lowest value
for the frame.
:auto: Try to pick a working mode from the ones above automatically.
You can also try to use ``--no-correct-pts`` for files with completely
broken timestamps.
``--media-title=<string>``
``--force-media-title=<string>``
Force the contents of the ``media-title`` property to this value. Useful
for scripts which want to set a title, without overriding the user's
setting in ``--title``.
``--slave-broken``
Switches on the old slave mode. This is for testing only, and incompatible
to the removed ``--slave`` switch.
.. attention::
Changes incompatible to slave mode applications have been made. In
particular, the status line output was changed, which is used by some
applications to determine the current playback position. This switch
has been renamed to prevent these applications from working with this
version of mpv, because it would lead to buggy and confusing behavior
only. Moreover, the slave mode protocol is so horribly bad that it
should not be used for new programs, nor should existing programs
attempt to adapt to the changed output and use the ``--slave-broken``
switch. Instead, a new, saner protocol should be developed (and will be,
if there is enough interest).
This affects most third-party GUI frontends.
+9 -1
View File
@@ -5,7 +5,7 @@ The On Screen Controller (short: OSC) is a minimal GUI integrated with mpv to
offer basic mouse-controllability. It is intended to make interaction easier
for new users and to enable precise and direct seeking.
The OSC is enabled by default if mpv was compiled with lua support. It can be
The OSC is enabled by default if mpv was compiled with Lua support. It can be
disabled entirely using the ``--osc=no`` option.
Using the OSC
@@ -235,6 +235,14 @@ Configurable Options
| Default: slider
| Sets the style of the seekbar, slider (diamond marker) or bar (fill)
``timetotal``
| Default: no
| Show total time instead of time remaining
``timems``
| Default: no
| Display timecodes with milliseconds
Script Commands
~~~~~~~~~~~~~~~
+32 -101
View File
@@ -17,6 +17,10 @@ normal filter parameters.
To get a full list of available video filters, see ``--vf=help``.
Also, keep in mind that most actual filters are available via the ``lavfi``
wrapper, which gives you access to most of libavfilter's filters. This
includes all filters that have been ported from MPlayer to libavfilter.
Video filters are managed in lists. There are a few commands to manage the
filter list.
@@ -97,7 +101,7 @@ Available filters are:
All parameters are optional.
``<w>,<h>``
``<w>:<h>``
scaled width/height (default: original width/height)
:0: scaled d_width/d_height
@@ -152,7 +156,7 @@ Available filters are:
number (1.33). Alternatively, you may specify the exact display width and
height desired. Note that this filter does *not* do any scaling itself; it
just affects what later scalers (software or hardware) will do when
auto-scaling to correct aspect.
auto-scaling to the correct aspect.
``<w>,<h>``
New display width and height.
@@ -255,26 +259,6 @@ Available filters are:
:limited: limited range (16-235 for luma, 16-240 for chroma)
:full: full range (0-255 for both luma and chroma)
``<outputlevels>``
RGB color levels used with YUV to RGB conversion. Normally, output devices
such as PC monitors use full range color levels. However, some TVs and
video monitors expect studio RGB levels. Providing full range output to a
device expecting studio level input results in crushed blacks and whites,
the reverse in dim gray blacks and dim whites.
The same limitations as with ``<colormatrix>`` apply.
Available color ranges are:
:auto: automatic selection (equals to full range) (default)
:limited: limited range (16-235 per component), studio levels
:full: full range (0-255 per component), PC levels
.. note::
It is advisable to use your graphics driver's color range option
instead, if available.
``<primaries>``
RGB primaries the source file was encoded with. Normally this should be set
in the file header, but when playing broken or mistagged files this can be
@@ -409,41 +393,6 @@ Available filters are:
``'--vf=lavfi=yadif:o="threads=2,thread_type=slice"'``
forces a specific threading configuration.
``noise[=<strength>[:averaged][:pattern][:temporal][:uniform][:hq]``
Adds noise.
``strength``
Set the noise for all components. If you want different strength
values for luma and chroma, use libavfilter's noise filter directly
(using ``--vf=lavfi=[noise=...]``), or tell the libavfilter developers
to stop being stupid.
``averaged``
averaged temporal noise (smoother, but a lot slower)
``pattern``
mix random noise with a (semi)regular pattern
``temporal``
temporal noise (noise pattern changes between frames)
``uniform``
uniform noise (Gaussian otherwise)
``hqdn3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp]``
This filter aims to reduce image noise producing smooth images and making
still images really still (This should enhance compressibility.).
``<luma_spatial>``
spatial luma strength (default: 4)
``<chroma_spatial>``
spatial chroma strength (default: 3)
``<luma_tmp>``
luma temporal strength (default: 6)
``<chroma_tmp>``
chroma temporal strength (default:
``luma_tmp*chroma_spatial/luma_spatial``)
``eq[=gamma:contrast:brightness:saturation:rg:gg:bg:weight]``
Software equalizer that uses lookup tables (slow), allowing gamma correction
in addition to simple brightness and contrast adjustment. The parameters are
@@ -470,23 +419,6 @@ Available filters are:
and just plain white. A value of 0.0 turns the gamma correction all
the way down while 1.0 leaves it at its full strength (default: 1.0).
``unsharp[=lx:ly:la:cx:cy:ca]``
unsharp mask / Gaussian blur
``l`` is for the luma component, ``c`` for the chroma component. ``x``/``y``
is the filter size. ``a`` is the amount.
``lx``, ``ly``, ``cx``, ``cy``
width and height of the matrix, odd sized in both directions (min =
3:3, max = 13:11 or 11:13, usually something between 3:3 and 7:7)
``la``, ``ca``
Relative amount of sharpness/blur to add to the image (a sane range
should be -1.5-1.5).
:<0: blur
:>0: sharpen
``pullup[=jl:jr:jt:jb:sb:mp]``
Pulldown reversal (inverse telecine) filter, capable of handling mixed
hard-telecine, 24000/1001 fps progressive, and 30000/1001 fps progressive
@@ -518,7 +450,7 @@ Available filters are:
video. The main purpose of setting ``mp`` to a chroma plane is to reduce
CPU load and make pullup usable in realtime on slow machines.
``yadif=[mode[:enabled=yes|no]]``
``yadif=[mode:interlaced-only]``
Yet another deinterlacing filter
``<mode>``
@@ -527,40 +459,24 @@ Available filters are:
:frame-nospatial: Like ``frame`` but skips spatial interlacing check.
:field-nospatial: Like ``field`` but skips spatial interlacing check.
``<enabled>``
:yes: Filter is active (default).
:no: Filter is not active, but can be activated with the ``D`` key
(or any other key that toggles the ``deinterlace`` property).
``<interlaced-only>``
:no: Deinterlace all frames (default).
:yes: Only deinterlace frames marked as interlaced (default if this
filter is inserted via ``deinterlace`` property).
This filter, is automatically inserted when using the ``D`` key (or any
This filter, is automatically inserted when using the ``d`` key (or any
other key that toggles the ``deinterlace`` property or when using the
``--deinterlace`` switch), assuming the video output does not have native
deinterlacing support.
If you just want to set the default mode, put this filter and its options
into ``--vf-defaults`` instead, and enable deinterlacing with ``D`` or
into ``--vf-defaults`` instead, and enable deinterlacing with ``d`` or
``--deinterlace``.
Also note that the ``D`` key is stupid enough to insert an interlacer twice
Also note that the ``d`` key is stupid enough to insert a deinterlacer twice
when inserting yadif with ``--vf``, so using the above methods is
recommended.
``delogo[=x:y:w:h:t:show]``
Suppresses a TV station logo by a simple interpolation of the surrounding
pixels. Just set a rectangle covering the logo and watch it disappear (and
sometimes something even uglier appear - your mileage may vary).
``<x>,<y>``
top left corner of the logo
``<w>,<h>``
width and height of the cleared rectangle
``<t>``
Thickness of the fuzzy edge of the rectangle (added to ``w`` and
``h``). When set to -1, a green rectangle is drawn on the screen to
simplify finding the right ``x``,``y``,``w``,``h`` parameters.
``show``
Draw a rectangle showing the area defined by x/y/w/h.
``sub=[=bottom-margin:top-margin]``
Moves subtitle rendering to an arbitrary point in the filter chain, or force
subtitle rendering in the video filter as opposed to using video output OSD
@@ -669,6 +585,8 @@ Available filters are:
Loads an external library to filter the image. The library interface
is the ``vf_dlopen`` interface specified using ``libmpcodecs/vf_dlopen.h``.
.. warning:: This filter is deprecated.
``dll=<library>``
Specify the library to load. This may require a full file system path
in some cases. This argument is required.
@@ -778,7 +696,7 @@ Available filters are:
``vapoursynth-lazy``
The same as ``vapoursynth``, but doesn't load Python scripts. Instead, a
custom backend using Lua and the raw VapourSynth API is used. The syntax
is completely different, and absolutely no conveniencve features are
is completely different, and absolutely no convenience features are
provided. There's no type checking either, and you can trigger crashes.
.. admonition:: Example:
@@ -803,7 +721,7 @@ Available filters are:
``vavpp``
VA-AP-API video post processing. Works with ``--vo=vaapi`` and ``--vo=opengl``
only. Currently deinterlaces. This filter is automatically inserted if
deinterlacing is requested (either using the ``D`` key, by default mapped to
deinterlacing is requested (either using the ``d`` key, by default mapped to
the command ``cycle deinterlace``, or the ``--deinterlace`` option).
``deint=<method>``
@@ -820,10 +738,14 @@ Available filters are:
depends on the GPU hardware, the GPU drivers, driver bugs, and
mpv bugs.
``<interlaced-only>``
:no: Deinterlace all frames.
:yes: Only deinterlace frames marked as interlaced (default).
``vdpaupp``
VDPAU video post processing. Works with ``--vo=vdpau`` and ``--vo=opengl``
only. This filter is automatically inserted if deinterlacing is requested
(either using the ``D`` key, by default mapped to the command
(either using the ``d`` key, by default mapped to the command
``cycle deinterlace``, or the ``--deinterlace`` option). When enabling
deinterlacing, it is always preferred over software deinterlacer filters
if the ``vdpau`` VO is used, and also if ``opengl`` is used and hardware
@@ -864,12 +786,21 @@ Available filters are:
``pullup``
Try to apply inverse telecine, needs motion adaptive temporal
deinterlacing.
``interlaced-only=<yes|no>``
If ``yes`` (default), only deinterlace frames marked as interlaced.
``hqscaling=<0-9>``
0
Use default VDPAU scaling (default).
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.
``buffer=<num>``
Buffer ``<num>`` frames in the filter chain. This filter is probably pretty
useless, except for debugging. (Note that this won't help smoothing out
+315 -81
View File
@@ -20,13 +20,10 @@ normal driver parameters.
See ``--vo=help`` for a list of compiled-in video output drivers.
The recommended output drivers are ``--vo=vdpau`` and ``--vo=opengl-hq``.
All other drivers are just for compatibility or special purposes.
.. admonition:: Example
``--vo=opengl,xv,``
Try the ``opengl`` driver, then the ``xv`` driver, then others.
The recommended output driver is ``--vo=opengl-hq``. All other drivers are
for compatibility or special purposes. By default, ``--vo=opengl`` is used,
but if that appears not to work, it fallback to other drivers (in the same
order as listed by ``--vo=help``).
Available video output drivers are:
@@ -69,6 +66,12 @@ Available video output drivers are:
``no-colorkey``
Disables color-keying.
``buffers=<number>``
Number of image buffers to use for the internal ringbuffer (default: 2).
Increasing this will use more memory, but might help with the X server
not responding quickly enough if video FPS is close to or higher than
the display refresh rate.
``x11`` (X11 only)
Shared memory video output driver without hardware acceleration that works
whenever X11 is present.
@@ -102,7 +105,7 @@ Available video output drivers are:
Select deinterlacing mode (default: 0). In older versions (as well as
MPlayer/mplayer2) you could use this option to enable deinterlacing.
This doesn't work anymore, and deinterlacing is enabled with either
the ``D`` key (by default mapped to the command ``cycle deinterlace``),
the ``d`` key (by default mapped to the command ``cycle deinterlace``),
or the ``--deinterlace`` option. Also, to select the default deint mode,
you should use something like ``--vf-defaults=vdpaupp:deint-mode=temporal``
instead of this sub-option.
@@ -290,6 +293,29 @@ Available video output drivers are:
color space conversion and chroma upsampling is generally in the hand of
the hardware decoder APIs.
``opengl`` makes use of FBOs by default. Sometimes you can achieve better
quality or performance by changing the ``fbo-format`` suboption to
``rgb16f``, ``rgb32f`` or ``rgb``. Known problems include Mesa/Intel not
accepting ``rgb16``, Mesa sometimes not being compiled with float texture
support, and some OS X setups being very slow with ``rgb16`` but fast
with ``rgb32f``. If you have problems, you can also try passing the
``dumb-mode=yes`` sub-option.
``dumb-mode=<yes|no>``
This mode is extremely restricted, and will disable most extended
OpenGL features. This includes high quality scalers and custom
shaders!
It is intended for hardware that does not support FBOs (including GLES,
which supports it insufficiently), or to get some more performance out
of bad or old hardware.
This mode is forced automatically if needed, and this option is mostly
useful for debugging. It's also enabled automatically if nothing uses
features which require FBOs.
This option might be silently removed in the future.
``scale=<filter>``
``bilinear``
@@ -336,6 +362,9 @@ Available video output drivers are:
exchange for adding some blur. This filter is good at temporal
interpolation, and also known as "smoothmotion" (see ``tscale``).
``custom``
A user-defined custom shader (see ``scale-shader``).
There are some more filters, but most are not as useful. For a complete
list, pass ``help`` as value, e.g.::
@@ -352,10 +381,6 @@ Available video output drivers are:
Scale parameter (``t``). Increasing this makes the result blurrier.
Defaults to 1.
sharpen3, sharpen5
Sharpening strength. Increasing this makes the image sharper but
adds more ringing and aliasing. Defaults to 0.5.
oversample
Minimum distance to an edge before interpolation is used. Setting
this to 0 will always interpolate edges, whereas setting it to 0.5
@@ -385,8 +410,8 @@ Available video output drivers are:
between 0.0 and 1.0. The default value of 0.0 disables antiringing
entirely.
Note that this doesn't affect the special filters ``bilinear``,
``bicubic_fast`` or ``sharpen``.
Note that this doesn't affect the special filters ``bilinear`` and
``bicubic_fast``.
``scale-window=<window>``
(Advanced users only) Choose a custom windowing function for the kernel.
@@ -406,6 +431,15 @@ Available video output drivers are:
Scale parameter (t). Increasing this makes the window wider.
Defaults to 1.
``scaler-lut-size=<4..10>``
Set the size of the lookup texture for scaler kernels (default: 6).
The actual size of the texture is ``2^N`` for an option value of ``N``.
So the lookup texture with the default setting uses 64 samples.
All weights are bilinearly interpolated from those samples, so
increasing the size of lookup table might improve the accuracy of
scaler.
``scaler-resizes-only``
Disable the scaler if the video image is not resized. In that case,
``bilinear`` is used instead whatever is set with ``scale``. Bilinear
@@ -452,6 +486,11 @@ Available video output drivers are:
Unfortunately, this can lead to flicker on LCD displays, since these
have a high reaction time.
``temporal-dither-period=<1-128>``
Determines how often the dithering pattern is updated when
``temporal-dither`` is in use. 1 (the default) will update on every
video frame, 2 on every other frame, etc.
``debug``
Check for OpenGL errors, i.e. call ``glGetError()``. Also request a
debug OpenGL context (which does nothing with current graphics drivers
@@ -461,6 +500,10 @@ Available video output drivers are:
Reduce stuttering caused by mismatches in the video fps and display
refresh rate (also known as judder).
.. warning:: This requires setting the ``--video-sync`` option to one
of the ``display-`` modes, or it will be silently disabled.
This was not required before mpv 0.14.0.
This essentially attempts to interpolate the missing frames by
convoluting the video along the temporal axis. The filter used can be
controlled using the ``tscale`` setting.
@@ -492,12 +535,17 @@ Available video output drivers are:
The filter used for interpolating the temporal axis (frames). This is
only used if ``interpolation`` is enabled. The only valid choices
for ``tscale`` are separable convolution filters (use ``tscale=help``
to get a list). The default is ``oversample``.
to get a list). The default is ``mitchell``.
Note that the maximum supported filter radius is currently 3, and that
using filters with larger radius may introduce issues when pausing or
framestepping, proportional to the radius used. It is recommended to
stick to a radius of 1 or 2.
Note that the maximum supported filter radius is currently 3, due to
limitations in the number of video textures that can be loaded
simultaneously.
``tscale-clamp``
Clamp the ``tscale`` filter kernel's value range to [0-1]. This reduces
excessive ringing artifacts in the temporal domain (which typically
manifest themselves as short flashes or fringes of black, mostly
around moving edges) in exchange for potentially adding more blur.
``dscale-radius``, ``cscale-radius``, ``tscale-radius``, etc.
Set filter parameters for ``dscale``, ``cscale`` and ``tscale``,
@@ -506,22 +554,172 @@ Available video output drivers are:
See the corresponding options for ``scale``.
``linear-scaling``
Scale in linear light. This is automatically enabled if
``target-prim``, ``target-trc``, ``icc-profile`` or
``sigmoid-upscaling`` is set. It should only be used with a
``fbo-format`` that has at least 16 bit precision.
Scale in linear light. It should only be used with a ``fbo-format``
that has at least 16 bit precision.
``fancy-downscaling``
``correct-downscaling``
When using convolution based filters, extend the filter size
when downscaling. Trades quality for reduced downscaling performance.
when downscaling. Increases quality, but reduces performance while
downscaling.
This is automatically disabled for anamorphic video, because this
feature doesn't work correctly with different scale factors in
different directions.
This will perform slightly sub-optimally for anamorphic video (but still
better than without it) since it will extend the size to match only the
milder of the scale factors between the axes.
``prescale=<filter>``
This option provides non-convolution-based filters for upscaling. These
filters resize the video to multiple of the original size (all currently
supported prescalers can only perform image doubling in a single pass).
Generally another convolution based filter (the main scaler) will be
applied after prescaler to match the target display size.
``none``
Disable all prescalers. This is the default.
``superxbr``
A relatively fast prescaler originally developed for pixel art.
Some parameters can be tuned with ``superxbr-sharpness`` and
``superxbr-edge-strength`` options.
``nnedi3``
An artificial neural network based deinterlacer, which can be used
to upscale images.
Extremely slow and requires a recent mid or high end graphics card
to work smoothly (as of 2015).
Note that all the filters above are designed (or implemented) to process
luma plane only and probably won't work as intended for video in RGB
format.
``prescale-passes=<1..5>``
The number of passes to apply the prescaler (defaults to be 1). Setting
it to 2 will perform a 4x upscaling.
``prescale-downscaling-threshold=<0..32>``
This option prevents "overkill" use of prescalers, which can be caused
by misconfiguration, or user trying to play a video with much larger
size. With this option, user can specify the maximal allowed downscaling
ratio in both dimension. To satisfy it, the number of passes for
prescaler will be reduced, and if necessary prescaler could also be
disabled.
The default value is 2.0, and should be able to prevent most seemingly
unreasonable use of prescalers. Most user would probably want to set it
to a smaller value between 1.0 and 1.5 for better performance.
A value less than 1.0 will disable the check.
``nnedi3-neurons=<16|32|64|128>``
Specify the neurons for nnedi3 prescaling (defaults to be 32). The
rendering time is expected to be linear to the number of neurons.
``nnedi3-window=<8x4|8x6>``
Specify the size of local window for sampling in nnedi3 prescaling
(defaults to be ``8x4``). The ``8x6`` window produces sharper images,
but is also slower.
``nnedi3-upload=<ubo|shader>``
Specify how to upload the NN weights to GPU. Depending on the graphics
card, driver, shader compiler and nnedi3 settings, both method can be
faster or slower.
``ubo``
Upload these weights via uniform buffer objects. This is the
default. (requires OpenGL 3.1 / GLES 3.0)
``shader``
Hard code all the weights into the shader source code. (requires
OpenGL 3.3 / GLES 3.0)
``pre-shaders=<files>``, ``post-shaders=<files>``, ``scale-shader=<file>``
Custom GLSL fragment shaders.
pre-shaders (list)
These get applied after conversion to RGB and before linearization
and upscaling. Operates on non-linear RGB (same as input). This is
the best place to put things like sharpen filters.
scale-shader
This gets used instead of scale/cscale when those options are set
to ``custom``. The colorspace it operates on depends on the values
of ``linear-scaling`` and ``sigmoid-upscaling``, so no assumptions
should be made here.
post-shaders (list)
These get applied after upscaling and subtitle blending (when
``blend-subtitles`` is enabled), but before color management.
Operates on linear RGB if ``linear-scaling`` is in effect,
otherwise non-linear RGB. This is the best place for colorspace
transformations (eg. saturation mapping).
These files must define a function with the following signature::
vec4 sample(sampler2D tex, vec2 pos, vec2 tex_size)
The meanings of the parameters are as follows:
sampler2D tex
The source texture for the shader.
vec2 pos
The position to be sampled, in coordinate space [0-1].
vec2 tex_size
The size of the texture, in pixels. This may differ from image_size,
eg. for subsampled content or for post-shaders.
In addition to these parameters, the following uniforms are also
globally available:
float random
A random number in the range [0-1], different per frame.
int frame
A simple count of frames rendered, increases by one per frame and
never resets (regardless of seeks).
vec2 image_size
The size in pixels of the input image.
For example, a shader that inverts the colors could look like this::
vec4 sample(sampler2D tex, vec2 pos, vec2 tex_size)
{
vec4 color = texture(tex, pos);
return vec4(1.0 - color.rgb, color.a);
}
``deband``
Enable the debanding algorithm. This greatly reduces the amount of
visible banding, blocking and other quantization artifacts, at the
expensive of very slightly blurring some of the finest details. In
practice, it's virtually always an improvement - the only reason to
disable it would be for performance.
``deband-iterations=<1..16>``
The number of debanding steps to perform per sample. Each step reduces
a bit more banding, but takes time to compute. Note that the strength
of each step falls off very quickly, so high numbers (>4) are
practically useless. (Default 1)
``deband-threshold=<0..4096>``
The debanding filter's cut-off threshold. Higher numbers increase the
debanding strength dramatically but progressively diminish image
details. (Default 64)
``deband-range=<1..64>``
The debanding filter's initial radius. The radius increases linearly
for each iteration. A higher radius will find more gradients, but
a lower radius will smooth more aggressively. (Default 16)
If you increase the ``deband-iterations``, you should probably
decrease this to compensate.
``deband-grain=<0..4096>``
Add some extra noise to the image. This significantly helps cover up
remaining quantization artifacts. Higher numbers add more noise.
(Default 48)
``sigmoid-upscaling``
When upscaling, use a sigmoidal color transform to avoid emphasizing
ringing artifacts. This also enables ``linear-scaling``.
ringing artifacts. This also implies ``linear-scaling``.
``sigmoid-center``
The center of the sigmoid curve used for ``sigmoid-upscaling``, must
@@ -531,9 +729,15 @@ Available video output drivers are:
The slope of the sigmoid curve used for ``sigmoid-upscaling``, must
be a float between 1.0 and 20.0. Defaults to 6.5 if not specified.
``no-npot``
Force use of power-of-2 texture sizes. For debugging only.
Borders will be distorted due to filtering.
``sharpen=<value>``
If set to a value other than 0, enable an unsharp masking filter.
Positive values will sharpen the image (but add more ringing and
aliasing). Negative values will blur the image. If your GPU is powerful
enough, consider alternatives like the ``ewa_lanczossharp`` scale
filter, or the ``scale-blur`` sub-option.
(This feature is the replacement for the old ``sharpen3`` and
``sharpen5`` scalers.)
``glfinish``
Call ``glFinish()`` before and after swapping buffers (default: disabled).
@@ -548,14 +752,28 @@ Available video output drivers are:
X11/GLX only.
``dwmflush=<no|windowed|yes>``
Calls ``DwmFlush`` after swapping buffers on Windows (default: no).
``vsync-fences=<N>``
Synchronize the CPU to the Nth past frame using the ``GL_ARB_sync``
extension. A value of 0 disables this behavior (default). A value of
1 means it will synchronize to the current frame after rendering it.
Like ``glfinish`` and ``waitvsync``, this can lower or ruin performance.
Its advantage is that it can span multiple frames, and effectively limit
the number of frames the GPU queues ahead (which also has an influence
on vsync).
``dwmflush=<no|windowed|yes|auto>``
Calls ``DwmFlush`` after swapping buffers on Windows (default: auto).
It also sets ``SwapInterval(0)`` to ignore the OpenGL timing. Values
are: no (disabled), windowed (only in windowed mode), yes (also in
full screen).
The value ``auto`` will try to determine whether the compositor is
active, and calls ``DwmFlush`` only if it seems to be.
This may help getting more consistent frame intervals, especially with
high-fps clips - which might also reduce dropped frames. Typically a
value of 1 should be enough since full screen may bypass the DWM.
value of ``windowed`` should be enough since full screen may bypass the
DWM.
Windows only.
@@ -573,20 +791,39 @@ Available video output drivers are:
Cocoa/OS X
win
Win32/WGL
x11, x11es
X11/GLX (the ``es`` variant forces GLES)
angle
Direct3D11 through the OpenGL ES translation layer ANGLE. This
supports almost everything the ``win`` backend does, except ICC
profiles, high bit depth video input, and the ``nnedi3`` prescaler.
dxinterop (experimental)
Win32, using WGL for rendering and Direct3D 9Ex for presentation.
Works on Nvidia and AMD only.
x11
X11/GLX
wayland
Wayland/EGL
x11egl, x11egles
X11/EGL (the ``es`` variant forces GLES)
drm-egl
DRM/EGL
x11egl
X11/EGL
``es=<mode>``
Select whether to use GLES:
yes
Try to prefer ES over Desktop GL
no
Try to prefer desktop GL over ES
auto
Use the default for each backend (default)
``fbo-format=<fmt>``
Selects the internal format of textures used for FBOs. The format can
influence performance and quality of the video output. (FBOs are not
always used, and typically only when using extended scalers.)
influence performance and quality of the video output.
``fmt`` can be one of: rgb, rgba, rgb8, rgb10, rgb10_a2, rgb16, rgb16f,
rgb32f, rgba12, rgba16, rgba16f, rgba32f.
Default: rgba16.
Default: ``auto``, which maps to rgba16 on desktop GL, and rgb10_a2 on
GLES (e.g. ANGLE).
``gamma=<0.1..2.0>``
Set a gamma value (default: 1.0). If gamma is adjusted in other ways
@@ -660,20 +897,23 @@ Available video output drivers are:
``icc-profile=<file>``
Load an ICC profile and use it to transform linear RGB to screen output.
Needs LittleCMS 2 support compiled in. This option overrides the
``target-prim`` and ``target-trc`` options. It also enables
``linear-scaling``.
``target-prim``, ``target-trc`` and ``icc-profile-auto`` options.
``icc-profile-auto``
Automatically select the ICC display profile currently specified by
the display settings of the operating system.
NOTE: Only implemented on OS X and X11
NOTE: On Windows, the default profile must be an ICC profile. WCS
profiles are not supported.
``icc-cache=<file>``
Store and load the 3D LUT created from the ICC profile in this file.
``icc-cache-dir=<dirname>``
Store and load the 3D LUTs created from the ICC profile in this directory.
This can be used to speed up loading, since LittleCMS 2 can take a while
to create the 3D LUT. Note that this file contains an uncompressed LUT.
Its size depends on the ``3dlut-size``, and can be very big.
to create a 3D LUT. Note that these files contain uncompressed LUTs.
Their size depends on the ``3dlut-size``, and can be very big.
NOTE: This is not cleaned automatically, so old, unused cache files
may stick around indefinitely.
``icc-intent=<value>``
Specifies the ICC intent used for the color transformation (when using
@@ -697,8 +937,8 @@ Available video output drivers are:
Blend subtitles directly onto upscaled video frames, before
interpolation and/or color management (default: no). Enabling this
causes subtitles to be affected by ``icc-profile``, ``target-prim``,
``target-trc``, ``interpolation``, ``gamma`` and ``linear-scaling``.
It also increases subtitle performance when using ``interpolation``.
``target-trc``, ``interpolation``, ``gamma`` and ``post-shader``. It
also increases subtitle performance when using ``interpolation``.
The downside of enabling this is that it restricts subtitles to the
visible portion of the video, so you can't have subtitles exist in the
@@ -744,18 +984,11 @@ Available video output drivers are:
This is equivalent to::
--vo=opengl:scale=spline36:cscale=spline36:dscale=mitchell:dither-depth=auto:fancy-downscaling:sigmoid-upscaling
--vo=opengl:scale=spline36:cscale=spline36:dscale=mitchell:dither-depth=auto:correct-downscaling:sigmoid-upscaling:pbo:deband:es=no
Note that some cheaper LCDs do dithering that gravely interferes with
``opengl``'s dithering. Disabling dithering with ``dither-depth=no`` helps.
Unlike ``opengl``, ``opengl-hq`` makes use of FBOs by default. Sometimes you
can achieve better quality or performance by changing the ``fbo-format``
suboption to ``rgb16f``, ``rgb32f`` or ``rgb``. Known problems include
Mesa/Intel not accepting ``rgb16``, Mesa sometimes not being compiled with
float texture support, and some OS X setups being very slow with ``rgb16``
but fast with ``rgb32f``.
``sdl``
SDL 2.0+ Render video output driver, depending on system with or without
hardware acceleration. Should work on all platforms supported by SDL 2.0.
@@ -791,7 +1024,7 @@ Available video output drivers are:
``deint-mode=<mode>``
Select deinterlacing algorithm. Note that by default deinterlacing is
initially always off, and needs to be enabled with the ``D`` key
initially always off, and needs to be enabled with the ``d`` key
(default key binding for ``cycle deinterlace``).
This option doesn't apply if libva supports video post processing (vpp).
@@ -816,6 +1049,12 @@ Available video output drivers are:
``null``
Produces no video output. Useful for benchmarking.
Usually, it's better to disable video with ``--no-video`` instead.
``fps=<value>``
Simulate display FPS. This artificially limits how many frames the
VO accepts per second.
``caca``
Color ASCII art video output driver that works on a text console.
@@ -883,25 +1122,6 @@ Available video output drivers are:
``opengl-cb``
For use with libmpv direct OpenGL embedding; useless in any other contexts.
(See ``<mpv/opengl_cb.h>``.)
Usually, ``opengl-cb`` renders frames asynchronously by client and this
can cause some frame drops. In order to provide a way to handle this
situation, ``opengl-cb`` has its own frame queue and calls update callback
more frequently if the queue is not empty regardless of existence of new frame.
Once the queue is filled, ``opengl-cb`` drops frames automatically.
With default options, ``opengl-cb`` renders only the latest frame and drops
all frames handed over while waiting render function after update callback.
``frame-queue-size=<1..100>``
The maximum count of frames which the frame queue can hold (default: 1)
``frame-drop-mode=<pop|clear>``
Select the behavior when the frame queue is full.
pop
Drop the oldest frame in the frame queue. (default)
clear
Drop all frames in the frame queue.
This also supports many of the suboptions the ``opengl`` VO has. Run
``mpv --vo=opengl-cb:help`` for a list.
@@ -921,10 +1141,20 @@ Available video output drivers are:
selected layer, to handle the window background and OSD. Actual video
rendering will happen on the layer above the selected layer.
``background=<yes|no>``
Whether to render a black background behind the video (default: no).
Normally it's better to kill the console framebuffer instead, which
gives better performance.
``osd=<yes|no>``
Enabled by default. If disabled with ``no``, no OSD layer is created.
This also means there will be no subtitles rendered.
``drm`` (Direct Rendering Manager)
Video output driver using Kernel Mode Setting / Direct Rendering Manager.
Does not support hardware acceleration. Should be used when one doesn't
want to install full-blown graphical environment (e.g. no X).
Should be used when one doesn't want to install full-blown graphical
environment (e.g. no X). Does not support hardware acceleration (if you
need this, check the ``drm-egl`` backend for ``opengl`` VO).
``connector=<number>``
Select the connector to use (usually this is a monitor.) If set to -1,
@@ -933,3 +1163,7 @@ Available video output drivers are:
``devpath=<filename>``
Path to graphic card device.
(default: /dev/dri/card0)
``mode=<number>``
Mode ID to use (resolution, bit depth and frame rate).
(default: 0)
+6 -2
View File
@@ -52,6 +52,7 @@ Input
Also see: http://github.com/mpv-player/mpv/wiki/IR-remotes
* Joystick support was removed. It was considered useless and was the cause
of some problems (e.g. a laptop's accelerator being recognized as joystick).
* Support for relative seeking by percentage.
Audio
~~~~~
@@ -93,6 +94,8 @@ Video
* Image subtitles (DVDs etc.) are rendered in color and use more correct
positioning (color for image subs can be disabled with ``--sub-gray``).
* Support for the X11 video output is removed, since it was considered
deprecated. SDL video output can still be used as a fallback.
OSD and terminal
~~~~~~~~~~~~~~~~
@@ -276,7 +279,7 @@ Command Line Switches
``-xineramascreen`` ``--screen`` (different values)
``-xy W`` ``--autofit=W``
``-zoom`` Inverse available as ``--video-unscaled``
``dvdnav://`` ``dvdnav://menu``
``dvdnav://`` Removed.
``dvd://1`` ``dvd://0`` (0-based offset)
=========================== ========================================
@@ -396,7 +399,8 @@ Slave mode
Assuming the system supports ``/dev/stdin``.
(The option was readded in 0.5.1 and sets exactly these options.)
(The option was added back in 0.5.1 and sets exactly these options. It was
removed in 0.10.x again.)
* A JSON RPC protocol giving access to the client API is also supported. See
`JSON IPC`_ for more information.
+69 -27
View File
@@ -1,64 +1,106 @@
Release Policy
==============
Every few months, a new release is cut off of the master branch and is assigned
a 0.X.0 version number.
Once or twice a month, a new release is cut off of the master branch and is
assigned a 0.X.Y version number, where X is incremented each time a release
contains breaking changes, such as changed options or added/removed features,
and Y is incremented if a release contains only bugfixes and other minor
changes.
As part of the maintenance process, minor releases are made, which are assigned
0.X.Y version numbers. Minor releases contain bug fixes only. They never merge
the master branch, and no features are added to it. Only the latest release is
maintained.
There is only one release branch that keeps track of the latest version and
will not be maintained separately.
The goal of releases is to provide stability and an unchanged base for the sake
of Linux distributions. If you want the newest features, just use the master
branch, which is stable most of the time, except sometimes, when it's not.
The goal of releases is to provide Linux distributions with something to
package. If you want the newest features, just use the master branch.
We try our best to keep it deployable at all times.
Releases other than the latest release are unsupported and unmaintained.
Release procedure
-----------------
- Create branch release/0.X or cherry-pick commits to the relevant branch.
- Merge master into branch release/current.
- Create and/or update the ``RELEASE_NOTES`` file.
- Create and/or update the `RELEASE_NOTES` file.
- Create and/or update the ``VERSION`` file.
- Create and/or update the `VERSION` file.
- Update ``DOCS/client-api-changes.rst`` (on major releases).
- Update `DOCS/client-api-changes.rst` (on major releases).
- Create tag v0.X.Y.
- Push branch and tag to GitHub.
- Create a new GitHub release using the content of ``RELEASE_NOTES`` related to
- Create a new GitHub release using the content of `RELEASE_NOTES` related to
the new version.
Release notes template
----------------------
Here is a template that can be used for writing the ``RELEASE_NOTES`` file.
Here is a template that can be used for writing the `RELEASE_NOTES` file.
```markdown
Release 0.X.Y
=============
Changes
-------
Features
--------
- List of changes.
New
~~~
Bug fixes
---------
- List of new features
- List of bug fixes.
Removed
~~~~~~~
New features
------------
- List of removed features
- List of new features.
Deprecated
~~~~~~~~~~
- List of deprecated features
Behavior
--------
- List of user-visible changes in behavior
Options and Commands
--------------------
Added
~~~~~
- List of added options and commands
Changed
~~~~~~~
- List of changed options and commands
Renamed
~~~~~~~
- List of renamed options and commands
Deprecated
~~~~~~~~~~
- List of deprecated options and commands
Removed
~~~~~~~
- List of removed options and commands
Fixes and Minor Enhancements
----------------------------
- List of fixes and minor enhancements
This listing is not complete. There are many more bug fixes and changes. The
complete change log can be viewed by running ``git log <start>..<end>`` in
complete change log can be viewed by running `git log <start>..<end>` in
the git repository.
```
@@ -66,6 +108,6 @@ Note that the "Release 0.X.Y" title should be removed when creating a new GitHub
release.
When creating a new point release its changes should be added on top of the
``RELEASE_NOTES`` file (with the appropriate title) so that all the changes in
the current 0.X branch will be included. This way the ``RELEASE_NOTES`` file
`RELEASE_NOTES` file (with the appropriate title) so that all the changes in
the current 0.X branch will be included. This way the `RELEASE_NOTES` file
can be used by distributors as changelog for point releases too.
+1 -2
View File
@@ -75,8 +75,7 @@ talloc.h & talloc.c:
allocation call will never return NULL.
One very useful feature of talloc is fast tracking of memory leaks. ("Fast"
as in it doesn't require valgrind.) You can enable it by passing the option
--leak-report as first parameter, or better, setting the
as in it doesn't require valgrind.) You can enable it by setting the
MPV_LEAK_REPORT environment variable to "1":
export MPV_LEAK_REPORT=1
This will list all unfree'd allocations on exit.
+2 -2
View File
@@ -1,7 +1,7 @@
waf build system overview
=========================
mpv's new build system is based on waf and it should completly replace the
mpv's new build system is based on waf and it should completely replace the
custom ./configure + Makefile based system inherited from MPlayer.
Goals and the choice of waf
@@ -65,7 +65,7 @@ This defines a feature called ``vdpau`` which can be enabled or disabled by
the users with configure flags (that's the meaning of ``--``). This feature
depends on another feature whose name is ``x11``, and the autodetection check
consists of running ``pkg-config`` and looking for ``vdpau`` with version
``>= 0.2``. If the check succeds a ``#define HAVE_VDPAU 1`` will be added to
``>= 0.2``. If the check succeeds a ``#define HAVE_VDPAU 1`` will be added to
``config.h``, if not ``#define HAVE_VDPAU 0`` will be added.
The defines names are automatically prepended with ``HAVE_``, capitalized and
+20 -11
View File
@@ -26,6 +26,21 @@ variety of video file formats, audio and video codecs, and subtitle types.
Releases can be found on the [release list][releases].
## System requirements
- A not too ancient Linux, or Windows Vista or later, or OSX 10.8 or later.
- A somewhat capable CPU. Hardware decoding might sometimes help if the CPU
is too slow to decode video realtime, but must be explicitly enabled with
the `--hwdec` option. On Windows, a CPU with SSE4 instruction set is required
to get decent hardware decoding performance.
- A not too crappy GPU. mpv is not intended to be used with bad GPUs. There are
many caveats with drivers or system compositors causing tearing, stutter,
etc. On Windows, you might want to make sure the graphics drivers are
current, especially OpenGL. In some cases, ancient fallback video output
methods can help (such as `--vo=xv` on Linux), but this use is not
recommended or supported.
## Downloads
@@ -57,9 +72,6 @@ To build the software you can use `./waf build`: the result of the compilation
will be located in `build/mpv`. You can use `./waf install` to install mpv
to the *prefix* after it is compiled.
NOTE: Using the old build system (with `./old-configure`) should still work,
but will be removed in a future version of mpv.
Essential dependencies (incomplete list):
- gcc or clang
@@ -73,7 +85,7 @@ Essential dependencies (incomplete list):
- libass (OSD, OSC, text subtitles)
- Lua (optional, required for the OSC pseudo-GUI and youtube-dl integration)
- libjpeg (optional, used for screenshots only)
- Enca (optional, for subtitle charset detection)
- uchardet (optional, for subtitle charset detection)
- vdpau and vaapi libraries for hardware decoding on Linux (optional)
Libass dependencies:
@@ -106,6 +118,7 @@ OSX.
If you want to build a Windows binary, you either have to use MSYS2 and MinGW,
or cross-compile from Linux with MinGW. See [Windows compilation][windows_compilation].
## FFmpeg vs. Libav
@@ -174,11 +187,9 @@ list of changes is located [here][mplayer-changes].
Most activity happens on the IRC channel and the github issue tracker. The
mailing lists are mostly unused.
- **Github issue tracker**: [issue tracker][issue-tracker] (report bugs here)
- **GitHub issue tracker**: [issue tracker][issue-tracker] (report bugs here)
- **User IRC Channel**: `#mpv` on `irc.freenode.net`
- **Developer IRC Channel**: `#mpv-devel` on `irc.freenode.net`
- **Users Mailing List**: `mpv-users@googlegroups.com` ([Archive / Subscribe][mpv-users]).
- **Devel Mailing List**: `mpv-devel@googlegroups.com` ([Archive / Subscribe][mpv-devel])
To contact the `mpv` team in private write to `mpv-team@googlegroups.com`. Use
only if discretion is required.
@@ -187,14 +198,12 @@ only if discretion is required.
[mpv-build]: https://github.com/mpv-player/mpv-build
[homebrew-mpv]: https://github.com/mpv-player/homebrew-mpv
[issue-tracker]: https://github.com/mpv-player/mpv/issues
[mpv-users]: https://groups.google.com/forum/?hl=en#!forum/mpv-users
[mpv-devel]: https://groups.google.com/forum/?hl=en#!forum/mpv-devel
[ffmpeg_vs_libav]: https://github.com/mpv-player/mpv/wiki/FFmpeg-versus-Libav
[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
## License
## License
[GPLv2](https://github.com/mpv-player/mpv/blob/master/LICENSE)
Mostly GPLv2 or later. See [details.](https://github.com/mpv-player/mpv/blob/master/Copyright)
+625 -2
View File
@@ -1,3 +1,626 @@
Release 0.14.0
==============
Build System Changes
--------------------
- build: install scalable svg icon as well
- vo_opengl: require --enable-gpl3 for nnedi
- win32: enable internal pthreads wrapper by default
Features
--------
New
~~~
- vo_opengl: add experimental dxinterop backend (renders with OpenGL, displays through Direct3D; broken with Intel drivers)
- vo_opengl: add initial ANGLE support
- windows: implement icc-profile-auto
- windows: support taskbar button progress indicator (issue #2399)
Removed
~~~~~~~
- Windows XP support
- demux: remove old subtitle parser (FFmpeg users are unaffected; Libav loses support for some minor formats)
- demux_libass: remove this demuxer (libavformat takes its place)
- stream: drop old Linux PVR support
Options and Commands
--------------------
Added
~~~~~
- command, vo: add estimated-display-fps property
- command: add vsync-ratio property
- command: export some per-video-frame information (issue #2444)
- vo_opengl: make LOOKUP_TEXTURE_SIZE configurable
- windows: add option to set VO MMCSS profile
Changed
~~~~~~~
- --sub-fix-timing now applies to ASS subtitles as well
- command: rename vo-missed-frame-count property to vo-delayed-frame-count
- input.conf: add default bindings for changing window scale (issue #2500)
- videotoolbox: make decoder format customizable
- vo_opengl: disable interpolation without display-sync
- vo_opengl: make tscale=mitchell:tscale-clamp the default
- vo_rpi: add an option to disable OSD
Fixes and Minor Enhancements
----------------------------
- af_lavrresample: clamp float output to range
- ao: disambiguate default device list entries
- ao_alsa: filter audio device list
- ao_alsa: list bidirectional devices too
- ao_openal: accommodate more sample formats (issue #2494)
- ao_openal: fix virtual speaker positioning
- ao_wasapi: only report per-app volume in shared mode
- ao_wasapi: work around DTS passthrough failure
- build: make vaapi-wayland depend on gl-wayland (issue #2476)
- demux: fix seeking in .ts
- demux_lavf: mark ASS tracks as always UTF-8
- demux_mkv: fix incremental indexing with single-keyframe files (issue #2498)
- drm: fix setting up connectors
- dxva2: reject 10 bit HEVC (issue #2516)
- player: replace mistimed-frame-count with vsync-ratio on status line
- sd_ass: fix secondary subtitle mode
- various display-sync improvements
- vo_opengl: enable NNEDI3 prescaler on OpenGL ES 3.0
- vo_opengl: enable colormatrix even for RGB input
- vo_opengl: fix backend autoprobing, attempt to improve GLX vs. EGL backend detection
- vo_opengl: fix backend=x11 on Intel
- vo_opengl: fix issues with some obscure pixel formats (e.g. rgb555)
- vo_opengl: fix precision loss of fruit dithering matrix
- vo_opengl: force dumb mode if RG textures are not available
- vo_opengl: improve boundary check for polar filters
- vo_opengl: various GLES compatibility improvements
- vo_opengl: win32: test for exclusive mode
- vo_opengl_cb: do not block on flipping when redrawing
- vo_rpi: set aspect ratio
- win32: fix console output with raw stdio functions
- windows: try to avoid detection as exclusive fullscreen window (issue #2177)
- x11: request bypassing compositor (issue #2502)
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API. A complete changelog can be seen by running
`git log v0.13.0..v0.14.0` in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.13.0...v0.14.0 or
http://git.srsfckn.biz/mpv/log/?qt=range&q=v0.13.0..v0.14.0
Release 0.13.0
==============
NOTE: The previous release changed the default format for youtube-dl and
removed some workarounds related to MPEG DASH support. However, the required
changes to FFmpeg code (FFmpeg commit 4ab56667594842283dc5ae07f0daba2a2cb4d3af)
are not in any FFmpeg release yet (as of 2015-11-10), so for now, playing DASH
streams requires using FFmpeg git master. You can work around this by using the
--ytdl-format=best option.
Features
--------
New
~~~
- SVG version of the icon (with symbolic counterpart)
- stream_libarchive: add multivolume support
- vo_opengl: add prescaling framework along with Super-xBR and NNEDI3 (currently very slow) prescalers (issue #2230)
Options and Commands
--------------------
Added
~~~~~
- command: add mistimed-frame-count property
- vo_opengl: add vsync-fences option
Changed
~~~~~~~
- command: make display-fps property writable
- options: enable mpeg2 hw decoding by default if hw decoding is requested
- vo_opengl: rename fancy-downscaling to correct-downscaling
- vo_opengl: correct-downscaling: enable also for anamorphic clips
- vo_opengl: rename "drm_egl" to "drm-egl"
- vo_opengl: disable drm-egl autopickup
- vo_opengl: never load vaapi GLX interop by default
Fixes and Minor Enhancements
----------------------------
- ao_alsa: fix 7.1 over HDMI
- audio: do not require full audio chain reinit for speed changes
- rpi: add support for codecs other than h264 (mpeg2 for now)
- vd_lavc: make hwdec fallback more tolerant
- video: fix playback of pal8
- video: multiple display-sync fixes
- vo: fix no-audio mode with interpolation enabled/display-sync disabled
- vo_direct3d: fix operation (issue #2434)
- vo_drm: handle possible errors from sigaction
- vo_drm: show osd in audio only mode
- vo_opengl: do not attempt to cache frames in FBO in dumb-mode (issue #2432)
- vo_opengl: win32: always request MMCSS for DWM
- vo_opengl: win32: try to enable DwmFlush by default
- vo_vdpau: check VDP_RGBA_FORMAT_A8 support
- win32: request MMCSS "Playback" profile
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API. A complete changelog can be seen by running
`git log v0.12.0..v0.13.0` in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.12.0...v0.13.0 or
http://git.srsfckn.biz/mpv/log/?qt=range&q=v0.12.0..v0.13.0
Release 0.12.0
==============
NOTE: This release changes the default format for youtube-dl and removes some
workarounds related to MPEG DASH support. However, the required changes to
FFmpeg code are not in any FFmpeg release yet (as of 2015-10-29), so for now,
playing DASH streams requires using FFmpeg git master. You can work around
this by using the --ytdl-format=best option.
Features
--------
New
~~~
- vo_opengl: support new VAAPI EGL interop (requires Mesa 11)
- vo_opengl: vaapi: add Wayland support
- bring back the x11 video output
- vo_opengl: support all kinds of GBRP formats
Removed
~~~~~~~
- video: remove VDA support (VideoToolbox is preferred)
Behavior
--------
- vo_opengl: enable X11 EGL backend by default (disabled for NVIDIA due to driver bugs)
- ytdl: don't override user-set format in no-video mode
- sub: adjust behavior on mismatching video/subtitle aspect ratio
Options and Commands
--------------------
Added
~~~~~
- audio: add option for falling back to ao_null
- options: add support for client certificate authentication
- input: add key name for U+3000 IDEOGRAPHIC SPACE
- player: add audio drop/duplicate mode to video-sync
Changed
~~~~~~~
- vo_opengl: remove sharpen scalers, add sharpen sub-option
- vo_opengl: make sw suboption work without explicit backend selection
- command: make time properties unavailable if timestamp is unknown
- command: do not return 0 for bitrate if unknown (make property unavailable instead)
- vo_opengl: make the default debanding settings less excessive
- ytdl: disable --all-subs if "sub-lang" is in raw-options
Removed
~~~~~~~
- video: remove user-controllable PTS sorting (--pts-association-mode)
Fixes and Minor Enhancements
----------------------------
- player: fix another --force-window bug
- player: add wav to list of external audio file extensions
- ao_alsa: fix failure to find any sample format
- player: make stop command actually stop in all cases
- audio: various fixes related to audio device hotplugging
- vo_xv: fix crash with --wid
- ytdl: Remove DASH hacks, use DASH by default
- player: be slightly less prone to framedrop in display sync mode
- sd_lavc: extend subtitle resolution if images go outside video frame
- player: offset chapter display by start time
- command: make bitrate properties work correctly for external tracks
- w32_common: disable IME
- player: fix display-sync A/V calculation on high playback speeds
- player: fix display sync A/V difference estimation on drops
- player: raise display sync desync tolerance
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API. A complete changelog can be seen by running
`git log v0.11.0..v0.12.0` in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.11.0...v0.12.0 or
http://git.srsfckn.biz/mpv/log/?qt=range&q=v0.11.0..v0.12.0
Release 0.11.0
==============
Features
--------
New
~~~
- vo_opengl: implement debanding
Removed
~~~~~~~
- audio/filter: remove center, extrastereo, karaoke, sinesuppress, sub,
surround, sweep, ladspa, hrtf, export and bs2b filters (these are either
considered useless or have replacements in lavfi)
- video/filter: remove lavfi wrappers for noise, hqdn3d, unsharp and delogo
(these filters remain usable through lavfi)
Behavior
--------
- vo_opengl: require FBOs by default (use dumb-mode suboption for old hardware
and broken drivers)
- vo_opengl: enable debanding by default for the opengl-hq preset
- audio/out: use new sample format determination code
- player: prefer logical current directory path (affects logic for resuming
playback)
- vf_vdpaurb: Pass through non-hardware-decoded content
- player: make force-window=immediate work in auto-profiles
Options and Commands
--------------------
Added
~~~~~
- af_lavrresample: add normalize suboption
- vo_opengl: add deband, deband-iterations, deband-threshold, deband-range and
deband-grain suboptions
- af_lavfi: implement af-metadata property (like vf-metadata)
Changed
~~~~~~~
- command: make "add <property> 0" not change the value
Removed
~~~~~~~
- vo_opengl: remove source-shader suboption
Fixes and Minor Enhancements
----------------------------
- options: fix --no-config
- cache: do not include backbuffer size in total stream cache size
- audio/format: actually prefer float over double sample format for
int->float conversions
- audio/format: fix interlaved vs. non-interleaved conversions
- audio/format: revise format conversion scoring
- video: make --field-dominance set interlaced flag
- vf: vf_stereo3d compilation depends on libavfilter
- vf_yadif: add hack for Libav compatibility
- player: add opus to list of external audio file extensions
- build: allow disabling vapoursynth completely
- libmpv/win32: allow multiple windows at the same time
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API. A complete changelog can be seen by running
`git log v0.10.0..v0.11.0` in the git repository or by visiting either
https://github.com/mpv-player/mpv/compare/v0.10.0...v0.11.0 or
http://git.srsfckn.biz/mpv/log/?qt=range&q=v0.10.0..v0.11.0
Release 0.10.0
==============
Features
--------
New
~~~
- uchardet support
- Matroska: reading cue sheets embedded in tags
- Support for VideoToolbox hardware decoding
- Display sync mode (--display-sync)
- --force-window=immediate mode
- fd:// protocol
- libarchive wrapper for reading compressed archives
- TOOLS/lua: zones.lua
- Support for the "new" libavcodec VDPAU API
- vf_vdpaurb, Add a new filter for reading back VDPAU decoded frames
- DXVA2: HEVC support
- Enabled HEVC profiles with VA API
- HEVC added to whitelist of hwdec codecs
- vo_null: framerate emulation
- vo_opengl: support for custom shaders
- vo_opengl: temporal-dither-period option
- vo_opengl: tscale-clamp option
- vo_opengl: option to attach target-prim/target-csp to window screenshots
- vo_opengl_cb: "block" framedrop mode (now default)
- vo_opengl_cb: support for interpolation
- vo_vdpau: rotation support
- ytdl_hook: support for 'multi_video' results
Removed
~~~~~~~
- af_convert24 (af_lavrresample does this now)
- af_dummy
- audio: S8, U16, U24, U32 formats
- DVD and BD menu support
- TOOLS: youtube-starttime.lua
- VA API: compatibility crap (< 0.34.0) and vo_vaapi deinterlacer
- vo_x11
Deprecated
~~~~~~~~~~
- vf_dlopen
Behavior
--------
- audio: softvol scale is now cubic
- cache: readahead size is limited to half the cache size at the beginning
- charset_conv: "auto" encoding detection now prefers uchardet
- demux_playlist: skip hidden directories
- input.conf: O toggles between 2 states only
- input.conf: Ctrl+s key binding for window screenshots
- input.conf: mouse volume control (horizontal scrolling) inverted
- input.conf: L to toggle infinite looping
- input.conf: remap d/D keys (dropped framedrop cycle, replaced with deinterlacing toggle)
- player: disabled seeking on unseekable streams even if the cache is enabled
- player: parses and exposes m3u playlist titles
- player: --term-playing-msg is now in a separate log category
- player: removed automatic DVB channel advancement on no data
- player: now restores video-aspect on playback resume
- player: now uses exit code 0 by default for quit, 4 for signals, etc.
- player: warns against using HLS URLs with --playlist
- screenshots: changed the default directory in pseudo-gui mode to desktop
- screenshots: screenshot directory is now created automatically
- screenshots: default template is now prefixed with "mpv-"
- TOOLS/lua/autoload: adds all files on start
- vo: vo_wayland moved up in autoprobe list
- vo_opengl: enabled pbo by default with opengl-hq
- vo_opengl: cache dir for ICC profiles is now created automatically
- w32: shift drag and drop appends
- x11: shift drag and drop appends
Options and Commands
--------------------
Added
~~~~~
- af_volume: replaygain-fallback option
- ao_coreaudio: change-physical-format option
- ao_coreaudio: exclusive option
- ao_null: channel-layouts option for testing channel layout selection
- audio: --audio-spdif as new method for enabling passthrough
- cache: --cache-backbuffer to configure cache backbuffer size
- command: define-section command for defining input bindings
- command: audio-params and audio-out-params properties
- command: keypress, keydown, and keyup commands
- command: playlist_shuffle command
- command: option-info/N/set-locally property indicating per-file options
- command: protocol-list property
- command: track-list/N/audio-channels property
- demux: --demuxer-max-packets and --demuxer-max-bytes options to control maximum queue size
- input: relative percentage seek
- osc: time display configuration options
- player: --playlist-pos option
- screenshots: --screenshot-jpeg-source-chroma option to disable JPEG 4:4:4 output
- screenshots: --screenshot-high-bit-depth option to allow or disallow 16 bit output
- screenshots: --screenshot-directory option
- sub: --stretch-image-subs-to-screen option for stretching image subtitles to screen
- TOOLS/stats-conv: allow passing regex via command line
- video: --video-aspect-method option to configure container vs. bitstream aspect ratio
- vo_drm: mode suboption to set the mode ID to use
- vo_opengl_cb, vo_opengl: --hwdec-preload option for preloading hwdec context
- vo_rpi: background disabled by default
- vo_xv: buffers suboption to configure number of buffers
- win32: portable config mode
Changed
~~~~~~~
- audio: changed the range of the volume option/property (0 is still silence, and 100 now always means unchanged volume)
- command: allow changing deinterlace property any time
- command: allow changing track properties while no file is loaded
- command: always make video-aspect property accessible
- command: better choice when to allow playback-related commands
- command: change OSD symbol for absolute perc. seek
- command: change the default action for rescan_external_files
- command: change the hwdec properties
- command: define-section with empty contents removes a section
- command: export stereo 3D tags
- command: make auto-deinterlacing output at field rate
- command: make deinterlace property use interlaced-only yadif mode
- command: make property event mask matching more restrictive
- command: make the playback-time property writable
- input: allow - as separator between commands, instead of _
- options: --loop without argument means looping forever
- options: make keyvalue list parsing less strict
- player: extend --hls-bitrate option
- vf_yadif: expose interlaced frame mode
- video: --video-stereo-mode=no to disable automatic stereo conversion
- vo_opengl_cb, vo_opengl: --hwdec-preload for preloading hwdec context
- vo_opengl: replace icc-cache with icc-cache-dir
- vo_opengl: icc-profile overrides icc-profile-auto
Renamed
~~~~~~~
- command: rename audio-format property to audio-codec-name
- options: rename --media-title option to --force-media-title
- vo_opengl: rename use_full_range to use_normalized_range
Deprecated
~~~~~~~~~~
- --ad-spdif-dtshd (use --audio-spdif=dts-hd)
- audio-samplerate property
- length property
Removed
~~~~~~~
- get_property command
- --demuxer-readahead-packets and --demuxer-readahead-bytes
- image_writer: don't use jpeg baseline, and remove useless jpeg-optimize and jpeg-baseline options
- --leak-report
- --slave-broken
- vo_opengl: npot suboption
Fixes and Minor Enhancements
----------------------------
- ad_spdif: use DTS-HD passthrough only if the audio is really DTS-HD
- af: fix behavior with filter chains that require a large number of auto-inserted conversion filters
- af_lavcac3enc: fix A/V sync
- ao_alsa: accept 7.1 over HDMI
- ao_alsa: refuse to use spdif if AES flags can't be set
- ao_wasapi: fix crash on hotplug init error
- audio: avoid wasting CPU due to continuous wakeup
- audio: do not exit when loading small files in paused mode
- audio: fix channel map fallback selection
- audio: fix crash on uninit
- audio: fix --end handling
- audio: fix EOF state with --keep-open
- audio: fix restoring volume
- charset_conv: fix switched parameters
- charset_conv: use our own UTF-8 check with ENCA only
- cocoa: don't load hardcoded icon if running from bundle
- cocoa: hide cursor using a blank image instead of a system-wide API
- command: do not exit playback if the B point of A-B loop is past EOF
- command: fix audio-out-detected-device property
- command: fix track property when no file is loaded
- command: fix video-aspect property update notification
- command: let track properties return option value in idle mode
- demux: don't get stuck on some cases of timestamp resets
- demux: handle Matroska-style replaygain tags as well
- demux_lavf: do a better job at guessing the vobsub .sub filename
- demux_mkv: disable ordered chapters if ChapterTimeEnd is missing
- demux_mkv: discard broken index
- demux_mkv: fix mpeg2 mapping
- demux_mkv: ignore deprecated FrameRate, do not assume PAL
- demux_mkv: improve video duration detection heuristic
- demux_mkv: parse FLAC channel layouts
- demux_playlist: make mime type comparison case-insensitive
- dxva2: fix handling of cropped video
- idet.sh: Support larger files
- mp_image: fix vf_vdpaupp references
- options: fix conversion of flags to strings
- options: move program name to end of window title
- options: remove the period at the end of "No file."
- osc: completely disable if no VO window exists
- osc: exit tick immediately if disabled
- osc: reinit on playlist changes
- osx: add NULL check for input context in a missing case
- player: fix crashes when adding external tracks before loading main file
- player: increase tick event update frequency
- player: make decoding cover art more robust
- player: raise maximum idle time
- player: return better guess for playback time during seeks
- player: show larger cache sizes in MB on status line
- player: slim down A/V desync warning
- sd_ass: assume negative durations are unknown durations, and handle them
- terminal: disable terminal foreground state polling
- terminal-unix: set terminal mode on init
- timer: fix a corner case on clock changes
- TOOLS: make autodeint detect telecine in parallel
- TOOLS/zsh.pl: die loudly if mpv fails to run
- vaapi: prefer direct display over copy-back
- vaapi: fix some videos only showing up green
- vaapi: treat cropped decoder output slightly more correctly
- vda: add support for nv12 image formats
- vd_lavc: fix a hw decoding fallback case
- vf_stereo3d: drop internal implementation
- vf_vavpp: don't attempt to deinterlace progressive frames
- vf_vavpp: fix bob deinterlacing for bottom field first videos
- vf_vdpaupp: Don't crash when evaluating interlacing of NULL mpi
- video: always re-probe auto deint filter on filter reconfig
- video: better heuristic for timestamp resets
- video: fix panscan in vertical case
- video: fix VideoToolbox/VDA autodetection
- video: unbreak EOF with video-only files that have timestamp resets
- vo_direct3d: fix broken pseudo GUI drag and drop hint
- vo_drm: fix centering with regard to stride
- vo_drm: fix crashes with --profile=pseudo-gui
- vo_drm: fix resolution not restored after exiting
- vo_drm: fix stride problem for certain devices
- vo_drm: make VT switching non mandatory
- vo: free frames before killing VO
- vo_opengl: avoid broken shader if hwdec fails to provide textures
- vo_opengl_cb: drop frames eagerly if frames are not rendered
- vo_opengl: CMS no longer implies linear scaling
- vo_opengl: fix alpha video in one case
- vo_opengl: fix dangling pointers with vo_cmdline
- vo_opengl: fix framestepping/pausing + interpolation
- vo_opengl: fix "freezes" after seeking with interpolation on
- vo_opengl: fix scale=oversample's threshold calculations
- vo_opengl: framebuffers work under GLES 2
- vo_opengl: improve robustness against PBO failure
- vo_opengl: reimplement tscale=oversample
- vo_opengl: reject future images in different formats
- vo_opengl: X11: don't leak when GL init fails
- vo: restore frame-drop logic for high-fps clips
- vo_rpi: fix blackscreen before the first subtitle/OSD is rendered
- vo_rpi, vo_opengl: do not globally terminate EGL on VO uninit
- vo_sdl: fix glaring memory leak
- vo_vdpau: check maximum video size
- vo_vdpau: limit output surfaces to allowed maximum dimensions
- win32: fix window resize logic
- win32: fix crashes when changing system time
- x11: Handle external fullscreen toggles
- ytdl: catch bogus extractor info
- ytdl: do not use deprecated media-title option
- ytdl: don't print failure warning when youtube-dl was killed by us
- ytdl: get start_time
This listing is not complete. Check DOCS/client-api-changes.rst for a history
of changes to the client API. A complete changelog can be seen by running
`git log v0.9.2..v0.10.0` in the git repository or by visiting
https://github.com/mpv-player/mpv/compare/v0.9.2...v0.10.0.
Release 0.9.2
=============
@@ -39,8 +662,8 @@ Bug fixes
`libmpv` from creating the singleton.
This listing is not complete. A complete changelog can be seen by running
`git log v0.9.1..` in the git repository or by visiting
https://github.com/mpv-player/mpv/compare/v0.9.1...release/0.9.
`git log v0.9.1..v0.9.2` in the git repository or by visiting
https://github.com/mpv-player/mpv/compare/v0.9.1...v0.9.2.
Release 0.9.1
=============
+2 -2
View File
@@ -9,8 +9,8 @@ use warnings;
# the exact contents of the original file.
# FIXME: why not a char array?
# treat only alphanumeric and not-" punctuation as safe
my $unsafe_chars = qr{[^][A-Za-z0-9!#%&'()*+,./:;<=>?^_{|}~ -]};
# 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;
Regular → Executable
+1 -1
View File
@@ -5,7 +5,7 @@
conv() {
echo
identify -format "icon: %w %h" "$1"
echo `identify -format "icon: %w %h" "$1"`
convert "$1" -depth 8 rgba:-
}
+7 -7
View File
@@ -47,7 +47,7 @@ judge()
progressive=$((progressive + progressive1))
undetermined=$((undetermined + undetermined1))
done <<EOF
$(testfun "$@")
$(testfun "$@" | sed 's/:/: /g')
EOF
interlaced=$((bff + tff))
@@ -95,18 +95,18 @@ case "$verdict" in
exit 0
;;
interlaced-tff)
judge "$@" --vf-clr --vf-pre=pullup --field-dominance=top
judge "$@" --vf-clr --vf-pre=lavfi=\[setfield=tff\],pullup
case "$verdict" in
progressive)
[ -n "$ILDETECT_DRY_RUN" ] || \
$ILDETECT_MPV "$@" --vf-pre=pullup --field-dominance=top
$ILDETECT_MPV "$@" --vf-pre=lavfi=\[setfield=tff\],pullup
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 1
;;
*)
[ -n "$ILDETECT_DRY_RUN" ] || \
$ILDETECT_MPV "$@" --vf-pre=yadif --field-dominance=top
$ILDETECT_MPV "$@" --vf-pre=lavfi=\[setfield=tff\],yadif
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 2
@@ -114,18 +114,18 @@ case "$verdict" in
esac
;;
interlaced-bff)
judge "$@" --vf-clr --vf-pre=pullup --field-dominance=bottom
judge "$@" --vf-clr --vf-pre=lavfi=\[setfield=bff\],pullup
case "$verdict" in
progressive)
[ -n "$ILDETECT_DRY_RUN" ] || \
$ILDETECT_MPV "$@" --vf-pre=pullup --field-dominance=bottom
$ILDETECT_MPV "$@" --vf-pre=lavfi=\[setfield=bff\],pullup
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 1
;;
*)
[ -n "$ILDETECT_DRY_RUN" ] || \
$ILDETECT_MPV "$@" --vf-pre=yadif --field-dominance=bottom
$ILDETECT_MPV "$@" --vf-pre=lavfi=\[setfield=bff\],yadif
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 2
+1 -1
View File
@@ -84,7 +84,7 @@ sub elem_by_hexid {
# used by elem when setting the 'valname' key
use constant TYPE_MAP => {
uint => 'uint64_t',
str => 'struct bstr',
str => 'char *',
binary => 'struct bstr',
ebml_id => 'uint32_t',
float => 'double',
+26 -45
View File
@@ -2,21 +2,16 @@
-- appropriate deinterlacing filter based on a short section of the
-- currently playing video.
--
-- It registers the key-binding ctrl+d, which when pressed, inserts
-- the filter vf=lavfi=idet. After 4 second, it examines the results
-- to determine whether the content progressive or interlaced and the
-- interlacing field dominance. It immediately sets the latter within
-- mpv.
-- It registers the key-binding ctrl+d, which when pressed, inserts the filters
-- ``vf=lavfi=idet,pullup,vf=lavfi=idet``. After 4 seconds, it removes these
-- filters and decides whether the content is progressive, interlaced, or
-- telecined and the interlacing field dominance.
--
-- If the content is judged not to be progressive, it may be either
-- interlaced or telecined. To determine which one, the video is
-- seeked back to the detection starting point with the "pullup"
-- filter inserted. After another four seconds, if idet thinks that
-- the pulled up viedo is "progressive", then pullup is the correct
-- filter and this script leaves it in places while removing the idet
-- filter. Otherwise, the content plain interlaced and mpv's deinterlace
-- property is set. This will usually insert the yadif deinterlacing filter.
-- Based on this information, it may set mpv's ``deinterlace`` property (which
-- usually inserts the yadif filter), or insert the ``pullup`` filter if the
-- content is telecined. It also sets mpv's ``field-dominance`` property.
--
-- OPTIONS:
-- The default detection time may be overridden by adding
--
-- --script-opts=autodeint.detect_seconds=<number of seconds>
@@ -37,6 +32,7 @@ require "mp.msg"
script_name = mp.get_script_name()
detect_label = string.format("%s-detect", script_name)
pullup_label = string.format("%s", script_name)
ivtc_detect_label = string.format("%s-ivtc-detect", script_name)
-- number of seconds to gather cropdetect data
detect_seconds = tonumber(mp.get_opt(string.format("%s.detect_seconds", script_name)))
@@ -69,30 +65,29 @@ function start_detect()
mp.set_property("deinterlace","no")
del_filter_if_present(pullup_label)
percent_pos = mp.get_property("percent-pos")
-- insert the detection filter
local cmd = string.format('vf add @%s:lavfi=graph="idet"', detect_label)
local cmd = string.format('vf add @%s:lavfi=graph="idet",@%s:pullup,@%s:lavfi=graph="idet"',
detect_label, pullup_label, ivtc_detect_label)
if not mp.command(cmd) then
mp.msg.error("failed to insert detection filter")
mp.msg.error("failed to insert detection filters")
return
end
-- wait to gather data
timer = mp.add_timeout(detect_seconds, judge_field_dominance)
timer = mp.add_timeout(detect_seconds, select_filter)
end
function stop_detect()
del_filter_if_present(detect_label)
del_filter_if_present(ivtc_detect_label)
timer = nil
mp.set_property("playback-pos", percent_pos)
end
progressive, interlaced_tff, interlaced_bff, interlaced = 0, 1, 2, 3, 4
function judge()
function judge(label)
-- get the metadata
local result = mp.get_property_native(string.format("vf-metadata/%s", detect_label))
local result = mp.get_property_native(string.format("vf-metadata/%s", label))
num_tff = tonumber(result["lavfi.idet.multiple.tff"])
num_bff = tonumber(result["lavfi.idet.multiple.bff"])
num_progressive = tonumber(result["lavfi.idet.multiple.progressive"])
@@ -100,10 +95,10 @@ function judge()
num_interlaced = num_tff + num_bff
num_determined = num_interlaced + num_progressive
mp.msg.verbose("progressive = "..num_progressive)
mp.msg.verbose("interlaced-tff = "..num_tff)
mp.msg.verbose("interlaced-bff = "..num_bff)
mp.msg.verbose("undetermined = "..num_undetermined)
mp.msg.verbose(label.." progressive = "..num_progressive)
mp.msg.verbose(label.." interlaced-tff = "..num_tff)
mp.msg.verbose(label.." interlaced-bff = "..num_bff)
mp.msg.verbose(label.." undetermined = "..num_undetermined)
if num_determined < num_undetermined then
mp.msg.warn("majority undetermined frames")
@@ -119,11 +114,12 @@ function judge()
end
end
function judge_field_dominance()
verdict = judge()
function select_filter()
-- handle the first detection filter results
verdict = judge(detect_label)
if verdict == progressive then
stop_detect()
mp.msg.info("progressive: doing nothing")
stop_detect()
return
elseif verdict == interlaced_tff then
mp.set_property("field-dominance", "top")
@@ -133,21 +129,8 @@ function judge_field_dominance()
mp.set_property("field-dominance", "auto")
end
local cmd = string.format("vf pre @%s:pullup", pullup_label)
if not mp.command(cmd) then
mp.msg.error("failed to insert pullup filter")
stop_detect()
return
end
-- redo the detection with the pullup filter to see if it's telecined
mp.set_property("percent-pos", percent_pos)
timer = mp.add_timeout(detect_seconds, judge_ivtc)
end
function judge_ivtc()
verdict = judge()
-- handle the ivtc detection filter results
verdict = judge(ivtc_detect_label)
if verdict == progressive then
mp.msg.info(string.format("telecinied with %s field dominance: using pullup", mp.get_property("field-dominance")))
stop_detect()
@@ -157,8 +140,6 @@ function judge_ivtc()
mp.set_property("deinterlace","yes")
stop_detect()
end
return
end
mp.add_key_binding("ctrl+d", script_name, start_detect)
+15 -3
View File
@@ -4,8 +4,8 @@
-- alphabetically, and adds entries before and after the current file to
-- the internal playlist. (It stops if the it would add an already existing
-- playlist entry at the same position - this makes it "stable".)
-- Add at most 5 * 2 files when starting a file (before + after).
MAXENTRIES = 5
-- Add at most 5000 * 2 files when starting a file (before + after).
MAXENTRIES = 5000
function Set (t)
local set = {}
@@ -30,7 +30,12 @@ function add_files_at(index, files)
end
function get_extension(path)
return string.match(path, "%.([^%.]+)$" )
match = string.match(path, "%.([^%.]+)$" )
if match == nil then
return "nomatch"
else
return match
end
end
table.filter = function(t, iter)
@@ -47,6 +52,13 @@ function find_and_add_entries()
if #dir == 0 then
return
end
local pl_count = mp.get_property_number("playlist-count", 1)
if (pl_count > 1 and autoload == nil) or
(pl_count == 1 and EXTENSIONS[string.lower(get_extension(filename))] == nil) then
return
else
autoload = true
end
local files = mputils.readdir(dir, "files")
if files == nil then
+3 -1
View File
@@ -1,5 +1,7 @@
-- Rebuild the terminal status line as a lua script
-- Be aware that this will require more cpu power!
-- Also, this is based on a rather old version of the
-- builtin mpv status line.
-- Add a string to the status line
function atsl(s)
@@ -28,7 +30,7 @@ function update_status_line()
atsl(mp.get_property_osd("time-pos"))
atsl(" / ");
atsl(mp.get_property_osd("length"));
atsl(mp.get_property_osd("duration"));
atsl(" (")
atsl(mp.get_property_osd("percent-pos", -1))
-34
View File
@@ -1,34 +0,0 @@
--sets the startime of a youtube video as specified in the "t=HHhMMmSSs" part of the url
--NOTE: This might become obsolete once youtube-dl adds the functionality
local msg = require 'mp.msg'
function youtube_starttime()
url = mp.get_property("path", "")
start = 0
if string.find(url, "youtu%.?be") and
((url:find("http://") == 1) or (url:find("https://") == 1)) then
time = string.match(url, "[#&%?]t=%d*h?%d*m?%d+s?m?h?")
--the time-string can start with #, & or ? followed by t= and the timing parameters
--at least one number needs to be present after t=, followed by h, m, s or nothing (>implies s)
if time then
for pos in string.gmatch(time,"%d+%a?") do
if string.match(pos,"%d+h") then --find out multiplier for
multiplier = 60*60 --hours
elseif string.match(pos,"%d+m") then
multiplier = 60 --minutes
else multiplier = 1 end --seconds
start = start + (string.match(pos,"%d+") * multiplier)
end
msg.info("parsed '" .. time .. "' into '" .. start .. "' seconds")
end
mp.set_property("file-local-options/start",start)
end
end
mp.add_hook("on_load", 50, youtube_starttime)
+74
View File
@@ -0,0 +1,74 @@
-- zones.lua: mpv script for handling commands depending on where the mouse pointer is at,
-- mostly for mouse wheel handling, by configuring it via input.conf, e.g.:
--
-- Ported from avih's ( https://github.com/avih ) zones.js
--
-- Vertical positions can be top, middle, bottom or "*" to represent the whole column.
-- Horizontal positions can be left, middle, bottom or "*" to represent the whole row.
-- "default" will be the fallback command to be used if no command is assigned to that area.
--
-- input.conf example of use:
-- # wheel up/down with mouse
-- MOUSE_BTN3 script_message_to zones commands "middle-right: add brightness 1" "*-left: add volume 5" "default: seek 10"
-- MOUSE_BTN4 script_message_to zones commands "middle-right: add brightness -1" "*-left: add volume -5" "default: seek -10"
local ZONE_THRESH_PERCENTAGE = 20;
-- sides get 20% each, mid gets 60%, same vertically
local msg = mp.msg
function getMouseZone()
-- returns the mouse zone as two strings [top/middle/bottom], [left/middle/right], e.g. "middle", "right"
local screenW, screenH = mp.get_osd_resolution()
local mouseX, mouseY = mp.get_mouse_pos()
local threshY = screenH * ZONE_THRESH_PERCENTAGE / 100
local threshX = screenW * ZONE_THRESH_PERCENTAGE / 100
local yZone = (mouseY < threshY) and "top" or (mouseY < (screenH - threshY)) and "middle" or "bottom"
local xZone = (mouseX < threshX) and "left" or (mouseX < (screenW - threshX)) and "middle" or "right"
return yZone, xZone
end
function main (...)
local arg={...}
msg.debug('commands: \n\t'..table.concat(arg,'\n\t'))
local keyY, keyX = getMouseZone()
msg.debug("mouse at: " .. keyY .. '-' .. keyX)
local fallback = nil
for i, v in ipairs(arg) do
cmdY = v:match("^([%w%*]+)%-?[%w%*]*:")
cmdX = v:match("^[%w%*]*%-([%w%*]+)%s*:")
cmd = v:match("^[%S]-%s*:%s*(.+)")
msg.debug('cmdY: '..tostring(cmdY))
msg.debug('cmdX: '..tostring(cmdX))
msg.debug('cmd : '..tostring(cmd))
if (cmdY == keyY and cmdX == keyX) then
msg.verbose("running cmd: "..cmd)
mp.command(cmd)
return
elseif (cmdY == "*" and cmdX == keyX) or
(cmdY == keyY and cmdX == "*") then
msg.verbose("running cmd: "..cmd)
mp.command(cmd)
return
elseif cmdY == "default" then
fallback = cmd
end
end
if fallback ~= nil then
msg.verbose("running cmd: "..fallback)
mp.command(fallback)
return
else
msg.debug("no command assigned for "..keyY .. '-' .. keyX)
return
end
end
mp.register_script_message("commands", main)
+60 -22
View File
@@ -4,6 +4,13 @@
# Cleanups all over the place (c) 2001 pl
# Rewritten for mpv in 2014.
#
#
# Warning: this is not officially supported. Use on your own risk. Might require
# modifications when used on systems other than Linux. Contributors
# are not expected to update these files when making changes to the
# normal/preferred waf build system.
#
#
# This configure script is *not* autoconf-based and has different semantics.
# It attempts to autodetect all settings and options where possible. It is
# possible to override autodetection with the --enable-option/--disable-option
@@ -169,13 +176,13 @@ options_state_machine() {
opt_yes_no _tv "TV interface (TV/DVB grabbers)" yes
opt_yes_no _tv_v4l2 "Video4Linux2 TV interface"
opt_yes_no _libv4l2 "libv4l2"
opt_yes_no _pvr "Video4Linux2 MPEG PVR"
opt_yes_no _smb "Samba (SMB) input"
opt_yes_no _lcms2 "LCMS2 support"
opt_yes_no _bluray "Blu-ray support"
opt_yes_no _dvdread "libdvdread"
opt_yes_no _dvdnav "libdvdnav"
opt_yes_no _enca "ENCA charset oracle library"
opt_yes_no _uchardet "uchardet charset detection library"
opt_yes_no _libass "subtitle rendering with libass"
opt_yes_no _libavdevice "libavdevice demuxers"
opt_yes_no _libavfilter "libavfilter"
@@ -183,8 +190,6 @@ options_state_machine() {
opt_yes_no _libcdio "libcdio support"
opt_yes_no _librubberband "librubberband support"
opt_yes_no _ffmpeg "skip FFmpeg/Libav autodetection"
opt_yes_no _ladspa "LADSPA plugin support"
opt_yes_no _libbs2b "libbs2b audio filter support"
opt_yes_no _libavresample "libavresample (preferred over libswresample)"
opt_yes_no _libswresample "libswresample"
opt_yes_no _caca "CACA video output"
@@ -208,6 +213,7 @@ options_state_machine() {
opt_yes_no _lua "Lua scripting"
opt_yes_no _vapoursynth "VapourSynth filter bridge (Python)"
opt_yes_no _vapoursynth_lazy "VapourSynth filter bridge (Lua)"
opt_yes_no _libarchive "libarchive"
opt_yes_no _encoding "encoding functionality" yes
opt_yes_no _build_man "building manpage"
}
@@ -376,7 +382,7 @@ addcflags() { cflag_check "$@" && OURCFLAGS="$OURCFLAGS $@" ; }
OURCFLAGS="-std=c99 -Wall $_opt"
addcflags -g -g3 -ggdb
addcflags -Wundef -Wmissing-prototypes -Wshadow -Wno-switch -Wparentheses -Wpointer-arith -Wredundant-decls -Wno-pointer-sign -Werror=implicit-function-declaration -Wno-error=deprecated-declarations -Wno-error=unused-function
addcflags -Wundef -Wmissing-prototypes -Wshadow -Wno-switch -Wparentheses -Wpointer-arith -Wno-redundant-decls -Wno-pointer-sign -Werror=implicit-function-declaration -Wno-error=deprecated-declarations -Wno-error=unused-function
# clang
addcflags -Wno-logical-op-parentheses -fcolor-diagnostics -Wno-tautological-compare -Wno-tautological-constant-out-of-range-compare
# extra
@@ -506,9 +512,12 @@ check_statement_libs "compiler support for __sync built-ins" $_sync SYNC_BUILTIN
stdint.h 'int64_t test = 0; test = __sync_add_and_fetch(&test, 1)'
_sync=$(defretval)
_any_atomic=yes
if test "$_atomic" = no && test "$_sync" = no && test "$_stdatomic" = no ; then
echo "your compiler must support either stdatomic.h, or __atomic, or __sync built-ins."
_any_atomic=no
fi
define_yes_no $_any_atomic HAVE_ATOMICS
check_compile "iconv" $_iconv ICONV waftools/fragments/iconv.c " " "-liconv" "-liconv $_ld_dl"
_iconv=$(defretval)
@@ -600,12 +609,13 @@ define_yes_no $_vdpau HAVE_VDPAU_HWACCEL
check_pkg_config "VAAPI" $_vaapi VAAPI 'libva >= 0.32.0 libva-x11 >= 0.32.0'
_vaapi=$(defretval)
define_yes_no $_vaapi HAVE_VAAPI_HWACCEL
define_yes_no $_vaapi HAVE_VAAPI_X11
_vaapi_wayland=no
if test "$_vaapi" = yes ; then
check_pkg_config "VAAPI VPP" auto VAAPI_VPP 'libva >= 0.34.0'
else
check_yes_no no VAAPI_VPP
_vaapi_wayland=auto
fi
check_pkg_config "VAAPI Wayland" $_vaapi_wayland VAAPI_WAYLAND 'libva-wayland >= 0.34.0'
check_pkg_config "Xinerama" $_xinerama XINERAMA 'xinerama'
@@ -693,6 +703,11 @@ _vaapi_glx=no
(test "$_gl_x11" = yes && test "$_vaapi" = yes) && _vaapi_glx=auto
check_pkg_config "VAAPI with OpenGL/X11" $_vaapi_glx VAAPI_GLX 'libva-glx >= 0.32.0'
_vaapi_x_egl=no
(test "$_gl_x11_egl" = yes && test "$_vaapi" = yes) && _vaapi_x_egl=yes
check_yes_no $_vaapi_x_egl VAAPI_X_EGL
check_yes_no $_vaapi_x_egl VAAPI_EGL
check_pkg_config "SDL 2.0" $_sdl2 SDL2 'sdl2'
check_statement_libs "OSS Audio" $_ossaudio OSS_AUDIO $_soundcard_header "int x = SNDCTL_DSP_SETFRAGMENT;"
@@ -732,15 +747,11 @@ echo "LIBASS_OSD = $_libass" >> $CONFIG_MAK
echo "DUMMY_OSD = $_dummy_osd" >> $CONFIG_MAK
check_pkg_config "ENCA" $_enca ENCA 'enca'
check_pkg_config "uchardet" $_uchardet UCHARDET 'uchardet'
check_pkg_config "zlib" auto ZLIB 'zlib'
test $(defretval) = no && die "Unable to find development files for zlib."
test "$_dl" = no && _ladspa=no
check_statement_libs "LADSPA plugin support" $_ladspa LADSPA ladspa.h 'LADSPA_Descriptor ld = {0}'
check_pkg_config "libbs2b audio filter support" $_libbs2b LIBBS2B 'libbs2b'
check_pkg_config "LCMS2 support" $_lcms2 LCMS2 'lcms2 >= 2.6'
check_pkg_config "FFmpeg/Libav" $_ffmpeg FFMPEG \
@@ -786,6 +797,30 @@ api_statement_check \
libavutil/frame.h \
'enum AVFrameSideDataType type = AV_FRAME_DATA_SKIP_SAMPLES'
api_statement_check \
"libavutil av_version_info()" \
HAVE_AV_VERSION_INFO \
libavutil/avutil.h \
'const char *x = av_version_info()'
api_statement_check \
"libavutil new pixdesc fields" \
HAVE_AV_NEW_PIXDESC \
libavutil/pixdesc.h \
'AVComponentDescriptor d; int x = d.depth'
api_statement_check \
"libavcodec 64 bit AVPacket.duration" \
HAVE_AV_AVPACKET_INT64_DURATION \
libavcodec/avcodec.h \
'int x[(int)sizeof(((AVPacket){0}).duration) - 7]'
api_statement_check \
"libavcodec AVSubtitleRect AVPicture removal" \
HAVE_AV_SUBTITLE_NOPICT \
libavcodec/avcodec.h \
'AVSubtitleRect r = {.linesize={0}}'
check_pkg_config "libavfilter" $_libavfilter LIBAVFILTER 'libavfilter >= 5.0.0'
check_pkg_config "libavdevice" $_libavdevice LIBAVDEVICE 'libavdevice >= 55.0.0'
@@ -800,9 +835,6 @@ check_trivial "TV audio input" $_tv_v4l2 AUDIO_INPUT
test $_tv_v4l2 = no && _libv4l2=no
check_pkg_config "libv4l2 support" $_libv4l2 LIBV4L2 'libv4l2'
test "$_tv_v4l2" = no && _pvr=no
check_compile "Video 4 Linux 2 MPEG PVR interface" $_pvr PVR waftools/fragments/pvr.c
# Note: Lua has no official .pc file, so there are different OS-specific ones.
# Also, we support luajit, which is compatible to 5.1.
@@ -817,9 +849,9 @@ test_lua "lua >= 5.1.0 lua < 5.2.0"
test_lua "lua5.1 >= 5.1.0" # debian
test_lua "lua51 >= 5.1.0" # OpenBSD
test_lua "luajit >= 2.0.0"
test_lua "lua >= 5.2.0"
test_lua "lua5.2 >= 5.2.0" # debian
test_lua "lua52 >= 5.2.0" # OpenBSD
test_lua "lua >= 5.2.0"
test "$_lua" != yes && check_yes_no no LUA
@@ -841,6 +873,8 @@ if test "$_vapoursynth" = no && test "$_vapoursynth_lazy" = no ; then
fi
check_trivial "VapourSynth core" $_vapoursynth_core VAPOURSYNTH_CORE
check_pkg_config "libarchive support" $_libarchive LIBARCHIVE 'libarchive >= 3.0.0'
check_trivial "encoding" $_encoding ENCODING
# needs dlopen on unix
@@ -858,7 +892,7 @@ CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
# in-tree builds.
if test ! -f Makefile ; then
ln -s old-makefile Makefile
ln -s TOOLS/old-makefile Makefile
fi
cat > old_build/config.mak << EOF
@@ -905,11 +939,7 @@ cat > $TMPC << EOF
/* we didn't bother to add actual config checks for this, or they are
for platforms not supported by this configure script */
#define HAVE_BSD_FSTATFS 0
#define HAVE_LINUX_FSTATFS 0
#define HAVE_VDA_AV_VDA_ALLOC_CONTEXT 0
#define HAVE_VDA_HWACCEL 0
#define HAVE_VDA_LIBAVCODEC_REFCOUNTING 0
#define HAVE_VDA_GL 0
#define HAVE_LINUX_FSTATFS 1
#define HAVE_GL_COCOA 0
#define HAVE_COCOA 0
#define HAVE_COCOA_APPLICATION 0
@@ -936,6 +966,14 @@ cat > $TMPC << EOF
#define HAVE_RPI_GLES 0
#define HAVE_AV_PIX_FMT_MMAL 0
#define HAVE_DRM 0
#define HAVE_EGL_DRM 0
#define HAVE_VIDEOTOOLBOX_HWACCEL 0
#define HAVE_VIDEOTOOLBOX_GL 0
#define HAVE_SSE4_INTRINSICS 1
#define HAVE_C11_TLS 1
#define HAVE_EGL_ANGLE 0
#define HAVE_GPL3 1
#define HAVE_WIN32 0
#ifdef __OpenBSD__
#define DEFAULT_CDROM_DEVICE "/dev/rcd0c"
+34 -42
View File
@@ -35,18 +35,13 @@ SOURCES-$(DVDREAD) += stream/stream_dvd.c \
SOURCES-$(DVDNAV) += stream/stream_dvdnav.c \
stream/stream_dvd_common.c
SOURCES-$(LADSPA) += audio/filter/af_ladspa.c
SOURCES-$(RUBBERBAND) += audio/filter/af_rubberband.c
SOURCES-$(LIBASS) += sub/ass_mp.c sub/sd_ass.c \
demux/demux_libass.c
SOURCES-$(LIBASS) += sub/ass_mp.c sub/sd_ass.c
SOURCES-$(LIBBLURAY) += stream/stream_bluray.c
SOURCES-$(LIBBS2B) += audio/filter/af_bs2b.c
SOURCES-$(LIBSMBCLIENT) += stream/stream_smb.c
SOURCES-$(PVR) += stream/stream_pvr.c
SOURCES-$(TV) += stream/stream_tv.c stream/tv.c \
stream/frequencies.c stream/tvi_dummy.c \
demux/demux_tv.c
@@ -58,19 +53,26 @@ SOURCES-$(LIBASS_OSD) += sub/osd_libass.c
SOURCES-$(ALSA) += audio/out/ao_alsa.c
SOURCES-$(CACA) += video/out/vo_caca.c
SOURCES-$(SDL2) += audio/out/ao_sdl.c video/out/vo_sdl.c
SOURCES-$(GL) += video/out/gl_common.c video/out/gl_osd.c \
video/out/vo_opengl.c video/out/gl_lcms.c \
video/out/gl_video.c video/out/dither.c \
video/out/gl_hwdec.c video/out/gl_utils.c \
SOURCES-$(GL) += video/out/opengl/common.c \
video/out/opengl/osd.c \
video/out/opengl/lcms.c \
video/out/opengl/video.c \
video/out/opengl/video_shaders.c \
video/out/dither.c \
video/out/opengl/hwdec.c \
video/out/opengl/utils.c \
video/out/opengl/superxbr.c \
video/out/opengl/nnedi3.c \
video/out/vo_opengl.c \
video/out/vo_opengl_cb.c
SOURCES-$(ENCODING) += video/out/vo_lavc.c audio/out/ao_lavc.c \
common/encode_lavc.c
SOURCES-$(GL_X11) += video/out/x11_common.c video/out/gl_x11.c
SOURCES-$(EGL_X11) += video/out/x11_common.c video/out/gl_x11egl.c
SOURCES-$(GL_X11) += video/out/x11_common.c video/out/opengl/x11.c
SOURCES-$(EGL_X11) += video/out/x11_common.c video/out/opengl/x11egl.c
SOURCES-$(GL_WAYLAND) += video/out/wayland_common.c \
video/out/gl_wayland.c
video/out/opengl/wayland.c
SOURCES-$(JACK) += audio/out/ao_jack.c
SOURCES-$(OPENAL) += audio/out/ao_openal.c
@@ -80,13 +82,15 @@ SOURCES-$(RSOUND) += audio/out/ao_rsound.c
SOURCES-$(SNDIO) += audio/out/ao_sndio.c
SOURCES-$(VDPAU) += video/vdpau.c video/vdpau_mixer.c \
video/out/vo_vdpau.c video/decode/vdpau.c \
video/filter/vf_vdpaupp.c
SOURCES-$(VDPAU_GL_X11) += video/out/gl_hwdec_vdpau.c
video/filter/vf_vdpaupp.c \
video/filter/vf_vdpaurb.c
SOURCES-$(VDPAU_GL_X11) += video/out/opengl/hwdec_vdpau.c
SOURCES-$(VAAPI) += video/out/vo_vaapi.c \
video/decode/vaapi.c \
video/filter/vf_vavpp.c \
video/vaapi.c
SOURCES-$(VAAPI_VPP) += video/filter/vf_vavpp.c
SOURCES-$(VAAPI_GLX) += video/out/gl_hwdec_vaglx.c
SOURCES-$(VAAPI_GLX) += video/out/opengl/hwdec_vaglx.c
SOURCES-$(VAAPI_X_EGL) += video/out/opengl/hwdec_vaegl.c
SOURCES-$(X11) += video/out/vo_x11.c video/out/x11_common.c
SOURCES-$(XV) += video/out/vo_xv.c
@@ -96,18 +100,16 @@ SOURCES-$(WAYLAND) += video/out/vo_wayland.c \
video/out/wayland/memfile.c
SOURCES-$(LIBAVFILTER) += video/filter/vf_lavfi.c \
video/filter/vf_delogo.c \
video/filter/vf_gradfun.c \
video/filter/vf_hqdn3d.c \
video/filter/vf_noise.c \
video/filter/vf_pullup.c \
video/filter/vf_rotate.c \
video/filter/vf_unsharp.c \
video/filter/vf_yadif.c \
audio/filter/af_lavfi.c
SOURCES-$(LUA) += player/lua.c
SOURCES-$(VAPOURSYNTH_CORE) += video/filter/vf_vapoursynth.c
SOURCES-$(LIBARCHIVE) += demux/demux_libarchive.c \
stream/stream_libarchive.c
SOURCES-$(DLOPEN) += video/filter/vf_dlopen.c
SOURCES = audio/audio.c \
@@ -121,31 +123,17 @@ SOURCES = audio/audio.c \
audio/decode/ad_spdif.c \
audio/decode/dec_audio.c \
audio/filter/af.c \
audio/filter/af_center.c \
audio/filter/af_channels.c \
audio/filter/af_convert24.c \
audio/filter/af_convertsignendian.c \
audio/filter/af_delay.c \
audio/filter/af_dummy.c \
audio/filter/af_equalizer.c \
audio/filter/af_export.c \
audio/filter/af_extrastereo.c \
audio/filter/af_format.c \
audio/filter/af_hrtf.c \
audio/filter/af_karaoke.c \
audio/filter/af_lavcac3enc.c \
audio/filter/af_lavrresample.c \
audio/filter/af_pan.c \
audio/filter/af_scaletempo.c \
audio/filter/af_sinesuppress.c \
audio/filter/af_sub.c \
audio/filter/af_surround.c \
audio/filter/af_sweep.c \
audio/filter/af_drc.c \
audio/filter/af_volume.c \
audio/filter/filter.c \
audio/filter/tools.c \
audio/filter/window.c \
audio/out/ao.c \
audio/out/ao_null.c \
audio/out/ao_pcm.c \
@@ -160,6 +148,7 @@ SOURCES = audio/audio.c \
common/tags.c \
common/version.c \
demux/codec_tags.c \
demux/cue.c \
demux/demux.c \
demux/demux_edl.c \
demux/demux_cue.c \
@@ -171,7 +160,6 @@ SOURCES = audio/audio.c \
demux/demux_playlist.c \
demux/demux_rar.c \
demux/demux_raw.c \
demux/demux_subreader.c \
demux/ebml.c \
demux/packet.c \
demux/timeline.c \
@@ -207,7 +195,7 @@ SOURCES = audio/audio.c \
player/client.c \
player/configfiles.c \
player/command.c \
player/discnav.c \
player/external_files.c \
player/loadfile.c \
player/main.c \
player/misc.c \
@@ -232,7 +220,6 @@ SOURCES = audio/audio.c \
stream/stream_rar.c \
sub/dec_sub.c \
sub/draw_bmp.c \
sub/find_subfiles.c \
sub/img_convert.c \
sub/osd.c \
sub/sd_lavc.c \
@@ -246,6 +233,7 @@ SOURCES = audio/audio.c \
ta/ta_talloc.c \
video/csputils.c \
video/fmt-conversion.c \
video/gpu_memcpy.c \
video/image_writer.c \
video/img_format.c \
video/mp_image.c \
@@ -360,6 +348,10 @@ video/out/x11_common.c: video/out/x11_icon.inc
video/out/x11_icon.inc: TOOLS/file2string.pl video/out/x11_icon.bin
./$^ >$@
video/out/opengl/nnedi3.c: video/out/opengl/nnedi3_weights.inc
video/out/opengl/nnedi3_weights.inc: TOOLS/file2string.pl video/out/opengl/nnedi3_weights.bin
./$^ >$@
sub/osd_libass.c: sub/osd_font.h
sub/osd_font.h: TOOLS/file2string.pl sub/osd_font.otf
./$^ >$@
@@ -382,8 +374,8 @@ config.mak: configure
@echo "####### Please run ./configure again - it's changed! #######"
@echo "############################################################"
version.h .version: version.sh
./$<
old_build/version.h .version: version.sh
./version.sh --versionh=old_build/version.h
# Force version.sh to run to potentially regenerate version.h
-include .version
@@ -394,7 +386,7 @@ version.h .version: version.sh
###### dependency declarations / specific CFLAGS ######
common/version.c: version.h
common/version.c: old_build/version.h
DOCS/man/mpv.1: DOCS/man/af.rst \
DOCS/man/ao.rst \
@@ -465,7 +457,7 @@ clean:
-$(RM) $(call ADD_ALL_DIRS,/*.o /*.a /*.ho /*~)
-$(RM) mpv
-$(RM) DOCS/man/*/mpv.1
-$(RM) version.h
-$(RM) old_build/version.h version.h
-$(RM) input/input_conf.h
-$(RM) video/out/vdpau_template.c
-$(RM) demux/ebml_types.h demux/ebml_defs.c
+1 -1
View File
@@ -40,7 +40,7 @@ def apply_plist_template(plist_file, version):
print (line.rstrip().replace('${VERSION}', version))
def main():
version = sh("./version.sh --print").strip()
version = sh("./version.sh").strip()
usage = "usage: %prog [options] arg"
parser = OptionParser(usage)
@@ -1,2 +1 @@
screenshot-template=~/Desktop/shot%n
profile=pseudo-gui
+41 -17
View File
@@ -1,11 +1,15 @@
#!/usr/bin/env python3
import matplotlib.pyplot as plot
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import sys
import re
filename = sys.argv[1]
event_regex = re.compile(".*")
events = ".*"
if len(sys.argv) > 2:
events = sys.argv[2]
event_regex = re.compile(events)
"""
This script is meant to display stats written by mpv --dump-stats=filename.
@@ -26,8 +30,8 @@ Currently, the following event types are supported:
'end' <name> end of the named event
'value' <float> <name> a normal value (as opposed to event)
'event-timed' <ts> <name> singular event at the given timestamp
'value-timed' <ts> <float> <name>
a value for an event at the given timestamp
'value-timed' <ts> <float> <name> a value for an event at the given timestamp
'range-timed' <ts1> <ts2> <name> like start/end, but explicit times
<name> singular event (same as 'signal')
"""
@@ -35,8 +39,8 @@ Currently, the following event types are supported:
class G:
events = {}
start = None
# http://matplotlib.org/api/markers_api.html#module-matplotlib.markers
markers = ["o", "8", "s", "p", "*", "h", "+", "x", "D"]
markers = ["o", "s", "t", "d"]
curveno = 0
def find_marker():
if len(G.markers) == 0:
@@ -91,6 +95,15 @@ for line in [line.split("#")[0].strip() for line in open(filename, "r")]:
val = int(val) / SCALE - G.start
e = get_event(name, "event-signal")
e.vals.append((val, 1))
elif event.startswith("range-timed "):
_, ts1, ts2, name = event.split(" ", 3)
ts1 = int(ts1) / SCALE - G.start
ts2 = int(ts2) / SCALE - G.start
e = get_event(name, "event")
e.vals.append((ts1, 0))
e.vals.append((ts1, 1))
e.vals.append((ts2, 1))
e.vals.append((ts2, 0))
elif event.startswith("value-timed "):
_, tsval, val, name = event.split(" ", 3)
tsval = int(tsval) / SCALE - G.start
@@ -116,20 +129,31 @@ for e, index in zip(G.sevents, range(len(G.sevents))):
else:
e.vals = [(x, y * (m - index) / m) for (x, y) in e.vals]
fig = plot.figure()
fig.hold(True)
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
app = QtGui.QApplication([])
win = pg.GraphicsWindow()
#win.resize(1500, 900)
ax = [None, None]
plots = 2 if hasval else 1
ax[0] = fig.add_subplot(plots, 1, 1)
ax[0] = win.addPlot()
if hasval:
ax[1] = fig.add_subplot(plots, 1, 2, sharex=ax[0])
legends = [[], []]
win.nextRow()
ax[1] = win.addPlot()
ax[1].setXLink(ax[0])
for cur in ax:
if cur is not None:
cur.addLegend(offset = (-1, 1))
for e in G.sevents:
cur = ax[1 if e.type == "value" else 0]
pl, = cur.plot([x for x,y in e.vals], [y for x,y in e.vals], label=e.name)
args = {'name': e.name,'antialias':True}
if e.type == "event-signal":
plot.setp(pl, marker = e.marker, linestyle = "None")
for cur in ax:
if cur is not None:
cur.legend()
plot.show()
args['symbol'] = e.marker
args['pen'] = None
else:
args['pen'] = pg.mkPen(pg.intColor(G.curveno), width=0)
G.curveno += 1
n = cur.plot([x for x,y in e.vals], [y for x,y in e.vals], **args)
QtGui.QApplication.instance().exec_()
+13 -2
View File
@@ -141,7 +141,7 @@ sub parse_main_opts {
my ($cmd, $regex) = @_;
my @list;
my @lines = split /\n/, `"$mpv" --no-config $cmd`;
my @lines = call_mpv($cmd);
foreach my $line (@lines) {
my ($name, $desc) = ($line =~ /^$regex/) or next;
@@ -206,7 +206,7 @@ sub parse_opts {
my ($cmd, $regex) = @_;
my @list;
my @lines = split /\n/, `"$mpv" --no-config $cmd`;
my @lines = call_mpv($cmd);
foreach my $line (@lines) {
if ($line !~ /^$regex/) {
@@ -226,3 +226,14 @@ sub parse_opts {
return @list;
}
sub call_mpv {
my ($cmd) = @_;
my $output = `"$mpv" --no-config $cmd`;
if ($? == -1) {
die "Could not run mpv: $!";
} elsif ((my $exit_code = $? >> 8) != 0) {
die "mpv returned $exit_code with output:\n$output";
}
return split /\n/, $output;
}
+1 -1
View File
@@ -1 +1 @@
0.9.2
0.14.0
+30 -22
View File
@@ -34,8 +34,8 @@ static void update_redundant_info(struct mp_audio *mpa)
assert(mp_chmap_is_empty(&mpa->channels) ||
mp_chmap_is_valid(&mpa->channels));
mpa->nch = mpa->channels.num;
mpa->bps = af_fmt2bps(mpa->format);
if (AF_FORMAT_IS_PLANAR(mpa->format)) {
mpa->bps = af_fmt_to_bytes(mpa->format);
if (af_fmt_is_planar(mpa->format)) {
mpa->spf = 1;
mpa->num_planes = mpa->nch;
mpa->sstride = mpa->bps;
@@ -58,13 +58,6 @@ void mp_audio_set_num_channels(struct mp_audio *mpa, int num_channels)
update_redundant_info(mpa);
}
// Use old MPlayer/ALSA channel layout.
void mp_audio_set_channels_old(struct mp_audio *mpa, int num_channels)
{
mp_chmap_from_channels_alsa(&mpa->channels, num_channels);
update_redundant_info(mpa);
}
void mp_audio_set_channels(struct mp_audio *mpa, const struct mp_chmap *chmap)
{
mpa->channels = *chmap;
@@ -93,15 +86,19 @@ bool mp_audio_config_valid(const struct mp_audio *mpa)
char *mp_audio_config_to_str_buf(char *buf, size_t buf_sz, struct mp_audio *mpa)
{
char ch[128];
mp_chmap_to_str_buf(ch, sizeof(ch), &mpa->channels);
char *hr_ch = mp_chmap_to_str_hr(&mpa->channels);
if (strcmp(hr_ch, ch) != 0)
mp_snprintf_cat(ch, sizeof(ch), " (%s)", hr_ch);
snprintf(buf, buf_sz, "%dHz %s %dch %s", mpa->rate,
mp_chmap_to_str(&mpa->channels), mpa->channels.num,
af_fmt_to_str(mpa->format));
ch, mpa->channels.num, af_fmt_to_str(mpa->format));
return buf;
}
void mp_audio_force_interleaved_format(struct mp_audio *mpa)
{
if (AF_FORMAT_IS_PLANAR(mpa->format))
if (af_fmt_is_planar(mpa->format))
mp_audio_set_format(mpa, af_fmt_from_planar(mpa->format));
}
@@ -118,7 +115,6 @@ void mp_audio_set_null_data(struct mp_audio *mpa)
mpa->allocated[n] = NULL;
}
mpa->samples = 0;
mpa->readonly = false;
}
static int get_plane_size(const struct mp_audio *mpa, int samples)
@@ -160,8 +156,8 @@ void mp_audio_realloc(struct mp_audio *mpa, int samples)
if (!mpa->allocated[n] || size != mpa->allocated[n]->size) {
if (av_buffer_realloc(&mpa->allocated[n], size) < 0)
abort(); // OOM
mpa->planes[n] = mpa->allocated[n]->data;
}
mpa->planes[n] = mpa->allocated[n]->data;
}
for (int n = mpa->num_planes; n < MP_NUM_CHANNELS; n++) {
av_buffer_unref(&mpa->allocated[n]);
@@ -192,8 +188,18 @@ int mp_audio_get_allocated_size(struct mp_audio *mpa)
{
int size = 0;
for (int n = 0; n < mpa->num_planes; n++) {
int s = mpa->allocated[n] ? mpa->allocated[n]->size / mpa->sstride : 0;
size = n == 0 ? s : MPMIN(size, s);
for (int i = 0; i < MP_NUM_CHANNELS && mpa->allocated[i]; i++) {
uint8_t *start = mpa->allocated[i]->data;
uint8_t *end = start + mpa->allocated[i]->size;
uint8_t *plane = mpa->planes[n];
if (plane >= start && plane < end) {
int s = MPMIN((end - plane) / mpa->sstride, INT_MAX);
size = n == 0 ? s : MPMIN(size, s);
goto next;
}
}
return 0; // plane is not covered by any buffer
next: ;
}
return size;
}
@@ -251,7 +257,7 @@ void mp_audio_skip_samples(struct mp_audio *data, int samples)
// Will return true for non-refcounted frames.
bool mp_audio_is_writeable(struct mp_audio *data)
{
bool ok = !data->readonly;
bool ok = true;
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
if (data->allocated[n])
ok &= av_buffer_is_writable(data->allocated[n]);
@@ -317,21 +323,23 @@ struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe)
}
// If we can't handle the format (e.g. too many channels), bail out.
if (!mp_audio_config_valid(new) || avframe->nb_extended_buf)
if (!mp_audio_config_valid(new))
goto fail;
for (int n = 0; n < AV_NUM_DATA_POINTERS; n++) {
if (!avframe->buf[n])
for (int n = 0; n < AV_NUM_DATA_POINTERS + avframe->nb_extended_buf; n++) {
AVBufferRef *buf = n < AV_NUM_DATA_POINTERS ? avframe->buf[n]
: avframe->extended_buf[n - AV_NUM_DATA_POINTERS];
if (!buf)
break;
if (n >= MP_NUM_CHANNELS)
goto fail;
new->allocated[n] = av_buffer_ref(avframe->buf[n]);
new->allocated[n] = av_buffer_ref(buf);
if (!new->allocated[n])
goto fail;
}
for (int n = 0; n < new->num_planes; n++)
new->planes[n] = avframe->data[n];
new->planes[n] = avframe->extended_data[n];
new->samples = avframe->nb_samples;
return new;
+7 -4
View File
@@ -35,16 +35,19 @@ struct mp_audio {
int nch; // number of channels (redundant with chmap)
int spf; // sub-samples per sample on each plane
int num_planes; // number of planes
int bps; // size of sub-samples (af_fmt2bps(format))
int bps; // size of sub-samples (af_fmt_to_bytes(format))
// private
bool readonly;
double pts; // currently invalid within the filter chain
// --- private
// These do not necessarily map directly to planes[]. They can have
// different order or count. There shouldn't be more buffers than planes.
// If allocated[n] is NULL, allocated[n+1] must also be NULL.
struct AVBufferRef *allocated[MP_NUM_CHANNELS];
};
void mp_audio_set_format(struct mp_audio *mpa, int format);
void mp_audio_set_num_channels(struct mp_audio *mpa, int num_channels);
void mp_audio_set_channels_old(struct mp_audio *mpa, int num_channels);
void mp_audio_set_channels(struct mp_audio *mpa, const struct mp_chmap *chmap);
void mp_audio_copy_config(struct mp_audio *dst, const struct mp_audio *src);
bool mp_audio_config_equals(const struct mp_audio *a, const struct mp_audio *b);
+9
View File
@@ -119,6 +119,15 @@ void mp_audio_buffer_prepend_silence(struct mp_audio_buffer *ab, int samples)
mp_audio_fill_silence(ab->buffer, 0, samples);
}
void mp_audio_buffer_duplicate(struct mp_audio_buffer *ab, int samples)
{
assert(samples >= 0 && samples <= ab->buffer->samples);
int oldlen = ab->buffer->samples;
ab->buffer->samples += samples;
mp_audio_realloc_min(ab->buffer, ab->buffer->samples);
mp_audio_copy(ab->buffer, oldlen, ab->buffer, oldlen - samples, samples);
}
// Get the start of the current readable buffer.
void mp_audio_buffer_peek(struct mp_audio_buffer *ab, struct mp_audio *out_mpa)
{
+1
View File
@@ -35,6 +35,7 @@ void mp_audio_buffer_get_write_buffer(struct mp_audio_buffer *ab, int minsamples
void mp_audio_buffer_finish_write(struct mp_audio_buffer *ab, int samples);
void mp_audio_buffer_append(struct mp_audio_buffer *ab, struct mp_audio *mpa);
void mp_audio_buffer_prepend_silence(struct mp_audio_buffer *ab, int samples);
void mp_audio_buffer_duplicate(struct mp_audio_buffer *ab, int samples);
void mp_audio_buffer_peek(struct mp_audio_buffer *ab, struct mp_audio *out_mpa);
void mp_audio_buffer_skip(struct mp_audio_buffer *ab, int samples);
void mp_audio_buffer_clear(struct mp_audio_buffer *ab);
+43 -45
View File
@@ -18,6 +18,8 @@
#include <stdlib.h>
#include <assert.h>
#include <libavutil/common.h>
#include "common/common.h"
#include "common/msg.h"
#include "chmap.h"
@@ -68,6 +70,7 @@ static const char *const std_layout_names[][2] = {
{"quad", "fl-fr-bl-br"},
{"quad(side)", "fl-fr-sl-sr"},
{"3.1", "fl-fr-fc-lfe"},
{"3.1(back)", "fl-fr-lfe-bc"}, // not in lavc
{"5.0", "fl-fr-fc-bl-br"},
{"5.0(alsa)", "fl-fr-bl-br-fc"}, // not in lavc
{"5.0(side)", "fl-fr-fc-sl-sr"},
@@ -81,21 +84,23 @@ static const char *const std_layout_names[][2] = {
{"hexagonal", "fl-fr-fc-bl-br-bc"},
{"6.1", "fl-fr-fc-lfe-bc-sl-sr"},
{"6.1(back)", "fl-fr-fc-lfe-bl-br-bc"}, // lavc calls this "6.1" too
{"6.1(top)", "fl-fr-fc-lfe-bl-br-tc"}, // not in lavc
{"6.1(front)", "fl-fr-lfe-flc-frc-sl-sr"},
{"7.0", "fl-fr-fc-bl-br-sl-sr"},
{"7.0(front)", "fl-fr-fc-flc-frc-sl-sr"},
{"7.0(rear)", "fl-fr-fc-bl-br-sdl-sdr"}, // not in lavc
{"7.1", "fl-fr-fc-lfe-bl-br-sl-sr"},
{"7.1(alsa)", "fl-fr-bl-br-fc-lfe-sl-sr"}, // not in lavc
{"7.1(wide)", "fl-fr-fc-lfe-bl-br-flc-frc"},
{"7.1(wide-side)", "fl-fr-fc-lfe-flc-frc-sl-sr"},
{"7.1(rear)", "fl-fr-fc-lfe-bl-br-sdl-sdr"},
{"7.1(rear)", "fl-fr-fc-lfe-bl-br-sdl-sdr"}, // not in lavc
{"octagonal", "fl-fr-fc-bl-br-bc-sl-sr"},
{"downmix", "dl-dr"},
{"auto", ""}, // not in lavc
{0}
};
static const struct mp_chmap default_layouts[MP_NUM_CHANNELS + 1] = {
static const struct mp_chmap default_layouts[] = {
{0}, // empty
MP_CHMAP_INIT_MONO, // mono
MP_CHMAP2(FL, FR), // stereo
@@ -107,19 +112,6 @@ static const struct mp_chmap default_layouts[MP_NUM_CHANNELS + 1] = {
MP_CHMAP8(FL, FR, FC, LFE, BL, BR, SL, SR), // 7.1
};
// The channel order was lavc/waveex, but differs from lavc for 5, 6 and 8
// channels. 3 and 7 channels were likely undefined (no ALSA support).
// I'm not sure about the 4 channel case: ALSA uses "quad", while the ffmpeg
// default layout is "4.0".
static const char *const mplayer_layouts[MP_NUM_CHANNELS + 1] = {
[1] = "mono",
[2] = "stereo",
[4] = "quad",
[5] = "5.0(alsa)",
[6] = "5.1(alsa)",
[8] = "7.1(alsa)",
};
// Returns true if speakers are mapped uniquely, and there's at least 1 channel.
bool mp_chmap_is_valid(const struct mp_chmap *src)
{
@@ -215,24 +207,11 @@ void mp_chmap_fill_na(struct mp_chmap *map, int num)
// mp_chmap_is_valid(dst) will return false.
void mp_chmap_from_channels(struct mp_chmap *dst, int num_channels)
{
if (num_channels < 0 || num_channels > MP_NUM_CHANNELS) {
*dst = (struct mp_chmap) {0};
} else {
*dst = (struct mp_chmap) {0};
if (num_channels >= 0 && num_channels < MP_ARRAY_SIZE(default_layouts))
*dst = default_layouts[num_channels];
}
}
// Try to do what mplayer/mplayer2/mpv did before channel layouts were
// introduced, i.e. get the old default channel order.
void mp_chmap_from_channels_alsa(struct mp_chmap *dst, int num_channels)
{
if (num_channels < 0 || num_channels > MP_NUM_CHANNELS) {
*dst = (struct mp_chmap) {0};
} else {
mp_chmap_from_str(dst, bstr0(mplayer_layouts[num_channels]));
if (!dst->num)
mp_chmap_from_channels(dst, num_channels);
}
if (!dst->num)
mp_chmap_set_unknown(dst, num_channels);
}
// Set *dst to an unknown layout for the given numbers of channels.
@@ -293,12 +272,18 @@ void mp_chmap_remove_useless_channels(struct mp_chmap *map,
// Speakers not representable by ffmpeg/libav are dropped.
// Warning: this ignores the order of the channels, and will return a channel
// mask even if the order is different from libavcodec's.
// Also, "unknown" channel maps are translated to non-sense channel
// maps with the same number of channels.
uint64_t mp_chmap_to_lavc_unchecked(const struct mp_chmap *src)
{
// lavc has no concept for unknown layouts yet, so pick a default
struct mp_chmap t = *src;
if (t.num > 64)
return 0;
// lavc has no concept for unknown layouts yet, so pick something that does
// the job of signaling the number of channels, even if it makes no sense
// as a proper layout.
if (mp_chmap_is_unknown(&t))
mp_chmap_from_channels(&t, t.num);
return t.num == 64 ? (uint64_t)-1 : (1ULL << t.num) - 1;
uint64_t mask = 0;
for (int n = 0; n < t.num; n++) {
if (t.speaker[n] < 64) // ignore MP_SPEAKER_ID_NA etc.
@@ -354,6 +339,8 @@ bool mp_chmap_is_lavc(const struct mp_chmap *src)
return true;
}
// Warning: for "unknown" channel maps, this returns something that may not
// make sense. Invalid channel maps are not changed.
void mp_chmap_reorder_to_lavc(struct mp_chmap *map)
{
if (!mp_chmap_is_valid(map))
@@ -382,8 +369,8 @@ void mp_chmap_get_reorder(int src[MP_NUM_CHANNELS], const struct mp_chmap *from,
return;
}
for (int n = 0; n < from->num; n++) {
for (int i = 0; i < to->num; i++) {
for (int n = 0; n < to->num; n++) {
for (int i = 0; i < from->num; i++) {
if (to->speaker[n] == from->speaker[i]) {
src[n] = i;
break;
@@ -395,20 +382,12 @@ void mp_chmap_get_reorder(int src[MP_NUM_CHANNELS], const struct mp_chmap *from,
assert(src[n] < 0 || (to->speaker[n] == from->speaker[src[n]]));
}
static int popcount64(uint64_t bits)
{
int r = 0;
for (int n = 0; n < 64; n++)
r += !!(bits & (1ULL << n));
return r;
}
// Return the number of channels only in a.
int mp_chmap_diffn(const struct mp_chmap *a, const struct mp_chmap *b)
{
uint64_t a_mask = mp_chmap_to_lavc_unchecked(a);
uint64_t b_mask = mp_chmap_to_lavc_unchecked(b);
return popcount64((a_mask ^ b_mask) & a_mask);
return av_popcount64((a_mask ^ b_mask) & a_mask);
}
// Returns something like "fl-fr-fc". If there's a standard layout in lavc
@@ -511,6 +490,25 @@ bool mp_chmap_from_str(struct mp_chmap *dst, bstr src)
return true;
}
// Output a human readable "canonical" channel map string. Converting this from
// a string back to a channel map can yield a different map, but the string
// looks nicer. E.g. "fc-fl-fr-na" becomes "3.0".
char *mp_chmap_to_str_hr_buf(char *buf, size_t buf_size, const struct mp_chmap *src)
{
struct mp_chmap map = *src;
mp_chmap_remove_na(&map);
for (int n = 0; std_layout_names[n][0]; n++) {
struct mp_chmap s;
if (mp_chmap_from_str(&s, bstr0(std_layout_names[n][0])) &&
mp_chmap_equals_reordered(&s, &map))
{
map = s;
break;
}
}
return mp_chmap_to_str_buf(buf, buf_size, &map);
}
void mp_chmap_print_help(struct mp_log *log)
{
mp_info(log, "Speakers:\n");
+5 -3
View File
@@ -22,7 +22,7 @@
#include <stdbool.h>
#include "misc/bstr.h"
#define MP_NUM_CHANNELS 8
#define MP_NUM_CHANNELS 16
// Speaker a channel can be assigned to.
// This corresponds to WAVEFORMATEXTENSIBLE channel mask bit indexes.
@@ -47,7 +47,7 @@ enum mp_speaker_id {
MP_SPEAKER_ID_TBL, // TOP_BACK_LEFT
MP_SPEAKER_ID_TBC, // TOP_BACK_CENTER
MP_SPEAKER_ID_TBR, // TOP_BACK_RIGHT
// Inofficial/libav* extensions
// Unofficial/libav* extensions
MP_SPEAKER_ID_DL = 29, // STEREO_LEFT (stereo downmix special speakers)
MP_SPEAKER_ID_DR, // STEREO_RIGHT
MP_SPEAKER_ID_WL, // WIDE_LEFT
@@ -108,7 +108,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_from_channels_alsa(struct mp_chmap *dst, int num_channels);
void mp_chmap_remove_useless_channels(struct mp_chmap *map,
const struct mp_chmap *requested);
@@ -128,6 +127,9 @@ int mp_chmap_diffn(const struct mp_chmap *a, const struct mp_chmap *b);
char *mp_chmap_to_str_buf(char *buf, size_t buf_size, const struct mp_chmap *src);
#define mp_chmap_to_str(m) mp_chmap_to_str_buf((char[64]){0}, 64, (m))
char *mp_chmap_to_str_hr_buf(char *buf, size_t buf_size, const struct mp_chmap *src);
#define mp_chmap_to_str_hr(m) mp_chmap_to_str_hr_buf((char[128]){0}, 128, (m))
bool mp_chmap_from_str(struct mp_chmap *dst, bstr src);
struct mp_log;
+117 -37
View File
@@ -20,6 +20,7 @@
#include <limits.h>
#include "common/common.h"
#include "common/msg.h"
#include "chmap_sel.h"
static const struct mp_chmap speaker_replacements[][2] = {
@@ -58,6 +59,29 @@ static bool replace_speakers(struct mp_chmap *map, struct mp_chmap list[2])
return false;
}
// These go strictly from the first to the second entry and always use the
// full layout (possibly reordered and/or padding channels added).
static const struct mp_chmap preferred_remix[][2] = {
// mono can be perfectly played as stereo
{ MP_CHMAP_INIT_MONO, MP_CHMAP_INIT_STEREO },
};
// Conversion from src to dst is explicitly encouraged and should be preferred
// over "mathematical" upmixes or downmixes (which minimize lost channels).
static bool test_preferred_remix(const struct mp_chmap *src,
const struct mp_chmap *dst)
{
struct mp_chmap src_p = *src, dst_p = *dst;
mp_chmap_remove_na(&src_p);
mp_chmap_remove_na(&dst_p);
for (int n = 0; n < MP_ARRAY_SIZE(preferred_remix); n++) {
if (mp_chmap_equals_reordered(&src_p, &preferred_remix[n][0]) &&
mp_chmap_equals_reordered(&dst_p, &preferred_remix[n][1]))
return true;
}
return false;
}
// Allow all channel layouts that can be expressed with mp_chmap.
// (By default, all layouts are rejected.)
void mp_chmap_sel_add_any(struct mp_chmap_sel *s)
@@ -71,17 +95,6 @@ void mp_chmap_sel_add_waveext(struct mp_chmap_sel *s)
s->allow_waveext = true;
}
// Classic ALSA-based MPlayer layouts.
void mp_chmap_sel_add_alsa_def(struct mp_chmap_sel *s)
{
for (int n = 1; n <= MP_NUM_CHANNELS; n++) {
struct mp_chmap t;
mp_chmap_from_channels_alsa(&t, n);
if (t.num)
mp_chmap_sel_add_map(s, &t);
}
}
// Add a channel map that should be allowed.
void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *map)
{
@@ -176,6 +189,10 @@ bool mp_chmap_sel_adjust(const struct mp_chmap_sel *s, struct mp_chmap *map)
return true;
}
}
if (mp_chmap_sel_fallback(s, map))
return true;
for (int i = 0; i < MP_ARRAY_SIZE(speaker_replacements); i++) {
struct mp_chmap t = *map;
struct mp_chmap *r = (struct mp_chmap *)speaker_replacements[i];
@@ -185,9 +202,6 @@ bool mp_chmap_sel_adjust(const struct mp_chmap_sel *s, struct mp_chmap *map)
}
}
if (mp_chmap_sel_fallback(s, map))
return true;
// Fallback to mono/stereo as last resort
*map = (struct mp_chmap) MP_CHMAP_INIT_STEREO;
if (test_layout(s, map))
@@ -199,40 +213,94 @@ bool mp_chmap_sel_adjust(const struct mp_chmap_sel *s, struct mp_chmap *map)
return false;
}
// Like mp_chmap_diffn(), but find the minimum difference with all possible
// speaker replacements considered.
static int mp_chmap_diffn_r(const struct mp_chmap *a, const struct mp_chmap *b)
{
int mindiff = INT_MAX;
for (int i = -1; i < (int)MP_ARRAY_SIZE(speaker_replacements); i++) {
struct mp_chmap ar = *a;
if (i >= 0) {
struct mp_chmap *r = (struct mp_chmap *)speaker_replacements[i];
if (!replace_speakers(&ar, r))
continue;
}
int d = mp_chmap_diffn(&ar, b);
if (d < mindiff)
mindiff = d;
}
// Special-case: we consider stereo a replacement for mono. (This is not
// true in the other direction. Also, fl-fr is generally not a replacement
// for fc. Thus it's not part of the speaker replacement list.)
struct mp_chmap mono = MP_CHMAP_INIT_MONO;
struct mp_chmap stereo = MP_CHMAP_INIT_STEREO;
if (mp_chmap_equals(&mono, b) && mp_chmap_equals(&stereo, a))
mindiff = 0;
return mindiff;
}
// Decide whether we should prefer old or new for the requested layout.
// Return true if new should be used, false if old should be used.
// If old is empty, always return new (initial case).
static bool mp_chmap_is_better(struct mp_chmap *req, struct mp_chmap *old,
struct mp_chmap *new)
{
int old_lost = mp_chmap_diffn(req, old); // num. channels only in req
int new_lost = mp_chmap_diffn(req, new);
// Initial case
if (!old->num)
return true;
// Exact pick - this also ensures that the best layout is chosen if the
// layouts are the same, but with different order of channels.
if (mp_chmap_equals(req, old))
return false;
if (mp_chmap_equals(req, new))
return true;
// If there's no exact match, strictly do a preferred conversion.
bool old_pref = test_preferred_remix(req, old);
bool new_pref = test_preferred_remix(req, new);
if (old_pref && !new_pref)
return false;
if (!old_pref && new_pref)
return true;
int old_lost_r = mp_chmap_diffn_r(req, old); // num. channels only in req
int new_lost_r = mp_chmap_diffn_r(req, new);
// Imperfect upmix (no real superset) - minimize lost channels
if (new_lost_r != old_lost_r)
return new_lost_r < old_lost_r;
int old_lost = mp_chmap_diffn(req, old);
int new_lost = mp_chmap_diffn(req, new);
// If the situation is equal with replaced speakers, but one of them loses
// less if no replacements are performed, pick the better one, even if it
// means an upmix. This prefers exact supersets over inexact equivalents.
if (new_lost != old_lost)
return new_lost < old_lost;
struct mp_chmap old_p = *old, new_p = *new;
mp_chmap_remove_na(&old_p);
mp_chmap_remove_na(&new_p);
// Some kind of upmix. If it's perfect, prefer the smaller one. Even if not,
// both have equal loss, so also prefer the smaller one.
// Drop padding channels (NA) for the sake of this check, as the number of
// padding channels isn't really meaningful.
if (new_p.num != old_p.num)
return new_p.num < old_p.num;
// Again, with physical channels (minimizes number of NA channels).
return new->num < old->num;
}
// Determine which channel map to fallback to given a source channel map.
bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map)
{
// special case: if possible always fallback mono to stereo (instead of
// looking for a multichannel upmix)
struct mp_chmap mono = MP_CHMAP_INIT_MONO;
struct mp_chmap stereo = MP_CHMAP_INIT_STEREO;
if (mp_chmap_equals(&mono, map) && test_layout(s, &stereo)) {
*map = stereo;
return true;
}
struct mp_chmap best = {0};
for (int n = 0; n < s->num_chmaps; n++) {
@@ -241,17 +309,8 @@ bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map)
if (mp_chmap_is_unknown(&e))
continue;
// in case we didn't match any fallback retry after replacing speakers
for (int i = -1; i < (int)MP_ARRAY_SIZE(speaker_replacements); i++) {
struct mp_chmap t = *map;
if (i >= 0) {
struct mp_chmap *r = (struct mp_chmap *)speaker_replacements[i];
if (!replace_speakers(&t, r))
continue;
}
if (mp_chmap_is_better(&t, &best, &e))
best = e;
}
if (mp_chmap_is_better(map, &best, &e))
best = e;
}
if (best.num) {
@@ -288,3 +347,24 @@ bool mp_chmap_sel_get_def(const struct mp_chmap_sel *s, struct mp_chmap *map,
}
return map->num > 0;
}
// Print the set of allowed channel layouts.
void mp_chmal_sel_log(const struct mp_chmap_sel *s, struct mp_log *log, int lev)
{
if (!mp_msg_test(log, lev))
return;
for (int i = 0; i < s->num_chmaps; i++)
mp_msg(log, lev, " - %s\n", mp_chmap_to_str(&s->chmaps[i]));
for (int i = 0; i < MP_SPEAKER_ID_COUNT; i++) {
if (!s->speakers[i])
continue;
struct mp_chmap l = {.num = 1, .speaker = { i }};
mp_msg(log, lev, " - #%s\n",
i == MP_SPEAKER_ID_FC ? "fc" : mp_chmap_to_str_hr(&l));
}
if (s->allow_waveext)
mp_msg(log, lev, " - waveext\n");
if (s->allow_any)
mp_msg(log, lev, " - anything\n");
}
+3 -1
View File
@@ -37,7 +37,6 @@ struct mp_chmap_sel {
void mp_chmap_sel_add_any(struct mp_chmap_sel *s);
void mp_chmap_sel_add_waveext(struct mp_chmap_sel *s);
void mp_chmap_sel_add_waveext_def(struct mp_chmap_sel *s);
void mp_chmap_sel_add_alsa_def(struct mp_chmap_sel *s);
void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *map);
void mp_chmap_sel_add_speaker(struct mp_chmap_sel *s, int id);
bool mp_chmap_sel_adjust(const struct mp_chmap_sel *s, struct mp_chmap *map);
@@ -45,4 +44,7 @@ bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map);
bool mp_chmap_sel_get_def(const struct mp_chmap_sel *s, struct mp_chmap *map,
int num);
struct mp_log;
void mp_chmal_sel_log(const struct mp_chmap_sel *s, struct mp_log *log, int lev);
#endif
+6 -17
View File
@@ -116,7 +116,7 @@ static int init(struct dec_audio *da, const char *decoder)
mp_set_avopts(da->log, lavc_context, opts->avopts);
lavc_context->codec_tag = sh->format;
lavc_context->codec_tag = sh->codec_tag;
lavc_context->sample_rate = sh_audio->samplerate;
lavc_context->bit_rate = sh_audio->bitrate;
lavc_context->block_align = sh_audio->block_align;
@@ -126,11 +126,7 @@ static int init(struct dec_audio *da, const char *decoder)
lavc_context->channel_layout = mp_chmap_to_lavc(&sh_audio->channels);
// demux_mkv
if (sh_audio->codecdata_len && sh_audio->codecdata &&
!lavc_context->extradata) {
mp_lavc_set_extradata(lavc_context, sh_audio->codecdata,
sh_audio->codecdata_len);
}
mp_lavc_set_extradata(lavc_context, sh->extradata, sh->extradata_size);
if (sh->lav_headers)
mp_copy_lav_codec_headers(lavc_context, sh->lav_headers);
@@ -195,12 +191,6 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
AVPacket pkt;
mp_set_av_packet(&pkt, mpkt, NULL);
// If we don't have a PTS yet, use the first packet PTS we can get.
if (da->pts == MP_NOPTS_VALUE && mpkt && mpkt->pts != MP_NOPTS_VALUE) {
da->pts = mpkt->pts;
da->pts_offset = 0;
}
int got_frame = 0;
av_frame_unref(priv->avframe);
int ret = avcodec_decode_audio4(avctx, priv->avframe, &got_frame, &pkt);
@@ -229,10 +219,6 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
return mpkt ? AD_OK : AD_EOF;
double out_pts = mp_pts_from_av(priv->avframe->pkt_pts, NULL);
if (out_pts != MP_NOPTS_VALUE) {
da->pts = out_pts;
da->pts_offset = 0;
}
struct mp_audio *mpframe = mp_audio_from_avframe(priv->avframe);
if (!mpframe)
@@ -248,6 +234,8 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
}
mp_audio_set_channels(mpframe, &lavc_chmap);
mpframe->pts = out_pts;
#if HAVE_AVFRAME_SKIP_SAMPLES
AVFrameSideData *sd =
av_frame_get_side_data(priv->avframe, AV_FRAME_DATA_SKIP_SAMPLES);
@@ -258,7 +246,8 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
uint32_t skip = MPMIN(priv->skip_samples, mpframe->samples);
if (skip) {
mp_audio_skip_samples(mpframe, skip);
da->pts_offset += skip;
if (mpframe->pts != MP_NOPTS_VALUE)
mpframe->pts += skip / (double)mpframe->rate;
priv->skip_samples -= skip;
}
if (pad <= mpframe->samples)
+90 -20
View File
@@ -34,10 +34,12 @@
struct spdifContext {
struct mp_log *log;
enum AVCodecID codec_id;
AVFormatContext *lavf_ctx;
int out_buffer_len;
uint8_t out_buffer[OUTBUF_SIZE];
bool need_close;
bool use_dts_hd;
struct mp_audio fmt;
};
@@ -76,17 +78,78 @@ static int init(struct dec_audio *da, const char *decoder)
struct spdifContext *spdif_ctx = talloc_zero(NULL, struct spdifContext);
da->priv = spdif_ctx;
spdif_ctx->log = da->log;
spdif_ctx->use_dts_hd = da->opts->dtshd;
if (strcmp(decoder, "dts-hd") == 0) {
decoder = "dts";
spdif_ctx->use_dts_hd = true;
}
spdif_ctx->codec_id = mp_codec_to_av_codec_id(decoder);
return spdif_ctx->codec_id != AV_CODEC_ID_NONE;
}
static int determine_codec_profile(struct dec_audio *da, AVPacket *pkt)
{
struct spdifContext *spdif_ctx = da->priv;
int profile = FF_PROFILE_UNKNOWN;
AVCodecContext *ctx = NULL;
AVFrame *frame = NULL;
AVCodec *codec = avcodec_find_decoder(spdif_ctx->codec_id);
if (!codec)
goto done;
frame = av_frame_alloc();
if (!frame)
goto done;
ctx = avcodec_alloc_context3(codec);
if (!ctx)
goto done;
if (avcodec_open2(ctx, codec, NULL) < 0) {
av_free(ctx); // don't attempt to avcodec_close() an unopened ctx
ctx = NULL;
goto done;
}
int got_frame = 0;
if (avcodec_decode_audio4(ctx, frame, &got_frame, pkt) < 1 || !got_frame)
goto done;
profile = ctx->profile;
done:
av_frame_free(&frame);
if (ctx)
avcodec_close(ctx);
avcodec_free_context(&ctx);
if (profile == FF_PROFILE_UNKNOWN)
MP_WARN(da, "Failed to parse codec profile.\n");
return profile;
}
static int init_filter(struct dec_audio *da, AVPacket *pkt)
{
struct spdifContext *spdif_ctx = da->priv;
int profile = FF_PROFILE_UNKNOWN;
if (spdif_ctx->codec_id == AV_CODEC_ID_DTS)
profile = determine_codec_profile(da, pkt);
AVFormatContext *lavf_ctx = avformat_alloc_context();
if (!lavf_ctx)
goto fail;
spdif_ctx->lavf_ctx = lavf_ctx;
lavf_ctx->oformat = av_guess_format("spdif", NULL, NULL);
if (!lavf_ctx->oformat)
goto fail;
spdif_ctx->lavf_ctx = lavf_ctx;
void *buffer = av_mallocz(OUTBUF_SIZE);
if (!buffer)
abort();
@@ -106,14 +169,14 @@ static int init(struct dec_audio *da, const char *decoder)
if (!stream)
goto fail;
stream->codec->codec_id = mp_codec_to_av_codec_id(decoder);
stream->codec->codec_id = spdif_ctx->codec_id;
AVDictionary *format_opts = NULL;
int num_channels = 0;
int sample_format = 0;
int samplerate = 0;
switch (stream->codec->codec_id) {
switch (spdif_ctx->codec_id) {
case AV_CODEC_ID_AAC:
sample_format = AF_FORMAT_S_AAC;
samplerate = 48000;
@@ -124,18 +187,21 @@ static int init(struct dec_audio *da, const char *decoder)
samplerate = 48000;
num_channels = 2;
break;
case AV_CODEC_ID_DTS:
if (da->opts->dtshd) {
case AV_CODEC_ID_DTS: {
bool is_hd = profile == FF_PROFILE_DTS_HD_HRA ||
profile == FF_PROFILE_DTS_HD_MA;
if (spdif_ctx->use_dts_hd && is_hd) {
av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000
sample_format = AF_FORMAT_S_DTSHD;
samplerate = 192000;
num_channels = 2*4;
sample_format = AF_FORMAT_S_DTSHD;
samplerate = 192000;
num_channels = 2*4;
} else {
sample_format = AF_FORMAT_S_DTS;
samplerate = 48000;
num_channels = 2;
sample_format = AF_FORMAT_S_DTS;
samplerate = 48000;
num_channels = 2;
}
break;
}
case AV_CODEC_ID_EAC3:
sample_format = AF_FORMAT_S_EAC3;
samplerate = 192000;
@@ -167,17 +233,16 @@ static int init(struct dec_audio *da, const char *decoder)
spdif_ctx->need_close = true;
return 1;
return 0;
fail:
uninit(da);
return 0;
return -1;
}
static int decode_packet(struct dec_audio *da, struct mp_audio **out)
{
struct spdifContext *spdif_ctx = da->priv;
AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
spdif_ctx->out_buffer_len = 0;
@@ -188,16 +253,18 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
if (!mpkt)
return AD_EOF;
double pts = mpkt->pts;
AVPacket pkt;
mp_set_av_packet(&pkt, mpkt, NULL);
pkt.pts = pkt.dts = 0;
if (mpkt->pts != MP_NOPTS_VALUE) {
da->pts = mpkt->pts;
da->pts_offset = 0;
if (!spdif_ctx->lavf_ctx) {
if (init_filter(da, &pkt) < 0)
return AD_ERR;
}
int ret = av_write_frame(lavf_ctx, &pkt);
int ret = av_write_frame(spdif_ctx->lavf_ctx, &pkt);
talloc_free(mpkt);
avio_flush(lavf_ctx->pb);
avio_flush(spdif_ctx->lavf_ctx->pb);
if (ret < 0)
return AD_ERR;
@@ -207,6 +274,7 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
return AD_ERR;
memcpy((*out)->planes[0], spdif_ctx->out_buffer, spdif_ctx->out_buffer_len);
(*out)->pts = pts;
return 0;
}
@@ -235,6 +303,8 @@ static void add_decoders(struct mp_decoder_list *list)
"libavformat/spdifenc audio pass-through decoder");
}
}
mp_add_decoder(list, "spdif", "dts", "dts-hd",
"libavformat/spdifenc audio pass-through decoder");
}
const struct ad_functions ad_spdif = {
+38 -11
View File
@@ -18,6 +18,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <assert.h>
#include <libavutil/mem.h>
@@ -52,6 +53,7 @@ static const struct ad_functions * const ad_drivers[] = {
static void uninit_decoder(struct dec_audio *d_audio)
{
audio_reset_decoding(d_audio);
if (d_audio->ad_driver) {
MP_VERBOSE(d_audio, "Uninit audio decoder.\n");
d_audio->ad_driver->uninit(d_audio);
@@ -59,6 +61,8 @@ static void uninit_decoder(struct dec_audio *d_audio)
d_audio->ad_driver = NULL;
talloc_free(d_audio->priv);
d_audio->priv = NULL;
d_audio->afilter->initialized = -1;
d_audio->decode_format = (struct mp_audio){0};
}
static int init_audio_codec(struct dec_audio *d_audio, const char *decoder)
@@ -81,11 +85,21 @@ struct mp_decoder_list *audio_decoder_list(void)
return list;
}
static struct mp_decoder_list *audio_select_decoders(const char *codec,
char *selection)
static struct mp_decoder_list *audio_select_decoders(struct dec_audio *d_audio)
{
struct MPOpts *opts = d_audio->opts;
const char *codec = d_audio->header->codec;
struct mp_decoder_list *list = audio_decoder_list();
struct mp_decoder_list *new = mp_select_decoders(list, codec, selection);
struct mp_decoder_list *new =
mp_select_decoders(list, codec, opts->audio_decoders);
if (d_audio->spdif_passthrough) {
struct mp_decoder_list *spdif =
mp_select_decoder_list(list, codec, "spdif", opts->audio_spdif);
mp_append_decoders(spdif, new);
talloc_free(new);
new = spdif;
}
talloc_free(list);
return new;
}
@@ -99,14 +113,13 @@ static const struct ad_functions *find_driver(const char *name)
return NULL;
}
int audio_init_best_codec(struct dec_audio *d_audio, char *audio_decoders)
int audio_init_best_codec(struct dec_audio *d_audio)
{
uninit_decoder(d_audio);
assert(!d_audio->ad_driver);
audio_reset_decoding(d_audio);
struct mp_decoder_entry *decoder = NULL;
struct mp_decoder_list *list =
audio_select_decoders(d_audio->header->codec, audio_decoders);
struct mp_decoder_list *list = audio_select_decoders(d_audio);
mp_print_decoders(d_audio->log, MSGL_V, "Codec list:", list);
@@ -145,8 +158,8 @@ void audio_uninit(struct dec_audio *d_audio)
if (!d_audio)
return;
MP_VERBOSE(d_audio, "Uninit audio filters...\n");
af_destroy(d_audio->afilter);
uninit_decoder(d_audio);
af_destroy(d_audio->afilter);
talloc_free(d_audio->waiting);
talloc_free(d_audio);
}
@@ -158,14 +171,28 @@ static int decode_new_frame(struct dec_audio *da)
if (ret < 0)
return ret;
if (da->pts == MP_NOPTS_VALUE && da->header->missing_timestamps)
da->pts = 0;
if (da->waiting) {
if (da->waiting->pts != MP_NOPTS_VALUE) {
if (da->pts != MP_NOPTS_VALUE) {
da->pts += da->pts_offset / (double)da->waiting->rate;
da->pts_offset = 0;
}
// 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 || da->pts_offset != 0 ||
fabs(da->pts - da->waiting->pts) > 0.001)
{
da->pts = da->waiting->pts;
da->pts_offset = 0;
}
}
da->pts_offset += da->waiting->samples;
da->decode_format = *da->waiting;
mp_audio_set_null_data(&da->decode_format);
}
if (da->pts == MP_NOPTS_VALUE && da->header->missing_timestamps)
da->pts = 0;
}
return mp_audio_config_valid(da->waiting) ? AD_OK : AD_ERR;
}
+2 -1
View File
@@ -30,6 +30,7 @@ struct dec_audio {
struct mp_log *log;
struct MPOpts *opts;
struct mpv_global *global;
bool spdif_passthrough, spdif_failed;
const struct ad_functions *ad_driver;
struct sh_stream *header;
struct af_stream *afilter;
@@ -57,7 +58,7 @@ enum {
};
struct mp_decoder_list *audio_decoder_list(void);
int audio_init_best_codec(struct dec_audio *d_audio, char *audio_decoders);
int audio_init_best_codec(struct dec_audio *d_audio);
int audio_decode(struct dec_audio *d_audio, struct mp_audio_buffer *outbuf,
int minsamples);
int initial_audio_decode(struct dec_audio *d_audio);
+40 -137
View File
@@ -31,70 +31,37 @@
#include "af.h"
// Static list of filters
extern const struct af_info af_info_dummy;
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_force;
extern const struct af_info af_info_volume;
extern const struct af_info af_info_equalizer;
extern const struct af_info af_info_pan;
extern const struct af_info af_info_surround;
extern const struct af_info af_info_sub;
extern const struct af_info af_info_export;
extern const struct af_info af_info_drc;
extern const struct af_info af_info_extrastereo;
extern const struct af_info af_info_lavcac3enc;
extern const struct af_info af_info_lavrresample;
extern const struct af_info af_info_sweep;
extern const struct af_info af_info_hrtf;
extern const struct af_info af_info_ladspa;
extern const struct af_info af_info_center;
extern const struct af_info af_info_sinesuppress;
extern const struct af_info af_info_karaoke;
extern const struct af_info af_info_scaletempo;
extern const struct af_info af_info_bs2b;
extern const struct af_info af_info_lavfi;
extern const struct af_info af_info_convert24;
extern const struct af_info af_info_convertsignendian;
extern const struct af_info af_info_rubberband;
static const struct af_info *const filter_list[] = {
&af_info_dummy,
&af_info_delay,
&af_info_channels,
&af_info_format,
&af_info_volume,
&af_info_equalizer,
&af_info_pan,
&af_info_surround,
&af_info_sub,
&af_info_export,
&af_info_drc,
&af_info_extrastereo,
&af_info_lavcac3enc,
&af_info_lavrresample,
&af_info_sweep,
&af_info_hrtf,
#if HAVE_LADSPA
&af_info_ladspa,
#endif
#if HAVE_RUBBERBAND
&af_info_rubberband,
#endif
&af_info_center,
&af_info_sinesuppress,
&af_info_karaoke,
&af_info_scaletempo,
#if HAVE_LIBBS2B
&af_info_bs2b,
#endif
#if HAVE_LIBAVFILTER
&af_info_lavfi,
#endif
// Must come last, because they're fallback format conversion filter
&af_info_convert24,
&af_info_convertsignendian,
NULL
};
@@ -192,24 +159,11 @@ static struct af_instance *af_create(struct af_stream *s, char *name,
MP_ERR(s, "Couldn't find audio filter '%s'.\n", name);
return NULL;
}
const struct af_info *info = desc.p;
/* Make sure that the filter is not already in the list if it is
non-reentrant */
if (info->flags & AF_FLAGS_NOT_REENTRANT) {
for (struct af_instance *cur = s->first; cur; cur = cur->next) {
if (cur->info == info) {
MP_ERR(s, "There can only be one "
"instance of the filter '%s' in each stream\n", name);
return NULL;
}
}
}
MP_VERBOSE(s, "Adding filter %s \n", name);
struct af_instance *af = talloc_zero(NULL, struct af_instance);
*af = (struct af_instance) {
.info = info,
.info = desc.p,
.data = talloc_zero(af, struct mp_audio),
.log = mp_log_new(af, s->log, name),
.replaygain_data = s->replaygain_data,
@@ -334,89 +288,9 @@ 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 int af_count_filters(struct af_stream *s)
{
int count = 0;
for (struct af_instance *af = s->first; af; af = af->next)
count++;
return count;
}
// Finds the first conversion filter on the way from srcfmt to dstfmt.
// Conversions form a DAG: each node is a format/filter pair, and possible
// conversions are edges. We search the DAG for the shortest path.
// Some cases visit the same filter multiple times, but with different formats
// (like u24le->s8), so one node per format or filter separate is not enough.
// Returns the filter and dest. format for the first conversion step.
// (So we know what conversion filter with what format to insert next.)
static char *af_find_conversion_filter(int srcfmt, int *dstfmt)
{
#define MAX_NODES (64 * 32)
int num_fmt = 0, num_filt = 0;
for (int n = 0; filter_list[n]; n++)
num_filt = n + 1;
for (int n = 0; af_fmtstr_table[n].format; n++)
num_fmt = n + 1;
int num_nodes = num_fmt * num_filt;
assert(num_nodes < MAX_NODES);
bool visited[MAX_NODES] = {0};
unsigned char distance[MAX_NODES];
short previous[MAX_NODES] = {0};
for (int n = 0; n < num_nodes; n++) {
distance[n] = 255;
if (af_fmtstr_table[n % num_fmt].format == srcfmt)
distance[n] = 0;
}
while (1) {
int next = -1;
for (int n = 0; n < num_nodes; n++) {
if (!visited[n] && (next < 0 || (distance[n] < distance[next])))
next = n;
}
if (next < 0 || distance[next] == 255)
return NULL;
visited[next] = true;
int fmt = next % num_fmt;
if (af_fmtstr_table[fmt].format == *dstfmt) {
// Best match found
for (int cur = next; cur >= 0; cur = previous[cur] - 1) {
if (distance[cur] == 1) {
*dstfmt = af_fmtstr_table[cur % num_fmt].format;
return (char *)filter_list[cur / num_fmt]->name;
}
}
return NULL;
}
for (int n = 0; filter_list[n]; n++) {
const struct af_info *af = filter_list[n];
if (!af->test_conversion)
continue;
for (int i = 0; af_fmtstr_table[i].format; i++) {
if (i != fmt && af->test_conversion(af_fmtstr_table[fmt].format,
af_fmtstr_table[i].format))
{
int other = n * num_fmt + i;
int ndist = distance[next] + 1;
if (ndist < distance[other]) {
distance[other] = ndist;
previous[other] = next + 1;
}
}
}
}
}
assert(0);
#undef MAX_NODES
}
static bool af_is_conversion_filter(struct af_instance *af)
{
return af && af->info->test_conversion != NULL;
return af && strcmp(af->info->name, "lavrresample") == 0;
}
// in is what af can take as input - insert a conversion filter if the actual
@@ -436,21 +310,24 @@ static int af_fix_format_conversion(struct af_stream *s,
if (actual.format == in.format)
return AF_FALSE;
int dstfmt = in.format;
char *filter = af_find_conversion_filter(actual.format, &dstfmt);
if (!filter)
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)))
if (AF_OK != (rv = new->control(new, AF_CONTROL_SET_FORMAT, &dstfmt))) {
af_remove(s, new);
return rv;
}
*p_af = new;
return AF_OK;
}
@@ -528,8 +405,8 @@ static int af_reinit(struct af_stream *s)
// 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 7 retries per filter (channel, rate, 5x format conversions)
int max_retry = af_count_filters(s) * 7;
// Up to 4 retries per filter (channel, rate, format conversions)
int max_retry = 4;
int retry = 0;
while (af) {
if (retry >= max_retry)
@@ -575,8 +452,8 @@ static int af_reinit(struct af_stream *s)
int fmt_in1 = af->prev->data->format;
int fmt_in2 = in.format;
if (af_fmt_is_valid(fmt_in1) && af_fmt_is_valid(fmt_in2)) {
bool spd1 = AF_FORMAT_IS_IEC61937(fmt_in1);
bool spd2 = AF_FORMAT_IS_IEC61937(fmt_in2);
bool spd1 = af_fmt_is_spdif(fmt_in1);
bool spd2 = af_fmt_is_spdif(fmt_in2);
if (spd1 != spd2 && af->next) {
MP_WARN(af, "Filter %s apparently cannot be used due to "
"spdif passthrough - removing it.\n",
@@ -584,7 +461,8 @@ static int af_reinit(struct af_stream *s)
struct af_instance *aft = af->prev;
af_remove(s, af);
af = aft->next;
break;
retry++;
continue;
}
}
goto negotiate_error;
@@ -601,6 +479,8 @@ 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
@@ -733,7 +613,7 @@ struct af_instance *af_add(struct af_stream *s, char *name, char *label,
return NULL;
new->label = talloc_strdup(new, label);
// Reinitalize the filter list
// Reinitialize the filter list
if (af_reinit(s) != AF_OK) {
af_remove_by_label(s, label);
return NULL;
@@ -803,6 +683,18 @@ void af_control_all(struct af_stream *s, int cmd, void *arg)
af->control(af, cmd, arg);
}
int af_control_by_label(struct af_stream *s, int cmd, void *arg, bstr label)
{
char *label_str = bstrdup0(NULL, label);
struct af_instance *cur = af_find_by_label(s, label_str);
talloc_free(label_str);
if (cur) {
return cur->control ? cur->control(cur, cmd, arg) : CONTROL_NA;
} else {
return CONTROL_UNKNOWN;
}
}
// Used by filters to add a filtered frame to the output queue.
// Ownership of frame is transferred from caller to the filter chain.
void af_add_output_frame(struct af_instance *af, struct mp_audio *frame)
@@ -832,6 +724,16 @@ static struct mp_audio *af_dequeue_output_frame(struct af_instance *af)
return res;
}
static void read_remaining(struct af_instance *af)
{
int num_frames;
do {
num_frames = af->num_out_queued;
if (!af->filter_out || af->filter_out(af) < 0)
break;
} while (num_frames != af->num_out_queued);
}
static int af_do_filter(struct af_instance *af, struct mp_audio *frame)
{
if (frame)
@@ -871,6 +773,7 @@ int af_output_frame(struct af_stream *s, bool eof)
// Flush remaining frames on EOF, but do that only if the previous
// filters have been flushed (i.e. they have no more output).
if (eof && !last) {
read_remaining(cur);
int r = af_do_filter(cur, NULL);
if (r < 0)
return r;
+11 -14
View File
@@ -27,6 +27,7 @@
#include "audio/chmap.h"
#include "audio/audio.h"
#include "common/msg.h"
#include "common/common.h"
struct af_instance;
struct mpv_global;
@@ -34,10 +35,6 @@ struct mpv_global;
// Number of channels
#define AF_NCH MP_NUM_CHANNELS
// Flags used for defining the behavior of an audio filter
#define AF_FLAGS_REENTRANT 0x00000000
#define AF_FLAGS_NOT_REENTRANT 0x00000001
// Flags for af->filter()
#define AF_FILTER_FLAG_EOF 1
@@ -46,9 +43,7 @@ struct mpv_global;
struct af_info {
const char *info;
const char *name;
const int flags;
int (*open)(struct af_instance *vf);
bool (*test_conversion)(int src_format, int dst_format);
int priv_size;
const void *priv_defaults;
const struct m_option *options;
@@ -105,13 +100,12 @@ struct af_stream {
};
// Return values
#define AF_DETACH 2
#define AF_OK 1
#define AF_TRUE 1
#define AF_FALSE 0
#define AF_UNKNOWN -1
#define AF_ERROR -2
#define AF_FATAL -3
#define AF_DETACH (CONTROL_OK + 1)
#define AF_OK CONTROL_OK
#define AF_TRUE CONTROL_TRUE
#define AF_FALSE CONTROL_FALSE
#define AF_UNKNOWN CONTROL_UNKNOWN
#define AF_ERROR CONTROL_ERROR
// Parameters for af_control_*
enum af_control {
@@ -128,6 +122,7 @@ enum af_control {
AF_CONTROL_GET_PAN_BALANCE,
AF_CONTROL_SET_PLAYBACK_SPEED,
AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE,
AF_CONTROL_GET_METADATA,
};
// Argument for AF_CONTROL_SET_PAN_LEVEL
@@ -146,6 +141,7 @@ int af_remove_by_label(struct af_stream *s, char *label);
struct af_instance *af_find_by_label(struct af_stream *s, char *label);
struct af_instance *af_control_any_rev(struct af_stream *s, int cmd, void *arg);
void af_control_all(struct af_stream *s, int cmd, void *arg);
int af_control_by_label(struct af_stream *s, int cmd, void *arg, bstr label);
void af_seek_reset(struct af_stream *s);
void af_add_output_frame(struct af_instance *af, struct mp_audio *frame);
@@ -158,8 +154,9 @@ double af_calc_delay(struct af_stream *s);
int af_test_output(struct af_instance *af, struct mp_audio *out);
int af_from_dB(int n, float *in, float *out, float k, float mi, float ma);
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 */
-172
View File
@@ -1,172 +0,0 @@
/*
* The Bauer stereophonic-to-binaural DSP using bs2b library:
* http://bs2b.sourceforge.net/
*
* Copyright (c) 2009 Andrew Savchenko
*
* 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 <bs2b.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include "af.h"
#include "options/m_option.h"
/// Internal specific data of the filter
struct af_bs2b {
int fcut; ///< cut frequency in Hz
int feed; ///< feed level for low frequencies in 0.1*dB
int profile ; ///< profile (available crossfeed presets)
t_bs2bdp filter; ///< instance of a library filter
};
#define DEF_FILTER(fmt, name) \
static int filter_##name(struct af_instance *af, struct mp_audio *data) \
{ \
if (!data) \
return 0; \
if (af_make_writeable(af, data) < 0) { \
talloc_free(data); \
return -1; \
} \
bs2b_cross_feed_##name(((struct af_bs2b*)(af->priv))->filter, \
(data->planes[0]), data->samples); \
af_add_output_frame(af, data); \
return 0; \
}
#define GET_FILTER(fmt, name) \
case AF_FORMAT_##fmt: return filter_##name;
#define FILTERS \
FILTER(FLOAT, f) \
FILTER(S32, s32) \
FILTER(U32, u32) \
FILTER(S24, s24) \
FILTER(U24, u24) \
FILTER(S16, s16) \
FILTER(U16, u16) \
FILTER(S8, s8) \
FILTER(U8, u8)
#define FILTER DEF_FILTER
FILTERS
#undef FILTER
typedef int (*filter)(struct af_instance *af, struct mp_audio *d);
static filter get_filter(int fmt)
{
switch (fmt) {
#define FILTER GET_FILTER
FILTERS
#undef FILTER
default: return NULL;
}
}
/// Initialization and runtime control
static int control(struct af_instance *af, int cmd, void *arg)
{
struct af_bs2b *s = af->priv;
switch (cmd) {
case AF_CONTROL_REINIT: {
int format;
// Sanity check
if (!arg) return AF_ERROR;
format = ((struct mp_audio*)arg)->format;
af->data->rate = ((struct mp_audio*)arg)->rate;
mp_audio_set_num_channels(af->data, 2); // bs2b is useful only for 2ch audio
mp_audio_set_format(af->data, format);
/* check for formats supported by libbs2b
and assign corresponding handlers */
af->filter_frame = get_filter(format);
if (!af->filter_frame) {
af->filter_frame = filter_f;
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
}
// bs2b have srate limits, try to resample if needed
if (af->data->rate > BS2B_MAXSRATE || af->data->rate < BS2B_MINSRATE) {
af->data->rate = BS2B_DEFAULT_SRATE;
MP_WARN(af, "Requested sample rate %d Hz is out of bounds [%d..%d] Hz.\n"
"Trying to resample to %d Hz.\n",
af->data->rate, BS2B_MINSRATE, BS2B_MAXSRATE, BS2B_DEFAULT_SRATE);
}
bs2b_set_srate(s->filter, (long)af->data->rate);
MP_VERBOSE(af, "using format %s\n",
af_fmt_to_str(af->data->format));
return af_test_output(af,(struct mp_audio*)arg);
}
}
return AF_UNKNOWN;
}
/// Deallocate memory and close library
static void uninit(struct af_instance *af)
{
struct af_bs2b *s = af->priv;
if (s->filter)
bs2b_close(s->filter);
}
/// Allocate memory, set function pointers and init library
static int af_open(struct af_instance *af)
{
struct af_bs2b *s = af->priv;
af->control = control;
af->uninit = uninit;
// NULL means failed initialization
if (!(s->filter = bs2b_open())) {
return AF_ERROR;
}
if (s->profile)
bs2b_set_level(s->filter, s->profile);
// set fcut and feed only if specified, otherwise defaults will be used
if (s->fcut)
bs2b_set_level_fcut(s->filter, s->fcut);
if (s->feed)
bs2b_set_level_feed(s->filter, s->feed);
return AF_OK;
}
#define OPT_BASE_STRUCT struct af_bs2b
/// Description of this filter
const struct af_info af_info_bs2b = {
.info = "Bauer stereophonic-to-binaural audio filter",
.name = "bs2b",
.open = af_open,
.priv_size = sizeof(struct af_bs2b),
.options = (const struct m_option[]) {
OPT_INTRANGE("fcut", fcut, 0, BS2B_MINFCUT, BS2B_MAXFCUT),
OPT_INTRANGE("feed", feed, 0, BS2B_MINFEED, BS2B_MAXFEED),
OPT_CHOICE("profile", profile, 0,
({"unset", 0},
{"default", BS2B_DEFAULT_CLEVEL},
{"cmoy", BS2B_CMOY_CLEVEL},
{"jmeier", BS2B_JMEIER_CLEVEL})),
{0}
},
};
-104
View File
@@ -1,104 +0,0 @@
/*
* This filter adds a center channel to the audio stream by
* averaging the left and right channel.
* There are two runtime controls one for setting which channel
* to insert the center-audio into called AF_CONTROL_SUB_CH.
*
* FIXME: implement a high-pass filter for better results.
*
* copyright (c) 2005 Alex Beregszaszi
*
* 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 "common/common.h"
#include "af.h"
// Data for specific instances of this filter
typedef struct af_center_s
{
int ch; // Channel number which to insert the filtered data
}af_center_t;
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
af_center_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_channels_old(af->data, MPMAX(s->ch+1,((struct mp_audio*)arg)->nch));
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
return af_test_output(af,(struct mp_audio*)arg);
}
}
return AF_UNKNOWN;
}
static int filter_frame(struct af_instance* af, struct mp_audio* data)
{
if (!data)
return 0;
if (af_make_writeable(af, data) < 0) {
talloc_free(data);
return -1;
}
struct mp_audio* c = data; // Current working data
af_center_t* s = af->priv; // Setup for this instance
float* a = c->planes[0]; // Audio data
int nch = c->nch; // Number of channels
int len = c->samples*c->nch; // Number of samples in current audio block
int ch = s->ch; // Channel in which to insert the center audio
register int i;
// Run filter
for(i=0;i<len;i+=nch){
// Average left and right
a[i+ch] = (a[i]/2) + (a[i+1]/2);
}
af_add_output_frame(af, data);
return 0;
}
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
af->control=control;
af->filter_frame = filter_frame;
return AF_OK;
}
#define OPT_BASE_STRUCT af_center_t
const struct af_info af_info_center = {
.info = "Audio filter for adding a center channel",
.name = "center",
.flags = AF_FLAGS_NOT_REENTRANT,
.open = af_open,
.priv_size = sizeof(af_center_t),
.options = (const struct m_option[]) {
OPT_INTRANGE("channel", ch, 0, 0, AF_NCH - 1, OPTDEF_INT(1)),
{0}
},
};
-122
View File
@@ -1,122 +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 <stdlib.h>
#include <assert.h>
#include "audio/format.h"
#include "af.h"
#include "osdep/endian.h"
static bool test_conversion(int src_format, int dst_format)
{
return (src_format == AF_FORMAT_U24 && dst_format == AF_FORMAT_U32) ||
(src_format == AF_FORMAT_S24 && dst_format == AF_FORMAT_S32) ||
(src_format == AF_FORMAT_U32 && dst_format == AF_FORMAT_U24) ||
(src_format == AF_FORMAT_S32 && dst_format == AF_FORMAT_S24);
}
static int control(struct af_instance *af, int cmd, void *arg)
{
switch (cmd) {
case AF_CONTROL_REINIT: {
struct mp_audio *in = arg;
struct mp_audio orig_in = *in;
struct mp_audio *out = af->data;
if (!test_conversion(in->format, out->format))
return AF_DETACH;
if ((in->format & AF_FORMAT_BITS_MASK) == AF_FORMAT_24BIT) {
mp_audio_set_format(out, af_fmt_change_bits(in->format, 32));
} else if ((in->format & AF_FORMAT_BITS_MASK) == AF_FORMAT_32BIT) {
mp_audio_set_format(out, af_fmt_change_bits(in->format, 24));
} else {
abort();
}
out->rate = in->rate;
mp_audio_set_channels(out, &in->channels);
assert(test_conversion(in->format, out->format));
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
}
case AF_CONTROL_SET_FORMAT: {
mp_audio_set_format(af->data, *(int*)arg);
return AF_OK;
}
}
return AF_UNKNOWN;
}
// The LSB is always ignored.
#if BYTE_ORDER == BIG_ENDIAN
#define SHIFT(x) ((3-(x))*8)
#else
#define SHIFT(x) (((x)+1)*8)
#endif
static int filter(struct af_instance *af, struct mp_audio *data)
{
if (!data)
return 0;
struct mp_audio *out =
mp_audio_pool_get(af->out_pool, af->data, data->samples);
if (!out) {
talloc_free(data);
return -1;
}
mp_audio_copy_attributes(out, data);
size_t len = mp_audio_psize(data) / data->bps;
if (data->bps == 4) {
for (int s = 0; s < len; s++) {
uint32_t val = *((uint32_t *)data->planes[0] + s);
uint8_t *ptr = (uint8_t *)out->planes[0] + s * 3;
ptr[0] = val >> SHIFT(0);
ptr[1] = val >> SHIFT(1);
ptr[2] = val >> SHIFT(2);
}
} else {
for (int s = 0; s < len; s++) {
uint8_t *ptr = (uint8_t *)data->planes[0] + s * 3;
uint32_t val = ptr[0] << SHIFT(0)
| ptr[1] << SHIFT(1)
| ptr[2] << SHIFT(2);
*((uint32_t *)out->planes[0] + s) = val;
}
}
talloc_free(data);
af_add_output_frame(af, out);
return 0;
}
static int af_open(struct af_instance *af)
{
af->control = control;
af->filter_frame = filter;
return AF_OK;
}
const struct af_info af_info_convert24 = {
.info = "Convert between 24 and 32 bit sample format",
.name = "convert24",
.open = af_open,
.test_conversion = test_conversion,
};
-107
View File
@@ -1,107 +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 <stdlib.h>
#include <assert.h>
#include "af.h"
#include "audio/format.h"
#include "osdep/endian.h"
static bool test_conversion(int src_format, int dst_format)
{
if ((src_format & AF_FORMAT_PLANAR) ||
(dst_format & AF_FORMAT_PLANAR))
return false;
if (((src_format & ~AF_FORMAT_SIGN_MASK) ==
(dst_format & ~AF_FORMAT_SIGN_MASK)) &&
((src_format & AF_FORMAT_TYPE_MASK) == AF_FORMAT_I))
return true;
return false;
}
static int control(struct af_instance *af, int cmd, void *arg)
{
switch (cmd) {
case AF_CONTROL_REINIT: {
struct mp_audio *in = arg;
struct mp_audio orig_in = *in;
struct mp_audio *out = af->data;
if (!test_conversion(in->format, out->format))
return AF_DETACH;
out->rate = in->rate;
mp_audio_set_channels(out, &in->channels);
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
}
case AF_CONTROL_SET_FORMAT: {
mp_audio_set_format(af->data, *(int*)arg);
return AF_OK;
}
}
return AF_UNKNOWN;
}
static void si2us(void *data, int len, int bps)
{
ptrdiff_t i = -(len * bps);
uint8_t *p = &((uint8_t *)data)[len * bps];
if (BYTE_ORDER == LITTLE_ENDIAN && bps > 1)
p += bps - 1;
if (len <= 0)
return;
do {
p[i] ^= 0x80;
} while (i += bps);
}
static int filter(struct af_instance *af, struct mp_audio *data)
{
if (!data)
return 0;
if (af_make_writeable(af, data) < 0) {
talloc_free(data);
return -1;
}
int infmt = data->format;
int outfmt = af->data->format;
size_t len = data->samples * data->nch;
if ((infmt & AF_FORMAT_SIGN_MASK) != (outfmt & AF_FORMAT_SIGN_MASK))
si2us(data->planes[0], len, data->bps);
mp_audio_set_format(data, outfmt);
af_add_output_frame(af, data);
return 0;
}
static int af_open(struct af_instance *af)
{
af->control = control;
af->filter_frame = filter;
return AF_OK;
}
const struct af_info af_info_convertsignendian = {
.info = "Convert between sample format sign",
.name = "convertsign",
.open = af_open,
.test_conversion = test_conversion,
};
+4 -5
View File
@@ -131,7 +131,7 @@ static void method1_int16(af_drc_t *s, struct mp_audio *c)
data[i] = tmp;
}
// Evaulation of newavg (not 100% accurate because of values clamping)
// Evaluation of newavg (not 100% accurate because of values clamping)
newavg = s->mul * curavg;
// Stores computed values for future smoothing
@@ -168,7 +168,7 @@ static void method1_float(af_drc_t *s, struct mp_audio *c)
for (i = 0; i < len; i++)
data[i] *= s->mul;
// Evaulation of newavg (not 100% accurate because of values clamping)
// Evaluation of newavg (not 100% accurate because of values clamping)
newavg = s->mul * curavg;
// Stores computed values for future smoothing
@@ -216,7 +216,7 @@ static void method2_int16(af_drc_t *s, struct mp_audio *c)
data[i] = tmp;
}
// Evaulation of newavg (not 100% accurate because of values clamping)
// Evaluation of newavg (not 100% accurate because of values clamping)
newavg = s->mul * curavg;
// Stores computed values for future smoothing
@@ -262,7 +262,7 @@ static void method2_float(af_drc_t *s, struct mp_audio *c)
for (i = 0; i < len; i++)
data[i] *= s->mul;
// Evaulation of newavg (not 100% accurate because of values clamping)
// Evaluation of newavg (not 100% accurate because of values clamping)
newavg = s->mul * curavg;
// Stores computed values for future smoothing
@@ -324,7 +324,6 @@ static int af_open(struct af_instance* af){
const struct af_info af_info_drc = {
.info = "Dynamic range compression filter",
.name = "drc",
.flags = AF_FLAGS_NOT_REENTRANT,
.open = af_open,
.priv_size = sizeof(af_drc_t),
.options = (const struct m_option[]) {
-61
View File
@@ -1,61 +0,0 @@
/*
* The name speaks for itself. This filter is a dummy and will
* not blow up regardless of what you do with it.
*
* 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 "af.h"
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
switch(cmd){
case AF_CONTROL_REINIT: ;
*af->data = *(struct mp_audio*)arg;
MP_VERBOSE(af, "Was reinitialized: %iHz/%ich/%s\n",
af->data->rate,af->data->nch,af_fmt_to_str(af->data->format));
return AF_OK;
}
return AF_UNKNOWN;
}
// Filter data through filter
static int filter(struct af_instance* af, struct mp_audio* data)
{
af_add_output_frame(af, data);
return 0;
}
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
af->control=control;
af->filter_frame=filter;
return AF_OK;
}
// Description of this filter
const struct af_info af_info_dummy = {
.info = "dummy",
.name = "dummy",
.open = af_open,
};
-1
View File
@@ -203,7 +203,6 @@ static int af_open(struct af_instance* af){
const struct af_info af_info_equalizer = {
.info = "Equalizer audio filter",
.name = "equalizer",
.flags = AF_FLAGS_NOT_REENTRANT,
.open = af_open,
.priv_size = sizeof(af_equalizer_t),
.options = (const struct m_option[]) {
-237
View File
@@ -1,237 +0,0 @@
/*
* This audio filter exports the incoming signal to other processes
* using memory mapping. The memory mapped area contains a header:
* int nch,
* int size,
* unsigned long long counter (updated every time the contents of
* the area changes),
* the rest is payload (non-interleaved).
*
* Authors: Anders; Gustavo Sverzut Barbieri <gustavo.barbieri@ic.unicamp.br>
*
* 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 <unistd.h>
#include "config.h"
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "osdep/io.h"
#include "talloc.h"
#include "af.h"
#include "options/path.h"
#define DEF_SZ 512 // default buffer size (in samples)
#define SHARED_FILE "mpv-af_export" /* default file name
(relative to ~/.mpv/ */
#define SIZE_HEADER (2 * sizeof(int) + sizeof(unsigned long long))
// Data for specific instances of this filter
typedef struct af_export_s
{
unsigned long long count; // Used for sync
void* buf[AF_NCH]; // Buffers for storing the data before it is exported
int sz; // Size of buffer in samples
int wi; // Write index
int fd; // File descriptor to shared memory area
char* filename; // File to export data
uint8_t *mmap_area; // MMap shared area
} af_export_t;
/* Initialization and runtime control
af audio filter instance
cmd control command
arg argument
*/
static int control(struct af_instance* af, int cmd, void* arg)
{
af_export_t* s = af->priv;
switch (cmd){
case AF_CONTROL_REINIT:{
int i=0;
int mapsize;
// Free previous buffers
free(s->buf[0]);
// unmap previous area
if(s->mmap_area)
munmap(s->mmap_area, SIZE_HEADER + (af->data->bps*s->sz*af->data->nch));
// close previous file descriptor
if(s->fd)
close(s->fd);
// Accept only int16_t as input format (which sucks)
mp_audio_copy_config(af->data, (struct mp_audio*)arg);
mp_audio_set_format(af->data, AF_FORMAT_S16);
// Allocate new buffers (as one continuous block)
s->buf[0] = calloc(s->sz*af->data->nch, af->data->bps);
if(NULL == s->buf[0]) {
MP_FATAL(af, "Out of memory\n");
return AF_ERROR;
}
for(i = 1; i < af->data->nch; i++)
s->buf[i] = (uint8_t *)s->buf[0] + i*s->sz*af->data->bps;
if (!s->filename) {
MP_FATAL(af, "No filename set.\n");
return AF_ERROR;
}
// Init memory mapping
s->fd = open(s->filename, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
MP_INFO(af, "Exporting to file: %s\n", s->filename);
if(s->fd < 0) {
MP_FATAL(af, "Could not open/create file: %s\n",
s->filename);
return AF_ERROR;
}
// header + buffer
mapsize = (SIZE_HEADER + (af->data->bps * s->sz * af->data->nch));
// grow file to needed size
for(i = 0; i < mapsize; i++){
char null = 0;
write(s->fd, (void*) &null, 1);
}
// mmap size
s->mmap_area = mmap(0, mapsize, PROT_READ|PROT_WRITE,MAP_SHARED, s->fd, 0);
if(s->mmap_area == NULL)
MP_FATAL(af, "Could not mmap file %s\n", s->filename);
MP_INFO(af, "Memory mapped to file: %s (%p)\n",
s->filename, s->mmap_area);
// Initialize header
*((int*)s->mmap_area) = af->data->nch;
*((int*)s->mmap_area + 1) = s->sz * af->data->bps * af->data->nch;
msync(s->mmap_area, mapsize, MS_ASYNC);
// Use test_output to return FALSE if necessary
return af_test_output(af, (struct mp_audio*)arg);
}
}
return AF_UNKNOWN;
}
/* Free allocated memory and clean up other stuff too.
af audio filter instance
*/
static void uninit( struct af_instance* af )
{
af_export_t* s = af->priv;
free(s->buf[0]);
// Free mmaped area
if(s->mmap_area)
munmap(s->mmap_area, sizeof(af_export_t));
if(s->fd > -1)
close(s->fd);
}
/* Filter data through filter
af audio filter instance
data audio data
*/
static int filter(struct af_instance *af, struct mp_audio *data)
{
if (!data)
return 0;
struct mp_audio* c = data; // Current working data
af_export_t* s = af->priv; // Setup for this instance
int16_t* a = c->planes[0]; // Incomming sound
int nch = c->nch; // Number of channels
int len = c->samples*c->nch; // Number of sample in data chunk
int sz = s->sz; // buffer size (in samples)
int flag = 0; // Set to 1 if buffer is filled
int ch, i;
// Fill all buffers
for(ch = 0; ch < nch; ch++){
int wi = s->wi; // Reset write index
int16_t* b = s->buf[ch]; // Current buffer
// Copy data to export buffers
for(i = ch; i < len; i += nch){
b[wi++] = a[i];
if(wi >= sz){ // Don't write outside the end of the buffer
flag = 1;
break;
}
}
s->wi = wi % s->sz;
}
// Export buffer to mmaped area
if(flag){
// update buffer in mapped area
memcpy(s->mmap_area + SIZE_HEADER, s->buf[0], sz * c->bps * nch);
s->count++; // increment counter (to sync)
memcpy(s->mmap_area + SIZE_HEADER - sizeof(s->count),
&(s->count), sizeof(s->count));
}
af_add_output_frame(af, data);
return 0;
}
/* Allocate memory and set function pointers
af audio filter instance
returns AF_OK or AF_ERROR
*/
static int af_open( struct af_instance* af )
{
af->control = control;
af->uninit = uninit;
af->filter_frame = filter;
af_export_t *priv = af->priv;
if (!priv->filename || !priv->filename[0]) {
MP_FATAL(af, "no export filename given");
return AF_ERROR;
}
return AF_OK;
}
#define OPT_BASE_STRUCT af_export_t
const struct af_info af_info_export = {
.info = "Sound export filter",
.name = "export",
.open = af_open,
.priv_size = sizeof(af_export_t),
.options = (const struct m_option[]) {
OPT_STRING("filename", filename, 0),
OPT_INTRANGE("buffersamples", sz, 0, 1, 2048, OPTDEF_INT(DEF_SZ)),
{0}
},
};
-132
View File
@@ -1,132 +0,0 @@
/*
* Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard
*
* 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 <math.h>
#include <limits.h>
#include "common/common.h"
#include "af.h"
// Data for specific instances of this filter
typedef struct af_extrastereo_s
{
float mul;
}af_extrastereo_t;
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
switch(cmd){
case AF_CONTROL_REINIT:{
// Sanity check
if(!arg) return AF_ERROR;
mp_audio_copy_config(af->data, (struct mp_audio*)arg);
mp_audio_force_interleaved_format(af->data);
mp_audio_set_num_channels(af->data, 2);
if (af->data->format != AF_FORMAT_FLOAT)
mp_audio_set_format(af->data, AF_FORMAT_S16);
return af_test_output(af,(struct mp_audio*)arg);
}
}
return AF_UNKNOWN;
}
// Filter data through filter
static void play_s16(af_extrastereo_t *s, struct mp_audio* data)
{
register int i = 0;
int16_t *a = (int16_t*)data->planes[0]; // Audio data
int len = data->samples*data->nch; // Number of samples
int avg, l, r;
for (i = 0; i < len; i+=2)
{
avg = (a[i] + a[i + 1]) / 2;
l = avg + (int)(s->mul * (a[i] - avg));
r = avg + (int)(s->mul * (a[i + 1] - avg));
a[i] = MPCLAMP(l, SHRT_MIN, SHRT_MAX);
a[i + 1] = MPCLAMP(r, SHRT_MIN, SHRT_MAX);
}
}
static void play_float(af_extrastereo_t *s, struct mp_audio* data)
{
register int i = 0;
float *a = (float*)data->planes[0]; // Audio data
int len = data->samples * data->nch; // Number of samples
float avg, l, r;
for (i = 0; i < len; i+=2)
{
avg = (a[i] + a[i + 1]) / 2;
l = avg + (s->mul * (a[i] - avg));
r = avg + (s->mul * (a[i + 1] - avg));
a[i] = af_softclip(l);
a[i + 1] = af_softclip(r);
}
}
static int filter_frame(struct af_instance *af, struct mp_audio *data)
{
if (!data)
return 0;
if (af_make_writeable(af, data) < 0) {
talloc_free(data);
return -1;
}
if (data->format == AF_FORMAT_FLOAT) {
play_float(af->priv, data);
} else {
play_s16(af->priv, data);
}
af_add_output_frame(af, data);
return 0;
}
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
af->control=control;
af->filter_frame = filter_frame;
return AF_OK;
}
#define OPT_BASE_STRUCT af_extrastereo_t
const struct af_info af_info_extrastereo = {
.info = "Increase difference between audio channels",
.name = "extrastereo",
.flags = AF_FLAGS_NOT_REENTRANT,
.open = af_open,
.priv_size = sizeof(af_extrastereo_t),
.options = (const struct m_option[]) {
OPT_FLOAT("mul", mul, 0, OPTDEF_FLOAT(2.5)),
{0}
},
};
-670
View File
@@ -1,670 +0,0 @@
/*
* Experimental audio filter that mixes 5.1 and 5.1 with matrix
* encoded rear channels into headphone signal using FIR filtering
* with HRTF.
*
* Author: ylai
*
* 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 <math.h>
#include <libavutil/common.h>
#include "af.h"
#include "dsp.h"
/* HRTF filter coefficients and adjustable parameters */
#include "af_hrtf.h"
typedef struct af_hrtf_s {
/* Lengths */
int dlbuflen, hrflen, basslen;
/* L, C, R, Ls, Rs channels */
float *lf, *rf, *lr, *rr, *cf, *cr;
const float *cf_ir, *af_ir, *of_ir, *ar_ir, *or_ir, *cr_ir;
int cf_o, af_o, of_o, ar_o, or_o, cr_o;
/* Bass */
float *ba_l, *ba_r;
float *ba_ir;
/* Whether to matrix decode the rear center channel */
int matrix_mode;
/* How to decode the input:
0 = 5/5+1 channels
1 = 2 channels
2 = matrix encoded 2 channels */
int decode_mode;
/* Full wave rectified (FWR) amplitudes and gain used to steer the
active matrix decoding of front channels (variable names
lpr/lmr means Lt + Rt, Lt - Rt) */
float l_fwr, r_fwr, lpr_fwr, lmr_fwr;
float adapt_l_gain, adapt_r_gain, adapt_lpr_gain, adapt_lmr_gain;
/* Matrix input decoding require special FWR buffer, since the
decoding is done in place. */
float *fwrbuf_l, *fwrbuf_r, *fwrbuf_lr, *fwrbuf_rr;
/* Rear channel delay buffer for matrix decoding */
float *rear_dlbuf;
/* Full wave rectified amplitude and gain used to steer the active
matrix decoding of center rear channel */
float lr_fwr, rr_fwr, lrprr_fwr, lrmrr_fwr;
float adapt_lr_gain, adapt_rr_gain;
float adapt_lrprr_gain, adapt_lrmrr_gain;
/* Cyclic position on the ring buffer */
int cyc_pos;
int print_flag;
int mode;
} af_hrtf_t;
/* Convolution on a ring buffer
* nx: length of the ring buffer
* nk: length of the convolution kernel
* sx: ring buffer
* sk: convolution kernel
* offset: offset on the ring buffer, can be
*/
static float conv(const int nx, const int nk, const float *sx, const float *sk,
const int offset)
{
/* k = reminder of offset / nx */
int k = offset >= 0 ? offset % nx : nx + (offset % nx);
if(nk + k <= nx)
return af_filter_fir(nk, sx + k, sk);
else
return af_filter_fir(nk + k - nx, sx, sk + nx - k) +
af_filter_fir(nx - k, sx + k, sk);
}
/* Detect when the impulse response starts (significantly) */
static int pulse_detect(const float *sx)
{
/* nmax must be the reference impulse response length (128) minus
s->hrflen */
const int nmax = 128 - HRTFFILTLEN;
const float thresh = IRTHRESH;
int i;
for(i = 0; i < nmax; i++)
if(fabs(sx[i]) > thresh)
return i;
return 0;
}
/* Fuzzy matrix coefficient transfer function to "lock" the matrix on
a effectively passive mode if the gain is approximately 1 */
static inline float passive_lock(float x)
{
const float x1 = x - 1;
const float ax1s = fabs(x - 1) * (1.0 / MATAGCLOCK);
return x1 - x1 / (1 + ax1s * ax1s) + 1;
}
/* Unified active matrix decoder for 2 channel matrix encoded surround
sources */
static inline void matrix_decode(short *in, const int k, const int il,
const int ir, const int decode_rear,
const int dlbuflen,
float l_fwr, float r_fwr,
float lpr_fwr, float lmr_fwr,
float *adapt_l_gain, float *adapt_r_gain,
float *adapt_lpr_gain, float *adapt_lmr_gain,
float *lf, float *rf, float *lr,
float *rr, float *cf)
{
const int kr = (k + MATREARDELAY) % dlbuflen;
float l_gain = (l_fwr + r_fwr) /
(1 + l_fwr + l_fwr);
float r_gain = (l_fwr + r_fwr) /
(1 + r_fwr + r_fwr);
/* The 2nd axis has strong gain fluctuations, and therefore require
limits. The factor corresponds to the 1 / amplification of (Lt
- Rt) when (Lt, Rt) is strongly correlated. (e.g. during
dialogues). It should be bigger than -12 dB to prevent
distortion. */
float lmr_lim_fwr = lmr_fwr > M9_03DB * lpr_fwr ?
lmr_fwr : M9_03DB * lpr_fwr;
float lpr_gain = (lpr_fwr + lmr_lim_fwr) /
(1 + lpr_fwr + lpr_fwr);
float lmr_gain = (lpr_fwr + lmr_lim_fwr) /
(1 + lmr_lim_fwr + lmr_lim_fwr);
float lmr_unlim_gain = (lpr_fwr + lmr_fwr) /
(1 + lmr_fwr + lmr_fwr);
float lpr, lmr;
float l_agc, r_agc, lpr_agc, lmr_agc;
float f, d_gain, c_gain, c_agc_cfk;
#if 0
static int counter = 0;
static FILE *fp_out;
if(counter == 0)
fp_out = fopen("af_hrtf.log", "w");
if(counter % 240 == 0)
fprintf(fp_out, "%g %g %g %g %g ", counter * (1.0 / 48000),
l_gain, r_gain, lpr_gain, lmr_gain);
#endif
/*** AXIS NO. 1: (Lt, Rt) -> (C, Ls, Rs) ***/
/* AGC adaption */
d_gain = (fabs(l_gain - *adapt_l_gain) +
fabs(r_gain - *adapt_r_gain)) * 0.5;
f = d_gain * (1.0 / MATAGCTRIG);
f = MATAGCDECAY - MATAGCDECAY / (1 + f * f);
*adapt_l_gain = (1 - f) * *adapt_l_gain + f * l_gain;
*adapt_r_gain = (1 - f) * *adapt_r_gain + f * r_gain;
/* Matrix */
l_agc = in[il] * passive_lock(*adapt_l_gain);
r_agc = in[ir] * passive_lock(*adapt_r_gain);
cf[k] = (l_agc + r_agc) * M_SQRT1_2;
if(decode_rear) {
lr[kr] = rr[kr] = (l_agc - r_agc) * M_SQRT1_2;
/* Stereo rear channel is steered with the same AGC steering as
the decoding matrix. Note this requires a fast updating AGC
at the order of 20 ms (which is the case here). */
lr[kr] *= (l_fwr + l_fwr) /
(1 + l_fwr + r_fwr);
rr[kr] *= (r_fwr + r_fwr) /
(1 + l_fwr + r_fwr);
}
/*** AXIS NO. 2: (Lt + Rt, Lt - Rt) -> (L, R) ***/
lpr = (in[il] + in[ir]) * M_SQRT1_2;
lmr = (in[il] - in[ir]) * M_SQRT1_2;
/* AGC adaption */
d_gain = fabs(lmr_unlim_gain - *adapt_lmr_gain);
f = d_gain * (1.0 / MATAGCTRIG);
f = MATAGCDECAY - MATAGCDECAY / (1 + f * f);
*adapt_lpr_gain = (1 - f) * *adapt_lpr_gain + f * lpr_gain;
*adapt_lmr_gain = (1 - f) * *adapt_lmr_gain + f * lmr_gain;
/* Matrix */
lpr_agc = lpr * passive_lock(*adapt_lpr_gain);
lmr_agc = lmr * passive_lock(*adapt_lmr_gain);
lf[k] = (lpr_agc + lmr_agc) * M_SQRT1_2;
rf[k] = (lpr_agc - lmr_agc) * M_SQRT1_2;
/*** CENTER FRONT CANCELLATION ***/
/* A heuristic approach exploits that Lt + Rt gain contains the
information about Lt, Rt correlation. This effectively reshapes
the front and rear "cones" to concentrate Lt + Rt to C and
introduce Lt - Rt in L, R. */
/* 0.67677 is the emprical lower bound for lpr_gain. */
c_gain = 8 * (*adapt_lpr_gain - 0.67677);
c_gain = c_gain > 0 ? c_gain : 0;
/* c_gain should not be too high, not even reaching full
cancellation (~ 0.50 - 0.55 at current AGC implementation), or
the center will s0und too narrow. */
c_gain = MATCOMPGAIN / (1 + c_gain * c_gain);
c_agc_cfk = c_gain * cf[k];
lf[k] -= c_agc_cfk;
rf[k] -= c_agc_cfk;
cf[k] += c_agc_cfk + c_agc_cfk;
#if 0
if(counter % 240 == 0)
fprintf(fp_out, "%g %g %g %g %g\n",
*adapt_l_gain, *adapt_r_gain,
*adapt_lpr_gain, *adapt_lmr_gain,
c_gain);
counter++;
#endif
}
static inline void update_ch(af_hrtf_t *s, short *in, const int k)
{
const int fwr_pos = (k + FWRDURATION) % s->dlbuflen;
/* Update the full wave rectified total amplitude */
/* Input matrix decoder */
if(s->decode_mode == HRTF_MIX_MATRIX2CH) {
s->l_fwr += abs(in[0]) - fabs(s->fwrbuf_l[fwr_pos]);
s->r_fwr += abs(in[1]) - fabs(s->fwrbuf_r[fwr_pos]);
s->lpr_fwr += abs(in[0] + in[1]) -
fabs(s->fwrbuf_l[fwr_pos] + s->fwrbuf_r[fwr_pos]);
s->lmr_fwr += abs(in[0] - in[1]) -
fabs(s->fwrbuf_l[fwr_pos] - s->fwrbuf_r[fwr_pos]);
}
/* Rear matrix decoder */
if(s->matrix_mode) {
s->lr_fwr += abs(in[2]) - fabs(s->fwrbuf_lr[fwr_pos]);
s->rr_fwr += abs(in[3]) - fabs(s->fwrbuf_rr[fwr_pos]);
s->lrprr_fwr += abs(in[2] + in[3]) -
fabs(s->fwrbuf_lr[fwr_pos] + s->fwrbuf_rr[fwr_pos]);
s->lrmrr_fwr += abs(in[2] - in[3]) -
fabs(s->fwrbuf_lr[fwr_pos] - s->fwrbuf_rr[fwr_pos]);
}
switch (s->decode_mode) {
case HRTF_MIX_51:
/* 5/5+1 channel sources */
s->lf[k] = in[0];
s->cf[k] = in[4];
s->rf[k] = in[1];
s->fwrbuf_lr[k] = s->lr[k] = in[2];
s->fwrbuf_rr[k] = s->rr[k] = in[3];
break;
case HRTF_MIX_MATRIX2CH:
/* Matrix encoded 2 channel sources */
s->fwrbuf_l[k] = in[0];
s->fwrbuf_r[k] = in[1];
matrix_decode(in, k, 0, 1, 1, s->dlbuflen,
s->l_fwr, s->r_fwr,
s->lpr_fwr, s->lmr_fwr,
&(s->adapt_l_gain), &(s->adapt_r_gain),
&(s->adapt_lpr_gain), &(s->adapt_lmr_gain),
s->lf, s->rf, s->lr, s->rr, s->cf);
break;
case HRTF_MIX_STEREO:
/* Stereo sources */
s->lf[k] = in[0];
s->rf[k] = in[1];
s->cf[k] = s->lr[k] = s->rr[k] = 0;
break;
}
/* We need to update the bass compensation delay line, too. */
// TODO: should this use lf/cf/rf etc. instead?
s->ba_l[k] = in[0];
s->ba_r[k] = in[1];
if (s->decode_mode == HRTF_MIX_51) {
s->ba_l[k] += in[4] + in[2];
s->ba_r[k] += in[4] + in[3];
}
}
static void clear_coeff(af_hrtf_t *s, float *c)
{
memset(c, 0, s->dlbuflen * sizeof(float));
}
static void reset(af_hrtf_t *s)
{
clear_coeff(s, s->lf);
clear_coeff(s, s->rf);
clear_coeff(s, s->lr);
clear_coeff(s, s->rr);
clear_coeff(s, s->cf);
clear_coeff(s, s->cr);
clear_coeff(s, s->ba_l);
clear_coeff(s, s->ba_r);
clear_coeff(s, s->fwrbuf_l);
clear_coeff(s, s->fwrbuf_r);
clear_coeff(s, s->fwrbuf_lr);
clear_coeff(s, s->fwrbuf_rr);
}
/* Initialization and runtime control */
static int control(struct af_instance *af, int cmd, void* arg)
{
af_hrtf_t *s = af->priv;
int test_output_res;
switch(cmd) {
case AF_CONTROL_REINIT:
reset(s);
af->data->rate = 48000;
mp_audio_set_channels_old(af->data, ((struct mp_audio*)arg)->nch);
if(af->data->nch == 2) {
/* 2 channel input */
if(s->decode_mode != HRTF_MIX_MATRIX2CH) {
/* Default behavior is stereo mixing. */
s->decode_mode = HRTF_MIX_STEREO;
}
} else if (af->data->nch < 5) {
mp_audio_set_channels_old(af->data, 5);
}
mp_audio_set_format(af->data, AF_FORMAT_S16);
test_output_res = af_test_output(af, (struct mp_audio*)arg);
// after testing input set the real output format
mp_audio_set_num_channels(af->data, 2);
s->print_flag = 1;
return test_output_res;
case AF_CONTROL_RESET:
reset(s);
return AF_OK;
}
return AF_UNKNOWN;
}
/* Deallocate memory */
static void uninit(struct af_instance *af)
{
af_hrtf_t *s = af->priv;
free(s->lf);
free(s->rf);
free(s->lr);
free(s->rr);
free(s->cf);
free(s->cr);
free(s->ba_l);
free(s->ba_r);
free(s->ba_ir);
free(s->fwrbuf_l);
free(s->fwrbuf_r);
free(s->fwrbuf_lr);
free(s->fwrbuf_rr);
}
/* Filter data through filter
Two "tricks" are used to compensate the "color" of the KEMAR data:
1. The KEMAR data is refiltered to ensure that the front L, R channels
on the same side of the ear are equalized (especially in the high
frequencies).
2. A bass compensation is introduced to ensure that 0-200 Hz are not
damped (without any real 3D acoustical image, however).
*/
static int filter(struct af_instance *af, struct mp_audio *data)
{
af_hrtf_t *s = af->priv;
if (!data)
return 0;
struct mp_audio *outframe =
mp_audio_pool_get(af->out_pool, &af->fmt_out, data->samples);
if (!outframe) {
talloc_free(data);
return -1;
}
mp_audio_copy_attributes(outframe, data);
short *in = data->planes[0]; // Input audio data
short *out = outframe->planes[0]; // Output audio data
short *end = in + data->samples * data->nch; // Loop end
float common, left, right, diff, left_b, right_b;
const int dblen = s->dlbuflen, hlen = s->hrflen, blen = s->basslen;
if(s->print_flag) {
s->print_flag = 0;
switch (s->decode_mode) {
case HRTF_MIX_51:
MP_INFO(af, "Using HRTF to mix %s discrete surround into "
"L, R channels\n", s->matrix_mode ? "5+1" : "5");
break;
case HRTF_MIX_STEREO:
MP_INFO(af, "Using HRTF to mix stereo into "
"L, R channels\n");
break;
case HRTF_MIX_MATRIX2CH:
MP_INFO(af, "Using active matrix to decode 2 channel "
"input, HRTF to mix %s matrix surround into "
"L, R channels\n", "3/2");
break;
default:
MP_WARN(af, "bogus decode_mode: %d\n", s->decode_mode);
break;
}
if(s->matrix_mode)
MP_INFO(af, "Using active matrix to decode rear center "
"channel\n");
}
/* MPlayer's 5 channel layout (notation for the variable):
*
* 0: L (LF), 1: R (RF), 2: Ls (LR), 3: Rs (RR), 4: C (CF), matrix
* encoded: Cs (CR)
*
* or: L = left, C = center, R = right, F = front, R = rear
*
* Filter notation:
*
* CF
* OF AF
* Ear->
* OR AR
* CR
*
* or: C = center, A = same side, O = opposite, F = front, R = rear
*/
while(in < end) {
const int k = s->cyc_pos;
update_ch(s, in, k);
/* Simulate a 7.5 ms -20 dB echo of the center channel in the
front channels (like reflection from a room wall) - a kind of
psycho-acoustically "cheating" to focus the center front
channel, which is normally hard to be perceived as front */
s->lf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen];
s->rf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen];
switch (s->decode_mode) {
case HRTF_MIX_51:
case HRTF_MIX_MATRIX2CH:
/* Mixer filter matrix */
common = conv(dblen, hlen, s->cf, s->cf_ir, k + s->cf_o);
if(s->matrix_mode) {
/* In matrix decoding mode, the rear channel gain must be
renormalized, as there is an additional channel. */
matrix_decode(in, k, 2, 3, 0, s->dlbuflen,
s->lr_fwr, s->rr_fwr,
s->lrprr_fwr, s->lrmrr_fwr,
&(s->adapt_lr_gain), &(s->adapt_rr_gain),
&(s->adapt_lrprr_gain), &(s->adapt_lrmrr_gain),
s->lr, s->rr, NULL, NULL, s->cr);
common +=
conv(dblen, hlen, s->cr, s->cr_ir, k + s->cr_o) *
M1_76DB;
left =
( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) +
(conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) +
conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o)) *
M1_76DB + common);
right =
( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) +
(conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) +
conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o)) *
M1_76DB + common);
} else {
left =
( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) +
conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) +
conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o) +
common);
right =
( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) +
conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) +
conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o) +
common);
}
break;
case HRTF_MIX_STEREO:
left =
( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o));
right =
( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o));
break;
default:
/* make gcc happy */
left = 0.0;
right = 0.0;
break;
}
/* Bass compensation for the lower frequency cut of the HRTF. A
cross talk of the left and right channel is introduced to
match the directional characteristics of higher frequencies.
The bass will not have any real 3D perception, but that is
OK (note at 180 Hz, the wavelength is about 2 m, and any
spatial perception is impossible). */
left_b = conv(dblen, blen, s->ba_l, s->ba_ir, k);
right_b = conv(dblen, blen, s->ba_r, s->ba_ir, k);
left += (1 - BASSCROSS) * left_b + BASSCROSS * right_b;
right += (1 - BASSCROSS) * right_b + BASSCROSS * left_b;
/* Also mix the LFE channel (if available) */
if(data->nch >= 6) {
left += in[5] * M3_01DB;
right += in[5] * M3_01DB;
}
/* Amplitude renormalization. */
left *= AMPLNORM;
right *= AMPLNORM;
switch (s->decode_mode) {
case HRTF_MIX_51:
case HRTF_MIX_STEREO:
/* "Cheating": linear stereo expansion to amplify the 3D
perception. Note: Too much will destroy the acoustic space
and may even result in headaches. */
diff = STEXPAND2 * (left - right);
out[0] = av_clip_int16(left + diff);
out[1] = av_clip_int16(right - diff);
break;
case HRTF_MIX_MATRIX2CH:
/* Do attempt any stereo expansion with matrix encoded
sources. The L, R channels are already stereo expanded
by the steering, any further stereo expansion will sound
very unnatural. */
out[0] = av_clip_int16(left);
out[1] = av_clip_int16(right);
break;
}
/* Next sample... */
in = &in[data->nch];
out = &out[af->data->nch];
(s->cyc_pos)--;
if(s->cyc_pos < 0)
s->cyc_pos += dblen;
}
talloc_free(data);
af_add_output_frame(af, outframe);
return 0;
}
static int allocate(af_hrtf_t *s)
{
if ((s->lf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->rf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->lr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->rr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->cf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->cr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->ba_l = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->ba_r = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->fwrbuf_l =
malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->fwrbuf_r =
malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->fwrbuf_lr =
malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
if ((s->fwrbuf_rr =
malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
return 0;
}
/* Allocate memory and set function pointers */
static int af_open(struct af_instance* af)
{
int i;
af_hrtf_t *s;
float fc;
af->control = control;
af->uninit = uninit;
af->filter_frame = filter;
s = af->priv;
s->dlbuflen = DELAYBUFLEN;
s->hrflen = HRTFFILTLEN;
s->basslen = BASSFILTLEN;
s->cyc_pos = s->dlbuflen - 1;
/* With a full (two axis) steering matrix decoder, s->matrix_mode
should not be enabled lightly (it will also steer the Ls, Rs
channels). */
s->matrix_mode = 0;
s->decode_mode = HRTF_MIX_51;
switch (s->mode) {
case 0: /* Use matrix rear decoding. */
s->matrix_mode = 1;
break;
case 1: /* Input needs matrix decoding. */
s->decode_mode = HRTF_MIX_MATRIX2CH;
break;
case 2:
s->matrix_mode = 0;
break;
}
s->print_flag = 1;
if (allocate(s) != 0) {
MP_ERR(af, "Memory allocation error.\n");
return AF_ERROR;
}
for(i = 0; i < s->dlbuflen; i++)
s->lf[i] = s->rf[i] = s->lr[i] = s->rr[i] = s->cf[i] =
s->cr[i] = 0;
s->lr_fwr =
s->rr_fwr = 0;
s->cf_ir = cf_filt + (s->cf_o = pulse_detect(cf_filt));
s->af_ir = af_filt + (s->af_o = pulse_detect(af_filt));
s->of_ir = of_filt + (s->of_o = pulse_detect(of_filt));
s->ar_ir = ar_filt + (s->ar_o = pulse_detect(ar_filt));
s->or_ir = or_filt + (s->or_o = pulse_detect(or_filt));
s->cr_ir = cr_filt + (s->cr_o = pulse_detect(cr_filt));
if((s->ba_ir = malloc(s->basslen * sizeof(float))) == NULL) {
MP_ERR(af, "Memory allocation error.\n");
return AF_ERROR;
}
fc = 2.0 * BASSFILTFREQ / (float)af->data->rate;
if(af_filter_design_fir(s->basslen, s->ba_ir, &fc, LP | KAISER, 4 * M_PI) ==
-1) {
MP_ERR(af, "Unable to design low-pass "
"filter.\n");
return AF_ERROR;
}
for(i = 0; i < s->basslen; i++)
s->ba_ir[i] *= BASSGAIN;
return AF_OK;
}
#define OPT_BASE_STRUCT af_hrtf_t
const struct af_info af_info_hrtf = {
.info = "HRTF Headphone",
.name = "hrtf",
.open = af_open,
.priv_size = sizeof(af_hrtf_t),
.options = (const struct m_option[]) {
OPT_CHOICE("mode", mode, 0, ({"m", 0}, {"s", 1}, {"0", 2})),
{0}
},
};
-510
View File
@@ -1,510 +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_AF_HRTF_H
#define MPLAYER_AF_HRTF_H
#define HRTF_MIX_51 0
#define HRTF_MIX_STEREO 1
#define HRTF_MIX_MATRIX2CH 2
/* Amplitude scaling factors */
#define M17_0DB 0.1414213562
#define M9_03DB 0.3535533906
#define M6_99DB 0.4472135955
#define M4_77DB 0.5773502692
#define M3_01DB 0.7071067812
#define M1_76DB 0.8164965809
#define DELAYBUFLEN 1024 /* Length of the delay buffer */
#define HRTFFILTLEN 64 /* HRTF filter length */
#define IRTHRESH 0.001 /* Impulse response pruning thresh. */
#define AMPLNORM M6_99DB /* Overall amplitude renormalization */
#define BASSFILTFREQ 180 /* Bass compensation filter cut (Hz) */
#define BASSFILTLEN 193 /* Bass compensation filter length */
#define BASSGAIN M_SQRT2 /* Bass compensation gain */
#define BASSCROSS 0.35 /* Bass cross talk */
#define FWRDURATION 240 /* FWR average duration (samples) */
#define MATREARDELAY 720 /* Matrix mode rear delay (samples) */
#define MATAGCTRIG 8.0 /* (Fuzzy) AGC trigger */
#define MATAGCDECAY 1.0 /* AGC baseline decay rate (1/samp.) */
#define MATAGCLOCK 0.2 /* AGC range (around 1) where the
matrix behaves passively */
#define MATCOMPGAIN 0.37 /* Cross talk compensation gain,
0.50 - 0.55 is full cancellation. */
#define CFECHODELAY 360 /* Center front echo delay (samples) */
#define CFECHOAMPL M17_0DB /* Center front echo amplitude */
#define STEXPAND2 0.07 /* Stereo expansion / 2 */
/* Head related impulse response (HRIR) derived from KEMAR measurement
data by Bill Gardner <billg@media.mit.edu> and Keith Martin
<kdm@media.mit.edu>
URL: http://sound.media.mit.edu/KEMAR.html
Distributed under GPL with authors' permission
*/
/* EQUALIZED KEMAR HRIR
How to generate these data:
1. You need the MIT Media Lab's KEMAR data, read it into an software
capable of signal/time series analysis (like Mathematica, Matlab,
...)
2. Construct an equalizing FIR inverse filter by calculating the
transfer function of the front, same side impulse response, then
take 1 over the absolute magnitude.
3. Cut the poles in the inverse filter's transfer function
specification by limiting the amplification to 2.5 (note, this
number assumes that you have correct signal processing
normalization of the Fourier transform).
4. Design the FIR inverse filter by calculating the inverse Fourier
transform, then chopping the coefficients down to a reasonable
number (N = 15 is used here), apply the Kaiser-Bessel window (alpha
= 2 is used here). Note the objective is remove the color bias
only (as if you are using an equalizer), _not_ to do a full inverse
filtering. (Note: beta = pi*alpha in other notation.)
For N = 15, alpha = 2, you should get the following impulse
response:
0.001001558668605168, 0.00698457265741865, 0.040453643039829436,
0.012230541722147855, -0.11939760844854072, 0.16468099899755967,
-0.30297563073747436, 1.3140211791355982, -0.30297563073747436,
0.16468099899755967, -0.11939760844854072, 0.012230541722147855,
0.040453643039829436, 0.00698457265741865, 0.001001558668605168
5. Linearly convolve all KEMAR HRIR with this inverse filter.
6. Resample from 44.1 kHz sampling frequency to 48 kHz.
*/
/* Center front (-5 degree) - not 0 degree in order to create a clear
front image from a finite distance */
static const float cf_filt[128] = {
-0.00008638082319075036, 0.0003198059946385229,
-0.0005010631339162132, 0.0011424741331126876,
-0.001584220794688753, 0.001742715363246275,
-0.0011080796626780694, 0.0001651829990860167,
0.005235028337314985, 0.0035223828473357776,
0.010057681388431303, -0.033469432129545514,
0.013391253316233523, 0.004858462839827063,
0.08172161220103627, 0.26158596134500023,
-0.12420314583323326, -0.14298458356097565,
0.14421897280453896, -0.1635792507629016,
-0.02187136722480014, 0.2426863044711817,
0.07229814207917194, 0.0942742651913879,
0.29856830878076834, 0.2944146162057754,
-0.12122157003421209, -0.19640092165631157,
0.11623836502034968, -0.05794027397995521,
-0.34313138341973776, -0.19487516249168105,
0.010118993953802401, -0.09460218797710966,
-0.16761521117359582, 0.004154461610153861,
0.052768641758969316, -0.00041823982226147407,
0.021634960445143514, 0.07562793486871108,
0.08895407129506479, 0.039857755093416214,
0.044257936180422945, 0.061557584906101664,
0.015547268541895703, -0.023908191934932484,
0.009498030443468223, 0.03816269003221337,
-0.009820500607303615, -0.042003975527908084,
-0.03335447117311547, -0.029294510859746596,
-0.05212623136198511, -0.073427547153205,
-0.061190797824958836, -0.04620925059966413,
-0.04204619420702159, -0.02331915902615157,
0.00211481411477094, 0.00852563995740107,
0.008766809731743399, 0.008666632180812078,
0.018279202191625352, 0.02924332751289675,
0.022293148257836494, 0.012362146008584188,
0.008572582458807008, 0.006491370763597344,
-0.0019366944997535774, -0.006318669309634434,
-0.006457921690218669, -0.015050265524669974,
-0.02110660282616213, -0.017027809096377904,
-0.01651052305334348, -0.022770064150046673,
-0.01999875754219472, -0.012294792027337775,
-0.011506057031057188, -0.011448970577312903,
-0.004823572302580925, 0.0022451134042777883,
0.004145473526859826, 0.005629030064546135,
0.008588029213398785, 0.010092048834844231,
0.007182013245552008, 0.0014600979508720656,
-0.0038314646272511756, -0.003443901997881347,
-0.0029483418254804047, -0.007609357112679647,
-0.006518368948030822, -0.004495803701497202,
-0.007109113004849672, -0.008346237278084265,
-0.005560847336252453, -0.002993453167553188,
-0.005122897816824269, -0.004389782626604215,
-0.0010912633695218108, -0.0019712029474458835,
-0.005870162265802235, -0.005626159534954128,
-0.00027254977910844407, 0.0013794425431633785,
-0.0005919083190430062, -0.0007861203545416682,
-0.0007049560240893946, -0.0032720188494468868,
-0.004460645567968504, -0.0032018528193571696,
-0.0030579229375062105, -0.003593998902656612,
-0.0038032977997776445, -0.004613776010454773,
-0.0059796549143736845, -0.00420126194319768,
-0.0012374419948287222, 0.0008572699213050608,
0.0021490971020081094, 0.00047295283198381995,
-0.0009670277915884887, -0.001354440866080231,
-0.002962902746547851, -0.00533935813338141,
-0.005469203016468759, -0.004355784273189485
};
/* Front, same side (30 degree) */
static const float af_filt[128] = {
-0.004140580614755493, 0.005790934614385445,
0.003318916682081112, 0.014257145544366063,
0.007328442487127339, -0.06550381777876194,
0.03502225818161845, -0.013090579770708259,
0.2517776798694195, 0.420770489950659,
-0.3418854608834852, -0.24371032493696737,
0.04901356150030018, -0.1778083521632833,
0.26448004245714163, 0.23245199964546834,
0.033053145803936305, 0.46811222821062415,
0.5359265986255611, -0.011912195468533787,
-0.39763432601411647, -0.034482864386898314,
0.029445398240649626, -0.3850940407863262,
-0.3272328478175581, -0.14701421403616477,
-0.08522137400169517, -0.14936851633336035,
-0.09432605283433723, 0.0991200405937827,
0.011075012089917331, -0.0051036489980274685,
0.0933903289749412, 0.1344189369609565,
0.10507466913017807, 0.04240159324684365,
0.06559270110638656, 0.026984119875617524,
-0.03359846103238096, -0.018000197099174275,
0.042031818548178244, 0.03849039666888434,
-0.02450829674011345, -0.03407882403088576,
-0.029230189282961977, -0.046964865291761734,
-0.09458258700116245, -0.1527349330901158,
-0.15411577687826097, -0.08761679790956928,
-0.033623549089171874, -0.007204768531481949,
0.008273425020444852, 0.021368717994908505,
0.04366608267875025, 0.05660907333076205,
0.06775726495503939, 0.05621881735271431,
0.03576231950669927, 0.02500825834889175,
0.015423811076054601, 0.007903258334503761,
-0.0053873014137761945, -0.006987955469434698,
-0.012027972007598602, -0.025228281243816594,
-0.026225091797257318, -0.023809293997344882,
-0.03250172017712295, -0.03195696301067249,
-0.01784813952189948, -0.01663267233760342,
-0.016184530450468065, -0.011659883749357463,
-0.0035378511240219163, -0.0005485800790443406,
0.0018432660108168625, 0.011634844139907534,
0.018333603402051105, 0.020447379185133056,
0.00850783664147828, 0.0004694148911037838,
-0.0017047130409786676, -0.0022409152834483997,
-0.000860472174892845, -0.004111075059198666,
-0.003527843382056666, -0.009640160874903018,
-0.01750044574231376, -0.015613389403672443,
-0.010790028120953001, -0.0095313499955768,
-0.007469721416726809, -0.0019186578145117315,
-0.00014977322572890802, -0.0029803838028179728,
-0.006520567233727221, 0.000035015132033882596,
0.009245098100543752, 0.009896930052308656,
0.008316744929565786, 0.004575207140193997,
-0.0000647420103997081, -0.004502916832871627,
-0.004225962213251224, -0.002886014126381486,
-0.006416834142585976, -0.007156609995423569,
-0.008840274447579472, -0.01441763751386817,
-0.015435817484659574, -0.00924487254924743,
-0.0021571721940235205, 0.0028540722992305453,
0.00273577475088536, -0.000788412365513805,
-0.0032650029728365907, -0.003880217646231338,
-0.0035302087299613778, -0.0038531436176586246,
-0.0011921632190514074, -0.0020722967099011938,
-0.004985351145629344, -0.0042375588844648735,
-0.003030360463006021, -0.0014161075428041471,
-0.0005083025643192044, 0.00035096963769606926
};
/* Front, opposite (-30 degree) */
static const float of_filt[128] = {
-0.000013472538374193126, -0.00008048061877079751,
0.000043927265781258155, -0.000017931700794858892,
-0.000034774602476112886, -0.00009576223008735474,
0.0001557797638630691, -0.00018742885883751094,
0.00026512448626705716, -0.0001451040203319678,
-0.00008263233117758043, 0.0006486245853639179,
-0.0010631408451846698, 0.0026571994100746143,
0.0014179177997092787, 0.0062326502956616256,
-0.008194149324545333, -0.006568029415878379,
0.009538759710818582, 0.012309193558632693,
0.12336638055838955, 0.046164307101829005,
-0.10228706407884815, 0.04047687260345798,
-0.00296595313977046, -0.07057949208414134,
0.08172114840714612, 0.08736490764127891,
0.05105250431333021, 0.11627179512747428,
0.20717888490340705, 0.09375052213570291,
-0.09784374168330194, -0.010493571845901443,
0.053131894303891716, -0.10157443971694806,
-0.16264032634244974, -0.05402369511361273,
-0.0274403608654217, -0.09860277022495063,
-0.06841875821090282, -0.004434574400066223,
-0.0005222661652743502, -0.006231881259827263,
0.014410397820340159, 0.04885649512730243,
0.04361962569042684, 0.03399214029009391,
0.04961073933475931, 0.04067325604132289,
0.007850647519227257, 0.004564440466905299,
0.02257107958021618, 0.008183791928884486,
-0.014913479343180557, -0.018685938460856224,
-0.01745737397226911, -0.02327177054233603,
-0.03723048632685227, -0.044739390162299685,
-0.042651220125613766, -0.03730017561004743,
-0.029039465434276192, -0.01885087458914294,
-0.01207127752277769, -0.006779800724164512,
-0.001930416967444157, 0.000029454577995528385,
0.0013822760965755472, 0.0014799128583230202,
0.0002068200609199832, 0.0022254295286201083,
0.005143858159434566, 0.0018580542060917013,
-0.0019426046325146259, -0.0014464042108543495,
-0.0034430083560735582, -0.009692758426099499,
-0.011840035292593485, -0.010716508855893968,
-0.012939889036853034, -0.0121846427935653,
-0.006198503315630782, -0.0023186723099380305,
-0.002679872498314837, -0.003086020446226295,
-0.0015709623347698936, -0.0008147490468332398,
-0.0012384575726770983, -0.0005212877089109362,
0.0017707578744906142, 0.001324932723905786,
-0.0017023653780617696, -0.0045108927752919425,
-0.005422155613096912, -0.0039489323837623835,
-0.005295995750506547, -0.00629706566356189,
-0.004685732198036754, -0.0048076735568143,
-0.005978864279217503, -0.005928999306332966,
-0.004187703549017582, -0.003213999896976475,
-0.0028068699816073414, -0.0010889703907593833,
0.0003276714243495386, -0.0013015007040186994,
-0.003208050402434782, -0.0025115319088208545,
-0.0013787553006401076, -0.0018279087370218635,
-0.0025904836507747754, -0.002071221947222004,
-0.0026424212922485594, -0.0039837031817577,
-0.0041635566057380965, -0.004355223489150822,
-0.004350395332709937, -0.0036693292471930263,
-0.003386384394185026, -0.003972568655001128,
-0.004332336840023821, -0.002648767912111827,
-0.001384410080218114, -0.0011353792711849466,
-0.0013726264946164232, -0.0020075119315034313
};
/* Rear, same side (135 degree) */
static const float ar_filt[128] = {
0.004573315040810066, 0.0013592578059426913,
0.01553271930902704, -0.0002356117224941317,
-0.05746098219774702, 0.03430688963370445,
0.00808371687447385, 0.21893535841158596,
0.2984357591724814, -0.3302799746504719,
-0.3194029149806245, 0.21633225051331056,
0.24371260938097083, -0.08843705549751085,
0.03939684701343366, 0.45386926431114494,
0.07599118140753386, -0.18114706160474578,
0.285640624686038, 0.4049515236666218,
-0.05347890222071792, -0.31464359045319074,
-0.1033502246468194, -0.04553593949283157,
-0.1880747731157464, -0.13629090230626037,
-0.10435789106123239, -0.19818232801888755,
-0.16701805476330397, -0.022793111199284,
0.058049696762683685, 0.007048321372693906,
-0.002966419183225961, 0.10140569697797763,
0.11648999956673124, 0.05218347182779882,
0.028427001212735392, 0.04151900310166159,
-0.0006960604221423734, -0.05898623212226975,
-0.03801934531173312, -0.029306970535287986,
-0.04549125782835908, -0.0599222718506552,
-0.058299618975430116, -0.03765579129720727,
-0.03559302657499581, -0.020647901025903054,
-0.005720957338744348, -0.0041915732688915545,
-0.0011470880098346143, 0.008737404798553,
0.023444168098121512, 0.024204226042172663,
0.01894897166475026, 0.020807655257479588,
0.021570431128040954, 0.006800556178576289,
-0.009000089216921362, -0.010969824547067934,
-0.0033653428332822374, -0.012676936164668659,
-0.026739938673413587, -0.023427869194287573,
-0.023302007105117244, -0.023647155590533712,
-0.021289317515613106, -0.009120487305069884,
0.0009251551667728967, 0.00004285344125653763,
-0.00009042365479456271, 0.00022573242339446494,
0.00720168491586098, 0.007111875505402431,
0.003186514817683482, 0.00810087718334745,
0.012619557025922575, 0.007854726400013397,
-0.0024013592881066267, -0.001452457473161119,
-0.0025535188366093945, -0.012428911627809337,
-0.013729251536694145, -0.0070099675146427344,
-0.007165284278706593, -0.01639289295622301,
-0.015831795079778305, -0.007305768485523729,
-0.003608863157004021, -0.0032640528878698084,
0.0030901263998481944, 0.00749497566124848,
0.002515185532327241, 0.00004840875738621367,
0.0017596043486043966, 0.0046229941553338144,
0.0034259167322926096, 0.003707347634186093,
0.0035584806528586328, -0.0019078936035275198,
-0.006057343815214898, -0.0069262470468817,
-0.004345020728618624, -0.004177623355574794,
-0.005373506556122508, -0.006624933928893836,
-0.008679541408588839, -0.010718719681595322,
-0.011392246979594496, -0.007893917064389902,
-0.0027572935365832536, -0.00006064707149834412,
-0.0012512537319656323, -0.0024501501002409786,
-0.0022106788572895998, -0.00234124933370301,
-0.0008953445167066823, 0.0005393670625637734,
-0.00033175600142209297, -0.004023994309351289,
-0.008655472335784443, -0.009899957354849682,
-0.008664952919996412, -0.00553483124503576,
-0.003735336089277662, -0.002754824348643885,
-0.0026884314856593368, -0.004084181815125924
};
/* Rear, opposite (-135 degree) */
static const float or_filt[128] = {
0.0001220944028243897, -0.000021785381808441314,
5.823057988603169e-6, -0.00001217768176447613,
-0.00006123604397345513, 5.574117262531134e-6,
-0.00004935331914366778, 1.1771577934768211e-6,
-0.000059236211621095756, 9.503536190497286e-6,
-0.0001494445696103564, 0.00012248858284145305,
-0.0000963975321456313, 6.017905197665205e-6,
0.00003353395360402643, -0.0001931511015359506,
0.0005113536523931485, -0.0005676652619386114,
0.0012057159755477467, 0.0009370492250339692,
0.004596472288877981, -0.0018831773384237068,
-0.008208535225621212, 0.0038178646400751056,
0.008726517739105965, 0.06664363898418262,
0.06788684221502142, -0.04492315162807267,
-0.04019906311255255, 0.026203059677375153,
0.013678129114847544, -0.014334962223993527,
0.010141709596167392, 0.11559131576945537,
0.1586402064538425, 0.059975334707967023,
0.004671725963777715, 0.031498678282775874,
0.014338626006524587, -0.014749719448472231,
-0.02055508237941379, -0.05407690143992048,
-0.07767559836886143, -0.05029091786216801,
-0.030808335706574427, -0.03401958135442541,
-0.030520368430288967, -0.014168302104259355,
0.011907621259989802, 0.014286081013069,
0.006377467879613449, 0.018546823568277478,
0.028297012771618273, 0.025222339408338186,
0.021931611353415138, 0.019708894333646355,
0.01729258494072014, 0.017468204169564034,
0.009729094845051928, -0.002976992018531901,
-0.00956986166277019, -0.016125733548332074,
-0.02934094241442545, -0.04133767871051455,
-0.043536981145416466, -0.0385966307108608,
-0.02784453599342459, -0.018995135307247116,
-0.012849534096536747, -0.004437491064613308,
0.00028385411598204655, 0.003776874988516643,
0.008069432041547833, 0.008764754183751848,
0.008020908861878062, 0.006830351461360802,
0.002218330884267235, -0.0020478725582339444,
-0.003997428121462543, -0.007066287373515421,
-0.00940847412544698, -0.010938998446237963,
-0.011775483016151306, -0.011391103919484287,
-0.010586061195163017, -0.009842793078929053,
-0.007753202010139829, -0.00569213732353025,
-0.006506783349722073, -0.005346134281903736,
-0.003913089814898934, -0.0036091443854759727,
-0.0020328564301266287, 0.00017932870773467683,
0.0032779786679056357, 0.003969695813293966,
0.0020339334412434987, -0.00011345940675415259,
-0.0018344103399567666, -0.003556764701666365,
-0.004263523639408391, -0.002940568582022133,
-0.0034341188272627556, -0.006023399920020824,
-0.0077456903203677865, -0.007912219312377842,
-0.00625202770436523, -0.00530785086116117,
-0.005569722659634311, -0.004664448462594344,
-0.0037747773914077747, -0.004175649656985592,
-0.004659601521384289, -0.005008602967819641,
-0.004730625079902729, -0.0034039554356604146,
-0.0017110333873406587, -0.0006091938771510242,
-0.0016051679050678297, -0.003312864664007262,
-0.004505512715977288, -0.004152222189861692,
-0.003218596419678823, -0.0027277806209877343,
-0.001715005444317267, -0.0012589960071233749,
-0.001852908777923165, -0.002540339553144362
};
/* Center rear (180 degree) */
static const float cr_filt[128] = {
-0.00005989110716536726, -0.00022790291829128702,
0.0002659166098971966, -0.0003774772716776257,
0.0004540309551867803, -0.000420238187386368,
0.00025518536450885686, 0.00028285526288953955,
-0.001016391007574093, 0.0028634984299063795,
0.0021574799687976045, 0.01035121276682072,
-0.010481720917298163, -0.013197198495899292,
0.0031928225328717195, 0.02903137843618603,
0.1632429772511569, 0.1047487989875262,
-0.10464685060623742, -0.09260196288035998,
-0.007514241993554443, 0.013596249226741712,
-0.019876166508450258, 0.1255626123599804,
0.3648170359521724, 0.19458249753223478,
-0.04434070930031298, 0.046582528121935265,
0.09484427347230277, -0.03137795311969644,
-0.10297437925363695, -0.09351091015917065,
-0.1129521092162064, -0.14925322995658827,
-0.1231466295584665, -0.06356719756705227,
-0.05442277895126282, -0.07568433015661316,
-0.023314932828602003, 0.04260950721318558,
0.02249026315598923, 0.02048195669571197,
0.05651342117268278, 0.05885038917623213,
0.03797102097397795, 0.011767394419953451,
0.00560502503429481, 0.005051125343961189,
-0.012925933188033823, -0.023918884651306566,
-0.013251659441678816, -0.010694772488866284,
-0.03080486448617846, -0.03661278237783158,
-0.0379227303416262, -0.042189005718490775,
-0.026595666344596286, -0.009759025956801257,
-0.002064986663513004, -0.002420117028098389,
-0.006629991977552491, 0.004619970897631026,
0.019450642967537877, 0.0173521119057514,
0.017641425439988062, 0.02270029598048491,
0.018976431925275348, 0.009299852902290885,
-0.001695039371619912, -0.00675162574265618,
-0.009380968871003034, -0.011208396125485165,
-0.01308640049201482, -0.0165636375633249,
-0.022004099870933345, -0.025173458684139286,
-0.016918759559175375, -0.00865150653575917,
-0.006999929082792643, -0.005454830010518988,
-0.0021129521131095317, 0.00018717090054046307,
-0.0002864344788569993, 0.0017615225381095569,
0.006985907557802283, 0.010577308310476465,
0.006466104789306027, -0.0014988738575948326,
-0.0039669755229277195, -0.0065156971200080235,
-0.009343206924192169, -0.0076430644693577495,
-0.004395214976600924, -0.003052735340422483,
-0.007019103043066595, -0.00974109267696527,
-0.007968015032797376, -0.007801513845528344,
-0.007535748903681969, -0.003543341967287925,
0.0015083125553729722, 0.0023345972556147025,
-0.0010043623069557037, -0.0025295765105203746,
-0.0023701840891643634, -0.0005908186035024362,
0.0029826252289082847, 0.004829048542117764,
0.004488360022902081, 0.00002643748103005408,
-0.0042100779212597295, -0.006170600558114495,
-0.007267149164680168, -0.006825522903494639,
-0.006899834372739123, -0.0073493916110062675,
-0.009554351265163382, -0.011790297433830197,
-0.010645796603734424, -0.0064661575394022106,
-0.002026743466524137, -0.0004337034584909932,
-0.0011172647031654614, -0.0017947816283674731,
-0.00255615052036616, -0.0017721562881944813,
-0.0002379619297227554, 0.0007130120121089036
};
#endif /* MPLAYER_AF_HRTF_H */
-86
View File
@@ -1,86 +0,0 @@
/*
* simple voice removal filter
*
* copyright (c) 2006 Reynaldo H. Verdejo Pinochet
* Based on code by Alex Beregszaszi for his 'center' filter.
*
* 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 "af.h"
// Data for specific instances of this filter
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
switch(cmd){
case AF_CONTROL_REINIT:
mp_audio_copy_config(af->data, (struct mp_audio*)arg);
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
return af_test_output(af,(struct mp_audio*)arg);
}
return AF_UNKNOWN;
}
static int filter_frame(struct af_instance *af, struct mp_audio *c)
{
if (!c)
return 0;
if (af_make_writeable(af, c) < 0) {
talloc_free(c);
return 0;
}
float* a = c->planes[0]; // Audio data
int nch = c->nch; // Number of channels
int len = c->samples*nch; // Number of samples in current audio block
register int i;
/*
FIXME1 add a low band pass filter to avoid suppressing
centered bass/drums
FIXME2 better calculated* attenuation factor
*/
for(i=0;i<len;i+=nch)
{
a[i] = (a[i] - a[i+1]) * 0.7;
a[i+1]=a[i];
}
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->filter_frame = filter_frame;
return AF_OK;
}
// Description of this filter
const struct af_info af_info_karaoke = {
.info = "Simple karaoke/voice-removal audio filter",
.name = "karaoke",
.flags = AF_FLAGS_NOT_REENTRANT,
.open = af_open,
};
-851
View File
@@ -1,851 +0,0 @@
/*
* LADSPA plugin loader
*
* Written by Ivo van Poorten <ivop@euronet.nl>
* Copyright (C) 2004, 2005
*
* 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/>.
*/
/* ------------------------------------------------------------------------- */
/* Global Includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <math.h>
#include <limits.h>
#include <dlfcn.h>
#include <ladspa.h>
/* ------------------------------------------------------------------------- */
/* Local Includes */
#include "af.h"
#define _(x) (x)
/* ------------------------------------------------------------------------- */
/* Filter specific data */
typedef struct af_ladspa_s
{
int status; /**< Status of the filter.
* Either AF_OK or AF_ERROR
* Because MPlayer re-inits audio filters that
* _clearly_ returned AF_ERROR anyway, I use this
* in play() to skip the processing and return
* the data unchanged.
*/
int activated; /**< 0 or 1. Activate LADSPA filters only once, even
* if the buffers get resized, to avoid a stuttering
* filter.
*/
char *file;
char *label;
char *controls;
char *myname; /**< It's easy to have a concatenation of file and label */
void *libhandle;
const LADSPA_Descriptor *plugin_descriptor;
int nports;
int ninputs;
int *inputs;
int noutputs;
int *outputs;
int ninputcontrols;
int *inputcontrolsmap; /**< Map input port number [0-] to actual port */
float *inputcontrols;
int noutputcontrols;
int *outputcontrolsmap;
float *outputcontrols;
int nch; /**< number of channels */
int bufsize;
float **inbufs;
float **outbufs;
LADSPA_Handle *chhandles;
} af_ladspa_t;
/* ------------------------------------------------------------------------- */
static int af_open(struct af_instance *af);
static int af_ladspa_malloc_failed(char*);
/* ------------------------------------------------------------------------- */
#define OPT_BASE_STRUCT af_ladspa_t
const struct af_info af_info_ladspa = {
.info = "LADSPA plugin loader",
.name = "ladspa",
.open = af_open,
.priv_size = sizeof(af_ladspa_t),
.options = (const struct m_option[]) {
OPT_STRING("file", file, 0),
OPT_STRING("label", label, 0),
OPT_STRING("controls", controls, 0),
{0}
},
};
/* ------------------------------------------------------------------------- */
/* By lack of a better word (in my vocabulary) this is called 'parse'.
* Feel free to suggest an alternative.
*/
/** \brief Check for inputs, outputs and controls of a given filter.
*
* This function counts and checks all input, output and control ports
* of the filter that was loaded. If it turns out to be a valid
* filter for MPlayer use, it prints out a list of all controls and
* the corresponding range of its value at message level MSGL_V.
*
* \param setup Current setup of the filter. Must have its
* plugin_descriptor set!
*
* \return Returns AF_OK if it has a valid input/output/controls
* configuration. Else, it returns AF_ERROR.
*/
static int af_ladspa_parse_plugin(struct af_instance *af) {
af_ladspa_t *setup = af->priv;
int p, i;
const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
LADSPA_PortDescriptor d;
LADSPA_PortRangeHint hint;
if (!setup->libhandle)
return AF_ERROR; /* only call parse after a succesful load */
if (!setup->plugin_descriptor)
return AF_ERROR; /* same as above */
/* let's do it */
setup->nports = pdes->PortCount;
/* allocate memory for all inputs/outputs/controls */
setup->inputs = calloc(setup->nports, sizeof(int));
if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname);
setup->outputs = calloc(setup->nports, sizeof(int));
if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname);
setup->inputcontrolsmap = calloc(setup->nports, sizeof(int));
if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
setup->inputcontrols = calloc(setup->nports, sizeof(float));
if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname);
setup->outputcontrolsmap = calloc(setup->nports, sizeof(int));
if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
setup->outputcontrols = calloc(setup->nports, sizeof(float));
if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname);
/* set counts to zero */
setup->ninputs = 0;
setup->noutputs = 0;
setup->ninputcontrols = 0;
setup->noutputcontrols = 0;
/* check all ports, see what type it is and set variables according to
* what we have found
*/
for (p=0; p<setup->nports; p++) {
d = pdes->PortDescriptors[p];
if (LADSPA_IS_PORT_AUDIO(d)) {
if (LADSPA_IS_PORT_INPUT(d)) {
setup->inputs[setup->ninputs] = p;
setup->ninputs++;
} else if (LADSPA_IS_PORT_OUTPUT(d)) {
setup->outputs[setup->noutputs] = p;
setup->noutputs++;
}
}
if (LADSPA_IS_PORT_CONTROL(d)) {
if (LADSPA_IS_PORT_INPUT(d)) {
setup->inputcontrolsmap[setup->ninputcontrols] = p;
setup->ninputcontrols++;
/* set control to zero. set values after reading the rest
* of the suboptions and check LADSPA_?_HINT's later.
*/
setup->inputcontrols[p] = 0.0f;
} else if (LADSPA_IS_PORT_OUTPUT(d)) {
/* read and handle these too, otherwise filters that have them
* will sig11
*/
setup->outputcontrolsmap[setup->noutputcontrols]=p;
setup->noutputcontrols++;
setup->outputcontrols[p] = 0.0f;
}
}
}
if (setup->ninputs == 0) {
MP_WARN(af, "%s: %s\n", setup->myname,
_("WARNING! This LADSPA plugin has no audio inputs.\n The incoming audio signal will be lost."));
} else if (setup->ninputs == 1) {
MP_VERBOSE(af, "%s: this is a mono effect\n", setup->myname);
} else if (setup->ninputs == 2) {
MP_VERBOSE(af, "%s: this is a stereo effect\n", setup->myname);
} else {
MP_VERBOSE(af, "%s: this is a %i-channel effect, "
"support is experimental\n", setup->myname, setup->ninputs);
}
if (setup->noutputs == 0) {
MP_ERR(af, "%s: %s\n", setup->myname,
_("This LADSPA plugin has no audio outputs."));
return AF_ERROR;
}
if (setup->noutputs != setup->ninputs ) {
MP_ERR(af, "%s: %s\n", setup->myname,
_("The number of audio inputs and audio outputs of the LADSPA plugin differ."));
return AF_ERROR;
}
MP_VERBOSE(af, "%s: this plugin has %d input control(s)\n",
setup->myname, setup->ninputcontrols);
/* Print list of controls and its range of values it accepts */
for (i=0; i<setup->ninputcontrols; i++) {
p = setup->inputcontrolsmap[i];
hint = pdes->PortRangeHints[p];
MP_VERBOSE(af, " --- %d %s [", i, pdes->PortNames[p]);
if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
MP_VERBOSE(af, "%0.2f , ", hint.LowerBound);
} else {
MP_VERBOSE(af, "... , ");
}
if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
MP_VERBOSE(af, "%0.2f]\n", hint.UpperBound);
} else {
MP_VERBOSE(af, "...]\n");
}
}
return AF_OK;
}
/* ------------------------------------------------------------------------- */
/* This function might "slightly" look like dlopenLADSPA in the LADSPA SDK :-)
* But, I changed a few things, because imho it was broken. It did not support
* relative paths, only absolute paths that start with a /
* I think ../../some/dir/foobar.so is just as valid. And if one wants to call
* his library '...somename...so' he's crazy, but it should be allowed.
* So, search the path first, try plain *filename later.
* Also, try adding .so first! I like the recursion the SDK did, but it's
* better the other way around. -af ladspa=cmt:amp_stereo:0.5 is easier to type
* than -af ladspa=cmt.so:amp_stereo:0.5 :-))
*/
/** \brief dlopen() wrapper
*
* This is a wrapper around dlopen(). It tries various variations of the
* filename (with or without the addition of the .so extension) in various
* directories specified by the LADSPA_PATH environment variable. If all fails
* it tries the filename directly as an absolute path to the library.
*
* \param filename filename of the library to load.
* \param flag see dlopen(3) for a description of the flags.
*
* \return returns a pointer to the loaded library on success, or
* NULL if it fails to load.
*/
static void* mydlopen(const char *filename, int flag) {
char *buf;
const char *end, *start, *ladspapath;
int endsinso;
size_t filenamelen;
void *result = NULL;
#if defined(__MINGW32__) || defined(__CYGWIN__)
/* For Windows there's only absolute path support.
* If you have a Windows machine, feel free to fix this.
* (path separator, shared objects extension, et cetera). */
MP_VERBOSE(af, "\ton windows, only absolute pathnames "
"are supported\n");
MP_VERBOSE(af, "\ttrying %s\n", filename);
return dlopen(filename, flag);
#endif
filenamelen = strlen(filename);
endsinso = 0;
if (filenamelen > 3)
endsinso = (strcmp(filename+filenamelen-3, ".so") == 0);
if (!endsinso) {
buf=malloc(filenamelen+4);
strcpy(buf, filename);
strcat(buf, ".so");
result=mydlopen(buf, flag);
free(buf);
}
if (result)
return result;
ladspapath=getenv("LADSPA_PATH");
if (ladspapath) {
start=ladspapath;
while (*start != '\0') {
int needslash;
end=start;
while ( (*end != ':') && (*end != '\0') )
end++;
buf=malloc(filenamelen + 2 + (end-start) );
if (end > start)
strncpy(buf, start, end-start);
needslash=0;
if (end > start)
if (*(end-1) != '/') {
needslash = 1;
buf[end-start] = '/';
}
strcpy(buf+needslash+(end-start), filename);
result=dlopen(buf, flag);
free(buf);
if (result)
return result;
start = end;
if (*start == ':')
start++;
} /* end while there's still more in the path */
} /* end if there's a ladspapath */
/* last resort, just open it again, so the dlerror() message is correct */
return dlopen(filename,flag);
}
/* ------------------------------------------------------------------------- */
/** \brief Load a LADSPA Plugin
*
* This function loads the LADSPA plugin specified by the file and label
* that are present in the setup variable. First, it loads the library.
* If it fails, it returns AF_ERROR. If not, it continues to look for the
* specified label. If it finds it, it sets the plugin_descriptor inside
* setup and returns AF_OK. If it doesn't, it returns AF_ERROR. Special case
* is a label called 'help'. In that case, it prints a list of all available
* labels (filters) in the library specified by file.
*
* \param setup Current setup of the filter. Contains filename and label.
*
* \return Either AF_ERROR or AF_OK, depending on the success of the operation.
*/
static int af_ladspa_load_plugin(struct af_instance *af) {
af_ladspa_t *setup = af->priv;
const LADSPA_Descriptor *ladspa_descriptor;
LADSPA_Descriptor_Function descriptor_function;
int i;
/* load library */
MP_VERBOSE(af, "%s: loading ladspa plugin library %s\n",
setup->myname, setup->file);
setup->libhandle = mydlopen(setup->file, RTLD_NOW);
if (!setup->libhandle) {
MP_ERR(af, "%s: %s %s\n\t%s\n", setup->myname,
_("failed to load"), setup->file, dlerror() );
return AF_ERROR;
}
MP_VERBOSE(af, "%s: library found.\n", setup->myname);
/* find descriptor function */
dlerror();
descriptor_function = (LADSPA_Descriptor_Function) dlsym (setup->libhandle,
"ladspa_descriptor");
if (!descriptor_function) {
MP_ERR(af, "%s: %s\n\t%s\n", setup->myname,
_("Couldn't find ladspa_descriptor() function in the specified library file."), dlerror());
return AF_ERROR;
}
/* if label == help, list all labels in library and exit */
if (strcmp(setup->label, "help") == 0) {
MP_INFO(af, "%s: %s %s:\n", setup->myname,
_("available labels in"), setup->file);
for (i=0; ; i++) {
ladspa_descriptor = descriptor_function(i);
if (ladspa_descriptor == NULL) {
return AF_ERROR;
}
MP_INFO(af, " %-16s - %s (%lu)\n",
ladspa_descriptor->Label,
ladspa_descriptor->Name,
ladspa_descriptor->UniqueID);
}
}
MP_VERBOSE(af, "%s: looking for label\n", setup->myname);
/* find label in library */
for (i=0; ; i++) {
ladspa_descriptor = descriptor_function(i);
if (ladspa_descriptor == NULL) {
MP_ERR(af, "%s: %s\n", setup->myname,
_("Couldn't find label in plugin library."));
return AF_ERROR;
}
if (strcmp(ladspa_descriptor->Label, setup->label) == 0) {
setup->plugin_descriptor = ladspa_descriptor;
MP_VERBOSE(af, "%s: %s found\n", setup->myname,
setup->label);
return AF_OK;
}
}
return AF_OK;
}
/* ------------------------------------------------------------------------- */
/** \brief Print a malloc() failed error message.
*
* Generic function which can be called if a call to malloc(), calloc(),
* strdup(), et cetera, failed. It prints a message to the console and
* returns AF_ERROR.
*
* \return AF_ERROR
*/
static int af_ladspa_malloc_failed(char *myname) {
return AF_ERROR;
}
/* ------------------------------------------------------------------------- */
/** \brief Controls the filter.
*
* Control the behaviour of the filter.
*
* Commands:
* CONTROL_REINIT Sets the af structure with proper values for number
* of channels, rate, format, et cetera.
* \param af Audio filter instance
* \param cmd The command to execute
* \param arg Arguments to the command
*
* \return Either AF_ERROR or AF_OK, depending on the succes of the
* operation.
*/
static int control(struct af_instance *af, int cmd, void *arg) {
af_ladspa_t *setup = (af_ladspa_t*) af->priv;
switch(cmd) {
case AF_CONTROL_REINIT:
MP_VERBOSE(af, "%s: (re)init\n", setup->myname);
if (!arg) return AF_ERROR;
/* accept FLOAT, let af_format do conversion */
mp_audio_copy_config(af->data, (struct mp_audio*)arg);
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
return af_test_output(af, (struct mp_audio*)arg);
}
return AF_UNKNOWN;
}
/* ------------------------------------------------------------------------- */
/** \brief Uninitialise the LADSPA Plugin Loader filter.
*
* This function deactivates the plugin(s), cleans up, frees all allocated
* memory and exits.
*
* \return No return value.
*/
static void uninit(struct af_instance *af) {
if (af->priv) {
af_ladspa_t *setup = (af_ladspa_t*) af->priv;
const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
if (setup->myname) {
MP_VERBOSE(af, "%s: cleaning up\n", setup->myname);
free(setup->myname);
}
if (setup->chhandles) {
for (int i = 0; i < setup->nch; i+=setup->ninputs) {
if (pdes->deactivate) pdes->deactivate(setup->chhandles[i]);
if (pdes->cleanup) pdes->cleanup(setup->chhandles[i]);
}
free(setup->chhandles);
}
free(setup->inputcontrolsmap);
free(setup->inputcontrols);
free(setup->outputcontrolsmap);
free(setup->outputcontrols);
free(setup->inputs);
free(setup->outputs);
if (setup->inbufs) {
for(int i = 0; i < setup->nch; i++)
free(setup->inbufs[i]);
free(setup->inbufs);
}
if (setup->outbufs) {
for (int i = 0; i < setup->nch; i++)
free(setup->outbufs[i]);
free(setup->outbufs);
}
if (setup->libhandle)
dlclose(setup->libhandle);
}
}
/* ------------------------------------------------------------------------- */
/** \brief Process chunk of audio data through the selected LADSPA Plugin.
*
* \param af Pointer to audio filter instance
* \param data Pointer to chunk of audio data
*
* \return Either AF_ERROR or AF_OK
*/
static int filter_frame(struct af_instance *af, struct mp_audio *data)
{
if (!data)
return 0;
af_ladspa_t *setup = af->priv;
const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
float *audio = (float*)data->planes[0];
int nsamples = data->samples*data->nch;
int nch = data->nch;
int rate = data->rate;
int i, p;
if (setup->status !=AF_OK) {
talloc_free(data);
return -1;
}
if (af_make_writeable(af, data) < 0) {
talloc_free(data);
return -1;
}
/* See if it's the first call. If so, setup inbufs/outbufs, instantiate
* plugin, connect ports and activate plugin
*/
if ( (setup->bufsize != nsamples/nch) || (setup->nch != nch) ) {
/* if setup->nch==0, it's the first call, if not, something has
* changed and all previous mallocs have to be freed
*/
if (setup->nch != 0) {
MP_TRACE(af, "%s: bufsize change; free old buffer\n",
setup->myname);
if(setup->inbufs) {
for(i=0; i<setup->nch; i++)
free(setup->inbufs[i]);
free(setup->inbufs);
}
if(setup->outbufs) {
for(i=0; i<setup->nch; i++)
free(setup->outbufs[i]);
free(setup->outbufs);
}
} /* everything is freed */
setup->bufsize = nsamples/nch;
setup->nch = nch;
setup->inbufs = calloc(nch, sizeof(float*));
setup->outbufs = calloc(nch, sizeof(float*));
MP_TRACE(af, "%s: bufsize = %d\n",
setup->myname, setup->bufsize);
for(i=0; i<nch; i++) {
setup->inbufs[i] = calloc(setup->bufsize, sizeof(float));
setup->outbufs[i] = calloc(setup->bufsize, sizeof(float));
}
/* only on the first call, there are no handles. */
if (!setup->chhandles) {
setup->chhandles = calloc(nch, sizeof(LADSPA_Handle));
/* create handles
* for stereo effects, create one handle for two channels
*/
for(i=0; i<nch; i++) {
if (i % setup->ninputs) { /* stereo effect */
/* copy the handle from previous channel */
setup->chhandles[i] = setup->chhandles[i-1];
continue;
}
setup->chhandles[i] = pdes->instantiate(pdes, rate);
}
}
/* connect input/output ports for each channel/filter instance
*
* always (re)connect ports
*/
for(i=0; i<nch; i++) {
pdes->connect_port(setup->chhandles[i],
setup->inputs[i % setup->ninputs],
setup->inbufs[i]);
pdes->connect_port(setup->chhandles[i],
setup->outputs[i % setup->ninputs],
setup->outbufs[i]);
/* connect (input) controls */
for (p=0; p<setup->nports; p++) {
LADSPA_PortDescriptor d = pdes->PortDescriptors[p];
if (LADSPA_IS_PORT_CONTROL(d)) {
if (LADSPA_IS_PORT_INPUT(d)) {
pdes->connect_port(setup->chhandles[i], p,
&(setup->inputcontrols[p]) );
} else {
pdes->connect_port(setup->chhandles[i], p,
&(setup->outputcontrols[p]) );
}
}
}
/* Activate filter (if it isn't already :) ) */
if (pdes->activate && !setup->activated && i % setup->ninputs == 0)
pdes->activate(setup->chhandles[i]);
} /* All channels/filters done! except for... */
setup->activated = 1;
/* Stereo effect with one channel left. Use same buffer for left
* and right. connect it to the second port.
*/
for (p = i; p % setup->ninputs; p++) {
pdes->connect_port(setup->chhandles[i-1],
setup->inputs[p % setup->ninputs],
setup->inbufs[i-1]);
pdes->connect_port(setup->chhandles[i-1],
setup->outputs[p % setup->ninputs],
setup->outbufs[i-1]);
} /* done! */
} /* setup for first call/change of bufsize is done.
* normal playing routine follows...
*/
/* Right now, I use a separate input and output buffer.
* I could change this to in-place processing (inbuf==outbuf), but some
* ladspa filters are broken and are not able to handle that. This seems
* fast enough, so unless somebody complains, it stays this way :)
*/
/* Fill inbufs */
for (p=0; p<setup->bufsize; p++) {
for (i=0; i<nch; i++) {
setup->inbufs[i][p] = audio[p*nch + i];
}
}
/* Run filter(s) */
for (i=0; i<nch; i+=setup->ninputs) {
pdes->run(setup->chhandles[i], setup->bufsize);
}
/* Extract outbufs */
for (p=0; p<setup->bufsize; p++) {
for (i=0; i<nch; i++) {
audio[p*nch + i] = setup->outbufs[i][p];
}
}
/* done */
af_add_output_frame(af, data);
return 0;
}
/* ------------------------------------------------------------------------- */
/** \brief Open LADSPA Plugin Loader Filter
*
* \param af Audio Filter instance
*
* \return Either AF_ERROR or AF_OK
*/
static int af_open(struct af_instance *af) {
af->control=control;
af->uninit=uninit;
af->filter_frame = filter_frame;
af_ladspa_t *setup = af->priv;
setup->status = AF_ERROR; /* will be set to AF_OK if
* all went OK and filter()
* should proceed.
*/
setup->myname = strdup(af_info_ladspa.name);
if (!setup->myname)
return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
if (!setup->file || !setup->file[0]) {
MP_ERR(af, "%s: %s\n", setup->myname,
_("No library file specified."));
uninit(af);
return AF_ERROR;
}
if (!setup->label || !setup->label[0]) {
MP_ERR(af, "%s: %s\n", setup->myname,
_("No filter label specified."));
uninit(af);
return AF_ERROR;
}
free(setup->myname);
setup->myname = calloc(strlen(af_info_ladspa.name)+strlen(setup->file)+
strlen(setup->label)+6, 1);
snprintf(setup->myname, strlen(af_info_ladspa.name)+
strlen(setup->file)+strlen(setup->label)+6, "%s: (%s:%s)",
af_info_ladspa.name, setup->file, setup->label);
/* load plugin :) */
if ( af_ladspa_load_plugin(af) != AF_OK )
return AF_ERROR;
/* see what inputs, outputs and controls this plugin has */
if ( af_ladspa_parse_plugin(af) != AF_OK )
return AF_ERROR;
/* ninputcontrols is set by now, read control values from arg */
float val;
char *line = setup->controls;
for (int i = 0; i < setup->ninputcontrols; i++) {
if (!line || (i != 0 && *line != ',')) {
MP_ERR(af, "%s: %s\n", setup->myname,
_("Not enough controls specified on the command line."));
return AF_ERROR;
}
if (i != 0)
line++;
if (sscanf(line, "%f", &val) != 1) {
MP_ERR(af, "%s: %s\n", setup->myname,
_("Not enough controls specified on the command line."));
return AF_ERROR;
}
setup->inputcontrols[setup->inputcontrolsmap[i]] = val;
line = strchr(line, ',');
}
MP_VERBOSE(af, "%s: input controls: ", setup->myname);
for (int i = 0; i < setup->ninputcontrols; i++) {
MP_VERBOSE(af, "%0.4f ",
setup->inputcontrols[setup->inputcontrolsmap[i]]);
}
MP_VERBOSE(af, "\n");
/* check boundaries of inputcontrols */
MP_VERBOSE(af, "%s: checking boundaries of input controls\n",
setup->myname);
for (int i = 0; i < setup->ninputcontrols; i++) {
int p = setup->inputcontrolsmap[i];
LADSPA_PortRangeHint hint =
setup->plugin_descriptor->PortRangeHints[p];
val = setup->inputcontrols[p];
if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) &&
val < hint.LowerBound) {
MP_ERR(af, "%s: Input control #%d is below lower boundary of %0.4f.\n",
setup->myname, i, hint.LowerBound);
return AF_ERROR;
}
if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
val > hint.UpperBound) {
MP_ERR(af, "%s: Input control #%d is above upper boundary of %0.4f.\n",
setup->myname, i, hint.UpperBound);
return AF_ERROR;
}
}
MP_VERBOSE(af, "%s: all controls have sane values\n",
setup->myname);
/* All is well! */
setup->status = AF_OK;
return AF_OK;
}
/* ------------------------------------------------------------------------- */
+39 -21
View File
@@ -26,7 +26,6 @@
#include <assert.h>
#include <libavcodec/avcodec.h>
#include <libavutil/audioconvert.h>
#include <libavutil/intreadwrite.h>
#include <libavutil/common.h>
#include <libavutil/bswap.h>
@@ -50,7 +49,6 @@ const uint16_t ac3_bitrate_tab[19] = {
typedef struct af_ac3enc_s {
struct AVCodec *lavc_acodec;
struct AVCodecContext *lavc_actx;
AVPacket pkt;
int bit_rate;
struct mp_audio *input; // frame passed to libavcodec
struct mp_audio *pending; // unconsumed input data
@@ -75,7 +73,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
struct mp_audio *in = arg;
struct mp_audio orig_in = *in;
if (AF_FORMAT_IS_SPECIAL(in->format) || in->nch < s->cfg_min_channel_num)
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);
@@ -147,7 +145,6 @@ static void uninit(struct af_instance* af)
af_ac3enc_t *s = af->priv;
if (s) {
av_free_packet(&s->pkt);
if(s->lavc_actx) {
avcodec_close(s->lavc_actx);
av_free(s->lavc_actx);
@@ -156,6 +153,13 @@ 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;
}
static int filter_frame(struct af_instance *af, struct mp_audio *audio)
{
af_ac3enc_t *s = af->priv;
@@ -166,6 +170,7 @@ static int filter_frame(struct af_instance *af, struct mp_audio *audio)
talloc_free(s->pending);
s->pending = audio;
update_delay(af);
return 0;
}
@@ -177,22 +182,27 @@ static void swap_16(uint16_t *ptr, size_t size)
// Copy data from input frame to encode frame (because libavcodec wants a full
// AC3 frame for encoding, while filter input frames can be smaller or larger).
// Return true if the
static bool fill_buffer(af_ac3enc_t *s)
// Return true if the frame is complete.
static bool fill_buffer(struct af_instance *af)
{
af_ac3enc_t *s = af->priv;
af->delay = 0;
if (s->pending) {
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);
mp_audio_skip_samples(s->pending, copy);
}
update_delay(af);
return s->input->samples >= s->in_samples;
}
static int filter_out(struct af_instance *af)
{
af_ac3enc_t *s = af->priv;
if (!fill_buffer(s))
if (!fill_buffer(af))
return 0; // need more input
AVFrame *frame = av_frame_alloc();
@@ -200,6 +210,8 @@ static int filter_out(struct af_instance *af)
MP_FATAL(af, "Could not allocate memory \n");
return -1;
}
int err = -1;
frame->nb_samples = s->in_samples;
frame->format = s->lavc_actx->sample_fmt;
frame->channel_layout = s->lavc_actx->channel_layout;
@@ -209,30 +221,33 @@ static int filter_out(struct af_instance *af)
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, &s->pkt, frame, &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) {
MP_FATAL(af, "Encode failed.\n");
return -1;
goto done;
}
MP_DBG(af, "avcodec_encode_audio got %d, pending %d.\n",
s->pkt.size, s->pending->samples);
pkt.size, s->pending->samples);
struct mp_audio *out =
mp_audio_pool_get(af->out_pool, af->data, s->out_samples);
if (!out)
return -1;
goto done;
mp_audio_copy_attributes(out, s->pending);
int frame_size = s->pkt.size;
int frame_size = pkt.size;
int header_len = 0;
char hdr[8];
if (s->cfg_add_iec61937_header && s->pkt.size > 5) {
int bsmod = s->pkt.data[5] & 0x7;
if (s->cfg_add_iec61937_header && pkt.size > 5) {
int bsmod = pkt.data[5] & 0x7;
int len = frame_size;
frame_size = AC3_FRAME_SIZE * 2 * 2;
@@ -250,13 +265,18 @@ static int filter_out(struct af_instance *af)
char *buf = (char *)out->planes[0];
memcpy(buf, hdr, header_len);
memcpy(buf + header_len, s->pkt.data, s->pkt.size);
memset(buf + header_len + s->pkt.size, 0,
frame_size - (header_len + s->pkt.size));
swap_16((uint16_t *)(buf + header_len), s->pkt.size / 2);
memcpy(buf + header_len, pkt.data, pkt.size);
memset(buf + header_len + pkt.size, 0,
frame_size - (header_len + pkt.size));
swap_16((uint16_t *)(buf + header_len), pkt.size / 2);
out->samples = frame_size / out->sstride;
af_add_output_frame(af, out);
return 0;
update_delay(af);
err = 0;
done:
av_packet_unref(&pkt);
return err;
}
static int af_open(struct af_instance* af){
@@ -294,8 +314,6 @@ static int af_open(struct af_instance* af){
MP_VERBOSE(af, "[af_lavcac3enc]: in sample format: %s\n",
af_fmt_to_str(s->in_sampleformat));
av_init_packet(&s->pkt);
s->input = talloc_zero(s, struct mp_audio);
if (s->cfg_bit_rate) {
+28 -3
View File
@@ -34,11 +34,14 @@
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include "config.h"
#include "audio/format.h"
#include "audio/fmt-conversion.h"
#include "af.h"
#include "common/av_common.h"
#include "common/tags.h"
#include "options/m_option.h"
@@ -63,6 +66,8 @@ struct priv {
bool eof;
struct mp_tags *metadata;
// options
char *cfg_graph;
char **cfg_avopts;
@@ -190,6 +195,10 @@ static int control(struct af_instance *af, int cmd, void *arg)
if (af_to_avformat(in->format) == AV_SAMPLE_FMT_NONE)
mp_audio_set_format(in, AF_FORMAT_FLOAT);
// Removing this requires fixing AVFrame.data vs. AVFrame.extended_data
if (in->channels.num > AV_NUM_DATA_POINTERS)
return AF_ERROR;
if (!mp_chmap_is_lavc(&in->channels))
mp_chmap_reorder_to_lavc(&in->channels); // will always work
@@ -206,13 +215,19 @@ static int control(struct af_instance *af, int cmd, void *arg)
mp_chmap_from_lavc(&out_cm, l_out->channel_layout);
mp_audio_set_channels(out, &out_cm);
if (!mp_audio_config_valid(out))
if (!mp_audio_config_valid(out) || out->channels.num > AV_NUM_DATA_POINTERS)
return AF_ERROR;
p->timebase_out = l_out->time_base;
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
}
case AF_CONTROL_GET_METADATA:
if (p->metadata) {
*(struct mp_tags *)arg = *p->metadata;
return CONTROL_OK;
}
return CONTROL_NA;
case AF_CONTROL_RESET:
reset(af);
return AF_OK;
@@ -220,6 +235,17 @@ static int control(struct af_instance *af, int cmd, void *arg)
return AF_UNKNOWN;
}
static void get_metadata_from_av_frame(struct af_instance *af, AVFrame *frame)
{
#if HAVE_AVFRAME_METADATA
struct priv *p = af->priv;
if (!p->metadata)
p->metadata = talloc_zero(p, struct mp_tags);
mp_tags_copy_from_av_dictionary(p->metadata, av_frame_get_metadata(frame));
#endif
}
static int filter_frame(struct af_instance *af, struct mp_audio *data)
{
struct priv *p = af->priv;
@@ -307,6 +333,7 @@ static int filter_out(struct af_instance *af)
af->delay = in_time - out_time;
}
get_metadata_from_av_frame(af, frame);
af_add_output_frame(af, out);
av_frame_free(&frame);
return 0;
@@ -326,8 +353,6 @@ static int af_open(struct af_instance *af)
af->uninit = uninit;
af->filter_frame = filter_frame;
af->filter_out = filter_out;
// Removing this requires fixing AVFrame.data vs. AVFrame.extended_data
assert(MP_NUM_CHANNELS <= AV_NUM_DATA_POINTERS);
return AF_OK;
}
+233 -164
View File
@@ -28,9 +28,9 @@
#include <assert.h>
#include <libavutil/opt.h>
#include <libavutil/audioconvert.h>
#include <libavutil/common.h>
#include <libavutil/samplefmt.h>
#include <libavutil/channel_layout.h>
#include <libavutil/mathematics.h>
#include "common/common.h"
@@ -49,6 +49,7 @@
#define avresample_convert(ctx, out, out_planesize, out_samples, in, in_planesize, in_samples) \
swr_convert(ctx, out, out_samples, (const uint8_t**)(in), in_samples)
#define avresample_set_channel_mapping swr_set_channel_mapping
#define avresample_set_compensation swr_set_compensation
#else
#error "config.h broken or no resampler found"
#endif
@@ -58,12 +59,30 @@
#include "options/m_option.h"
#include "audio/filter/af.h"
#include "audio/fmt-conversion.h"
#include "osdep/endian.h"
struct af_resample_opts {
int filter_size;
int phase_shift;
int linear;
double cutoff;
int normalize;
};
struct af_resample {
int allow_detach;
char **avopts;
double playback_speed;
struct AVAudioResampleContext *avrctx;
struct mp_audio avrctx_fmt; // output format of avrctx
struct mp_audio pool_fmt; // format used to allocate frames for avrctx output
struct mp_audio pre_out_fmt; // format before final conversion (S24)
struct AVAudioResampleContext *avrctx_out; // for output channel reordering
struct af_resample_opts opts; // opts requested by the user
// At least libswresample keeps a pointer around for this:
int reorder_in[MP_NUM_CHANNELS];
int reorder_out[MP_NUM_CHANNELS];
struct mp_audio_pool *reorder_buffer;
int in_rate_af; // filter input sample rate
int in_rate; // actual rate (used by lavr), adjusted for playback speed
@@ -74,51 +93,53 @@ struct af_resample_opts {
struct mp_chmap out_channels;
};
struct af_resample {
int allow_detach;
char **avopts;
double playback_speed;
struct mp_audio *pending;
bool avrctx_ok;
struct AVAudioResampleContext *avrctx;
struct mp_audio avrctx_fmt; // output format of avrctx
struct AVAudioResampleContext *avrctx_out; // for output channel reordering
struct af_resample_opts ctx; // opts in the context
struct af_resample_opts opts; // opts requested by the user
// At least libswresample keeps a pointer around for this:
int reorder_in[MP_NUM_CHANNELS];
int reorder_out[MP_NUM_CHANNELS];
struct mp_audio_pool *reorder_buffer;
};
#if HAVE_LIBAVRESAMPLE
static int get_delay(struct af_resample *s)
static double get_delay(struct af_resample *s)
{
return avresample_get_delay(s->avrctx);
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_drain_samples(struct af_resample *s)
static int get_out_samples(struct af_resample *s, int in_samples)
{
return avresample_get_out_samples(s->avrctx, 0);
return avresample_get_out_samples(s->avrctx, in_samples);
}
#else
static int get_delay(struct af_resample *s)
static double get_delay(struct af_resample *s)
{
return swr_get_delay(s->avrctx, s->ctx.in_rate);
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_drain_samples(struct af_resample *s)
static int get_out_samples(struct af_resample *s, int in_samples)
{
return 4096; // libswscale does not have this
#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
static void close_lavrr(struct af_instance *af)
{
struct af_resample *s = af->priv;
if (s->avrctx)
avresample_close(s->avrctx);
avresample_free(&s->avrctx);
if (s->avrctx_out)
avresample_close(s->avrctx_out);
avresample_free(&s->avrctx_out);
}
static int resample_frame(struct AVAudioResampleContext *r,
struct mp_audio *out, struct mp_audio *in)
{
@@ -141,27 +162,21 @@ static int rate_from_speed(int rate, double speed)
return lrint(rate * speed);
}
static bool needs_lavrctx_reconfigure(struct af_resample *s,
struct mp_audio *in,
struct mp_audio *out)
// Return the format libavresample should convert to, given the final output
// format mp_format. In some cases (S24) we perform an extra conversion step,
// and signal here what exactly libavresample should output. It will be the
// input to the final conversion to mp_format.
static int check_output_conversion(int mp_format)
{
return s->ctx.in_rate_af != in->rate ||
s->ctx.in_format != in->format ||
!mp_chmap_equals(&s->ctx.in_channels, &in->channels) ||
s->ctx.out_rate != out->rate ||
s->ctx.out_format != out->format ||
!mp_chmap_equals(&s->ctx.out_channels, &out->channels) ||
s->ctx.filter_size != s->opts.filter_size ||
s->ctx.phase_shift != s->opts.phase_shift ||
s->ctx.linear != s->opts.linear ||
s->ctx.cutoff != s->opts.cutoff;
if (mp_format == AF_FORMAT_S24)
return AV_SAMPLE_FMT_S32;
return af_to_avformat(mp_format);
}
static bool test_conversion(int src_format, int dst_format)
bool af_lavrresample_test_conversion(int src_format, int dst_format)
{
return af_to_avformat(src_format) != AV_SAMPLE_FMT_NONE &&
af_to_avformat(dst_format) != AV_SAMPLE_FMT_NONE;
check_output_conversion(dst_format) != AV_SAMPLE_FMT_NONE;
}
// mp_chmap_get_reorder() performs:
@@ -181,52 +196,48 @@ static void transpose_order(int *map, int num)
}
static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
struct mp_audio *out)
struct mp_audio *out, bool verbose)
{
struct af_resample *s = af->priv;
s->avrctx_ok = false;
close_lavrr(af);
s->avrctx = avresample_alloc_context();
s->avrctx_out = avresample_alloc_context();
if (!s->avrctx || !s->avrctx_out)
goto error;
enum AVSampleFormat in_samplefmt = af_to_avformat(in->format);
enum AVSampleFormat out_samplefmt = af_to_avformat(out->format);
enum AVSampleFormat out_samplefmtp =
af_to_avformat(af_fmt_to_planar(out->format));
enum AVSampleFormat out_samplefmt = check_output_conversion(out->format);
enum AVSampleFormat out_samplefmtp = av_get_planar_sample_fmt(out_samplefmt);
if (in_samplefmt == AV_SAMPLE_FMT_NONE ||
out_samplefmt == AV_SAMPLE_FMT_NONE ||
out_samplefmtp == AV_SAMPLE_FMT_NONE)
return AF_ERROR;
goto error;
avresample_close(s->avrctx);
avresample_close(s->avrctx_out);
s->out_rate = out->rate;
s->in_rate_af = in->rate;
s->in_rate = rate_from_speed(in->rate, s->playback_speed);
s->out_format = out->format;
s->in_format = in->format;
s->out_channels= out->channels;
s->in_channels = in->channels;
talloc_free(s->pending);
s->pending = NULL;
av_opt_set_int(s->avrctx, "filter_size", s->opts.filter_size, 0);
av_opt_set_int(s->avrctx, "phase_shift", s->opts.phase_shift, 0);
av_opt_set_int(s->avrctx, "linear_interp", s->opts.linear, 0);
s->ctx.out_rate = out->rate;
s->ctx.in_rate_af = in->rate;
s->ctx.in_rate = rate_from_speed(in->rate, s->playback_speed);
s->ctx.out_format = out->format;
s->ctx.in_format = in->format;
s->ctx.out_channels= out->channels;
s->ctx.in_channels = in->channels;
s->ctx.filter_size = s->opts.filter_size;
s->ctx.phase_shift = s->opts.phase_shift;
s->ctx.linear = s->opts.linear;
s->ctx.cutoff = s->opts.cutoff;
av_opt_set_int(s->avrctx, "filter_size", s->ctx.filter_size, 0);
av_opt_set_int(s->avrctx, "phase_shift", s->ctx.phase_shift, 0);
av_opt_set_int(s->avrctx, "linear_interp", s->ctx.linear, 0);
av_opt_set_double(s->avrctx, "cutoff", s->ctx.cutoff, 0);
av_opt_set_double(s->avrctx, "cutoff", s->opts.cutoff, 0);
#if HAVE_LIBSWRESAMPLE
av_opt_set_double(s->avrctx, "rematrix_maxval", 1.0, 0);
av_opt_set_double(s->avrctx, "rematrix_maxval", s->opts.normalize ? 1 : 1000, 0);
#else
av_opt_set_int(s->avrctx, "normalize_mix_level", s->opts.normalize, 0);
#endif
if (mp_set_avopts(af->log, s->avrctx, s->avopts) < 0)
return AF_ERROR;
goto error;
struct mp_chmap map_in = in->channels;
struct mp_chmap map_out = out->channels;
@@ -241,19 +252,24 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
uint64_t in_ch_layout = mp_chmap_to_lavc_unchecked(&map_in);
uint64_t out_ch_layout = mp_chmap_to_lavc_unchecked(&map_out);
struct mp_chmap in_lavc;
struct mp_chmap in_lavc, out_lavc;
mp_chmap_from_lavc(&in_lavc, in_ch_layout);
mp_chmap_from_lavc(&out_lavc, out_ch_layout);
if (verbose && !mp_chmap_equals(&in_lavc, &out_lavc)) {
MP_VERBOSE(af, "Remix: %s -> %s\n", mp_chmap_to_str(&in_lavc),
mp_chmap_to_str(&out_lavc));
}
if (in_lavc.num != map_in.num) {
// For handling NA channels, we would have to add a planarization step.
MP_FATAL(af, "Unsupported channel remapping.\n");
return AF_ERROR;
goto error;
}
mp_chmap_get_reorder(s->reorder_in, &map_in, &in_lavc);
transpose_order(s->reorder_in, map_in.num);
struct mp_chmap out_lavc;
mp_chmap_from_lavc(&out_lavc, out_ch_layout);
if (mp_chmap_equals(&out_lavc, &map_out)) {
// No intermediate step required - output new format directly.
out_samplefmtp = out_samplefmt;
@@ -262,48 +278,61 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
struct mp_chmap withna = out_lavc;
mp_chmap_fill_na(&withna, map_out.num);
if (withna.num != map_out.num)
return AF_ERROR;
mp_chmap_get_reorder(s->reorder_out, &out_lavc, &map_out);
goto error;
}
mp_chmap_get_reorder(s->reorder_out, &out_lavc, &map_out);
s->avrctx_fmt = *out;
mp_audio_set_channels(&s->avrctx_fmt, &out_lavc);
mp_audio_set_format(&s->avrctx_fmt, af_from_avformat(out_samplefmtp));
s->pre_out_fmt = *out;
mp_audio_set_format(&s->pre_out_fmt, af_from_avformat(out_samplefmt));
// If there are NA channels, the final output will have more channels than
// the avrctx output. Also, avrctx will output planar (out_samplefmtp was
// not overwritten). Allocate the output frame with more channels, so the
// NA channels can be trivially added.
s->pool_fmt = s->avrctx_fmt;
if (map_out.num > out_lavc.num)
mp_audio_set_channels(&s->pool_fmt, &map_out);
// Real conversion; output is input to avrctx_out.
av_opt_set_int(s->avrctx, "in_channel_layout", in_ch_layout, 0);
av_opt_set_int(s->avrctx, "out_channel_layout", out_ch_layout, 0);
av_opt_set_int(s->avrctx, "in_sample_rate", s->ctx.in_rate, 0);
av_opt_set_int(s->avrctx, "out_sample_rate", s->ctx.out_rate, 0);
av_opt_set_int(s->avrctx, "in_sample_rate", s->in_rate, 0);
av_opt_set_int(s->avrctx, "out_sample_rate", s->out_rate, 0);
av_opt_set_int(s->avrctx, "in_sample_fmt", in_samplefmt, 0);
av_opt_set_int(s->avrctx, "out_sample_fmt", out_samplefmtp, 0);
// Just needs the correct number of channels.
int fake_out_ch_layout = av_get_default_channel_layout(map_out.num);
// Just needs the correct number of channels for deplanarization.
struct mp_chmap fake_chmap;
mp_chmap_set_unknown(&fake_chmap, map_out.num);
uint64_t fake_out_ch_layout = mp_chmap_to_lavc_unchecked(&fake_chmap);
if (!fake_out_ch_layout)
return AF_ERROR;
// Deplanarize if needed.
goto error;
av_opt_set_int(s->avrctx_out, "in_channel_layout", fake_out_ch_layout, 0);
av_opt_set_int(s->avrctx_out, "out_channel_layout", fake_out_ch_layout, 0);
av_opt_set_int(s->avrctx_out, "in_sample_fmt", out_samplefmtp, 0);
av_opt_set_int(s->avrctx_out, "out_sample_fmt", out_samplefmt, 0);
av_opt_set_int(s->avrctx_out, "in_sample_rate", s->ctx.out_rate, 0);
av_opt_set_int(s->avrctx_out, "out_sample_rate", s->ctx.out_rate, 0);
av_opt_set_int(s->avrctx_out, "in_sample_rate", s->out_rate, 0);
av_opt_set_int(s->avrctx_out, "out_sample_rate", s->out_rate, 0);
// API has weird requirements, quoting avresample.h:
// * This function can only be called when the allocated context is not open.
// * Also, the input channel layout must have already been set.
avresample_set_channel_mapping(s->avrctx, s->reorder_in);
if (avresample_open(s->avrctx) < 0 ||
avresample_open(s->avrctx_out) < 0)
{
if (avresample_open(s->avrctx) < 0 || avresample_open(s->avrctx_out) < 0) {
MP_ERR(af, "Cannot open Libavresample Context. \n");
return AF_ERROR;
goto error;
}
s->avrctx_ok = true;
return AF_OK;
error:
close_lavrr(af);
return AF_ERROR;
}
@@ -331,20 +360,20 @@ static int control(struct af_instance *af, int cmd, void *arg)
if (af_to_avformat(in->format) == AV_SAMPLE_FMT_NONE)
mp_audio_set_format(in, AF_FORMAT_FLOAT);
if (af_to_avformat(out->format) == AV_SAMPLE_FMT_NONE)
if (check_output_conversion(out->format) == AV_SAMPLE_FMT_NONE)
mp_audio_set_format(out, in->format);
int r = ((in->format == orig_in.format) &&
mp_chmap_equals(&in->channels, &orig_in.channels))
? AF_OK : AF_FALSE;
if (r == AF_OK && needs_lavrctx_reconfigure(s, in, out))
r = configure_lavrr(af, in, out);
if (r == AF_OK)
r = configure_lavrr(af, in, out, true);
return r;
}
case AF_CONTROL_SET_FORMAT: {
int format = *(int *)arg;
if (format && af_to_avformat(format) == AV_SAMPLE_FMT_NONE)
if (format && check_output_conversion(format) == AV_SAMPLE_FMT_NONE)
return AF_FALSE;
mp_audio_set_format(af->data, format);
@@ -359,89 +388,94 @@ static int control(struct af_instance *af, int cmd, void *arg)
return AF_OK;
case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: {
s->playback_speed = *(double *)arg;
int new_rate = rate_from_speed(s->ctx.in_rate_af, s->playback_speed);
if (new_rate != s->ctx.in_rate && s->avrctx_ok && af->fmt_out.format) {
// Before reconfiguring, drain the audio that is still buffered
// in the resampler.
struct mp_audio *pending = talloc_zero(NULL, struct mp_audio);
mp_audio_copy_config(pending, &af->fmt_out);
pending->samples = get_drain_samples(s);
if (pending->samples > 0) {
mp_audio_realloc_min(pending, pending->samples);
int r = resample_frame(s->avrctx, pending, NULL);
pending->samples = MPMAX(r, 0);
}
// Reinitialize resampler.
configure_lavrr(af, &af->fmt_in, &af->fmt_out);
s->pending = pending;
}
return AF_OK;
}
case AF_CONTROL_RESET:
drop_all_output(s);
if (s->avrctx)
drop_all_output(s);
return AF_OK;
}
return AF_UNKNOWN;
}
#undef ctx_opt_set_int
#undef ctx_opt_set_dbl
static void uninit(struct af_instance *af)
{
struct af_resample *s = af->priv;
if (s->avrctx)
avresample_close(s->avrctx);
avresample_free(&s->avrctx);
if (s->avrctx_out)
avresample_close(s->avrctx_out);
avresample_free(&s->avrctx_out);
talloc_free(s->pending);
close_lavrr(af);
}
// The LSB is always ignored.
#if BYTE_ORDER == BIG_ENDIAN
#define SHIFT24(x) ((3-(x))*8)
#else
#define SHIFT24(x) (((x)+1)*8)
#endif
static void extra_output_conversion(struct af_instance *af, struct mp_audio *mpa)
{
if (mpa->format == AF_FORMAT_S32 && af->data->format == AF_FORMAT_S24) {
size_t len = mp_audio_psize(mpa) / mpa->bps;
for (int s = 0; s < len; s++) {
uint32_t val = *((uint32_t *)mpa->planes[0] + s);
uint8_t *ptr = (uint8_t *)mpa->planes[0] + s * 3;
ptr[0] = val >> SHIFT24(0);
ptr[1] = val >> SHIFT24(1);
ptr[2] = val >> SHIFT24(2);
}
mp_audio_set_format(mpa, AF_FORMAT_S24);
}
for (int p = 0; p < mpa->num_planes; p++) {
void *ptr = mpa->planes[p];
int total = mpa->samples * mpa->spf;
if (af_fmt_from_planar(mpa->format) == AF_FORMAT_FLOAT) {
for (int s = 0; s < total; s++)
((float *)ptr)[s] = av_clipf(((float *)ptr)[s], -1.0f, 1.0f);
} else if (af_fmt_from_planar(mpa->format) == AF_FORMAT_DOUBLE) {
for (int s = 0; s < total; s++)
((double *)ptr)[s] = MPCLAMP(((double *)ptr)[s], -1.0, 1.0);
}
}
}
// This relies on the tricky way mpa was allocated.
static void reorder_planes(struct mp_audio *mpa, int *reorder,
struct mp_chmap *newmap)
{
struct mp_audio prev = *mpa;
for (int n = 0; n < newmap->num; n++) {
int src = reorder[n];
if (src < 0) {
src = 0; // Use the first plane for padding channels.
mpa->readonly = true;
}
assert(src < mpa->num_planes);
mpa->planes[n] = prev.planes[src];
}
mp_audio_set_channels(mpa, newmap);
// The trailing planes were never written by avrctx, they're the NA channels.
int next_na = prev.num_planes;
for (int n = 0; n < mpa->num_planes; n++) {
int src = reorder[n];
assert(src >= -1 && src < prev.num_planes);
if (src >= 0) {
mpa->planes[n] = prev.planes[src];
} else {
assert(next_na < mpa->num_planes);
mpa->planes[n] = prev.planes[next_na++];
af_fill_silence(mpa->planes[n], mpa->sstride * mpa->samples,
mpa->format);
}
}
}
static int filter(struct af_instance *af, struct mp_audio *in)
static int filter_resample(struct af_instance *af, struct mp_audio *in)
{
struct af_resample *s = af->priv;
if (s->pending) {
if (s->pending->samples) {
af_add_output_frame(af, s->pending);
} else {
talloc_free(s->pending);
}
s->pending = NULL;
}
int samples = get_out_samples(s, in ? in->samples : 0);
int samples = avresample_available(s->avrctx) +
av_rescale_rnd(get_delay(s) + (in ? in->samples : 0),
s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP);
struct mp_audio out_format = s->avrctx_fmt;
struct mp_audio out_format = s->pool_fmt;
struct mp_audio *out = mp_audio_pool_get(af->out_pool, &out_format, samples);
if (!out)
goto error;
if (in)
mp_audio_copy_attributes(out, in);
af->delay = get_delay(s) / (double)s->ctx.in_rate;
if (!s->avrctx)
goto error;
if (out->samples) {
out->samples = resample_frame(s->avrctx, out, in);
@@ -449,11 +483,15 @@ static int filter(struct af_instance *af, struct mp_audio *in)
goto error;
}
if (out->samples && !mp_audio_config_equals(out, af->data)) {
assert(AF_FORMAT_IS_PLANAR(out->format));
reorder_planes(out, s->reorder_out, &af->data->channels);
if (!mp_audio_config_equals(out, af->data)) {
struct mp_audio *new = mp_audio_pool_get(s->reorder_buffer, af->data,
struct mp_audio real_out = *out;
mp_audio_copy_config(out, &s->avrctx_fmt);
if (out->samples && !mp_audio_config_equals(out, &s->pre_out_fmt)) {
assert(af_fmt_is_planar(out->format) && out->format == real_out.format);
reorder_planes(out, s->reorder_out, &s->pool_fmt.channels);
if (!mp_audio_config_equals(out, &s->pre_out_fmt)) {
struct mp_audio *new = mp_audio_pool_get(s->reorder_buffer,
&s->pre_out_fmt,
out->samples);
if (!new)
goto error;
@@ -466,12 +504,17 @@ static int filter(struct af_instance *af, struct mp_audio *in)
}
}
extra_output_conversion(af, out);
talloc_free(in);
if (out->samples) {
af_add_output_frame(af, out);
} else {
talloc_free(out);
}
af->delay = get_delay(s);
return 0;
error:
talloc_free(in);
@@ -479,6 +522,39 @@ error:
return -1;
}
static int filter(struct af_instance *af, struct mp_audio *in)
{
struct af_resample *s = af->priv;
int new_rate = rate_from_speed(s->in_rate_af, s->playback_speed);
bool need_reinit = fabs(new_rate / (double)s->in_rate - 1) > 0.01;
if (s->avrctx) {
AVRational r = av_d2q(s->playback_speed * s->in_rate_af / s->in_rate,
INT_MAX / 2);
// Essentially, swr/avresample_set_compensation() does 2 things:
// - adjust output sample rate by sample_delta/compensation_distance
// - reset the adjustment after compensation_distance output samples
// Increase the compensation_distance to avoid undesired reset
// semantics - we want to keep the ratio for the whole frame we're
// feeding it, until the next filter() call.
int mult = INT_MAX / 2 / MPMAX(MPMAX(abs(r.num), abs(r.den)), 1);
r = (AVRational){ r.num * mult, r.den * mult };
if (avresample_set_compensation(s->avrctx, r.den - r.num, r.den) < 0)
need_reinit = true;
}
if (need_reinit && new_rate != s->in_rate) {
// Before reconfiguring, drain the audio that is still buffered
// in the resampler.
filter_resample(af, NULL);
// Reinitialize resampler.
configure_lavrr(af, &af->fmt_in, &af->fmt_out, false);
}
return filter_resample(af, in);
}
static int af_open(struct af_instance *af)
{
struct af_resample *s = af->priv;
@@ -490,17 +566,9 @@ static int af_open(struct af_instance *af)
if (s->opts.cutoff <= 0.0)
s->opts.cutoff = af_resample_default_cutoff(s->opts.filter_size);
s->avrctx = avresample_alloc_context();
s->avrctx_out = avresample_alloc_context();
s->reorder_buffer = mp_audio_pool_create(s);
if (s->avrctx && s->avrctx_out) {
return AF_OK;
} else {
MP_ERR(af, "Cannot initialize Libavresample Context. \n");
uninit(af);
return AF_ERROR;
}
return AF_OK;
}
#define OPT_BASE_STRUCT struct af_resample
@@ -509,13 +577,13 @@ const struct af_info af_info_lavrresample = {
.info = "Sample frequency conversion using libavresample",
.name = "lavrresample",
.open = af_open,
.test_conversion = test_conversion,
.priv_size = sizeof(struct af_resample),
.priv_defaults = &(const struct af_resample) {
.opts = {
.filter_size = 16,
.cutoff = 0.0,
.phase_shift = 10,
.normalize = 1,
},
.playback_speed = 1.0,
.allow_detach = 1,
@@ -526,6 +594,7 @@ const struct af_info af_info_lavrresample = {
OPT_FLAG("linear", opts.linear, 0),
OPT_DOUBLE("cutoff", opts.cutoff, M_OPT_RANGE, .min = 0, .max = 1),
OPT_FLAG("detach", allow_detach, 0),
OPT_FLAG("normalize", opts.normalize, 0),
OPT_KEYVALUELIST("o", avopts, 0),
{0}
},
-3
View File
@@ -286,9 +286,6 @@ static void update_speed(struct af_instance *af, float speed)
s->frames_stride_scaled = s->scale * s->frames_stride;
s->frames_stride_error = MPMIN(s->frames_stride_error, s->frames_stride_scaled);
MP_VERBOSE(af, "%.3f speed * %.3f scale_nominal = %.3f\n",
s->speed, s->scale_nominal, s->scale);
}
// Initialization and runtime control
-117
View File
@@ -1,117 +0,0 @@
/*
* Copyright (C) 2006 Michael Niedermayer
* Copyright (C) 2004 Alex Beregszaszi
* based upon af_extrastereo.c by Pierre Lombard
*
* 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 <math.h>
#include <limits.h>
#include "af.h"
// Data for specific instances of this filter
typedef struct af_sinesuppress_s
{
double freq;
double decay;
double real;
double imag;
double ref;
double pos;
}af_sinesuppress_t;
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
switch(cmd){
case AF_CONTROL_REINIT:{
// Sanity check
if(!arg) return AF_ERROR;
mp_audio_copy_config(af->data, (struct mp_audio*)arg);
mp_audio_set_num_channels(af->data, 1);
mp_audio_set_format(af->data, AF_FORMAT_S16);
return af_test_output(af,(struct mp_audio*)arg);
}
}
return AF_UNKNOWN;
}
static int play_s16(struct af_instance *af, struct mp_audio *data)
{
if (!data)
return 0;
if (af_make_writeable(af, data) < 0) {
talloc_free(data);
return -1;
}
af_sinesuppress_t *s = af->priv;
register int i = 0;
int16_t *a = (int16_t*)data->planes[0]; // Audio data
int len = data->samples*data->nch; // Number of samples
for (i = 0; i < len; i++)
{
double co= cos(s->pos);
double si= sin(s->pos);
s->real += co * a[i];
s->imag += si * a[i];
s->ref += co * co;
a[i] -= (s->real * co + s->imag * si) / s->ref;
s->real -= s->real * s->decay;
s->imag -= s->imag * s->decay;
s->ref -= s->ref * s->decay;
s->pos += 2 * M_PI * s->freq / data->rate;
}
MP_VERBOSE(af, "f:%8.2f: amp:%8.2f\n", s->freq, sqrt(s->real*s->real + s->imag*s->imag) / s->ref);
af_add_output_frame(af, data);
return 0;
}
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
af->control=control;
af->filter_frame = play_s16;
return AF_OK;
}
#define OPT_BASE_STRUCT af_sinesuppress_t
const struct af_info af_info_sinesuppress = {
.info = "Sine Suppress",
.name = "sinesuppress",
.open = af_open,
.priv_size = sizeof(af_sinesuppress_t),
.options = (const struct m_option[]) {
OPT_DOUBLE("freq", freq, 0, OPTDEF_DOUBLE(50.0)),
OPT_DOUBLE("decay", decay, 0, OPTDEF_DOUBLE(0.0001)),
{0}
},
};
-148
View File
@@ -1,148 +0,0 @@
/*
* Copyright (C) 2002 Anders Johansson ajh@watri.uwa.edu.au
*
* 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/>.
*/
/* This filter adds a sub-woofer channels to the audio stream by
averaging the left and right channel and low-pass filter them. The
low-pass filter is implemented as a 4th order IIR Butterworth
filter, with a variable cutoff frequency between 10 and 300 Hz. The
filter gives 24dB/octave attenuation. There are two runtime
controls one for setting which channel to insert the sub-audio into
called AF_CONTROL_SUB_CH and one for setting the cutoff frequency
called AF_CONTROL_SUB_FC.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common/common.h"
#include "af.h"
#include "dsp.h"
// Q value for low-pass filter
#define Q 1.0
// Analog domain biquad section
typedef struct{
float a[3]; // Numerator coefficients
float b[3]; // Denominator coefficients
} biquad_t;
// S-parameters for designing 4th order Butterworth filter
static const biquad_t sp[2] = {{{1.0,0.0,0.0},{1.0,0.765367,1.0}},
{{1.0,0.0,0.0},{1.0,1.847759,1.0}}};
// Data for specific instances of this filter
typedef struct af_sub_s
{
float w[2][4]; // Filter taps for low-pass filter
float q[2][2]; // Circular queues
float fc; // Cutoff frequency [Hz] for low-pass filter
float k; // Filter gain;
int ch; // Channel number which to insert the filtered data
}af_sub_t;
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
af_sub_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_channels_old(af->data, MPMAX(s->ch+1,((struct mp_audio*)arg)->nch));
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
// Design low-pass filter
s->k = 1.0;
if((-1 == af_filter_szxform(sp[0].a, sp[0].b, Q, s->fc,
(float)af->data->rate, &s->k, s->w[0])) ||
(-1 == af_filter_szxform(sp[1].a, sp[1].b, Q, s->fc,
(float)af->data->rate, &s->k, s->w[1])))
return AF_ERROR;
return af_test_output(af,(struct mp_audio*)arg);
}
}
return AF_UNKNOWN;
}
#ifndef IIR
#define IIR(in,w,q,out) { \
float h0 = (q)[0]; \
float h1 = (q)[1]; \
float hn = (in) - h0 * (w)[0] - h1 * (w)[1]; \
out = hn + h0 * (w)[2] + h1 * (w)[3]; \
(q)[1] = h0; \
(q)[0] = hn; \
}
#endif
static int filter_frame(struct af_instance *af, struct mp_audio *data)
{
if (!data)
return 0;
if (af_make_writeable(af, data) < 0) {
talloc_free(data);
return -1;
}
struct mp_audio* c = data; // Current working data
af_sub_t* s = af->priv; // Setup for this instance
float* a = c->planes[0]; // Audio data
int len = c->samples*c->nch; // Number of samples in current audio block
int nch = c->nch; // Number of channels
int ch = s->ch; // Channel in which to insert the sub audio
register int i;
// Run filter
for(i=0;i<len;i+=nch){
// Average left and right
register float x = 0.5 * (a[i] + a[i+1]);
IIR(x * s->k, s->w[0], s->q[0], x);
IIR(x , s->w[1], s->q[1], a[i+ch]);
}
af_add_output_frame(af, data);
return 0;
}
// Allocate memory and set function pointers
static int af_open(struct af_instance* af){
af->control=control;
af->filter_frame = filter_frame;
return AF_OK;
}
#define OPT_BASE_STRUCT af_sub_t
const struct af_info af_info_sub = {
.info = "Audio filter for adding a sub-base channel",
.name = "sub",
.flags = AF_FLAGS_NOT_REENTRANT,
.open = af_open,
.priv_size = sizeof(af_sub_t),
.options = (const struct m_option[]) {
OPT_FLOATRANGE("fc", fc, 0, 20, 300, OPTDEF_FLOAT(60.0)),
OPT_INTRANGE("ch", ch, 0, 0, AF_NCH - 1, OPTDEF_INT(5)),
{0}
},
};
-246
View File
@@ -1,246 +0,0 @@
/*
* Filter to do simple decoding of matrixed surround sound.
* This will provide a (basic) surround-sound effect from
* audio encoded for Dolby Surround, Pro Logic etc.
*
* Original author: Steve Davies <steve@daviesfam.org>
*
* 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/>.
*/
/* The principle: Make rear channels by extracting anti-phase data
from the front channels, delay by 20ms and feed to rear in anti-phase
*/
/* SPLITREAR: Define to decode two distinct rear channels - this
doesn't work so well in practice because separation in a passive
matrix is not high. C (dialogue) to Ls and Rs 14dB or so - so
dialogue leaks to the rear. Still - give it a try and send
feedback. Comment this define for old behavior of a single
surround sent to rear in anti-phase */
#define SPLITREAR 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "af.h"
#include "dsp.h"
#define L 32 // Length of fir filter
#define LD 65536 // Length of delay buffer
// 32 Tap fir filter loop unrolled
#define FIR(x,w,y) \
y = ( w[0] *x[0] +w[1] *x[1] +w[2] *x[2] +w[3] *x[3] \
+ w[4] *x[4] +w[5] *x[5] +w[6] *x[6] +w[7] *x[7] \
+ w[8] *x[8] +w[9] *x[9] +w[10]*x[10]+w[11]*x[11] \
+ w[12]*x[12]+w[13]*x[13]+w[14]*x[14]+w[15]*x[15] \
+ w[16]*x[16]+w[17]*x[17]+w[18]*x[18]+w[19]*x[19] \
+ w[20]*x[20]+w[21]*x[21]+w[22]*x[22]+w[23]*x[23] \
+ w[24]*x[24]+w[25]*x[25]+w[26]*x[26]+w[27]*x[27] \
+ w[28]*x[28]+w[29]*x[29]+w[30]*x[30]+w[31]*x[31])
// Add to circular queue macro + update index
#ifdef SPLITREAR
#define ADDQUE(qi,rq,lq,r,l)\
lq[qi]=lq[qi+L]=(l);\
rq[qi]=rq[qi+L]=(r);\
qi=(qi-1)&(L-1);
#else
#define ADDQUE(qi,lq,l)\
lq[qi]=lq[qi+L]=(l);\
qi=(qi-1)&(L-1);
#endif
// Macro for updating queue index in delay queues
#define UPDATEQI(qi) qi=(qi+1)&(LD-1)
// instance data
typedef struct af_surround_s
{
float lq[2*L]; // Circular queue for filtering left rear channel
float rq[2*L]; // Circular queue for filtering right rear channel
float w[L]; // FIR filter coefficients for surround sound 7kHz low-pass
float* dr; // Delay queue right rear channel
float* dl; // Delay queue left rear channel
float d; // Delay time
int i; // Position in circular buffer
int wi; // Write index for delay queue
int ri; // Read index for delay queue
}af_surround_t;
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
af_surround_t *s = af->priv;
switch(cmd){
case AF_CONTROL_REINIT:{
struct mp_audio *in = arg;
float fc;
if (!mp_chmap_is_stereo(&in->channels)) {
MP_ERR(af, "Only stereo input is supported.\n");
return AF_DETACH;
}
mp_audio_set_format(in, AF_FORMAT_FLOAT);
mp_audio_copy_config(af->data, in);
mp_audio_set_channels_old(af->data, in->nch * 2);
// Surround filer coefficients
fc = 2.0 * 7000.0/(float)af->data->rate;
if (-1 == af_filter_design_fir(L, s->w, &fc, LP|HAMMING, 0)){
MP_ERR(af, "Unable to design low-pass filter.\n");
return AF_ERROR;
}
// Free previous delay queues
free(s->dl);
free(s->dr);
// Allocate new delay queues
s->dl = calloc(LD,af->data->bps);
s->dr = calloc(LD,af->data->bps);
if((NULL == s->dl) || (NULL == s->dr))
MP_FATAL(af, "Out of memory\n");
// Initialize delay queue index
if(AF_OK != af_from_ms(1, &s->d, &s->wi, af->data->rate, 0.0, 1000.0))
return AF_ERROR;
// printf("%i\n",s->wi);
s->ri = 0;
return AF_OK;
}
}
return AF_UNKNOWN;
}
// The beginnings of an active matrix...
static const float steering_matrix[][12] = {
// LL RL LR RR LS RS
// LLs RLs LRs RRs LC RC
{.707, .0, .0, .707, .5, -.5,
.5878, -.3928, .3928, -.5878, .5, .5},
};
// Experimental moving average dominance
//static int amp_L = 0, amp_R = 0, amp_C = 0, amp_S = 0;
static int filter_frame(struct af_instance *af, struct mp_audio *data)
{
if (!data)
return 0;
struct mp_audio *outframe =
mp_audio_pool_get(af->out_pool, &af->fmt_out, data->samples);
if (!outframe) {
talloc_free(data);
return -1;
}
mp_audio_copy_attributes(outframe, data);
af_surround_t* s = (af_surround_t*)af->priv;
const float* m = steering_matrix[0];
float* in = data->planes[0]; // Input audio data
float* out = outframe->planes[0]; // Output audio data
float* end = in + data->samples * data->nch;
int i = s->i; // Filter queue index
int ri = s->ri; // Read index for delay queue
int wi = s->wi; // Write index for delay queue
while(in < end){
/* Dominance:
abs(in[0]) abs(in[1]);
abs(in[0]+in[1]) abs(in[0]-in[1]);
10 * log( abs(in[0]) / (abs(in[1])|1) );
10 * log( abs(in[0]+in[1]) / (abs(in[0]-in[1])|1) ); */
/* About volume balancing...
Surround encoding does the following:
Lt=L+.707*C+.707*S, Rt=R+.707*C-.707*S
So S should be extracted as:
(Lt-Rt)
But we are splitting the S to two output channels, so we
must take 3dB off as we split it:
Ls=Rs=.707*(Lt-Rt)
Trouble is, Lt could be +1, Rt -1, so possibility that S will
overflow. So to avoid that, we cut L/R by 3dB (*.707), and S by
6dB (/2). This keeps the overall balance, but guarantees no
overflow. */
// Output front left and right
out[0] = m[0]*in[0] + m[1]*in[1];
out[1] = m[2]*in[0] + m[3]*in[1];
// Low-pass output @ 7kHz
FIR((&s->lq[i]), s->w, s->dl[wi]);
// Delay output by d ms
out[2] = s->dl[ri];
#ifdef SPLITREAR
// Low-pass output @ 7kHz
FIR((&s->rq[i]), s->w, s->dr[wi]);
// Delay output by d ms
out[3] = s->dr[ri];
#else
out[3] = -out[2];
#endif
// Update delay queues indexes
UPDATEQI(ri);
UPDATEQI(wi);
// Calculate and save surround in circular queue
#ifdef SPLITREAR
ADDQUE(i, s->rq, s->lq, m[6]*in[0]+m[7]*in[1], m[8]*in[0]+m[9]*in[1]);
#else
ADDQUE(i, s->lq, m[4]*in[0]+m[5]*in[1]);
#endif
// Next sample...
in = &in[data->nch];
out = &out[af->data->nch];
}
// Save indexes
s->i = i; s->ri = ri; s->wi = wi;
talloc_free(data);
af_add_output_frame(af, outframe);
return 0;
}
static int af_open(struct af_instance* af){
af->control=control;
af->filter_frame = filter_frame;
return AF_OK;
}
#define OPT_BASE_STRUCT af_surround_t
const struct af_info af_info_surround =
{
.info = "Surround decoder filter",
.name = "surround",
.flags = AF_FLAGS_NOT_REENTRANT,
.open = af_open,
.priv_size = sizeof(af_surround_t),
.options = (const struct m_option[]) {
OPT_FLOATRANGE("d", d, 0, 0, 1000, OPTDEF_FLOAT(20.0)),
{0}
},
};
-92
View File
@@ -1,92 +0,0 @@
/*
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
*
* 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 <math.h>
#include "config.h"
#include "af.h"
typedef struct af_sweep_s{
double x;
double delta;
}af_sweept;
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
struct mp_audio *data= (struct mp_audio*)arg;
switch(cmd){
case AF_CONTROL_REINIT:
mp_audio_copy_config(af->data, data);
mp_audio_set_format(af->data, AF_FORMAT_S16);
return af_test_output(af, data);
}
return AF_UNKNOWN;
}
static int filter_frame(struct af_instance *af, struct mp_audio *data)
{
if (!data)
return 0;
if (af_make_writeable(af, data) < 0) {
talloc_free(data);
return 0;
}
af_sweept *s = af->priv;
int i, j;
int16_t *in = (int16_t*)data->planes[0];
int chans = data->nch;
int in_len = data->samples;
for(i=0; i<in_len; i++){
for(j=0; j<chans; j++)
in[i*chans+j]= 32000*sin(s->x*s->x);
s->x += s->delta;
if(2*s->x*s->delta >= 3.141592) s->x=0;
}
af_add_output_frame(af, data);
return 0;
}
static int af_open(struct af_instance* af){
af->control=control;
af->filter_frame = filter_frame;
return AF_OK;
}
#define OPT_BASE_STRUCT af_sweept
const struct af_info af_info_sweep = {
.info = "sine sweep",
.name = "sweep",
.open = af_open,
.priv_size = sizeof(af_sweept),
.options = (const struct m_option[]) {
OPT_DOUBLE("delta", delta, 0),
{0}
},
};
+21 -6
View File
@@ -30,18 +30,28 @@
#include "demux/demux.h"
struct priv {
float vol; // User-specified non-linear volume
float level; // User-specified gain level for each channel
float rgain; // Replaygain level
int rgain_track; // Enable/disable track based replaygain
int rgain_album; // Enable/disable album based replaygain
float rgain_preamp; // Set replaygain pre-amplification
int rgain_clip; // Enable/disable clipping prevention
float replaygain_fallback;
int soft; // Enable/disable soft clipping
int fast; // Use fix-point volume control
int detach; // Detach if gain volume is neutral
float cfg_volume;
};
// Convert to gain value from dB. input <= -200dB will become 0 gain.
static float from_dB(float in, float k, float mi, float ma)
{
if (in <= -200)
return 0.0;
return pow(10.0, MPCLAMP(in, mi, ma) / k);
}
static int control(struct af_instance *af, int cmd, void *arg)
{
struct priv *s = af->priv;
@@ -58,7 +68,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
} else {
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
}
if (AF_FORMAT_IS_PLANAR(in->format))
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) {
@@ -73,7 +83,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
}
gain += s->rgain_preamp;
af_from_dB(1, &gain, &s->rgain, 20.0, -200.0, 60.0);
s->rgain = from_dB(gain, 20.0, -200.0, 60.0);
MP_VERBOSE(af, "Applying replay-gain: %f\n", s->rgain);
@@ -81,16 +91,21 @@ static int control(struct af_instance *af, int cmd, void *arg)
s->rgain = MPMIN(s->rgain, 1.0 / peak);
MP_VERBOSE(af, "...with clipping prevention: %f\n", s->rgain);
}
} else if (s->replaygain_fallback) {
s->rgain = from_dB(s->replaygain_fallback, 20.0, -200.0, 60.0);
MP_VERBOSE(af, "Applying fallback gain: %f\n", s->rgain);
}
if (s->detach && fabs(s->level * s->rgain - 1.0) < 0.00001)
return AF_DETACH;
return af_test_output(af, in);
}
case AF_CONTROL_SET_VOLUME:
s->level = *(float *)arg;
s->vol = *(float *)arg;
s->level = pow(s->vol, 3);
MP_VERBOSE(af, "volume gain: %f\n", s->level);
return AF_OK;
case AF_CONTROL_GET_VOLUME:
*(float *)arg = s->level;
*(float *)arg = s->vol;
return AF_OK;
}
return AF_UNKNOWN;
@@ -143,7 +158,7 @@ static int af_open(struct af_instance *af)
struct priv *s = af->priv;
af->control = control;
af->filter_frame = filter;
af_from_dB(1, &s->cfg_volume, &s->level, 20.0, -200.0, 60.0);
s->level = from_dB(s->cfg_volume, 20.0, -200.0, 60.0);
return AF_OK;
}
@@ -153,7 +168,6 @@ static int af_open(struct af_instance *af)
const struct af_info af_info_volume = {
.info = "Volume control audio filter",
.name = "volume",
.flags = AF_FLAGS_NOT_REENTRANT,
.open = af_open,
.priv_size = sizeof(struct priv),
.options = (const struct m_option[]) {
@@ -162,6 +176,7 @@ const struct af_info af_info_volume = {
OPT_FLAG("replaygain-album", rgain_album, 0),
OPT_FLOATRANGE("replaygain-preamp", rgain_preamp, 0, -15, 15),
OPT_FLAG("replaygain-clip", rgain_clip, 0),
OPT_FLOATRANGE("replaygain-fallback", replaygain_fallback, 0, -200, 60),
OPT_FLAG("softclip", soft, 0),
OPT_FLAG("s16", fast, 0),
OPT_FLAG("detach", detach, 0),
-359
View File
@@ -1,359 +0,0 @@
/*
* design and implementation of different types of digital filters
*
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
*
* 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 <math.h>
#include "dsp.h"
/******************************************************************************
* FIR filter implementations
******************************************************************************/
/* C implementation of FIR filter y=w*x
n number of filter taps, where mod(n,4)==0
w filter taps
x input signal must be a circular buffer which is indexed backwards
*/
inline FLOAT_TYPE af_filter_fir(register unsigned int n, const FLOAT_TYPE* w,
const FLOAT_TYPE* x)
{
register FLOAT_TYPE y; // Output
y = 0.0;
do{
n--;
y+=w[n]*x[n];
}while(n != 0);
return y;
}
/******************************************************************************
* FIR filter design
******************************************************************************/
/* Design FIR filter using the Window method
n filter length must be odd for HP and BS filters
w buffer for the filter taps (must be n long)
fc cutoff frequencies (1 for LP and HP, 2 for BP and BS)
0 < fc < 1 where 1 <=> Fs/2
flags window and filter type as defined in filter.h
variables are ored together: i.e. LP|HAMMING will give a
low pass filter designed using a hamming window
opt beta constant used only when designing using kaiser windows
returns 0 if OK, -1 if fail
*/
int af_filter_design_fir(unsigned int n, FLOAT_TYPE* w, const FLOAT_TYPE* fc,
unsigned int flags, FLOAT_TYPE opt)
{
unsigned int o = n & 1; // Indicator for odd filter length
unsigned int end = ((n + 1) >> 1) - o; // Loop end
unsigned int i; // Loop index
FLOAT_TYPE k1 = 2 * M_PI; // 2*pi*fc1
FLOAT_TYPE k2 = 0.5 * (FLOAT_TYPE)(1 - o);// Constant used if the filter has even length
FLOAT_TYPE k3; // 2*pi*fc2 Constant used in BP and BS design
FLOAT_TYPE g = 0.0; // Gain
FLOAT_TYPE t1,t2,t3; // Temporary variables
FLOAT_TYPE fc1,fc2; // Cutoff frequencies
// Sanity check
if(!w || (n == 0)) return -1;
// Get window coefficients
switch(flags & WINDOW_MASK){
case(BOXCAR):
af_window_boxcar(n,w); break;
case(TRIANG):
af_window_triang(n,w); break;
case(HAMMING):
af_window_hamming(n,w); break;
case(HANNING):
af_window_hanning(n,w); break;
case(BLACKMAN):
af_window_blackman(n,w); break;
case(FLATTOP):
af_window_flattop(n,w); break;
case(KAISER):
af_window_kaiser(n,w,opt); break;
default:
return -1;
}
if(flags & (LP | HP)){
fc1=*fc;
// Cutoff frequency must be < 0.5 where 0.5 <=> Fs/2
fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1/2 : 0.25;
k1 *= fc1;
if(flags & LP){ // Low pass filter
// If the filter length is odd, there is one point which is exactly
// in the middle. The value at this point is 2*fCutoff*sin(x)/x,
// where x is zero. To make sure nothing strange happens, we set this
// value separately.
if (o){
w[end] = fc1 * w[end] * 2.0;
g=w[end];
}
// Create filter
for (i=0 ; i<end ; i++){
t1 = (FLOAT_TYPE)(i+1) - k2;
w[end-i-1] = w[n-end+i] = w[end-i-1] * sin(k1 * t1)/(M_PI * t1); // Sinc
g += 2*w[end-i-1]; // Total gain in filter
}
}
else{ // High pass filter
if (!o) // High pass filters must have odd length
return -1;
w[end] = 1.0 - (fc1 * w[end] * 2.0);
g= w[end];
// Create filter
for (i=0 ; i<end ; i++){
t1 = (FLOAT_TYPE)(i+1);
w[end-i-1] = w[n-end+i] = -1 * w[end-i-1] * sin(k1 * t1)/(M_PI * t1); // Sinc
g += ((i&1) ? (2*w[end-i-1]) : (-2*w[end-i-1])); // Total gain in filter
}
}
}
if(flags & (BP | BS)){
fc1=fc[0];
fc2=fc[1];
// Cutoff frequencies must be < 1.0 where 1.0 <=> Fs/2
fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1/2 : 0.25;
fc2 = ((fc2 <= 1.0) && (fc2 > 0.0)) ? fc2/2 : 0.25;
k3 = k1 * fc2; // 2*pi*fc2
k1 *= fc1; // 2*pi*fc1
if(flags & BP){ // Band pass
// Calculate center tap
if (o){
g=w[end]*(fc1+fc2);
w[end] = (fc2 - fc1) * w[end] * 2.0;
}
// Create filter
for (i=0 ; i<end ; i++){
t1 = (FLOAT_TYPE)(i+1) - k2;
t2 = sin(k3 * t1)/(M_PI * t1); // Sinc fc2
t3 = sin(k1 * t1)/(M_PI * t1); // Sinc fc1
g += w[end-i-1] * (t3 + t2); // Total gain in filter
w[end-i-1] = w[n-end+i] = w[end-i-1] * (t2 - t3);
}
}
else{ // Band stop
if (!o) // Band stop filters must have odd length
return -1;
w[end] = 1.0 - (fc2 - fc1) * w[end] * 2.0;
g= w[end];
// Create filter
for (i=0 ; i<end ; i++){
t1 = (FLOAT_TYPE)(i+1);
t2 = sin(k1 * t1)/(M_PI * t1); // Sinc fc1
t3 = sin(k3 * t1)/(M_PI * t1); // Sinc fc2
w[end-i-1] = w[n-end+i] = w[end-i-1] * (t2 - t3);
g += 2*w[end-i-1]; // Total gain in filter
}
}
}
// Normalize gain
g=1/g;
for (i=0; i<n; i++)
w[i] *= g;
return 0;
}
/******************************************************************************
* IIR filter design
******************************************************************************/
/* Helper functions for the bilinear transform */
/* Pre-warp the coefficients of a numerator or denominator.
Note that a0 is assumed to be 1, so there is no wrapping
of it.
*/
static void af_filter_prewarp(FLOAT_TYPE* a, FLOAT_TYPE fc, FLOAT_TYPE fs)
{
FLOAT_TYPE wp;
wp = 2.0 * fs * tan(M_PI * fc / fs);
a[2] = a[2]/(wp * wp);
a[1] = a[1]/wp;
}
/* Transform the numerator and denominator coefficients of s-domain
biquad section into corresponding z-domain coefficients.
The transfer function for z-domain is:
1 + alpha1 * z^(-1) + alpha2 * z^(-2)
H(z) = -------------------------------------
1 + beta1 * z^(-1) + beta2 * z^(-2)
Store the 4 IIR coefficients in array pointed by coef in following
order:
beta1, beta2 (denominator)
alpha1, alpha2 (numerator)
Arguments:
a - s-domain numerator coefficients
b - s-domain denominator coefficients
k - filter gain factor. Initially set to 1 and modified by each
biquad section in such a way, as to make it the
coefficient by which to multiply the overall filter gain
in order to achieve a desired overall filter gain,
specified in initial value of k.
fs - sampling rate (Hz)
coef - array of z-domain coefficients to be filled in.
Return: On return, set coef z-domain coefficients and k to the gain
required to maintain overall gain = 1.0;
*/
static void af_filter_bilinear(const FLOAT_TYPE* a, const FLOAT_TYPE* b, FLOAT_TYPE* k,
FLOAT_TYPE fs, FLOAT_TYPE *coef)
{
FLOAT_TYPE ad, bd;
/* alpha (Numerator in s-domain) */
ad = 4. * a[2] * fs * fs + 2. * a[1] * fs + a[0];
/* beta (Denominator in s-domain) */
bd = 4. * b[2] * fs * fs + 2. * b[1] * fs + b[0];
/* Update gain constant for this section */
*k *= ad/bd;
/* Denominator */
*coef++ = (2. * b[0] - 8. * b[2] * fs * fs)/bd; /* beta1 */
*coef++ = (4. * b[2] * fs * fs - 2. * b[1] * fs + b[0])/bd; /* beta2 */
/* Numerator */
*coef++ = (2. * a[0] - 8. * a[2] * fs * fs)/ad; /* alpha1 */
*coef = (4. * a[2] * fs * fs - 2. * a[1] * fs + a[0])/ad; /* alpha2 */
}
/* IIR filter design using bilinear transform and prewarp. Transforms
2nd order s domain analog filter into a digital IIR biquad link. To
create a filter fill in a, b, Q and fs and make space for coef and k.
Example Butterworth design:
Below are Butterworth polynomials, arranged as a series of 2nd
order sections:
Note: n is filter order.
n Polynomials
-------------------------------------------------------------------
2 s^2 + 1.4142s + 1
4 (s^2 + 0.765367s + 1) * (s^2 + 1.847759s + 1)
6 (s^2 + 0.5176387s + 1) * (s^2 + 1.414214 + 1) * (s^2 + 1.931852s + 1)
For n=4 we have following equation for the filter transfer function:
1 1
T(s) = --------------------------- * ----------------------------
s^2 + (1/Q) * 0.765367s + 1 s^2 + (1/Q) * 1.847759s + 1
The filter consists of two 2nd order sections since highest s power
is 2. Now we can take the coefficients, or the numbers by which s
is multiplied and plug them into a standard formula to be used by
bilinear transform.
Our standard form for each 2nd order section is:
a2 * s^2 + a1 * s + a0
H(s) = ----------------------
b2 * s^2 + b1 * s + b0
Note that Butterworth numerator is 1 for all filter sections, which
means s^2 = 0 and s^1 = 0
Let's convert standard Butterworth polynomials into this form:
0 + 0 + 1 0 + 0 + 1
--------------------------- * --------------------------
1 + ((1/Q) * 0.765367) + 1 1 + ((1/Q) * 1.847759) + 1
Section 1:
a2 = 0; a1 = 0; a0 = 1;
b2 = 1; b1 = 0.765367; b0 = 1;
Section 2:
a2 = 0; a1 = 0; a0 = 1;
b2 = 1; b1 = 1.847759; b0 = 1;
Q is filter quality factor or resonance, in the range of 1 to
1000. The overall filter Q is a product of all 2nd order stages.
For example, the 6th order filter (3 stages, or biquads) with
individual Q of 2 will have filter Q = 2 * 2 * 2 = 8.
Arguments:
a - s-domain numerator coefficients, a[1] is always assumed to be 1.0
b - s-domain denominator coefficients
Q - Q value for the filter
k - filter gain factor. Initially set to 1 and modified by each
biquad section in such a way, as to make it the
coefficient by which to multiply the overall filter gain
in order to achieve a desired overall filter gain,
specified in initial value of k.
fs - sampling rate (Hz)
coef - array of z-domain coefficients to be filled in.
Note: Upon return from each call, the k argument will be set to a
value, by which to multiply our actual signal in order for the gain
to be one. On second call to szxform() we provide k that was
changed by the previous section. During actual audio filtering
k can be used for gain compensation.
return -1 if fail 0 if success.
*/
int af_filter_szxform(const FLOAT_TYPE* a, const FLOAT_TYPE* b, FLOAT_TYPE Q, FLOAT_TYPE fc,
FLOAT_TYPE fs, FLOAT_TYPE *k, FLOAT_TYPE *coef)
{
FLOAT_TYPE at[3];
FLOAT_TYPE bt[3];
if(!a || !b || !k || !coef || (Q>1000.0 || Q< 1.0))
return -1;
memcpy(at,a,3*sizeof(FLOAT_TYPE));
memcpy(bt,b,3*sizeof(FLOAT_TYPE));
bt[1]/=Q;
/* Calculate a and b and overwrite the original values */
af_filter_prewarp(at, fc, fs);
af_filter_prewarp(bt, fc, fs);
/* Execute bilinear transform */
af_filter_bilinear(at, bt, k, fs, coef);
return 0;
}
-74
View File
@@ -1,74 +0,0 @@
/*
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
*
* 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/>.
*/
#if !defined MPLAYER_DSP_H
# error Never use filter.h directly; include dsp.h instead.
#endif
#ifndef MPLAYER_FILTER_H
#define MPLAYER_FILTER_H
// Design and implementation of different types of digital filters
// Flags used for filter design
// Filter characteristics
#define LP 0x00010000 // Low pass
#define HP 0x00020000 // High pass
#define BP 0x00040000 // Band pass
#define BS 0x00080000 // Band stop
#define TYPE_MASK 0x000F0000
// Window types
#define BOXCAR 0x00000001
#define TRIANG 0x00000002
#define HAMMING 0x00000004
#define HANNING 0x00000008
#define BLACKMAN 0x00000010
#define FLATTOP 0x00000011
#define KAISER 0x00000012
#define WINDOW_MASK 0x0000001F
// Parallel filter design
#define FWD 0x00000001 // Forward indexing of polyphase filter
#define REW 0x00000002 // Reverse indexing of polyphase filter
#define ODD 0x00000010 // Make filter HP
// Exported functions
FLOAT_TYPE af_filter_fir(unsigned int n, const FLOAT_TYPE* w, const FLOAT_TYPE* x);
int af_filter_design_fir(unsigned int n, FLOAT_TYPE* w, const FLOAT_TYPE* fc,
unsigned int flags, FLOAT_TYPE opt);
int af_filter_szxform(const FLOAT_TYPE* a, const FLOAT_TYPE* b, FLOAT_TYPE Q,
FLOAT_TYPE fc, FLOAT_TYPE fs, FLOAT_TYPE *k,
FLOAT_TYPE *coef);
/* Add new data to circular queue designed to be used with a FIR
filter. xq is the circular queue, in pointing at the new sample, xi
current index for xq and n the length of the filter. xq must be n*2
long.
*/
#define af_filter_updateq(n,xi,xq,in)\
xq[xi]=(xq)[(xi)+(n)]=*(in);\
xi=(++(xi))&((n)-1);
#endif /* MPLAYER_FILTER_H */
-18
View File
@@ -21,24 +21,6 @@
#include "common/common.h"
#include "af.h"
/* Convert to gain value from dB. Returns AF_OK if of and AF_ERROR if
* fail. input <= -200dB will become 0 gain. */
int af_from_dB(int n, float* in, float* out, float k, float mi, float ma)
{
int i = 0;
// Sanity check
if(!in || !out)
return AF_ERROR;
for(i=0;i<n;i++){
if(in[i]<=-200)
out[i]=0.0;
else
out[i]=pow(10.0,MPCLAMP(in[i],mi,ma)/k);
}
return AF_OK;
}
/* Convert from ms to sample time */
int af_from_ms(int n, float* in, int* out, int rate, float mi, float ma)
{
-212
View File
@@ -1,212 +0,0 @@
/*
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
*
* 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/>.
*/
/* Calculates a number of window functions. The following window
functions are currently implemented: Boxcar, Triang, Hanning,
Hamming, Blackman, Flattop and Kaiser. In the function call n is
the number of filter taps and w the buffer in which the filter
coefficients will be stored.
*/
#include <math.h>
#include "dsp.h"
/*
// Boxcar
//
// n window length
// w buffer for the window parameters
*/
void af_window_boxcar(int n, FLOAT_TYPE* w)
{
int i;
// Calculate window coefficients
for (i=0 ; i<n ; i++)
w[i] = 1.0;
}
/*
// Triang a.k.a Bartlett
//
// | (N-1)|
// 2 * |k - -----|
// | 2 |
// w = 1.0 - ---------------
// N+1
// n window length
// w buffer for the window parameters
*/
void af_window_triang(int n, FLOAT_TYPE* w)
{
FLOAT_TYPE k1 = (FLOAT_TYPE)(n & 1);
FLOAT_TYPE k2 = 1/((FLOAT_TYPE)n + k1);
int end = (n + 1) >> 1;
int i;
// Calculate window coefficients
for (i=0 ; i<end ; i++)
w[i] = w[n-i-1] = (2.0*((FLOAT_TYPE)(i+1))-(1.0-k1))*k2;
}
/*
// Hanning
// 2*pi*k
// w = 0.5 - 0.5*cos(------), where 0 < k <= N
// N+1
// n window length
// w buffer for the window parameters
*/
void af_window_hanning(int n, FLOAT_TYPE* w)
{
int i;
FLOAT_TYPE k = 2*M_PI/((FLOAT_TYPE)(n+1)); // 2*pi/(N+1)
// Calculate window coefficients
for (i=0; i<n; i++)
*w++ = 0.5*(1.0 - cos(k*(FLOAT_TYPE)(i+1)));
}
/*
// Hamming
// 2*pi*k
// w(k) = 0.54 - 0.46*cos(------), where 0 <= k < N
// N-1
//
// n window length
// w buffer for the window parameters
*/
void af_window_hamming(int n,FLOAT_TYPE* w)
{
int i;
FLOAT_TYPE k = 2*M_PI/((FLOAT_TYPE)(n-1)); // 2*pi/(N-1)
// Calculate window coefficients
for (i=0; i<n; i++)
*w++ = 0.54 - 0.46*cos(k*(FLOAT_TYPE)i);
}
/*
// Blackman
// 2*pi*k 4*pi*k
// w(k) = 0.42 - 0.5*cos(------) + 0.08*cos(------), where 0 <= k < N
// N-1 N-1
//
// n window length
// w buffer for the window parameters
*/
void af_window_blackman(int n,FLOAT_TYPE* w)
{
int i;
FLOAT_TYPE k1 = 2*M_PI/((FLOAT_TYPE)(n-1)); // 2*pi/(N-1)
FLOAT_TYPE k2 = 2*k1; // 4*pi/(N-1)
// Calculate window coefficients
for (i=0; i<n; i++)
*w++ = 0.42 - 0.50*cos(k1*(FLOAT_TYPE)i) + 0.08*cos(k2*(FLOAT_TYPE)i);
}
/*
// Flattop
// 2*pi*k 4*pi*k
// w(k) = 0.2810638602 - 0.5208971735*cos(------) + 0.1980389663*cos(------), where 0 <= k < N
// N-1 N-1
//
// n window length
// w buffer for the window parameters
*/
void af_window_flattop(int n,FLOAT_TYPE* w)
{
int i;
FLOAT_TYPE k1 = 2*M_PI/((FLOAT_TYPE)(n-1)); // 2*pi/(N-1)
FLOAT_TYPE k2 = 2*k1; // 4*pi/(N-1)
// Calculate window coefficients
for (i=0; i<n; i++)
*w++ = 0.2810638602 - 0.5208971735*cos(k1*(FLOAT_TYPE)i)
+ 0.1980389663*cos(k2*(FLOAT_TYPE)i);
}
/* Computes the 0th order modified Bessel function of the first kind.
// (Needed to compute Kaiser window)
//
// y = sum( (x/(2*n))^2 )
// n
*/
#define BIZ_EPSILON 1E-21 // Max error acceptable
static FLOAT_TYPE besselizero(FLOAT_TYPE x)
{
FLOAT_TYPE temp;
FLOAT_TYPE sum = 1.0;
FLOAT_TYPE u = 1.0;
FLOAT_TYPE halfx = x/2.0;
int n = 1;
do {
temp = halfx/(FLOAT_TYPE)n;
u *=temp * temp;
sum += u;
n++;
} while (u >= BIZ_EPSILON * sum);
return sum;
}
/*
// Kaiser
//
// n window length
// w buffer for the window parameters
// b beta parameter of Kaiser window, Beta >= 1
//
// Beta trades the rejection of the low pass filter against the
// transition width from passband to stop band. Larger Beta means a
// slower transition and greater stop band rejection. See Rabiner and
// Gold (Theory and Application of DSP) under Kaiser windows for more
// about Beta. The following table from Rabiner and Gold gives some
// feel for the effect of Beta:
//
// All ripples in dB, width of transition band = D*N where N = window
// length
//
// BETA D PB RIP SB RIP
// 2.120 1.50 +-0.27 -30
// 3.384 2.23 0.0864 -40
// 4.538 2.93 0.0274 -50
// 5.658 3.62 0.00868 -60
// 6.764 4.32 0.00275 -70
// 7.865 5.0 0.000868 -80
// 8.960 5.7 0.000275 -90
// 10.056 6.4 0.000087 -100
*/
void af_window_kaiser(int n, FLOAT_TYPE* w, FLOAT_TYPE b)
{
FLOAT_TYPE tmp;
FLOAT_TYPE k1 = 1.0/besselizero(b);
int k2 = 1 - (n & 1);
int end = (n + 1) >> 1;
int i;
// Calculate window coefficients
for (i=0 ; i<end ; i++){
tmp = (FLOAT_TYPE)(2*i + k2) / ((FLOAT_TYPE)n - 1.0);
w[end-(1&(!k2))+i] = w[end-1-i] = k1 * besselizero(b*sqrt(1.0 - tmp*tmp));
}
}
-42
View File
@@ -1,42 +0,0 @@
/*
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
*
* 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/>.
*/
/* Calculates a number of window functions. The following window
functions are currently implemented: Boxcar, Triang, Hanning,
Hamming, Blackman, Flattop and Kaiser. In the function call n is
the number of filter taps and w the buffer in which the filter
coefficients will be stored.
*/
#if !defined MPLAYER_DSP_H
# error Never use window.h directly; include dsp.h instead.
#endif
#ifndef MPLAYER_WINDOW_H
#define MPLAYER_WINDOW_H
void af_window_boxcar(int n, FLOAT_TYPE* w);
void af_window_triang(int n, FLOAT_TYPE* w);
void af_window_hanning(int n, FLOAT_TYPE* w);
void af_window_hamming(int n, FLOAT_TYPE* w);
void af_window_blackman(int n, FLOAT_TYPE* w);
void af_window_flattop(int n, FLOAT_TYPE* w);
void af_window_kaiser(int n, FLOAT_TYPE* w, FLOAT_TYPE b);
#endif /* MPLAYER_WINDOW_H */
+131 -102
View File
@@ -27,42 +27,68 @@
#include "common/common.h"
#include "audio/filter/af.h"
int af_fmt2bps(int format)
// number of bytes per sample, 0 if invalid/unknown
int af_fmt_to_bytes(int format)
{
switch (format & AF_FORMAT_BITS_MASK) {
case AF_FORMAT_8BIT: return 1;
case AF_FORMAT_16BIT: return 2;
case AF_FORMAT_24BIT: return 3;
case AF_FORMAT_32BIT: return 4;
case AF_FORMAT_64BIT: return 8;
switch (af_fmt_from_planar(format)) {
case AF_FORMAT_U8: return 1;
case AF_FORMAT_S16: return 2;
case AF_FORMAT_S24: return 3;
case AF_FORMAT_S32: return 4;
case AF_FORMAT_FLOAT: return 4;
case AF_FORMAT_DOUBLE: return 8;
}
if (af_fmt_is_spdif(format))
return 2;
return 0;
}
int af_fmt2bits(int format)
int af_fmt_change_bytes(int format, int bytes)
{
return af_fmt2bps(format) * 8;
}
static int bits_to_mask(int bits)
{
switch (bits) {
case 8: return AF_FORMAT_8BIT;
case 16: return AF_FORMAT_16BIT;
case 24: return AF_FORMAT_24BIT;
case 32: return AF_FORMAT_32BIT;
case 64: return AF_FORMAT_64BIT;
}
return 0;
}
int af_fmt_change_bits(int format, int bits)
{
if (!af_fmt_is_valid(format))
if (!af_fmt_is_valid(format) || !bytes)
return 0;
int mask = bits_to_mask(bits);
format = (format & ~AF_FORMAT_BITS_MASK) | mask;
return af_fmt_is_valid(format) ? format : 0;
for (int fmt = 1; fmt < AF_FORMAT_COUNT; fmt++) {
if (af_fmt_to_bytes(fmt) == bytes &&
af_fmt_is_float(fmt) == af_fmt_is_float(format) &&
af_fmt_is_planar(fmt) == af_fmt_is_planar(format) &&
(fmt == format || (!af_fmt_is_spdif(fmt) && !af_fmt_is_spdif(format))))
return fmt;
}
return 0;
}
// All formats are considered signed, except explicitly unsigned int formats.
bool af_fmt_is_unsigned(int format)
{
return format == AF_FORMAT_U8 || format == AF_FORMAT_U8P;
}
bool af_fmt_is_float(int format)
{
format = af_fmt_from_planar(format);
return format == AF_FORMAT_FLOAT || format == AF_FORMAT_DOUBLE;
}
// true for both unsigned and signed ints
bool af_fmt_is_int(int format)
{
return format && !af_fmt_is_spdif(format) && !af_fmt_is_float(format);
}
// false for interleaved and AF_FORMAT_UNKNOWN
bool af_fmt_is_planar(int format)
{
return format && af_fmt_to_planar(format) == format;
}
bool af_fmt_is_spdif(int format)
{
return af_format_sample_alignment(format) > 1;
}
bool af_fmt_is_pcm(int format)
{
return af_fmt_is_valid(format) && !af_fmt_is_spdif(format);
}
static const int planar_formats[][2] = {
@@ -99,58 +125,40 @@ int af_fmt_from_planar(int format)
return format;
}
const struct af_fmt_entry af_fmtstr_table[] = {
{"u8", AF_FORMAT_U8},
{"s8", AF_FORMAT_S8},
{"u16", AF_FORMAT_U16},
{"s16", AF_FORMAT_S16},
{"u24", AF_FORMAT_U24},
{"s24", AF_FORMAT_S24},
{"u32", AF_FORMAT_U32},
{"s32", AF_FORMAT_S32},
{"float", AF_FORMAT_FLOAT},
{"double", AF_FORMAT_DOUBLE},
{"u8p", AF_FORMAT_U8P},
{"s16p", AF_FORMAT_S16P},
{"s32p", AF_FORMAT_S32P},
{"floatp", AF_FORMAT_FLOATP},
{"doublep", AF_FORMAT_DOUBLEP},
{"spdif-aac", AF_FORMAT_S_AAC},
{"spdif-ac3", AF_FORMAT_S_AC3},
{"spdif-dts", AF_FORMAT_S_DTS},
{"spdif-dtshd", AF_FORMAT_S_DTSHD},
{"spdif-eac3", AF_FORMAT_S_EAC3},
{"spdif-mp3", AF_FORMAT_S_MP3},
{"spdif-truehd",AF_FORMAT_S_TRUEHD},
{0}
};
bool af_fmt_is_valid(int format)
{
for (int i = 0; af_fmtstr_table[i].name; i++) {
if (af_fmtstr_table[i].format == format)
return true;
}
return false;
return format > 0 && format < AF_FORMAT_COUNT;
}
const char *af_fmt_to_str(int format)
{
for (int i = 0; af_fmtstr_table[i].name; i++) {
if (af_fmtstr_table[i].format == format)
return af_fmtstr_table[i].name;
switch (format) {
case AF_FORMAT_U8: return "u8";
case AF_FORMAT_S16: return "s16";
case AF_FORMAT_S24: return "s24";
case AF_FORMAT_S32: return "s32";
case AF_FORMAT_FLOAT: return "float";
case AF_FORMAT_DOUBLE: return "double";
case AF_FORMAT_U8P: return "u8p";
case AF_FORMAT_S16P: return "s16p";
case AF_FORMAT_S32P: return "s32p";
case AF_FORMAT_FLOATP: return "floatp";
case AF_FORMAT_DOUBLEP: return "doublep";
case AF_FORMAT_S_AAC: return "spdif-aac";
case AF_FORMAT_S_AC3: return "spdif-ac3";
case AF_FORMAT_S_DTS: return "spdif-dts";
case AF_FORMAT_S_DTSHD: return "spdif-dtshd";
case AF_FORMAT_S_EAC3: return "spdif-eac3";
case AF_FORMAT_S_MP3: return "spdif-mp3";
case AF_FORMAT_S_TRUEHD: return "spdif-truehd";
}
return "??";
}
int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int samplerate)
{
assert(!AF_FORMAT_IS_PLANAR(format));
int bps = af_fmt2bps(format);
assert(!af_fmt_is_planar(format));
int bps = af_fmt_to_bytes(format);
int framelen = channels * bps;
int bytes = seconds * bps * samplerate;
if (bytes % framelen)
@@ -158,64 +166,85 @@ int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int sampler
return bytes;
}
int af_str2fmt_short(bstr str)
{
for (int i = 0; af_fmtstr_table[i].name; i++) {
if (!bstrcasecmp0(str, af_fmtstr_table[i].name))
return af_fmtstr_table[i].format;
}
return 0;
}
void af_fill_silence(void *dst, size_t bytes, int format)
{
bool us = (format & AF_FORMAT_SIGN_MASK) == AF_FORMAT_US;
memset(dst, us ? 0x80 : 0, bytes);
memset(dst, af_fmt_is_unsigned(format) ? 0x80 : 0, bytes);
}
#define FMT_DIFF(type, a, b) (((a) & type) - ((b) & type))
// Returns a "score" that serves as heuristic how lossy or hard a conversion is.
// If the formats are equal, 1024 is returned. If they are gravely incompatible
// (like s16<->ac3), INT_MIN is returned. If there is implied loss of precision
// (like s16->s8), a value <0 is returned.
int af_format_conversion_score(int dst_format, int src_format)
static int af_format_conversion_score(int dst_format, int src_format)
{
if (dst_format == AF_FORMAT_UNKNOWN || src_format == AF_FORMAT_UNKNOWN)
return INT_MIN;
if (dst_format == src_format)
return 1024;
// Can't be normally converted
if (AF_FORMAT_IS_SPECIAL(dst_format) || AF_FORMAT_IS_SPECIAL(src_format))
if (!af_fmt_is_pcm(dst_format) || !af_fmt_is_pcm(src_format))
return INT_MIN;
int score = 1024;
if (FMT_DIFF(AF_FORMAT_INTERLEAVING_MASK, dst_format, src_format))
if (af_fmt_is_planar(dst_format) != af_fmt_is_planar(src_format))
score -= 1; // has to (de-)planarize
if (FMT_DIFF(AF_FORMAT_SIGN_MASK, dst_format, src_format))
score -= 4; // has to swap sign
if (FMT_DIFF(AF_FORMAT_TYPE_MASK, dst_format, src_format)) {
int dst_bits = dst_format & AF_FORMAT_BITS_MASK;
if ((dst_format & AF_FORMAT_TYPE_MASK) == AF_FORMAT_F) {
// For int->float, always prefer 32 bit float.
score -= dst_bits == AF_FORMAT_32BIT ? 8 : 0;
if (af_fmt_is_float(dst_format) != af_fmt_is_float(src_format)) {
int dst_bytes = af_fmt_to_bytes(dst_format);
if (af_fmt_is_float(dst_format)) {
// For int->float, consider a lower bound on the precision difference.
int bytes = (dst_bytes == 4 ? 3 : 6) - af_fmt_to_bytes(src_format);
if (bytes >= 0) {
score -= 8 * bytes; // excess precision
} else {
score += 1024 * (bytes - 1); // precision is lost (i.e. s32 -> float)
}
} else {
// For float->int, always prefer highest bit depth int
score -= 8 * (AF_FORMAT_64BIT - dst_bits);
// float->int is the worst case. Penalize heavily and
// prefer highest bit depth int.
score -= 1048576 * (8 - dst_bytes);
}
score -= 512; // penalty for any float <-> int conversion
} else {
int bits = FMT_DIFF(AF_FORMAT_BITS_MASK, dst_format, src_format);
if (bits > 0) {
score -= 8 * bits; // has to add padding
} else if (bits < 0) {
score -= 1024 - 8 * bits; // has to reduce bit depth
int bytes = af_fmt_to_bytes(dst_format) - af_fmt_to_bytes(src_format);
if (bytes > 0) {
score -= 8 * bytes; // has to add padding
} else if (bytes < 0) {
score += 1024 * (bytes - 1); // has to reduce bit depth
}
}
// Consider this the worst case.
if (FMT_DIFF(AF_FORMAT_TYPE_MASK, dst_format, src_format))
score -= 2048; // has to convert float<->int
return score;
}
struct entry {
int fmt;
int score;
};
static int cmp_entry(const void *a, const void *b)
{
#define CMP_INT(a, b) (a > b ? 1 : (a < b ? -1 : 0))
return -CMP_INT(((struct entry *)a)->score, ((struct entry *)b)->score);
}
// Return a list of sample format compatible to src_format, sorted by order
// of preference. out_formats[0] will be src_format (as long as it's valid),
// and the list is terminated with 0 (AF_FORMAT_UNKNOWN).
// Keep in mind that this also returns formats with flipped interleaving
// (e.g. for s16, it returns [s16, s16p, ...]).
void af_get_best_sample_formats(int src_format, int out_formats[AF_FORMAT_COUNT])
{
int num = 0;
struct entry e[AF_FORMAT_COUNT];
for (int fmt = 1; fmt < AF_FORMAT_COUNT; fmt++) {
int score = af_format_conversion_score(fmt, src_format);
if (score > INT_MIN)
e[num++] = (struct entry){fmt, score};
}
qsort(e, num, sizeof(e[0]), cmp_entry);
for (int n = 0; n < num; n++)
out_formats[n] = e[n].fmt;
out_formats[num] = 0;
}
// Return the number of samples that make up one frame in this format.
// You get the byte size by multiplying them with sample size and channel count.
int af_format_sample_alignment(int format)
+33 -81
View File
@@ -22,96 +22,50 @@
#ifndef MPLAYER_AF_FORMAT_H
#define MPLAYER_AF_FORMAT_H
#include <stddef.h>
#include <stdbool.h>
#include "misc/bstr.h"
// Signed/unsigned
#define AF_FORMAT_SI (0<<0) // Signed
#define AF_FORMAT_US (1<<0) // Unsigned
#define AF_FORMAT_SIGN_MASK (1<<0)
// Bits used
// Some code assumes they're sorted by size.
#define AF_FORMAT_8BIT (0<<1)
#define AF_FORMAT_16BIT (1<<1)
#define AF_FORMAT_24BIT (2<<1)
#define AF_FORMAT_32BIT (3<<1)
#define AF_FORMAT_64BIT (4<<1)
#define AF_FORMAT_BITS_MASK (7<<1)
// Fixed/floating point/special
#define AF_FORMAT_I (1<<4) // Int
#define AF_FORMAT_F (2<<4) // Foating point
#define AF_FORMAT_S (4<<4) // special (IEC61937)
#define AF_FORMAT_TYPE_MASK (7<<4)
// Interleaving (planar formats have data for each channel in separate planes)
#define AF_FORMAT_INTERLEAVED (0<<7) // must be 0
#define AF_FORMAT_PLANAR (1<<7)
#define AF_FORMAT_INTERLEAVING_MASK (1<<7)
#define AF_FORMAT_S_CODEC(n) ((n)<<8)
#define AF_FORMAT_S_CODEC_MASK (15 <<8) // 16 codecs max.
#define AF_FORMAT_MASK ((1<<12)-1)
#define AF_INTP (AF_FORMAT_I|AF_FORMAT_PLANAR)
#define AF_FLTP (AF_FORMAT_F|AF_FORMAT_PLANAR)
#define AF_FORMAT_S_(n) (AF_FORMAT_S_CODEC(n)|AF_FORMAT_S|AF_FORMAT_16BIT)
// actual sample formats
enum af_format {
AF_FORMAT_UNKNOWN = 0,
AF_FORMAT_UNKNOWN = 0,
AF_FORMAT_U8 = AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_8BIT,
AF_FORMAT_S8 = AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_8BIT,
AF_FORMAT_U16 = AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_16BIT,
AF_FORMAT_S16 = AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_16BIT,
AF_FORMAT_U24 = AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_24BIT,
AF_FORMAT_S24 = AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_24BIT,
AF_FORMAT_U32 = AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_32BIT,
AF_FORMAT_S32 = AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_32BIT,
AF_FORMAT_FLOAT = AF_FORMAT_F|AF_FORMAT_32BIT,
AF_FORMAT_DOUBLE = AF_FORMAT_F|AF_FORMAT_64BIT,
AF_FORMAT_U8,
AF_FORMAT_S16,
AF_FORMAT_S24,
AF_FORMAT_S32,
AF_FORMAT_FLOAT,
AF_FORMAT_DOUBLE,
// Planar variants
AF_FORMAT_U8P = AF_INTP|AF_FORMAT_US|AF_FORMAT_8BIT,
AF_FORMAT_S16P = AF_INTP|AF_FORMAT_SI|AF_FORMAT_16BIT,
AF_FORMAT_S32P = AF_INTP|AF_FORMAT_SI|AF_FORMAT_32BIT,
AF_FORMAT_FLOATP = AF_FLTP|AF_FORMAT_32BIT,
AF_FORMAT_DOUBLEP = AF_FLTP|AF_FORMAT_64BIT,
AF_FORMAT_U8P,
AF_FORMAT_S16P,
AF_FORMAT_S32P,
AF_FORMAT_FLOATP,
AF_FORMAT_DOUBLEP,
// All of these use IEC61937 framing, and otherwise pretend to be like PCM.
AF_FORMAT_S_AAC = AF_FORMAT_S_(0),
AF_FORMAT_S_AC3 = AF_FORMAT_S_(1),
AF_FORMAT_S_DTS = AF_FORMAT_S_(2),
AF_FORMAT_S_DTSHD = AF_FORMAT_S_(3),
AF_FORMAT_S_EAC3 = AF_FORMAT_S_(4),
AF_FORMAT_S_MP3 = AF_FORMAT_S_(5),
AF_FORMAT_S_TRUEHD = AF_FORMAT_S_(6),
AF_FORMAT_S_AAC,
AF_FORMAT_S_AC3,
AF_FORMAT_S_DTS,
AF_FORMAT_S_DTSHD,
AF_FORMAT_S_EAC3,
AF_FORMAT_S_MP3,
AF_FORMAT_S_TRUEHD,
AF_FORMAT_COUNT
};
#define AF_FORMAT_IS_IEC61937(f) (((f) & AF_FORMAT_TYPE_MASK) == AF_FORMAT_S)
#define AF_FORMAT_IS_SPECIAL(f) AF_FORMAT_IS_IEC61937(f)
#define AF_FORMAT_IS_FLOAT(f) (!!((f) & AF_FORMAT_F))
// false for interleaved and AF_FORMAT_UNKNOWN
#define AF_FORMAT_IS_PLANAR(f) (!!((f) & AF_FORMAT_PLANAR))
struct af_fmt_entry {
const char *name;
int format;
};
extern const struct af_fmt_entry af_fmtstr_table[];
int af_str2fmt_short(bstr str);
const char *af_fmt_to_str(int format);
int af_fmt2bps(int format);
int af_fmt2bits(int format);
int af_fmt_change_bits(int format, int bits);
int af_fmt_to_bytes(int format);
int af_fmt_change_bytes(int format, int bytes);
bool af_fmt_is_valid(int format);
bool af_fmt_is_unsigned(int format);
bool af_fmt_is_float(int format);
bool af_fmt_is_int(int format);
bool af_fmt_is_planar(int format);
bool af_fmt_is_spdif(int format);
bool af_fmt_is_pcm(int format);
int af_fmt_to_planar(int format);
int af_fmt_from_planar(int format);
@@ -119,11 +73,9 @@ int af_fmt_from_planar(int format);
// Amount of bytes that contain audio of the given duration, aligned to frames.
int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int samplerate);
bool af_fmt_is_valid(int format);
void af_fill_silence(void *dst, size_t bytes, int format);
int af_format_conversion_score(int dst_format, int src_format);
void af_get_best_sample_formats(int src_format, int out_formats[AF_FORMAT_COUNT]);
int af_format_sample_alignment(int format);
+15 -16
View File
@@ -69,10 +69,10 @@ bool mixer_audio_initialized(struct mixer *mixer)
return !!mixer->ao;
}
float mixer_getneutralvolume(struct mixer *mixer)
float mixer_getmaxvolume(struct mixer *mixer)
{
// gain == 1
return mixer->softvol ? 1.0 / mixer->opts->softvol_max * 100.0 * 100.0 : 100;
return mixer->softvol ? mixer->opts->softvol_max : 100;
}
static void checkvolume(struct mixer *mixer)
@@ -85,8 +85,8 @@ static void checkvolume(struct mixer *mixer)
float gain;
if (!af_control_any_rev(mixer->af, AF_CONTROL_GET_VOLUME, &gain))
gain = 1.0;
vol.left = (gain / (mixer->opts->softvol_max / 100.0)) * 100.0;
vol.right = (gain / (mixer->opts->softvol_max / 100.0)) * 100.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
@@ -122,14 +122,14 @@ void mixer_getvolume(struct mixer *mixer, float *l, float *r)
static void setvolume_internal(struct mixer *mixer, float l, float r)
{
struct ao_control_vol vol = {.left = l, .right = r};
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 * mixer->opts->softvol_max / 100.0;
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;
@@ -144,8 +144,9 @@ void mixer_setvolume(struct mixer *mixer, float l, float r)
{
checkvolume(mixer); // to check mute status
mixer->vol_l = av_clipf(l, 0, 100);
mixer->vol_r = av_clipf(r, 0, 100);
float max = mixer_getmaxvolume(mixer);
mixer->vol_l = MPCLAMP(l, 0, max);
mixer->vol_r = MPCLAMP(r, 0, max);
if (mixer->ao && !(mixer->emulate_mute && mixer->muted))
setvolume_internal(mixer, mixer->vol_l, mixer->vol_r);
}
@@ -226,7 +227,7 @@ void mixer_setbalance(struct mixer *mixer, float val)
return;
}
/* make all other channels pass thru since by default pan blocks all */
/* 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;
@@ -242,9 +243,8 @@ char *mixer_get_volume_restore_data(struct mixer *mixer)
{
if (!mixer->driver[0])
return NULL;
return talloc_asprintf(NULL, "%s:%f:%f:%d:%f", mixer->driver, mixer->vol_l,
mixer->vol_r, mixer->muted_by_us,
mixer->opts->softvol_max);
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)
@@ -315,11 +315,10 @@ static void restore_volume(struct mixer *mixer)
char *data = mixer->opts->mixer_restore_volume_data;
if (!mixer->persistent_volume && data && data[0]) {
char drv[40];
float v_l, v_r, s;
float v_l, v_r;
int m;
if (sscanf(data, "%39[^:]:%f:%f:%d:%f", drv, &v_l, &v_r, &m, &s) == 5) {
float diff = fabs(mixer->opts->softvol_max - s);
if (strcmp(mixer->driver, drv) == 0 && diff < 0.01) {
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;
+1 -1
View File
@@ -44,7 +44,7 @@ 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_getneutralvolume(struct mixer *mixer);
float mixer_getmaxvolume(struct mixer *mixer);
char *mixer_get_volume_restore_data(struct mixer *mixer);
#endif /* MPLAYER_MIXER_H */
+63 -59
View File
@@ -191,14 +191,14 @@ static struct ao *ao_init(bool probing, struct mpv_global *global,
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, args);
samplerate, format, channels, rdevice, redirect, NULL);
}
goto fail;
}
ao->sstride = af_fmt2bps(ao->format);
ao->sstride = af_fmt_to_bytes(ao->format);
ao->num_planes = 1;
if (AF_FORMAT_IS_PLANAR(ao->format)) {
if (af_fmt_is_planar(ao->format)) {
ao->num_planes = ao->channels.num;
} else {
ao->sstride *= ao->channels.num;
@@ -240,6 +240,7 @@ 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,
struct encode_lavc_context *encode_lavc_ctx,
int samplerate, int format, struct mp_chmap channels)
@@ -248,58 +249,67 @@ struct ao *ao_init_best(struct mpv_global *global,
void *tmp = talloc_new(NULL);
struct mp_log *log = mp_log_new(tmp, global->log, "ao");
struct ao *ao = NULL;
struct m_obj_settings *ao_list = opts->audio_driver_list;
struct m_obj_settings *ao_list = NULL;
int ao_num = 0;
for (int n = 0; opts->audio_driver_list && opts->audio_driver_list[n].name; n++)
MP_TARRAY_APPEND(tmp, ao_list, ao_num, opts->audio_driver_list[n]);
bool forced_dev = false;
char *pref_ao, *pref_dev;
split_ao_device(tmp, opts->audio_device, &pref_ao, &pref_dev);
if (!(ao_list && ao_list[0].name) && pref_ao) {
if (!ao_num && pref_ao) {
// Reuse the autoselection code
ao_list = talloc_zero_array(tmp, struct m_obj_settings, 2);
ao_list[0].name = pref_ao;
MP_TARRAY_APPEND(tmp, ao_list, ao_num,
(struct m_obj_settings){.name = pref_ao});
forced_dev = true;
}
if (ao_list && ao_list[0].name) {
for (int n = 0; ao_list[n].name; n++) {
if (strlen(ao_list[n].name) == 0)
goto autoprobe;
mp_verbose(log, "Trying preferred audio driver '%s'\n",
ao_list[n].name);
char *dev = NULL;
if (pref_ao && strcmp(ao_list[n].name, pref_ao) == 0)
dev = pref_dev;
if (dev)
mp_verbose(log, "Using preferred device '%s'\n", dev);
ao = ao_init(false, global, input_ctx, encode_lavc_ctx,
samplerate, format, channels, dev,
ao_list[n].name, ao_list[n].attribs);
if (ao)
goto done;
mp_err(log, "Failed to initialize audio driver '%s'\n",
ao_list[n].name);
if (forced_dev) {
mp_err(log, "This audio driver/device was forced with the "
"--audio-device option.\n"
"Try unsetting it.\n");
}
bool autoprobe = ao_num == 0;
// Something like "--ao=a,b," means do autoprobing after a and b fail.
if (ao_num && strlen(ao_list[ao_num - 1].name) == 0) {
ao_num -= 1;
autoprobe = true;
}
if (autoprobe) {
for (int n = 0; audio_out_drivers[n]; n++) {
const struct ao_driver *driver = audio_out_drivers[n];
if (driver == &audio_out_null)
break;
MP_TARRAY_APPEND(tmp, ao_list, ao_num,
(struct m_obj_settings){.name = (char *)driver->name});
}
goto done;
}
autoprobe: ;
// now try the rest...
for (int i = 0; audio_out_drivers[i]; i++) {
const struct ao_driver *driver = audio_out_drivers[i];
if (driver == &audio_out_null)
break;
ao = ao_init(true, global, input_ctx, encode_lavc_ctx, samplerate,
format, channels, NULL, (char *)driver->name, NULL);
if (ao_null_fallback) {
MP_TARRAY_APPEND(tmp, ao_list, ao_num,
(struct m_obj_settings){.name = "null"});
}
for (int n = 0; n < ao_num; n++) {
struct m_obj_settings *entry = &ao_list[n];
bool probing = n + 1 != ao_num;
mp_verbose(log, "Trying audio driver '%s'\n", entry->name);
char *dev = NULL;
if (pref_ao && pref_dev && strcmp(entry->name, pref_ao) == 0) {
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);
if (ao)
goto done;
break;
if (!probing)
mp_err(log, "Failed to initialize audio driver '%s'\n", entry->name);
if (dev && forced_dev) {
mp_err(log, "This audio driver/device was forced with the "
"--audio-device option.\nTry unsetting it.\n");
}
}
done:
talloc_free(tmp);
return ao;
}
@@ -307,7 +317,8 @@ done:
// Uninitialize and destroy the AO. Remaining audio must be dropped.
void ao_uninit(struct ao *ao)
{
ao->api->uninit(ao);
if (ao)
ao->api->uninit(ao);
talloc_free(ao);
}
@@ -410,22 +421,11 @@ void ao_hotplug_event(struct ao *ao)
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
struct mp_chmap *map)
{
if (mp_msg_test(ao->log, MSGL_DEBUG)) {
for (int i = 0; i < s->num_chmaps; i++) {
struct mp_chmap c = s->chmaps[i];
struct mp_chmap cr = c;
mp_chmap_reorder_norm(&cr);
MP_DBG(ao, "chmap_sel #%d: %s (%s)\n", i, mp_chmap_to_str(&c),
mp_chmap_to_str(&cr));
}
}
MP_VERBOSE(ao, "Channel layouts:\n");
mp_chmal_sel_log(s, ao->log, MSGL_V);
bool r = mp_chmap_sel_adjust(s, map);
if (r) {
struct mp_chmap mapr = *map;
mp_chmap_reorder_norm(&mapr);
MP_DBG(ao, "result: %s (%s)\n", mp_chmap_to_str(map),
mp_chmap_to_str(&mapr));
}
if (r)
MP_VERBOSE(ao, "result: %s\n", mp_chmap_to_str(map));
return r;
}
@@ -493,8 +493,12 @@ static void get_devices(struct ao *ao, struct ao_device_list *list)
if (ao->driver->list_devs)
ao->driver->list_devs(ao, list);
// Add at least a default entry
if (list->num_devices == num)
ao_device_list_add(list, ao, &(struct ao_device_desc){"", "Default"});
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});
}
}
bool ao_hotplug_check_update(struct ao_hotplug *hp)
+1
View File
@@ -72,6 +72,7 @@ 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,
struct encode_lavc_context *encode_lavc_ctx,
int samplerate, int format, struct mp_chmap channels);
+325 -225
View File
@@ -50,12 +50,13 @@
struct priv {
snd_pcm_t *alsa;
bool device_lost;
snd_pcm_format_t alsa_fmt;
int can_pause;
bool can_pause;
snd_pcm_sframes_t prepause_frames;
double delay_before_pause;
int buffersize; // in frames
int outburst; // in frames
snd_pcm_uframes_t buffersize;
snd_pcm_uframes_t outburst;
char *cfg_device;
char *cfg_mixer_device;
@@ -83,6 +84,21 @@ struct priv {
MP_WARN(ao, "%s: %s\n", (message), snd_strerror(err)); \
} while (0)
// Common code for handling ENODEV, which happens if a device gets "lost", and
// can't be used anymore. Returns true if alsa_err is not ENODEV.
static bool check_device_present(struct ao *ao, int alsa_err)
{
struct priv *p = ao->priv;
if (alsa_err != -ENODEV)
return true;
if (!p->device_lost) {
MP_WARN(ao, "Device lost, trying to recover...\n");
ao_request_reload(ao);
p->device_lost = true;
}
return false;
}
static int control(struct ao *ao, enum aocontrol cmd, void *arg)
{
struct priv *p = ao->priv;
@@ -101,7 +117,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
long get_vol, set_vol;
float f_multi;
if (AF_FORMAT_IS_SPECIAL(ao->format))
if (!af_fmt_is_pcm(ao->format))
return CONTROL_FALSE;
snd_mixer_selem_id_alloca(&sid);
@@ -204,17 +220,14 @@ alsa_error:
}
static const int mp_to_alsa_format[][2] = {
{AF_FORMAT_S8, SND_PCM_FORMAT_S8},
{AF_FORMAT_U8, SND_PCM_FORMAT_U8},
{AF_FORMAT_U16, SND_PCM_FORMAT_U16},
{AF_FORMAT_S16, SND_PCM_FORMAT_S16},
{AF_FORMAT_U32, SND_PCM_FORMAT_U32},
{AF_FORMAT_S32, SND_PCM_FORMAT_S32},
{AF_FORMAT_U24,
MP_SELECT_LE_BE(SND_PCM_FORMAT_U24_3LE, SND_PCM_FORMAT_U24_3BE)},
{AF_FORMAT_S24,
MP_SELECT_LE_BE(SND_PCM_FORMAT_S24_3LE, SND_PCM_FORMAT_S24_3BE)},
{AF_FORMAT_FLOAT, SND_PCM_FORMAT_FLOAT},
{AF_FORMAT_DOUBLE, SND_PCM_FORMAT_FLOAT64},
{AF_FORMAT_S_MP3, SND_PCM_FORMAT_MPEG},
{AF_FORMAT_UNKNOWN, SND_PCM_FORMAT_UNKNOWN},
};
@@ -225,6 +238,8 @@ static int find_alsa_format(int af_format)
if (mp_to_alsa_format[n][0] == af_format)
return mp_to_alsa_format[n][1];
}
if (af_fmt_is_spdif(af_format))
return SND_PCM_FORMAT_S16;
return SND_PCM_FORMAT_UNKNOWN;
}
@@ -251,8 +266,11 @@ static const int alsa_to_mp_channels[][2] = {
{SND_CHMAP_TRL, MP_SP(TBL)},
{SND_CHMAP_TRR, MP_SP(TBR)},
{SND_CHMAP_TRC, MP_SP(TBC)},
{SND_CHMAP_RRC, MP_SP(SDR)},
{SND_CHMAP_RLC, MP_SP(SDL)},
{SND_CHMAP_MONO, MP_SP(FC)},
{SND_CHMAP_NA, MP_SPEAKER_ID_NA},
{SND_CHMAP_UNKNOWN, MP_SPEAKER_ID_NA},
{SND_CHMAP_LAST, MP_SPEAKER_ID_COUNT}
};
@@ -266,28 +284,48 @@ static int find_mp_channel(int alsa_channel)
return MP_SPEAKER_ID_COUNT;
}
static int find_alsa_channel(int mp_channel)
{
for (int i = 0; alsa_to_mp_channels[i][1] != MP_SPEAKER_ID_COUNT; i++) {
if (alsa_to_mp_channels[i][1] == mp_channel)
return alsa_to_mp_channels[i][0];
}
#define CHMAP(n, ...) &(struct mp_chmap) MP_CONCAT(MP_CHMAP, n) (__VA_ARGS__)
return SND_CHMAP_UNKNOWN;
// Replace each channel in a with b (a->num == b->num)
static void replace_submap(struct mp_chmap *dst, struct mp_chmap *a,
struct mp_chmap *b)
{
struct mp_chmap t = *dst;
if (!mp_chmap_is_valid(&t) || mp_chmap_diffn(a, &t) != 0)
return;
assert(a->num == b->num);
for (int n = 0; n < t.num; n++) {
for (int i = 0; i < a->num; i++) {
if (t.speaker[n] == a->speaker[i]) {
t.speaker[n] = b->speaker[i];
break;
}
}
}
if (mp_chmap_is_valid(&t))
*dst = t;
}
static int mp_chmap_from_alsa(struct mp_chmap *dst, snd_pcm_chmap_t *src)
static bool mp_chmap_from_alsa(struct mp_chmap *dst, snd_pcm_chmap_t *src)
{
*dst = (struct mp_chmap) {0};
if (src->channels > MP_NUM_CHANNELS)
return -1;
return false;
dst->num = src->channels;
for (int c = 0; c < dst->num; c++)
dst->speaker[c] = find_mp_channel(src->pos[c]);
return 0;
// Assume anything with 1 channel is mono.
if (dst->num == 1)
dst->speaker[0] = MP_SP(FC);
// Remap weird Intel HDA HDMI 7.1 layouts correctly.
replace_submap(dst, CHMAP(6, FL, FR, BL, BR, SDL, SDR),
CHMAP(6, FL, FR, SL, SR, BL, BR));
return mp_chmap_is_valid(dst);
}
static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
@@ -300,18 +338,21 @@ static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
return false;
for (int i = 0; maps[i] != NULL; i++) {
struct mp_chmap entry;
mp_chmap_from_alsa(&entry, &maps[i]->map);
char aname[128];
if (snd_pcm_chmap_print(&maps[i]->map, sizeof(aname), aname) <= 0)
aname[0] = '\0';
if (mp_chmap_is_valid(&entry)) {
MP_VERBOSE(ao, "Got supported channel map: %s (type %s)\n",
mp_chmap_to_str(&entry),
snd_pcm_chmap_type_name(maps[i]->type));
mp_chmap_sel_add_map(&chmap_sel, &entry);
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);
} else {
char tmp[128];
if (snd_pcm_chmap_print(&maps[i]->map, sizeof(tmp), tmp) > 0)
MP_VERBOSE(ao, "skipping unknown ALSA channel map: %s\n", tmp);
MP_VERBOSE(ao, "skipping unknown ALSA channel map: %s\n", aname);
}
}
@@ -320,6 +361,108 @@ static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
return ao_chmap_sel_adjust(ao, &chmap_sel, chmap);
}
// Map back our selected channel layout to an ALSA one. This is done this way so
// that our ALSA->mp_chmap mapping function only has to go one way.
// The return value is to be freed with free().
static snd_pcm_chmap_t *map_back_chmap(struct ao *ao, struct mp_chmap *chmap)
{
struct priv *p = ao->priv;
if (!mp_chmap_is_valid(chmap))
return NULL;
snd_pcm_chmap_query_t **maps = snd_pcm_query_chmaps(p->alsa);
if (!maps)
return NULL;
snd_pcm_chmap_t *alsa_chmap = NULL;
for (int i = 0; maps[i] != NULL; i++) {
struct mp_chmap entry;
if (!mp_chmap_from_alsa(&entry, &maps[i]->map))
continue;
if (mp_chmap_equals(chmap, &entry) ||
(mp_chmap_equals_reordered(chmap, &entry) &&
maps[i]->type == SND_CHMAP_TYPE_VAR))
{
alsa_chmap = calloc(1, sizeof(*alsa_chmap) +
sizeof(alsa_chmap->pos[0]) * entry.num);
if (!alsa_chmap)
break;
alsa_chmap->channels = entry.num;
// Undo if mp_chmap_reorder() was called on the result.
int reorder[MP_NUM_CHANNELS];
mp_chmap_get_reorder(reorder, chmap, &entry);
for (int n = 0; n < entry.num; n++)
alsa_chmap->pos[n] = maps[i]->map.pos[reorder[n]];
break;
}
}
snd_pcm_free_chmaps(maps);
return alsa_chmap;
}
static int set_chmap(struct ao *ao, struct mp_chmap *dev_chmap, int num_channels)
{
struct priv *p = ao->priv;
int err;
snd_pcm_chmap_t *alsa_chmap = map_back_chmap(ao, dev_chmap);
if (alsa_chmap) {
char tmp[128];
if (snd_pcm_chmap_print(alsa_chmap, sizeof(tmp), tmp) > 0)
MP_VERBOSE(ao, "trying to set ALSA channel map: %s\n", tmp);
err = snd_pcm_set_chmap(p->alsa, alsa_chmap);
if (err == -ENXIO) {
// A device my not be able to set any channel map, even channel maps
// that were reported as supported. This is either because the ALSA
// device is broken (dmix), or because the driver has only 1
// channel map per channel count, and setting the map is not needed.
MP_VERBOSE(ao, "device returned ENXIO when setting channel map %s\n",
mp_chmap_to_str(dev_chmap));
} else {
CHECK_ALSA_WARN("Channel map setup failed");
}
free(alsa_chmap);
}
alsa_chmap = snd_pcm_get_chmap(p->alsa);
if (alsa_chmap) {
char tmp[128];
if (snd_pcm_chmap_print(alsa_chmap, sizeof(tmp), tmp) > 0)
MP_VERBOSE(ao, "channel map reported by ALSA: %s\n", tmp);
struct mp_chmap chmap;
mp_chmap_from_alsa(&chmap, alsa_chmap);
MP_VERBOSE(ao, "which we understand as: %s\n", mp_chmap_to_str(&chmap));
if (p->cfg_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");
} else if (!mp_chmap_is_valid(&chmap)) {
MP_WARN(ao, "Got unknown channel map from ALSA.\n");
} 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))
MP_VERBOSE(ao, "which is what we requested.\n");
ao->channels = chmap;
}
free(alsa_chmap);
}
return 0;
}
#else /* HAVE_CHMAP_API */
static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
@@ -327,6 +470,11 @@ static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
return false;
}
static int set_chmap(struct ao *ao, struct mp_chmap *dev_chmap, int num_channels)
{
return 0;
}
#endif /* else HAVE_CHMAP_API */
static int map_iec958_srate(int srate)
@@ -347,8 +495,8 @@ static int map_iec958_srate(int srate)
}
// ALSA device strings can have parameters. They are usually appended to the
// device name. Since there can be various forms, and we (sometimes) want to
// append them to unknown device strings, which possibly already include params.
// device name. There can be various forms, and we (sometimes) want to append
// them to unknown device strings, which possibly already include params.
static char *append_params(void *ta_parent, const char *device, const char *p)
{
if (!p || !p[0])
@@ -375,8 +523,9 @@ static char *append_params(void *ta_parent, const char *device, const char *p)
static int try_open_device(struct ao *ao, const char *device)
{
struct priv *p = ao->priv;
int err;
if (AF_FORMAT_IS_IEC61937(ao->format)) {
if (af_fmt_is_spdif(ao->format)) {
void *tmp = talloc_new(NULL);
char *params = talloc_asprintf(tmp,
"AES0=%d,AES1=%d,AES2=0,AES3=%d",
@@ -385,15 +534,29 @@ 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);
int 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, 0);
if (err < 0) {
// Some spdif-capable devices do not accept the AES0 parameter,
// and instead require the iec958 pseudo-device (they will play
// noise otherwise). Unfortunately, ALSA gives us no way to map
// these devices, so try it for the default device only.
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);
}
}
talloc_free(tmp);
if (!err)
return 0;
} else {
MP_VERBOSE(ao, "opening device '%s'\n", device);
err = snd_pcm_open(&p->alsa, device, SND_PCM_STREAM_PLAYBACK, 0);
}
MP_VERBOSE(ao, "opening device '%s'\n", device);
return snd_pcm_open(&p->alsa, device, SND_PCM_STREAM_PLAYBACK, 0);
return err;
}
static void uninit(struct ao *ao)
@@ -404,23 +567,19 @@ static void uninit(struct ao *ao)
int err;
err = snd_pcm_close(p->alsa);
p->alsa = NULL;
CHECK_ALSA_ERROR("pcm close error");
}
alsa_error: ;
}
#define INIT_OK 0
#define INIT_ERROR -1
#define INIT_BRAINDEATH -2
static int init_device(struct ao *ao, bool second_try)
static int init_device(struct ao *ao)
{
struct priv *p = ao->priv;
int err;
const char *device = "default";
if (AF_FORMAT_IS_IEC61937(ao->format))
device = "iec958";
if (ao->device)
device = ao->device;
if (p->cfg_device && p->cfg_device[0])
@@ -433,55 +592,58 @@ static int init_device(struct ao *ao, bool second_try)
CHECK_ALSA_WARN("Unable to set blocking mode");
snd_pcm_hw_params_t *alsa_hwparams;
snd_pcm_sw_params_t *alsa_swparams;
snd_pcm_hw_params_alloca(&alsa_hwparams);
snd_pcm_sw_params_alloca(&alsa_swparams);
err = snd_pcm_hw_params_any(p->alsa, alsa_hwparams);
CHECK_ALSA_ERROR("Unable to get initial parameters");
if (AF_FORMAT_IS_IEC61937(ao->format)) {
if (ao->format == AF_FORMAT_S_MP3) {
p->alsa_fmt = SND_PCM_FORMAT_MPEG;
} else {
p->alsa_fmt = SND_PCM_FORMAT_S16;
}
} else {
p->alsa_fmt = find_alsa_format(ao->format);
}
if (p->alsa_fmt == SND_PCM_FORMAT_UNKNOWN) {
p->alsa_fmt = SND_PCM_FORMAT_S16;
ao->format = AF_FORMAT_S16;
// Some ALSA drivers have broken delay reporting, so disable the ALSA
// resampling plugin by default.
if (!p->cfg_resample) {
err = snd_pcm_hw_params_set_rate_resample(p->alsa, alsa_hwparams, 0);
CHECK_ALSA_ERROR("Unable to disable resampling");
}
err = snd_pcm_hw_params_test_format(p->alsa, alsa_hwparams, p->alsa_fmt);
if (err < 0) {
if (AF_FORMAT_IS_IEC61937(ao->format))
CHECK_ALSA_ERROR("Unable to set IEC61937 format");
MP_INFO(ao, "Format %s is not supported by hardware, trying default.\n",
af_fmt_to_str(ao->format));
p->alsa_fmt = SND_PCM_FORMAT_S16;
ao->format = AF_FORMAT_S16;
}
err = snd_pcm_hw_params_set_format(p->alsa, alsa_hwparams, p->alsa_fmt);
CHECK_ALSA_ERROR("Unable to set format");
snd_pcm_access_t access = AF_FORMAT_IS_PLANAR(ao->format)
snd_pcm_access_t access = af_fmt_is_planar(ao->format)
? SND_PCM_ACCESS_RW_NONINTERLEAVED
: SND_PCM_ACCESS_RW_INTERLEAVED;
err = snd_pcm_hw_params_set_access(p->alsa, alsa_hwparams, access);
if (err < 0 && AF_FORMAT_IS_PLANAR(ao->format)) {
if (err < 0 && af_fmt_is_planar(ao->format)) {
ao->format = af_fmt_from_planar(ao->format);
access = SND_PCM_ACCESS_RW_INTERLEAVED;
err = snd_pcm_hw_params_set_access(p->alsa, alsa_hwparams, access);
}
CHECK_ALSA_ERROR("Unable to set access type");
bool found_format = false;
int try_formats[AF_FORMAT_COUNT];
af_get_best_sample_formats(ao->format, try_formats);
for (int n = 0; try_formats[n]; n++) {
if (af_fmt_is_planar(ao->format) != af_fmt_is_planar(try_formats[n]))
continue; // implied SND_PCM_ACCESS mismatches
p->alsa_fmt = find_alsa_format(try_formats[n]);
MP_VERBOSE(ao, "trying format %s\n", af_fmt_to_str(try_formats[n]));
if (snd_pcm_hw_params_test_format(p->alsa, alsa_hwparams, p->alsa_fmt) >= 0) {
ao->format = try_formats[n];
found_format = true;
break;
}
}
if (!found_format) {
MP_ERR(ao, "Can't find appropriate sample format.\n");
goto alsa_error;
}
err = snd_pcm_hw_params_set_format(p->alsa, alsa_hwparams, p->alsa_fmt);
CHECK_ALSA_ERROR("Unable to set format");
struct mp_chmap dev_chmap = ao->channels;
if (AF_FORMAT_IS_IEC61937(ao->format) || p->cfg_ignore_chmap) {
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 {
@@ -500,153 +662,51 @@ static int init_device(struct ao *ao, bool second_try)
goto alsa_error;
}
if (num_channels != ao->channels.num) {
int req = ao->channels.num;
mp_chmap_from_channels_alsa(&ao->channels, num_channels);
if (!mp_chmap_is_valid(&ao->channels))
mp_chmap_from_channels(&ao->channels, 2);
MP_ERR(ao, "Couldn't get requested number of channels (%d), fallback "
"to %s.\n", req, mp_chmap_to_str(&ao->channels));
}
// Some ALSA drivers have broken delay reporting, so disable the ALSA
// resampling plugin by default.
if (!p->cfg_resample) {
err = snd_pcm_hw_params_set_rate_resample(p->alsa, alsa_hwparams, 0);
CHECK_ALSA_ERROR("Unable to disable resampling");
}
err = snd_pcm_hw_params_set_rate_near
(p->alsa, alsa_hwparams, &ao->samplerate, NULL);
CHECK_ALSA_ERROR("Unable to set samplerate-2");
snd_pcm_hw_params_t *hwparams_backup;
snd_pcm_hw_params_alloca(&hwparams_backup);
snd_pcm_hw_params_copy(hwparams_backup, alsa_hwparams);
// Cargo-culted buffer settings; might still be useful for PulseAudio.
err = snd_pcm_hw_params_set_buffer_time_near
(p->alsa, alsa_hwparams, &(unsigned int){BUFFER_TIME}, NULL);
CHECK_ALSA_WARN("Unable to set buffer time near");
err = snd_pcm_hw_params_set_periods_near
(p->alsa, alsa_hwparams, &(unsigned int){FRAGCOUNT}, NULL);
CHECK_ALSA_WARN("Unable to set periods");
if (err >= 0) {
err = snd_pcm_hw_params_set_periods_near
(p->alsa, alsa_hwparams, &(unsigned int){FRAGCOUNT}, NULL);
CHECK_ALSA_WARN("Unable to set periods");
}
if (err < 0)
snd_pcm_hw_params_copy(alsa_hwparams, hwparams_backup);
/* finally install hardware parameters */
err = snd_pcm_hw_params(p->alsa, alsa_hwparams);
CHECK_ALSA_ERROR("Unable to set hw-parameters");
/* end setting hw-params */
if (set_chmap(ao, &dev_chmap, num_channels) < 0)
goto alsa_error;
#if HAVE_CHMAP_API
if (mp_chmap_is_valid(&dev_chmap)) {
snd_pcm_chmap_t *alsa_chmap =
calloc(1, sizeof(*alsa_chmap) +
sizeof(alsa_chmap->pos[0]) * dev_chmap.num);
if (!alsa_chmap)
goto alsa_error;
alsa_chmap->channels = dev_chmap.num;
for (int c = 0; c < dev_chmap.num; c++)
alsa_chmap->pos[c] = find_alsa_channel(dev_chmap.speaker[c]);
// mpv and ALSA use different conventions for mono
if (dev_chmap.num == 1 && dev_chmap.speaker[0] == MP_SP(FC))
alsa_chmap->pos[0] = SND_CHMAP_MONO;
char tmp[128];
if (snd_pcm_chmap_print(alsa_chmap, sizeof(tmp), tmp) > 0)
MP_VERBOSE(ao, "trying to set ALSA channel map: %s\n", tmp);
err = snd_pcm_set_chmap(p->alsa, alsa_chmap);
if (err == -ENXIO) {
// I consider this an ALSA bug: the channel map was reported as
// supported, but we still can't set it. It happens virtually
// always with dmix, though.
MP_VERBOSE(ao, "Device does not support requested channel map (%s)\n",
mp_chmap_to_str(&dev_chmap));
} else {
CHECK_ALSA_WARN("Channel map setup failed");
}
free(alsa_chmap);
if (num_channels != ao->channels.num) {
int req = ao->channels.num;
mp_chmap_from_channels(&ao->channels, MPMIN(2, num_channels));
MP_ERR(ao, "Asked for %d channels, got %d - fallback to %s.\n", req,
num_channels, mp_chmap_to_str(&ao->channels));
}
snd_pcm_chmap_t *alsa_chmap = snd_pcm_get_chmap(p->alsa);
if (alsa_chmap) {
char tmp[128];
if (snd_pcm_chmap_print(alsa_chmap, sizeof(tmp), tmp) > 0)
MP_VERBOSE(ao, "channel map reported by ALSA: %s\n", tmp);
struct mp_chmap chmap;
mp_chmap_from_alsa(&chmap, alsa_chmap);
MP_VERBOSE(ao, "which we understand as: %s\n", mp_chmap_to_str(&chmap));
if (p->cfg_ignore_chmap) {
MP_VERBOSE(ao, "user set ignore-chmap; ignoring the channel map.\n");
} else if (AF_FORMAT_IS_IEC61937(ao->format)) {
MP_VERBOSE(ao, "using spdif passthrough; ignoring the channel map.\n");
} else if (mp_chmap_is_valid(&chmap)) {
// Is it one that contains NA channels?
struct mp_chmap without_na = chmap;
mp_chmap_remove_na(&without_na);
if (mp_chmap_is_valid(&without_na) &&
!mp_chmap_equals(&without_na, &chmap) &&
!second_try)
{
// Sometimes, ALSA will advertise certain chmaps, but it's not
// possible to set them. This can happen with dmix: as of
// alsa 1.0.28, dmix can do stereo only, but advertises the
// surround chmaps of the underlying device. In this case,
// requesting e.g. 5.1 will fail, but it will still allow
// setting 6 channels. Then it will return something like
// "FL FR NA NA NA NA" as channel map. This means we would
// have to pad stereo output to 6 channels with silence, which
// is way too complicated in the general case. You can't change
// the number of channels to 2 either, because the hw params
// are already set! So just fuck it and reopen the device with
// the chmap "cleaned out" of NA entries.
MP_VERBOSE(ao, "Working around braindead ALSA behavior.\n");
err = snd_pcm_close(p->alsa);
p->alsa = NULL;
CHECK_ALSA_ERROR("pcm close error");
ao->channels = without_na;
return INIT_BRAINDEATH;
}
if (mp_chmap_equals(&chmap, &ao->channels)) {
MP_VERBOSE(ao, "which is what we requested.\n");
} else if (chmap.num == ao->channels.num) {
MP_VERBOSE(ao, "using the ALSA channel map.\n");
ao->channels = chmap;
} else {
MP_WARN(ao, "ALSA channel map conflicts with channel count!\n");
}
} else {
MP_WARN(ao, "Got unknown channel map from ALSA.\n");
}
// mpv and ALSA use different conventions for mono
if (ao->channels.num == 1)
ao->channels.speaker[0] = MP_SP(FC);
free(alsa_chmap);
}
#endif
snd_pcm_uframes_t bufsize;
err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams, &bufsize);
err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams, &p->buffersize);
CHECK_ALSA_ERROR("Unable to get buffersize");
p->buffersize = bufsize;
MP_VERBOSE(ao, "got buffersize=%i samples\n", p->buffersize);
snd_pcm_uframes_t chunk_size;
err = snd_pcm_hw_params_get_period_size(alsa_hwparams, &chunk_size, NULL);
err = snd_pcm_hw_params_get_period_size(alsa_hwparams, &p->outburst, NULL);
CHECK_ALSA_ERROR("Unable to get period size");
MP_VERBOSE(ao, "got period size %li\n", chunk_size);
p->outburst = chunk_size;
p->can_pause = snd_pcm_hw_params_can_pause(alsa_hwparams);
snd_pcm_sw_params_t *alsa_swparams;
snd_pcm_sw_params_alloca(&alsa_swparams);
/* setting software parameters */
err = snd_pcm_sw_params_current(p->alsa, alsa_swparams);
CHECK_ALSA_ERROR("Unable to get sw-parameters");
@@ -656,7 +716,7 @@ static int init_device(struct ao *ao, bool second_try)
/* start playing when one period has been written */
err = snd_pcm_sw_params_set_start_threshold
(p->alsa, alsa_swparams, chunk_size);
(p->alsa, alsa_swparams, p->outburst);
CHECK_ALSA_ERROR("Unable to set start threshold");
/* disable underrun reporting */
@@ -672,15 +732,15 @@ static int init_device(struct ao *ao, bool second_try)
err = snd_pcm_sw_params(p->alsa, alsa_swparams);
CHECK_ALSA_ERROR("Unable to set sw-parameters");
/* end setting sw-params */
MP_VERBOSE(ao, "hw pausing supported: %s\n", p->can_pause ? "yes" : "no");
MP_VERBOSE(ao, "buffersize: %d samples\n", (int)p->buffersize);
MP_VERBOSE(ao, "period size: %d samples\n", (int)p->outburst);
p->can_pause = snd_pcm_hw_params_can_pause(alsa_hwparams);
return INIT_OK;
return 0;
alsa_error:
uninit(ao);
return INIT_ERROR;
return -1;
}
static int init(struct ao *ao)
@@ -691,10 +751,33 @@ static int init(struct ao *ao)
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
int r = init_device(ao, false);
if (r == INIT_BRAINDEATH)
r = init_device(ao, true); // retry with normalized channel layout
return r == INIT_OK ? 0 : -1;
int r = init_device(ao);
// 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
// stereo only, but advertises the surround chmaps of the underlying device.
// In this case, e.g. setting 6 channels will succeed, but requesting 5.1
// afterwards will fail. Then it will return something like "FL FR NA NA NA NA"
// as channel map. This means we would have to pad stereo output to 6
// channels with silence, which would require lots of extra processing. You
// can't change the number of channels to 2 either, because the hw params
// are already set! So just fuck it and reopen the device with the chmap
// "cleaned out" of NA entries.
if (r >= 0) {
struct mp_chmap without_na = ao->channels;
mp_chmap_remove_na(&without_na);
if (mp_chmap_is_valid(&without_na) && without_na.num <= 2 &&
ao->channels.num > 2)
{
MP_VERBOSE(ao, "Working around braindead dmix multichannel behavior.\n");
uninit(ao);
ao->channels = without_na;
r = init_device(ao);
}
}
return r;
}
static void drain(struct ao *ao)
@@ -712,6 +795,8 @@ static int get_space(struct ao *ao)
snd_pcm_status_alloca(&status);
err = snd_pcm_status(p->alsa, status);
if (!check_device_present(ao, err))
goto alsa_error;
CHECK_ALSA_ERROR("cannot get pcm status");
unsigned space = snd_pcm_status_get_avail(status);
@@ -755,7 +840,6 @@ static void audio_pause(struct ao *ao)
CHECK_ALSA_ERROR("pcm pause error");
}
} else {
MP_VERBOSE(ao, "pause not supported by hardware\n");
if (snd_pcm_delay(p->alsa, &p->prepause_frames) < 0
|| p->prepause_frames < 0)
p->prepause_frames = 0;
@@ -830,7 +914,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
return 0;
do {
if (AF_FORMAT_IS_PLANAR(ao->format)) {
if (af_fmt_is_planar(ao->format)) {
res = snd_pcm_writen(p->alsa, data, samples);
} else {
res = snd_pcm_writei(p->alsa, data[0], samples);
@@ -838,9 +922,8 @@ static int play(struct ao *ao, void **data, int samples, int flags)
if (res == -EINTR || res == -EAGAIN) { /* retry */
res = 0;
} else if (res == -ENODEV) {
MP_WARN(ao, "Device lost, trying to recover...\n");
ao_request_reload(ao);
} else if (!check_device_present(ao, res)) {
goto alsa_error;
} else if (res < 0) {
if (res == -ESTRPIPE) { /* suspend */
resume_device(ao);
@@ -894,6 +977,20 @@ alsa_error:
return -1;
}
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"};
for (int i = 0; i < MP_ARRAY_SIZE(crap); i++) {
int l = strlen(crap[i]);
if (name && strncmp(name, crap[i], l) == 0 &&
(!name[l] || name[l] == ':'))
return true;
}
return false;
}
static void list_devs(struct ao *ao, struct ao_device_list *list)
{
void **hints;
@@ -904,15 +1001,18 @@ static void list_devs(struct ao *ao, struct ao_device_list *list)
char *name = snd_device_name_get_hint(hints[n], "NAME");
char *desc = snd_device_name_get_hint(hints[n], "DESC");
char *io = snd_device_name_get_hint(hints[n], "IOID");
if (io && strcmp(io, "Output") != 0)
continue;
char desc2[1024];
snprintf(desc2, sizeof(desc2), "%s", desc ? desc : "");
for (int i = 0; desc2[i]; i++) {
if (desc2[i] == '\n')
desc2[i] = '/';
if (!is_useless_device(name) && (!io || strcmp(io, "Output") == 0)) {
char desc2[1024];
snprintf(desc2, sizeof(desc2), "%s", desc ? desc : "");
for (int i = 0; desc2[i]; i++) {
if (desc2[i] == '\n')
desc2[i] = '/';
}
ao_device_list_add(list, ao, &(struct ao_device_desc){name, desc2});
}
ao_device_list_add(list, ao, &(struct ao_device_desc){name, desc2});
free(name);
free(desc);
free(io);
}
snd_device_name_free_hint(hints);
+103 -247
View File
@@ -25,18 +25,22 @@
#include "options/m_option.h"
#include "misc/ring.h"
#include "common/msg.h"
#include "audio/out/ao_coreaudio_properties.h"
#include "audio/out/ao_coreaudio_utils.h"
#include "ao_coreaudio_chmap.h"
#include "ao_coreaudio_properties.h"
#include "ao_coreaudio_utils.h"
struct priv {
AudioDeviceID device;
AudioUnit audio_unit;
uint64_t hw_latency_us;
};
bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
struct mp_chmap *chmap);
AudioStreamBasicDescription original_asbd;
AudioStreamID original_asbd_stream;
int change_physical_format;
int exclusive;
};
static int64_t ca_get_hardware_latency(struct ao *ao) {
struct priv *p = ao->priv;
@@ -52,12 +56,8 @@ static int64_t ca_get_hardware_latency(struct ao *ao) {
&size);
CHECK_CA_ERROR("cannot get audio unit latency");
uint32_t frames = 0;
err = CA_GET_O(p->device, kAudioDevicePropertyLatency, &frames);
CHECK_CA_ERROR("cannot get device latency");
uint64_t audiounit_latency_us = audiounit_latency_sec * 1e6;
uint64_t device_latency_us = ca_frames_to_us(ao, frames);
uint64_t device_latency_us = ca_get_device_latency_us(ao, p->device);
MP_VERBOSE(ao, "audiounit latency [us]: %lld\n", audiounit_latency_us);
MP_VERBOSE(ao, "device latency [us]: %lld\n", device_latency_us);
@@ -74,11 +74,14 @@ static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags,
{
struct ao *ao = ctx;
struct priv *p = ao->priv;
AudioBuffer buf = buffer_list->mBuffers[0];
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 += p->hw_latency_us + ca_get_latency(ts) + ca_frames_to_us(ao, frames);
ao_read_data(ao, &buf.mData, frames, end);
ao_read_data(ao, planes, frames, end);
return noErr;
}
@@ -121,8 +124,8 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
return CONTROL_UNKNOWN;
}
static bool init_chmap(struct ao *ao);
static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd);
static void init_physical_format(struct ao *ao);
static bool reinit_device(struct ao *ao) {
struct priv *p = ao->priv;
@@ -143,8 +146,10 @@ coreaudio_error:
static int init(struct ao *ao)
{
if (AF_FORMAT_IS_IEC61937(ao->format)) {
MP_WARN(ao, "detected IEC61937, redirecting to coreaudio_exclusive\n");
struct priv *p = ao->priv;
if (!af_fmt_is_pcm(ao->format) || p->exclusive) {
MP_VERBOSE(ao, "redirecting to coreaudio_exclusive\n");
ao->redirect = "coreaudio_exclusive";
return CONTROL_ERROR;
}
@@ -152,10 +157,11 @@ static int init(struct ao *ao)
if (!reinit_device(ao))
goto coreaudio_error;
if (!init_chmap(ao))
goto coreaudio_error;
if (p->change_physical_format)
init_physical_format(ao);
ao->format = af_fmt_from_planar(ao->format);
if (!ca_init_chmap(ao, p->device))
goto coreaudio_error;
AudioStreamBasicDescription asbd;
ca_fill_asbd(ao, &asbd);
@@ -169,95 +175,83 @@ coreaudio_error:
return CONTROL_ERROR;
}
static AudioChannelLayout* ca_query_layout(struct ao *ao, void *talloc_ctx)
static void init_physical_format(struct ao *ao)
{
struct priv *p = ao->priv;
OSStatus err;
uint32_t psize;
AudioChannelLayout *r = NULL;
OSErr err;
AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) {
.mSelector = kAudioDevicePropertyPreferredChannelLayout,
.mScope = kAudioDevicePropertyScopeOutput,
.mElement = kAudioObjectPropertyElementWildcard,
};
void *tmp = talloc_new(NULL);
err = AudioObjectGetPropertyDataSize(p->device, &p_addr, 0, NULL, &psize);
CHECK_CA_ERROR("could not get device preferred layout (size)");
AudioStreamBasicDescription asbd;
ca_fill_asbd(ao, &asbd);
r = talloc_size(talloc_ctx, psize);
AudioStreamID *streams;
size_t n_streams;
err = AudioObjectGetPropertyData(p->device, &p_addr, 0, NULL, &psize, r);
CHECK_CA_ERROR("could not get device preferred layout (get)");
err = CA_GET_ARY_O(p->device, kAudioDevicePropertyStreams,
&streams, &n_streams);
CHECK_CA_ERROR("could not get number of streams");
coreaudio_error:
return r;
}
talloc_steal(tmp, streams);
static AudioChannelLayout* ca_query_stereo_layout(struct ao *ao, void *talloc_ctx)
{
struct priv *p = ao->priv;
OSStatus err;
const int nch = 2;
uint32_t channels[nch];
AudioChannelLayout *r = NULL;
MP_VERBOSE(ao, "Found %zd substream(s).\n", n_streams);
AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) {
.mSelector = kAudioDevicePropertyPreferredChannelsForStereo,
.mScope = kAudioDevicePropertyScopeOutput,
.mElement = kAudioObjectPropertyElementWildcard,
};
for (int i = 0; i < n_streams; i++) {
AudioStreamRangedDescription *formats;
size_t n_formats;
uint32_t psize = sizeof(channels);
err = AudioObjectGetPropertyData(p->device, &p_addr, 0, NULL, &psize, channels);
CHECK_CA_ERROR("could not get device preferred stereo layout");
MP_VERBOSE(ao, "Looking at formats in substream %d...\n", i);
psize = sizeof(AudioChannelLayout) + nch * sizeof(AudioChannelDescription);
r = talloc_zero_size(talloc_ctx, psize);
r->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
r->mNumberChannelDescriptions = nch;
err = CA_GET_ARY(streams[i], kAudioStreamPropertyAvailablePhysicalFormats,
&formats, &n_formats);
AudioChannelDescription desc = {0};
desc.mChannelFlags = kAudioChannelFlags_AllOff;
if (!CHECK_CA_WARN("could not get number of stream formats"))
continue; // try next one
for(int i = 0; i < nch; i++) {
desc.mChannelLabel = channels[i];
r->mChannelDescriptions[i] = desc;
talloc_steal(tmp, formats);
uint32_t direction;
err = CA_GET(streams[i], kAudioStreamPropertyDirection, &direction);
CHECK_CA_ERROR("could not get stream direction");
if (direction != 0) {
MP_VERBOSE(ao, "Not an output stream.\n");
continue;
}
AudioStreamBasicDescription best_asbd = {0};
for (int j = 0; j < n_formats; j++) {
AudioStreamBasicDescription *stream_asbd = &formats[j].mFormat;
ca_print_asbd(ao, "- ", stream_asbd);
if (!best_asbd.mFormatID || ca_asbd_is_better(&asbd, &best_asbd,
stream_asbd))
best_asbd = *stream_asbd;
}
if (best_asbd.mFormatID) {
p->original_asbd_stream = streams[i];
err = CA_GET(p->original_asbd_stream,
kAudioStreamPropertyPhysicalFormat,
&p->original_asbd);
CHECK_CA_WARN("could not get current physical stream format");
if (ca_asbd_equals(&p->original_asbd, &best_asbd)) {
MP_VERBOSE(ao, "Requested format already set, not changing.\n");
p->original_asbd.mFormatID = 0;
break;
}
if (!ca_change_physical_format_sync(ao, streams[i], best_asbd))
p->original_asbd = (AudioStreamBasicDescription){0};
break;
}
}
coreaudio_error:
return r;
}
static bool init_chmap(struct ao *ao)
{
struct priv *p = ao->priv;
void *ta_ctx = talloc_new(NULL);
struct mp_chmap_sel chmap_sel = {.tmp = p};
struct mp_chmap chmap = {0};
AudioChannelLayout *ml = ca_query_layout(ao, ta_ctx);
if (ml && ca_layout_to_mp_chmap(ao, ml, &chmap))
mp_chmap_sel_add_map(&chmap_sel, &chmap);
AudioChannelLayout *sl = ca_query_stereo_layout(ao, ta_ctx);
if (sl && ca_layout_to_mp_chmap(ao, sl, &chmap))
mp_chmap_sel_add_map(&chmap_sel, &chmap);
talloc_free(ta_ctx);
if (!ao_chmap_sel_adjust(ao, &chmap_sel, &ao->channels)) {
MP_ERR(ao, "could not select a suitable channel map among the "
"hardware supported ones. Make sure to configure your "
"output device correctly in 'Audio MIDI Setup.app'\n");
goto coreaudio_error;
}
return true;
coreaudio_error:
return false;
talloc_free(tmp);
return;
}
static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd)
@@ -350,13 +344,23 @@ static void uninit(struct ao *ao)
AudioOutputUnitStop(p->audio_unit);
AudioUnitUninitialize(p->audio_unit);
AudioComponentInstanceDispose(p->audio_unit);
if (p->original_asbd.mFormatID) {
OSStatus err = CA_SET(p->original_asbd_stream,
kAudioStreamPropertyPhysicalFormat,
&p->original_asbd);
CHECK_CA_WARN("could not restore physical stream format");
}
}
static OSStatus hotplug_cb(AudioObjectID id, UInt32 naddr,
const AudioObjectPropertyAddress addr[],
void *ctx) {
reinit_device(ctx);
ao_hotplug_event(ctx);
void *ctx)
{
struct ao *ao = ctx;
MP_VERBOSE(ao, "Handling potential hotplug event...\n");
reinit_device(ao);
ao_hotplug_event(ao);
return noErr;
}
@@ -412,159 +416,6 @@ static void hotplug_uninit(struct ao *ao)
}
}
// Channel Mapping functions
static const int speaker_map[][2] = {
{ kAudioChannelLabel_Left, MP_SPEAKER_ID_FL },
{ kAudioChannelLabel_Right, MP_SPEAKER_ID_FR },
{ kAudioChannelLabel_Center, MP_SPEAKER_ID_FC },
{ kAudioChannelLabel_LFEScreen, MP_SPEAKER_ID_LFE },
{ kAudioChannelLabel_LeftSurround, MP_SPEAKER_ID_BL },
{ kAudioChannelLabel_RightSurround, MP_SPEAKER_ID_BR },
{ kAudioChannelLabel_LeftCenter, MP_SPEAKER_ID_FLC },
{ kAudioChannelLabel_RightCenter, MP_SPEAKER_ID_FRC },
{ kAudioChannelLabel_CenterSurround, MP_SPEAKER_ID_BC },
{ kAudioChannelLabel_LeftSurroundDirect, MP_SPEAKER_ID_SL },
{ kAudioChannelLabel_RightSurroundDirect, MP_SPEAKER_ID_SR },
{ kAudioChannelLabel_TopCenterSurround, MP_SPEAKER_ID_TC },
{ kAudioChannelLabel_VerticalHeightLeft, MP_SPEAKER_ID_TFL },
{ kAudioChannelLabel_VerticalHeightCenter, MP_SPEAKER_ID_TFC },
{ kAudioChannelLabel_VerticalHeightRight, MP_SPEAKER_ID_TFR },
{ kAudioChannelLabel_TopBackLeft, MP_SPEAKER_ID_TBL },
{ kAudioChannelLabel_TopBackCenter, MP_SPEAKER_ID_TBC },
{ kAudioChannelLabel_TopBackRight, MP_SPEAKER_ID_TBR },
// unofficial extensions
{ kAudioChannelLabel_RearSurroundLeft, MP_SPEAKER_ID_SDL },
{ kAudioChannelLabel_RearSurroundRight, MP_SPEAKER_ID_SDR },
{ kAudioChannelLabel_LeftWide, MP_SPEAKER_ID_WL },
{ kAudioChannelLabel_RightWide, MP_SPEAKER_ID_WR },
{ kAudioChannelLabel_LFE2, MP_SPEAKER_ID_LFE2 },
{ kAudioChannelLabel_HeadphonesLeft, MP_SPEAKER_ID_DL },
{ kAudioChannelLabel_HeadphonesRight, MP_SPEAKER_ID_DR },
{ kAudioChannelLabel_Unknown, MP_SPEAKER_ID_NA },
{ 0, -1 },
};
static 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)
return speaker_map[i][1];
return -1;
}
static void ca_log_layout(struct ao *ao, int l, AudioChannelLayout *layout)
{
if (!mp_msg_test(ao->log, l))
return;
AudioChannelDescription *descs = layout->mChannelDescriptions;
mp_msg(ao->log, l, "layout: tag: <%u>, bitmap: <%u>, "
"descriptions <%u>\n",
(unsigned) layout->mChannelLayoutTag,
(unsigned) layout->mChannelBitmap,
(unsigned) layout->mNumberChannelDescriptions);
for (int i = 0; i < layout->mNumberChannelDescriptions; i++) {
AudioChannelDescription d = descs[i];
mp_msg(ao->log, l, " - description %d: label <%u, %u>, "
" flags: <%u>, coords: <%f, %f, %f>\n", i,
(unsigned) d.mChannelLabel,
(unsigned) ca_label_to_mp_speaker_id(d.mChannelLabel),
(unsigned) d.mChannelFlags,
d.mCoordinates[0],
d.mCoordinates[1],
d.mCoordinates[2]);
}
}
static AudioChannelLayout *ca_layout_to_custom_layout(
struct ao *ao, void *talloc_ctx, AudioChannelLayout *l)
{
AudioChannelLayoutTag tag = l->mChannelLayoutTag;
AudioChannelLayout *r;
OSStatus err;
if (tag == kAudioChannelLayoutTag_UseChannelBitmap) {
uint32_t psize;
err = AudioFormatGetPropertyInfo(
kAudioFormatProperty_ChannelLayoutForBitmap,
sizeof(uint32_t), &l->mChannelBitmap, &psize);
CHECK_CA_ERROR("failed to convert channel bitmap to descriptions (info)");
r = talloc_size(NULL, psize);
err = AudioFormatGetProperty(
kAudioFormatProperty_ChannelLayoutForBitmap,
sizeof(uint32_t), &l->mChannelBitmap, &psize, r);
CHECK_CA_ERROR("failed to convert channel bitmap to descriptions (get)");
} else if (tag != kAudioChannelLayoutTag_UseChannelDescriptions) {
uint32_t psize;
err = AudioFormatGetPropertyInfo(
kAudioFormatProperty_ChannelLayoutForTag,
sizeof(AudioChannelLayoutTag), &l->mChannelLayoutTag, &psize);
r = talloc_size(NULL, psize);
CHECK_CA_ERROR("failed to convert channel tag to descriptions (info)");
err = AudioFormatGetProperty(
kAudioFormatProperty_ChannelLayoutForTag,
sizeof(AudioChannelLayoutTag), &l->mChannelLayoutTag, &psize, r);
CHECK_CA_ERROR("failed to convert channel tag to descriptions (get)");
} else {
r = l;
}
return r;
coreaudio_error:
return NULL;
}
bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
struct mp_chmap *chmap)
{
void *talloc_ctx = talloc_new(NULL);
MP_DBG(ao, "input channel layout:\n");
ca_log_layout(ao, MSGL_DEBUG, layout);
AudioChannelLayout *l = ca_layout_to_custom_layout(ao, talloc_ctx, layout);
if (!l)
goto coreaudio_error;
MP_VERBOSE(ao, "converted input channel layout:\n");
ca_log_layout(ao, MSGL_V, l);
if (l->mNumberChannelDescriptions > MP_NUM_CHANNELS) {
MP_VERBOSE(ao, "layout has too many descriptions (%u, max: %d)\n",
(unsigned) l->mNumberChannelDescriptions, MP_NUM_CHANNELS);
return false;
}
int next_na = MP_SPEAKER_ID_NA;
for (int n = 0; n < l->mNumberChannelDescriptions; n++) {
AudioChannelLabel label = l->mChannelDescriptions[n].mChannelLabel;
int speaker = ca_label_to_mp_speaker_id(label);
if (speaker < 0) {
MP_VERBOSE(ao, "channel label=%u unusable to build channel "
"bitmap, skipping layout\n", (unsigned) label);
goto coreaudio_error;
} else {
chmap->speaker[n] = speaker;
chmap->num = n + 1;
}
}
talloc_free(talloc_ctx);
return chmap->num > 0;
coreaudio_error:
MP_VERBOSE(ao, "converted input channel layout (failed):\n");
ca_log_layout(ao, MSGL_V, layout);
talloc_free(talloc_ctx);
return false;
}
#define OPT_BASE_STRUCT struct priv
const struct ao_driver audio_out_coreaudio = {
@@ -579,4 +430,9 @@ const struct ao_driver audio_out_coreaudio = {
.hotplug_uninit = hotplug_uninit,
.list_devs = ca_get_device_list,
.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}
},
};
+302
View File
@@ -0,0 +1,302 @@
/*
* 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 "common/common.h"
#include "ao_coreaudio_utils.h"
#include "ao_coreaudio_chmap.h"
static const int speaker_map[][2] = {
{ kAudioChannelLabel_Left, MP_SPEAKER_ID_FL },
{ kAudioChannelLabel_Right, MP_SPEAKER_ID_FR },
{ kAudioChannelLabel_Center, MP_SPEAKER_ID_FC },
{ kAudioChannelLabel_LFEScreen, MP_SPEAKER_ID_LFE },
{ kAudioChannelLabel_LeftSurround, MP_SPEAKER_ID_BL },
{ kAudioChannelLabel_RightSurround, MP_SPEAKER_ID_BR },
{ kAudioChannelLabel_LeftCenter, MP_SPEAKER_ID_FLC },
{ kAudioChannelLabel_RightCenter, MP_SPEAKER_ID_FRC },
{ kAudioChannelLabel_CenterSurround, MP_SPEAKER_ID_BC },
{ kAudioChannelLabel_LeftSurroundDirect, MP_SPEAKER_ID_SL },
{ kAudioChannelLabel_RightSurroundDirect, MP_SPEAKER_ID_SR },
{ kAudioChannelLabel_TopCenterSurround, MP_SPEAKER_ID_TC },
{ kAudioChannelLabel_VerticalHeightLeft, MP_SPEAKER_ID_TFL },
{ kAudioChannelLabel_VerticalHeightCenter, MP_SPEAKER_ID_TFC },
{ kAudioChannelLabel_VerticalHeightRight, MP_SPEAKER_ID_TFR },
{ kAudioChannelLabel_TopBackLeft, MP_SPEAKER_ID_TBL },
{ kAudioChannelLabel_TopBackCenter, MP_SPEAKER_ID_TBC },
{ kAudioChannelLabel_TopBackRight, MP_SPEAKER_ID_TBR },
// unofficial extensions
{ kAudioChannelLabel_RearSurroundLeft, MP_SPEAKER_ID_SDL },
{ kAudioChannelLabel_RearSurroundRight, MP_SPEAKER_ID_SDR },
{ kAudioChannelLabel_LeftWide, MP_SPEAKER_ID_WL },
{ kAudioChannelLabel_RightWide, MP_SPEAKER_ID_WR },
{ kAudioChannelLabel_LFE2, MP_SPEAKER_ID_LFE2 },
{ kAudioChannelLabel_HeadphonesLeft, MP_SPEAKER_ID_DL },
{ kAudioChannelLabel_HeadphonesRight, MP_SPEAKER_ID_DR },
{ kAudioChannelLabel_Unknown, MP_SPEAKER_ID_NA },
{ 0, -1 },
};
static 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)
return speaker_map[i][1];
return -1;
}
static void ca_log_layout(struct ao *ao, int l, AudioChannelLayout *layout)
{
if (!mp_msg_test(ao->log, l))
return;
AudioChannelDescription *descs = layout->mChannelDescriptions;
mp_msg(ao->log, l, "layout: tag: <%u>, bitmap: <%u>, "
"descriptions <%u>\n",
(unsigned) layout->mChannelLayoutTag,
(unsigned) layout->mChannelBitmap,
(unsigned) layout->mNumberChannelDescriptions);
for (int i = 0; i < layout->mNumberChannelDescriptions; i++) {
AudioChannelDescription d = descs[i];
mp_msg(ao->log, l, " - description %d: label <%u, %u>, "
" flags: <%u>, coords: <%f, %f, %f>\n", i,
(unsigned) d.mChannelLabel,
(unsigned) ca_label_to_mp_speaker_id(d.mChannelLabel),
(unsigned) d.mChannelFlags,
d.mCoordinates[0],
d.mCoordinates[1],
d.mCoordinates[2]);
}
}
static AudioChannelLayout *ca_layout_to_custom_layout(struct ao *ao,
void *talloc_ctx,
AudioChannelLayout *l)
{
AudioChannelLayoutTag tag = l->mChannelLayoutTag;
AudioChannelLayout *r;
OSStatus err;
if (tag == kAudioChannelLayoutTag_UseChannelDescriptions)
return l;
if (tag == kAudioChannelLayoutTag_UseChannelBitmap) {
uint32_t psize;
err = AudioFormatGetPropertyInfo(
kAudioFormatProperty_ChannelLayoutForBitmap,
sizeof(uint32_t), &l->mChannelBitmap, &psize);
CHECK_CA_ERROR("failed to convert channel bitmap to descriptions (info)");
r = talloc_size(NULL, psize);
err = AudioFormatGetProperty(
kAudioFormatProperty_ChannelLayoutForBitmap,
sizeof(uint32_t), &l->mChannelBitmap, &psize, r);
CHECK_CA_ERROR("failed to convert channel bitmap to descriptions (get)");
} else {
uint32_t psize;
err = AudioFormatGetPropertyInfo(
kAudioFormatProperty_ChannelLayoutForTag,
sizeof(AudioChannelLayoutTag), &l->mChannelLayoutTag, &psize);
r = talloc_size(NULL, psize);
CHECK_CA_ERROR("failed to convert channel tag to descriptions (info)");
err = AudioFormatGetProperty(
kAudioFormatProperty_ChannelLayoutForTag,
sizeof(AudioChannelLayoutTag), &l->mChannelLayoutTag, &psize, r);
CHECK_CA_ERROR("failed to convert channel tag to descriptions (get)");
}
MP_VERBOSE(ao, "converted input channel layout:\n");
ca_log_layout(ao, MSGL_V, l);
return r;
coreaudio_error:
return NULL;
}
static bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
struct mp_chmap *chmap)
{
void *talloc_ctx = talloc_new(NULL);
MP_VERBOSE(ao, "input channel layout:\n");
ca_log_layout(ao, MSGL_V, layout);
AudioChannelLayout *l = ca_layout_to_custom_layout(ao, talloc_ctx, layout);
if (!l)
goto coreaudio_error;
if (l->mNumberChannelDescriptions > MP_NUM_CHANNELS) {
MP_VERBOSE(ao, "layout has too many descriptions (%u, max: %d)\n",
(unsigned) l->mNumberChannelDescriptions, MP_NUM_CHANNELS);
return false;
}
chmap->num = l->mNumberChannelDescriptions;
for (int n = 0; n < l->mNumberChannelDescriptions; n++) {
AudioChannelLabel label = l->mChannelDescriptions[n].mChannelLabel;
int speaker = ca_label_to_mp_speaker_id(label);
if (speaker < 0) {
MP_VERBOSE(ao, "channel label=%u unusable to build channel "
"bitmap, skipping layout\n", (unsigned) label);
goto coreaudio_error;
}
chmap->speaker[n] = speaker;
}
talloc_free(talloc_ctx);
MP_VERBOSE(ao, "mp chmap: %s\n", mp_chmap_to_str(chmap));
return mp_chmap_is_valid(chmap) && !mp_chmap_is_unknown(chmap);
coreaudio_error:
MP_VERBOSE(ao, "converted input channel layout (failed):\n");
ca_log_layout(ao, MSGL_V, layout);
talloc_free(talloc_ctx);
return false;
}
static AudioChannelLayout* ca_query_layout(struct ao *ao,
AudioDeviceID device,
void *talloc_ctx)
{
OSStatus err;
uint32_t psize;
AudioChannelLayout *r = NULL;
AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) {
.mSelector = kAudioDevicePropertyPreferredChannelLayout,
.mScope = kAudioDevicePropertyScopeOutput,
.mElement = kAudioObjectPropertyElementWildcard,
};
err = AudioObjectGetPropertyDataSize(device, &p_addr, 0, NULL, &psize);
CHECK_CA_ERROR("could not get device preferred layout (size)");
r = talloc_size(talloc_ctx, psize);
err = AudioObjectGetPropertyData(device, &p_addr, 0, NULL, &psize, r);
CHECK_CA_ERROR("could not get device preferred layout (get)");
coreaudio_error:
return r;
}
static AudioChannelLayout* ca_query_stereo_layout(struct ao *ao,
AudioDeviceID device,
void *talloc_ctx)
{
OSStatus err;
const int nch = 2;
uint32_t channels[nch];
AudioChannelLayout *r = NULL;
AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) {
.mSelector = kAudioDevicePropertyPreferredChannelsForStereo,
.mScope = kAudioDevicePropertyScopeOutput,
.mElement = kAudioObjectPropertyElementWildcard,
};
uint32_t psize = sizeof(channels);
err = AudioObjectGetPropertyData(device, &p_addr, 0, NULL, &psize, channels);
CHECK_CA_ERROR("could not get device preferred stereo layout");
psize = sizeof(AudioChannelLayout) + nch * sizeof(AudioChannelDescription);
r = talloc_zero_size(talloc_ctx, psize);
r->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
r->mNumberChannelDescriptions = nch;
AudioChannelDescription desc = {0};
desc.mChannelFlags = kAudioChannelFlags_AllOff;
for(int i = 0; i < nch; i++) {
desc.mChannelLabel = channels[i];
r->mChannelDescriptions[i] = desc;
}
coreaudio_error:
return r;
}
static void ca_retrieve_layouts(struct ao *ao, struct mp_chmap_sel *s,
AudioDeviceID device)
{
void *ta_ctx = talloc_new(NULL);
struct mp_chmap chmap;
AudioChannelLayout *ml = ca_query_layout(ao, device, ta_ctx);
if (ml && ca_layout_to_mp_chmap(ao, ml, &chmap))
mp_chmap_sel_add_map(s, &chmap);
AudioChannelLayout *sl = ca_query_stereo_layout(ao, device, ta_ctx);
if (sl && ca_layout_to_mp_chmap(ao, sl, &chmap))
mp_chmap_sel_add_map(s, &chmap);
talloc_free(ta_ctx);
}
bool ca_init_chmap(struct ao *ao, AudioDeviceID device)
{
struct mp_chmap_sel chmap_sel = {0};
ca_retrieve_layouts(ao, &chmap_sel, device);
if (!chmap_sel.num_chmaps)
mp_chmap_sel_add_map(&chmap_sel, &(struct mp_chmap)MP_CHMAP_INIT_STEREO);
mp_chmap_sel_add_map(&chmap_sel, &(struct mp_chmap)MP_CHMAP_INIT_MONO);
if (!ao_chmap_sel_adjust(ao, &chmap_sel, &ao->channels)) {
MP_ERR(ao, "could not select a suitable channel map among the "
"hardware supported ones. Make sure to configure your "
"output device correctly in 'Audio MIDI Setup.app'\n");
return false;
}
return true;
}
void ca_get_active_chmap(struct ao *ao, AudioDeviceID device, int channel_count,
struct mp_chmap *out_map)
{
// Apparently, we have to guess by looking back at the supported layouts,
// and I haven't found a property that retrieves the actual currently
// active channel layout.
struct mp_chmap_sel chmap_sel = {0};
ca_retrieve_layouts(ao, &chmap_sel, device);
// Use any exact match.
for (int n = 0; n < chmap_sel.num_chmaps; n++) {
if (chmap_sel.chmaps[n].num == channel_count) {
MP_VERBOSE(ao, "mismatching channels - fallback #%d\n", n);
*out_map = chmap_sel.chmaps[n];
return;
}
}
// Fall back to stereo or mono, and fill the rest with silence. (We don't
// know what the device expects. We could use a larger default layout here,
// but let's not.)
mp_chmap_from_channels(out_map, MPMIN(2, channel_count));
out_map->num = channel_count;
for (int n = 2; n < out_map->num; n++)
out_map->speaker[n] = MP_SPEAKER_ID_NA;
MP_WARN(ao, "mismatching channels - falling back to %s\n",
mp_chmap_to_str(out_map));
}
Loaded 100 of 383 files, more files were not shown because too many files have changed in this diff. Show more