Compare commits

...
97 Commits
Author SHA1 Message Date
wm4 844e8f2b51 Release 0.3.4 2014-01-31 19:11:48 +01:00
wm4 3f4ed8920f vo_wayland: silence shadowing warning
No real problem.
2014-01-31 19:10:15 +01:00
wm4 7ad2999b5f quvi: disable subtitle fetching by default
This is slow and unreliable, basically unusable.
2014-01-31 19:08:30 +01:00
Andre D 14fdbe07ac quvi: add option to not fetch subtitles
Signed-off-by: wm4 <wm4@nowhere>
2014-01-31 19:08:26 +01:00
wm4 61ed9a8747 demux_lavf: fix crash with empty files
This used to work; I'm not sure when or why it regressed. When setting
AVProbeData.filename to NULL, libavformat will crash in rtp_probe() by
unconditionally accessing the string.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

This reverts commit 96e75d234a.

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

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

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

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

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

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

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

No files matched your search

+1 -1
View File
@@ -147,7 +147,7 @@ Available filters are:
0 no matrix decoding (default)
==== ===================================
``equalizer=[g1:g2:g3:...:g10]``
``equalizer=g1:g2:g3:...:g10``
10 octave band graphic equalizer, implemented using 10 IIR band-pass
filters. This means that it works regardless of what type of audio is
being played back. The center frequencies for the 10 bands are:
+1 -1
View File
@@ -3,7 +3,7 @@ LUA SCRIPTING
mpv can load Lua scripts. These scripts can be used to control mpv in a similar
way to slave mode. mpv provides the builtin module ``mp`` (can be loaded
with ``require 'mpv'``), which provides functions to send commands to the
with ``require 'mp'``), which provides functions to send commands to the
mpv core and to retrieve information about playback state, user settings,
file information, and so on.
+23 -5
View File
@@ -1142,6 +1142,9 @@ OPTIONS
Allow hardware decoding for a given list of codecs only. The special value
``all`` always allows all codecs.
You can get the list of allowed codecs with ``mpv --vd=help``. Remove the
prefix, e.g. instead of ``lavc:h264`` use ``h264``.
By default this is set to ``h264,vc1,wmv3``.
This is usually only needed with broken GPUs, where a codec is reported
@@ -1369,8 +1372,7 @@ OPTIONS
:trace: very noisy debug messages
One special case is the ``identify`` module name. This is silenced by
default, and can be set to ``trace`` level to enable the remains of the
code once enabled with the ``-identify`` option.
default, and can be enabled with the ``-identify`` option.
``--msgmodule``
Prepend module name in front of each console message.
@@ -1609,6 +1611,9 @@ OPTIONS
controls how much of the image is cropped. May not work with all video
output drivers.
``--pause``
Start the player in paused state.
``--playing-msg=<string>``
Print out a string after starting playback. The string is expanded for
properties, e.g. ``--playing-msg='file: ${filename}'`` will print the string
@@ -1741,6 +1746,15 @@ OPTIONS
Also see ``--really-quiet`` and ``--msglevel``.
``--quvi-fetch-subtitles=<yes|no>``
Toggles fetching of subtitles from streaming sites with libquvi. Disabled
by default, because it's unreliable and slow. Note that when enabled,
subtitles will always be fetched, even if subtitles are explicitly
disabled with ``--no-sub`` (because you might want to enable subtitles
at runtime).
Supported when using libquvi 0.9.x.
``--quvi-format=<best|default|...>``
Video format/quality that is directly passed to libquvi (default: ``best``).
This is used when opening links to streaming sites like YouTube. The
@@ -2023,8 +2037,10 @@ OPTIONS
the top of the screen) alongside the normal subtitle, and provides a way
to render two subtitles at once.
there are some caveats associated with this feature. For example, secondary
subtitles are never shown on the terminal if video is disabled.
there are some caveats associated with this feature. For example, bitmap
subtitles will always be rendered in their usual position, so selecting a
bitmap subtitle as secondary subtitle will result in overlapping subtitles.
Secondary subtitles are never shown on the terminal if video is disabled.
.. note::
@@ -2362,7 +2378,7 @@ OPTIONS
Some ``--sws`` options are tunable. The description of the ``scale``
video filter has further information.
``--term-osd, --no-term-osd``
``--term-osd, --no-term-osd``, ``--term-osd=force``
Display OSD messages on the console when no video output is available.
Enabled by default.
@@ -2371,6 +2387,8 @@ OPTIONS
console. The escape sequence should move the pointer to the beginning of
the line used for the OSD and clear it (default: ``^[[A\r^[[K``).
``force`` enables terminal OSD even if a video window is created.
``--title=<string>``
Set the window title. Properties are expanded on playback start.
(See `Property Expansion`_.)
+2 -2
View File
@@ -429,7 +429,7 @@ Available filters are:
``'--vf=lavfi=yadif:o="threads=2,thread_type=slice"'``
forces a specific threading configuration.
``noise[=<strength>[:average][:pattern][:temporal][:uniform][:hq]``
``noise[=<strength>[:averaged][:pattern][:temporal][:uniform][:hq]``
Adds noise.
``strength``
@@ -438,7 +438,7 @@ Available filters are:
(using ``--vf=lavfi=[noise=...]``), or tell the libavfilter developers
to stop being stupid.
``average``
``averaged``
averaged temporal noise (smoother, but a lot slower)
``pattern``
+41
View File
@@ -0,0 +1,41 @@
Changes
-------
- Build system switches to waf. The old build system is still available by
running ``./old-configure``, but it will be removed some time in the future.
- The "run" input command changes in a not backwards compatible way.
- Some input.conf commands were replaced (such as speed_mult).
- Many audio/video filter have changed sub-options in a not backwards
compatible way. (This is a consequence of unifying audio/video filter
option parsing.)
- Most video filters now use libavfilter internally if available.
- Disable key autorepeat for some key binds, which prevents accidentally
triggering a binding multiple times.
- Encoding: install and include encoding profiles by default.
Bug fixes
---------
- Fix a bug that degraded vdpau playback after ~1 hour of runtime.
- Restrict hardware decoding to codecs where it generally makes sense. This
excludes mpeg4 for example, which often causes hardware decoders to decode to
garbage. Use ``--hwdec-codecs`` to enable hardware decoding for more codecs.
New features
------------
- Add window-scale property, which allows changing the window size via mpv key
bindings.
- Add revert_seek command, which is meant to undo accidental seeks.
- Hardware decoding (vdpau, vda, vaapi) can now be used with vo_opengl.
- Pulseaudio: set pulse stream name to mpv window title (like MPlayer).
- Support showing 2 subtitles at a time (``--secondary-sid``).
- Re-add some basic ``dvdnav://`` support. This doesn't handle navigation
highlights correctly, but navigation should mostly work. (Note that
``dvdnav://`` by default starts the longest title, instead of the DVD menu.
The menu is available with ``dvdnav://menu``.)
- Win32: you can drop files on the mpv window.
This listing is not complete. There are many more bug fixes and changes. The
complete change log can be viewed by running ``git log f572d2..f06a87`` in
the git repository.
+1
View File
@@ -0,0 +1 @@
0.3.4
+5
View File
@@ -15,6 +15,9 @@
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <limits.h>
#include <stdlib.h>
#include <assert.h>
#include <libavutil/mem.h>
@@ -145,6 +148,8 @@ static void mp_audio_destructor(void *ptr)
void mp_audio_realloc(struct mp_audio *mpa, int samples)
{
assert(samples >= 0);
if (samples >= INT_MAX / mpa->sstride)
abort(); // oom
int size = MPMAX(samples * mpa->sstride, 1);
for (int n = 0; n < mpa->num_planes; n++) {
if (size != mpa->allocated[n]) {
+18 -18
View File
@@ -345,26 +345,28 @@ static int af_count_filters(struct af_stream *s)
// (So we know what conversion filter with what format to insert next.)
static char *af_find_conversion_filter(int srcfmt, int *dstfmt)
{
#define NUM_FMT 64
#define NUM_FILT 32
#define NUM_NODES (NUM_FMT * NUM_FILT)
#define MAX_NODES (64 * 32)
int num_fmt = 0, num_filt = 0;
for (int n = 0; filter_list[n]; n++)
assert(n < NUM_FILT);
num_filt = n + 1;
for (int n = 0; af_fmtstr_table[n].format; n++)
assert(n < NUM_FMT);
num_fmt = n + 1;
bool visited[NUM_NODES] = {0};
unsigned char distance[NUM_NODES];
short previous[NUM_NODES] = {0};
for (int n = 0; n < NUM_NODES; n++) {
int num_nodes = num_fmt * num_filt;
assert(num_nodes < MAX_NODES);
bool visited[MAX_NODES] = {0};
unsigned char distance[MAX_NODES];
short previous[MAX_NODES] = {0};
for (int n = 0; n < num_nodes; n++) {
distance[n] = 255;
if (af_fmtstr_table[n % NUM_FMT].format == srcfmt)
if (af_fmtstr_table[n % num_fmt].format == srcfmt)
distance[n] = 0;
}
while (1) {
int next = -1;
for (int n = 0; n < NUM_NODES; n++) {
for (int n = 0; n < num_nodes; n++) {
if (!visited[n] && (next < 0 || (distance[n] < distance[next])))
next = n;
}
@@ -372,13 +374,13 @@ static char *af_find_conversion_filter(int srcfmt, int *dstfmt)
return NULL;
visited[next] = true;
int fmt = next % NUM_FMT;
int fmt = next % num_fmt;
if (af_fmtstr_table[fmt].format == *dstfmt) {
// Best match found
for (int cur = next; cur >= 0; cur = previous[cur] - 1) {
if (distance[cur] == 1) {
*dstfmt = af_fmtstr_table[cur % NUM_FMT].format;
return (char *)filter_list[cur / NUM_FMT]->name;
*dstfmt = af_fmtstr_table[cur % num_fmt].format;
return (char *)filter_list[cur / num_fmt]->name;
}
}
return NULL;
@@ -392,7 +394,7 @@ static char *af_find_conversion_filter(int srcfmt, int *dstfmt)
if (i != fmt && af->test_conversion(af_fmtstr_table[fmt].format,
af_fmtstr_table[i].format))
{
int other = n * NUM_FMT + i;
int other = n * num_fmt + i;
int ndist = distance[next] + 1;
if (ndist < distance[other]) {
distance[other] = ndist;
@@ -403,9 +405,7 @@ static char *af_find_conversion_filter(int srcfmt, int *dstfmt)
}
}
assert(0);
#undef NUM_FMT
#undef NUM_FILT
#undef NODE_N
#undef MAX_NODES
}
static bool af_is_conversion_filter(struct af_instance *af)
+2 -2
View File
@@ -153,13 +153,13 @@ static int af_open(struct af_instance* af){
int j,k;
int nch = s->nch;
if(AF_OK != control(af,AF_CONTROL_SET_PAN_NOUT, &nch))
if(nch && AF_OK != control(af,AF_CONTROL_SET_PAN_NOUT, &nch))
return AF_ERROR;
// Read pan values
char *cp = s->matrixstr;
j = 0; k = 0;
while(k < AF_NCH){
while(cp && k < AF_NCH){
sscanf(cp, "%f%n" , &s->level[j][k], &n);
MP_VERBOSE(af, "[pan] Pan level from channel %i to"
" channel %i = %f\n",k,j,s->level[j][k]);
+4 -5
View File
@@ -585,9 +585,11 @@ static void audio_resume(struct ao *ao)
if (snd_pcm_state(p->alsa) == SND_PCM_STATE_SUSPENDED) {
MP_INFO(ao, "PCM in suspend mode, trying to resume.\n");
while ((err = snd_pcm_resume(p->alsa)) == -EAGAIN)
sleep(1);
}
if (p->can_pause) {
err = snd_pcm_pause(p->alsa, 0);
CHECK_ALSA_ERROR("pcm resume error");
@@ -639,11 +641,8 @@ static int play(struct ao *ao, void **data, int samples, int flags)
/* nothing to do */
res = 0;
} else if (res == -ESTRPIPE) { /* suspend */
MP_INFO(ao, "PCM in suspend mode, trying to resume.\n");
while ((res = snd_pcm_resume(p->alsa)) == -EAGAIN)
sleep(1);
}
if (res < 0) {
audio_resume(ao);
} else if (res < 0) {
MP_ERR(ao, "Write error: %s\n", snd_strerror(res));
res = snd_pcm_prepare(p->alsa);
int err = res;
-17
View File
@@ -36,10 +36,6 @@
#include "misc/ring.h"
#include "ao.h"
#ifndef BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE
#define BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE 0x00000001
#endif
#ifndef PKEY_Device_FriendlyName
DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName,
0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20,
@@ -136,17 +132,6 @@ static int fill_VistaBlob(wasapi_state *state)
{
if (!state)
return 1;
HMODULE hkernel32 = GetModuleHandleW(L"kernel32.dll");
if (!hkernel32)
return 1;
WINBOOL (WINAPI *pSetDllDirectory)(LPCWSTR lpPathName) =
(WINBOOL (WINAPI *)(LPCWSTR))GetProcAddress(hkernel32, "SetDllDirectoryW");
WINBOOL (WINAPI *pSetSearchPathMode)(DWORD Flags) =
(WINBOOL (WINAPI *)(DWORD))GetProcAddress(hkernel32, "SetSearchPathMode");
if (pSetSearchPathMode)
pSetDllDirectory(L""); /* Attempt to use safe search paths */
if (pSetSearchPathMode)
pSetSearchPathMode(BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE);
state->VistaBlob.hAvrt = LoadLibraryW(L"avrt.dll");
if (!state->VistaBlob.hAvrt)
goto exit_label;
@@ -160,8 +145,6 @@ static int fill_VistaBlob(wasapi_state *state)
exit_label:
if (state->VistaBlob.hAvrt)
FreeLibrary(state->VistaBlob.hAvrt);
if (pSetSearchPathMode)
pSetDllDirectory(NULL);
return 1;
}
+11 -2
View File
@@ -19,5 +19,14 @@
// At this point both gcc and clang had __sync_synchronize support for some
// time. We only support a full memory barrier.
#define mp_memory_barrier() __sync_synchronize()
#define mp_atomic_add_and_fetch(a, b) __sync_add_and_fetch(a, b)
#include "config.h"
#if HAVE_ATOMIC_BUILTINS
# define mp_memory_barrier() __atomic_thread_fence(__ATOMIC_SEQ_CST)
# define mp_atomic_add_and_fetch(a, b) __atomic_add_fetch(a, b,__ATOMIC_SEQ_CST)
#elif HAVE_SYNC_BUILTINS
# define mp_memory_barrier() __sync_synchronize()
# define mp_atomic_add_and_fetch(a, b) __sync_add_and_fetch(a, b)
#else
# error "this should have been a configuration error, report a bug please"
#endif
+1
View File
@@ -152,6 +152,7 @@ struct demuxer_params {
int matroska_wanted_segment;
bool *matroska_was_valid;
struct ass_library *ass_library;
bool expect_subtitle;
};
typedef struct demuxer {
+33 -27
View File
@@ -90,12 +90,16 @@ struct format_hack {
const char *mime_type;
int probescore;
float analyzeduration;
bool max_probe; // use probescore only if max. probe size reached
};
static const struct format_hack format_hacks[] = {
// for webradios
{"aac", "audio/aacp", 25, 0.5},
{"aac", "audio/aac", 25, 0.5},
{"mp3", "audio/mpeg", 25, 0.5},
// some mp3 files don't detect correctly
{"mp3", NULL, 24, .max_probe = true},
{0}
};
@@ -104,15 +108,6 @@ static const char *format_blacklist[] = {
0
};
static const struct format_hack *find_format_from_mime_type(char *mime_type)
{
for (int n = 0; format_hacks[n].ff_name; n++) {
if (strcasecmp(format_hacks[n].mime_type, mime_type) == 0)
return &format_hacks[n];
}
return NULL;
}
static int mp_read(void *opaque, uint8_t *buf, int size)
{
struct demuxer *demuxer = opaque;
@@ -223,17 +218,9 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
priv->filename = sep + 1;
}
const char *expected_format = NULL;
int expected_format_probescore = AVPROBE_SCORE_MAX;
char *mime_type = demuxer->stream->mime_type;
if (lavfdopts->allow_mimetype && mime_type) {
priv->format_hack = find_format_from_mime_type(mime_type);
if (priv->format_hack) {
expected_format = priv->format_hack->ff_name;
expected_format_probescore = priv->format_hack->probescore;
}
}
if (!lavfdopts->allow_mimetype || !mime_type)
mime_type = "";
const char *format = lavfdopts->format;
if (!format)
@@ -264,17 +251,18 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
AVProbeData avpd = {
// Disable file-extension matching with normal checks
.filename = check <= DEMUX_CHECK_REQUEST ? priv->filename : NULL,
.filename = check <= DEMUX_CHECK_REQUEST ? priv->filename : "",
.buf_size = 0,
.buf = av_mallocz(PROBE_BUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE),
};
while (avpd.buf_size < PROBE_BUF_SIZE) {
bool final_probe = false;
do {
int nsize = av_clip(avpd.buf_size * 2, INITIAL_PROBE_SIZE,
PROBE_BUF_SIZE);
bstr buf = stream_peek(s, nsize);
if (buf.len <= avpd.buf_size)
break;
final_probe = true;
memcpy(avpd.buf, buf.start, buf.len);
avpd.buf_size = buf.len;
@@ -283,20 +271,32 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
if (priv->avif) {
MP_VERBOSE(demuxer, "Found '%s' at score=%d size=%d.\n",
priv->avif->name, score, avpd.buf_size);
priv->avif->name, score, avpd.buf_size);
priv->format_hack = NULL;
for (int n = 0; format_hacks[n].ff_name; n++) {
const struct format_hack *entry = &format_hacks[n];
if (strcmp(entry->ff_name, priv->avif->name) != 0)
continue;
if (entry->mime_type && strcasecmp(entry->mime_type, mime_type) != 0)
continue;
priv->format_hack = entry;
break;
}
if (score >= min_probe)
break;
if (expected_format) {
if (strcmp(priv->avif->name, expected_format) == 0 &&
score >= expected_format_probescore)
if (priv->format_hack) {
if (score >= priv->format_hack->probescore &&
(!priv->format_hack->max_probe || final_probe))
break;
}
}
priv->avif = NULL;
}
priv->format_hack = NULL;
} while (!final_probe);
av_free(avpd.buf);
@@ -458,6 +458,12 @@ static void handle_stream(demuxer_t *demuxer, int i)
memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size);
sh_sub->extradata_len = codec->extradata_size;
}
// Hack for MicroDVD: if time_base matches the ffmpeg microdvd reader's
// default FPS (23.976), assume the MicroDVD file did not declare a
// FPS, and the MicroDVD file uses frame based timing.
if (codec->time_base.num == 125 && codec->time_base.den == 2997)
sh_sub->frame_based = true;
break;
}
case AVMEDIA_TYPE_ATTACHMENT: {
+18 -9
View File
@@ -723,7 +723,7 @@ static int demux_mkv_read_cues(demuxer_t *demuxer)
stream_t *s = demuxer->stream;
if (opts->index_mode == 0 || opts->index_mode == 2) {
ebml_read_skip(s, NULL);
ebml_read_skip(demuxer->log, -1, s);
return 0;
}
@@ -1128,7 +1128,7 @@ static int read_header_element(struct demuxer *demuxer, uint32_t id,
res = 2;
}
if (!at_filepos && id != EBML_ID_INVALID)
ebml_read_skip(s, NULL);
ebml_read_skip(demuxer->log, -1, s);
return res;
}
@@ -2270,7 +2270,7 @@ static void index_block(demuxer_t *demuxer, struct block_info *block)
}
}
static int read_block(demuxer_t *demuxer, struct block_info *block)
static int read_block(demuxer_t *demuxer, int64_t end, struct block_info *block)
{
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
stream_t *s = demuxer->stream;
@@ -2281,7 +2281,7 @@ static int read_block(demuxer_t *demuxer, struct block_info *block)
free_block(block);
length = ebml_read_length(s, NULL);
if (length > 500000000)
if (length > 500000000 || stream_tell(s) + length > (uint64_t)end)
goto exit;
block->alloc = malloc(length + AV_LZO_INPUT_PADDING);
if (!block->alloc)
@@ -2442,7 +2442,7 @@ static int read_block_group(demuxer_t *demuxer, int64_t end,
break;
case MATROSKA_ID_BLOCK:
if (read_block(demuxer, block) < 0)
if (read_block(demuxer, end, block) < 0)
goto error;
break;
@@ -2454,11 +2454,12 @@ static int read_block_group(demuxer_t *demuxer, int64_t end,
block->keyframe = false;
break;
case MATROSKA_ID_CLUSTER:
case EBML_ID_INVALID:
goto error;
default:
if (ebml_read_skip_or_resync_cluster(demuxer->log, s, NULL) != 0)
if (ebml_read_skip(demuxer->log, end, s) != 0)
goto error;
break;
}
@@ -2491,6 +2492,8 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block)
case MATROSKA_ID_BLOCKGROUP: {
int64_t end = ebml_read_length(s, NULL);
end += stream_tell(s);
if (end > mkv_d->cluster_end)
goto find_next_cluster;
int res = read_block_group(demuxer, end, block);
if (res < 0)
goto find_next_cluster;
@@ -2501,7 +2504,7 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block)
case MATROSKA_ID_SIMPLEBLOCK: {
*block = (struct block_info){ .simple = true };
int res = read_block(demuxer, block);
int res = read_block(demuxer, mkv_d->cluster_end, block);
if (res < 0)
goto find_next_cluster;
if (res > 0)
@@ -2517,7 +2520,7 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block)
goto find_next_cluster;
default: ;
if (ebml_read_skip_or_resync_cluster(demuxer->log, s, NULL) != 0)
if (ebml_read_skip(demuxer->log, mkv_d->cluster_end, s) != 0)
goto find_next_cluster;
break;
}
@@ -2532,7 +2535,13 @@ static int read_next_block(demuxer_t *demuxer, struct block_info *block)
break;
if (s->eof)
return -1;
ebml_read_skip_or_resync_cluster(demuxer->log, s, NULL);
// For the sake of robustness, consider even unknown level 1
// elements the same as unknown/broken IDs.
if (!ebml_is_mkv_level1_id(id) ||
ebml_read_skip(demuxer->log, -1, s) != 0)
{
ebml_resync_cluster(demuxer->log, s);
}
}
next_cluster:
mkv_d->cluster_end = ebml_read_length(s, NULL);
+3
View File
@@ -1337,6 +1337,9 @@ static int d_open_file(struct demuxer *demuxer, enum demux_check check)
if (check > DEMUX_CHECK_REQUEST)
return -1;
if (!demuxer->params || !demuxer->params->expect_subtitle)
return -1;
struct stream *ps = read_probe_stream(demuxer->stream, PROBE_SIZE);
struct subreader sr;
+36 -36
View File
@@ -41,6 +41,26 @@
#define SIZE_MAX ((size_t)-1)
#endif
// Whether the id is a known Matroska level 1 element (allowed as element on
// global file level, after the level 0 MATROSKA_ID_SEGMENT).
// This (intentionally) doesn't include "global" elements.
bool ebml_is_mkv_level1_id(uint32_t id)
{
switch (id) {
case MATROSKA_ID_SEEKHEAD:
case MATROSKA_ID_INFO:
case MATROSKA_ID_CLUSTER:
case MATROSKA_ID_TRACKS:
case MATROSKA_ID_CUES:
case MATROSKA_ID_ATTACHMENTS:
case MATROSKA_ID_CHAPTERS:
case MATROSKA_ID_TAGS:
return true;
default:
return false;
}
}
/*
* Read: the element content data ID.
* Return: the ID.
@@ -252,21 +272,32 @@ char *ebml_read_utf8(stream_t *s, uint64_t *length)
/*
* Skip the current element.
* end: the end of the parent element or -1 (for robust error handling)
*/
int ebml_read_skip(stream_t *s, uint64_t *length)
int ebml_read_skip(struct mp_log *log, int64_t end, stream_t *s)
{
uint64_t len;
int l;
int64_t pos = stream_tell(s);
len = ebml_read_length(s, &l);
if (len == EBML_UINT_INVALID)
return 1;
if (length)
*length = len + l;
goto invalid;
stream_skip(s, len);
int64_t pos2 = stream_tell(s);
if (len >= INT64_MAX - pos2 || (end > 0 && pos2 + len > end))
goto invalid;
if (!stream_skip(s, len))
goto invalid;
return 0;
invalid:
mp_err(log, "Invalid EBML length at position %"PRId64"\n", pos);
stream_seek(s, pos);
return 1;
}
/*
@@ -291,37 +322,6 @@ int ebml_resync_cluster(struct mp_log *log, stream_t *s)
return -1;
}
/*
* Skip the current element, or on error, call ebml_resync_cluster().
*/
int ebml_read_skip_or_resync_cluster(struct mp_log *log, stream_t *s,
uint64_t *length)
{
uint64_t len;
int l;
len = ebml_read_length(s, &l);
if (len == EBML_UINT_INVALID)
goto resync;
if (length)
*length = len + l;
int64_t pos = stream_tell(s);
// When reading corrupted elements, len will often be a random high number,
// and stream_skip() will fail when skipping past EOF.
if (!stream_skip(s, len)) {
stream_seek(s, pos);
goto resync;
}
return 0;
resync:
return ebml_resync_cluster(log, s) < 0 ? -1 : 1;
}
/*
* Read the next element, but only the header. The contents
* are supposed to be sub-elements which can be read separately.
+2 -3
View File
@@ -92,6 +92,7 @@ struct ebml_parse_ctx {
#define EBML_FLOAT_INVALID -1000000000.0
bool ebml_is_mkv_level1_id(uint32_t id);
uint32_t ebml_read_id (stream_t *s, int *length);
uint64_t ebml_read_vlen_uint (bstr *buffer);
int64_t ebml_read_vlen_int (bstr *buffer);
@@ -101,9 +102,7 @@ int64_t ebml_read_int (stream_t *s, uint64_t *length);
double ebml_read_float (stream_t *s, uint64_t *length);
char *ebml_read_ascii (stream_t *s, uint64_t *length);
char *ebml_read_utf8 (stream_t *s, uint64_t *length);
int ebml_read_skip (stream_t *s, uint64_t *length);
int ebml_read_skip_or_resync_cluster(struct mp_log *log, stream_t *s,
uint64_t *length);
int ebml_read_skip(struct mp_log *log, int64_t end, stream_t *s);
int ebml_resync_cluster(struct mp_log *log, stream_t *s);
uint32_t ebml_read_master (stream_t *s, uint64_t *length);
+4 -1
View File
@@ -2,11 +2,14 @@
Type=Application
Name=mpv Media Player
Name[ca]=Reproductor multimèdia mpv
Name[cs]=mpv přehrávač
Name[pl]=mpv odtwarzacz multimedialny
Name[ru]=Проигрыватель mpv
GenericName=Multimedia player
GenericName[cs]=Multimediální přehrávač
Comment=Play movies and songs
Comment[ca]=Reproduïu vídeos i cançons
Comment[cs]=Přehrává filmy a hudbu
Comment[de]=Filme und Musik abspielen
Comment[es]=Reproduzca vídeos y canciones
Comment[fr]=Lecteur multimédia
@@ -20,5 +23,5 @@ Exec=mpv --really-quiet --force-window -- %F
Terminal=false
NoDisplay=true
Categories=AudioVideo;Audio;Video;Player;TV;
MimeType=application/ogg;application/x-ogg;application/sdp;application/smil;application/x-smil;application/streamingmedia;application/x-streamingmedia;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/aac;audio/x-aac;audio/m4a;audio/x-m4a;audio/mp1;audio/x-mp1;audio/mp2;audio/x-mp2;audio/mp3;audio/x-mp3;audio/mpeg;audio/x-mpeg;audio/mpegurl;audio/x-mpegurl;audio/mpg;audio/x-mpg;audio/rn-mpeg;audio/scpls;audio/x-scpls;audio/vnd.rn-realaudio;audio/wav;audio/x-pn-windows-pcm;audio/x-realaudio;audio/x-pn-realaudio;audio/x-ms-wma;audio/x-pls;audio/x-wav;video/mpeg;video/x-mpeg;video/x-mpeg2;video/mp4;video/msvideo;video/x-msvideo;video/quicktime;video/vnd.rn-realvideo;video/x-ms-afs;video/x-ms-asf;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-avi;video/x-fli;video/x-flv;video/x-theora;video/x-matroska;video/webm;audio/x-flac;
MimeType=application/ogg;application/x-ogg;application/sdp;application/smil;application/x-smil;application/streamingmedia;application/x-streamingmedia;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/aac;audio/x-aac;audio/m4a;audio/x-m4a;audio/mp1;audio/x-mp1;audio/mp2;audio/x-mp2;audio/mp3;audio/x-mp3;audio/mpeg;audio/x-mpeg;audio/mpegurl;audio/x-mpegurl;audio/mpg;audio/x-mpg;audio/rn-mpeg;audio/scpls;audio/x-scpls;audio/vnd.rn-realaudio;audio/wav;audio/x-pn-windows-pcm;audio/x-realaudio;audio/x-pn-realaudio;audio/x-ms-wma;audio/x-pls;audio/x-wav;video/mpeg;video/x-mpeg;video/x-mpeg2;video/mp4;video/msvideo;video/x-msvideo;video/quicktime;video/vnd.rn-realvideo;video/x-ms-afs;video/x-ms-asf;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-avi;video/x-fli;video/x-flv;video/x-theora;video/x-matroska;video/webm;audio/x-flac;audio/x-vorbis+ogg;video/x-ogm+ogg;
X-KDE-Protocols=ftp,http,https,mms,rtmp,rtsp,sftp,smb
+34
View File
@@ -1329,6 +1329,38 @@ if test "$_pthreads" = no ; then
die "Unable to find pthreads support."
fi
echocheck "compiler support for __atomic built-ins"
_atomic=no
for _ld_tmp in "" "-latomic" ; do
statement_check stdint.h 'int64_t test = 0; test = __atomic_add_fetch(&test, 1, __ATOMIC_SEQ_CST)' $_ld_tmp &&
libs_mplayer="$libs_mplayer $_ld_tmp" && _atomic=yes && break
done
if test "$_atomic" = yes ; then
def_atomic="#define HAVE_ATOMIC_BUILTINS 1"
else
def_atomic="#define HAVE_ATOMIC_BUILTINS 0"
fi
echores "$_atomic"
if test "$_atomic" = no ; then
echocheck "compiler support for __sync built-ins"
_sync=no
statement_check stdint.h 'int64_t test = 0; test = __sync_add_and_fetch(&test, 1)' && _sync=yes
if test "$_sync" = yes ; then
def_sync="#define HAVE_SYNC_BUILTINS 1"
else
def_sync="#define HAVE_SYNC_BUILTINS 0"
fi
echores "$_sync"
else
def_sync="#define HAVE_SYNC_BUILTINS 0"
fi
if test "$_atomic" = no && test "$_sync" = no ; then
die "your compiler must support either __atomic or __sync built-ins."
fi
if test "$_pthreads" = yes ; then
# Cargo-cult for -lrt, which is needed on not so recent glibc version for
@@ -3521,6 +3553,8 @@ $def_avresample_has_set_channel_mapping
$def_fast_64bit
$def_pthreads
$def_atomic
$def_sync
#define HAVE_INLINE_ASM 1
+11
View File
@@ -1299,6 +1299,17 @@ static int parse_msglevels(struct mp_log *log, const m_option_t *opt,
if (param.start == NULL)
return M_OPT_MISSING_PARAM;
if (bstr_equals0(param, "help")) {
mp_info(log, "Syntax: --msglevel=module1=level:module2=level:...\n"
"'module' is output prefix as shown with -v, or a prefix\n"
"of it. level is one of:\n\n"
" fatal error warn info status v debug trace\n\n"
"The level specifies the minimum log level a message\n"
"must have to be printed.\n"
"The special module name 'all' affects all modules.\n");
return M_OPT_EXIT;
}
bstr s = param;
while (1) {
int res = mp_msg_split_msglevel(&s, &(bstr){0}, &(int){0});
+2
View File
@@ -316,6 +316,7 @@ const m_option_t mp_opts[] = {
({"no", 0}, {"attachment", 1})),
OPT_STRING("quvi-format", quvi_format, 0),
OPT_FLAG("quvi-fetch-subtitles", quvi_fetch_subtitles, 0),
#if HAVE_CDDA
{ "cdda", (void *)&cdda_opts, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
@@ -718,6 +719,7 @@ const struct MPOpts mp_default_opts = {
.sub_visibility = 1,
.sub_pos = 100,
.sub_speed = 1.0,
.quvi_fetch_subtitles = 0,
.audio_output_channels = MP_CHMAP_INIT_STEREO,
.audio_output_format = 0, // AF_FORMAT_UNKNOWN
.playback_speed = 1.,
+1
View File
@@ -158,6 +158,7 @@ typedef struct MPOpts {
int forced_subs_only;
int stretch_dvd_subs;
char *quvi_format;
int quvi_fetch_subtitles;
// subreader.c
int suboverlap_enabled;
+1 -1
View File
@@ -46,7 +46,7 @@ char *mp_get_win_config_path(const char *filename)
void *tmp = talloc_new(NULL);
#ifndef __CYGWIN__
if (SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE, NULL,
if (SHGetFolderPathW(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL,
SHGFP_TYPE_CURRENT, w_appdir) != S_OK)
w_appdir[0] = '\0';
#endif
+6 -2
View File
@@ -47,6 +47,8 @@
#include "input/keycodes.h"
#include "terminal.h"
static int use_terminal;
#if HAVE_TERMIOS
static volatile struct termios tio_orig;
static volatile int tio_orig_set;
@@ -454,7 +456,7 @@ static volatile int getch2_enabled = 0;
static void do_activate_getch2(void)
{
if (getch2_active)
if (getch2_active || !use_terminal)
return;
#if HAVE_TERMINFO || HAVE_TERMCAP
@@ -612,6 +614,8 @@ void terminal_setup_stdin_cmd_input(struct input_ctx *ictx)
int terminal_init(void)
{
load_termcap(NULL);
use_terminal = isatty(1);
if (use_terminal)
load_termcap(NULL);
return 0;
}
+5 -1
View File
@@ -3052,6 +3052,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
case MP_CMD_RUN: {
#ifndef __MINGW32__
mp_msg(mpctx->statusline, MSGL_STATUS, "\n");
char *args[MP_CMD_MAX_ARGS + 1] = {0};
for (int n = 0; n < cmd->nargs; n++)
args[n] = cmd->args[n].v.s;
@@ -3062,7 +3063,10 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
// about having to wait for the second process to terminate.
if (fork() == 0) {
execvp(args[0], args);
_exit(0);
// mp_msg() is not safe to be called from a forked process.
char s[] = "Executing program failed.\n";
write(2, s, sizeof(s) - 1);
_exit(1);
}
_exit(0);
}
+7 -7
View File
@@ -57,6 +57,13 @@ bool mp_parse_cfgfiles(struct MPContext *mpctx)
bool r = true;
char *conffile;
// The #if is a stupid hack to avoid errors if libavfilter is not available.
#if HAVE_VF_LAVFI && HAVE_ENCODING
conffile = mp_find_config_file(tmp, mpctx->global, "encoding-profiles.conf");
if (conffile && mp_path_exists(conffile))
m_config_parse_config_file(mpctx->mconfig, conffile, 0);
#endif
if (m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mpv.conf", 0) < 0) {
r = false;
goto done;
@@ -77,13 +84,6 @@ bool mp_parse_cfgfiles(struct MPContext *mpctx)
}
}
// The #if is a stupid hack to avoid errors if libavfilter is not available.
#if HAVE_VF_LAVFI && HAVE_ENCODING
conffile = mp_find_config_file(tmp, mpctx->global, "encoding-profiles.conf");
if (conffile && mp_path_exists(conffile))
m_config_parse_config_file(mpctx->mconfig, conffile, 0);
#endif
done:
talloc_free(tmp);
return r;
+1
View File
@@ -128,6 +128,7 @@ struct track {
// If this track is from an external file (e.g. subtitle file).
bool is_external;
bool no_default; // pretend it's not external for auto-selection
char *external_filename;
bool auto_loaded;
+1 -1
View File
@@ -243,7 +243,7 @@ void mp_nav_get_highlight(struct osd_state *osd, struct mp_osd_res res,
sub->y = nav->highlight[1];
sub->w = MPCLAMP(nav->highlight[2] - sub->x, 0, sizes[0]);
sub->h = MPCLAMP(nav->highlight[3] - sub->y, 0, sizes[1]);
sub->stride = sub->w;
sub->stride = sub->w * 4;
out_imgs->format = SUBBITMAP_RGBA;
out_imgs->parts = sub;
out_imgs->num_parts = sub->w > 0 && sub->h > 0 && nav->hi_visible;
+18 -8
View File
@@ -281,7 +281,7 @@ void reselect_demux_streams(struct MPContext *mpctx)
// Note: we assume that all demuxer streams are covered by the track list.
for (int t = 0; t < mpctx->num_tracks; t++) {
struct track *track = mpctx->tracks[t];
if (track->demuxer)
if (track->demuxer && track->stream)
demuxer_select_track(track->demuxer, track->stream, track->selected);
}
}
@@ -443,13 +443,16 @@ static struct track *add_stream_track(struct MPContext *mpctx,
track->preloaded = !!stream->sub->track;
// Needed for DVD and Blu-ray.
if (!track->lang) {
struct stream *st = track->demuxer->stream;
if (!track->lang && (st->uncached_type == STREAMTYPE_BLURAY ||
st->uncached_type == STREAMTYPE_DVD))
{
struct stream_lang_req req = {
.type = track->type,
.id = map_id_from_demuxer(track->demuxer, track->type,
track->demuxer_id)
};
stream_control(track->demuxer->stream, STREAM_CTRL_GET_LANG, &req);
stream_control(st, STREAM_CTRL_GET_LANG, &req);
if (req.name[0])
track->lang = talloc_strdup(track, req.name);
}
@@ -472,6 +475,8 @@ static void add_dvd_tracks(struct MPContext *mpctx)
struct demuxer *demuxer = mpctx->demuxer;
struct stream *stream = demuxer->stream;
struct stream_dvd_info_req info;
if (stream->uncached_type != STREAMTYPE_DVD)
return;
if (stream_control(stream, STREAM_CTRL_GET_DVD_INFO, &info) > 0) {
for (int n = 0; n < info.num_subs; n++) {
struct track *track = talloc_ptrtype(NULL, track);
@@ -508,7 +513,7 @@ static int match_lang(char **langs, char *lang)
* lang is a string list, NULL is same as empty list
* Sort tracks based on the following criteria, and pick the first:
* 0) track matches tid (always wins)
* 1) track is external
* 1) track is external (no_default cancels this)
* 1b) track was passed explicitly (is not an auto-loaded subtitle)
* 2) earlier match in lang list
* 3) track is marked default
@@ -520,8 +525,10 @@ static int match_lang(char **langs, char *lang)
// Return whether t1 is preferred over t2
static bool compare_track(struct track *t1, struct track *t2, char **langs)
{
if (t1->is_external != t2->is_external)
return t1->is_external;
bool ext1 = t1->is_external && !t1->no_default;
bool ext2 = t2->is_external && !t2->no_default;
if (ext1 != ext2)
return ext1;
if (t1->auto_loaded != t2->auto_loaded)
return !t1->auto_loaded;
int l1 = match_lang(langs, t1->lang), l2 = match_lang(langs, t2->lang);
@@ -549,7 +556,7 @@ static struct track *select_track(struct MPContext *mpctx,
if (!pick || compare_track(track, pick, langs))
pick = track;
}
if (pick && !select_fallback && !pick->is_external
if (pick && !select_fallback && !(pick->is_external && !pick->no_default)
&& !match_lang(langs, pick->lang) && !pick->default_track)
pick = NULL;
if (pick && pick->attached_picture && !mpctx->opts->audio_display)
@@ -776,6 +783,7 @@ static struct track *open_external_file(struct MPContext *mpctx, char *filename,
opts->stream_cache_seek_min_percent);
struct demuxer_params params = {
.ass_library = mpctx->ass_library, // demux_libass requires it
.expect_subtitle = filter == STREAM_SUB,
};
struct demuxer *demuxer =
demux_open(stream, demuxer_name, &params, mpctx->global);
@@ -838,8 +846,10 @@ static void open_subtitles_from_resolve(struct MPContext *mpctx)
struct track *t =
open_external_file(mpctx, s, opts->sub_demuxer_name, 0, STREAM_SUB);
talloc_free(s);
if (t)
if (t) {
t->lang = talloc_strdup(t, sub->lang);
t->no_default = true;
}
}
}
+25 -1
View File
@@ -78,6 +78,14 @@
#if defined(__MINGW32__) || defined(__CYGWIN__)
#include <windows.h>
#ifndef BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE
#define BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE (0x0001)
#endif
#ifndef BASE_SEARCH_PATH_PERMANENT
#define BASE_SEARCH_PATH_PERMANENT (0x8000)
#endif
#endif
const char mp_help_text[] =
@@ -260,7 +268,23 @@ static void osdep_preinit(int *p_argc, char ***p_argv)
#if defined(__MINGW32__) || defined(__CYGWIN__)
// stop Windows from showing all kinds of annoying error dialogs
SetErrorMode(0x8003);
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
// Enable heap corruption detection
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
WINBOOL (WINAPI *pSetDllDirectory)(LPCWSTR lpPathName) =
(WINBOOL (WINAPI *)(LPCWSTR))GetProcAddress(kernel32, "SetDllDirectoryW");
WINBOOL (WINAPI *pSetSearchPathMode)(DWORD Flags) =
(WINBOOL (WINAPI *)(DWORD))GetProcAddress(kernel32, "SetSearchPathMode");
// Always use safe search paths for DLLs and other files, ie. never use the
// current directory
if (pSetSearchPathMode)
pSetDllDirectory(L"");
if (pSetSearchPathMode)
pSetSearchPathMode(BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE);
#endif
terminal_init();
+9 -6
View File
@@ -435,9 +435,12 @@ static void add_seek_osd_messages(struct MPContext *mpctx)
set_osd_bar_chapters(mpctx, OSD_BAR_SEEK);
}
if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_TEXT) {
mp_osd_msg_t *msg = add_osd_msg(mpctx, OSD_MSG_TEXT, 1,
mpctx->opts->osd_duration);
msg->show_position = true;
// Never in term-osd mode
if (mpctx->video_out && mpctx->opts->term_osd != 1) {
mp_osd_msg_t *msg = add_osd_msg(mpctx, OSD_MSG_TEXT, 1,
mpctx->opts->osd_duration);
msg->show_position = true;
}
}
if (mpctx->add_osd_seek_info & OSD_SEEK_INFO_CHAPTER_TEXT) {
char *chapter = chapter_display_name(mpctx, get_current_chapter(mpctx));
@@ -485,8 +488,8 @@ void update_osd_msg(struct MPContext *mpctx)
mpctx->terminal_osd_text = talloc_strdup(mpctx, msg->msg);
// Multi-line message => clear what will be the second line
write_status_line(mpctx, "");
MP_MSG(mpctx, MSGL_STATUS, "%s%s\n", opts->term_osd_esc,
mpctx->terminal_osd_text);
mp_msg(mpctx->statusline, MSGL_STATUS,
"%s%s\n", opts->term_osd_esc, mpctx->terminal_osd_text);
print_status(mpctx);
}
}
@@ -512,6 +515,6 @@ void update_osd_msg(struct MPContext *mpctx)
// Clear the term osd line
if (opts->term_osd && mpctx->terminal_osd_text[0]) {
mpctx->terminal_osd_text[0] = '\0';
MP_MSG(mpctx, MSGL_STATUS, "%s\n", opts->term_osd_esc);
mp_msg(mpctx->statusline, MSGL_STATUS, "%s\n", opts->term_osd_esc);
}
}
+3 -3
View File
@@ -71,8 +71,8 @@ static const char av_desync_help_text[] =
" This is due to vsync limiting the framerate.\n"
"- Playing from a slow network source.\n"
" Download the file instead.\n"
"- Try to find out whether audio or video is causing this by experimenting\n"
" with --no-video and --no-audio.\n"
"- Try to find out whether audio/video/subs are causing this by experimenting\n"
" with --no-video, --no-audio, or --no-sub.\n"
"- If you swiched audio or video tracks, try seeking to force synchronization.\n"
"If none of this helps you, file a bug report.\n\n";
@@ -924,7 +924,7 @@ static double get_wakeup_period(struct MPContext *mpctx)
*/
double sleeptime = WAKEUP_PERIOD;
#ifndef HAVE_POSIX_SELECT
#if !HAVE_POSIX_SELECT
// No proper file descriptor event handling; keep waking up to poll input
sleeptime = MPMIN(sleeptime, 0.02);
#endif
+14
View File
@@ -65,6 +65,7 @@ static void reconfig_video(struct MPContext *mpctx,
const struct mp_image_params *params,
bool probe_only)
{
struct MPOpts *opts = mpctx->opts;
struct dec_video *d_video = mpctx->d_video;
d_video->decoder_output = *params;
@@ -96,6 +97,19 @@ static void reconfig_video(struct MPContext *mpctx,
int r = vo_reconfig(mpctx->video_out, &p, 0);
if (r < 0)
d_video->vfilter->initialized = -1;
if (r >= 0) {
if (opts->gamma_gamma != 1000)
video_set_colors(d_video, "gamma", opts->gamma_gamma);
if (opts->gamma_brightness != 1000)
video_set_colors(d_video, "brightness", opts->gamma_brightness);
if (opts->gamma_contrast != 1000)
video_set_colors(d_video, "contrast", opts->gamma_contrast);
if (opts->gamma_saturation != 1000)
video_set_colors(d_video, "saturation", opts->gamma_saturation);
if (opts->gamma_hue != 1000)
video_set_colors(d_video, "hue", opts->gamma_hue);
}
}
static void recreate_video_filters(struct MPContext *mpctx)
+15 -7
View File
@@ -33,6 +33,9 @@
// the cache is active.
#define CACHE_UPDATE_CONTROLS_TIME 2.0
// Time in seconds the cache prints a new message at all.
#define CACHE_NO_SPAM 5.0
#include <stdio.h>
#include <stdlib.h>
@@ -77,6 +80,7 @@ struct priv {
// Owned by the main thread
stream_t *cache; // wrapper stream, used by demuxer etc.
double last_warn_time;
// Owned by the cache thread
stream_t *stream; // "real" stream, used to read from the source media
@@ -142,15 +146,19 @@ static int cache_wakeup_and_wait(struct priv *s, double *retry_time)
if (stream_check_interrupt(0))
return CACHE_INTERRUPTED;
// Print a "more severe" warning after waiting 1 second and no new data
if ((*retry_time) >= 1.0) {
MP_ERR(s, "Cache keeps not responding.\n");
} else if (*retry_time > 0.1) {
MP_WARN(s, "Cache is not responding - slow/stuck network connection?\n");
}
double start = mp_time_sec();
if (!s->last_warn_time || start - s->last_warn_time >= CACHE_NO_SPAM) {
// Print a "more severe" warning after waiting 1 second and no new data
if ((*retry_time) >= 1.0) {
MP_ERR(s, "Cache keeps not responding.\n");
s->last_warn_time = start;
} else if (*retry_time > 0.1) {
MP_WARN(s, "Cache is not responding - slow/stuck network connection?\n");
s->last_warn_time = start;
}
}
pthread_cond_signal(&s->wakeup);
mpthread_cond_timed_wait(&s->wakeup, &s->mutex, CACHE_WAIT_TIME);
+1 -1
View File
@@ -61,7 +61,7 @@ static char *col_dup(void *talloc_ctx, const char *src)
}
/* Finds the start of all the columns */
static int parse_line(char **ptr, char *cols[6])
static int parse_line(char **ptr, char *cols[7])
{
int col;
cols[0] = *ptr;
+1 -1
View File
@@ -111,7 +111,7 @@ struct mp_resolve_result *mp_resolve_quvi(const char *url,
quvi_media_free(media);
}
if (quvi_supports(q, url, mode, QUVI_SUPPORTS_TYPE_SUBTITLE)) {
if (opts->quvi_fetch_subtitles && quvi_supports(q, url, mode, QUVI_SUPPORTS_TYPE_SUBTITLE)) {
mp_info(log, "Getting subtitles...\n");
quvi_subtitle_t qsub = quvi_subtitle_new(q, url);
if (mp_quvi_ok(q, log)) {
+1 -1
View File
@@ -562,7 +562,7 @@ struct bstr stream_peek(stream_t *s, int len)
while (buf_valid < len) {
int chunk = MPMAX(len - buf_valid, STREAM_BUFFER_SIZE);
if (s->sector_size)
chunk = STREAM_BUFFER_SIZE;
chunk = s->sector_size;
assert(buf_valid + chunk <= TOTAL_BUFFER_SIZE);
int read = stream_read_unbuffered(s, &s->buffer[buf_valid], chunk);
if (read == 0)
+1
View File
@@ -35,6 +35,7 @@ enum streamtype {
STREAMTYPE_RADIO,
STREAMTYPE_DVB,
STREAMTYPE_DVD,
STREAMTYPE_BLURAY,
STREAMTYPE_PVR,
STREAMTYPE_TV,
STREAMTYPE_MF,
+1
View File
@@ -390,6 +390,7 @@ err_no_info:
b->current_angle = angle;
b->current_title = title;
s->type = STREAMTYPE_BLURAY;
s->end_pos = title_size;
s->sector_size = BLURAY_SECTOR_SIZE;
s->flags = MP_STREAM_SEEK;
+2 -1
View File
@@ -190,7 +190,7 @@ pvr_uninit (struct pvr_t *pvr)
return;
/* close device */
if (pvr->dev_fd)
if (pvr->dev_fd != -1)
close (pvr->dev_fd);
free (pvr->video_dev);
@@ -1520,6 +1520,7 @@ pvr_stream_open (stream_t *stream, int mode)
return STREAM_UNSUPPORTED;
pvr = pvr_init ();
pvr->log = stream->log;
/**
* if the url, i.e. 'pvr://8', contains the channel, use it,
+1 -1
View File
@@ -126,7 +126,7 @@ static mp_vcd_priv_t* vcd_read_toc(stream_t *stream, int fd){
static int vcd_read(mp_vcd_priv_t* vcd,char *mem){
#ifndef sun
memcpy(vcd->buf,&vcd->entry.cdte_addr.msf,sizeof(struct cdrom_msf));
memcpy(vcd->buf,&vcd->entry.cdte_addr.msf,sizeof(vcd->entry.cdte_addr.msf));
if(ioctl(vcd->fd,CDROMREADRAW,vcd->buf)==-1) return 0; // EOF?
memcpy(mem,&vcd->buf[VCD_SECTOR_OFFS],VCD_SECTOR_DATA);
#else
+1 -1
View File
@@ -420,7 +420,7 @@ bool sub_read_all_packets(struct dec_sub *sub, struct sh_stream *sh)
// 23.976 FPS is used as default timebase for frame based formats
if (sub->video_fps && sh->sub->frame_based)
sub_speed *= sub->video_fps / 23.976;
sub_speed *= 23.976 / sub->video_fps;
if (opts->sub_fps && sub->video_fps)
sub_speed *= opts->sub_fps / sub->video_fps;
+4 -1
View File
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <math.h>
#include <libavutil/common.h>
#include <ass/ass.h>
@@ -142,9 +143,11 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res dim, double pts,
opts->ass_vsfilter_aspect_compat))
{
// Let's use the original video PAR for vsfilter compatibility:
scale = scale
double par = scale
* (ctx->video_params.d_w / (double)ctx->video_params.d_h)
/ (ctx->video_params.w / (double)ctx->video_params.h);
if (isnormal(par))
scale = par;
}
mp_ass_configure(renderer, opts, &dim);
ass_set_aspect_ratio(renderer, scale, 1);
+8 -3
View File
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <libavcodec/avcodec.h>
#include <libavutil/common.h>
@@ -182,11 +183,13 @@ static void decode(struct sd *sd, struct demux_packet *packet)
sub.num_rects);
for (int i = 0; i < sub.num_rects; i++) {
struct AVSubtitleRect *r = sub.rects[i];
struct sub_bitmap *b = &priv->inbitmaps[i];
struct osd_bmp_indexed *img = &priv->imgs[i];
struct sub_bitmap *b = &priv->inbitmaps[priv->count];
struct osd_bmp_indexed *img = &priv->imgs[priv->count];
if (!(r->flags & AV_SUBTITLE_FLAG_FORCED) &&
opts->forced_subs_only)
continue;
if (r->w == 0 || r->h == 0)
continue;
img->bitmap = r->pict.data[0];
assert(r->nb_colors > 0);
assert(r->nb_colors * 4 <= sizeof(img->palette));
@@ -234,9 +237,11 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res d, double pts,
if (priv->avctx->codec_id == AV_CODEC_ID_DVD_SUBTITLE &&
opts->stretch_dvd_subs) {
// For DVD subs, try to keep the subtitle PAR at display PAR.
video_par =
double par =
(priv->video_params.d_w / (double)priv->video_params.d_h)
/ (priv->video_params.w / (double)priv->video_params.h);
if (isnormal(par))
video_par = par;
}
int insize[2];
get_resolution(sd, insize);
+2 -30
View File
@@ -26,7 +26,6 @@
struct sd_spu_priv {
void *spudec;
struct mp_image_params video_params;
};
static bool is_dvd_sub(const char *t)
@@ -72,22 +71,8 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res d, double pts,
spudec_set_forced_subs_only(priv->spudec, opts->forced_subs_only);
spudec_heartbeat(priv->spudec, pts * 90000);
if (spudec_visible(priv->spudec)) {
double xscale = 1;
double yscale = 1;
if (opts->stretch_dvd_subs) {
// For DVD subs, try to keep the subtitle PAR at display PAR.
double video_par =
(priv->video_params.d_w / (double)priv->video_params.d_h)
/ (priv->video_params.w / (double)priv->video_params.h);
if (video_par > 1.0) {
xscale /= video_par;
} else {
yscale *= video_par;
}
}
spudec_get_indexed(priv->spudec, &d, xscale, yscale, res);
}
if (spudec_visible(priv->spudec))
spudec_get_indexed(priv->spudec, &d, 1, 1, res);
}
static void reset(struct sd *sd)
@@ -105,25 +90,12 @@ static void uninit(struct sd *sd)
talloc_free(priv);
}
static int control(struct sd *sd, enum sd_ctrl cmd, void *arg)
{
struct sd_spu_priv *priv = sd->priv;
switch (cmd) {
case SD_CTRL_SET_VIDEO_PARAMS:
priv->video_params = *(struct mp_image_params *)arg;
return CONTROL_OK;
default:
return CONTROL_UNKNOWN;
}
}
const struct sd_functions sd_spu = {
.name = "spu",
.supports_format = supports_format,
.init = init,
.decode = decode,
.get_bitmaps = get_bitmaps,
.control = control,
.reset = reset,
.uninit = uninit,
};
+1
View File
@@ -54,6 +54,7 @@ void *ta_find_parent(void *ptr);
// Utility functions
size_t ta_calc_array_size(size_t element_size, size_t count);
size_t ta_calc_prealloc_elems(size_t nextidx);
void *ta_new_context(void *ta_parent);
void *ta_steal_(void *ta_parent, void *ptr);
void *ta_memdup(void *ta_parent, void *ptr, size_t size);
+6 -3
View File
@@ -77,14 +77,17 @@ char *ta_talloc_asprintf_append_buffer(char *s, const char *fmt, ...) TA_PRF(2,
#define MP_TALLOC_ELEMS(p) (talloc_get_size(p) / sizeof((p)[0]))
#define MP_RESIZE_ARRAY(ctx, p, count) do { \
(p) = talloc_realloc_size((ctx), p, (count) * sizeof((p)[0])); } while (0)
#define MP_RESIZE_ARRAY(ctx, p, count) \
do { \
(p) = ta_xrealloc_size(ctx, p, \
ta_calc_array_size(sizeof((p)[0]), count)); \
} while (0)
#define MP_TARRAY_GROW(ctx, p, nextidx) \
do { \
size_t nextidx_ = (nextidx); \
if (nextidx_ >= MP_TALLOC_ELEMS(p)) \
MP_RESIZE_ARRAY(ctx, p, (nextidx_ + 1) * 2);\
MP_RESIZE_ARRAY(ctx, p, ta_calc_prealloc_elems(nextidx_)); \
} while (0)
#define MP_GROW_ARRAY(p, nextidx) MP_TARRAY_GROW(NULL, p, nextidx)
+11
View File
@@ -30,6 +30,17 @@ size_t ta_calc_array_size(size_t element_size, size_t count)
return element_size * count;
}
// This is used when an array has to be enlarged for appending new elements.
// Return a "good" size for the new array (in number of elements). This returns
// a value >= nextidx, unless the calculation overflows, in which case SIZE_MAX
// is returned.
size_t ta_calc_prealloc_elems(size_t nextidx)
{
if (nextidx >= ((size_t)-1) / 2 - 1)
return (size_t)-1;
return (nextidx + 1) * 2;
}
static void dummy_dtor(void *p){}
/* Create an empty (size 0) TA allocation, which is prepared in a way such that
-11
View File
@@ -436,17 +436,6 @@ int video_reconfig_filters(struct dec_video *d_video,
d_video->vf_input = p;
if (opts->gamma_gamma != 1000)
video_set_colors(d_video, "gamma", opts->gamma_gamma);
if (opts->gamma_brightness != 1000)
video_set_colors(d_video, "brightness", opts->gamma_brightness);
if (opts->gamma_contrast != 1000)
video_set_colors(d_video, "contrast", opts->gamma_contrast);
if (opts->gamma_saturation != 1000)
video_set_colors(d_video, "saturation", opts->gamma_saturation);
if (opts->gamma_hue != 1000)
video_set_colors(d_video, "hue", opts->gamma_hue);
return 0;
}
+4
View File
@@ -175,6 +175,10 @@ static int mp_chroma_div_up(int size, int shift)
// Caller has to make sure this doesn't exceed the allocated plane data/strides.
void mp_image_set_size(struct mp_image *mpi, int w, int h)
{
// av_image_check_size has similar checks and triggers around 16000*16000
if (w >= (1 << 14) || h >= (1 << 14) || w < 0 || h < 0)
abort();
mpi->w = mpi->display_w = w;
mpi->h = mpi->display_h = h;
for (int n = 0; n < mpi->num_planes; n++) {
+17 -20
View File
@@ -71,6 +71,9 @@ struct vo_cocoa_state {
void (*resize_redraw)(struct vo *vo, int w, int h);
struct mp_log *log;
uint32_t old_dwidth;
uint32_t old_dheight;
};
void *vo_cocoa_glgetaddr(const char *s)
@@ -218,8 +221,6 @@ static void vo_cocoa_update_screen_info(struct vo *vo)
aspect_save_screenres(vo, r.size.width, r.size.height);
opts->screenwidth = r.size.width;
opts->screenheight = r.size.height;
vo->xinerama_x = r.origin.x;
vo->xinerama_y = r.origin.y;
}
static void resize_window(struct vo *vo)
@@ -259,7 +260,7 @@ static void create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
struct vo_cocoa_state *s = vo->cocoa;
struct mp_vo_opts *opts = vo->opts;
const NSRect contentRect = NSMakeRect(0, 0, d_width, d_height);
const NSRect contentRect = NSMakeRect(vo->dx, vo->dy, d_width, d_height);
int window_mask = 0;
if (opts->border) {
@@ -273,7 +274,8 @@ static void create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
[[MpvVideoWindow alloc] initWithContentRect:contentRect
styleMask:window_mask
backing:NSBackingStoreBuffered
defer:NO];
defer:NO
screen:s->current_screen];
s->view = [[[MpvVideoView alloc] initWithFrame:contentRect] autorelease];
[s->view setWantsBestResolutionOpenGLSurface:YES];
@@ -296,7 +298,6 @@ static void create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
[s->window setDelegate:s->window];
[s->window makeMainWindow];
[s->window setFrameOrigin:NSMakePoint(vo->dx, vo->dy)];
[s->window makeKeyAndOrderFront:nil];
[NSApp activateIgnoringOtherApps:YES];
@@ -356,14 +357,6 @@ static void cocoa_set_window_title(struct vo *vo, const char *title)
talloc_free(talloc_ctx);
}
static void update_window(struct vo *vo, int d_width, int d_height)
{
struct vo_cocoa_state *s = vo->cocoa;
[s->window queueNewVideoSize:NSMakeSize(d_width, d_height)];
cocoa_set_window_title(vo, vo_get_window_title(vo));
vo_cocoa_fullscreen(vo);
}
static void vo_cocoa_resize_redraw(struct vo *vo, int width, int height)
{
struct vo_cocoa_state *s = vo->cocoa;
@@ -386,9 +379,8 @@ static void vo_cocoa_resize_redraw(struct vo *vo, int width, int height)
vo_cocoa_set_current_context(vo, false);
}
int vo_cocoa_config_window(struct vo *vo, uint32_t d_width,
uint32_t d_height, uint32_t flags,
int gl3profile)
int vo_cocoa_config_window(struct vo *vo, uint32_t width, uint32_t height,
uint32_t flags, int gl3profile)
{
struct vo_cocoa_state *s = vo->cocoa;
__block int ctxok = 0;
@@ -398,6 +390,10 @@ int vo_cocoa_config_window(struct vo *vo, uint32_t d_width,
s->enable_resize_redraw = false;
s->aspdat = vo->aspdat;
bool reset_size = s->old_dwidth != width || s->old_dheight != height;
s->old_dwidth = width;
s->old_dheight = height;
if (flags & VOFLAG_HIDDEN) {
// This is certainly the first execution of vo_config_window and
// is called in order for an OpenGL based VO to perform detection
@@ -417,16 +413,17 @@ int vo_cocoa_config_window(struct vo *vo, uint32_t d_width,
}
if (!s->window)
create_window(vo, d_width, d_height, flags);
create_window(vo, width, height, flags);
}
if (s->window) {
// Everything is properly initialized
update_window(vo, d_width, d_height);
if (reset_size)
[s->window queueNewVideoSize:NSMakeSize(width, height)];
cocoa_set_window_title(vo, vo_get_window_title(vo));
vo_cocoa_fullscreen(vo);
}
});
dispatch_sync(dispatch_get_main_queue(), ^{
s->inside_sync_section = false;
s->enable_resize_redraw = true;
});
+1
View File
@@ -20,6 +20,7 @@
#include <IOSurface/IOSurface.h>
#include <CoreVideo/CoreVideo.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/CGLIOSurface.h>
#include "video/decode/dec_video.h"
#include "cocoa_common.h"
+55 -72
View File
@@ -16,27 +16,10 @@
* with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <wayland-egl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include "wayland_common.h"
#include "gl_common.h"
struct egl_context {
EGLSurface egl_surface;
struct wl_egl_window *egl_window;
struct {
EGLDisplay dpy;
EGLContext ctx;
EGLConfig conf;
} egl;
};
static void egl_resize(struct vo_wayland_state *wl,
struct egl_context *ctx)
static void egl_resize(struct vo_wayland_state *wl)
{
int32_t x = wl->window.sh_x;
int32_t y = wl->window.sh_y;
@@ -45,7 +28,7 @@ static void egl_resize(struct vo_wayland_state *wl,
// get the real size of the window
// this improves moving the window while resizing it
wl_egl_window_get_attached_size(ctx->egl_window,
wl_egl_window_get_attached_size(wl->egl_context.egl_window,
&wl->window.width,
&wl->window.height);
@@ -60,7 +43,7 @@ static void egl_resize(struct vo_wayland_state *wl,
if (y != 0)
y = wl->window.height - height;
wl_egl_window_resize(ctx->egl_window, width, height, x, y);
wl_egl_window_resize(wl->egl_context.egl_window, width, height, x, y);
wl->window.width = width;
wl->window.height = height;
@@ -74,7 +57,6 @@ static void egl_resize(struct vo_wayland_state *wl,
}
static bool egl_create_context(struct vo_wayland_state *wl,
struct egl_context *egl_ctx,
MPGLContext *ctx,
bool enable_alpha)
{
@@ -83,7 +65,7 @@ static bool egl_create_context(struct vo_wayland_state *wl,
GL *gl = ctx->gl;
const char *eglstr = "";
if (!(egl_ctx->egl.dpy = eglGetDisplay(wl->display.display)))
if (!(wl->egl_context.egl.dpy = eglGetDisplay(wl->display.display)))
return false;
EGLint config_attribs[] = {
@@ -98,7 +80,7 @@ static bool egl_create_context(struct vo_wayland_state *wl,
};
/* major and minor here returns the supported EGL version (e.g.: 1.4) */
if (eglInitialize(egl_ctx->egl.dpy, &major, &minor) != EGL_TRUE)
if (eglInitialize(wl->egl_context.egl.dpy, &major, &minor) != EGL_TRUE)
return false;
MP_VERBOSE(wl, "EGL version %d.%d\n", major, minor);
@@ -106,38 +88,36 @@ static bool egl_create_context(struct vo_wayland_state *wl,
EGLint context_attribs[] = {
EGL_CONTEXT_MAJOR_VERSION_KHR,
MPGL_VER_GET_MAJOR(ctx->requested_gl_version),
/* EGL_CONTEXT_MINOR_VERSION_KHR, */
/* MPGL_VER_GET_MINOR(ctx->requested_gl_version), */
/* EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, 0, */
/* Segfaults on anything else than the major version */
EGL_NONE
};
if (eglBindAPI(EGL_OPENGL_API) != EGL_TRUE)
return false;
eglChooseConfig(egl_ctx->egl.dpy, config_attribs,
&egl_ctx->egl.conf, 1, &n);
eglChooseConfig(wl->egl_context.egl.dpy, config_attribs,
&wl->egl_context.egl.conf, 1, &n);
egl_ctx->egl.ctx = eglCreateContext(egl_ctx->egl.dpy,
egl_ctx->egl.conf,
EGL_NO_CONTEXT,
context_attribs);
if (!egl_ctx->egl.ctx) {
wl->egl_context.egl.ctx = eglCreateContext(wl->egl_context.egl.dpy,
wl->egl_context.egl.conf,
EGL_NO_CONTEXT,
context_attribs);
if (!wl->egl_context.egl.ctx) {
/* fallback to any GL version */
MP_WARN(wl, "can't create context for requested OpenGL version: "
"fall back to any version available\n");
context_attribs[0] = EGL_NONE;
egl_ctx->egl.ctx = eglCreateContext(egl_ctx->egl.dpy,
egl_ctx->egl.conf,
EGL_NO_CONTEXT,
context_attribs);
wl->egl_context.egl.ctx = eglCreateContext(wl->egl_context.egl.dpy,
wl->egl_context.egl.conf,
EGL_NO_CONTEXT,
context_attribs);
if (!egl_ctx->egl.ctx)
if (!wl->egl_context.egl.ctx)
return false;
}
eglMakeCurrent(egl_ctx->egl.dpy, NULL, NULL, egl_ctx->egl.ctx);
eglMakeCurrent(wl->egl_context.egl.dpy, NULL, NULL, wl->egl_context.egl.ctx);
eglstr = eglQueryString(egl_ctx->egl.dpy, EGL_EXTENSIONS);
eglstr = eglQueryString(wl->egl_context.egl.dpy, EGL_EXTENSIONS);
mpgl_load_functions(gl, (void*(*)(const GLubyte*))eglGetProcAddress, eglstr,
wl->log);
@@ -148,26 +128,24 @@ static bool egl_create_context(struct vo_wayland_state *wl,
}
static void egl_create_window(struct vo_wayland_state *wl,
struct egl_context *egl_ctx,
uint32_t width,
uint32_t height)
{
egl_ctx->egl_window = wl_egl_window_create(wl->window.surface,
wl->window.width,
wl->window.height);
wl->egl_context.egl_window = wl_egl_window_create(wl->window.surface,
wl->window.width,
wl->window.height);
egl_ctx->egl_surface = eglCreateWindowSurface(egl_ctx->egl.dpy,
egl_ctx->egl.conf,
egl_ctx->egl_window,
NULL);
wl->egl_context.egl_surface = eglCreateWindowSurface(wl->egl_context.egl.dpy,
wl->egl_context.egl.conf,
wl->egl_context.egl_window,
NULL);
eglMakeCurrent(egl_ctx->egl.dpy,
egl_ctx->egl_surface,
egl_ctx->egl_surface,
egl_ctx->egl.ctx);
eglMakeCurrent(wl->egl_context.egl.dpy,
wl->egl_context.egl_surface,
wl->egl_context.egl_surface,
wl->egl_context.egl.ctx);
wl_display_dispatch_pending(wl->display.display);
}
static bool config_window_wayland(struct MPGLContext *ctx,
@@ -175,7 +153,6 @@ static bool config_window_wayland(struct MPGLContext *ctx,
uint32_t d_height,
uint32_t flags)
{
struct egl_context * egl_ctx = ctx->priv;
struct vo_wayland_state * wl = ctx->vo->wayland;
bool enable_alpha = !!(flags & VOFLAG_ALPHA);
bool ret = false;
@@ -183,23 +160,23 @@ static bool config_window_wayland(struct MPGLContext *ctx,
if (!vo_wayland_config(ctx->vo, d_width, d_height, flags))
return false;
if (!egl_ctx->egl.ctx) {
if (!wl->egl_context.egl.ctx) {
/* Create OpenGL context */
ret = egl_create_context(wl, egl_ctx, ctx, enable_alpha);
ret = egl_create_context(wl, ctx, enable_alpha);
/* If successfully created the context and we don't want to hide the
* window than also create the window immediately */
if (ret && !(VOFLAG_HIDDEN & flags))
egl_create_window(wl, egl_ctx, d_width, d_height);
egl_create_window(wl, d_width, d_height);
return ret;
}
else {
if (!egl_ctx->egl_window) {
if (!wl->egl_context.egl_window) {
/* If the context exists and the hidden flag is unset then
* create the window */
if (!(VOFLAG_HIDDEN & flags))
egl_create_window(wl, egl_ctx, d_width, d_height);
egl_create_window(wl, d_width, d_height);
}
return true;
}
@@ -208,35 +185,41 @@ static bool config_window_wayland(struct MPGLContext *ctx,
static void releaseGlContext_wayland(MPGLContext *ctx)
{
GL *gl = ctx->gl;
struct egl_context * egl_ctx = ctx->priv;
struct vo_wayland_state *wl = ctx->vo->wayland;
gl->Finish();
eglMakeCurrent(egl_ctx->egl.dpy, NULL, NULL, EGL_NO_CONTEXT);
eglDestroyContext(egl_ctx->egl.dpy, egl_ctx->egl.ctx);
eglTerminate(egl_ctx->egl.dpy);
eglReleaseThread();
wl_egl_window_destroy(egl_ctx->egl_window);
egl_ctx->egl.ctx = NULL;
wl_egl_window_destroy(wl->egl_context.egl_window);
eglDestroySurface(wl->egl_context.egl.dpy, wl->egl_context.egl_surface);
eglMakeCurrent(wl->egl_context.egl.dpy, NULL, NULL, EGL_NO_CONTEXT);
eglDestroyContext(wl->egl_context.egl.dpy, wl->egl_context.egl.ctx);
eglTerminate(wl->egl_context.egl.dpy);
wl->egl_context.egl.ctx = NULL;
}
static void swapGlBuffers_wayland(MPGLContext *ctx)
{
struct egl_context * egl_ctx = ctx->priv;
struct vo_wayland_state *wl = ctx->vo->wayland;
eglSwapBuffers(wl->egl_context.egl.dpy, wl->egl_context.egl_surface);
}
eglSwapBuffers(egl_ctx->egl.dpy, egl_ctx->egl_surface);
static int control(struct vo *vo, int *events, int request, void *data)
{
struct vo_wayland_state *wl = vo->wayland;
int r = vo_wayland_control(vo, events, request, data);
if (wl->window.events & VO_EVENT_RESIZE)
egl_resize(wl, egl_ctx);
if (*events & VO_EVENT_RESIZE)
egl_resize(wl);
return r;
}
void mpgl_set_backend_wayland(MPGLContext *ctx)
{
ctx->priv = talloc_zero(ctx, struct egl_context);
ctx->config_window = config_window_wayland;
ctx->releaseGlContext = releaseGlContext_wayland;
ctx->swapGlBuffers = swapGlBuffers_wayland;
ctx->vo_control = vo_wayland_control;
ctx->vo_control = control;
ctx->vo_init = vo_wayland_init;
ctx->vo_uninit = vo_wayland_uninit;
}
+1
View File
@@ -25,6 +25,7 @@
#include <QuartzCore/QuartzCore.h>
#if HAVE_VDA_HWACCEL
#include <IOSurface/IOSurface.h>
#include <OpenGL/CGLIOSurface.h>
#endif
#include <assert.h>
+62 -56
View File
@@ -149,7 +149,7 @@ struct priv {
// options
int enable_alpha;
int use_default;
int use_rgb565;
};
/* copied from weston clients */
@@ -232,6 +232,21 @@ static bool is_alpha_format(const struct fmtentry *fmt)
return !!(mp_imgfmt_get_desc(fmt->mp_fmt).flags & MP_IMGFLAG_ALPHA);
}
static const struct fmtentry * is_wayland_format_supported(struct priv *p,
enum wl_shm_format fmt)
{
struct supported_format *sf;
// find the matching format first
wl_list_for_each(sf, &p->format_list, link) {
if (sf->fmt->wl_fmt == fmt) {
return sf->fmt;
}
}
return NULL;
}
static void buffer_swap(struct priv *p)
{
if (!p->back_buffer->is_new)
@@ -240,9 +255,6 @@ static void buffer_swap(struct priv *p)
struct buffer *tmp = p->back_buffer;
p->back_buffer = p->front_buffer;
p->front_buffer = tmp;
// after swap set is_new to false, but keep busy
p->back_buffer->is_new = false;
}
@@ -250,31 +262,30 @@ static void buffer_swap(struct priv *p)
// is busy (unlikely)
static struct buffer * buffer_get_back(struct priv *p)
{
if (p->back_buffer->is_new || p->back_buffer->is_busy)
if (p->back_buffer->is_busy)
return NULL;
p->back_buffer->is_busy = true;
return p->back_buffer;
}
static bool buffer_finalise_back(struct priv *p)
static bool buffer_finalise_back(struct buffer *buf)
{
p->back_buffer->is_new = true;
p->back_buffer->is_busy = false;
buf->is_new = true;
return true;
}
static struct buffer * buffer_get_front(struct priv *p)
{
if (!p->front_buffer->is_new)
return NULL;
p->front_buffer->is_busy = true;
return p->front_buffer;
}
static bool buffer_finalise_front(struct priv *p)
static bool buffer_finalise_front(struct buffer *buf)
{
p->front_buffer->is_new = false; // is_busy is reset on handle_release
buf->is_new = false; // is_busy is reset on handle_release
return true;
}
@@ -469,36 +480,30 @@ static void frame_handle_redraw(void *data,
struct vo_wayland_state *wl = p->wl;
struct buffer *buf = buffer_get_front(p);
if (p->resize_attach) {
if (buf) {
wl_surface_attach(wl->window.surface, buf->wlbuf, p->x, p->y);
wl_surface_damage(wl->window.surface, 0, 0, p->dst_w, p->dst_h);
wl_surface_commit(wl->window.surface);
if (callback)
wl_callback_destroy(callback);
p->redraw_callback = NULL;
buffer_finalise_front(p);
p->resize_attach = false;
p->redraw_callback = wl_surface_frame(wl->window.surface);
wl_callback_add_listener(p->redraw_callback, &frame_listener, p);
wl_surface_commit(wl->window.surface);
buffer_finalise_front(buf);
destroy_shm_buffer(&p->tmp_buffer);
// I have to destroy the callback and return early to avoid black flickers
// I don't exactly know why this, but I guess the back buffer is still
// empty. The callback loop will be restored on the next flip_page call
return;
// to avoid multiple resizes of non-shown frames
if (p->resize_attach) {
destroy_shm_buffer(&p->tmp_buffer);
p->resize_attach = false;
}
}
else {
if (callback)
wl_callback_destroy(callback);
wl_surface_attach(wl->window.surface, buf->wlbuf, 0, 0);
wl_surface_damage(wl->window.surface, 0, 0, p->dst_w, p->dst_h);
if (callback)
wl_callback_destroy(callback);
p->redraw_callback = wl_surface_frame(wl->window.surface);
wl_callback_add_listener(p->redraw_callback, &frame_listener, p);
wl_surface_commit(wl->window.surface);
buffer_finalise_front(p);
p->redraw_callback = NULL;
}
}
static const struct wl_callback_listener frame_listener = {
@@ -535,7 +540,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
struct buffer *buf = buffer_get_back(p);
if (!buf) {
MP_WARN(p->wl, "can't draw, back buffer is busy\n");
MP_VERBOSE(p->wl, "can't draw, back buffer is busy\n");
return;
}
@@ -549,7 +554,7 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
mp_sws_scale(p->sws, &img, &src);
mp_image_setrefp(&p->original_image, mpi);
buffer_finalise_back(p);
buffer_finalise_back(buf);
}
static void draw_osd(struct vo *vo, struct osd_state *osd)
@@ -566,7 +571,7 @@ static void flip_page(struct vo *vo)
buffer_swap(p);
if (!p->redraw_callback) {
MP_INFO(p->wl, "restart frame callback\n");
MP_DBG(p->wl, "restart frame callback\n");
frame_handle_redraw(p, NULL, 0);
}
}
@@ -591,13 +596,13 @@ static int reconfig(struct vo *vo, struct mp_image_params *fmt, int flags)
struct priv *p = vo->priv;
mp_image_unrefp(&p->original_image);
p->width = vo->dwidth;
p->height = vo->dheight;
p->width = fmt->w;
p->height = fmt->h;
p->in_format = *fmt;
struct supported_format *sf;
// find the same format first
// find the matching format first
wl_list_for_each(sf, &p->format_list, link) {
if (sf->fmt->mp_fmt == fmt->imgfmt && (p->enable_alpha == sf->is_alpha)) {
p->pref_format = sf->fmt;
@@ -605,25 +610,22 @@ static int reconfig(struct vo *vo, struct mp_image_params *fmt, int flags)
}
}
// if the format is not supported choose one of the fancy formats next
// the default formats are always last
if (!p->pref_format) {
wl_list_for_each(sf, &p->format_list, link) {
if (p->enable_alpha == sf->is_alpha) {
p->pref_format = sf->fmt;
break;
}
}
}
// if use default is enable overwrite the auto selected one
if (p->use_default) {
// if use default is enable overwrite the auto selected one
if (p->enable_alpha)
p->pref_format = &fmttable[DEFAULT_ALPHA_FORMAT_ENTRY];
else
p->pref_format = &fmttable[DEFAULT_FORMAT_ENTRY];
}
// overides alpha
// use rgb565 if performance is your main concern
if (p->use_rgb565) {
const struct fmtentry *mp_fmt =
is_wayland_format_supported(p, WL_SHM_FORMAT_RGB565);
if (mp_fmt)
p->pref_format = mp_fmt;
}
p->bytes_per_pixel = mp_imgfmt_get_desc(p->pref_format->mp_fmt).bytes[0];
MP_VERBOSE(p->wl, "bytes per pixel: %d\n", p->bytes_per_pixel);
@@ -635,6 +637,9 @@ static int reconfig(struct vo *vo, struct mp_image_params *fmt, int flags)
vo_wayland_config(vo, vo->dwidth, vo->dheight, flags);
if (p->wl->window.events & VO_EVENT_RESIZE)
resize(p);
return 0;
}
@@ -644,6 +649,9 @@ static void uninit(struct vo *vo)
for (int i = 0; i < MAX_BUFFERS; ++i)
destroy_shm_buffer(&p->buffers[i]);
if (p->redraw_callback)
wl_callback_destroy(p->redraw_callback);
talloc_free(p->original_image);
vo_wayland_uninit(vo);
@@ -653,10 +661,8 @@ static int preinit(struct vo *vo)
{
struct priv *p = vo->priv;
if (!vo_wayland_init(vo)) {
MP_ERR(p->wl, "could not initalise backend\n");
if (!vo_wayland_init(vo))
return -1;
}
p->vo = vo;
p->wl = vo->wayland;
@@ -724,7 +730,7 @@ const struct vo_driver video_out_wayland = {
.uninit = uninit,
.options = (const struct m_option[]) {
OPT_FLAG("alpha", enable_alpha, 0),
OPT_FLAG("default-format", use_default, 0),
OPT_FLAG("rgb565", use_rgb565, 0),
{0}
},
};
+2 -1
View File
@@ -486,7 +486,7 @@ static int reinit_window_state(struct vo *vo)
DWORD style = update_style(vo, GetWindowLong(w32->window, GWL_STYLE));
if (vo->opts->fullscreen || vo->opts->ontop)
if (vo->opts->ontop)
layer = HWND_TOPMOST;
// xxx not sure if this can trigger any unwanted messages (WM_MOVE/WM_SIZE)
@@ -506,6 +506,7 @@ static int reinit_window_state(struct vo *vo)
vo->dheight = vo->opts->screenheight;
w32->window_x = vo->xinerama_x;
w32->window_y = vo->xinerama_y;
style &= ~WS_OVERLAPPEDWINDOW;
} else {
if (toggle_fs) {
// Restore window position and size when switching from fullscreen.
+86 -46
View File
@@ -144,7 +144,7 @@ static void display_handle_delete_id(void *data,
MP_DBG(wl, "Object %u deleted\n", id);
}
const struct wl_display_listener display_listener = {
static const struct wl_display_listener display_listener = {
display_handle_error,
display_handle_delete_id
};
@@ -171,7 +171,7 @@ static void ssurface_handle_popup_done(void *data,
{
}
const struct wl_shell_surface_listener shell_surface_listener = {
static const struct wl_shell_surface_listener shell_surface_listener = {
ssurface_handle_ping,
ssurface_handle_configure,
ssurface_handle_popup_done
@@ -220,7 +220,7 @@ static void output_handle_mode(void *data,
output->flags = flags;
}
const struct wl_output_listener output_listener = {
static const struct wl_output_listener output_listener = {
output_handle_geometry,
output_handle_mode
};
@@ -329,7 +329,7 @@ static void keyboard_handle_modifiers(void *data,
0, 0, group);
}
const struct wl_keyboard_listener keyboard_listener = {
static const struct wl_keyboard_listener keyboard_listener = {
keyboard_handle_keymap,
keyboard_handle_enter,
keyboard_handle_leave,
@@ -443,7 +443,6 @@ static void seat_handle_capabilities(void *data,
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !wl->input.keyboard) {
wl->input.keyboard = wl_seat_get_keyboard(seat);
wl_keyboard_set_user_data(wl->input.keyboard, wl);
wl_keyboard_add_listener(wl->input.keyboard, &keyboard_listener, wl);
}
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && wl->input.keyboard) {
@@ -452,7 +451,6 @@ static void seat_handle_capabilities(void *data,
}
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wl->input.pointer) {
wl->input.pointer = wl_seat_get_pointer(seat);
wl_pointer_set_user_data(wl->input.pointer, wl);
wl_pointer_add_listener(wl->input.pointer, &pointer_listener, wl);
}
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wl->input.pointer) {
@@ -466,13 +464,12 @@ static const struct wl_seat_listener seat_listener = {
};
static void registry_handle_global (void *data,
struct wl_registry *registry,
struct wl_registry *reg,
uint32_t id,
const char *interface,
uint32_t version)
{
struct vo_wayland_state *wl = data;
struct wl_registry *reg = wl->display.registry;
if (strcmp(interface, "wl_compositor") == 0) {
@@ -578,6 +575,8 @@ static void shedule_resize(struct vo_wayland_state *wl,
int32_t x, y;
float temp_aspect = width / (float) MPMAX(height, 1);
MP_DBG(wl, "shedule resize: %dx%d\n", width, height);
if (width < minimum_size)
width = minimum_size;
@@ -587,29 +586,27 @@ static void shedule_resize(struct vo_wayland_state *wl,
// don't keep the aspect ration in fullscreen mode, because the compositor
// shows the desktop in the border regions if the video has not the same
// aspect ration as the screen
if (!wl->window.is_fullscreen) {
/* if only the height is changed we have to calculate the width
* in any other case we calculate the height */
switch (edges) {
case WL_SHELL_SURFACE_RESIZE_TOP:
case WL_SHELL_SURFACE_RESIZE_BOTTOM:
/* if only the height is changed we have to calculate the width
* in any other case we calculate the height */
switch (edges) {
case WL_SHELL_SURFACE_RESIZE_TOP:
case WL_SHELL_SURFACE_RESIZE_BOTTOM:
width = wl->window.aspect * height;
break;
case WL_SHELL_SURFACE_RESIZE_LEFT:
case WL_SHELL_SURFACE_RESIZE_RIGHT:
case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: // just a preference
case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
height = (1 / wl->window.aspect) * width;
break;
default:
if (wl->window.aspect < temp_aspect)
width = wl->window.aspect * height;
break;
case WL_SHELL_SURFACE_RESIZE_LEFT:
case WL_SHELL_SURFACE_RESIZE_RIGHT:
case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: // just a preference
case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
else
height = (1 / wl->window.aspect) * width;
break;
default:
if (wl->window.aspect < temp_aspect)
width = wl->window.aspect * height;
else
height = (1 / wl->window.aspect) * width;
break;
}
break;
}
if (edges & WL_SHELL_SURFACE_RESIZE_LEFT)
@@ -634,6 +631,9 @@ static void shedule_resize(struct vo_wayland_state *wl,
static bool create_display (struct vo_wayland_state *wl)
{
if (wl->vo->probing && !getenv("XDG_RUNTIME_DIR"))
return false;
wl->display.display = wl_display_connect(NULL);
if (!wl->display.display) {
@@ -646,7 +646,6 @@ static bool create_display (struct vo_wayland_state *wl)
wl_display_add_listener(wl->display.display, &display_listener, wl);
wl_list_init(&wl->display.output_list);
wl->display.registry = wl_display_get_registry(wl->display.display);
wl_registry_add_listener(wl->display.registry, &registry_listener, wl);
@@ -659,15 +658,33 @@ static bool create_display (struct vo_wayland_state *wl)
static void destroy_display (struct vo_wayland_state *wl)
{
struct vo_wayland_output *output = NULL;
struct vo_wayland_output *tmp = NULL;
wl_list_for_each_safe(output, tmp, &wl->display.output_list, link) {
if (output && output->output) {
wl_output_destroy(output->output);
output->output = NULL;
wl_list_remove(&output->link);
}
}
if (wl->display.shm)
wl_shm_destroy(wl->display.shm);
if (wl->display.shell)
wl_shell_destroy(wl->display.shell);
if (wl->display.compositor)
wl_compositor_destroy(wl->display.compositor);
wl_registry_destroy(wl->display.registry);
wl_display_flush(wl->display.display);
wl_display_disconnect(wl->display.display);
if (wl->display.registry)
wl_registry_destroy(wl->display.registry);
if (wl->display.display) {
wl_display_flush(wl->display.display);
wl_display_disconnect(wl->display.display);
}
}
static bool create_window (struct vo_wayland_state *wl)
@@ -692,8 +709,11 @@ static bool create_window (struct vo_wayland_state *wl)
static void destroy_window (struct vo_wayland_state *wl)
{
wl_shell_surface_destroy(wl->window.shell_surface);
wl_surface_destroy(wl->window.surface);
if (wl->window.shell_surface)
wl_shell_surface_destroy(wl->window.shell_surface);
if (wl->window.surface)
wl_surface_destroy(wl->window.surface);
}
static bool create_cursor (struct vo_wayland_state *wl)
@@ -742,9 +762,11 @@ static void destroy_input (struct vo_wayland_state *wl)
wl_keyboard_destroy(wl->input.keyboard);
xkb_map_unref(wl->input.xkb.keymap);
xkb_state_unref(wl->input.xkb.state);
xkb_context_unref(wl->input.xkb.context);
}
if (wl->input.xkb.context)
xkb_context_unref(wl->input.xkb.context);
if (wl->input.pointer)
wl_pointer_destroy(wl->input.pointer);
@@ -762,11 +784,14 @@ int vo_wayland_init (struct vo *vo)
wl->vo = vo;
wl->log = mp_log_new(wl, vo->log, "wayland");
wl_list_init(&wl->display.output_list);
if (!create_input(wl)
|| !create_display(wl)
|| !create_window(wl)
|| !create_cursor(wl))
{
vo_wayland_uninit(vo);
return false;
}
@@ -788,12 +813,11 @@ void vo_wayland_uninit (struct vo *vo)
static void vo_wayland_ontop (struct vo *vo)
{
vo->opts->ontop = !vo->opts->ontop;
vo->opts->fullscreen = !vo->opts->fullscreen;
/* use the already existing code to leave fullscreen mode and go into
* toplevel mode */
vo_wayland_fullscreen(vo);
struct vo_wayland_state *wl = vo->wayland;
MP_DBG(wl, "going ontop\n");
vo->opts->ontop = 1;
wl_shell_surface_set_toplevel(wl->window.shell_surface);
shedule_resize(wl, 0, wl->window.width, wl->window.height);
}
static void vo_wayland_border (struct vo *vo)
@@ -919,6 +943,9 @@ static void vo_wayland_update_screeninfo (struct vo *vo)
}
}
wl->window.fs_width = opts->screenwidth;
wl->window.fs_height = opts->screenheight;
aspect_save_screenres(vo, opts->screenwidth, opts->screenheight);
}
@@ -980,13 +1007,26 @@ bool vo_wayland_config (struct vo *vo, uint32_t d_width,
{
struct vo_wayland_state *wl = vo->wayland;
wl->window.width = d_width;
wl->window.height = d_height;
wl->window.p_width = d_width;
wl->window.p_height = d_height;
wl->window.aspect = wl->window.width / (float) MPMAX(wl->window.height, 1);
wl->window.aspect = d_width / (float) MPMAX(d_height, 1);
vo_wayland_fullscreen(vo);
if (!(flags & VOFLAG_HIDDEN)) {
if (!wl->window.is_init) {
wl->window.width = d_width;
wl->window.height = d_height;
}
if (vo->opts->fullscreen) {
if (wl->window.is_fullscreen)
shedule_resize(wl, 0, wl->window.fs_width, wl->window.fs_height);
else
vo_wayland_fullscreen(vo);
}
else
vo_wayland_ontop(vo);
wl->window.is_init = true;
}
return true;
}
+24 -1
View File
@@ -27,6 +27,12 @@
#include "config.h"
#if HAVE_GL_WAYLAND
#include <wayland-egl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#endif
struct vo;
struct vo_wayland_output {
@@ -43,6 +49,20 @@ struct vo_wayland_state {
struct vo *vo;
struct mp_log* log;
#if HAVE_GL_WAYLAND
struct {
EGLSurface egl_surface;
struct wl_egl_window *egl_window;
struct {
EGLDisplay dpy;
EGLContext ctx;
EGLConfig conf;
} egl;
} egl_context;
#endif
struct {
int fd;
struct wl_display *display;
@@ -60,7 +80,7 @@ struct vo_wayland_state {
} display;
struct {
int32_t width;
int32_t width; // current size of the window
int32_t height;
int32_t p_width; // previous sizes for leaving fullscreen
int32_t p_height;
@@ -70,7 +90,10 @@ struct vo_wayland_state {
int32_t sh_y;
float aspect;
bool is_init; // true if the window has a valid size
bool is_fullscreen; // don't keep aspect ratio in fullscreen mode
int32_t fs_width; // fullscreen sizes
int32_t fs_height;
struct wl_surface *surface;
int32_t mouse_x; // mouse position inside the surface
+14 -1
View File
@@ -3,7 +3,8 @@ from waftools.checks.generic import *
from waflib import Utils
import os
__all__ = ["check_pthreads", "check_iconv", "check_lua", "check_oss_4front"]
__all__ = ["check_pthreads", "check_iconv", "check_lua", "check_oss_4front",
"check_cocoa"]
pthreads_program = load_fragment('pthreads.c')
@@ -51,10 +52,12 @@ def check_lua(ctx, dependency_identifier):
lua_versions = [
( '51', 'lua >= 5.1.0 lua < 5.2.0'),
( '51deb', 'lua5.1 >= 5.1.0'), # debian
( '51fbsd', 'lua-5.1 >= 5.1.0'), # FreeBSD
( 'luajit', 'luajit >= 2.0.0' ),
# assume all our dependencies (libquvi in particular) link with 5.1
( '52', 'lua >= 5.2.0' ),
( '52deb', 'lua5.2 >= 5.2.0'), # debian
( '52fbsd', 'lua-5.2 >= 5.2.0'), # FreeBSD
]
if ctx.options.LUA_VER:
@@ -101,3 +104,13 @@ def check_oss_4front(ctx, dependency_identifier):
fragment=load_fragment('oss_audio.c'))
return fn(ctx, dependency_identifier)
def check_cocoa(ctx, dependency_identifier):
fn = check_cc(
fragment = load_fragment('cocoa.m'),
compile_filename = 'test.m',
framework_name = ['Cocoa', 'IOKit', 'OpenGL'],
includes = ctx.srcnode.abspath(),
linkflags = '-fobjc-arc')
return fn(ctx, dependency_identifier)
+2
View File
@@ -2,6 +2,8 @@
#import <OpenGL/OpenGL.h>
#import <Cocoa/Cocoa.h>
#include "osdep/macosx_compat.h"
int main(int argc, char **argv) {
@autoreleasepool {
NSArray *ary = @[@1, @2, @3];
+1 -1
View File
@@ -6,7 +6,7 @@ def __get_version__(ctx):
cwd=ctx.srcnode.abspath())
process.wait()
(version, err) = process.communicate()
return version.strip()
return version.strip().decode("utf-8")
def __get_build_date__():
import time
+25 -7
View File
@@ -77,7 +77,7 @@ main_dependencies = [
'desc': 'linker support for --nxcompat --no-seh --dynamicbase',
'func': check_cc(linkflags=['-Wl,--nxcompat', '-Wl,--no-seh', '-Wl,--dynamicbase'])
}, {
'name': 'ebx_available',
'name': 'ebx-available',
'desc': 'ebx availability',
'func': check_cc(fragment=load_fragment('ebx.c'))
} , {
@@ -98,6 +98,27 @@ main_dependencies = [
'func': check_pthreads,
'req': True,
'fmsg': 'Unable to find pthreads support.'
}, {
'name': 'atomic-builtins',
'desc': 'compiler support for __atomic built-ins',
'func': check_libs(['atomic'],
check_statement('stdint.h',
'int64_t test = 0;'
'test = __atomic_add_fetch(&test, 1, __ATOMIC_SEQ_CST)'))
}, {
'name': 'sync-builtins',
'desc': 'compiler support for __sync built-ins',
'func': check_statement('stdint.h',
'int64_t test = 0;'
'test = __sync_add_and_fetch(&test, 1)'),
'deps_neg': [ 'atomic-builtins' ],
}, {
'name': 'thread-synchronization-builtins',
'desc': 'compiler support for usable thread synchronization built-ins',
'func': check_true,
'deps_any': ['atomic-builtins', 'sync-builtins'],
'req': True,
'fmsg': 'your compiler must support either __atomic or __sync built-ins',
}, {
'name': 'librt',
'desc': 'linking with -lrt',
@@ -314,6 +335,7 @@ Libav libraries ({0}). Aborting.".format(" ".join(libav_pkg_config_checks))
'name': '--libswresample',
'desc': 'libswresample',
'func': check_pkg_config('libswresample', '>= 0.17.102'),
'deps_neg': ['libavresample'],
}, {
'name': 'resampler',
'desc': 'usable resampler found',
@@ -477,11 +499,7 @@ video_output_features = [
{
'name': '--cocoa',
'desc': 'Cocoa',
'func': check_cc(
fragment=load_fragment('cocoa.m'),
compile_filename='test.m',
framework_name=['Cocoa', 'IOKit', 'OpenGL'],
linkflags='-fobjc-arc')
'func': check_cocoa
} , {
'name': 'gdi',
'desc': 'GDI',
@@ -748,7 +766,7 @@ def options(opt):
group.add_option('--lua',
type = 'string',
dest = 'LUA_VER',
help = "select Lua package which should be autodetected. Choices: 51 51deb 52 52deb luajit")
help = "select Lua package which should be autodetected. Choices: 51 51deb 51fbsd 52 52deb 52fbsd luajit")
@conf
def is_debug_build(ctx):