Compare commits

..
249 Commits
Author SHA1 Message Date
wm4 f1409ceacf Release 0.3.10 2014-05-24 16:54:54 +02:00
Yomi0 44f62ff6f3 tl_mpv_edl: correct misspelling on line 233
Closes #783

Signed-off-by: wm4 <wm4@nowhere>
2014-05-24 16:54:54 +02:00
wm4 55c3055784 vo_vdpau: always allocate the black pixel
black_pixel is an (apparently necessary) 1x1 black surface used for
clearing the screen. It was allocated in RGB mode only, but is sometimes
used in YUV mode too.
2014-05-24 16:54:54 +02:00
Jerome Leclanche 58fbe50d68 x11: fix a warning with --disable-xext
Signed-off-by: wm4 <wm4@nowhere>
2014-05-24 16:45:00 +02:00
wm4 6a0036ea03 build: "tv-v4l2" needs "tv"
Fixes #795.
2014-05-24 16:44:55 +02:00
wm4 2e4fdf01f5 vo_vaapi: don't redraw twice
After VOCTRL_REDRAW_FRAME, flip_page is called, which renders the frame.
The current code rendered the frame twice; drop the redundant call.
2014-05-24 16:44:44 +02:00
Juan Francisco Cantero Hurtado a2259b3fd3 Fix the build on OpenBSD and FreeBSD
Without this change, the compiler uses by default the "talloc.h" file
installed by the package libtalloc within /usr/local/include. Found and
tested on OpenBSD but FreeBSD has the same patch on its ports tree.
2014-05-24 16:44:40 +02:00
wm4 aeeb7a92f2 README: describe release cycle 2014-05-24 16:43:28 +02:00
Alexander Preisinger 1e2f3191a7 wayland: fix typo
So long in the code without me noticing. Embarassing!
2014-05-24 16:41:00 +02:00
wm4 51d030308e build: fix OpenBSD DVD/CDROM device names
Closes #781.
2014-05-24 16:40:42 +02:00
wm4 4cd8aab84f manpage: update --playlist entry 2014-05-24 16:40:19 +02:00
wm4 3795154155 player: don't assign "false" to pointer
This is legal in theory. "false" expand to 0, and 0 is a valid pointer
value. But I guess this was not really intended.

Found by cppcheck.
2014-05-24 16:39:52 +02:00
wm4 461198e149 build: removed undefined behavior from PVR check
This shouldn't matter, but it's probably better if the code to check is
valid - otherwise an extremely clever compiler might fail to compile it,
and the feature would be misdetected. (Probably.)

Found by cppcheck.
2014-05-24 16:39:46 +02:00
wm4 7b1f12adba player: don't complain on too long filenames
mpv supports per-file config files, basically filename+".conf". We use
a static buffer for the new filename, and if that buffer is too small,
we print a warning. This is confusing for e.g. long URLs, so just hide
the warning by default.

Why not dynamically allocate the buffer? Who cares.
2014-05-24 16:39:27 +02:00
wm4 cf1645aebb old-makefile: add a missing source directory
Fixes "make clean".
2014-05-24 16:39:21 +02:00
wm4 1b20ec4864 x11: fix potentially unaligned access in icon loader
Tried to load a 32 bit value by dereferencing a uint32_t pointer, but
the pointer is not guaranteed to be aligned, not even in practice.
2014-05-24 16:39:12 +02:00
wm4 ee529da760 sub: fix undefined behavior in ASS color calculation (2)
Same problem as previous commit, fix by using the MP_ASS_RGBA() macro.
2014-05-24 16:39:09 +02:00
wm4 c9e6e7cc04 sub: fix undefined behavior in ASS color calculation
This might shift bits into the sign, which is undefined behavior. Making
the right operand unsigned was supposed to help with this, but it seems
it did nothing, and C99 makes the result type dependent on the left
operand only.
2014-05-24 16:39:06 +02:00
wm4 cb1d1e7a62 Fix bogus copyright text
This file was copied from gl_hwdec_vaglx.c to have a basic skeleton, but
no actual code is left from it.
2014-05-24 16:32:23 +02:00
wm4 e6d4ec62ae mixer: don't restore volume with different --softvol-max settings
Changing --softvol-max and then resuming would change the volume level
on resume to something different than the original volume. This is
because the user volume setting is always between 0-100, and 100
corresponds to --softvol-max gain.

Avoid that changing -softvol-max and resuming an older file could lead
to a too loud volume level by refusing to restore if --softvol-max
changed.
2014-05-24 16:32:00 +02:00
wm4 e7e2a6c8f7 demux_lavf: one more hack for mp3 from network
mp3 has a hack lowering the probescore for format detection. This is
because detecting mp3s is hard due to their nature, and the fact that
ID3v2 tags are sometimes several megabytes big.

When playing mp3 from network, the mime-type is usually set, and that
matches the format hack entry meant for webradios, overriding the normal
mp3 entry. This can lead to network mp3s not being detected. Lower the
network case to the same probescore as on-disk mp3s. The difference is
that for network mp3s, we don't load the full probe-buffer, and we lower
the amount of audio the demuxer will read to collect data on opening
(0.5 seconds instead of typically 5 seconds).
2014-05-24 16:29:46 +02:00
wm4 6643ebaa28 manpage: fix vf_scale options 2014-05-24 16:29:11 +02:00
wm4 98d33db5da input: fix stack overflow when checking for abort cmd
This can happen when the input stream is somehow blocking on network,
and the user still send input in one way or another, and one of the
commands is a compound command ("cmd a ; cmd b").
2014-05-24 16:28:11 +02:00
wm4 ca8dc9147b Release 0.3.9 2014-04-30 11:47:07 +02:00
wm4 df8b99490c demux: add hack to get initial ICY info to be printed
Newly added metadata (such as the ICY title, sent some seconds after
opening the stream) simply wasn't printed.

This problem doesn't exist in git master.

Fixes #753.
2014-04-30 11:46:40 +02:00
wm4 c78142a973 TOOLS/umpv: make it work with Python 3 (again)
Apparently, the 3rd (2nd) parameter to string.translate() function was
removed.

Also, make_abs() had a mistake - not sure how this passed testing.
2014-04-30 11:45:32 +02:00
wm4 a8e6caf56b TOOLS/umpv: don't mangle URLs
This attempted to prefix the current directory to URLs, because it
didn't recognize them as already absolute paths.
2014-04-30 11:45:32 +02:00
wm4 e6cca1e43b TOOLS/umpv: allow passing 0 files
Some might use that to just create an empty window with --force-window
--idle (for whatever reasons).
2014-04-30 11:45:32 +02:00
wm4 d7538d3597 TOOLS/umpv: allow passing options
But only via a special environment variable.
2014-04-30 11:45:32 +02:00
wm4 f3eb5b143c TOOLS/umpv: make it work with Python 3
Apparently they removed octal literals, and made them invalid syntax.
2014-04-30 11:45:32 +02:00
Stefano Pigozzi 9993fd8888 build: use -pthread when available
Our code currently tries to link -lpthread and adds stuff like -D_REENTRANT
based on the target platform.

GCC actually supports to just pass a -pthread compiler and linker flag that
will automatically enable threading and define the correct symbols for the
platform, so let's try to just use that as our first choice.

clang also supports -pthread but it must be used only as a compiler flag,
so we also take care of that scenario with this commit.
2014-04-30 11:45:31 +02:00
wm4 d9c3a51d87 terminal: always use SA_RESTART with sigaction()
One problem is that for example stdio functions won't restart syscalls
manually, and instead treat EINTR as an error. So passing SA_RESTART is
the only sane thing to do, unless you have special requirements, which
we don't.
2014-04-30 11:45:31 +02:00
wm4 619fa761af demux_mkv: enable parsing for VP9
VP9 packets can contain 2 frames in some video packets (from which 1
frame is invisible). Due to a design mismatch between libvpx and the
libavcodec vp9 decoder, libvpx can take the "full" packets, but lavc vp9
can not. The consequence is that we have to split the packets if we want
to feed them to the lavc codec.

This is not entirely correct yet: timestamp handling is missing.
--demuxer=lavf and ffmpeg native utilities have the same problem. We can
fix this only once the ffmpeg VP9 parser is fixed.
2014-04-30 11:45:31 +02:00
wm4 717d729dcb osd: make code C99
This used an unnamed union, which is allowed in GNU C and C11, but not
C99. This broke the build with some older compilers.

Replaces pull request #744.
2014-04-30 11:45:31 +02:00
Alexander Preisinger 4eb5b62e5a Revert "wayland: print waylands display erros"
This reverts commit 6e34b0ec1f.

There has always been an error message "proxy already has a listener" and
I couldn't reproduce where it is comming from until now. The display interface
already has a listener and we can't overwrite it. Now remove the code and avoid
this error message.

Conflicts:
	video/out/wayland_common.c
2014-04-30 11:45:31 +02:00
wm4 b9e32d0d3d manpage: fix grammar 2014-04-30 11:45:31 +02:00
wm4 28e2b95f58 manpage: forced->used 2014-04-30 11:45:31 +02:00
wm4 491f633a20 stream: use uninterruptible sleep on reconnecting
This is the only function which actually used the time argument of
stream_check_interrupt(). Considering that the whole player freezes
anyway, this is not worth the complication.

Also generally reduce the maximum wait time due to timeout. Introduce
exponential backoff, which makes the first reconnect retries faster, but
still waits up to 500ms in the later retries.
2014-04-30 11:45:31 +02:00
wm4 eb5e45855a manpage: improve --osd-level description 2014-04-30 11:45:31 +02:00
wm4 59e55bb0e1 demux_mkv: enable parsing for mp3
For some reason, some files appear to have broken mp3 packets, or at
least in a form that libavcodec can't deal with. The audio in the sample
file in question could not be decoded using libavcodec.

The problematic file had variable packet sizes, and the libavcodec
decoder kept printing "mp3: Header missing" for each packet it was fed.
Remuxing with mkvmerge fixes the problem. The mp3 data is probably not
VBR, and remuxing resulted in fixed-size mp3 frames. So I don't know why
the sample file was muxed this way - it might just be incorrect.

The sample file had "libmkv 0.6.4" as MuxingApp (although I could not
get mkvinfo to print this element, maybe the file uses an incorrect
element ID), and "HandBrake 0.9.4" as WritingApp.

Note that the libmpg123 decoder does not have any issues with it. It's
probably more robust, because libmpg123 was made to decode whole mp3
files, not just single frames.

Fixes issue #742.
2014-04-30 11:45:31 +02:00
Stefano Pigozzi 9f46be7373 ao_coreaudio: log even more info in verbose mode
This logs more info that can be used for debugging purposes, in particular
it prints all the AudioChannelDescription in the descriptions array.
2014-04-30 11:45:31 +02:00
Stefano Pigozzi 3623fb38ee ao_coreaudio: add verbose output of detected channel layouts
This can be useful for debugging purposes.
2014-04-30 11:45:31 +02:00
wm4 1ad9e322e3 cache: remove redundant log prefix 2014-04-30 11:45:31 +02:00
Kevin Mitchell cad63810c5 man: minor typo why not to use portaudio 2014-04-30 11:45:31 +02:00
wm4 da17c64c76 vf: remove autoinserted filters on reconfig
When using rotation with hw decoding, and the VO does not support
rotation, vf_rotate is attempted to be inserted. This will go wrong, and
after that it can't recover because a vf_scale filter was autoinserted.
Just removing all autoinserted filters before reconfig fixes this.
2014-04-30 11:45:31 +02:00
wm4 57f32f7ca8 vf: add function to remove a filter from the chain 2014-04-30 11:45:31 +02:00
wm4 3d85137495 encode: don't resume playback when encoding
The previous commit doesn't handle additionally loaded config files,
such as the playback resume mechanism.
2014-04-30 11:45:31 +02:00
wm4 4aff0076a0 manpage: add notes when to use/not use certain AO and VO drivers
Conflicts:
	DOCS/man/en/vo.rst
2014-04-30 11:45:31 +02:00
James Ross-Gowan 70f8ea228d encode: disable keep-open when encoding 2014-04-30 11:45:31 +02:00
wm4 3196f4cdd7 audio: preallocate audio buffers on resize
This avoids too many realloc() calls if the caller is appending to an
audo buffer. This case is actually quite noticeable when using something
that buffers a large amount of audio.
2014-04-30 11:45:31 +02:00
wm4 4fa0853c34 Release 0.3.8 2014-04-17 22:58:58 +02:00
wm4 6598b55c35 af_lavcac3enc: detach on any passthrough format, not just ac3 2014-04-17 22:58:48 +02:00
wm4 848d7979e5 README: mention minimum FFmpeg/Libav versions 2014-04-17 22:58:48 +02:00
Kevin Mitchell 13301daf6a talloc README: more human readible api reference 2014-04-17 22:58:48 +02:00
Ricardo Vieira 763a38f889 wayland: don't schedule resize if going fullscreen
mpv was resizing to the same size before it went to fullscreen, we don't need to schedule a resize because the compositor will send a configure event with the new dimensions and thats when we should do it.
2014-04-17 22:58:48 +02:00
James Ross-Gowan ed1e4de452 manpage: fix --vf=scale options 2014-04-17 22:58:48 +02:00
wm4 0e2fe55fde encode: write 2-pass stats only per-packet
The stats were retrieved and written on every encode call, instead of
every encode call that actually returned a packet. ffmpeg.c also does it
this way, so it must be "more correct". Fixes 2-pass encoding.
2014-04-17 22:58:48 +02:00
wm4 22cfb48b52 encode: add a missing \n to a log call
Conflicts:
	audio/out/ao_lavc.c
2014-04-17 22:58:48 +02:00
wm4 4a07120f83 terminal-unix: reject overlong termcap strings
Our own tables have size for only 8 chars, so these sequences must be
rejected. It seems strings of length 8 are still ok, because the code
uses memcmp and not strcmp, so still allow these.

Based on mplayer-svn commit r37129.
2014-04-17 22:58:48 +02:00
wm4 d06ff691ed vo_vdpau: add an additional check for timestamp robustness
This might be a good idea in order to prevent queuing a frame too far in
the future (causing apparent freezing of the video display), or dropping
an infinite number of frames (also apparent as freezing).

I think at this point this is most of what we can do if the vdpau time
source is unreliable (like with Mesa). There are still inherent race
conditions which can't be fixed.
2014-04-17 22:58:48 +02:00
wm4 34cee2a77d vo_vdpau: document what WRAP_ADD does
This wasn't necessarily clear.
2014-04-17 22:58:47 +02:00
wm4 8f5eb7b780 vo_vdpau: simplify previous vsync timestamp calculation
The strange thing about this code was the shift parameter of the
prev_vs2 function. The parameter is used to handle timestamps before the
last vsync, since the % operator handles negative values incorrectly.
Most callers set shift to 0, and _usually_ pass a timestamp after the
last vsync. One caller sets it to 16, and can pass a timestamp before
the last timestamp.

The mystery is why prev_vs2 doesn't just compensate for the % operator
semantics in the most simple way: if the result of the operator is
negative, add the divisor to it. Instead, it adds a huge value to it
(how huge is influenced by shift). If shift is 0, the result of the
function will not be aligned to vsyncs.

I have no idea why it was written in this way. Were there concerns about
certain numeric overflows that could happen in the calculations? But I
can't think of any (the difference between ts and vc->recent_vsync_time
is usually not that huge). Or is there something more clever about it,
which is important for the timing code? I can't think of anything
either.

So scrap it and simplify it.
2014-04-17 22:58:47 +02:00
wm4 b991c072f6 vo_vdpau: simplify time management and make it more robust
vo_vdpau used a somewhat complicated and fragile mechanism to convert
the vdpau time to internal mpv time. This was fragile as in it couldn't
deal well with Mesa's (apparently) random timestamps, which can change
the base offset in multiple situations. It can happen when moving the
mpv window to a different screen, and somehow it also happens when
pausing the player.

It seems this mechanism to synchronize the vdpau time is not actually
needed. There are only 2 places where sync_vdptime() is used (i.e.
returning the current vdpau time interpolated by system time).

The first call is for determining the PTS used to queue a frame. This
also uses convert_to_vdptime(). It's easily replaced by querying the
time directly, and adding the wait time to it (rel_pts_ns in the patch).

The second call is pretty odd: it updates the vdpau time a second time
in the same function. From what I can see, this can matter only if
update_presentation_queue_status() is very slow. I'm not sure what to
make out of this, because the call merely queries the presentation
queue. Just assume it isn't slow, and that we don't have to update the
time.

Another potential issue with this is that we call VdpPresentationQueueGetTime()
every frame now, instead of every 5 seconds and interpolating the other
calls via system time. More over, this is per video frame (which can be
portantially dropped, and not per actually displayed frame. Assume this
doesn't matter.

This simplifies the code, and should make it more robust on Mesa. But
note that what Mesa does is obviously insane - this is one situation
where you really need a stable time source. There are still plenty of
race condition windows where things can go wrong, although this commit
should drastically reduce the possibility of this.

In my tests, everything worked well. But I have no access to a Mesa
system with vdpau, so it needs testing by others.

See github issues #520, #694, #695.
2014-04-17 22:58:47 +02:00
wm4 3c2777994b vo_vdpau: more debugging output
Might help to debug certain problems with Mesa.
2014-04-17 22:58:47 +02:00
Kevin Mitchell 80741f27f3 remove redundant/outdated line from encodeing.rst:"what works" 2014-04-17 22:58:47 +02:00
wm4 3d18ab77b3 DOCS/encoding: make "What does not work yet" a proper RST section 2014-04-17 22:58:47 +02:00
wm4 8d2baaa318 ass_mp: don't use --subcp for --ass-styles
The --ass-styles option is implemented by calling ass_read_styles().
This function can take a codepage (so libass will use iconv to convert
it). This was implemented before our --subcp option was changed, and
this code was not updated. Now libass fails opening iconv, because
--subcp is not always (and not by default) a valid iconv codepage.

Just always pass NULL, which means the file passed to --ass-styles must
be in UTF-8. The --ass-styles option is a fringe option anyway (and will
destroy your subtitles), so having codepage support for it isn't
important at all.
2014-04-17 22:58:46 +02:00
wm4 2758bc462d Release 0.3.7 2014-03-30 17:56:54 +02:00
wm4 2687b43dd0 vf_eq: don't malloc priv struct
There wasn't any reason for this. In fact, it's a memory leak. The
proper priv struct is already allocated vf.c and the option parser.
2014-03-30 17:55:12 +02:00
Sebastian Morr bb40daf367 player: add missing "-" to options in workaround notice on A/V desynchronization
While it technically works, using GNU-style options seems cleaner nowadays.

Signed-off-by: wm4 <wm4@nowhere>
2014-03-30 17:55:07 +02:00
wm4 cc1f926441 player: dvdnav: fix start time when entering and leaving menu
Unfortunately, quite a hack, because we have check the nav state
outside of discnav.c.
2014-03-30 17:54:50 +02:00
wm4 67f653324a mf: fix operation with --cache
demux_mf.c explicitly checks for the stream type to check whether images
are opened via pattern (mf://..., i.e. stream_mf.c) or directly. Of
course the stream type is not set to STREAMTYPE_MF if the stream is
wrapped through the cache, so it tried to open the pattern directly as
file, which failed.

Fix this by disabling caching for mf://. The cache doesn't make sense
here anyway, because each file is opened and closed every frame (perhaps
to avoid memory bloat).
2014-03-30 17:54:33 +02:00
wm4 6e2c29b786 player: fix unchecked access for chapter metadata
It's possible that MPContext has a chapter list, but the demuxer
doesn't. In this case, accesing the chapter-metadata property would
lead to invalid accesses.

(This fixes the out of bound access, but in theory, the returned data
can still be incorrect, since MPContext chapters don't need to map
directly to demuxer chapters.)
2014-03-30 17:54:30 +02:00
wm4 e565217f22 stream_cdda: print cd text header only if there are any cd text fields 2014-03-30 17:54:18 +02:00
wm4 144c67efaf stream_cdda: remove unused stuff
This cd_info_t struct was practically unused. The only thing it did was
storing the track name of the form "Track %d" in a very roundabout way.
Remove it. (It made more sense when there was still CDDB support.)
2014-03-30 17:54:15 +02:00
wm4 96d7e80ddf stream_cdda: fix track time accuracy
Don't use an integer division to get the time, since that would round on
second boundaries. Also round up the time by sector size. Seeking rounds
down due to alignment constraints, but if we round up the time, we can
make it land on the exact destination sector.

This fixes that the track change code printed the previous track when
seeking by chapter.
2014-03-30 17:54:10 +02:00
wm4 dde72c5c54 stream_cdda: report track times
Report the time for each chapter (tracks are treated as chapters). This
allows us to get rid of the "old" chapter mechanism, and also behaves
better with the frontend.

This makes assumptions about the audio formats, but that format is
hardcoded anyway in the rawaudio demuxer defaults (and always was).
2014-03-30 17:54:05 +02:00
wm4 577d03da0c dvdnav: fix minor memory leak
This was usually handled at the end of the switch statement, so if
something returns from the function before that, the event has to be
freed explicitly.
2014-03-30 17:53:46 +02:00
xylosper fc510f0da8 dvdnav: make MP_NAV_EVENT_RESET_ALL handled properly
dvdnav.c did not handle event in regular sequence. Usually this
does not make any trouble except around MP_NAV_EVENT_RESET_ALL.
Those events should be handled in regular sequence. If they're
mixed, it can make wrong result.
For instance, MP_NAV_EVENT_HIGHLIGHT right after
MP_NAV_EVENT_RESET_ALL should not be ignored but it might be
because MP_NAV_EVENT_RESET_ALL makes the demuxer reloaded and osd
hidden.
2014-03-30 17:53:05 +02:00
xylosper 8d5775a8d2 dvdnav: prevent reallocation of fake highlight buffer
Since subsizes were never updated, the bitmap buffer was always
reallocated whenever mp_nav_get_highlight() called.
2014-03-30 17:52:43 +02:00
xylosper cf8ff2fd87 stream_bluray: fix for significant memory leak
It's obvious but, since STREAM_CTRL_GET_TIME_LENGTH is called
frequently, the amount of leaked memory here is quite big.
2014-03-30 17:51:45 +02:00
wm4 852c924a60 manpage: clarify what to pass to --hwdec-codecs option 2014-03-30 17:51:28 +02:00
wm4 1685d198b9 vd_lavc: ridiculous workaround for Libav 9 compatibility
This "sometimes" crashed when seeking. The fault apparently lies in
libavcodec: the decoder returns an unreferenced frame! This is
completely insane, but somehow I'm apparently still expected to
work this around. As a reaction, I will drop Libav 9 support in the
next commit. (While this commit will go into release/0.3.)
2014-03-30 17:50:11 +02:00
wm4 1e2d28f567 DOCS/coding-style: add another requirement for commit messages 2014-03-30 17:50:02 +02:00
wm4 89973ebca1 options: fix off-by-1 error in option help output 2014-03-30 17:49:57 +02:00
wm4 3f4e528f73 manpage: af: minor syntax improvements
Conflicts:
	DOCS/man/en/af.rst
2014-03-30 17:49:19 +02:00
Ryan Goulden 6f7c9f516e build: fix unicode handling of the version string
Don't pass unicode types to waf ENV.
As per https://code.google.com/p/waf/issues/detail?id=1420
This directly fixes the "CFVersion" key in the .app bundle plist.
2014-03-30 17:47:57 +02:00
James Ross-Gowan 33e0074603 player/main: Fix Cygwin build
Xlib.h (included from x11_common.h) defines a macro 'Status' as 'int'.
This messed up a bunch of definitions in windows.h and broke the build
in Cygwin. Including windows.h first seems to solve the problem.

This commit also removes the definition of an unused flag.

Conflicts:
	player/main.c
2014-03-30 17:47:44 +02:00
wm4 b6ed94fa7c DOCS/coding-style: add an example and another rule 2014-03-30 17:42:40 +02:00
wm4 a419703549 README: split list of dependencies
And make some additions.

I'm not really sure why we list dependencies that are not ours, but that
of external libraries. Still might be useful, though.
2014-03-30 17:42:30 +02:00
wm4 5171da86e3 DOCS: add coding style
I've tried not to be too detailed (because it's not a reference, just
some guidelines), but it still got relatively long. Also contains
conventions for sending patches.
2014-03-30 17:42:11 +02:00
James Ross-Gowan 7bd670949c w32_common: prevent MOUSE_BTN0 sticking after drag
The window doesn't recieve a WM_LBUTTONUP message after it's dragged,
probably because it's swallowed by the modal loop. To stop the button
from sticking, release it manually when the drag is complete.
2014-03-30 17:42:07 +02:00
James Ross-Gowan 421b2be348 w32_common: capture mouse input
Mouse buttons can get stuck down if the button is pressed inside the
video window and released outside. Avoid this by capturing mouse input
when a button is pressed.
2014-03-30 17:42:02 +02:00
Diogo Franco b659476ed9 options.rst: correct broken URL 2014-03-30 17:39:31 +02:00
wm4 689c3f47a8 Release 0.3.6 2014-03-11 00:23:11 +01:00
wm4 677d4615ba Revert "player: simplify audio reset when seeking"
This reverts commit 75dd3ec210.

This broke seeking with ordered chapters in some situations. While
the reverted commit was perfectly fine for playback of normal files,
it overlooked that in the ordered chapters case switching segments
actually reinitialized the audio chain completely, including the
decoder. And decoders still read packets on initialization. We can
restore the original commit as soon as decoders stop doing this.
2014-03-11 00:22:33 +01:00
wm4 5f788a7812 ao_alsa: fix return value for volume operations with spdif
This AO pretended to support volume operations when in spdif passthrough
mode, but actually did nothing. This is wrong: at least the GET
operations must write their argument. Signal that volume is unsupported
instead.

This was probably a hack to prevent insertion of volume filters or so,
but it didn't work anyway, while recovering after failed volume filter
insertion does work, so this is not needed at all.
2014-03-11 00:21:45 +01:00
foo86 dba25e13c0 ao_alsa: check ALSA PCM state before pause and resume
It is possible to have ao->reset() called between ao->pause() and
ao->resume() when seeking during the pause. If the underlying PCM
supports pausing, resuming an already reset PCM will produce an error.
Avoid that by explicitly checking PCM state before calling
snd_pcm_pause().

Signed-off-by: wm4 <wm4@nowhere>
2014-03-11 00:21:32 +01:00
Hans-Kristian Arntzen 623b97e45a ao_rsound: pass correct data type to rsd_set_param()
Signed-off-by: wm4 <wm4@nowhere>
2014-03-11 00:20:56 +01:00
Hans-Kristian Arntzen 7a645ba62f build: fix compilation with MinGW-w64
References to WinMM/OLE/UUID were missing.

Signed-off-by: wm4 <wm4@nowhere>
2014-03-11 00:20:53 +01:00
wm4 63afe3eb98 lua: add license header
Oops.
2014-03-11 00:20:26 +01:00
wm4 72c70eb05b ao_jack: fix termination on the end of file
The player didn't quit when the end of a file was reached. The reason
for this is that jack reported a constant audio delay even when all
audio was done playing. Whether that was recognized as EOF by the player
depended whether the exact value was higher or lower than the player's
threshhold for what it considers no more audio.

get_delay() should return amount of time it takes until the last sample
written to the audio buffer reaches the speaker. Therefore, we have to
track the estimated time when the last sample is done, and subtract it
from the calculated latency. Basically, the latency is the only amount
of time left in the delay, and it should go towards 0 as audio reaches
ths speakers.

I'm not sure if this is correct, but at least it solves the problem. One
suspicious thing is that we use system time to estimate the end of the
audio time. Maybe using jack_frame_time() would be more correct. But
apart from this, there doesn't seem to be a better way to handle this.
2014-03-11 00:19:56 +01:00
wm4 df0ec55499 build: update waf
<lachs0r> it fixes issues with recent python3
2014-03-11 00:19:43 +01:00
wm4 542bcdfc9d command: fix null pointer dereference in idle mode
Pressing 'h' in idle mode -> crash.
2014-03-11 00:19:26 +01:00
Andrey Morozov 218667b5a2 vdpau: change the error message when video too large 2014-03-11 00:16:46 +01:00
wm4 13a0e34aec example.conf: change subtitle codepage example to use UTF-8 fallback
This should be pretty safe compared to forcing the codepage.
2014-03-11 00:16:20 +01:00
Yaser Alraddadi 76b7a1a713 example.conf: subtitle encoding
Signed-off-by: wm4 <wm4@nowhere>

Closes #580.
2014-03-11 00:16:18 +01:00
wm4 6d6eee2e70 manpage: fix yadif example in one case 2014-03-11 00:15:53 +01:00
wm4 89f20cd2f3 input: check for abort cmd in multi-commands
MP_CMD_COMMAND_LIST commands (used to implement key bindings with
multiple commands) were not checked for abort commands. Implement it.

Remove the remarks about multi-commands being special from the manpage.
Seek coalescing is handled differently now, and the issue with abort
commands is fixed with this commit.
2014-03-11 00:14:30 +01:00
James Ross-Gowan cce2b675ac input: ignore modifiers when releasing keys
This prevents keys from getting stuck if the modifier is released before
the base key.
2014-03-11 00:14:22 +01:00
wm4 c1ed4dc242 video: add rounding to aspect ratio calculations
Small errors are unavoidable, but truncation can cause anamorphic video
to be off by 1 or 2 pixels.
2014-03-11 00:13:57 +01:00
wm4 712657a894 player: fix start time if timeline is used (ordered chapters, EDL)
When timeline was used, and the --start option was not used, the initial
seek (needed to switch to the first timeline segment) seeked to -1 due
to an oversight.

Conflicts:
	player/loadfile.c
2014-03-11 00:13:39 +01:00
wm4 496956de3d edl: fix offset of user-visible chapters
Basically, chapter marks and chapter seek-points were incorrect, while
the rest worked.
2014-03-11 00:12:25 +01:00
James Ross-Gowan 483e703793 w32_common: don't set small icon
Windows will automatically choose the correct icon size if this field is
unset.
2014-03-11 00:12:00 +01:00
elevengu 717cdeb95d win32: restore support for exe directory as config directory
Same rationale as b2c2fe7a but updated to work with path-win.c

Signed-off-by: wm4 <wm4@nowhere>

Merges/closes #543.
2014-03-11 00:10:20 +01:00
wm4 315f3a9218 crosscompile-mingw: improve instructions for MXE 2014-03-11 00:10:17 +01:00
xylosper d857722618 sd_lavc: handle subtitles with no subtitle resolution set
Set subtitle resolution to video resolution when avctx->width and
avctx->height are zero.

This can happen with broken vobsubs that have no size set in their
.idx file (or Matroska extradata). At least with the test file provided
in issue #551, using the video resolution as fallback instead of what
guess_resolution() does is better.

Note that these files clearly are broken. It seems this particular
file was created by trying to use ffmpeg to transcode DVB subtitles
to vobsub, and ffmpeg "forgot" to set the subtitle resolution in the
destination file. On the other hand, ffmpeg DVB and PGS decoders set
the resolution on the first subtitle packet (or somewhere close), so
it's not really clear what to do here.

Closes #551.

Signed-off-by: wm4 <wm4@nowhere>

Patch by xylosper, rewritten commit message by wm4.
2014-03-11 00:09:52 +01:00
Diogo Franco (Kovensky) 6d9d597b10 Parse::Matroska::Reader: get rid of bigrat
It seems that it was causing issues with certain perl setups (such as
the one on issue #549). It also turns out that it was not behaving correctly
(not all constants were being promoted to big nums as they should), so we
use explicit objects to derive the constants.

There were also precedence issues. I wonder if this even worked right to
begin with.

The 'double' path (8-byte floats) is untested, as I couldn't easily find
a file with such a field.

Closes #549.
2014-03-11 00:08:57 +01:00
Diogo Franco (Kovensky) c4d905b567 build: Add -U__STRICT_ANSI__ to CFLAGS on Cygwin
Cygwin's libc (newlib) doesn't obey a lot of unix feature test macros,
including _GNU_SOURCE; as a result, a lot of functions and defines get
masked out -- important defines such as M_PI and strcasecmp. Work around
it by undefining __STRICT_ANSI__ on cygwin systems.

This will still cause compilation issues on any non-cygwin system that
uses newlib, but hopefully nobody does that, or if they do, they will
find this commit message and know to add -U__STRICT_ANSI__ to their
CFLAGS. Hopefully.
2014-03-11 00:08:53 +01:00
wm4 e4c69376fc sub: handle vobsub-in-mp4
The mplayer decoder (spudec.c) actually handled this. There was explicit
code for binary palettes (16 32 bit values), and the subtitle resolution
was handled by video resolution coincidentally matching the subtitle
resolution.

Whoever puts vobsub into mp4 should be punished.

Fixes the sample gundam_sample.mp4, closes github issue #547.
2014-03-11 00:08:29 +01:00
wm4 842689bbf6 sd_lavc: use mp_lavc_set_extradata()
This includes the magical input padding required by libavcodec, which we
possibly didn't do before this commit.
2014-03-11 00:07:57 +01:00
wm4 5ab2aa84e0 Factor out setting AVCodecContext extradata 2014-03-11 00:07:51 +01:00
Stefano Pigozzi 229d398ba9 cocoa: fix deadlock during initialization [2]
Fixup commit for 20fa191ad.
2014-03-11 00:04:15 +01:00
wm4 5f1b155307 build: bump libmpg123 version
The minimum required version was bumped in the old configure script, but
for the waf build system is was somehow forgotten or overlooked.
Probably happened while the waf build system was developed in a separate
branch.

Closes #546.
2014-03-11 00:04:10 +01:00
Stefano Pigozzi 241cbe5065 cocoa: fix deadlock during initialization
Thanks to @wm4 for catching the bug.

Fixes #405
2014-03-11 00:04:07 +01:00
wm4 76d771a6fa Release 0.3.5 2014-02-12 22:39:52 +01:00
nand 19caba0794 vo_opengl: make :srgb decompand the BT.709 values correctly
This is the same issue as addressed by 257d9f1, except this time for
the :srgb option as well. (257d9f1 only addressed :icc-profile)

The conditions of the srgb_compand mix() call are also flipped to
prevent an off-by-one error.
2014-02-12 22:34:44 +01:00
wm4 391546c52f command: fix metadata property
This crashed when retrieving the raw property value. Oops.
2014-02-12 22:34:28 +01:00
Alexander Preisinger a8af6a7852 wayland/shm: prevent the window from flying away
With the new xdg_shell the problem will be no gone by itself.
2014-02-12 22:34:09 +01:00
wm4 960aca3386 manpage: document --aspect special values
Use of these is "discouraged", but they're there to select these special
cases with the "aspect" property. They really should use some sort of
choice option type, but since it would be some work to make these work
with float values, the simple and dumb alternative was picked.
2014-02-12 22:33:54 +01:00
wm4 e72a327d74 video: fix --no-aspect
This also affects the --aspect option and the "aspect" property.
2014-02-12 22:33:52 +01:00
nand 87f955f3e9 vo_opengl: fix typo in gamma function's parameter
The correct value is 0.081, not 0.18. The scale factor also needed
slight adjustment due to the order of operations.
2014-02-12 22:33:32 +01:00
Jonas Zetterberg 5536ebe82f vo_vdpau: Discard zero timestamps
Some drivers do not supply timestamps, use old timestamp in these conditions.
2014-02-12 22:33:29 +01:00
Jonas Zetterberg ef8b37ca2a vo_vdpau: Ensure presentation time is within bounds
When a time sync happens the last sync time is the minimum time that can be
used for presentation.
2014-02-12 22:33:27 +01:00
wm4 d4a5513847 demux: fix some newlines in output messages 2014-02-12 22:33:09 +01:00
wm4 d42212cd67 player: fix an assert when reinitializing audio in some cases
This sometimes happened when changing playback speed (= reinitializing
audio) after seeking of playback start. The assertion in audio.c:441 was
triggered, because buffer_playable_samples wasn't reset correctly when
the audio buffer was cleared or shortened. The assertion is correct and
should hold up any time.
2014-02-12 22:33:03 +01:00
nand 674cc1d3a9 vo_opengl: use exactly the values defined by BT.709 for CMS
I could not see any difference whatsoever, but for usage with a 3DLUT
there's zero performance difference so we might as well follow the spec to
the letter.
2014-02-12 22:32:56 +01:00
wm4 c47bb9ca42 gl_x11: don't require a X visual for modern GL context creation
Legacy GL context creation (glXCreateContext) explicitly requires a X
visual, while the modern one (glXCreateContextAttribsARB) does not for
some reason. So fail only on the legacy code path if we don't find a
visual. Note that vo_x11_config_vo_window() will select a default visual
if a NULL visual is passed to it.
2014-02-12 22:32:43 +01:00
wm4 938dad0b88 gl_x11: always request true color visual
This fixes issue #504. For some reason, glXChooseFBConfig() will return
a fbconfig with no associated visual. (I'm not sure if this allowed.
They don't always have a visual, but since GLX_X_RENDERABLE is set
and GLX_DRAWABLE_TYPE is (implicitly) set to GLX_WINDOW_BIT, why would
there be no visual?)

Even worse, a test program seems to show that a 16 bit fbconfig is
selected (instead of 24/32 bit), which doesn't sound nice at all. Since
there _are_ better fbconfigs available, glXChooseFBConfig() should
normally sort them by quality, and return the better ones first. It's
worth noting that this function should also prefer GLX_TRUE_COLOR
over anything else, although this comes last in the sort order.

Whatever is going on, requesting GLX_X_VISUAL_TYPE with GLX_TRUE_COLOR
seems to fix it.
2014-02-12 22:32:40 +01:00
wm4 82b5361946 umpv: silence mpv terminal output
Now it does basically the same as mkv.desktop. Explanation is included
in the description comment.
2014-02-12 22:32:06 +01:00
wm4 f99f48684b umpv: improve description 2014-02-12 22:32:04 +01:00
wm4 25864a5539 umpv: use --force-window
This makes it show a window even when playing audio-only files.
2014-02-12 22:32:02 +01:00
wm4 524d9585fd audio: fix signedness of AF_FORMAT_S32P
This was marked as unsigned, but it's signed. Found by xylosper.
2014-02-12 22:32:00 +01:00
wm4 95a72baf92 mf: don't limit filename length with PATH_MAX
Use an arbitrary constant instead, which is as good as PATH_MAX.

This helps us to avoid having to think about pull request #523.

Also fix a case where a potentially signed char was passed to isspace().
2014-02-12 22:31:54 +01:00
wm4 48112a74ed player: refresh OSD on track switching
Apparently, at least sub_reload was missing a refresh at all.
2014-02-12 22:31:40 +01:00
Alexander Preisinger 8427cdc717 wayland: change minimum version
Change minimum version to 1.3 and remove the version checking in the source
code.
2014-02-12 22:31:27 +01:00
wm4 b695ca1e27 x11: fix initial VO size
This was done incorrectly in the previous commit: the fallback size used
the window size as requested with the first config call, which is the
size of the hidden window in the vo_opengl case. (That damn hidden
window again...)

Conflicts:
	video/out/x11_common.c
2014-02-12 22:31:21 +01:00
wm4 801feb6420 x11: remove apparently useless code
This code essentially does nothing. As far as I could find out, this
actually used to do something. Then it was removed with commit efe7c39f,
leaving some leftover code that didn't do anything useful. This happened
12 years ago!

Also remove a commented debug printf.
2014-02-12 22:30:34 +01:00
wm4 de6a452039 x11: fix race condition when setting aspect when leaving fullscreen
vo_opengl creates a hidden X11 window to probe the OpenGL context. It
must do that before creating a visible window, because VO creation and
VO config are separate phases.

There's a race condition involving the hidden window: when starting with
--fs, and then leaving fullscreen, the unfullscreened window is
sometimes set to the aspect ratio of the hidden window. I'm not sure why
the window size itself uses the correct size (but corrupted by the wrong
aspect), but that's perhaps because the window manager is free to ignore
the size hint while honoring the aspect, or something equally messed up.

It turns out this happens because x11_common.c thinks the size of the
hidden window is the size of the unfullscreened window. This in turn
happens because vo_x11_update_geometry() reads the size of the hidden
window when called in vo_x11_fullscreen() (called from
vo_x11_config_vo_window()) when mapping the fullscreen window. At that
point, the window could be mapped, but not necessarily. If it's not
mapped, it will get the size of the unfullscreened window... I think.

One could fix this by actively waiting until the window is mapped. Try
to pick a less hacky approach instead, and never read the window size
until MapNotify is received.

vo_x11_create_window() needs a hack, because we'd possibly set the VO's
size to 0, resulting e.g. in vdpau to fail initialization. (It'll print
error messages until a proper resize is received.)

Conflicts:
	video/out/x11_common.c
2014-02-12 22:30:23 +01:00
wm4 4b764b6cc6 old-configure: use -std=c99
See previous commit.
2014-02-12 22:29:50 +01:00
wm4 7b7c31b190 build: switch to -std=c99 for saner float semantics
This fixes a weird bug with aspect ratio handling. It has to do with
float handling: with -std=gnu99, gcc implicitly enables broken non-
standard semantics giving float variables excess precision. This can for
example make this fail in theory: "float a = 0.1; assert(a == a);"

While standard C allows excess precision _within_ expressions, it
requires truncation when storing float values in variables of types
"float" or "double". The "gnu99" mode breaks this. It can be unbroken by
using "c99", or by specifying -fexcess-precision=standard. The former
seems less likely to break compilers other than modern gcc. Note that
-ffloat-store would also fix this, but also makes float expressions less
efficient and less precise for no reason.

The code that mistakenly fails because of this is dec_video.c line 393.
It caused the container aspect to be ignored in some or all situations,
depending how the compiler optimizes. For example, on gcc-4.6 with -Os,
the aspect is always ignored.

In future, we should probably just get rid of storing aspects as floats.

Note: requires mingw-w64 trunk for math.h fixes (M_PI was hidden).
2014-02-12 22:29:21 +01:00
wm4 70a66b461d cache: refuse to seek outside of cache boundaries
Note that this still happens in the stream level, so we can't have
nice highlevel behavior restricting seeking. Instead, if a seek leads
to the demuxer requesting data outside of the cached range, the seek
will simply fail. This might confuse the demuxer, and the resulting
behavior is not necessarily useful.

Note that this also doesn't try to skip data on a forward seek. This
would just freeze the stream with slow unseekable streams.

One nice thing is that stream.h has a separate function for merely
skipping data (separate from seeking forward), which is pretty useful
in this case: we want skipping of data to work, even if we reject
seeking forward by skipping data as too expensive. This probably is
or will be useful for demux_mkv.c.
2014-02-12 22:29:11 +01:00
wm4 844e8f2b51 Release 0.3.4 2014-01-31 19:11:48 +01:00
wm4 3f4ed8920f vo_wayland: silence shadowing warning
No real problem.
2014-01-31 19:10:15 +01:00
wm4 7ad2999b5f quvi: disable subtitle fetching by default
This is slow and unreliable, basically unusable.
2014-01-31 19:08:30 +01:00
Andre D 14fdbe07ac quvi: add option to not fetch subtitles
Signed-off-by: wm4 <wm4@nowhere>
2014-01-31 19:08:26 +01:00
wm4 61ed9a8747 demux_lavf: fix crash with empty files
This used to work; I'm not sure when or why it regressed. When setting
AVProbeData.filename to NULL, libavformat will crash in rtp_probe() by
unconditionally accessing the string.

We used to set the filename to NULL to prevent probing by file extension
when we don't deem it as necessary. Using an empty string also works for
this purpose.
2014-01-31 19:08:12 +01:00
wm4 0801345d68 mp_image: reject too large image sizes
Larger sizes can introduce overflows, depending on the image format. In
the worst case, something larger than 16000x16000 with 8 bytes per pixel
will overflow 31 bits.

Maybe there should be a proper failure path instead of a hard crash, but
not yet. I imagine anything that sets a higher image size than a known
working size should be forced to call a function to check the size (much
like in ffmpeg/libavutil).
2014-01-31 19:07:47 +01:00
wm4 5bd0fe5daf sd_lavc: skip 0 sized sub-bitmaps
Not everything in the OSD path handles 0x0 sized sub-bitmaps well. At
least the code implementing --sub-gray had severe problems with it.

Fix this by skipping such bitmaps.
2014-01-31 19:07:43 +01:00
Alexander Preisinger cab3c5fbb8 wayland/shm: RGB888 as default, change options
RGB565 is one of the fastest and most supported formats on low end consumer
devices, but ffmpeg spams warning when using it. Make it opt-in instead of
opt-out.
2014-01-31 19:07:40 +01:00
Alexander Preisinger 99ceae8cc3 wayland/shm: fix memory leak 2014-01-31 19:07:37 +01:00
Alexander Preisinger ebe04ab692 wayland/shm: remove resize boilerplate
The problem seems to have solved itself. I guess the previous changes to
resizing and commit ba101ab made this possible. Consider me happy for removing
that crap.
2014-01-31 19:07:31 +01:00
James Ross-Gowan 808aa08cc0 w32: use safe DLL search paths everywhere
Windows applications that use LoadLibrary are vulnerable to DLL
preloading attacks if a malicious DLL with the same name as a system DLL
is placed in the current directory. mpv had some code to avoid this in
ao_wasapi.c. This commit just moves it to main.c, since there's no
reason it can't be used process-wide.

This change can affect how plugins are loaded in AviSynth, but it
shouldn't be a problem since MPC-HC also does this and it's a very
popular AviSynth client.
2014-01-31 19:07:09 +01:00
James Ross-Gowan 2065e0ba36 w32: enable heap corruption detection
Enable the terminate-on-corruption feature. This is recommended for new
Windows applications and shouldn't cause a performance hit. It actually
shouldn't change anything for 64-bit builds, since Win64 has this
switched on by default.

See:
http://blogs.msdn.com/b/michael_howard/archive/2008/02/18/faq-about-heapsetinformation-in-windows-vista-and-heap-based-buffer-overruns.aspx
2014-01-31 19:07:07 +01:00
James Ross-Gowan 3c43a022af w32: don't disable the error reporting dialog
Windows users expect this when a program crashes. Without it, the
program just disappears. Also change the SetErrorMode call to use macros
instead of a hardcoded constant.
2014-01-31 19:07:05 +01:00
wm4 02513cd5df sub: fix crash with certain uses of --vf=sub
If, for some reason, the subtitle renderer attempts to render a
subtitle before SD_CTRL_SET_VIDEO_PARAMS was called, it passed a
value calculated from invalid values. This can happen with --vf=sub
and --start. The crash happens if 1. there was a subtitle packet that
falls into the timestamp of the rendered video frame, 2. the playloop
hasn't informed the subtitle decoder about the video resolution yet
(normally unneeded, because that is used for weird corner cases only,
so this code is a bit fuzzy), and 3. something actually requests a
frame to be drawn from the subtitle renderer, like with vf_sub.

The actual crash was due to passing NaN as pixel aspect to libass,
which then created glyphs with ridiculous sizes, involving a few
integer overflows and unchecked mallocs.

The sd_lavc.c and sd_spu.c cases probably don't crash, but I'm not
sure, and it's better fix them anyway.

Not bothering with sd_spu.c, this crap is for compatibility and will
be removed soon.

Note that this would have been no problem, had the code checked whether
SD_CTRL_SET_VIDEO_PARAMS was actually called. This commit adds such a
check (although it basically checks after using the parameters).

Regression since 49caa0a7 and 633fde4a.
2014-01-31 19:06:58 +01:00
wm4 4d986d2a98 demux_lavf: add hack to workaround too unreliable mp3 detection
This generally affects mp3 files that don't have any (or many) mp3
frames in the first 2 MB. 2 MB is the maximum probe size, and
libavformat returns a low probescore even if we give it the full 2 MB.
Trying to probe a larger buffer (or even the full file) doesn't work for
mysterious reasons.

The workaround consists in accepting a very weak probescore if the
format is detected as mp3 and we probed already 2 MB.
2014-01-31 19:06:49 +01:00
wm4 ada6f96811 demux_lavf: refactor format probing hack
Restructure it a bit, so we can use the format hack list even if no mime
type applies. Shouldn't change anything functionally yet. Preparation
for the next commit.
2014-01-31 19:06:44 +01:00
wm4 321b3952b0 vo_wayland: fix confusion of video and window sizes 2014-01-31 19:06:29 +01:00
reimar d49b49ff96 stream_pvr: Fix fd check, -1 indicates invalid, not 0.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@36677 b3059339-0415-0410-9bf9-f77b7e298cf2
2014-01-31 19:06:20 +01:00
wm4 f088abb2bf audio: fix balance control
Balance controls as used by mixer.c was broken, because af_pan.c stopped
accepting its arguments. We have to allow 0 channels explicitly. Also,
fix null pointer access if the matrix parameter is not used.

Regression from commit 82983970.
2014-01-31 19:06:17 +01:00
wm4 4a3975bf7e waf: try to fix unicode/byte string messup
Some mpv builds identify with e.g. "mpv b'0.3.3' ". The version looks
like str() was called on a Python byte string. I couldn't reproduce it
on my machine (I tried with both Python 2 and 3), so I'm not exactly
sure what's going on here, but I'm hoping this commit does fix it.
2014-01-31 19:05:20 +01:00
wm4 a064143899 manpage: fix af_equalizer syntax
This doesn't need quoting, for some reason.
2014-01-31 19:04:54 +01:00
11rcombs f264d52099 af: fixed out-of-bounds accesses caused by NUM_FMT and co.
Signed-off-by: wm4 <wm4@nowhere>

This merges pull request #496. The problem was that at least the
initialization of the distance[] array accessed af_fmtstr_table[]
entries that were out of bounds. Small cosmetic changes applied to
the original pull request.
2014-01-31 19:04:29 +01:00
reimar 74a3c169b5 cookies.c: cols must (and does) have 7 elements.
Doesn't affect the generated code, but avoids confusion
in both humans and newer Coverity versions.

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@36623 b3059339-0415-0410-9bf9-f77b7e298cf2
2014-01-31 19:04:15 +01:00
reimar 34d9787fcf vcd_read: Fix sizeof argument.
The struct we need to copy is actually a cdrom_msf0, not cdrom_msf.
Even though the kernel for no good reason reads it in as a
cdrom_msf struct, but only uses the part shared with cdrom_msf0 -
this is probably a kernel bug.

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@36622 b3059339-0415-0410-9bf9-f77b7e298cf2
2014-01-31 19:04:09 +01:00
wm4 1c0b80d518 mkv.desktop: add two more mime types
Stolen from github issue #484. No idea whether they're needed.
2014-01-31 19:03:57 +01:00
wm4 a9bafeb589 cache: remove debug code
This was accidentally committed.

<rcombs> `mp_sleep_us(100000);` <-- are you drunk?
2014-01-31 19:03:17 +01:00
wm4 3a33db3d92 cache: reduce message spam
Output only 1 message every 5 seconds at most.
2014-01-31 19:02:45 +01:00
wm4 d276f753f7 Release 0.3.3 2014-01-15 21:03:02 +01:00
Grzegorz Blach c06000eef8 Detect Lua on FreeBSD 2014-01-15 20:57:17 +01:00
wm4 1bc1cd2305 player: avoid stalling when starting a network stream
Starting a network stream could stall by executing uncacheable stream
control requests (STREAM_CTRL_GET_LANG and STREAM_CTRL_GET_DVD_INFO).
Being uncacheable means the player has to wait until the cache is done
reading the current block of data. These requests can't be cached
because they're too complicated, so the only way to avoid them is
special casing the DVD and Bluray streams (which are the only things
which need these requests), and not doing them in other cases.

(This is kind of inelegant, but so is the rest of the DVD/BD code.)
2014-01-15 20:57:09 +01:00
wm4 a735a2abd7 demux_mkv: improve robustness by explicitly checking for level 1 elements
Matroska makes it pretty hard to resync correctly on broken files:
random data returns "valid" EBML IDs with a high probability, and when
trying to skip them it's likely that you skip a random amount of data
(instead of considering the element length invalid).

Improve upon this by skipping known level 1 elements only. Consider
everything else invalid and call the resync code. This might result in
annoying behavior when Matroska adds new level 1 elements, although it
won't be particularly harmful. Matroska doesn't really allow us to do
better (even mkvtoolnix explicitly checks for known level 1 elements).

Since we now don't always want to combine EBML element skipping and
resyncing, remove ebml_read_skip_or_resync_cluster(), and make
ebml_read_skip() more tolerant against skipping broken elements.

Also, don't resync when reading sub-elements, and instead do resyncing
when reading them results in an error.
2014-01-15 20:56:16 +01:00
wm4 112c1abe31 demux_mkv: avoid skipping too much data in corrupted files
Until now, corrupted files were detected if the size of an element (that
should be skipped) was larger than the remaining file. This still could
skip larger regions of the file itself if the broken size happened to be
within the file.

Change it so that it's never allowed to skip outside the parent's
element.
2014-01-15 20:56:13 +01:00
wm4 362b35b631 manpage: document --term-osd=force
Apparently this was forgotten when it was first added, or maybe it's an
arrifact from the rst conversion.

Conflicts:
	DOCS/man/en/options.rst
2014-01-15 20:54:32 +01:00
wm4 49cf0af294 player: don't block terminal OSD while seeking
Seeking usually show the status on OSD. In terminal OSD mode, no status
is shown, because there is already a separate status line.
Unfortunately, the mechanism for showing the status was still active,
which forced showing no message while the code for showing seek status
was active.
2014-01-15 20:53:44 +01:00
wm4 1b26874710 player: mention subtitles in av_desync_help_text
Insane .ass subtitle scripts can cause severe slowdown (depending on the
speed of the machine, or the insanity of the script), so mention how to
test without subtitles. This is mainly to make the user aware that
subtitle rendering can be a problem. For longwinded explanation, there
isn't enough space.
2014-01-15 20:53:41 +01:00
Stefano Pigozzi 8fe636da7a cocoa: fix window placement on secondary screens
For a long time the cocoa backend set the xinerama_x/y and used dx/dy from the
VO instance. This somewhat worked with some workarounds but wasn't really
what was supposed to be happening. Moreover 27e4360, which touched this
workaround introduced a regression.

New code doesn't set the xinerama_x/y values so that dx/dy are offsets in the
current screen (not a virtual screen composed of all the screens). The screen
reference detected during VOCTRL_UPDATE_SCREENINFO is also passed down to the
window initialization code.

Fixes #472
2014-01-15 20:53:19 +01:00
Stefano Pigozzi 812f149585 cocoa: refactor init window positioning code 2014-01-15 20:53:14 +01:00
wm4 635424c8f0 demux_lavf: add hack for MicroDVD for assuming frame based timing
MicroDVD files _can_ contain real timestamps instead of frame timestamps
if they declare a FPS. But this seems to be rare, so ignore that if the
FPS happens to match with the libavformat microdvd parser's default FPS.

This might actually break files that declare 23.976 FPS, but the video
file is not 23.976 FPS, but the chance that this happens is probably
very low, and the commit fixes the more common breakage with 25 FPS
video.
2014-01-15 20:51:50 +01:00
wm4 2319918721 sub: fix frame based subtitle timestamp handling
Subtitle formats with frame based timing require using the video FPS to
compute proper subtitle timestamps. But it looks like the calculation to
do that was inversed.
2014-01-15 20:51:47 +01:00
Alexander Preisinger 9fabf85a44 wayland: properly empty output list 2014-01-15 20:51:39 +01:00
Alexander Preisinger 54fd5d0979 wayland/shm: don't crash if initialization failed 2014-01-15 20:51:37 +01:00
wm4 d141d281ca wayland: fix crash when initialization fails
On X11, if no wayland compositor is running, wl_list_init() will never
be called. This will cause destroy_display() to segfault when trying to
iterate over the list.
2014-01-15 20:51:32 +01:00
Alexander Preisinger ebc3d74b04 wayland/shm: tone down warnings
Those warnings are printed far too often and actually aren't usefull at all.
2014-01-15 20:51:19 +01:00
Alexander Preisinger a63fab8921 wayland: fix memory leaks
There are still some leaks from wayland-cursor stuff, but there is no way to
free the memory as user of the cursor library.

Conflicts:
	video/out/wayland_common.c
2014-01-15 20:50:52 +01:00
wm4 4ee8d8d3f9 player: fix setting smaller timeout on Windows systems
On Windows, we don't have proper input event wakeup handling, so we
need to lower the playloop timeout in order to react fast to input.

Closes #387.
2014-01-15 20:50:02 +01:00
Alexander Preisinger 574a2484c1 wayland: cleanup registry_handle_global
The wl_registry object is already passed as a parameter. No need to create
a temporary variable.
2014-01-15 20:49:57 +01:00
Alexander Preisinger f5b92bee5e wayland: remove set_user_data from seat_listener
The user_data is passed on add_listener and can later be changed with
set_user_data. But because we don't want to change it later and because it is
the same object remove the set_user_data call.

This might be a copy&paste leftover from the initial draft for the wayland
backend.
2014-01-15 20:49:55 +01:00
Alexander Preisinger ca3d7144db wayland: use static consistently
Declare everything that is only needed inside wayland_common.c as static.
2014-01-15 20:49:52 +01:00
wm4 86e7c3defb terminal: don't initialize termcap etc. if stdout is not a terminal
Otherwise, it seems one of the term* libraries will write escape
sequences to stdout, for whatever reason.
2014-01-15 20:49:42 +01:00
Alexander Preisinger 0fe1385d80 wayland: fix fullscreen & resizing for good
I added enough logic to never set ontop or fullscreen twitce.
This commit keeps also the size of the video if multiple videos are played.
If the ratio differs the width will be kept at the same size and only the
height changes.
2014-01-15 20:49:32 +01:00
wm4 f4e9371d0f manpage: mention how to get a list of codecs for use with --hwdec-codecs 2014-01-15 20:49:26 +01:00
wm4 909185d49e wayland: silence annoying libwayland-client message
libwayland-client contains the following code [1]:

	runtime_dir = getenv("XDG_RUNTIME_DIR");
	if (!runtime_dir) {
		fprintf(stderr,
			"error: XDG_RUNTIME_DIR not set in the environment.\n");

This means this message will unconditionally and unavoidably be printed
if XDG_RUNTIME_DIR is not set. Since mpv is a terminal program, and we
want to avoid unnecessary output, work it around by not attempting to
use wayland if this environment variable is not set.

[1] http://cgit.freedesktop.org/wayland/wayland/tree/src/wayland-client.c#n636
    (cd0dccd01e16fa404e03974d30ded3aebdb1c4bc)
2014-01-15 20:49:22 +01:00
wm4 c18c324c6f wayland: fix some memory leaks on initialization failure
This commonly happens when initializing vo_opengl on a X11-only system.

Unfortunately, most wl_*_destroy() functions appear not to accept NULL
pointers, making partial deinitialization a pain: you have to add your
own NULL checks everywhere to avoid crashes.

xkb.context is uninitialized separately, because you can initialize it
just fine, even if the rest of input initialization fails.
2014-01-15 20:49:19 +01:00
wm4 6b20c24413 Release 0.3.2 2014-01-06 20:32:24 +01:00
Stefano Pigozzi 5c42d1eb92 cocoa: don't reset window size when the video size doesn't change
Fixes #459
2014-01-06 20:27:55 +01:00
Martin Herkt e34132f8d5 w32_common: don't force topmost on fullscreen
Fixes #457, #444.
2014-01-06 20:27:53 +01:00
Martin Herkt bd7ff23f96 Windows: use roaming AppData instead of local
Whatever. Fixes #458.
2014-01-06 20:27:47 +01:00
wm4 e6c184e2b1 build: don't depend on both libavresample and libswresample
When both libavresample and libswresample were detected, the script
enabled both at the same time. This is not supported; although nothing
bad happened apparently. Make the dependencies both mutually exclusive.
2014-01-06 20:23:10 +01:00
wm4 33c4920967 player: always ise [statusline] for terminal OSD
This was inconsistent: the actual statusline used [statusline] as
message prefix, while other parts of the terminal OSD used [cplayer]
(and MSGL_STATUS). This commit makes it consistent.
2014-01-06 20:23:06 +01:00
wm4 0c36f655e1 player: print an error message if run command fails
Note that we can't use mp_msg, because it's not async-signal safe (we
might be running other threads while forking, so only functions
specified to be async-signal safe can be called, and this doesn't
include stdio; mp_msg acquires a mutex too).

Also, always print a \n before running the program to flush the status
line. The effect is that a program running successfully as well as the
error message will effectively start on a new line.
2014-01-06 20:23:03 +01:00
wm4 cd31697dd8 manpage: fix typo 2014-01-06 20:22:57 +01:00
wm4 c497b82583 player: don't select subtitles added from quvi by default
Quvi subtitles are considered external subtitles (simply because they're
separate from the audio/video stream), but for the sake of subtitle
auto-selection, they should not be considered external.

Change this so that quvi subtitles are treated like muxed subtitles
(with default flag never set). This means subtitles won't be selected by
default, unless explicitly requested with --sid or --slang.
2014-01-06 20:22:53 +01:00
Alexander Preisinger 6f5dfb5102 Revert "wayland/egl: use redraw callback"
Because of this commit there were problems displaying the frmase in their right
order.

This reverts commit 96e75d234a.

Conflicts:
	video/out/gl_wayland.c
	video/out/wayland_common.h
2014-01-06 20:22:43 +01:00
Alexander Preisinger 59f970d492 wayland: remove workaround
The changes in the vo_wayland_ontop function have no effect on the workaround.

Somehow the problem just disappeared. I guess it is because of the new control
function in gl_wayland.c where the resize happens immediatly after the event
dispatch/flush.
2014-01-06 20:22:41 +01:00
wm4 29c74b42b4 demux_subreader: reject file if not opened by --sub
demux_subreader.c contains the old MPlayer subtitle parser, and I have
absolutely no confidence in this (very crappy) code. There might be
one or two security risks associated with running that code on
arbitrary input.
2014-01-06 20:22:26 +01:00
Alexander Preisinger 4b2a3e50e2 wayland/egl: misc fixes and cleanups 2014-01-06 20:22:11 +01:00
Alexander Preisinger 35b01c9604 wayland/egl: use redraw callback
This solves the issue where we would not receive any frame events. The
difference to my earlier tests is that now it looks like eglSwapBuffers uses
it's own event queue or something similiar along the lines. Becaues the
performance is the same as without any redraw callback.
2014-01-06 20:22:08 +01:00
Alexander Preisinger 09b95257fe wayland/egl: add egl_context to the wayland state
At the moment there are visual glitches when we resize the window. This happens
because in wayland there a special function for resizing EGL windows.

To prevent the glitches move the egl_context to the wayland state in
wayland_common.h and add a new control function to gl_wayland.c to wrap the
vo_wayland_control function to check for resize events.

With the new control wrapper the glitches are gone and the resizing is fluid.
2014-01-06 20:22:06 +01:00
Alexander Preisinger 0cf2df38d1 wayland: Remove nonsense comment and add warning
The reason a segmentation happend here was because we couldn't get the
requested minor version. The major version is enough for differentiating
between OpenGL 3 and OpenGL 2. If it fails there is still a fallback to any
version available.

Also add a warning if we use the fallback.
2014-01-06 20:22:03 +01:00
Alexander Preisinger 4326fdfe2a wayland: move workaround to fullscreen code
Because of this workaround there was a bug in the wayland vo.
Now it works on both vos (opengl and shm) as it should.
2014-01-06 20:21:55 +01:00
Martin Herkt 9755850b3d manpage: mention --pause 2014-01-06 20:21:45 +01:00
wm4 96b50e770b dvdnav: set correct stride for fake highlights
This didn't really matter, because the fake highlight rectangle is in a
single color, and every pixel has the same color value.
2014-01-06 20:21:43 +01:00
wm4 9f6551160a stream_pvr: fix crash on initialization
Fallout from the mp_msg conversions.
2014-01-06 20:21:39 +01:00
wm4 89b854165e audio: check for overflows 2014-01-06 20:21:37 +01:00
wm4 0beece4397 ta: check overflow in array realloc macros 2014-01-06 20:21:19 +01:00
Stefano Pigozzi 8abdf1f56e vda: fix build on OS X 10.7
Looks like on 10.8 OpenGL.h recursively includes CGLIOSurface.h. That is not
the case for 10.7 so the build was broken on that version of OS X.
2014-01-06 20:21:17 +01:00
Stefano Pigozzi 5a81f7678e build: fix cocoa configure check on OS X 10.7
It failed because the 10.7 SDK doesn't natively support array and dictionary
subscripting.
2014-01-06 20:21:14 +01:00
Alexander Preisinger e26286dfdb wayland/opengl: fix garbage borders
It seems mpv draws garbage in those regions. Now we calculate the aspect and
let weston draw the black borders.
2014-01-06 20:21:11 +01:00
Alexander Preisinger 389232e5a2 wayland/shm: only commit new frames
Only attach and commit new buffers. This also increases performance when
paused.
2014-01-06 20:21:09 +01:00
Alexander Preisinger c5de0b0a6c wayland: don't change set fullscreen twice
Newest weston chrashes if we call set_fullscreen twice. This is a major bug
I which I should probably report.
2014-01-06 20:21:07 +01:00
Martin Herkt f9bdfc0782 ao_alsa: Unbreak pause/resume
Well that was dumb.
2014-01-06 20:20:57 +01:00
Martin Herkt 5c9a7e24f6 ao_alsa: Fix PCM resume after suspend
Fixes #324
2014-01-06 20:20:55 +01:00
wm4 b56f61d2ab stream: always respect sector_size, fixes cdda://
Streams like CDDA have special requirements in what quantities data can
be read: you can only read a sector at once, not more and not less. The
stream_peek() function didn't respect that and set less (used internal
buffer size of 2048 bytes, instead of CD sector size of 2352 bytes), so
no data was read and EOF was accidentally set, making playback with
cdda:// fail.

This is a regression since commit 9a723f, but that commit merely exposed
the issue (the redundant seek would clear the EOF flag).
2014-01-06 20:20:48 +01:00
Stefano Pigozzi 82ab3a8160 build: fix typo 2014-01-01 21:50:42 +01:00
wm4 e371f2ebd3 Release 0.3.1 2014-01-01 21:03:51 +01:00
Stefano Pigozzi 29b68d69c0 build: make configure fail if both __atomic and __sync are not available 2014-01-01 20:57:27 +01:00
wm4 6c770eb6df manpage: clarifications about bitmap subtitles and --secondary-sid 2014-01-01 20:57:25 +01:00
wm4 965f336917 options: make --msglevel=help print something helpful 2014-01-01 20:57:22 +01:00
wm4 47fae324c7 manpage: fix description on the slave mode msglevel 2014-01-01 20:57:18 +01:00
wm4 6ab0dbf2ed player: load encoding-profiles.conf before the main config
Otherwise one can't add profiles based on the encoding profiles.
2014-01-01 20:57:16 +01:00
Miro Hrončok c002196ffe mpv.desktop: Add Czech translations 2014-01-01 20:57:14 +01:00
wm4 3c8fc4588d player: fix DVD playback
Crashed in case of lazily added subtitle streams, which add tracks with
track->stream set to NULL.

Fixes gituhub issue #439.
2014-01-01 20:57:12 +01:00
Alessandro Ghedini 416015f059 compat: use __atomic operations instead of __sync, when present
Fixes #434
Fixes #437
2014-01-01 20:57:09 +01:00
Alessandro Ghedini 773db053aa build: check for libatomic and __atomic operations
Add check in old-configure as well. Reformat the check to use a maximum of 80
columns in the wscript.
Signed-off-by: Stefano Pigozzi <stefano.pigozzi@gmail.com>
2014-01-01 20:57:06 +01:00
wm4 a8c09d003f manpage: fix vf_noise parameter name 2014-01-01 20:57:02 +01:00
wm4 1284a6b6b0 video: fix --brightness etc. options
They were set before the VO was intitialized, which silently failed.
2013-12-29 22:17:50 +01:00
wm4 78c35e42ea Release 0.3.0 2013-12-29 18:06:41 +01:00
632 changed files with 65981 additions and 83611 deletions

No files matched your search

+7 -8
View File
@@ -14,21 +14,20 @@
/input/input_conf.h
/tags
/TAGS
/video/out/gl_video_shaders.h
/video/out/x11_icon.inc
/demux/ebml_defs.c
/demux/ebml_types.h
/sub/osd_font.h
/player/lua/*.inc
/DOCS/man/mpv.1
/DOCS/man/mpv.aux
/DOCS/man/mpv.log
/DOCS/man/mpv.out
/DOCS/man/mpv.pdf
/DOCS/man/mpv.toc
/DOCS/man/*/mpv.1
/DOCS/man/*/mpv.aux
/DOCS/man/*/mpv.log
/DOCS/man/*/mpv.out
/DOCS/man/*/mpv.pdf
/DOCS/man/*/mpv.toc
/waf
/waf-*
/waf3-*
/build
/.waf*
/.lock-waf_*
+9 -41
View File
@@ -1,41 +1,16 @@
language: c
os:
- linux
- osx
env:
matrix:
- LIBAV=libav-stable
- LIBAV=libav-git
- LIBAV=ffmpeg-stable
- LIBAV=ffmpeg-git
global:
# Coverity token
- secure: "H21mSRlMhk4BKS0xHZvCFGJxteCP0hRVUxTuNfM2Z9HBsyutuLEYMtViLO86VtM+Tqla3xXPzUdS4ozLwI72Ax/5ZUDXACROj73yW6QhFB5D6rLut12+FjqC7M33Qv2hl0xwgNBmR5dsm1ToP37+Wn+ecJQNvN8fkTXF+HVzOEw="
- LIBAV=libav-stable
- LIBAV=libav-git
- LIBAV=ffmpeg-stable
- LIBAV=ffmpeg-git
compiler:
- clang
- gcc
branches:
only:
- master
- ci
- coverity_scan
matrix:
exclude:
- os: osx
env: LIBAV=libav-stable
- os: osx
env: LIBAV=libav-git
- os: osx
env: LIBAV=ffmpeg-git
- os: osx
compiler: gcc
- os: linux
env: LIBAV=ffmpeg-stable
- os: linux
compiler: clang
before_install: ./travis-deps libass-stable $LIBAV
script:
@@ -43,20 +18,13 @@ script:
- ./waf configure
- ./waf build
notifications-policy: &notifications-policy
on_success: change
on_failure: always
notifications:
email: false
irc:
channels:
- "irc.freenode.org#mpv-player-dev"
on_success: change
on_failure: always
addons:
coverity_scan:
project:
name: "mpv-player/mpv"
description: "Build submitted via Travis CI"
notification_email: mpv-team@googlegroups.com
build_command_prepend: "./bootstrap.py && ./waf configure"
build_command: "./waf build"
branch_pattern: coverity_scan
<<: *notifications-policy
+160
View File
@@ -0,0 +1,160 @@
1. Input layer, supported devices, methods:
- plain file, with seeking
- STDIN, without seeking backward
- network streaming (currently plain wget-like HTTP and MMS (.asx))
- VCD (Video CD) track, by direct CDROM device access (not requires mounting disc)
- DVD titles using .IFO structure, by direct DVD device access (not requires mounting disc)
- DVD titles using menu navigation (experimental/alpha, not yet finished!!!)
- CDDA - raw audio from audio CD-ROM discs (using cdparanoia libs)
- RTP streaming (mpeg-ps over multicast only)
- LIVE555 streaming - support SDP/RTSP (using the LIVE555 libs)
- SMB - file access over samba (experimental)
2. Demuxer/parser layer, supported file/media formats:
- MPEG streams (ES,PES,PS. no TS support yet)
note: mpeg demuxer silently ignore non-mpeg content, and find mpeg packets
in arbitrary streams. it means you can play directly VCD images (for example
CDRwin's .BIN files) without extracting mpeg files first (with tools like vcdgear)
It accepts all PES variants, including files created by VDR.
Note: VOB (video object) is simple mpeg stream, but it usually has 01BD
packets which may contain subtitles and non-mpeg audio. Usually found on DVD discs.
Headers: mpeg streams has no global header. each frame sequence (also called GOP,
group of pictures) contains an sequence header, it describes that block.
In normal mpeg 1/2 content there are groups of 12-15 frames (24/30 fps).
It means you can freely seek in mpeg streams, and even can cut it to
small parts with standard file tools (dd, cut) without destroying it.
Codecs: video is always mpeg video (mpeg1, mpeg2 or mpeg4).
audio is usually mpeg audio (any layer allowed, but it's layer 2 in most files)
but 01BD packets may contain AC3, DTS or LPCM too.
FPS: mpeg2 content allows variable framerate, in form of delayed frames.
It's mostly used for playback 24fps content at 29.97/30 fps (NTSC) rate.
(so called Telecine or 3:2 pulldown effect)
It means you see 30 frames per second, but there are only 24 different
pictures and some of them are shown longer to fill 30 frame time.
If you encode such files with mencoder, using -ofps 24 or -ofps 23.976
is recommended.
- AVI streams.
Two kind of RIFF AVI files exists:
1. interleaved: audio and video content is interleaved. it's faster and
requires only 1 reading thread, so it's recommended (and mostly used).
2. non-interleaved: audio and video aren't interleaved, i mean first come
whole video followed by whole audio. it requires 2 reading process or
1 reading with lots of seeking. very bad for network or cdrom.
3. badly interleaved streams: mplayer detects interleaving at startup and
enables -ni option if it finds non-interleaved content. but sometimes
the stream seems to be interleaved, but with bad sync so it should be
played as non-interleaved otherwise you get a-v desync or buffer overflow.
MPlayer supports 2 kind of timing for AVI files:
- bps-based: it is based on bitrate/samplerate of video/audio stream.
this method is used by most players, including avifile and wmp.
files with broken headers, and files created with VBR audio but not
vbr-compliant encoder will result a-v desync with this method.
(mostly at seeking).
- interleaving-based: note: it can't be used togethwer with -ni
it doesn't use bitrate stuff of header, it uses the relative position
of interleaved audio and video chunks. makes some badly encoded file
with vbr audio playable.
Headers: AVI files has a mandatory header at the begin of the file,
describing video parameters (resolution, fps) and codecs. Optionally
they have an INDEX block at the end of the file. It's optional, but
most files has such block, because it's REQUIRED for seeking.
Btw usually it can be rebuilt from file content, mplayer does it with
the -idx switch. MPlayer can recreate broken index blocks using -forceidx.
As AVI files needs index for random access, broken files with no index
are usually unplayable.
Of course, cutting/joining AVI files needs special programs.
Codecs: any audio and video codecs allowed, but I note that VBR audio is
not well supported by most players. The file format makes it possible to
use VBR audio, but most players expect CBR audio and fails with VBR,
as VBR is unusual, and Microsoft's AVI specs only describe CBR audio.
I also note, that most AVI encoders/multiplexers create bad files if
using VBR audio. only 2 exception (known by me): NaNDub and MEncoder.
FPS: only constant framerate allowed, but it's possible to skip frames.
- ASF streams:
ASF (active streaming format) comes from Microsoft. they developed two
variant of ASF, v1.0 and v2.0. v1.0 is used by their media tools (wmp and
wme) and v2.0 is published and patented :). of course, they differ,
no compatibility at all. (it's just a legality game)
MPlayer supports only v1.0, as nobody ever seen v2.0 files :)
Note, that .ASF files are nowdays come with extension .WMA or .WMV.
UPDATE: MS recently released the ASF v1.0 specs too, but it has some
restrictions making it illegal to read by us :)
Headers: Stream headers (codecs parameters) can be everywhere (in theory),
but all files i've seen had it at the beginning of the file.
Asf uses fixed packet size, so it is seekable without any INDEX block,
and broken files are playable well.
Codecs: video is mostly microsoft's mpeg4 variants: MP42, MP43 (aka DivX),
WMV1 and WMV2. but any codecs allowed.
audio is usually wma or voxware, sometimes mp3, but any codecs allowed.
FPS: no fixed fps, every video frame has an exact timestamp instead.
I've got stream with up to 3 sec frame display times.
- QuickTime / MOV files:
They come from Mac users, usually with .mov or .qt extension, but as
MPEG Group chose quicktime as recommended file format for MPEG4,
sometimes you meet quicktime files with .mpg or .mp4 extension.
At first look, it's a mixture of ASF and AVI.
It requires INDEX block for random access and seeking, and even for
playback, like AVI, but uses timestamps instead of constant framerate
and has more flexible stream options (including network stuff) like ASF.
Headers: header can be placed at the beginning or at the end of file.
About half of my files have it at the beginning, others have it at the end.
Broken files are only playable if they have header at the beginning!
Codecs: any codecs allowed, both CBR and VBR.
Note: most new mov files use Sorenson video and QDesign Music audio,
they are patented, closed, secret, (TM)-ed etc formats, only Apple's
quicktime player is able to playback these files (on win/mac only).
- VIVO files:
They are funny streams. They have a human-readable ascii header at
the beginning, followed by interleaved audio and video chunks.
It has no index block, has no fixed packetsize or sync bytes, and most
files even has no keyframes, so forget seeking!
Video is standard h.263 (in vivo/2.0 files it's modified, non-standard
h.263), audio is either standard g.723 or Vivo Siren codec.
Note, that microsoft licensed vivo stuff, and included in their netshow
v2.0 program, so there are VfW/ACM codecs for vivo video and audio.
- RealMedia files:
A mixture of AVI and ASF features. It has mandatory headers at the
beginning and an optional INDEX (missing in most files).
The file is constructed of variable size chunks, with small header
telling the stream ID, timestamp, flags (keyframe...) and size.
But it has some features found in ASF files:
The video is actually double-muxed, the video chunks are really
appended fragments of the video frame. RV30+ supports B frames, so
you have to parse some bits of the first fragment to get the real PTS.
The audio frames are fixed size (CBR) but using the same scrambling
(out-of-order interleaving) as in the ASF files.
Codecs: Audio is either COOK(er), SIPR(o), ATRAC3 or DNET.
The DNET is actually a byte-swapped low-bitrate Dolby AC3 variant :)
Video is RV10 (h263 variant), RV20 (rp G2), RV30 (rp v8) or RV40 (rp v9).
FPS: variable, just like in ASF.
Note, that similarity of real and asf has some background - they worked
together on the (never finished/used) ASF v2 spec for some time.
- GIF files:
The GIF format is a common format for web graphics that supports
animation. These are read through libungif or compatible library.
Variable frame delays are supported, but seeking is not supported.
Seeking will be supported once an index of gif frames can be built.
+228
View File
@@ -0,0 +1,228 @@
So, I'll describe how this stuff works.
The main modules:
1. stream.c: this is the input layer, this reads the input media (file, stdin,
vcd, dvd, network etc). what it has to know: appropriate buffering by
sector, seek, skip functions, reading by bytes, or blocks with any size.
The stream_t (stream.h) structure describes the input stream, file/device.
There is a stream cache layer (cache2.c), it's a wrapper for the stream
API. It does fork(), then emulates stream driver in the parent process,
and stream user in the child process, while proxying between them using
preallocated big memory chunk for FIFO buffer.
2. demuxer.c: this does the demultiplexing (separating) of the input to
audio, video or dvdsub channels, and their reading by buffered packages.
The demuxer.c is basically a framework, which is the same for all the
input formats, and there are parsers for each of them (mpeg-es,
mpeg-ps, avi, avi-ni, asf), these are in the demux_*.c files.
The structure is the demuxer_t. There is only one demuxer.
2.a. demux_packet_t, that is DP.
Contains one chunk (avi) or packet (asf,mpg). They are stored in memory as
in linked list, cause of their different size.
2.b. demuxer stream, that is DS.
Struct: demux_stream_t
Every channel (a/v/s) has one. This contains the packets for the stream
(see 2.a). For now, there can be 3 for each demuxer :
- audio (d_audio)
- video (d_video)
- DVD subtitle (d_dvdsub)
2.c. stream header. There are 2 types (for now): sh_audio_t and sh_video_t
This contains every parameter essential for decoding, such as input/output
buffers, chosen codec, fps, etc. There are each for every stream in
the file. At least one for video, if sound is present then another,
but if there are more, then there'll be one structure for each.
These are filled according to the header (avi/asf), or demux_mpg.c
does it (mpg) if it founds a new stream. If a new stream is found,
the ====> Found audio/video stream: <id> messages is displayed.
The chosen stream header and its demuxer are connected together
(ds->sh and sh->ds) to simplify the usage. So it's enough to pass the
ds or the sh, depending on the function.
For example: we have an asf file, 6 streams inside it, 1 audio, 5
video. During the reading of the header, 6 sh structs are created, 1
audio and 5 video. When it starts reading the packet, it chooses the
stream for the first found audio & video packet, and sets the sh
pointers of d_audio and d_video according to them. So later it reads
only these streams. Of course the user can force choosing a specific
stream with
-vid and -aid switches.
A good example for this is the DVD, where the english stream is not
always the first, so every VOB has different language :)
That's when we have to use for example the -aid 128 switch.
Now, how this reading works?
- demuxer.c/demux_read_data() is called, it gets how many bytes,
and where (memory address), would we like to read, and from which
DS. The codecs call this.
- this checks if the given DS's buffer contains something, if so, it
reads from there as much as needed. If there isn't enough, it calls
ds_fill_buffer(), which:
- checks if the given DS has buffered packages (DP's), if so, it moves
the oldest to the buffer, and reads on. If the list is empty, it
calls demux_fill_buffer() :
- this calls the parser for the input format, which reads the file
onward, and moves the found packages to their buffers.
Well it we'd like an audio package, but only a bunch of video
packages are available, then sooner or later the:
DEMUXER: Too many (%d in %d bytes) audio packets in the buffer
error shows up.
2.d. video.c: this file/function handle the reading and assembling of the
video frames. each call to video_read_frame() should read and return a
single video frame, and it's duration in seconds (float).
The implementation is splitted to 2 big parts - reading from mpeg-like
streams and reading from one-frame-per-chunk files (avi, asf, mov).
Then it calculates duration, either from fixed FPS value, or from the
PTS difference between and after reading the frame.
2.e. other utility functions: there are some useful code there, like
AVI muxer, or mp3 header parser, but leave them for now.
So everything is ok 'till now. It can be found in libmpdemux/ library.
It should compile outside of mplayer tree, you just have to implement few
simple functions, like mp_msg() to print messages, etc.
See libmpdemux/test.c for example.
See also formats.txt, for description of common media file formats and their
implementation details in libmpdemux.
Now, go on:
3. mplayer.c - ooh, he's the boss :)
Its main purpose is connecting the other modules, and maintaining A/V
sync.
The given stream's actual position is in the 'timer' field of the
corresponding stream header (sh_audio / sh_video).
The structure of the playing loop :
while(not EOF) {
fill audio buffer (read & decode audio) + increase a_frame
read & decode a single video frame + increase v_frame
sleep (wait until a_frame>=v_frame)
display the frame
apply A-V PTS correction to a_frame
handle events (keys,lirc etc) -> pause,seek,...
}
When playing (a/v), it increases the variables by the duration of the
played a/v.
- with audio this is played bytes / sh_audio->o_bps
Note: i_bps = number of compressed bytes for one second of audio
o_bps = number of uncompressed bytes for one second of audio
(this is = bps*samplerate*channels)
- with video this is usually == 1.0/fps, but I have to note that
fps doesn't really matters at video, for example asf doesn't have that,
instead there is "duration" and it can change per frame.
MPEG2 has "repeat_count" which delays the frame by 1-2.5 ...
Maybe only AVI and MPEG1 has fixed fps.
So everything works right until the audio and video are in perfect
synchronity, since the audio goes, it gives the timing, and if the
time of a frame passed, the next frame is displayed.
But what if these two aren't synchronized in the input file?
PTS correction kicks in. The input demuxers read the PTS (presentation
timestamp) of the packages, and with it we can see if the streams
are synchronized. Then MPlayer can correct the a_frame, within
a given maximal bounder (see -mc option). The summary of the
corrections can be found in c_total .
Of course this is not everything, several things suck.
For example the soundcards delay, which has to be corrected by
MPlayer! The audio delay is the sum of all these:
- bytes read since the last timestamp:
t1 = d_audio->pts_bytes/sh_audio->i_bps
- if Win32/ACM then the bytes stored in audio input buffer
t2 = a_in_buffer_len/sh_audio->i_bps
- uncompressed bytes in audio out buffer
t3 = a_buffer_len/sh_audio->o_bps
- not yet played bytes stored in the soundcard's (or DMA's) buffer
t4 = get_audio_delay()/sh_audio->o_bps
From this we can calculate what PTS we need for the just played
audio, then after we compare this with the video's PTS, we have
the difference!
Life didn't get simpler with AVI. There's the "official" timing
method, the BPS-based, so the header contains how many compressed
audio bytes or chunks belong to one second of frames.
In the AVI stream header there are 2 important fields, the
dwSampleSize, and dwRate/dwScale pairs:
- If the dwSampleSize is 0, then it's VBR stream, so its bitrate
isn't constant. It means that 1 chunk stores 1 sample, and
dwRate/dwScale gives the chunks/sec value.
- If the dwSampleSize is >0, then it's constant bitrate, and the
time can be measured this way: time = (bytepos/dwSampleSize) /
(dwRate/dwScale) (so the sample's number is divided with the
samplerate). Now the audio can be handled as a stream, which can
be cut to chunks, but can be one chunk also.
The other method can be used only for interleaved files: from
the order of the chunks, a timestamp (PTS) value can be calculated.
The PTS of the video chunks are simple: chunk number * fps
The audio is the same as the previous video chunk was.
We have to pay attention to the so called "audio preload", that is,
there is a delay between the audio and video streams. This is
usually 0.5-1.0 sec, but can be totally different.
The exact value was measured until now, but now the demux_avi.c
handles it: at the audio chunk after the first video, it calculates
the A/V difference, and take this as a measure for audio preload.
3.a. audio playback:
Some words on audio playback:
Not the playing is hard, but:
1. knowing when to write into the buffer, without blocking
2. knowing how much was played of what we wrote into
The first is needed for audio decoding, and to keep the buffer
full (so the audio will never skip). And the second is needed for
correct timing, because some soundcards delay even 3-7 seconds,
which can't be forgotten about.
To solve this, the OSS gives several possibilities:
- ioctl(SNDCTL_DSP_GETODELAY): tells how many unplayed bytes are in
the soundcard's buffer -> perfect for timing, but not all drivers
support it :(
- ioctl(SNDCTL_DSP_GETOSPACE): tells how much can we write into the
soundcard's buffer, without blocking. If the driver doesn't
support GETODELAY, we can use this to know how much the delay is.
- select(): should tell if we can write into the buffer without
blocking. Unfortunately it doesn't say how much we could :((
Also, doesn't/badly works with some drivers.
Only used if none of the above works.
4. Codecs. Consists of libmpcodecs/* and separate files or libs,
for example libmpeg2, loader, mp3lib.
mplayer.c doesn't call them directly, but through the dec_audio.c and
dec_video.c files, so the mplayer.c doesn't have to know anything about
the codecs.
libmpcodecs contains wrapper for every codecs, some of them include the
codec function implementation, some calls functions from other files
included with mplayer, some calls optional external libraries.
file naming convention in libmpcodecs:
ad_*.c - audio decoder (called through dec_audio.c)
vd_*.c - video decoder (called through dec_video.c)
ve_*.c - video encoder (used by mencoder)
vf_*.c - video filter (see option -vf)
On this topic, see also:
libmpcodecs.txt - The structure of the codec-filter path, with explanation
dr-methods.txt - Direct rendering, MPI buffer management for video codecs
codecs.conf.txt - How to write/edit codec configuration file (codecs.conf)
codec-devel.txt - Mike's hints about codec development - a bit OUTDATED
hwac3.txt - about SP/DIF audio passthrough
5. libvo: this displays the frame.
for details on this, read libvo.txt
6. libao2: this control audio playing
6.a audio plugins
for details on this, read libao2.txt
+145
View File
@@ -0,0 +1,145 @@
mails by A'rpi and Marcus Blomenkamp <Marcus.Blomenkamp@epost.de>
describing how this ac3-passtrough hack work under linux and mplayer...
-----------------------------------------------------------------------
Hi,
> I received the following patch from Steven Brookes <stevenjb@mda.co.uk>.
> He is working on fixing the digital audio output of the dxr3 driver and
> told me he fixed some bugs in mplayer along the way. I don't know shit
> about hwac3 output so all I did was to make sure the patch applied
> against latest cvs.
> This is from his e-mail to me:
>
> "Secondly there is a patch to dec_audio.c and
> ac3-iec958 to fix the -ac hwac3 codec stuff and to use liba52 to sync it.
> Seems to work for everything I've thrown at and maintains sync for all audio
> types through the DXR3."
patch applied (with some comments added and an unwanted change (in software
a52 decoder) removed)
now i understand how this whole hwac3 mess work.
it's very very tricky. it virtually decodes ac3 to LPCM packets, but really
it keeps the original compressed data padded by zeros. this way it's
constant bitrate, and sync is calculated just like for stereo PCM.
(so it bypass LPCM-capable media converters...)
so, every ac3 frame is translated to 6144 byte long tricky LPCM packet.
6144 = 4*(6*256) = 4 * samples_per_ac3_frame = LPCM size of uncompressed ac3
frame.
i wanna know if it works for sblive and other ac3-capable cards too?
(i can't test it, lack of ac3 decoder)
A'rpi / Astral & ESP-team
-----------------------------------------------------------------------
Hi folks.
I spend some time fiddling with ac3 passthrough in mplayer. The
traditional way of setting the output format to AFMT_AC3 was no ideal
solution since not all digital io cards/drivers supported this format or
honoured it to set the spdif non-audio bit. To make it short, it only
worked with oss sblive driver IIRC.
Inspired by alsa's ac3dec program I found an alternative way by
inspecting to which format the alsa device had been set. Suprise: it was
simple 16bit_le 2_channel pcm. So setting the non-audio bit doesn't
necessarily mean the point. The only important thing seems to be
bit-identical output at the correct samplerate. Modern AV-Receivers seem
to be quite tolerant/compatible.
So I changed the output format of hwac3 from
AFMT_AC3 channels=1
to
AFMT_S16_LE channels=2
and corrected the absolute time calculation. That was all to get it
running for me.
-----------------------------------------------------------------------
Hi there.
Perhaps I can clear up some mystification about AC3 passthrough in
general and mplayer in special:
To get the external decoder solution working, it must be fed with data
which is bitidentical to the chunks in the source ac3 file (compressed
data is very picky about bit errors). Additionally - or better to say
'historically' - the non-audio bit should be set in the spdif status
fields to prevent old spdif hardware from reproducing ugly scratchy
noise. Note: for current decoders (probably those with DTS capability)
this safety bit isn't needed anymore. At least I can state that for my
Sherwood RVD-6095RDS. I think it is due to DTS because DTS sound can
reside on a ordinary AudioCD and an ordinary AudioCD-Player will always
have it's audio-bit set.
The sample format of the data must be 2channel 16bit (little endian
IIRC). Samplerates are 48kHz - although my receiver also accepts
44100Hz. I do not know if this is due to an over-compatability of my
receiver or if 44100 is also possible in the ac3 specs. For safety's
sake lets keep this at 48000Hz. AC3 data chunks are inserted into the
stream every 0x1600 bytes (don't bite me on that, look into
'ac3-iec958.c': 'ac3_iec958_build_burst').
To come back to the problem: data must be played bit-identically through
the soundcard at the correct samplerate and should optionally have it's
non-audio bit set. There are two ways to accomplish this:
1) Some OSS guy invented the format AFMT_AC3. Soundcard drivers
implementing this format should therefore adjust it's mixers and
switches to produce the desired output. Unfortunately some soundcard
drivers do not support this format correctly and most do not even
support it at all (including ALSA).
2) The alternative approach currently in mplayer CVS is to simply set
the output format to 48kHz16bitLE and rely on the user to have the
soundcard mixers adjusted properly.
I do have two soundcards with digital IO facilities (CMI8738 and
Trident4DWaveNX based) plus the mentioned decoder. I'm currently running
Linux-2.4.17. Following configurations are happily running here:
1. Trident with ALSA drivers (OSS does not support Hoontech's dig. IO)
2. CMI with ALSA drivers
3. CMI with OSS drivers
For Linux I'd suggest using ALSA because of it's cleaner architecture
and more consitent user interface. Not to mention that it'll be the
standard sound support in Linux soon.
For those who want to stick to OSS drivers: The CMI8738 drivers works
out-of-the-box, if the PCM/Wave mixer is set to 100%.
For ALSA I'd suggest using its OSS emulation. More on that later.
ALSA-0.9 invented the idea of cards, devices and dubdevices. You can
reach the digital interface of all supported cards consitently by using
the device 'hw:x,2' (x counting from 0 is the number of your soundcard).
So most people would end up at 'hw:0,2'. This device can only be opened
in sample formats and rates which are directly supported in hardware
hence no samplerate conversion is done keeping the stream as-is. However
most consumer soundcards do not support 44kHz so it would definitively
be a bad idea to use this as your standard device if you wanted to
listen to some mp3s (most of them are 44kHz due to CD source). Here the
OSS comes to play again. You can configure which OSS device (/dev/dsp
and /dev/adsp) uses which ALSA device. So I'd suggest pointing the
standard '/dev/dsp' to standard 'hw:0,0' which suports mixing and
samplerate conversion. No further reconfiguration would be needed for
your sound apps. For movies I'd point '/dev/adsp' to 'hw:0,2' and
configure mplayer to use adsp instead of dsp. The samplerate constrain
is no big deal here since movies usually are in 48Khz anyway. The
configuration in '/etc/modules.conf' is no big deal also:
alias snd-card-0 snd-card-cmipci # insert your card here
alias snd-card-1 snd-pcm-oss # load OSS emulation
options snd-pcm-oss snd_dsp_map=0 snd_adsp_map=2 # do the mapping
This works flawlessly in combination with alsa's native
SysVrc-init-script 'alsasound'. Be sure to disable any distribution
dependent script (e.g. Mandrake-8.1 has an 'alsa' script which depends
on ALSA-0.5).
Sorry for you *BSD'lers out there. I have no grasp on sound support there.
HTH Marcus
+56
View File
@@ -0,0 +1,56 @@
6. libao2: this control audio playing
As in libvo (see 5.) also here are some drivers, based on the same API:
static int control(int cmd, int arg);
This is for reading/setting driver-specific and other special parameters.
Not really used for now.
static int init(int rate,int channels,int format,int flags);
The init of driver, opens device, sets sample rate, channels, sample format
parameters.
Sample format: usually AFMT_S16_LE or AFMT_U8, for more definitions see
dec_audio.c and linux/soundcards.h files!
static void uninit(void);
Guess what.
Ok I help: closes the device, not (yet) called when exit.
static void reset(void);
Resets device. To be exact, it's for deleting buffers' contents,
so after reset() the previously received stuff won't be output.
(called if pause or seek)
static int get_space(void);
Returns how many bytes can be written into the audio buffer without
blocking (making caller process wait). MPlayer occasionally checks the
remaining space and tries to fill the buffer with play() if there's free
space. The buffer size used should be sane; a buffer that is too small
could run empty before MPlayer tries filling it again (normally once per
video frame), a buffer that is too big would force MPlayer decode the file
far ahead trying to find enough audio data to fill it.
static int play(void* data,int len,int flags);
Plays a bit of audio, which is received throught the "data" memory area, with
a size of "len". It has to copy the data, because they can be overwritten
after the call is made. Doesn't have to use all the bytes; it has to
return the number of bytes used used (copied to buffer). If
flags|AOPLAY_FINAL_CHUNK is true then this is the last audio in the file.
The purpose of this flag is to tell aos that round down the audio played
from "len" to a multiple of some chunksize that this "len" should not be
rounded down to 0 or the data will never be played (as MPlayer will never
call play() with a larger len).
static float get_delay(void);
Returns how long time it will take to play the data currently in the
output buffer. Be exact, if possible, since the whole timing depends
on this! In the worst case, return the maximum delay.
!!! Because the video is synchronized to the audio (card), it's very important
!!! that the get_delay function is correctly implemented!
static void audio_pause(void);
Pause playing but do not delete buffered data if possible.
static void audio_resume(void);
Continue playing after audio_pause().
+173
View File
@@ -0,0 +1,173 @@
libvo --- the library to handle video output by A'rpi, 2002.04
============================================
Note: before start on this, read colorspaces.txt !
The constants for different pixelformats are defined in img_format.h,
their usage is mandatory.
WARNING: Please keep in mind that some of this information may be out-dated,
so if you are working on a new vo, consider submitting preliminary patches
very early on. Currently vo_gl is one of the more up-to-date VOs to use
as reference if you are unsure about something and do not want to ask on the
list.
vo_vdpau and vo_direct3d may be a good choice, too, they use different
approaches closer to the sometimes convoluted way DirectX works.
Each vo driver _has_ to implement these:
preinit():
init the video system (to support querying for supported formats)
uninit():
Uninit the whole system, this is on the same "level" as preinit.
control():
Current controls (VOCTRL_QUERY_FORMAT must be implemented,
VOCTRL_DRAW_IMAGE, VOCTRL_FULLSCREEN, VOCTRL_UPDATE_SCREENINFO
should be implemented):
VOCTRL_QUERY_FORMAT - queries if a given pixelformat is supported.
It also returns various flags decsirbing the capabilities
of the driver with teh given mode. for the flags, see
file vfcaps.h !
the most important flags, every driver must properly report
these:
0x1 - supported (with or without conversion)
0x2 - supported without conversion (define 0x1 too!)
0x100 - driver/hardware handles timing (blocking)
also SET sw/hw scaling and osd support flags, and flip,
and accept_stride if you implement VOCTRL_DRAW_IMAGE (see bellow)
NOTE: VOCTRL_QUERY_FORMAT may be called _before_ first config()
but is always called between preinit() and uninit()
VOCTRL_GET_IMAGE
libmpcodecs Direct Rendering interface
You need to update mpi (mp_image.h) structure, for example,
look at vo_x11, vo_sdl, vo_xv or mga_common.
VOCTRL_DRAW_IMAGE
replacement for the current draw_slice/draw_frame way of
passing video frames. by implementing SET_IMAGE, you'll get
image in mp_image struct instead of by calling draw_*.
unless you return VO_TRUE for VOCTRL_DRAW_IMAGE call, the
old-style draw_* functils will be called!
Note: draw_slice is still mandatory, for per-slice rendering!
VOCTRL_RESET - reset the video device
This is sent on seeking and similar and is useful if you are
using a device which prebuffers frames that need to flush them
before refilling audio/video buffers.
VOCTRL_PAUSE
VOCTRL_RESUME
VOCTRL_GUISUPPORT
return true only if driver supports co-operation with
MPlayer's GUI (not yet used by GUI)
VOCTRL_SET_EQUALIZER
set the video equalizer to the given values
two arguments are provided: item and value
item is a string, the possible values are (currently):
brightness, contrast, saturation, hue
VOCTRL_GET_EQUALIZER
get the current video equalizer values
two arguments are provided: item and value
item is a string, the possible values are (currently):
brightness, contrast, saturation, hue
VOCTRL_ONTOP
Makes the player window stay-on-top. Only supported (currently)
by drivers which use X11, except SDL, as well as directx and
gl2 under Windows.
VOCTRL_BORDER
Makes the player window borderless.
VOCTRL_FULLSCREEN
Switch from and to fullscreen mode
VOCTRL_GET_PANSCAN
VOCTRL_SET_PANSCAN
Needed to implement pan-scan support ('w' and 'e' keys during
playback in fullscreen mode)
VOCTRL_START_SLICE
Called before the first draw_slice of each frame, useful if
you need to do some set-up work.
VOCTRL_DRAW_EOSD
Required for EOSD (ASS subtitle) support. Provides all
information necessary to draw the EOSD for the current video
frame.
VOCTRL_GET_EOSD_RES
Required for EOSD (ASS subtitle) support. Informs the ASS
renderer about the properties of the drawing area (size,
borders).
VOCTRL_SET_DEINTERLACE
VOCTRL_GET_DEINTERLACE
Get or set deinterlacing status for VOs that support some kind
of deinterlacing.
VOCTRL_UPDATE_SCREENINFO
Should set the xinerama_x, xinerama_y, vo_screenwidth and
vo_screenheight appropriately for the currently used
monitor and -xineramascreen option.
Usually should simply call the w32_update_xinerama_info or
update_xinerama_info function.
By supporting this, the VO also requests the newer API
that sets vo_dx, vo_dy etc. appropriately before config()
is called.
config():
Set up the video system. You get the dimensions and flags.
width, height: size of the source image
d_width, d_height: wanted scaled/display size (it's a hint)
Flags:
0x01 - force fullscreen (-fs)
0x02 - allow mode switching (-vm)
0x04 - allow software scaling (-zoom)
0x08 - flipping (-flip)
They're defined as VOFLAG_* (see libvo/video_out.h)
IMPORTANT NOTE: config() may be called 0 (zero), 1 or more (2,3...)
times between preinit() and uninit() calls. You MUST handle it, and
you shouldn't crash at second config() call or at uninit() without
any config() call! To make your life easier, vo_config_count is
set to the number of previous config() call, counted from preinit().
It's set by the caller (vf_vo.c), you don't have to increase it!
So, you can check for vo_config_count>0 in uninit() when freeing
resources allocated in config() to avoid crash!
You should implement VOCTRL_UPDATE_SCREENINFO so that vo_dx, vo_dy,
vo_dwidth and vo_dheight are already pre-set to values that take
aspect and -geometry into account. It is also necessary to properly
support multi-monitor setups (if based on x11_common, w32_common).
draw_slice(): this displays YV12 pictures (3 planes, one full sized that
contains brightness (Y), and 2 quarter-sized which the colour-info
(U,V). MPEG codecs (libmpeg2, opendivx) use this. This doesn't have
to display the whole frame, only update small parts of it.
If this is not supported, it must be signaled in QUERY_FORMAT with
VOCAP_NOSLICES.
draw_frame(): this is the older interface, this displays only complete
frames, and can do only packed format (YUY2, RGB/BGR).
Win32 codecs use this (DivX, Indeo, etc).
If you implement VOCTRL_DRAW_IMAGE, you do not need to implement draw_frame.
draw_osd(): this displays subtitles and OSD.
It's a bit tricky to use it, since it's a callback-style stuff.
It should call vo_draw_text() with screen dimension and your
draw_alpha implementation for the pixelformat (function pointer).
The vo_draw_text() checks the characters to draw, and calls
draw_alpha() for each. As a help, osd.c contains draw_alpha for
each pixelformats, use this if possible!
Note that if you do not draw directly onto the video you should
use vo_draw_text_ext() which allows you to specify the border
values etc. needed to draw DVD menu highlights at the correct place.
If you do not want to implement this, you can still use -vf
expand=osd=1 to draw the OSD, or even implement code to insert
this filter automatically.
Make sure you set VFCAP_OSD depending on whether you implemented it
or not.
NOTE: This one will be obsolete soon! But it's still useful when
you want to do tricks, like rendering osd _after_ hardware scaling
(tdfxfb) or render subtitles under of the image (vo_mpegpes, sdl)
NOTE2: above NOTE is probably wrong, there are currently no plans to
obsolete draw_osd, though there is the more advanced EOSD support for
ASS subtitles.
flip_page(): this is called after each frame, this displays the buffer for
real. This is 'swapbuffers' when doublebuffering.
Try to do as little work here as possible, since that affect jitter/
A-V sync.
+100
View File
@@ -0,0 +1,100 @@
TITLE=Weird Al Yankovic - The Saga Begins (clip)
# just to be informative (maybe future
# use?)
FILE=14233792,7972c637f619e01854ecb453b7339e3f # size,md5
AUTHOR=Gabucino
TYPE=VIDEO # maybe AUDIO in future (for displaying
# mp3 lyrics while playing or whatever)
FORMAT=TIME # this file contains measures based on
# TIME, not frames.
# if FORMAT is a number, then it's frame based, i.e.:
# FORMAT=25
NOTE=MPlayerSub test file v0.1
# first number : wait this much after previous subtitle disappeared
# second number : display the current subtitle for this many seconds
15 3
A long, long time ago...
0 3
in a galaxy far away...
0 3
Naboo was under an attack.
1 2.5
And I thought me and
Qui-Gon Jinn could
0 2.5
talk the Federation into
0 4
...maybe cutting them a
little slack.
2 3
But their response, it
didn't thrill us,
0 3
They locked the doors,
and tried to kill us.
0 2.5
We escaped from that gas,
0 3.5
then met Jar-jar and
Boss-Nass.
1 6
We took a bongo from the
scene and we went to
Theed to see the Queen.
0 5
We all wound' up on
Tatooine.
0 6
That's where, we've found
this boy.
0 4
Oh my, my this here
Anakin guy,
0 5
maybe Vader someday
later now he's just
a small fry.
0 4
And he left his home and
kissed his mommy goodbye,
0 5
singing "Soon I'm gonna be
a Jedi!"
6 6
Did you know this junkyard
slave isn't even old enough
to shave,
0 3
but he can use the Force,
they say.
1 6
Ahh, do you see him hitting
on the queen though he's
just nine and she's fourteen
0 6
yeah, he's probably gonna
marry her, someday!
+19
View File
@@ -0,0 +1,19 @@
software scaler filter docs
-ssf cgb=<float> chrominance gaussian blur
useful for videos with some chroma (color) noise (TV captures, VHS, ...)
-ssf lgb=<float> -> luminance gaussian blur
hmm, mostly special effect, could be used as lame noise reducer though
-ssf chs=<int> -> shift chrominance horizontally
-ssf cvs=<int> -> shift chrominance vertically
useful if the luma & chroma are not aligned exactly
-ssf cs=<float> -> chrominance sharpen
-ssf ls=<float> -> luminance sharpen
simple sharpening filter
note: these will only work if the swscaler is used at all (use -vf scale)
example: mplayer foobar.avi -vf scale -ssf lgb=3.0
+68
View File
@@ -0,0 +1,68 @@
artifact types:
---------------------------------------------------------------------
ringing
wave or noise like patterns around sharp edges
bad: sinc, lanczos (with high filter length)
acceptable: lanczos (with low filter length), cubic, spline
ok: area, (fast)blinear, gauss, point
blur
loss of detail / high frequency
bad: gauss with high variance
acceptable: (fast)bilinear, area
ok: others
aliasing (only downscale)
straight lines look like staircases
areas of high detail look worse
regular patterns turn into a funny looking mess (moire patterns)
bad: fast bilinear, point, gauss with low variance
acceptable: area
ok: others
blocky (upscale only)
looks like the image is made of rectangular blocks like a mosaic
bad: point
ok: others
recommendations: (based upon my personal opinion many ppl might disagree ...)
---------------------------------------------------------------------
the recommended scalers for upscaling:
fast_bilinear, point if speed is important
cubic, spline, lanczos if quality is important
the recommended scalers for downscaling:
fast_bilinear, point if speed is important
gauss, bilinear if quality is important
cubic, spline, lanczos if a sharper picture is important
note: when encoding at a limited amount of bits (not constant quantizer)
then a slightly blurred input might look better after decoding than a slightly
sharpened one, especially for lower bitrates
sws numbers / names / artifact types
-------------------------------------------------------------------------
r ringing
b blurry
a aliasing (downscale only)
m mosaic (blocky) (upscale only)
-sws 0 fast bilinear bA
-sws 1 bilinear b
-sws 2 bicubic high sharpness r
low sharpness b
-sws 3 experimental ????
-sws 4 nearest neighbour AM
-sws 5 area ba
-sws 6 luma bicubic / chroma bilinear r
-sws 7 gauss low sharpness B
high sharpness AM
-sws 8 sinc R
-sws 9 lanczos long filter R
short filter b
-sws 10 bicubic spline r
Notes:
area upscale is identical to bilinear
-96
View File
@@ -1,96 +0,0 @@
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.
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),
while C API additions bump the minor version (i.e. the second number is
increased). Changes to properties/commands/options may also lead to a minor
version bump, in particular if they are incompatible.
The version number is the same as used for MPV_CLIENT_API_VERSION (see
``client.h`` how to convert between major/minor version numbers and the flat
32 bit integer).
Also, read the section ``Compatibility`` in ``client.h``.
API changes
===========
::
1.17 - add MPV_FORMAT_BYTE_ARRAY
--- mpv 0.9.0 will be released ---
1.16 - add mpv_opengl_cb_report_flip()
- introduce mpv_opengl_cb_draw() and deprecate mpv_opengl_cb_render()
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 ---
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)
1.13 - add MPV_EVENT_QUEUE_OVERFLOW
1.12 - add class Handle to qthelper.hpp
- improve opengl_cb.h API uninitialization behavior, and fix the qml
example
- add mpv_create_client() function
1.11 - add OpenGL rendering interop API - allows an application to combine
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 ---
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
- add MPV_END_FILE_REASON_ERROR and the mpv_event_end_file.error field
for slightly better error reporting on playback failure
- add --stop-playback-on-init-failure option, and make it the default
behavior for libmpv only
- add qthelper.hpp set_option_variant()
- mark the following events as deprecated:
MPV_EVENT_TRACKS_CHANGED
MPV_EVENT_TRACK_SWITCHED
MPV_EVENT_PAUSE
MPV_EVENT_UNPAUSE
MPV_EVENT_METADATA_UPDATE
MPV_EVENT_CHAPTER_CHANGE
They are handled better with mpv_observe_property() as mentioned in
the documentation comments. They are not removed and still work.
1.8 - add qthelper.hpp
1.7 - add mpv_command_node(), mpv_command_node_async()
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 ---
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
measure until XEmbed is implemented and confirmed working.
Note: in 1.6, "input-x11-keyboard" was renamed to "input-vo-keyboard",
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 ---
1.3 - add MPV_MAKE_VERSION()
1.2 - remove "stream-time-pos" property (no replacement)
1.1 - remap dvdnav:// to dvd://
- add "--cache-file", "--cache-file-size"
- add "--colormatrix-primaries" (and property)
- add "primaries" sub-field to image format properties
- add "playback-time" property
- extend the "--start" option; a leading "+", which was previously
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 ---
1.0 - the API is declared stable
-14
View File
@@ -1,14 +0,0 @@
All examples in this directory and its sub-directories are licensed
under one of the following licenses:
WTFPL, ISC, Ms-PL, AGPLv3, BSD (any)
Pick any license of your liking, and disregard the others.
(The full text of each license is available on this website:
http://opensource.org/licenses/alphabetical )
Additionally, you may consider the example code to be public domain.
You are free to use any of the example code without further
requirements or need for attribution.
-30
View File
@@ -1,30 +0,0 @@
Client API examples
===================
All these examples use the mpv client API through libmpv.
cocoa
-----
Shows how to embed the mpv video window in Objective-C/Cocoa.
qt
--
Shows how to embed the mpv video window in Qt (using normal desktop widgets).
qml
---
Shows how to use mpv's OpenGL video renderer in QtQuick2 with QML.
qml_direct
----------
Alternative example, which typically avoids a FBO indirection. Might be
slightly faster, but is less flexible and harder to use.
simple
------
Very primitive terminal-only example. Shows some most basic API usage.
-211
View File
@@ -1,211 +0,0 @@
// 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.
// Build with: clang -o cocoabasic cocoabasic.m `pkg-config --libs --cflags mpv`
#include <mpv/client.h>
#include <stdio.h>
#include <stdlib.h>
static inline void check_error(int status)
{
if (status < 0) {
printf("mpv API error: %s\n", mpv_error_string(status));
exit(1);
}
}
#import <Cocoa/Cocoa.h>
@interface CocoaWindow : NSWindow
@end
@implementation CocoaWindow
- (BOOL)canBecomeMainWindow { return YES; }
- (BOOL)canBecomeKeyWindow { return YES; }
@end
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
mpv_handle *mpv;
dispatch_queue_t queue;
NSWindow *w;
NSView *wrapper;
}
@end
static void wakeup(void *);
@implementation AppDelegate
- (void)createWindow {
int mask = NSTitledWindowMask|NSClosableWindowMask|
NSMiniaturizableWindowMask|NSResizableWindowMask;
self->w = [[CocoaWindow alloc]
initWithContentRect:NSMakeRect(0,0, 1280, 720)
styleMask:mask
backing:NSBackingStoreBuffered
defer:NO];
[self->w setTitle:@"cocoabasic example"];
[self->w makeMainWindow];
[self->w makeKeyAndOrderFront:nil];
NSRect frame = [[self->w contentView] bounds];
self->wrapper = [[NSView alloc] initWithFrame:frame];
[self->wrapper setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
[[self->w contentView] addSubview:self->wrapper];
[self->wrapper release];
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: @"mpv_command('stop')" action:@selector(mpv_stop) keyEquivalent:@""];
[sm addItemWithTitle: @"mpv_command('quit')" action:@selector(mpv_quit) keyEquivalent:@""];
[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];
// Deal with MPV in the background.
queue = dispatch_queue_create("mpv", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
mpv = mpv_create();
if (!mpv) {
printf("failed creating context\n");
exit(1);
}
int64_t wid = (intptr_t) self->wrapper;
check_error(mpv_set_option(mpv, "wid", MPV_FORMAT_INT64, &wid));
// Maybe set some options here, like default key bindings.
// NOTE: Interaction with the window seems to be broken for now.
check_error(mpv_set_option_string(mpv, "input-default-bindings", "yes"));
// for testing!
check_error(mpv_set_option_string(mpv, "input-media-keys", "yes"));
check_error(mpv_set_option_string(mpv, "input-cursor", "no"));
check_error(mpv_set_option_string(mpv, "input-vo-keyboard", "yes"));
// request important errors
check_error(mpv_request_log_messages(mpv, "warn"));
check_error(mpv_initialize(mpv));
// 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));
});
}
- (void) handleEvent:(mpv_event *)event
{
switch (event->event_id) {
case MPV_EVENT_SHUTDOWN: {
mpv_detach_destroy(mpv);
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);
}
case MPV_EVENT_VIDEO_RECONFIG: {
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *subviews = [self->wrapper subviews];
if ([subviews count] > 0) {
// mpv's events view
NSView *eview = [self->wrapper subviews][0];
[self->w makeFirstResponder:eview];
}
});
}
default:
printf("event: %s\n", mpv_event_name(event->event_id));
}
}
- (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];
}
// Ostensibly, mpv's window would be hooked up to this.
- (BOOL) windowShouldClose:(id)sender
{
return NO;
}
- (void) mpv_stop
{
if (mpv) {
const char *args[] = {"stop", NULL};
mpv_command(mpv, args);
}
}
- (void) mpv_quit
{
if (mpv) {
const char *args[] = {"quit", NULL};
mpv_command(mpv, args);
}
}
@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 EXIT_SUCCESS;
}
-136
View File
@@ -1,136 +0,0 @@
#include "main.h"
#include <stdexcept>
#include <clocale>
#include <QObject>
#include <QtGlobal>
#include <QOpenGLContext>
#include <QGuiApplication>
#include <QtGui/QOpenGLFramebufferObject>
#include <QtQuick/QQuickWindow>
#include <QtQuick/QQuickView>
class MpvRenderer : public QQuickFramebufferObject::Renderer
{
static void *get_proc_address(void *ctx, const char *name) {
(void)ctx;
QOpenGLContext *glctx = QOpenGLContext::currentContext();
if (!glctx)
return NULL;
return (void *)glctx->getProcAddress(QByteArray(name));
}
mpv::qt::Handle mpv;
QQuickWindow *window;
mpv_opengl_cb_context *mpv_gl;
public:
MpvRenderer(const MpvObject *obj)
: mpv(obj->mpv), window(obj->window()), mpv_gl(obj->mpv_gl)
{
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");
}
virtual ~MpvRenderer()
{
// 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 render()
{
QOpenGLFramebufferObject *fbo = framebufferObject();
window->resetOpenGLState();
mpv_opengl_cb_draw(mpv_gl, fbo->handle(), fbo->width(), fbo->height());
window->resetOpenGLState();
}
};
MpvObject::MpvObject(QQuickItem * parent)
: QQuickFramebufferObject(parent), mpv_gl(0)
{
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");
// Setup the callback that will make QtQuick update and redraw if there
// is a new video frame. Use a queued connection: this makes sure the
// doUpdate() function is run on the GUI thread.
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, MpvObject::on_update, (void *)this);
connect(this, &MpvObject::onUpdate, this, &MpvObject::doUpdate,
Qt::QueuedConnection);
}
MpvObject::~MpvObject()
{
if (mpv_gl)
mpv_opengl_cb_set_update_callback(mpv_gl, NULL, NULL);
}
void MpvObject::on_update(void *ctx)
{
MpvObject *self = (MpvObject *)ctx;
emit self->onUpdate();
}
// connected to onUpdate(); signal makes sure it runs on the GUI thread
void MpvObject::doUpdate()
{
update();
}
void MpvObject::command(const QVariant& params)
{
mpv::qt::command_variant(mpv, params);
}
void MpvObject::setProperty(const QString& name, const QVariant& value)
{
mpv::qt::set_property_variant(mpv, name, value);
}
QQuickFramebufferObject::Renderer *MpvObject::createRenderer() const
{
window()->setPersistentOpenGLContext(true);
window()->setPersistentSceneGraph(true);
return new MpvRenderer(this);
}
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
// Qt sets the locale in the QGuiApplication constructor, but libmpv
// requires the LC_NUMERIC category to be set to "C", so change it back.
std::setlocale(LC_NUMERIC, "C");
qmlRegisterType<MpvObject>("mpvtest", 1, 0, "MpvObject");
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setSource(QUrl("qrc:///mpvtest/main.qml"));
view.show();
return app.exec();
}
-36
View File
@@ -1,36 +0,0 @@
#ifndef MPVRENDERER_H_
#define MPVRENDERER_H_
#include <QtQuick/QQuickFramebufferObject>
#include <mpv/client.h>
#include <mpv/opengl_cb.h>
#include <mpv/qthelper.hpp>
class MpvRenderer;
class MpvObject : public QQuickFramebufferObject
{
Q_OBJECT
mpv::qt::Handle mpv;
mpv_opengl_cb_context *mpv_gl;
friend class MpvRenderer;
public:
MpvObject(QQuickItem * parent = 0);
virtual ~MpvObject();
virtual Renderer *createRenderer() const;
public slots:
void command(const QVariant& params);
void setProperty(const QString& name, const QVariant& value);
signals:
void onUpdate();
private slots:
void doUpdate();
private:
static void on_update(void *ctx);
};
#endif
-71
View File
@@ -1,71 +0,0 @@
import QtQuick 2.0
import QtQuick.Controls 1.0
import mpvtest 1.0
Item {
width: 1280
height: 720
MpvObject {
id: renderer
anchors.fill: parent
MouseArea {
anchors.fill: parent
onClicked: renderer.command(["loadfile", "../../../test.mkv"])
}
}
Rectangle {
id: labelFrame
anchors.margins: -50
radius: 5
color: "white"
border.color: "black"
opacity: 0.8
anchors.fill: box
}
Row {
id: box
anchors.bottom: renderer.bottom
anchors.left: renderer.left
anchors.right: renderer.right
anchors.margins: 100
Text {
anchors.margins: 10
wrapMode: Text.WordWrap
text: "QtQuick and mpv are both rendering stuff.\n
Click to load ../../../test.mkv"
}
// Don't take these controls too seriously. They're for testing.
Column {
CheckBox {
id: checkbox
anchors.margins: 10
// Heavily filtered means good, right?
text: "Make video look like on a Smart TV"
onClicked: {
if (checkbox.checked) {
renderer.command(["vo_cmdline", "scale=sharpen3:scale-param1=5.0"])
} else {
renderer.command(["vo_cmdline", ""])
}
}
}
Slider {
id: slider
anchors.margins: 10
anchors.left: checkbox.left
anchors.right: checkbox.right
minimumValue: -100
maximumValue: 100
value: 0
onValueChanged: renderer.setProperty("gamma", slider.value | 0)
}
}
}
}
-11
View File
@@ -1,11 +0,0 @@
QT += qml quick
HEADERS += main.h
SOURCES += main.cpp
CONFIG += link_pkgconfig debug
PKGCONFIG += mpv
RESOURCES += mpvtest.qrc
OTHER_FILES += main.qml
-5
View File
@@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/mpvtest">
<file>main.qml</file>
</qresource>
</RCC>
@@ -1,159 +0,0 @@
#include "main.h"
#include <stdexcept>
#include <clocale>
#include <QObject>
#include <QtGlobal>
#include <QOpenGLContext>
#include <QGuiApplication>
#include <QtQuick/QQuickWindow>
#include <QtQuick/QQuickView>
static void *get_proc_address(void *ctx, const char *name) {
(void)ctx;
QOpenGLContext *glctx = QOpenGLContext::currentContext();
if (!glctx)
return NULL;
return (void *)glctx->getProcAddress(QByteArray(name));
}
MpvRenderer::MpvRenderer(mpv::qt::Handle a_mpv, mpv_opengl_cb_context *a_mpv_gl)
: mpv(a_mpv), mpv_gl(a_mpv_gl), window(0), size()
{
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");
}
MpvRenderer::~MpvRenderer()
{
// 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 MpvRenderer::paint()
{
window->resetOpenGLState();
// This uses 0 as framebuffer, which indicates that mpv will render directly
// to the frontbuffer. Note that mpv will always switch framebuffers
// explicitly. Some QWindow setups (such as using QQuickWidget) actually
// want you to render into a FBO in the beforeRendering() signal, and this
// code won't work there.
// The negation is used for rendering with OpenGL's flipped coordinates.
mpv_opengl_cb_draw(mpv_gl, 0, size.width(), -size.height());
window->resetOpenGLState();
}
MpvObject::MpvObject(QQuickItem * parent)
: QQuickItem(parent), mpv_gl(0), renderer(0)
{
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");
// Setup the callback that will make QtQuick update and redraw if there
// is a new video frame. Use a queued connection: this makes sure the
// doUpdate() function is run on the GUI thread.
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, MpvObject::on_update, (void *)this);
connect(this, &MpvObject::onUpdate, this, &MpvObject::doUpdate,
Qt::QueuedConnection);
connect(this, &QQuickItem::windowChanged,
this, &MpvObject::handleWindowChanged);
}
MpvObject::~MpvObject()
{
if (mpv_gl)
mpv_opengl_cb_set_update_callback(mpv_gl, NULL, NULL);
}
void MpvObject::handleWindowChanged(QQuickWindow *win)
{
if (!win)
return;
connect(win, &QQuickWindow::beforeSynchronizing,
this, &MpvObject::sync, Qt::DirectConnection);
connect(win, &QQuickWindow::sceneGraphInvalidated,
this, &MpvObject::cleanup, Qt::DirectConnection);
connect(win, &QQuickWindow::frameSwapped,
this, &MpvObject::swapped, Qt::DirectConnection);
win->setClearBeforeRendering(false);
}
void MpvObject::sync()
{
if (!renderer) {
renderer = new MpvRenderer(mpv, mpv_gl);
connect(window(), &QQuickWindow::beforeRendering,
renderer, &MpvRenderer::paint, Qt::DirectConnection);
}
renderer->window = window();
renderer->size = window()->size() * window()->devicePixelRatio();
}
void MpvObject::swapped()
{
mpv_opengl_cb_report_flip(mpv_gl, 0);
}
void MpvObject::cleanup()
{
if (renderer) {
delete renderer;
renderer = 0;
}
}
void MpvObject::on_update(void *ctx)
{
MpvObject *self = (MpvObject *)ctx;
emit self->onUpdate();
}
// connected to onUpdate(); signal makes sure it runs on the GUI thread
void MpvObject::doUpdate()
{
window()->update();
}
void MpvObject::command(const QVariant& params)
{
mpv::qt::command_variant(mpv, params);
}
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
// Qt sets the locale in the QGuiApplication constructor, but libmpv
// requires the LC_NUMERIC category to be set to "C", so change it back.
std::setlocale(LC_NUMERIC, "C");
qmlRegisterType<MpvObject>("mpvtest", 1, 0, "MpvObject");
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setSource(QUrl("qrc:///mpvtest/main.qml"));
view.show();
return app.exec();
}
@@ -1,51 +0,0 @@
#ifndef MPVRENDERER_H_
#define MPVRENDERER_H_
#include <QtQuick/QQuickItem>
#include <mpv/client.h>
#include <mpv/opengl_cb.h>
#include <mpv/qthelper.hpp>
class MpvRenderer : public QObject
{
Q_OBJECT
mpv::qt::Handle mpv;
mpv_opengl_cb_context *mpv_gl;
QQuickWindow *window;
QSize size;
friend class MpvObject;
public:
MpvRenderer(mpv::qt::Handle a_mpv, mpv_opengl_cb_context *a_mpv_gl);
virtual ~MpvRenderer();
public slots:
void paint();
};
class MpvObject : public QQuickItem
{
Q_OBJECT
mpv::qt::Handle mpv;
mpv_opengl_cb_context *mpv_gl;
MpvRenderer *renderer;
public:
MpvObject(QQuickItem * parent = 0);
virtual ~MpvObject();
public slots:
void command(const QVariant& params);
void sync();
void swapped();
void cleanup();
signals:
void onUpdate();
private slots:
void doUpdate();
void handleWindowChanged(QQuickWindow *win);
private:
static void on_update(void *ctx);
};
#endif
@@ -1,49 +0,0 @@
import QtQuick 2.0
import QtQuick.Controls 1.0
import mpvtest 1.0
Item {
width: 1280
height: 720
MpvObject {
id: renderer
// This object isn't real and not visible; it just renders into the
// background of the containing Window.
width: 0
height: 0
}
MouseArea {
anchors.fill: parent
onClicked: renderer.command(["loadfile", "../../../test.mkv"])
}
Rectangle {
id: labelFrame
anchors.margins: -50
radius: 5
color: "white"
border.color: "black"
opacity: 0.8
anchors.fill: box
}
Row {
id: box
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 100
Text {
anchors.margins: 10
wrapMode: Text.WordWrap
text: "QtQuick and mpv are both rendering stuff.\n
In this example, mpv is always in the background.\n
Click to load ../../../test.mkv"
}
}
}
@@ -1,11 +0,0 @@
QT += qml quick
HEADERS += main.h
SOURCES += main.cpp
CONFIG += link_pkgconfig debug
PKGCONFIG += mpv
RESOURCES += mpvtest.qrc
OTHER_FILES += main.qml
@@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/mpvtest">
<file>main.qml</file>
</qresource>
</RCC>
-225
View File
@@ -1,225 +0,0 @@
// This example can be built with: qmake && make
#include <clocale>
#include <sstream>
#include <stdexcept>
#include <QtGlobal>
#include <QFileDialog>
#include <QStatusBar>
#include <QMenuBar>
#include <QMenu>
#include <QGridLayout>
#include <QApplication>
#include <QTextEdit>
#if QT_VERSION >= 0x050000
#include <QJsonDocument>
#endif
#include <mpv/qthelper.hpp>
#include "qtexample.h"
static void wakeup(void *ctx)
{
// This callback is invoked from any mpv thread (but possibly also
// recursively from a thread that is calling the mpv API). Just notify
// the Qt GUI thread to wake up (so that it can process events with
// mpv_wait_event()), and return as quickly as possible.
MainWindow *mainwindow = (MainWindow *)ctx;
emit mainwindow->mpv_events();
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setWindowTitle("Qt embedding demo");
setMinimumSize(640, 480);
QMenu *menu = menuBar()->addMenu(tr("&File"));
QAction *on_open = new QAction(tr("&Open"), this);
on_open->setShortcuts(QKeySequence::Open);
on_open->setStatusTip(tr("Open a file"));
connect(on_open, &QAction::triggered, this, &MainWindow::on_file_open);
menu->addAction(on_open);
QAction *on_new = new QAction(tr("&New window"), this);
connect(on_new, &QAction::triggered, this, &MainWindow::on_new_window);
menu->addAction(on_new);
statusBar();
QMainWindow *log_window = new QMainWindow(this);
log = new QTextEdit(log_window);
log->setReadOnly(true);
log_window->setCentralWidget(log);
log_window->setWindowTitle("mpv log window");
log_window->setMinimumSize(500, 50);
log_window->show();
mpv = mpv_create();
if (!mpv)
throw std::runtime_error("can't create mpv instance");
// Create a video child window. Force Qt to create a native window, and
// pass the window ID to the mpv wid option. Works on: X11, win32, Cocoa
mpv_container = new QWidget(this);
setCentralWidget(mpv_container);
mpv_container->setAttribute(Qt::WA_DontCreateNativeAncestors);
mpv_container->setAttribute(Qt::WA_NativeWindow);
// If you have a HWND, use: int64_t wid = (intptr_t)hwnd;
int64_t wid = mpv_container->winId();
mpv_set_option(mpv, "wid", MPV_FORMAT_INT64, &wid);
// Enable default bindings, because we're lazy. Normally, a player using
// mpv as backend would implement its own key bindings.
mpv_set_option_string(mpv, "input-default-bindings", "yes");
// Enable keyboard input on the X11 window. For the messy details, see
// --input-vo-keyboard on the manpage.
mpv_set_option_string(mpv, "input-vo-keyboard", "yes");
// Let us receive property change events with MPV_EVENT_PROPERTY_CHANGE if
// this property changes.
mpv_observe_property(mpv, 0, "time-pos", MPV_FORMAT_DOUBLE);
mpv_observe_property(mpv, 0, "track-list", MPV_FORMAT_NODE);
mpv_observe_property(mpv, 0, "chapter-list", MPV_FORMAT_NODE);
// Request log messages with level "info" or higher.
// They are received as MPV_EVENT_LOG_MESSAGE.
mpv_request_log_messages(mpv, "info");
// From this point on, the wakeup function will be called. The callback
// can come from any thread, so we use the QueuedConnection mechanism to
// relay the wakeup in a thread-safe way.
connect(this, &MainWindow::mpv_events, this, &MainWindow::on_mpv_events,
Qt::QueuedConnection);
mpv_set_wakeup_callback(mpv, wakeup, this);
if (mpv_initialize(mpv) < 0)
throw std::runtime_error("mpv failed to initialize");
}
void MainWindow::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;
std::stringstream ss;
ss << "At: " << time;
statusBar()->showMessage(QString::fromStdString(ss.str()));
} else if (prop->format == MPV_FORMAT_NONE) {
// The property is unavailable, which probably means playback
// was stopped.
statusBar()->showMessage("");
}
} else if (strcmp(prop->name, "chapter-list") == 0 ||
strcmp(prop->name, "track-list") == 0)
{
// Dump the properties as JSON for demo purposes.
#if QT_VERSION >= 0x050000
if (prop->format == MPV_FORMAT_NODE) {
QVariant v = mpv::qt::node_to_variant((mpv_node *)prop->data);
// Abuse JSON support for easily printing the mpv_node contents.
QJsonDocument d = QJsonDocument::fromVariant(v);
append_log("Change property " + QString(prop->name) + ":\n");
append_log(d.toJson().data());
}
#endif
}
break;
}
case MPV_EVENT_VIDEO_RECONFIG: {
// Retrieve the new video size.
int64_t w, h;
if (mpv_get_property(mpv, "dwidth", MPV_FORMAT_INT64, &w) >= 0 &&
mpv_get_property(mpv, "dheight", MPV_FORMAT_INT64, &h) >= 0 &&
w > 0 && h > 0)
{
// Note that the MPV_EVENT_VIDEO_RECONFIG event doesn't necessarily
// imply a resize, and you should check yourself if the video
// dimensions really changed.
// mpv itself will scale/letter box the video to the container size
// if the video doesn't fit.
std::stringstream ss;
ss << "Reconfig: " << w << " " << h;
statusBar()->showMessage(QString::fromStdString(ss.str()));
}
break;
}
case MPV_EVENT_LOG_MESSAGE: {
struct mpv_event_log_message *msg = (struct mpv_event_log_message *)event->data;
std::stringstream ss;
ss << "[" << msg->prefix << "] " << msg->level << ": " << msg->text;
append_log(QString::fromStdString(ss.str()));
break;
}
case MPV_EVENT_SHUTDOWN: {
mpv_terminate_destroy(mpv);
mpv = NULL;
break;
}
default: ;
// Ignore uninteresting or unknown events.
}
}
// This slot is invoked by wakeup() (through the mpv_events signal).
void MainWindow::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 MainWindow::on_file_open()
{
QString filename = QFileDialog::getOpenFileName(this, "Open file");
if (mpv) {
const QByteArray c_filename = filename.toUtf8();
const char *args[] = {"loadfile", c_filename.data(), NULL};
mpv_command_async(mpv, 0, args);
}
}
void MainWindow::on_new_window()
{
(new MainWindow())->show();
}
void MainWindow::append_log(const QString &text)
{
QTextCursor cursor = log->textCursor();
cursor.movePosition(QTextCursor::End);
cursor.insertText(text);
log->setTextCursor(cursor);
}
MainWindow::~MainWindow()
{
if (mpv)
mpv_terminate_destroy(mpv);
}
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.
std::setlocale(LC_NUMERIC, "C");
MainWindow w;
w.show();
return a.exec();
}
-37
View File
@@ -1,37 +0,0 @@
#ifndef QTEXAMPLE_H
#define QTEXAMPLE_H
#include <QMainWindow>
#include <mpv/client.h>
class QTextEdit;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_file_open();
void on_new_window();
void on_mpv_events();
signals:
void mpv_events();
private:
QWidget *mpv_container;
mpv_handle *mpv;
QTextEdit *log;
void append_log(const QString &text);
void create_player();
void handle_mpv_event(mpv_event *event);
};
#endif // QTEXAMPLE_H
-12
View File
@@ -1,12 +0,0 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = qtexample
TEMPLATE = app
CONFIG += link_pkgconfig debug
PKGCONFIG += mpv
SOURCES += qtexample.cpp
HEADERS += qtexample.h
-54
View File
@@ -1,54 +0,0 @@
// Build with: gcc -o simple simple.c `pkg-config --libs --cflags mpv`
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <mpv/client.h>
static inline void check_error(int status)
{
if (status < 0) {
printf("mpv API error: %s\n", mpv_error_string(status));
exit(1);
}
}
int main(int argc, char *argv[])
{
if (argc != 2) {
printf("pass a single media file as argument\n");
return 1;
}
mpv_handle *ctx = mpv_create();
if (!ctx) {
printf("failed creating context\n");
return 1;
}
// Enable default key bindings, so the user can actually interact with
// the player (and e.g. close the window).
check_error(mpv_set_option_string(ctx, "input-default-bindings", "yes"));
mpv_set_option_string(ctx, "input-vo-keyboard", "yes");
int val = 1;
check_error(mpv_set_option(ctx, "osc", MPV_FORMAT_FLAG, &val));
// Done setting up options.
check_error(mpv_initialize(ctx));
// Play this file.
const char *cmd[] = {"loadfile", argv[1], NULL};
check_error(mpv_command(ctx, cmd));
// Let it play, and wait until the user quits.
while (1) {
mpv_event *event = mpv_wait_event(ctx, 10000);
printf("event: %s\n", mpv_event_name(event->event_id));
if (event->event_id == MPV_EVENT_SHUTDOWN)
break;
}
mpv_terminate_destroy(ctx);
return 0;
}
+48 -61
View File
@@ -1,65 +1,11 @@
How to contribute
=================
General
-------
The main contact for mpv development is IRC, specifically #mpv-player
and #mpv-player-dev on Freenode.
Sending patches
---------------
- Make a github pull request, or send a link to a plaintext patch created with
``git format-patch``. diffs posted as pastebins (especially if the http link
returns HTML) just cause extra work for everyone, because they lack commit
message and authorship information.
- When creating pull requests, be sure to test your changes. If you didn't, please
say so in the pull request message.
- Write informative commit messages. Use present tense to describe the
situation with the patch applied, and past tense for the situation before
the change.
- The subject line (the first line in a commit message) should contain a
prefix identifying the sub system, followed by a short description what
impact this commit has. This subject line shouldn't be longer than 72
characters, because it messes up the output of many git tools otherwise.
For example, you fixed a crash in af_volume.c:
Bad: ``fixed the bug (wtf?)``
Good: ``af_volume: fix crash due to null pointer access``
Having a prefix gives context, and is especially useful when trying to find
a specific change by looking at the history, or when running ``git blame``.
- The body of the commit message (everything else after the subject line) should
be as informative as possible and contain everything that isn't obvious. Don't
hesitate to dump as much information as you can - it doesn't cost you
anything. Put some effort into it. If someone finds a bug months or years
later, and finds that it's caused by your commit (even though your commit was
supposed to fix another bug), it would be bad if there wasn't enough
information to test the original bug. The old bug might be reintroduced while
fixing the new bug.
The commit message should be wrapped on 72 characters per line, because git
tools usually do not break text automatically. On the other hand, you do not
need to break text that would be unnatural to break (like data for test cases,
or long URLs).
Important: put an empty line between the subject line and the commit message.
If this is missing, it will break display in common git tools.
- Try to separate cosmetic and functional changes. It's ok to make a few
additional cosmetic changes in the same file you're working on. But don't do
something like reformatting a whole file, and hiding an actual functional
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.
Code formatting
---------------
Coding style
============
mpv uses C99 with K&R formatting, with some exceptions.
General formatting
------------------
- Use the K&R indent style.
- Use 4 spaces of indentation, never use tabs (except in Makefiles).
- Add a single space between keywords and binary operators. There are some other
@@ -121,8 +67,6 @@ mpv uses C99 with K&R formatting, with some exceptions.
very_long_condition_b)
{
code();
} else {
...
}
```
- Remove any trailing whitespace.
@@ -150,3 +94,46 @@ General coding
- If you add features that require intrusive changes, discuss them on the dev
channel first. There might be a better way to add a feature and it can avoid
wasted work.
Sending patches
---------------
- Make a github pull request, or send a link to a plaintext patch created with
``git format-patch``. diffs posted as pastebins (especially if the http link
returns HTML) just cause extra work for everyone, because they lack commit
message and authorship information.
- Write informative commit messages. Use present tense to describe the
situation with the patch applied, and past tense for the situation before
the change.
- The subject line (the first line in a commit message) should contain a
prefix identifying the sub system, followed by a short description what
impact this commit has. This subject line shouldn't be longer than 72
characters, because it messes up the output of many git tools otherwise.
For example, you fixed a crash in af_volume.c:
Bad: ``fixed the bug (wtf?)``
Good: ``af_volume: fix crash due to null pointer access``
Having a prefix gives context, and is especially useful when trying to find
a specific change by looking at the history, or when running ``git blame``.
- The body of the commit message (everything else after the subject line) should
be as informative as possible and contain everything that isn't obvious. Don't
hesitate to dump as much information as you can - it doesn't cost you
anything. Put some effort into it. If someone finds a bug months or years
later, and finds that it's caused by your commit (even though your commit was
supposed to fix another bug), it would be bad if there wasn't enough
information to test the original bug. The old bug might be reintroduced while
fixing the new bug.
The commit message should be wrapped on 72 characters per line, because git
tools usually do not break text automatically. On the other hand, you do not
need to break text that would be unnatural to break (like data for test cases,
or long URLs).
Important: put an empty line between the subject line and the commit message.
If this is missing, it will break display in common git tools.
- Try to separate cosmetic and functional changes. It's ok to make a few
additional cosmetic changes in the same file you're working on, but don't do
something like reformatting a whole file and hiding an actual functional
change in the same commit.
-212
View File
@@ -1,212 +0,0 @@
Compiling for Windows
=====================
Compiling for Windows is supported with MinGW-w64. This can be used to produce
both 32-bit and 64-bit executables, and it works for building on Windows and
cross-compiling from Linux and Cygwin. MinGW-w64 is available from:
http://mingw-w64.sourceforge.net.
While building a complete MinGW-w64 toolchain yourself is possible, there are a
few build environments and scripts to help ease the process, such as MSYS2 and
MXE. Note that MinGW environments included in Linux distributions are often
broken, outdated and useless, and usually don't use MinGW-w64.
**Warning**: the original MinGW (http://www.mingw.org) is unsupported.
Cross-compilation
=================
When cross-compiling, you have to run mpv's configure with these arguments:
```bash
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
```
[MXE](http://mxe.cc) makes it very easy to bootstrap a complete MingGW-w64
environment from a Linux machine. See a working example below.
Alternatively, you can try [mingw-w64-cmake](https://github.com/lachs0r/mingw-w64-cmake),
which bootstraps a MinGW-w64 environment and builds mpv and dependencies.
Example with MXE
----------------
```bash
# Before starting, make sure you install MXE prerequisites. MXE will download
# and build all target dependencies, but no host dependencies. For example,
# you need a working compiler, or MXE can't build the crosscompiler.
#
# Refer to
#
# http://mxe.cc/#requirements
#
# Scroll down for disto/OS-specific instructions to install them.
# Download MXE. Note that compiling the required packages requires about 1.4 GB
# or more!
cd /opt
git clone https://github.com/mxe/mxe mxe
cd mxe
# Set build options.
# The JOBS environment variable controls threads to use when building. DO NOT
# use the regular `make -j4` option with MXE as it will slow down the build.
# Alternatively, you can set this in the make command by appending "JOBS=4"
# to the end of command:
echo "JOBS := 4" >> settings.mk
# The MXE_TARGET environment variable builds MinGW-w64 for 32 bit targets.
# Alternatively, you can specify this in the make command by appending
# "MXE_TARGETS=i686-w64-mingw32" to the end of command:
echo "MXE_TARGETS := i686-w64-mingw32.static" >> settings.mk
# If you want to build 64 bit version, use this:
# echo "MXE_TARGETS := x86_64-w64-mingw32.static" >> settings.mk
# Build required packages. The following provide a minimum required to build
# a reasonable mpv binary (though not an absolute minimum).
make gcc ffmpeg libass jpeg pthreads lua
# Add MXE binaries to $PATH
export PATH=/opt/mxe/usr/bin/:$PATH
# Build mpv. The target will be used to automatically select the name of the
# build tools involved (e.g. it will use i686-w64-mingw32.static-gcc).
cd ..
git clone https://github.com/mpv-player/mpv.git
cd mpv
python ./bootstrap.py
DEST_OS=win32 TARGET=i686-w64-mingw32.static ./waf configure
# Or, if 64 bit version,
# DEST_OS=win32 TARGET=x86_64-w64-mingw32.static ./waf configure
./waf build
```
Native compilation with MSYS2
=============================
For Windows developers looking to get started quickly, MSYS2 can be used to
compile mpv natively on a Windows machine. The MSYS2 repositories have binary
packages for most of mpv's dependencies, so the process should only involve
building mpv itself.
To build 64-bit mpv on Windows:
Installing MSYS2
----------------
1. Download an installer from https://msys2.github.io/
It doesn't matter whether the i686 or the x86_64 version is used. Both can
build 32-bit and 64-bit binaries when running on a 64-bit version of Windows.
2. Add ``C:\msys64\mingw64\bin`` to your ``%PATH%``. mpv will depend on several
DLLs in this folder.
3. Start a MinGW-w64 shell (``mingw64_shell.bat``). For a 32-bit build, use
``mingw32_shell.bat``.
Updating MSYS2
--------------
To prevent errors during post-install, ``msys2-runtime`` and ``pacman`` must be
updated first.
```bash
# Check for updates to msys2-runtime and pacman. If there were updates, restart
# MSYS2 before continuing.
pacman -Sy --needed msys2-runtime pacman
# Update everything else
pacman -Su
```
Installing mpv dependencies
---------------------------
```bash
# Install MSYS2 build dependencies and a MinGW-w64 compiler
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
# Install additional (optional) dependencies
pacman -S mingw-w64-x86_64-libdvdnav mingw-w64-x86_64-mpg123 mingw-w64-x86_64-libguess
```
For a 32-bit build, install ``mingw-w64-i686-*`` packages instead.
Building mpv
------------
Clone the latest mpv from git and install waf:
```bash
git clone https://github.com/mpv-player/mpv.git && cd mpv
./bootstrap.py
```
Finally, compile and install mpv. Binaries will be installed to
``/mingw64/bin``.
```bash
# For a 32-bit build, use --prefix=/mingw32 instead
./waf configure CC=gcc --prefix=/mingw64
./waf install
```
Or, compile and install both libmpv and mpv:
```bash
./waf configure CC=gcc --enable-libmpv-shared --prefix=/mingw64
./waf install
# waf installs libmpv to the wrong directory, so fix it up
mv -f /mingw64/bin/pkgconfig/mpv.pc /mingw64/lib/pkgconfig/
mv -f /mingw64/bin/libmpv.dll.a /mingw64/lib/
sed -i 's_/mingw64/bin_/mingw64/lib_' /mingw64/lib/pkgconfig/mpv.pc
rmdir /mingw64/bin/pkgconfig
```
Additional dependencies
=======================
pthreads
--------
mpv will use a pthreads wrapper by default. Either pthreads-win32 or
winpthreads should work. The latter is packaged with most MinGW-w64
environments, including MSYS2, so it shouldn't be a problem. If you don't have
a pthreads wrapper or you want to build mpv without one, configure with:
```bash
./waf configure --enable-win32-internal-pthreads
```
libwaio
-------
If you want to use ``--input-file``, you need libwaio. It's available from
git://midipix.org/waio
To compile libwaio in MSYS2, run:
```bash
git clone git://midipix.org/waio && cd waio
# 32-bit build, run from mingw32_shell.bat
./build-mingw-nt32 lib-static CC=gcc AR=ar
cp -r include/waio /mingw32/include
cp lib32/libwaio.a /mingw32/lib
# 64-bit build, run from mingw64_shell.bat
./build-mingw-nt64 lib-static CC=gcc AR=ar
cp -r include/waio /mingw64/include
cp lib64/libwaio.a /mingw64/lib
```
+54
View File
@@ -0,0 +1,54 @@
Cross compiling mpv to Windows is supported with MinGW-w64. This can be used to
produce both 32 bit and 64 bit executables. MinGW-w64 is available from
http://mingw-w64.sourceforge.net.
You have to run mpv's configure with these arguments:
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
Using mingw-w64-cmake to setup a MinGW-w64 environment is recommended (this will
also build mpv and its dependencies): https://github.com/lachs0r/mingw-w64-cmake
Alternatively, use MXE: http://mxe.cc
With MXE, you have to modify the file settings.mk to target MinGW-w64 (even if
you compile to 32 bit).
Warning: the original MinGW (http://www.mingw.org) is unsupported.
Note that MinGW environments included in Linux distributions are often broken,
outdated and useless, and usually don't use MinGW-w64.
Example with MXE
================
# Download MXE. Note that compiling the required packages requires about 1 GB
# or more!
cd /opt
git clone https://github.com/mxe/mxe mingw
cd mingw
# Edit the MXE target, so that MinGW-w64 for 32 bit targets is built.
echo "MXE_TARGETS := i686-w64-mingw32" > settings.mk
# Build required packages. The following provide a minimum required to build
# mpv. (Not all of the following packages are strictly required.)
make gcc
make ffmpeg
make libass
make jpeg
make pthreads
# Build mpv. The target will be used to automatically select the name of the
# build tools involved (e.g. it will use i686-w64-mingw32-gcc).
git clone https://github.com/mpv-player/mpv.git
cd mpv
export PATH=/opt/mingw/usr/bin/:$PATH
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
./waf build
# This should work. Note however that MXE’s ffmpeg package might be very old
# in order to avoid breaking e.g. xine-lib, so you might want to update that
# or build it manually as well.
+5 -21
View File
@@ -27,13 +27,13 @@ The general simplified syntax is::
<filename>,<start in seconds>,<length in seconds>
If the start time is omitted, 0 is used. If the length is omitted, the
estimated remaining duration of the source file is used.
estimated duration of the source file is used.
Note::
mpv can't use ordered chapter files in EDL entries. Usage of relative or
absolute paths as well as any protocol prefixes is prevented for security
reasons.
mpv can't use ordered chapter files or libquvi-resolved URLs in EDL
entries. Usage of relative or absolute paths as well as any protocol
prefixes is prevented for security reasons.
Syntax of mpv EDL files
@@ -78,7 +78,7 @@ The parameter name defines the meaning of the parameter:
2) ``start``, a time value that specifies the start offset into the source file.
3) ``length``, a time value that specifies the length of the segment.
See the section below for the format of timestamps.
(Currently, time values are floating point values in seconds.)
Unnamed parameters carry implicit names. The parameter position determines
which of the parameters listed above is set. For example, the second parameter
@@ -95,22 +95,6 @@ to ``20``, ``param3`` to ``value,escaped``, ``param4`` to ``value2``.
Instead of line breaks, the character ``;`` can be used. Line feed bytes and
``;`` are treated equally.
Timestamp format
================
Currently, time values are floating point values in seconds.
As an extension, you can set the ``timestamps=chapters`` option. If this option
is set, timestamps have to be integers, and refer to chapter numbers, starting
with 0.
Example::
# mpv EDL v0
file.mkv,2,4,timestamps=chapters
Plays chapter 3 and ends with the start of chapter 7 (4 chapters later).
Syntax of EDL URIs
==================
+1 -6
View File
@@ -25,7 +25,7 @@ from the input video. Note that not all codecs and not all formats support VFR
encoding, and some which do have bugs when a target bitrate is specified - use
-ofps or -oautofps to force CFR encoding in these cases.
Of course, the options can be stored in a profile, like this .config/mpv/mpv.conf
Of course, the options can be stored in a profile, like this .mpv/config
section::
[myencprofile]
@@ -38,11 +38,6 @@ section::
oac = aac
oacopts-add = b=96k
It's also possible to define default encoding options by putting them into
the section named ``[encoding]``. (This behavior changed after mpv 0.3.x. In
mpv 0.3.x, config options in the default section / no section were applied
to encoding. This is not the case anymore.)
One can then encode using this profile using the command::
mpv infile -o outfile.mp4 -profile myencprofile
-13
View File
@@ -1,13 +0,0 @@
CHANGELOG
=========
There is no real changelog, but you can look at the following things:
* The release changelog, which should contain most user-visible changes,
including new features and bug fixes:
https://github.com/mpv-player/mpv/releases
* The git log, which is the "real" changelog
* The file ``mplayer-changes.rst`` in the ``DOCS`` sub directory on the git
repository, which used to be in place of this section. It documents some
changes that happened since mplayer2 forked off MPlayer.
+19
View File
@@ -0,0 +1,19 @@
[latex2e writer]
use-latex-docinfo: yes
use-latex-toc: yes
hyperlink-color: Blue!30!RoyalPurple!70!Black
latex-preamble: \usepackage[usenames,dvipsnames]{xcolor}
\usepackage{fullpage}
\usepackage{graphicx}
\renewcommand{\familydefault}{\sfdefault}
\makeatletter
\renewcommand{\maketitle}{
\begin{center}
\vspace*{-1.5em}
\begin{Huge}
\@title
\end{Huge}
\end{center}
}
\makeatother
+43 -78
View File
@@ -63,7 +63,7 @@ Available filters are:
Set AVOptions on the SwrContext or AVAudioResampleContext. These should
be documented by FFmpeg or Libav.
``lavcac3enc[=tospdif[:bitrate[:minch]]]``
``lavcac3enc[=tospdif[:bitrate[:minchn]]]``
Encode multi-channel audio to AC-3 at runtime using libavcodec. Supports
16-bit native-endian input format, maximum 6 channels. The output is
big-endian when outputting a raw AC-3 stream, native-endian when
@@ -72,17 +72,15 @@ Available filters are:
``tospdif=<yes|no>``
Output raw AC-3 stream if ``no``, output to S/PDIF for
pass-through if ``yes`` (default).
passthrough if ``yes`` (default).
``bitrate=<rate>``
The bitrate use for the AC-3 stream. Set it to 384 to get 384 kbps.
The default is 640. Some receivers might not be able to handle this.
Valid values: 32, 40, 48, 56, 64, 80, 96, 112, 128,
160, 192, 224, 256, 320, 384, 448, 512, 576, 640.
The special value ``auto`` selects a default bitrate based on the
The special value ``default`` selects a default bitrate based on the
input channel number:
:1ch: 96
@@ -92,9 +90,9 @@ Available filters are:
:5ch: 448
:6ch: 448
``minch=<n>``
If the input channel number is less than ``<minch>``, the filter will
detach itself (default: 3).
``minchn=<n>``
If the input channel number is less than ``<minchn>``, the filter will
detach itself (default: 5).
``sweep[=speed]``
Produces a sine sweep.
@@ -103,7 +101,7 @@ Available filters are:
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
Remove a sine at the specified frequency. Useful to get rid of the 50/60Hz
noise on low quality audio equipment. It only works on mono input.
``<freq>``
@@ -184,7 +182,7 @@ Available filters are:
``mpv --af=equalizer=11:11:10:5:0:-12:0:5:12:12 media.avi``
Would amplify the sound in the upper and lower frequency region
while canceling it almost completely around 1 kHz.
while canceling it almost completely around 1kHz.
``channels=nch[:routes]``
Can be used for adding, removing, routing and copying audio channels. If
@@ -225,21 +223,14 @@ Available filters are:
automatically up- and downmix standard channel layouts.
``format=format:srate:channels:out-format:out-srate:out-channels``
Does not do any format conversion itself. Rather, it may cause the
filter system to insert necessary conversion filters before or after this
filter if needed. It is primarily useful for controlling the audio format
going into other filters. To specify the format for audio output, see
``--audio-format``, ``--audio-samplerate``, and ``--audio-channels``. This
filter is able to force a particular format, whereas ``--audio-*``
may be overridden by the ao based on output compatibility.
Force a specific audio format/configuration without actually changing the
audio data. Keep in mind that the filter system might auto-insert actual
conversion filters before or after this filter if needed.
All parameters are optional. The first 3 parameters restrict what the filter
accepts as input. They will therefore cause conversion filters to be
inserted before this one. The ``out-`` parameters tell the filters or audio
outputs following this filter how to interpret the data without actually
doing a conversion. Setting these will probably just break things unless you
really know you want this for some reason, such as testing or dealing with
broken media.
accepts as input. The ``out-`` parameters change the audio format, without
actually doing a conversion. The data will be 'reinterpreted' by the
filters or audio outputs following this filter.
``<format>``
Force conversion to this format. Use ``--af=format=format=help`` to get
@@ -250,7 +241,7 @@ Available filters are:
48000 for example.
``<channels>``
Force mixing to a specific channel layout. See ``--audio-channels`` option
Force mixing to a specific channel layout. See ``--channels`` option
for possible values.
``<out-format>``
@@ -259,16 +250,21 @@ Available filters are:
``<out-channels>``
*NOTE*: this filter used to be named ``force``. The old ``format`` filter
used to do conversion itself, unlike this one which lets the filter system
handle the conversion.
See also ``--format``, ``--srate``, and ``--channels`` for related options.
Keep in mind that ``--channels`` does not actually force the number of
channels in most cases, while this filter can do this.
*NOTE*: this filter used to be named ``force``. Also, unlike the old
``format`` filter, this does not do any actual conversion anymore.
Conversion is done by other, automatically inserted filters.
``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.
``convertsignendian``
Filter for internal use only. Converts between signed/unsigned formats
and formats with different endian.
``volume[=<volumedb>[:...]]``
Implements software volume control. Use this filter with caution since it
@@ -280,20 +276,9 @@ Available filters are:
once for every audio stream.
``<volumedb>``
Sets the desired gain in dB for all channels in the stream from -200 dB
to +60 dB, where -200 dB mutes the sound completely and +60 dB equals a
Sets the desired gain in dB for all channels in the stream from -200dB
to +60dB, where -200dB mutes the sound completely and +60dB equals a
gain of 1000 (default: 0).
``replaygain-track``
Adjust volume gain according to the track-gain replaygain value stored
in the file metadata.
``replaygain-album``
Like replaygain-track, but using the album-gain value instead.
``replaygain-preamp``
Pre-amplification gain in dB to apply to the selected replaygain gain
(default: 0).
``replaygain-clip=yes|no``
Prevent clipping caused by replaygain by automatically lowering the
gain (default). Use ``replaygain-clip=no`` to disable this.
``softclip``
Turns soft clipping on. Soft-clipping can make the
sound more smooth if very high volume levels are used. Enable this
@@ -304,17 +289,11 @@ Available filters are:
``s16``
Force S16 sample format if set. Lower quality, but might be faster
in some situations.
``detach``
Remove the filter if the volume is not changed at audio filter config
time. Useful with replaygain: if the current file has no replaygain
tags, then the filter will be removed if this option is enabled.
(If ``--softvol=yes`` is used and the player volume controls are used
during playback, a different volume filter will be inserted.)
.. admonition:: Example
``mpv --af=volume=10.1 media.avi``
Would amplify the sound by 10.1 dB and hard-clip if the sound level
Would amplify the sound by 10.1dB and hard-clip if the sound level
is too high.
``pan=n:[<matrix>]``
@@ -354,7 +333,7 @@ Available filters are:
If you just want to force remixing to a certain output channel layout,
it is easier to use the ``format`` filter. For example,
``mpv '--af=format=channels=5.1' '--audio-channels=5.1'`` would always force
``mpv '--af=format=channels=5.1' '--channels=5.1'`` would always force
remixing audio to 5.1 and output it like this.
``sub[=fc:ch]``
@@ -371,8 +350,8 @@ Available filters are:
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
cutoff frequency in Hz for the low-pass filter (20Hz to 300Hz)
(default: 60Hz) For the best result try setting the cutoff frequency
as low as possible. This will improve the stereo or surround sound
experience.
``<ch>``
@@ -383,8 +362,8 @@ Available filters are:
.. 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
``mpv --af=sub=100:4 --channels=5 media.avi``
Would add a subwoofer channel with a cutoff frequency of 100Hz to
output channel 4.
``center``
@@ -411,8 +390,8 @@ Available filters are:
.. admonition:: Example
``mpv --af=surround=15 --audio-channels=4 media.avi``
Would add surround sound decoding with 15 ms delay for the sound to
``mpv --af=surround=15 --channels=4 media.avi``
Would add surround sound decoding with 15ms delay for the sound to
the rear speakers.
``delay[=[ch1,ch2,...]]``
@@ -440,8 +419,8 @@ Available filters are:
.. admonition:: Example
``mpv --af=delay=[10.5,10.5,0,0,7,0] media.avi``
Would delay front left and right by 10.5 ms, the two rear channels
and the subwoofer by 0 ms and the center channel by 7 ms.
Would delay front left and right by 10.5ms, the two rear channels
and the subwoofer by 0ms and the center channel by 7ms.
``export=mmapped_file:nsamples]``
Exports the incoming signal to other processes using memory mapping
@@ -567,10 +546,9 @@ Available filters are:
Scale tempo in sync with speed (default).
pitch
Reverses effect of filter. Scales pitch without altering tempo.
Add this to your ``input.conf`` to step by musical semi-tones::
[ multiply speed 0.9438743126816935
] multiply speed 1.059463094352953
Add ``[ speed_mult 0.9438743126816935`` and ``] speed_mult
1.059463094352953`` to your ``input.conf`` to step by musical
semi-tones.
.. warning::
@@ -592,7 +570,7 @@ Available filters are:
tempo.
``mpv --af=scaletempo=stride=30:overlap=.50:search=10 media.ogg``
Would tweak the quality and performance parameters.
Would tweak the quality and performace parameters.
``mpv --af=format=float,scaletempo media.ogg``
Would make scaletempo use float code. Maybe faster on some
@@ -603,22 +581,8 @@ Available filters are:
Changing playback speed would change pitch, leaving audio tempo at
1.2x.
``rubberband``
High quality pitch correction with librubberband. This can be used in place
of ``scaletempo``, and will be used to adjust audio pitch when playing
at speed different from normal.
This filter has a number of sub-options. You can list them with
``mpv --af=rubberband=help``. This will also show the default values
for each option. The options are not documented here, because they are
merely passed to librubberband. Look at the librubberband documentation
to learn what each option does:
http://breakfastquay.com/rubberband/code-doc/classRubberBand_1_1RubberBandStretcher.html
(The mapping of the mpv rubberband filter sub-option names and values to
those of librubberband follows a simple pattern: ``"Option" + Name + Value``.)
``lavfi=graph``
Filter audio using FFmpeg's libavfilter.
Filter audio using ffmpeg's libavfilter.
``<graph>``
Libavfilter graph. See ``lavfi`` video filter for details - the graph
@@ -631,3 +595,4 @@ Available filters are:
``o=<string>``
AVOptions.
+39 -113
View File
@@ -23,25 +23,27 @@ normal driver parameters.
where PulseAudio is used. On Windows, ``--ao=wasapi`` is preferred,
though it might cause trouble sometimes, in which case ``--ao=dsound``
should be used. On BSD systems, ``--ao=oss`` or `--ao=sndio`` may work
(the latter being experimental). On OS X systems, use ``--ao=coreaudio``.
(the latter being experimental). On OSX systems, use ``--ao=coreaudio``.
.. admonition:: Examples
- ``--ao=alsa,oss,`` Try the ALSA driver, then the OSS driver, then others.
- ``--ao=alsa:resample=yes:device=[plughw:0,3]`` Lets ALSA resample and
sets the device-name as first card, fourth device.
- ``--ao=alsa:no-block:device=[hw:0,3]`` Sets noblock-mode and the
device-name as first card, fourth device.
Available audio output drivers are:
``alsa`` (Linux only)
ALSA audio output driver
``device=<device>``
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
"spdif" device, unless you really know how to set it correctly.
``no-block``
Sets noblock-mode.
``resample=yes``
Enable ALSA resampling plugin. (This is disabled by default, because
some drivers report incorrect audio delay in some cases.)
``device=<device>``
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
"spdif" device, unless you really know how to set it correctly.
``mixer-device=<device>``
Set the mixer device used with ``--no-softvol`` (default: ``default``).
``mixer-name=<name>``
@@ -51,18 +53,6 @@ Available audio output drivers are:
Set the index of the mixer channel (default: 0). Consider the output of
"``amixer scontrols``", then the index is the number that follows the
name of the element.
``non-interleaved``
Allow output of non-interleaved formats (if the audio decoder uses
this format). Currently disabled by default, because some popular
ALSA plugins are utterly broken with non-interleaved formats.
``ingore-chmap``
Don't read or set the channel map of the ALSA device - only request the
required number of channels, and then pass the audio as-is to it. This
option most likely should not be used. It can be useful for debugging,
or for static setups with a specially engineered ALSA configuration (in
this case you should always force the same layout with ``--audio-channels``,
or it will work only for files which use the layout implicit to your
ALSA device).
.. note::
@@ -76,42 +66,6 @@ Available audio output drivers are:
shells (like zsh), you have to quote the option string to prevent the
shell from interpreting the brackets instead of passing them to mpv.
Actually, you should use the ``--audio-device`` option, instead of
setting the device directly.
.. warning::
Handling of multichannel/surround audio changed in mpv 0.8.0 from the
behavior in MPlayer/mplayer2 and older versions of mpv.
The old behavior is that the player always downmixed to stereo by
default. The ``--audio-channels`` (or ``--channels`` before that) option
had to be set to get multichannel audio. Then playing stereo would
use the ``default`` device (which typically allows multiple programs
to play audio at the same time via dmix), while playing anything with
more channels would open one of the hardware devices, e.g. via the
``surround51`` alias (typically with exclusive access). Whether the
player would use exclusive access or not would depend on the file
being played.
The new behavior since mpv 0.8.0 always enables multichannel audio,
i.e. ``--audio-channels=auto`` is the default. However, since ALSA
provides no good way to play multichannel audio in a non-exclusive
way (without blocking other applications from using audio), the player
is restricted to the capabilities of the ``default`` device by default,
which means it supports only stereo and mono (at least with current
typical ALSA configurations). But if a hardware device is selected,
then multichannel audio will typically work.
The short story is: if you want multichannel audio with ALSA, use
``--audio-device`` to select the device (use ``--audio-device=help``
to get a list of all devices and their mpv name).
You can also try `using the upmix plugin <http://git.io/vfuAy>`_.
This setup enables multichannel audio on the ``default`` device
with automatic upmixing with shared access, so playing stereo
and multichannel audio at the same time will work as expected.
``oss``
OSS audio output driver
@@ -132,6 +86,9 @@ Available audio output drivers are:
``name=<client>``
Client name that is passed to JACK (default: ``mpv``). Useful
if you want to have certain connections established automatically.
``(no-)estimate``
Estimate the audio delay, supposed to make the video playback smoother
(default: enabled).
``(no-)autostart``
Automatically start jackd if necessary (default: disabled). Note that
this tends to be unreliable and will flood stdout with server messages.
@@ -156,17 +113,12 @@ Available audio output drivers are:
with fixed setups.
``coreaudio`` (Mac OS X only)
Native Mac OS X audio output driver using AudioUnits and the CoreAudio
sound server.
Native Mac OS X audio output driver
Automatically redirects to ``coreaudio_exclusive`` when playing compressed
formats.
``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).
``device_id=<id>``
ID of output device to use (0 = default device)
``help``
List all available output devices with their IDs.
``openal``
Experimental OpenAL audio output driver
@@ -182,22 +134,18 @@ Available audio output drivers are:
string uses a local connection, "localhost" uses network transfer
(most likely not what you want).
``buffer=<1-2000|native>``
Set the audio buffer size in milliseconds. A higher value buffers
more data, and has a lower probability of buffer underruns. A smaller
value makes the audio stream react faster, e.g. to playback speed
changes. Default: 250.
``portaudio``
PortAudio audio output driver. This works on all platforms, and has
extensive MS Windows support.
``latency-hacks=<yes|no>``
Enable hacks to workaround PulseAudio timing bugs (default: no). If
enabled, mpv will do elaborate latency calculations on its own. If
disabled, it will use PulseAudio automatically updated timing
information. Disabling this might help with e.g. networked audio or
some plugins, while enabling it might help in some unknown situations
(it used to be required to get good behavior on old PulseAudio versions).
.. note:: This driver is not very useful. It was added in the hope of
providing portable audio API across all platforms, but turned
out semi-broken and underfeatured.
If you have stuttering video when using pulse, try to enable this
option. (Or alternatively, try to update PulseAudio.)
``device``
Specify the subdevice to use. Giving ``help`` as device name lists all
devices found by PortAudio. Devices can be given as numeric values,
starting from ``1``.
``dsound`` (Windows only)
DirectX DirectSound audio output driver
@@ -208,9 +156,6 @@ Available audio output drivers are:
Sets the device number to use. Playing a file with ``-v`` will show a
list of available devices.
``buffersize=<ms>``
DirectSound buffer size in milliseconds (default: 200).
``sdl``
SDL 1.2+ audio output driver. Should work on any platform supported by SDL
1.2, but may require the ``SDL_AUDIODRIVER`` environment variable to be set
@@ -245,21 +190,6 @@ Available audio output drivers are:
``outburst``
Simulated chunk size in samples.
``speed``
Simulated audio playback speed as a multiplier. Usually, a real audio
device will not go exactly as fast as the system clock. It will deviate
just a little, and this option helps simulating this.
``latency``
Simulated device latency. This is additional to EOF.
``broken-eof``
Simulate broken audio drivers, which always add the fixed device
latency to the reported audio playback position.
``broken-delay``
Simulate broken audio drivers, which don't report latency correctly.
``pcm``
Raw PCM/WAVE file writer audio output
@@ -270,10 +200,6 @@ Available audio output drivers are:
Write the sound to ``<filename>`` instead of the default
``audiodump.wav``. If ``no-waveheader`` is specified, the default is
``audiodump.pcm``.
``(no-)append``
Append to the file, instead of overwriting it. Always use this with the
``no-waveheader`` option - with ``waveheader`` it's broken, because
it will write a WAVE header every time the file is opened.
``rsound``
Audio output to an RSound daemon
@@ -304,19 +230,19 @@ Available audio output drivers are:
``wasapi``
Audio output to the Windows Audio Session API.
``device=<id>``
Uses the requested endpoint instead of the system's default audio
endpoint. Both the number and the ID String are valid; the ID String
is guaranteed to not change unless the driver is uninstalled.
Also supports searching active devices by name. If more than one
device matches the name, refuses loading it.
To get a list of the valid devices, give ``help`` as the id. The
list is the same as the ``list`` suboption, but stops the player
initialization.
``exclusive``
Requests exclusive, direct hardware access. By definition prevents
sound playback of any other program until mpv exits.
``device=<id>``
Uses the requested endpoint instead of the system's default audio
endpoint. Both an ordinal number (0,1,2,...) and the GUID
String are valid; the GUID string is guaranteed to not change
unless the driver is uninstalled.
Also supports searching active devices by human readable name. If more
than one device matches the name, refuses loading it.
This option is mostly deprecated in favour of the more general
``--audio-device`` option. That said, ``--audio-device=help`` will give
a list of valid device GUIDs (prefixed with ``wasapi/``), as well as
their human readable names, which should work here.
``list``
Lists all audio endpoints (output devices) present in the system.
+293
View File
@@ -0,0 +1,293 @@
CHANGES FROM OTHER VERSIONS OF MPLAYER
======================================
**mpv** is based on mplayer2, which in turn is based on the original
MPlayer (also called mplayer, mplayer-svn, mplayer1). Many changes
have been made. Some changes are incompatible, or completely change how the
player behaves.
General Changes for MPlayer to mplayer2
---------------------------------------
* Removal of the internal GUI, MEncoder, OSD menu
* Better pause handling (do not unpause on a command)
* Better MKV support (such as ordered chapters)
* vo_vdpau improvements
* Precise seeking support
* No embedded copy of ffmpeg and other libraries
* Native OpenGL backend for OSX
* General OSX improvements
* Improvements in audio/video sync handling
* Cleaned up terminal output
* Gapless audio support (``--gapless-audio``)
* Improved responsiveness on user input
* Support for modifier keys (alt, shift, ctrl) in input.conf
* OSS4 volume control
* More correct color reproduction (color matrix generation)
* Use libass for subtitle rendering by default (better quality)
* Generally preferring ffmpeg/libav over internal demuxers and decoders
* Improvements when playing multiple files (``--fixed-vo``)
* Screenshot improvements (instant screenshots without 1-frame delay, allow
taking screenshots even with hardware decoding)
* Improved support for PulseAudio
* General code cleanups
* Many more changes
General Changes for mplayer2 to mpv
-----------------------------------
* Switch back to GPLv2+.
* Removal of lots of unneeded code to encourage developer activity (less
obscure scary zombie code that kills any desire for hacking the codebase)
* Removal of dust and dead bodies (code-wise), such as kernel drivers for
decades old hardware
* Removal of support for dead platforms
* Generally improved MS Windows support (dealing with unicode filenames,
improved ``--vo=direct3d``, improved window handling)
* Better OSD rendering (using libass). This has full unicode support, and
languages like Arabic should be better supported.
* Cleaned up terminal output (nicer status line, less useless noise)
* Support for playing URLs of popular streaming sites directly
(e.g. ``mpv https://www.youtube.com/watch?v=...``)
* Improved OpenGL output (``--vo=opengl-hq``)
* Make ``--softvol`` default (**mpv** is not a mixer control panel)
* Improved support for .cue files
* Screenshot improvements (can save screenshots as JPG or PNG, configurable
filenames, support for taking screenshots with or without subtitles - the
``screenshot`` video filter is not needed anymore, and should not be put
into the mpv config file)
* Removal of teletext support
* Removal of most builtin demuxers, using libavformat instead
* Removal of builtin network support, using libavformat instead (also,
support https via libavformat)
* Replace image VOs (``--vo=jpeg`` etc.) with ``--vo=image``
* Do not lose settings when playing a new file in the same player instance
* New location for config files, new name for the binary.
* Slave mode compatibility broken (see below)
* Encoding functionality (replacement for mencoder, see ``DOCS/encoding.rst``)
* Remove ``--vo=gif89a``, ``--vo=md5sum``, ``--vo=yuv4mpeg``, as encoding can
handle these use cases. For yuv4mpeg, for example, use:
``mpv input.mkv -o output.y4m --no-audio --oautofps --oneverdrop``.
* Image subtitles (DVDs etc.) are rendered in color and use more correct
positioning (color can be disabled with ``--sub-gray``)
* Wayland support
* Support for precise scrolling which scales the parameter of commands. If the
input doesn't support precise scrolling the scale factor stays 1.
* OSX: Cocoa event loop is independent from mplayer's event loop, so user
actions like accessing menus and live resizing do not block the playback.
* OSX: Apple Remote support.
* OSX: Media Keys support.
* Windows: Added WASAPI audio output.
* New OSD bar with chapter marks and not positioned in the middle of the video
(though this can be customized with the ``--osd-bar-align-y`` option).
* Allow customizing whether a key binding for seeking shows the video time, the
OSD bar, or nothing (see section `Input Command Prefixes`_).
* Display list of chapters and audio/subtitle tracks on OSD (see section
`Properties`_).
* ``--keep-open`` option to stop the player from closing the window and
exiting after playback ends.
* Re-enable screensaver while the player is paused.
* Matroska edition switching at runtime.
* Support for libavfilter (for video->video and audio->audio). This allows
using most of FFmpeg's filters, which improve greatly on the old MPlayer
filters in features, performance, and correctness.
* Improved downmixing and output of surround audio. Instead of using hardcoded
pan filters to do remixing, use libavresample. Channel maps are used to
identify the channel layout, so e.g. ``3.0`` and ``2.1`` audio can be
distinguished.
* Allow resuming playback at a later point with ``Shift+q``, also see
``quit_watch_later`` input command.
* Support mapping multiple commands to one key.
* Allow changing/adjusting video filters at runtime. (This is also used to make
the ``D`` key insert vf_yadif if deinterlacing is not supported otherwise.)
* Native VAAPI support
* OSX: VDA support using libavcodec hwaccel API insted of FFmpeg's decoder. Up
to 2-2.5x reduction in CPU usage.
* Make hardware decoding in general work with the ``opengl`` video output.
* General bug fixes and removal of long-standing issues
* General code cleanups (including refactoring or rewrites of many parts)
* Many more changes
Detailed Listing of User-visible Changes
----------------------------------------
This listing is about changed command line switches, slave commands, and similar
things. Completely removed features are not listed.
Command Line Switches
~~~~~~~~~~~~~~~~~~~~~
* There is a new command line syntax, which is generally preferred over the old
syntax. ``-optname optvalue`` becomes ``--optname=optvalue``.
The old syntax will not be removed in the near future. However, the new
syntax is mentioned in all documentation and so on, so it is a good thing to
know about this change.
(The new syntax was introduced in mplayer2.)
* In general, negating switches like ``-noopt`` now have to be written as
``-no-opt``, or better ``--no-opt``.
* Per-file options are not the default anymore. You can explicitly specify
file-local options. See ``Usage`` section.
* Table of renamed/replaced switches:
=========================== ========================================
Old New
=========================== ========================================
``-no<opt>`` ``--no-<opt>`` (add a dash)
``-nosound`` ``--no-audio``
``-use-filename-title`` ``--title='${filename}'``
``-loop 0`` ``--loop=inf``
``-hardframedrop`` ``--framedrop=hard``
``-osdlevel`` ``--osd-level``
``-delay`` ``--audio-delay``
``-subdelay`` ``--sub-delay``
``-subpos`` ``--sub-pos``
``-forcedsubsonly`` ``--sub-forced-only``
``-benchmark`` ``--untimed`` (no stats)
``-xineramascreen`` ``--screen`` (different values)
``-ss`` ``--start``
``-endpos`` ``--length``
``-cursor-autohide-delay`` ``--cursor-autohide``
``-sub-fuzziness`` ``--autosub-match``
``-subfont`` ``--sub-text-font``
``-font`` ``--osd-font``
``-subfont-*`` ``--sub-text-*``, ``--osd-*``
``-subfont-text-scale`` ``--sub-scale``
``-spugauss`` ``--sub-gauss``
``-vobsub`` ``--sub`` (pass the .idx file)
``-ass-bottom-margin`` ``--vf=sub=bottom:top``
``-vc ffh264vdpau`` (etc.) ``--hwdec=vdpau``
``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``)
``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts``
``-x W``, ``-y H`` ``--geometry=WxH`` + ``--no-keepaspect``
``-xy W`` ``--autofit=W``
``-a52drc level`` ``--ad-lavc-ac3drc=level``
``-dumpstream`` ``--stream-dump=<filename>``
``-capture`` ``--stream-capture=<filename>``
``-stop-xscreensaver`` ``--stop-screensaver``
``-subfile`` ``--sub``
``-lavdopts ...`` ``--vd-lavc-...``
``-lavfdopts`` ``--demuxer-lavf-...``
``-rawaudio ...`` ``--demuxer-rawaudio-...``
``-rawvideo ...`` ``--demuxer-rawvideo-...``
``-mixer`` AO suboptions (``alsa``, ``oss``)
``-mixer-channel`` AO suboptions (``alsa``, ``oss``)
``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``
``-af volnorm`` ``--af=drc`` (renamed)
``-zoom`` Inverse available as ``--video-unscaled``
``-panscanrange`` ``--video-zoom``, ``--video-pan-x/y``
``-pp ...`` ``'--vf=pp=[...]'``
``-pphelp`` ``--vf=pp:help``
``dvdnav://`` ``dvdnav://menu``
=========================== ========================================
.. note::
``-opt val`` becomes ``--opt=val``.
.. note::
Quite some video filters, video outputs, audio filters, audio outputs, had
changes in their option parsing. These aren't mentioned in the table above.
Also, some video and audio filters have been removed, and you have to use
libavfilter (using ``--vf=lavfi=[...]`` or ``--af=lavfi=[...]``) to get
them back.
input.conf and Slave Commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Table of renamed input commands:
This lists only commands that are not always gracefully handled by the
internal legacy translation layer. If an input.conf contains any legacy
commands, a warning will be printed when starting the player. The warnings
also show the replacement commands.
Properties containing ``_`` to separate words use ``-`` instead.
+--------------------------------+----------------------------------------+
| Old | New |
+================================+========================================+
| ``pt_step 1 [0|1]`` | ``playlist_next [weak|force]`` |
| | (translation layer cannot deal with |
| | whitespace) |
+--------------------------------+----------------------------------------+
| ``pt_step -1 [0|1]`` | ``playlist_prev [weak|force] (same)`` |
+--------------------------------+----------------------------------------+
| ``switch_ratio [<ratio>]`` | ``set aspect <ratio>`` |
| | |
| | ``set aspect 0`` (to reset aspect) |
+--------------------------------+----------------------------------------+
| ``step_property_osd <prop>`` | ``cycle <prop> <step>`` (wraps), |
| ``<step> <dir>`` | ``add <prop> <step>`` (clamps). |
| | ``<dir>`` parameter unsupported. Use |
| | a negative ``<step>`` instead. |
+--------------------------------+----------------------------------------+
| ``step_property <prop>`` | Prefix ``cycle`` or ``add`` with |
| ``<step> <dir>`` | ``no-osd``: ``no-osd cycle <prop>`` |
| | ``<step>`` |
+--------------------------------+----------------------------------------+
| ``osd_show_property_text`` | ``show_text <text>`` |
| ``<text>`` | The property expansion format string |
| | syntax slightly changed. |
+--------------------------------+----------------------------------------+
| ``osd_show_text`` | Now does the same as |
| | ``osd_show_property_text``. Use the |
| | ``raw`` prefix to disable property |
| | expansion. |
+--------------------------------+----------------------------------------+
| ``show_tracks`` | ``show_text ${track-list}`` |
+--------------------------------+----------------------------------------+
| ``show_chapters`` | ``show_text ${chapter-list}`` |
+--------------------------------+----------------------------------------+
| ``af_switch``, ``af_add``, ... | ``af set|add|...`` |
+--------------------------------+----------------------------------------+
Other
~~~~~
* The playtree has been removed. **mpv**'s internal playlist is a simple and
flat list now. This simplifies the code and makes **mpv** usage less
confusing.
* Slave mode is broken. This mode is entirely insane in the ``old`` versions of
MPlayer. A proper slave mode application needed tons of code and hacks to get
it right. The main problem is that slave mode is a bad and incomplete
interface, and to get around that, applications parsed output messages
intended for users. It is hard to know which messages exactly are parsed by
slave mode applications. This makes it virtually impossible to improve
terminal output intended for users without possibly breaking something.
This is absolutely insane, and **mpv** will not try to keep slave mode
compatible. If you are a developer of a slave mode application, contact us,
and a new and better protocol can be developed.
Policy for Removed Features
---------------------------
Features are a good thing, because they make users happy. As such, it is
attempted to preserve useful features as far as possible. But if a feature is
likely to be not used by many, and causes problems otherwise, it will be
removed. Developers should not be burdened with fixing or cleaning up code that
has no actual use.
It is always possible to add back removed features. File a feature request if a
feature you relied on has been removed, and you want it back. Though it might be
rejected in the worst case, it is much more likely that it will be either added
back, or that a better solution will be implemented.
Why this Fork?
--------------
* MPlayer wants to maintain old code, even if it is very bad code. It seems
mplayer2 was forked because MPlayer developers refused to get rid of all the
cruft. The mplayer2 and MPlayer codebases also deviated enough to make a
reunification unlikely.
* mplayer2 development is slow, and it is hard to get in changes. Details
withheld as to not turn this into a rant.
* MPlayer rarely merged from mplayer2, and mplayer2 practically stopped
merging from MPlayer (not even code cleanups or new features are merged)
* **mpv** intends to continuously merge from mplayer-svn and mplayer2, while
speeding up development. There is willingness for significant changes, even
if this means breaking compatibility.
@@ -3,7 +3,7 @@ ENCODING
You can encode files from one format/codec to another using this facility.
``--o=<filename>``
``-o <filename>``
Enables encoding mode and specifies the output file name.
``--of=<format>``
@@ -38,7 +38,7 @@ You can encode files from one format/codec to another using this facility.
``--oautofps``
Sets the output format time base to the guessed frame rate of the input
video (simulates MEncoder behavior, useful for AVI; may cause frame drops).
video (simulates mencoder behavior, useful for AVI; may cause frame drops).
Note that not all codecs and not all formats support VFR encoding, and some
which do have bugs when a target bitrate is specified - use ``--ofps`` or
``--oautofps`` to force CFR encoding in these cases.
@@ -74,7 +74,7 @@ You can encode files from one format/codec to another using this facility.
.. admonition:: Example
"``--oac=libmp3lame --oacopts=b=128000``"
selects 128 kbps MP3 encoding.
selects 128kbps MP3 encoding.
Options are managed in lists. There are a few commands to manage the
options list.
@@ -149,7 +149,3 @@ You can encode files from one format/codec to another using this facility.
container formats, e.g. AVI). In this mode, discontinuities are not fixed
and all pts are passed through as-is. Never seek backwards or use multiple
input files in this mode!
``--no-ometadata``
Turns off copying of metadata from input files to output files when
encoding (which is enabled by default).
+696
View File
@@ -0,0 +1,696 @@
INPUT.CONF
==========
The input.conf file consists of a list of key bindings, for example::
s screenshot # take a screenshot with the s key
Each line maps a key to an input command. Keys are specified with their literal
value (upper case if combined with ``Shift``), or a name for special keys. For
example, ``a`` maps to the ``a`` key without shift, and ``A`` maps to ``a``
with shift.
A list of special keys can be obtained with
``mpv --input-keylist``
In general, keys can be combined with ``Shift``, ``Ctrl`` and ``Alt``::
ctrl+q quit
**mpv** can be started in input test mode, which displays key bindings and the
commands they're bound to on the OSD, instead of executing the commands::
mpv --input-test --demuxer=rawvideo --demuxer-rawvideo=w=1280:h=720 /dev/zero
(Commands which normally close the player will not work in this mode, and you
must kill **mpv** externally to make it exit.)
General Input Command Syntax
----------------------------
``[Shift+][Ctrl+][Alt+][Meta+]<key> [{<section>}] [<prefixes>] <command> (<argument>)* [; <command>]``
Note that by default, the right Alt key can be used to create special
characters, and thus does not register as a modifier. The option
``--no-right-alt-gr`` changes this behavior.
Newlines always start a new binding. ``#`` starts a comment (outside of quoted
string arguments). To bind commands to the ``#`` key, ``SHARP`` can be used.
``<key>`` is either the literal character the key produces (ASCII or Unicode
character), or a symbolic name (as printed by ``--input-keylist``).
``<section>`` (braced with ``{`` and ``}``) is the input section for this
command.
Arguments are separated by whitespace. This applies even to string arguments.
For this reason, string arguments should be quoted with ``"``. Inside quotes,
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"
List of Input Commands
----------------------
``ignore``
Use this to "block" keys that should be unbound, and do nothing. Useful for
disabling default bindings, without disabling all bindings with
``--no-input-default-bindings``.
``seek <seconds> [relative|absolute|absolute-percent|- [default-precise|exact|keyframes]]``
Change the playback position. By default, seeks by a relative amount of
seconds.
The second argument sets the seek mode:
relative (default)
Seek relative to current position (a negative value seeks backwards).
absolute
Seek to a given time.
absolute-percent
Seek to a given percent position.
The third argument defines how exact the seek is:
default-precise (default)
Follow the default behavior as set by ``--hr-seek``, which by default
does imprecise seeks (like ``keyframes``).
exact
Always do exact/hr/precise seeks (slow).
keyframes
Always restart playback at keyframe boundaries (fast).
``revert_seek``
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.
``frame_step``
Play one frame, then pause.
``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.
see the ``--hr-seek-demuxer-offset`` option). Video filters or other video
postprocessing that modifies timing of frames (e.g. deinterlacing) should
usually work, but might make backstepping silently behave incorrectly in
corner cases.
This does not work with audio-only playback.
``set <property> "<value>"``
Set the given property to the given value.
``add <property> [<value>]``
Add the given value to the property. On overflow or underflow, clamp the
property to the maximum. If ``<value>`` is omitted, assume ``1``.
``cycle <property> [up|down]``
Cycle the given property. ``up`` and ``down`` set the cycle direction. On
overflow, set the property back to the minimum, on underflow set it to the
maximum. If ``up`` or ``down`` is omitted, assume ``up``.
``multiply <property> <factor>``
Multiplies the value of a property with the numeric factor.
``screenshot [subtitles|video|window|- [single|each-frame]]``
Take a screenshot.
First argument:
<subtitles> (default)
Save the video image, in its original resolution, and with subtitles.
Some video outputs may still include the OSD in the output under certain
circumstances.
<video>
Like ``subtitles``, but typically without OSD or subtitles. The exact
behavior depends on the selected video output.
<window>
Save the contents of the mpv window. Typically scaled, with OSD and
subtitles. The exact behavior depends on the selected video output, and
if no support is available, this will act like ``video``.
Second argument:
<single> (default)
Take a single screenshot.
<each-frame>
Take a screenshot each frame. Issue this command again to stop taking
screenshots.
``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).
The second argument is like the first argument to ``screenshot``.
This command tries to never overwrite files. If the file already exists,
it fails.
Like all input command parameters, the filename is subject to property
expansion as described in `Property Expansion`_.
``playlist_next [weak|force]``
Go to the next entry on the playlist.
weak (default)
If the last file on the playlist is currently played, do nothing.
force
Terminate playback if there are no more files on the playlist.
``playlist_prev [weak|force]``
Go to the previous entry on the playlist.
weak (default)
If the first file on the playlist is currently played, do nothing.
force
Terminate playback if the first file is being played.
``loadfile "<file>" [replace|append]``
Load the given file and play it.
Second argument:
<replace> (default)
Stop playback of the current file, and play the new file immediately.
<append>
Append the file to the playlist.
``loadlist "<playlist>" [replace|append]``
Load the given playlist file (like ``--playlist``).
``playlist_clear``
Clear the playlist, except the currently played file.
``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>``
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.)
``run "command" "arg1" "arg2" ...``
(Unix only)
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
is run directly, with each argument passed separately. Each argument is
expanded like in `Property Expansion`_. Note that there is a static limit
of (as of this writing) 10 arguments (this limit could be raised on demand).
The program is run in a detached way. mpv doesn't wait until the command
is completed, but continues playback right after spawning it.
To get the old behavior, use ``/bin/sh`` and ``-c`` as the first two
arguments.
.. admonition:: Example
``run "/bin/sh" "-c" "echo ${title} > /tmp/playing"``
This is not a particularly good example, because it doesn't handle
escaping, and a specially prepared file might allow an attacker to
execute arbitrary shell commands. It is recommended to write a small
shell script, and call that with ``run``.
``quit [<code>]``
Exit the player using the given exit code.
``quit_watch_later``
Exit player, and store current playback position. Playing that file later
will seek to the previous position on start.
``sub_add "<file>"``
Load the given subtitle file. It is not selected as current subtitle after
loading.
``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>]``
Reload the given subtitle tracks. If the ``id`` argument is missing, remove
the current track. (Works on external subtitle files only.)
This works by unloading and re-adding the subtitle track.
``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>``
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
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.
``osd [<level>]``
Toggle OSD level. If ``<level>`` is specified, set the OSD mode
(see ``--osd-level`` for valid values).
``print_text "<string>"``
Print text to stdout. The string can contain properties (see
`Property Expansion`_).
``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.
<duration>
The time in ms to show the message for. By default, it uses the same
value as ``--osd-duration``.
<level>
The minimum OSD level to show the text at (see ``--osd-level``).
``show_progress``
Show the progress bar, the elapsed time and the total duration of the file
on the OSD.
Input Commands that are Possibly Subject to Change
--------------------------------------------------
``af set|add|toggle|del|clr "filter1=params,filter2,..."``
Change audio filter chain. See ``vf`` command.
``vf set|add|toggle|del|clr "filter1=params,filter2,..."``
Change video filter chain.
The first argument decides what happens:
set
Overwrite the previous filter chain with the new one.
add
Append the new filter chain to the previous one.
toggle
Check if the given filter (with the exact parameters) is already
in the video chain. If yes, remove the filter. If no, add the filter.
(If several filters are passed to the command, this is done for
each filter.)
del
Remove the given filters from the video chain. Unlike in the other
cases, the second parameter is a comma separated list of filter names
or integer indexes. ``0`` would denote the first filter. Negative
indexes start from the last filter, and ``-1`` denotes the last
filter.
clr
Remove all filters. Note that like the other sub-commands, this does
not control automatically inserted filters.
You can assign labels to filter by prefixing them with ``@name:`` (where
``name`` is a user-chosen arbitrary identifier). Labels can be used to
refer to filters by name in all of the filter chain modification commands.
For ``add``, using an already used label will replace the existing filter.
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
are not shown on the list, only what was requested by the user.
.. admonition:: Example for input.conf
- ``a vf set flip`` turn video upside-down on the ``a`` key
- ``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 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
reset to 0 once the last value is reached.
The internal counter is associated using the property name and the value
list. If multiple commands (bound to different keys) use the same name
and value list, they will share the internal counter.
The special argument ``!reverse`` can be used to cycle the value list in
reverse. Compared with a command that just lists the value in reverse, this
command will actually share the internal counter with the forward-cycling
key binding.
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 all key bindings in the named input section.
The enabled input sections form a stack. Bindings in sections on the top of
the stack are preferred to lower sections. This command puts the section
on top of the stack. If the section was already on the stack, it is
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.
``disable_section "<section>"``
Disable the named input section. Undoes ``enable_section``.
``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.
Overlays are usually displayed in screen resolution, but with some VOs,
the resolution is reduced to that of the video's. You can read the
``osd-width`` and ``osd-height`` properties. At least with ``--vo-xv`` and
anamorphic video (such as DVD), ``osd-par`` should be read as well, and the
overlay should be aspect-compensated. (Future directions: maybe mpv should
take care of some of these things automatically, but it's hard to tell
where to draw the line.)
``id`` is an integer between 0 and 63 identifying the overlay element. The
ID can be used to add multiple overlay parts, update a part by using this
command with an already existing ID, or to remove a part with
``overlay_remove``. Using a previously unused ID will add a new overlay,
while reusing an ID will update it. (Future directions: there should be
something to ensure different programs wanting to create overlays don't
conflict with each others, should that ever be needed.)
``x`` and ``y`` specify the position where the OSD should be displayed.
``file`` specifies the file the raw image data is read from. It can be
either a numeric UNIX file descriptor prefixed with ``@`` (e.g. ``@4``),
or a filename. The file will be mapped into memory with ``mmap()``. Some VOs
will pass the mapped pointer directly to display APIs (e.g. opengl or
vdpau), so no actual copying is involved. Truncating the source file while
the overlay is active will crash the player. You shouldn't change the data
while the overlay is active, because the data is essentially accessed at
random points. Instead, call ``overlay_add`` again (preferably with a
different memory region to prevent tearing).
``offset`` is the offset of the first pixel in the source file. It is
passed directly to ``mmap`` and is subject to certain restrictions
(see ``man mmap`` for details). In particular, this value has to be a
multiple of the system's page size.
``fmt`` is a string identifying the image format. Currently, only ``bgra``
is defined. This format has 4 bytes per pixels, with 8 bits per component.
The least significant 8 bits are blue, and the most significant 8 bits
are alpha (in little endian, the components are B-G-R-A, with B as first
byte). This uses premultiplied alpha: every color component is already
multiplied with the alpha component. This means the numeric value of each
component is equal to or smaller than the alpha component. (Violating this
rule will lead to different results with different VOs: numeric overflows
resulting from blending broken alpha values is considered something that
shouldn't happen, and consequently implementations don't ensure that you
get predictable behavior in this case.)
``w``, ``h``, and ``stride`` specify the size of the overlay. ``w`` is the
visible width of the overlay, while ``stride`` gives the width in bytes in
memory. In the simple case, and with the ``bgra`` format, ``stride==4*w``.
In general, the total amount of memory accessed is ``stride * h``.
(Technically, the minimum size would be ``stride * (h - 1) + w * 4``, but
for simplicity, the player will access all ``stride * h`` bytes.)
.. admonition:: Warning
When updating the overlay, you should prepare a second shared memory
region (e.g. make use of the offset parameter) and add this as overlay,
instead of reusing the same memory every time. Otherwise, you might
get the equivalent of tearing, when your application and mpv write/read
the buffer at the same time. Also, keep in mind that mpv might access
an overlay's memory at random times whenever it feels the need to do
so, for example when redrawing the screen.
``overlay_remove <id>``
Remove an overlay added with ``overlay_add`` and the same ID. Does nothing
if no overlay with this ID exists.
Undocumented commands: ``tv_start_scan``, ``tv_step_channel``, ``tv_step_norm``,
``tv_step_chanlist``, ``tv_set_channel``, ``tv_last_channel``, ``tv_set_freq``,
``tv_step_freq``, ``tv_set_norm``, ``dvb_set_channel`` (all of these
should be replaced by properties), ``stop`` (questionable use), ``get_property``
(?), ``vo_cmdline`` (experimental).
Input Command Prefixes
----------------------
These prefixes are placed between key name and the actual command. Multiple
prefixes can be specified. They are separated by whitespace.
``osd-auto`` (default)
Use the default behavior for this command.
``no-osd``
Do not use any OSD for this command.
``osd-bar``
If possible, show a bar with this command. Seek commands will show the
progress bar, property changing commands may show the newly set value.
``osd-msg``
If possible, show an OSD message with this command. Seek command show
the current playback time, property changing commands show the newly set
value as text.
``osd-msg-bar``
Combine osd-bar and osd-msg.
``raw``
Do not expand properties in string arguments. (Like ``"${property-name}"``.)
``expand-properties`` (default)
All string arguments are expanded as described in `Property Expansion`_.
All of the osd prefixes are still overridden by the global ``--osd-level``
settings.
Undocumented prefixes: ``pausing``, ``pausing_keep``, ``pausing_toggle``,
``pausing_keep_force``. (Should these be made official?)
Input Sections
--------------
Input sections group a set of bindings, and enable or disable them at once.
In ``input.conf``, each key binding is assigned to an input section, rather
than actually having explicit text sections.
Also see ``enable_section`` and ``disable_section`` commands.
Predefined bindings:
``default``
Bindings without input section are implicitly assigned to this section. It
is enabled by default during normal playback.
``encode``
Section which is active in encoding mode. It is enabled exclusively, so
that bindings in the ``default`` sections are ignored.
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
expansion. (See `Property Expansion`_.)
The ``W`` column indicates whether the property is generally writable. If an
option is referenced, the property should take/return exactly the same values
as the option.
=============================== = ==================================================
Name W Comment
=============================== = ==================================================
``osd-level`` x see ``--osd-level``
``osd-scale`` x osd font size multiplicator, see ``--osd-scale``
``loop`` x see ``--loop``
``speed`` x see ``--speed``
``filename`` currently played file (path stripped)
``path`` currently played file (full path)
``media-title`` filename, title tag, or libquvi ``QUVIPROP_PAGETITLE``
``demuxer``
``stream-path`` filename (full path) of stream layer filename
``stream-pos`` x byte position in source stream
``stream-start`` start byte offset in source stream
``stream-end`` end position in bytes in source stream
``stream-length`` length in bytes (``${stream-end} - ${stream-start}``)
``stream-time-pos`` x time position in source stream (also see ``time-pos``)
``length`` length of the current file in seconds
``avsync`` last A/V synchronization difference
``percent-pos`` x position in current file (0-100)
``ratio-pos`` x position in current file (0.0-1.0)
``time-pos`` x position in current file in seconds
``time-remaining`` estimated remaining length of the file in seconds
``playtime-remaining`` ``time-remaining`` scaled by the the current ``speed``
``chapter`` x current chapter number
``edition`` x current MKV edition number
``titles`` number of DVD titles
``chapters`` number of chapters
``editions`` number of MKV editions
``angle`` x current DVD angle
``metadata`` metadata key/value pairs
``metadata/<key>`` value of metadata entry ``<key>``
``chapter-metadata`` metadata of current chapter (works similar)
``pause`` x pause status (bool)
``cache`` network cache fill state (0-100)
``pts-association-mode`` x see ``--pts-association-mode``
``hr-seek`` x see ``--hr-seek``
``volume`` x current volume (0-100)
``mute`` x current mute status (bool)
``audio-delay`` x see ``--audio-delay``
``audio-format`` audio format (string)
``audio-codec`` audio codec selected for decoding
``audio-bitrate`` audio bitrate
``samplerate`` audio samplerate
``channels`` number of audio channels
``aid`` x current audio track (similar to ``--aid``)
``audio`` x alias for ``aid``
``balance`` x audio channel balance
``fullscreen`` x see ``--fullscreen``
``deinterlace`` x similar to ``--deinterlace``
``colormatrix`` x see ``--colormatrix``
``colormatrix-input-range`` x see ``--colormatrix-input-range``
``colormatrix-output-range`` x see ``--colormatrix-output-range``
``ontop`` x see ``--ontop``
``border`` x see ``--border``
``framedrop`` x see ``--framedrop``
``gamma`` x see ``--gamma``
``brightness`` x see ``--brightness``
``contrast`` x see ``--contrast``
``saturation`` x see ``--saturation``
``hue`` x see ``--hue``
``panscan`` x see ``--panscan``
``video-format`` video format (string)
``video-codec`` video codec selected for decoding
``video-bitrate`` video bitrate
``width`` video width (container or decoded size)
``height`` video height
``fps`` container FPS (may contain bogus values)
``dwidth`` video width (after filters and aspect scaling)
``dheight`` video height
``window-scale`` x window size multiplier (1 means video size)
``aspect`` x video aspect
``osd-width`` last known OSD width (can be 0)
``osd-height`` last known OSD height (can be 0)
``osd-par`` last known OSD display pixel aspect (can be 0)
``vid`` x current video track (similar to ``--vid``)
``video`` x alias for ``vid``
``video-align-x`` x see ``--video-align-x``
``video-align-y`` x see ``--video-align-y``
``video-pan-x`` x see ``--video-pan-x``
``video-pan-y`` x see ``--video-pan-y``
``video-zoom`` x see ``--video-zoom``
``video-unscaled`` x see ``--video-unscaled``
``program`` x switch TS program (write-only)
``sid`` x current subtitle track (similar to ``--sid``)
``secondary-sid`` x secondary subtitle track (``--secondary-sid``)
``sub`` x alias for ``sid``
``sub-delay`` x see ``--sub-delay``
``sub-pos`` x see ``--sub-pos``
``sub-visibility`` x see ``--sub-visibility``
``sub-forced-only`` x see ``--sub-forced-only``
``sub-scale`` x subtitle font size multiplicator
``ass-use-margins`` x see ``--ass-use-margins``
``ass-vsfilter-aspect-compat`` x see ``--ass-vsfilter-aspect-compat``
``ass-style-override`` x see ``--ass-style-override``
``stream-capture`` x a filename, see ``--capture``
``tv-brightness`` x
``tv-contrast`` x
``tv-saturation`` x
``tv-hue`` x
``playlist-pos`` current position on playlist
``playlist-count`` number of total playlist entries
``playlist`` playlist, current entry marked
``track-list`` list of audio/video/sub tracks, current entry marked
``chapter-list`` list of chapters, current entry marked
``quvi-format`` x see ``--quvi-format``
``af`` x see ``--af``
``vf`` x see ``--vf``
``options/name`` read-only access to value of option ``--name``
=============================== = ==================================================
Property Expansion
------------------
All string arguments to input commands as well as certain options (like
``--playing-msg``) are subject to property expansion.
.. admonition:: Example for input.conf
``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
``raw`` prefix in front of commands.
The following expansions are supported:
``${NAME}``
Expands to the value of the property ``NAME``. If retrieving the property
fails, expand to an error string. (Use ``${NAME:}`` with a trailing
``:`` to expand to an empty string instead.)
If ``NAME`` is prefixed with ``=``, expand to the raw value of the property
(see section below).
``${NAME:STR}``
Expands to the value of the property ``NAME``, or ``STR`` if the
property cannot be retrieved. ``STR`` is expanded recursively.
``${?NAME:STR}``
Expands to ``STR`` (recursively) if the property ``NAME`` is available.
``${!NAME:STR}``
Expands to ``STR`` (recursively) if the property ``NAME`` cannot be
retrieved.
``${?NAME==VALUE:STR}``
Expands to ``STR`` (recursively) if the property ``NAME`` expands to a
string equal to ``VALUE``. You can prefix ``NAME`` with ``=`` in order to
compare the raw value of a property (see section below). If the property
is unavailable, or other errors happen when retrieving it, the value is
never considered equal.
Note that ``VALUE`` can't contain any of the characters ``:`` or ``}``.
Also, it is possible that escaping with ``"`` or ``%`` might be added in
the future, should the need arise.
``${!NAME==VALUE:STR}``
Same as with the ``?`` variant, but ``STR`` is expanded if the value is
not equal. (Using the same semantics as with ``?``.)
``$$``
Expands to ``$``.
``$}``
Expands to ``}``. (To produce this character inside recursive
expansion.)
``$>``
Disable property expansion and special handling of ``$`` for the rest
of the string.
In places where property expansion is allowed, C-style escapes are often
accepted as well. Example:
- ``\n`` becomes a newline character
- ``\\`` expands to ``\``
Raw and Formatted Properties
----------------------------
Normally, properties are formatted as human-readable text, meant to be
displayed on OSD or on the terminal. It is possible to retrieve an unformatted
(raw) value from a property by prefixing its name with ``=``. These raw values
can be parsed by other programs and follow the same conventions as the options
associated with the properties.
.. admonition:: Examples
- ``${time-pos}`` expands to ``00:14:23`` (if playback position is at 14
minutes 23 seconds)
- ``${=time-pos}`` expands to ``863.4`` (same time, plus 400 milliseconds -
milliseconds are normally not shown in the formatted case)
Sometimes, the difference in amount of information carried by raw and formatted
property values can be rather big. In some cases, raw values have more
information, like higher precision than seconds with ``time-pos``. Sometimes
it is the other way around, e.g. ``aid`` shows track title and language in the
formatted case, but only the track number if it is raw.
+18
View File
@@ -0,0 +1,18 @@
LUA SCRIPTING
=============
mpv can load Lua scripts. These scripts can be used to control mpv in a similar
way to slave mode. mpv provides the builtin module ``mp`` (can be loaded
with ``require 'mp'``), which provides functions to send commands to the
mpv core and to retrieve information about playback state, user settings,
file information, and so on.
.. admonition:: Warning
Lua scripting is work in progress, and it's in a very early stage. When
writing scripts, rely only on the features and functions documented here.
Everything else is subject to change.
.. admonition:: Warning
Nothing is finished and documented yet.
+105 -366
View File
@@ -2,23 +2,44 @@ mpv
###
##############
a media player
a movie player
##############
:Author: wm4
:Copyright: GPLv2+
:Manual section: 1
:Manual group: multimedia
.. raw:: latex
\tableofcontents
\pagebreak
SYNOPSIS
========
| **mpv** [options] [file|URL|PLAYLIST|-]
| **mpv** [options] [file|URL|-]
| **mpv** [options] --playlist=PLAYLIST
| **mpv** [options] files
| **mpv** [options] {group of files and options}
| **mpv** [bd]://[title][/device] [options]
| **mpv** dvd://[title|[start\_title]-end\_title][/device] [options]
| **mpv** dvdnav://[longest|menu|title][/device] [options]
| **mpv** \vcd://[/device]
| **mpv** \tv://[channel][/input_id] [options]
| **mpv** radio://[channel|frequency][/capture] [options]
| **mpv** \pvr:// [options]
| **mpv** \dvb://[card\_number@]channel [options]
| **mpv** \mf://[filemask|\@listfile] [-mf options] [options]
| **mpv** cdda://track[-endtrack][:speed][/device] [options]
| **mpv** [file|mms[t]|http|httpproxy|rt[s]p|ftp|udp|smb]://[user:pass\@]URL[:port] [options]
| **mpv** edl://[edl specification as in edl-mpv.rst]
DESCRIPTION
===========
**mpv** is a media player based on MPlayer and mplayer2. It supports a wide variety of video
**mpv** is a movie player based on MPlayer and mplayer2. It supports a wide variety of video
file formats, audio and video codecs, and subtitle types. Special input URL
types are available to read input from a variety of sources other than disk
files. Depending on platform, a variety of different video and audio output
@@ -32,25 +53,22 @@ INTERACTIVE CONTROL
===================
mpv has a fully configurable, command-driven control layer which allows you
to control mpv using keyboard, mouse, or remote control (there is no
LIRC support - configure remotes as input devices instead).
See the ``--input-`` options for ways to customize it.
to control mpv using keyboard, mouse, joystick or remote control (with
LIRC). See the ``--input-`` options for ways to customize it.
Keyboard Control
----------------
LEFT and RIGHT
Seek backward/forward 5 seconds. Shift+arrow does a 1 second exact seek
Seek backward/forward 10 seconds. Shift+arrow does a 1 second exact seek
(see ``--hr-seek``).
UP and DOWN
Seek forward/backward 1 minute. Shift+arrow does a 5 second exact seek (see
``--hr-seek``).
Ctrl+LEFT and Ctrl+RIGHT
Seek to the previous/next subtitle. Subject to some restrictions and
might not work always; see ``sub_seek`` command.
PGUP and PGDWN
Seek forward/backward 10 minutes.
[ and ]
Decrease/increase current playback speed by 10%.
@@ -65,32 +83,41 @@ BACKSPACE
Go backward/forward in the playlist.
ENTER
Go forward in the playlist.
Go forward in the playlist, even over the end.
p / SPACE
Pause (pressing again unpauses).
\.
Step forward. Pressing once will pause, every consecutive press will
Step forward. Pressing once will pause movie, every consecutive press will
play one frame and then go into pause mode again.
,
Step backward. Pressing once will pause, every consecutive press will
Step backward. Pressing once will pause movie, every consecutive press will
play one frame in reverse and then go into pause mode again.
q
q / ESC
Stop playing and quit.
Q
Like ``q``, but store the current playback position. Playing the same file
later will resume at the old playback position if possible.
U
Stop playing (and quit if ``--idle`` is not used).
\+ and -
Adjust audio delay by +/- 0.1 seconds.
/ and *
Decrease/increase volume.
9 and 0
Decrease/increase volume.
( and )
Adjust audio balance in favor of left/right channel.
m
Mute sound.
@@ -100,22 +127,19 @@ m
\#
Cycle through the available audio tracks.
TAB (MPEG-TS and libavformat only)
Cycle through the available programs.
f
Toggle fullscreen (see also ``--fs``).
ESC
Exit fullscreen mode.
T
Toggle stay-on-top (see also ``--ontop``).
w and e
Decrease/increase pan-and-scan range.
o (also P)
Show progression bar, elapsed time and total duration on the OSD.
O
o
Toggle OSD states: none / seek / seek + timer / seek + timer + total time.
d
@@ -128,20 +152,12 @@ v
j and J
Cycle through the available subtitles.
F
Toggle displaying "forced subtitles".
x and z
Adjust subtitle delay by +/- 0.1 seconds.
l
Set/clear A-B loop points. See ``ab_loop`` command for details.
Ctrl + and Ctrl -
Adjust audio delay by +/- 0.1 seconds.
u
Switch between applying no style overrides to SSA/ASS subtitles, and
overriding them almost completely with the normal subtitle style. See
``--ass-style-override`` for more info.
V
Toggle subtitle VSFilter aspect compatibility mode. See
``--ass-vsfilter-aspect-compat`` for more info.
@@ -159,20 +175,22 @@ S
I
Show filename on the OSD.
PGUP and PGDWN
P
Show progression bar, elapsed time and total duration on the OSD.
! and @
Seek to the beginning of the previous/next chapter. In most cases,
"previous" will actually go to the beginning of the current chapter; see
``--chapter-seek-threshold``.
Shift+PGUP and Shift+PGDWN
Seek backward or forward by 10 minutes. (This used to be mapped to
PGUP/PGDWN without Shift.)
D
D (``--vo=vdpau``, ``--vf=yadif`` only)
Activate/deactivate deinterlacer.
A
Cycle aspect ratio override.
Cycle through the available DVD angles.
c
Change YUV colorspace.
(The following keys are valid only when using a video output that supports the
corresponding adjustment, or the software equalizer (``--vf=eq``).)
@@ -189,24 +207,22 @@ corresponding adjustment, or the software equalizer (``--vf=eq``).)
7 and 8
Adjust saturation.
(The following keys are valid only on OS X.)
(The following keys are valid only on OSX.)
command + 0
Resize video window to half its original size.
(On other platforms, you can bind keys to change the ``window-scale``
property.)
Resize movie window to half its original size.
command + 1
Resize video window to its original size.
Resize movie window to its original size.
command + 2
Resize video window to double its original size.
Resize movie window to double its original size.
command + f
Toggle fullscreen (see also ``--fs``).
command + [ and command + ]
Set video window alpha.
Set movie window alpha.
(The following keys are valid if you have a keyboard with multimedia keys.)
@@ -225,6 +241,12 @@ support.)
h and k
Select previous/next channel.
n
Change norm.
u
Change channel list.
Mouse Control
-------------
@@ -245,47 +267,13 @@ is the same as ``--no-fs``.
If an option is marked as *(XXX only)*, it will only work in combination with
the *XXX* option or if *XXX* is compiled in.
Escaping spaces and other special characters
--------------------------------------------
.. note::
Keep in mind that the shell will partially parse and mangle the arguments you
pass to mpv. For example, you might need to quote or escape options and
filenames:
The suboption parser (used for example for ``--ao=pcm`` suboptions)
supports a special kind of string-escaping intended for use with external
GUIs.
``mpv "filename with spaces.mkv" --title="window title"``
It gets more complicated if the suboption parser is involved. The suboption
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 ``[...]``.
Additionally, there is a special form of quoting with ``%n%`` described below.
For example, the ``opengl`` VO can take multiple options:
``mpv test.mkv --vo=opengl:scale=lanczos:icc-profile=file.icc,xv``
This passes ``scale=lanczos`` and ``icc-profile=file.icc`` to ``opengl``,
and also specifies ``xv`` as fallback VO. If the icc-profile path contains
spaces or characters like ``,`` or ``:``, you need to quote them:
``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 ``"``
quotes.
The ``[...]`` form of quotes wraps everything between ``[`` and ``]``. It's
useful with shells that don't interpret these characters in the middle of
an argument (like bash). These quotes are balanced (since mpv 0.9.0): the ``[``
and ``]`` nest, and the quote terminates on the last ``]`` that has no matching
``[`` within the string. (For example, ``[a[b]c]`` results in ``a[b]c``.)
The fixed-length quoting syntax is intended for use with external
scripts and programs.
It is started with ``%`` and has the following format::
It has the following format::
%n%string_of_length_n
@@ -297,15 +285,6 @@ It is started with ``%`` and has the following format::
``mpv --ao=pcm:file=%`expr length "$NAME"`%"$NAME" test.avi``
Suboptions passed to the client API are also subject to escaping. Using
``mpv_set_option_string()`` is exactly like passing ``--name=data`` to the
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
of maps and arrays. (``--vo`` supports this in the same way, although this
fact is undocumented.)
Paths
-----
@@ -321,11 +300,10 @@ console controls. (Which makes it suitable for playing data piped to stdin.)
For paths passed to suboptions, the situation is further complicated by the
need to escape special characters. To work this around, the path can be
additionally wrapped in the fixed-length syntax, e.g. ``%n%string_of_length_n``
(see above).
additionally wrapped in the ``%n%string_of_length_n`` syntax (see above).
Some mpv options interpret paths starting with ``~``. Currently, the prefix
``~~/`` expands to the mpv configuration directory (usually ``~/.config/mpv/``).
``~~/`` expands to the mpv configuration directory (usually ``~/.mpv/``).
``~/`` expands to the user's home directory. (The trailing ``/`` is always
required.)
@@ -378,7 +356,7 @@ Location and Syntax
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``.
user-specific one is ``~/.mpv/config``.
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
@@ -394,17 +372,6 @@ setting them to *no*. Even suboptions can be specified in this way.
# Use quotes for text that can contain spaces:
status-msg="Time: ${time-pos}"
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 ``'``,
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
this manually. (This is a mess and should probably be changed at some point.)
Putting Command Line Options into the Configuration File
--------------------------------------------------------
@@ -424,13 +391,13 @@ File-specific Configuration Files
---------------------------------
You can also write file-specific configuration files. If you wish to have a
configuration file for a file called 'video.avi', create a file named
'video.avi.conf' with the file-specific options in it and put it in
``~/.config/mpv/``. You can also put the configuration file in the same directory
as the file to be played. Both require you to set the ``--use-filedir-conf``
configuration file for a file called 'movie.avi', create a file named
'movie.avi.conf' with the file-specific options in it and put it in
``~/.mpv/``. You can also put the configuration file in the same directory
as the file to be played, as long as you give the ``--use-filedir-conf``
option (either on the command line or in your global config file). If a
file-specific configuration file is found in the same directory, no
file-specific configuration is loaded from ``~/.config/mpv``. In addition, the
file-specific configuration is loaded from ``~/.mpv``. In addition, the
``--use-filedir-conf`` option enables directory-specific configuration files.
For this, mpv first tries to load a mpv.conf from the same directory
as the file played and then tries to load any file-specific configuration.
@@ -451,11 +418,12 @@ profile name ``default`` to continue with normal options.
::
[vo.vdpau]
# Use hardware decoding
# Use hardware decoding (might break playback of some h264 files)
hwdec=vdpau
[protocol.dvd]
profile-desc="profile for dvd:// streams"
vf=pp=hb/vb/dr/al/fd
alang=en
[extension.flv]
@@ -478,169 +446,11 @@ A screenshot will usually contain the unscaled video contents at the end of the
video filter chain and subtitles. By default, ``S`` takes screenshots without
subtitles, while ``s`` includes subtitles.
Unlike with MPlayer, the ``screenshot`` video filter is not required. This
filter was never required in mpv, and has been removed.
TERMINAL STATUS LINE
====================
During playback, mpv shows the playback status on the terminal. It looks like
something like this:
``AV: 00:03:12 / 00:24:25 (13%) A-V: -0.000``
The status line can be overridden with the ``--term-status-msg`` option.
The following is a list of things that can show up in the status line. Input
properties, that can be used to get the same information manually, are also
listed.
- ``AV:`` or ``V:`` (video only) or ``A:`` (audio only)
- The current time position in ``HH:MM:SS`` format (``playback-time`` property)
- The total file duration (absent if unknown) (``length`` property)
- Playback speed, e.g. `` x2.0``. Only visible if the speed is not normal. This
is the user-requested speed, and not the actual speed (usually they should
be the same, unless playback is too slow). (``speed`` property.)
- Playback percentage, e.g. ``(13%)``. How much of the file has been played.
Normally calculated out of playback position and duration, but can fallback
to other methods (like byte position) if these are not available.
(``percent-pos`` property.)
- The audio/video sync as ``A-V: 0.000``. This is the difference between
audio and video time. Normally it should be 0 or close to 0. If it's growing,
it might indicate a playback problem. (``avsync`` property.)
- Total A/V sync change, e.g. ``ct: -0.417``. Normally invisible. Can show up
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.
- 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.
(``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,
the second value shows *additional* data buffered in the stream cache in
kilobytes. (``demuxer-cache-duration`` and ``cache-used`` properties.)
PROTOCOLS
=========
``http://...``, ``https://``, ...
Many network protocols are supported, but the protocol prefix must always
be specified. mpv will never attempt to guess whether a filename is
actually a network address. A protocol prefix is always required.
Note that not all prefixes are documented here. Undocumented prefixes are
either aliases to documented protocols, or are just redirections to
protocols implemented and documented in FFmpeg.
``-``
Play data from stdin.
``smb://PATH``
Play a path from Samba share.
``bd://[title][/device]`` ``--bluray-device=PATH``
Play a Blu-Ray disc. Currently, this does not accept ISO files. Instead,
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.
``dvdnav://`` is an old alias for ``dvd://`` and does exactly the same
thing.
``dvdread://...:``
Play a DVD using the old libdvdread code. This is what MPlayer and older
mpv versions use for ``dvd://``. Use is discouraged. It's provided only
for compatibility and for transition.
``tv://[channel][/input_id]`` ``--tv-...``
Analogue TV via V4L. Also useful for webcams. (Linux only.)
``pvr://`` ``--pvr-...``
PVR. (Linux only.)
``dvb://[cardnumber@]channel`` ``--dvbin-...``
Digital TV via DVB. (Linux only.)
``mf://[filemask|@listfile]`` ``--mf-...``
Play a series of images as video.
``cdda://track[-endtrack][:speed][/device]`` ``--cdrom-device=PATH`` ``--cdda-...``
Play CD.
``lavf://...``
Access any FFmpeg/Libav libavformat protocol. Basically, this passed the
string after the ``//`` directly to libavformat.
``av://type:options``
This is intended for using libavdevice inputs. ``type`` is the libavdevice
demuxer name, and ``options`` is the (pseudo-)filename passed to the
demuxer.
For example, ``mpv av://lavfi:mandelbrot`` makes use of the libavfilter
wrapper included in libavdevice, and will use the ``mandelbrot`` source
filter to generate input data.
``avdevice://`` is an alias.
``file://PATH``
A local path as URL. Might be useful in some special use-cases. Note that
``PATH`` itself should start with a third ``/`` to make the path an
absolute path.
``edl://[edl specification as in edl-mpv.rst]``
Stitch together parts of multiple files and play them.
``null://``
Simulate an empty file.
``memory://data``
Use the ``data`` part as source data.
PSEUDO GUI MODE
===============
mpv has no official GUI, other than the OSC (`ON SCREEN CONTROLLER`_), which
is not a full GUI and is not meant to be. However, to compensate for the lack
of expected GUI behavior, mpv will in some cases start with some settings
changed to behave slightly more like a GUI mode.
Currently this happens only in the following cases:
- if started using the ``mpv.desktop`` file on Linux (e.g. started from menus
or file associations provided by desktop environments)
- if started from explorer.exe on Windows (technically, if it was started on
Windows, and all of the stdout/stderr/stdin handles are unset)
- manually adding ``--profile=pseudo-gui`` to the command line
This mode implicitly adds ``--profile=pseudo-gui`` to the command line, with
the ``pseudo-gui`` profile being predefined with the following contents:
::
[pseudo-gui]
terminal=no
force-window=yes
idle=once
This follows the mpv config file format. To customize pseudo-GUI mode, you can
put your own ``pseudo-gui`` profile into your ``mpv.conf``. This profile will
enhance the default profile, rather than overwrite it.
The profile always overrides other settings in ``mpv.conf``.
The ``screenshot`` video filter is not required when using a recommended GUI
video output driver. It should normally not be added to the config file, as
taking screenshots is handled by the VOs, and adding the screenshot filter will
break hardware decoding. (The filter may still be useful for taking screenshots
at a certain point within the video chain when using multiple video filters.)
.. include:: options.rst
@@ -660,8 +470,6 @@ The profile always overrides other settings in ``mpv.conf``.
.. include:: lua.rst
.. include:: ipc.rst
.. include:: changes.rst
ENVIRONMENT VARIABLES
@@ -670,28 +478,23 @@ ENVIRONMENT VARIABLES
There are a number of environment variables that can be used to control the
behavior of mpv.
``HOME``, ``XDG_CONFIG_HOME``
Used to determine mpv config directory. If ``XDG_CONFIG_HOME`` is not set,
``$HOME/.config/mpv`` is used.
``$HOME/.mpv`` is always added to the list of config search paths with a
lower priority.
``XDG_CONFIG_DIRS``
If set, XDG-style system configuration directories are used. Otherwise,
the UNIX convention (``PREFIX/etc/mpv/``) is used.
``HOME``
Used to determine mpv config directory: ``$HOME/.mpv``
``TERM``
Used to determine terminal type.
``MPV_HOME``
Directory where mpv looks for user settings. Overrides ``HOME``, and mpv
will try to load the config file as ``$MPV_HOME/mpv.conf``.
will try to load the config file as ``$MPV_HOME/config``.
``MPV_VERBOSE`` (see also ``-v`` and ``--msg-level``)
``MPV_LOCALEDIR``
Directory where mpv looks for gettext translation files (if enabled).
``MPV_VERBOSE`` (see also ``-v`` and ``--msglevel``)
Set the initial verbosity level across all message modules (default: 0).
This is an integer, and the resulting verbosity corresponds to the number
of ``--v`` options passed to the command line.
The resulting verbosity corresponds to that of ``--msglevel=5`` plus the
value of ``MPV_VERBOSE``.
``MPV_LEAK_REPORT``
If set to ``1``, enable internal talloc leak reporting. Note that this can
@@ -797,78 +600,14 @@ FILES
=====
``/usr/local/etc/mpv/mpv.conf``
mpv system-wide settings (depends on ``--prefix`` passed to configure - mpv
in default configuration will use ``/usr/local/etc/mpv/`` as config
directory, while most Linux distributions will set it to ``/etc/mpv/``).
mpv system-wide settings (depends on ``--prefix`` passed to configure)
``~/.config/mpv/mpv.conf``
mpv user settings (see `CONFIGURATION FILES`_ section)
``~/.mpv/config``
mpv user settings
``~/.config/mpv/input.conf``
key bindings (see `INPUT.CONF`_ section)
``~/.mpv/input.conf``
input bindings (see ``--input-keylist`` for the full list)
``~/.config/mpv/scripts/``
All files in this directory are loaded as if they were passed to the
``--script`` option. They are loaded in alphabetical order, and sub-directories
and files with no ``.lua`` extension are ignored. The ``--load-scripts=no``
option disables loading these files.
``~/.config/mpv/watch_later/``
Contains temporary config files needed for resuming playback of files with
the watch later feature. See for example the ``Q`` key binding, or the
``quit_watch_later`` input command.
Each file is a small config file which is loaded if the corresponding media
file is loaded. It contains the playback position and some (not necessarily
all) settings that were changed during playback. The filenames are hashed
from the full paths of the media files. It's in general not possible to
extract the media filename from this hash. However, you can set the
``--write-filename-in-watch-later-config`` option, and the player will
add the media filename to the contents of the resume config file.
``~/.config/mpv/lua-settings/osc.conf``
This is loaded by the OSC script. See the `ON SCREEN CONTROLLER`_ docs
for details.
Other files in this directory are specific to the corresponding scripts
as well, and the mpv core doesn't touch them.
Note that the environment variables ``$XDG_CONFIG_HOME`` and ``$MPV_HOME`` can
override the standard directory ``~/.config/mpv/``.
Also, the old config location at ``~/.mpv/`` is still read, and if the XDG
variant does not exist, will still be preferred.
FILES ON WINDOWS
================
On win32 (if compiled with MinGW, but not Cygwin), the default config file
locations are different. They are generally located under ``%APPDATA%/mpv/``.
For example, the path to mpv.conf is ``%APPDATA%/mpv/mpv.conf``, which maps to
a system and user-specific path, for example
``C:\users\USERNAME\Application Data\mpv\mpv.conf``
You can find the exact path by running ``echo %APPDATA%\mpv\mpv.conf`` in cmd.exe.
Other config files (such as ``input.conf``) are in the same directory. See the
`FILES`_ section above.
The environment variable ``$MPV_HOME`` completely overrides these, like on
UNIX.
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
one from the directory with higher priority will be loaded.
A third config directory with lowest priority is the directory named ``mpv``
in the same directory as ``mpv.exe``. This used to be the directory with
highest priority, but is now discouraged to use and might be removed in the
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
=====================
@@ -886,8 +625,8 @@ Play only chapters 5, 6, 7:
Play only titles 5, 6, 7:
``mpv dvd://5-7``
Play a multi-angle DVD:
``mpv dvd://1 --dvd-angle=2``
Play a multiangle DVD:
``mpv dvd://1 --dvdangle=2``
Play from a different DVD device:
``mpv dvd://1 --dvd-device=/dev/dvd2``
File diff suppressed because it is too large. Load diff
+7 -66
View File
@@ -122,24 +122,12 @@ time remaining
left-click toggle between total and remaining time
============= ================================================
Key Bindings
~~~~~~~~~~~~
These key bindings are active by default if nothing else is already bound to
these keys. In case of collision, the function needs to be bound to a
different key. See the `Script Commands`_ section.
============= ================================================
del Hide the OSC permanently until mpv is restarted.
============= ================================================
Configuration
-------------
The OSC offers limited configuration through a config file
``lua-settings/osc.conf`` placed in mpv's user dir and through the
``--script-opts`` command-line option. Options provided through the command-line
will override those from the config file.
The OSC offers limited configuration through a config file ``plugin_osc.conf``
placed in mpv's user dir.
Config Syntax
~~~~~~~~~~~~~
@@ -147,25 +135,14 @@ Config Syntax
The config file must exactly follow the following syntax::
# this is a comment
optionA=value1
optionB=value2
parameter1=value1
parameter2=value2
``#`` can only be used at the beginning of a line and there may be no
spaces around the ``=`` or anywhere else.
Command-line Syntax
~~~~~~~~~~~~~~~~~~~
To avoid collisions with other scripts, all options need to be prefixed with
``osc-``.
Example::
--script-opts=osc-optionA=value1,osc-optionB=value2
Configurable Options
~~~~~~~~~~~~~~~~~~~~
Configurable parameters
~~~~~~~~~~~~~~~~~~~~~~~
``showwindowed``
| Default: yes
@@ -216,46 +193,10 @@ Configurable Options
| Default: 0
| Size of the deadzone. The deadzone is an area that makes the mouse act
like leaving the window. Movement there won't make the OSC show up and
it will hide immediately if the mouse enters it. The deadzone starts
at the window border opposite to the OSC and the size controls how much
of the window it will span. Values between 0 and 1.
it will hide immediately if the mouse enters it.
``minmousemove``
| Default: 3
| Minimum amount of pixels the mouse has to move between ticks to make
the OSC show up
``layout``
| Default: box
| The layout for the OSC. Currently available are: box, slimbox,
bottombar and topbar.
``seekbarstyle``
| Default: slider
| Sets the style of the seekbar, slider (diamond marker) or bar (fill)
Script Commands
~~~~~~~~~~~~~~~
The OSC script listens to certain script commands. These commands can bound
in ``input.conf``, or sent by other scripts.
``enable-osc``
Undoes ``disable-osc`` or the effect of the ``del`` key.
``disable-osc``
Hide the OSC permanently. This is also what the ``del`` key does.
``osc-message``
Show a message on screen using the OSC. First argument is the message,
second the duration in seconds.
Example
You could put this into ``input.conf`` to hide the OSC with the ``a`` key and
to unhide it with ``b``::
a script_message disable-osc
b script_message enable-osc
+324 -331
View File
@@ -47,7 +47,7 @@ Available filters are:
``crop[=w:h:x:y]``
Crops the given part of the image and discards the rest. Useful to remove
black bands from widescreen videos.
black bands from widescreen movies.
``<w>,<h>``
Cropped width and height, defaults to original width and height.
@@ -55,7 +55,7 @@ Available filters are:
Position of the cropped picture, defaults to center.
``expand[=w:h:x:y:aspect:round]``
Expands (not scales) video resolution to the given value and places the
Expands (not scales) movie resolution to the given value and places the
unscaled original at coordinates x, y.
``<w>,<h>``
@@ -88,12 +88,19 @@ Available filters are:
``mirror``
Mirrors the image on the Y axis.
``rotate[=0|90|180|270]``
Rotates the image by a multiple of 90 degrees clock-wise.
``rotate[=<0-7>]``
Rotates the image by 90 degrees and optionally flips it. For values
between 4-7 rotation is only done if the movie geometry is portrait and
not landscape.
:0: Rotate by 90 degrees clockwise and flip (default).
:1: Rotate by 90 degrees clockwise.
:2: Rotate by 90 degrees counterclockwise.
:3: Rotate by 90 degrees counterclockwise and flip.
``scale[=w:h:param:param2:chr-drop:noup:arnd``
Scales the image with the software scaler (slow) and performs a YUV<->RGB
color space conversion (see also ``--sws``).
colorspace conversion (see also ``--sws``).
All parameters are optional.
@@ -120,9 +127,9 @@ Available filters are:
0.33:0.33 Mitchell-Netravali spline
1.00:0.00 cubic B-spline
--sws=7 (Gaussian): sharpness (0 (soft) - 100 (sharp))
--sws=7 (gaussian): sharpness (0 (soft) - 100 (sharp))
--sws=9 (Lanczos): filter length (1-10)
--sws=9 (lanczos): filter length (1-10)
``<chr-drop>``
chroma skipping
@@ -143,8 +150,8 @@ Available filters are:
Accurate rounding for the vertical scaler, which may be faster or
slower than the default rounding.
:no: Disable accurate rounding (default).
:yes: Enable accurate rounding.
:0: Disable accurate rounding (default).
:1: Enable accurate rounding.
``dsize[=w:h:aspect-method:r:aspect]``
Changes the intended display size/aspect at an arbitrary point in the
@@ -207,152 +214,23 @@ Available filters are:
For a list of available formats, see ``format=fmt=help``.
``<fmt>``
Format name, e.g. rgb15, bgr24, 420p, etc. (default: don't change).
Format name, e.g. rgb15, bgr24, 420p, etc. (default: yuyv).
``<outfmt>``
Format name that should be substituted for the output. If they do not
have the same bytes per pixel and chroma subsamplimg, it will fail.
``<colormatrix>``
Controls the YUV to RGB color space conversion when playing video. There
are various standards. Normally, BT.601 should be used for SD video, and
BT.709 for HD video. (This is done by default.) Using incorrect color space
results in slightly under or over saturated and shifted colors.
Format name that should be substituted for the output. If this is not
100% compatible with the ``<fmt>`` value, it will crash.
These options are not always supported. Different video outputs provide
varying degrees of support. The ``opengl`` and ``vdpau`` video output
drivers usually offer full support. The ``xv`` output can set the color
space if the system video driver supports it, but not input and output
levels. The ``scale`` video filter can configure color space and input
levels, but only if the output format is RGB (if the video output driver
supports RGB output, you can force this with ``-vf scale,format=rgba``).
If this option is set to ``auto`` (which is the default), the video's
color space flag will be used. If that flag is unset, the color space
will be selected automatically. This is done using a simple heuristic that
attempts to distinguish SD and HD video. If the video is larger than
1279x576 pixels, BT.709 (HD) will be used; otherwise BT.601 (SD) is
selected.
Available color spaces are:
:auto: automatic selection (default)
:bt.601: ITU-R BT.601 (SD)
:bt.709: ITU-R BT.709 (HD)
:bt.2020-ncl: ITU-R BT.2020 non-constant luminance system
:bt.2020-cl: ITU-R BT.2020 constant luminance system
:smpte-240m: SMPTE-240M
``<colorlevels>``
YUV color levels used with YUV to RGB conversion. This option is only
necessary when playing broken files which do not follow standard color
levels or which are flagged wrong. If the video does not specify its
color range, it is assumed to be limited range.
The same limitations as with ``<colormatrix>`` apply.
Available color ranges are:
:auto: automatic selection (normally limited range) (default)
: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
used to override the setting.
This option only affects video output drivers that perform color
management, for example ``opengl`` with the ``target-prim`` or
``icc-profile`` suboptions set.
If this option is set to ``auto`` (which is the default), the video's
primaries flag will be used. If that flag is unset, the color space will
be selected automatically, using the following heuristics: If the
``<colormatrix>`` is set or determined as BT.2020 or BT.709, the
corresponding primaries are used. Otherwise, if the video height is
exactly 576 (PAL), BT.601-625 is used. If it's exactly 480 or 486 (NTSC),
BT.601-525 is used. If the video resolution is anything else, BT.709 is
used.
Available primaries are:
:auto: automatic selection (default)
:bt.601-525: ITU-R BT.601 (SD) 525-line systems (NTSC, SMPTE-C)
:bt.601-625: ITU-R BT.601 (SD) 625-line systems (PAL, SECAM)
:bt.709: ITU-R BT.709 (HD) (same primaries as sRGB)
:bt.2020: ITU-R BT.2020 (UHD)
:apple: Apple RGB
:adobe: Adobe RGB (1998)
:prophoto: ProPhoto RGB (ROMM)
:cie1931: CIE 1931 RGB
``<gamma>``
Gamma function 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
used to override the setting.
This option only affects video output drivers that perform color management.
If this option is set to ``auto`` (which is the default), the gamma will
be set to BT.1886 for YCbCr content, sRGB for RGB content and Linear for
XYZ content.
Available gamma functions are:
:auto: automatic selection (default)
:bt.1886: ITU-R BT.1886 (approximation of BT.601/BT.709/BT.2020 curve)
:srgb: IEC 61966-2-4 (sRGB)
:linear: Linear light
:gamma1.8: Pure power curve (gamma 1.8)
:gamma2.2: Pure power curve (gamma 2.2)
:gamma2.8: Pure power curve (gamma 2.8)
:prophoto: ProPhoto RGB (ROMM) curve
``<stereo-in>``
Set the stereo mode the video is assumed to be encoded in. Takes the
same values as the ``--video-stereo-mode`` option.
``<stereo-out>``
Set the stereo mode the video should be displayed as. Takes the
same values as the ``--video-stereo-mode`` option.
``<rotate>``
Set the rotation the video is assumed to be encoded with in degrees.
The special value ``-1`` uses the input format.
``<dw>``, ``<dh>``
Set the display size. Note that setting the display size such that
the video is scaled in both directions instead of just changing the
aspect ratio is an implementation detail, and might change later.
``<dar>``
Set the display aspect ratio of the video frame. This is a float,
but values such as ``[16:9]`` can be passed too (``[...]`` for quoting
to prevent the option parser from interpreting the ``:`` character).
.. admonition:: Examples
====================== =====================
Valid Invalid (will crash)
====================== =====================
``format=rgb24:bgr24`` ``format=rgb24:420p``
``format=yuyv:uyvy``
====================== =====================
``noformat[=fmt]``
Restricts the color space for the next filter without doing any conversion.
Unlike the format filter, this will allow any color space except the one
Restricts the colorspace for the next filter without doing any conversion.
Unlike the format filter, this will allow any colorspace except the one
you specify.
.. note:: For a list of available formats, see ``noformat=fmt=help``.
@@ -360,6 +238,150 @@ Available filters are:
``<fmt>``
Format name, e.g. rgb15, bgr24, 420p, etc. (default: 420p).
``pp[=[filter1[:option1[:option2...]]/[-]filter2...]]``
Enables the specified chain of postprocessing subfilters. Subfilters must
be separated by '/' and can be disabled by prepending a '-'. Each
subfilter and some options have a short and a long name that can be used
interchangeably, i.e. ``dr``/``dering`` are the same. All subfilters share
common options to determine their scope:
``a/autoq``
Automatically switch the subfilter off if the CPU is too slow.
``c/chrom``
Do chrominance filtering, too (default).
``y/nochrom``
Do luminance filtering only (no chrominance).
``n/noluma``
Do chrominance filtering only (no luminance).
.. note::
``--vf=pp:help`` shows a list of available subfilters.
.. note::
Unlike in MPlayer or in earlier versions, you must quote the pp string
if it contains ``:`` characters, e.g. ``'--vf=pp=[...]'``.
Available subfilters are:
``hb/hdeblock[:difference[:flatness]]``
horizontal deblocking filter
:<difference>: Difference factor where higher values mean more
deblocking (default: 32).
:<flatness>: Flatness threshold where lower values mean more
deblocking (default: 39).
``vb/vdeblock[:difference[:flatness]]``
vertical deblocking filter
:<difference>: Difference factor where higher values mean more
deblocking (default: 32).
:<flatness>: Flatness threshold where lower values mean more
deblocking (default: 39).
``ha/hadeblock[:difference[:flatness]]``
accurate horizontal deblocking filter
:<difference>: Difference factor where higher values mean more
deblocking (default: 32).
:<flatness>: Flatness threshold where lower values mean more
deblocking (default: 39).
``va/vadeblock[:difference[:flatness]]``
accurate vertical deblocking filter
:<difference>: Difference factor where higher values mean more
deblocking (default: 32).
:<flatness>: Flatness threshold where lower values mean more
deblocking (default: 39).
The horizontal and vertical deblocking filters share the difference and
flatness values so you cannot set different horizontal and vertical
thresholds.
``h1/x1hdeblock``
experimental horizontal deblocking filter
``v1/x1vdeblock``
experimental vertical deblocking filter
``dr/dering``
deringing filter
``tn/tmpnoise[:threshold1[:threshold2[:threshold3]]]``
temporal noise reducer
:<threshold1>: larger -> stronger filtering
:<threshold2>: larger -> stronger filtering
:<threshold3>: larger -> stronger filtering
``al/autolevels[:f/fullyrange]``
automatic brightness / contrast correction
:f/fullyrange: Stretch luminance to (0-255).
``lb/linblenddeint``
Linear blend deinterlacing filter that deinterlaces the given block by
filtering all lines with a (1 2 1) filter.
``li/linipoldeint``
Linear interpolating deinterlacing filter that deinterlaces the given
block by linearly interpolating every second line.
``ci/cubicipoldeint``
Cubic interpolating deinterlacing filter deinterlaces the given block
by cubically interpolating every second line.
``md/mediandeint``
Median deinterlacing filter that deinterlaces the given block by
applying a median filter to every second line.
``fd/ffmpegdeint``
FFmpeg deinterlacing filter that deinterlaces the given block by
filtering every second line with a (-1 4 2 4 -1) filter.
``l5/lowpass5``
Vertically applied FIR lowpass deinterlacing filter that deinterlaces
the given block by filtering all lines with a (-1 2 6 2 -1) filter.
``fq/forceQuant[:quantizer]``
Overrides the quantizer table from the input with the constant
quantizer you specify.
:<quantizer>: quantizer to use
``de/default``
default pp filter combination (hb:a,vb:a,dr:a)
``fa/fast``
fast pp filter combination (h1:a,v1:a,dr:a)
``ac``
high quality pp filter combination (ha:a:128:7,va:a,dr:a)
.. note::
This filter is only available if FFmpeg/libav has been compiled
with libpostproc enabled.
.. admonition:: Examples
``--vf=pp=hb/vb/dr/al``
horizontal and vertical deblocking, deringing and automatic
brightness/contrast
``--vf=pp=de/-al``
default filters without brightness/contrast correction
``--vf=pp=[default/tmpnoise:1:2:3]``
Enable default filters & temporal denoiser.
``--vf=pp=[hb:y/vb:a]``
Horizontal deblocking on luminance only, and switch vertical
deblocking on or off automatically depending on available CPU time.
``lavfi=graph[:sws-flags[:o=opts]]``
Filter video using FFmpeg's libavfilter.
@@ -428,7 +450,11 @@ Available filters are:
temporal noise (noise pattern changes between frames)
``uniform``
uniform noise (Gaussian otherwise)
uniform noise (gaussian otherwise)
``hq``
high quality (slightly better looking, slightly slower) - not available
when using libavfilter
``hqdn3d[=luma_spatial:chroma_spatial:luma_tmp:chroma_tmp]``
This filter aims to reduce image noise producing smooth images and making
@@ -470,8 +496,21 @@ 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).
``ilpack[=mode]``
When interlaced video is stored in YUV 4:2:0 formats, chroma interlacing
does not line up properly due to vertical downsampling of the chroma
channels. This filter packs the planar 4:2:0 data into YUY2 (4:2:2) format
with the chroma lines in their proper locations, so that in any given
scanline, the luma and chroma data both come from the same field.
``<mode>``
Select the sampling mode.
:0: nearest-neighbor sampling, fast but incorrect
:1: linear interpolation (default)
``unsharp[=lx:ly:la:cx:cy:ca]``
unsharp mask / Gaussian blur
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.
@@ -487,6 +526,9 @@ Available filters are:
:<0: blur
:>0: sharpen
``swapuv``
Swap U & V plane.
``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,6 +560,120 @@ 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.
``divtc[=options]``
Inverse telecine for deinterlaced video. If 3:2-pulldown telecined video
has lost one of the fields or is deinterlaced using a method that keeps
one field and interpolates the other, the result is a juddering video that
has every fourth frame duplicated. This filter is intended to find and
drop those duplicates and restore the original film framerate. Two
different modes are available: One-pass mode is the default and is
straightforward to use, but has the disadvantage that any changes in the
telecine phase (lost frames or bad edits) cause momentary judder until the
filter can resync again. Two-pass mode avoids this by analyzing the entire
video beforehand so it will have forward knowledge about the phase changes
and can resync at the exact spot. These passes do *not* correspond to pass
one and two of the encoding process. You must run an extra pass using
``divtc`` pass one before the actual encoding throwing the resulting video
away. Then use ``divtc`` pass two for the actual encoding. If you use
multiple encoder passes, use ``divtc`` pass two for all of them.
The options are:
``pass=1|2``
Use two pass mode.
``file=<filename>``
Set the two pass log filename (default: ``framediff.log``).
``threshold=<value>``
Set the minimum strength the telecine pattern must have for the filter
to believe in it (default: 0.5). This is used to avoid recognizing
false pattern from the parts of the video that are very dark or very
still.
``window=<numframes>``
Set the number of past frames to look at when searching for pattern
(default: 30). Longer window improves the reliability of the pattern
search, but shorter window improves the reaction time to the changes
in the telecine phase. This only affects the one-pass mode. The
two-pass mode currently uses fixed window that extends to both future
and past.
``phase=0|1|2|3|4``
Sets the initial telecine phase for one pass mode (default: 0). The
two-pass mode can see the future, so it is able to use the correct
phase from the beginning, but one-pass mode can only guess. It catches
the correct phase when it finds it, but this option can be used to fix
the possible juddering at the beginning. The first pass of the two
pass mode also uses this, so if you save the output from the first
pass, you get constant phase result.
``deghost=<value>``
Set the deghosting threshold (0-255 for one-pass mode, -255-255 for
two-pass mode, default 0). If nonzero, deghosting mode is used. This
is for video that has been deinterlaced by blending the fields
together instead of dropping one of the fields. Deghosting amplifies
any compression artifacts in the blended frames, so the parameter
value is used as a threshold to exclude those pixels from deghosting
that differ from the previous frame less than specified value. If two
pass mode is used, then negative value can be used to make the filter
analyze the whole video in the beginning of pass-2 to determine
whether it needs deghosting or not and then select either zero or the
absolute value of the parameter. Specify this option for pass 2, it
makes no difference on pass 1.
``phase[=t|b|p|a|u|T|B|A|U][:v]``
Delay interlaced video by one field time so that the field order changes.
The intended use is to fix PAL movies that have been captured with the
opposite field order to the film-to-video transfer. The options are:
``t``
Capture field order top-first, transfer bottom-first. Filter will
delay the bottom field.
``b``
Capture bottom-first, transfer top-first. Filter will delay the top
field.
``p``
Capture and transfer with the same field order. This mode only exists
for the documentation of the other options to refer to, but if you
actually select it, the filter will faithfully do nothing ;-)
``a``
Capture field order determined automatically by field flags, transfer
opposite. Filter selects among ``t`` and ``b`` modes on a frame by frame
basis using field flags. If no field information is available, then this
works just like ``u``.
``u``
Capture unknown or varying, transfer opposite. Filter selects among
``t`` and ``b`` on a frame by frame basis by analyzing the images and
selecting the alternative that produces best match between the fields.
``T``
Capture top-first, transfer unknown or varying. Filter selects among
``t`` and ``p`` using image analysis.
``B``
Capture bottom-first, transfer unknown or varying. Filter selects
among ``b`` and ``p`` using image analysis.
``A``
Capture determined by field flags, transfer unknown or varying. Filter
selects among ``t``, ``b`` and ``p`` using field flags and image
analysis. If no field information is available, then this works just
like ``U``. This is the default mode.
``U``
Both capture and transfer unknown or varying. Filter selects among
``t``, ``b`` and ``p`` using image analysis only.
``v``
Verbose operation. Prints the selected mode for each frame and the
average squared difference between fields for ``t``, ``b``, and ``p``
alternatives. (Ignored when libavfilter is used.)
``yadif=[mode[:enabled=yes|no]]``
Yet another deinterlacing filter
@@ -558,9 +714,20 @@ Available filters are:
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.
``file=<file>``
You can specify a text file to load the coordinates from. Each line
must have a timestamp (in seconds, and in ascending order) and the
``x:y:w:h:t`` coordinates (``t`` can be omitted).
(Not supported when using libavfilter.)
``show``
Draw a rectangle showing the area defined by x/y/w/h.
``screenshot``
Optional filter for screenshot support. This is only needed if the video
output does not provide working direct screenshot support. Note that it is
not always safe to insert this filter by default. See `TAKING SCREENSHOTS`_
for details.
``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
@@ -568,9 +735,9 @@ Available filters are:
``<bottom-margin>``
Adds a black band at the bottom of the frame. The SSA/ASS renderer can
place subtitles there (with ``--sub-use-margins``).
place subtitles there (with ``--ass-use-margins``).
``<top-margin>``
Black band on the top for toptitles (with ``--sub-use-margins``).
Black band on the top for toptitles (with ``--ass-use-margins``).
.. admonition:: Examples
@@ -614,8 +781,8 @@ Available filters are:
anaglyph red/cyan color (red filter on left eye, cyan filter on
right eye)
``arcd`` or ``anaglyph_red_cyan_dubois``
anaglyph red/cyan color optimized with the least-squares
projection of Dubois (red filter on left eye, cyan filter on right
anaglyph red/cyan color optimized with the least squares
projection of dubois (red filter on left eye, cyan filter on right
eye)
``agmg`` or ``anaglyph_green_magenta_gray``
anaglyph green/magenta gray (green filter on left eye, magenta
@@ -648,7 +815,7 @@ Available filters are:
``gradfun[=strength[:radius|:size=<size>]]``
Fix the banding artifacts that are sometimes introduced into nearly flat
regions by truncation to 8-bit color depth. Interpolates the gradients that
regions by truncation to 8bit color depth. Interpolates the gradients that
should go where the bands are, and dithers them.
``<strength>``
@@ -685,121 +852,6 @@ Available filters are:
``a3=<string>``
Specify the fourth parameter to pass to the library.
``vapoursynth=file:buffered-frames:concurrent-frames``
Loads a VapourSynth filter script. This is intended for streamed
processing: mpv actually provides a source filter, instead of using a
native VapourSynth video source. The mpv source will answer frame
requests only within a small window of frames (the size of this window
is controlled with the ``buffered-frames`` parameter), and requests outside
of that will return errors. As such, you can't use the full power of
VapourSynth, but you can use certain filters.
If you just want to play video generated by a VapourSynth (i.e. using
a native VapourSynth video source), it's better to use ``vspipe`` and a
FIFO to feed the video to mpv. The same applies if the filter script
requires random frame access (see ``buffered-frames`` parameter).
This filter is experimental. If it turns out that it works well and is
used, it will be ported to libavfilter. Otherwise, it will be just removed.
``file``
Filename of the script source. Currently, this is always a python
script. The variable ``video_in`` is set to the mpv video source,
and it is expected that the script reads video from it. (Otherwise,
mpv will decode no video, and the video packet queue will overflow,
eventually leading to audio being stopped.) The script is also
expected to pass through timestamps using the ``_DurationNum`` and
``_DurationDen`` frame properties.
.. admonition:: Example:
::
import vapoursynth as vs
core = vs.get_core()
core.std.AddBorders(video_in, 10, 10, 20, 20).set_output()
.. warning::
The script will be reloaded on every seek. This is done to reset
the filter properly on discontinuities.
``buffered-frames``
Maximum number of decoded video frames that should be buffered before
the filter (default: 4). This specifies the maximum number of frames
the script can requests backwards. E.g. if ``buffered-frames=5``, and
the script just requested frame 15, it can still request frame 10, but
frame 9 is not available anymore. If it requests frame 30, mpv will
decode 15 more frames, and keep only frames 25-30.
The actual number of buffered frames also depends on the value of the
``concurrent-frames`` option. Currently, both option values are
multiplied to get the final buffer size.
(Normally, VapourSynth source filters must provide random access, but
mpv was made for playback, and does not provide frame-exact random
access. The way this video filter works is a compromise to make simple
filters work anyway.)
``concurrent-frames``
Number of frames that should be requested in parallel. The
level of concurrency depends on the filter and how quickly mpv can
decode video to feed the filter. This value should probably be
proportional to the number of cores on your machine. Most time,
making it higher than the number of cores can actually make it
slower.
By default, this uses the special value ``auto``, which sets the option
to the number of detected logical CPU cores.
The following variables are defined by mpv:
``video_in``
The mpv video source as vapoursynth clip. Note that this has no length
set, which confuses many filters. Using ``Trim`` on the clip with a
high dummy length can turn it into a finite clip.
``video_in_dw``, ``video_in_dh``
Display size of the video. Can be different from video size if the
video does not use square pixels (e.g. DVD).
``container_fps``
FPS value as reported by file headers. This value can be wrong or
completely broken (e.g. 0 or NaN). Even if the value is correct,
if another filter changes the real FPS (by dropping or inserting
frames), the value of this variable might not be useful. Note that
the ``--fps`` command line option overrides this value.
Useful for some filters which insist on having a FPS.
``display_fps``
Refresh rate of the current display. Note that this value can be 0.
``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
provided. There's no type checking either, and you can trigger crashes.
.. admonition:: Example:
::
video_out = invoke("morpho", "Open", {clip = video_in})
The special variable ``video_in`` is the mpv video source, while the
special variable ``video_out`` is used to read video from. The 1st argument
is the plugin (queried with ``getPluginByNs``), the 2nd is the filter name,
and the 3rd argument is a table with the arguments. Positional arguments
are not supported. The types must match exactly. Since Lua is terrible and
can't distinguish integers and floats, integer arguments must be prefixed
with ``i_``, in which case the prefix is removed and the argument is cast
to an integer. Should the argument's name start with ``i_``, you're out of
luck.
Clips (VSNodeRef) are passed as light userdata, so trying to pass any
other userdata type will result in hard crashes.
``vavpp``
VA-AP-API video post processing. Works with ``--vo=vaapi`` and ``--vo=opengl``
only. Currently deinterlaces. This filter is automatically inserted if
@@ -815,63 +867,4 @@ Available filters are:
Show only first field (going by ``--field-dominance``).
bob
bob deinterlacing (default).
weave, motion-adaptive, motion-compensated
Advanced deinterlacing algorithms. Whether these actually work
depends on the GPU hardware, the GPU drivers, driver bugs, and
mpv bugs.
``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
``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
decoding was activated at least once (i.e. vdpau was loaded).
``sharpen=<-1-1>``
For positive values, apply a sharpening algorithm to the video, for
negative values a blurring algorithm (default: 0).
``denoise=<0-1>``
Apply a noise reduction algorithm to the video (default: 0; no noise
reduction).
``deint=<yes|no>``
Whether deinterlacing is enabled (default: no). If enabled, it will use
the mode selected with ``deint-mode``.
``deint-mode=<first-field|bob|temporal|temporal-spatial>``
Select deinterlacing mode (default: temporal).
All modes respect ``--field-dominance``.
Note that there's currently a mechanism that allows the ``vdpau`` VO to
change the ``deint-mode`` of auto-inserted ``vdpaupp`` filters. To avoid
confusion, it's recommended not to use the ``--vo=vdpau`` suboptions
related to filtering.
first-field
Show only first field.
bob
Bob deinterlacing.
temporal
Motion-adaptive temporal deinterlacing. May lead to A/V desync
with slow video hardware and/or high resolution.
temporal-spatial
Motion-adaptive temporal deinterlacing with edge-guided spatial
interpolation. Needs fast video hardware.
``chroma-deint``
Makes temporal deinterlacers operate both on luma and chroma (default).
Use no-chroma-deint to solely use luma and speed up advanced
deinterlacing. Useful with slow video memory.
``pullup``
Try to apply inverse telecine, needs motion adaptive temporal
deinterlacing.
``hqscaling=<0-9>``
0
Use default VDPAU scaling (default).
1-9
Apply high quality VDPAU scaling (needs capable hardware).
``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
latencies with decoding, because the filter will never output a frame if
the buffer isn't full, except on EOF.)
+822
View File
@@ -0,0 +1,822 @@
VIDEO OUTPUT DRIVERS
====================
Video output drivers are interfaces to different video output facilities. The
syntax is:
``--vo=<driver1[:suboption1[=value]:...],driver2,...[,]>``
Specify a priority list of video output drivers to be used.
If the list has a trailing ',', mpv will fall back on drivers not contained
in the list. Suboptions are optional and can mostly be omitted.
You can also set defaults for each driver. The defaults are applied before the
normal driver parameters.
``--vo-defaults=<driver1[:parameter1:parameter2:...],driver2,...>``
Set defaults for each driver.
.. note::
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.
Available video output drivers are:
``xv`` (X11 only)
Uses the XVideo extension to enable hardware-accelerated display. This is
the most compatible VO on X, but may be low-quality, and has issues with
OSD and subtitle display.
.. note:: This driver is for compatibility with old systems.
``adaptor=<number>``
Select a specific XVideo adaptor (check xvinfo results).
``port=<number>``
Select a specific XVideo port.
``ck=<cur|use|set>``
Select the source from which the colorkey is taken (default: cur).
cur
The default takes the colorkey currently set in Xv.
use
Use but do not set the colorkey from mpv (use the ``--colorkey``
option to change it).
set
Same as use but also sets the supplied colorkey.
``ck-method=<man|bg|auto>``
Sets the colorkey drawing method (default: man).
man
Draw the colorkey manually (reduces flicker in some cases).
bg
Set the colorkey as window background.
auto
Let Xv draw the colorkey.
``colorkey=<number>``
Changes the colorkey to an RGB value of your choice. ``0x000000`` is
black and ``0xffffff`` is white.
``no-colorkey``
Disables colorkeying.
``x11`` (X11 only)
Shared memory video output driver without hardware acceleration that works
whenever X11 is present.
.. note:: This is a fallback only, and should not be normally used.
``vdpau`` (X11 only)
Uses the VDPAU interface to display and optionally also decode video.
Hardware decoding is used with ``--hwdec=vdpau``.
``sharpen=<-1-1>``
For positive values, apply a sharpening algorithm to the video, for
negative values a blurring algorithm (default: 0).
``denoise=<0-1>``
Apply a noise reduction algorithm to the video (default: 0; no noise
reduction).
``deint=<-4-4>``
Select deinterlacing mode (default: -3). Positive values choose mode
and enable deinterlacing. Corresponding negative values select the
same deinterlacing mode, but do not enable deinterlacing on startup
(useful in configuration files to specify which mode will be enabled by
the "D" key). All modes respect ``--field-dominance``.
0
Same as -3.
1
Show only first field.
2
Bob deinterlacing.
3
Motion-adaptive temporal deinterlacing. May lead to A/V desync
with slow video hardware and/or high resolution.
4
Motion-adaptive temporal deinterlacing with edge-guided spatial
interpolation. Needs fast video hardware.
``chroma-deint``
Makes temporal deinterlacers operate both on luma and chroma (default).
Use no-chroma-deint to solely use luma and speed up advanced
deinterlacing. Useful with slow video memory.
``pullup``
Try to apply inverse telecine, needs motion adaptive temporal
deinterlacing.
``hqscaling=<0-9>``
0
Use default VDPAU scaling (default).
1-9
Apply high quality VDPAU scaling (needs capable hardware).
``fps=<number>``
Override autodetected display refresh rate value (the value is needed
for framedrop to allow video playback rates higher than display
refresh rate, and for vsync-aware frame timing adjustments). Default 0
means use autodetected value. A positive value is interpreted as a
refresh rate in Hz and overrides the autodetected value. A negative
value disables all timing adjustment and framedrop logic.
``composite-detect``
NVIDIA's current VDPAU implementation behaves somewhat differently
under a compositing window manager and does not give accurate frame
timing information. With this option enabled, the player tries to
detect whether a compositing window manager is active. If one is
detected, the player disables timing adjustments as if the user had
specified ``fps=-1`` (as they would be based on incorrect input). This
means timing is somewhat less accurate than without compositing, but
with the composited mode behavior of the NVIDIA driver, there is no
hard playback speed limit even without the disabled logic. Enabled by
default, use ``no-composite-detect`` to disable.
``queuetime_windowed=<number>`` and ``queuetime_fs=<number>``
Use VDPAU's presentation queue functionality to queue future video
frame changes at most this many milliseconds in advance (default: 50).
See below for additional information.
``output_surfaces=<2-15>``
Allocate this many output surfaces to display video frames (default:
3). See below for additional information.
``colorkey=<#RRGGBB|#AARRGGBB>``
Set the VDPAU presentation queue background color, which in practice
is the colorkey used if VDPAU operates in overlay mode (default:
``#020507``, some shade of black). If the alpha component of this value
is 0, the default VDPAU colorkey will be used instead (which is usually
green).
``force-yuv``
Never accept RGBA input. This means mpv will insert a filter to convert
to a YUV format before the VO. Sometimes useful to force availability
of certain YUV-only features, like video equalizer or deinterlacing.
Using the VDPAU frame queueing functionality controlled by the queuetime
options makes mpv's frame flip timing less sensitive to system CPU load and
allows mpv to start decoding the next frame(s) slightly earlier, which can
reduce jitter caused by individual slow-to-decode frames. However, the
NVIDIA graphics drivers can make other window behavior such as window moves
choppy if VDPAU is using the blit queue (mainly happens if you have the
composite extension enabled) and this feature is active. If this happens on
your system and it bothers you then you can set the queuetime value to 0 to
disable this feature. The settings to use in windowed and fullscreen mode
are separate because there should be no reason to disable this for
fullscreen mode (as the driver issue should not affect the video itself).
You can queue more frames ahead by increasing the queuetime values and the
``output_surfaces`` count (to ensure enough surfaces to buffer video for a
certain time ahead you need at least as many surfaces as the video has
frames during that time, plus two). This could help make video smoother in
some cases. The main downsides are increased video RAM requirements for
the surfaces and laggier display response to user commands (display
changes only become visible some time after they're queued). The graphics
driver implementation may also have limits on the length of maximum
queuing time or number of queued surfaces that work well or at all.
``direct3d_shaders`` (Windows only)
Video output driver that uses the Direct3D interface.
.. note:: This driver is for compatibility with systems that don't provide
proper OpenGL drivers.
``prefer-stretchrect``
Use ``IDirect3DDevice9::StretchRect`` over other methods if possible.
``disable-stretchrect``
Never render the video using ``IDirect3DDevice9::StretchRect``.
``disable-textures``
Never render the video using D3D texture rendering. Rendering with
textures + shader will still be allowed. Add ``disable-shaders`` to
completely disable video rendering with textures.
``disable-shaders``
Never use shaders when rendering video.
``only-8bit``
Never render YUV video with more than 8 bits per component.
Using this flag will force software conversion to 8-bit.
``disable-texture-align``
Normally texture sizes are always aligned to 16. With this option
enabled, the video texture will always have exactly the same size as
the video itself.
Debug options. These might be incorrect, might be removed in the future,
might crash, might cause slow downs, etc. Contact the developers if you
actually need any of these for performance or proper operation.
``force-power-of-2``
Always force textures to power of 2, even if the device reports
non-power-of-2 texture sizes as supported.
``texture-memory=N``
Only affects operation with shaders/texturing enabled, and (E)OSD.
Values for N:
0
default, will often use an additional shadow texture + copy
1
use ``D3DPOOL_MANAGED``
2
use ``D3DPOOL_DEFAULT``
3
use ``D3DPOOL_SYSTEMMEM``, but without shadow texture
``swap-discard``
Use ``D3DSWAPEFFECT_DISCARD``, which might be faster.
Might be slower too, as it must(?) clear every frame.
``exact-backbuffer``
Always resize the backbuffer to window size.
``direct3d`` (Windows only)
Same as ``direct3d_shaders``, but with the options ``disable-textures``
and ``disable-shaders`` forced.
.. note:: This driver is for compatibility with old systems.
``corevideo`` (Mac OS X 10.6 and later)
Mac OS X CoreVideo video output driver. Uses the CoreVideo APIs to fill
PixelBuffers and generate OpenGL textures from them (useful as a fallback
for ``opengl``).
.. note:: This driver is for compatibility with old systems.
``opengl``
OpenGL video output driver. It supports extended scaling methods, dithering
and color management.
By default, it tries to use fast and fail-safe settings. Use the alias
``opengl-hq`` to use this driver with defaults set to high quality
rendering.
Requires at least OpenGL 2.1 and the ``GL_ARB_texture_rg`` extension. For
older drivers, ``opengl-old`` may work.
Some features are available with OpenGL 3 capable graphics drivers only
(or if the necessary extensions are available).
Hardware decoding over OpenGL-interop is supported to some degree. Note
that in this mode, some corner case might not be gracefully handled, and
colorspace conversion and chroma upsampling is generally in the hand of
the hardware decoder APIs.
``lscale=<filter>``
``bilinear``
Bilinear hardware texture filtering (fastest, mid-quality).
This is the default.
``lanczos2``
Lanczos scaling with radius=2. Provides good quality and speed.
This is the default when using ``opengl-hq``.
``lanczos3``
Lanczos with radius=3.
``bicubic_fast``
Bicubic filter. Has a blurring effect on the image, even if no
scaling is done.
``sharpen3``
Unsharp masking (sharpening) with radius=3 and a default strength
of 0.5 (see ``lparam1``).
``sharpen5``
Unsharp masking (sharpening) with radius=5 and a default strength
of 0.5 (see ``lparam1``).
``mitchell``
Mitchell-Netravali. The ``b`` and ``c`` parameters can be set with
``lparam1`` and ``lparam2``. Both are set to 1/3 by default.
There are some more filters. For a complete list, pass ``help`` as
value, e.g.::
mpv --vo=opengl:lscale=help
``lparam1=<value>``
Set filter parameters. Ignored if the filter is not tunable. These are
unset by default, and use the filter specific default if applicable.
``lparam2=<value>``
See ``lparam1``.
``scaler-resizes-only``
Disable the scaler if the video image is not resized. In that case,
``bilinear`` is used instead whatever is set with ``lscale``. Bilinear
will reproduce the source image perfectly if no scaling is performed.
Note that this option never affects ``cscale``, although the different
processing chain might do chroma scaling differently if ``lscale`` is
disabled.
``stereo=<value>``
Select a method for stereo display. You may have to use ``--aspect`` to
fix the aspect value. Experimental, do not expect too much from it.
no
Normal 2D display
red-cyan
Convert side by side input to full-color red-cyan stereo.
green-magenta
Convert side by side input to full-color green-magenta stereo.
quadbuffer
Convert side by side input to quadbuffered stereo. Only supported
by very few OpenGL cards.
``srgb``
Enable gamma-correct scaling by working in linear light. This
makes use of sRGB textures and framebuffers.
This option forces the options ``indirect`` and ``gamma``.
.. note::
for YUV colorspaces, gamma 1/0.45 (2.222) is assumed. RGB input is
always assumed to be in sRGB.
This option is not really useful, as gamma-correct scaling has not much
influence on typical video playback. Most visible effect comes from
slightly different gamma.
``pbo``
Enable use of PBOs. This is slightly faster, but can sometimes lead to
sporadic and temporary image corruption (in theory, because reupload
is not retried when it fails), and perhaps actually triggers slower
paths with drivers that don't support PBOs properly.
``dither-depth=<N|no|auto>``
Set dither target depth to N. Default: no.
no
Disable any dithering done by mpv.
auto
Automatic selection. If output bit depth cannot be detected,
8 bits per component are assumed.
8
Dither to 8 bit output.
Note that the depth of the connected video display device can not be
detected. Often, LCD panels will do dithering on their own, which
conflicts with ``opengl``'s dithering and leads to ugly output.
``dither-size-fruit=<2-8>``
Set the size of the dither matrix (default: 6). The actual size of
the matrix is ``(2^N) x (2^N)`` for an option value of ``N``, so a
value of 6 gives a size of 64x64. The matrix is generated at startup
time, and a large matrix can take rather long to compute (seconds).
Used in ``dither=fruit`` mode only.
``dither=<fruit|ordered|no>``
Select dithering algorithm (default: fruit).
``temporal-dither``
Enable temporal dithering. (Only active if dithering is enabled in
general.) This changes between 8 different dithering pattern on each
frame by changing the orientation of the tiled dithering matrix.
Unfortunately, this can lead to flicker on LCD displays, since these
have a high reaction time.
``debug``
Check for OpenGL errors, i.e. call ``glGetError()``. Also request a
debug OpenGL context (which does nothing with current graphics drivers
as of this writing).
``swapinterval=<n>``
Interval in displayed frames between two buffer swaps.
1 is equivalent to enable VSYNC, 0 to disable VSYNC.
``no-scale-sep``
When using a separable scale filter for luma, usually two filter
passes are done. This is often faster. However, it forces
conversion to RGB in an extra pass, so it can actually be slower
if used with fast filters on small screen resolutions. Using
this options will make rendering a single operation.
Note that chroma scalers are always done as 1-pass filters.
``cscale=<n>``
As ``lscale``, but for chroma (2x slower with little visible effect).
Note that with some scaling filters, upscaling is always done in
RGB. If chroma is not subsampled, this option is ignored, and the
luma scaler is used instead. Setting this option is often useless.
``fancy-downscaling``
When using convolution based filters, extend the filter size
when downscaling. Trades quality for reduced downscaling performance.
``no-npot``
Force use of power-of-2 texture sizes. For debugging only.
Borders will be distorted due to filtering.
``glfinish``
Call ``glFinish()`` before swapping buffers
``sw``
Continue even if a software renderer is detected.
``backend=<sys>``
The value ``auto`` (the default) selects the windowing backend. You
can also pass ``help`` to get a complete list of compiled in backends
(sorted by autoprobe order).
auto
auto-select (default)
cocoa
Cocoa/OSX
win
Win32/WGL
x11
X11/GLX
wayland
Wayland/EGL
``indirect``
Do YUV conversion and scaling as separate passes. This will first render
the video into a video-sized RGB texture, and draw the result on screen.
The luma scaler is used to scale the RGB image when rendering to screen.
The chroma scaler is used only on YUV conversion, and only if the video
is chroma-subsampled (usually the case).
This mechanism is disabled on RGB input.
Specifying this option directly is generally useful for debugging only.
``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.)
``fmt`` can be one of: rgb, rgba, rgb8, rgb10, rgb10_a2, rgb16, rgb16f,
rgb32f, rgba12, rgba16, rgba16f, rgba32f.
Default: rgb.
``gamma``
Always enable gamma control. (Disables delayed enabling.)
``icc-profile=<file>``
Load an ICC profile and use it to transform linear RGB to screen output.
Needs LittleCMS2 support compiled in.
``icc-cache=<file>``
Store and load the 3D LUT created from the ICC profile in this file.
This can be used to speed up loading, since LittleCMS2 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.
``icc-intent=<value>``
0
perceptual
1
relative colorimetric
2
saturation
3
absolute colorimetric (default)
``3dlut-size=<r>x<g>x<b>``
Size of the 3D LUT generated from the ICC profile in each dimension.
Default is 128x256x64.
Sizes must be a power of two, and 256 at most.
``alpha=<blend|yes|no>``
Decides what to do if the input has an alpha component (default: blend).
blend
Blend the frame against a black background.
yes
Try to create a framebuffer with alpha component. This only makes sense
if the video contains alpha information (which is extremely rare). May
not be supported on all platforms. If alpha framebuffers are
unavailable, it silently falls back on a normal framebuffer. Note
that when using FBO indirections (such as with ``opengl-hq``), an FBO
format with alpha must be specified with the ``fbo-format`` option.
no
Ignore alpha component.
``chroma-location=<auto|center|left>``
Set the YUV chroma sample location. auto means use the bitstream
flags (default: auto).
``rectangle-textures``
Force use of rectangle textures (default: no). Normally this shouldn't
have any advantages over normal textures. Note that hardware decoding
overrides this flag.
``opengl-hq``
Same as ``opengl``, but with default settings for high quality rendering.
This is equivalent to::
--vo=opengl:lscale=lanczos2:dither-depth=auto:fbo-format=rgb16
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 OSX setups being very slow with ``rgb16``
but fast with ``rgb32f``.
``opengl-old``
OpenGL video output driver, old version. Video size must be smaller
than the maximum texture size of your OpenGL implementation. Intended to
work even with the most basic OpenGL implementations, but also makes use
of newer extensions which allow support for more color spaces.
The code performs very few checks, so if a feature does not work, this
might be because it is not supported by your card and/or OpenGL
implementation, even if you do not get any error message. Use ``glxinfo``
or a similar tool to display the supported OpenGL extensions.
.. note:: This driver is for compatibility with old systems.
``(no-)ati-hack``
ATI drivers may give a corrupted image when PBOs are used (when using
``force-pbo``). This option fixes this, at the expense of using a bit
more memory.
``(no-)force-pbo``
Always uses PBOs to transfer textures even if this involves an extra
copy. Currently this gives a little extra speed with NVIDIA drivers
and a lot more speed with ATI drivers. May need the ``ati-hack``
suboption to work correctly.
``(no-)scaled-osd``
Scales the OSD and subtitles instead of rendering them at display size
(default: disabled).
``rectangle=<0,1,2>``
Select usage of rectangular textures, which saves video RAM, but often
is slower (default: 0).
0
Use power-of-two textures (default).
1
Use the ``GL_ARB_texture_rectangle`` extension.
2
Use the ``GL_ARB_texture_non_power_of_two`` extension. In some
cases only supported in software and thus very slow.
``swapinterval=<n>``
Minimum interval between two buffer swaps, counted in displayed frames
(default: 1). 1 is equivalent to enabling VSYNC, 0 to disabling VSYNC.
Values below 0 will leave it at the system default. This limits the
framerate to (horizontal refresh rate / n). Requires
``GLX_SGI_swap_control`` support to work. With some (most/all?)
implementations this only works in fullscreen mode.
``ycbcr``
Use the ``GL_MESA_ycbcr_texture`` extension to convert YUV to RGB. In
most cases this is probably slower than doing software conversion to
RGB.
``yuv=<n>``
Select the type of YUV to RGB conversion. The default is
auto-detection deciding between values 0 and 2.
0
Use software conversion. Compatible with all OpenGL versions.
Provides brightness, contrast and saturation control.
1
Same as 2. This used to use NVIDIA-specific extensions, which
did not provide any advantages over using fragment programs, except
possibly on very ancient graphics cards. It produced a gray-ish
output, which is why it has been removed.
2
Use a fragment program. Needs the ``GL_ARB_fragment_program``
extension and at least three texture units. Provides brightness,
contrast, saturation and hue control.
3
Use a fragment program using the ``POW`` instruction. Needs the
``GL_ARB_fragment_program`` extension and at least three texture
units. Provides brightness, contrast, saturation, hue and gamma
control. Gamma can also be set independently for red, green and
blue. Method 4 is usually faster.
4
Use a fragment program with additional lookup. Needs the
``GL_ARB_fragment_program`` extension and at least four texture
units. Provides brightness, contrast, saturation, hue and gamma
control. Gamma can also be set independently for red, green and
blue.
5
Use ATI-specific method (for older cards). This uses an
ATI-specific extension (``GL_ATI_fragment_shader`` - not
``GL_ARB_fragment_shader``!). At least three texture units are
needed. Provides saturation and hue control. This method is fast
but inexact.
6
Use a 3D texture to do conversion via lookup. Needs the
``GL_ARB_fragment_program extension`` and at least four texture
units. Extremely slow (software emulation) on some (all?) ATI
cards since it uses a texture with border pixels. Provides
brightness, contrast, saturation, hue and gamma control. Gamma can
also be set independently for red, green and blue. Speed depends
more on GPU memory bandwidth than other methods.
``lscale=<n>``
Select the scaling function to use for luminance scaling. Only valid
for yuv modes 2, 3, 4 and 6.
0
Use simple linear filtering (default).
1
Use bicubic B-spline filtering (better quality). Needs one
additional texture unit. Older cards will not be able to handle
this for chroma at least in fullscreen mode.
2
Use cubic filtering in horizontal, linear filtering in vertical
direction. Works on a few more cards than method 1.
3
Same as 1 but does not use a lookup texture. Might be faster on
some cards.
4
Use experimental unsharp masking with 3x3 support and a default
strength of 0.5 (see ``filter-strength``).
5
Use experimental unsharp masking with 5x5 support and a default
strength of 0.5 (see ``filter-strength``).
``cscale=<n>``
Select the scaling function to use for chrominance scaling. For
details see ``lscale``.
``filter-strength=<value>``
Set the effect strength for the ``lscale``/``cscale`` filters that
support it.
``stereo=<value>``
Select a method for stereo display. You may have to use ``--aspect`` to
fix the aspect value. Experimental, do not expect too much from it.
0
Normal 2D display
1
Convert side by side input to full-color red-cyan stereo.
2
Convert side by side input to full-color green-magenta stereo.
3
Convert side by side input to quadbuffered stereo. Only supported
by very few OpenGL cards.
The following options are only useful if writing your own fragment programs.
``customprog=<filename>``
Load a custom fragment program from ``<filename>``.
``customtex=<filename>``
Load a custom "gamma ramp" texture from ``<filename>``. This can be used
in combination with ``yuv=4`` or with the ``customprog`` option.
``(no-)customtlin``
If enabled (default) use ``GL_LINEAR`` interpolation, otherwise use
``GL_NEAREST`` for customtex texture.
``(no-)customtrect``
If enabled, use ``texture_rectangle`` for the ``customtex`` texture.
Default is disabled.
``(no-)mipmapgen``
If enabled, mipmaps for the video are automatically generated. This
should be useful together with the ``customprog`` and the ``TXB``
instruction to implement blur filters with a large radius. For most
OpenGL implementations, this is very slow for any non-RGB formats.
Default is disabled.
Normally there is no reason to use the following options; they mostly
exist for testing purposes.
``(no-)glfinish``
Call ``glFinish()`` before swapping buffers. Slower but in some cases
more correct output (default: disabled).
``(no-)manyfmts``
Enables support for more (RGB and BGR) color formats (default: enabled).
Needs OpenGL version >= 1.2.
``slice-height=<0-...>``
Number of lines copied to texture in one piece (default: 0). 0 for
whole image.
``sw``
Continue even if a software renderer is detected.
``backend=<sys>``
auto
auto-select (default)
cocoa
Cocoa/OSX
win
Win32/WGL
x11
X11/GLX
wayland
Wayland/EGL
``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.
For tuning, refer to your copy of the file ``SDL_hints.h``.
.. note:: This driver is for compatibility with systems that don't provide
proper graphics drivers, or which support GLES only.
``sw``
Continue even if a software renderer is detected.
``switch-mode``
Instruct SDL to switch the monitor video mode when going fullscreen.
``vaapi``
Intel VA API video output driver with support for hardware decoding. Note
that there is absolutely no reason to use this, other than wanting to use
hardware decoding to save power on laptops, or possibly preventing video
tearing with some setups.
.. note:: This driver is for compatibility with crappy systems. You can
use vaapi hardware decoding with ``--vo=opengl`` too.
``scaling=<algorithm>``
default
Driver default (mpv default as well).
fast
Fast, but low quality.
hq
Unspecified driver dependent high-quality scaling, slow.
nla
``non-linear anamorphic scaling``
``deint-mode=<mode>``
Select deinterlacing algorithm. Note that by default deinterlacing is
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).
In this case, the default for ``deint-mode`` is ``no``, and enabling
deinterlacing via user interaction using the methods mentioned above
actually inserts the ``vavpp`` video filter. If vpp is not actually
supported with the libva backend in use, you can use this option to
forcibly enable VO based deinterlacing.
no
Don't allow deinterlacing (default for newer libva).
first-field
Show only first field (going by ``--field-dominance``).
bob
bob deinterlacing (default for older libva).
``scaled-osd=<yes|no>``
If enabled, then the OSD is rendered at video resolution and scaled to
display resolution. By default, this is disabled, and the OSD is
rendered at display resolution if the driver supports it.
``null``
Produces no video output. Useful for benchmarking.
``caca``
Color ASCII art video output driver that works on a text console.
.. note:: This driver is a joke.
``image``
Output each frame into an image file in the current directory. Each file
takes the frame number padded with leading zeros as name.
``format=<format>``
Select the image file format.
jpg
JPEG files, extension .jpg. (Default.)
jpeg
JPEG files, extension .jpeg.
png
PNG files.
ppm
Portable bitmap format.
pgm
Portable graymap format.
pgmyuv
Portable graymap format, using the YV12 pixel format.
tga
Truevision TGA.
``png-compression=<0-9>``
PNG compression factor (speed vs. file size tradeoff) (default: 7)
``png-filter=<0-5>``
Filter applied prior to PNG compression (0 = none; 1 = sub; 2 = up;
3 = average; 4 = Paeth; 5 = mixed) (default: 5)
``jpeg-quality=<0-100>``
JPEG quality factor (default: 90)
``(no-)jpeg-progressive``
Specify standard or progressive JPEG (default: no).
``(no-)jpeg-baseline``
Specify use of JPEG baseline or not (default: yes).
``jpeg-optimize=<0-100>``
JPEG optimization factor (default: 100)
``jpeg-smooth=<0-100>``
smooth factor (default: 0)
``jpeg-dpi=<1->``
JPEG DPI (default: 72)
``outdir=<dirname>``
Specify the directory to save the image files to (default: ``./``).
``wayland`` (Wayland only)
Wayland shared memory video output as fallback for ``opengl``.
.. note:: This driver is for compatibility with systems that don't provide
working OpenGL drivers.
``default-format``
Use the default RGB32 format instead of an auto-detected one.
``alpha``
Use a buffer format that supports videos and images with alpha
information
-1881
View File
File diff suppressed because it is too large. Load diff
-225
View File
@@ -1,225 +0,0 @@
JSON IPC
========
mpv can be controlled by external programs using the JSON-based IPC protocol. It
can be enabled by specifying the path to a unix socket using the option
``--input-unix-socket``. Clients can connect to this socket and send commands to
the player or receive events from it.
.. warning::
This is not intended to be a secure network protocol. It is explicitly
insecure: there is no authentication, no encryption, and the commands
themselves are insecure too. For example, the ``run`` command is exposed,
which can run arbitrary system commands. The use-case is controlling the
player locally. This is not different from the MPlayer slave protocol.
Socat example
-------------
You can use the ``socat`` tool to send commands (and receive reply) from the
shell. Assuming mpv was started with:
::
mpv file.mkv --input-unix-socket=/tmp/mpvsocket
Then you can control it using socat:
::
> echo '{ "command": ["get_property", "playback-time"] }' | socat - /tmp/mpvsocket
{"data":190.482000,"error":"success"}
In this case, socat copies data between stdin/stdout and the mpv socket
connection.
See the ``--idle`` option how to make mpv start without exiting immediately or
playing a file.
It's also possible to send input.conf style text-only commands:
::
> echo 'show_text ${playback-time}' | socat - /tmp/mpvsocket
But you won't get a reply over the socket. (This particular command shows the
playback time on the player's OSD.)
Protocol
--------
Clients can execute commands on the player by sending JSON messages of the
following form:
::
{ "command": ["command_name", "param1", "param2", ...] }
where ``command_name`` is the name of the command to be executed, followed by a
list of parameters. Parameters must be formatted as native JSON values
(integers, strings, booleans, ...). Every message **must** be terminated with
``\n``. Additionally, ``\n`` must not appear anywhere inside the message. In
practice this means that messages should be minified before being sent to mpv.
mpv will then send back a reply indicating whether the command was run
correctly, and an additional field holding the command-specific return data (it
can also be null).
::
{ "error": "success", "data": null }
mpv will also send events to clients with JSON messages of the following form:
::
{ "event": "event_name" }
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.
All commands, replies, and events are separated from each other with a line
break character (``\n``).
If the first character (after skipping whitespace) is not ``{``, the command
will be interpreted as non-JSON text command, as they are used in input.conf
(or ``mpv_command_string()`` in the client API). Additionally, line starting
with ``#`` and empty lines are ignored.
Currently, embedded 0 bytes terminate the current line, but you should not
rely on this.
Commands
--------
Additionally to the commands described in `List of Input Commands`_, a few
extra commands can also be used as part of the protocol:
``client_name``
Return the name of the client as string. This is the string ``ipc-N`` with
N being an integer number.
``get_time_us``
Return the current mpv internal time in microseconds as a number. This is
basically the system time, with an arbitrary offset.
``get_property``
Return the value of the given property. The value will be sent in the data
field of the replay message.
Example:
::
{ "command": ["get_property", "volume"] }
{ "data": 50.0, "error": "success" }
``get_property_string``
Like ``get_property``, but the resulting data will always be a string.
Example:
::
{ "command": ["get_property_string", "volume"] }
{ "data": "50.000000", "error": "success" }
``set_property``
Set the given property to the given value. See `Properties`_ for more
information about properties.
Example:
::
{ "command": ["set_property", "pause", true] }
{ "error": "success" }
``set_property_string``
Like ``set_property``, but the argument value must be passed as string.
Example:
::
{ "command": ["set_property_string", "pause", "yes"] }
{ "error": "success" }
``observe_property``
Watch a property for changes. If the given property is changed, then an
event of type ``property-change`` will be generated
Example:
::
{ "command": ["observe_property", 1, "volume"] }
{ "error": "success" }
{ "event": "property-change", "id": 1, "data": 52.0, "name": "volume" }
``observe_property_string``
Like ``observe_property``, but the resulting data will always be a string.
Example:
::
{ "command": ["observe_property_string", 1, "volume"] }
{ "error": "success" }
{ "event": "property-change", "id": 1, "data": "52.000000", "name": "volume" }
``unobserve_property``
Undo ``observe_property`` or ``observe_property_string``. This requires the
numeric id passed to the observe command as argument.
Example:
::
{ "command": ["unobserve_property", 1] }
{ "error": "success" }
``request_log_messages``
Enable output of mpv log messages. They will be received as events. The
parameter to this command is the log-level (see ``mpv_request_log_messages``
C API function).
Log message output is meant for humans only (mostly for debugging).
Attempting to retrieve information by parsing these messages will just
lead to breakages with future mpv releases. Instead, make a feature request,
and ask for a proper event that returns the information you need.
``enable_event``, ``disable_event``
Enables or disables the named event. Mirrors the ``mpv_request_event`` C
API function. If the string ``all`` is used instead of an event name, all
events are enabled or disabled.
By default, most events are enabled, and there is not much use for this
command.
``suspend``
Suspend the mpv main loop. There is a long-winded explanation of this in
the C API function ``mpv_suspend()``. In short, this prevents the player
from displaying the next video frame, so that you don't get blocked when
trying to access the player.
``resume``
Undo one ``suspend`` call. ``suspend`` increments an internal counter, and
``resume`` decrements it. When 0 is reached, the player is actually resumed.
``get_version``
Returns the client API version the C API of the remote mpv instance
provides. (Also see ``DOCS/client-api-changes.rst``.)
UTF-8
-----
Normally, all strings are in UTF-8. Sometimes it can happen that strings are
in some broken encoding (often happens with file tags and such, and filenames
on many Unixes are not required to be in UTF-8 either). This means that mpv
sometimes sends invalid JSON. If that is a problem for the client application's
parser, it should filter the raw data for invalid UTF-8 sequences and perform
the desired replacement, before feeding the data to its JSON parser.
mpv will not attempt to construct invalid UTF-8 with broken escape sequences.
-774
View File
@@ -1,774 +0,0 @@
LUA SCRIPTING
=============
mpv can load Lua scripts. Scripts passed to the ``--script`` option, or found in
the ``scripts`` subdirectory of the mpv configuration directory (usually
``~/.config/mpv/scripts/``) will be loaded on program start. mpv also appends the
``scripts`` subdirectory to the end of Lua's path so you can import scripts from
there too. Since it's added to the end, don't name scripts you want to import
the same as Lua libraries because they will be overshadowed by them.
mpv provides the built-in module ``mp``, which contains functions to send
commands to the mpv core and to retrieve information about playback state, user
settings, file information, and so on.
These scripts can be used to control mpv in a similar way to slave mode.
Technically, the Lua code uses the client API internally.
Example
-------
A script which leaves fullscreen mode when the player is paused:
::
function on_pause_change(name, value)
if value == true then
mp.set_property("fullscreen", "no")
end
end
mp.observe_property("pause", "bool", on_pause_change)
Details on the script initialization and lifecycle
--------------------------------------------------
Your script will be loaded by the player at program start from the ``scripts``
configuration subdirectory, or from a path specified with the ``--script``
option. Some scripts are loaded internally (like ``--osc``). Each script runs in
its own thread. Your script is first run "as is", and once that is done, the event loop
is entered. This event loop will dispatch events received by mpv and call your
own event handlers which you have registered with ``mp.register_event``, or
timers added with ``mp.add_timeout`` or similar.
When the player quits, all scripts will be asked to terminate. This happens via
a ``shutdown`` event, which by default will make the event loop return. If your
script got into an endless loop, mpv will probably behave fine during playback
(unless the player is suspended, see ``mp.suspend``), but it won't terminate
when quitting, because it's waiting on your script.
Internally, the C code will call the Lua function ``mp_event_loop`` after
loading a Lua script. This function is normally defined by the default prelude
loaded before your script (see ``player/lua/defaults.lua`` in the mpv sources).
The event loop will wait for events and dispatch events registered with
``mp.register_event``. It will also handle timers added with ``mp.add_timeout``
and similar (by waiting with a timeout).
Since mpv 0.6.0, the player will wait until the script is fully loaded before
continuing normal operation. The player considers a script as fully loaded as
soon as it starts waiting for mpv events (or it exits). In practice this means
the player will more or less hang until the script returns from the main chunk
(and ``mp_event_loop`` is called), or the script calls ``mp_event_loop`` or
``mp.dispatch_events`` directly. This is done to make it possible for a script
to fully setup event handlers etc. before playback actually starts. In older
mpv versions, this happened asynchronously.
mp functions
------------
The ``mp`` module is preloaded, although it can be loaded manually with
``require 'mp'``. It provides the core client API.
``mp.command(string)``
Run the given command. This is similar to the commands used in input.conf.
See `List of Input Commands`_.
Returns ``true`` on success, or ``nil, error`` on error.
``mp.commandv(arg1, arg2, ...)``
Similar to ``mp.command``, but pass each command argument as separate
parameter. This has the advantage that you don't have to care about
quoting and escaping in some cases.
Example:
::
mp.command("loadfile " .. filename .. " append")
mp.commandv("loadfile", filename, "append")
These two commands are equivalent, except that the first version breaks
if the filename contains spaces or certain special characters.
Note that properties are *not* expanded. You can use either ``mp.command``,
the ``expand-properties`` prefix, or the ``mp.get_property`` family of
functions.
``mp.command_native(table [,def])``
Similar to ``mp.commandv``, but pass the argument list as table. This has
the advantage that in at least some cases, arguments can be passed as
native types.
Returns a result table on success (usually empty), or ``def, error`` on
error. ``def`` is the second parameter provided to the function, and is
nil if it's missing.
``mp.get_property(name [,def])``
Return the value of the given property as string. These are the same
properties as used in input.conf. See `Properties`_ for a list of
properties. The returned string is formatted similar to ``${=name}``
(see `Property Expansion`_).
Returns the string on success, or ``def, error`` on error. ``def`` is the
second parameter provided to the function, and is nil if it's missing.
``mp.get_property_osd(name [,def])``
Similar to ``mp.get_property``, but return the property value formatted for
OSD. This is the same string as printed with ``${name}`` when used in
input.conf.
Returns the string on success, or ``def, error`` on error. ``def`` is the
second parameter provided to the function, and is an empty string if it's
missing. Unlike ``get_property()``, assigning the return value to a variable
will always result in a string.
``mp.get_property_bool(name [,def])``
Similar to ``mp.get_property``, but return the property value as Boolean.
Returns a Boolean on success, or ``def, error`` on error.
``mp.get_property_number(name [,def])``
Similar to ``mp.get_property``, but return the property value as number.
Note that while Lua does not distinguish between integers and floats,
mpv internals do. This function simply request a double float from mpv,
and mpv will usually convert integer property values to float.
Returns a number on success, or ``def, error`` on error.
``mp.get_property_native(name [,def])``
Similar to ``mp.get_property``, but return the property value using the best
Lua type for the property. Most time, this will return a string, Boolean,
or number. Some properties (for example ``chapter-list``) are returned as
tables.
Returns a value on success, or ``def, error`` on error. Note that ``nil``
might be a possible, valid value too in some corner cases.
``mp.set_property(name, value)``
Set the given property to the given string value. See ``mp.get_property``
and `Properties`_ for more information about properties.
Returns true on success, or ``nil, error`` on error.
``mp.set_property_bool(name, value)``
Similar to ``mp.set_property``, but set the given property to the given
Boolean value.
``mp.set_property_number(name, value)``
Similar to ``mp.set_property``, but set the given property to the given
numeric value.
Note that while Lua does not distinguish between integers and floats,
mpv internals do. This function will test whether the number can be
represented as integer, and if so, it will pass an integer value to mpv,
otherwise a double float.
``mp.set_property_native(name, value)``
Similar to ``mp.set_property``, but set the given property using its native
type.
Since there are several data types which can not represented natively in
Lua, this might not always work as expected. For example, while the Lua
wrapper can do some guesswork to decide whether a Lua table is an array
or a map, this would fail with empty tables. Also, there are not many
properties for which it makes sense to use this, instead of
``set_property``, ``set_property_bool``, ``set_property_number``.
For these reasons, this function should probably be avoided for now, except
for properties that use tables natively.
``mp.get_time()``
Return the current mpv internal time in seconds as a number. This is
basically the system time, with an arbitrary offset.
``mp.add_key_binding(key, name|fn [,fn [,flags]])``
Register callback to be run on a key binding. The binding will be mapped to
the given ``key``, which is a string describing the physical key. This uses
the same key names as in input.conf, and also allows combinations
(e.g. ``ctrl+a``).
After calling this function, key presses will cause the function ``fn`` to
be called (unless the user remapped the key with another binding).
The ``name`` argument should be a short symbolic string. It allows the user
to remap the key binding via input.conf using the ``script_message``
command, and the name of the key binding (see below for
an example). The name should be unique across other bindings in the same
script - if not, the previous binding with the same name will be
overwritten. You can omit the name, in which case a random name is generated
internally.
The last argument is used for optional flags. This is a table, which can
have the following entries:
``repeatable``
If set to ``true``, enables key repeat for this specific binding.
``complex``
If set to ``true``, then ``fn`` is called on both key up and down
events (as well as key repeat, if enabled), with the first
argument being a table. This table has an ``event`` entry, which
is set to one of the strings ``down``, ``repeat``, ``up`` or
``press`` (the latter if key up/down can't be tracked). It further
has an ``is_mouse`` entry, which tells whether the event was caused
by a mouse button.
Internally, key bindings are dispatched via the ``script_message_to`` or
``script_binding`` input commands and ``mp.register_script_message``.
Trying to map multiple commands to a key will essentially prefer a random
binding, while the other bindings are not called. It is guaranteed that
user defined bindings in the central input.conf are preferred over bindings
added with this function (but see ``mp.add_forced_key_binding``).
Example:
::
function something_handler()
print("the key was pressed")
end
mp.add_key_binding("x", "something", something_handler)
This will print the message ``the key was pressed`` when ``x`` was pressed.
The user can remap these key bindings. Then the user has to put the
following into his input.conf to remap the command to the ``y`` key:
::
y script_binding something
This will print the message when the key ``y`` is pressed. (``x`` will
still work, unless the user remaps it.)
You can also explicitly send a message to a named script only. Assume the
above script was using the filename ``fooscript.lua``:
::
y script_binding fooscript.something
``mp.add_forced_key_binding(...)``
This works almost the same as ``mp.add_key_binding``, but registers the
key binding in a way that will overwrite the user's custom bindings in his
input.conf. (``mp.add_key_binding`` overwrites default key bindings only,
but not those by the user's input.conf.)
``mp.remove_key_binding(name)``
Remove a key binding added with ``mp.add_key_binding`` or
``mp.add_forced_key_binding``. Use the same name as you used when adding
the bindings. It's not possible to remove bindings for which you omitted
the name.
``mp.register_event(name, fn)``
Call a specific function when an event happens. The event name is a string,
and the function fn is a Lua function value.
Some events have associated data. This is put into a Lua table and passed
as argument to fn. The Lua table by default contains a ``name`` field,
which is a string containing the event name. If the event has an error
associated, the ``error`` field is set to a string describing the error,
on success it's not set.
If multiple functions are registered for the same event, they are run in
registration order, which the first registered function running before all
the other ones.
Returns true if such an event exists, false otherwise.
See `Events`_ and `List of events`_ for details.
``mp.unregister_event(fn)``
Undo ``mp.register_event(..., fn)``. This removes all event handlers that
are equal to the ``fn`` parameter. This uses normal Lua ``==`` comparison,
so be careful when dealing with closures.
``mp.observe_property(name, type, fn)``
Watch a property for changes. If the property ``name`` is changed, then
the function ``fn(name)`` will be called. ``type`` can be ``nil``, or be
set to one of ``none``, ``native``, ``bool``, ``string``, or ``number``.
``none`` is the same as ``nil``. For all other values, the new value of
the property will be passed as second argument to ``fn``, using
``mp.get_property_<type>`` to retrieve it. This means if ``type`` is for
example ``string``, ``fn`` is roughly called as in
``fn(name, mp.get_property_string(name))``.
If possible, change events are coalesced. If a property is changed a bunch
of times in a row, only the last change triggers the change function. (The
exact behavior depends on timing and other things.)
In some cases the function is not called even if the property changes.
Whether this can happen depends on the property.
If the ``type`` is ``none`` or ``nil``, sporadic property change events are
possible. This means the change function ``fn`` can be called even if the
property doesn't actually change.
``mp.unobserve_property(fn)``
Undo ``mp.observe_property(..., fn)``. This removes all property handlers
that are equal to the ``fn`` parameter. This uses normal Lua ``==``
comparison, so be careful when dealing with closures.
``mp.add_timeout(seconds, fn)``
Call the given function fn when the given number of seconds has elapsed.
Note that the number of seconds can be fractional. For now, the timer's
resolution may be as low as 50 ms, although this will be improved in the
future.
This is a one-shot timer: it will be removed when it's fired.
Returns a timer object. See ``mp.add_periodic_timer`` for details.
``mp.add_periodic_timer(seconds, fn)``
Call the given function periodically. This is like ``mp.add_timeout``, but
the timer is re-added after the function fn is run.
Returns a timer object. The timer object provides the following methods:
``stop()``
Disable the timer. Does nothing if the timer is already disabled.
This will remember the current elapsed time when stopping, so that
``resume()`` essentially unpauses the timer.
``kill()``
Disable the timer. Resets the elapsed time. ``resume()`` will
restart the timer.
``resume()``
Restart the timer. If the timer was disabled with ``stop()``, this
will resume at the time it was stopped. If the timer was disabled
with ``kill()``, or if it's a previously fired one-shot timer (added
with ``add_timeout()``), this starts the timer from the beginning,
using the initially configured timeout.
``timeout`` (RW)
This field contains the current timeout period. This value is not
updated as time progresses. It's only used to calculate when the
timer should fire next when the timer expires.
If you write this, you can call ``t:kill() ; t:resume()`` to reset
the current timeout to the new one. (``t:stop()`` won't use the
new timeout.)
``oneshot`` (RW)
Whether the timer is periodic (``false``) or fires just once
(``true``). This value is used when the timer expires (but before
the timer callback function fn is run).
Note that these are method, and you have to call them using ``:`` instead
of ``.`` (Refer to http://www.lua.org/manual/5.2/manual.html#3.4.9 .)
Example:
::
seconds = 0
timer = mp.add_periodic_timer(1, function()
print("called every second")
# stop it after 10 seconds
seconds = seconds + 1
if seconds >= 10 then
timer:kill()
end
end)
``mp.get_opt(key)``
Return a setting from the ``--script-opts`` option. It's up to the user and
the script how this mechanism is used. Currently, all scripts can access
this equally, so you should be careful about collisions.
``mp.get_script_name()``
Return the name of the current script. The name is usually made of the
filename of the script, with directory and file extension removed. If
there are several script which would have the same name, it's made unique
by appending a number.
.. admonition:: Example
The script ``/path/to/fooscript.lua`` becomes ``fooscript``.
``mp.osd_message(text [,duration])``
Show an OSD message on the screen. ``duration`` is in seconds, and is
optional (uses ``--osd-duration`` by default).
Advanced mp functions
---------------------
These also live in the ``mp`` module, but are documented separately as they
are useful only in special situations.
``mp.suspend()``
Suspend the mpv main loop. There is a long-winded explanation of this in
the C API function ``mpv_suspend()``. In short, this prevents the player
from displaying the next video frame, so that you don't get blocked when
trying to access the player.
This is automatically called by the event handler.
``mp.resume()``
Undo one ``mp.suspend()`` call. ``mp.suspend()`` increments an internal
counter, and ``mp.resume()`` decrements it. When 0 is reached, the player
is actually resumed.
``mp.resume_all()``
This resets the internal suspend counter and resumes the player. (It's
like calling ``mp.resume()`` until the player is actually resumed.)
You might want to call this if you're about to do something that takes a
long time, but doesn't really need access to the player (like a network
operation). Note that you still can access the player at any time.
``mp.get_wakeup_pipe()``
Calls ``mpv_get_wakeup_pipe()`` and returns the read end of the wakeup
pipe. (See ``client.h`` for details.)
``mp.get_next_timeout()``
Return the relative time in seconds when the next timer (``mp.add_timeout``
and similar) expires. If there is no timer, return ``nil``.
``mp.dispatch_events([allow_wait])``
This can be used to run custom event loops. If you want to have direct
control what the Lua script does (instead of being called by the default
event loop), you can set the global variable ``mp_event_loop`` to your
own function running the event loop. From your event loop, you should call
``mp.dispatch_events()`` to dequeue and dispatch mpv events.
If the ``allow_wait`` parameter is set to ``true``, the function will block
until the next event is received or the next timer expires. Otherwise (and
this is the default behavior), it returns as soon as the event loop is
emptied. It's strongly recommended to use ``mp.get_next_timeout()`` and
``mp.get_wakeup_pipe()`` if you're interested in properly working
notification of new events and working timers.
This function calls ``mp.suspend()`` and ``mp.resume_all()`` on its own.
``mp.enable_messages(level)``
Set the minimum log level of which mpv message output to receive. These
messages are normally printed to the terminal. By calling this function,
you can set the minimum log level of messages which should be received with
the ``log-message`` event. See the description of this event for details.
The level is a string, see ``msg.log`` for allowed log levels.
``mp.register_script_message(name, fn)``
This is a helper to dispatch ``script_message`` or ``script_message_to``
invocations to Lua functions. ``fn`` is called if ``script_message`` or
``script_message_to`` (with this script as destination) is run
with ``name`` as first parameter. The other parameters are passed to ``fn``.
If a message with the given name is already registered, it's overwritten.
Used by ``mp.add_key_binding``, so be careful about name collisions.
``mp.unregister_script_message(name)``
Undo a previous registration with ``mp.register_script_message``. Does
nothing if the ``name`` wasn't registered.
mp.msg functions
----------------
This module allows outputting messages to the terminal, and can be loaded
with ``require 'mp.msg'``.
``msg.log(level, ...)``
The level parameter is the message priority. It's a string and one of
``fatal``, ``error``, ``warn``, ``info``, ``v``, ``debug``. The user's
settings will determine which of these messages will be visible. Normally,
all messages are visible, except ``v`` and ``debug``.
The parameters after that are all converted to strings. Spaces are inserted
to separate multiple parameters.
You don't need to add newlines.
``msg.fatal(...)``, ``msg.error(...)``, ``msg.warn(...)``, ``msg.info(...)``, ``msg.verbose(...)``, ``msg.debug(...)``
All of these are shortcuts and equivalent to the corresponding
``msg.log(level, ...)`` call.
mp.options functions
--------------------
mpv comes with a built-in module to manage options from config-files and the
command-line. All you have to do is to supply a table with default options to
the read_options function. The function will overwrite the default values
with values found in the config-file and the command-line (in that order).
``options.read_options(table [, identifier])``
A ``table`` with key-value pairs. The type of the default values is
important for converting the values read from the config file or
command-line back. Do not use ``nil`` as a default value!
The ``identifier`` is used to identify the config-file and the command-line
options. These needs to unique to avoid collisions with other scripts.
Defaults to ``mp.get_script_name()``.
Example implementation::
require 'mp.options'
local options = {
optionA = "defaultvalueA",
optionB = -0.5,
optionC = true,
}
read_options(options, "myscript")
print(option.optionA)
The config file will be stored in ``lua-settings/identifier.conf`` in mpv's user
folder. Comment lines can be started with # and stray spaces are not removed.
Boolean values will be represented with yes/no.
Example config::
# comment
optionA=Hello World
optionB=9999
optionC=no
Command-line options are read from the ``--script-opts`` parameter. To avoid
collisions, all keys have to be prefixed with ``identifier-``.
Example command-line::
--script-opts=myscript-optionA=TEST,myscript-optionB=0,myscript-optionC=yes
mp.utils options
----------------
This built-in module provides generic helper functions for Lua, and have
strictly speaking nothing to do with mpv or video/audio playback. They are
provided for convenience. Most compensate for Lua's scarce standard library.
Be warned that any of these functions might disappear any time. They are not
strictly part of the guaranteed API.
``utils.getcwd()``
Returns the directory that mpv was launched from. On error, ``nil, error``
is returned.
``utils.readdir(path [, filter])``
Enumerate all entries at the given path on the filesystem, and return them
as array. Each entry is a directory entry (without the path).
The list is unsorted (in whatever order the operating system returns it).
If the ``filter`` argument is given, it must be one of the following
strings:
``files``
List regular files only. This excludes directories, special files
(like UNIX device files or FIFOs), and dead symlinks. It includes
UNIX symlinks to regular files.
``dirs``
List directories only, or symlinks to directories. ``.`` and ``..``
are not included.
``normal``
Include the results of both ``files`` and ``dirs``. (This is the
default.)
``all``
List all entries, even device files, dead symlinks, FIFOs, and the
``.`` and ``..`` entries.
On error, ``nil, error`` is returned.
``utils.split_path(path)``
Split a path into directory component and filename component, and return
them. The first return value is always the directory. The second return
value is the trailing part of the path, the directory entry.
``utils.join_path(p1, p2)``
Return the concatenation of the 2 paths. Tries to be clever. For example,
if ```p2`` is an absolute path, p2 is returned without change.
``utils.subprocess(t)``
Runs an external process and waits until it exits. Returns process status
and the captured output.
The parameter ``t`` is a table. The function reads the following entries:
``args``
Array of strings. The first array entry is the executable. This
can be either an absolute path, or a filename with no path
components, in which case the ``PATH`` environment variable is
used to resolve the executable. The other array elements are
passed as command line arguments.
``cancellable``
Optional. If set to ``true`` (default), then if the user stops
playback or goes to the next file while the process is running,
the process will be killed.
``max_size``
Optional. The maximum size in bytes of the data that can be captured
from stdout. (Default: 16 MB.)
The function returns a table as result with the following entries:
``status``
The raw exit status of the process. It will be negative on error.
``stdout``
Captured output stream as string, limited to ``max_size``.
``error``
``nil`` on success. The string ``killed`` if the process was
terminated in an unusual way. The string ``init`` if the process
could not be started.
On Windows, ``killed`` is only returned when 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])``
Parses the given string argument as JSON, and returns it as a Lua table. On
error, returns ``nil, error``. (Currently, ``error`` is just a string
reading ``error``, because there is no fine-grained error reporting of any
kind.)
The returned value uses similar conventions as ``mp.get_property_native()``
to distinguish empty objects and arrays.
If the ``trail`` parameter is ``true`` (or any value equal to ``true``),
then trailing non-whitespace text is tolerated by the function, and the
trailing text is returned as 3rd return value. (The 3rd return value is
always there, but with ``trail`` set, no error is raised.)
``utils.format_json(v)``
Format the given Lua table (or value) as a JSON string and return it. On
error, returns ``nil, error``. (Errors usually only happen on value types
incompatible with JSON.)
The argument value uses similar conventions as ``mp.set_property_native()``
to distinguish empty objects and arrays.
``utils.to_string(v)``
Turn the given value into a string. Formats tables and their contents. This
doesn't do anything special; it is only needed because Lua is terrible.
Events
------
Events are notifications from player core to scripts. You can register an
event handler with ``mp.register_event``.
Note that all scripts (and other parts of the player) receive events equally,
and there's no such thing as blocking other scripts from receiving events.
Example:
::
function my_fn(event)
print("start of playback!")
end
mp.register_event("file-loaded", my_fn)
List of events
--------------
``start-file``
Happens right before a new file is loaded. When you receive this, the
player is loading the file (or possibly already done with it).
``end-file``
Happens after a file was unloaded. Typically, the player will load the
next file right away, or quit if this was the last file.
``file-loaded``
Happens after a file was loaded and begins playback.
``seek``
Happens on seeking. (This might include cases when the player seeks
internally, even without user interaction. This includes e.g. segment
changes when playing ordered chapters Matroska files.)
``playback-restart``
Start of playback after seek or after file was loaded.
``idle``
Idle mode is entered. This happens when playback ended, and the player was
started with ``--idle`` or ``--force-window``. This mode is implicitly ended
when the ``start-file`` or ``shutdown`` events happen.
``tick``
Called after a video frame was displayed. This is a hack, and you should
avoid using it. Use timers instead and maybe watch pausing/unpausing events
to avoid wasting CPU when the player is paused.
``shutdown``
Sent when the player quits, and the script should terminate. Normally
handled automatically. See `Details on the script initialization and lifecycle`_.
``log-message``
Receives messages enabled with ``mp.enable_messages``. The message data
is contained in the table passed as first parameter to the event handler.
The table contains, in addition to the default event fields, the following
fields:
``prefix``
The module prefix, identifies the sender of the message. This is what
the terminal player puts in front of the message text when using the
``--v`` option, and is also what is used for ``--msg-level``.
``level``
The log level as string. See ``msg.log`` for possible log level names.
Note that later versions of mpv might add new levels or remove
(undocumented) existing ones.
``text``
The log message. The text will end with a newline character. Sometimes
it can contain multiple lines.
Keep in mind that these messages are meant to be hints for humans. You
should not parse them, and prefix/level/text of messages might change
any time.
``get-property-reply``
Undocumented (not useful for Lua scripts).
``set-property-reply``
Undocumented (not useful for Lua scripts).
``command-reply``
Undocumented (not useful for Lua scripts).
``client-message``
Undocumented (used internally).
``video-reconfig``
Happens on video output or filter reconfig.
``audio-reconfig``
Happens on audio output or filter reconfig.
The following events also happen, but are deprecated: ``tracks-changed``,
``track-switched``, ``pause``, ``unpause``, ``metadata-update``,
``chapter-change``. Use ``mp.observe_property()`` instead.
Extras
------
This documents experimental features, or features that are "too special" to
guarantee a stable interface.
``mp.add_hook(type, priority, fn)``
Add a hook callback for ``type`` (a string identifying a certain kind of
hook). These hooks allow the player to call script functions and wait for
their result (normally, the Lua scripting interface is asynchronous from
the point of view of the player core). ``priority`` is an arbitrary integer
that allows ordering among hooks of the same kind. Using the value 50 is
recommended as neutral default value. ``fn`` is the function that will be
called during execution of the hook.
See `Hooks`_ for currently existing hooks and what they do - only the hook
list is interesting; handling hook execution is done by the Lua script
function automatically.
-935
View File
@@ -1,935 +0,0 @@
VIDEO OUTPUT DRIVERS
====================
Video output drivers are interfaces to different video output facilities. The
syntax is:
``--vo=<driver1[:suboption1[=value]:...],driver2,...[,]>``
Specify a priority list of video output drivers to be used.
If the list has a trailing ',', mpv will fall back on drivers not contained
in the list. Suboptions are optional and can mostly be omitted.
You can also set defaults for each driver. The defaults are applied before the
normal driver parameters.
``--vo-defaults=<driver1[:parameter1:parameter2:...],driver2,...>``
Set defaults for each driver.
.. note::
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.
Available video output drivers are:
``xv`` (X11 only)
Uses the XVideo extension to enable hardware-accelerated display. This is
the most compatible VO on X, but may be low-quality, and has issues with
OSD and subtitle display.
.. note:: This driver is for compatibility with old systems.
``adaptor=<number>``
Select a specific XVideo adapter (check xvinfo results).
``port=<number>``
Select a specific XVideo port.
``ck=<cur|use|set>``
Select the source from which the color key is taken (default: cur).
cur
The default takes the color key currently set in Xv.
use
Use but do not set the color key from mpv (use the ``--colorkey``
option to change it).
set
Same as use but also sets the supplied color key.
``ck-method=<man|bg|auto>``
Sets the color key drawing method (default: man).
man
Draw the color key manually (reduces flicker in some cases).
bg
Set the color key as window background.
auto
Let Xv draw the color key.
``colorkey=<number>``
Changes the color key to an RGB value of your choice. ``0x000000`` is
black and ``0xffffff`` is white.
``no-colorkey``
Disables color-keying.
``x11`` (X11 only)
Shared memory video output driver without hardware acceleration that works
whenever X11 is present.
.. note:: This is a fallback only, and should not be normally used.
``vdpau`` (X11 only)
Uses the VDPAU interface to display and optionally also decode video.
Hardware decoding is used with ``--hwdec=vdpau``.
.. note::
Earlier versions of mpv (and MPlayer, mplayer2) provided sub-options
to tune vdpau post-processing, like ``deint``, ``sharpen``, ``denoise``,
``chroma-deint``, ``pullup``, ``hqscaling``. These sub-options are
deprecated, and you should use the ``vdpaupp`` video filter instead.
``sharpen=<-1-1>``
(Deprecated. See note about ``vdpaupp``.)
For positive values, apply a sharpening algorithm to the video, for
negative values a blurring algorithm (default: 0).
``denoise=<0-1>``
(Deprecated. See note about ``vdpaupp``.)
Apply a noise reduction algorithm to the video (default: 0; no noise
reduction).
``deint=<-4-4>``
(Deprecated. See note about ``vdpaupp``.)
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``),
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.
0
Pick the ``vdpaupp`` video filter default, which corresponds to 3.
1
Show only first field.
2
Bob deinterlacing.
3
Motion-adaptive temporal deinterlacing. May lead to A/V desync
with slow video hardware and/or high resolution.
4
Motion-adaptive temporal deinterlacing with edge-guided spatial
interpolation. Needs fast video hardware.
``chroma-deint``
(Deprecated. See note about ``vdpaupp``.)
Makes temporal deinterlacers operate both on luma and chroma (default).
Use no-chroma-deint to solely use luma and speed up advanced
deinterlacing. Useful with slow video memory.
``pullup``
(Deprecated. See note about ``vdpaupp``.)
Try to apply inverse telecine, needs motion adaptive temporal
deinterlacing.
``hqscaling=<0-9>``
(Deprecated. See note about ``vdpaupp``.)
0
Use default VDPAU scaling (default).
1-9
Apply high quality VDPAU scaling (needs capable hardware).
``fps=<number>``
Override autodetected display refresh rate value (the value is needed
for framedrop to allow video playback rates higher than display
refresh rate, and for vsync-aware frame timing adjustments). Default 0
means use autodetected value. A positive value is interpreted as a
refresh rate in Hz and overrides the autodetected value. A negative
value disables all timing adjustment and framedrop logic.
``composite-detect``
NVIDIA's current VDPAU implementation behaves somewhat differently
under a compositing window manager and does not give accurate frame
timing information. With this option enabled, the player tries to
detect whether a compositing window manager is active. If one is
detected, the player disables timing adjustments as if the user had
specified ``fps=-1`` (as they would be based on incorrect input). This
means timing is somewhat less accurate than without compositing, but
with the composited mode behavior of the NVIDIA driver, there is no
hard playback speed limit even without the disabled logic. Enabled by
default, use ``no-composite-detect`` to disable.
``queuetime_windowed=<number>`` and ``queuetime_fs=<number>``
Use VDPAU's presentation queue functionality to queue future video
frame changes at most this many milliseconds in advance (default: 50).
See below for additional information.
``output_surfaces=<2-15>``
Allocate this many output surfaces to display video frames (default:
3). See below for additional information.
``colorkey=<#RRGGBB|#AARRGGBB>``
Set the VDPAU presentation queue background color, which in practice
is the colorkey used if VDPAU operates in overlay mode (default:
``#020507``, some shade of black). If the alpha component of this value
is 0, the default VDPAU colorkey will be used instead (which is usually
green).
``force-yuv``
Never accept RGBA input. This means mpv will insert a filter to convert
to a YUV format before the VO. Sometimes useful to force availability
of certain YUV-only features, like video equalizer or deinterlacing.
Using the VDPAU frame queuing functionality controlled by the queuetime
options makes mpv's frame flip timing less sensitive to system CPU load and
allows mpv to start decoding the next frame(s) slightly earlier, which can
reduce jitter caused by individual slow-to-decode frames. However, the
NVIDIA graphics drivers can make other window behavior such as window moves
choppy if VDPAU is using the blit queue (mainly happens if you have the
composite extension enabled) and this feature is active. If this happens on
your system and it bothers you then you can set the queuetime value to 0 to
disable this feature. The settings to use in windowed and fullscreen mode
are separate because there should be no reason to disable this for
fullscreen mode (as the driver issue should not affect the video itself).
You can queue more frames ahead by increasing the queuetime values and the
``output_surfaces`` count (to ensure enough surfaces to buffer video for a
certain time ahead you need at least as many surfaces as the video has
frames during that time, plus two). This could help make video smoother in
some cases. The main downsides are increased video RAM requirements for
the surfaces and laggier display response to user commands (display
changes only become visible some time after they're queued). The graphics
driver implementation may also have limits on the length of maximum
queuing time or number of queued surfaces that work well or at all.
``direct3d_shaders`` (Windows only)
Video output driver that uses the Direct3D interface.
.. note:: This driver is for compatibility with systems that don't provide
proper OpenGL drivers.
``prefer-stretchrect``
Use ``IDirect3DDevice9::StretchRect`` over other methods if possible.
``disable-stretchrect``
Never render the video using ``IDirect3DDevice9::StretchRect``.
``disable-textures``
Never render the video using D3D texture rendering. Rendering with
textures + shader will still be allowed. Add ``disable-shaders`` to
completely disable video rendering with textures.
``disable-shaders``
Never use shaders when rendering video.
``only-8bit``
Never render YUV video with more than 8 bits per component.
Using this flag will force software conversion to 8-bit.
``disable-texture-align``
Normally texture sizes are always aligned to 16. With this option
enabled, the video texture will always have exactly the same size as
the video itself.
Debug options. These might be incorrect, might be removed in the future,
might crash, might cause slow downs, etc. Contact the developers if you
actually need any of these for performance or proper operation.
``force-power-of-2``
Always force textures to power of 2, even if the device reports
non-power-of-2 texture sizes as supported.
``texture-memory=<mode>``
Only affects operation with shaders/texturing enabled, and (E)OSD.
Possible values:
``default`` (default)
Use ``D3DPOOL_DEFAULT``, with a ``D3DPOOL_SYSTEMMEM`` texture for
locking. If the driver supports ``D3DDEVCAPS_TEXTURESYSTEMMEMORY``,
``D3DPOOL_SYSTEMMEM`` is used directly.
``default-pool``
Use ``D3DPOOL_DEFAULT``. (Like ``default``, but never use a
shadow-texture.)
``default-pool-shadow``
Use ``D3DPOOL_DEFAULT``, with a ``D3DPOOL_SYSTEMMEM`` texture for
locking. (Like ``default``, but always force the shadow-texture.)
``managed``
Use ``D3DPOOL_MANAGED``.
``scratch``
Use ``D3DPOOL_SCRATCH``, with a ``D3DPOOL_SYSTEMMEM`` texture for
locking.
``swap-discard``
Use ``D3DSWAPEFFECT_DISCARD``, which might be faster.
Might be slower too, as it must(?) clear every frame.
``exact-backbuffer``
Always resize the backbuffer to window size.
``direct3d`` (Windows only)
Same as ``direct3d_shaders``, but with the options ``disable-textures``
and ``disable-shaders`` forced.
.. note:: This driver is for compatibility with old systems.
``opengl``
OpenGL video output driver. It supports extended scaling methods, dithering
and color management.
By default, it tries to use fast and fail-safe settings. Use the alias
``opengl-hq`` to use this driver with defaults set to high quality
rendering.
Requires at least OpenGL 2.1.
Some features are available with OpenGL 3 capable graphics drivers only
(or if the necessary extensions are available).
OpenGL ES 2.0 and 3.0 are supported as well.
Hardware decoding over OpenGL-interop is supported to some degree. Note
that in this mode, some corner case might not be gracefully handled, and
color space conversion and chroma upsampling is generally in the hand of
the hardware decoder APIs.
``scale=<filter>``
``bilinear``
Bilinear hardware texture filtering (fastest, very low quality).
This is the default for compatibility reasons.
``spline36``
Mid quality and speed. This is the default when using ``opengl-hq``.
``lanczos``
Lanczos scaling. Provides mid quality and speed. Generally worse
than ``spline36``, but it results in a slightly sharper image
which is good for some content types. The number of taps can be
controlled with ``scale-radius``, but is best left unchanged.
This filter corresponds to the old ``lanczos3`` alias if the default
radius is used, while ``lanczos2`` corresponds to a radius of 2.
(This filter is an alias for ``sinc``-windowed ``sinc``)
``ewa_lanczos``
Elliptic weighted average Lanczos scaling. Also known as Jinc.
Relatively slow, but very good quality. The radius can be
controlled with ``scale-radius``. Increasing the radius makes the
filter sharper but adds more ringing.
(This filter is an alias for ``jinc``-windowed ``jinc``)
``ewa_lanczossharp``
A slightly sharpened version of ewa_lanczos, preconfigured to use
an ideal radius and parameter. If your hardware can run it, this is
probably what you should use by default.
``mitchell``
Mitchell-Netravali. The ``B`` and ``C`` parameters can be set with
``scale-param1`` and ``scale-param2``. This filter is very good at
downscaling (see ``dscale``).
``oversample``
A version of nearest neighbour that (naively) oversamples pixels,
so that pixels overlapping edges get linearly interpolated instead
of rounded. This essentially removes the small imperfections and
judder artifacts caused by nearest-neighbour interpolation, in
exchange for adding some blur. This filter is good at temporal
interpolation, and also known as "smoothmotion" (see ``tscale``).
There are some more filters, but most are not as useful. For a complete
list, pass ``help`` as value, e.g.::
mpv --vo=opengl:scale=help
``scale-param1=<value>``, ``scale-param2=<value>``
Set filter parameters. Ignored if the filter is not tunable.
Currently, this affects the following filter parameters:
bcspline
Spline parameters (``B`` and ``C``). Defaults to 0.5 for both.
gaussian
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
will never interpolate, thus behaving as if the regular nearest
neighbour algorithm was used. Defaults to 0.0.
``scale-blur=<value>``
Kernel scaling factor (also known as a blur factor). Decreasing this
makes the result sharper, increasing it makes it blurrier (default 0).
If set to 0, the kernel's preferred blur factor is used. Note that
setting this too low (eg. 0.5) leads to bad results. It's generally
recommended to stick to values between 0.8 and 1.2.
``scale-radius=<value>``
Set radius for filters listed below, must be a float number between 0.5
and 16.0. Defaults to the filter's preferred radius if not specified.
``sinc`` and derivatives, ``jinc`` and derivatives, ``gaussian``, ``box`` and ``triangle``
Note that depending on filter implementation details and video scaling
ratio, the radius that actually being used might be different
(most likely being increased a bit).
``scale-antiring=<value>``
Set the antiringing strength. This tries to eliminate ringing, but can
introduce other artifacts in the process. Must be a float number
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``.
``scale-window=<window>``
(Advanced users only) Choose a custom windowing function for the kernel.
Defaults to the filter's preferred window if unset. Use
``scale-window=help`` to get a list of supported windowing functions.
``scale-wparam=<window>``
(Advanced users only) Configure the parameter for the window function
given by ``scale-window``. Ignored if the window is not tunable.
Currently, this affects the following window parameters:
kaiser
Window parameter (alpha). Defaults to 6.33.
blackman
Window parameter (alpha). Defaults to 0.16.
gaussian
Scale parameter (t). Increasing this makes the window wider.
Defaults to 1.
``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
will reproduce the source image perfectly if no scaling is performed.
Note that this option never affects ``cscale``.
``pbo``
Enable use of PBOs. This is slightly faster, but can sometimes lead to
sporadic and temporary image corruption (in theory, because reupload
is not retried when it fails), and perhaps actually triggers slower
paths with drivers that don't support PBOs properly.
``dither-depth=<N|no|auto>``
Set dither target depth to N. Default: no.
no
Disable any dithering done by mpv.
auto
Automatic selection. If output bit depth cannot be detected,
8 bits per component are assumed.
8
Dither to 8 bit output.
Note that the depth of the connected video display device can not be
detected. Often, LCD panels will do dithering on their own, which
conflicts with ``opengl``'s dithering and leads to ugly output.
``dither-size-fruit=<2-8>``
Set the size of the dither matrix (default: 6). The actual size of
the matrix is ``(2^N) x (2^N)`` for an option value of ``N``, so a
value of 6 gives a size of 64x64. The matrix is generated at startup
time, and a large matrix can take rather long to compute (seconds).
Used in ``dither=fruit`` mode only.
``dither=<fruit|ordered|no>``
Select dithering algorithm (default: fruit). (Normally, the
``dither-depth`` option controls whether dithering is enabled.)
``temporal-dither``
Enable temporal dithering. (Only active if dithering is enabled in
general.) This changes between 8 different dithering pattern on each
frame by changing the orientation of the tiled dithering matrix.
Unfortunately, this can lead to flicker on LCD displays, since these
have a high reaction time.
``debug``
Check for OpenGL errors, i.e. call ``glGetError()``. Also request a
debug OpenGL context (which does nothing with current graphics drivers
as of this writing).
``interpolation``
Reduce stuttering caused by mismatches in the video fps and display
refresh rate (also known as judder).
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.
Note that this relies on vsync to work, see ``swapinterval`` for more
information.
``swapinterval=<n>``
Interval in displayed frames between two buffer swaps.
1 is equivalent to enable VSYNC, 0 to disable VSYNC. Defaults to 1 if
not specified.
Note that this depends on proper OpenGL vsync support. On some platforms
and drivers, this only works reliably when in fullscreen mode. It may
also require driver-specific hacks if using multiple monitors, to
ensure mpv syncs to the right one. Compositing window managers can
also lead to bad results, as can missing or incorrect display FPS
information (see ``--display-fps``).
``dscale=<filter>``
Like ``scale``, but apply these filters on downscaling instead. If this
option is unset, the filter implied by ``scale`` will be applied.
``cscale=<filter>``
As ``scale``, but for interpolating chroma information. If the image
is not subsampled, this option is ignored entirely.
``tscale=<filter>``
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``.
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.
``dscale-radius``, ``cscale-radius``, ``tscale-radius``, etc.
Set filter parameters for ``dscale``, ``cscale`` and ``tscale``,
respectively.
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.
``fancy-downscaling``
When using convolution based filters, extend the filter size
when downscaling. Trades quality for reduced downscaling performance.
This is automatically disabled for anamorphic video, because this
feature doesn't work correctly with different scale factors in
different directions.
``sigmoid-upscaling``
When upscaling, use a sigmoidal color transform to avoid emphasizing
ringing artifacts. This also enables ``linear-scaling``.
``sigmoid-center``
The center of the sigmoid curve used for ``sigmoid-upscaling``, must
be a float between 0.0 and 1.0. Defaults to 0.75 if not specified.
``sigmoid-slope``
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.
``glfinish``
Call ``glFinish()`` before and after swapping buffers (default: disabled).
Slower, but might help getting better results when doing framedropping.
Can completely ruin performance. The details depend entirely on the
OpenGL driver.
``waitvsync``
Call ``glXWaitVideoSyncSGI`` after each buffer swap (default: disabled).
This may or may not help with video timing accuracy and frame drop. It's
possible that this makes video output slower, or has no effect at all.
X11/GLX only.
``dwmflush=<no|windowed|yes>``
Calls ``DwmFlush`` after swapping buffers on Windows (default: no).
It also sets ``SwapInterval(0)`` to ignore the OpenGL timing. Values
are: no (disabled), windowed (only in windowed mode), yes (also in
full screen).
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.
Windows only.
``sw``
Continue even if a software renderer is detected.
``backend=<sys>``
The value ``auto`` (the default) selects the windowing backend. You
can also pass ``help`` to get a complete list of compiled in backends
(sorted by autoprobe order).
auto
auto-select (default)
cocoa
Cocoa/OS X
win
Win32/WGL
x11, x11es
X11/GLX (the ``es`` variant forces GLES)
wayland
Wayland/EGL
x11egl, x11egles
X11/EGL (the ``es`` variant forces GLES)
``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.)
``fmt`` can be one of: rgb, rgba, rgb8, rgb10, rgb10_a2, rgb16, rgb16f,
rgb32f, rgba12, rgba16, rgba16f, rgba32f.
Default: rgba.
``gamma=<0.1..2.0>``
Set a gamma value (default: 1.0). If gamma is adjusted in other ways
(like with the ``--gamma`` option or key bindings and the ``gamma``
property), the value is multiplied with the other gamma value.
Recommended values based on the environmental brightness:
1.0
Brightly illuminated (default)
0.9
Slightly dim
0.8
Pitch black room
``gamma-auto``
Automatically corrects the gamma value depending on ambient lighting
conditions (adding a gamma boost for dark rooms).
With ambient illuminance of 64lux, mpv will pick the 1.0 gamma value
(no boost), and slightly increase the boost up until 0.8 for 16lux.
NOTE: Only implemented on OS X.
``target-prim=<value>``
Specifies the primaries of the display. Video colors will be adapted
to this colorspace if necessary. Valid values are:
auto
Disable any adaptation (default)
bt.470m
ITU-R BT.470 M
bt.601-525
ITU-R BT.601 (525-line SD systems, eg. NTSC), SMPTE 170M/240M
bt.601-625
ITU-R BT.601 (625-line SD systems, eg. PAL/SECAM), ITU-R BT.470 B/G
bt.709
ITU-R BT.709 (HD), IEC 61966-2-4 (sRGB), SMPTE RP177 Annex B
bt.2020
ITU-R BT.2020 (UHD)
apple
Apple RGB
adobe
Adobe RGB (1998)
prophoto
ProPhoto RGB (ROMM)
cie1931
CIE 1931 RGB (not to be confused with CIE XYZ)
``target-trc=<value>``
Specifies the transfer characteristics (gamma) of the display. Video
colors will be adjusted to this curve. Valid values are:
auto
Disable any adaptation (default)
bt.1886
ITU-R BT.1886 curve, without the brightness drop (approx. 1.961)
srgb
IEC 61966-2-4 (sRGB)
linear
Linear light output
gamma1.8
Pure power curve (gamma 1.8), also used for Apple RGB
gamma2.2
Pure power curve (gamma 2.2)
gamma2.8
Pure power curve (gamma 2.8), also used for BT.470-BG
prophoto
ProPhoto RGB (ROMM)
``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``.
``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
``icc-cache=<file>``
Store and load the 3D LUT created from the ICC profile in this file.
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.
``icc-intent=<value>``
Specifies the ICC intent used for the color transformation (when using
``icc-profile``).
0
perceptual
1
relative colorimetric (default)
2
saturation
3
absolute colorimetric
``3dlut-size=<r>x<g>x<b>``
Size of the 3D LUT generated from the ICC profile in each dimension.
Default is 128x256x64.
Sizes must be a power of two, and 512 at most.
``blend-subtitles=<yes|video|no>``
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``.
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
black margins below a video (for example).
If ``video`` is selected, the behavior is similar to ``yes``, but subs
are drawn at the video's native resolution, and scaled along with the
video.
.. warning:: This changes the way subtitle colors are handled. Normally,
subtitle colors are assumed to be in sRGB and color managed
as such. Enabling this makes them treated as being in the
video's color space instead. This is good if you want
things like softsubbed ASS signs to match the video colors,
but may cause SRT subtitles or similar to look slightly off.
``alpha=<blend|yes|no>``
Decides what to do if the input has an alpha component (default: blend).
blend
Blend the frame against a black background.
yes
Try to create a framebuffer with alpha component. This only makes sense
if the video contains alpha information (which is extremely rare). May
not be supported on all platforms. If alpha framebuffers are
unavailable, it silently falls back on a normal framebuffer. Note
that if you set the ``fbo-format`` option to a non-default value,
a format with alpha must be specified, or this won't work.
no
Ignore alpha component.
``rectangle-textures``
Force use of rectangle textures (default: no). Normally this shouldn't
have any advantages over normal textures. Note that hardware decoding
overrides this flag.
``background=<color>``
Color used to draw parts of the mpv window not covered by video.
See ``--osd-color`` option how colors are defined.
``opengl-hq``
Same as ``opengl``, but with default settings for high quality rendering.
This is equivalent to::
--vo=opengl:scale=spline36:cscale=spline36:dscale=mitchell:dither-depth=auto:fbo-format=rgba16:fancy-downscaling:sigmoid-upscaling
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.
For tuning, refer to your copy of the file ``SDL_hints.h``.
.. note:: This driver is for compatibility with systems that don't provide
proper graphics drivers, or which support GLES only.
``sw``
Continue even if a software renderer is detected.
``switch-mode``
Instruct SDL to switch the monitor video mode when going fullscreen.
``vaapi``
Intel VA API video output driver with support for hardware decoding. Note
that there is absolutely no reason to use this, other than wanting to use
hardware decoding to save power on laptops, or possibly preventing video
tearing with some setups.
.. note:: This driver is for compatibility with crappy systems. You can
use vaapi hardware decoding with ``--vo=opengl`` too.
``scaling=<algorithm>``
default
Driver default (mpv default as well).
fast
Fast, but low quality.
hq
Unspecified driver dependent high-quality scaling, slow.
nla
``non-linear anamorphic scaling``
``deint-mode=<mode>``
Select deinterlacing algorithm. Note that by default deinterlacing is
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).
In this case, the default for ``deint-mode`` is ``no``, and enabling
deinterlacing via user interaction using the methods mentioned above
actually inserts the ``vavpp`` video filter. If vpp is not actually
supported with the libva backend in use, you can use this option to
forcibly enable VO based deinterlacing.
no
Don't allow deinterlacing (default for newer libva).
first-field
Show only first field (going by ``--field-dominance``).
bob
bob deinterlacing (default for older libva).
``scaled-osd=<yes|no>``
If enabled, then the OSD is rendered at video resolution and scaled to
display resolution. By default, this is disabled, and the OSD is
rendered at display resolution if the driver supports it.
``null``
Produces no video output. Useful for benchmarking.
``caca``
Color ASCII art video output driver that works on a text console.
.. note:: This driver is a joke.
``image``
Output each frame into an image file in the current directory. Each file
takes the frame number padded with leading zeros as name.
``format=<format>``
Select the image file format.
jpg
JPEG files, extension .jpg. (Default.)
jpeg
JPEG files, extension .jpeg.
png
PNG files.
ppm
Portable bitmap format.
pgm
Portable graymap format.
pgmyuv
Portable graymap format, using the YV12 pixel format.
tga
Truevision TGA.
``png-compression=<0-9>``
PNG compression factor (speed vs. file size tradeoff) (default: 7)
``png-filter=<0-5>``
Filter applied prior to PNG compression (0 = none; 1 = sub; 2 = up;
3 = average; 4 = Paeth; 5 = mixed) (default: 5)
``jpeg-quality=<0-100>``
JPEG quality factor (default: 90)
``(no-)jpeg-progressive``
Specify standard or progressive JPEG (default: no).
``(no-)jpeg-baseline``
Specify use of JPEG baseline or not (default: yes).
``jpeg-optimize=<0-100>``
JPEG optimization factor (default: 100)
``jpeg-smooth=<0-100>``
smooth factor (default: 0)
``jpeg-dpi=<1->``
JPEG DPI (default: 72)
``outdir=<dirname>``
Specify the directory to save the image files to (default: ``./``).
``wayland`` (Wayland only)
Wayland shared memory video output as fallback for ``opengl``.
.. note:: This driver is for compatibility with systems that don't provide
working OpenGL drivers.
``alpha``
Use a buffer format that supports videos and images with alpha
information
``rgb565``
Use RGB565 as buffer format. This format is implemented on most
platforms, especially on embedded where it is far more efficient then
RGB8888.
``triple-buffering``
Use 3 buffers instead of 2. This can lead to more fluid playback, but
uses more memory.
``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.
This also supports the ``vo_cmdline`` command.
``rpi`` (Raspberry Pi)
Native video output on the Raspberry Pi using the MMAL API.
``display=<number>``
Select the display number on which the video overlay should be shown
(default: 0).
``layer=<number>``
Select the dispmanx layer on which the video overlay should be shown
(default: -10). Note that mpv will also use the 2 layers above the
selected layer, to handle the window background and OSD. Actual video
rendering will happen on the layer above the selected layer.
``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).
``connector=<number>``
Select the connector to use (usually this is a monitor.) If set to -1,
mpv renders the output on the first available connector. (default: -1)
``devpath=<filename>``
Path to graphic card device.
(default: /dev/dri/card0)
-446
View File
@@ -1,446 +0,0 @@
CHANGES FROM OTHER VERSIONS OF MPLAYER
======================================
**mpv** is based on mplayer2, which in turn is based on the original MPlayer
(also called mplayer, mplayer-svn, mplayer1). Many changes have been made, a
large part of which is incompatible or completely changes how the player
behaves. Although there are still many similarities to its ancestors, **mpv**
should generally be treated as a completely different program.
.. note::
These lists are incomplete.
General Changes from MPlayer to mpv
-----------------------------------
This listing is about changes introduced by mplayer2 and mpv relatively to
MPlayer.
Player
~~~~~~
* New name for the binary (``mpv``). New location for config files (either
``~/.config/mpv/mpv.conf``, or if you want, ``~/.mpv/config``).
* Encoding functionality (replacement for MEncoder, see the `ENCODING`_ section).
* Support for Lua scripting (see the `LUA SCRIPTING`_ section).
* Better pause handling (e.g. do not unpause on a command).
* Precise seeking support.
* Improvements in audio/video sync handling.
* Do not lose settings when playing a new file in the same player instance.
* Slave mode compatibility broken (see below).
* Re-enable screensaver while the player is paused.
* Allow resuming playback at a later point with ``Shift+q``, also see the
``quit_watch_later`` input command.
* ``--keep-open`` option to stop the player from closing the window and
exiting after playback ends.
* A client API, that allows embedding **mpv** into applications
(see ``libmpv/client.h`` in the sources).
Input
~~~~~
* Improved default keybindings. MPlayer bindings are also available (see
``etc/mplayer-input.conf`` in the source tree).
* Improved responsiveness on user input.
* Support for modifier keys (alt, shift, ctrl) in input.conf.
* Allow customizing whether a key binding for seeking shows the video time, the
OSD bar, or nothing (see the `Input Command Prefixes`_ section).
* Support mapping multiple commands to one key.
* Classic LIRC support was removed. Install remotes as input devices instead.
This way they will send X11 key events to the mpv window, which can be bound
using the normal ``input.conf``.
* 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).
Audio
~~~~~
* Support for gapless audio (see the ``--gapless-audio`` option).
* Support for OSS4 volume control.
* Improved support for PulseAudio.
* Make ``--softvol`` default (**mpv** is not a mixer control panel).
* By default, do pitch correction if playback speed is increased.
* Improved downmixing and output of surround audio:
- Instead of using hardcoded pan filters to do remixing, libavresample is used
- Channel maps are used to identify the channel layout, so e.g. ``3.0`` and
``2.1`` audio can be distinguished.
Video
~~~~~
* Wayland support.
* Native support for VAAPI and VDA. Improved VDPAU video output.
* Improved OpenGL output (see the ``opengl-hq`` video output).
* Make hardware decoding work with the ``opengl`` video output.
* Support for libavfilter (for video->video and audio->audio). This allows
using most of FFmpeg's filters, which improve greatly on the old MPlayer
filters in features, performance, and correctness.
* More correct color reproduction (color matrix generation), including support
for BT.2020 (Ultra HD) and linear XYZ (Digital Cinema) inputs.
* Support for color managed displays, via ICC profiles.
* High-quality image resamplers (see the ``opengl`` ``scale`` suboption).
* Support for scaling in (sigmoidized) linear light.
* Better subtitle rendering using libass by default.
* Improvements when playing multiple files (``-fixed-vo`` is default, do not
reset settings by default when playing a new file).
* Replace image video outputs (``--vo=jpeg`` etc.) with ``--vo=image``.
* Removal of ``--vo=gif89a``, ``--vo=md5sum``, ``--vo=yuv4mpeg``, as encoding
can handle these use cases. For yuv4mpeg, for example, use::
mpv input.mkv -o output.y4m --no-audio --oautofps --oneverdrop
* Image subtitles (DVDs etc.) are rendered in color and use more correct
positioning (color for image subs can be disabled with ``--sub-gray``).
OSD and terminal
~~~~~~~~~~~~~~~~
* Cleaned up terminal output: nicer status line, less useless noise.
* Improved OSD rendering using libass, with full Unicode support.
* New OSD bar with chapter marks. Not positioned in the middle of the video
(this can be customized with the ``--osd-bar-align-y`` option).
* Display list of chapters and audio/subtitle tracks on OSD (see the
`Properties`_ section).
Screenshots
~~~~~~~~~~~
* Instant screenshots without 1-frame delay.
* Support for taking screenshots even with hardware decoding.
* Support for saving screenshots as JPEG or PNG.
* Support for configurable file names.
* Support for taking screenshots with or without subtitles.
Note that the ``screenshot`` video filter is not needed anymore, and should not
be put into the mpv config file.
Miscellaneous
~~~~~~~~~~~~~
* Better MKV support (e.g. ordered chapters, 3D metadata).
* Matroska edition switching at runtime.
* Support for playing URLs of popular streaming sites directly.
(e.g. ``mpv https://www.youtube.com/watch?v=...``).
Requires a recent version of ``youtube-dl`` to be installed. Can be
disabled with ``ytdl=no`` in the mpv config file.
* Support for precise scrolling which scales the parameter of commands. If the
input doesn't support precise scrolling the scale factor stays 1.
* Allow changing/adjusting video filters at runtime. (This is also used to make
the ``D`` key insert vf_yadif if deinterlacing is not supported otherwise).
* Improved support for .cue files.
Mac OS X
~~~~~~~~
* Native OpenGL backend.
* Cocoa event loop is independent from MPlayer's event loop, so user
actions like accessing menus and live resizing do not block the playback.
* Apple Remote support.
* Media Keys support.
* VDA support using libavcodec hwaccel API instead of FFmpeg's decoder with up
to 2-2.5x reduction in CPU usage.
Windows
~~~~~~~
* Improved support for Unicode file names.
* Improved window handling.
* Do not block playback when moving the window.
* Improved Direct3D video output.
* Added WASAPI audio output.
Internal changes
~~~~~~~~~~~~~~~~
* Switch to GPLv2+ (see ``Copyright`` file for details).
* Removal of lots of cruft:
- Internal GUI (replaced by the OSC, see the `ON SCREEN CONTROLLER`_ section).
- MEncoder (replaced by native encoding, see the `ENCODING`_ section).
- OSD menu.
- Kernel video drivers for Linux 2.4 (including VIDIX).
- Teletext support.
- Support for dead platforms.
- Most built-in demuxers have been replaced by their libavformat counterparts.
- Built-in network support has been replaced by libavformat's (which also
supports https URLs).
- Embedded copies of libraries (such as FFmpeg).
* General code cleanups (including refactoring or rewrites of many parts).
* New build system.
* Many bug fixes and removal of long-standing issues.
* Generally preferring FFmpeg/Libav over internal demuxers, decoders, and
filters.
Detailed Listing of User-visible Changes
----------------------------------------
This listing is about changed command line switches, slave commands, and similar
things. Completely removed features are not listed.
Command Line Switches
~~~~~~~~~~~~~~~~~~~~~
* There is a new command line syntax, which is generally preferred over the old
syntax. ``-optname optvalue`` becomes ``--optname=optvalue``.
The old syntax will not be removed. However, the new syntax is mentioned in
all documentation and so on, and unlike the old syntax is not ambiguous,
so it is a good thing to know about this change.
* In general, negating switches like ``-noopt`` now have to be written as
``-no-opt`` or ``--no-opt``.
* Per-file options are not the default anymore. You can explicitly specify
file-local options. See ``Usage`` section.
* Many options have been renamed, removed or changed semantics. Some options
that are required for a good playback experience with MPlayer are now
superfluous or even worse than the defaults, so make sure to read the manual
before trying to use your existing configuration with **mpv**.
* Table of renamed/replaced switches:
=========================== ========================================
Old New
=========================== ========================================
``-no<opt>`` ``--no-<opt>`` (add a dash)
``-a52drc level`` ``--ad-lavc-ac3drc=level``
``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``)
``-af volnorm`` ``--af=drc`` (renamed)
``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts``
``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``
``-aspect`` ``--video-aspect``
``-ass-bottom-margin`` ``--vf=sub=bottom:top``
``-ass`` ``--sub-ass``
``-audiofile-cache`` (removed; the main cache settings are used)
``-audiofile`` ``--audio-file``
``-benchmark`` ``--untimed`` (no stats)
``-capture`` ``--stream-capture=<filename>``
``-channels`` ``--audio-channels`` (changed semantics)
``-cursor-autohide-delay`` ``--cursor-autohide``
``-delay`` ``--audio-delay``
``-dumpstream`` ``--stream-dump=<filename>``
``-dvdangle`` ``--dvd-angle``
``-endpos`` ``--length``
``-fixed-vo`` (removed; always the default)
``-font`` ``--osd-font``
``-forcedsubsonly`` ``--sub-forced-only``
``-forceidx`` ``--index``
``-format`` ``--audio-format``
``-fsmode-dontuse`` (removed)
``-fstype`` ``--x11-netwm`` (changed semantics)
``-hardframedrop`` ``--framedrop=hard``
``-identify`` (removed; use TOOLS/mpv_identify.sh)
``-idx`` ``--index``
``-lavdopts ...`` ``--vd-lavc-...``
``-lavfdopts`` ``--demuxer-lavf-...``
``-loop 0`` ``--loop=inf``
``-mixer-channel`` AO suboptions (``alsa``, ``oss``)
``-mixer`` AO suboptions (``alsa``, ``oss``)
``-mouse-movements`` ``--input-cursor``
``-msgcolor`` ``--msg-color``
``-msglevel`` ``--msg-level`` (changed semantics)
``-msgmodule`` ``--msg-module``
``-name`` ``--x11-name``
``-noar`` ``--no-input-appleremote``
``-noautosub`` ``--no-sub-auto``
``-noconsolecontrols`` ``--no-input-terminal``
``-nosound`` ``--no-audio``
``-osdlevel`` ``--osd-level``
``-panscanrange`` ``--video-zoom``, ``--video-pan-x/y``
``-playing-msg`` ``--term-playing-msg``
``-pp ...`` ``'--vf=lavfi=[pp=...]'``
``-pphelp`` (See FFmpeg libavfilter documentation.)
``-rawaudio ...`` ``--demuxer-rawaudio-...``
``-rawvideo ...`` ``--demuxer-rawvideo-...``
``-spugauss`` ``--sub-gauss``
``-srate`` ``--audio-samplerate``
``-ss`` ``--start``
``-ssf <sub>`` ``--sws-...``
``-stop-xscreensaver`` ``--stop-screensaver``
``-sub-fuzziness`` ``--sub-auto``
``-sub`` ``--sub-file``
``-subcp`` ``--sub-codepage``
``-subdelay`` ``--sub-delay``
``-subfile`` ``--sub-file``
``-subfont-*`` ``--sub-text-*``, ``--osd-*``
``-subfont-text-scale`` ``--sub-scale``
``-subfont`` ``--sub-text-font``
``-subfps`` ``--sub-fps``
``-subpos`` ``--sub-pos``
``-sws`` ``--sws-scaler``
``-tvscan`` ``--tv-scan``
``-use-filename-title`` ``--title='${filename}'``
``-vc ffh264vdpau`` (etc.) ``--hwdec=vdpau``
``-vobsub`` ``--sub-file`` (pass the .idx file)
``-x W``, ``-y H`` ``--geometry=WxH`` + ``--no-keepaspect``
``-xineramascreen`` ``--screen`` (different values)
``-xy W`` ``--autofit=W``
``-zoom`` Inverse available as ``--video-unscaled``
``dvdnav://`` ``dvdnav://menu``
``dvd://1`` ``dvd://0`` (0-based offset)
=========================== ========================================
.. note::
``-opt val`` becomes ``--opt=val``.
.. note::
Quite some video filters, video outputs, audio filters, audio outputs, had
changes in their option parsing. These aren't mentioned in the table above.
Also, some video and audio filters have been removed, and you have to use
libavfilter (using ``--vf=lavfi=[...]`` or ``--af=lavfi=[...]``) to get
them back.
input.conf and Slave Commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Table of renamed input commands:
This lists only commands that are not always gracefully handled by the
internal legacy translation layer. If an input.conf contains any legacy
commands, a warning will be printed when starting the player. The warnings
also show the replacement commands.
Properties containing ``_`` to separate words use ``-`` instead.
+--------------------------------+----------------------------------------+
| Old | New |
+================================+========================================+
| ``pt_step 1 [0|1]`` | ``playlist_next [weak|force]`` |
| | (translation layer cannot deal with |
| | whitespace) |
+--------------------------------+----------------------------------------+
| ``pt_step -1 [0|1]`` | ``playlist_prev [weak|force] (same)`` |
+--------------------------------+----------------------------------------+
| ``switch_ratio [<ratio>]`` | ``set video-aspect <ratio>`` |
| | |
| | ``set video-aspect 0`` (reset aspect) |
+--------------------------------+----------------------------------------+
| ``step_property_osd <prop>`` | ``cycle <prop> <step>`` (wraps), |
| ``<step> <dir>`` | ``add <prop> <step>`` (clamps). |
| | ``<dir>`` parameter unsupported. Use |
| | a negative ``<step>`` instead. |
+--------------------------------+----------------------------------------+
| ``step_property <prop>`` | Prefix ``cycle`` or ``add`` with |
| ``<step> <dir>`` | ``no-osd``: ``no-osd cycle <prop>`` |
| | ``<step>`` |
+--------------------------------+----------------------------------------+
| ``osd_show_property_text`` | ``show_text <text>`` |
| ``<text>`` | The property expansion format string |
| | syntax slightly changed. |
+--------------------------------+----------------------------------------+
| ``osd_show_text`` | Now does the same as |
| | ``osd_show_property_text``. Use the |
| | ``raw`` prefix to disable property |
| | expansion. |
+--------------------------------+----------------------------------------+
| ``show_tracks`` | ``show_text ${track-list}`` |
+--------------------------------+----------------------------------------+
| ``show_chapters`` | ``show_text ${chapter-list}`` |
+--------------------------------+----------------------------------------+
| ``af_switch``, ``af_add``, ... | ``af set|add|...`` |
+--------------------------------+----------------------------------------+
| ``tv_start_scan`` | ``set tv-scan yes`` |
+--------------------------------+----------------------------------------+
| ``tv_set_channel <val>`` | ``set tv-channel <val>`` |
+--------------------------------+----------------------------------------+
| ``tv_step_channel`` | ``cycle tv-channel`` |
+--------------------------------+----------------------------------------+
| ``dvb_set_channel <v1> <v2>`` | ``set dvb-channel <v1>-<v2>`` |
+--------------------------------+----------------------------------------+
| ``dvb_step_channel`` | ``cycle dvb-channel`` |
+--------------------------------+----------------------------------------+
| ``tv_set_freq <val>`` | ``set tv-freq <val>`` |
+--------------------------------+----------------------------------------+
| ``tv_step_freq`` | ``cycle tv-freq`` |
+--------------------------------+----------------------------------------+
| ``tv_set_norm <norm>`` | ``set tv-norm <norm>`` |
+--------------------------------+----------------------------------------+
| ``tv_step_norm`` | ``cycle tv-norm`` |
+--------------------------------+----------------------------------------+
.. note::
Due to lack of hardware and users using the TV/DVB/PVR features, and
due to the need to cleanup the related command code, it's possible
that the new commands are buggy or behave worse. This can be improved
if testers are available. Otherwise, some of the TV code will be
removed at some point.
Slave mode
~~~~~~~~~~
* Slave mode was removed. A proper slave mode application needed tons of code
and hacks to get
it right. The main problem is that slave mode is a bad and incomplete
interface, and to get around that, applications parsed output messages
intended for users. It is hard to know which messages exactly are parsed by
slave mode applications. This makes it virtually impossible to improve
terminal output intended for users without possibly breaking something.
This is absolutely insane, and since initial improvements to **mpv** quickly
made slave mode incompatible to most applications, it was removed as useless
cruft. The client API (see below) is provided instead.
``--identify`` was replaced by the ``TOOLS/mpv_identify.sh`` wrapper script.
* For some time (until including release 0.4.x), mpv supported a
``--slave-broken`` option. The following options are equivalent:
::
--input-file=/dev/stdin --input-terminal=no
Assuming the system supports ``/dev/stdin``.
(The option was readded in 0.5.1 and sets exactly these options.)
* A JSON RPC protocol giving access to the client API is also supported. See
`JSON IPC`_ for more information.
* **mpv** also provides a client API, which can be used to embed the player
by loading it as shared library. (See ``libmpv/client.h`` in the sources.)
It might also be possible to implement a custom slave mode-like protocol
using Lua scripting.
Policy for Removed Features
---------------------------
**mpv** is in active development. If something is in the way of more important
development (such as fixing bugs or implementing new features), we sometimes
remove features. Usually this happens only with old features that either seem
to be useless, or are not used by anyone. Often these are obscure, or
"inherited", or were marked experimental, but never received any particular
praise by any users.
Sometimes, features are replaced by something new. The new code will be either
simpler or more powerful, but doesn't necessarily provide everything the old
feature did.
We can not exclude that we accidentally remove features that are actually
popular. Generally, we do not know how much a specific functionality is used.
If you miss a feature and think it should be re-added, please open an issue
on the mpv bug tracker. Hopefully, a solution can be found. Often, it turns
out that re-adding something is not much of a problem, or that there are
better alternatives.
Why this Fork?
--------------
mplayer2 is practically dead, and mpv started out as a branch containing
new/experimental development. (Some of it was merged right *after* the fork
was made public, seemingly as an acknowledgment that development, or at
least merging, should have been more active.)
MPlayer is focused on not breaking anything, but is stuck with a horrible
codebase resistant to cleanup. (Unless you do what mpv did - merciless and
consequent pruning of bad, old code.) Cleanup and keeping broken things
conflict, so the kind of development mpv strives for can't be done within
MPlayer due to clashing development policies.
Additionally, mplayer2 already had lots of changes over MPlayer, which would
have needed to be backported to the MPlayer codebase. This would not only
have been hard (several years of diverging development), but also would have
been impossible due to the aforementioned MPlayer development policy.
-71
View File
@@ -1,71 +0,0 @@
Release Policy
==============
Every few months, a new release is cut off of the master branch and is assigned
a 0.X.0 version number.
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.
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.
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.
- Create and/or update the ``RELEASE_NOTES`` file.
- Create and/or update the ``VERSION`` file.
- 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
the new version.
Release notes template
----------------------
Here is a template that can be used for writing the ``RELEASE_NOTES`` file.
```markdown
Release 0.X.Y
=============
Changes
-------
- List of changes.
Bug fixes
---------
- List of bug fixes.
New features
------------
- List of new features.
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
the git repository.
```
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
can be used by distributors as changelog for point releases too.
+31 -47
View File
@@ -1,4 +1,6 @@
This file intends to give a big picture overview of how mpv is structured.
NOTE: DOCS/OUTDATED-tech/* may contain more detailed information, but most of it
is possibly or definitely outdated. This file intends to give a big
picture of how mpv is structured.
player/*.c:
Essentially makes up the player applications, including the main() function
@@ -17,12 +19,12 @@ player/*.c:
* check help options etc. (call handle_help_options()), possibly exit
* call play_files() function that works down the playlist:
* run idle loop (idle_loop()), until there are files in the
playlist or an exit command was given (only if --idle it set)
playlist or an exit command was given (slave mode only)
* actually load and play a file in play_current_file():
* run all the dozens of functions to load the file and
initialize playback
* run a small loop that does normal playback, until the file is
done or a command terminates playback
done or a slave command terminates playback
(on each iteration, run_playloop() is called, which is rather
big and complicated - it decodes some audio and video on
each frame, waits for input, etc.)
@@ -31,28 +33,15 @@ player/*.c:
* loop, or exit if no next file or quit is requested
(see enum stop_play_reason)
* call exit_player_with_rc()
* run_playloop():
* calls fill_audio_out_buffers()
This checks whether new audio needs to be decoded, and pushes it
to the AO.
* calls write_video()
Decode new video, and push it to the VO.
* determines whether playback of the current file has ended
* determines when to start playback after seeks
* and calls a whole lot of other stuff
(Really, this function does everything.)
Things worth saying about the playback core:
- most state is in MPContext (core.h), which is not available to the
subsystems
- the currently played tracks are in mpctx->current_tracks, and decoder
state in d_video/d_audio/d_sub
- the currently played tracks are in sh_video and sh_audio
- the timeline stuff is used only with MKV ordered chapters (and some other
minor features: cue, edl)
- most state is in MPContext (mp_core.h), which is not available to the
subsystems
- the other subsystems rarely call back into the frontend, and the frontend
polls them instead (probably a good thing)
- one exceptions are wakeup callbacks, which notify a "higher" component
of a changed situation in a subsystem
I like to call the player/*.c files the "frontend".
@@ -95,7 +84,7 @@ talloc.h & talloc.c:
(See ta/README for details.)
player/command.c:
This contains the implementation for client API commands and properties.
This contains the implementation for slave commands and properties.
Properties are essentially dynamic variables changed by certain commands.
This is basically responsible for all user commands, like initiating
seeking, switching tracks, etc. It calls into other player/*.c files,
@@ -105,10 +94,9 @@ player/core.h:
Data structures and function prototypes for most of player/*.c. They are
usually not accessed by other parts of mpv for the sake of modularization.
player/client.c:
This implements the client API (libmpv/client.h). For the most part, this
just calls into other parts of the player. This also manages a ringbuffer
of events from player to clients.
Note that there are lots of global variables floating around everywhere
else. This is an ongoing transition, and eventually there should be no
global variables anymore.
options/options.h, options/options.c
options.h contains the global option struct MPOpts. The option declarations
@@ -116,7 +104,7 @@ options/options.h, options/options.c
options.c. Most default values for options and MPOpts are in
mp_default_opts at the end of options.c.
MPOpts is unfortunately quite monolithic, and virtually accessed by
MPOpts is unfortunarely quite monolithic, and virtually accessed by
everything.But some components (like video outputs and video filters) have
their own sub-option tables separate from MPOpts.
@@ -124,18 +112,19 @@ options/options.h, options/options.c
parser-mpcmd.c, and uses the option table in options.c.
input/input.c:
This translates keyboard input comming from VOs and other sources (such
as remote control devices like Apple IR or client API commands) to the
This translates keyboard input comming from libvo and other sources (such
as remote control devices like Apple IR or slave mode commands) to the
key bindings listed in the user's (or the builtin) input.conf and turns
them into items of type struct mp_cmd. These commands are queued, and read
by playloop.c. They get pushed with run_command() to command.c.
Note that keyboard input and commands used by the client API are the same.
The client API only uses the command parser though, and has its own queue
of input commands somewhere else.
Note that keyboard input and slave mode input are essentially the same
things. Just looking at input.conf should make this clear. (The other
direction of slave mode communication, mpv to application, consists of
random mp_msg() calls all over the code in all parts of the player.)
common/msg.h:
All terminal output must go through mp_msg().
All terminal output should go through mp_msg().
stream/*:
File input is implemented here. stream.h/.c provides a simple stream based
@@ -194,7 +183,7 @@ video/out/:
vo_opengl can pick a windowing system at runtime, e.g. the same binary can
provide both X11 and Cocoa support on OSX.
VOs can be reconfigured at runtime. A vo_config() call can change the video
VOs can be reconfigured at runtime. A config() call can change the video
resolution and format, without destroying the window.
vo_vdpau and vo_opengl should be taken as reference.
@@ -216,12 +205,9 @@ audio/filter/:
audio/out/:
Audio outputs.
Unlike VOs, AOs can't be reconfigured on a format change. On audio format
changes, the AO will simply be closed and re-opened.
There are wrappers to support for two types of audio APIs: push.c and
pull.c. ao.c calls into one of these. They contain generic code to deal
with the data flow these APIs impose.
Unlike VOs, AOs can't be reconfigured on a format change. Without
--gapless-audio, even playing a new file will close and re-open the audio
device.
Note that mpv synchronizes the video to the audio. That's the reason
why buggy audio drivers can have a bad influence on playback quality.
@@ -229,19 +215,17 @@ audio/out/:
sub/:
Contains subtitle and OSD rendering.
osd.c/.h is actually the OSD code. It queries dec_sub.c to retrieve
sub.c/.h is actually the OSD code. It queries dec_sub.c to retrieve
decoded/rendered subtitles. osd_libass.c is the actual implementation of
the OSD text renderer (which uses libass, and takes care of all the tricky
fontconfig/freetype API usage and text layouting).
The VOs call osd.c to render OSD and subtitle (via e.g. osd_draw()). osd.c
in turn asks dec_sub.c for subtitle overlay bitmaps, which relays the
request to one of the sd_*.c subtitle decoders/renderers.
Subtitle loading is in demux/. The MPlayer subreader.c is mostly gone - parts
of it survive in demux_subreader.c. It's used as last fallback, or to handle
some text subtitle types on Libav. It should go away eventually. Normally,
subtitles are loaded via demux_lavf.c.
Subtitle loading is now in demux/ instead. demux_libass.c wraps loading
.ass subtitles via libass. demux_lavf.c loads most subtitle types via
FFmpeg. demux_subreader.c is the old MPlayer code. It's used as last
fallback, or to handle some text subtitle types on Libav. (It also can
load UTF-16 encoded subtitles without requiring the use of -subcp.)
demux_subreader.c should eventually go away (maybe).
The subtitles are passed to dec_sub.c and the subtitle decoders in sd_*.c
as they are demuxed. All text subtitles are rendered by sd_ass.c. If text
+3 -4
View File
@@ -20,9 +20,8 @@ shortcomings:
part is this pieces are spread apart in the configure and copy pasted for
any single case. That brings us to..
2) --enable-feature has to be overridden by the user and helps them understand that
they have libraries missing and should install them for the feature to be
enabled.
2) --enable-feature has to override the user and help him understand that he
has libraries missing and should install them for the feature to be enabled.
3) Must be customizable, hackable, pleasant to the developer eyes and to work
with in general.
@@ -46,7 +45,7 @@ mpv's custom configure step on top of waf
To some extents mpv has a custom build system written on top of waf. This
document will not go over the standard waf behaviour as that is documented in
the `Waf book <http://docs.waf.googlecode.com/git/book_17/single.html>`_.
the ``Waf book``.
All of the configuration process is handled with a declarative approach. Lists
of dictionaries define the checks, and some custom Python code traverses these
+43 -108
View File
@@ -1,39 +1,19 @@
![http://mpv.io/](https://raw.githubusercontent.com/mpv-player/mpv.io/master/source/images/mpv-logo-128.png)
mpv
===
## mpv
[![Build Status](https://api.travis-ci.org/mpv-player/mpv.png)](https://travis-ci.org/mpv-player/mpv)
--------------
Overview
--------
* [Overview](#overview)
* [Downloads](#downloads)
* [Compilation](#compilation)
* [FFmpeg vs. Libav](#ffmpeg-vs-libav)
* [Release cycle](#release-cycle)
* [Bug reports](#bug-reports)
* [Contributing](#contributing)
* [Relation to MPlayer and mplayer2](#relation-to-mplayer-and-mplayer2)
* [Wiki](https://github.com/mpv-player/mpv/wiki)
* [Man pages](http://mpv.io/manual/master/)
* [Contact](#contact)
* [License](#license)
## Overview
**mpv** is a media player based on MPlayer and mplayer2. It supports a wide
**mpv** is a movie player based on MPlayer and mplayer2. It supports a wide
variety of video file formats, audio and video codecs, and subtitle types.
Releases can be found on the [release list][releases].
## Downloads
For semi-official builds and third-party packages please see
[mpv.io](http://mpv.io/installation/).
## Compilation
If you are wondering what's different from mplayer2 and MPlayer you can read
more about the [changes][changes].
Compilation
-----------
Compiling with full features requires development files for several
external libraries. Below is a list of some important requirements.
@@ -64,25 +44,17 @@ Essential dependencies (incomplete list):
- gcc or clang
- X development headers (xlib, X extensions, libvdpau, libGL, libXv, ...)
- Audio output development headers (libasound/ALSA, pulseaudio)
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavfilter
and either libswresample or libavresample)
At least FFmpeg 2.4.0 or Libav 11 is required.
- zlib
- iconv (normally provided by the system libc)
- 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)
- vdpau and vaapi libraries for hardware decoding on Linux (optional)
- Audio output development headers (libasound, pulseaudio)
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavresample)
At least FFmpeg 1.2.4 or Libav 9.10 is required. (If FFmpeg was compiled
without libavresample, at least FFmpeg 2.0 is required.)
- libjpeg (for screenshots)
- libquvi if you want to play Youtube videos directly
Libass dependencies:
- gcc or clang, yasm on x86 and x86_64
- fribidi, freetype, fontconfig development headers (for libass)
- harfbuzz (optional, required for correct rendering of combining characters,
particularly for correct rendering of non-English text on OSX, and
Arabic/Indic scripts on any platform)
FFmpeg dependencies:
@@ -103,98 +75,61 @@ If you are running Mac OSX and using homebrew we provide [homebrew-mpv][homebrew
to date formula that compiles mpv with sensible dependencies and defaults for
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
FFmpeg vs. Libav
----------------
Generally, mpv should work with the latest release as well as the git version
of both FFmpeg and Libav. But FFmpeg is preferred, and some mpv features work
with FFmpeg only (subtitle formats in particular).
with FFmpeg only. See the [wiki article][ffmpeg_vs_libav] about the issue.
## Release cycle
Release cycle
-------------
Every few months, a new release is cut off of the master branch and is assigned
a 0.X.0 version number.
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.
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.
Every few months, a new release is cut off of the master branch. Currently,
these releases are assigned a version number ``0.X.0``. Only the latest release
is maintained. 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. 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. (The master branch is stable most of the time, except sometimes, when
it's not.)
Releases other than the latest release are unsupported and unmaintained.
See the [release policy document][release-policy] for more information.
## Bug reports
Bug reports
-----------
Please use the [issue tracker][issue-tracker] provided by GitHub to send us bug
reports or feature requests.
## Contributing
Contributing
------------
For small changes you can just send us pull requests through GitHub. For bigger
changes come and talk to us on IRC before you start working on them. It will
make code review easier for both parties later on.
## Relation to MPlayer and mplayer2
Contact
-------
These forms of contact are meant to ask questions about mpv usage, give
feedback on mpv and discuss it's development.
mpv is based on mplayer2, which in turn is based on the original MPlayer
(also called mplayer, mplayer-svn, mplayer1). Many changes have been made, a
large part of which is incompatible or completely changes how the player
behaves. Although there are still many similarities to its ancestors, mpv
should generally be treated as a completely different program.
If possible, please avoid posting bugs here and use the [issue tracker][issue-tracker]
instead.
mpv was forked because we wanted to modernize MPlayer. This includes
removing cruft (including features which stopped making sense 10 years ago),
and of course adding modern features. Such huge and intrusive changes made it
infeasible to work directly with MPlayer, which is mostly focused on
preservation, so a fork had to be made. (Actually, mpv is based on mplayer2,
which already started this process of removing cruft.)
In general, mpv should be considered a completely new program, rather than a
MPlayer drop-in replacement.
If you are wondering what's different from mplayer2 and MPlayer, an incomplete
list of changes is located [here][mplayer-changes].
## Contact
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)
- **User IRC Channel**: `#mpv-player` on `irc.freenode.net`
- **Developer IRC Channel**: `#mpv-player-dev` on `irc.freenode.net`
- **Users IRC Channel**: `#mpv-player` 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.
To contact the `mpv` team in private write to `mpv-team@googlegroups.com`.
[releases]: https://github.com/mpv-player/mpv/releases
[changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/man/en/changes.rst
[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
[GPLv2](https://github.com/mpv-player/mpv/blob/master/LICENSE)
+27 -594
View File
@@ -1,608 +1,41 @@
Release 0.9.0
=============
Changes
-------
Changes that may break users' config files have been annotated with a `(!)`.
- Note: mpv is not compatible with Lua 5.3. Lua 5.1 or 5.2 is required.
- The minimum required libass version is now 0.12.1 or newer.
- The minimum required FFmpeg version is now 2.4.0 (equiv. Libav 11) or newer.
- The internal libmpg123 support was removed. This was already not used by
default in the previous release.
- `(!)` The LIRC support was removed. Configure LIRC remotes as input devices
instead.
- `(!)` The Linux Joystick support was removed.
- `(!)` `vf_screenshot` was removed, as they are now handled at a VO level and
is compatible with all VOs.
- `(!)` `--ass-use-margins` has been renamed to `--sub-use-margins` and applies
only to plain-text (non-ASS) subtitles (enabled by default). The new
`--ass-force-margins` option applies only to ASS subtitles (disabled by
default). To get the old behaviour back, enable both at the same time.
- `(!)` The `--sub-scale-with-window` option now only applies to plain text
(non-ASS) subtitles (enabled by default). The new `--ass-scale-with-window`
option does the same but only with ASS subtitles (disabled by default).
- `(!)` The range for the `param1` for the `gaussian` `vo_opengl` scaler has
been redefined. Instead of being an arbitrary 1-100 range, have a default
value of 1.0, and anything higher is blurrier.
- `(!)` The `seek`, `playlist_next, `playlist_prev`, `loadfile` and `loadlist`
parameters no longer accept numerical parameters where symbolic parameter
names exist.
- `(!)` `vo_opengl` changes:
- `(!)` The `smoothmotion` suboption has been renamed to `interpolation`.
The old name is still supported for now.
- `(!)` The `bilinear_slow` scaler has been renamed to `triangle`.
- `(!)` `scale-down` has been renamed to `dscale` and now has its own set of
config options (e.g. `dscale-radius`).
- `(!)` Scaler radius no longer defaults to `3` but to a preferred value
that may be different for each filter.
- The `scale-radius` option may now go down as low as `0.5`, which is the
value used by the `nearest` filter.
- `spline36` is the new `cscale` default for `opengl-hq`. This might break
setups that use `fbo-format=rgb8`. To work around it, leave `fbo-format`
as its default, or set to something higher than 8, or set `cscale=bilinear`,
the previous default.
- `(!)` `vf_format` no longer converts video to YUYV if there is no parameter.
Video is now passed unchanged unless a format is specifically requested.
- `(!)` The `--colormatrix`, `--colormatrix-input-range`,
`--colormatrix-output-range` and `--colormatrix-primaries` options have been
converted into `vf_format` suboptions. See commit 27715b7 and the manual for
details.
- `vf_mirror`'s implementation was replaced with calling into `libavfilter`'s
`vf_hflip` filter, thus depending on `libavfilter` to function.
- The `device` subption to `ao_wasapi` has been deprecated in favor of
`--audio-device`.
- `--video-rotate` now allows 360 as an argument instead of stopping at 359.
- Several improvements to `af_scaletempo`.
- Options that have multiple options and also include a "yes" option now
default to that if specified with no arguments.
- The default value of `--cache-default` is now 150000 (153.6 MB, ~146 MiB).
- JPEG screenshots now use the same subsampling as the source video. The images
are still RGB regardless of source format though.
- Build system switches to waf. The old build system is still available by
running ``./old-configure``, but it will be removed some time in the future.
- The "run" input command changes in a not backwards compatible way.
- Some input.conf commands were replaced (such as speed_mult).
- Many audio/video filter have changed sub-options in a not backwards
compatible way. (This is a consequence of unifying audio/video filter
option parsing.)
- Most video filters now use libavfilter internally if available.
- Disable key autorepeat for some key binds, which prevents accidentally
triggering a binding multiple times.
- Encoding: install and include encoding profiles by default.
Bug fixes
---------
- mpv no longer saves position on files that can't be resumed (issue #1701).
- (X11) Fix the player thinking the mouse has left the window in some WMs /
embeddings (issue #1672).
- mpv no longer freezes on wayland when the compositor stops asking it to draw
itself (e.g. when minimized) (issue #249).
- `.ac3` files are no longer rejected by `--audio-file-auto` (issue #1759).
- `ao_wasapi` now automatically enables `exclusive` when passthrough is
attempted (issue #1742).
- Attempt to fix flickering on Intel VAAPI drivers with `--hwdec=vaapi` and
`--vo=opengl` (issue #1765).
- `youtube-dl` will no longer download video streams when video playback
is disabled with `--no-video`.
- (Windows) mpv now prevents system sleep when playing a video-only file.
Previously, only files with an opened audio track would prevent sleep.
- Fix a bug that degraded vdpau playback after ~1 hour of runtime.
- Restrict hardware decoding to codecs where it generally makes sense. This
excludes mpeg4 for example, which often causes hardware decoders to decode to
garbage. Use ``--hwdec-codecs`` to enable hardware decoding for more codecs.
New features
------------
- `vo_opengl` features:
- Added `ewa_ginseng`, `ewa_hanning`, `robidoux`, `robidouxsharp`,
`oversample` and `haasnsoft` scalers.
- There are now `ewa_lanczossoft` and `ewa_lanczossharp` aliases to
`ewa_lanczos` that are tuned to be blurrier and sharper, respectively.
- Added `gamma-auto` option that uses ambient light sensors to automatically
adjust the video gamma. See commit c028d78 for details.
- Added `blend-subtitles` option to draw subtitles directly into the video
instead of rendered afterwards. Potentially necessary for correct rendering
with files that use ASS subtitles for typesetting in combination with an
`icc-profile`. There is a default option for drawing after upscaling,
and a `video` option for drawing before upscaling. See details and warning
on the manual.
- There is now a `tscale` option, used to choose the temporal scaler used
in the `interpolation` mode (previously `smoothmotion`).
- There is a new `scale-blur` parameter to adjust the amount of blur that
most of the filters produce. Deviating from the default may introduce
artifacts in EWA filters.
- (Windows) There is now a `dwmflush` option that might help improve
rendering of high-fps video. Disabled by default. See manual for options.
- New Linux-only `vo_drm` video output driver. Uses the direct rendering /
kernel modesetting drivers to draw directly to the framebuffer, but with
no hardware acceleration. See manual for details.
- New `pseudo-gui` builtin profile, automatically used when launched from
`mpv.desktop` by opening `mpv.exe` on windows (`mpv.com` still works as
usual), or by opening the `mpv.app` bundle. The `pseudo-gui` tries to make
the player window behave closer to what a desktop player would do, by not
immediately closing and allowing the user to drag&drop files for playback.
See manual for details.
- mpv can now play directories by automatically playing their contents instead.
Works everywhere but on Windows, due to issues with Windows' C runtime.
- Add support to pitch correct stretched audio with librubberband.
- Add support for the Raspberry Pi 2's hardware decoder when FFmpeg (or Libav)
is built with `--enable-mmal`. See commit 8fff125 for details.
- The `--cache` option now accepts a "yes" option, that always enables a
`--cache-default`-sized cache on all cases a cache can be used, unless
`--cache-default` disables caching.
- `ao_pulse`, `ao_coreaudio` and `ao_wasapi` now support device hotplugging.
- New `--osd-align-x` and `--osd-align-y` options can be used to align the OSD
independently from subtitles.
- New `--osd-bold` and `--sub-text-bold` options can be enabled to bold all
OSD or plain-text subtitle text, respectively.
- Added a default keybind to the `u` key that enables/disables ASS style
overriding. When enabled, is equivalent to `--ass-style-override=force`.
- There is now a `MOUSE_ENTER` keybind, that is called when the mouse cursor
enters the VO from outside.
- The new `--ytdl-params` option can be set to arguments that are always given
to `youtube-dl` invocations. There is no sanity checking, so invalid options
can prevent `mpv` from working with http URLs.
- There's a new `--demuxer-mkv-fix-timestamps` option, enabled by default, that
tries to guess more accurate video timestamps by using FPS information, if
available. See manual for details.
- The new `--window-scale` option can be used to scale the video window by the
specified multiplier, before other options such as `--autofit` are applied.
- `vo_direct3d_shaders` now supports NV12 colorspace without using stretchrect,
but it seems no drivers actually support that.
- (Client API) Added a `rescan_external_files` command, as requested on issue
#1586.
- (Client API) If enabled, initializing the Client API will now also load the
user's `mpv.conf`.
- (Client API) There's a new `mpv_opengl_cb_report_flip()` call for API users
to call to inform mpv of when exactly a frame was displayed.
- (Client API) The `mpv_opengl_cb_render()` function was deprecated in favor
of the new, simpler `mpv_opengl_cb_draw()` function.
- (Client API) There is a new `screenshot_raw` command. See `input.rst` for
details.
- The `--input-file` argument may now also be a file descriptor in the form
"fd://N", where N is the FD number.
This listing is not complete. A complete changelog can be seen by running
`git log v0.8.0..v0.9.0` in the git repository.
Release 0.8.3
=============
Changes
-------
- Documentation fixes and updates.
- (Client API) Clarify `mpv_opengl_cb_render`'s viewport parameter behavior.
Bug fixes
---------
- (X11) Fix crash on `vo_xv:no-colorkey` with the Overlay adapter. (bug #1629)
- (X11) `--stop-screensaver` is now implemented by calling into
`xdg-screensaver`, fixing some compatibility issues that prevented it from
actually stopping screensavers.
- Make the video equalizer work correctly on some VAAPI drivers. (bug #1647)
- Prevent OSD from disappearing when clicking on mozplugger. (bug #1672)
- The new DVB-S2 support code, using S2API, now builds on FreeBSD.
- Fix decoding of seekable matroska from unseekable network stream. (bug #1656)
- (OSX) Fix crashing when closing a VO's window (usually at exit). (bug #1657)
- (OSX) Unhide the mouse cursor when over the Dock or Launchpad. (bug #513)
- (OSX) Fix mouse cursor autohiding when the player is fullscreen.
- `vf_vavpp` (VAAPI postprocessing) now deinterlaces video correctly.
- `smb://` streams now use the stream cache (used to be inefficient).
- (Windows) Do not hide the mouse cursor when it is hovering the window menu.
- Fix 8-channel output on `ao_jack`. (bug #1688)
- Fix `--mf-fps` parameter on JPEG files. (bug #1689)
- Fix anamorphic scaling being ignored if it was very minor.
This listing is not complete. A complete changelog can be seen by running
`git log v0.8.2..v0.8.3` in the git repository.
Release 0.8.2
=============
Bug fixes
---------
- Fix OSD placement accidentally messed up in 0.8.1.
Release 0.8.1
=============
Changes
-------
- DOCS/client-api-changes has been correctly updated for the v0.8.0 release
series.
- Quality and major perfomance improvements to smoothmotion.
- Silence the "[ytdl_hook] WARNING: video doesn't have subtitles" warning.
- Other documentation updates.
Bug fixes
---------
- Attempt to fix OpenGL shader compilation on Intel windows drivers. (bug
#1536)
- Attempt to improve the OpenGL shader's compatibility with GLES2.
- (Windows) Fix noise when seeking while using wasapi:exclusive. (bug #1529)
- Fix the waf-based build system when used with newer versions of waf with
python3.
- Documentation fixes. (includes bug #1608)
New features
------------
- mpv now tries to load '.vtt' subtitles.
This listing is not complete. A complete changelog can be seen by running
`git log v0.8.0..v0.8.1` in the git repository.
Release 0.8.0
=============
Changes
-------
Changes that may break users' config files have been annotated with a `(!)`.
- `(!)` vo_opengl_old has been removed. OpenGL rendering now requires hardware
that can do at least OpenGL 2.1, the oldest version supported by vo_opengl.
- `(!)` vf_pp has been removed. A version of it can still be accessed through
lavfilter (e.g. --vf=lavfi=[pp...]), but it receives no QP information.
Also, vf_dlopen no longer passes QP information to its loaded plugin either
(it's always 0).
- `(!)` vf_softpulldown, vf_swapuv, vf_phase, vf_divtc and vf_ilpack have all
been removed. Ports or alternative versions of these filters are available
through libavfilter (vf_lavfi).
- vf_pullup and vf_noise now are simply wrappers to their libavfilter
equivalents. Both are only currently available on FFmpeg (not Libav).
- `(!)` ao_portaudio has been removed. There is good support for the native
audio drivers of all major desktop platforms, as well as ao_sdl and
ao_openal as fallbacks.
- `(!)` vo_opengl's `lscale` suboption has been renamed to `scale`; `lradius`
is now `scale-radius`, `lparam1` and `lparam2` are now respectively
`scale-param1` and `scale-param2`; `lscale-down` is now `scale-down`.
The `cscale` suboption remains as is.
- `(!)` Several of the `vo_opengl` radius-preset aliases supported by `scale`
have been removed; use `scale-radius` to set if needed. For example, use
`--vo=opengl:scale=lanczos:scale-radius=2` instead of `scale=lanczos2`.
The default radius is recommended for most filters.
- `(!)` vo_opengl no longer supports the `stereo` suboption. The anaglyph
effect can be reproduced with the stereo3d filter. The quadbuffer support,
which requires expensive specialized hardware to begin with, is removed.
- `(!)` The `approx-gamma` suboption to vo_opengl has been removed. The
BT.1886 specification says that it's actually how it's supposed to be done
so it is now the default when `srgb` or `icc-profile` are enabled. This does
not include BT.1886's gamma drop.
- `(!)` The `no-scale-sep` and `indirect` suboptions to vo_opengl have been
removed. These are now autodetected and enabled whenever they would have
benefit.
- `(!)` The `--lua` and `--lua-opts` parameters / options are now called
`--script` and `--script-opts`, respectively. The `lua` subdir of the mpv
config dir is also now expected to be called `scripts` instead.
- `(!)` The `--fixed-vo` option has been removed. It has been the default for
a long time anyway, and disabling fixed-vo is not useful.
- vo_opengl_hq has been updated to take into account new features.
`fancy-downscaling` and `sigmoid-upscaling` are enabled,
"mitchell" is now the default for `scale-down`.
- The `sub-visibility` OSD message is now clearer about whether subtitles
are hidden or just not available / selected.
- The device IDs given to `--audio-device` for use with ao_coreaudio now use
UIDs, so they don't change when devices are added/removed or after reboots.
- `--msg-level` now also accepts ',' as separator.
- (Client API) The client API now refuses to initialize if the LC_NUMERIC
locale is not "C".
- (Client API) The native type of the `msg-level` parameter is now a key-value
list. Setting or reading it as a string still works.
- (Slave API) The `get_property` command is now deprecated.
- Documentation updates.
- PDF documentation is now disabled by default due to rst2pdf being fickle,
causing weird build errors.
- Print desync messages with negative A/V sync as well. While rare, it could
happen with some uses of `--autosync`.
Bug fixes
---------
- (Windows) Avoid resizing the video window when player is minimized, might
address bug #1547.
- (NetBSD) Fix build with v4l2.
- (Linux) Attempt to address conflicts with the pulseaudio mixer. (bug #1578)
- Multiple cdda:// fixes. (bugs #1555, #1560)
- VP9 timestamps no longer cause "missing PTS" warnings with new enough FFmpeg
builds.
- Fix a crash when using H.264 hardware decoding on new enough libavcodecs.
(bug #1587)
New features
------------
- vo_opengl now supports frame blending to eliminate stuttering when the video
framerate does not nicely match the display framerate through the
`smoothmotion` suboption. This is not meant to artificially increase the
video's FPS, so there is no "soap opera effect" or difficulties with some
video types (e.g. anime).
- vo_opengl now supports sigmoidal upscaling (e.g. for fullscreen), which
reduces ringing induced by upscaling, enabled through the
`sigmoid-upscaling` suboption.
- vo_opengl now supports ewa_lanczos (Jinc) scaling, which provides higher
quality with less aliasing. It supports an experimental `scale-antiringing`
parameter, which tries to further reduce video ringing.
- vo_opengl now has a `linear-scaling` suboption, that makes the scalers work
in linear light. Implied by the `srgb`, `icc-profile` or the new
`sigmoid-upscaling` suboption.
- vo_opengl has improved downscaling for higher downscale ratios when
`fancy-downscaling` is enabled.
- Add `--keep-open=always` to make `--keep-open` apply to all files instead of
only the last.
- mpv now filters the tags that are printed on the console to try to hide
useless metadata. The filter works as a whitelist, and can be configured
with the `--display-tags` option.
- Add a `--sub-scale-by-window` option that, when set to 'no', prevents
subtitles from changing their pixel size when the window changes sizes.
- vo_opengl now technically has GLES 2 and 3 support (but not GLES 1). GLES 3
support is only tested on Mesa's software emulation. GLES 2 has been tested
on nvidia drivers. Both GLES modes are feature deficient and inefficient due
to GLES limitations, so they should not be preferred over the standard
OpenGL mode.
- (X11) vo_opengl now supports the `icc-profile-auto` option on X11 hosts.
- The 'A' key now by default cycles through a list of preset aspect ratios.
Meant to be used to work around broken files.
- There is now a "force" mode for `--loop`. Works like "inf", but tries to
open files/streams even if there was an error on the previous attempt.
- There is now a `--log-file` option to write mpv's log messages to a specifed
file.
- There is now a `--audio-file-auto` option to automatically load an external
audio file with certain constraints. Will only load external audio if the
playing file has a video stream. Set to "exact" by default. (bug #967)
- There is now a `--network-timeout` option to specify a timeout in seconds
for network access. If 0 (default), uses the libavformat default. If a
protocol that doesn't support timeouts is used, this option is ignored.
- (X11) The XF86 special keys are now all mappable in `input.conf`. All keys
documented in `XF86keysym.h` are available, but only as their numeric codes.
- (Linux) The DVB implementation now supports DVB-S2 through S2API.
- (Linux) The VDR format for `channels.conf` is now supported and preferred.
See http://linuxtv.org/vdrwiki/index.php/Syntax_of_channels.conf for the
syntax. Tuning to DVB-S2 channels requires the VDR-format `channels.conf`.
- (Linux) There is now a `--dvbin-full-transponder` option for handling
special broadcast cases where PIDs switch, or just to work around incomplete
PID data.
- (Client API) There is now an opengl_cb VO, which receives the OpenGL context
from the libmpv client. This allows a client to render libmpv video directly
to a provided OpenGL context without having to use --wid embedding.
- (Client API) The aforementioned --wid parameter can now be set at any time,
but has no effect if a file is already loaded.
- (Client API) The list of DVD titles can now be queried.
- (Client API) There is now a `filtered-metadata` property, containing only
the tags allowed by `--display-tags`.
- (Client API) There is now support for XEmbed `--wid` targets, such as a
`GtkSocket`'s `gtk_socket_get_id()`.
- (Client API) There is now a `file-format` property with a symbolic name
for the file format. In some cases this might be a comma separated list
of various different extensions due to libavformat idiosyncrasies.
- (Client API) There is now a `mouse` command for generating mouse events
over the video window.
- (Client API) There is now a `partially-seekable` property that indicates
whether a file is only considered `seekable` because of the stream cache,
but would not be seekable otherwise (e.g. realtime stream, or HTTP with
no resume support). Small relative seeks may be fine, but larger seeks
will likely fail.
- (Client API) There is now an MPV_EVENT_QUEUE_OVERFLOW event that is posted
whenever events have to be dropped because the queue is full. No further
events are posted until the MPV_EVENT_QUEUE_OVERFLOW is consumed to avoid
duplicated posting.
- (Client API) There is now a helper `mpv_wait_async_requests()` function
that blocks until all known async requests have completed. (bug #1542)
- (Client API) There is now a `detected-hwdec` property that returns the
detected hardware decoder when one is successfully opened. This probably
only returns a valid value after playback has started.
- (Client API) There are now `audio_add`, `audio_remove` and `audio_reload`
counterparts to the equivalent `sub_` commands for handling external audio
files.
This listing is not complete. A complete changelog can be seen by running
`git log v0.7.0..v0.8.0` in the git repository.
Release 0.7.3
=============
Changes
-------
- Several documentation updates and typo fixes.
- Don't show "0%" position when the stream is infinite / has unknown length.
- Fixes the config file loading order so that lower priority `mpv.conf` files
don't override higher priority `config` files.
- (OSX) Remove coreaudio_exclusive from the "auto" codec list.
- Failing to create a GL3 context is now a warning instead of error, to reduce
user confusion.
- The subtitle decoder now gets reset when cycling subtitles. This makes the
currently shown subtitle event disappear even if cycling back to the current
subtitle track.
- `--shuffle` and `--merge-files` now affects the contents of playlist files,
instead of just the list of files given as arguments to mpv.
- `./waf install` avoids installing a few additional data/config files if only
libmpv was built.
- Improved channel mapping when the file's channel map doesn't match the AO's
available channel maps.
- (OSX) VDA now gracefully refuses to run on non-OpenGL3-capable systems instead
of trying and failing to build its shaders.
- Add workaround for vf_vapoursynth filters that expect an FPS.
- The default value for `--screenshot-template` now shows up in
`--list-options`.
- `ao_pulse`'s `latency-hacks` suboption is now off by default, as it causes
issues with newer pulseaudio releases. If A/V Sync issues happen, either
add the `latency-hacks=on` pulse suboption in mpv.conf, or update the
pulseaudio daemon (bug #1430).
- (Linux) `ao_alsa` now deals better with audio device disconnection.
- Client API: timestamp properties that have no value return "no" instead of
magic number.
Bug fixes
---------
- (Windows, OSX) Many `ao_wasapi` and `ao_coreaudio` fixes.
- (OSX) Make the window title update correctly on OS X Yosemite.
- Fixes for handling mono audio on various AOs.
- (Linux) Fixes resuming from suspend on ao_alsa.
- Fixes for playlist file parsing.
- Overly long options in the --list-options output now break the column layout
instead of getting truncated; fixes shell completion scripts.
- Fix rendering resolution of certain DVB subtitles (bug #1425).
- Fix EDL or --merge-files breaking timestamps with .avi files.
- Workaround for libavcodec bug with the VP9 codec parser (bug #1448),
fixes possible crash.
- Improve robustness of the matroska parser with broken files (bugs #1457,
#1461).
- Improve 10bit video compatibility with older GPUs (specially Intel) (bug
#1383).
- Fixes flashing the VO window when playing a list of files that includes
non-media files (bug #1459).
- Workaround for window embedding in OpenBox (bug #1235)
- Fixes for several crashes and lockups (bugs #838, #1389, #1408, #1463, #1473,
#1474).
- Fixes for the zsh completion script (bugs #997)
New features
------------
- mpv now prints the contents of its config.h when running in verbose mode, to
aid with debugging.
- The `include=` option now accepts `~` to refer to the HOME dir (bug #1406).
- `af_volume` now prints ReplayGain values in verbose mode.
- m3u playlists that don't have the `#EXTM3U` header are now accepted if they
"look like" ASCII or UTF-8 text and have the .m3u extension.
- Chapter marks in the seek bar now update when switching files.
- Supports embedded cover art in MKV files (bug #1374).
- (Windows) Video window can now be resized even with --no-border.
- (Windows) Client API: the "run" command now works on Windows too.
- (Linux) vo_wayland now supports key modifiers (Meta, Alt, Control, Shift)
- Client API: "display-names" property is now observable.
This listing is not complete. A complete changelog can be seen by running
`git log v0.7.2..v0.7.3` in the git repository.
Release 0.7.2
=============
Changes
-------
- Give precedence to the DVD menu navigation keyboard bindings so that user
defined LEFT/RIGHT/... bindings don't break DVD menu navigation.
- Try to fallback to the "default" device if the selected device is busy in the
alsa AO.
- Don't create Dock icon for audio only files on OS X.
- Save screenshots to desktop when using the app bundle on OS X.
- Restore ab-loop settings with playback resume.
- Bump required youtube-dl version to 2014.11.26 and enable the ytdl_hook Lua
script by default (now playing videos from YouTube and the like will work
out of the box without any configuration change needed).
Bug fixes
---------
- Don't signal an error if --stream-dump is used.
- Fix removing key bindings from Lua scripts.
- Reject channel descriptions with too many channels in the coreaudio AO.
- Don't async redraw when waiting for VO redraw on OS X (this fixes the very
annoying glitch where the black bars disappear for a single frame when going
fullscreen).
- Fix mono playback with the also AO.
- Don't crash if framebuffers are not available in the opengl VO.
New features
------------
- Try to handle multi-arc videos in the ytdl_hook Lua script.
- Add window-scale property, which allows changing the window size via mpv key
bindings.
- Add revert_seek command, which is meant to undo accidental seeks.
- Hardware decoding (vdpau, vda, vaapi) can now be used with vo_opengl.
- Pulseaudio: set pulse stream name to mpv window title (like MPlayer).
- Support showing 2 subtitles at a time (``--secondary-sid``).
- Re-add some basic ``dvdnav://`` support. This doesn't handle navigation
highlights correctly, but navigation should mostly work. (Note that
``dvdnav://`` by default starts the longest title, instead of the DVD menu.
The menu is available with ``dvdnav://menu``.)
- Win32: you can drop files on the mpv window.
This listing is not complete. There are many more bug fixes and changes. The
complete change log can be viewed by running ``git log 47ec404..c7d6b21`` in
the git repository.
Release 0.7.1
=============
Changes
-------
- Don't show the volume neutral marker on the OSD if softvol is disabled.
- Don't select a subtitle track when executing the sub_add input command in
"auto" mode.
Bug fixes
---------
- Fix busy loop when seeking while paused (this fixes a problem with pulseaudio
that caused mpv and the pulseaudio daemon to use 100% CPU).
- Fix Lua function utils.subprocess() in Windows versions older than Vista.
- Avoid creating a window bigger than the screen on Windows.
- Don't ignore the last line in m3u playlists.
- Don't crash if a codec could not be opened.
- Dynamically allocate audio channel map entries (this should fix a crash in
the alsa and coreaudio AOs with audio devices that support more than 20
channel maps).
- Ignore the "srgb" option in the opengl VO if hardware decoding is enabled.
- Linearize non-RGB sRGB files correctly (eg. JPEG).
- Fix opening reference URLs (.file/id=) on OS X.
This listing is not complete. There are many more bug fixes and changes. The
complete change log can be viewed by running ``git log 8d8b36d..6583ad6`` in
the git repository.
Release 0.7.0
=============
Changes
-------
- Buffer partial log messages in the client API (the client API will now only
pass full log messages to clients).
- Remove ncurses/terminfo/termcap support (it was disabled by default and
replaced by new code since v0.6.0).
- Enable cdda:// support by default again (it was disabled since v0.6.0).
- Cascade-load input.conf (if there are several input.confs in the set of valid
config paths, load them all).
- Draw the OSD twice in 3D mode (this fixes subtitles display in 3D mode).
- Make wasapi the default AO on Windows again since many of its problems have
been solved.
- Use "site-functions" subdir to install the zsh completion script instead of
the Debian-specific "vendor-completions" (also provide the --zshdir waf
configure option for changing this value).
- Improve synchronization between the Cocoa GUI and the player (this fixes some
long standing deadlock issues on Mac OS X).
- Remove --fs-missioncontrol option (only relevant to Mac OS X).
New features
------------
- Enable pitch correction by default when playing at higher speeds (this can be
controlled with the --audio-pitch-correction option).
- Open stream and demuxer asynchronously (this should avoid having the player
get blocked on network streams).
- Add cache-buffering-state property for querying the cache fill status until
the player unpauses.
- Add support for listing and selecting the audio device (note that it is not
implemented for all AOs, see the --audio-device option for more information).
- Add support for a JSON-based IPC mechanism (note that this is not currently
supported on Windows, see the JSON IPC section in the manpage for more
information).
- Add Lua utility function for starting processes (see utils.subprocess() in the
manpage).
- Add Lua utility function for parsing JSON (see utils.parse_json() in the
manpage).
- Add field-dominance property (see --field-dominance option).
- Add video-rotate property (see --video-rotate option).
- Add playback-abort property for querying whether playback is stopped or is to
be stopped.
- Add cursor-autohide property (see --cursor-autohide option).
- Add vo-configured property for querying whether a window is created.
- Add support for dxva2 hardware acceleration on Windows.
- Drop libquvi support (this has been replaced by a built-in Lua script that
invokes the youtube-dl tool, which needs to be installed, see the --ytdl
option).
- Add support for loading chapters from an external file (see the
--chapters-file option).
- Add window-minimized property for querying whether the window is minimized
(works for X11 only).
- Make it possible to configure the OSC seekbar style (see the "seekbarstyle"
OSC option).
- Add support for libmpv on Mac OS X (it used to be broken, now it's fully
functional and also provides support for embedding the mpv window inside a
Cocoa/Qt application).
- Try to use the audio channel map reported by ALSA in the alsa AO.
- Add option to disable text OSD rendering completely (useful for working around
certain fontconfig issues, see the --use-text-osd option).
This listing is not complete. There are many more bug fixes and changes. The
complete change log can be viewed by running ``git log 7759c18..9479daa`` in
complete change log can be viewed by running ``git log f572d2..f06a87`` in
the git repository.
-94
View File
@@ -1,94 +0,0 @@
#!/usr/bin/env python
import re
import os
import sys
import shutil
import subprocess
from functools import partial
sys_re = re.compile("^/System")
usr_re = re.compile("^/usr/lib/")
exe_re = re.compile("@executable_path")
def is_user_lib(objfile, libname):
return not sys_re.match(libname) and \
not usr_re.match(libname) and \
not exe_re.match(libname) and \
not "libobjc." in libname and \
not "libSystem." in libname and \
not "libc." in libname and \
not "libgcc." in libname and \
not os.path.basename(libname) == 'Python' and \
not os.path.basename(objfile) in libname
def otool(objfile):
command = "otool -L %s | grep -e '\t' | awk '{ print $1 }'" % objfile
output = subprocess.check_output(command, shell = True)
return filter(partial(is_user_lib, objfile), output.split())
def install_name_tool_change(old, new, objfile):
subprocess.call(["install_name_tool", "-change", old, new, objfile])
def install_name_tool_id(name, objfile):
subprocess.call(["install_name_tool", "-id", name, objfile])
def libraries(objfile, result = dict()):
libs_list = otool(objfile)
result[objfile] = set(libs_list)
for lib in libs_list:
if lib not in result:
libraries(lib, result)
return result
def leafs(libs_dict, processed = []):
result = []
processed = set(processed)
for objfile, libs in libs_dict.items():
if libs <= processed:
result.append(objfile)
return result
def lib_path(binary):
return os.path.join(os.path.dirname(binary), 'lib')
def lib_name(lib):
return os.path.join("@executable_path", "lib", os.path.basename(lib))
def process_libraries(libs_dict, binary, processed = []):
ls = leafs(libs_dict, processed)
diff = set(ls) - set(processed)
if diff == set([binary]):
return
for src in diff:
name = lib_name(src)
dst = os.path.join(lib_path(binary), os.path.basename(src))
shutil.copy(src, dst)
os.chmod(dst, 0o755)
install_name_tool_id(name, dst)
if src in libs_dict[binary]:
install_name_tool_change(src, name, binary)
for p in processed:
if p in libs_dict[src]:
install_name_tool_change(p, lib_name(p), dst)
process_libraries(libs_dict, binary, ls)
def main():
binary = os.path.abspath(sys.argv[1])
if not os.path.exists(lib_path(binary)):
os.makedirs(lib_path(binary))
libs = libraries(binary)
print(libs)
process_libraries(libs, binary)
if __name__ == "__main__":
main()
+2 -2
View File
@@ -5,8 +5,8 @@
conv() {
echo
identify -format "icon: %w %h" "$1"
convert "$1" -depth 8 rgba:-
identify -format "icon: %w %h" $1
convert $1 -depth 8 rgba:-
}
(echo "# File generated by gen-x11-icon.sh" ;
-158
View File
@@ -1,158 +0,0 @@
#!/bin/sh
: "${MPV:=mpv}"
: "${ILDETECT_MPV:=$MPV}"
: "${ILDETECT_MPVFLAGS:=--start=35% --length=35}"
: "${ILDETECT_DRY_RUN:=}"
: "${ILDETECT_QUIET:=}"
: "${ILDETECT_RUN_INTERLACED_ONLY:=}"
: "${ILDETECT_FORCE_RUN:=}"
# This script uses ffmpeg's "idet" filter for interlace detection. In the
# long run this should replace ildetect.sh+ildetect.so.
# exit status:
# 0 progressive
# 1 telecine
# 2 interlaced
# 8 unknown
# 16 detect fail
# 17+ mpv's status | 16
testfun()
{
$ILDETECT_MPV "$@" \
--vf-add=lavfi="[idet]" --msg-level ffmpeg=v \
--o= --vo=null --no-audio --untimed \
$ILDETECT_MPVFLAGS \
| { if [ -n "$ILDETECT_QUIET" ]; then cat; else tee /dev/stderr; fi } \
| grep "Parsed_idet_0: Multi frame detection: "
}
judge()
{
tff=0
bff=0
progressive=0
undetermined=0
while read -r _ _ _ _ _ _ tff1 _ bff1 _ progressive1 _ undetermined1 _; do
case "$tff1$bff1$progressive1$undetermined1" in
*[!0-9]*)
printf >&2 'ERROR: Unrecognized idet output: %s\n' "$out"
exit 16
;;
esac
tff=$((tff + tff1))
bff=$((bff + bff1))
progressive=$((progressive + progressive1))
undetermined=$((undetermined + undetermined1))
done <<EOF
$(testfun "$@")
EOF
interlaced=$((bff + tff))
determined=$((interlaced + progressive))
if [ "$undetermined" -gt "$determined" ] || [ "$determined" -lt 250 ]; then
echo >&2 "ERROR: Less than 50% or 250 frames are determined."
[ -n "$ILDETECT_FORCE_RUN" ] || exit 8
echo >&2 "Assuming interlacing."
if [ "$tff" -gt $((bff * 10)) ]; then
verdict="interlaced-tff"
elif [ "$bff" -gt $((tff * 10)) ]; then
verdict="interlaced-bff"
else
verdict="interlaced"
fi
elif [ $((interlaced * 20)) -gt "$progressive" ]; then
# At least 5% of the frames are interlaced!
if [ "$tff" -gt $((bff * 10)) ]; then
verdict="interlaced-tff"
elif [ "$bff" -gt $((tff * 10)) ]; then
verdict="interlaced-bff"
else
echo >&2 "ERROR: Content is interlaced, but can't determine field order."
[ -n "$ILDETECT_FORCE_RUN" ] || exit 8
echo >&2 "Assuming interlacing with default field order."
verdict="interlaced"
fi
else
# Likely progressive
verdict="progressive"
fi
printf '%s\n' "$verdict"
}
judge "$@" --vf-clr
case "$verdict" in
progressive)
[ -n "$ILDETECT_DRY_RUN" ] || \
[ -n "$ILDETECT_RUN_INTERLACED_ONLY" ] || \
$ILDETECT_MPV "$@"
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 0
;;
interlaced-tff)
judge "$@" --vf-clr --vf-pre=pullup --field-dominance=top
case "$verdict" in
progressive)
[ -n "$ILDETECT_DRY_RUN" ] || \
$ILDETECT_MPV "$@" --vf-pre=pullup --field-dominance=top
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 1
;;
*)
[ -n "$ILDETECT_DRY_RUN" ] || \
$ILDETECT_MPV "$@" --vf-pre=yadif --field-dominance=top
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 2
;;
esac
;;
interlaced-bff)
judge "$@" --vf-clr --vf-pre=pullup --field-dominance=bottom
case "$verdict" in
progressive)
[ -n "$ILDETECT_DRY_RUN" ] || \
$ILDETECT_MPV "$@" --vf-pre=pullup --field-dominance=bottom
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 1
;;
*)
[ -n "$ILDETECT_DRY_RUN" ] || \
$ILDETECT_MPV "$@" --vf-pre=yadif --field-dominance=bottom
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 2
;;
esac
;;
interlaced)
judge "$@" --vf-clr --vf-pre=pullup
case "$verdict" in
progressive)
[ -n "$ILDETECT_DRY_RUN" ] || \
$ILDETECT_MPV "$@" --vf-pre=pullup
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 1
;;
*)
[ -n "$ILDETECT_DRY_RUN" ] || \
$ILDETECT_MPV "$@" --vf-pre=yadif
r=$?
[ $r -eq 0 ] || exit $((r | 16))
exit 2
;;
esac
;;
*)
echo >&2 "ERROR: Internal error."
exit 16
;;
esac
-6
View File
@@ -232,7 +232,6 @@ sub define_matroska {
elem('Block', 'a1', 'binary'),
elem('BlockDuration', '9b', 'uint'),
elem('ReferenceBlock*', 'fb', 'sint'),
elem('DiscardPadding', '75A2', 'sint'),
}),
elem('SimpleBlock*', 'a3', 'binary'),
}),
@@ -257,8 +256,6 @@ sub define_matroska {
elem('CodecPrivate', '63a2', 'binary'),
elem('CodecName', '258688', 'str'),
elem('CodecDecodeAll', 'aa', 'uint'),
elem('CodecDelay', '56AA', 'uint'),
elem('SeekPreRoll', '56BB', 'uint'),
elem('Video', 'e0', {
elem('FlagInterlaced', '9a', 'uint'),
elem('PixelWidth', 'b0', 'uint'),
@@ -268,7 +265,6 @@ sub define_matroska {
elem('DisplayUnit', '54b2', 'uint'),
elem('FrameRate', '2383e3', 'float'),
elem('ColourSpace', '2eb524', 'binary'),
elem('StereoMode', '53b8', 'uint'),
}),
elem('Audio', 'e1', {
elem('SamplingFrequency', 'b5', 'float'),
@@ -296,8 +292,6 @@ sub define_matroska {
elem('CueTrackPositions*', 'b7', {
elem('CueTrack', 'f7', 'uint'),
elem('CueClusterPosition', 'f1', 'uint'),
elem('CueRelativePosition','f0', 'uint'),
elem('CueDuration', 'b2', 'uint'),
}),
}),
}),
-14
View File
@@ -1,14 +0,0 @@
mpv lua scripts
===============
The lua scripts in this folder can be loaded on a one-time basis by
adding the option
--script=/path/to/script.lua
to mpv's command line.
Where appropriate, they may also be placed in ~/.config/mpv/scripts/ from
where they will be automatically loaded when mpv starts.
Some of these are just for testing mpv internals.
-13
View File
@@ -1,13 +0,0 @@
local utils = require("mp.utils")
mp.observe_property("audio-device-list", "native", function(name, val)
print("Audio device list changed:")
for index, e in ipairs(val) do
print(" - '" .. e.name .. "' (" .. e.description .. ")")
end
end)
mp.observe_property("audio-out-detected-device", "native", function(name, val)
print("Detected audio device changed:")
print(" - '" .. val)
end)
-113
View File
@@ -1,113 +0,0 @@
-- This script uses the lavfi cropdetect filter to automatically
-- insert a crop filter with appropriate parameters for the currently
-- playing video.
--
-- It registers the key-binding "C" (shift+c), which when pressed,
-- inserts the filter vf=lavfi=cropdetect. After 1 second, it then
-- inserts the filter vf=crop=w:h:x:y, where w,h,x,y are determined
-- from the vf-metadata gathered by cropdetect. The cropdetect filter
-- is removed immediately after the crop filter is inserted as it is
-- no longer needed.
--
-- If the "C" key is pressed again, the crop filter is removed
-- restoring playback to its original state.
--
-- Since the crop parameters are determined from the 1 second of video
-- between inserting the cropdetect and crop filters, the "C" key
-- should be pressed at a position in the video where the crop region
-- is unambiguous (i.e., not a black frame, black background title
-- card, or dark scene).
--
-- The default delay between insertion of the cropdetect and
-- crop filters may be overridden by adding
--
-- --script-opts=autocrop.detect_seconds=<number of seconds>
--
-- to mpv's arguments. This may be desirable to allow cropdetect more
-- time to collect data.
require "mp.msg"
script_name = mp.get_script_name()
cropdetect_label = string.format("%s-cropdetect", script_name)
crop_label = string.format("%s-crop", script_name)
-- number of seconds to gather cropdetect data
detect_seconds = tonumber(mp.get_opt(string.format("%s.detect_seconds", script_name)))
if not detect_seconds then
detect_seconds = 1
end
function del_filter_if_present(label)
-- necessary because mp.command('vf del @label:filter') raises an
-- error if the filter doesn't exist
local vfs = mp.get_property_native("vf")
for i,vf in pairs(vfs) do
if vf["label"] == label then
table.remove(vfs, i)
mp.set_property_native("vf", vfs)
return true
end
end
return false
end
function autocrop_start()
-- exit if cropdetection is already in progress
if timer then
mp.msg.warn("already cropdetecting!")
return
end
-- if there's a crop filter, remove it and exit
if del_filter_if_present(crop_label) then
return
end
-- insert the cropdetect filter
ret=mp.command(
string.format(
'vf add @%s:lavfi=graph="cropdetect=limit=24:round=2:reset=0"',
cropdetect_label
)
)
-- wait to gather data
timer=mp.add_timeout(detect_seconds, do_crop)
end
function do_crop()
-- get the metadata
local cropdetect_metadata = mp.get_property_native(
string.format("vf-metadata/%s", cropdetect_label)
)
-- use it to crop if its valid
if cropdetect_metadata then
if cropdetect_metadata["lavfi.cropdetect.w"]
and cropdetect_metadata["lavfi.cropdetect.h"]
and cropdetect_metadata["lavfi.cropdetect.x"]
and cropdetect_metadata["lavfi.cropdetect.y"]
then
mp.command(string.format("vf add @%s:crop=%s:%s:%s:%s",
crop_label,
cropdetect_metadata["lavfi.cropdetect.w"],
cropdetect_metadata["lavfi.cropdetect.h"],
cropdetect_metadata["lavfi.cropdetect.x"],
cropdetect_metadata["lavfi.cropdetect.y"]))
else
mp.msg.error(
"Got empty crop data. You might need to increase detect_seconds."
)
end
else
mp.msg.error(
"No crop data. Was the cropdetect filter successfully inserted?"
)
mp.msg.error(
"Does your version of ffmpeg/libav support AVFrame metadata?"
)
end
-- remove the cropdetect filter
del_filter_if_present(cropdetect_label)
timer=nil
end
mp.add_key_binding("C", "auto_crop", autocrop_start)
-164
View File
@@ -1,164 +0,0 @@
-- This script uses the lavfi idet filter to automatically insert the
-- 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.
--
-- 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.
--
-- The default detection time may be overridden by adding
--
-- --script-opts=autodeint.detect_seconds=<number of seconds>
--
-- to mpv's arguments. This may be desirable to allow idet more
-- time to collect data.
--
-- To see counts of the various types of frames for each detection phase,
-- the verbosity can be increased with
--
-- --msg-level autodeint=v
--
-- This script requires a recent version of ffmpeg for which the idet
-- filter adds the required metadata.
require "mp.msg"
script_name = mp.get_script_name()
detect_label = string.format("%s-detect", script_name)
pullup_label = string.format("%s", script_name)
-- number of seconds to gather cropdetect data
detect_seconds = tonumber(mp.get_opt(string.format("%s.detect_seconds", script_name)))
if not detect_seconds then
detect_seconds = 4
end
function del_filter_if_present(label)
-- necessary because mp.command('vf del @label:filter') raises an
-- error if the filter doesn't exist
local vfs = mp.get_property_native("vf")
for i,vf in pairs(vfs) do
if vf["label"] == label then
table.remove(vfs, i)
mp.set_property_native("vf", vfs)
return true
end
end
return false
end
function start_detect()
-- exit if detection is already in progress
if timer then
mp.msg.warn("already detecting!")
return
end
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)
if not mp.command(cmd) then
mp.msg.error("failed to insert detection filter")
return
end
-- wait to gather data
timer = mp.add_timeout(detect_seconds, judge_field_dominance)
end
function stop_detect()
del_filter_if_present(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()
-- get the metadata
local result = mp.get_property_native(string.format("vf-metadata/%s", detect_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"])
num_undetermined = tonumber(result["lavfi.idet.multiple.undetermined"])
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)
if num_determined < num_undetermined then
mp.msg.warn("majority undetermined frames")
end
if num_progressive > 20*num_interlaced then
return progressive
elseif num_tff > 10*num_bff then
return interlaced_tff
elseif num_bff > 10*num_tff then
return interlaced_bff
else
return interlaced
end
end
function judge_field_dominance()
verdict = judge()
if verdict == progressive then
stop_detect()
mp.msg.info("progressive: doing nothing")
return
elseif verdict == interlaced_tff then
mp.set_property("field-dominance", "top")
elseif verdict == interlaced_bff then
mp.set_property("field-dominance", "bottom")
elseif verdict == interlaced then
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()
if verdict == progressive then
mp.msg.info(string.format("telecinied with %s field dominance: using pullup", mp.get_property("field-dominance")))
stop_detect()
else
mp.msg.info(string.format("interlaced with %s field dominance: setting deinterlace property", mp.get_property("field-dominance")))
del_filter_if_present(pullup_label)
mp.set_property("deinterlace","yes")
stop_detect()
end
return
end
mp.add_key_binding("ctrl+d", script_name, start_detect)
-117
View File
@@ -1,117 +0,0 @@
-- This script automatically loads playlist entries before and after the
-- the currently played file. It does so by scanning the directory a file is
-- located in when starting playback. It sorts the directory entries
-- 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
function Set (t)
local set = {}
for _, v in pairs(t) do set[v] = true end
return set
end
EXTENSIONS = Set {
'mkv', 'avi', 'mp4', 'ogv', 'webm', 'rmvb', 'flv', 'wmv', 'mpeg', 'mpg', 'm4v', '3gp',
'mp3', 'wav', 'ogv', 'flac', 'm4a', 'wma',
}
mputils = require 'mp.utils'
function add_files_at(index, files)
index = index - 1
local oldcount = mp.get_property_number("playlist-count", 1)
for i = 1, #files do
mp.commandv("loadfile", files[i], "append")
mp.commandv("playlist_move", oldcount + i - 1, index + i - 1)
end
end
function get_extension(path)
return string.match(path, "%.([^%.]+)$" )
end
table.filter = function(t, iter)
for i = #t, 1, -1 do
if not iter(t[i]) then
table.remove(t, i)
end
end
end
function find_and_add_entries()
local path = mp.get_property("path", "")
local dir, filename = mputils.split_path(path)
if #dir == 0 then
return
end
local files = mputils.readdir(dir, "files")
if files == nil then
return
end
table.filter(files, function (v, k)
local ext = get_extension(v)
if ext == nil then
return false
end
return EXTENSIONS[string.lower(ext)]
end)
table.sort(files, function (a, b)
return string.lower(a) < string.lower(b)
end)
if dir == "." then
dir = ""
end
local pl = mp.get_property_native("playlist", {})
local pl_current = mp.get_property_number("playlist-pos", 0) + 1
-- Find the current pl entry (dir+"/"+filename) in the sorted dir list
local current
for i = 1, #files do
if files[i] == filename then
current = i
break
end
end
if current == nil then
return
end
local append = {[-1] = {}, [1] = {}}
for direction = -1, 1, 2 do -- 2 iterations, with direction = -1 and +1
for i = 1, MAXENTRIES do
local file = files[current + i * direction]
local pl_e = pl[pl_current + i * direction]
if file == nil or file[1] == "." then
break
end
local filepath = dir .. file
if pl_e then
-- If there's a playlist entry, and it's the same file, stop.
if pl_e.filename == filepath then
break
end
end
if direction == -1 then
if pl_current == 1 then -- never add additional entries in the middle
mp.msg.info("Prepending " .. file)
table.insert(append[-1], 1, filepath)
end
else
mp.msg.info("Adding " .. file)
table.insert(append[1], filepath)
end
end
end
add_files_at(pl_current + 1, append[1])
add_files_at(pl_current, append[-1])
end
mp.register_event("start-file", find_and_add_entries)
-56
View File
@@ -1,56 +0,0 @@
-- This script cycles between deinterlacing, pullup (inverse
-- telecine), and both filters off. It uses the "deinterlace" property
-- so that a hardware deinterlacer will be used if available.
--
-- It overrides the default deinterlace toggle keybinding "D"
-- (shift+d), so that rather than merely cycling the "deinterlace" property
-- between on and off, it adds a "pullup" step to the cycle.
--
-- It provides OSD feedback as to the actual state of the two filters
-- after each cycle step/keypress.
--
-- Note: if hardware decoding is enabled, pullup filter will likely
-- fail to insert.
--
-- TODO: It might make sense to use hardware assisted vdpaupp=pullup,
-- if available, but I don't have hardware to test it. Patch welcome.
script_name = mp.get_script_name()
pullup_label = string.format("%s-pullup", script_name)
function pullup_on()
for i,vf in pairs(mp.get_property_native('vf')) do
if vf['label'] == pullup_label then
return "yes"
end
end
return "no"
end
function do_cycle()
if pullup_on() == "yes" then
-- if pullup is on remove it
mp.command(string.format("vf del @%s:pullup", pullup_label))
return
elseif mp.get_property("deinterlace") == "yes" then
-- if deinterlace is on, turn it off and insert pullup filter
mp.set_property("deinterlace", "no")
mp.command(string.format("vf add @%s:pullup", pullup_label))
return
else
-- if neither is on, turn on deinterlace
mp.set_property("deinterlace", "yes")
return
end
end
function cycle_deinterlace_pullup_handler()
do_cycle()
-- independently determine current state and give user feedback
mp.osd_message(string.format("deinterlace: %s\n"..
"pullup: %s",
mp.get_property("deinterlace"),
pullup_on()))
end
mp.add_key_binding("D", "cycle-deinterlace-pullup", cycle_deinterlace_pullup_handler)
-99
View File
@@ -1,99 +0,0 @@
-- This script enables live control of the dynamic range compression
-- (drc) audio filter while the video is playing back. This can be
-- useful to avoid having to stop and restart mpv to adjust filter
-- parameters. See the entry for "drc" under the "AUDIO FILTERS"
-- section of the man page for a complete description of the filter.
--
-- This script registers the key-binding "\" to toggle the filter between
--
-- * off
-- * method=1 (single-sample smoothing)
-- * method=2 (multi-sample smoothing)
--
-- It registers the keybindings ctrl+9/ctrl+0 to decrease/increase the
-- target ampltiude. These keys will insert the filter at the default
-- target amplitude of 0.25 if it was not previously present.
--
-- OSD feedback of the current filter state is displayed on pressing
-- each bound key.
script_name = mp.get_script_name()
function print_state(params)
if params then
mp.osd_message(script_name..":\n"
.."method = "..params["method"].."\n"
.."target = "..params["target"])
else
mp.osd_message(script_name..":\noff")
end
end
function get_index_of_drc(afs)
for i,af in pairs(afs) do
if af["label"] == script_name then
return i
end
end
end
function append_drc(afs)
afs[#afs+1] = {
name = "drc",
label = script_name,
params = {
method = "1",
target = "0.25"
}
}
print_state(afs[#afs]["params"])
end
function modify_or_create_af(fun)
afs = mp.get_property_native("af")
i = get_index_of_drc(afs)
if not i then
append_drc(afs)
else
fun(afs, i)
end
mp.set_property_native("af", afs)
end
function drc_toggle_method_handler()
modify_or_create_af(
function (afs, i)
new_method=(afs[i]["params"]["method"]+1)%3
if new_method == 0 then
table.remove(afs, i)
print_state(nil)
else
afs[i]["params"]["method"] = tostring((afs[i]["params"]["method"])%2+1)
print_state(afs[i]["params"])
end
end
)
end
function drc_scale_target(factor)
modify_or_create_af(
function (afs)
afs[i]["params"]["target"] = tostring(afs[i]["params"]["target"]*factor)
print_state(afs[i]["params"])
end
)
end
function drc_louder_handler()
drc_scale_target(2.0)
end
function drc_quieter_handler()
drc_scale_target(0.5)
end
-- toggle between off, method 1 and method 2
mp.add_key_binding("\\", "drc_toggle_method", drc_toggle_method_handler)
-- increase or decrease target volume
mp.add_key_binding("ctrl+9", "drc_quieter", drc_quieter_handler)
mp.add_key_binding("ctrl+0", "drc_louder", drc_louder_handler)
-14
View File
@@ -1,14 +0,0 @@
-- Test script for property change notification mechanism.
-- Note that watching/reading some properties can be very expensive, or
-- require the player to synchronously wait on network (when playing
-- remote files), so you should in general only watch properties you
-- are interested in.
local utils = require("mp.utils")
for i,name in ipairs(mp.get_property_native("property-list")) do
mp.observe_property(name, "native", function(name, val)
print("property '" .. name .. "' changed to '" ..
utils.to_string(val) .. "'")
end)
end
-19
View File
@@ -1,19 +0,0 @@
--makes mpv disable ontop when pausing and re-enable it again when resuming playback
--please note that this won't do anything if ontop was not enabled before pausing
local was_ontop = false
mp.observe_property("pause", "bool", function(name, value)
local ontop = mp.get_property_native("ontop")
if value then
if ontop then
mp.set_property_native("ontop", false)
was_ontop = true
end
else
if was_ontop and not ontop then
mp.set_property_native("ontop", true)
end
was_ontop = false
end
end)
-20
View File
@@ -1,20 +0,0 @@
-- This script pauses playback when minimizing the window, and resumes playback
-- if it's brought back again. If the player was already paused when minimizing,
-- then try not to mess with the pause state.
local did_minimize = false
mp.observe_property("window-minimized", "bool", function(name, value)
local pause = mp.get_property_native("pause")
if value == true then
if pause == false then
mp.set_property_native("pause", true)
did_minimize = true
end
elseif value == false then
if did_minimize and (pause == true) then
mp.set_property_native("pause", false)
end
did_minimize = false
end
end)
-69
View File
@@ -1,69 +0,0 @@
-- Rebuild the terminal status line as a lua script
-- Be aware that this will require more cpu power!
-- Add a string to the status line
function atsl(s)
newStatus = newStatus .. s
end
function update_status_line()
-- Reset the status line
newStatus = ""
if mp.get_property_bool("pause") then
atsl("(Paused) ")
elseif mp.get_property_bool("paused-for-cache") then
atsl("(Buffering) ")
end
if mp.get_property("vid") ~= "no" then
atsl("A")
end
if mp.get_property("aid") ~= "no" then
atsl("V")
end
atsl(": ")
atsl(mp.get_property_osd("time-pos"))
atsl(" / ");
atsl(mp.get_property_osd("length"));
atsl(" (")
atsl(mp.get_property_osd("percent-pos", -1))
atsl("%)")
local r = mp.get_property_number("speed", -1)
if r ~= 1 then
atsl(string.format(" x%4.2f", r))
end
r = mp.get_property_number("avsync", nil)
if r ~= nil then
atsl(string.format(" A-V: %7.3f", r))
end
r = mp.get_property("total-avsync-change", 0)
if math.abs(r) > 0.05 then
atsl(string.format(" ct:%7.3f", r))
end
r = mp.get_property_number("drop-frame-count", -1)
if r > 0 then
atsl(" Late: ")
atsl(r)
end
r = mp.get_property_number("cache", 0)
if r > 0 then
atsl(string.format(" Cache: %d%% ", r))
end
-- Set the new status line
mp.set_property("options/term-status-msg", newStatus)
end
-- Register the event
mp.register_event("tick", update_status_line)
-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)
+1 -1
View File
@@ -64,7 +64,7 @@ sub generate_c_header {
# Output a counter variable for each element
# (presence/absence for scalars, item count for arrays)
for my $subel (sort values %{$el->{subelements}}) {
for my $subel (values %{$el->{subelements}}) {
print " int n_$subel->{fieldname};\n"
}
print "};\n";
+150 -127
View File
@@ -17,134 +17,157 @@
# When multiple files were specified, their info will be put into FOO_* for the
# first file, FOO_1_* for the second file, FOO_2_* for the third file, etc.
__midentify__main() {
case "$0" in
mpv_identify.sh|*/mpv_identify.sh)
# we are NOT being sourced
[ -n "$1" ] && set -- '' "$@"
;;
esac
if [ "$#" -lt 2 ]; then
cat >&2 <<EOF
Usage 1 (for humans only): $0 filename.mkv
will print all property values.
Note that this output really shouldn't be parsed, as the
format is subject to change.
Usage 2 (for use by scripts): see top of this file
NOTE: for mkv with ordered chapters, this may
not always identify the specified file, but the
file providing the first chapter. Specify
--no-ordered-chapters to prevent this.
EOF
return 2
fi
local LF="
"
local nextprefix="$1"
shift
if [ -n "$nextprefix" ]; then
# in case of error, we always want this unset
unset "${nextprefix}path"
fi
local allprops="
filename
path
stream-start
stream-end
stream-length
demuxer
length
chapters
editions
titles
audio
audio-bitrate
audio-codec
audio-format
channels
samplerate
video
angle
video-bitrate
video-codec
video-format
video-aspect
fps
width
height
dwidth
dheight
sub
"
# TODO add metadata support once mpv can do it
local propstr="X-MIDENTIFY-START:$LF"
local key
for key in $allprops; do
propstr="${propstr}X-MIDENTIFY: $key \${=$key}$LF"
key="$(printf '%s\n' "$key" | tr - _)"
unset "$nextprefix$key"
done
local fileindex=0
local prefix=
local line
while IFS= read -r line; do
case "$line" in
X-MIDENTIFY-START:)
if [ -n "$nextprefix" ]; then
prefix="$nextprefix"
if [ "$fileindex" -gt 0 ]; then
nextprefix="${prefix%${fileindex}_}"
fi
fileindex="$((fileindex+1))"
nextprefix="${nextprefix}${fileindex}_"
for key in $allprops; do
key="$(printf '%s\n' "$key" | tr - _)"
unset "$nextprefix$key"
done
else
if [ "$fileindex" -gt 0 ]; then
printf '\n'
fi
fileindex="$((fileindex+1))"
fi
case "$0" in
mpv_identify.sh|*/mpv_identify.sh)
# we are NOT being sourced
case "$1" in
'')
;;
X-MIDENTIFY:\ *)
local key="${line#X-MIDENTIFY: }"
local value="${key#* }"
key="${key%% *}"
key="$(printf '%s\n' "$key" | tr - _)"
if [ -n "$nextprefix" ]; then
if [ -z "$prefix" ]; then
echo >&2 "Got X-MIDENTIFY: without X-MIDENTIFY-START:"
elif [ -n "$value" ]; then
eval "$prefix$key"='"$value"'
fi
else
if [ -n "$value" ]; then
printf '%s=%s\n' "$key" "$value"
fi
fi
*)
set -- '' "$@"
;;
esac
done <<EOF
$(${MPV:-mpv} --term-playing-msg="$propstr" --vo=null --ao=null \
--frames=1 --quiet --no-cache --no-config -- "$@")
EOF
}
;;
esac
__midentify__main "$@"
if [ $# -lt 2 ]; then
echo >&2 "Usage 1 (for humans only): $0 filename.mkv"
echo >&2 "will print all property values."
echo >&2 "Note that this output really shouldn't be parsed, as the"
echo >&2 "format is subject to change."
echo >&2
echo >&2 "Usage 2 (for use by scripts): see top of this file"
echo >&2
echo >&2 "NOTE: for mkv with ordered chapters, this may"
echo >&2 "not always identify the specified file, but the"
echo >&2 "file providing the first chapter. Specify"
echo >&2 "--no-ordered-chapters to prevent this."
exit 1
fi
if [ -z "$MPV" ]; then
MPV="mpv"
fi
__midentify__LF="
"
__midentify__nextprefix=$1
shift
if [ -n "$__midentify__nextprefix" ]; then
# in case of error, we always want this unset
eval unset $__midentify__nextprefix'path'
fi
__midentify__allprops="
filename
path
stream-start
stream-end
stream-length
demuxer
length
chapters
editions
titles
audio
audio-bitrate
audio-codec
audio-format
channels
samplerate
video
angle
video-bitrate
video-codec
video-format
aspect
fps
width
height
dwidth
dheight
sub
"
# TODO add metadata support once mpv can do it
__midentify__propstr="X-MIDENTIFY-START:$__midentify__LF"
for __midentify__key in $__midentify__allprops; do
__midentify__propstr=$__midentify__propstr"X-MIDENTIFY: $__midentify__key \${=$__midentify__key}$__midentify__LF"
__midentify__key=`echo "$__midentify__key" | tr - _`
eval unset $__midentify__nextprefix$__midentify__key
done
__midentify__output=`$MPV --playing-msg="$__midentify__propstr" --vo=null --ao=null --frames=1 --quiet --no-cache --no-config "$@"`
__midentify__fileindex=0
__midentify__prefix=
while :; do
case "$__midentify__output" in
'')
break
;;
*$__midentify__LF*)
__midentify__line=${__midentify__output%%$__midentify__LF*}
__midentify__output=${__midentify__output#*$__midentify__LF}
;;
*)
__midentify__line=$__midentify__output
__midentify__output=
;;
esac
case "$__midentify__line" in
X-MIDENTIFY-START:)
if [ -n "$__midentify__nextprefix" ]; then
__midentify__prefix=$__midentify__nextprefix
if [ $__midentify__fileindex -gt 0 ]; then
__midentify__nextprefix=${__midentify__prefix%$__midentify__fileindex\_}
fi
__midentify__fileindex=$(($__midentify__fileindex+1))
__midentify__nextprefix=$__midentify__nextprefix$__midentify__fileindex\_
for __midentify__key in $__midentify__allprops; do
__midentify__key=`echo "$__midentify__key" | tr - _`
eval unset $__midentify__nextprefix$__midentify__key
done
else
if [ $__midentify__fileindex -gt 0 ]; then
echo
fi
__midentify__fileindex=$(($__midentify__fileindex+1))
fi
;;
X-MIDENTIFY:\ *)
__midentify__key=${__midentify__line#X-MIDENTIFY:\ }
__midentify__value=${__midentify__key#* }
__midentify__key=${__midentify__key%% *}
__midentify__key=`echo "$__midentify__key" | tr - _`
if [ -n "$__midentify__nextprefix" ]; then
if [ -z "$__midentify__prefix" ]; then
echo >&2 "Got X-MIDENTIFY: without X-MIDENTIFY-START:"
elif [ -n "$__midentify__value" ]; then
eval $__midentify__prefix$__midentify__key=\$__midentify__value
fi
else
if [ -n "$__midentify__value" ]; then
echo "$__midentify__key=$__midentify__value"
fi
fi
;;
esac
done
unset __midentify__fileindex
unset __midentify__allprops
unset __midentify__key
unset __midentify__LF
unset __midentify__line
unset __midentify__output
unset __midentify__nextprefix
unset __midentify__prefix
unset __midentify__propstr
unset __midentify__value
+67 -4
View File
@@ -1,14 +1,35 @@
#!/usr/bin/env python
import os
import re
import shutil
import sys
import fileinput
from optparse import OptionParser
from textwrap import dedent
def sh(command):
return os.popen(command).read()
def dylib_lst(input_file):
return sh("otool -L %s | grep -e '\t' | awk '{ print $1 }'" % input_file)
sys_re = re.compile("/System")
exe_re = re.compile("@executable_path")
binary_name = sys.argv[1]
def is_user_lib(libname, input_file):
return not sys_re.match(libname) and \
not exe_re.match(libname) and \
not "libobjc" in libname and \
not "libSystem" in libname and \
not "libgcc" in libname and \
not os.path.basename(input_file) in libname and \
not libname == ''
def user_dylib_lst(input_file):
return [lib for lib in dylib_lst(input_file).split("\n") if
is_user_lib(lib, input_file)]
def bundle_path(binary_name):
return "%s.app" % binary_name
@@ -35,9 +56,51 @@ def copy_bundle(binary_name):
def copy_binary(binary_name):
shutil.copy(binary_name, target_binary(binary_name))
def run_install_name_tool(target_file, dylib_path, dest_dir, root=True):
new_dylib_path = os.path.join("@executable_path", "lib",
os.path.basename(dylib_path))
sh("install_name_tool -change %s %s %s" % \
(dylib_path, new_dylib_path, target_file))
if root:
sh("install_name_tool -id %s %s" % \
(new_dylib_path, os.path.join(dest_dir,
os.path.basename(dylib_path))))
def cp_dylibs(target_file, dest_dir):
for dylib_path in user_dylib_lst(target_file):
dylib_dest_path = os.path.join(dest_dir, os.path.basename(dylib_path))
try:
shutil.copy(dylib_path, dylib_dest_path)
except IOError:
if re.match("dylib$", target_file):
reinstall_what = target_file
else:
reinstall_what = dylib_path
sys.exit(dedent("""\
%s uses library %s which is not available anymore.
This is most likely because you uninstalled %s.
Please reinstall %s to fix it's dependencies.""" % \
(target_file, dylib_path, dylib_path, reinstall_what) ))
os.chmod(dylib_dest_path, 0o755)
cp_dylibs(dylib_dest_path, dest_dir)
def fix_dylibs_paths(target_file, dest_dir, root=True):
for dylib_path in user_dylib_lst(target_file):
dylib_dest_path = os.path.join(dest_dir, os.path.basename(dylib_path))
run_install_name_tool(target_file, dylib_path, dest_dir, root)
fix_dylibs_paths(dylib_dest_path, dest_dir, False)
def apply_plist_template(plist_file, version):
for line in fileinput.input(plist_file, inplace=1):
print (line.rstrip().replace('${VERSION}', version))
sh("sed -i -e 's/${VERSION}/%s/g' %s" % (version, plist_file))
def bundle_dependencies(binary_name):
lib_bundle_directory = os.path.join(target_directory(binary_name), "lib")
cp_dylibs(binary_name, lib_bundle_directory)
fix_dylibs_paths(target_binary(binary_name), lib_bundle_directory)
def main():
version = sh("./version.sh --print").strip()
@@ -65,7 +128,7 @@ def main():
if options.deps:
print("> bundling dependencies")
sh(" ".join(["TOOLS/dylib-unhell.py", target_binary(binary_name)]))
bundle_dependencies(binary_name)
print("done.")
+1 -632
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
@@ -88,7 +88,6 @@
<string>VOB</string>
<string>WEBM</string>
<string>WMV</string>
<string>MK3D</string>
<string>asf</string>
<string>avi</string>
<string>cpk</string>
@@ -123,7 +122,6 @@
<string>vob</string>
<string>webm</string>
<string>wmv</string>
<string>mk3d</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
@@ -210,7 +208,6 @@
<string>mms</string>
<string>mmst</string>
<string>http</string>
<string>https</string>
<string>httpproxy</string>
<string>rtp</string>
<string>rtsp</string>
@@ -233,633 +230,5 @@
</array>
</dict>
</array>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.audio</string>
</array>
<key>UTTypeDescription</key>
<string>AC3 Audio</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.ac3</string>
<key>UTTypeReferenceURL</key>
<string>http://wiki.multimedia.cx/index.php?title=AC3</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>ac3</string>
<string>a52</string>
<string>eac3</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.audio</string>
</array>
<key>UTTypeDescription</key>
<string>DTS Audio</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.dts</string>
<key>UTTypeReferenceURL</key>
<string>http://wiki.multimedia.cx/index.php?title=DTS</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>dts</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.audio</string>
</array>
<key>UTTypeDescription</key>
<string>Free Lossless Audio Codec</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.flac</string>
<key>UTTypeReferenceURL</key>
<string>http://flac.sourceforge.net/format.html</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>flac</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.audio</string>
</array>
<key>UTTypeDescription</key>
<string>Matroska Audio</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.mka</string>
<key>UTTypeReferenceURL</key>
<string>http://www.matroska.org</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>mka</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.audio</string>
</array>
<key>UTTypeDescription</key>
<string>Ogg Audio</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.ogg-audio</string>
<key>UTTypeReferenceURL</key>
<string>http://xiph.org/ogg</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>ogg</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.audio</string>
</array>
<key>UTTypeDescription</key>
<string>PCM Audio</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.pcm</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/Pulse-code_modulation</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>pcm</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.audio</string>
</array>
<key>UTTypeDescription</key>
<string>Windows Media Audio</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.wma</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/Windows_Media_Audio</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>wma</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>Audio Video Interleave</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.avi</string>
<key>UTTypeReferenceURL</key>
<string>http://www.the-labs.com/Video/odmlff2-avidef.pdf</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>avi</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>DIVX Video</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.divx</string>
<key>UTTypeReferenceURL</key>
<string>http://www.divx.com</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>divx</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>DV Video</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.dv</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/DV</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>dv</string>
<string>hdv</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>Flash Video</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.flv</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/Flash_Video</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>flv</string>
<string>f4v</string>
<string>f4p</string>
<string>swf</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>MPEG-2 Transport Stream</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.mts</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/.m2ts</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>trp</string>
<string>m2t</string>
<string>m2ts</string>
<string>mts</string>
<string>mtv</string>
<string>ts</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>Matroska Video</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.mkv</string>
<key>UTTypeReferenceURL</key>
<string>http://www.matroska.org</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>mkv</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>Matroska stereoscopic/3D video</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.mk3d</string>
<key>UTTypeReferenceURL</key>
<string>http://www.matroska.org</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>mk3d</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>WebM Video</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.webm</string>
<key>UTTypeReferenceURL</key>
<string>http://www.webmproject.org</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>webm</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>Ogg Video</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.ogv</string>
<key>UTTypeReferenceURL</key>
<string>http://xiph.org/ogg</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>ogm</string>
<string>ogv</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>Real Media</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.rmvb</string>
<key>UTTypeReferenceURL</key>
<string>http://www.real.com</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>rmvb</string>
<string>rm</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>Video Object</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.vob</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/VOB</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>vob</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>Windows Media Video</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.wmv</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/Windows_Media_Video</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>wmv</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>XVID Video</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.xvid</string>
<key>UTTypeReferenceURL</key>
<string>http://www.xvid.org</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>xvid</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>AVC raw stream</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.h264</string>
<key>UTTypeReferenceURL</key>
<string>http://www.itu.int/rec/T-REC-H.264</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>264</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>HEVC raw stream</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.hevc</string>
<key>UTTypeReferenceURL</key>
<string>http://hevc.info</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>hevc</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>YUV stream</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.yuv</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/YUV</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>yuv</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.movie</string>
</array>
<key>UTTypeDescription</key>
<string>YUV4MPEG2 stream</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.y4m</string>
<key>UTTypeReferenceURL</key>
<string>http://wiki.multimedia.cx/index.php?title=YUV4MPEG2</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>y4m</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.plain-text</string>
</array>
<key>UTTypeDescription</key>
<string>SubRip Subtitle</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.subrip</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/SubRip</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>srt</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.plain-text</string>
</array>
<key>UTTypeDescription</key>
<string>MicroDVD Subtitle</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.sub</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/MicroDVD</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>sub</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.plain-text</string>
</array>
<key>UTTypeDescription</key>
<string>SubStation Alpha Subtitle</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.ass</string>
<key>UTTypeReferenceURL</key>
<string>https://github.com/libass/libass</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>ass</string>
<string>ssa</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>VobSub Subtitle</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.vobsub</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/DirectVobSub</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>idx</string>
<string>sub</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.plain-text</string>
</array>
<key>UTTypeDescription</key>
<string>SAMI Subtitle</string>
<key>UTTypeIconFile</key>
<string>document.icns</string>
<key>UTTypeIdentifier</key>
<string>io.mpv.smi</string>
<key>UTTypeReferenceURL</key>
<string>http://en.wikipedia.org/wiki/SAMI</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>smi</string>
<string>smil</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>
@@ -1,2 +0,0 @@
screenshot-template=~/Desktop/shot%n
profile=pseudo-gui
-135
View File
@@ -1,135 +0,0 @@
#!/usr/bin/env python3
import matplotlib.pyplot as plot
import sys
import re
filename = sys.argv[1]
event_regex = re.compile(".*")
"""
This script is meant to display stats written by mpv --dump-stats=filename.
In general, each line in that file is an event of the form:
<timestamp in microseconds> <text> '#' <comment>
e.g.:
10474959 start flip #cplayer
<text> is what MP_STATS(log, "...") writes. The rest is added by msg.c.
Currently, the following event types are supported:
'signal' <name> singular event
'start' <name> start of the named event
'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
<name> singular event (same as 'signal')
"""
class G:
events = {}
start = None
# http://matplotlib.org/api/markers_api.html#module-matplotlib.markers
markers = ["o", "8", "s", "p", "*", "h", "+", "x", "D"]
def find_marker():
if len(G.markers) == 0:
return "o"
m = G.markers[0]
G.markers = G.markers[1:]
return m
class Event:
pass
def get_event(event, evtype):
if event not in G.events:
e = Event()
e.name = event
e.vals = []
e.type = evtype
e.marker = "o"
if e.type == "event-signal":
e.marker = find_marker()
if not event_regex.match(e.name):
return e
G.events[event] = e
return G.events[event]
SCALE = 1e6 # microseconds to seconds
for line in [line.split("#")[0].strip() for line in open(filename, "r")]:
line = line.strip()
if not line:
continue
ts, event = line.split(" ", 1)
ts = int(ts) / SCALE
if G.start is None:
G.start = ts
ts = ts - G.start
if event.startswith("start "):
e = get_event(event[6:], "event")
e.vals.append((ts, 0))
e.vals.append((ts, 1))
elif event.startswith("end "):
e = get_event(event[4:], "event")
e.vals.append((ts, 1))
e.vals.append((ts, 0))
elif event.startswith("value "):
_, val, name = event.split(" ", 2)
val = float(val)
e = get_event(name, "value")
e.vals.append((ts, val))
elif event.startswith("event-timed "):
_, val, name = event.split(" ", 2)
val = int(val) / SCALE - G.start
e = get_event(name, "event-signal")
e.vals.append((val, 1))
elif event.startswith("value-timed "):
_, tsval, val, name = event.split(" ", 3)
tsval = int(tsval) / SCALE - G.start
val = float(val)
e = get_event(name, "value")
e.vals.append((tsval, val))
elif event.startswith("signal "):
name = event.split(" ", 2)[1]
e = get_event(name, "event-signal")
e.vals.append((ts, 1))
else:
e = get_event(event, "event-signal")
e.vals.append((ts, 1))
# deterministically sort them; make sure the legend is sorted too
G.sevents = list(G.events.values())
G.sevents.sort(key=lambda x: x.name)
hasval = False
for e, index in zip(G.sevents, range(len(G.sevents))):
m = len(G.sevents)
if e.type == "value":
hasval = True
else:
e.vals = [(x, y * (m - index) / m) for (x, y) in e.vals]
fig = plot.figure()
fig.hold(True)
ax = [None, None]
plots = 2 if hasval else 1
ax[0] = fig.add_subplot(plots, 1, 1)
if hasval:
ax[1] = fig.add_subplot(plots, 1, 2, sharex=ax[0])
legends = [[], []]
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)
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()
+41 -16
View File
@@ -21,13 +21,20 @@ script after that will start a new mpv instance.
Note that you can control the mpv instance by writing to the command fifo:
echo "cycle fullscreen" > ~/.umpv_fifo
echo "cycle fullscreen" > /tmp/umpv-fifo-*
Note: you can supply custom mpv path and options with the MPV environment
variable. The environment variable will be split on whitespace, and the
first item is used as path to mpv binary and the rest is passed as options
_if_ the script starts mpv. If mpv is not started by the script (i.e. mpv
is already running), this will be ignored.
Note: you can supply custom options with the UMPV_OPTIONS environment variable.
The environment variable will be split on whitespace, and each item is
passed as option to mpv _if_ the script starts mpv. If mpv is not started
by the script (i.e. mpv is already running), the options will be ignored.
Warning:
The script attempts to make sure the FIFO is safely created (i.e. not world-
writable), and checks that it's really a FIFO. This is important for security,
because the FIFO allows anyone with write access to run arbitrary commands
in mpv's context using the "run" input command. If you are worried about
security, you should verify that the code handles these concerns correctly.
"""
import sys
@@ -38,17 +45,21 @@ import fcntl
import stat
import string
if len(sys.argv) < 1:
sys.exit(1)
files = sys.argv[1:]
# this is the same method mpv uses to decide this
# this is about the same method mpv uses to decide this
def is_url(filename):
parts = filename.split("://", 1)
parts = filename.split(":", 1)
if len(parts) < 2:
return False
# protocol prefix has no special characters => it's an URL
allowed_symbols = string.ascii_letters + string.digits + '_'
prefix = parts[0]
return all(map(lambda c: c in allowed_symbols, prefix))
for c in prefix:
if string.ascii_letters.find(c) < 0:
return False
return True
# make them absolute; also makes them safe against interpretation as options
def make_abs(filename):
@@ -57,7 +68,10 @@ def make_abs(filename):
return filename
files = [make_abs(f) for f in files]
FIFO = os.path.join(os.getenv("HOME"), ".umpv_fifo")
opts_env = os.getenv("UMPV_OPTIONS")
opts_env = opts_env.split() if opts_env else []
FIFO = "/tmp/umpv-fifo-" + os.getenv("USER")
fifo_fd = -1
try:
@@ -70,6 +84,14 @@ except OSError as e:
else:
raise e
if fifo_fd >= 0:
st = os.fstat(fifo_fd)
if (((st.st_mode & (stat.S_IRWXG | stat.S_IRWXO)) != 0) or
(not stat.S_ISFIFO(st.st_mode)) or
(st.st_uid != os.getuid())):
print("error: command FIFO is not a FIFO or has bogus permissions")
sys.exit(1)
if fifo_fd >= 0:
# Unhandled race condition: what if mpv is terminating right now?
fcntl.fcntl(fifo_fd, fcntl.F_SETFL, 0) # set blocking mode
@@ -86,12 +108,15 @@ else:
try:
os.unlink(FIFO)
except OSError as e:
pass
os.mkfifo(FIFO, 0o600)
if e.errno == errno.ENOENT:
pass
else:
raise e
os.mkfifo(FIFO, int("0600", 8))
opts = (os.getenv("MPV") or "mpv").split()
opts.extend(["--no-terminal", "--force-window", "--input-file=" + FIFO,
"--"])
opts = ["mpv", "--really-quiet", "--force-window", "--input-file=" + FIFO]
opts.extend(opts_env)
opts.append("--")
opts.extend(files)
subprocess.check_call(opts)
+1 -1
View File
@@ -19,7 +19,7 @@
# 02110-1301 USA
#
FILTERS = telecine tile rectangle framestep ildetect
FILTERS = showqscale telecine tile rectangle framestep ildetect
COMMON = filterutils.o
OBJECTS = $(patsubst %,%.o,$(FILTERS)) $(COMMON)
+4 -3
View File
@@ -32,11 +32,11 @@
/*
* frame stepping filter
*
* usage: --vf=dlopen=/path/to/framestep.so:5
* usage: -vf dlopen=./framestep.so:5
*
* outputs every 5th frame
*
* usage: --vf=dlopen=/path/to/framestep.so:5:3
* usage: -vf dlopen=./framestep.so:5:3
*
* outputs every 5th frame, starting with frame index 3 (default: 0)
*/
@@ -90,7 +90,8 @@ int vf_dlopen_getcontext(struct vf_dlopen_context *ctx, int argc, const char **a
if (argc != 1 && argc != 2)
return -1;
framestep_data_t *framestep = calloc(1,sizeof(framestep_data_t));
framestep_data_t *framestep = malloc(sizeof(framestep_data_t));
memset(framestep, 0, sizeof(*framestep));
framestep->step = atoi(argv[0]);
framestep->pos = (argc >= 2) ? atoi(argv[1]) : 0;
+3 -2
View File
@@ -267,7 +267,8 @@ int vf_dlopen_getcontext(struct vf_dlopen_context *ctx, int argc, const char **a
(void) argc;
(void) argv;
ildetect_data_t *il = calloc(1,sizeof(ildetect_data_t));
ildetect_data_t *il = malloc(sizeof(ildetect_data_t));
memset(il, 0, sizeof(*il));
#define A(i,d) ((argc>(i) && *argv[i]) ? atof(argv[i]) : (d))
il->method = A(0, 0);
@@ -283,7 +284,7 @@ int vf_dlopen_getcontext(struct vf_dlopen_context *ctx, int argc, const char **a
il->tc_decision_threshold = A(10, 0.2);
static struct vf_dlopen_formatpair map[] = {
{ "gray", "gray" },
{ "y8", "y8" },
{ NULL, NULL }
};
ctx->format_mapping = map;
+1
View File
@@ -11,6 +11,7 @@ esac
: ${MPV:=mpv}
: ${ILDETECT_MPV:=$MPV}
: ${ILDETECT_MPV:=$MPV}
: ${ILDETECT_MPVFLAGS:=--start=35% --length=35}
: ${ILDETECT_DRY_RUN:=}
: ${ILDETECT_QUIET:=}
+4 -3
View File
@@ -35,7 +35,7 @@
/*
* rectangle
*
* usage: --vf=dlopen=/path/to/rectangle.so
* usage: -vf dlopen=./rectangle.so
*
* provides an editable rectangle
* NOTE: unix only, and requires xterm to be installed. Don't ask.
@@ -345,10 +345,11 @@ int vf_dlopen_getcontext(struct vf_dlopen_context *ctx, int argc, const char **a
(void) argc;
(void) argv;
static struct vf_dlopen_formatpair map[] = {
{ "yuv420p", "yuv420p" },
{ "yv12", "yv12" },
{ NULL, NULL }
};
privdata *priv = calloc(1,sizeof(privdata));
privdata *priv = malloc(sizeof(privdata));
memset(priv, 0, sizeof(*priv));
priv->step = 8;
if(argc >= 1)
priv->w = atoi(argv[0]);
+120
View File
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2012 Rudolf Polzer <divVerent@xonotic.org>
*
* This file is part of mpv's vf_dlopen examples.
*
* mpv's vf_dlopen examples are free software; you can redistribute them and/or
* modify them under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the
* License, or (at your option) any later version.
*
* mpv's vf_dlopen examples are distributed in the hope that they will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv's vf_dlopen examples; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vf_dlopen.h"
/*
* qscale visualizer
*
* usage: -vf dlopen=./showqscale.so
*
* uses reddish colors for high QPs, and greenish colors for low QPs
*/
#define PLANE_Y 0
#define PLANE_U 1
#define PLANE_V 2
static int qs_put_image(struct vf_dlopen_context *ctx)
{
unsigned int x, y, p;
assert(ctx->inpic.planes == ctx->outpic[0].planes);
for (p = 0; p < ctx->outpic[0].planes; ++p) {
assert(ctx->inpic.planewidth[p] == ctx->outpic[0].planewidth[p]);
assert(ctx->inpic.planeheight[p] == ctx->outpic[0].planeheight[p]);
if ((p == PLANE_U || p == PLANE_V) && ctx->inpic_qscale)
continue;
#if 0
// copy as is
for (y = 0; y < ctx->outpic[0].planeheight[p]; ++y)
memcpy(
&ctx->outpic[0].plane[p][ctx->outpic[0].planestride[p] * y],
&inpic[ctx->outpic[0].planeofs[p] + ctx->inpic.planestride[p] * y],
ctx->outpic[0].planewidth[p]
);
#else
// reduce contrast
for (y = 0; y < ctx->outpic[0].planeheight[p]; ++y)
for (x = 0; x < ctx->outpic[0].planewidth[p]; ++x)
ctx->outpic[0].plane[p][ctx->outpic[0].planestride[p] * y + x] =
0x20 + ((ctx->inpic.plane[p][ctx->inpic.planestride[p] * y + x] * 3) >> 2);
#endif
}
if (ctx->inpic_qscale) {
int qmin = 255;
int qmax = -255;
// clear U plane
p = PLANE_U;
for (y = 0; y < ctx->outpic[0].planeheight[p]; ++y)
memset(
&ctx->outpic[0].plane[p][ctx->outpic[0].planestride[p] * y],
0x80,
ctx->outpic[0].planewidth[p]
);
// replace V by the qp (0 = green, 12 = red)
p = PLANE_V;
for (y = 0; y < ctx->outpic[0].planeheight[p]; ++y)
for (x = 0; x < ctx->outpic[0].planewidth[p]; ++x) {
int q = ctx->inpic_qscale[
(x >> (ctx->inpic_qscaleshift - ctx->inpic.planexshift[p])) +
(y >> (ctx->inpic_qscaleshift - ctx->inpic.planeyshift[p])) * ctx->inpic_qscalestride];
if (q < qmin)
qmin = q;
if (q > qmax)
qmax = q;
int v = 128 + 21 * (q - 6); // range: 0 = green, 12 = red
if (v < 0)
v = 0;
if (v > 255)
v = 255;
ctx->outpic[0].plane[p][ctx->outpic[0].planestride[p] * y + x] = v;
}
// printf("qscale range: %d .. %d\n", qmin, qmax);
}
ctx->outpic[0].pts = ctx->inpic.pts;
return 1;
}
int vf_dlopen_getcontext(struct vf_dlopen_context *ctx, int argc, const char **argv)
{
VF_DLOPEN_CHECK_VERSION(ctx);
(void) argc;
(void) argv;
static struct vf_dlopen_formatpair map[] = {
{ "yv12", "yv12" },
{ NULL, NULL }
};
ctx->format_mapping = map;
ctx->put_image = qs_put_image;
return 1;
}
+3 -2
View File
@@ -32,7 +32,7 @@
/*
* telecine filter
*
* usage: --vf=dlopen=/path/to/telecine.so:t:23
* usage: -vf dlopen=./telecine.so:t:23
*
* Parameter: first parameter is "t" for top field first, "b" for bottom field first
* then digits (0-9) for how many fields a frame is to be displayed
@@ -237,7 +237,8 @@ int vf_dlopen_getcontext(struct vf_dlopen_context *ctx, int argc, const char **a
if (!a0[0] || a0[1] || !a1[0] || argc > 2)
return -1;
tc_data_t *tc = calloc(1,sizeof(tc_data_t));
tc_data_t *tc = malloc(sizeof(tc_data_t));
memset(tc, 0, sizeof(*tc));
if (a0[0] == 't')
tc->firstfield = 0;
+7 -6
View File
@@ -30,17 +30,17 @@
/*
* tile filter
*
* usage: --vf=dlopen=/path/to/tile.so:4:3
* usage: -vf dlopen=./tile.so:4:3
*
* only supports rgb24 and yuv420p for now
* only supports rgb24 and yv12 for now
* in theory can support any format where rows are a multiple of bytes, and the
* multiple is known
*/
#define ALLFORMATS \
/* format bytes xmul ymul */ \
FORMAT("rgb24" , 3, 1, 1) \
FORMAT("yuv420p", 1, 2, 2)
/* format bytes xmul ymul */ \
FORMAT("rgb24", 3, 1, 1) \
FORMAT("yv12", 1, 2, 2)
typedef struct {
int rows, cols;
@@ -150,7 +150,8 @@ int vf_dlopen_getcontext(struct vf_dlopen_context *ctx, int argc, const char **a
if (argc != 2)
return -1;
tile_data_t *tile = calloc(1,sizeof(tile_data_t));
tile_data_t *tile = malloc(sizeof(tile_data_t));
memset(tile, 0, sizeof(*tile));
tile->cols = atoi(argv[0]);
tile->rows = atoi(argv[1]);
-228
View File
@@ -1,228 +0,0 @@
#!/usr/bin/perl
# Generate ZSH completion
use strict;
use warnings;
my $mpv = $ARGV[0] || 'mpv';
my @opts = parse_main_opts('--list-options', '^ (\-\-[^\s\*]*)\*?\s*(.*)');
my @ao = parse_opts('--ao=help', '^ ([^\s\:]*)\s*: (.*)');
my @vo = parse_opts('--vo=help', '^ ([^\s\:]*)\s*: (.*)');
my @af = parse_opts('--af=help', '^ ([^\s\:]*)\s*: (.*)');
my @vf = parse_opts('--vf=help', '^ ([^\s\:]*)\s*: (.*)');
my @protos = parse_opts('--list-protocols', '^ ([^\s]*)');
my ($opts_str, $ao_str, $vo_str, $af_str, $vf_str, $protos_str);
$opts_str .= qq{ '$_' \\\n} foreach (@opts);
chomp $opts_str;
$ao_str .= qq{ '$_' \\\n} foreach (@ao);
chomp $ao_str;
$vo_str .= qq{ '$_' \\\n} foreach (@vo);
chomp $vo_str;
$af_str .= qq{ '$_' \\\n} foreach (@af);
chomp $af_str;
$vf_str .= qq{ '$_' \\\n} foreach (@vf);
chomp $vf_str;
$protos_str = join(' ', @protos);
my $profile_comp = <<'EOS';
local -a profiles
local current
for current in "${(@f)$($words[1] --profile=help)}"; do
current=${current//\*/\\\*}
current=${current//\:/\\\:}
current=${current//\[/\\\[}
current=${current//\]/\\\]}
if [[ $current =~ $'\t'([^$'\t']*)$'\t'(.*) ]]; then
if [[ -n $match[2] ]]; then
current="$match[1][$match[2]]"
else
current="$match[1]"
fi
profiles=($profiles $current)
fi
done
if [[ $state == show-profile ]]; then
# For --show-profile, only one allowed
if (( ${#profiles} > 0 )); then
_values 'profile' $profiles && rc=0
fi
else
# For --profile, multiple allowed
profiles=($profiles 'help[list profiles]')
_values -s , 'profile(s)' $profiles && rc=0
fi
EOS
chomp $profile_comp;
my $tmpl = <<"EOS";
#compdef mpv
# mpv zsh completion
local curcontext="\$curcontext" state state_descr line
typeset -A opt_args
local rc=1
_arguments -C -S \\
$opts_str
'*:files:->mfiles' && rc=0
case \$state in
ao)
_values -s , 'audio outputs' \\
$ao_str
&& rc=0
;;
vo)
_values -s , 'video outputs' \\
$vo_str
&& rc=0
;;
af)
_values -s , 'audio filters' \\
$af_str
&& rc=0
;;
vf)
_values -s , 'video filters' \\
$vf_str
&& rc=0
;;
profile|show-profile)
$profile_comp
;;
files)
compset -P '*,'
compset -S ',*'
_files -r ',/ \\t\\n\\-' && rc=0
;;
mfiles)
local expl
_tags files urls
while _tags; do
_requested files expl 'media file' _files -g \\
"*.(#i)(asf|asx|avi|flac|flv|m1v|m2p|m2v|m4v|mjpg|mka|mkv|mov|mp3|mp4|mpe|mpeg|mpg|ogg|ogm|ogv|qt|rm|ts|vob|wav|webm|wma|wmv)(-.)" && rc=0
if _requested urls; then
while _next_label urls expl URL; do
_urls "\$expl[@]" && rc=0
compadd -S '' "\$expl[@]" $protos_str && rc=0
done
fi
(( rc )) || return 0
done
;;
esac
return rc
EOS
print $tmpl;
sub parse_main_opts {
my ($cmd, $regex) = @_;
my @list;
my @lines = split /\n/, `"$mpv" --no-config $cmd`;
foreach my $line (@lines) {
my ($name, $desc) = ($line =~ /^$regex/) or next;
next if ($desc eq 'removed' || $desc eq 'alias');
if ($desc =~ /^Flag/) {
push @list, $name;
$name =~ /^--(.*)/;
if ($1 !~ /^(\{|\}|v|list-options|really-quiet|no-.*)$/) {
push @list, "--no-$1";
}
} elsif ($desc =~ /^Print/) {
push @list, $name;
} else {
# Option takes argument
my $entry = $name;
$desc =~ s/\:/\\:/g;
$entry .= "=-:$desc:";
if ($desc =~ /^Choices\\: ([^(]*)/) {
my $choices = $1;
$choices =~ s/ +$//; # strip trailing space
$entry .= "($choices)";
# If "no" is one of the choices, it can also be
# negated like a flag (--no-whatever).
if ($choices =~ /\bno\b/) {
$name =~ s/^--/--no-/;
push @list, $name;
}
} elsif ($line =~ /\[file\]/) {
$entry .= '->files';
} elsif ($name =~ /^--(ao|vo|af|vf|profile|show-profile)$/) {
$entry .= "->$1";
}
push @list, $entry;
}
}
# Sort longest first, because zsh won't complete an option listed
# after one that's a prefix of it.
@list = sort {
$a =~ /([^=]*)/; my $ma = $1;
$b =~ /([^=]*)/; my $mb = $1;
length($mb) <=> length($ma)
} @list;
return @list;
}
sub parse_opts {
my ($cmd, $regex) = @_;
my @list;
my @lines = split /\n/, `"$mpv" --no-config $cmd`;
foreach my $line (@lines) {
if ($line !~ /^$regex/) {
next;
}
my $entry = $1;
if (defined $2) {
my $desc = $2;
$desc =~ s/\:/\\:/g;
$entry .= "[$desc]";
}
push @list, $entry
}
return @list;
}
+1 -1
View File
@@ -1 +1 @@
0.9.0
0.3.10
+38 -217
View File
@@ -20,13 +20,10 @@
#include <stdlib.h>
#include <assert.h>
#include <libavutil/buffer.h>
#include <libavutil/frame.h>
#include <libavutil/version.h>
#include <libavutil/mem.h>
#include "talloc.h"
#include "common/common.h"
#include "fmt-conversion.h"
#include "audio.h"
static void update_redundant_info(struct mp_audio *mpa)
@@ -34,8 +31,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_fmt2bits(mpa->format) / 8;
if (af_fmt_is_planar(mpa->format)) {
mpa->spf = 1;
mpa->num_planes = mpa->nch;
mpa->sstride = mpa->bps;
@@ -91,17 +88,23 @@ bool mp_audio_config_valid(const struct mp_audio *mpa)
&& mpa->rate >= 1 && mpa->rate < 10000000;
}
char *mp_audio_config_to_str_buf(char *buf, size_t buf_sz, struct mp_audio *mpa)
char *mp_audio_fmt_to_str(int srate, const struct mp_chmap *chmap, int format)
{
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));
return buf;
char *chstr = mp_chmap_to_str(chmap);
char *res = talloc_asprintf(NULL, "%dHz %s %dch %s", srate, chstr,
chmap->num, af_fmt_to_str(format));
talloc_free(chstr);
return res;
}
char *mp_audio_config_to_str(struct mp_audio *mpa)
{
return mp_audio_fmt_to_str(mpa->rate, &mpa->channels, mpa->format);
}
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));
}
@@ -113,27 +116,19 @@ int mp_audio_psize(struct mp_audio *mpa)
void mp_audio_set_null_data(struct mp_audio *mpa)
{
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
for (int n = 0; n < MP_NUM_CHANNELS; n++)
mpa->planes[n] = NULL;
mpa->allocated[n] = NULL;
}
mpa->samples = 0;
}
static int get_plane_size(const struct mp_audio *mpa, int samples)
{
if (samples < 0 || !mp_audio_config_valid(mpa))
return -1;
if (samples >= INT_MAX / mpa->sstride)
return -1;
return MPMAX(samples * mpa->sstride, 1);
}
static void mp_audio_destructor(void *ptr)
{
struct mp_audio *mpa = ptr;
for (int n = 0; n < MP_NUM_CHANNELS; n++)
av_buffer_unref(&mpa->allocated[n]);
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
// Note: don't free if not allocated by mp_audio_realloc
if (mpa->allocated[n])
av_free(mpa->planes[n]);
}
}
/* Reallocate the data stored in mpa->planes[n] so that enough samples are
@@ -152,19 +147,27 @@ static void mp_audio_destructor(void *ptr)
*/
void mp_audio_realloc(struct mp_audio *mpa, int samples)
{
int size = get_plane_size(mpa, samples);
if (size < 0)
abort(); // oom or invalid parameters
assert(samples >= 0);
if (samples >= INT_MAX / mpa->sstride)
abort(); // oom
int size = MPMAX(samples * mpa->sstride, 1);
for (int n = 0; n < mpa->num_planes; n++) {
if (!mpa->allocated[n] || size != mpa->allocated[n]->size) {
if (av_buffer_realloc(&mpa->allocated[n], size) < 0)
abort(); // OOM
mpa->planes[n] = mpa->allocated[n]->data;
if (size != mpa->allocated[n]) {
// Note: av_realloc() can't be used (see libavutil doxygen)
void *new = av_malloc(size);
if (!new)
abort();
if (mpa->allocated[n])
memcpy(new, mpa->planes[n], MPMIN(mpa->allocated[n], size));
av_free(mpa->planes[n]);
mpa->planes[n] = new;
mpa->allocated[n] = size;
}
}
for (int n = mpa->num_planes; n < MP_NUM_CHANNELS; n++) {
av_buffer_unref(&mpa->allocated[n]);
av_free(mpa->planes[n]);
mpa->planes[n] = NULL;
mpa->allocated[n] = 0;
}
talloc_set_destructor(mpa, mp_audio_destructor);
}
@@ -191,7 +194,7 @@ 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;
int s = mpa->allocated[n] / mpa->sstride;
size = n == 0 ? s : MPMIN(size, s);
}
return size;
@@ -227,14 +230,6 @@ void mp_audio_copy(struct mp_audio *dst, int dst_offset,
}
}
// Copy fields that describe characteristics of the audio frame, but which are
// not part of the core format (format/channels/rate), and not part of the
// data (samples).
void mp_audio_copy_attributes(struct mp_audio *dst, struct mp_audio *src)
{
// nothing yet
}
// Set data to the audio after the given number of samples (i.e. slice it).
void mp_audio_skip_samples(struct mp_audio *data, int samples)
{
@@ -245,177 +240,3 @@ void mp_audio_skip_samples(struct mp_audio *data, int samples)
data->samples -= samples;
}
// Return false if the frame data is shared, true otherwise.
// Will return true for non-refcounted frames.
bool mp_audio_is_writeable(struct mp_audio *data)
{
bool ok = true;
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
if (data->allocated[n])
ok &= av_buffer_is_writable(data->allocated[n]);
}
return ok;
}
static void mp_audio_steal_data(struct mp_audio *dst, struct mp_audio *src)
{
talloc_set_destructor(dst, mp_audio_destructor);
mp_audio_destructor(dst);
*dst = *src;
talloc_set_destructor(src, NULL);
talloc_free(src);
}
// Make sure the frame owns the audio data, and if not, copy the data.
// Return negative value on failure (which means it can't be made writeable).
// Non-refcounted frames are always considered writeable.
int mp_audio_make_writeable(struct mp_audio *data)
{
if (!mp_audio_is_writeable(data)) {
struct mp_audio *new = talloc(NULL, struct mp_audio);
*new = *data;
mp_audio_set_null_data(new); // use format only
mp_audio_realloc(new, data->samples);
new->samples = data->samples;
mp_audio_copy(new, 0, data, 0, data->samples);
mp_audio_steal_data(data, new);
}
return 0;
}
struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe)
{
AVFrame *tmp = NULL;
struct mp_audio *new = talloc_zero(NULL, struct mp_audio);
talloc_set_destructor(new, mp_audio_destructor);
mp_audio_set_format(new, af_from_avformat(avframe->format));
struct mp_chmap lavc_chmap;
mp_chmap_from_lavc(&lavc_chmap, avframe->channel_layout);
#if LIBAVUTIL_VERSION_MICRO >= 100
// FFmpeg being special again
if (lavc_chmap.num != avframe->channels)
mp_chmap_from_channels(&lavc_chmap, avframe->channels);
#endif
new->rate = avframe->sample_rate;
mp_audio_set_channels(new, &lavc_chmap);
// Force refcounted frame.
if (!avframe->buf[0]) {
tmp = av_frame_alloc();
if (!tmp)
goto fail;
if (av_frame_ref(tmp, avframe) < 0)
goto fail;
avframe = tmp;
}
// If we can't handle the format (e.g. too many channels), bail out.
if (!mp_audio_config_valid(new) || avframe->nb_extended_buf)
goto fail;
for (int n = 0; n < AV_NUM_DATA_POINTERS; n++) {
if (!avframe->buf[n])
break;
if (n >= MP_NUM_CHANNELS)
goto fail;
new->allocated[n] = av_buffer_ref(avframe->buf[n]);
if (!new->allocated[n])
goto fail;
}
for (int n = 0; n < new->num_planes; n++)
new->planes[n] = avframe->data[n];
new->samples = avframe->nb_samples;
return new;
fail:
talloc_free(new);
av_frame_free(&tmp);
return NULL;
}
struct mp_audio_pool {
AVBufferPool *avpool;
int element_size;
};
struct mp_audio_pool *mp_audio_pool_create(void *ta_parent)
{
return talloc_zero(ta_parent, struct mp_audio_pool);
}
static void mp_audio_pool_destructor(void *p)
{
struct mp_audio_pool *pool = p;
av_buffer_pool_uninit(&pool->avpool);
}
// Allocate data using the given format and number of samples.
// Returns NULL on error.
struct mp_audio *mp_audio_pool_get(struct mp_audio_pool *pool,
const struct mp_audio *fmt, int samples)
{
int size = get_plane_size(fmt, samples);
if (size < 0)
return NULL;
if (!pool->avpool || size > pool->element_size) {
size_t alloc = ta_calc_prealloc_elems(size);
if (alloc >= INT_MAX)
return NULL;
av_buffer_pool_uninit(&pool->avpool);
pool->element_size = alloc;
pool->avpool = av_buffer_pool_init(pool->element_size, NULL);
if (!pool->avpool)
return NULL;
talloc_set_destructor(pool, mp_audio_pool_destructor);
}
struct mp_audio *new = talloc_ptrtype(NULL, new);
talloc_set_destructor(new, mp_audio_destructor);
*new = *fmt;
mp_audio_set_null_data(new);
new->samples = samples;
for (int n = 0; n < new->num_planes; n++) {
new->allocated[n] = av_buffer_pool_get(pool->avpool);
if (!new->allocated[n]) {
talloc_free(new);
return NULL;
}
new->planes[n] = new->allocated[n]->data;
}
return new;
}
// Return a copy of the given frame.
// Returns NULL on error.
struct mp_audio *mp_audio_pool_new_copy(struct mp_audio_pool *pool,
struct mp_audio *frame)
{
struct mp_audio *new = mp_audio_pool_get(pool, frame, frame->samples);
if (new) {
mp_audio_copy(new, 0, frame, 0, new->samples);
mp_audio_copy_attributes(new, frame);
}
return new;
}
// Exactly like mp_audio_make_writeable(), but get the data from the pool.
int mp_audio_pool_make_writeable(struct mp_audio_pool *pool,
struct mp_audio *data)
{
if (mp_audio_is_writeable(data))
return 0;
struct mp_audio *new = mp_audio_pool_get(pool, data, data->samples);
if (!new)
return -1;
mp_audio_copy(new, 0, data, 0, data->samples);
mp_audio_copy_attributes(new, data);
mp_audio_steal_data(data, new);
return 0;
}
+4 -20
View File
@@ -35,10 +35,10 @@ 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_fmt2bits(format) / 8)
// private
struct AVBufferRef *allocated[MP_NUM_CHANNELS];
int allocated[MP_NUM_CHANNELS]; // use mp_audio_get_allocated_size()
};
void mp_audio_set_format(struct mp_audio *mpa, int format);
@@ -49,8 +49,8 @@ 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);
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);
#define mp_audio_config_to_str(m) mp_audio_config_to_str_buf((char[64]){0}, 64, (m))
char *mp_audio_fmt_to_str(int srate, const struct mp_chmap *chmap, int format);
char *mp_audio_config_to_str(struct mp_audio *mpa);
void mp_audio_force_interleaved_format(struct mp_audio *mpa);
@@ -66,22 +66,6 @@ void mp_audio_fill_silence(struct mp_audio *mpa, int start, int length);
void mp_audio_copy(struct mp_audio *dst, int dst_offset,
struct mp_audio *src, int src_offset, int length);
void mp_audio_copy_attributes(struct mp_audio *dst, struct mp_audio *src);
void mp_audio_skip_samples(struct mp_audio *data, int samples);
bool mp_audio_is_writeable(struct mp_audio *data);
int mp_audio_make_writeable(struct mp_audio *data);
struct AVFrame;
struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe);
struct mp_audio_pool;
struct mp_audio_pool *mp_audio_pool_create(void *ta_parent);
struct mp_audio *mp_audio_pool_get(struct mp_audio_pool *pool,
const struct mp_audio *fmt, int samples);
struct mp_audio *mp_audio_pool_new_copy(struct mp_audio_pool *pool,
struct mp_audio *frame);
int mp_audio_pool_make_writeable(struct mp_audio_pool *pool,
struct mp_audio *frame);
#endif
+15 -44
View File
@@ -18,13 +18,12 @@
#include <stdlib.h>
#include <assert.h>
#include "common/common.h"
#include "common/msg.h"
#include "chmap.h"
// Names taken from libavutil/channel_layout.c (Not accessible by API.)
// Use of these names is hard-coded in some places (e.g. ao_alsa.c)
static const char *const speaker_names[MP_SPEAKER_ID_COUNT][2] = {
static const char *speaker_names[MP_SPEAKER_ID_COUNT][2] = {
[MP_SPEAKER_ID_FL] = {"fl", "front left"},
[MP_SPEAKER_ID_FR] = {"fr", "front right"},
[MP_SPEAKER_ID_FC] = {"fc", "front center"},
@@ -54,12 +53,10 @@ static const char *const speaker_names[MP_SPEAKER_ID_COUNT][2] = {
// Names taken from libavutil/channel_layout.c (Not accessible by API.)
// Channel order corresponds to lavc/waveex, except for the alsa entries.
static const char *const std_layout_names[][2] = {
static const char *std_layout_names[][2] = {
{"empty", ""}, // not in lavc
{"mono", "fc"},
{"1.0", "fc"}, // not in lavc
{"stereo", "fl-fr"},
{"2.0", "fl-fr"}, // not in lavc
{"2.1", "fl-fr-lfe"},
{"3.0", "fl-fr-fc"},
{"3.0(back)", "fl-fr-bc"},
@@ -87,10 +84,8 @@ static const char *const std_layout_names[][2] = {
{"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"},
{"octagonal", "fl-fr-fc-bl-br-bc-sl-sr"},
{"downmix", "dl-dr"},
{"auto", ""}, // not in lavc
{0}
};
@@ -110,7 +105,7 @@ static const struct mp_chmap default_layouts[MP_NUM_CHANNELS + 1] = {
// 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] = {
static const char *mplayer_layouts[MP_NUM_CHANNELS + 1] = {
[1] = "mono",
[2] = "stereo",
[4] = "quad",
@@ -377,61 +372,37 @@ void mp_chmap_get_reorder(int dst[MP_NUM_CHANNELS], const struct mp_chmap *from,
assert(to->speaker[dst[n]] == from->speaker[n]);
}
// Performs the difference between a and b, and store it in diff. If b has
// channels that do not appear in a, those will not appear in the difference.
// To get to those the argument ordering in the function call has to be
// inverted. For the same reason, the diff with a superset will return no
// speakers.
void mp_chmap_diff(const struct mp_chmap *a, const struct mp_chmap *b,
struct mp_chmap *diff)
{
uint64_t a_mask = mp_chmap_to_lavc_unchecked(a);
uint64_t b_mask = mp_chmap_to_lavc_unchecked(b);
mp_chmap_from_lavc(diff, (a_mask ^ b_mask) & a_mask);
}
// Checks whether a contains all the speakers in b
bool mp_chmap_contains(const struct mp_chmap *a, const struct mp_chmap *b)
{
struct mp_chmap d1;
struct mp_chmap d2;
mp_chmap_diff(a, b, &d1);
mp_chmap_diff(b, a, &d2);
return a->num >= b->num && d1.num >= 0 && d2.num == 0;
}
// Returns something like "fl-fr-fc". If there's a standard layout in lavc
// order, return that, e.g. "3.0" instead of "fl-fr-fc".
// Unassigned but valid speakers get names like "sp28".
char *mp_chmap_to_str_buf(char *buf, size_t buf_size, const struct mp_chmap *src)
char *mp_chmap_to_str(const struct mp_chmap *src)
{
buf[0] = '\0';
char *res = talloc_strdup(NULL, "");
if (mp_chmap_is_unknown(src)) {
snprintf(buf, buf_size, "unknown%d", src->num);
return buf;
}
if (mp_chmap_is_unknown(src))
return talloc_asprintf_append_buffer(res, "unknown%d", src->num);
for (int n = 0; n < src->num; n++) {
int sp = src->speaker[n];
const char *s = sp < MP_SPEAKER_ID_COUNT ? speaker_names[sp][0] : NULL;
char sp_buf[10];
char buf[10];
if (!s) {
snprintf(sp_buf, sizeof(sp_buf), "sp%d", sp);
s = sp_buf;
snprintf(buf, sizeof(buf), "sp%d", sp);
s = buf;
}
mp_snprintf_cat(buf, buf_size, "%s%s", n > 0 ? "-" : "", s);
res = talloc_asprintf_append_buffer(res, "%s%s", n > 0 ? "-" : "", s);
}
// To standard layout name
for (int n = 0; std_layout_names[n][0]; n++) {
if (strcmp(buf, std_layout_names[n][1]) == 0) {
snprintf(buf, buf_size, "%s", std_layout_names[n][0]);
if (res && strcmp(res, std_layout_names[n][1]) == 0) {
talloc_free(res);
res = talloc_strdup(NULL, std_layout_names[n][0]);
break;
}
}
return buf;
return res;
}
// If src can be parsed as channel map (as produced by mp_chmap_to_str()),
+4 -12
View File
@@ -20,14 +20,14 @@
#include <inttypes.h>
#include <stdbool.h>
#include "misc/bstr.h"
#include "bstr/bstr.h"
#define MP_NUM_CHANNELS 8
// Speaker a channel can be assigned to.
// This corresponds to WAVEFORMATEXTENSIBLE channel mask bit indexes.
// E.g. channel_mask = (1 << MP_SPEAKER_ID_FL) | ...
enum mp_speaker_id {
enum {
// Official WAVEFORMATEXTENSIBLE (shortened names)
MP_SPEAKER_ID_FL = 0, // FRONT_LEFT
MP_SPEAKER_ID_FR, // FRONT_RIGHT
@@ -61,8 +61,7 @@ enum mp_speaker_id {
MP_SPEAKER_ID_UNKNOWN0 = 64,
MP_SPEAKER_ID_UNKNOWN_LAST = MP_SPEAKER_ID_UNKNOWN0 + MP_NUM_CHANNELS - 1,
// Including the unassigned IDs in between. This is not a valid ID anymore,
// but is still within uint8_t.
// Including the unassigned IDs in between. This is not a valid ID anymore.
MP_SPEAKER_ID_COUNT,
};
@@ -120,14 +119,7 @@ void mp_chmap_reorder_to_lavc(struct mp_chmap *map);
void mp_chmap_get_reorder(int dst[MP_NUM_CHANNELS], const struct mp_chmap *from,
const struct mp_chmap *to);
void mp_chmap_diff(const struct mp_chmap *a, const struct mp_chmap *b,
struct mp_chmap *diff);
bool mp_chmap_contains(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(const struct mp_chmap *src);
bool mp_chmap_from_str(struct mp_chmap *dst, bstr src);
struct mp_log;
+27 -132
View File
@@ -17,23 +17,22 @@
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include "common/common.h"
#include "chmap_sel.h"
static const struct mp_chmap speaker_replacements[][2] = {
// 5.1 <-> 5.1 (side)
{ MP_CHMAP2(SL, SR), MP_CHMAP2(BL, BR) },
// 7.1 <-> 7.1 (rear ext)
{ MP_CHMAP2(SL, SR), MP_CHMAP2(SDL, SDR) },
// 5.1 and 5.1(side) are practically the same. It doesn't make much sense to
// reject either of them.
static const int replaceable_speakers[][2] = {
{MP_SPEAKER_ID_SL, MP_SPEAKER_ID_BL},
{MP_SPEAKER_ID_SR, MP_SPEAKER_ID_BR},
{-1},
};
// Try to replace speakers from the left of the list with the ones on the
// right, or the other way around.
static bool replace_speakers(struct mp_chmap *map, struct mp_chmap list[2])
// list[] contains a list of speaker pairs, with each pair indicating how
// a speaker can be swapped for another speaker. Try to replace speakers from
// the left of the list with the ones on the right, or the other way around.
static bool replace_speakers(struct mp_chmap *map, const int list[][2])
{
assert(list[0].num == list[1].num);
if (!mp_chmap_is_valid(map))
return false;
for (int dir = 0; dir < 2; dir++) {
@@ -42,9 +41,9 @@ static bool replace_speakers(struct mp_chmap *map, struct mp_chmap list[2])
bool replaced = false;
struct mp_chmap t = *map;
for (int n = 0; n < t.num; n++) {
for (int i = 0; i < list[0].num; i++) {
if (t.speaker[n] == list[from].speaker[i]) {
t.speaker[n] = list[to].speaker[i];
for (int i = 0; list[i][0] != -1; i++) {
if (t.speaker[n] == list[i][from]) {
t.speaker[n] = list[i][to];
replaced = true;
break;
}
@@ -74,7 +73,7 @@ void mp_chmap_sel_add_waveext(struct mp_chmap_sel *s)
// 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++) {
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
struct mp_chmap t;
mp_chmap_from_channels_alsa(&t, n);
if (t.num)
@@ -82,27 +81,20 @@ void mp_chmap_sel_add_alsa_def(struct mp_chmap_sel *s)
}
}
#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
// Add a channel map that should be allowed.
void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *map)
{
if (!mp_chmap_is_valid(map))
return;
if (!s->chmaps)
s->chmaps = s->chmaps_storage;
if (s->num_chmaps == MP_ARRAY_SIZE(s->chmaps_storage)) {
if (!s->tmp)
return;
s->chmaps = talloc_memdup(s->tmp, s->chmaps, sizeof(s->chmaps_storage));
}
if (s->chmaps != s->chmaps_storage)
MP_TARRAY_GROW(s->tmp, s->chmaps, s->num_chmaps);
s->chmaps[s->num_chmaps++] = *map;
assert(s->num_chmaps < ARRAY_LEN(s->chmaps));
if (mp_chmap_is_valid(map))
s->chmaps[s->num_chmaps++] = *map;
}
// Allow all waveext formats in default order.
void mp_chmap_sel_add_waveext_def(struct mp_chmap_sel *s)
{
for (int n = 1; n <= MP_NUM_CHANNELS; n++) {
for (int n = 1; n < MP_NUM_CHANNELS; n++) {
struct mp_chmap map;
mp_chmap_from_channels(&map, n);
mp_chmap_sel_add_map(s, &map);
@@ -176,118 +168,21 @@ bool mp_chmap_sel_adjust(const struct mp_chmap_sel *s, struct mp_chmap *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];
if (replace_speakers(&t, r) && test_layout(s, &t)) {
*map = t;
return true;
}
}
if (mp_chmap_sel_fallback(s, map))
// 5.1 <-> 5.1(side)
if (replace_speakers(map, replaceable_speakers) && test_layout(s, map))
return true;
// Fallback to mono/stereo as last resort
*map = (struct mp_chmap) MP_CHMAP_INIT_STEREO;
if (test_layout(s, map))
return true;
*map = (struct mp_chmap) MP_CHMAP_INIT_MONO;
if (map->num == 1) {
*map = (struct mp_chmap) MP_CHMAP_INIT_MONO;
} else if (map->num >= 2) {
*map = (struct mp_chmap) MP_CHMAP_INIT_STEREO;
}
if (test_layout(s, map))
return true;
*map = (struct mp_chmap) {0};
return false;
}
#define UPMIX_IDX 0
#define DOWNMIX_IDX 1
#define FALLBACK_IDX 2
static bool test_fallbacks(struct mp_chmap *a, struct mp_chmap *b,
int best_diffs[2], struct mp_chmap best[2])
{
struct mp_chmap diff1, diff2;
mp_chmap_diff(a, b, &diff1);
if (mp_chmap_contains(a, b) && best_diffs[UPMIX_IDX] > diff1.num) {
best[UPMIX_IDX] = *a;
best_diffs[UPMIX_IDX] = diff1.num;
return true;
}
mp_chmap_diff(b, a, &diff2);
if (mp_chmap_contains(b, a) && best_diffs[DOWNMIX_IDX] > diff2.num) {
best[DOWNMIX_IDX] = *a;
best_diffs[DOWNMIX_IDX] = diff2.num;
return true;
}
if (diff1.num > 0 && best_diffs[FALLBACK_IDX] > diff1.num) {
best[FALLBACK_IDX] = *a;
best_diffs[FALLBACK_IDX] = diff1.num;
return true;
}
if (diff2.num > 0 && best_diffs[FALLBACK_IDX] > diff2.num) {
best[FALLBACK_IDX] = *a;
best_diffs[FALLBACK_IDX] = diff2.num;
return true;
}
return false;
}
// Determine which channel map to fallback to given a source channel map. It
// uses the following heuristic:
// 1) If mono is required always prefer stereo to a multichannel upmix.
// 2) Search for an upmix that is an exact superset of the required chmap.
// 3) Search for a downmix that is the exact subset of the required chmap.
// 4) Search for either an upmix or downmix that is the closest (minimum
// difference of speakers) to the required chmap.
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;
}
int best_diffs[] = { INT_MAX, INT_MAX, INT_MAX };
struct mp_chmap best[] = { {0}, {0}, {0} };
for (int n = 0; n < s->num_chmaps; n++) {
struct mp_chmap e = s->chmaps[n];
if (mp_chmap_is_unknown(&e))
continue;
if (test_fallbacks(&e, map, best_diffs, best))
continue;
// in case we didn't match any fallback retry after replacing speakers
for (int i = 0; i < MP_ARRAY_SIZE(speaker_replacements); i++) {
struct mp_chmap t = e;
struct mp_chmap *r = (struct mp_chmap *)speaker_replacements[i];
if (replace_speakers(&t, r)) {
if (test_fallbacks(&t, map, best_diffs, best))
continue;
}
}
}
for (int i = UPMIX_IDX; i < MP_ARRAY_SIZE(best); i++) {
if (best_diffs[i] < INT_MAX) {
*map = best[i];
return true;
}
}
return false;
}
// Set map to a default layout with num channels. Used for audio APIs that
// return a channel count as part of format negotiation, but give no
// information about the channel layout.
+1 -6
View File
@@ -26,12 +26,8 @@ struct mp_chmap_sel {
// should be considered opaque
bool allow_any, allow_waveext;
bool speakers[MP_SPEAKER_ID_COUNT];
struct mp_chmap *chmaps;
struct mp_chmap chmaps[20];
int num_chmaps;
struct mp_chmap chmaps_storage[20];
void *tmp; // set to any talloc context to allow more chmaps entries
};
void mp_chmap_sel_add_any(struct mp_chmap_sel *s);
@@ -41,7 +37,6 @@ 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);
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);
+6 -5
View File
@@ -1,18 +1,19 @@
/*
* This file is part of mpv.
* This file is part of MPlayer.
*
* mpv is free software; you can redistribute it and/or modify
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPLAYER_AD_H
@@ -35,7 +36,7 @@ struct ad_functions {
int (*init)(struct dec_audio *da, const char *decoder);
void (*uninit)(struct dec_audio *da);
int (*control)(struct dec_audio *da, int cmd, void *arg);
int (*decode_packet)(struct dec_audio *da, struct mp_audio **out);
int (*decode_audio)(struct dec_audio *da, struct mp_audio *buffer, int maxlen);
};
enum ad_ctrl {
+216 -90
View File
@@ -1,18 +1,19 @@
/*
* This file is part of mpv.
* This file is part of MPlayer.
*
* mpv is free software; you can redistribute it and/or modify
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
@@ -24,7 +25,6 @@
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libavutil/common.h>
#include <libavutil/intreadwrite.h>
#include "talloc.h"
@@ -33,49 +33,153 @@
#include "common/codecs.h"
#include "common/msg.h"
#include "options/options.h"
#include "common/av_opts.h"
#include "ad.h"
#include "audio/fmt-conversion.h"
#include "compat/libav.h"
struct priv {
AVCodecContext *avctx;
AVFrame *avframe;
struct mp_audio frame;
bool force_channel_map;
struct demux_packet *packet;
uint32_t skip_samples;
};
static void uninit(struct dec_audio *da);
static int decode_new_packet(struct dec_audio *da);
#define OPT_BASE_STRUCT struct ad_lavc_params
struct ad_lavc_params {
float ac3drc;
int downmix;
int threads;
char **avopts;
#define OPT_BASE_STRUCT struct MPOpts
const m_option_t ad_lavc_decode_opts_conf[] = {
OPT_FLOATRANGE("ac3drc", ad_lavc_param.ac3drc, 0, 0, 2),
OPT_FLAG("downmix", ad_lavc_param.downmix, 0),
OPT_INTRANGE("threads", ad_lavc_param.threads, 0, 1, 16),
OPT_STRING("o", ad_lavc_param.avopt, 0),
{0}
};
const struct m_sub_options ad_lavc_conf = {
.opts = (const m_option_t[]) {
OPT_FLOATRANGE("ac3drc", ac3drc, 0, 0, 6),
OPT_FLAG("downmix", downmix, 0),
OPT_INTRANGE("threads", threads, 0, 1, 16),
OPT_KEYVALUELIST("o", avopts, 0),
{0}
},
.size = sizeof(struct ad_lavc_params),
.defaults = &(const struct ad_lavc_params){
.ac3drc = 0,
.downmix = 1,
.threads = 1,
},
struct pcm_map
{
int tag;
const char *codecs[6]; // {any, 1byte, 2bytes, 3bytes, 4bytes, 8bytes}
};
// NOTE: these are needed to make rawaudio with demux_mkv work.
static const struct pcm_map tag_map[] = {
// Microsoft PCM
{0x0, {NULL, "pcm_u8", "pcm_s16le", "pcm_s24le", "pcm_s32le"}},
{0x1, {NULL, "pcm_u8", "pcm_s16le", "pcm_s24le", "pcm_s32le"}},
// MS PCM, Extended
{0xfffe, {NULL, "pcm_u8", "pcm_s16le", "pcm_s24le", "pcm_s32le"}},
// IEEE float
{0x3, {"pcm_f32le", [5] = "pcm_f64le"}},
// 'raw '
{0x20776172, {"pcm_s16be", [1] = "pcm_u8"}},
// 'twos', used by demux_mkv.c internally
{MKTAG('t', 'w', 'o', 's'),
{NULL, "pcm_s8", "pcm_s16be", "pcm_s24be", "pcm_s32be"}},
{-1},
};
// For demux_rawaudio.c; needed because ffmpeg doesn't have these sample
// formats natively.
static const struct pcm_map af_map[] = {
{AF_FORMAT_U8, {"pcm_u8"}},
{AF_FORMAT_S8, {"pcm_u8"}},
{AF_FORMAT_U16_LE, {"pcm_u16le"}},
{AF_FORMAT_U16_BE, {"pcm_u16be"}},
{AF_FORMAT_S16_LE, {"pcm_s16le"}},
{AF_FORMAT_S16_BE, {"pcm_s16be"}},
{AF_FORMAT_U24_LE, {"pcm_u24le"}},
{AF_FORMAT_U24_BE, {"pcm_u24be"}},
{AF_FORMAT_S24_LE, {"pcm_s24le"}},
{AF_FORMAT_S24_BE, {"pcm_s24be"}},
{AF_FORMAT_U32_LE, {"pcm_u32le"}},
{AF_FORMAT_U32_BE, {"pcm_u32be"}},
{AF_FORMAT_S32_LE, {"pcm_s32le"}},
{AF_FORMAT_S32_BE, {"pcm_s32be"}},
{AF_FORMAT_FLOAT_LE, {"pcm_f32le"}},
{AF_FORMAT_FLOAT_BE, {"pcm_f32be"}},
{AF_FORMAT_DOUBLE_LE, {"pcm_f64le"}},
{AF_FORMAT_DOUBLE_BE, {"pcm_f64be"}},
{-1},
};
static const char *find_pcm_decoder(const struct pcm_map *map, int format,
int bits_per_sample)
{
int bytes = (bits_per_sample + 7) / 8;
if (bytes == 8)
bytes = 5; // 64 bit entry
for (int n = 0; map[n].tag != -1; n++) {
const struct pcm_map *entry = &map[n];
if (entry->tag == format) {
const char *dec = NULL;
if (bytes >= 1 && bytes <= 5)
dec = entry->codecs[bytes];
if (!dec)
dec = entry->codecs[0];
if (dec)
return dec;
}
}
return NULL;
}
static int setup_format(struct dec_audio *da)
{
struct priv *priv = da->priv;
AVCodecContext *lavc_context = priv->avctx;
struct sh_audio *sh_audio = da->header->audio;
// Note: invalid parameters are rejected by dec_audio.c
int fmt = lavc_context->sample_fmt;
mp_audio_set_format(&da->decoded, af_from_avformat(fmt));
if (!da->decoded.format)
MP_FATAL(da, "unsupported lavc format %s", av_get_sample_fmt_name(fmt));
da->decoded.rate = lavc_context->sample_rate;
if (!da->decoded.rate && sh_audio->wf) {
// If not set, try container samplerate.
// (Maybe this can't happen, and it's an artifact from the past.)
da->decoded.rate = sh_audio->wf->nSamplesPerSec;
MP_WARN(da, "using container rate.\n");
}
struct mp_chmap lavc_chmap;
mp_chmap_from_lavc(&lavc_chmap, lavc_context->channel_layout);
// No channel layout or layout disagrees with channel count
if (lavc_chmap.num != lavc_context->channels)
mp_chmap_from_channels(&lavc_chmap, lavc_context->channels);
if (priv->force_channel_map) {
if (lavc_chmap.num == sh_audio->channels.num)
lavc_chmap = sh_audio->channels;
}
mp_audio_set_channels(&da->decoded, &lavc_chmap);
return 0;
}
static void set_from_wf(AVCodecContext *avctx, MP_WAVEFORMATEX *wf)
{
avctx->channels = wf->nChannels;
avctx->sample_rate = wf->nSamplesPerSec;
avctx->bit_rate = wf->nAvgBytesPerSec * 8;
avctx->block_align = wf->nBlockAlign;
avctx->bits_per_coded_sample = wf->wBitsPerSample;
if (wf->cbSize > 0)
mp_lavc_set_extradata(avctx, wf + 1, wf->cbSize);
}
static int init(struct dec_audio *da, const char *decoder)
{
struct MPOpts *mpopts = da->opts;
struct ad_lavc_params *opts = mpopts->ad_lavc_params;
struct ad_lavc_param *opts = &mpopts->ad_lavc_param;
AVCodecContext *lavc_context;
AVCodec *lavc_codec;
struct sh_stream *sh = da->header;
@@ -84,7 +188,13 @@ static int init(struct dec_audio *da, const char *decoder)
struct priv *ctx = talloc_zero(NULL, struct priv);
da->priv = ctx;
ctx->force_channel_map = sh_audio->force_channels;
if (sh_audio->wf && strcmp(decoder, "pcm") == 0) {
decoder = find_pcm_decoder(tag_map, sh->format,
sh_audio->wf->wBitsPerSample);
} else if (sh_audio->wf && strcmp(decoder, "mp-pcm") == 0) {
decoder = find_pcm_decoder(af_map, sh->format, 0);
ctx->force_channel_map = true;
}
lavc_codec = avcodec_find_decoder_by_name(decoder);
if (!lavc_codec) {
@@ -95,37 +205,40 @@ static int init(struct dec_audio *da, const char *decoder)
lavc_context = avcodec_alloc_context3(lavc_codec);
ctx->avctx = lavc_context;
ctx->avframe = av_frame_alloc();
lavc_context->refcounted_frames = 1;
ctx->avframe = avcodec_alloc_frame();
lavc_context->codec_type = AVMEDIA_TYPE_AUDIO;
lavc_context->codec_id = lavc_codec->id;
if (opts->downmix) {
lavc_context->request_channel_layout =
mp_chmap_to_lavc(&mpopts->audio_output_channels);
// Compatibility for Libav 9
av_opt_set_int(lavc_context, "request_channels",
mpopts->audio_output_channels.num,
AV_OPT_SEARCH_CHILDREN);
}
// Always try to set - option only exists for AC3 at the moment
av_opt_set_double(lavc_context, "drc_scale", opts->ac3drc,
AV_OPT_SEARCH_CHILDREN);
#if HAVE_AVFRAME_SKIP_SAMPLES
// Let decoder add AV_FRAME_DATA_SKIP_SAMPLES.
av_opt_set(lavc_context, "flags2", "+skip_manual", AV_OPT_SEARCH_CHILDREN);
#endif
mp_set_avopts(da->log, lavc_context, opts->avopts);
if (opts->avopt) {
if (parse_avopts(lavc_context, opts->avopt) < 0) {
MP_ERR(da, "setting AVOptions '%s' failed.\n", opts->avopt);
uninit(da);
return 0;
}
}
lavc_context->codec_tag = sh->format;
lavc_context->sample_rate = sh_audio->samplerate;
lavc_context->bit_rate = sh_audio->bitrate;
lavc_context->block_align = sh_audio->block_align;
lavc_context->bits_per_coded_sample = sh_audio->bits_per_coded_sample;
lavc_context->channels = sh_audio->channels.num;
if (!mp_chmap_is_unknown(&sh_audio->channels))
lavc_context->channel_layout = mp_chmap_to_lavc(&sh_audio->channels);
lavc_context->bit_rate = sh_audio->i_bps * 8;
lavc_context->channel_layout = mp_chmap_to_lavc(&sh_audio->channels);
// demux_mkv
if (sh_audio->wf)
set_from_wf(lavc_context, sh_audio->wf);
// demux_mkv, demux_mpg
if (sh_audio->codecdata_len && sh_audio->codecdata &&
!lavc_context->extradata) {
mp_lavc_set_extradata(lavc_context, sh_audio->codecdata,
@@ -135,7 +248,7 @@ static int init(struct dec_audio *da, const char *decoder)
if (sh->lav_headers)
mp_copy_lav_codec_headers(lavc_context, sh->lav_headers);
mp_set_avcodec_threads(da->log, lavc_context, opts->threads);
mp_set_avcodec_threads(lavc_context, opts->threads);
/* open it */
if (avcodec_open2(lavc_context, lavc_codec, NULL) < 0) {
@@ -143,6 +256,26 @@ static int init(struct dec_audio *da, const char *decoder)
uninit(da);
return 0;
}
MP_VERBOSE(da, "INFO: libavcodec \"%s\" init OK!\n",
lavc_codec->name);
// Decode at least 1 sample: (to get header filled)
for (int tries = 1; ; tries++) {
int x = decode_new_packet(da);
if (x >= 0 && ctx->frame.samples > 0) {
MP_VERBOSE(da, "Initial decode succeeded after %d packets.\n", tries);
break;
}
if (tries >= 50) {
MP_ERR(da, "initial decode failed\n");
uninit(da);
return 0;
}
}
da->i_bps = lavc_context->bit_rate / 8;
if (sh_audio->wf && sh_audio->wf->nAvgBytesPerSec)
da->i_bps = sh_audio->wf->nAvgBytesPerSec;
return 1;
}
@@ -160,7 +293,7 @@ static void uninit(struct dec_audio *da)
av_freep(&lavc_context->extradata);
av_freep(&lavc_context);
}
av_frame_free(&ctx->avframe);
avcodec_free_frame(&ctx->avframe);
}
static int control(struct dec_audio *da, int cmd, void *arg)
@@ -169,24 +302,24 @@ static int control(struct dec_audio *da, int cmd, void *arg)
switch (cmd) {
case ADCTRL_RESET:
avcodec_flush_buffers(ctx->avctx);
ctx->frame.samples = 0;
talloc_free(ctx->packet);
ctx->packet = NULL;
ctx->skip_samples = 0;
return CONTROL_TRUE;
}
return CONTROL_UNKNOWN;
}
static int decode_packet(struct dec_audio *da, struct mp_audio **out)
static int decode_new_packet(struct dec_audio *da)
{
struct priv *priv = da->priv;
AVCodecContext *avctx = priv->avctx;
priv->frame.samples = 0;
struct demux_packet *mpkt = priv->packet;
if (!mpkt) {
if (demux_read_packet_async(da->header, &mpkt) == 0)
return AD_WAIT;
}
if (!mpkt)
mpkt = demux_read_packet(da->header);
priv->packet = talloc_steal(priv, mpkt);
@@ -202,7 +335,6 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
}
int got_frame = 0;
av_frame_unref(priv->avframe);
int ret = avcodec_decode_audio4(avctx, priv->avframe, &got_frame, &pkt);
if (mpkt) {
// At least "shorten" decodes sub-frames, instead of the whole packet.
@@ -219,14 +351,22 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
}
// LATM may need many packets to find mux info
if (ret == AVERROR(EAGAIN))
return AD_OK;
return 0;
}
if (ret < 0) {
MP_ERR(da, "Error decoding audio.\n");
return AD_ERR;
MP_VERBOSE(da, "lavc_audio: error\n");
return -1;
}
if (!got_frame)
return mpkt ? AD_OK : AD_EOF;
return mpkt ? 0 : -1; // -1: eof
if (setup_format(da) < 0)
return -1;
priv->frame.samples = priv->avframe->nb_samples;
mp_audio_copy_config(&priv->frame, &da->decoded);
for (int n = 0; n < priv->frame.num_planes; n++)
priv->frame.planes[n] = priv->avframe->data[n];
double out_pts = mp_pts_from_av(priv->avframe->pkt_pts, NULL);
if (out_pts != MP_NOPTS_VALUE) {
@@ -234,49 +374,35 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
da->pts_offset = 0;
}
struct mp_audio *mpframe = mp_audio_from_avframe(priv->avframe);
if (!mpframe)
return AD_ERR;
MP_DBG(da, "Decoded %d -> %d samples\n", in_len,
priv->frame.samples);
return 0;
}
struct mp_chmap lavc_chmap = mpframe->channels;
if (lavc_chmap.num != avctx->channels)
mp_chmap_from_channels(&lavc_chmap, avctx->channels);
if (priv->force_channel_map) {
struct sh_audio *sh_audio = da->header->audio;
if (lavc_chmap.num == sh_audio->channels.num)
lavc_chmap = sh_audio->channels;
static int decode_audio(struct dec_audio *da, struct mp_audio *buffer, int maxlen)
{
struct priv *priv = da->priv;
if (!priv->frame.samples) {
if (decode_new_packet(da) < 0)
return -1;
}
mp_audio_set_channels(mpframe, &lavc_chmap);
#if HAVE_AVFRAME_SKIP_SAMPLES
AVFrameSideData *sd =
av_frame_get_side_data(priv->avframe, AV_FRAME_DATA_SKIP_SAMPLES);
if (sd && sd->size >= 10) {
char *d = sd->data;
priv->skip_samples += AV_RL32(d + 0);
uint32_t pad = AV_RL32(d + 4);
uint32_t skip = MPMIN(priv->skip_samples, mpframe->samples);
if (skip) {
mp_audio_skip_samples(mpframe, skip);
da->pts_offset += skip;
priv->skip_samples -= skip;
}
if (pad <= mpframe->samples)
mpframe->samples -= pad;
}
#endif
if (!mp_audio_config_equals(buffer, &priv->frame))
return 0;
*out = mpframe;
av_frame_unref(priv->avframe);
MP_DBG(da, "Decoded %d -> %d samples\n", in_len, mpframe->samples);
buffer->samples = MPMIN(priv->frame.samples, maxlen);
mp_audio_copy(buffer, 0, &priv->frame, 0, buffer->samples);
mp_audio_skip_samples(&priv->frame, buffer->samples);
da->pts_offset += buffer->samples;
return 0;
}
static void add_decoders(struct mp_decoder_list *list)
{
mp_add_lavc_decoders(list, AVMEDIA_TYPE_AUDIO);
mp_add_decoder(list, "lavc", "pcm", "pcm", "Raw PCM");
mp_add_decoder(list, "lavc", "mp-pcm", "mp-pcm", "Raw PCM");
}
const struct ad_functions ad_lavc = {
@@ -285,5 +411,5 @@ const struct ad_functions ad_lavc = {
.init = init,
.uninit = uninit,
.control = control,
.decode_packet = decode_packet,
.decode_audio = decode_audio,
};
+375
View File
@@ -0,0 +1,375 @@
/*
* MPEG 1.0/2.0/2.5 audio layer I, II, III decoding with libmpg123
*
* Copyright (C) 2010-2013 Thomas Orgis <thomas@orgis.org>
*
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "config.h"
#include "ad.h"
#include "common/msg.h"
#include <mpg123.h>
#if (defined MPG123_API_VERSION) && (MPG123_API_VERSION < 33)
#error "This should not happen"
#endif
struct ad_mpg123_context {
mpg123_handle *handle;
bool new_format;
int sample_size;
bool need_data;
/* Running mean for bit rate, stream length estimation. */
float mean_rate;
unsigned int mean_count;
/* Time delay for updates. */
short delay;
/* If the stream is actually VBR. */
char vbr;
};
static void uninit(struct dec_audio *da)
{
struct ad_mpg123_context *con = da->priv;
mpg123_close(con->handle);
mpg123_delete(con->handle);
mpg123_exit();
}
/* This initializes libmpg123 and prepares the handle, including funky
* parameters. */
static int preinit(struct dec_audio *da)
{
int err;
struct ad_mpg123_context *con;
/* Assumption: You always call preinit + init + uninit, on every file.
* But you stop at preinit in case it fails.
* If that is not true, one must ensure not to call mpg123_init / exit
* twice in a row. */
if (mpg123_init() != MPG123_OK)
return 0;
da->priv = talloc_zero(NULL, struct ad_mpg123_context);
con = da->priv;
/* Auto-choice of optimized decoder (first argument NULL). */
con->handle = mpg123_new(NULL, &err);
if (!con->handle)
goto bad_end;
/* Basic settings.
* Don't spill messages, enable better resync with non-seekable streams.
* Give both flags individually without error checking to keep going with
* old libmpg123. Generally, it is not fatal if the flags are not
* honored */
mpg123_param(con->handle, MPG123_ADD_FLAGS, MPG123_QUIET, 0.0);
/* Do not bail out on malformed streams at all.
* MPlayer does not handle a decoder throwing the towel on crappy input. */
mpg123_param(con->handle, MPG123_RESYNC_LIMIT, -1, 0.0);
/* Open decisions: Configure libmpg123 to force encoding (or stay open about
* library builds that support only float or int32 output), (de)configure
* gapless decoding (won't work with seeking in MPlayer, though).
* Don't forget to eventually enable ReplayGain/RVA support, too.
* Let's try to run with the default for now. */
/* That would produce floating point output.
* You can get 32 and 24 bit ints, even 8 bit via format matrix.
* If wanting a specific encoding here, configure format matrix and
* make sure it is in set_format(). */
/* mpg123_param(con->handle, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.); */
/* Example for RVA choice (available since libmpg123 1.0.0):
mpg123_param(con->handle, MPG123_RVA, MPG123_RVA_MIX, 0.0) */
/* Prevent funky automatic resampling.
* This way, we can be sure that one frame will never produce
* more than 1152 stereo samples.
* Background:
* Going to decode directly to the output buffer. It is important to have
* MPG123_AUTO_RESAMPLE disabled for the buffer size being an all-time
* limit.
* We need at least 1152 samples. dec_audio.c normally guarantees this. */
mpg123_param(con->handle, MPG123_REMOVE_FLAGS, MPG123_AUTO_RESAMPLE, 0.);
return 1;
bad_end:
if (!con->handle)
MP_ERR(da, "mpg123 preinit error: %s\n",
mpg123_plain_strerror(err));
else
MP_ERR(da, "mpg123 preinit error: %s\n",
mpg123_strerror(con->handle));
uninit(da);
return 0;
}
static int mpg123_format_to_af(int mpg123_encoding)
{
/* Without external force, mpg123 will always choose signed encoding,
* and non-16-bit only on builds that don't support it.
* Be reminded that it doesn't matter to the MPEG file what encoding
* is produced from it. */
switch (mpg123_encoding) {
case MPG123_ENC_SIGNED_8: return AF_FORMAT_S8;
case MPG123_ENC_SIGNED_16: return AF_FORMAT_S16;
case MPG123_ENC_SIGNED_32: return AF_FORMAT_S32;
case MPG123_ENC_FLOAT_32: return AF_FORMAT_FLOAT;
}
return 0;
}
/* libmpg123 has a new format ready; query and store, return return value
of mpg123_getformat() */
static int set_format(struct dec_audio *da)
{
struct ad_mpg123_context *con = da->priv;
int ret;
long rate;
int channels;
int encoding;
ret = mpg123_getformat(con->handle, &rate, &channels, &encoding);
if (ret == MPG123_OK) {
mp_audio_set_num_channels(&da->decoded, channels);
da->decoded.rate = rate;
int af = mpg123_format_to_af(encoding);
if (!af) {
/* This means we got a funny custom build of libmpg123 that only supports an unknown format. */
MP_ERR(da, "Bad encoding from mpg123: %i.\n", encoding);
return MPG123_ERR;
}
mp_audio_set_format(&da->decoded, af);
con->sample_size = channels * (af_fmt2bits(af) / 8);
con->new_format = 0;
}
return ret;
}
static int feed_new_packet(struct dec_audio *da)
{
struct ad_mpg123_context *con = da->priv;
int ret;
struct demux_packet *pkt = demux_read_packet(da->header);
if (!pkt)
return -1; /* EOF. */
/* Next bytes from that presentation time. */
if (pkt->pts != MP_NOPTS_VALUE) {
da->pts = pkt->pts;
da->pts_offset = 0;
}
/* Have to use mpg123_feed() to avoid decoding here. */
ret = mpg123_feed(con->handle, pkt->buffer, pkt->len);
talloc_free(pkt);
if (ret == MPG123_ERR)
return -1;
if (ret == MPG123_NEW_FORMAT)
con->new_format = 1;
return 0;
}
/* Now we really start accessing some data and determining file format.
* Format now is allowed to change on-the-fly. Here is the only point
* that has MPlayer react to errors. We have to pray that exceptional
* erros in other places simply cannot occur. */
static int init(struct dec_audio *da, const char *decoder)
{
if (!preinit(da))
return 0;
struct ad_mpg123_context *con = da->priv;
int ret;
ret = mpg123_open_feed(con->handle);
if (ret != MPG123_OK)
goto fail;
for (int n = 0; ; n++) {
if (feed_new_packet(da) < 0) {
ret = MPG123_NEED_MORE;
goto fail;
}
size_t got_now = 0;
ret = mpg123_decode_frame(con->handle, NULL, NULL, &got_now);
if (ret == MPG123_OK || ret == MPG123_NEW_FORMAT) {
ret = set_format(da);
if (ret == MPG123_OK)
break;
}
if (ret != MPG123_NEED_MORE)
goto fail;
// max. 16 retries (randomly chosen number)
if (n > 16) {
ret = MPG123_NEED_MORE;
goto fail;
}
}
return 1;
fail:
if (ret == MPG123_NEED_MORE) {
MP_ERR(da, "Could not find mp3 stream.\n");
} else {
MP_ERR(da, "mpg123 init error: %s\n",
mpg123_strerror(con->handle));
}
uninit(da);
return 0;
}
/* Compute bitrate from frame size. */
static int compute_bitrate(struct mpg123_frameinfo *i)
{
static const int samples_per_frame[4][4] = {
{-1, 384, 1152, 1152}, /* MPEG 1 */
{-1, 384, 1152, 576}, /* MPEG 2 */
{-1, 384, 1152, 576}, /* MPEG 2.5 */
{-1, -1, -1, -1}, /* Unknown */
};
return (int) ((i->framesize + 4) * 8 * i->rate * 0.001 /
samples_per_frame[i->version][i->layer] + 0.5);
}
/* Update mean bitrate. This could be dropped if accurate time display
* on audio file playback is not desired. */
static void update_info(struct dec_audio *da)
{
struct ad_mpg123_context *con = da->priv;
struct mpg123_frameinfo finfo;
if (mpg123_info(con->handle, &finfo) != MPG123_OK)
return;
if (finfo.vbr != MPG123_CBR) {
if (--con->delay < 1) {
if (++con->mean_count > ((unsigned int) -1) / 2)
con->mean_count = ((unsigned int) -1) / 4;
/* Might not be numerically optimal, but works fine enough. */
con->mean_rate = ((con->mean_count - 1) * con->mean_rate +
finfo.bitrate) / con->mean_count;
da->i_bps = (int) (con->mean_rate * 1000 / 8);
con->delay = 10;
}
} else {
da->i_bps = (finfo.bitrate ? finfo.bitrate : compute_bitrate(&finfo))
* 1000 / 8;
con->delay = 1;
con->mean_rate = 0.;
con->mean_count = 0;
}
}
static int decode_audio(struct dec_audio *da, struct mp_audio *buffer, int maxlen)
{
struct ad_mpg123_context *con = da->priv;
void *buf = buffer->planes[0];
int ret;
if (con->new_format) {
ret = set_format(da);
if (ret == MPG123_OK) {
return 0; // let caller handle format change
} else if (ret == MPG123_NEED_MORE) {
con->need_data = true;
} else {
goto mpg123_fail;
}
}
if (con->need_data) {
if (feed_new_packet(da) < 0)
return -1;
}
if (!mp_audio_config_equals(&da->decoded, buffer))
return 0;
size_t got_now = 0;
ret = mpg123_replace_buffer(con->handle, buf, maxlen * con->sample_size);
if (ret != MPG123_OK)
goto mpg123_fail;
ret = mpg123_decode_frame(con->handle, NULL, NULL, &got_now);
int got_samples = got_now / con->sample_size;
buffer->samples += got_samples;
da->pts_offset += got_samples;
if (ret == MPG123_NEW_FORMAT) {
con->new_format = true;
} else if (ret == MPG123_NEED_MORE) {
con->need_data = true;
} else if (ret != MPG123_OK && ret != MPG123_DONE) {
goto mpg123_fail;
}
update_info(da);
return 0;
mpg123_fail:
MP_ERR(da, "mpg123 decoding error: %s\n",
mpg123_strerror(con->handle));
return -1;
}
static int control(struct dec_audio *da, int cmd, void *arg)
{
struct ad_mpg123_context *con = da->priv;
switch (cmd) {
case ADCTRL_RESET:
mpg123_close(con->handle);
if (mpg123_open_feed(con->handle) != MPG123_OK) {
MP_ERR(da, "mpg123 failed to reopen stream: %s\n",
mpg123_strerror(con->handle));
return CONTROL_FALSE;
}
return CONTROL_TRUE;
}
return CONTROL_UNKNOWN;
}
static void add_decoders(struct mp_decoder_list *list)
{
mp_add_decoder(list, "mpg123", "mp3", "mp3",
"High-performance decoder using libmpg123");
}
const struct ad_functions ad_mpg123 = {
.name = "mpg123",
.add_decoders = add_decoders,
.init = init,
.uninit = uninit,
.control = control,
.decode_audio = decode_audio,
};
+44 -34
View File
@@ -1,20 +1,21 @@
/*
* This file is part of MPlayer.
*
* Copyright (C) 2012 Naoya OYAMA
*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
@@ -35,17 +36,18 @@
struct spdifContext {
struct mp_log *log;
AVFormatContext *lavf_ctx;
int iec61937_packet_size;
int out_buffer_len;
uint8_t out_buffer[OUTBUF_SIZE];
int out_buffer_size;
uint8_t *out_buffer;
bool need_close;
struct mp_audio fmt;
};
static int write_packet(void *p, uint8_t *buf, int buf_size)
{
struct spdifContext *ctx = p;
int buffer_left = OUTBUF_SIZE - ctx->out_buffer_len;
int buffer_left = ctx->out_buffer_size - ctx->out_buffer_len;
if (buf_size > buffer_left) {
MP_ERR(ctx, "spdif packet too large.\n");
buf_size = buffer_left;
@@ -115,48 +117,55 @@ static int init(struct dec_audio *da, const char *decoder)
int samplerate = 0;
switch (stream->codec->codec_id) {
case AV_CODEC_ID_AAC:
sample_format = AF_FORMAT_S_AAC;
spdif_ctx->iec61937_packet_size = 16384;
sample_format = AF_FORMAT_IEC61937_LE;
samplerate = 48000;
num_channels = 2;
break;
case AV_CODEC_ID_AC3:
sample_format = AF_FORMAT_S_AC3;
spdif_ctx->iec61937_packet_size = 6144;
sample_format = AF_FORMAT_AC3_LE;
samplerate = 48000;
num_channels = 2;
break;
case AV_CODEC_ID_DTS:
if (da->opts->dtshd) {
av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000
sample_format = AF_FORMAT_S_DTSHD;
spdif_ctx->iec61937_packet_size = 32768;
sample_format = AF_FORMAT_IEC61937_LE;
samplerate = 192000;
num_channels = 2*4;
} else {
sample_format = AF_FORMAT_S_DTS;
spdif_ctx->iec61937_packet_size = 32768;
sample_format = AF_FORMAT_AC3_LE;
samplerate = 48000;
num_channels = 2;
}
break;
case AV_CODEC_ID_EAC3:
sample_format = AF_FORMAT_S_EAC3;
spdif_ctx->iec61937_packet_size = 24576;
sample_format = AF_FORMAT_IEC61937_LE;
samplerate = 192000;
num_channels = 2;
break;
case AV_CODEC_ID_MP3:
sample_format = AF_FORMAT_S_MP3;
spdif_ctx->iec61937_packet_size = 4608;
sample_format = AF_FORMAT_MPEG2;
samplerate = 48000;
num_channels = 2;
break;
case AV_CODEC_ID_TRUEHD:
sample_format = AF_FORMAT_S_TRUEHD;
spdif_ctx->iec61937_packet_size = 61440;
sample_format = AF_FORMAT_IEC61937_LE;
samplerate = 192000;
num_channels = 8;
break;
default:
abort();
}
mp_audio_set_num_channels(&spdif_ctx->fmt, num_channels);
mp_audio_set_format(&spdif_ctx->fmt, sample_format);
spdif_ctx->fmt.rate = samplerate;
mp_audio_set_num_channels(&da->decoded, num_channels);
mp_audio_set_format(&da->decoded, sample_format);
da->decoded.rate = samplerate;
if (avformat_write_header(lavf_ctx, &format_opts) < 0) {
MP_FATAL(da, "libavformat spdif initialization failed.\n");
@@ -174,39 +183,40 @@ fail:
return 0;
}
static int decode_packet(struct dec_audio *da, struct mp_audio **out)
static int decode_audio(struct dec_audio *da, struct mp_audio *buffer, int maxlen)
{
struct spdifContext *spdif_ctx = da->priv;
AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
int sstride = 2 * da->decoded.channels.num;
assert(sstride == buffer->sstride);
if (maxlen * sstride < spdif_ctx->iec61937_packet_size)
return 0;
spdif_ctx->out_buffer_len = 0;
spdif_ctx->out_buffer_size = maxlen * sstride;
spdif_ctx->out_buffer = buffer->planes[0];
struct demux_packet *mpkt;
if (demux_read_packet_async(da->header, &mpkt) == 0)
return AD_WAIT;
struct demux_packet *mpkt = demux_read_packet(da->header);
if (!mpkt)
return AD_EOF;
return -1;
AVPacket pkt;
mp_set_av_packet(&pkt, mpkt, NULL);
pkt.pts = pkt.dts = 0;
MP_VERBOSE(da, "spdif packet, size=%d\n", pkt.size);
if (mpkt->pts != MP_NOPTS_VALUE) {
da->pts = mpkt->pts;
da->pts_offset = 0;
}
int ret = av_write_frame(lavf_ctx, &pkt);
talloc_free(mpkt);
avio_flush(lavf_ctx->pb);
buffer->samples = spdif_ctx->out_buffer_len / sstride;
da->pts_offset += buffer->samples;
talloc_free(mpkt);
if (ret < 0)
return AD_ERR;
int samples = spdif_ctx->out_buffer_len / spdif_ctx->fmt.sstride;
*out = mp_audio_pool_get(da->pool, &spdif_ctx->fmt, samples);
if (!*out)
return AD_ERR;
memcpy((*out)->planes[0], spdif_ctx->out_buffer, spdif_ctx->out_buffer_len);
return -1;
return 0;
}
@@ -243,5 +253,5 @@ const struct ad_functions ad_spdif = {
.init = init,
.uninit = uninit,
.control = control,
.decode_packet = decode_packet,
.decode_audio = decode_audio,
};
+182 -77
View File
@@ -1,18 +1,19 @@
/*
* This file is part of mpv.
* This file is part of MPlayer.
*
* mpv is free software; you can redistribute it and/or modify
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
@@ -24,9 +25,10 @@
#include "demux/codec_tags.h"
#include "config.h"
#include "common/codecs.h"
#include "common/msg.h"
#include "misc/bstr.h"
#include "bstr/bstr.h"
#include "stream/stream.h"
#include "demux/demux.h"
@@ -41,15 +43,40 @@
#include "audio/filter/af.h"
extern const struct ad_functions ad_mpg123;
extern const struct ad_functions ad_lavc;
extern const struct ad_functions ad_spdif;
static const struct ad_functions * const ad_drivers[] = {
#if HAVE_MPG123
&ad_mpg123,
#endif
&ad_lavc,
&ad_spdif,
NULL
};
// ad_mpg123 needs to be able to decode 1152 samples at once
// ad_spdif needs up to 8192
#define DECODE_MAX_UNIT MPMAX(8192, 1152)
// At least 8192 samples, plus hack for ad_mpg123 and ad_spdif
#define DECODE_BUFFER_SAMPLES (8192 + DECODE_MAX_UNIT)
// Drop audio buffer and reinit it (after format change)
// Returns whether the format was valid at all.
static bool reinit_audio_buffer(struct dec_audio *da)
{
if (!mp_audio_config_valid(&da->decoded)) {
MP_ERR(da, "Audio decoder did not specify audio "
"format, or requested an unsupported configuration!\n");
return false;
}
mp_audio_buffer_reinit(da->decode_buffer, &da->decoded);
mp_audio_buffer_preallocate_min(da->decode_buffer, DECODE_BUFFER_SAMPLES);
return true;
}
static void uninit_decoder(struct dec_audio *d_audio)
{
if (d_audio->ad_driver) {
@@ -70,6 +97,12 @@ static int init_audio_codec(struct dec_audio *d_audio, const char *decoder)
return 0;
}
d_audio->decode_buffer = mp_audio_buffer_create(NULL);
if (!reinit_audio_buffer(d_audio)) {
uninit_decoder(d_audio);
return 0;
}
return 1;
}
@@ -130,7 +163,14 @@ int audio_init_best_codec(struct dec_audio *d_audio, char *audio_decoders)
d_audio->decoder_desc =
talloc_asprintf(d_audio, "%s [%s:%s]", decoder->desc, decoder->family,
decoder->decoder);
MP_VERBOSE(d_audio, "Selected audio codec: %s\n", d_audio->decoder_desc);
MP_INFO(d_audio, "Selected audio codec: %s\n",
d_audio->decoder_desc);
MP_VERBOSE(d_audio, "AUDIO: %d Hz, %d ch, %s\n",
d_audio->decoded.rate, d_audio->decoded.channels.num,
af_fmt_to_str(d_audio->decoded.format));
MP_SMODE(d_audio, "ID_AUDIO_BITRATE=%d\nID_AUDIO_RATE=%d\n" "ID_AUDIO_NCH=%d\n",
d_audio->i_bps * 8, d_audio->decoded.rate,
d_audio->decoded.channels.num);
} else {
MP_ERR(d_audio, "Failed to initialize an audio decoder for codec '%s'.\n",
d_audio->header->codec ? d_audio->header->codec : "<unknown>");
@@ -144,111 +184,176 @@ 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);
if (d_audio->afilter) {
MP_VERBOSE(d_audio, "Uninit audio filters...\n");
af_destroy(d_audio->afilter);
d_audio->afilter = NULL;
}
uninit_decoder(d_audio);
talloc_free(d_audio->waiting);
talloc_free(d_audio->decode_buffer);
talloc_free(d_audio);
}
static int decode_new_frame(struct dec_audio *da)
int audio_init_filters(struct dec_audio *d_audio, int in_samplerate,
int *out_samplerate, struct mp_chmap *out_channels,
int *out_format)
{
while (!da->waiting) {
int ret = da->ad_driver->decode_packet(da, &da->waiting);
if (ret < 0)
return ret;
if (!d_audio->afilter)
d_audio->afilter = af_new(d_audio->global);
struct af_stream *afs = d_audio->afilter;
if (da->pts == MP_NOPTS_VALUE && da->header->missing_timestamps)
da->pts = 0;
// input format: same as codec's output format:
mp_audio_buffer_get_format(d_audio->decode_buffer, &afs->input);
// Sample rate can be different when adjusting playback speed
afs->input.rate = in_samplerate;
if (da->waiting) {
da->pts_offset += da->waiting->samples;
da->decode_format = *da->waiting;
mp_audio_set_null_data(&da->decode_format);
// output format: same as ao driver's input format (if missing, fallback to input)
afs->output.rate = *out_samplerate;
mp_audio_set_channels(&afs->output, out_channels);
mp_audio_set_format(&afs->output, *out_format);
char *s_from = mp_audio_config_to_str(&afs->input);
char *s_to = mp_audio_config_to_str(&afs->output);
MP_VERBOSE(d_audio, "Building audio filter chain for %s -> %s...\n", s_from, s_to);
talloc_free(s_from);
talloc_free(s_to);
// let's autoprobe it!
if (af_init(afs) != 0) {
af_destroy(afs);
d_audio->afilter = NULL;
return 0; // failed :(
}
*out_samplerate = afs->output.rate;
*out_channels = afs->output.channels;
*out_format = afs->output.format;
return 1;
}
// Filter len bytes of input, put result into outbuf.
static int filter_n_bytes(struct dec_audio *da, struct mp_audio_buffer *outbuf,
int len)
{
int error = 0;
struct mp_audio config;
mp_audio_buffer_get_format(da->decode_buffer, &config);
while (mp_audio_buffer_samples(da->decode_buffer) < len) {
int maxlen = mp_audio_buffer_get_write_available(da->decode_buffer);
if (maxlen < DECODE_MAX_UNIT)
break;
struct mp_audio buffer;
mp_audio_buffer_get_write_buffer(da->decode_buffer, maxlen, &buffer);
buffer.samples = 0;
error = da->ad_driver->decode_audio(da, &buffer, maxlen);
if (error < 0)
break;
// Commit the data just read as valid data
mp_audio_buffer_finish_write(da->decode_buffer, buffer.samples);
// Format change
if (!mp_audio_config_equals(&da->decoded, &config)) {
// If there are still samples left in the buffer, let them drain
// first, and don't signal a format change to the caller yet.
if (mp_audio_buffer_samples(da->decode_buffer) > 0)
break;
error = -2;
break;
}
}
return mp_audio_config_valid(da->waiting) ? AD_OK : AD_ERR;
}
/* Decode packets until we know the audio format. Then reinit the buffer.
* Returns AD_OK on success, negative AD_* code otherwise.
* Also returns AD_OK if already initialized (and does nothing).
*/
int initial_audio_decode(struct dec_audio *da)
{
return decode_new_frame(da);
}
// Filter
struct mp_audio filter_data;
mp_audio_buffer_peek(da->decode_buffer, &filter_data);
filter_data.rate = da->afilter->input.rate; // due to playback speed change
len = MPMIN(filter_data.samples, len);
filter_data.samples = len;
bool eof = filter_data.samples == 0 && error < 0;
static bool copy_output(struct af_stream *afs, struct mp_audio_buffer *outbuf,
int minsamples, bool eof)
{
while (mp_audio_buffer_samples(outbuf) < minsamples) {
if (af_output_frame(afs, eof) < 0)
return true; // error, stop doing stuff
struct mp_audio *mpa = af_read_output_frame(afs);
if (!mpa)
return false; // out of data
mp_audio_buffer_append(outbuf, mpa);
talloc_free(mpa);
if (af_filter(da->afilter, &filter_data, eof ? AF_FILTER_FLAG_EOF : 0) < 0)
return -1;
mp_audio_buffer_append(outbuf, &filter_data);
if (eof && filter_data.samples > 0)
error = 0; // don't end playback yet
// remove processed data from decoder buffer:
mp_audio_buffer_skip(da->decode_buffer, len);
// Assume the filter chain is drained from old data at this point.
// (If not, the remaining old data is discarded.)
if (error == -2) {
if (!reinit_audio_buffer(da))
error = -1; // switch to invalid format
}
return true;
return error;
}
/* Try to get at least minsamples decoded+filtered samples in outbuf
* (total length including possible existing data).
* Return 0 on success, or negative AD_* error code.
* Return 0 on success, -1 on error/EOF (not distinguidaed).
* In the former case outbuf has at least minsamples buffered on return.
* In case of EOF/error it might or might not be. */
int audio_decode(struct dec_audio *da, struct mp_audio_buffer *outbuf,
int audio_decode(struct dec_audio *d_audio, struct mp_audio_buffer *outbuf,
int minsamples)
{
struct af_stream *afs = da->afilter;
if (afs->initialized < 1)
return AD_ERR;
// Indicates that a filter seems to be buffering large amounts of data
int huge_filter_buffer = 0;
// Decoded audio must be cut at boundaries of this many samples
// (Note: the reason for this is unknown, possibly a refactoring artifact)
int unitsize = 16;
MP_STATS(da, "start audio");
/* Filter output size will be about filter_multiplier times input size.
* If some filter buffers audio in big blocks this might only hold
* as average over time. */
double filter_multiplier = af_calc_filter_multiplier(d_audio->afilter);
int res;
while (1) {
res = 0;
if (copy_output(afs, outbuf, minsamples, false))
int prev_buffered = -1;
while (minsamples >= 0) {
int buffered = mp_audio_buffer_samples(outbuf);
if (minsamples < buffered || buffered == prev_buffered)
break;
prev_buffered = buffered;
res = decode_new_frame(da);
if (res < 0) {
// drain filters first (especially for true EOF case)
copy_output(afs, outbuf, minsamples, true);
break;
int decsamples = (minsamples - buffered) / filter_multiplier;
// + some extra for possible filter buffering
decsamples += unitsize << 5;
if (huge_filter_buffer) {
/* Some filter must be doing significant buffering if the estimated
* input length didn't produce enough output from filters.
* Feed the filters 250 samples at a time until we have enough
* output. Very small amounts could make filtering inefficient while
* large amounts can make mpv demux the file unnecessarily far ahead
* to get audio data and buffer video frames in memory while doing
* so. However the performance impact of either is probably not too
* significant as long as the value is not completely insane. */
decsamples = 250;
}
// On format change, make sure to drain the filter chain.
if (!mp_audio_config_equals(&afs->input, da->waiting)) {
copy_output(afs, outbuf, minsamples, true);
res = AD_NEW_FMT;
break;
}
/* if this iteration does not fill buffer, we must have lots
* of buffering in filters */
huge_filter_buffer = 1;
struct mp_audio *mpa = da->waiting;
da->waiting = NULL;
if (af_filter_frame(afs, mpa) < 0)
return AD_ERR;
int res = filter_n_bytes(d_audio, outbuf, decsamples);
if (res < 0)
return res;
}
MP_STATS(da, "end audio");
return res;
return 0;
}
void audio_reset_decoding(struct dec_audio *d_audio)
{
if (d_audio->ad_driver)
d_audio->ad_driver->control(d_audio, ADCTRL_RESET, NULL);
af_seek_reset(d_audio->afilter);
if (d_audio->afilter)
af_control_all(d_audio->afilter, AF_CONTROL_RESET, NULL);
d_audio->pts = MP_NOPTS_VALUE;
d_audio->pts_offset = 0;
if (d_audio->waiting) {
talloc_free(d_audio->waiting);
d_audio->waiting = NULL;
}
if (d_audio->decode_buffer)
mp_audio_buffer_clear(d_audio->decode_buffer);
}
Loaded 100 of 632 files, more files were not shown because too many files have changed in this diff. Show more