Compare commits

...
73 Commits
Author SHA1 Message Date
Alessandro Ghedini 1783e8cade Release 0.7.2 2014-12-20 12:00:13 +01:00
wm4 c7d6b21789 options: enable --ytdl by default
Let's see who complains...
2014-12-19 19:23:28 +01:00
ChrisK2 8d4e6498c3 ytdl: bump requrired youtube-dl version to 2014.11.26 2014-12-19 19:23:22 +01:00
ChrisK2 9984f4fffd ytdl: Try to handle multi-arc videos
this currently uses a sketchy but apparently working workaround,
which will be removed once the neccessary changes in youtube-dl
are implemented

Fixes #1277
2014-12-19 19:23:15 +01:00
ChrisK2 75a62c7a64 ytdl: When using DASH, print actual duration
prints the actual duration as reported by youtube-dl to the
terminal when available
2014-12-19 19:23:11 +01:00
wm4 73eaadf6c3 vo_opengl: clamp filters to their size
This gives better results with fancy-downscaling. The issue here is that
fancy-downscalign "extends" the filter radius by some amount, which
requires using a larger filter size and shader. Then most of the filter
is "unused", but some filters still return non-0 coefficients, which
create heavy artifacts. Just clamp them off.

I'm not sure if this is the right solution, but at least it's better
than before.
2014-12-19 19:23:07 +01:00
Stefano Pigozzi 292f6f1904 cocoa: don't change app activation policy in libmpv
/cc @mpv-player/stable
2014-12-17 20:15:38 +01:00
Stefano Pigozzi 5a2947c9d0 cocoa: remove urlencoding for url open events
This fixes using the mpv:// custom protocol on Yosemite were apparently
we receive an url which is automatically urlencoded by the system.

/cc mpv-player/stable
2014-12-17 20:15:07 +01:00
Stefano Pigozzi fdea35a71b ao_coreaudio: add missing goto for error path 2014-12-17 20:13:23 +01:00
wm4 8f6eb196cd build: require alsa libs not older than 6 years
Some IEC958 flags we use have been introduced in 2008, which makes
compilation fail on older systems.
2014-12-17 20:12:44 +01:00
wm4 3b6e063599 vo_x11: don't attempt to resize when unconfigured
Fixes #1347.

The previous commit actually fixes the crash.
2014-12-17 20:12:06 +01:00
wm4 015218f8c8 vo_x11: check allocation errors
Avoids a crash if allocation fails.
2014-12-17 20:11:41 +01:00
wm4 00d1d6d807 build: add checks for some compiler warning flags 2014-12-17 20:11:30 +01:00
wm4 49c3cbfb4e vd_lavc: fix error handling path
The ctx->pic check must uninitialize the decoder.
2014-12-17 20:11:12 +01:00
wm4 925becfb15 mp_image: check for malloc failure
Or rather, the only reason av_buffer_create() can fail is a malloc
failure.
2014-12-17 20:11:03 +01:00
wm4 2cebc52065 stream_cdda: don't return number of tracks as number of titles
Apparently, we treat different tracks as titles, so returning the number
of titles (which is user-visible as "disc-titles" property) is
completely misguided.
2014-12-17 20:10:54 +01:00
wm4 34e504bf93 Check some mallocs
Fixes #1337.
2014-12-17 20:09:24 +01:00
James Ross-Gowan f0649ce841 pipe-win32: possible fix for Windows XP deadlock
This fixes a hang with the VirtualBox OpenGL drivers. It might help
with #1325 as well.
2014-12-17 20:09:05 +01:00
wm4 65af6a55b7 manpage: fix mistake in --video-zoom mention
Fixes #1331.
2014-12-17 20:08:48 +01:00
wm4 1326d3f0b8 command: fix crash with some forms of script_binding
"script_binding name ..." just crashed it. Oops.
2014-12-17 20:08:15 +01:00
wm4 b062b54626 vo_opengl: fix linkage type
Can happen on Windows, I suppose.
2014-12-17 20:06:05 +01:00
wm4 9bee56cc67 vo_opengl: don't crash if framebuffers are not available
In theory, vo_opengl supports operation without framebuffers. But this
has been broken for a while now (commit cc00b3ff is a contender). It
crashed because it unconditionally called gl->BindFramebuffer() (which
is NULL if framebuffers are missing).

Since this function is actually only called to set the default
framebuffer, the simplest way to deal with this is to provide a dummy
function, insteas of uglifying the code with additional if branches.
2014-12-17 20:05:46 +01:00
James Ross-Gowan 9fb0180eb2 w32_common: fix GUID linking in Cygwin 2014-12-17 20:05:07 +01:00
wm4 4f8af1a518 player: restore ab-loop settings with playback resume
Fixes #1324.
2014-12-17 20:05:01 +01:00
wm4 62b6048468 build: fix --disable-libass
Still supported, but obviously untested.

You shouldn't use this option anyway.
2014-12-17 20:04:02 +01:00
ChrisK2 b6363c8100 DOCS: Improve documentation of --ytdl-format option
As suggested in #1321
2014-12-08 00:06:41 +01:00
wm4 db4cec8a6c sub: remove assertion
This should clearly be impossible, but it seems to happen with ordered
chapters for a user.

Since I can't tell what the actual bug is and it seems impossible to
know the details without downloading possibly huge files, this is
probably the best we can do.

Should at least partially fix #1319.
2014-12-08 00:06:17 +01:00
reimar 4de6f4f616 af_hrtf: Fix out-of-range read.
Based on patch by Yuriy Kaminskiy [yumkam gmail].

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@37330 b3059339-0415-0410-9bf9-f77b7e298cf2
Signed-off-by: wm4 <wm4@nowhere>
2014-12-08 00:04:42 +01:00
wm4 7c53bb4bb1 demux_mkv: reject 0 TimecodeScale
Also reject anything over INT_MAX; no particular reason for this upper
bound.

Fixes #1317.
2014-12-08 00:04:27 +01:00
Stefano Pigozzi 115709e3c1 cocoa: save screenshots to desktop when using app bundle
Fixes #947
2014-12-08 00:03:39 +01:00
Stefano Pigozzi 1e8dbf8212 cocoa: don't create Dock icon for audio only files
fixes #635
2014-12-08 00:03:34 +01:00
wm4 1bfaab13ca ao_alsa: hackfix mono playback
ALSA returns "FL" as channel layout when trying to play mono. mpv and
libavresample don't like this; in particular, using libavresample to
convert stereo to "FL" fails.
2014-12-08 00:02:45 +01:00
wm4 083235d91f osc, dvd, bd: fix mouse state when changing menu modes
The flags weren't correctly set, and the mouse cursor remained visible
after leaving menu mode.

This was apparently broken in 0.7.0 too.

Fixes #1316.
2014-12-08 00:02:24 +01:00
wm4 bc4e115b30 discnav: remove redundant call
This was made the default a while ago.
2014-12-08 00:02:16 +01:00
Stefano Pigozzi 807763c85e coreaudio: don't output too many channel descriptions
for #1279 and #1249
2014-12-07 23:59:33 +01:00
Stefano Pigozzi 69fa6c4b73 coreaudio: add missing \n in log line 2014-12-07 23:59:23 +01:00
Stefano Pigozzi 3141381c2e coreaudio: don't print layout a second time
For #1279
2014-12-07 23:59:16 +01:00
Stefano Pigozzi 8f847437a9 cocoa: don't async redraw when waiting for VO redraw
This fixes the very annoying glitch where the black bars disappear for
a single frame when going fullscreen.
2014-12-07 23:59:02 +01:00
wm4 487fcea6f4 ao_alsa: try to fallback to "default" device if device is busy
ALSA is crap. It's impossible to make multichannel playback just do the
right thing. dmix (the default on most distros) can do stereo only, and
will refuse to play multichannel. On the other hand, if you try like mpv
(and mplayer) to open a multichannel device (like "surround51" etc.),
this will actually open a hardware device, which will either fail if
dmix is active, or block out dmix if opening succeeds.

This commit falls back to "default" (i.e. dmix) if opening a
multichannel device fails, which is a tiny step towards the right
behavior. (Although fixing it fully is impossible.)
2014-12-07 23:57:34 +01:00
wm4 63a31db0a3 input: add a hack to fix keyboard navigation with dvd/bd menu
If the user has LEFT/RIGHT/etc. bound in his input.conf, then these were
overriding the menu keys in dvdnav mode.

This hack works because the dvdnav crap happens to be the only user of
MP_INPUT_ON_TOP. If it finds a default key binding in the dvdnav menu
section, it will use that, instead of continuing search and possibly
finding the user key bindings meant for normal playback.
2014-12-07 23:56:25 +01:00
Stefano Pigozzi 575edecccb coreaudio: reject descriptions with too many channels
This is a fix attempt for #1279 and #1249.
2014-12-07 23:55:28 +01:00
Stefano Pigozzi 14adda8f6b coreaudio: fix more layout prints 2014-12-07 23:55:08 +01:00
Stefano Pigozzi 7cacff6d61 coreaudio: fix prints of uint32_t in log_layout 2014-12-07 23:54:22 +01:00
wm4 4ced125239 dvd, bd, osc: disable OSC while a menu is active
They interfere.

It turns out that commit b6ca4a48 actually broke this in weird ways, but
this solution is better anyway.
2014-12-07 23:54:12 +01:00
wm4 ac94c81134 input, lua: make removing key bindings work
This just kept adding bindings to the input section, rather than
defining it. One bad effect was that mp.remove_key_binding() in Lua
didn't work.
2014-12-07 23:52:33 +01:00
wm4 9501050ddc osc: always force mouse_move binding
So the OSC will still appear when using --no-input-default-bindings. It
also means it may override a user's mouse_move binding, but I guess
users who don't want the OSC should just use the --no-osc option.
2014-12-07 23:50:41 +01:00
wm4 c688880f9e lua: fix broken error message
luaL_error() doesn't support %.*s, because it uses Lua's own format
string mechanism that just looks like the C one. Just drop this part.
2014-12-07 23:50:13 +01:00
wm4 47ec404a52 player: don't signal an error if --stream-dump is used
The player thinks an error happened because no audio or video was played
after finishing the file, but this obviously makes no sense with stream
dumping. (error_playing follows the client API convention that negative
values are errors.)
2014-12-07 23:49:55 +01:00
Alessandro Ghedini 18b15a436f Release 0.7.1 2014-12-02 18:24:30 +01:00
Stefano Pigozzi 6583ad6970 cocoa: fix opening reference URLs (.file/id=)
Fixes #1202

/cc @mpv-player/stable
2014-12-01 21:38:51 +01:00
Niklas Haas 863701391c vo_opengl: Linearize non-RGB sRGB files correctly (eg. JPEG)
Signed-off-by: wm4 <wm4@nowhere>
2014-12-01 21:07:26 +01:00
Niklas Haas 3803c14279 vo_opengl: Reword comment in shader
I didn't quite understand this comment after looking at the code again
months later, so I reworded it for better clarity.
2014-12-01 21:07:12 +01:00
wm4 39126c3828 vo_opengl: make operator precedence explicit
More readable.
2014-12-01 21:07:06 +01:00
Stefano Pigozzi b9cfc3622c ao_coreaudio: initialize fetched properties to zeros
Should hopefully fix #1249 and #1279
2014-12-01 21:06:07 +01:00
wm4 1b0bf6507e options: fix channel map options sometimes failing
Channel amp otpions were not copied correctly: it copied the size of a
pointer to struct chmap, not the struct itself. Since mp_chmap is
currently 9 bytes, this meant the last channel entry was not copied
correctly on 64 bit systems, leading to very strange failures. It could
be triggered especially when using the client API, because the client
API always copies options on access (mpv command line options tend to
work directly on options).
2014-12-01 21:06:00 +01:00
wm4 7ca6aa4ad0 options: fix swapped deprecated/replacement in warning
This was relevant for --af and --vo (both use this option type, and have
deprecated aliases).
2014-12-01 21:05:56 +01:00
wm4 b82a98722a player: simplify and fix ordered chapter EOF handling
Ordered chapter EOF was handled as special-case of ending the last
segment. This broke --kee-open, because it set AT_END_OF_FILE in an
"inconvenient" place (after checking for --keep-open, and before the
code that exits playback if EOF is reached).

We don't actually need to handle the last segment specially. Instead, we
remain in the same segment if it ends. The normal playback logic will
recognize EOF, because the end of the segment "cuts off" the file.

Now timeline_set_from_time() never "fails", and we can remove the old
segment EOF handling code in mp_seek().
2014-12-01 21:05:53 +01:00
wm4 3d6d7012ff command: sub_add with "auto" should not always select a subtitle track
Running "sub_add file.srt auto" during hook execution automatically
selected the first added track. This happened because all tracks added
with sub_add are marked as "external", and external subtitles are always
selected by default.

Fix this by negating the "external" flag when autoselecting subtitles
during loading. The no_default flag exists for this purpose; it was
probably added for libquvi originally, where we had the same issue.
2014-12-01 21:05:49 +01:00
wm4 3051ff9f25 mixer: don't show softvol neutral marker on OSD if not using softvol
Also fix the comment on the softvol field.
2014-12-01 21:05:45 +01:00
wm4 9bf66294f8 vo_opengl: fix srgb with certain inputs
Sampling from the source texture and scaling must always be done
separately in this mode.

Fix suggested by haasn.

Still looks a bit wrong, though.
2014-12-01 21:05:20 +01:00
wm4 577378b827 vo_opengl: something
Insert explanation here.

Fixes #1023.
2014-12-01 21:05:15 +01:00
wm4 1679222e18 audio: fix one of the previous commits
Fixes commit 52c51149. It broke multichannel (or possibly everything)
for ao_alsa, ao_oss, ao_sndio.
2014-12-01 18:31:49 +01:00
wm4 74270cd1db audio: allow more than 20 channel map entries
This could trigger an assertion when using ao_alsa or ao_coreaudio. The
code was simply assuming the number of channel maps was bounded
statically (which was true at first in both AOs).

Fix by using dynamic memory allocation. It needs to be explicitly
enabled by the AOs by setting a temp context, because otherwise the
memory couldn't be freed. (Or at least this seems to be the most elegant
solution.)

Fixes #1306.
2014-12-01 15:41:26 +01:00
wm4 718bf3b39e vd_lavc: don't crash if codec could not be opened
Fixes #1307.
2014-12-01 15:41:17 +01:00
wm4 5ecb381d78 demux_playlist: don't ignore last line in m3u
If EOF is reached after reading a line, the EOF flag is set. This was a
problem for the m3u code, which checked for EOF _after_ reading a line,
which will discard the last line read.

Also fix a typo in an unrelated part of the file.
2014-12-01 15:40:57 +01:00
wm4 17f1332955 win32: add screen offset when handling overlarge windows
MS Windows doesn't allow windows larger than the screen, so we include
a hack to make the window smaller. This hack recenters the window (what
else would it do?).

It didn't account for the virtual offset of the current screen, and it
was reported that it forces the window to the first screen.

Should fix #1292.
2014-12-01 15:38:28 +01:00
Stefano Pigozzi f4a1dfdffb build: fix typos
thanks to @Nikoli
2014-11-28 15:51:43 +01:00
James Ross-Gowan d3972125a1 subprocess-win: remove a Vista-only flag
PIPE_REJECT_REMOTE_CLIENTS isn't supported on XP. It's not really
needed, so remove it. Also fix error checking for CreateNamedPipe.
2014-11-28 15:51:39 +01:00
wm4 71f504a43d demux_mkv: fix a possible out of bounds access
The if branch has a weak check to test whether the codec_id is the short
ID, and handles the long IDs in the else branch. The long IDs are all
longer than 12 bytes long, so hardcoding the string offset to get the
trailing part of the name makes sense. But the if condition checks for
another thing, which could get the else branch run even if the codec_id
is short.

Fix the bogus control flow and check if the codec_id is long enough. One
of these checks could be considered redundant, but include them both for
defensive coding.
2014-11-28 15:51:32 +01:00
wm4 bc1370041d audio: alternative fix for previous commit
This is a somewhat obscure situation, and happens only if audio starts
again after it has ended (in particular can happens with files where
audio starts later). It doesn't matter much whether audio starts
immediately or some milliseconds later, so simplify it.
2014-11-28 15:51:03 +01:00
wm4 4f74869cd8 audio: fix busy loop when seeking while paused
When playing paused, the amount of decoded audio is limited to a small
amount (1 sample), because we don't write any audio to the AO when
paused. The small amount could trigger the case of the wanted audio
being too far in the future in the PTS sync code, which set the audio
status to STATUS_DRAINING, which in turn triggered the EOF code in the
next iteration. This was ok, but unfortunately, this triggered another
retry in order to check resuming from EOF by setting the status to
STATUS_SYNCING, which in turn lead to the busy loop by alternating
between the 2 states. So don't try resyncing while paused.

Since the PTS syncing code also calls ao_reset(), this could cause the
pulseaudio daemon to consume some CPU time as well.

This was caused by commit 33b57f55. Before that, the playloop was merely
run more often, but didn't cause any problems.

Fixes #1288.
2014-11-28 15:50:58 +01:00
Alessandro Ghedini 8d8b36df1b manpage: lua: fix typo paramater -> parameter 2014-11-28 15:49:52 +01:00
Alessandro Ghedini 2da6c95208 Release 0.7.0 2014-11-25 20:18:53 +01:00
47 changed files with 476 additions and 163 deletions

No files matched your search

+1
View File
@@ -25,6 +25,7 @@ API changes
:: ::
--- mpv 0.7.0 is released ---
1.10 - deprecate/disable everything directly related to script_dispatch 1.10 - deprecate/disable everything directly related to script_dispatch
(most likely affects nobody) (most likely affects nobody)
1.9 - add enum mpv_end_file_reason for mpv_event_end_file.reason 1.9 - add enum mpv_end_file_reason for mpv_event_end_file.reason
+2 -2
View File
@@ -113,8 +113,8 @@ Miscellaneous
* Matroska edition switching at runtime. * Matroska edition switching at runtime.
* Support for playing URLs of popular streaming sites directly. * Support for playing URLs of popular streaming sites directly.
(e.g. ``mpv https://www.youtube.com/watch?v=...``). (e.g. ``mpv https://www.youtube.com/watch?v=...``).
Requires a recent version of ``youtube-dl`` to be installed, and Requires a recent version of ``youtube-dl`` to be installed. Can be
``ytdl=yes`` in the mpv config file. disabled with ``ytdl=no`` in the mpv config file.
* Support for precise scrolling which scales the parameter of commands. If the * Support for precise scrolling which scales the parameter of commands. If the
input doesn't support precise scrolling the scale factor stays 1. input doesn't support precise scrolling the scale factor stays 1.
* Allow changing/adjusting video filters at runtime. (This is also used to make * Allow changing/adjusting video filters at runtime. (This is also used to make
+1 -1
View File
@@ -573,7 +573,7 @@ strictly part of the guaranteed API.
Runs an external process and waits until it exits. Returns process status Runs an external process and waits until it exits. Returns process status
and the captured output. and the captured output.
The paramater ``t`` is a table. The function reads the following entries: The parameter ``t`` is a table. The function reads the following entries:
``args`` ``args``
Array of strings. The first array entry is the executable. This Array of strings. The first array entry is the executable. This
+6 -6
View File
@@ -426,20 +426,20 @@ Program Behavior
Enable the youtube-dl hook-script. It will look at the input URL, and will 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, play the video located on the website. This works with many streaming sites,
not just the one the scripts are named after. This requires a recent version not just the one the scripts are named after. This requires a recent version
of youtube-dl to be installed on the system. 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. If the script can't do anything with an URL, it will do nothing.
Currently disabled by default, because youtube-dl's generic extractor can
get stuck on some URL, preventing playback.
(Note: this is the replacement for the now removed libquvi support.) (Note: this is the replacement for the now removed libquvi support.)
``--ytdl-format=<best|worst|mp4|webm|...>`` ``--ytdl-format=<best|worst|mp4|webm|...>``
Video format/quality that is directly passed to youtube-dl. The possible Video format/quality that is directly passed to youtube-dl. The possible
values are specific to the website and the video, for a given url the values are specific to the website and the video, for a given url the
available formats can be found with the command available formats can be found with the command
``youtube-dl --list-formats URL``. ``youtube-dl --list-formats URL``. See youtube-dl's documentation for
available aliases. To use experimental DASH support for youtube, use
``bestvideo+bestaudio``.
(Default: ``best``)
Video Video
----- -----
@@ -577,7 +577,7 @@ Video
Disable scaling of the video. If the window is larger than the video, Disable scaling of the video. If the window is larger than the video,
black bars are added. Otherwise, the video is cropped. The video still black bars are added. Otherwise, the video is cropped. The video still
can be influenced by the other ``--video-...`` options. (If the can be influenced by the other ``--video-...`` options. (If the
``--video-zoom`` option is set to a value other than ``1``, scaling is ``--video-zoom`` option is set to a value other than ``0``, scaling is
enabled, but the video isn't automatically scaled to the window size.) enabled, but the video isn't automatically scaled to the window size.)
The video and monitor aspects aspect will be ignored. Aspect correction The video and monitor aspects aspect will be ignored. Aspect correction
+135
View File
@@ -0,0 +1,135 @@
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.
Release 0.7.1
=============
Changes
-------
- Don't show the volume neutral marker on the OSD if softvol is disabled.
- Don't select a subtitle track when executing the sub_add input command in
"auto" mode.
Bug fixes
---------
- Fix busy loop when seeking while paused (this fixes a problem with pulseaudio
that caused mpv and the pulseaudio daemon to use 100% CPU).
- Fix Lua function utils.subprocess() in Windows versions older than Vista.
- Avoid creating a window bigger than the screen on Windows.
- Don't ignore the last line in m3u playlists.
- Don't crash if a codec could not be opened.
- Dynamically allocate audio channel map entries (this should fix a crash in
the alsa and coreaudio AOs with audio devices that support more than 20
channel maps).
- Ignore the "srgb" option in the opengl VO if hardware decoding is enabled.
- Linearize non-RGB sRGB files correctly (eg. JPEG).
- Fix opening reference URLs (.file/id=) on OS X.
This listing is not complete. There are many more bug fixes and changes. The
complete change log can be viewed by running ``git log 8d8b36d..6583ad6`` in
the git repository.
Release 0.7.0
=============
Changes
-------
- Buffer partial log messages in the client API (the client API will now only
pass full log messages to clients).
- Remove ncurses/terminfo/termcap support (it was disabled by default and
replaced by new code since v0.6.0).
- Enable cdda:// support by default again (it was disabled since v0.6.0).
- Cascade-load input.conf (if there are several input.confs in the set of valid
config paths, load them all).
- Draw the OSD twice in 3D mode (this fixes subtitles display in 3D mode).
- Make wasapi the default AO on Windows again since many of its problems have
been solved.
- Use "site-functions" subdir to install the zsh completion script instead of
the Debian-specific "vendor-completions" (also provide the --zshdir waf
configure option for changing this value).
- Improve synchronization between the Cocoa GUI and the player (this fixes some
long standing deadlock issues on Mac OS X).
- Remove --fs-missioncontrol option (only relevant to Mac OS X).
New features
------------
- Enable pitch correction by default when playing at higher speeds (this can be
controlled with the --audio-pitch-correction option).
- Open stream and demuxer asynchronously (this should avoid having the player
get blocked on network streams).
- Add cache-buffering-state property for querying the cache fill status until
the player unpauses.
- Add support for listing and selecting the audio device (note that it is not
implemented for all AOs, see the --audio-device option for more information).
- Add support for a JSON-based IPC mechanism (note that this is not currently
supported on Windows, see the JSON IPC section in the manpage for more
information).
- Add Lua utility function for starting processes (see utils.subprocess() in the
manpage).
- Add Lua utility function for parsing JSON (see utils.parse_json() in the
manpage).
- Add field-dominance property (see --field-dominance option).
- Add video-rotate property (see --video-rotate option).
- Add playback-abort property for querying whether playback is stopped or is to
be stopped.
- Add cursor-autohide property (see --cursor-autohide option).
- Add vo-configured property for querying whether a window is created.
- Add support for dxva2 hardware acceleration on Windows.
- Drop libquvi support (this has been replaced by a built-in Lua script that
invokes the youtube-dl tool, which needs to be installed, see the --ytdl
option).
- Add support for loading chapters from an external file (see the
--chapters-file option).
- Add window-minimized property for querying whether the window is minimized
(works for X11 only).
- Make it possible to configure the OSC seekbar style (see the "seekbarstyle"
OSC option).
- Add support for libmpv on Mac OS X (it used to be broken, now it's fully
functional and also provides support for embedding the mpv window inside a
Cocoa/Qt application).
- Try to use the audio channel map reported by ALSA in the alsa AO.
- Add option to disable text OSD rendering completely (useful for working around
certain fontconfig issues, see the --use-text-osd option).
This listing is not complete. There are many more bug fixes and changes. The
complete change log can be viewed by running ``git log 7759c18..9479daa`` in
the git repository.
@@ -0,0 +1 @@
screenshot-template=~/Desktop/shot%n
+1
View File
@@ -0,0 +1 @@
0.7.2
+12 -5
View File
@@ -81,14 +81,21 @@ void mp_chmap_sel_add_alsa_def(struct mp_chmap_sel *s)
} }
} }
#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
// Add a channel map that should be allowed. // Add a channel map that should be allowed.
void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *map) void mp_chmap_sel_add_map(struct mp_chmap_sel *s, const struct mp_chmap *map)
{ {
assert(s->num_chmaps < ARRAY_LEN(s->chmaps)); if (!mp_chmap_is_valid(map))
if (mp_chmap_is_valid(map)) return;
s->chmaps[s->num_chmaps++] = *map; if (!s->chmaps)
s->chmaps = s->chmaps_storage;
if (s->num_chmaps == MP_ARRAY_SIZE(s->chmaps_storage)) {
if (!s->tmp)
return;
s->chmaps = talloc_memdup(s->tmp, s->chmaps, sizeof(s->chmaps_storage));
}
if (s->chmaps != s->chmaps_storage)
MP_TARRAY_GROW(s->tmp, s->chmaps, s->num_chmaps);
s->chmaps[s->num_chmaps++] = *map;
} }
// Allow all waveext formats in default order. // Allow all waveext formats in default order.
+5 -1
View File
@@ -26,8 +26,12 @@ struct mp_chmap_sel {
// should be considered opaque // should be considered opaque
bool allow_any, allow_waveext; bool allow_any, allow_waveext;
bool speakers[MP_SPEAKER_ID_COUNT]; bool speakers[MP_SPEAKER_ID_COUNT];
struct mp_chmap chmaps[20]; struct mp_chmap *chmaps;
int num_chmaps; int num_chmaps;
struct mp_chmap chmaps_storage[20];
void *tmp; // set to any talloc context to allow more chmaps entries
}; };
void mp_chmap_sel_add_any(struct mp_chmap_sel *s); void mp_chmap_sel_add_any(struct mp_chmap_sel *s);
+7 -2
View File
@@ -280,8 +280,13 @@ static inline void update_ch(af_hrtf_t *s, short *in, const int k)
} }
/* We need to update the bass compensation delay line, too. */ /* We need to update the bass compensation delay line, too. */
s->ba_l[k] = in[0] + in[4] + in[2]; // TODO: should this use lf/cf/rf etc. instead?
s->ba_r[k] = in[4] + in[1] + in[3]; s->ba_l[k] = in[0];
s->ba_r[k] = in[1];
if (s->decode_mode == HRTF_MIX_51) {
s->ba_l[k] += in[4] + in[2];
s->ba_r[k] += in[4] + in[3];
}
} }
static void clear_coeff(af_hrtf_t *s, float *c) static void clear_coeff(af_hrtf_t *s, float *c)
+2 -2
View File
@@ -36,7 +36,7 @@ struct mixer {
struct ao *ao; struct ao *ao;
struct af_stream *af; struct af_stream *af;
// Static, dependent on ao/softvol settings // Static, dependent on ao/softvol settings
bool softvol; // use AO (true) or af_volume (false) bool softvol; // use AO (false) or af_volume (true)
bool ao_softvol; // AO has private or per-app volume bool ao_softvol; // AO has private or per-app volume
bool emulate_mute; // if true, emulate mute with volume=0 bool emulate_mute; // if true, emulate mute with volume=0
// Last known values (possibly out of sync with reality) // Last known values (possibly out of sync with reality)
@@ -72,7 +72,7 @@ bool mixer_audio_initialized(struct mixer *mixer)
float mixer_getneutralvolume(struct mixer *mixer) float mixer_getneutralvolume(struct mixer *mixer)
{ {
// gain == 1 // gain == 1
return 1.0 / mixer->opts->softvol_max * 100.0 * 100.0; return mixer->softvol ? 1.0 / mixer->opts->softvol_max * 100.0 * 100.0 : 100;
} }
static void checkvolume(struct mixer *mixer) static void checkvolume(struct mixer *mixer)
+10 -2
View File
@@ -279,7 +279,7 @@ static int find_alsa_channel(int mp_channel)
static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap) static bool query_chmaps(struct ao *ao, struct mp_chmap *chmap)
{ {
struct priv *p = ao->priv; struct priv *p = ao->priv;
struct mp_chmap_sel chmap_sel = {0}; struct mp_chmap_sel chmap_sel = {.tmp = p};
snd_pcm_chmap_query_t **maps = snd_pcm_query_chmaps(p->alsa); snd_pcm_chmap_query_t **maps = snd_pcm_query_chmaps(p->alsa);
if (!maps) if (!maps)
@@ -461,17 +461,22 @@ static int init(struct ao *ao)
if (strcmp(device, "default") != 0) if (strcmp(device, "default") != 0)
device = talloc_asprintf(ao, "plug:%s", device); device = talloc_asprintf(ao, "plug:%s", device);
} }
const char *old_dev = device;
if (ao->device) if (ao->device)
device = ao->device; device = ao->device;
if (p->cfg_device && p->cfg_device[0]) if (p->cfg_device && p->cfg_device[0])
device = p->cfg_device; device = p->cfg_device;
bool user_set_device = device != old_dev; // not strcmp()
MP_VERBOSE(ao, "using device: %s\n", device); MP_VERBOSE(ao, "using device: %s\n", device);
MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version()); MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
err = try_open_device(ao, device, p->cfg_block ? 0 : SND_PCM_NONBLOCK); err = try_open_device(ao, device, p->cfg_block ? 0 : SND_PCM_NONBLOCK);
if (err < 0) { if (err < 0) {
if (err != -EBUSY && !p->cfg_block) { if (err == -EBUSY && !user_set_device && strcmp(device, "default") != 0) {
MP_WARN(ao, "Device '%s' busy, retrying default.\n", device);
err = try_open_device(ao, "default", 0);
} else if (err != -EBUSY && !p->cfg_block) {
MP_WARN(ao, "Open in nonblock-mode " MP_WARN(ao, "Open in nonblock-mode "
"failed, trying to open in block-mode.\n"); "failed, trying to open in block-mode.\n");
err = try_open_device(ao, device, 0); err = try_open_device(ao, device, 0);
@@ -630,6 +635,9 @@ static int init(struct ao *ao)
MP_WARN(ao, "Got unknown channel map from ALSA.\n"); MP_WARN(ao, "Got unknown channel map from ALSA.\n");
} }
if (ao->channels.num == 1)
ao->channels.speaker[0] = MP_SP(FC);
free(alsa_chmap); free(alsa_chmap);
} }
#endif #endif
+27 -13
View File
@@ -185,7 +185,7 @@ static bool init_chmap(struct ao *ao)
&layouts, &n_layouts); &layouts, &n_layouts);
CHECK_CA_ERROR("could not get audio device prefered layouts"); CHECK_CA_ERROR("could not get audio device prefered layouts");
struct mp_chmap_sel chmap_sel = {0}; struct mp_chmap_sel chmap_sel = {.tmp = p};
for (int i = 0; i < n_layouts; i++) { for (int i = 0; i < n_layouts; i++) {
struct mp_chmap chmap = {0}; struct mp_chmap chmap = {0};
if (ca_layout_to_mp_chmap(ao, &layouts[i], &chmap)) if (ca_layout_to_mp_chmap(ao, &layouts[i], &chmap))
@@ -354,22 +354,28 @@ static void ca_log_layout(struct ao *ao, AudioChannelLayout *layout)
AudioChannelDescription *descs = layout->mChannelDescriptions; AudioChannelDescription *descs = layout->mChannelDescriptions;
MP_VERBOSE(ao, "layout: tag: <%d>, bitmap: <%d>, " MP_VERBOSE(ao, "layout: tag: <%u>, bitmap: <%u>, "
"descriptions <%d>\n", "descriptions <%u>\n",
layout->mChannelLayoutTag, (unsigned) layout->mChannelLayoutTag,
layout->mChannelBitmap, (unsigned) layout->mChannelBitmap,
layout->mNumberChannelDescriptions); (unsigned) layout->mNumberChannelDescriptions);
for (int i = 0; i < layout->mNumberChannelDescriptions; i++) { for (int i = 0; i < layout->mNumberChannelDescriptions; i++) {
AudioChannelDescription d = descs[i]; AudioChannelDescription d = descs[i];
MP_VERBOSE(ao, " - description %d: label <%d, %d>, flags: <%u>, " MP_VERBOSE(ao, " - description %d: label <%u, %u>, "
"coords: <%f, %f, %f>\n", i, " flags: <%u>, coords: <%f, %f, %f>\n", i,
d.mChannelLabel, (unsigned) d.mChannelLabel,
ca_label_to_mp_speaker_id(d.mChannelLabel), (unsigned) ca_label_to_mp_speaker_id(d.mChannelLabel),
d.mChannelFlags, (unsigned) d.mChannelFlags,
d.mCoordinates[0], d.mCoordinates[0],
d.mCoordinates[1], d.mCoordinates[1],
d.mCoordinates[2]); d.mCoordinates[2]);
if (i >= 32) {
MP_VERBOSE(ao, " detected more than 32 channel descriptions, "
"skipping output");
break;
}
} }
} }
@@ -410,14 +416,22 @@ bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
// to the waveextensible definition: this is the kind of // to the waveextensible definition: this is the kind of
// descriptions we process here. // descriptions we process here.
if (layout->mNumberChannelDescriptions > MP_NUM_CHANNELS) {
MP_VERBOSE(ao, "layout has too many descriptions (%u, max: %d)\n",
(unsigned) layout->mNumberChannelDescriptions,
MP_NUM_CHANNELS);
return false;
}
for (int n = 0; n < layout->mNumberChannelDescriptions; n++) { for (int n = 0; n < layout->mNumberChannelDescriptions; n++) {
AudioChannelLabel label = layout->mChannelDescriptions[n].mChannelLabel; AudioChannelLabel label = layout->mChannelDescriptions[n].mChannelLabel;
uint8_t speaker = ca_label_to_mp_speaker_id(label); uint8_t speaker = ca_label_to_mp_speaker_id(label);
if (label == kAudioChannelLabel_Unknown) if (label == kAudioChannelLabel_Unknown)
continue; continue;
if (speaker < 0) { if (speaker < 0) {
MP_VERBOSE(ao, "channel label=%d unusable to build channel " MP_VERBOSE(ao, "channel label=%u unusable to build channel "
"bitmap, skipping layout\n", label); "bitmap, skipping layout\n", (unsigned) label);
goto coreaudio_error;
} else { } else {
chmap->speaker[n] = speaker; chmap->speaker[n] = speaker;
chmap->num = n + 1; chmap->num = n + 1;
+2 -2
View File
@@ -62,7 +62,7 @@ OSStatus ca_get_ary(AudioObjectID id, ca_scope scope, ca_sel selector,
err = AudioObjectGetPropertyDataSize(id, &p_addr, 0, NULL, &p_size); err = AudioObjectGetPropertyDataSize(id, &p_addr, 0, NULL, &p_size);
CHECK_CA_ERROR_SILENT_L(coreaudio_error); CHECK_CA_ERROR_SILENT_L(coreaudio_error);
*data = talloc_size(NULL, p_size); *data = talloc_zero_size(NULL, p_size);
*elements = p_size / element_size; *elements = p_size / element_size;
err = ca_get(id, scope, selector, p_size, *data); err = ca_get(id, scope, selector, p_size, *data);
@@ -87,7 +87,7 @@ OSStatus ca_get_str(AudioObjectID id, ca_scope scope, ca_sel selector,
CFStringGetMaximumSizeForEncoding( CFStringGetMaximumSizeForEncoding(
CFStringGetLength(string), CA_CFSTR_ENCODING) + 1; CFStringGetLength(string), CA_CFSTR_ENCODING) + 1;
*data = talloc_size(NULL, size); *data = talloc_zero_size(NULL, size);
CFStringGetCString(string, *data, size, CA_CFSTR_ENCODING); CFStringGetCString(string, *data, size, CA_CFSTR_ENCODING);
CFRelease(string); CFRelease(string);
coreaudio_error: coreaudio_error:
+4
View File
@@ -286,6 +286,8 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
.buf_size = 0, .buf_size = 0,
.buf = av_mallocz(PROBE_BUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE), .buf = av_mallocz(PROBE_BUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE),
}; };
if (!avpd.buf)
return -1;
bool final_probe = false; bool final_probe = false;
do { do {
@@ -679,6 +681,8 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
return -1; return -1;
avfc = avformat_alloc_context(); avfc = avformat_alloc_context();
if (!avfc)
return -1;
if (lavfdopts->cryptokey) if (lavfdopts->cryptokey)
parse_cryptokey(avfc, lavfdopts->cryptokey); parse_cryptokey(avfc, lavfdopts->cryptokey);
+12 -6
View File
@@ -345,6 +345,10 @@ static int demux_mkv_read_info(demuxer_t *demuxer)
if (info.n_timecode_scale) { if (info.n_timecode_scale) {
mkv_d->tc_scale = info.timecode_scale; mkv_d->tc_scale = info.timecode_scale;
MP_VERBOSE(demuxer, "| + timecode scale: %" PRIu64 "\n", mkv_d->tc_scale); MP_VERBOSE(demuxer, "| + timecode scale: %" PRIu64 "\n", mkv_d->tc_scale);
if (mkv_d->tc_scale < 1 || mkv_d->tc_scale > INT_MAX) {
res = -1;
goto out;
}
} }
if (info.n_duration) { if (info.n_duration) {
mkv_d->duration = info.duration * mkv_d->tc_scale / 1e9; mkv_d->duration = info.duration * mkv_d->tc_scale / 1e9;
@@ -1414,20 +1418,22 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
sh_a->bitrate = 16000 * 8; sh_a->bitrate = 16000 * 8;
sh_a->block_align = 1024; sh_a->block_align = 1024;
if (!strcmp(track->codec_id, MKV_A_AAC) && track->private_data) { if (!strcmp(track->codec_id, MKV_A_AAC)) {
if (!extradata_len) { if (track->private_data && !extradata_len) {
extradata = track->private_data; extradata = track->private_data;
extradata_len = track->private_size; extradata_len = track->private_size;
} }
} else { } else {
/* Recreate the 'private data' */ /* Recreate the 'private data' */
/* which faad2 uses in its initialization */
srate_idx = aac_get_sample_rate_index(track->a_sfreq); srate_idx = aac_get_sample_rate_index(track->a_sfreq);
if (!strncmp(&track->codec_id[12], "MAIN", 4)) const char *tail = "";
if (strlen(track->codec_id) >= 12)
tail = &track->codec_id[12];
if (!strncmp(tail, "MAIN", 4))
profile = 0; profile = 0;
else if (!strncmp(&track->codec_id[12], "LC", 2)) else if (!strncmp(tail, "LC", 2))
profile = 1; profile = 1;
else if (!strncmp(&track->codec_id[12], "SSR", 3)) else if (!strncmp(tail, "SSR", 3))
profile = 2; profile = 2;
else else
profile = 3; profile = 3;
+2 -2
View File
@@ -86,7 +86,7 @@ static int parse_m3u(struct pl_parser *p)
return -1; return -1;
if (p->probing) if (p->probing)
return 0; return 0;
while (!pl_eof(p)) { while (line.len || !pl_eof(p)) {
if (line.len > 0 && !bstr_startswith0(line, "#")) if (line.len > 0 && !bstr_startswith0(line, "#"))
pl_add(p, line); pl_add(p, line);
line = bstr_strip(pl_get_line(p)); line = bstr_strip(pl_get_line(p));
@@ -110,7 +110,7 @@ static int parse_ref_init(struct pl_parser *p)
"application/vnd.ms.wms-hdr.asfv1", NULL}; "application/vnd.ms.wms-hdr.asfv1", NULL};
bstr burl = bstr0(p->s->url); bstr burl = bstr0(p->s->url);
if (bstr_eatstart0(&burl, "http://") && check_mimetype(p->s, mmsh_types)) { if (bstr_eatstart0(&burl, "http://") && check_mimetype(p->s, mmsh_types)) {
MP_INFO(p, "Redirectiong to mmsh://\n"); MP_INFO(p, "Redirecting to mmsh://\n");
playlist_add_file(p->pl, talloc_asprintf(p, "mmsh://%.*s", BSTR_P(burl))); playlist_add_file(p->pl, talloc_asprintf(p, "mmsh://%.*s", BSTR_P(burl)));
return 0; return 0;
} }
+6 -3
View File
@@ -445,6 +445,8 @@ static struct cmd_bind *find_any_bind_for_key(struct input_ctx *ictx,
} }
if (s->flags & MP_INPUT_EXCLUSIVE) if (s->flags & MP_INPUT_EXCLUSIVE)
break; break;
if (best_bind && (s->flags & MP_INPUT_ON_TOP))
break;
} }
return best_bind; return best_bind;
@@ -1019,14 +1021,15 @@ void mp_input_define_section(struct input_ctx *ictx, char *name, char *location,
if (!name || !name[0]) if (!name || !name[0])
return; // parse_config() changes semantics with restrict_section==empty return; // parse_config() changes semantics with restrict_section==empty
input_lock(ictx); input_lock(ictx);
// Delete:
struct cmd_bind_section *bs = get_bind_section(ictx, bstr0(name));
remove_binds(bs, builtin);
if (contents) { if (contents) {
// Redefine:
parse_config(ictx, builtin, bstr0(contents), location, name); parse_config(ictx, builtin, bstr0(contents), location, name);
} else { } else {
// Disable: // Disable:
mp_input_disable_section(ictx, name); mp_input_disable_section(ictx, name);
// Delete:
struct cmd_bind_section *bs = get_bind_section(ictx, bstr0(name));
remove_binds(bs, builtin);
} }
input_unlock(ictx); input_unlock(ictx);
} }
+10
View File
@@ -45,6 +45,16 @@ static void read_pipe_thread(struct mp_input_src *src, void *param)
goto done; goto done;
} }
// If we're reading from stdin, unset it. All I/O on synchronous handles is
// serialized, so stupid DLLs that call GetFileType on stdin can hang the
// process if they do it while we're reading from it. At least, the
// VirtualBox OpenGL ICD is affected by this, but only on Windows XP.
// GetFileType works differently in later versions of Windows. See:
// https://support.microsoft.com/kb/2009703
// http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx
if ((void*)_get_osfhandle(fd) == GetStdHandle(STD_INPUT_HANDLE))
SetStdHandle(STD_INPUT_HANDLE, NULL);
waio = waio_alloc((void *)_get_osfhandle(fd), 0, NULL, NULL); waio = waio_alloc((void *)_get_osfhandle(fd), 0, NULL, NULL);
if (!waio) { if (!waio) {
MP_ERR(src, "Can't initialize win32 file reader.\n"); MP_ERR(src, "Can't initialize win32 file reader.\n");
+2 -2
View File
@@ -2146,7 +2146,7 @@ static int parse_chmap(struct mp_log *log, const m_option_t *opt,
const m_option_type_t m_option_type_chmap = { const m_option_type_t m_option_type_chmap = {
.name = "Audio channels or channel map", .name = "Audio channels or channel map",
.size = sizeof(struct mp_chmap *), .size = sizeof(struct mp_chmap),
.parse = parse_chmap, .parse = parse_chmap,
.copy = copy_opt, .copy = copy_opt,
}; };
@@ -2620,7 +2620,7 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt,
if (m_obj_list_find(&desc, list, str)) { if (m_obj_list_find(&desc, list, str)) {
if (desc.replaced_name) if (desc.replaced_name)
mp_warn(log, "Driver '%s' has been replaced with '%s'!\n", mp_warn(log, "Driver '%s' has been replaced with '%s'!\n",
desc.name, desc.replaced_name); desc.replaced_name, desc.name);
} else { } else {
if (!list->allow_unknown_entries) { if (!list->allow_unknown_entries) {
mp_err(log, "Option %.*s: %.*s doesn't exist.\n", mp_err(log, "Option %.*s: %.*s doesn't exist.\n",
+1 -1
View File
@@ -614,7 +614,7 @@ const struct MPOpts mp_default_opts = {
.use_text_osd = 1, .use_text_osd = 1,
#if HAVE_LUA #if HAVE_LUA
.lua_load_osc = 1, .lua_load_osc = 1,
.lua_load_ytdl = 0, .lua_load_ytdl = 1,
.lua_ytdl_format = NULL, .lua_ytdl_format = NULL,
#endif #endif
.auto_load_scripts = 1, .auto_load_scripts = 1,
+6 -17
View File
@@ -233,6 +233,8 @@ Application *mpv_shared_app(void)
options:NSAnchoredSearch options:NSAnchoredSearch
range:NSMakeRange(0, [MPV_PROTOCOL length])]; range:NSMakeRange(0, [MPV_PROTOCOL length])];
url = [url stringByRemovingPercentEncoding];
self.files = @[url]; self.files = @[url];
if (self.willStopOnOpenEvent) { if (self.willStopOnOpenEvent) {
@@ -329,7 +331,10 @@ void init_cocoa_application(void)
NSApp = mpv_shared_app(); NSApp = mpv_shared_app();
[NSApp setDelegate:NSApp]; [NSApp setDelegate:NSApp];
[NSApp initialize_menu]; [NSApp initialize_menu];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
// Will be set to Regular from cocoa_common during UI creation so that we
// don't create an icon when playing audio only files.
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
atexit_b(^{ atexit_b(^{
// Because activation policy has just been set to behave like a real // Because activation policy has just been set to behave like a real
@@ -439,21 +444,6 @@ static bool bundle_started_from_finder(int argc, char **argv)
} }
} }
static const char macosx_icon[] =
#include "osdep/macosx_icon.inc"
;
static void set_application_icon(NSApplication *app)
{
NSData *icon_data = [NSData dataWithBytesNoCopy:(void *)macosx_icon
length:sizeof(macosx_icon)
freeWhenDone:NO];
NSImage *icon = [[NSImage alloc] initWithData:icon_data];
[app setApplicationIconImage:icon];
[icon release];
[icon_data release];
}
void macosx_finder_args_preinit(int *argc, char ***argv) void macosx_finder_args_preinit(int *argc, char ***argv)
{ {
Application *app = mpv_shared_app(); Application *app = mpv_shared_app();
@@ -475,7 +465,6 @@ void macosx_finder_args_preinit(int *argc, char ***argv)
*argc = cocoa_argc; *argc = cocoa_argc;
*argv = cocoa_argv; *argv = cocoa_argv;
} else { } else {
set_application_icon(app);
for (int i = 0; i < *argc; i++ ) { for (int i = 0; i < *argc; i++ ) {
NSString *arg = [NSString stringWithUTF8String:(*argv)[i]]; NSString *arg = [NSString stringWithUTF8String:(*argv)[i]];
[app.argumentsList addObject:arg]; [app.argumentsList addObject:arg];
+4 -2
View File
@@ -440,8 +440,10 @@ void cocoa_set_input_context(struct input_ctx *input_context)
size_t num_files = [files count]; size_t num_files = [files count];
char **files_utf8 = talloc_array(NULL, char*, num_files); char **files_utf8 = talloc_array(NULL, char*, num_files);
[files enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *_){ [files enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *_){
char *filename = (char *)[obj UTF8String]; NSURL *url = [NSURL URLWithString:obj];
size_t bytes = [obj lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; NSString *path = [url path];
char *filename = (char *)[path UTF8String];
size_t bytes = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
files_utf8[i] = talloc_memdup(files_utf8, filename, bytes + 1); files_utf8[i] = talloc_memdup(files_utf8, filename, bytes + 1);
}]; }];
mp_event_drop_files(_inputContext, num_files, files_utf8); mp_event_drop_files(_inputContext, num_files, files_utf8);
+2 -3
View File
@@ -111,9 +111,8 @@ static int create_overlapped_pipe(HANDLE *read, HANDLE *write)
// overlapped pipes, so instead, use a named pipe with a unique name // overlapped pipes, so instead, use a named pipe with a unique name
*read = CreateNamedPipeW(buf, PIPE_ACCESS_INBOUND | *read = CreateNamedPipeW(buf, PIPE_ACCESS_INBOUND |
FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED, FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 0, 4096, 0, NULL);
1, 0, 4096, 0, NULL); if (*read == INVALID_HANDLE_VALUE)
if (!*read)
goto error; goto error;
// Open the write end of the pipe as a synchronous handle // Open the write end of the pipe as a synchronous handle
-1
View File
@@ -515,7 +515,6 @@ static void do_fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
// later. Retrying is needed to get the correct sync PTS. // later. Retrying is needed to get the correct sync PTS.
if (mpctx->audio_status >= STATUS_DRAINING && status == AD_OK) { if (mpctx->audio_status >= STATUS_DRAINING && status == AD_OK) {
mpctx->audio_status = STATUS_SYNCING; mpctx->audio_status = STATUS_SYNCING;
mpctx->sleeptime = 0;
return; // retry on next iteration return; // retry on next iteration
} }
+4 -2
View File
@@ -4350,7 +4350,9 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
struct track *sub = mp_add_subtitles(mpctx, cmd->args[0].v.s); struct track *sub = mp_add_subtitles(mpctx, cmd->args[0].v.s);
if (!sub) if (!sub)
return -1; return -1;
if (cmd->args[1].v.i != 1) { if (cmd->args[1].v.i == 1) {
sub->no_default = true;
} else {
mp_switch_track(mpctx, sub->type, sub); mp_switch_track(mpctx, sub->type, sub);
mp_mark_user_track_selection(mpctx, 0, sub->type); mp_mark_user_track_selection(mpctx, 0, sub->type);
} }
@@ -4492,7 +4494,7 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
char *sep = strchr(name, '/'); char *sep = strchr(name, '/');
char *target = NULL; char *target = NULL;
char space[MAX_CLIENT_NAME]; char space[MAX_CLIENT_NAME];
if (name) { if (sep) {
snprintf(space, sizeof(space), "%.*s", (int)(sep - name), name); snprintf(space, sizeof(space), "%.*s", (int)(sep - name), name);
target = space; target = space;
name = sep + 1; name = sep + 1;
+2
View File
@@ -243,6 +243,8 @@ static const char *const backup_properties[] = {
"options/ass-use-margins", "options/ass-use-margins",
"options/ass-vsfilter-aspect-compat", "options/ass-vsfilter-aspect-compat",
"options/ass-style-override", "options/ass-style-override",
"options/ab-loop-a",
"options/ab-loop-b",
0 0
}; };
+2 -3
View File
@@ -125,9 +125,8 @@ void mp_nav_init(struct MPContext *mpctx)
MP_VERBOSE(mpctx->nav_state, "enabling\n"); MP_VERBOSE(mpctx->nav_state, "enabling\n");
mp_input_enable_section(mpctx->input, "discnav", 0); mp_input_enable_section(mpctx->input, "discnav",
mp_input_set_section_mouse_area(mpctx->input, "discnav-menu", MP_INPUT_ALLOW_VO_DRAGGING | MP_INPUT_ALLOW_HIDE_CURSOR);
INT_MIN, INT_MIN, INT_MAX, INT_MAX);
update_state(mpctx); update_state(mpctx);
} }
+9 -5
View File
@@ -300,14 +300,17 @@ double timeline_set_from_time(struct MPContext *mpctx, double pts, bool *need_re
{ {
if (pts < 0) if (pts < 0)
pts = 0; pts = 0;
int new = mpctx->num_timeline_parts - 1;
for (int i = 0; i < mpctx->num_timeline_parts; i++) { for (int i = 0; i < mpctx->num_timeline_parts; i++) {
struct timeline_part *p = mpctx->timeline + i; if (pts < mpctx->timeline[i + 1].start) {
if (pts < (p + 1)->start) { new = i;
*need_reset = timeline_set_part(mpctx, i, false); break;
return pts - p->start + p->source_start;
} }
} }
return MP_NOPTS_VALUE;
*need_reset = timeline_set_part(mpctx, new, false);
return pts - mpctx->timeline[new].start + mpctx->timeline[new].source_start;
} }
static int find_new_tid(struct MPContext *mpctx, enum stream_type t) static int find_new_tid(struct MPContext *mpctx, enum stream_type t)
@@ -964,6 +967,7 @@ static void play_current_file(struct MPContext *mpctx)
if (opts->stream_dump && opts->stream_dump[0]) { if (opts->stream_dump && opts->stream_dump[0]) {
stream_dump(mpctx); stream_dump(mpctx);
mpctx->error_playing = 1;
goto terminate_playback; goto terminate_playback;
} }
+1 -1
View File
@@ -1043,7 +1043,7 @@ static int script_input_enable_section(lua_State *L)
} else if (bstr_equals0(val, "exclusive")) { } else if (bstr_equals0(val, "exclusive")) {
flags |= MP_INPUT_EXCLUSIVE; flags |= MP_INPUT_EXCLUSIVE;
} else { } else {
luaL_error(L, "invalid flag: '%.*s'", BSTR_P(val)); luaL_error(L, "invalid flag");
} }
} }
mp_input_enable_section(mpctx->input, section, flags); mp_input_enable_section(mpctx->input, section, flags);
+16 -3
View File
@@ -1853,9 +1853,13 @@ function tick()
end end
end end
function do_enable_keybindings()
mp.enable_key_bindings("showhide", "allow-vo-dragging|allow-hide-cursor")
end
function enable_osc(enable) function enable_osc(enable)
if enable then if enable then
mp.enable_key_bindings("showhide") do_enable_keybindings()
show_osc() show_osc()
else else
hide_osc() hide_osc()
@@ -1876,12 +1880,21 @@ mp.observe_property("fullscreen", "bool", function(name, val) state.fullscreen =
mp.observe_property("pause", "bool", pause_state) mp.observe_property("pause", "bool", pause_state)
mp.observe_property("cache-idle", "bool", cache_state) mp.observe_property("cache-idle", "bool", cache_state)
mp.observe_property("disc-menu-active", "bool", function(name, val)
if val == true then
hide_osc()
mp.disable_key_bindings("showhide")
else
do_enable_keybindings()
end
end)
-- mouse show/hide bindings -- mouse show/hide bindings
mp.set_key_bindings({ mp.set_key_bindings({
{"mouse_move", function(e) process_event("mouse_move", nil) end}, {"mouse_move", function(e) process_event("mouse_move", nil) end},
{"mouse_leave", mouse_leave}, {"mouse_leave", mouse_leave},
}, "showhide") }, "showhide", "force")
mp.enable_key_bindings("showhide", "allow-vo-dragging|allow-hide-cursor") do_enable_keybindings()
--mouse input bindings --mouse input bindings
mp.set_key_bindings({ mp.set_key_bindings({
+42 -15
View File
@@ -3,7 +3,7 @@ local msg = require 'mp.msg'
local ytdl = { local ytdl = {
path = "youtube-dl", path = "youtube-dl",
minver = "2014.11.09", minver = "2014.11.26",
vercheck = nil, vercheck = nil,
} }
@@ -97,30 +97,57 @@ mp.add_hook("on_load", 10, function ()
elseif not (json["_type"] == nil) and (json["_type"] == "playlist") then elseif not (json["_type"] == nil) and (json["_type"] == "playlist") then
-- a playlist -- a playlist
local playlist = "#EXTM3U\n" -- some funky guessing to detect multi-arc videos
for i, entry in pairs(json.entries) do if not (json.entries[1]["webpage_url"] == nil)
local site = entry.url and (json.entries[1]["webpage_url"] == json["webpage_url"]) then
msg.verbose("multi-arc video detected, building EDL")
-- some extractors will still return the full info for
-- all clips in the playlist and the URL will point local playlist = "edl://"
-- directly to the file in that case, which we don't for i, entry in pairs(json.entries) do
-- want so get the webpage URL instead, which is what
-- we want playlist = playlist .. entry.url .. ";"
if not (entry["webpage_url"] == nil) then
site = entry["webpage_url"]
end end
playlist = playlist .. "ytdl://" .. site .. "\n" msg.debug("EDL: " .. playlist)
end
mp.set_property("stream-open-filename", "memory://" .. playlist)
mp.set_property("stream-open-filename", playlist)
if not (json.title == nil) then
mp.set_property("file-local-options/media-title", json.title)
end
else
local playlist = "#EXTM3U\n"
for i, entry in pairs(json.entries) do
local site = entry.url
-- some extractors will still return the full info for
-- all clips in the playlist and the URL will point
-- directly to the file in that case, which we don't
-- want so get the webpage URL instead, which is what
-- we want
if not (entry["webpage_url"] == nil) then
site = entry["webpage_url"]
end
playlist = playlist .. "ytdl://" .. site .. "\n"
end
mp.set_property("stream-open-filename", "memory://" .. playlist)
end
else -- probably a video else -- probably a video
local streamurl = "" local streamurl = ""
-- DASH? -- DASH?
if not (json["requested_formats"] == nil) then if not (json["requested_formats"] == nil) then
msg.info("NOTE: Using DASH, expect inaccurate duration.") msg.info("Using DASH, expect inaccurate duration.")
if not (json.duration == nil) then
msg.info("actual duration: " .. mp.format_time(json.duration))
end
-- video url -- video url
streamurl = json["requested_formats"][1].url streamurl = json["requested_formats"][1].url
+3 -12
View File
@@ -214,16 +214,6 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
bool need_reset = false; bool need_reset = false;
demuxer_amount = timeline_set_from_time(mpctx, seek.amount, demuxer_amount = timeline_set_from_time(mpctx, seek.amount,
&need_reset); &need_reset);
if (demuxer_amount == MP_NOPTS_VALUE) {
assert(!need_reset);
mpctx->stop_play = AT_END_OF_FILE;
// When seeking outside of the file, but not when ending last segment.
if (!timeline_fallthrough) {
clear_audio_output_buffers(mpctx);
reset_playback_state(mpctx);
}
return -1;
}
if (need_reset) { if (need_reset) {
reinit_video_chain(mpctx); reinit_video_chain(mpctx);
reinit_audio_chain(mpctx); reinit_audio_chain(mpctx);
@@ -961,10 +951,11 @@ void run_playloop(struct MPContext *mpctx)
mpctx->audio_status == STATUS_EOF && mpctx->audio_status == STATUS_EOF &&
mpctx->video_status == STATUS_EOF) mpctx->video_status == STATUS_EOF)
{ {
if (end_is_new_segment) { int new_part = mpctx->timeline_part + 1;
if (end_is_new_segment && new_part < mpctx->num_timeline_parts) {
mp_seek(mpctx, (struct seek_params){ mp_seek(mpctx, (struct seek_params){
.type = MPSEEK_ABSOLUTE, .type = MPSEEK_ABSOLUTE,
.amount = mpctx->timeline[mpctx->timeline_part+1].start .amount = mpctx->timeline[new_part].start
}, true); }, true);
} else } else
mpctx->stop_play = AT_END_OF_FILE; mpctx->stop_play = AT_END_OF_FILE;
+3 -4
View File
@@ -127,8 +127,8 @@ void uninit_sub_renderer(struct MPContext *mpctx)
static void init_sub_renderer(struct MPContext *mpctx) {} static void init_sub_renderer(struct MPContext *mpctx) {}
void uninit_sub_renderer(struct MPContext *mpctx) {} void uninit_sub_renderer(struct MPContext *mpctx) {}
void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts, void mp_ass_configure_fonts(struct ass_renderer *a, struct MPOpts *b,
struct mp_osd_res *dim) {} struct mpv_global *c, struct mp_log *d) {}
#endif #endif
@@ -227,10 +227,9 @@ static void update_subtitle(struct MPContext *mpctx, int order)
struct track *track = mpctx->current_track[order][STREAM_SUB]; struct track *track = mpctx->current_track[order][STREAM_SUB];
struct dec_sub *dec_sub = mpctx->d_sub[order]; struct dec_sub *dec_sub = mpctx->d_sub[order];
if (!track) if (!track || !dec_sub)
return; return;
assert(dec_sub);
int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB; int obj = order ? OSDTYPE_SUB2 : OSDTYPE_SUB;
if (mpctx->d_video) { if (mpctx->d_video) {
-5
View File
@@ -243,11 +243,6 @@ static int control(stream_t *stream, int cmd, void *arg)
{ {
cdda_priv *p = stream->priv; cdda_priv *p = stream->priv;
switch (cmd) { switch (cmd) {
case STREAM_CTRL_GET_NUM_TITLES:
{
*(unsigned int *)arg = p->cd->tracks;
return STREAM_OK;
}
case STREAM_CTRL_GET_NUM_CHAPTERS: case STREAM_CTRL_GET_NUM_CHAPTERS:
{ {
int start_track = get_track_by_sector(p, p->start_sector); int start_track = get_track_by_sector(p, p->start_sector);
+7
View File
@@ -67,6 +67,13 @@ enum mp_csp_prim {
MP_CSP_PRIM_COUNT MP_CSP_PRIM_COUNT
}; };
enum mp_csp_trc {
MP_CSP_TRC_NONE,
MP_CSP_TRC_BT_2020_APPROX,
MP_CSP_TRC_BT_2020_EXACT,
MP_CSP_TRC_SRGB
};
// Any enum mp_csp_prim value is a valid index (except MP_CSP_PRIM_COUNT) // Any enum mp_csp_prim value is a valid index (except MP_CSP_PRIM_COUNT)
extern const char *const mp_csp_prim_names[MP_CSP_PRIM_COUNT]; extern const char *const mp_csp_prim_names[MP_CSP_PRIM_COUNT];
+15 -10
View File
@@ -353,6 +353,8 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
ctx->hwdec_fmt = 0; ctx->hwdec_fmt = 0;
ctx->avctx = avcodec_alloc_context3(lavc_codec); ctx->avctx = avcodec_alloc_context3(lavc_codec);
AVCodecContext *avctx = ctx->avctx; AVCodecContext *avctx = ctx->avctx;
if (!ctx->avctx)
goto error;
avctx->bit_rate = 0; avctx->bit_rate = 0;
avctx->opaque = vd; avctx->opaque = vd;
avctx->codec_type = AVMEDIA_TYPE_VIDEO; avctx->codec_type = AVMEDIA_TYPE_VIDEO;
@@ -360,15 +362,15 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
avctx->refcounted_frames = 1; avctx->refcounted_frames = 1;
ctx->pic = av_frame_alloc(); ctx->pic = av_frame_alloc();
if (!ctx->pic)
goto error;
if (ctx->hwdec) { if (ctx->hwdec) {
avctx->thread_count = 1; avctx->thread_count = 1;
avctx->get_format = get_format_hwdec; avctx->get_format = get_format_hwdec;
avctx->get_buffer2 = get_buffer2_hwdec; avctx->get_buffer2 = get_buffer2_hwdec;
if (ctx->hwdec->init(ctx) < 0) { if (ctx->hwdec->init(ctx) < 0)
uninit_avctx(vd); goto error;
return;
}
} else { } else {
mp_set_avcodec_threads(avctx, lavc_param->threads); mp_set_avcodec_threads(avctx, lavc_param->threads);
} }
@@ -418,11 +420,14 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
mp_copy_lav_codec_headers(avctx, sh->lav_headers); mp_copy_lav_codec_headers(avctx, sh->lav_headers);
/* open it */ /* open it */
if (avcodec_open2(avctx, lavc_codec, NULL) < 0) { if (avcodec_open2(avctx, lavc_codec, NULL) < 0)
MP_ERR(vd, "Could not open codec.\n"); goto error;
uninit_avctx(vd);
return; return;
}
error:
MP_ERR(vd, "Could not open codec.\n");
uninit_avctx(vd);
} }
static void uninit_avctx(struct dec_video *vd) static void uninit_avctx(struct dec_video *vd)
@@ -430,7 +435,7 @@ static void uninit_avctx(struct dec_video *vd)
vd_ffmpeg_ctx *ctx = vd->priv; vd_ffmpeg_ctx *ctx = vd->priv;
AVCodecContext *avctx = ctx->avctx; AVCodecContext *avctx = ctx->avctx;
if (avctx) if (avctx && avctx->codec)
avcodec_flush_buffers(avctx); avcodec_flush_buffers(avctx);
if (ctx->hwdec && ctx->hwdec->uninit) if (ctx->hwdec && ctx->hwdec->uninit)
+2
View File
@@ -734,6 +734,8 @@ struct AVFrame *mp_image_to_av_frame_and_unref(struct mp_image *img)
void *ptr = new_ref->planes[n]; void *ptr = new_ref->planes[n];
size_t size = new_ref->stride[n] * new_ref->h; size_t size = new_ref->stride[n] * new_ref->h;
frame->buf[n] = av_buffer_create(ptr, size, free_img, dummy_ref, flags); frame->buf[n] = av_buffer_create(ptr, size, free_img, dummy_ref, flags);
if (!frame->buf[n])
abort();
} }
talloc_free(new_ref); talloc_free(new_ref);
return frame; return frame;
+26 -2
View File
@@ -144,6 +144,22 @@ static void disable_power_management(struct vo *vo)
&s->power_mgmt_assertion); &s->power_mgmt_assertion);
} }
static const char macosx_icon[] =
#include "osdep/macosx_icon.inc"
;
static void set_application_icon(NSApplication *app)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSData *icon_data = [NSData dataWithBytesNoCopy:(void *)macosx_icon
length:sizeof(macosx_icon)
freeWhenDone:NO];
NSImage *icon = [[NSImage alloc] initWithData:icon_data];
[app setApplicationIconImage:icon];
[icon release];
[pool release];
}
int vo_cocoa_init(struct vo *vo) int vo_cocoa_init(struct vo *vo)
{ {
struct vo_cocoa_state *s = talloc_zero(vo, struct vo_cocoa_state); struct vo_cocoa_state *s = talloc_zero(vo, struct vo_cocoa_state);
@@ -195,7 +211,10 @@ void vo_cocoa_uninit(struct vo *vo)
[s->gl_ctx release]; [s->gl_ctx release];
[s->view removeFromSuperview]; [s->view removeFromSuperview];
[s->view release]; [s->view release];
if (s->window) [s->window release]; if (s->window) {
[s->window release];
[NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];
}
}); });
} }
@@ -453,6 +472,9 @@ int vo_cocoa_config_window(struct vo *vo, uint32_t flags, void *gl_ctx)
// reconfiguration code. // reconfiguration code.
s->pending_events |= VO_EVENT_RESIZE; s->pending_events |= VO_EVENT_RESIZE;
}); });
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
set_application_icon(NSApp);
return 0; return 0;
} }
@@ -731,7 +753,9 @@ void *vo_cocoa_cgl_pixel_format(struct vo *vo)
@synthesize vout = _video_output; @synthesize vout = _video_output;
- (void)performAsyncResize:(NSSize)size { - (void)performAsyncResize:(NSSize)size {
vo_cocoa_resize_redraw(self.vout, size.width, size.height); struct vo_cocoa_state *s = self.vout->cocoa;
if (!s->waiting_frame)
vo_cocoa_resize_redraw(self.vout, size.width, size.height);
} }
- (BOOL)keyboardEnabled { - (BOOL)keyboardEnabled {
+2 -1
View File
@@ -91,7 +91,8 @@ void mp_compute_weights(struct filter_kernel *filter, double f, float *out_w)
double sum = 0; double sum = 0;
for (int n = 0; n < filter->size; n++) { for (int n = 0; n < filter->size; n++) {
double x = f - (n - filter->size / 2 + 1); double x = f - (n - filter->size / 2 + 1);
double w = filter->weight(filter, fabs(x) / filter->inv_scale); double c = fabs(x) / filter->inv_scale;
double w = c <= filter->radius ? filter->weight(filter, c) : 0;
out_w[n] = w; out_w[n] = w;
sum += w; sum += w;
} }
+9
View File
@@ -141,6 +141,11 @@ static bool is_software_gl(GL *gl)
strcmp(renderer, "Mesa X11") == 0; strcmp(renderer, "Mesa X11") == 0;
} }
static void GLAPIENTRY dummy_glBindFramebuffer(GLenum target, GLuint framebuffer)
{
assert(framebuffer == 0);
}
#define FN_OFFS(name) offsetof(GL, name) #define FN_OFFS(name) offsetof(GL, name)
#define DEF_FN(name) {FN_OFFS(name), {"gl" # name}} #define DEF_FN(name) {FN_OFFS(name), {"gl" # name}}
@@ -618,6 +623,10 @@ void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *),
mp_verbose(log, "Detected OpenGL features:"); mp_verbose(log, "Detected OpenGL features:");
list_features(gl->mpgl_caps, log, MSGL_V, false); list_features(gl->mpgl_caps, log, MSGL_V, false);
// Provided for simpler handling if no framebuffer support is available.
if (!gl->BindFramebuffer)
gl->BindFramebuffer = &dummy_glBindFramebuffer;
} }
/** /**
+26 -7
View File
@@ -901,10 +901,25 @@ static void compile_shaders(struct gl_video *p)
bool use_conv_gamma = p->conv_gamma != 1.0; bool use_conv_gamma = p->conv_gamma != 1.0;
bool use_const_luma = p->image_params.colorspace == MP_CSP_BT_2020_C; bool use_const_luma = p->image_params.colorspace == MP_CSP_BT_2020_C;
enum mp_csp_trc gamma_fun = MP_CSP_TRC_NONE;
// Linear light scaling is only enabled when either color correction // Linear light scaling is only enabled when either color correction
// option (3dlut or srgb) is enabled, otherwise scaling is done in the // option (3dlut or srgb) is enabled, otherwise scaling is done in the
// source space. We also need to linearize for constant luminance systems. // source space. We also need to linearize for constant luminance systems.
bool convert_to_linear_gamma = !p->is_linear_rgb && use_cms || use_const_luma; if ((!p->is_linear_rgb && use_cms) || use_const_luma) {
// We just use the color level range to distinguish between PC
// content like images, which are most likely sRGB, and TV content
// like movies, which are most likely BT.2020
if (p->image_params.colorlevels == MP_CSP_LEVELS_PC && !p->hwdec_active) {
// FIXME: I don't know if hwdec sets the color levels to PC or not,
// but let's avoid the bug just in case.
gamma_fun = MP_CSP_TRC_SRGB;
} else if (p->opts.approx_gamma) {
gamma_fun = MP_CSP_TRC_BT_2020_APPROX;
} else {
gamma_fun = MP_CSP_TRC_BT_2020_EXACT;
}
}
// Figure out the right color spaces we need to convert, if any // Figure out the right color spaces we need to convert, if any
enum mp_csp_prim prim_src = p->image_params.primaries, prim_dest; enum mp_csp_prim prim_src = p->image_params.primaries, prim_dest;
@@ -943,9 +958,11 @@ static void compile_shaders(struct gl_video *p)
char *header_osd = talloc_strdup(tmp, header); char *header_osd = talloc_strdup(tmp, header);
shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV_APPROX", shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV_APPROX",
use_cms && p->opts.approx_gamma); use_cms && gamma_fun == MP_CSP_TRC_BT_2020_APPROX);
shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV_BT2020", shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV_BT2020",
use_cms && !p->opts.approx_gamma); use_cms && gamma_fun == MP_CSP_TRC_BT_2020_EXACT);
shader_def_opt(&header_osd, "USE_OSD_LINEAR_CONV_SRGB",
use_cms && gamma_fun == MP_CSP_TRC_SRGB);
shader_def_opt(&header_osd, "USE_OSD_CMS_MATRIX", use_cms_matrix); shader_def_opt(&header_osd, "USE_OSD_CMS_MATRIX", use_cms_matrix);
shader_def_opt(&header_osd, "USE_OSD_3DLUT", p->use_lut_3d); shader_def_opt(&header_osd, "USE_OSD_3DLUT", p->use_lut_3d);
// 3DLUT overrides SRGB // 3DLUT overrides SRGB
@@ -980,9 +997,11 @@ static void compile_shaders(struct gl_video *p)
shader_def_opt(&header_conv, "USE_CONV_GAMMA", use_conv_gamma); shader_def_opt(&header_conv, "USE_CONV_GAMMA", use_conv_gamma);
shader_def_opt(&header_conv, "USE_CONST_LUMA", use_const_luma); shader_def_opt(&header_conv, "USE_CONST_LUMA", use_const_luma);
shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_APPROX", shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_APPROX",
convert_to_linear_gamma && p->opts.approx_gamma); gamma_fun == MP_CSP_TRC_BT_2020_APPROX);
shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_BT2020", shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_BT2020",
convert_to_linear_gamma && !p->opts.approx_gamma); gamma_fun == MP_CSP_TRC_BT_2020_EXACT);
shader_def_opt(&header_conv, "USE_LINEAR_LIGHT_SRGB",
gamma_fun == MP_CSP_TRC_SRGB);
if (p->opts.alpha_mode > 0 && p->has_alpha && p->plane_count > 3) if (p->opts.alpha_mode > 0 && p->has_alpha && p->plane_count > 3)
shader_def(&header_conv, "USE_ALPHA_PLANE", "3"); shader_def(&header_conv, "USE_ALPHA_PLANE", "3");
if (p->opts.alpha_mode == 2 && p->has_alpha) if (p->opts.alpha_mode == 2 && p->has_alpha)
@@ -1018,7 +1037,7 @@ static void compile_shaders(struct gl_video *p)
// Don't sample from input video textures before converting the input to // Don't sample from input video textures before converting the input to
// linear light. // linear light.
if (use_input_gamma || use_conv_gamma) if (use_input_gamma || use_conv_gamma || gamma_fun != MP_CSP_TRC_NONE)
use_indirect = true; use_indirect = true;
// It doesn't make sense to scale the chroma with cscale in the 1. scale // It doesn't make sense to scale the chroma with cscale in the 1. scale
@@ -1409,7 +1428,7 @@ static void init_video(struct gl_video *p, const struct mp_image_params *params)
p->image_dh = params->d_h; p->image_dh = params->d_h;
p->image_params = *params; p->image_params = *params;
if (p->is_rgb && (p->opts.srgb || p->use_lut_3d)) { if (p->is_rgb && (p->opts.srgb || p->use_lut_3d) && !p->hwdec_active) {
// If we're opening an RGB source like a png file or similar, // If we're opening an RGB source like a png file or similar,
// we just sample it using GL_SRGB which treats it as an sRGB source // we just sample it using GL_SRGB which treats it as an sRGB source
// and pretend it's linear as far as CMS is concerned // and pretend it's linear as far as CMS is concerned
+19 -2
View File
@@ -43,6 +43,12 @@
// Earlier GLSL doesn't support mix() with bvec // Earlier GLSL doesn't support mix() with bvec
#if __VERSION__ >= 130 #if __VERSION__ >= 130
vec3 srgb_expand(vec3 v)
{
return mix(v / 12.92, pow((v + vec3(0.055))/1.055, vec3(2.4)),
lessThanEqual(vec3(0.04045), v));
}
vec3 srgb_compand(vec3 v) vec3 srgb_compand(vec3 v)
{ {
return mix(v * 12.92, 1.055 * pow(v, vec3(1.0/2.4)) - 0.055, return mix(v * 12.92, 1.055 * pow(v, vec3(1.0/2.4)) - 0.055,
@@ -98,6 +104,9 @@ void main() {
#ifdef USE_OSD_LINEAR_CONV_BT2020 #ifdef USE_OSD_LINEAR_CONV_BT2020
color.rgb = bt2020_expand(color.rgb); color.rgb = bt2020_expand(color.rgb);
#endif #endif
#ifdef USE_OSD_LINEAR_CONV_SRGB
color.rgb = srgb_expand(color.rgb);
#endif
#ifdef USE_OSD_CMS_MATRIX #ifdef USE_OSD_CMS_MATRIX
// Convert to the right target gamut first (to BT.709 for sRGB, // Convert to the right target gamut first (to BT.709 for sRGB,
// and to BT.2020 for 3DLUT). Normal clamping here as perceptually // and to BT.2020 for 3DLUT). Normal clamping here as perceptually
@@ -419,8 +428,9 @@ void main() {
lessThanEqual(color.br, vec2(0))) + color.gg; lessThanEqual(color.br, vec2(0))) + color.gg;
#endif #endif
#ifdef USE_COLORMATRIX #ifdef USE_COLORMATRIX
// Clamp down here to avoid clipping CbCr details before CONST_LUMA // CONST_LUMA involves numbers outside the [0,1] range so we make sure
// has a chance to convert them. // to clip here, after the (possible) USE_CONST_LUMA calculations are done,
// instead of immediately after the colormatrix conversion.
color = clamp(color, 0, 1); color = clamp(color, 0, 1);
#endif #endif
// If we are scaling in linear light (SRGB or 3DLUT option enabled), we // If we are scaling in linear light (SRGB or 3DLUT option enabled), we
@@ -438,6 +448,13 @@ void main() {
// ... and actual BT.2020 (two-part function) // ... and actual BT.2020 (two-part function)
color = bt2020_expand(color); color = bt2020_expand(color);
#endif #endif
#ifdef USE_LINEAR_LIGHT_SRGB
// This is not needed for most sRGB content since we can use GL_SRGB to
// directly sample RGB texture in linear light, but for things which are
// also sRGB but in a different format (such as JPEG's YUV), we need
// to convert to linear light manually.
color = srgb_expand(color);
#endif
#ifdef USE_CONST_LUMA #ifdef USE_CONST_LUMA
// Calculate the green channel from the expanded RYcB // Calculate the green channel from the expanded RYcB
// The BT.2020 specification says Yc = 0.2627*R + 0.6780*G + 0.0593*B // The BT.2020 specification says Yc = 0.2627*R + 0.6780*G + 0.0593*B
+13 -5
View File
@@ -152,7 +152,7 @@ static int find_depth_from_visuals(struct vo *vo, Visual ** visual_return)
return bestvisual_depth; return bestvisual_depth;
} }
static void getMyXImage(struct priv *p, int foo) static bool getMyXImage(struct priv *p, int foo)
{ {
struct vo *vo = p->vo; struct vo *vo = p->vo;
#if HAVE_SHM && HAVE_XEXT #if HAVE_SHM && HAVE_XEXT
@@ -212,6 +212,10 @@ shmemerror:
p->myximage[foo] = p->myximage[foo] =
XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap, XCreateImage(vo->x11->display, p->vinfo.visual, p->depth, ZPixmap,
0, NULL, p->image_width, p->image_height, 8, 0); 0, NULL, p->image_width, p->image_height, 8, 0);
if (!p->myximage[foo]) {
MP_WARN(vo, "could not allocate image");
return false;
}
size_t sz = p->myximage[foo]->bytes_per_line * p->image_height + 32; size_t sz = p->myximage[foo]->bytes_per_line * p->image_height + 32;
p->ImageDataOrig[foo] = calloc(1, sz); p->ImageDataOrig[foo] = calloc(1, sz);
p->myximage[foo]->data = p->ImageDataOrig[foo] + 16 p->myximage[foo]->data = p->ImageDataOrig[foo] + 16
@@ -220,6 +224,7 @@ shmemerror:
#if HAVE_SHM && HAVE_XEXT #if HAVE_SHM && HAVE_XEXT
} }
#endif #endif
return true;
} }
static void freeMyXImage(struct priv *p, int foo) static void freeMyXImage(struct priv *p, int foo)
@@ -342,8 +347,10 @@ static bool resize(struct vo *vo)
p->image_height = p->dst_h; p->image_height = p->dst_h;
p->num_buffers = 2; p->num_buffers = 2;
for (int i = 0; i < p->num_buffers; i++) for (int i = 0; i < p->num_buffers; i++) {
getMyXImage(p, i); if (!getMyXImage(p, i))
return -1;
}
const struct fmt2Xfmtentry_s *fmte = fmt2Xfmt; const struct fmt2Xfmtentry_s *fmte = fmt2Xfmt;
while (fmte->mpfmt) { while (fmte->mpfmt) {
@@ -615,7 +622,8 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_GET_PANSCAN: case VOCTRL_GET_PANSCAN:
return VO_TRUE; return VO_TRUE;
case VOCTRL_SET_PANSCAN: case VOCTRL_SET_PANSCAN:
resize(vo); if (vo->config_ok)
resize(vo);
return VO_TRUE; return VO_TRUE;
case VOCTRL_REDRAW_FRAME: case VOCTRL_REDRAW_FRAME:
draw_image(vo, p->original_image); draw_image(vo, p->original_image);
@@ -629,7 +637,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
int events = 0; int events = 0;
int r = vo_x11_control(vo, &events, request, data); int r = vo_x11_control(vo, &events, request, data);
if (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE)) if (vo->config_ok && (events & (VO_EVENT_EXPOSE | VO_EVENT_RESIZE)))
resize(vo); resize(vo);
vo_event(vo, events); vo_event(vo, events);
return r; return r;
+3 -2
View File
@@ -22,6 +22,7 @@
#include <assert.h> #include <assert.h>
#include <windows.h> #include <windows.h>
#include <windowsx.h> #include <windowsx.h>
#include <initguid.h>
#include <ole2.h> #include <ole2.h>
#include "options/options.h" #include "options/options.h"
@@ -904,8 +905,8 @@ static int reinit_window_state(struct vo_w32_state *w32)
// Center the final window // Center the final window
n_w = r.right - r.left; n_w = r.right - r.left;
n_h = r.bottom - r.top; n_h = r.bottom - r.top;
r.left = screen_w / 2 - n_w / 2; r.left = w32->screenrc.x0 + screen_w / 2 - n_w / 2;
r.top = screen_h / 2 - n_h / 2; r.top = w32->screenrc.y0 + screen_h / 2 - n_h / 2;
r.right = r.left + n_w; r.right = r.left + n_w;
r.bottom = r.top + n_h; r.bottom = r.top + n_h;
} }
+8 -8
View File
@@ -31,14 +31,14 @@ def __add_generic_flags__(ctx):
def __add_gcc_flags__(ctx): def __add_gcc_flags__(ctx):
ctx.env.CFLAGS += ["-Wall", "-Wundef", "-Wmissing-prototypes", "-Wshadow", ctx.env.CFLAGS += ["-Wall", "-Wundef", "-Wmissing-prototypes", "-Wshadow",
"-Wno-switch", "-Wno-parentheses", "-Wpointer-arith", "-Wno-switch", "-Wno-parentheses", "-Wpointer-arith",
"-Wredundant-decls", "-Wno-pointer-sign", "-Wredundant-decls", "-Wno-pointer-sign"]
"-Werror=implicit-function-declaration", __test_and_add_flags__(ctx, ["-Werror=implicit-function-declaration",
"-Wno-error=deprecated-declarations", "-Wno-error=deprecated-declarations",
"-Wno-error=unused-function" ] "-Wno-error=unused-function",
__test_and_add_flags__(ctx, ["-Wempty-body"]) "-Wempty-body",
__test_and_add_flags__(ctx, ["-Wdisabled-optimization"]) "-Wdisabled-optimization",
__test_and_add_flags__(ctx, ["-Wstrict-prototypes"]) "-Wstrict-prototypes",
__test_and_add_flags__(ctx, ["-Wno-format-zero-length"]) "-Wno-format-zero-length"])
def __add_clang_flags__(ctx): def __add_clang_flags__(ctx):
ctx.env.CFLAGS += ["-Wno-logical-op-parentheses", "-fcolor-diagnostics", ctx.env.CFLAGS += ["-Wno-logical-op-parentheses", "-fcolor-diagnostics",
+3 -3
View File
@@ -539,7 +539,7 @@ audio_output_features = [
}, { }, {
'name': '--alsa', 'name': '--alsa',
'desc': 'ALSA audio output', 'desc': 'ALSA audio output',
'func': check_pkg_config('alsa'), 'func': check_pkg_config('alsa >= 1.0.18'),
}, { }, {
'name': '--coreaudio', 'name': '--coreaudio',
'desc': 'CoreAudio audio output', 'desc': 'CoreAudio audio output',
@@ -825,14 +825,14 @@ def options(opt):
opt.parse_features('build and install options', build_options) opt.parse_features('build and install options', build_options)
optional_features = main_dependencies + libav_dependencies optional_features = main_dependencies + libav_dependencies
opt.parse_features('optional feaures', optional_features) opt.parse_features('optional features', optional_features)
opt.parse_features('audio outputs', audio_output_features) opt.parse_features('audio outputs', audio_output_features)
opt.parse_features('video outputs', video_output_features) opt.parse_features('video outputs', video_output_features)
opt.parse_features('hwaccels', hwaccel_features) opt.parse_features('hwaccels', hwaccel_features)
opt.parse_features('tv features', radio_and_tv_features) opt.parse_features('tv features', radio_and_tv_features)
opt.parse_features('standalone app', standalone_features) opt.parse_features('standalone app', standalone_features)
group = opt.get_option_group("optional feaures") group = opt.get_option_group("optional features")
group.add_option('--lua', group.add_option('--lua',
type = 'string', type = 'string',
dest = 'LUA_VER', dest = 'LUA_VER',