Compare commits

..
111 Commits
Author SHA1 Message Date
wm4 7fe9126bba Release 0.8.2 2015-02-26 19:13:34 +01:00
wm4 22863d6a79 Revert "osd: force alignment for OSD bar"
This reverts commit ff10bd65d6.

Fixes #1631.
2015-02-26 19:11:42 +01:00
Diogo Franco (Kovensky) 5ccd91d639 Fix typo... 2015-02-26 17:20:01 +09:00
Diogo Franco (Kovensky) 37bf8de258 Release 0.8.1 2015-02-26 11:08:23 +09:00
wm4 2d3e4fb1b9 cache: use MPCLAMP() macro
(cherry picked from commit e85bcc1223)
2015-02-26 11:03:15 +09:00
wm4 78cd25388c cache: limit to file size
Saves some memory. Should be especially helpful if many small files are
loaded, like when mass-loading subtitle files and the cache is enabled.

(cherry picked from commit 899f0cd51e)
2015-02-26 11:03:08 +09:00
Stefano Pigozzi 32f0adaeae remove dead comment
(cherry picked from commit f3eb6ae783)
2015-02-26 11:02:44 +09:00
Stefano Pigozzi 70a7d9d2c5 build: move QuartzCore linking to the cocoa check
It's needed for the DisplayLink functions so it must be enabled for the basic
cocoa code.

(cherry picked from commit 8e80b3fd2f)
2015-02-26 11:02:38 +09:00
wm4 cf14511b1d demux_mkv_timeline: fix potential issue when enabling cache
If the cache is enabled, the demuxer is closed and opened again (because
currently, the cache can not be enabled atfer data was already read).
The call for opening a new demuxer uses the same params struct, which
references the ctx->uids array. But there is a MP_TARRAY_GROW()
invocation somewhere on the way, which can reallocate the ctx->uids
array, making params.uids a dangling pointer.

This issue probably existed for a longer time, probably since 5cd33853
(slightly more obvious since f50b105d).

(cherry picked from commit 9349cfca91)
2015-02-26 11:01:25 +09:00
wm4 a6d57d654a demux_mkv_timeline: move uids array to context too
Again removes some indirections and extra arguments.

Also replace some memcpy/memmoves with assignments. (Assignments became
possible only later, when reference UIDs were turned into a struct.)

(cherry picked from commit 02bd54c0ac)
2015-02-26 10:45:42 +09:00
wm4 63671a4fbb demux_mkv_timeline: pass sources array as part of context
Removes tripple pointer indirections and such.

(cherry picked from commit 2bf0a5f2bc)
2015-02-26 10:40:35 +09:00
wm4 8ace70cfa6 demux_mkv: minor refactor for deferred cue reading
Should behave about the same, but reduces code some duplication with
seeking and reading a header element pointed to by a SeekHead. It also
makes behavior with incomplete files slightly better.

(cherry picked from commit 2e23be5a7b)
2015-02-26 10:39:02 +09:00
wm4 1e0edb3e6f demux_mkv: don't spam too many warnings with partial files
Limit it to a single message. It often printed more than that, and in
some cases (old files with "cluster" index), spammed a lot.

(cherry picked from commit a761a1531a)
2015-02-26 10:38:53 +09:00
Diogo Franco (Kovensky) 4ed46bfa25 Update RELEASE_NOTES 2015-02-25 15:26:03 +09:00
Diogo Franco (Kovensky) 423d47130a Fix compilation
Broken by unchecked cherry-picking of 53867aa.
2015-02-25 11:16:18 +09:00
Niklas Haas 7a02593dc4 vo_opengl: greatly increase smoothmotion performance
Instead of rendering and upscaling each video frame on every vsync, this
version of the algorithm only draws them once and caches the result,
so the only operation that has to run on every vsync is a cheap linear
interpolation, plus CMS/dithering.

On my machine, this is a huge speedup for 24 Hz content (on a 60 Hz
monitor), up to 120% faster. (The speedup is not quite 250% because of
the overhead that the larger FBOs and CMS provides)

In terms of the implementation, this commit basically swaps
interpolation and upscaling - upscaling is moved to inter_program, and
interpolation is moved to the final_program.

Furthermore, the main bulk of the frame rendering logic (upscaling etc.)
was moved to a separete function, which is called from
gl_video_interpolate_frame only if it's actually necessarily, and
skipped otherwise.

(cherry picked from commit 010cf183fe)
2015-02-25 11:10:27 +09:00
Niklas Haas 220d28b902 manpage: update documentation for smoothmotion
Hopefully, this will really clear up how the thing is supposed to work
(and that it's not SVP, nor MVTools).

I also removed instances of the word "interpolation", since that's a
term that's easily misleading.

Finally, I expanded on smoothmotion-threshold since the purpose/meaning
was a bit confusing.

(cherry picked from commit 9fa73b6f64)
2015-02-25 11:10:01 +09:00
wm4 ff10bd65d6 osd: force alignment for OSD bar
Overwrite the alignment applied by the OSD style. Additionally, remove
the initialization of the Alignment field in create_ass_track(); the
value is always overwritten by mp_ass_set_style() later.

Fixes #1626.

(cherry picked from commit 53641a689d)
2015-02-25 11:09:20 +09:00
wm4 e2895e9684 osd: always reset style params
There was some logic to set certain things on init only. Not sure why
this was done (saving some cheap calculations?) - but since the next
call would override these style settings by applying the usual subtitle
style, I don't think this was intended.

(cherry picked from commit 9fbcb56bee)
2015-02-25 11:09:10 +09:00
wm4 83be06c0ad vo_opengl: another GLES2 issue
GLES2 randomly does not support the transpose parameter in matrix
uniform calls. So we have to do this manually. Sure it was worth to
mutilate the standard just so all these shitty SoC vendors can safe 3
lines of code.

(Obviously trying to handle all of GLES2 to GL 4.x in a single codebase
was a mistake.)

(cherry picked from commit cc011415ff)
2015-02-25 11:08:53 +09:00
wm4 fd7077ade9 vo_opengl: extend ifdef against shader arrays
GLES2 shaders do not have line continuation characters. Abuse the
HAVE_ARRAYS define to exclude code which uses arrays, and which also
happens to cover all code that defines multi-line macros. (So yes, this
is a hack.)

(cherry picked from commit 2c8d16d89f)
2015-02-25 11:08:39 +09:00
wm4 d40ccc3416 old-build: proper atomics are not strictly required
(cherry picked from commit a92cab736f)
2015-02-25 11:08:27 +09:00
wm4 57f5ad445d video: remove redundant codec parameters
Remove coded_width and coded_height. This was originally added in commit
fd7dde40, when BITMAPINFOHEADER was killed. The separate fields became
redundant in commit e68f4be1. Remove them (nothing passed to the
decoders actually changes with _this_ commit).

(cherry picked from commit 5baf74fa24)
2015-02-25 11:08:15 +09:00
wm4 a5458a624d ytdl: add --no-warnings
Silences "[ytdl_hook] WARNING: video doesn't have subtitles", which was
an annoying and pointless message printed with almost all youtube
videos.

(cherry picked from commit 7cff2e4131)
2015-02-25 11:01:05 +09:00
Jaime Marquínez Ferrándiz edf0b93703 ytdl: Adapt to new subtitles structure
The requested formats can be sorted by preference and the result gives now an url or the subtitles file content

(cherry picked from commit 7281a72fab)
2015-02-25 11:00:55 +09:00
Kevin Mitchell 6bf46eae23 ao/wasapi: move resume to audio thread
This echanges the two events hForceFeed/hFeedDone for hResume. This
like the last commit makes things more deterministic.

Importantly, the forcefeed is only done if there is not already a full
buffer yet to be played by the device. This should fix some of the
problems with exclusive mode.

This commit also removes the necessity to have a proxy to the
AudioClient object in the main thread.

fixes #1529

(cherry picked from commit c52833bf16)
2015-02-25 10:59:25 +09:00
Kevin Mitchell 774e818371 ao_wasapi: move reset into audio thread
This makes things a bit more deterministic. It ensures that the audio
thread isn't doing anything between IAudioClient_Stop(),
IAudioClient_Reset() and setting the sample_count to 0.

Buffer overfilling on resume is still a problem in exclusive mode (see
next commit).

(cherry picked from commit 446fd5a43a)
2015-02-25 10:59:19 +09:00
wm4 352c00fd08 encoding: allow encoding to channel configurations other than stereo
A while ago, we made mpv output the native number of channels by
default, instead of stereo. I assumed this was not wanted for encode
mode.

This commit keeps the assumption, but allows setting the number of audio
output channels at all, instead of always forcing stereo. (Pretty much a
hack.)

(cherry picked from commit 636d6d724d)
2015-02-25 10:51:05 +09:00
wm4 589b38c187 vf: fix indentation level of verbose output
Just so that it has the same indentation as the extremely similar audio
filter output.

(cherry picked from commit 24e7280178)
2015-02-25 10:50:50 +09:00
wm4 62bc8442be DOCS/client_api_examples/simple: fix option
"input-x11-keyboard" still works, but is a deprecated alias with the
same functionality.

(cherry picked from commit cf395e1754)
2015-02-25 10:50:39 +09:00
wm4 0edd08a1f6 client API: hint that opengl_cb is an alternative to window embedding
(cherry picked from commit d77fdc8f82)
2015-02-25 10:50:31 +09:00
Niklas Haas 7f5378680b vo_opengl: slightly improve ewa_lanczos windowing
The original filter window was design for a radius based on the true
zero, but we always cut it off at our selection of radius either way (by
necessity, due to the square matrix we sample from).

This window is tweaked from the original (true radius) to our actual
cut-off radius, and hence improves the result in a few edge cases. The
main win is the reduction of code complexity, since we no longer need to
know what the true radius actually is.

(cherry picked from commit 1ecd9727f0)
2015-02-25 10:50:16 +09:00
wm4 4753a92b80 player: fix demuxer lifetime management
Commit f54220d9 attempted to improve this, but it got worse. Now there
was a crash when ytdl_hook.lua added external tracks. This happened
because close_unused_demuxers() assumed that sources[0] was the main
demuxer (so that it didn't close it). This assumption failed, because
the ytdl script can add external tracks before the main file is loaded.
The easy fix would have been to check for master_demuxer, and not i==0.
But instead give up on the old idea, make some stricter assumptions how
demuxers and external tracks map, and simplify the code.

(cherry picked from commit 53867aa9d8)
2015-02-24 12:16:00 +09:00
Stefano Pigozzi 584a27e3b8 build: print pkg-config query on failure
(cherry picked from commit 0466ce2f98)
2015-02-24 12:13:05 +09:00
wm4 b4abc0a037 manpage: ipc: add a socat example
Requested, and should be quite good at giving an overview how it works.

(cherry picked from commit af435e0a02)
2015-02-24 12:12:34 +09:00
wm4 192318a216 video: un-discourage "vaapi-copy" hwdec mode
Maybe I don't know what I'm doing. I'm fairly certain though that Intel
does not know what they're doing.

(cherry picked from commit d71bbcbc98)
2015-02-21 21:00:50 +09:00
wm4 822e6e0dd1 player: move timeline scanning (ordered chapters etc.) to a thread
Do timeline building (scanning & opening reference files for ordered
chapters, and more) in a thread. As a result, this process can actually
be stopped without having to kill the player.

This is pretty simple: just reuse the demuxer opening thread. We have
to give up on the idea that open_demux_reentrant() is reusable, though.

(Althoughthe timeline readers still need some fixes before they react to
the quit request.)

(cherry picked from commit 44411674eb)
2015-02-21 20:49:50 +09:00
wm4 45b63c78cd player: cosmetics: async/non-blocking -> reentrant
These functions do blocking work on a separate thread, but wait until
they return. So they are not async or non-blocking. But they do react to
user-input and client API accesses, which makes them reentrant.

(cherry picked from commit 2c305d5b29)
2015-02-21 20:49:32 +09:00
wm4 de47273716 stream_file: open pipes non-blocking
Now the player can actually be quit if a pipe was opened, but nobody is
writing to it.

(cherry picked from commit 3c9344a1a9)
2015-02-21 20:49:11 +09:00
wm4 7ace4f2115 vo_opengl: minor robustness improvement in function loader
Check the scanf() return value, and don't continue if it doesn't find
both numbers (can happen with GLES 1.0). Also, some implementations can
return NULL from glGetString() if something is "broken".

(cherry picked from commit 9861abf8ff)
2015-02-21 20:48:43 +09:00
Niklas Haas f67dfcbec6 vo_opengl: fix smoothmotion coefficient calculation, for real this time
I've reworked pretty much all the logic to correspond to what the theory
actually describes. With this commit, playback is wonderfully smooth on
my machine.

(cherry picked from commit 4356e893a1)
2015-02-21 20:48:24 +09:00
wm4 6b9f7923af demux_lavf: apply hacks even if format is forced
Some of the hacks were not applied if the file format was forced. Commit
37a0c914 moved them to a table, which is checked with normal probing
only.

Fixes #1612 (DVD forces mpeg, which in turn has to export native stream
IDs specifically).

Do some code restructuring on the way. For example, the probescore can
simply be set to the correct initial value, instead of checking whether
it was set at all.

(cherry picked from commit 611f9ab0a8)
2015-02-21 20:48:15 +09:00
wm4 c36b1d01c1 manpage: fix vf_scale arnd parameter
It probably was always a flag, so the documentation became invalid as
soon as mpv stopped accepting 0/1 for flags.

Fixes #1608.

(cherry picked from commit b230f32624)
2015-02-21 20:47:55 +09:00
wm4 07222d14f9 build: fix Python 3 unicode issue with waf 1.8.6
Starting with waf 1.8.6 (in Python 3), the hcode variable isn't a
string, but a byte string.

This commit adds the solution proposed in the upstream waf bug report:
https://code.google.com/p/waf/issues/detail?id=1535

It seems a bit overly verbose, but on the other hand, this solution has
the chance of being most correct/compatible.

Fixes #1604.

(cherry picked from commit 14b231119d)
2015-02-19 19:33:49 +09:00
Diogo Franco (Kovensky) 28fbee7f03 Update RELEASE_NOTES 2015-02-19 13:44:57 +09:00
wm4 b3d2daaa1d demux_lavf: blacklist bintext files
Whatever the hell that is. FFmpeg tries to open any files with .bin file
extension with this demuxer (unless it finds a better demuxer), and then
reads the whole damn file, along with spamming dumb crap.

(cherry picked from commit 79006ef66d)
2015-02-19 13:39:39 +09:00
wm4 3437ea23f6 cache: silence "EOF reached" message
This message will be printed relatively often once EOF is reached. In
some cases this is rather annoying, for example when playing HLS. (With
HLS, the stream is just a playlist file, while libavformat opens actual
media files without mpv's knowledge, so the cache is completely useless
and hits EOF instantly.)

That it retries reading is apparently a good thing: at least local files
can grow, and even after the player got the EOF, playback _could_ be
resumed by basically polling and detecting that there is more data. So
I'm not changing this behavior yet.

(cherry picked from commit 3f5b5b758d)
2015-02-19 13:39:39 +09:00
wm4 16856994e9 demux_lavf: reorganize hacks
An attempt to make format-specifics more declarative. (In my opinion,
all of this should be either provided by libavformat, or should not be
needed.)

I'm still leaving many checks with matches_avinputformat_name(), because
they're so specific.

Also useful for the following commit.

(cherry picked from commit 37a0c9140a)
2015-02-19 13:39:39 +09:00
wm4 c22c440c9c demux_lavf: set interrupt_callback
Helps with terminating the stream if e.g. HLS streams are stuck. (For
other demuxers, the stream's interrupt callback already takes care of
this.)

(cherry picked from commit ff992e093b)
2015-02-19 13:39:39 +09:00
Jaime Marquínez Ferrándiz be42f4c212 find_subfiles: Add 'vtt' to subtitle extensions
(cherry picked from commit aa98049877)
2015-02-19 13:39:39 +09:00
wm4 1b5f127cb0 demux, matroska: remove demuxer type field
The Matroska timeline code was the only thing which still used the
demuxer.type field. This field explicitly identifies a demuxer
implementation. The purpose of the Matroska timeline code was to reject
files that are not Matroska. But it already forces the Matroska format,
meaning loading will explicitly only use the Matroska demuxer. If the
demuxer can't open the file, no other demuxer will be tried, and thus
checking the field is redundant.

The change in demux_mkv_timeline.c removes the if condition, and
unindents the if body.

(cherry picked from commit fa9b587426)
2015-02-19 13:39:39 +09:00
wm4 7ea82eb7bc demux: remove file_contents field
Only demux_cue and demux_edl used it. It's a weird field and doesn't
help with anything anymore - by now, it only saves a priv context in the
mentioned demuxers. Reducing the number of confusing things the demuxer
struct has is more important than minimizing the code.

(cherry picked from commit 082371a160)
2015-02-19 13:39:39 +09:00
wm4 3be989dcd0 demux_edl: make independent from MPContext
(cherry picked from commit d7a4cb14ff)
2015-02-19 13:39:38 +09:00
wm4 0adc8ee5c1 demux_edl: move implementation
Same deal as with demux_cue, and a separate commit for the same reasons.

(cherry picked from commit 1e44c811f3)
2015-02-19 13:39:38 +09:00
wm4 55fe8aab6a demux_cue: make independent from MPContext
Also see previous commit(s).

(cherry picked from commit 10781c2a9c)
2015-02-19 13:39:38 +09:00
wm4 b2aa388f27 demux_cue: move implementation
Move the implementation, of which most was in tl_cue.c, to demux_cue.c.
Currently, this is illogical, because tl_cue.c still accesses MPContext.
This is going to change, and then it will be better if everything is in
demux_cue.c. This is only a separate commit to distinguish code movement
and actual work; the next commit will do the actual work.

(cherry picked from commit 7f03f46882)
2015-02-19 13:39:38 +09:00
wm4 fea1dc0cd5 demux: copy priv pointer too
Weird, but helps with the case a demuxer gets handed its own instance
from outside.

(cherry picked from commit f9872ab26f)
2015-02-19 13:39:38 +09:00
wm4 8161b47e73 matroska: move timeline code to demux/
Separate from previous commit, because git is bad at tracking file
renames when the file contents are also changed.

(cherry picked from commit edc0007e74)
2015-02-19 13:39:38 +09:00
wm4 f113e03b89 matroska: make timeline code independent of MPContext
(cherry picked from commit 5a186d5942)
2015-02-19 13:39:38 +09:00
wm4 630a7b7d82 player: use a separate context for timeline loader stuff
Instead of accessing MPContext in player/timeline/*, create a separate
context struct, which the timeline loaders fill out. It turns out that
there's not much in the way too big MPContext that these need to access.

One major PITA is managing (and closing) the set of open demuxers. The
problem is that we need a list of all demuxers to make sure no unneeded
streams are enabled.

This adds a callback to the demuxer_desc struct, with the intention of
leaving to to the demuxer to call the right loader, instead of
explicitly checking the demuxer type and dispatching manually in common
code. I also considered making the timeline part of the demuxer state,
but decided against: it's too much of a mess wrt. memory management and
threading, and also doesn't make it clear who owns the child demuxers.
With the struct timeline decoupled from the demuxer state, it's at least
somewhat clear that the child demuxers are independent from the "main"
demuxer.

The actual changes to player/timeline/* are separated in the following
commits, because they're quite verbose. Some artifacts will be removed
later as soon as there's only 1 timeline loading mechanism.

(cherry picked from commit a0a089f6a4)
2015-02-19 13:39:38 +09:00
wm4 a4e766a77f demux: chapters without metadata are allowed
Makes some of the following commits slightly simpler. Also fix a typo.

(cherry picked from commit 3efeee446e)
2015-02-19 13:39:38 +09:00
wm4 57deaa02d5 player: use a macro to remove an element from an array
Should be equivalent.

(cherry picked from commit 969edb9e0b)
2015-02-19 13:39:38 +09:00
wm4 a6accfdad7 player: actually close files when using sub_remove
Also effects some other cases.

The real reason for this is for keeping track of which demuxers can be
closed (see following commit). Since I don't want to use reference
counting for this, some sort of simplistic mark-and-sweep is done to
determine whether a demuxer is still needed.

(cherry picked from commit f54220d951)
2015-02-19 13:39:38 +09:00
wm4 8813fe090d DOCS/client-api-changes: mark 0.8.0 release
(There was a missing version bump for the msg-level change; just move it
under 1.14.)

(cherry picked from commit 0283815ee1)
2015-02-19 13:39:38 +09:00
wm4 72ba8515d5 demux_lavf: hack against hls showing "100%" position
The HLs protocol consists of a "playlist" main file, which mpv downloads
and passes to the HLS demuxer. The HLS demuxer actually requests segment
files containing media data on its own. The packets read from the
demuxer have a source file position set, but it's not from the main
file. This leads to a strange effect: as a last fallback, the player
will calculate the approximate playback position from the file
position/size ratio, and since the main file is tiny, this will always
show 100%. Fix this by resetting the packet file position.

This doesn't affect the case when HLS actually reports a duration.

(cherry picked from commit a64b1deaa6)
2015-02-19 13:39:38 +09:00
wm4 21f5d82dc5 etc/input.conf: remove a leftover
This is already mapped by default.

(cherry picked from commit 8b784fb1ca)
2015-02-19 13:24:59 +09:00
wm4 8c992458c3 vo_opengl: glsl: remove trailing \
This should be no problem... but it _might_ help with #1536, so it's
worth a try.

(cherry picked from commit 0063d94927)
2015-02-19 13:24:31 +09:00
wm4 40149c017c m_config: log options set by the client API too
(cherry picked from commit d34eabe286)
2015-02-19 13:24:09 +09:00
Diogo Franco (Kovensky) 0c9f10e0d1 Release v0.8.0 2015-02-17 14:06:06 +09:00
Diogo Franco (Kovensky) 5b0d06ca74 Fix typo in RELEASE_NOTES 2015-02-17 14:05:50 +09:00
Diogo Franco (Kovensky) a410451463 Fix typo on RELEASE_NOTES 2015-02-16 18:54:13 +09:00
Skyrainfit 3152eed6d8 mpv.desktop: Add zh-TW and zh-CN translations
(cherry picked from commit 31ac0574ad)
2015-02-16 18:45:05 +09:00
Diogo Franco (Kovensky) 02260882ce Bump VERSION to v0.8.0_rc3 2015-02-16 18:37:46 +09:00
Diogo Franco (Kovensky) cd5f0a8612 Update RELEASE_NOTES 2015-02-16 18:37:32 +09:00
wm4 23959eb5b4 osxbundle: config file special case isn't needed anymore
The previous commit effectively fixes the mess caused by 'config' vs.
'mpv.conf', and the hack introduced by commit e01a6dac and extended by
commit db167cd4 isn't needed anymore.

(cherry picked from commit 816d7bba1f)
2015-02-16 18:16:36 +09:00
wm4 21a95f5ed9 player: undeprecate 'config' files
Actually, it's pretty simple to look for multiple filenames at once,
since mp_find_all_config_files() is already a bit "special" anyway.

See #1569. Reverts most of commit db167cd4 (keeps osx-bundle.conf).

(cherry picked from commit a27aa68dd3)
2015-02-16 18:16:28 +09:00
wm4 6dc2a23cda vd_lavc: uninit the hwdec backend after closing the decoder
A recent behavior change in libavcodec's h264 decoder keeps at least 1
surface even after avcodec_flush_buffers() has been called. We used to
flush the decoder in order to make sure all surfaces are free'd, so that
the hw decoder can be safely uninitialized. This doesn't work anymore.

Fix it by closing the AVCodecContext before the hw decoder is
uninitialized. This is actually simpler and more robust. It seems to be
well-supported too.

Fixes invalid read accesses with vaapi-copy and dxva2-copy. These
destroyed the hwdec API fully on uninit, and could not deal with
surfaces surviving the decoder.

Probably fixes #1587.

(cherry picked from commit cf073138b2)
2015-02-16 18:15:20 +09:00
wm4 f94318babc x11: fix uninitialized variable reads
This line of code ended up in the wrong block in commit cd6dfcbe.

(cherry picked from commit f247294d73)
2015-02-16 18:15:05 +09:00
wm4 b476d21d0a client API: clarify filename string encoding
Admittedly, the behavior on Windows is not quite straightforward. The
behavior on the other platforms is equivalent to fopen().

Fixes #1585.

(cherry picked from commit a799a4c57f)
2015-02-16 18:14:10 +09:00
Stefano Pigozzi 16c7de4aab cocoa: remove unused function
(cherry picked from commit bf46f4c997)
2015-02-16 18:13:44 +09:00
Martin Herkt 8fdd688d48 x11: add XK_Cancel to the list of special keys
Some IR receivers emit this key by default for remote control
buttons. Make it mappable.

(cherry picked from commit 9aaec7cffb)
2015-02-16 18:13:36 +09:00
wm4 63304b95a1 Fix build on OSX broken by previous commit
Hopefully.

(cherry picked from commit 5247416735)
2015-02-16 18:13:29 +09:00
Julian f4263a811f vf_vapoursynth: add display refresh rate property
This value is not necessarily trustworthy (it might change) and can be
0.

(cherry picked from commit 349067a6ab)
2015-02-16 18:13:22 +09:00
wm4 a6bf8e7c36 x11: return a framerate even if no window is mapped
Falls back to the first display in the list returned by xrandr. Not
entirely correct, but makes some people happy (see #1575).

(cherry picked from commit cd6dfcbef4)
2015-02-16 18:13:15 +09:00
wm4 6488e77d8a player: deprecate 'config' files (use mpv.conf), warn against clashes
Apparently there's at least one distro which ships a /etc/mpv/mpv.conf
file (mpv doesn't install such a file). This breaks config files named
'config' located in the user's mpv config directory, because mpv first
loads files named 'config' and then 'mpv.conf'. There is no mechanism
for putting files with different names into the same config path order.
(Even worse, that mpv.conf file only set an option to the default value.
Why do distros always do very stupid things?)

Print a warning on collisions.

Although using 'config' was well-supported, supporting both names is
starting to become messy, so deprecate 'config' and print a warning if
one is found.

At least we will be able to remove the whole mess once 'config' files
are ignored...

This also affects the osx-bundle, which intentionally used these not-so-
optimal semantics. Solve it in a different way. (Unfortunately with an
ifdef - it's not required, but having to explain everyone why mpv tries
to load a osx-bundle.mpv file on Linux and Windows would consume
energy.)

Closes #1569.

(cherry picked from commit db167cd438)
2015-02-16 18:13:01 +09:00
wm4 34a856f465 command: mark get_property as deprecated
Using it just makes no sense. But we're really being nice about this and
don't remove it immediately.

(cherry picked from commit fd5403cb40)
2015-02-16 18:12:17 +09:00
wm4 db218a8d25 x11: make all XF86 special keys mappable
Makes all keys documented in XF86keysym.h mappable. This requires the
user to deal with numeric keycodes; no names are queried or exported.

This is an easy way to avoid adding all the hundreds of XF86 keys to
our X11 lookup table and mpv's keycode/name list.

(cherry picked from commit 417869f845)
2015-02-16 18:12:04 +09:00
wm4 e3064c3cb7 ipc: put playback core to sleep while dequeuing commands
Happens to fix #1581 due to an unfortunate interaction with the way the
VO does not react to commands for a while if a video frame is queued.
Slightly improves other situations as well, if the client spams mpv with
commands during playback.

(cherry picked from commit 32b56c56ba)
2015-02-16 18:11:52 +09:00
Stefano Pigozzi df4d15be7b vo_opengl: fix smoothmotion coefficient calculation
Using prev_pts as the start of the scale was plain wrong. Change it to
prev_vsync.

(cherry picked from commit 3931544ef3)
2015-02-16 18:09:45 +09:00
wm4 cb5adf4d72 cocoa: fix exiting the command line player
Commit e920a00eb assumed that terminate_cocoa_application() actually
would exit. But apparently that is not always the case; e.g. mpv --help
will just hang. The old code had a dummy exit(0), which was apparently
actually called. Fix by explicitly exiting if mpv_main() returns and
terminate_cocoa_application() does nothing.

(cherry picked from commit 9e14042e57)
2015-02-16 18:09:35 +09:00
wm4 440ba33639 encoding: fixed-vo option was removed
(cherry picked from commit 96547a810e)
2015-02-16 18:09:22 +09:00
wm4 e4eb9c5469 player: add a --loop=force mode
Requested. See manpage additions.

This also makes the magical loop_times constants slightly saner, but
shouldn't change the semantics of any existing --loop option values.

(cherry picked from commit aee0978d50)
2015-02-16 18:09:12 +09:00
wm4 4387919753 osx: move code to unset input context to the right place
Setting the input context is always called, both in cplayer and libmpv,
and under HAVE_COCOA. Unsetting the input context was done only the
cplayer uninit call. Also it was under HAVE_COCOA_APPLICATION, so it was
not unset in libmpv (dangling pointer).

(cherry picked from commit c59a4f12db)
2015-02-16 18:08:58 +09:00
wm4 94123474a4 osx: move cocoa specific call out of common code
This is almost equivalent, and gets rid of the ifdef.
2015-02-16 18:08:52 +09:00
wm4 50a7aac4d7 player: drop explicit exit() calls
The code in main.c calls exit() explicitly, but the code is actually
easier to follow by simply exiting from main() instead. The exit() call
in av_log.c happens only on severely broken builds, so replace it with
abort().

(Shuts up rpmlint warnings.)

(cherry picked from commit e920a00eba)
2015-02-16 18:08:38 +09:00
wm4 2051243a0f ao: set correct client name when listing devices
This is a small oversight. The client name (as set on command line
options or, more importantly, the client API) was not set when listing
devices e.g. via the "audio-device-list" property.

Might or might not fix #1578.

Also adjust the log level for an unrelated message.

(cherry picked from commit c152c59084)
2015-02-16 18:08:17 +09:00
Diogo Franco (Kovensky) a21d09d9f8 Update RELEASE_NOTES formatting 2015-02-13 13:27:38 +09:00
Diogo Franco (Kovensky) b95a0bfa77 Merge remote-tracking branch 'Cpuroast/release/0.8' into release/0.8
* Cpuroast/release/0.8:
  A few tweaks to the 0.80_rc2 release notes
2015-02-13 13:24:30 +09:00
Cpuroast 43f831b6ba A few tweaks to the 0.80_rc2 release notes
scale-radius=3 is the default, so use 2 as an example
Point out that ewa_lanczos (Jinc) is actually new.
2015-02-12 11:39:57 -05:00
wm4 b3eba216b7 Revert "player: make --force-window create the window immediately on start"
This reverts commit acc5e8f574.

As expected, some didn't like this. Others won't like this revert.
Whatever.

See #1561.

This should go into mpv 0.8.0 before it's released.

(cherry picked from commit 7bbc617019)
2015-02-12 21:39:10 +09:00
Diogo Franco (Kovensky) 0668c82da5 Bump version to v0.8.0_rc2 2015-02-12 21:23:45 +09:00
Diogo Franco (Kovensky) c1e8f3b479 Update RELEASE_NOTES 2015-02-12 13:31:03 +09:00
wm4 64a45f972c video/filters: simplify libavfilter bridge
Remove the confusing crap that allowed a filter using the libavfilter
bridge to be compiled without libavfilter. Instead, compile the wrappers
only if libavfilter is enabled at compile time.

The only filter which still requires it is vf_stereo3d (unfortunately).
Special-case this one. (The whole filter and how it interacts with lavfi
is pure braindeath anyway.)

(cherry picked from commit 2522bff565)
2015-02-12 09:53:43 +09:00
wm4 d4207c64e6 vf_noise: remove internal implementation
It requires libavfilter now, just like many other filters. Not sure if
it even makes sense to keep this wrapper.

(cherry picked from commit 73d23a9405)
2015-02-12 09:53:37 +09:00
wm4 abf1fc9a77 af: account for queued frames in audio position calculation
af_rubberband exposed this issue.

(cherry picked from commit d85aa35ffb)
2015-02-12 09:53:27 +09:00
Diogo Franco (Kovensky) da8e573b45 Bump version to -rc1 2015-02-12 00:06:37 +09:00
wm4 25c0097c67 dvb_tune: fix invalid syntax
Oops.
2015-02-11 23:59:35 +09:00
wm4 20d5efb419 audio: fix pool allocation
It reallocated the pool on every request, making the pool completely
useless. Oops.
2015-02-11 23:59:16 +09:00
Diogo Franco (Kovensky) a18b4b2b19 Add preliminary RELEASE_NOTES 2015-02-11 23:57:57 +09:00
wm4 a468e2869d manpage: fix af_scaletempo suggested commands 2015-02-11 23:55:12 +09:00
Diogo Franco (Kovensky) cb9975b942 Branch release/0.8, add -beta VERSION 2015-02-10 22:59:51 +09:00
424 changed files with 10077 additions and 14019 deletions

No files matched your search

+1
View File
@@ -14,6 +14,7 @@
/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
+2 -2
View File
@@ -2,7 +2,7 @@ language: c
os:
- linux
- osx
# - osx
env:
matrix:
- LIBAV=libav-stable
@@ -47,7 +47,7 @@ notifications:
email: false
irc:
channels:
- "irc.freenode.org#mpv-devel"
- "irc.freenode.org#mpv-player-dev"
on_success: change
on_failure: always
-9
View File
@@ -25,15 +25,6 @@ API changes
::
--- mpv 0.9.0 is released ---
1.17 - add MPV_FORMAT_BYTE_ARRAY
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
+15 -33
View File
@@ -33,7 +33,6 @@ static inline void check_error(int status)
mpv_handle *mpv;
dispatch_queue_t queue;
NSWindow *w;
NSView *wrapper;
}
@end
@@ -56,19 +55,11 @@ static void wakeup(void *);
[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"];
[sm addItemWithTitle: @"Shutdown mpv" action:@selector(shutdown) keyEquivalent:@"s"];
[NSApp setMenu:m];
[NSApp activateIgnoringOtherApps:YES];
}
@@ -102,7 +93,7 @@ static void wakeup(void *);
exit(1);
}
int64_t wid = (intptr_t) self->wrapper;
int64_t wid = (intptr_t) [self->w contentView];
check_error(mpv_set_option(mpv, "wid", MPV_FORMAT_INT64, &wid));
// Maybe set some options here, like default key bindings.
@@ -131,28 +122,24 @@ static void wakeup(void *);
- (void) handleEvent:(mpv_event *)event
{
switch (event->event_id) {
case MPV_EVENT_SHUTDOWN: {
mpv_detach_destroy(mpv);
case MPV_EVENT_SHUTDOWN:
// Clean up and shut down.
mpv_terminate_destroy(mpv);
mpv = NULL;
printf("event: shutdown\n");
dispatch_async(dispatch_get_main_queue(), ^{
[[NSApplication sharedApplication] terminate:nil];
});
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: {
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];
}
[self->w selectNextKeyView:nil];
});
}
default:
printf("event: %s\n", mpv_event_name(event->event_id));
@@ -179,18 +166,13 @@ static void wakeup(void *context) {
// Ostensibly, mpv's window would be hooked up to this.
- (BOOL) windowShouldClose:(id)sender
{
return NO;
[self shutdown];
if (self->w)
[self->w release];
return YES;
}
- (void) mpv_stop
{
if (mpv) {
const char *args[] = {"stop", NULL};
mpv_command(mpv, args);
}
}
- (void) mpv_quit
- (void) shutdown
{
if (mpv) {
const char *args[] = {"quit", NULL};
+2 -1
View File
@@ -46,8 +46,9 @@ public:
void render()
{
QOpenGLFramebufferObject *fbo = framebufferObject();
int vp[4] = {0, 0, fbo->width(), fbo->height()};
window->resetOpenGLState();
mpv_opengl_cb_draw(mpv_gl, fbo->handle(), fbo->width(), fbo->height());
mpv_opengl_cb_render(mpv_gl, fbo->handle(), vp);
window->resetOpenGLState();
}
};
-1
View File
@@ -3,7 +3,6 @@ QT += qml quick
HEADERS += main.h
SOURCES += main.cpp
QT_CONFIG -= no-pkg-config
CONFIG += link_pkgconfig debug
PKGCONFIG += mpv
+4 -9
View File
@@ -39,13 +39,15 @@ void MpvRenderer::paint()
{
window->resetOpenGLState();
// Render to the whole window.
int vp[4] = {0, 0, size.width(), -size.height()};
// 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());
mpv_opengl_cb_render(mpv_gl, 0, vp);
window->resetOpenGLState();
}
@@ -94,8 +96,6 @@ void MpvObject::handleWindowChanged(QQuickWindow *win)
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);
}
@@ -110,11 +110,6 @@ void MpvObject::sync()
renderer->size = window()->size() * window()->devicePixelRatio();
}
void MpvObject::swapped()
{
mpv_opengl_cb_report_flip(mpv_gl, 0);
}
void MpvObject::cleanup()
{
if (renderer) {
@@ -37,7 +37,6 @@ public:
public slots:
void command(const QVariant& params);
void sync();
void swapped();
void cleanup();
signals:
void onUpdate();
@@ -3,7 +3,6 @@ QT += qml quick
HEADERS += main.h
SOURCES += main.cpp
QT_CONFIG -= no-pkg-config
CONFIG += link_pkgconfig debug
PKGCONFIG += mpv
@@ -5,7 +5,6 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = qtexample
TEMPLATE = app
QT_CONFIG -= no-pkg-config
CONFIG += link_pkgconfig debug
PKGCONFIG += mpv
+2 -3
View File
@@ -66,9 +66,9 @@ echo "MXE_TARGETS := i686-w64-mingw32.static" >> settings.mk
# 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).
# mpv.
make gcc ffmpeg libass jpeg pthreads lua
make gcc ffmpeg libass jpeg pthreads
# Add MXE binaries to $PATH
export PATH=/opt/mxe/usr/bin/:$PATH
@@ -79,7 +79,6 @@ export PATH=/opt/mxe/usr/bin/:$PATH
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
+2 -7
View File
@@ -4,8 +4,8 @@ How to contribute
General
-------
The main contact for mpv development is IRC, specifically #mpv
and #mpv-devel on Freenode.
The main contact for mpv development is IRC, specifically #mpv-player
and #mpv-player-dev on Freenode.
Sending patches
---------------
@@ -14,9 +14,6 @@ Sending patches
``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.
@@ -121,8 +118,6 @@ mpv uses C99 with K&R formatting, with some exceptions.
very_long_condition_b)
{
code();
} else {
...
}
```
- Remove any trailing whitespace.
+21 -37
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
@@ -92,8 +92,8 @@ Available filters are:
:5ch: 448
:6ch: 448
``minch=<n>``
If the input channel number is less than ``<minch>``, the filter will
``minchn=<n>``
If the input channel number is less than ``<minchn>``, the filter will
detach itself (default: 3).
``sweep[=speed]``
@@ -225,21 +225,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
@@ -259,9 +252,14 @@ 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 ``--audio-format``, ``--audio-samplerate``, and
``--audio-channels`` for related options. Keep in mind that
``--audio-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
@@ -567,10 +565,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 ``[ multiply speed 0.9438743126816935`` and
``] multiply speed 1.059463094352953`` to your ``input.conf``
to step by musical semi-tones.
.. warning::
@@ -603,20 +600,6 @@ 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.
@@ -631,3 +614,4 @@ Available filters are:
``o=<string>``
AVOptions.
+15 -25
View File
@@ -55,14 +55,6 @@ Available audio output drivers are:
Allow output of non-interleaved formats (if the audio decoder uses
this format). Currently disabled by default, because some popular
ALSA plugins are utterly broken with non-interleaved formats.
``ingore-chmap``
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::
@@ -107,10 +99,8 @@ Available audio output drivers are:
``--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.
You can also try
`Using the upmix plugin <https://github.com/mpv-player/mpv/wiki/ALSA:-Surround-Sound-and-Upmixing>`_.
``oss``
OSS audio output driver
@@ -304,19 +294,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.
+37 -117
View File
@@ -86,11 +86,11 @@ List of Input Commands
disabling default bindings, without disabling all bindings with
``--no-input-default-bindings``.
``seek <seconds> [relative|absolute|absolute-percent|exact|keyframes]``
``seek <seconds> [relative|absolute|absolute-percent|- [default-precise|exact|keyframes]]``
Change the playback position. By default, seeks by a relative amount of
seconds.
The second argument consists of flags controlling the seek mode:
The second argument sets the seek mode:
relative (default)
Seek relative to current position (a negative value seeks backwards).
@@ -98,19 +98,16 @@ List of Input Commands
Seek to a given time.
absolute-percent
Seek to a given percent position.
keyframes
Always restart playback at keyframe boundaries (fast).
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).
Multiple flags can be combined, e.g.: ``absolute+keyframes``.
By default, ``keyframes`` is used for relative seeks, and ``exact`` is used
for absolute seeks.
Before mpv 0.9, the ``keyframes`` and ``exact`` flags had to be passed as
3rd parameter (essentially using a space instead of ``+``). The 3rd
parameter is still parsed, but is considered deprecated.
keyframes
Always restart playback at keyframe boundaries (fast).
``revert_seek [mode]``
Undoes the ``seek`` command, and some other commands that seek (but not
@@ -173,12 +170,16 @@ List of Input Commands
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. Note that you should disable frame-dropping when using
this mode - or you might receive duplicate images in cases when a
frame was dropped. This flag can be combined with the other flags,
e.g. ``video+each-frame``.
frame was dropped.
``screenshot_to_file "<filename>" [subtitles|video|window]``
Take a screenshot and save it to a given file. The format of the file will
@@ -187,7 +188,8 @@ List of Input Commands
The second argument is like the first argument to ``screenshot``.
If the file already exists, it's overwritten.
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`_.
@@ -398,21 +400,6 @@ List of Input Commands
``audio_reload [<id>]``
Reload the given audio tracks. See ``sub_reload`` command.
``rescan_external_files [<mode>]``
Rescan external files according to the current ``--sub-auto`` and
``--audio-file-auto`` settings. This can be used to auto-load external
files *after* the file was loaded.
The ``mode`` argument is one of the following:
<keep-selection> (default)
Do not change current track selections.
<reselect>
Select the default audio and video streams, which typically selects
external files with highest preference. (The implementation is not
perfect, and could be improved on request.)
Input Commands that are Possibly Subject to Change
--------------------------------------------------
@@ -631,15 +618,6 @@ Input Commands that are Possibly Subject to Change
unseekable streams that are going out of sync.
This command might be changed or removed in the future.
``screenshot_raw [subtitles|video|window]``
Return a screenshot in memory. This can be used only through the client
API. The MPV_FORMAT_NODE_MAP returned by this command has the ``w``, ``h``,
``stride`` fields set to obvious contents. A ``format`` field is set to
``bgr0`` by default. This format is organized as ``B8G8R8X8`` (where ``B``
is the LSB). The contents of the padding ``X`` is undefined. The ``data``
field is of type MPV_FORMAT_BYTE_ARRAY with the actual image data. The image
is freed as soon as the result node is freed.
Undocumented commands: ``tv_last_channel`` (TV/DVB only),
``get_property`` (deprecated), ``ao_reload`` (experimental/internal).
@@ -928,10 +906,6 @@ Property list
a BD or DVD. Use the ``discnav menu`` command to actually enter or leave
menu mode.
``disc-mouse-on-button``
Return ``yes`` when the mouse cursor is located on a button, or ``no``
when cursor is outside of any button for disc navigation.
``chapters``
Number of chapters.
@@ -1090,11 +1064,6 @@ Property list
guess is very unreliable, and often the property will not be available
at all, even if data is buffered.
``demuxer-cache-time``
Approximate time of video buffered in the demuxer, in seconds. Same as
``demuxer-cache-duration`` but returns the last timestamp of bufferred
data in demuxer.
``demuxer-cache-idle``
Returns ``yes`` if the demuxer is idle, which means the demuxer cache is
filled to the requested amount, and is currently not reading more data.
@@ -1140,6 +1109,9 @@ Property list
``audio-codec``
Audio codec selected for decoding.
``audio-bitrate``
Audio bitrate. This is probably a very bad guess in most cases.
``audio-samplerate``
Audio samplerate.
@@ -1167,18 +1139,17 @@ Property list
``field-dominance`` (RW)
See ``--field-dominance``
``colormatrix`` (R)
Redirects to ``video-params/colormatrix``. This parameter (as well as
similar ones) can be overridden with the ``format`` video filter.
``colormatrix`` (RW)
See ``--colormatrix``.
``colormatrix-input-range`` (R)
See ``colormatrix``.
``colormatrix-input-range`` (RW)
See ``--colormatrix-input-range``.
``colormatrix-output-range`` (R)
See ``colormatrix``.
``colormatrix-output-range`` (RW)
See ``--colormatrix-output-range``.
``colormatrix-primaries`` (R)
See ``colormatrix``.
``colormatrix-primaries`` (RW)
See ``--colormatrix-primaries``.
``ontop`` (RW)
See ``--ontop``.
@@ -1237,6 +1208,9 @@ Property list
``video-codec``
Video codec selected for decoding.
``video-bitrate``
Video bitrate (a bad guess).
``width``, ``height``
Video size. This uses the size of the video as decoded, or if no video
frame has been decoded yet, the (possibly incorrect) container indicated
@@ -1281,9 +1255,6 @@ Property list
``video-params/primaries``
The primaries in use as string. (Exact values subject to change.)
``video-params/gamma``
The gamma function in use as string. (Exact values subject to change.)
``video-params/chroma-location``
Chroma location as string. (Exact values subject to change.)
@@ -1354,13 +1325,6 @@ Property list
Names of the displays that the mpv window covers. On X11, these
are the xrandr names (LVDS1, HDMI1, DP1, VGA1, etc.).
``display-fps``
The refresh rate of the current display. Currently, this is the lowest FPS
of any display covered by the video, as retrieved by the underlying system
APIs (e.g. xrandr on X11). It is not the measured FPS. It's not necessarily
available on all platforms. Note that any of the listed facts may change
any time without a warning.
``video-aspect`` (RW)
Video aspect, see ``--video-aspect``.
@@ -1417,11 +1381,8 @@ Property list
``sub-scale`` (RW)
Subtitle font size multiplier.
``ass-force-margins`` (RW)
See ``--ass-force-margins``.
``sub-use-margins`` (RW)
See ``--sub-use-margins``.
``ass-use-margins`` (RW)
See ``--ass-use-margins``.
``ass-vsfilter-aspect-compat`` (RW)
See ``--ass-vsfilter-aspect-compat``.
@@ -1525,13 +1486,6 @@ Property list
``track-list/N/selected``
``yes`` if the track is currently decoded, ``no`` otherwise.
``track-list/N/ff-index``
The stream index as usually used by the FFmpeg utilities. Note that
this can be potentially wrong if a demuxer other than libavformat
(``--demuxer=lavf``) is used. For mkv files, the index will usually
match even if the default (builtin) demuxer is used, but there is
no hard guarantee.
When querying the property with the client API using ``MPV_FORMAT_NODE``,
or with Lua ``mp.get_property_native``, this will return a mpv_node with
the following contents:
@@ -1653,7 +1607,7 @@ Property list
whether the video window is visible. If the ``--force-window`` option is
used, this is usually always returns ``yes``.
``video-bitrate``, ``audio-bitrate``, ``sub-bitrate``
``packet-video-bitrate``, ``packet-audio-bitrate``, ``packet-sub-bitrate``
Bitrate values calculated on the packet level. This works by dividing the
bit size of all packets between two keyframes by their presentation
timestamp distance. (This uses the timestamps are stored in the file, so
@@ -1662,29 +1616,8 @@ Property list
bitrate. To make the property more UI friendly, updates to these properties
are throttled in a certain way.
The unit is bits per second. OSD formatting turns these values in kilobits
(or megabits, if appropriate), which can be prevented by using the
raw property value, e.g. with ``${=video-bitrate}``.
Note that the accuracy of these properties is influenced by a few factors.
If the underlying demuxer rewrites the packets on demuxing (done for some
file formats), the bitrate might be slightly off. If timestamps are bad
or jittery (like in Matroska), even constant bitrate streams might show
fluctuating bitrate.
How exactly these values are calculated might change in the future.
In earlier versions of mpv, these properties returned a static (but bad)
guess using a completely different method.
``packet-video-bitrate``, ``packet-audio-bitrate``, ``packet-sub-bitrate``
Old and deprecated properties for ``video-bitrate``, ``audio-bitrate``,
``sub-bitrate``. They behave exactly the same, but return a value in
kilobits. Also, they don't have any OSD formatting, though the same can be
achieved with e.g. ``${=video-bitrate}``.
These properties shouldn't be used anymore.
``audio-device-list``
Return the list of discovered audio devices. This is mostly for use with
the client API, and reflects what ``--audio-device=help`` with the command
@@ -1706,13 +1639,6 @@ Property list
human readable free form text. The description is an empty string if none
was received.
The special entry with the name set to ``auto`` selects the default audio
output driver and the default device.
The property can be watched with the property observation mechanism in
the client API and in Lua scripts. (Technically, change notification is
enabled the first time this property is read.)
``audio-device`` (RW)
Set the audio device. This directly reads/writes the ``--audio-device``
option, but on write accesses, the audio output will be scheduled for
@@ -1736,10 +1662,6 @@ Property list
Return the audio device selected by the AO driver (only implemented for
some drivers: currently only ``coreaudio``).
``working-directory``
Return the working directory of the mpv process. Can be useful for JSON IPC
users, because the command line player usually works with relative paths.
``mpv-version``
Return the mpv version/copyright string. Depending on how the binary was
built, it might contain either a release version, or just a git hash.
@@ -1779,6 +1701,7 @@ Property list
For many complex types, this isn't very accurate.
``option-info/<name>/set-from-commandline``
Return ``yes`` if the option was set from the mpv command line,
``no`` otherwise. What this is set to if the option is e.g. changed
at runtime is left undefined (meaning it could change in the future).
@@ -1805,10 +1728,7 @@ Property Expansion
------------------
All string arguments to input commands as well as certain options (like
``--term-playing-msg``) are subject to property expansion. Note that property
expansion does not work in places where e.g. numeric parameters are expected.
(For example, the ``add`` command does not do property expansion. The ``set``
command is an exception and not a general rule.)
``--term-playing-msg``) are subject to property expansion.
.. admonition:: Example for input.conf
-3
View File
@@ -79,9 +79,6 @@ mpv will also send events to clients with JSON messages of the following form:
where ``event_name`` is the name of the event. Additional event-specific fields
can also be present. See `List of events`_ for a list of all supported events.
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
+2 -33
View File
@@ -73,10 +73,6 @@ The ``mp`` module is preloaded, although it can be loaded manually with
Run the given command. This is similar to the commands used in input.conf.
See `List of Input Commands`_.
By default, this will show something on the OSD (depending on the command),
as if it was used in ``input.conf``. See `Input Command Prefixes`_ how
to influence OSD usage per command.
Returns ``true`` on success, or ``nil, error`` on error.
``mp.commandv(arg1, arg2, ...)``
@@ -98,9 +94,6 @@ The ``mp`` module is preloaded, although it can be loaded manually with
the ``expand-properties`` prefix, or the ``mp.get_property`` family of
functions.
Unlike ``mp.command``, this will not use OSD by default either (except
for some OSd-specific commands).
``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
@@ -333,6 +326,7 @@ The ``mp`` module is preloaded, although it can be loaded manually with
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
@@ -363,23 +357,6 @@ The ``mp`` module is preloaded, although it can be loaded manually with
(``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
@@ -518,7 +495,7 @@ Example implementation::
optionB = -0.5,
optionC = true,
}
read_options(options, "myscript")
options.read_options(options, "myscript")
print(option.optionA)
@@ -646,14 +623,6 @@ strictly part of the guaranteed API.
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.
+25 -69
View File
@@ -32,10 +32,8 @@ 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
----------------
@@ -137,11 +135,6 @@ l
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.
@@ -276,16 +269,14 @@ 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
The ``[...]`` from 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``.)
an argument (like bash).
The fixed-length quoting syntax is intended for use with external
scripts and programs.
A special kind of string-escaping intended for use with external scripts and
programs is started with ``%``.
It is started with ``%`` and has the following format::
It has the following format::
%n%string_of_length_n
@@ -321,8 +312,7 @@ 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/``).
@@ -378,8 +368,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``. For details and platform
specifics see the `FILES`_ section.
user-specific one is ``~/.config/mpv/mpv.conf``.
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
@@ -401,10 +390,10 @@ Escaping spaces and special characters
This is done like with command line options. The shell is not involved here,
but option values still need to be quoted as a whole if it contains certain
characters like spaces. A config entry can be quoted with ``"`` and ``'``,
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.)
as well as with the ``%n%`` syntax 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
--------------------------------------------------------
@@ -479,8 +468,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.
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.)
TERMINAL STATUS LINE
====================
@@ -518,13 +510,14 @@ listed.
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.)
to the display as well, e.g.: ``Dropped: 4/34``. This should almost never
happen, unless decoder-framedropping is enabled with one of the
``--framedrop`` options, the stream contains errors, or a weird codec is in
use. (``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.)
kilobytes. (``demuxer-cache-duration`` and ``cached-used`` properties.)
PROTOCOLS
@@ -610,39 +603,6 @@ PROTOCOLS
``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``.
.. include:: options.rst
.. include:: ao.rst
@@ -797,15 +757,11 @@ input command can take an exit code: in this case, that exit code is returned.
FILES
=====
For Windows-specifics, see `FILES ON WINDOWS`_ section.
``/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 user settings
``~/.config/mpv/input.conf``
key bindings (see `INPUT.CONF`_ section)
+147 -138
View File
@@ -104,9 +104,8 @@ Playback Control
``--speed=<0.01-100>``
Slow down or speed up playback by the factor given as parameter.
If ``--audio-pitch-correction`` (on by default) is used, playing with a
speed higher than normal automatically inserts the ``scaletempo`` audio
filter.
If ``--audio-pitch-correction`` is used, playing with a speed higher than
normal automatically inserts the ``scaletempo`` audio filter.
``--loop=<N|inf|force|no>``
Loops playback ``N`` times. A value of ``1`` plays it one time (default),
@@ -181,7 +180,6 @@ Playback Control
file, such as a chapter seek, but not for relative seeks like
the default behavior of arrow keys (default).
:yes: Use precise seeks whenever possible.
:always: Same as ``yes`` (for compatibility).
``--hr-seek-demuxer-offset=<seconds>``
This option exists to work around failures to do precise seeks (as in
@@ -440,8 +438,7 @@ Program Behavior
Enable the youtube-dl hook-script. It will look at the input URL, and will
play the video located on the website. This works with many streaming sites,
not just the one that the script is named after. This requires a recent
version of youtube-dl to be installed on the system. (Enabled by default,
except when the client API / libmpv is used.)
version of youtube-dl to be installed on the system. (Enabled by default.)
If the script can't do anything with an URL, it will do nothing.
@@ -456,18 +453,6 @@ Program Behavior
``bestvideo+bestaudio``.
(Default: ``best``)
``--ytdl-raw-options=<key>=<value>[,<key>=<value>[,...]]``
Pass arbitraty options to youtube-dl. Parameter and argument should be
passed as a key-value pair. Options without argument must include ``=``.
There is no sanity checking so it's possible to break things (i.e.
passing invalid parameters to youtube-dl).
.. admonition:: Example
``--ytdl-raw-options=username=user,password=pass``
``--ytdl-raw-options=force-ipv6=``
Video
-----
@@ -498,10 +483,6 @@ Video
Do not play video. With some demuxers this may not work. In those cases
you can try ``--vo=null`` instead.
mpv will try to download the audio only if media is streamed with
youtube-dl, because it saves bandwidth. This is done by setting the ytdl_format
to "bestaudio/best" in the ytdl_hook.lua script.
``--untimed``
Do not sleep when outputting video frames. Useful for benchmarks when used
with ``--no-audio.``
@@ -559,8 +540,7 @@ Video
:vaapi: requires ``--vo=opengl`` or ``--vo=vaapi`` (Linux with Intel GPUs only)
:vaapi-copy: copies video back into system RAM (Linux with Intel GPUs only)
:vda: requires ``--vo=opengl`` (OS X only)
:dxva2-copy: copies video back to system RAM (Windows only)
:rpi: requires ``--vo=rpi`` (Raspberry Pi only - default if available)
:dxva2-copy: copies video back to system RAM (Windows only) (experimental)
``auto`` tries to automatically enable hardware decoding using the first
available method. This still depends what VO you are using. For example,
@@ -571,7 +551,8 @@ Video
The ``vaapi-copy`` mode allows you to use vaapi with any VO. Because
this copies the decoded video back to system RAM, it's likely less efficient
than the ``vaapi`` mode.
than the ``vaapi`` mode. But there are reports that this is actually faster
as well, and avoids many issues with ``vaapi``.
.. note::
@@ -632,7 +613,7 @@ Video
This option is disabled if the ``--no-keepaspect`` option is used.
``--video-rotate=<0-360|no>``
``--video-rotate=<0-359|no>``
Rotate the video clockwise, in degrees. Currently supports 90° steps only.
If ``no`` is given, the video is never rotated, even if the file has
rotation metadata. (The rotation value is added to the rotation metadata,
@@ -819,7 +800,7 @@ Audio
-----
``--audio-pitch-correction=<yes|no>``
If this is enabled (default), playing with a speed different from normal
If this is enabled (default), playing with a speed higher than normal
automatically inserts the ``scaletempo`` audio filter. For details, see
audio filter section.
@@ -891,7 +872,8 @@ Audio
delay the audio, and negative values delay the video.
``--no-audio``
Do not play sound.
Do not play sound. With some demuxers this may not work. In those cases
you can try ``--ao=null`` instead.
``--mute=<auto|yes|no>``
Set startup audio mute status. ``auto`` (default) will not change the mute
@@ -920,14 +902,11 @@ Audio
``--ad-lavc-ac3drc=<level>``
Select the Dynamic Range Compression level for AC-3 audio streams.
``<level>`` is a float value ranging from 0 to 1, where 0 means no
compression (which is the default) and 1 means full compression (make loud
passages more silent and vice versa). Values up to 6 are also accepted, but
compression and 1 (which is the default) means full compression (make loud
passages more silent and vice versa). Values up to 2 are also accepted, but
are purely experimental. This option only shows an effect if the AC-3 stream
contains the required range compression information.
The standard mandates that DRC is enabled by default, but mpv (and some
other players) ignore this for the sake of better audio quality.
``--ad-lavc-downmix=<yes|no>``
Whether to request audio channel downmixing from the decoder (default: yes).
Some decoders, like AC-3, AAC and DTS, can remix audio on decoding. The
@@ -987,9 +966,8 @@ Audio
``--audio-display=<no|attachment>``
Setting this option to ``attachment`` (default) will display image
attachments (e.g. album cover art) when playing audio files. It will
display the first image found, and additional images are available as
video tracks.
attachments when playing audio files. It will display the first image
found, and additional images are available as video tracks.
Setting this option to ``no`` disables display of video entirely when
playing audio files.
@@ -1178,22 +1156,13 @@ Subtitles
doesn't covert the window fully, e.g. because screen aspect and window
aspect mismatch (and the player adds black bars).
Default: yes.
This option is misnamed. The difference to the confusingly similar sounding
option ``--sub-scale-by-window`` is that ``--sub-scale-with-window`` still
scales with the approximate window size, while the other option disables
this scaling.
Affects plain text subtitles only (or ASS if ``--ass-style-override`` is
set high enough).
``--ass-scale-with-window=<yes|no>``
Like ``--sub-scale-with-window``, but affects subtitles in ASS format only.
Like ``--sub-scale``, this can break ASS subtitles.
Default: no.
``--embeddedfonts``, ``--no-embeddedfonts``
Use fonts embedded in Matroska container files and ASS scripts (default:
enabled). These fonts can be used for SSA/ASS subtitle rendering.
@@ -1274,23 +1243,12 @@ Subtitles
:signfs: like ``yes``, but apply ``--sub-scale`` only to signs
:no: Render subtitles as forced by subtitle scripts.
:force: Try to force the font style as defined by the ``--sub-text-*``
options. Can break rendering easily.
options. Requires a modified libass, can break rendering easily.
Probably more reliable than ``force``.
``--ass-force-margins``
``--ass-use-margins``
Enables placing toptitles and subtitles in black borders when they are
available, if the subtitles are in the ASS format.
Default: no.
``--sub-use-margins``
Enables placing toptitles and subtitles in black borders when they are
available, if the subtitles are in a plain text format (or ASS if
``--ass-style-override`` is set high enough).
Default: yes.
Renamed from ``--ass-use-margins``. To place ASS subtitles in the borders
too (like the old option did), also add ``--ass-force-margins``.
available.
``--ass-vsfilter-aspect-compat=<yes|no>``
Stretch SSA/ASS subtitles when playing anamorphic videos for compatibility
@@ -1728,13 +1686,19 @@ Window
(depending on the video aspect ratio, the width or height will be
larger than 500 in order to keep the aspect ratio the same).
``--window-scale=<factor>``
Resize the video window to a multiple (or fraction) of the video size. This
option is applied before ``--autofit`` and other options are applied (so
they override this option).
For example, ``--window-scale=0.5`` would show the window at half the
video size.
``--autosync=<factor>``
Gradually adjusts the A/V sync based on audio delay measurements.
Specifying ``--autosync=0``, the default, will cause frame timing to be
based entirely on audio delay measurements. Specifying ``--autosync=1``
will do the same, but will subtly change the A/V correction algorithm. An
uneven video framerate in a video which plays fine with ``--no-audio`` can
often be helped by setting this to an integer value greater than 1. The
higher the value, the closer the timing will be to ``--no-audio``. Try
``--autosync=30`` to smooth out problems with sound drivers which do not
implement a perfect audio delay measurement. With this value, if large A/V
sync offsets occur, they will only take about 1 or 2 seconds to settle
out. This delay in reaction time to sudden A/V offsets should be the only
side-effect of turning this option on, for all sound drivers.
``--cursor-autohide=<number|no|always>``
Make mouse cursor automatically hide after given number of milliseconds.
@@ -1946,10 +1910,6 @@ Disc Devices
``--cdda-skip=<yes|no>``
(Never) accept imperfect data reconstruction.
``--cdda-cdtext=<yes|no>``
Print CD text. This is disabled by default, because it ruins perfomance
with CD-ROM drives for unknown reasons.
``--dvd-speed=<speed>``
Try to limit DVD speed (default: 0, no change). DVD base speed is 1385
kB/s, so an 8x drive can read at speeds up to 11080 kB/s. Slower speeds
@@ -1993,6 +1953,101 @@ Equalizer
negative of the image with this option. Not supported by all video output
drivers.
``--colormatrix=<colorspace>``
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.
The color space conversion is additionally influenced by the related
options --colormatrix-input-range and --colormatrix-output-range.
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
``--colormatrix-input-range=<color-range>``
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)
``--colormatrix-output-range=<color-range>``
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.
``--colormatrix-primaries=<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. By default, when unset, BT.709 is used for
all files except those tagged with a BT.2020 color matrix.
This option only affects video output drivers that perform color
management, for example ``opengl`` with the ``srgb`` 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)
Demuxer
-------
@@ -2020,12 +2075,6 @@ Demuxer
``--demuxer-lavf-format=<name>``
Force a specific libavformat demuxer.
``--demuxer-lavf-hacks=<yes|no>``
By default, some formats will be handled differently from other formats
by explicitly checking for them. Most of these compensate for weird or
imperfect behavior from libavformat demuxers. Passing ``no`` disables
these. For debugging and testing only.
``--demuxer-lavf-genpts-mode=<no|lavf>``
Mode for deriving missing packet PTS values from packet DTS. ``lavf``
enables libavformat's ``genpts`` option. ``no`` disables it. This used
@@ -2110,18 +2159,6 @@ Demuxer
will be slower (especially when playing over http), or that behavior with
broken files is much worse. So don't use this option.
``--demuxer-mkv-fix-timestamps=<yes|no>``
Fix rounded Matroska timestamps (enabled by default). Matroska usually
stores timestamps rounded to milliseconds. This means timestamps jitter
by some amount around the intended timestamp. mpv can correct the timestamps
based on the framerate value stored in the file: the timestamp is rounded
to the next frame (according to the framerate), unless the new timestamp
would deviate more than 1ms from the old one. This should undo the rounding
done by the muxer.
(The allowed deviation can be less than 1ms if the file uses a non-standard
timecode scale.)
``--demuxer-rawaudio-channels=<value>``
Number of channels (or channel layout) if ``--demuxer=rawaudio`` is used
(default: stereo).
@@ -2144,7 +2181,7 @@ Demuxer
Play a raw YUV sample::
mpv sample-720x576.yuv --demuxer=rawvideo \
--demuxer-rawvideo-w=720 --demuxer-rawvideo-h=576
--demuxer-rawvideo=w=720:h=576
``--demuxer-rawvideo-format=<value>``
Color space (fourcc) in hex or string for ``--demuxer=rawvideo``
@@ -2170,7 +2207,7 @@ Demuxer
``--demuxer-readahead-secs=<seconds>``
If ``--demuxer-thread`` is enabled, this controls how much the demuxer
should buffer ahead in seconds (default: 1). As long as no packet has
should buffer ahead in seconds (default: 0.2). As long as no packet has
a timestamp difference higher than the readahead amount relative to the
last packet returned to the decoder, the demuxer keeps reading.
@@ -2248,9 +2285,6 @@ Input
get replies or events. Use ``--input-unix-socket`` for something
bi-directional. On MS Windows, JSON commands are not available.
This can also specify a direct file descriptor with ``fd://N`` (UNIX only).
In this case, JSON replies will be written if the FD is writable.
See also ``--slave-broken``.
.. note::
@@ -2283,6 +2317,19 @@ Input
driver. Necessary to use the OSC, or to select the buttons in DVD menus.
Support depends on the VO in use.
``--input-joystick``, ``--no-input-joystick``
Enable/disable joystick support. Disabled by default.
``--input-js-dev``
Specifies the joystick device to use (default: ``/dev/input/js0``).
``--input-lirc``, ``--no-input-lirc``
Enable/disable LIRC support. Enabled by default.
``--input-lirc-conf=<filename>``
(LIRC only)
Specifies a configuration file for LIRC (default: ``~/.lircrc``).
``--input-media-keys=<yes|no>``
(OS X only)
Enable/disable media keys support. Enabled by default (except for libmpv).
@@ -2421,9 +2468,6 @@ OSD
``--osd-blur=<0..20.0>``, ``--sub-text-blur=<0..20.0>``
Gaussian blur factor. 0 means no blur applied (default).
``--osd-bold=<yes|no>``, ``--sub-text-bold=<yes|no>``
Format text on bold.
``--osd-border-color=<color>``, ``--sub-text-border-color=<color>``
See ``--osd-color``. Color used for the OSD/sub font border.
@@ -2468,8 +2512,7 @@ OSD
- ``--osd-color='#C0808080'`` set OSD to 50% gray with 75% alpha
``--osd-fractions``
Show OSD times with fractions of seconds (in millisecond precision). Useful
to see the exact timestamp of a video frame.
Show OSD times with fractions of seconds.
``--osd-level=<0-3>``
Specifies which mode the OSD should start in.
@@ -2498,17 +2541,6 @@ OSD
Default: 22.
``--osd-align-x=<left|center|right>``, ``--sub-text-align-x=...``
Control to which corner of the screen OSD or text subtitles should be
aligned to (default: ``center`` for subs, ``left`` for OSD).
Never applied to ASS subtitles, except in ``--no-sub-ass`` mode. Likewise,
this does not apply to image subtitles.
``--osd-align-y=<top|center|bottom>`` ``--sub-text-align-y=...``
Vertical position (default: ``bottom`` for subs, ``top`` for OSD).
Details see ``--osd-align-x``.
``--osd-scale=<factor>``
OSD font size multiplier, multiplied with ``--osd-font-size`` value.
@@ -2561,13 +2593,6 @@ Screenshot
:jpg: JPEG (default)
:jpeg: JPEG (same as jpg, but with .jpeg file ending)
``--screenshot-tag-colorspace=<yes|no>``
Tag screenshots with the appropriate colorspace.
Note that not all formats are supported.
Default: ``yes``.
``--screenshot-template=<template>``
Specify the filename template used to save screenshots. The template
specifies the filename without file extension, and can contain format
@@ -2866,7 +2891,7 @@ TV
Use _ for spaces in names (or play with quoting ;-) ). The channel
names will then be written using OSD, and the slave commands
``tv_step_channel``, ``tv_set_channel`` and ``tv_last_channel``
will be usable for a remote control. Not compatible with
will be usable for a remote control (see LIRC). Not compatible with
the ``frequency`` parameter.
.. note::
@@ -2975,13 +3000,11 @@ TV
Cache
-----
``--cache=<kBytes|yes|no|auto>``
``--cache=<kBytes|no|auto>``
Set the size of the cache in kilobytes, disable it with ``no``, or
automatically enable it if needed with ``auto`` (default: ``auto``).
With ``auto``, the cache will usually be enabled for network streams,
using the size set by ``--cache-default``. With ``yes``, the cache will
always be enabled with the size set by ``--cache-default`` (unless the
stream can not be cached, or ``--cache-default`` disables caching).
using the size set by ``--cache-default``.
May be useful when playing files from slow media, but can also have
negative effects, especially with file formats that require a lot of
@@ -2994,7 +3017,7 @@ Cache
because no space is reserved for seeking back yet.
``--cache-default=<kBytes|no>``
Set the size of the cache in kilobytes (default: 150000 KB). Using ``no``
Set the size of the cache in kilobytes (default: 25000 KB). Using ``no``
will not automatically enable the cache e.g. when playing from a network
stream. Note that using ``--cache`` will always override this option.
@@ -3067,7 +3090,7 @@ Cache
``--cache-secs=<seconds>``
How many seconds of audio/video to prefetch if the cache is active. This
overrides the ``--demuxer-readahead-secs`` option if and only if the cache
is enabled and the value is larger. (Default: 10.)
is enabled and the value is larger. (Default: 2.)
``--cache-pause``, ``--no-cache-pause``
Whether the player should automatically pause when the cache runs low,
@@ -3248,20 +3271,6 @@ Miscellaneous
``--mc=<seconds/frame>``
Maximum A-V sync correction per frame (in seconds)
``--autosync=<factor>``
Gradually adjusts the A/V sync based on audio delay measurements.
Specifying ``--autosync=0``, the default, will cause frame timing to be
based entirely on audio delay measurements. Specifying ``--autosync=1``
will do the same, but will subtly change the A/V correction algorithm. An
uneven video framerate in a video which plays fine with ``--no-audio`` can
often be helped by setting this to an integer value greater than 1. The
higher the value, the closer the timing will be to ``--no-audio``. Try
``--autosync=30`` to smooth out problems with sound drivers which do not
implement a perfect audio delay measurement. With this value, if large A/V
sync offsets occur, they will only take about 1 or 2 seconds to settle
out. This delay in reaction time to sudden A/V offsets should be the only
side-effect of turning this option on, for all sound drivers.
``--mf-fps=<value>``
Framerate used when decoding from multiple PNG or JPEG files with ``mf://``
(default: 1).
+10 -11
View File
@@ -169,35 +169,34 @@ Configurable Options
``showwindowed``
| Default: yes
| Enable the OSC when windowed
| Show OSC when windowed?
``showfullscreen``
| Default: yes
| Enable the OSC when fullscreen
| Show OSC when fullscreen?
``scalewindowed``
| Default: 1.0
| Scale factor of the OSC when windowed
| Default: 1
| Scaling of the controller when windowed
``scalefullscreen``
| Default: 1.0
| Scale factor of the OSC when fullscreen
| Default: 1
| Scaling of the controller when fullscreen
``scaleforcedwindow``
| Default: 2.0
| Scale factor of the OSC when rendered on a forced (dummy) window
| Default: 2
| Scaling of the controller when rendered on a forced (dummy) window
``vidscale``
| Default: yes
| Scale the OSC with the video
| ``no`` tries to keep the OSC size constant as much as the window size allows
| Scale the controller with the video?
``valign``
| Default: 0.8
| Vertical alignment, -1 (top) to 1 (bottom)
``halign``
| Default: 0.0
| Default: 0
| Horizontal alignment, -1 (left) to 1 (right)
``boxalpha``
+19 -142
View File
@@ -198,7 +198,7 @@ Available filters are:
``<aspect>``
Force an aspect ratio.
``format=fmt=<value>:colormatrix=<value>:...``
``format[=fmt[:outfmt]]``
Restricts the color space for the next filter without doing any conversion.
Use together with the scale filter for a real conversion.
@@ -207,148 +207,19 @@ 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.
@@ -561,6 +432,12 @@ Available filters are:
``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 +445,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
+101 -235
View File
@@ -308,72 +308,36 @@ Available video output drivers are:
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
Relatively slow, but very good quality. The number of taps can
be controlled with ``scale-radius``. Adding extra taps 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.
This filter supports antiringing (see ``scale-antiring``).
``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``).
Mitchell-Netravali. The ``b`` and ``c`` parameters can be set with
``scale-param1`` and ``scale-param2``. Both are set to 1/3 by default.
This filter is very good at downscaling (see ``scale-down``).
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:
``scale-param1=<value>``
Set filter parameters. Ignored if the filter is not tunable. These are
unset by default, and use the filter specific default if applicable.
bcspline
Spline parameters (``B`` and ``C``). Defaults to 0.5 for both.
``scale-param2=<value>``
See ``scale-param1``.
gaussian
Scale parameter (``t``). Increasing this makes the result blurrier.
Defaults to 1.
``scale-radius=<r>``
Set radius for filters listed below, must be a float number between 1.0
and 16.0. Defaults to be 3.0 if not specified.
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``
``sinc``, ``lanczos``, ``ewa_lanczos``, ``blackman``, ``gaussian``
Note that depending on filter implementation details and video scaling
ratio, the radius that actually being used might be different
@@ -385,26 +349,7 @@ Available video output drivers are:
between 0.0 and 1.0. The default value of 0.0 disables antiringing
entirely.
Note that this doesn't affect the special filters ``bilinear``,
``bicubic_fast`` or ``sharpen``.
``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.
Note that this currently only affects ``ewa_lanczos``.
``scaler-resizes-only``
Disable the scaler if the video image is not resized. In that case,
@@ -412,6 +357,21 @@ Available video output drivers are:
will reproduce the source image perfectly if no scaling is performed.
Note that this option never affects ``cscale``.
``srgb``
Convert and color correct the output to sRGB before displaying it on
the screen. This option enables ``linear-scaling``.
This option is equivalent to using ``icc-profile`` with an sRGB ICC
profile, but it is implemented without a 3DLUT and does not require
LittleCMS 2. If both ``srgb`` and ``icc-profile`` are present, the
latter takes precedence, as they are somewhat redundant.
Note: When playing back BT.2020 content with this option enabled, out
of gamut colors will be numerically clipped, which can potentially
change the hue and/or luminance. If this is not desired, it is
recommended to use ``icc-profile`` with an sRGB ICC profile instead,
when playing back wide-gamut BT.2020 content.
``pbo``
Enable use of PBOs. This is slightly faster, but can sometimes lead to
sporadic and temporary image corruption (in theory, because reupload
@@ -457,59 +417,31 @@ Available video output drivers are:
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.
1 is equivalent to enable VSYNC, 0 to disable VSYNC.
``cscale=<filter>``
As ``scale``, but for interpolating chroma information. If the image
is not subsampled, this option is ignored entirely.
is not subsampled, this option is ignored entirely. Note that the
implementation is currently always done as a single pass, so using
it with separable filters will result in slow performance for very
little visible benefit.
``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``.
``scale-down=<filter>``
Like ``scale``, but apply these filters on downscaling instead. If this
option is unset, the filter implied by ``scale`` will be applied.
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.
``cscale-param1``, ``cscale-param2``, ``cscale-radius``, ``cscale-antiring``
Set filter parameters and radius for ``cscale``.
``dscale-radius``, ``cscale-radius``, ``tscale-radius``, etc.
Set filter parameters for ``dscale``, ``cscale`` and ``tscale``,
respectively.
See the corresponding options for ``scale``.
See ``scale-param1``, ``scale-param2``, ``scale-radius`` and
``scale-antiring``.
``linear-scaling``
Scale in linear light. This is automatically enabled if
``target-prim``, ``target-trc``, ``icc-profile`` or
``sigmoid-upscaling`` is set. It should only be used with a
``fbo-format`` that has at least 16 bit precision.
Scale in linear light. This is automatically enabled if ``srgb``,
``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
@@ -548,17 +480,6 @@ Available video output drivers are:
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.
@@ -586,7 +507,7 @@ Available video output drivers are:
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: rgba16.
Default: rgba.
``gamma=<0.1..2.0>``
Set a gamma value (default: 1.0). If gamma is adjusted in other ways
@@ -602,67 +523,13 @@ Available video output drivers are:
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
Needs LittleCMS 2 support compiled in. This option overrides the ``srgb``
property, as using both is somewhat redundant. It also enables
``linear-scaling``.
``icc-profile-auto``
Automatically select the ICC display profile currently specified by
the display settings of the operating system.
@@ -676,8 +543,9 @@ Available video output drivers are:
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``).
Specifies the ICC Intent used for transformations between color spaces.
This affects the rendering when using ``icc-profile`` or ``srgb`` and
also affects the way DCP XYZ content gets converted to RGB.
0
perceptual
@@ -693,28 +561,6 @@ Available video output drivers are:
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).
@@ -730,6 +576,10 @@ Available video output drivers are:
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
@@ -739,12 +589,54 @@ Available video output drivers are:
Color used to draw parts of the mpv window not covered by video.
See ``--osd-color`` option how colors are defined.
``smoothmotion``
Reduce stuttering caused by mismatches in video fps and display
refresh rate (also known as judder).
Instead of drawing source frames for variable durations, smoothmotion
will blend frames that overlap the transition between two frames in
the source material.
For example, a 24 Hz clip played back on a 60 Hz display would normally
result in a pattern like this::
A A A B B C C C D D E E E F F
which has different lengths, alternating between 3 and 2. This
difference in frame duration is what causes judder.
With smoothmotion enabled, the pattern changes to::
A A A+B B B C C C+D D D E E E+F F F
where A+B is a blend of A and B. In this pattern, each frame gets a
(consistent) duration of roughly 2.5 - resulting in smooth motion.
GPU drivers or compositing window managers overriding vsync behavior
can lead to bad results. If the framerate is close to or over the
display refresh rate, results can be bad as well.
.. note:: On systems other than Linux or OS X, you currently must set
the ``--display-fps`` option, or the results will be bad.
``smoothmotion-threshold=<0.0-0.5>``
Mix threshold at which interpolation is skipped (default: 0.0 – never
skip).
For example, with a ``smoothmotion-threshold`` of 0.1, if the
smoothmotion algorithm would try to blend two frames by a ratio of
95% A + 5% B, it would simply display A instead. (Since the
distance, 0.05, is lower than the threshold)
Setting this to 0.5 would be similar to disabling smoothmotion
completely, since it would always just display the nearest frame.
``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:fancy-downscaling:sigmoid-upscaling
--vo=opengl:scale=spline36:scale-down=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.
@@ -903,33 +795,7 @@ Available video output drivers are:
clear
Drop all frames in the frame queue.
This also supports many of the suboptions the ``opengl`` VO has. Run
This also supports many of the suboptions the ``opengl`` VO has. Runs
``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)
+2 -6
View File
@@ -46,12 +46,6 @@ Input
* 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``.
Also see: http://github.com/mpv-player/mpv/wiki/IR-remotes
* Joystick support was removed. It was considered useless and was the cause
of some problems (e.g. a laptop's accelerator being recognized as joystick).
Audio
~~~~~
@@ -233,6 +227,7 @@ Command Line Switches
``-idx`` ``--index``
``-lavdopts ...`` ``--vd-lavc-...``
``-lavfdopts`` ``--demuxer-lavf-...``
``-lircconf`` ``--input-lirc-conf``
``-loop 0`` ``--loop=inf``
``-mixer-channel`` AO suboptions (``alsa``, ``oss``)
``-mixer`` AO suboptions (``alsa``, ``oss``)
@@ -244,6 +239,7 @@ Command Line Switches
``-noar`` ``--no-input-appleremote``
``-noautosub`` ``--no-sub-auto``
``-noconsolecontrols`` ``--no-input-terminal``
``-nojoystick`` ``--no-input-joystick``
``-nosound`` ``--no-audio``
``-osdlevel`` ``--osd-level``
``-panscanrange`` ``--video-zoom``, ``--video-pan-x/y``
+2 -3
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.
+24 -74
View File
@@ -1,39 +1,17 @@
![http://mpv.io/](https://raw.githubusercontent.com/mpv-player/mpv.io/master/source/images/mpv-logo-128.png)
## mpv
--------------
* [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
===
Overview
--------
**mpv** is a media 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.
@@ -67,10 +45,10 @@ Essential dependencies (incomplete list):
- Audio output development headers (libasound/ALSA, pulseaudio)
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavfilter
and either libswresample or libavresample)
At least FFmpeg 2.4.0 or Libav 11 is required.
At least FFmpeg 2.1.4 or Libav 10 is required.
- zlib
- iconv (normally provided by the system libc)
- libass (OSD, OSC, text subtitles)
- libass
- Lua (optional, required for the OSC pseudo-GUI and youtube-dl integration)
- libjpeg (optional, used for screenshots only)
- Enca (optional, for subtitle charset detection)
@@ -106,16 +84,16 @@ 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.
@@ -133,57 +111,35 @@ 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
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.
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
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` on `irc.freenode.net`
- **Developer IRC Channel**: `#mpv-devel` on `irc.freenode.net`
- **User IRC Channel**: `#mpv-player` on `irc.freenode.net`
- **Developer IRC Channel**: `#mpv-player-dev` 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.
[releases]: https://github.com/mpv-player/mpv/releases
[changes]: https://github.com/mpv-player/mpv/blob/master/DOCS/man/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
@@ -192,9 +148,3 @@ only if discretion is required.
[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)
+3 -493
View File
@@ -1,279 +1,10 @@
Release 0.9.2
=============
Changes
-------
- The Lua check now also checks for `lua52.pc`, as used by Arch Linux testing.
- (X11) `vo_opengl`'s `icc-profile-auto` now queries the current ICC profile
relative to the center of the window.
- `ao_coreaudio`, `ao_alsa` now support adding dummy padding channels for
better compatibility with hardware decoders that only support specific
channel counts (e.g. 5.1 now should work on a decoder that only accepts 7.1).
- Channel fallback (in case the audio device doesn't natively support a given
channel layout) has been improved.
- `vf_vapoursynth` now rejects unaligned video instead of outputting corrupted
video.
- mpv now tries to autoload `.sup` subtitles as well.
Bug fixes
---------
- `vo_opengl`'s default for `fbo-format` is now `rgba16`, to avoid rounding
errors when using non-default `cscale` (issue #1918).
- Improved framedrop behavior when playing video that has higher framerate
than the display (issue #1897).
- Trying to play a directory will no longer spam `Connection lost!` to the
console log.
- (Linux) Several `vo_rpi` bugfixes.
- (Linux) Several `vo_drm` bugfixes. Pan&Scan is now supported.
- (X11) Fix fullscreen behavior on certain window managers (issues #1937,
#1920).
- (OSX) The OSD no longer always shows up on startup.
- (OSX) Several `ao_coreaudio` and `ao_coreaudio_exclusive` bugfixes.
- (OSX) Fixed potential crash on exit when using Cocoa.
- (ClientAPI) `vo_opengl_cb` now actually applies options changed at runtime.
- (OSX, ClientAPI) Cocoa now works when both the `cplayer` (`mpv`) and `libmpv`
are built at the same time; however, `libmpv` now always creates an
application singleton. Cocoa has to be disabled completely to prevent
`libmpv` from creating the singleton.
This listing is not complete. A complete changelog can be seen by running
`git log v0.9.1..` in the git repository or by visiting
https://github.com/mpv-player/mpv/compare/v0.9.1...release/0.9.
Release 0.9.1
=============
Changes
-------
- mpv's IRC channel moved from #mpv-player to #mpv on chat.freenode.net.
- Documentation updates.
- The default value for the `--ytdl-format` option is now `best`, in order to
work around `youtube-dl`'s 2015.04.26 release enabling DASH by default, as
FFmpeg / Libav do not yet properly support DASH.
- When seeking, the current timestamp will show the predicted seek timestamp
instead, until the final timestamp is resolved. Improves UI responsiveness
on slow streams and/or large seeks.
Bug fixes
---------
- Corrected the release marker on DOCS/client-api-changes. The release manager
forgot to fix it before release...
- Fix `vo_vdpau` rendering garbage lines on H.264 video with non-mod16 size
(issue #1863).
- Fix a crash on exit if the "sub_reload" command had run successfully.
- Fixed seeking with the mouse when `osc-seekbarstyle=bar` is set (issue
#1876).
- (IPC) Fixed encoding of UTF-8 data in JSON (issue #1874).
New features
------------
This listing is not complete. A complete changelog can be seen by running
`git log v0.9.0..v0.9.1` in the git repository or by visiting
https://github.com/mpv-player/mpv/compare/v0.9.0...v0.9.1.
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.
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.
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 or by visiting
https://github.com/mpv-player/mpv/compare/v0.8.0...v0.9.0 (only 250 commits).
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 or by visiting
https://github.com/mpv-player/mpv/compare/v0.8.2...v0.8.3.
Release 0.8.2
=============
Bug fixes
---------
- Fix OSD placement accidentally messed up in 0.8.1 (commit 22863d6).
- Fix OSD placement accidentally messed up in 0.8.1.
Release 0.8.1
=============
@@ -304,8 +35,7 @@ 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 or by visiting
https://github.com/mpv-player/mpv/compare/v0.8.0...v0.8.1.
`git log v0.8.0..v0.8.1` in the git repository.
Release 0.8.0
=============
@@ -471,224 +201,4 @@ New features
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 or by visiting
https://github.com/mpv-player/mpv/compare/v0.7.0...v0.8.0 (only 250 commits).
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 or by visiting
https://github.com/mpv-player/mpv/compare/v0.7.2...v0.7.3.
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.
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 or by visiting
https://github.com/mpv-player/mpv/compare/47ec404...c7d6b21.
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 or by visiting
https://github.com/mpv-player/mpv/compare/8d8b36d...6583ad6.
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
the git repository or by visiting
https://github.com/mpv-player/mpv/compare/7759c18...9479daa (only 250 commits).
`git log v0.7.0..v0.8.0` in the git repository.
-2
View File
@@ -10,5 +10,3 @@ 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)
+1 -1
View File
@@ -102,7 +102,7 @@ function judge()
mp.msg.verbose("progressive = "..num_progressive)
mp.msg.verbose("interlaced-tff = "..num_tff)
mp.msg.verbose("interlaced-bff = "..num_bff)
mp.msg.verbose("interlaced-bff = "..num_bff)
mp.msg.verbose("undetermined = "..num_undetermined)
if num_determined < num_undetermined then
+1 -40
View File
@@ -7,17 +7,6 @@
-- 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)
@@ -29,44 +18,20 @@ function add_files_at(index, files)
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)
table.sort(files)
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
@@ -80,7 +45,6 @@ function find_and_add_entries()
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
@@ -89,7 +53,6 @@ function find_and_add_entries()
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.
@@ -97,7 +60,6 @@ function find_and_add_entries()
break
end
end
if direction == -1 then
if pl_current == 1 then -- never add additional entries in the middle
mp.msg.info("Prepending " .. file)
@@ -109,7 +71,6 @@ function find_and_add_entries()
end
end
end
add_files_at(pl_current + 1, append[1])
add_files_at(pl_current, append[-1])
end
+2 -2
View File
@@ -4,7 +4,7 @@
-- 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
-- This script registers the key-binding "\" to toggle the filter between
--
-- * off
-- * method=1 (single-sample smoothing)
@@ -92,7 +92,7 @@ function drc_quieter_handler()
drc_scale_target(0.5)
end
-- toggle between off, method 1 and method 2
-- 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)
-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)
+2
View File
@@ -2,6 +2,8 @@
-- if it's brought back again. If the player was already paused when minimizing,
-- then try not to mess with the pause state.
-- Note: currently works with X11 only.
local did_minimize = false
mp.observe_property("window-minimized", "bool", function(name, value)
-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";
@@ -1,2 +1,3 @@
screenshot-template=~/Desktop/shot%n
profile=pseudo-gui
quiet
idle=once
+1 -1
View File
@@ -21,7 +21,7 @@ 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" > ~/.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
+22
View File
@@ -0,0 +1,22 @@
#!/bin/sh
# Example of script for using mpv with youtube-dl
set -e
cookies_dir="$(mktemp -d /tmp/youtube-dl_mpv.XXXX)"
cookies_file="${cookies_dir}/cookies"
user_agent="$(youtube-dl --dump-user-agent)" # or set whatever you want
video_url=$(youtube-dl \
--user-agent="${user_agent}" \
--cookies="${cookies_file}" \
--get-url \
"$@")
set -f
${MPV:-mpv} \
--cookies \
--cookies-file="${cookies_file}" \
--user-agent="${user_agent}" \
-- ${video_url}
rm -rf "${cookies_dir}"
+55 -42
View File
@@ -7,15 +7,15 @@ use warnings;
my $mpv = $ARGV[0] || 'mpv';
my @opts = parse_main_opts('--list-options', '^ (\-\-[^\s\*]*)\*?\s*(.*)');
my @opts = parse_main_opts("$mpv --list-options", '^ (\-\-[^\s\*]*)\*?\s*(.*)');
my @ao = parse_opts('--ao=help', '^ ([^\s\:]*)\s*: (.*)');
my @vo = parse_opts('--vo=help', '^ ([^\s\:]*)\s*: (.*)');
my @ao = parse_opts("$mpv --ao=help", '^ ([^\s\:]*)\s*: (.*)');
my @vo = parse_opts("$mpv --vo=help", '^ ([^\s\:]*)\s*: (.*)');
my @af = parse_opts('--af=help', '^ ([^\s\:]*)\s*: (.*)');
my @vf = parse_opts('--vf=help', '^ ([^\s\:]*)\s*: (.*)');
my @af = parse_opts("$mpv --af=help", '^ ([^\s\:]*)\s*: (.*)');
my @vf = parse_opts("$mpv --vf=help", '^ ([^\s\:]*)\s*: (.*)');
my @protos = parse_opts('--list-protocols', '^ ([^\s]*)');
my @protos = parse_opts("$mpv --list-protocols", '^ ([^\s]*)');
my ($opts_str, $ao_str, $vo_str, $af_str, $vf_str, $protos_str);
@@ -34,35 +34,36 @@ chomp $af_str;
$vf_str .= qq{ '$_' \\\n} foreach (@vf);
chomp $vf_str;
$protos_str = join(' ', @protos);
$protos_str .= qq{$_ } foreach (@protos);
chomp $protos_str;
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]"
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
profiles=($profiles $current)
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
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;
@@ -82,27 +83,39 @@ $opts_str
case \$state in
ao)
_values -s , 'audio outputs' \\
local -a values
values=(
$ao_str
&& rc=0
)
_describe -t values 'audio outputs' values && rc=0
;;
vo)
_values -s , 'video outputs' \\
local -a values
values=(
$vo_str
&& rc=0
)
_describe -t values 'video outputs' values && rc=0
;;
af)
_values -s , 'audio filters' \\
local -a values
values=(
$af_str
&& rc=0
)
_describe -t values 'audio filters' values && rc=0
;;
vf)
_values -s , 'video filters' \\
local -a values
values=(
$vf_str
&& rc=0
)
_describe -t values 'video filters' values && rc=0
;;
profile|show-profile)
@@ -141,7 +154,7 @@ sub parse_main_opts {
my ($cmd, $regex) = @_;
my @list;
my @lines = split /\n/, `"$mpv" --no-config $cmd`;
my @lines = split /\n/, `$cmd`;
foreach my $line (@lines) {
my ($name, $desc) = ($line =~ /^$regex/) or next;
@@ -206,7 +219,7 @@ sub parse_opts {
my ($cmd, $regex) = @_;
my @list;
my @lines = split /\n/, `"$mpv" --no-config $cmd`;
my @lines = split /\n/, `$cmd`;
foreach my $line (@lines) {
if ($line !~ /^$regex/) {
@@ -218,7 +231,7 @@ sub parse_opts {
if (defined $2) {
my $desc = $2;
$desc =~ s/\:/\\:/g;
$entry .= "[$desc]";
$entry .= ':' . $desc;
}
push @list, $entry
+1 -1
View File
@@ -1 +1 @@
0.9.2
0.8.2
+3 -4
View File
@@ -35,7 +35,7 @@ static void update_redundant_info(struct mp_audio *mpa)
mp_chmap_is_valid(&mpa->channels));
mpa->nch = mpa->channels.num;
mpa->bps = af_fmt2bps(mpa->format);
if (AF_FORMAT_IS_PLANAR(mpa->format)) {
if (af_fmt_is_planar(mpa->format)) {
mpa->spf = 1;
mpa->num_planes = mpa->nch;
mpa->sstride = mpa->bps;
@@ -101,7 +101,7 @@ char *mp_audio_config_to_str_buf(char *buf, size_t buf_sz, struct mp_audio *mpa)
void mp_audio_force_interleaved_format(struct mp_audio *mpa)
{
if (AF_FORMAT_IS_PLANAR(mpa->format))
if (af_fmt_is_planar(mpa->format))
mp_audio_set_format(mpa, af_fmt_from_planar(mpa->format));
}
@@ -118,7 +118,6 @@ void mp_audio_set_null_data(struct mp_audio *mpa)
mpa->allocated[n] = NULL;
}
mpa->samples = 0;
mpa->readonly = false;
}
static int get_plane_size(const struct mp_audio *mpa, int samples)
@@ -251,7 +250,7 @@ void mp_audio_skip_samples(struct mp_audio *data, int samples)
// Will return true for non-refcounted frames.
bool mp_audio_is_writeable(struct mp_audio *data)
{
bool ok = !data->readonly;
bool ok = true;
for (int n = 0; n < MP_NUM_CHANNELS; n++) {
if (data->allocated[n])
ok &= av_buffer_is_writable(data->allocated[n]);
-1
View File
@@ -38,7 +38,6 @@ struct mp_audio {
int bps; // size of sub-samples (af_fmt2bps(format))
// private
bool readonly;
struct AVBufferRef *allocated[MP_NUM_CHANNELS];
};
+52 -65
View File
@@ -50,7 +50,6 @@ static const char *const speaker_names[MP_SPEAKER_ID_COUNT][2] = {
[MP_SPEAKER_ID_SDL] = {"sdl", "surround direct left"},
[MP_SPEAKER_ID_SDR] = {"sdr", "surround direct right"},
[MP_SPEAKER_ID_LFE2] = {"lfe2", "low frequency 2"},
[MP_SPEAKER_ID_NA] = {"na", "not available"},
};
// Names taken from libavutil/channel_layout.c (Not accessible by API.)
@@ -58,9 +57,7 @@ static const char *const speaker_names[MP_SPEAKER_ID_COUNT][2] = {
static const char *const 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"},
@@ -128,8 +125,7 @@ bool mp_chmap_is_valid(const struct mp_chmap *src)
int sp = src->speaker[n];
if (sp >= MP_SPEAKER_ID_COUNT || mapped[sp])
return false;
if (sp != MP_SPEAKER_ID_NA)
mapped[sp] = true;
mapped[sp] = true;
}
return src->num > 0;
}
@@ -144,10 +140,12 @@ bool mp_chmap_is_empty(const struct mp_chmap *src)
bool mp_chmap_is_unknown(const struct mp_chmap *src)
{
for (int n = 0; n < src->num; n++) {
if (src->speaker[n] != MP_SPEAKER_ID_NA)
return false;
int speaker = src->speaker[n];
if (speaker >= MP_SPEAKER_ID_UNKNOWN0 &&
speaker <= MP_SPEAKER_ID_UNKNOWN_LAST)
return true;
}
return mp_chmap_is_valid(src);
return false;
}
// Note: empty channel maps compare as equal. Invalid ones can equal too.
@@ -171,6 +169,15 @@ bool mp_chmap_equals_reordered(const struct mp_chmap *a, const struct mp_chmap *
return mp_chmap_equals(&t1, &t2);
}
bool mp_chmap_is_compatible(const struct mp_chmap *a, const struct mp_chmap *b)
{
if (mp_chmap_equals(a, b))
return true;
if (a->num == b->num && (mp_chmap_is_unknown(a) || mp_chmap_is_unknown(b)))
return true;
return false;
}
bool mp_chmap_is_stereo(const struct mp_chmap *src)
{
static const struct mp_chmap stereo = MP_CHMAP_INIT_STEREO;
@@ -190,26 +197,6 @@ void mp_chmap_reorder_norm(struct mp_chmap *map)
qsort(arr, map->num, 1, comp_uint8);
}
// Remove silent (NA) channels, if any.
void mp_chmap_remove_na(struct mp_chmap *map)
{
struct mp_chmap new = {0};
for (int n = 0; n < map->num; n++) {
int sp = map->speaker[n];
if (sp != MP_SPEAKER_ID_NA)
new.speaker[new.num++] = map->speaker[n];
}
*map = new;
}
// Add silent (NA) channels to map until map->num >= num.
void mp_chmap_fill_na(struct mp_chmap *map, int num)
{
assert(num <= MP_NUM_CHANNELS);
while (map->num < num)
map->speaker[map->num++] = MP_SPEAKER_ID_NA;
}
// Set *dst to a standard layout with the given number of channels.
// If the number of channels is invalid, an invalid map is set, and
// mp_chmap_is_valid(dst) will return false.
@@ -238,8 +225,6 @@ void mp_chmap_from_channels_alsa(struct mp_chmap *dst, int num_channels)
// Set *dst to an unknown layout for the given numbers of channels.
// If the number of channels is invalid, an invalid map is set, and
// mp_chmap_is_valid(dst) will return false.
// A mp_chmap with all entries set to NA is treated specially in some
// contexts (watch out for mp_chmap_is_unknown()).
void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels)
{
if (num_channels < 0 || num_channels > MP_NUM_CHANNELS) {
@@ -247,7 +232,7 @@ void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels)
} else {
dst->num = num_channels;
for (int n = 0; n < dst->num; n++)
dst->speaker[n] = MP_SPEAKER_ID_NA;
dst->speaker[n] = MP_SPEAKER_ID_UNKNOWN0 + n;
}
}
@@ -290,7 +275,6 @@ void mp_chmap_remove_useless_channels(struct mp_chmap *map,
}
// Return the ffmpeg/libav channel layout as in <libavutil/channel_layout.h>.
// Speakers not representable by ffmpeg/libav are dropped.
// Warning: this ignores the order of the channels, and will return a channel
// mask even if the order is different from libavcodec's.
uint64_t mp_chmap_to_lavc_unchecked(const struct mp_chmap *src)
@@ -300,10 +284,8 @@ uint64_t mp_chmap_to_lavc_unchecked(const struct mp_chmap *src)
if (mp_chmap_is_unknown(&t))
mp_chmap_from_channels(&t, t.num);
uint64_t mask = 0;
for (int n = 0; n < t.num; n++) {
if (t.speaker[n] < 64) // ignore MP_SPEAKER_ID_NA etc.
mask |= 1ULL << t.speaker[n];
}
for (int n = 0; n < t.num; n++)
mask |= 1ULL << t.speaker[n];
return mask;
}
@@ -364,51 +346,56 @@ void mp_chmap_reorder_to_lavc(struct mp_chmap *map)
// Get reordering array for from->to reordering. from->to must have the same set
// of speakers (i.e. same number and speaker IDs, just different order). Then,
// for each speaker n, src[n] will be set such that:
// to->speaker[n] = from->speaker[src[n]]
// (src[n] gives the source channel for destination channel n)
// If *from and *to don't contain the same set of speakers, then the above
// invariant is not guaranteed. Instead, src[n] can be set to -1 if the channel
// at to->speaker[n] is unmapped.
void mp_chmap_get_reorder(int src[MP_NUM_CHANNELS], const struct mp_chmap *from,
// for each speaker n, dst[n] will be set such that:
// to->speaker[dst[n]] = from->speaker[n]
// (dst[n] gives the source channel for destination channel n)
void mp_chmap_get_reorder(int dst[MP_NUM_CHANNELS], const struct mp_chmap *from,
const struct mp_chmap *to)
{
for (int n = 0; n < MP_NUM_CHANNELS; n++)
src[n] = -1;
assert(from->num == to->num);
if (mp_chmap_is_unknown(from) || mp_chmap_is_unknown(to)) {
for (int n = 0; n < to->num; n++)
src[n] = n < from->num ? n : -1;
for (int n = 0; n < from->num; n++)
dst[n] = n;
return;
}
// Same set of speakers required
assert(mp_chmap_equals_reordered(from, to));
for (int n = 0; n < from->num; n++) {
int src = from->speaker[n];
dst[n] = -1;
for (int i = 0; i < to->num; i++) {
if (to->speaker[n] == from->speaker[i]) {
src[n] = i;
if (src == to->speaker[i]) {
dst[n] = i;
break;
}
}
assert(dst[n] != -1);
}
for (int n = 0; n < to->num; n++)
assert(src[n] < 0 || (to->speaker[n] == from->speaker[src[n]]));
for (int n = 0; n < from->num; n++)
assert(to->speaker[dst[n]] == from->speaker[n]);
}
static int popcount64(uint64_t bits)
{
int r = 0;
for (int n = 0; n < 64; n++)
r += !!(bits & (1ULL << n));
return r;
}
// Return the number of channels only in a.
int mp_chmap_diffn(const struct mp_chmap *a, const struct mp_chmap *b)
// 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);
return popcount64((a_mask ^ b_mask) & a_mask);
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
+10 -10
View File
@@ -56,12 +56,10 @@ enum mp_speaker_id {
MP_SPEAKER_ID_SDR, // SURROUND_DIRECT_RIGHT
MP_SPEAKER_ID_LFE2, // LOW_FREQUENCY_2
// Speaker IDs >= 64 are not representable in WAVEFORMATEXTENSIBLE or libav*.
// "Silent" channels. These are sometimes used to insert padding for
// unused channels. Unlike other speaker types, multiple of these can
// occur in a single mp_chmap.
MP_SPEAKER_ID_NA = 64,
// Special mpv-specific speaker entries reserved for channels which have no
// known meaning.
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.
@@ -100,11 +98,10 @@ bool mp_chmap_is_empty(const struct mp_chmap *src);
bool mp_chmap_is_unknown(const struct mp_chmap *src);
bool mp_chmap_equals(const struct mp_chmap *a, const struct mp_chmap *b);
bool mp_chmap_equals_reordered(const struct mp_chmap *a, const struct mp_chmap *b);
bool mp_chmap_is_compatible(const struct mp_chmap *a, const struct mp_chmap *b);
bool mp_chmap_is_stereo(const struct mp_chmap *src);
void mp_chmap_reorder_norm(struct mp_chmap *map);
void mp_chmap_remove_na(struct mp_chmap *map);
void mp_chmap_fill_na(struct mp_chmap *map, int num);
void mp_chmap_from_channels(struct mp_chmap *dst, int num_channels);
void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels);
@@ -120,10 +117,13 @@ void mp_chmap_from_lavc(struct mp_chmap *dst, uint64_t src);
bool mp_chmap_is_lavc(const struct mp_chmap *src);
void mp_chmap_reorder_to_lavc(struct mp_chmap *map);
void mp_chmap_get_reorder(int src[MP_NUM_CHANNELS], const struct mp_chmap *from,
void mp_chmap_get_reorder(int dst[MP_NUM_CHANNELS], const struct mp_chmap *from,
const struct mp_chmap *to);
int mp_chmap_diffn(const struct mp_chmap *a, const struct mp_chmap *b);
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))
+55 -29
View File
@@ -74,7 +74,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)
@@ -102,7 +102,7 @@ void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *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);
@@ -199,29 +199,51 @@ bool mp_chmap_sel_adjust(const struct mp_chmap_sel *s, struct mp_chmap *map)
return false;
}
// Decide whether we should prefer old or new for the requested layout.
// Return true if new should be used, false if old should be used.
// If old is empty, always return new (initial case).
static bool mp_chmap_is_better(struct mp_chmap *req, struct mp_chmap *old,
struct mp_chmap *new)
#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])
{
int old_lost = mp_chmap_diffn(req, old); // num. channels only in req
int new_lost = mp_chmap_diffn(req, new);
struct mp_chmap diff1, diff2;
// Initial case
if (!old->num)
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;
}
// Imperfect upmix (no real superset) - minimize lost channels
if (new_lost != old_lost)
return new_lost < old_lost;
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;
}
// Some kind of upmix. If it's perfect, prefer the smaller one. Even if not,
// both have equal loss, so also prefer the smaller one.
return new->num < old->num;
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.
// 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
@@ -233,7 +255,8 @@ bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map)
return true;
}
struct mp_chmap best = {0};
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];
@@ -241,22 +264,25 @@ bool mp_chmap_sel_fallback(const struct mp_chmap_sel *s, struct mp_chmap *map)
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 = -1; i < (int)MP_ARRAY_SIZE(speaker_replacements); i++) {
struct mp_chmap t = *map;
if (i >= 0) {
struct mp_chmap *r = (struct mp_chmap *)speaker_replacements[i];
if (!replace_speakers(&t, r))
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;
}
if (mp_chmap_is_better(&t, &best, &e))
best = e;
}
}
if (best.num) {
*map = best;
return true;
for (int i = UPMIX_IDX; i < MP_ARRAY_SIZE(best); i++) {
if (best_diffs[i] < INT_MAX) {
*map = best[i];
return true;
}
}
return false;
+5 -4
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
+10 -6
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>
@@ -58,7 +59,7 @@ struct ad_lavc_params {
const struct m_sub_options ad_lavc_conf = {
.opts = (const m_option_t[]) {
OPT_FLOATRANGE("ac3drc", ac3drc, 0, 0, 6),
OPT_FLOATRANGE("ac3drc", ac3drc, 0, 0, 2),
OPT_FLAG("downmix", downmix, 0),
OPT_INTRANGE("threads", threads, 0, 1, 16),
OPT_KEYVALUELIST("o", avopts, 0),
@@ -66,7 +67,7 @@ const struct m_sub_options ad_lavc_conf = {
},
.size = sizeof(struct ad_lavc_params),
.defaults = &(const struct ad_lavc_params){
.ac3drc = 0,
.ac3drc = 1.,
.downmix = 1,
.threads = 1,
},
@@ -144,6 +145,9 @@ static int init(struct dec_audio *da, const char *decoder)
return 0;
}
if (lavc_context->bit_rate != 0)
da->bitrate = lavc_context->bit_rate;
return 1;
}
+304
View File
@@ -0,0 +1,304 @@
/*
* 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;
int sample_size;
/* 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;
struct mp_audio frame;
};
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 init(struct dec_audio *da, const char *decoder)
{
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.);
err = mpg123_open_feed(con->handle);
if (err != MPG123_OK)
goto bad_end;
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;
}
/* 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 /
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;
/* finfo.bitrate is expressed in kilobits */
const int bitrate = finfo.bitrate * 1000;
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 +
bitrate) / con->mean_count;
da->bitrate = (int) (con->mean_rate + 0.5);
con->delay = 10;
}
} else {
da->bitrate = bitrate ? bitrate : compute_bitrate(&finfo);
con->delay = 1;
con->mean_rate = 0.;
con->mean_count = 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(&con->frame, channels);
con->frame.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(&con->frame, af);
con->sample_size = channels * af_fmt2bps(af);
}
return ret;
}
static int decode_packet(struct dec_audio *da, struct mp_audio **out)
{
struct ad_mpg123_context *con = da->priv;
int ret;
struct demux_packet *pkt;
if (demux_read_packet_async(da->header, &pkt) == 0)
return AD_WAIT;
if (!pkt)
return AD_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_OK)
goto mpg123_fail;
unsigned char *audio = NULL;
size_t bytes = 0;
ret = mpg123_decode_frame(con->handle, NULL, &audio, &bytes);
if (ret == MPG123_NEED_MORE)
return 0;
if (ret != MPG123_OK && ret != MPG123_DONE && ret != MPG123_NEW_FORMAT)
goto mpg123_fail;
ret = set_format(da);
if (ret != MPG123_OK)
goto mpg123_fail;
if (con->sample_size < 1) {
MP_ERR(da, "no sample size\n");
return AD_ERR;
}
int got_samples = bytes / con->sample_size;
*out = mp_audio_pool_get(da->pool, &con->frame, got_samples);
if (!*out)
return AD_ERR;
memcpy((*out)->planes[0], audio, bytes);
update_info(da);
return 0;
mpg123_fail:
MP_ERR(da, "mpg123 decoding error: %s\n", mpg123_strerror(con->handle));
return AD_ERR;
}
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_packet = decode_packet,
};
+15 -5
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,6 +36,7 @@
struct spdifContext {
struct mp_log *log;
AVFormatContext *lavf_ctx;
int iec61937_packet_size;
int out_buffer_len;
uint8_t out_buffer[OUTBUF_SIZE];
bool need_close;
@@ -115,11 +117,13 @@ static int init(struct dec_audio *da, const char *decoder)
int samplerate = 0;
switch (stream->codec->codec_id) {
case AV_CODEC_ID_AAC:
spdif_ctx->iec61937_packet_size = 16384;
sample_format = AF_FORMAT_S_AAC;
samplerate = 48000;
num_channels = 2;
break;
case AV_CODEC_ID_AC3:
spdif_ctx->iec61937_packet_size = 6144;
sample_format = AF_FORMAT_S_AC3;
samplerate = 48000;
num_channels = 2;
@@ -127,26 +131,31 @@ static int init(struct dec_audio *da, const char *decoder)
case AV_CODEC_ID_DTS:
if (da->opts->dtshd) {
av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000
spdif_ctx->iec61937_packet_size = 32768;
sample_format = AF_FORMAT_S_DTSHD;
samplerate = 192000;
num_channels = 2*4;
} else {
spdif_ctx->iec61937_packet_size = 32768;
sample_format = AF_FORMAT_S_DTS;
samplerate = 48000;
num_channels = 2;
}
break;
case AV_CODEC_ID_EAC3:
spdif_ctx->iec61937_packet_size = 24576;
sample_format = AF_FORMAT_S_EAC3;
samplerate = 192000;
num_channels = 2;
break;
case AV_CODEC_ID_MP3:
spdif_ctx->iec61937_packet_size = 4608;
sample_format = AF_FORMAT_S_MP3;
samplerate = 48000;
num_channels = 2;
break;
case AV_CODEC_ID_TRUEHD:
spdif_ctx->iec61937_packet_size = 61440;
sample_format = AF_FORMAT_S_TRUEHD;
samplerate = 192000;
num_channels = 8;
@@ -191,6 +200,7 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out)
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;
+10 -7
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,6 +25,7 @@
#include "demux/codec_tags.h"
#include "config.h"
#include "common/codecs.h"
#include "common/msg.h"
#include "misc/bstr.h"
@@ -41,11 +43,15 @@
#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[] = {
&ad_lavc,
#if HAVE_MPG123
&ad_mpg123,
#endif
&ad_spdif,
NULL
};
@@ -158,9 +164,6 @@ static int decode_new_frame(struct dec_audio *da)
if (ret < 0)
return ret;
if (da->pts == MP_NOPTS_VALUE && da->header->missing_timestamps)
da->pts = 0;
if (da->waiting) {
da->pts_offset += da->waiting->samples;
da->decode_format = *da->waiting;
+5 -4
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_DEC_AUDIO_H
+14 -45
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 "config.h"
@@ -53,11 +54,11 @@ extern const struct af_info af_info_center;
extern const struct af_info af_info_sinesuppress;
extern const struct af_info af_info_karaoke;
extern const struct af_info af_info_scaletempo;
extern const struct af_info af_info_forcespeed;
extern const struct af_info af_info_bs2b;
extern const struct af_info af_info_lavfi;
extern const struct af_info af_info_convert24;
extern const struct af_info af_info_convertsignendian;
extern const struct af_info af_info_rubberband;
static const struct af_info *const filter_list[] = {
&af_info_dummy,
@@ -78,13 +79,11 @@ static const struct af_info *const filter_list[] = {
&af_info_hrtf,
#if HAVE_LADSPA
&af_info_ladspa,
#endif
#if HAVE_RUBBERBAND
&af_info_rubberband,
#endif
&af_info_center,
&af_info_sinesuppress,
&af_info_karaoke,
&af_info_forcespeed,
&af_info_scaletempo,
#if HAVE_LIBBS2B
&af_info_bs2b,
@@ -504,15 +503,6 @@ static int af_fix_rate(struct af_stream *s, struct af_instance **p_af,
return AF_OK;
}
static void reset_formats(struct af_stream *s)
{
for (struct af_instance *af = s->first; af; af = af->next) {
af->control(af, AF_CONTROL_SET_RESAMPLE_RATE, &(int){0});
af->control(af, AF_CONTROL_SET_CHANNELS, &(struct mp_chmap){0});
af->control(af, AF_CONTROL_SET_FORMAT, &(int){0});
}
}
// Return AF_OK on success or AF_ERROR on failure.
// Warning:
// A failed af_reinit() leaves the audio chain behind in a useless, broken
@@ -523,7 +513,6 @@ static int af_reinit(struct af_stream *s)
{
remove_auto_inserted_filters(s);
af_chain_forget_frames(s);
reset_formats(s);
s->first->fmt_in = s->first->fmt_out = s->input;
// Start with the second filter, as the first filter is the special input
// filter which needs no initialization.
@@ -570,23 +559,6 @@ static int af_reinit(struct af_stream *s)
retry++;
continue;
}
// If the format conversion is (probably) caused by spdif, then
// (as a feature) drop the filter, instead of failing hard.
int fmt_in1 = af->prev->data->format;
int fmt_in2 = in.format;
if (af_fmt_is_valid(fmt_in1) && af_fmt_is_valid(fmt_in2)) {
bool spd1 = AF_FORMAT_IS_IEC61937(fmt_in1);
bool spd2 = AF_FORMAT_IS_IEC61937(fmt_in2);
if (spd1 != spd2 && af->next) {
MP_WARN(af, "Filter %s apparently cannot be used due to "
"spdif passthrough - removing it.\n",
af->info->name);
struct af_instance *aft = af->prev;
af_remove(s, af);
af = aft->next;
break;
}
}
goto negotiate_error;
}
case AF_DETACH: { // Filter is redundant and wants to be unloaded
@@ -715,14 +687,8 @@ int af_init(struct af_stream *s)
to the stream s. The filter will be inserted somewhere nice in the
list of filters. The return value is a pointer to the new filter,
If the filter couldn't be added the return value is NULL. */
struct af_instance *af_add(struct af_stream *s, char *name, char *label,
char **args)
struct af_instance *af_add(struct af_stream *s, char *name, char **args)
{
assert(label);
if (af_find_by_label(s, label))
return NULL;
struct af_instance *new;
// Insert the filter somewhere nice
if (af_is_conversion_filter(s->first->next))
@@ -731,14 +697,17 @@ struct af_instance *af_add(struct af_stream *s, char *name, char *label,
new = af_prepend(s, s->first->next, name, args);
if (!new)
return NULL;
new->label = talloc_strdup(new, label);
// Reinitalize the filter list
if (af_reinit(s) != AF_OK) {
af_remove_by_label(s, label);
af_remove(s, new);
if (af_reinit(s) != AF_OK) {
af_uninit(s);
af_init(s);
}
return NULL;
}
return af_find_by_label(s, label);
return new;
}
struct af_instance *af_find_by_label(struct af_stream *s, char *label)
+8 -6
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_AF_H
@@ -140,8 +141,7 @@ struct af_stream *af_new(struct mpv_global *global);
void af_destroy(struct af_stream *s);
int af_init(struct af_stream *s);
void af_uninit(struct af_stream *s);
struct af_instance *af_add(struct af_stream *s, char *name, char *label,
char **args);
struct af_instance *af_add(struct af_stream *s, char *name, char **args);
int af_remove_by_label(struct af_stream *s, char *label);
struct af_instance *af_find_by_label(struct af_stream *s, char *label);
struct af_instance *af_control_any_rev(struct af_stream *s, int cmd, void *arg);
@@ -159,7 +159,9 @@ double af_calc_delay(struct af_stream *s);
int af_test_output(struct af_instance *af, struct mp_audio *out);
int af_from_dB(int n, float *in, float *out, float k, float mi, float ma);
int af_to_dB(int n, float *in, float *out, float k);
int af_from_ms(int n, float *in, int *out, int rate, float mi, float ma);
int af_to_ms(int n, int *in, float *out, int rate);
float af_softclip(float a);
#endif /* MPLAYER_AF_H */
+6 -6
View File
@@ -4,20 +4,21 @@
*
* Copyright (c) 2009 Andrew Savchenko
*
* 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 <bs2b.h>
@@ -163,8 +164,7 @@ const struct af_info af_info_bs2b = {
OPT_INTRANGE("fcut", fcut, 0, BS2B_MINFCUT, BS2B_MAXFCUT),
OPT_INTRANGE("feed", feed, 0, BS2B_MINFEED, BS2B_MAXFEED),
OPT_CHOICE("profile", profile, 0,
({"unset", 0},
{"default", BS2B_DEFAULT_CLEVEL},
({"default", BS2B_DEFAULT_CLEVEL},
{"cmoy", BS2B_CMOY_CLEVEL},
{"jmeier", BS2B_JMEIER_CLEVEL})),
{0}
+5 -4
View File
@@ -8,20 +8,21 @@
*
* copyright (c) 2005 Alex Beregszaszi
*
* 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>
+5 -4
View File
@@ -5,20 +5,21 @@
*
* Original author: Anders
*
* 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>
+5 -4
View File
@@ -5,20 +5,21 @@
*
* Original author: Anders
*
* 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>
+5 -4
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard
*
* 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>
+5 -4
View File
@@ -4,20 +4,21 @@
*
* Original author: Anders
*
* 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>
+5 -4
View File
@@ -6,20 +6,21 @@
*
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
*
* 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>
+5 -4
View File
@@ -9,20 +9,21 @@
*
* Authors: Anders; Gustavo Sverzut Barbieri <gustavo.barbieri@ic.unicamp.br>
*
* 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>
+5 -4
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard
*
* 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>
+71
View File
@@ -0,0 +1,71 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include "af.h"
struct priv {
double speed;
};
static int control(struct af_instance *af, int cmd, void *arg)
{
struct priv *priv = af->priv;
switch (cmd) {
case AF_CONTROL_REINIT: {
struct mp_audio *in = arg;
struct mp_audio orig_in = *in;
struct mp_audio *out = af->data;
mp_audio_copy_config(out, in);
out->rate = in->rate * priv->speed;
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
}
case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: {
priv->speed = *(double *)arg;
return AF_OK;
}
}
return AF_UNKNOWN;
}
static int filter(struct af_instance *af, struct mp_audio *data)
{
if (data)
mp_audio_copy_config(data, af->data);
af_add_output_frame(af, data);
return 0;
}
static int af_open(struct af_instance *af)
{
struct priv *priv = af->priv;
af->control = control;
af->filter_frame = filter;
priv->speed = 1.0;
return AF_OK;
}
#define OPT_BASE_STRUCT struct priv
const struct af_info af_info_forcespeed = {
.info = "Force audio speed",
.name = "forcespeed",
.open = af_open,
.priv_size = sizeof(struct priv),
};
+5 -4
View File
@@ -5,20 +5,21 @@
*
* Author: ylai
*
* 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>
+5 -4
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_AF_HRTF_H
+5 -4
View File
@@ -4,20 +4,21 @@
* copyright (c) 2006 Reynaldo H. Verdejo Pinochet
* Based on code by Alex Beregszaszi for his 'center' filter.
*
* 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>
+5 -4
View File
@@ -4,20 +4,21 @@
* Written by Ivo van Poorten <ivop@euronet.nl>
* Copyright (C) 2004, 2005
*
* 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.
*/
/* ------------------------------------------------------------------------- */
+5 -4
View File
@@ -3,20 +3,21 @@
*
* Copyright (C) 2007 Ulion <ulion A gmail P com>
*
* 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>
+1 -27
View File
@@ -61,8 +61,6 @@ struct priv {
AVRational timebase_out;
bool eof;
// options
char *cfg_graph;
char **cfg_avopts;
@@ -73,8 +71,6 @@ static void destroy_graph(struct af_instance *af)
struct priv *p = af->priv;
avfilter_graph_free(&p->graph);
p->in = p->out = NULL;
p->samples_in = 0;
p->eof = false;
}
static bool recreate_graph(struct af_instance *af, struct mp_audio *config)
@@ -171,12 +167,6 @@ error:
return false;
}
static void reset(struct af_instance *af)
{
if (!recreate_graph(af, &af->fmt_in))
MP_FATAL(af, "Can't recreate libavfilter filter after a seek reset.\n");
}
static int control(struct af_instance *af, int cmd, void *arg)
{
struct priv *p = af->priv;
@@ -213,9 +203,6 @@ static int control(struct af_instance *af, int cmd, void *arg)
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
}
case AF_CONTROL_RESET:
reset(af);
return AF_OK;
}
return AF_UNKNOWN;
}
@@ -223,16 +210,9 @@ static int control(struct af_instance *af, int cmd, void *arg)
static int filter_frame(struct af_instance *af, struct mp_audio *data)
{
struct priv *p = af->priv;
AVFrame *frame = NULL;
if (p->eof && data)
reset(af);
if (!p->graph)
goto error;
AVFilterLink *l_in = p->in->outputs[0];
AVFrame *frame = NULL;
if (data) {
frame = av_frame_alloc();
if (!frame)
@@ -275,9 +255,6 @@ static int filter_out(struct af_instance *af)
{
struct priv *p = af->priv;
if (!p->graph)
goto error;
AVFrame *frame = av_frame_alloc();
if (!frame)
goto error;
@@ -285,10 +262,7 @@ static int filter_out(struct af_instance *af)
int err = av_buffersink_get_frame(p->out, frame);
if (err == AVERROR(EAGAIN) || err == AVERROR_EOF) {
// Not an error situation - no more output buffers in queue.
// AVERROR_EOF means we shouldn't even give the filter more
// input, but we don't handle that completely correctly.
av_frame_free(&frame);
p->eof |= err == AVERROR_EOF;
return 0;
}
+64 -170
View File
@@ -2,29 +2,28 @@
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2013 Stefano Pigozzi <stefano.pigozzi@gmail.com>
*
* This file is part of mpv.
* Based on Michael Niedermayer's lavcresample.
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <math.h>
#include <assert.h>
#include <libavutil/opt.h>
@@ -33,7 +32,7 @@
#include <libavutil/samplefmt.h>
#include <libavutil/mathematics.h>
#include "common/common.h"
#include "talloc.h"
#include "config.h"
#if HAVE_LIBAVRESAMPLE
@@ -65,8 +64,7 @@ struct af_resample_opts {
int linear;
double cutoff;
int in_rate_af; // filter input sample rate
int in_rate; // actual rate (used by lavr), adjusted for playback speed
int in_rate;
int in_format;
struct mp_chmap in_channels;
int out_rate;
@@ -77,11 +75,7 @@ struct af_resample_opts {
struct af_resample {
int allow_detach;
char **avopts;
double playback_speed;
struct mp_audio *pending;
bool avrctx_ok;
struct AVAudioResampleContext *avrctx;
struct mp_audio avrctx_fmt; // output format of avrctx
struct AVAudioResampleContext *avrctx_out; // for output channel reordering
struct af_resample_opts ctx; // opts in the context
struct af_resample_opts opts; // opts requested by the user
@@ -100,10 +94,6 @@ static void drop_all_output(struct af_resample *s)
{
while (avresample_read(s->avrctx, NULL, 1000) > 0) {}
}
static int get_drain_samples(struct af_resample *s)
{
return avresample_get_out_samples(s->avrctx, 0);
}
#else
static int get_delay(struct af_resample *s)
{
@@ -113,39 +103,18 @@ static void drop_all_output(struct af_resample *s)
{
while (swr_drop_output(s->avrctx, 1000) > 0) {}
}
static int get_drain_samples(struct af_resample *s)
{
return 4096; // libswscale does not have this
}
#endif
static int resample_frame(struct AVAudioResampleContext *r,
struct mp_audio *out, struct mp_audio *in)
{
return avresample_convert(r,
out ? (uint8_t **)out->planes : NULL,
out ? mp_audio_get_allocated_size(out) : 0,
out ? out->samples : 0,
in ? (uint8_t **)in->planes : NULL,
in ? mp_audio_get_allocated_size(in) : 0,
in ? in->samples : 0);
}
static double af_resample_default_cutoff(int filter_size)
{
return FFMAX(1.0 - 6.5 / (filter_size + 8), 0.80);
}
static int rate_from_speed(int rate, double speed)
{
return lrint(rate * speed);
}
static bool needs_lavrctx_reconfigure(struct af_resample *s,
struct mp_audio *in,
struct mp_audio *out)
{
return s->ctx.in_rate_af != in->rate ||
return s->ctx.in_rate != in->rate ||
s->ctx.in_format != in->format ||
!mp_chmap_equals(&s->ctx.in_channels, &in->channels) ||
s->ctx.out_rate != out->rate ||
@@ -164,48 +133,22 @@ static bool test_conversion(int src_format, int dst_format)
af_to_avformat(dst_format) != AV_SAMPLE_FMT_NONE;
}
// mp_chmap_get_reorder() performs:
// to->speaker[n] = from->speaker[src[n]]
// but libavresample does:
// to->speaker[dst[n]] = from->speaker[n]
static void transpose_order(int *map, int num)
{
int nmap[MP_NUM_CHANNELS] = {0};
for (int n = 0; n < num; n++) {
for (int i = 0; i < num; i++) {
if (map[n] == i)
nmap[i] = n;
}
}
memcpy(map, nmap, sizeof(nmap));
}
static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
struct mp_audio *out)
{
struct af_resample *s = af->priv;
s->avrctx_ok = false;
enum AVSampleFormat in_samplefmt = af_to_avformat(in->format);
enum AVSampleFormat out_samplefmt = af_to_avformat(out->format);
enum AVSampleFormat out_samplefmtp =
af_to_avformat(af_fmt_to_planar(out->format));
if (in_samplefmt == AV_SAMPLE_FMT_NONE ||
out_samplefmt == AV_SAMPLE_FMT_NONE ||
out_samplefmtp == AV_SAMPLE_FMT_NONE)
if (in_samplefmt == AV_SAMPLE_FMT_NONE || out_samplefmt == AV_SAMPLE_FMT_NONE)
return AF_ERROR;
avresample_close(s->avrctx);
avresample_close(s->avrctx_out);
talloc_free(s->pending);
s->pending = NULL;
s->ctx.out_rate = out->rate;
s->ctx.in_rate_af = in->rate;
s->ctx.in_rate = rate_from_speed(in->rate, s->playback_speed);
s->ctx.in_rate = in->rate;
s->ctx.out_format = out->format;
s->ctx.in_format = in->format;
s->ctx.out_channels= out->channels;
@@ -221,10 +164,6 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
av_opt_set_double(s->avrctx, "cutoff", s->ctx.cutoff, 0);
#if HAVE_LIBSWRESAMPLE
av_opt_set_double(s->avrctx, "rematrix_maxval", 1.0, 0);
#endif
if (mp_set_avopts(af->log, s->avrctx, s->avopts) < 0)
return AF_ERROR;
@@ -241,52 +180,27 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
uint64_t in_ch_layout = mp_chmap_to_lavc_unchecked(&map_in);
uint64_t out_ch_layout = mp_chmap_to_lavc_unchecked(&map_out);
av_opt_set_int(s->avrctx, "in_channel_layout", in_ch_layout, 0);
av_opt_set_int(s->avrctx, "out_channel_layout", out_ch_layout, 0);
av_opt_set_int(s->avrctx, "in_sample_rate", s->ctx.in_rate, 0);
av_opt_set_int(s->avrctx, "out_sample_rate", s->ctx.out_rate, 0);
av_opt_set_int(s->avrctx, "in_sample_fmt", in_samplefmt, 0);
av_opt_set_int(s->avrctx, "out_sample_fmt", out_samplefmt, 0);
struct mp_chmap in_lavc;
mp_chmap_from_lavc(&in_lavc, in_ch_layout);
if (in_lavc.num != map_in.num) {
// For handling NA channels, we would have to add a planarization step.
MP_FATAL(af, "Unsupported channel remapping.\n");
return AF_ERROR;
}
mp_chmap_get_reorder(s->reorder_in, &map_in, &in_lavc);
transpose_order(s->reorder_in, map_in.num);
struct mp_chmap out_lavc;
mp_chmap_from_lavc(&out_lavc, out_ch_layout);
if (mp_chmap_equals(&out_lavc, &map_out)) {
// No intermediate step required - output new format directly.
out_samplefmtp = out_samplefmt;
} else {
// Verify that we really just reorder and/or insert NA channels.
struct mp_chmap withna = out_lavc;
mp_chmap_fill_na(&withna, map_out.num);
if (withna.num != map_out.num)
return AF_ERROR;
mp_chmap_get_reorder(s->reorder_out, &out_lavc, &map_out);
}
mp_chmap_get_reorder(s->reorder_out, &out_lavc, &map_out);
s->avrctx_fmt = *out;
mp_audio_set_channels(&s->avrctx_fmt, &out_lavc);
mp_audio_set_format(&s->avrctx_fmt, af_from_avformat(out_samplefmtp));
// Real conversion; output is input to avrctx_out.
av_opt_set_int(s->avrctx, "in_channel_layout", in_ch_layout, 0);
av_opt_set_int(s->avrctx, "out_channel_layout", out_ch_layout, 0);
av_opt_set_int(s->avrctx, "in_sample_rate", s->ctx.in_rate, 0);
av_opt_set_int(s->avrctx, "out_sample_rate", s->ctx.out_rate, 0);
av_opt_set_int(s->avrctx, "in_sample_fmt", in_samplefmt, 0);
av_opt_set_int(s->avrctx, "out_sample_fmt", out_samplefmtp, 0);
// Just needs the correct number of channels.
int fake_out_ch_layout = av_get_default_channel_layout(map_out.num);
if (!fake_out_ch_layout)
return AF_ERROR;
// Deplanarize if needed.
av_opt_set_int(s->avrctx_out, "in_channel_layout", fake_out_ch_layout, 0);
av_opt_set_int(s->avrctx_out, "out_channel_layout", fake_out_ch_layout, 0);
av_opt_set_int(s->avrctx_out, "in_sample_fmt", out_samplefmtp, 0);
// Same configuration; we just reorder.
av_opt_set_int(s->avrctx_out, "in_channel_layout", out_ch_layout, 0);
av_opt_set_int(s->avrctx_out, "out_channel_layout", out_ch_layout, 0);
av_opt_set_int(s->avrctx_out, "in_sample_fmt", out_samplefmt, 0);
av_opt_set_int(s->avrctx_out, "out_sample_fmt", out_samplefmt, 0);
av_opt_set_int(s->avrctx_out, "in_sample_rate", s->ctx.out_rate, 0);
av_opt_set_int(s->avrctx_out, "out_sample_rate", s->ctx.out_rate, 0);
@@ -295,6 +209,7 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
// * This function can only be called when the allocated context is not open.
// * Also, the input channel layout must have already been set.
avresample_set_channel_mapping(s->avrctx, s->reorder_in);
avresample_set_channel_mapping(s->avrctx_out, s->reorder_out);
if (avresample_open(s->avrctx) < 0 ||
avresample_open(s->avrctx_out) < 0)
@@ -302,25 +217,24 @@ static int configure_lavrr(struct af_instance *af, struct mp_audio *in,
MP_ERR(af, "Cannot open Libavresample Context. \n");
return AF_ERROR;
}
s->avrctx_ok = true;
return AF_OK;
}
static int control(struct af_instance *af, int cmd, void *arg)
{
struct af_resample *s = af->priv;
struct af_resample *s = (struct af_resample *) af->priv;
struct mp_audio *in = (struct mp_audio *) arg;
struct mp_audio *out = (struct mp_audio *) af->data;
switch (cmd) {
case AF_CONTROL_REINIT: {
struct mp_audio *in = arg;
struct mp_audio *out = af->data;
struct mp_audio orig_in = *in;
if (((out->rate == in->rate) || (out->rate == 0)) &&
(out->format == in->format) &&
(mp_chmap_equals(&out->channels, &in->channels) || out->nch == 0) &&
s->allow_detach && s->playback_speed == 1.0)
s->allow_detach)
return AF_DETACH;
if (out->rate == 0)
@@ -343,11 +257,10 @@ static int control(struct af_instance *af, int cmd, void *arg)
return r;
}
case AF_CONTROL_SET_FORMAT: {
int format = *(int *)arg;
if (format && af_to_avformat(format) == AV_SAMPLE_FMT_NONE)
if (af_to_avformat(*(int*)arg) == AV_SAMPLE_FMT_NONE)
return AF_FALSE;
mp_audio_set_format(af->data, format);
mp_audio_set_format(af->data, *(int*)arg);
return AF_OK;
}
case AF_CONTROL_SET_CHANNELS: {
@@ -355,28 +268,8 @@ static int control(struct af_instance *af, int cmd, void *arg)
return AF_OK;
}
case AF_CONTROL_SET_RESAMPLE_RATE:
af->data->rate = *(int *)arg;
out->rate = *(int *)arg;
return AF_OK;
case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: {
s->playback_speed = *(double *)arg;
int new_rate = rate_from_speed(s->ctx.in_rate_af, s->playback_speed);
if (new_rate != s->ctx.in_rate && s->avrctx_ok && af->fmt_out.format) {
// Before reconfiguring, drain the audio that is still buffered
// in the resampler.
struct mp_audio *pending = talloc_zero(NULL, struct mp_audio);
mp_audio_copy_config(pending, &af->fmt_out);
pending->samples = get_drain_samples(s);
if (pending->samples > 0) {
mp_audio_realloc_min(pending, pending->samples);
int r = resample_frame(s->avrctx, pending, NULL);
pending->samples = MPMAX(r, 0);
}
// Reinitialize resampler.
configure_lavrr(af, &af->fmt_in, &af->fmt_out);
s->pending = pending;
}
return AF_OK;
}
case AF_CONTROL_RESET:
drop_all_output(s);
return AF_OK;
@@ -396,51 +289,53 @@ static void uninit(struct af_instance *af)
if (s->avrctx_out)
avresample_close(s->avrctx_out);
avresample_free(&s->avrctx_out);
talloc_free(s->pending);
}
static void reorder_planes(struct mp_audio *mpa, int *reorder,
struct mp_chmap *newmap)
static bool needs_reorder(int *reorder, int num_ch)
{
for (int n = 0; n < num_ch; n++) {
if (reorder[n] != n)
return true;
}
return false;
}
static void reorder_planes(struct mp_audio *mpa, int *reorder)
{
struct mp_audio prev = *mpa;
for (int n = 0; n < newmap->num; n++) {
int src = reorder[n];
if (src < 0) {
src = 0; // Use the first plane for padding channels.
mpa->readonly = true;
}
assert(src < mpa->num_planes);
mpa->planes[n] = prev.planes[src];
for (int n = 0; n < mpa->num_planes; n++) {
assert(reorder[n] >= 0 && reorder[n] < mpa->num_planes);
mpa->planes[n] = prev.planes[reorder[n]];
}
}
mp_audio_set_channels(mpa, newmap);
static int resample_frame(struct AVAudioResampleContext *r,
struct mp_audio *out, struct mp_audio *in)
{
return avresample_convert(r,
out ? (uint8_t **)out->planes : NULL,
out ? mp_audio_get_allocated_size(out) : 0,
out ? out->samples : 0,
in ? (uint8_t **)in->planes : NULL,
in ? mp_audio_get_allocated_size(in) : 0,
in ? in->samples : 0);
}
static int filter(struct af_instance *af, struct mp_audio *in)
{
struct af_resample *s = af->priv;
if (s->pending) {
if (s->pending->samples) {
af_add_output_frame(af, s->pending);
} else {
talloc_free(s->pending);
}
s->pending = NULL;
}
int samples = avresample_available(s->avrctx) +
av_rescale_rnd(get_delay(s) + (in ? in->samples : 0),
s->ctx.out_rate, s->ctx.in_rate, AV_ROUND_UP);
struct mp_audio out_format = s->avrctx_fmt;
struct mp_audio *out = mp_audio_pool_get(af->out_pool, &out_format, samples);
struct mp_audio *out = mp_audio_pool_get(af->out_pool, af->data, samples);
if (!out)
goto error;
if (in)
mp_audio_copy_attributes(out, in);
mp_audio_realloc_min(out, out->samples);
af->delay = get_delay(s) / (double)s->ctx.in_rate;
if (out->samples) {
@@ -449,11 +344,11 @@ static int filter(struct af_instance *af, struct mp_audio *in)
goto error;
}
if (out->samples && !mp_audio_config_equals(out, af->data)) {
assert(AF_FORMAT_IS_PLANAR(out->format));
reorder_planes(out, s->reorder_out, &af->data->channels);
if (!mp_audio_config_equals(out, af->data)) {
struct mp_audio *new = mp_audio_pool_get(s->reorder_buffer, af->data,
if (needs_reorder(s->reorder_out, out->nch)) {
if (af_fmt_is_planar(out->format)) {
reorder_planes(out, s->reorder_out);
} else if (out->samples) {
struct mp_audio *new = mp_audio_pool_get(s->reorder_buffer, out,
out->samples);
if (!new)
goto error;
@@ -517,7 +412,6 @@ const struct af_info af_info_lavrresample = {
.cutoff = 0.0,
.phase_shift = 10,
},
.playback_speed = 1.0,
.allow_detach = 1,
},
.options = (const struct m_option[]) {
+5 -4
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au
*
* 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>
-225
View File
@@ -1,225 +0,0 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <assert.h>
#include <rubberband/rubberband-c.h>
#include "common/common.h"
#include "af.h"
struct priv {
RubberBandState rubber;
double speed;
struct mp_audio *pending;
bool needs_reset;
// Estimate how much librubberband has buffered internally.
// I could not find a way to do this with the librubberband API.
double rubber_delay;
// command line options
int opt_transients, opt_detector, opt_phase, opt_window,
opt_smoothing, opt_formant, opt_pitch, opt_channels;
};
static void update_speed(struct af_instance *af, double new_speed)
{
struct priv *p = af->priv;
p->speed = new_speed;
rubberband_set_time_ratio(p->rubber, 1.0 / p->speed);
}
static int control(struct af_instance *af, int cmd, void *arg)
{
struct priv *p = af->priv;
switch (cmd) {
case AF_CONTROL_REINIT: {
struct mp_audio *in = arg;
struct mp_audio orig_in = *in;
struct mp_audio *out = af->data;
in->format = AF_FORMAT_FLOATP;
mp_audio_copy_config(out, in);
if (p->rubber)
rubberband_delete(p->rubber);
int opts = p->opt_transients | p->opt_detector | p->opt_phase |
p->opt_window | p->opt_smoothing | p->opt_formant |
p->opt_pitch | p-> opt_channels |
RubberBandOptionProcessRealTime;
p->rubber = rubberband_new(in->rate, in->channels.num, opts, 1.0, 1.0);
if (!p->rubber) {
MP_FATAL(af, "librubberband initialization failed.\n");
return AF_ERROR;
}
update_speed(af, p->speed);
control(af, AF_CONTROL_RESET, NULL);
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
}
case AF_CONTROL_SET_PLAYBACK_SPEED: {
update_speed(af, *(double *)arg);
return AF_OK;
}
case AF_CONTROL_RESET:
if (p->rubber)
rubberband_reset(p->rubber);
talloc_free(p->pending);
p->pending = NULL;
p->rubber_delay = 0;
return AF_OK;
}
return AF_UNKNOWN;
}
static int filter_frame(struct af_instance *af, struct mp_audio *data)
{
struct priv *p = af->priv;
talloc_free(p->pending);
p->pending = data;
return 0;
}
static int filter_out(struct af_instance *af)
{
struct priv *p = af->priv;
while (rubberband_available(p->rubber) <= 0) {
const float *dummy[MP_NUM_CHANNELS] = {0};
const float **in_data = dummy;
size_t in_samples = 0;
if (p->pending) {
if (!p->pending->samples)
break;
// recover from previous EOF
if (p->needs_reset) {
rubberband_reset(p->rubber);
p->rubber_delay = 0;
}
p->needs_reset = false;
size_t needs = rubberband_get_samples_required(p->rubber);
in_data = (void *)&p->pending->planes;
in_samples = MPMIN(p->pending->samples, needs);
}
if (p->needs_reset)
break; // previous EOF
p->needs_reset = !p->pending; // EOF
rubberband_process(p->rubber, in_data, in_samples, p->needs_reset);
p->rubber_delay += in_samples;
if (!p->pending)
break;
mp_audio_skip_samples(p->pending, in_samples);
}
int out_samples = rubberband_available(p->rubber);
if (out_samples > 0) {
struct mp_audio *out =
mp_audio_pool_get(af->out_pool, af->data, out_samples);
if (!out)
return -1;
if (p->pending)
mp_audio_copy_config(out, p->pending);
float **out_data = (void *)&out->planes;
out->samples = rubberband_retrieve(p->rubber, out_data, out->samples);
p->rubber_delay -= out->samples * p->speed;
af_add_output_frame(af, out);
}
int delay_samples = p->rubber_delay;
if (p->pending)
delay_samples += p->pending->samples;
af->delay = delay_samples / (af->data->rate * p->speed);
return 0;
}
static void uninit(struct af_instance *af)
{
struct priv *p = af->priv;
if (p->rubber)
rubberband_delete(p->rubber);
talloc_free(p->pending);
}
static int af_open(struct af_instance *af)
{
af->control = control;
af->filter_frame = filter_frame;
af->filter_out = filter_out;
af->uninit = uninit;
return AF_OK;
}
#define OPT_BASE_STRUCT struct priv
const struct af_info af_info_rubberband = {
.info = "Pitch conversion with librubberband",
.name = "rubberband",
.open = af_open,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv) {
.speed = 1.0,
.opt_pitch = RubberBandOptionPitchHighConsistency,
.opt_transients = RubberBandOptionTransientsMixed,
.opt_formant = RubberBandOptionFormantPreserved,
},
.options = (const struct m_option[]) {
OPT_CHOICE("transients", opt_transients, 0,
({"crisp", RubberBandOptionTransientsCrisp},
{"mixed", RubberBandOptionTransientsMixed},
{"smooth", RubberBandOptionTransientsSmooth})),
OPT_CHOICE("detector", opt_detector, 0,
({"compound", RubberBandOptionDetectorCompound},
{"percussive", RubberBandOptionDetectorPercussive},
{"soft", RubberBandOptionDetectorSoft})),
OPT_CHOICE("phase", opt_phase, 0,
({"laminar", RubberBandOptionPhaseLaminar},
{"independent", RubberBandOptionPhaseIndependent})),
OPT_CHOICE("window", opt_window, 0,
({"standard", RubberBandOptionWindowStandard},
{"short", RubberBandOptionWindowShort},
{"long", RubberBandOptionWindowLong})),
OPT_CHOICE("smoothing", opt_smoothing, 0,
({"off", RubberBandOptionSmoothingOff},
{"on", RubberBandOptionSmoothingOn})),
OPT_CHOICE("formant", opt_formant, 0,
({"shifted", RubberBandOptionFormantShifted},
{"preserved", RubberBandOptionFormantPreserved})),
OPT_CHOICE("pitch", opt_pitch, 0,
({"quality", RubberBandOptionPitchHighQuality},
{"speed", RubberBandOptionPitchHighSpeed},
{"consistency", RubberBandOptionPitchHighConsistency})),
OPT_CHOICE("channels", opt_channels, 0,
({"apart", RubberBandOptionChannelsApart},
{"together", RubberBandOptionChannelsTogether})),
{0}
},
};
+39 -31
View File
@@ -14,20 +14,21 @@
*
* Copyright (c) 2007 Robert Juliano
*
* 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 <stdlib.h>
@@ -75,9 +76,9 @@ typedef struct af_scaletempo_s
float ms_stride;
float percent_overlap;
float ms_search;
#define SCALE_TEMPO 1
#define SCALE_PITCH 2
int speed_opt;
short speed_tempo;
short speed_pitch;
} af_scaletempo_t;
static int fill_queue(struct af_instance *af, struct mp_audio *data, int offset)
@@ -275,22 +276,6 @@ static int filter(struct af_instance *af, struct mp_audio *data)
return 0;
}
static void update_speed(struct af_instance *af, float speed)
{
af_scaletempo_t *s = af->priv;
s->speed = speed;
double factor = (s->speed_opt & SCALE_PITCH) ? 1.0 / s->speed : s->speed;
s->scale = factor * s->scale_nominal;
s->frames_stride_scaled = s->scale * s->frames_stride;
s->frames_stride_error = MPMIN(s->frames_stride_error, s->frames_stride_scaled);
MP_VERBOSE(af, "%.3f speed * %.3f scale_nominal = %.3f\n",
s->speed, s->scale_nominal, s->scale);
}
// Initialization and runtime control
static int control(struct af_instance *af, int cmd, void *arg)
{
@@ -302,9 +287,19 @@ static int control(struct af_instance *af, int cmd, void *arg)
int nch = data->nch;
int use_int = 0;
MP_VERBOSE(af, "%.3f speed * %.3f scale_nominal = %.3f\n",
s->speed, s->scale_nominal, s->scale);
mp_audio_force_interleaved_format(data);
mp_audio_copy_config(af->data, data);
if (s->scale == 1.0) {
if (s->speed_tempo && s->speed_pitch)
return AF_DETACH;
af->delay = 0;
return af_test_output(af, data);
}
if (data->format == AF_FORMAT_S16) {
use_int = 1;
} else {
@@ -314,10 +309,10 @@ static int control(struct af_instance *af, int cmd, void *arg)
s->frames_stride = srate * s->ms_stride;
s->bytes_stride = s->frames_stride * bps * nch;
s->frames_stride_scaled = s->scale * s->frames_stride;
s->frames_stride_error = 0;
af->delay = 0;
update_speed(af, s->speed);
int frames_overlap = s->frames_stride * s->percent_overlap;
if (frames_overlap <= 0) {
s->bytes_standing = s->bytes_stride;
@@ -427,14 +422,17 @@ static int control(struct af_instance *af, int cmd, void *arg)
return af_test_output(af, (struct mp_audio *)arg);
}
case AF_CONTROL_SET_PLAYBACK_SPEED: {
double speed = *(double *)arg;
if (s->speed_opt & SCALE_TEMPO) {
if (s->speed_opt & SCALE_PITCH)
if (s->speed_tempo) {
if (s->speed_pitch)
break;
update_speed(af, speed);
} else if (s->speed_opt & SCALE_PITCH) {
update_speed(af, speed);
break; // do not signal OK
s->speed = *(double *)arg;
s->scale = s->speed * s->scale_nominal;
} else {
if (s->speed_pitch) {
s->speed = 1 / *(double *)arg;
s->scale = s->speed * s->scale_nominal;
break;
}
}
return AF_OK;
}
@@ -458,12 +456,22 @@ static void uninit(struct af_instance *af)
free(s->table_window);
}
#define SCALE_TEMPO 1
#define SCALE_PITCH 2
// Allocate memory and set function pointers
static int af_open(struct af_instance *af)
{
af_scaletempo_t *s = af->priv;
af->control = control;
af->uninit = uninit;
af->filter_frame = filter;
s->speed_tempo = !!(s->speed_opt & SCALE_TEMPO);
s->speed_pitch = !!(s->speed_opt & SCALE_PITCH);
s->scale = s->speed * s->scale_nominal;
return AF_OK;
}
+5 -4
View File
@@ -3,20 +3,21 @@
* Copyright (C) 2004 Alex Beregszaszi
* based upon af_extrastereo.c by Pierre Lombard
*
* 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>
+5 -4
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) 2002 Anders Johansson ajh@watri.uwa.edu.au
*
* 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.
*/
/* This filter adds a sub-woofer channels to the audio stream by
+6 -5
View File
@@ -3,22 +3,23 @@
* This will provide a (basic) surround-sound effect from
* audio encoded for Dolby Surround, Pro Logic etc.
*
* Original author: Steve Davies <steve@daviesfam.org>
* original author: Steve Davies <steve@daviesfam.org>
*
* 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.
*/
/* The principle: Make rear channels by extracting anti-phase data
+5 -4
View File
@@ -1,20 +1,21 @@
/*
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
*
* 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>
+6 -5
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C)2002 Anders Johansson ajh@atri.curtin.edu.au
*
* 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>
@@ -58,7 +59,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
} else {
mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
}
if (AF_FORMAT_IS_PLANAR(in->format))
if (af_fmt_is_planar(in->format))
mp_audio_set_format(af->data, af_fmt_to_planar(af->data->format));
s->rgain = 1.0;
if ((s->rgain_track || s->rgain_album) && af->replaygain_data) {
+5 -4
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au
*
* 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_DSP_H
+5 -4
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) 2002 Anders Johansson ajh@atri.curtin.edu.au
*
* 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_EQUALIZER_H
+5 -4
View File
@@ -3,20 +3,21 @@
*
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
*
* 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 <string.h>
+5 -4
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
*
* 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.
*/
#if !defined MPLAYER_DSP_H
+37 -4
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 <math.h>
@@ -39,6 +40,24 @@ int af_from_dB(int n, float* in, float* out, float k, float mi, float ma)
return AF_OK;
}
/* Convert from gain value to dB. Returns AF_OK if of and AF_ERROR if
* fail. gain=0 will become -200 dB. k is just a multiplier. */
int af_to_dB(int n, float* in, float* out, float k)
{
int i = 0;
// Sanity check
if(!in || !out)
return AF_ERROR;
for(i=0;i<n;i++){
if(in[i] == 0.0)
out[i]=-200.0;
else
out[i]=k*log10(in[i]);
}
return AF_OK;
}
/* Convert from ms to sample time */
int af_from_ms(int n, float* in, int* out, int rate, float mi, float ma)
{
@@ -53,6 +72,20 @@ int af_from_ms(int n, float* in, int* out, int rate, float mi, float ma)
return AF_OK;
}
/* Convert from sample time to ms */
int af_to_ms(int n, int* in, float* out, int rate)
{
int i = 0;
// Sanity check
if(!in || !out || !rate)
return AF_ERROR;
for(i=0;i<n;i++)
out[i]=1000.0 * (float)in[i]/((float)rate);
return AF_OK;
}
/*
* test if output format matches
* af: audio filter
+5 -4
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
*
* 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.
*/
/* Calculates a number of window functions. The following window
+5 -4
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) 2001 Anders Johansson ajh@atri.curtin.edu.au
*
* 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.
*/
/* Calculates a number of window functions. The following window
+6 -5
View File
@@ -1,19 +1,20 @@
/*
* 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 <libavutil/avutil.h>
#include <libavutil/samplefmt.h>
+5 -4
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_SAMPLE_FMT_CONVERSION_H
+17 -21
View File
@@ -1,20 +1,21 @@
/*
* Copyright (C) 2005 Alex Beregszaszi
*
* 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>
@@ -44,6 +45,11 @@ int af_fmt2bits(int format)
return af_fmt2bps(format) * 8;
}
bool af_fmt_is_float(int format)
{
return !!(format & AF_FORMAT_F);
}
static int bits_to_mask(int bits)
{
switch (bits) {
@@ -99,6 +105,12 @@ int af_fmt_from_planar(int format)
return format;
}
// false for interleaved and AF_FORMAT_UNKNOWN
bool af_fmt_is_planar(int format)
{
return !!(format & AF_FORMAT_PLANAR);
}
const struct af_fmt_entry af_fmtstr_table[] = {
{"u8", AF_FORMAT_U8},
{"s8", AF_FORMAT_S8},
@@ -149,7 +161,7 @@ const char *af_fmt_to_str(int format)
int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int samplerate)
{
assert(!AF_FORMAT_IS_PLANAR(format));
assert(!af_fmt_is_planar(format));
int bps = af_fmt2bps(format);
int framelen = channels * bps;
int bytes = seconds * bps * samplerate;
@@ -215,19 +227,3 @@ int af_format_conversion_score(int dst_format, int src_format)
score -= 2048; // has to convert float<->int
return score;
}
// Return the number of samples that make up one frame in this format.
// You get the byte size by multiplying them with sample size and channel count.
int af_format_sample_alignment(int format)
{
switch (format) {
case AF_FORMAT_S_AAC: return 16384 / 4;
case AF_FORMAT_S_AC3: return 6144 / 4;
case AF_FORMAT_S_DTSHD: return 32768 / 16;
case AF_FORMAT_S_DTS: return 2048 / 4;
case AF_FORMAT_S_EAC3: return 24576 / 4;
case AF_FORMAT_S_MP3: return 4608 / 4;
case AF_FORMAT_S_TRUEHD: return 61440 / 16;
default: return 1;
}
}
+22 -24
View File
@@ -3,20 +3,21 @@
* The format definition only refers to the storage format,
* not the resolution.
*
* 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_AF_FORMAT_H
@@ -64,24 +65,24 @@
enum af_format {
AF_FORMAT_UNKNOWN = 0,
AF_FORMAT_U8 = AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_8BIT,
AF_FORMAT_S8 = AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_8BIT,
AF_FORMAT_U16 = AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_16BIT,
AF_FORMAT_S16 = AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_16BIT,
AF_FORMAT_U24 = AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_24BIT,
AF_FORMAT_S24 = AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_24BIT,
AF_FORMAT_U32 = AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_32BIT,
AF_FORMAT_S32 = AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_32BIT,
AF_FORMAT_U8 = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_8BIT),
AF_FORMAT_S8 = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_8BIT),
AF_FORMAT_U16 = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_16BIT),
AF_FORMAT_S16 = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_16BIT),
AF_FORMAT_U24 = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_24BIT),
AF_FORMAT_S24 = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_24BIT),
AF_FORMAT_U32 = (AF_FORMAT_I|AF_FORMAT_US|AF_FORMAT_32BIT),
AF_FORMAT_S32 = (AF_FORMAT_I|AF_FORMAT_SI|AF_FORMAT_32BIT),
AF_FORMAT_FLOAT = AF_FORMAT_F|AF_FORMAT_32BIT,
AF_FORMAT_DOUBLE = AF_FORMAT_F|AF_FORMAT_64BIT,
AF_FORMAT_FLOAT = (AF_FORMAT_F|AF_FORMAT_32BIT),
AF_FORMAT_DOUBLE = (AF_FORMAT_F|AF_FORMAT_64BIT),
// Planar variants
AF_FORMAT_U8P = AF_INTP|AF_FORMAT_US|AF_FORMAT_8BIT,
AF_FORMAT_S16P = AF_INTP|AF_FORMAT_SI|AF_FORMAT_16BIT,
AF_FORMAT_S32P = AF_INTP|AF_FORMAT_SI|AF_FORMAT_32BIT,
AF_FORMAT_FLOATP = AF_FLTP|AF_FORMAT_32BIT,
AF_FORMAT_DOUBLEP = AF_FLTP|AF_FORMAT_64BIT,
AF_FORMAT_U8P = (AF_INTP|AF_FORMAT_US|AF_FORMAT_8BIT),
AF_FORMAT_S16P = (AF_INTP|AF_FORMAT_SI|AF_FORMAT_16BIT),
AF_FORMAT_S32P = (AF_INTP|AF_FORMAT_SI|AF_FORMAT_32BIT),
AF_FORMAT_FLOATP = (AF_FLTP|AF_FORMAT_32BIT),
AF_FORMAT_DOUBLEP = (AF_FLTP|AF_FORMAT_64BIT),
// All of these use IEC61937 framing, and otherwise pretend to be like PCM.
AF_FORMAT_S_AAC = AF_FORMAT_S_(0),
@@ -95,9 +96,6 @@ enum af_format {
#define AF_FORMAT_IS_IEC61937(f) (((f) & AF_FORMAT_TYPE_MASK) == AF_FORMAT_S)
#define AF_FORMAT_IS_SPECIAL(f) AF_FORMAT_IS_IEC61937(f)
#define AF_FORMAT_IS_FLOAT(f) (!!((f) & AF_FORMAT_F))
// false for interleaved and AF_FORMAT_UNKNOWN
#define AF_FORMAT_IS_PLANAR(f) (!!((f) & AF_FORMAT_PLANAR))
struct af_fmt_entry {
const char *name;
@@ -111,10 +109,12 @@ const char *af_fmt_to_str(int format);
int af_fmt2bps(int format);
int af_fmt2bits(int format);
bool af_fmt_is_float(int format);
int af_fmt_change_bits(int format, int bits);
int af_fmt_to_planar(int format);
int af_fmt_from_planar(int format);
bool af_fmt_is_planar(int format);
// Amount of bytes that contain audio of the given duration, aligned to frames.
int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int samplerate);
@@ -125,6 +125,4 @@ void af_fill_silence(void *dst, size_t bytes, int format);
int af_format_conversion_score(int dst_format, int src_format);
int af_format_sample_alignment(int format);
#endif /* MPLAYER_AF_FORMAT_H */
+21 -38
View File
@@ -1,24 +1,24 @@
/*
* 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 <string.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <libavutil/common.h>
@@ -37,7 +37,7 @@ struct mixer {
struct af_stream *af;
// Static, dependent on ao/softvol settings
bool softvol; // use AO (false) or af_volume (true)
bool persistent_volume; // volume does not need to be restored
bool ao_softvol; // AO has private or per-app volume
bool emulate_mute; // if true, emulate mute with volume=0
// Last known values (possibly out of sync with reality)
float vol_l, vol_r;
@@ -88,7 +88,6 @@ static void checkvolume(struct mixer *mixer)
vol.left = (gain / (mixer->opts->softvol_max / 100.0)) * 100.0;
vol.right = (gain / (mixer->opts->softvol_max / 100.0)) * 100.0;
} else {
MP_DBG(mixer, "Reading volume from AO.\n");
// Rely on the values not changing if the query is not supported
ao_control(mixer->ao, AOCONTROL_GET_VOLUME, &vol);
ao_control(mixer->ao, AOCONTROL_GET_MUTE, &mixer->muted);
@@ -124,17 +123,14 @@ static void setvolume_internal(struct mixer *mixer, float l, float r)
{
struct ao_control_vol vol = {.left = l, .right = r};
if (!mixer->softvol) {
MP_DBG(mixer, "Setting volume on AO.\n");
if (ao_control(mixer->ao, AOCONTROL_SET_VOLUME, &vol) != CONTROL_OK)
MP_ERR(mixer, "Failed to change audio output volume.\n");
return;
}
float gain = (l + r) / 2.0 / 100.0 * mixer->opts->softvol_max / 100.0;
if (!af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)) {
if (gain == 1.0)
return;
MP_VERBOSE(mixer, "Inserting volume filter.\n");
if (!(af_add(mixer->af, "volume", "softvol", NULL)
if (!(af_add(mixer->af, "volume", NULL)
&& af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)))
MP_ERR(mixer, "No volume control available.\n");
}
@@ -143,7 +139,8 @@ static void setvolume_internal(struct mixer *mixer, float l, float r)
void mixer_setvolume(struct mixer *mixer, float l, float r)
{
checkvolume(mixer); // to check mute status
if (mixer->vol_l == l && mixer->vol_r == r)
return; // just prevent af_volume insertion when not needed
mixer->vol_l = av_clipf(l, 0, 100);
mixer->vol_r = av_clipf(r, 0, 100);
if (mixer->ao && !(mixer->emulate_mute && mixer->muted))
@@ -221,7 +218,7 @@ void mixer_setbalance(struct mixer *mixer, float val)
if (val == 0)
return;
if (!(af_pan_balance = af_add(mixer->af, "pan", "autopan", NULL))) {
if (!(af_pan_balance = af_add(mixer->af, "pan", NULL))) {
MP_ERR(mixer, "No balance control available.\n");
return;
}
@@ -249,23 +246,17 @@ char *mixer_get_volume_restore_data(struct mixer *mixer)
static void probe_softvol(struct mixer *mixer)
{
bool ao_perapp = ao_control(mixer->ao, AOCONTROL_HAS_PER_APP_VOLUME, 0) == 1;
bool ao_softvol = ao_control(mixer->ao, AOCONTROL_HAS_SOFT_VOLUME, 0) == 1;
assert(!(ao_perapp && ao_softvol));
mixer->persistent_volume = !ao_softvol;
mixer->ao_softvol =
ao_control(mixer->ao, AOCONTROL_HAS_SOFT_VOLUME, 0) == 1 ||
ao_control(mixer->ao, AOCONTROL_HAS_PER_APP_VOLUME, 0) == 1;
if (mixer->opts->softvol == SOFTVOL_AUTO) {
// No system-wide volume => fine with AO volume control.
mixer->softvol = !ao_softvol && !ao_perapp;
mixer->softvol = !mixer->ao_softvol;
} else {
mixer->softvol = mixer->opts->softvol == SOFTVOL_YES;
}
if (mixer->softvol)
mixer->persistent_volume = false;
MP_DBG(mixer, "Will use af_volume: %s\n", mixer->softvol ? "yes" : "no");
// If we can't use real volume control => force softvol.
if (!mixer->softvol) {
ao_control_vol_t vol;
@@ -294,9 +285,11 @@ static void restore_volume(struct mixer *mixer)
const char *prev_driver = mixer->driver;
mixer->driver = mixer->softvol ? "softvol" : ao_get_name(ao);
bool restore = mixer->softvol || mixer->ao_softvol;
// Restore old parameters if volume won't survive reinitialization.
// But not if volume scale is possibly different.
if (!mixer->persistent_volume && strcmp(mixer->driver, prev_driver) == 0) {
if (restore && strcmp(mixer->driver, prev_driver) == 0) {
force_vol_l = mixer->vol_l;
force_vol_r = mixer->vol_r;
}
@@ -313,7 +306,7 @@ static void restore_volume(struct mixer *mixer)
// Set parameters from playback resume.
char *data = mixer->opts->mixer_restore_volume_data;
if (!mixer->persistent_volume && data && data[0]) {
if (restore && data && data[0]) {
char drv[40];
float v_l, v_r, s;
int m;
@@ -323,7 +316,6 @@ static void restore_volume(struct mixer *mixer)
force_vol_l = v_l;
force_vol_r = v_r;
force_mute = !!m;
MP_DBG(mixer, "Restoring volume from resume config.\n");
}
}
talloc_free(mixer->opts->mixer_restore_volume_data);
@@ -339,14 +331,10 @@ static void restore_volume(struct mixer *mixer)
opts->mixer_init_mute = -1;
checkvolume(mixer);
if (force_vol_l >= 0 && force_vol_r >= 0) {
MP_DBG(mixer, "Restoring previous volume.\n");
if (force_vol_l >= 0 && force_vol_r >= 0)
mixer_setvolume(mixer, force_vol_l, force_vol_r);
}
if (force_mute >= 0) {
MP_DBG(mixer, "Restoring previous mute toggle.\n");
if (force_mute >= 0)
mixer_setmute(mixer, force_mute);
}
}
// Called after the audio filter chain is built or rebuilt.
@@ -358,8 +346,6 @@ void mixer_reinit_audio(struct mixer *mixer, struct ao *ao, struct af_stream *af
mixer->ao = ao;
mixer->af = af;
MP_DBG(mixer, "Reinit...\n");
probe_softvol(mixer);
restore_volume(mixer);
@@ -376,11 +362,8 @@ void mixer_uninit_audio(struct mixer *mixer)
if (!mixer->ao)
return;
MP_DBG(mixer, "Uninit...\n");
checkvolume(mixer);
if (mixer->muted_by_us && mixer->persistent_volume) {
MP_DBG(mixer, "Draining.\n");
if (mixer->muted_by_us && !mixer->softvol && !mixer->ao_softvol) {
/* Current audio output API combines playing the remaining buffered
* audio and uninitializing the AO into one operation, even though
* ideally unmute would happen between those two steps. We can't do
+5 -4
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_MIXER_H
+29 -124
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>
@@ -198,7 +199,7 @@ static struct ao *ao_init(bool probing, struct mpv_global *global,
ao->sstride = af_fmt2bps(ao->format);
ao->num_planes = 1;
if (AF_FORMAT_IS_PLANAR(ao->format)) {
if (af_fmt_is_planar(ao->format)) {
ao->num_planes = ao->channels.num;
} else {
ao->sstride *= ao->channels.num;
@@ -210,9 +211,6 @@ static struct ao *ao_init(bool probing, struct mpv_global *global,
if (ao->device_buffer)
MP_VERBOSE(ao, "device buffer: %d samples.\n", ao->device_buffer);
ao->buffer = MPMAX(ao->device_buffer, ao->def_buffer * ao->samplerate);
int align = af_format_sample_alignment(ao->format);
ao->buffer = (ao->buffer + align - 1) / align * align;
MP_VERBOSE(ao, "using soft-buffer of %d samples.\n", ao->buffer);
if (ao->api->init(ao) < 0)
@@ -385,26 +383,17 @@ bool ao_eof_reached(struct ao *ao)
// Query the AO_EVENT_*s as requested by the events parameter, and return them.
int ao_query_and_reset_events(struct ao *ao, int events)
{
return atomic_fetch_and(&ao->events_, ~(unsigned)events) & events;
int actual_events = 0;
if (atomic_load(&ao->request_reload)) // don't need to reset it
actual_events |= AO_EVENT_RELOAD;
return actual_events & events;
}
static void ao_add_events(struct ao *ao, int events)
{
atomic_fetch_or(&ao->events_, events);
if (ao->input_ctx)
mp_input_wakeup(ao->input_ctx);
}
// Request that the player core destroys and recreates the AO. Fully thread-safe.
// Request that the player core destroys and recreates the AO.
void ao_request_reload(struct ao *ao)
{
ao_add_events(ao, AO_EVENT_RELOAD);
}
// Notify the player that the device list changed. Fully thread-safe.
void ao_hotplug_event(struct ao *ao)
{
ao_add_events(ao, AO_EVENT_HOTPLUG);
atomic_store(&ao->request_reload, true);
mp_input_wakeup(ao->input_ctx);
}
bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
@@ -413,20 +402,10 @@ bool ao_chmap_sel_adjust(struct ao *ao, const struct mp_chmap_sel *s,
if (mp_msg_test(ao->log, MSGL_DEBUG)) {
for (int i = 0; i < s->num_chmaps; i++) {
struct mp_chmap c = s->chmaps[i];
struct mp_chmap cr = c;
mp_chmap_reorder_norm(&cr);
MP_DBG(ao, "chmap_sel #%d: %s (%s)\n", i, mp_chmap_to_str(&c),
mp_chmap_to_str(&cr));
MP_DBG(ao, "chmap_sel #%d: %s\n", i, mp_chmap_to_str(&c));
}
}
bool r = mp_chmap_sel_adjust(s, map);
if (r) {
struct mp_chmap mapr = *map;
mp_chmap_reorder_norm(&mapr);
MP_DBG(ao, "result: %s (%s)\n", mp_chmap_to_str(map),
mp_chmap_to_str(&mapr));
}
return r;
return mp_chmap_sel_adjust(s, map);
}
bool ao_chmap_sel_get_def(struct ao *ao, const struct mp_chmap_sel *s,
@@ -460,94 +439,31 @@ bool ao_untimed(struct ao *ao)
return ao->untimed;
}
// ---
struct ao_hotplug {
struct mpv_global *global;
struct input_ctx *input_ctx;
// A single AO instance is used to listen to hotplug events. It wouldn't
// make much sense to allow multiple AO drivers; all sane platforms have
// a single such audio API.
// This is _not_ the same AO instance as used for playing audio.
struct ao *ao;
// cached
struct ao_device_list *list;
bool needs_update;
};
struct ao_hotplug *ao_hotplug_create(struct mpv_global *global,
struct input_ctx *input_ctx)
const char *ao_get_detected_device(struct ao *ao)
{
struct ao_hotplug *hp = talloc_ptrtype(NULL, hp);
*hp = (struct ao_hotplug){
.global = global,
.input_ctx = input_ctx,
.needs_update = true,
};
return hp;
return ao->detected_device;
}
static void get_devices(struct ao *ao, struct ao_device_list *list)
struct ao_device_list *ao_get_device_list(struct mpv_global *global)
{
int num = list->num_devices;
if (ao->driver->list_devs)
ao->driver->list_devs(ao, list);
// Add at least a default entry
if (list->num_devices == num)
ao_device_list_add(list, ao, &(struct ao_device_desc){"", "Default"});
}
bool ao_hotplug_check_update(struct ao_hotplug *hp)
{
if (hp->ao && ao_query_and_reset_events(hp->ao, AO_EVENT_HOTPLUG)) {
hp->needs_update = true;
return true;
}
return false;
}
const char *ao_hotplug_get_detected_device(struct ao_hotplug *hp)
{
if (!hp || !hp->ao)
return NULL;
return hp->ao->detected_device;
}
// The return value is valid until the next call to this API.
struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp)
{
if (hp->list && !hp->needs_update)
return hp->list;
talloc_free(hp->list);
struct ao_device_list *list = talloc_zero(hp, struct ao_device_list);
hp->list = list;
struct ao_device_list *list = talloc_zero(NULL, struct ao_device_list);
MP_TARRAY_APPEND(list, list->devices, list->num_devices,
(struct ao_device_desc){"auto", "Autoselect device"});
for (int n = 0; audio_out_drivers[n]; n++) {
const struct ao_driver *d = audio_out_drivers[n];
if (d == &audio_out_null)
break; // don't add unsafe/special entries
struct ao *ao = ao_alloc(true, hp->global, hp->input_ctx,
(char *)d->name, NULL);
struct ao *ao = ao_alloc(true, global, NULL, (char *)d->name, NULL);
if (!ao)
continue;
if (ao->driver->hotplug_init) {
if (!hp->ao && ao->driver->hotplug_init(ao) >= 0)
hp->ao = ao; // keep this one
if (hp->ao && hp->ao->driver == d)
get_devices(hp->ao, list);
} else {
get_devices(ao, list);
}
if (ao != hp->ao)
talloc_free(ao);
int num = list->num_devices;
if (d->list_devs)
d->list_devs(ao, list);
// Add at least a default entry
if (list->num_devices == num)
ao_device_list_add(list, ao, &(struct ao_device_desc){"", "Default"});
talloc_free(ao);
}
hp->needs_update = false;
return list;
}
@@ -562,24 +478,13 @@ void ao_device_list_add(struct ao_device_list *list, struct ao *ao,
MP_TARRAY_APPEND(list, list->devices, list->num_devices, c);
}
void ao_hotplug_destroy(struct ao_hotplug *hp)
{
if (!hp)
return;
if (hp->ao && hp->ao->driver->hotplug_uninit)
hp->ao->driver->hotplug_uninit(hp->ao);
talloc_free(hp->ao);
talloc_free(hp);
}
void ao_print_devices(struct mpv_global *global, struct mp_log *log)
{
struct ao_hotplug *hp = ao_hotplug_create(global, NULL);
struct ao_device_list *list = ao_hotplug_get_device_list(hp);
struct ao_device_list *list = ao_get_device_list(global);
mp_info(log, "List of detected audio devices:\n");
for (int n = 0; n < list->num_devices; n++) {
struct ao_device_desc *desc = &list->devices[n];
mp_info(log, " '%s' (%s)\n", desc->name, desc->desc);
}
ao_hotplug_destroy(hp);
talloc_free(list);
}
+7 -14
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_AUDIO_OUT_H
@@ -47,7 +48,6 @@ enum aocontrol {
enum {
AO_EVENT_RELOAD = 1,
AO_EVENT_HOTPLUG = 2,
};
typedef struct ao_control_vol {
@@ -79,6 +79,7 @@ void ao_uninit(struct ao *ao);
void ao_get_format(struct ao *ao, struct mp_audio *format);
const char *ao_get_name(struct ao *ao);
const char *ao_get_description(struct ao *ao);
const char *ao_get_detected_device(struct ao *ao);
bool ao_untimed(struct ao *ao);
int ao_play(struct ao *ao, void **data, int samples, int flags);
int ao_control(struct ao *ao, enum aocontrol cmd, void *arg);
@@ -91,16 +92,8 @@ void ao_drain(struct ao *ao);
bool ao_eof_reached(struct ao *ao);
int ao_query_and_reset_events(struct ao *ao, int events);
void ao_request_reload(struct ao *ao);
void ao_hotplug_event(struct ao *ao);
struct ao_hotplug;
struct ao_hotplug *ao_hotplug_create(struct mpv_global *global,
struct input_ctx *input_ctx);
void ao_hotplug_destroy(struct ao_hotplug *hp);
bool ao_hotplug_check_update(struct ao_hotplug *hp);
const char *ao_hotplug_get_detected_device(struct ao_hotplug *hp);
struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp);
struct ao_device_list *ao_get_device_list(struct mpv_global *global);
void ao_print_devices(struct mpv_global *global, struct mp_log *log);
#endif /* MPLAYER_AUDIO_OUT_H */
+54 -71
View File
@@ -10,20 +10,21 @@
* 04/13/2004 merged with ao_alsa1.x, fixes provided by Jindrich Makovicka
* 04/25/2004 printfs converted to mp_msg, Zsolt.
*
* 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 <errno.h>
@@ -63,7 +64,6 @@ struct priv {
int cfg_mixer_index;
int cfg_resample;
int cfg_ni;
int cfg_ignore_chmap;
};
#define BUFFER_TIME 250000 // 250ms
@@ -252,7 +252,6 @@ static const int alsa_to_mp_channels[][2] = {
{SND_CHMAP_TRR, MP_SP(TBR)},
{SND_CHMAP_TRC, MP_SP(TBC)},
{SND_CHMAP_MONO, MP_SP(FC)},
{SND_CHMAP_NA, MP_SPEAKER_ID_NA},
{SND_CHMAP_LAST, MP_SPEAKER_ID_COUNT}
};
@@ -276,20 +275,6 @@ static int find_alsa_channel(int mp_channel)
return SND_CHMAP_UNKNOWN;
}
static int mp_chmap_from_alsa(struct mp_chmap *dst, snd_pcm_chmap_t *src)
{
*dst = (struct mp_chmap) {0};
if (src->channels > MP_NUM_CHANNELS)
return -1;
dst->num = src->channels;
for (int c = 0; c < dst->num; c++)
dst->speaker[c] = find_mp_channel(src->pos[c]);
return 0;
}
static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
{
struct priv *p = ao->priv;
@@ -300,8 +285,14 @@ static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
return false;
for (int i = 0; maps[i] != NULL; i++) {
struct mp_chmap entry;
mp_chmap_from_alsa(&entry, &maps[i]->map);
if (maps[i]->map.channels > MP_NUM_CHANNELS) {
MP_VERBOSE(ao, "skipping ALSA channel map with too many channels.\n");
continue;
}
struct mp_chmap entry = {.num = maps[i]->map.channels};
for (int c = 0; c < entry.num; c++)
entry.speaker[c] = find_mp_channel(maps[i]->map.pos[c]);
if (mp_chmap_is_valid(&entry)) {
MP_VERBOSE(ao, "Got supported channel map: %s (type %s)\n",
@@ -384,7 +375,6 @@ static int try_open_device(struct ao *ao, const char *device)
IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
map_iec958_srate(ao->samplerate));
const char *ac3_device = append_params(tmp, device, params);
MP_VERBOSE(ao, "opening device '%s' => '%s'\n", device, ac3_device);
int err = snd_pcm_open
(&p->alsa, ac3_device, SND_PCM_STREAM_PLAYBACK, 0);
talloc_free(tmp);
@@ -392,7 +382,6 @@ static int try_open_device(struct ao *ao, const char *device)
return 0;
}
MP_VERBOSE(ao, "opening device '%s'\n", device);
return snd_pcm_open(&p->alsa, device, SND_PCM_STREAM_PLAYBACK, 0);
}
@@ -413,19 +402,28 @@ alsa_error: ;
#define INIT_OK 0
#define INIT_ERROR -1
#define INIT_BRAINDEATH -2
static int init_device(struct ao *ao, bool second_try)
static int init_device(struct ao *ao)
{
struct priv *p = ao->priv;
int err;
if (!p->cfg_ni)
ao->format = af_fmt_from_planar(ao->format);
const char *device = "default";
if (AF_FORMAT_IS_IEC61937(ao->format))
if (AF_FORMAT_IS_IEC61937(ao->format)) {
device = "iec958";
MP_VERBOSE(ao, "playing AC3/iec61937/iec958, %i channels\n",
ao->channels.num);
}
if (ao->device)
device = ao->device;
if (p->cfg_device && p->cfg_device[0])
device = p->cfg_device;
MP_VERBOSE(ao, "using device: %s\n", device);
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
err = try_open_device(ao, device);
CHECK_ALSA_ERROR("Playback open error");
@@ -468,11 +466,11 @@ static int init_device(struct ao *ao, bool second_try)
err = snd_pcm_hw_params_set_format(p->alsa, alsa_hwparams, p->alsa_fmt);
CHECK_ALSA_ERROR("Unable to set format");
snd_pcm_access_t access = AF_FORMAT_IS_PLANAR(ao->format)
snd_pcm_access_t access = af_fmt_is_planar(ao->format)
? SND_PCM_ACCESS_RW_NONINTERLEAVED
: SND_PCM_ACCESS_RW_INTERLEAVED;
err = snd_pcm_hw_params_set_access(p->alsa, alsa_hwparams, access);
if (err < 0 && AF_FORMAT_IS_PLANAR(ao->format)) {
if (err < 0 && af_fmt_is_planar(ao->format)) {
ao->format = af_fmt_from_planar(ao->format);
access = SND_PCM_ACCESS_RW_INTERLEAVED;
err = snd_pcm_hw_params_set_access(p->alsa, alsa_hwparams, access);
@@ -480,7 +478,7 @@ static int init_device(struct ao *ao, bool second_try)
CHECK_ALSA_ERROR("Unable to set access type");
struct mp_chmap dev_chmap = ao->channels;
if (AF_FORMAT_IS_IEC61937(ao->format) || p->cfg_ignore_chmap) {
if (AF_FORMAT_IS_IEC61937(ao->format)) {
dev_chmap.num = 0; // disable chmap API
} else if (query_chmaps(ao, &dev_chmap)) {
ao->channels = dev_chmap;
@@ -501,12 +499,8 @@ static int init_device(struct ao *ao, bool second_try)
}
if (num_channels != ao->channels.num) {
int req = ao->channels.num;
MP_ERR(ao, "Couldn't get requested number of channels.\n");
mp_chmap_from_channels_alsa(&ao->channels, num_channels);
if (!mp_chmap_is_valid(&ao->channels))
mp_chmap_from_channels(&ao->channels, 2);
MP_ERR(ao, "Couldn't get requested number of channels (%d), fallback "
"to %s.\n", req, mp_chmap_to_str(&ao->channels));
}
// Some ALSA drivers have broken delay reporting, so disable the ALSA
@@ -556,11 +550,8 @@ static int init_device(struct ao *ao, bool second_try)
err = snd_pcm_set_chmap(p->alsa, alsa_chmap);
if (err == -ENXIO) {
// I consider this an ALSA bug: the channel map was reported as
// supported, but we still can't set it. It happens virtually
// always with dmix, though.
MP_VERBOSE(ao, "Device does not support requested channel map (%s)\n",
mp_chmap_to_str(&dev_chmap));
MP_WARN(ao, "Device does not support requested channel map (%s)\n",
mp_chmap_to_str(&dev_chmap));
} else {
CHECK_ALSA_WARN("Channel map setup failed");
}
@@ -574,24 +565,33 @@ static int init_device(struct ao *ao, bool second_try)
if (snd_pcm_chmap_print(alsa_chmap, sizeof(tmp), tmp) > 0)
MP_VERBOSE(ao, "channel map reported by ALSA: %s\n", tmp);
struct mp_chmap chmap;
mp_chmap_from_alsa(&chmap, alsa_chmap);
struct mp_chmap chmap = {.num = alsa_chmap->channels};
for (int c = 0; c < chmap.num; c++)
chmap.speaker[c] = find_mp_channel(alsa_chmap->pos[c]);
MP_VERBOSE(ao, "which we understand as: %s\n", mp_chmap_to_str(&chmap));
if (p->cfg_ignore_chmap) {
MP_VERBOSE(ao, "user set ignore-chmap; ignoring the channel map.\n");
} else if (AF_FORMAT_IS_IEC61937(ao->format)) {
if (AF_FORMAT_IS_IEC61937(ao->format)) {
MP_VERBOSE(ao, "using spdif passthrough; ignoring the channel map.\n");
} else if (mp_chmap_is_valid(&chmap)) {
if (mp_chmap_equals(&chmap, &ao->channels)) {
MP_VERBOSE(ao, "which is what we requested.\n");
} else if (chmap.num == ao->channels.num) {
MP_VERBOSE(ao, "using the ALSA channel map.\n");
ao->channels = chmap;
} else {
MP_WARN(ao, "ALSA channel map conflicts with channel count!\n");
}
} else {
// Is it one that contains NA channels?
struct mp_chmap without_na = chmap;
mp_chmap_remove_na(&without_na);
struct mp_chmap chmap2 = {0};
for (int c = 0; c < alsa_chmap->channels; c++) {
int alsa_ch = alsa_chmap->pos[c];
if (alsa_ch != SND_CHMAP_NA)
chmap2.speaker[chmap2.num++] = find_mp_channel(alsa_ch);
}
if (mp_chmap_is_valid(&without_na) &&
!mp_chmap_equals(&without_na, &chmap) &&
!second_try)
{
if (mp_chmap_is_valid(&chmap2)) {
// Sometimes, ALSA will advertise certain chmaps, but it's not
// possible to set them. This can happen with dmix: as of
// alsa 1.0.28, dmix can do stereo only, but advertises the
@@ -604,23 +604,13 @@ static int init_device(struct ao *ao, bool second_try)
// the number of channels to 2 either, because the hw params
// are already set! So just fuck it and reopen the device with
// the chmap "cleaned out" of NA entries.
MP_VERBOSE(ao, "Working around braindead ALSA behavior.\n");
err = snd_pcm_close(p->alsa);
p->alsa = NULL;
CHECK_ALSA_ERROR("pcm close error");
ao->channels = without_na;
ao->channels = chmap2;
return INIT_BRAINDEATH;
}
if (mp_chmap_equals(&chmap, &ao->channels)) {
MP_VERBOSE(ao, "which is what we requested.\n");
} else if (chmap.num == ao->channels.num) {
MP_VERBOSE(ao, "using the ALSA channel map.\n");
ao->channels = chmap;
} else {
MP_WARN(ao, "ALSA channel map conflicts with channel count!\n");
}
} else {
MP_WARN(ao, "Got unknown channel map from ALSA.\n");
}
@@ -685,15 +675,9 @@ alsa_error:
static int init(struct ao *ao)
{
struct priv *p = ao->priv;
if (!p->cfg_ni)
ao->format = af_fmt_from_planar(ao->format);
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
int r = init_device(ao, false);
int r = init_device(ao);
if (r == INIT_BRAINDEATH)
r = init_device(ao, true); // retry with normalized channel layout
r = init_device(ao); // retry with normalized channel layout
return r == INIT_OK ? 0 : -1;
}
@@ -830,7 +814,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
return 0;
do {
if (AF_FORMAT_IS_PLANAR(ao->format)) {
if (af_fmt_is_planar(ao->format)) {
res = snd_pcm_writen(p->alsa, data, samples);
} else {
res = snd_pcm_writei(p->alsa, data[0], samples);
@@ -950,7 +934,6 @@ const struct ao_driver audio_out_alsa = {
OPT_STRING("mixer-name", cfg_mixer_name, 0),
OPT_INTRANGE("mixer-index", cfg_mixer_index, 0, 0, 99),
OPT_FLAG("non-interleaved", cfg_ni, 0),
OPT_FLAG("ignore-chmap", cfg_ignore_chmap, 0),
{0}
},
};
+39 -96
View File
@@ -38,6 +38,11 @@ struct priv {
bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
struct mp_chmap *chmap);
static int64_t ca_frames_to_us(struct ao *ao, uint32_t frames)
{
return frames / (float) ao->samplerate * 1e6;
}
static int64_t ca_get_hardware_latency(struct ao *ao) {
struct priv *p = ao->priv;
@@ -68,6 +73,17 @@ coreaudio_error:
return 0;
}
static int64_t ca_get_latency(const AudioTimeStamp *ts)
{
uint64_t out = AudioConvertHostTimeToNanos(ts->mHostTime);
uint64_t now = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
if (now > out)
return 0;
return (out - now) * 1e-3;
}
static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags,
const AudioTimeStamp *ts, UInt32 bus,
UInt32 frames, AudioBufferList *buffer_list)
@@ -78,6 +94,7 @@ static OSStatus render_cb_lpcm(void *ctx, AudioUnitRenderActionFlags *aflags,
int64_t end = mp_time_us();
end += p->hw_latency_us + ca_get_latency(ts) + ca_frames_to_us(ao, frames);
ao_read_data(ao, &buf.mData, frames, end);
return noErr;
}
@@ -117,6 +134,8 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
return set_volume(ao, arg);
case AOCONTROL_HAS_SOFT_VOLUME:
return CONTROL_TRUE;
case AOCONTROL_HAS_PER_APP_VOLUME:
return CONTROL_TRUE;
}
return CONTROL_UNKNOWN;
}
@@ -124,23 +143,6 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
static bool init_chmap(struct ao *ao);
static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd);
static bool reinit_device(struct ao *ao) {
struct priv *p = ao->priv;
OSStatus err = ca_select_device(ao, ao->device, &p->device);
CHECK_CA_ERROR("failed to select device");
char *uid;
err = CA_GET_STR(p->device, kAudioDevicePropertyDeviceUID, &uid);
CHECK_CA_ERROR("failed to get device UID");
ao->detected_device = talloc_steal(ao, uid);
return true;
coreaudio_error:
return false;
}
static int init(struct ao *ao)
{
if (AF_FORMAT_IS_IEC61937(ao->format)) {
@@ -149,8 +151,15 @@ static int init(struct ao *ao)
return CONTROL_ERROR;
}
if (!reinit_device(ao))
goto coreaudio_error;
struct priv *p = ao->priv;
OSStatus err = ca_select_device(ao, ao->device, &p->device);
CHECK_CA_ERROR("failed to select device");
char *uid;
err = CA_GET_STR(p->device, kAudioDevicePropertyDeviceUID, &uid);
CHECK_CA_ERROR("failed to get device UID");
ao->detected_device = talloc_steal(ao, uid);
if (!init_chmap(ao))
goto coreaudio_error;
@@ -352,67 +361,6 @@ static void uninit(struct ao *ao)
AudioComponentInstanceDispose(p->audio_unit);
}
static OSStatus hotplug_cb(AudioObjectID id, UInt32 naddr,
const AudioObjectPropertyAddress addr[],
void *ctx) {
reinit_device(ctx);
ao_hotplug_event(ctx);
return noErr;
}
static uint32_t hotplug_properties[] = {
kAudioHardwarePropertyDevices,
kAudioHardwarePropertyDefaultOutputDevice
};
static int hotplug_init(struct ao *ao)
{
if (!reinit_device(ao))
goto coreaudio_error;
OSStatus err = noErr;
for (int i = 0; i < MP_ARRAY_SIZE(hotplug_properties); i++) {
AudioObjectPropertyAddress addr = {
hotplug_properties[i],
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
err = AudioObjectAddPropertyListener(
kAudioObjectSystemObject, &addr, hotplug_cb, (void *)ao);
if (err != noErr) {
char *c1 = fourcc_repr(hotplug_properties[i]);
char *c2 = fourcc_repr(err);
MP_ERR(ao, "failed to set device listener %s (%s)", c1, c2);
goto coreaudio_error;
}
}
return 0;
coreaudio_error:
return -1;
}
static void hotplug_uninit(struct ao *ao)
{
OSStatus err = noErr;
for (int i = 0; i < MP_ARRAY_SIZE(hotplug_properties); i++) {
AudioObjectPropertyAddress addr = {
hotplug_properties[i],
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
err = AudioObjectRemovePropertyListener(
kAudioObjectSystemObject, &addr, hotplug_cb, (void *)ao);
if (err != noErr) {
char *c1 = fourcc_repr(hotplug_properties[i]);
char *c2 = fourcc_repr(err);
MP_ERR(ao, "failed to set device listener %s (%s)", c1, c2);
}
}
}
// Channel Mapping functions
static const int speaker_map[][2] = {
{ kAudioChannelLabel_Left, MP_SPEAKER_ID_FL },
@@ -444,9 +392,7 @@ static const int speaker_map[][2] = {
{ kAudioChannelLabel_HeadphonesLeft, MP_SPEAKER_ID_DL },
{ kAudioChannelLabel_HeadphonesRight, MP_SPEAKER_ID_DR },
{ kAudioChannelLabel_Unknown, MP_SPEAKER_ID_NA },
{ 0, -1 },
{ kAudioChannelLabel_Unknown, MP_SPEAKER_ID_UNKNOWN0 },
};
static int ca_label_to_mp_speaker_id(AudioChannelLabel label)
@@ -542,10 +488,9 @@ bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
return false;
}
int next_na = MP_SPEAKER_ID_NA;
for (int n = 0; n < l->mNumberChannelDescriptions; n++) {
AudioChannelLabel label = l->mChannelDescriptions[n].mChannelLabel;
int speaker = ca_label_to_mp_speaker_id(label);
uint8_t speaker = ca_label_to_mp_speaker_id(label);
if (speaker < 0) {
MP_VERBOSE(ao, "channel label=%u unusable to build channel "
"bitmap, skipping layout\n", (unsigned) label);
@@ -568,15 +513,13 @@ coreaudio_error:
#define OPT_BASE_STRUCT struct priv
const struct ao_driver audio_out_coreaudio = {
.description = "CoreAudio AudioUnit",
.name = "coreaudio",
.uninit = uninit,
.init = init,
.control = control,
.pause = stop,
.resume = start,
.hotplug_init = hotplug_init,
.hotplug_uninit = hotplug_uninit,
.list_devs = ca_get_device_list,
.priv_size = sizeof(struct priv),
.description = "CoreAudio AudioUnit",
.name = "coreaudio",
.uninit = uninit,
.init = init,
.control = control,
.pause = stop,
.resume = start,
.list_devs = ca_get_device_list,
.priv_size = sizeof(struct priv),
};
+199 -109
View File
@@ -11,20 +11,21 @@
* module from VideoLAN:
* Copyright (c) 2006 Derk-Jan Hartman <hartman at videolan dot org>
*
* 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/>.
* along with MPlayer; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
@@ -34,20 +35,22 @@
* when you are wanting to do good buffering of audio).
*/
#include <CoreAudio/HostTime.h>
#include "config.h"
#include "ao.h"
#include "internal.h"
#include "audio/format.h"
#include "osdep/timer.h"
#include "osdep/atomics.h"
#include "options/m_option.h"
#include "misc/ring.h"
#include "common/msg.h"
#include "audio/out/ao_coreaudio_properties.h"
#include "audio/out/ao_coreaudio_utils.h"
static bool ca_format_is_compressed(AudioStreamBasicDescription asbd)
static void audio_pause(struct ao *ao);
static void audio_resume(struct ao *ao);
static void reset(struct ao *ao);
static bool ca_format_is_digital(AudioStreamBasicDescription asbd)
{
switch (asbd.mFormatID)
case 'IAC3':
@@ -58,7 +61,7 @@ static bool ca_format_is_compressed(AudioStreamBasicDescription asbd)
return false;
}
static bool ca_stream_supports_compressed(struct ao *ao, AudioStreamID stream)
static bool ca_stream_supports_digital(struct ao *ao, AudioStreamID stream)
{
AudioStreamRangedDescription *formats = NULL;
size_t n_formats;
@@ -72,7 +75,7 @@ static bool ca_stream_supports_compressed(struct ao *ao, AudioStreamID stream)
for (int i = 0; i < n_formats; i++) {
AudioStreamBasicDescription asbd = formats[i].mFormat;
ca_print_asbd(ao, "supported format:", &(asbd));
if (ca_format_is_compressed(asbd)) {
if (ca_format_is_digital(asbd)) {
talloc_free(formats);
return true;
}
@@ -83,7 +86,7 @@ coreaudio_error:
return false;
}
static bool ca_device_supports_compressed(struct ao *ao, AudioDeviceID device)
static bool ca_device_supports_digital(struct ao *ao, AudioDeviceID device)
{
AudioStreamID *streams = NULL;
size_t n_streams;
@@ -95,7 +98,7 @@ static bool ca_device_supports_compressed(struct ao *ao, AudioDeviceID device)
CHECK_CA_ERROR("could not get number of streams.");
for (int i = 0; i < n_streams; i++) {
if (ca_stream_supports_compressed(ao, streams[i])) {
if (ca_stream_supports_digital(ao, streams[i])) {
talloc_free(streams);
return true;
}
@@ -113,13 +116,15 @@ static OSStatus ca_property_listener(
const AudioObjectPropertyAddress addresses[],
void *data)
{
void *talloc_ctx = talloc_new(NULL);
for (int i = 0; i < n_addresses; i++) {
if (addresses[i].mSelector == selector) {
if (data)
atomic_store((atomic_bool *)data, true);
if (data) *(volatile int *)data = 1;
break;
}
}
talloc_free(talloc_ctx);
return noErr;
}
@@ -241,7 +246,7 @@ static bool ca_change_format(struct ao *ao, AudioStreamID stream,
{
OSStatus err = noErr;
AudioObjectPropertyAddress p_addr;
atomic_bool stream_format_changed = ATOMIC_VAR_INIT(false);
volatile int stream_format_changed = 0;
ca_print_asbd(ao, "setting stream format:", &change_format);
@@ -253,7 +258,7 @@ static bool ca_change_format(struct ao *ao, AudioStreamID stream,
};
err = AudioObjectAddPropertyListener(stream, &p_addr, ca_stream_listener,
&stream_format_changed);
(void *)&stream_format_changed);
if (!CHECK_CA_WARN("can't add property listener during format change")) {
return false;
}
@@ -264,32 +269,33 @@ static bool ca_change_format(struct ao *ao, AudioStreamID stream,
return false;
}
/* The AudioStreamSetProperty is not only asynchronous,
/* The AudioStreamSetProperty is not only asynchronious,
* it is also not Atomic, in its behaviour.
* Therefore we check 5 times before we really give up. */
bool format_set = false;
AudioStreamBasicDescription actual_format = {0};
for (int i = 0; i < 5; i++) {
err = CA_GET(stream, kAudioStreamPropertyPhysicalFormat, &actual_format);
if (!CHECK_CA_WARN("could not retrieve physical format"))
break;
format_set = ca_asbd_equals(&change_format, &actual_format);
if (format_set)
break;
for (int j = 0; !atomic_load(&stream_format_changed) && j < 50; j++)
for (int i = 0; !format_set && i < 5; i++) {
for (int j = 0; !stream_format_changed && j < 50; j++)
mp_sleep_us(10000);
bool old = true;
if (!atomic_compare_exchange_strong(&stream_format_changed, &old, false))
if (stream_format_changed) {
stream_format_changed = 0;
} else {
MP_VERBOSE(ao, "reached timeout\n");
}
AudioStreamBasicDescription actual_format;
err = CA_GET(stream, kAudioStreamPropertyPhysicalFormat, &actual_format);
ca_print_asbd(ao, "actual format in use:", &actual_format);
if (actual_format.mSampleRate == change_format.mSampleRate &&
actual_format.mFormatID == change_format.mFormatID &&
actual_format.mFramesPerPacket == change_format.mFramesPerPacket) {
format_set = true;
}
}
ca_print_asbd(ao, "actual format in use:", &actual_format);
err = AudioObjectRemovePropertyListener(stream, &p_addr, ca_stream_listener,
&stream_format_changed);
(void *)&stream_format_changed);
if (!CHECK_CA_WARN("can't remove property listener")) {
return false;
@@ -304,30 +310,38 @@ struct priv {
bool paused;
// audio render callback
struct mp_ring *buffer;
// digital render callback
AudioDeviceIOProcID render_cb;
// pid set for hog mode, (-1) means that hog mode on the device was
// released. hog mode is exclusive access to a device
pid_t hog_pid;
// stream selected for digital playback by the detection in init
AudioStreamID stream;
// stream index in an AudioBufferList
int stream_idx;
// format we changed the stream to, and the original format to restore
// format we changed the stream to: for the digital case each application
// sets the stream format for a device to what it needs
AudioStreamBasicDescription stream_asbd;
AudioStreamBasicDescription original_asbd;
bool changed_mixing;
atomic_bool stream_asbd_changed;
bool reload_requested;
uint32_t hw_latency_us;
int stream_asbd_changed;
bool muted;
};
static OSStatus render_cb_compressed(
static int get_ring_size(struct ao *ao)
{
return af_fmt_seconds_to_bytes(
ao->format, 0.5, ao->channels.num, ao->samplerate);
}
static OSStatus render_cb_digital(
AudioDeviceID device, const AudioTimeStamp *ts,
const void *in_data, const AudioTimeStamp *in_ts,
AudioBufferList *out_data, const AudioTimeStamp *out_ts, void *ctx)
@@ -337,61 +351,86 @@ static OSStatus render_cb_compressed(
AudioBuffer buf = out_data->mBuffers[p->stream_idx];
int requested = buf.mDataByteSize;
int pseudo_frames = requested / ao->sstride;
// we expect the callback to read full frames, which are aligned accordingly
if (pseudo_frames * ao->sstride != requested) {
MP_ERR(ao, "Unsupported unaligned read of %d bytes.\n", requested);
return kAudioHardwareUnspecifiedError;
}
int64_t end = mp_time_us();
end += p->hw_latency_us + ca_get_latency(ts)
+ ca_frames_to_us(ao, pseudo_frames);
ao_read_data(ao, &buf.mData, pseudo_frames, end);
// Check whether we need to reset the compressed output stream.
if (atomic_load(&p->stream_asbd_changed)) {
AudioStreamBasicDescription f;
OSErr err = CA_GET(p->stream, kAudioStreamPropertyPhysicalFormat, &f);
CHECK_CA_WARN("could not get stream format");
if (err == noErr && ca_asbd_equals(&p->stream_asbd, &f))
atomic_store(&p->stream_asbd_changed, false);
}
if (atomic_load(&p->stream_asbd_changed) && !p->reload_requested) {
p->reload_requested = true;
ao_request_reload(ao);
MP_INFO(ao, "Stream format changed! Reloading.\n");
}
if (p->muted)
mp_ring_drain(p->buffer, requested);
else
mp_ring_read(p->buffer, buf.mData, requested);
return noErr;
}
static int control(struct ao *ao, enum aocontrol cmd, void *arg)
{
struct priv *p = ao->priv;
ao_control_vol_t *control_vol;
switch (cmd) {
case AOCONTROL_GET_VOLUME:
control_vol = (ao_control_vol_t *)arg;
// Digital output has no volume adjust.
int digitalvol = p->muted ? 0 : 100;
*control_vol = (ao_control_vol_t) {
.left = digitalvol, .right = digitalvol,
};
return CONTROL_TRUE;
case AOCONTROL_SET_VOLUME:
control_vol = (ao_control_vol_t *)arg;
// Digital output can not set volume. Here we have to return true
// to make mixer forget it. Else mixer will add a soft filter,
// that's not we expected and the filter not support ac3 stream
// will cause mplayer die.
// Although not support set volume, but at least we support mute.
// MPlayer set mute by set volume to zero, we handle it.
if (control_vol->left == 0 && control_vol->right == 0)
p->muted = true;
else
p->muted = false;
return CONTROL_TRUE;
} // end switch
return CONTROL_UNKNOWN;
}
static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd);
static int init(struct ao *ao)
{
struct priv *p = ao->priv;
OSStatus err = ca_select_device(ao, ao->device, &p->device);
CHECK_CA_ERROR_L(coreaudio_error_nounlock, "failed to select device");
CHECK_CA_ERROR("failed to select device");
ao->format = af_fmt_from_planar(ao->format);
if (!AF_FORMAT_IS_IEC61937(ao->format)) {
MP_ERR(ao, "Only compressed formats are supported.\n");
goto coreaudio_error_nounlock;
bool supports_digital = false;
/* Probe whether device support S/PDIF stream output if input is AC3 stream,
* or anything else IEC61937-framed. */
if (AF_FORMAT_IS_IEC61937(ao->format)) {
if (ca_device_supports_digital(ao, p->device))
supports_digital = true;
}
if (!ca_device_supports_compressed(ao, p->device)) {
MP_ERR(ao, "selected device doesn't support compressed formats\n");
goto coreaudio_error_nounlock;
}
if (!supports_digital) {
MP_ERR(ao, "selected device doesn't support digital formats\n");
goto coreaudio_error;
} // closes if (!supports_digital)
// Build ASBD for the input format
AudioStreamBasicDescription asbd;
ca_fill_asbd(ao, &asbd);
return init_digital(ao, asbd);
coreaudio_error:
return CONTROL_ERROR;
}
static int init_digital(struct ao *ao, AudioStreamBasicDescription asbd)
{
struct priv *p = ao->priv;
OSStatus err = noErr;
uint32_t is_alive = 1;
err = CA_GET(p->device, kAudioDevicePropertyDeviceIsAlive, &is_alive);
CHECK_CA_WARN("could not check whether device is alive");
@@ -415,9 +454,15 @@ static int init(struct ao *ao)
CHECK_CA_ERROR("could not get number of streams");
for (int i = 0; i < n_streams && p->stream_idx < 0; i++) {
bool compressed = ca_stream_supports_compressed(ao, streams[i]);
bool digital = ca_stream_supports_digital(ao, streams[i]);
if (digital) {
err = CA_GET(streams[i], kAudioStreamPropertyPhysicalFormat,
&p->original_asbd);
if (!CHECK_CA_WARN("could not get stream's physical format to "
"revert to, getting the next one"))
continue;
if (compressed) {
AudioStreamRangedDescription *formats;
size_t n_formats;
@@ -435,8 +480,8 @@ static int init(struct ao *ao)
p->stream_idx = i;
for (int j = 0; j < n_formats; j++)
if (ca_format_is_compressed(formats[j].mFormat)) {
// select the compressed format that has exactly the same
if (ca_format_is_digital(formats[j].mFormat)) {
// select the digital format that has exactly the same
// samplerate. If an exact match cannot be found, select
// the format with highest samplerate as backup.
if (formats[j].mFormat.mSampleRate == asbd.mSampleRate) {
@@ -460,18 +505,14 @@ static int init(struct ao *ao)
talloc_free(streams);
if (p->stream_idx < 0) {
MP_WARN(ao , "can't find any compressed output stream format\n");
MP_WARN(ao , "can't find any digital output stream format\n");
goto coreaudio_error;
}
err = CA_GET(p->stream, kAudioStreamPropertyPhysicalFormat,
&p->original_asbd);
CHECK_CA_ERROR("could not get stream's original physical format");
if (!ca_change_format(ao, p->stream, p->stream_asbd))
goto coreaudio_error;
void *changed = &p->stream_asbd_changed;
void *changed = (void *) &(p->stream_asbd_changed);
err = ca_enable_device_listener(p->device, changed);
CHECK_CA_ERROR("cannot install format change listener during init");
@@ -483,44 +524,77 @@ static int init(struct ao *ao)
(p->stream_asbd.mBytesPerPacket /
p->stream_asbd.mFramesPerPacket);
uint32_t latency_frames = 0;
uint32_t latency_properties[] = {
kAudioDevicePropertyLatency,
kAudioDevicePropertyBufferFrameSize,
kAudioDevicePropertySafetyOffset,
};
for (int n = 0; n < MP_ARRAY_SIZE(latency_properties); n++) {
uint32_t temp;
err = CA_GET_O(p->device, latency_properties[n], &temp);
CHECK_CA_WARN("cannot get device latency");
if (err == noErr)
latency_frames += temp;
}
p->hw_latency_us = ca_frames_to_us(ao, latency_frames);
MP_VERBOSE(ao, "base latency: %d microseconds\n", (int)p->hw_latency_us);
p->buffer = mp_ring_new(p, get_ring_size(ao));
err = AudioDeviceCreateIOProcID(p->device,
(AudioDeviceIOProc)render_cb_compressed,
(AudioDeviceIOProc)render_cb_digital,
(void *)ao,
&p->render_cb);
CHECK_CA_ERROR("failed to register audio render callback");
CHECK_CA_ERROR("failed to register digital render callback");
reset(ao);
return CONTROL_TRUE;
coreaudio_error:
err = ca_unlock_device(p->device, &p->hog_pid);
CHECK_CA_WARN("can't release hog mode");
coreaudio_error_nounlock:
return CONTROL_ERROR;
}
static int play(struct ao *ao, void **data, int samples, int flags)
{
struct priv *p = ao->priv;
void *output_samples = data[0];
int num_bytes = samples * ao->sstride;
// Check whether we need to reset the digital output stream.
if (p->stream_asbd_changed) {
p->stream_asbd_changed = 0;
if (ca_stream_supports_digital(ao, p->stream)) {
if (!ca_change_format(ao, p->stream, p->stream_asbd)) {
MP_WARN(ao , "can't restore digital output\n");
} else {
MP_WARN(ao, "restoring digital output succeeded.\n");
reset(ao);
}
}
}
int wrote = mp_ring_write(p->buffer, output_samples, num_bytes);
audio_resume(ao);
return wrote / ao->sstride;
}
static void reset(struct ao *ao)
{
struct priv *p = ao->priv;
audio_pause(ao);
mp_ring_reset(p->buffer);
}
static int get_space(struct ao *ao)
{
struct priv *p = ao->priv;
return mp_ring_available(p->buffer) / ao->sstride;
}
static double get_delay(struct ao *ao)
{
// FIXME: should also report the delay of coreaudio itself (hardware +
// internal buffers)
struct priv *p = ao->priv;
return mp_ring_buffered(p->buffer) / (double)ao->bps;
}
static void uninit(struct ao *ao)
{
struct priv *p = ao->priv;
OSStatus err = noErr;
void *changed = &p->stream_asbd_changed;
void *changed = (void *) &(p->stream_asbd_changed);
err = ca_disable_device_listener(p->device, changed);
CHECK_CA_WARN("can't remove device listener, this may cause a crash");
@@ -544,16 +618,26 @@ static void audio_pause(struct ao *ao)
{
struct priv *p = ao->priv;
if (p->paused)
return;
OSStatus err = AudioDeviceStop(p->device, p->render_cb);
CHECK_CA_WARN("can't stop audio device");
CHECK_CA_WARN("can't stop digital device");
p->paused = true;
}
static void audio_resume(struct ao *ao)
{
struct priv *p = ao->priv;
if (!p->paused)
return;
OSStatus err = AudioDeviceStart(p->device, p->render_cb);
CHECK_CA_WARN("can't start audio device");
CHECK_CA_WARN("can't start digital device");
p->paused = false;
}
#define OPT_BASE_STRUCT struct priv
@@ -563,12 +647,18 @@ const struct ao_driver audio_out_coreaudio_exclusive = {
.name = "coreaudio_exclusive",
.uninit = uninit,
.init = init,
.play = play,
.control = control,
.get_space = get_space,
.get_delay = get_delay,
.reset = reset,
.pause = audio_pause,
.resume = audio_resume,
.list_devs = ca_get_device_list,
.priv_size = sizeof(struct priv),
.priv_defaults = &(const struct priv){
.stream_asbd_changed = ATOMIC_VAR_INIT(false),
.muted = false,
.stream_asbd_changed = 0,
.hog_pid = -1,
.stream = 0,
.stream_idx = -1,
+35 -138
View File
@@ -22,8 +22,6 @@
* on CoreAudio but not the AUHAL (such as using AudioQueue services).
*/
#include <CoreAudio/HostTime.h>
#include "audio/out/ao_coreaudio_utils.h"
#include "audio/out/ao_coreaudio_properties.h"
#include "osdep/timer.h"
@@ -88,7 +86,7 @@ OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device)
OSStatus err = noErr;
*device = kAudioObjectUnknown;
if (name && name[0]) {
if (name) {
CFStringRef uid = cfstr_from_cstr(name);
AudioValueTranslation v = (AudioValueTranslation) {
.mInputData = &uid,
@@ -116,19 +114,20 @@ OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device)
if (mp_msg_test(ao->log, MSGL_V)) {
char *desc;
OSStatus err2 = CA_GET_STR(*device, kAudioObjectPropertyName, &desc);
if (err2 == noErr) {
MP_VERBOSE(ao, "selected audio output device: %s (%" PRIu32 ")\n",
desc, *device);
talloc_free(desc);
}
err = CA_GET_STR(*device, kAudioObjectPropertyName, &desc);
CHECK_CA_ERROR("could not get selected audio device name");
MP_VERBOSE(ao, "selected audio output device: %s (%" PRIu32 ")\n",
desc, *device);
talloc_free(desc);
}
coreaudio_error:
return err;
}
char *fourcc_repr_buf(char *buf, size_t buf_size, uint32_t code)
char *fourcc_repr(void *talloc_ctx, uint32_t code)
{
// Extract FourCC letters from the uint32_t and finde out if it's a valid
// code that is made of letters.
@@ -140,45 +139,47 @@ char *fourcc_repr_buf(char *buf, size_t buf_size, uint32_t code)
};
bool valid_fourcc = true;
for (int i = 0; i < 4; i++) {
if (fcc[i] < 32 || fcc[i] >= 128)
for (int i = 0; i < 4; i++)
if (fcc[i] >= 32 && fcc[i] < 128)
valid_fourcc = false;
}
char *repr;
if (valid_fourcc)
snprintf(buf, buf_size, "'%c%c%c%c'", fcc[0], fcc[1], fcc[2], fcc[3]);
repr = talloc_asprintf(talloc_ctx, "'%c%c%c%c'",
fcc[0], fcc[1], fcc[2], fcc[3]);
else
snprintf(buf, buf_size, "%u", (unsigned int)code);
repr = talloc_asprintf(NULL, "%d", code);
return buf;
return repr;
}
bool check_ca_st(struct ao *ao, int level, OSStatus code, const char *message)
{
if (code == noErr) return true;
mp_msg(ao->log, level, "%s (%s)\n", message, fourcc_repr(code));
char *error_string = fourcc_repr(NULL, code);
mp_msg(ao->log, level, "%s (%s)\n", message, error_string);
talloc_free(error_string);
return false;
}
static void ca_fill_asbd_raw(AudioStreamBasicDescription *asbd, int mp_format,
int samplerate, int num_channels)
void ca_fill_asbd(struct ao *ao, AudioStreamBasicDescription *asbd)
{
asbd->mSampleRate = samplerate;
asbd->mSampleRate = ao->samplerate;
// Set "AC3" for other spdif formats too - unknown if that works.
asbd->mFormatID = AF_FORMAT_IS_IEC61937(mp_format) ?
asbd->mFormatID = AF_FORMAT_IS_IEC61937(ao->format) ?
kAudioFormat60958AC3 :
kAudioFormatLinearPCM;
asbd->mChannelsPerFrame = num_channels;
asbd->mBitsPerChannel = af_fmt2bits(mp_format);
asbd->mChannelsPerFrame = ao->channels.num;
asbd->mBitsPerChannel = af_fmt2bits(ao->format);
asbd->mFormatFlags = kAudioFormatFlagIsPacked;
if ((mp_format & AF_FORMAT_TYPE_MASK) == AF_FORMAT_F) {
if ((ao->format & AF_FORMAT_TYPE_MASK) == AF_FORMAT_F)
asbd->mFormatFlags |= kAudioFormatFlagIsFloat;
} else if ((mp_format & AF_FORMAT_SIGN_MASK) == AF_FORMAT_SI) {
if ((ao->format & AF_FORMAT_SIGN_MASK) == AF_FORMAT_SI)
asbd->mFormatFlags |= kAudioFormatFlagIsSignedInteger;
}
if (BYTE_ORDER == BIG_ENDIAN)
asbd->mFormatFlags |= kAudioFormatFlagIsBigEndian;
@@ -189,66 +190,17 @@ static void ca_fill_asbd_raw(AudioStreamBasicDescription *asbd, int mp_format,
(asbd->mBitsPerChannel / 8);
}
void ca_fill_asbd(struct ao *ao, AudioStreamBasicDescription *asbd)
{
ca_fill_asbd_raw(asbd, ao->format, ao->samplerate, ao->channels.num);
}
static bool ca_formatid_is_digital(uint32_t formatid)
{
switch (formatid)
case 'IAC3':
case 'iac3':
case kAudioFormat60958AC3:
case kAudioFormatAC3:
return true;
return false;
}
// This might be wrong, but for now it's sufficient for us.
static uint32_t ca_normalize_formatid(uint32_t formatID)
{
return ca_formatid_is_digital(formatID) ? kAudioFormat60958AC3 : formatID;
}
bool ca_asbd_equals(const AudioStreamBasicDescription *a,
const AudioStreamBasicDescription *b)
{
int flags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsFloat |
kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsBigEndian;
return (a->mFormatFlags & flags) == (b->mFormatFlags & flags) &&
a->mBitsPerChannel == b->mBitsPerChannel &&
ca_normalize_formatid(a->mFormatID) ==
ca_normalize_formatid(b->mFormatID) &&
a->mBytesPerPacket == b->mBytesPerPacket;
}
// Return the AF_FORMAT_* (AF_FORMAT_S16 etc.) corresponding to the asbd.
int ca_asbd_to_mp_format(const AudioStreamBasicDescription *asbd)
{
for (int n = 0; af_fmtstr_table[n].format; n++) {
int mp_format = af_fmtstr_table[n].format;
AudioStreamBasicDescription mp_asbd = {0};
ca_fill_asbd_raw(&mp_asbd, mp_format, 0, asbd->mChannelsPerFrame);
if (ca_asbd_equals(&mp_asbd, asbd))
return mp_format;
}
return 0;
}
void ca_print_asbd(struct ao *ao, const char *description,
const AudioStreamBasicDescription *asbd)
{
uint32_t flags = asbd->mFormatFlags;
char *format = fourcc_repr(asbd->mFormatID);
int mpfmt = ca_asbd_to_mp_format(asbd);
char *format = fourcc_repr(NULL, asbd->mFormatID);
MP_VERBOSE(ao,
"%s %7.1fHz %" PRIu32 "bit %s "
"[%" PRIu32 "][%" PRIu32 "bpp][%" PRIu32 "fbp]"
"[%" PRIu32 "bpf][%" PRIu32 "ch] "
"%s %s %s%s%s%s (%s)\n",
"%s %7.1fHz %" PRIu32 "bit [%s]"
"[%" PRIu32 "][%" PRIu32 "][%" PRIu32 "]"
"[%" PRIu32 "][%" PRIu32 "] "
"%s %s %s%s%s%s\n",
description, asbd->mSampleRate, asbd->mBitsPerChannel, format,
asbd->mFormatFlags, asbd->mBytesPerPacket, asbd->mFramesPerPacket,
asbd->mBytesPerFrame, asbd->mChannelsPerFrame,
@@ -257,63 +209,8 @@ void ca_print_asbd(struct ao *ao, const char *description,
(flags & kAudioFormatFlagIsSignedInteger) ? "S" : "U",
(flags & kAudioFormatFlagIsPacked) ? " packed" : "",
(flags & kAudioFormatFlagIsAlignedHigh) ? " aligned" : "",
(flags & kAudioFormatFlagIsNonInterleaved) ? " P" : "",
mpfmt ? af_fmt_to_str(mpfmt) : "-");
(flags & kAudioFormatFlagIsNonInterleaved) ? " P" : "");
talloc_free(format);
}
// Return whether new is an improvement over old. Assume a higher value means
// better quality, and we always prefer the value closest to the requested one,
// which is still larger than the requested one.
// Equal values prefer the new one (so ca_asbd_is_better() checks other params).
static bool value_is_better(double req, double old, double new)
{
if (new >= req) {
return old < req || new <= old;
} else {
return old < req && new >= old;
}
}
// Return whether new is an improvement over old (req is the requested format).
bool ca_asbd_is_better(AudioStreamBasicDescription *req,
AudioStreamBasicDescription *old,
AudioStreamBasicDescription *new)
{
if (new->mChannelsPerFrame > MP_NUM_CHANNELS)
return false;
if (old->mChannelsPerFrame > MP_NUM_CHANNELS)
return true;
if (req->mFormatID != new->mFormatID)
return false;
if (req->mFormatID != old->mFormatID)
return true;
if (!value_is_better(req->mBitsPerChannel, old->mBitsPerChannel,
new->mBitsPerChannel))
return false;
if (!value_is_better(req->mSampleRate, old->mSampleRate, new->mSampleRate))
return false;
if (!value_is_better(req->mChannelsPerFrame, old->mChannelsPerFrame,
new->mChannelsPerFrame))
return false;
return true;
}
int64_t ca_frames_to_us(struct ao *ao, uint32_t frames)
{
return frames / (float) ao->samplerate * 1e6;
}
int64_t ca_get_latency(const AudioTimeStamp *ts)
{
uint64_t out = AudioConvertHostTimeToNanos(ts->mHostTime);
uint64_t now = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime());
if (now > out)
return 0;
return (out - now) * 1e-3;
}
+1 -12
View File
@@ -31,9 +31,7 @@
CFStringRef cfstr_from_cstr(char *str);
char *cfstr_get_cstr(CFStringRef cfstr);
char *fourcc_repr_buf(char *buf, size_t buf_size, uint32_t code);
#define fourcc_repr(code) fourcc_repr_buf((char[40]){0}, 40, code)
char *fourcc_repr(void *talloc_ctx, uint32_t code);
bool check_ca_st(struct ao *ao, int level, OSStatus code, const char *message);
#define CHECK_CA_ERROR_L(label, message) \
@@ -57,14 +55,5 @@ OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device);
void ca_fill_asbd(struct ao *ao, AudioStreamBasicDescription *asbd);
void ca_print_asbd(struct ao *ao, const char *description,
const AudioStreamBasicDescription *asbd);
bool ca_asbd_equals(const AudioStreamBasicDescription *a,
const AudioStreamBasicDescription *b);
int ca_asbd_to_mp_format(const AudioStreamBasicDescription *asbd);
bool ca_asbd_is_better(AudioStreamBasicDescription *req,
AudioStreamBasicDescription *old,
AudioStreamBasicDescription *new);
int64_t ca_frames_to_us(struct ao *ao, uint32_t frames);
int64_t ca_get_latency(const AudioTimeStamp *ts);
#endif /* MPV_COREAUDIO_UTILS_H */
+5 -4
View File
@@ -3,20 +3,21 @@
*
* Copyright (c) 2004 Gabor Szecsi <deje@miki.hu>
*
* 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.
*/
/**
+5 -4
View File
@@ -6,20 +6,21 @@
*
* Copyleft 2013 by William Light <wrl@illest.net> for the mpv project
*
* 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/>.
* 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>
Loaded 100 of 424 files, more files were not shown because too many files have changed in this diff. Show more