Compare commits

...
68 Commits
Author SHA1 Message Date
wm4 c6bb684d55 Release 0.3.11 2014-06-14 14:08:26 +02:00
Philip Sequeira 4c97c3a1b3 build: version string as native str type for each Python version
Should resolve the "mpv b'...'" issue on Python 3 without breaking
things on Python 2.

Also, remove redundant wait for process.
2014-06-14 14:07:24 +02:00
wm4 4b36023273 tv: add missing header for clock_gettime
Not sure how this symbol becomes visible in glibc (probably accidental
or mandatory recursive inclusion via the other standard or Linux-
specific headers), but normally this include file is needed to get the
symbol.
2014-06-14 14:07:24 +02:00
wm4 864a2da9ea input.conf: make ESC quit when encoding 2014-06-14 14:07:23 +02:00
wm4 e6ac54e333 demux: use av_malloc for packets
Probably "needed" to get the correct alignment, although I'm not aware
of actual breakages or performance issues.

In fact we should probably always just allocate AVPackets, but for now
use the simple fix.
2014-06-14 14:07:23 +02:00
wm4 54c2a95792 demux: simplify packet resizing
Actually we don't need to resize packets; we just need to make them
shorter.
2014-06-14 14:07:23 +02:00
wm4 661633b689 demux: fix compilation with FFmpeg git
FFmpeg requires a bullshit padding after each input buffer, and they
just increased that padding without warning and without ABI or API bump.

We need this only in one file (although mp_image hardcodes something
similar, for which no FFmpeg API define is available), so drop our own
define.
2014-06-14 14:07:23 +02:00
iive a0eea7aba8 tv: use correct timestamps
Squashed from the following mplayer-svn commits. The '#' is removed from
the bug ID to prevent github from doing something stupid. Instead of
adding the mplayer configure check for clock_gettime(), the POSIX
identifiers are used for checking presence of the function.

Use correct type of timestamps when recording from v4l2. Fix 2176

Patch by Jarek Czekalski <jarekczek at poczta onet pl>.

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@37222 b3059339-0415-0410-9bf9-f77b7e298cf2

Allow building of v4l2 without clock_gettime().
Add overly verbose message in case monotone timestamps are required by the kernel.

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@37223 b3059339-0415-0410-9bf9-f77b7e298cf2
2014-06-14 14:07:23 +02:00
wm4 9de0db208d ao_alsa: make device the first sub option
This is more convenient.
2014-06-14 14:07:23 +02:00
wm4 d52c491fec tv: remove sysinfo() usage
This call was used limited the buffer size if installed RAM was below 16
MB. This stopped being useful a decade ago. The check could also
overflow on 32 bit systems. Just get rid of it.

old-configure changes skipped when cherry-picking for stable.

Conflicts:
	old-configure
2014-06-14 14:07:23 +02:00
wm4 ff2e39a3d2 vaapi: fix destruction with --hwdec=haapi-copy
This is incomplete; the video chain will still hold some vaapi objects
after destroying the decoder and thus the vaapi context. This is very
bad. Fixing it would require something like refcounting the vaapi
context, but I don't really want to.
2014-06-14 14:07:15 +02:00
wm4 844656d135 vo_vaapi: cleanup error handling on init
Close the X connection if initializing vaapi fails.
2014-06-14 13:51:14 +02:00
wm4 c0f85c18f8 video: better handling for (very) broken timestamps
Sometimes, Matroska files store monotonic PTS for h264 tracks with
b-frames, which means the decoder actually returns non-monotonic PTS.

Handle this with an evil trick: if DTS is missing, set it to the PTS.
Then the existing logic, which deals with falling back to DTS if PTS is
broken. Actually, this trick is not so evil at all, because usually, PTS
has no errors, and DTS is either always set, or always unset. So this
_should_ provoke no regressions (famous last words).

libavformat actually does something similar: it derives DTS from PTS in
ways unknown to me. The result is very broken, but it causes the DTS
fallback to become active, and thus happens to work.

Also, prevent the heuristic from being active if PTS is merely monotonic
instead of strictly-monotonic. Non-unique PTS is broken, but we can't
fallback to DTS anyway in these cases.

The specific mkv file that is fixed with this commit had the following
fields set:

  Muxing application: libebml v1.3.0 + libmatroska v1.4.1
  Writing application: mkvmerge v6.7.0 ('Back to the Ground') [...]

But I know that this should also fix playback of mencoder produced mkv
files.
2014-06-14 13:50:54 +02:00
wm4 60111d3f0f gl_common: correct a type
We pass a pointer to a GLint to sscanf, using the %d format. That format
_always_ takes int, and not GLint (whatever the heck that is). If GLint
is always int, then it doesn't make a difference, but is still better
because it doesn't play russian roulette with pointers.
2014-06-14 13:50:18 +02:00
wm4 2f86a06528 x11: fix datatype for _NET_WM_PID
Setting this property was added 12 years ago, and the code was always
incorrect. The underlying data type is "long", not "pid_t". It's well
possible that the data types are different, and the pointer to the pid
variable is directly passed to XChangeProperty, possibly invoking
undefined behavior.

It's funny, because in theory using pid_t for PIDs sounds more correct.
2014-06-14 13:50:02 +02:00
wm4 7e61bf134a input: make combined commands repeatable
Binding multiple commands at once where always considered not
repeatable, because the MP_CMD_COMMAND_LIST wasn't considered
repeatable.

Fixes #807 (probably).
2014-06-14 13:49:55 +02:00
wm4 61a2f3d2bf DOCS/coding-style: add a hint that new features should be documented 2014-06-14 13:47:38 +02:00
wm4 213ea94ee3 playlist: fix playlist_move on itself
A playlist_move command that moves an entry onto itself (both arguments
have the same index) should do nothing, but it did something broken. The
underlying reason is that it checks the prev pointer of the entry which
is temporarily removed for moving.
2014-06-14 13:47:18 +02:00
wm4 f1409ceacf Release 0.3.10 2014-05-24 16:54:54 +02:00
Yomi0 44f62ff6f3 tl_mpv_edl: correct misspelling on line 233
Closes #783

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

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

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

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

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

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

This problem doesn't exist in git master.

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

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

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

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

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

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

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

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

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

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

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

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

Fixes issue #742.
2014-04-30 11:45:31 +02:00
Stefano Pigozzi 9f46be7373 ao_coreaudio: log even more info in verbose mode
This logs more info that can be used for debugging purposes, in particular
it prints all the AudioChannelDescription in the descriptions array.
2014-04-30 11:45:31 +02:00
Stefano Pigozzi 3623fb38ee ao_coreaudio: add verbose output of detected channel layouts
This can be useful for debugging purposes.
2014-04-30 11:45:31 +02:00
wm4 1ad9e322e3 cache: remove redundant log prefix 2014-04-30 11:45:31 +02:00
Kevin Mitchell cad63810c5 man: minor typo why not to use portaudio 2014-04-30 11:45:31 +02:00
wm4 da17c64c76 vf: remove autoinserted filters on reconfig
When using rotation with hw decoding, and the VO does not support
rotation, vf_rotate is attempted to be inserted. This will go wrong, and
after that it can't recover because a vf_scale filter was autoinserted.
Just removing all autoinserted filters before reconfig fixes this.
2014-04-30 11:45:31 +02:00
wm4 57f32f7ca8 vf: add function to remove a filter from the chain 2014-04-30 11:45:31 +02:00
wm4 3d85137495 encode: don't resume playback when encoding
The previous commit doesn't handle additionally loaded config files,
such as the playback resume mechanism.
2014-04-30 11:45:31 +02:00
wm4 4aff0076a0 manpage: add notes when to use/not use certain AO and VO drivers
Conflicts:
	DOCS/man/en/vo.rst
2014-04-30 11:45:31 +02:00
James Ross-Gowan 70f8ea228d encode: disable keep-open when encoding 2014-04-30 11:45:31 +02:00
wm4 3196f4cdd7 audio: preallocate audio buffers on resize
This avoids too many realloc() calls if the caller is appending to an
audo buffer. This case is actually quite noticeable when using something
that buffers a large amount of audio.
2014-04-30 11:45:31 +02:00
50 changed files with 385 additions and 204 deletions

No files matched your search

+4 -2
View File
@@ -134,6 +134,8 @@ Sending patches
Important: put an empty line between the subject line and the commit message.
If this is missing, it will break display in common git tools.
- Try to separate cosmetic and functional changes. It's ok to make a few
additional cosmetic changes in the same file you're working on, but don't do
something like reformatting a whole file and hiding an actual functional
additional cosmetic changes in the same file you're working on. But don't do
something like reformatting a whole file, and hiding an actual functional
change in the same commit.
- If you add a new command line option, document it in options.rst. If you
add a new input property, document it in input.rst.
+28 -4
View File
@@ -18,7 +18,12 @@ normal driver parameters.
.. note::
See ``--ao=help`` for a list of compiled-in audio output drivers.
See ``--ao=help`` for a list of compiled-in audio output drivers. The
driver ``--ao=alsa`` is preferred. ``--ao=pulse`` is preferred on systems
where PulseAudio is used. On Windows, ``--ao=wasapi`` is preferred,
though it might cause trouble sometimes, in which case ``--ao=dsound``
should be used. On BSD systems, ``--ao=oss`` or `--ao=sndio`` may work
(the latter being experimental). On OSX systems, use ``--ao=coreaudio``.
.. admonition:: Examples
@@ -31,14 +36,14 @@ Available audio output drivers are:
``alsa`` (Linux only)
ALSA audio output driver
``device=<device>``
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
"spdif" device, unless you really know how to set it correctly.
``no-block``
Sets noblock-mode.
``resample=yes``
Enable ALSA resampling plugin. (This is disabled by default, because
some drivers report incorrect audio delay in some cases.)
``device=<device>``
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
"spdif" device, unless you really know how to set it correctly.
``mixer-device=<device>``
Set the mixer device used with ``--no-softvol`` (default: ``default``).
``mixer-name=<name>``
@@ -118,6 +123,9 @@ Available audio output drivers are:
``openal``
Experimental OpenAL audio output driver
.. note:: This driver is not very useful. Playing multi-channel audio with
it is slow.
``pulse``
PulseAudio audio output driver
@@ -130,6 +138,10 @@ Available audio output drivers are:
PortAudio audio output driver. This works on all platforms, and has
extensive MS Windows support.
.. note:: This driver is not very useful. It was added in the hope of
providing portable audio API across all platforms, but turned
out semi-broken and underfeatured.
``device``
Specify the subdevice to use. Giving ``help`` as device name lists all
devices found by PortAudio. Devices can be given as numeric values,
@@ -138,6 +150,8 @@ Available audio output drivers are:
``dsound`` (Windows only)
DirectX DirectSound audio output driver
.. note:: This driver is for compatibility with old systems.
``device=<devicenum>``
Sets the device number to use. Playing a file with ``-v`` will show a
list of available devices.
@@ -147,6 +161,10 @@ Available audio output drivers are:
1.2, but may require the ``SDL_AUDIODRIVER`` environment variable to be set
appropriately for your system.
.. note:: This driver is for compatibility with extremely foreign
environments, such as systems where none of the other drivers
are available.
``buflen=<length>``
Sets the audio buffer length in seconds. Is used only as a hint by the
sound system. Playing a file with ``-v`` will show the requested and
@@ -186,6 +204,10 @@ Available audio output drivers are:
``rsound``
Audio output to an RSound daemon
.. note:: Completely useless, unless you intend to run RSound. Not to be
confused with RoarAudio, which is something completely
different.
``host=<name/path>``
Set the address of the server (default: localhost). Can be either a
network hostname for TCP connections or a Unix domain socket path
@@ -197,6 +219,8 @@ Available audio output drivers are:
``sndio``
Audio output to the OpenBSD sndio sound system
.. note:: Experimental. There are known bugs and issues.
(Note: only supports mono, stereo, 4.0, 5.1 and 7.1 channel
layouts.)
+14 -9
View File
@@ -1558,10 +1558,10 @@ OPTIONS
``--osd-level=<0-3>``
Specifies which mode the OSD should start in.
:0: subtitles only
:1: volume + seek (default)
:2: volume + seek + timer + percentage
:3: volume + seek + timer + percentage + total time
:0: OSD completely disabled (subtitles only)
:1: enabled (shows up only on user interaction)
:2: enabled + current time visible by default
:3: enabled + ``--osd-status-msg`` (current time and status by default)
``--osd-margin-x=<size>, --sub-text-margin-x=<size>``
Left and right screen margin for the OSD/subs in scaled pixels (see
@@ -1648,20 +1648,25 @@ OPTIONS
file is dumped.
``--playlist=<filename>``
Play files according to a playlist file (ASX, Winamp, SMIL, or
one-file-per-line format).
Play files according to a playlist file (Supports some common formats.If
no format is detected, t will be treated as list of files, separated by
newline characters. Note that XML playlist formats are not supported.)
.. warning::
The way mpv parses and uses playlist files is not safe against
maliciously constructed files. Such files may trigger harmful actions.
The way mpv uses playlist files is not safe against maliciously
constructed files. Such files may trigger harmful actions.
This has been the case for all mpv and MPlayer versions, but
unfortunately this fact was not well documented earlier, and some people
have even misguidedly recommended use of ``--playlist`` with untrusted
sources. Do NOT use ``--playlist`` with random internet sources or files
you do not trust!
FIXME: This needs to be clarified and documented thoroughly.
The main problem is that playlists can point to arbitrary network
addresses (including local addresses inside of your LAN), and thus
can't be considered secure. Playlists also can contain entries using
other protocols, such as local files, or (most severely), special
protocols like ``avdevice://``, which are inherently unsafe.
``--priority=<prio>``
(Windows only.)
+11 -9
View File
@@ -98,10 +98,12 @@ Available filters are:
:2: Rotate by 90 degrees counterclockwise.
:3: Rotate by 90 degrees counterclockwise and flip.
``scale[=w:h[:interlaced[:chr-drop[:param[:param2[:noup[:arnd]]]]]]]``
``scale[=w:h:param:param2:chr-drop:noup:arnd``
Scales the image with the software scaler (slow) and performs a YUV<->RGB
colorspace conversion (see also ``--sws``).
All parameters are optional.
``<w>,<h>``
scaled width/height (default: original width/height)
@@ -114,14 +116,6 @@ Available filters are:
:-(n+8): Like -n above, but rounding the dimension to the closest
multiple of 16.
``<chr-drop>``
chroma skipping
:0: Use all available input lines for chroma.
:1: Use only every 2. input line for chroma.
:2: Use only every 4. input line for chroma.
:3: Use only every 8. input line for chroma.
``<param>[:<param2>]`` (see also ``--sws``)
Set some scaling parameters depending on the type of scaler selected
with ``--sws``::
@@ -137,6 +131,14 @@ Available filters are:
--sws=9 (lanczos): filter length (1-10)
``<chr-drop>``
chroma skipping
:0: Use all available input lines for chroma (default).
:1: Use only every 2. input line for chroma.
:2: Use only every 4. input line for chroma.
:3: Use only every 8. input line for chroma.
``<noup>``
Disallow upscaling past the original dimensions.
+25
View File
@@ -20,6 +20,9 @@ normal driver parameters.
See ``--vo=help`` for a list of compiled-in video output drivers.
The recommended output drivers are ``--vo=vdpau`` and ``--vo=opengl-hq``.
All other drivers are just for compatibility or special purposes.
.. admonition:: Example
``--vo=opengl,xv,``
@@ -32,6 +35,8 @@ Available video output drivers are:
the most compatible VO on X, but may be low-quality, and has issues with
OSD and subtitle display.
.. note:: This driver is for compatibility with old systems.
``adaptor=<number>``
Select a specific XVideo adaptor (check xvinfo results).
``port=<number>``
@@ -172,6 +177,9 @@ Available video output drivers are:
``direct3d_shaders`` (Windows only)
Video output driver that uses the Direct3D interface.
.. note:: This driver is for compatibility with systems that don't provide
proper OpenGL drivers.
``prefer-stretchrect``
Use ``IDirect3DDevice9::StretchRect`` over other methods if possible.
@@ -228,11 +236,15 @@ Available video output drivers are:
Same as ``direct3d_shaders``, but with the options ``disable-textures``
and ``disable-shaders`` forced.
.. note:: This driver is for compatibility with old systems.
``corevideo`` (Mac OS X 10.6 and later)
Mac OS X CoreVideo video output driver. Uses the CoreVideo APIs to fill
PixelBuffers and generate OpenGL textures from them (useful as a fallback
for ``opengl``).
.. note:: This driver is for compatibility with old systems.
``opengl``
OpenGL video output driver. It supports extended scaling methods, dithering
and color management.
@@ -519,6 +531,8 @@ Available video output drivers are:
implementation, even if you do not get any error message. Use ``glxinfo``
or a similar tool to display the supported OpenGL extensions.
.. note:: This driver is for compatibility with old systems.
``(no-)ati-hack``
ATI drivers may give a corrupted image when PBOs are used (when using
``force-pbo``). This option fixes this, at the expense of using a bit
@@ -692,6 +706,9 @@ Available video output drivers are:
hardware acceleration. Should work on all platforms supported by SDL 2.0.
For tuning, refer to your copy of the file ``SDL_hints.h``.
.. note:: This driver is for compatibility with systems that don't provide
proper graphics drivers, or which support GLES only.
``sw``
Continue even if a software renderer is detected.
@@ -704,6 +721,9 @@ Available video output drivers are:
hardware decoding to save power on laptops, or possibly preventing video
tearing with some setups.
.. note:: This driver is for compatibility with crappy systems. You can
use vaapi hardware decoding with ``--vo=opengl`` too.
``scaling=<algorithm>``
default
Driver default (mpv default as well).
@@ -744,6 +764,8 @@ Available video output drivers are:
``caca``
Color ASCII art video output driver that works on a text console.
.. note:: This driver is a joke.
``image``
Output each frame into an image file in the current directory. Each file
takes the frame number padded with leading zeros as name.
@@ -789,6 +811,9 @@ Available video output drivers are:
``wayland`` (Wayland only)
Wayland shared memory video output as fallback for ``opengl``.
.. note:: This driver is for compatibility with systems that don't provide
working OpenGL drivers.
``default-format``
Use the default RGB32 format instead of an auto-detected one.
+18 -2
View File
@@ -82,6 +82,22 @@ Generally, mpv should work with the latest release as well as the git version
of both FFmpeg and Libav. But FFmpeg is preferred, and some mpv features work
with FFmpeg only. See the [wiki article][ffmpeg_vs_libav] about the issue.
Release cycle
-------------
Every few months, a new release is cut off of the master branch. Currently,
these releases are assigned a version number ``0.X.0``. Only the latest release
is maintained. As part of the maintenance process, minor releases are made,
which are assigned ``0.X.Y`` version numbers. Minor releases contain bug fixes
only. They never merge the master branch, and no features are added to it. The
goal of releases is to provide stability and an unchanged base for the sake of
Linux distributions. If you want the newest features, just use the master
branch. (The master branch is stable most of the time, except sometimes, when
it's not.)
Releases other than the latest release are unsupported and unmaintained.
Bug reports
-----------
@@ -95,8 +111,8 @@ For small changes you can just send us pull requests through GitHub. For bigger
changes come and talk to us on IRC before you start working on them. It will
make code review easier for both parties later on.
Contacts
--------
Contact
-------
These forms of contact are meant to ask questions about mpv usage, give
feedback on mpv and discuss it's development.
+35 -6
View File
@@ -23,6 +23,11 @@ Note that you can control the mpv instance by writing to the command fifo:
echo "cycle fullscreen" > /tmp/umpv-fifo-*
Note: you can supply custom options with the UMPV_OPTIONS environment variable.
The environment variable will be split on whitespace, and each item is
passed as option to mpv _if_ the script starts mpv. If mpv is not started
by the script (i.e. mpv is already running), the options will be ignored.
Warning:
The script attempts to make sure the FIFO is safely created (i.e. not world-
@@ -38,13 +43,33 @@ import errno
import subprocess
import fcntl
import stat
import string
if len(sys.argv) < 2:
print("error: needs at least one file as argument.")
if len(sys.argv) < 1:
sys.exit(1)
files = sys.argv[1:]
# this is about the same method mpv uses to decide this
def is_url(filename):
parts = filename.split(":", 1)
if len(parts) < 2:
return False
# protocol prefix has no special characters => it's an URL
prefix = parts[0]
for c in prefix:
if string.ascii_letters.find(c) < 0:
return False
return True
# make them absolute; also makes them safe against interpretation as options
files = [os.path.abspath(f) for f in files]
def make_abs(filename):
if not is_url(filename):
return os.path.abspath(filename)
return filename
files = [make_abs(f) for f in files]
opts_env = os.getenv("UMPV_OPTIONS")
opts_env = opts_env.split() if opts_env else []
FIFO = "/tmp/umpv-fifo-" + os.getenv("USER")
@@ -87,7 +112,11 @@ else:
pass
else:
raise e
os.mkfifo(FIFO, 0600)
os.mkfifo(FIFO, int("0600", 8))
subprocess.check_call(["mpv", "--really-quiet", "--force-window",
"--input-file=" + FIFO, "--"] + files)
opts = ["mpv", "--really-quiet", "--force-window", "--input-file=" + FIFO]
opts.extend(opts_env)
opts.append("--")
opts.extend(files)
subprocess.check_call(opts)
+1 -1
View File
@@ -1 +1 @@
0.3.8
0.3.11
+7 -2
View File
@@ -173,10 +173,15 @@ void mp_audio_realloc(struct mp_audio *mpa, int samples)
}
// Like mp_audio_realloc(), but only reallocate if the audio grows in size.
// If the buffer is reallocated, also preallocate.
void mp_audio_realloc_min(struct mp_audio *mpa, int samples)
{
if (samples > mp_audio_get_allocated_size(mpa))
mp_audio_realloc(mpa, samples);
if (samples > mp_audio_get_allocated_size(mpa)) {
size_t alloc = ta_calc_prealloc_elems(samples);
if (alloc > INT_MAX)
abort(); // oom
mp_audio_realloc(mpa, alloc);
}
}
/* Get the size allocated for the data, in number of samples. If the allocated
+11 -8
View File
@@ -18,6 +18,7 @@
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <libavutil/common.h>
@@ -245,8 +246,9 @@ char *mixer_get_volume_restore_data(struct mixer *mixer)
{
if (!mixer->driver[0])
return NULL;
return talloc_asprintf(NULL, "%s:%f:%f:%d", mixer->driver, mixer->vol_l,
mixer->vol_r, mixer->muted_by_us);
return talloc_asprintf(NULL, "%s:%f:%f:%d:%f", mixer->driver, mixer->vol_l,
mixer->vol_r, mixer->muted_by_us,
mixer->opts->softvol_max);
}
static void probe_softvol(struct mixer *mixer)
@@ -307,19 +309,20 @@ static void restore_volume(struct mixer *mixer)
force_mute = opts->mixer_init_mute;
// Set parameters from playback resume.
char *restore_data = mixer->opts->mixer_restore_volume_data;
if (restore && restore_data && restore_data[0]) {
char *data = mixer->opts->mixer_restore_volume_data;
if (restore && data && data[0]) {
char drv[40];
float v_l, v_r;
float v_l, v_r, s;
int m;
if (sscanf(restore_data, "%39[^:]:%f:%f:%d", drv, &v_l, &v_r, &m) == 4) {
if (strcmp(mixer->driver, drv) == 0) {
if (sscanf(data, "%39[^:]:%f:%f:%d:%f", drv, &v_l, &v_r, &m, &s) == 5) {
float diff = fabs(mixer->opts->softvol_max - s);
if (strcmp(mixer->driver, drv) == 0 && diff < 0.01) {
force_vol_l = v_l;
force_vol_r = v_r;
force_mute = !!m;
}
}
talloc_free(restore_data);
talloc_free(mixer->opts->mixer_restore_volume_data);
mixer->opts->mixer_restore_volume_data = NULL;
}
+1 -1
View File
@@ -724,8 +724,8 @@ const struct ao_driver audio_out_alsa = {
.cfg_mixer_index = 0,
},
.options = (const struct m_option[]) {
OPT_FLAG("resample", cfg_resample, 0),
OPT_STRING("device", cfg_device, 0),
OPT_FLAG("resample", cfg_resample, 0),
OPT_FLAG("block", cfg_block, 0),
OPT_STRING("mixer-device", cfg_mixer_device, 0),
OPT_STRING("mixer-name", cfg_mixer_name, 0),
+27
View File
@@ -431,6 +431,32 @@ static bool ca_bitmap_from_ch_tag(struct ao *ao, AudioChannelLayout *layout,
}
}
static void ca_log_layout(struct ao *ao, AudioChannelLayout layout)
{
if (!mp_msg_test(ao->log, MSGL_V))
return;
AudioChannelDescription *descs = layout.mChannelDescriptions;
MP_VERBOSE(ao, "layout: tag: <%d>, bitmap: <%d>, "
"descriptions <%d>\n",
layout.mChannelLayoutTag,
layout.mChannelBitmap,
layout.mNumberChannelDescriptions);
for (int i = 0; i < layout.mNumberChannelDescriptions; i++) {
AudioChannelDescription d = descs[i];
MP_VERBOSE(ao, " - description %d: label <%d, %d>, flags: <%u>, "
"coords: <%f, %f, %f>\n", i,
d.mChannelLabel,
ca_label_to_mp_speaker_id(d.mChannelLabel),
d.mChannelFlags,
d.mCoordinates[0],
d.mCoordinates[1],
d.mCoordinates[2]);
}
}
void ca_bitmaps_from_layouts(struct ao *ao,
AudioChannelLayout *layouts, size_t n_layouts,
uint32_t **bitmaps, size_t *n_bitmaps)
@@ -440,6 +466,7 @@ void ca_bitmaps_from_layouts(struct ao *ao,
for (int i=0; i < n_layouts; i++) {
uint32_t bitmap = 0;
ca_log_layout(ao, layouts[i]);
switch (layouts[i].mChannelLayoutTag) {
case kAudioChannelLayoutTag_UseChannelBitmap:
+4 -1
View File
@@ -114,10 +114,13 @@ void playlist_clear(struct playlist *pl)
pl->current_was_replaced = false;
}
// Moves entry such that entry->prev = at (even if at is NULL)
// Moves the entry so that it takes "at"'s place (or move to end, if at==NULL).
void playlist_move(struct playlist *pl, struct playlist_entry *entry,
struct playlist_entry *at)
{
if (entry == at)
return;
struct playlist_entry *save_current = pl->current;
bool save_replaced = pl->current_was_replaced;
+12 -20
View File
@@ -44,10 +44,6 @@
#include <libavcodec/avcodec.h>
#if MP_INPUT_BUFFER_PADDING_SIZE < FF_INPUT_BUFFER_PADDING_SIZE
#error MP_INPUT_BUFFER_PADDING_SIZE is too small!
#endif
// Demuxer list
extern const struct demuxer_desc demuxer_desc_edl;
extern const struct demuxer_desc demuxer_desc_cue;
@@ -117,7 +113,7 @@ static void packet_destroy(void *ptr)
{
struct demux_packet *dp = ptr;
talloc_free(dp->avpacket);
free(dp->allocation);
av_free(dp->allocation);
}
static struct demux_packet *create_packet(size_t len)
@@ -143,12 +139,12 @@ static struct demux_packet *create_packet(size_t len)
struct demux_packet *new_demux_packet(size_t len)
{
struct demux_packet *dp = create_packet(len);
dp->buffer = malloc(len + MP_INPUT_BUFFER_PADDING_SIZE);
dp->buffer = av_malloc(len + FF_INPUT_BUFFER_PADDING_SIZE);
if (!dp->buffer) {
fprintf(stderr, "Memory allocation failure!\n");
abort();
}
memset(dp->buffer + len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
memset(dp->buffer + len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
dp->allocation = dp->buffer;
return dp;
}
@@ -168,21 +164,11 @@ struct demux_packet *new_demux_packet_from(void *data, size_t len)
return dp;
}
void resize_demux_packet(struct demux_packet *dp, size_t len)
void demux_packet_shorten(struct demux_packet *dp, size_t len)
{
if (len > 1000000000) {
fprintf(stderr, "Attempt to realloc demux packet over 1 GB!\n");
abort();
}
assert(dp->allocation);
dp->buffer = realloc(dp->buffer, len + MP_INPUT_BUFFER_PADDING_SIZE);
if (!dp->buffer) {
fprintf(stderr, "Memory allocation failure!\n");
abort();
}
memset(dp->buffer + len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
assert(len <= dp->len);
dp->len = len;
dp->allocation = dp->buffer;
memset(dp->buffer + dp->len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
}
void free_demux_packet(struct demux_packet *dp)
@@ -522,6 +508,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
.glog = log,
.filename = talloc_strdup(demuxer, stream->url),
.metadata = talloc_zero(demuxer, struct mp_tags),
.initializing = true,
};
demuxer->params = params; // temporary during open()
stream_seek(stream, stream->start_pos);
@@ -554,6 +541,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
"File is not seekable, but there's a cache: enabling seeking.\n");
demuxer->seekable = true;
}
demuxer->initializing = false;
return demuxer;
}
@@ -724,6 +712,8 @@ int demux_info_add_bstr(demuxer_t *demuxer, struct bstr opt, struct bstr param)
if (oldval) {
if (bstrcmp0(param, oldval) == 0)
return 0;
}
if (!demuxer->initializing) {
MP_INFO(demuxer, "Demuxer info %.*s changed to %.*s\n",
BSTR_P(opt), BSTR_P(param));
}
@@ -740,6 +730,8 @@ int demux_info_print(demuxer_t *demuxer)
if (!info || !info->num_keys)
return 0;
demux_info_update(demuxer);
mp_info(demuxer->glog, "Clip info:\n");
for (n = 0; n < info->num_keys; n++) {
mp_info(demuxer->glog, " %s: %s\n", info->keys[n], info->values[n]);
+2 -4
View File
@@ -80,9 +80,6 @@ enum demux_check {
DEMUX_CHECK_NORMAL, // normal, safe detection
};
// demux_lavf can pass lavf buffers using FF_INPUT_BUFFER_PADDING_SIZE instead
#define MP_INPUT_BUFFER_PADDING_SIZE 16
#define MAX_SH_STREAMS 256
struct demuxer;
@@ -170,6 +167,7 @@ typedef struct demuxer {
// File format allows PTS resets (even if the current file is without)
bool ts_resets_possible;
bool warned_queue_overflow;
bool initializing;
struct sh_stream **streams;
int num_streams;
@@ -209,7 +207,7 @@ struct demux_packet *new_demux_packet(size_t len);
// data must already have suitable padding
struct demux_packet *new_demux_packet_fromdata(void *data, size_t len);
struct demux_packet *new_demux_packet_from(void *data, size_t len);
void resize_demux_packet(struct demux_packet *dp, size_t len);
void demux_packet_shorten(struct demux_packet *dp, size_t len);
void free_demux_packet(struct demux_packet *dp);
struct demux_packet *demux_copy_packet(struct demux_packet *dp);
+1 -1
View File
@@ -97,8 +97,8 @@ 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", "audio/mpeg", 24, 0.5},
{"mp3", NULL, 24, .max_probe = true},
{0}
};
+5 -3
View File
@@ -1173,6 +1173,7 @@ typedef struct {
char *id;
int fourcc;
int extradata;
bool parse;
} videocodec_info_t;
static const videocodec_info_t vinfo[] = {
@@ -1185,11 +1186,11 @@ static const videocodec_info_t vinfo[] = {
{MKV_V_MPEG4_AVC, MP_FOURCC('a', 'v', 'c', '1'), 1},
{MKV_V_THEORA, MP_FOURCC('t', 'h', 'e', 'o'), 1},
{MKV_V_VP8, MP_FOURCC('V', 'P', '8', '0'), 0},
{MKV_V_VP9, MP_FOURCC('V', 'P', '9', '0'), 0},
{MKV_V_VP9, MP_FOURCC('V', 'P', '9', '0'), 0, true},
{MKV_V_DIRAC, MP_FOURCC('d', 'r', 'a', 'c'), 0},
{MKV_V_PRORES, MP_FOURCC('p', 'r', '0', '0'), 0},
{MKV_V_HEVC, MP_FOURCC('H', 'E', 'V', 'C'), 1},
{NULL, 0, 0}
{0}
};
static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track)
@@ -1273,6 +1274,7 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track)
extradata = track->private_data;
extradata_size = track->private_size;
}
track->parse = vi->parse;
if (!vi->id) {
MP_WARN(demuxer, "Unknown/unsupported "
"CodecID (%s) or missing/bad CodecPrivate\n"
@@ -1336,7 +1338,7 @@ static struct mkv_audio_tag {
bool parse;
} mkv_audio_tags[] = {
{ MKV_A_MP2, 0, 0x0055 },
{ MKV_A_MP3, 0, 0x0055 },
{ MKV_A_MP3, 0, 0x0055, true },
{ MKV_A_AC3, 1, 0x2000 },
{ MKV_A_EAC3, 1, MP_FOURCC('E', 'A', 'C', '3') },
{ MKV_A_DTS, 0, 0x2001 },
+1 -1
View File
@@ -204,7 +204,7 @@ static int raw_fill_buffer(demuxer_t *demuxer)
dp->pts = (dp->pos / p->frame_size) / p->frame_rate;
int len = stream_read(demuxer->stream, dp->buffer, dp->len);
resize_demux_packet(dp, len);
demux_packet_shorten(dp, len);
demuxer_add_packet(demuxer, demuxer->streams[0], dp);
return 1;
+1
View File
@@ -79,6 +79,7 @@
#Q quit_watch_later
#q {encode} quit
#ESC quit
#ESC {encode} quit
#p cycle pause # toggle pause/playback mode
#. frame_step # advance one frame and pause
#, frame_back_step # go back by one frame and pause
+7 -1
View File
@@ -271,13 +271,19 @@ bool mp_input_is_abort_cmd(struct mp_cmd *cmd)
if (cmd->id == MP_CMD_COMMAND_LIST) {
for (struct mp_cmd *sub = cmd->args[0].v.p; sub; sub = sub->queue_next)
{
if (mp_input_is_abort_cmd(cmd))
if (mp_input_is_abort_cmd(sub))
return true;
}
}
return false;
}
bool mp_input_is_repeatable_cmd(struct mp_cmd *cmd)
{
return (cmd->def && cmd->def->allow_auto_repeat) ||
cmd->id == MP_CMD_COMMAND_LIST;
}
void mp_print_cmd_list(struct mp_log *out)
{
for (int i = 0; mp_cmds[i].name; i++) {
+2
View File
@@ -110,6 +110,8 @@ enum mp_command_type {
struct mp_cmd;
bool mp_input_is_abort_cmd(struct mp_cmd *cmd);
bool mp_input_is_repeatable_cmd(struct mp_cmd *cmd);
struct bstr;
bool mp_replace_legacy_cmd(void *talloc_ctx, struct bstr *s);
+2 -2
View File
@@ -517,7 +517,7 @@ static void update_mouse_section(struct input_ctx *ictx)
}
// Called when the currently held-down key is released. This (usually) sends
// the a key-up versiob of the command associated with the keys that were held
// the a key-up version of the command associated with the keys that were held
// down.
// If the drop_current parameter is set to true, then don't send the key-up
// command. Unless we've already sent a key-down event, in which case the
@@ -1155,7 +1155,7 @@ mp_cmd_t *mp_input_get_cmd(struct input_ctx *ictx, int time, int peek_only)
struct mp_cmd *repeated = check_autorepeat(ictx);
if (repeated) {
repeated->repeated = true;
if (repeated->def && repeated->def->allow_auto_repeat) {
if (mp_input_is_repeatable_cmd(repeated)) {
queue_add_tail(queue, repeated);
} else {
talloc_free(repeated);
+1
View File
@@ -343,6 +343,7 @@ DIRS = . \
player/timeline \
demux \
misc \
options \
osdep \
osdep/ar \
player \
+1 -1
View File
@@ -518,7 +518,7 @@ static int setsigaction(int signo, void (*handler) (int),
else
sigemptyset(&sa.sa_mask);
sa.sa_flags = flags;
sa.sa_flags = flags | SA_RESTART;
return sigaction(signo, &sa, NULL);
}
+2 -2
View File
@@ -110,8 +110,8 @@ static void mp_load_per_file_config(struct MPContext *mpctx)
const char *file = mpctx->filename;
if (snprintf(cfg, sizeof(cfg), "%s.conf", file) >= sizeof(cfg)) {
MP_WARN(mpctx, "Filename is too long, "
"can not load file or directory specific config files\n");
MP_VERBOSE(mpctx, "Filename is too long, "
"can not load file or directory specific config files\n");
return;
}
+2
View File
@@ -401,8 +401,10 @@ static int mpv_main(int argc, char *argv[])
m_config_set_option0(mpctx->mconfig, "vo", "lavc");
m_config_set_option0(mpctx->mconfig, "ao", "lavc");
m_config_set_option0(mpctx->mconfig, "fixed-vo", "yes");
m_config_set_option0(mpctx->mconfig, "keep-open", "no");
m_config_set_option0(mpctx->mconfig, "force-window", "no");
m_config_set_option0(mpctx->mconfig, "gapless-audio", "yes");
m_config_set_option0(mpctx->mconfig, "resume-playback", "no");
mp_input_enable_section(mpctx->input, "encode", MP_INPUT_EXCLUSIVE);
}
#endif
+1 -1
View File
@@ -138,7 +138,7 @@ void update_window_title(struct MPContext *mpctx, bool force)
{
if (!mpctx->video_out && !mpctx->ao) {
talloc_free(mpctx->last_window_title);
mpctx->last_window_title = false;
mpctx->last_window_title = NULL;
return;
}
char *title = mp_property_expand_string(mpctx, mpctx->opts->wintitle);
+1 -1
View File
@@ -201,7 +201,7 @@ static void build_timeline(struct MPContext *mpctx, struct tl_parts *parts)
part->filename);
}
// Unkown length => use rest of the file. If duration is unknown, make
// Unknown length => use rest of the file. If duration is unknown, make
// something up.
if (part->length < 0)
part->length = (len < 0 ? 1 : len) - part->offset;
+1 -1
View File
@@ -514,7 +514,7 @@ static int cache_control(stream_t *cache, int cmd, void *arg)
if (r != STREAM_ERROR)
goto done;
MP_VERBOSE(s, "[cache] blocking for STREAM_CTRL %d\n", cmd);
MP_VERBOSE(s, "blocking for STREAM_CTRL %d\n", cmd);
s->control = cmd;
s->control_arg = arg;
+8 -2
View File
@@ -396,16 +396,22 @@ stream_t *open_output_stream(const char *filename, struct mpv_global *global)
static int stream_reconnect(stream_t *s)
{
#define MAX_RECONNECT_RETRIES 5
#define RECONNECT_SLEEP_MS 1000
#define RECONNECT_SLEEP_MAX_MS 500
if (!s->streaming)
return 0;
if (!(s->flags & MP_STREAM_SEEK_FW))
return 0;
int64_t pos = s->pos;
int sleep_ms = 5;
for (int retry = 0; retry < MAX_RECONNECT_RETRIES; retry++) {
MP_WARN(s, "Connection lost! Attempting to reconnect (%d)...\n", retry + 1);
if (stream_check_interrupt(retry ? RECONNECT_SLEEP_MS : 0))
if (retry) {
mp_sleep_us(sleep_ms * 1000);
sleep_ms = MPMIN(sleep_ms * 2, RECONNECT_SLEEP_MAX_MS);
}
if (stream_check_interrupt(0))
return 0;
s->eof = 1;
+49 -22
View File
@@ -40,15 +40,13 @@ known issues:
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <math.h>
#if HAVE_SYS_SYSINFO_H
#include <sys/sysinfo.h>
#endif
#if HAVE_SYS_VIDEOIO_H
#include <sys/videoio.h>
#else
@@ -71,6 +69,13 @@ known issues:
#define v4l2_munmap munmap
#endif
// flag introduced in kernel 3.10
#ifndef V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
#define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC 0x2000
#endif
#define HAVE_CLOCK_GETTIME (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
#define info tvi_info_v4l2
static tvi_handle_t *tvi_init_v4l2(struct mp_log *log, tv_param_t* tv_param);
/* information about this file */
@@ -112,8 +117,10 @@ typedef struct priv {
struct map *map;
int mapcount;
int frames;
volatile long long first_frame;
long long curr_frame;
volatile long long first_frame; ///< number of useconds
long long curr_frame; ///< usec, using kernel timestamps
int clk_id; /**< clk_id from clock_gettime
used in frame timestamps */
/* audio video interleaving ;-) */
volatile int streamon;
pthread_t audio_grabber_thread;
@@ -500,6 +507,30 @@ static int getstd(priv_t *priv)
return 0;
}
#if HAVE_CLOCK_GETTIME
/*
** Gets current timestamp, using specified clock id.
** @return number of microseconds.
*/
static long long get_curr_timestamp(int clk_id)
{
struct timespec ts;
clock_gettime(clk_id, &ts);
return (long long)ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
}
#else
/*
** Gets current timestamp, using system time.
** @return number of microseconds.
*/
static long long get_curr_timestamp(int clk_id)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (long long)tv.tv_sec * 1000000 + tv.tv_usec;
}
#endif
/***********************************************************************\
* *
* *
@@ -1230,13 +1261,6 @@ static int get_capture_buffer_size(priv_t *priv)
if (priv->tv_param->buffer_size >= 0) {
bufsize = priv->tv_param->buffer_size*1024*1024;
} else {
#if HAVE_SYS_SYSINFO_H
struct sysinfo si;
sysinfo(&si);
bufsize = (si.freeram/2)*si.mem_unit;
if ( bufsize < 16*1024*1024)
#endif
bufsize = 16*1024*1024;
}
@@ -1378,6 +1402,13 @@ static int start(priv_t *priv)
return 0;
}
priv->map[i].len = priv->map[i].buf.length;
#ifdef HAVE_CLOCK_GETTIME
priv->clk_id = (priv->map[i].buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC)
? CLOCK_MONOTONIC : CLOCK_REALTIME;
#else
if (priv->map[i].buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC)
mp_msg(MSGT_TV, MSGL_WARN, "MPlayer compiled without clock_gettime() that is needed to handle monotone video timestamps from the kernel. Expect desync.\n");
#endif
/* count up to make sure this is correct everytime */
priv->mapcount++;
@@ -1653,13 +1684,11 @@ static int get_video_framesize(priv_t *priv)
static void *audio_grabber(void *data)
{
priv_t *priv = (priv_t*)data;
struct timeval tv;
int i, audio_skew_ptr = 0;
long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
long long start_time_avg;
long long start_time_avg, curr_timestamp;
gettimeofday(&tv, NULL);
start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
start_time_avg = priv->audio_start_time = get_curr_timestamp(priv->clk_id);
audio_in_start_capture(&priv->audio_in);
for (i = 0; i < priv->aud_skew_cnt; i++)
priv->audio_skew_buffer[i] = 0;
@@ -1673,21 +1702,19 @@ static void *audio_grabber(void *data)
pthread_mutex_lock(&priv->skew_mutex);
if (priv->first_frame == 0) {
// there is no first frame yet (unlikely to happen)
gettimeofday(&tv, NULL);
start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
start_time_avg = priv->audio_start_time = get_curr_timestamp(priv->clk_id);
// fprintf(stderr, "warning - first frame not yet available!\n");
pthread_mutex_unlock(&priv->skew_mutex);
continue;
}
pthread_mutex_unlock(&priv->skew_mutex);
gettimeofday(&tv, NULL);
priv->audio_recv_blocks_total++;
current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
curr_timestamp = get_curr_timestamp(priv->clk_id);
current_time = curr_timestamp - priv->audio_start_time;
if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
start_time_avg += curr_timestamp - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
}
+1 -1
View File
@@ -31,7 +31,7 @@
#define MP_ASS_FONT_PLAYRESY 288
#define MP_ASS_RGBA(r, g, b, a) \
(((r) << 24U) | ((g) << 16) | ((b) << 8) | (0xFF - (a)))
(((unsigned)(r) << 24) | ((g) << 16) | ((b) << 8) | (0xFF - (a)))
// m_color argument
#define MP_ASS_COLOR(c) MP_ASS_RGBA((c).r, (c).g, (c).b, (c).a)
+3 -5
View File
@@ -52,11 +52,9 @@ struct sub_bitmap {
int x, y;
int dw, dh;
union {
struct {
uint32_t color;
} libass;
};
struct {
uint32_t color;
} libass;
};
struct sub_bitmaps {
+2 -2
View File
@@ -424,10 +424,10 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts)
int r = (color >> 24u) & 0xff;
int g = (color >> 16u) & 0xff;
int b = (color >> 8u) & 0xff;
int a = color & 0xff;
int a = 0xff - (color & 0xff);
int c[3] = {r, g, b};
mp_map_int_color(vs_rgb2yuv, 8, c);
mp_map_int_color(vs2rgb, 8, c);
sb->libass.color = (c[0] << 24u) | (c[1] << 16) | (c[2] << 8) | a;
sb->libass.color = MP_ASS_RGBA(c[0], c[1], c[2], a);
}
}
+9 -1
View File
@@ -290,6 +290,14 @@ struct mp_image *video_decode(struct dec_video *d_video,
bool sort_pts =
(opts->user_pts_assoc_mode != 1 || d_video->header->video->avi_dts)
&& opts->correct_pts;
struct demux_packet packet_copy;
if (packet && packet->dts == MP_NOPTS_VALUE) {
packet_copy = *packet;
packet = &packet_copy;
packet->dts = packet->pts;
}
double pkt_pts = packet ? packet->pts : MP_NOPTS_VALUE;
double pkt_dts = packet ? packet->dts : MP_NOPTS_VALUE;
@@ -323,7 +331,7 @@ struct mp_image *video_decode(struct dec_video *d_video,
if (pts == MP_NOPTS_VALUE) {
d_video->codec_pts = prev_codec_pts;
} else if (pts <= prev_codec_pts) {
} else if (pts < prev_codec_pts) {
d_video->num_codec_pts_problems++;
}
+4 -2
View File
@@ -334,11 +334,12 @@ static struct mp_image *allocate_image(struct lavc_ctx *ctx, int format,
static void destroy_va_dummy_ctx(struct priv *p)
{
va_destroy(p->ctx);
p->ctx = NULL;
p->display = NULL;
if (p->x11_display)
XCloseDisplay(p->x11_display);
p->x11_display = NULL;
va_destroy(p->ctx);
p->ctx = NULL;
}
// Creates a "private" VADisplay, disconnected from the VO. We just create a
@@ -372,6 +373,7 @@ static void uninit(struct lavc_ctx *ctx)
destroy_decoder(ctx);
va_surface_pool_release(p->pool);
p->pool = NULL;
if (p->x11_display)
destroy_va_dummy_ctx(p);
+20
View File
@@ -115,6 +115,8 @@ static const vf_info_t *const filter_list[] = {
NULL
};
static void vf_uninit_filter(vf_instance_t *vf);
static bool get_desc(struct m_obj_desc *dst, int index)
{
if (index >= MP_ARRAY_SIZE(filter_list) - 1)
@@ -270,6 +272,17 @@ static vf_instance_t *vf_open_filter(struct vf_chain *c, const char *name,
return vf_open(c, name, args);
}
void vf_remove_filter(struct vf_chain *c, struct vf_instance *vf)
{
assert(vf != c->first && vf != c->last); // these are sentinels
struct vf_instance *prev = c->first;
while (prev && prev->next != vf)
prev = prev->next;
assert(prev); // not inserted
prev->next = vf->next;
vf_uninit_filter(vf);
}
struct vf_instance *vf_append_filter(struct vf_chain *c, const char *name,
char **args)
{
@@ -439,6 +452,7 @@ static void update_formats(struct vf_chain *c, struct vf_instance *vf,
MP_INFO(c, "Using conversion filter.\n");
struct vf_instance *conv = vf_open(c, "scale", NULL);
if (conv) {
conv->autoinserted = true;
conv->next = vf->next;
vf->next = conv;
update_formats(c, conv, vf->last_outfmts);
@@ -492,6 +506,12 @@ int vf_reconfig(struct vf_chain *c, const struct mp_image_params *params)
{
struct mp_image_params cur = *params;
int r = 0;
for (struct vf_instance *vf = c->first; vf; ) {
struct vf_instance *next = vf->next;
if (vf->autoinserted)
vf_remove_filter(c, vf);
vf = next;
}
c->first->fmt_in = *params;
uint8_t unused[IMGFMT_END - IMGFMT_START];
update_formats(c, c->first, unused);
+2
View File
@@ -75,6 +75,7 @@ typedef struct vf_instance {
void (*uninit)(struct vf_instance *vf);
char *label;
bool autoinserted;
struct mp_image_params fmt_in, fmt_out;
@@ -134,6 +135,7 @@ struct mp_image *vf_output_queued_frame(struct vf_chain *c);
void vf_seek_reset(struct vf_chain *c);
struct vf_instance *vf_append_filter(struct vf_chain *c, const char *name,
char **args);
void vf_remove_filter(struct vf_chain *c, struct vf_instance *vf);
int vf_append_filter_list(struct vf_chain *c, struct m_obj_settings *list);
struct vf_instance *vf_find_by_label(struct vf_chain *c, const char *label);
void vf_print_filter_chain(struct vf_chain *c, int msglevel);
+1 -1
View File
@@ -502,7 +502,7 @@ void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *),
if (!gl->GetString)
gl->GetString = glGetString;
GLint major = 0, minor = 0;
int major = 0, minor = 0;
const char *version = gl->GetString(GL_VERSION);
sscanf(version, "%d.%d", &major, &minor);
gl->version = MPGL_VER(major, minor);
-2
View File
@@ -1,8 +1,6 @@
/*
* This file is part of mpv.
*
* Parts based on the MPlayer VA-API patch (see vo_vaapi.c).
*
* mpv is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
+9 -10
View File
@@ -301,12 +301,6 @@ static struct mp_image *get_screenshot(struct priv *p)
return img;
}
static bool redraw_frame(struct priv *p)
{
p->output_surface = p->visible_surface;
return render_to_screen(p, p->output_surfaces[p->output_surface]);
}
static void free_subpicture(struct priv *p, struct vaapi_osd_image *img)
{
if (img->image.image_id != VA_INVALID_ID)
@@ -528,7 +522,7 @@ static int control(struct vo *vo, uint32_t request, void *data)
return get_equalizer(p, eq->name, eq->valueptr);
}
case VOCTRL_REDRAW_FRAME:
redraw_frame(p);
p->output_surface = p->visible_surface;
return true;
case VOCTRL_SCREENSHOT: {
struct voctrl_screenshot_args *args = data;
@@ -577,16 +571,17 @@ static int preinit(struct vo *vo)
VAStatus status;
if (!vo_x11_init(vo))
return -1;
goto fail;
p->display = vaGetDisplay(vo->x11->display);
if (!p->display)
return -1;
goto fail;
p->mpvaapi = va_initialize(p->display, p->log);
if (!p->mpvaapi) {
vaTerminate(p->display);
return -1;
p->display = NULL;
goto fail;
}
p->pool = va_surface_pool_alloc(p->mpvaapi, VA_RT_FORMAT_YUV420);
@@ -636,6 +631,10 @@ static int preinit(struct vo *vo)
p->va_num_display_attrs = 0;
}
return 0;
fail:
uninit(vo);
return -1;
}
#define OPT_BASE_STRUCT struct priv
+6 -3
View File
@@ -655,6 +655,12 @@ static int initialize_vdpau_objects(struct vo *vo)
&vc->rgb_surfaces[n]);
CHECK_VDP_ERROR(vo, "Allocating RGB surface");
}
} else {
if (create_vdp_mixer(vo, vc->vdp_chroma_type) < 0)
return -1;
}
if (vc->black_pixel == VDP_INVALID_HANDLE) {
vdp_st = vdp->output_surface_create(vc->vdp_device, OUTPUT_RGBA_FORMAT,
1, 1, &vc->black_pixel);
CHECK_VDP_ERROR(vo, "Allocating clearing surface");
@@ -663,9 +669,6 @@ static int initialize_vdpau_objects(struct vo *vo)
(const void*[]){data},
(uint32_t[]){4}, NULL);
CHECK_VDP_ERROR(vo, "Initializing clearing surface");
} else {
if (create_vdp_mixer(vo, vc->vdp_chroma_type) < 0)
return -1;
}
forget_frames(vo, false);
+1 -1
View File
@@ -228,8 +228,8 @@ shmemerror:
static void freeMyXImage(struct priv *p, int foo)
{
struct vo *vo = p->vo;
#if HAVE_SHM && HAVE_XEXT
struct vo *vo = p->vo;
if (p->Shmem_Flag) {
XShmDetach(vo->x11->display, &p->Shminfo[foo]);
XDestroyImage(p->myximage[foo]);
+14 -53
View File
@@ -54,10 +54,10 @@ static int lookupkey(int key);
static void hide_cursor(struct vo_wayland_state * wl);
static void show_cursor(struct vo_wayland_state * wl);
static void shedule_resize(struct vo_wayland_state *wl,
uint32_t edges,
int32_t width,
int32_t height);
static void schedule_resize(struct vo_wayland_state *wl,
uint32_t edges,
int32_t width,
int32_t height);
static void vo_wayland_fullscreen (struct vo *vo);
@@ -112,43 +112,6 @@ static const struct mp_keymap keymap[] = {
/** Wayland listeners **/
static void display_handle_error(void *data,
struct wl_display *display,
void *object_id,
uint32_t code,
const char *message)
{
struct vo_wayland_state *wl = data;
const char * error_type_msg = "";
switch (code) {
case WL_DISPLAY_ERROR_INVALID_OBJECT:
error_type_msg = "Invalid object";
break;
case WL_DISPLAY_ERROR_INVALID_METHOD:
error_type_msg = "Invalid method";
break;
case WL_DISPLAY_ERROR_NO_MEMORY:
error_type_msg = "No memory";
break;
}
MP_ERR(wl, "%s: %s\n", error_type_msg, message);
}
static void display_handle_delete_id(void *data,
struct wl_display *display,
uint32_t id)
{
struct vo_wayland_state *wl = data;
MP_DBG(wl, "Object %u deleted\n", id);
}
static const struct wl_display_listener display_listener = {
display_handle_error,
display_handle_delete_id
};
static void ssurface_handle_ping(void *data,
struct wl_shell_surface *shell_surface,
uint32_t serial)
@@ -163,7 +126,7 @@ static void ssurface_handle_configure(void *data,
int32_t height)
{
struct vo_wayland_state *wl = data;
shedule_resize(wl, edges, width, height);
schedule_resize(wl, edges, width, height);
}
static void ssurface_handle_popup_done(void *data,
@@ -566,16 +529,16 @@ static void show_cursor (struct vo_wayland_state *wl)
wl_surface_commit(wl->cursor.surface);
}
static void shedule_resize(struct vo_wayland_state *wl,
uint32_t edges,
int32_t width,
int32_t height)
static void schedule_resize(struct vo_wayland_state *wl,
uint32_t edges,
int32_t width,
int32_t height)
{
int32_t minimum_size = 150;
int32_t x, y;
float temp_aspect = width / (float) MPMAX(height, 1);
MP_DBG(wl, "shedule resize: %dx%d\n", width, height);
MP_DBG(wl, "schedule resize: %dx%d\n", width, height);
if (width < minimum_size)
width = minimum_size;
@@ -644,8 +607,6 @@ static bool create_display (struct vo_wayland_state *wl)
return false;
}
wl_display_add_listener(wl->display.display, &display_listener, wl);
wl->display.registry = wl_display_get_registry(wl->display.display);
wl_registry_add_listener(wl->display.registry, &registry_listener, wl);
@@ -817,7 +778,7 @@ static void vo_wayland_ontop (struct vo *vo)
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);
schedule_resize(wl, 0, wl->window.width, wl->window.height);
}
static void vo_wayland_border (struct vo *vo)
@@ -853,7 +814,7 @@ static void vo_wayland_fullscreen (struct vo *vo)
MP_DBG(wl, "leaving fullscreen\n");
wl->window.is_fullscreen = false;
wl_shell_surface_set_toplevel(wl->window.shell_surface);
shedule_resize(wl, 0, wl->window.p_width, wl->window.p_height);
schedule_resize(wl, 0, wl->window.p_width, wl->window.p_height);
}
}
@@ -980,7 +941,7 @@ int vo_wayland_control (struct vo *vo, int *events, int request, void *arg)
case VOCTRL_SET_WINDOW_SIZE: {
int *s = arg;
if (!wl->window.is_fullscreen)
shedule_resize(wl, 0, s[0], s[1]);
schedule_resize(wl, 0, s[0], s[1]);
return VO_TRUE;
}
case VOCTRL_SET_CURSOR_VISIBILITY:
@@ -1018,7 +979,7 @@ bool vo_wayland_config (struct vo *vo, uint32_t d_width,
if (vo->opts->fullscreen) {
if (wl->window.is_fullscreen)
shedule_resize(wl, 0, wl->window.fs_width, wl->window.fs_height);
schedule_resize(wl, 0, wl->window.fs_width, wl->window.fs_height);
else
vo_wayland_fullscreen(vo);
}
+6 -5
View File
@@ -668,7 +668,7 @@ static void vo_x11_classhint(struct vo *vo, Window window, const char *name)
struct mp_vo_opts *opts = vo->opts;
struct vo_x11_state *x11 = vo->x11;
XClassHint wmClass;
pid_t pid = getpid();
long pid = getpid();
wmClass.res_name = opts->winname ? opts->winname : (char *)name;
wmClass.res_class = "mpv";
@@ -680,7 +680,8 @@ static void vo_x11_classhint(struct vo *vo, Window window, const char *name)
void vo_x11_uninit(struct vo *vo)
{
struct vo_x11_state *x11 = vo->x11;
assert(x11);
if (!x11)
return;
mp_input_put_key(vo->input_ctx, MP_INPUT_RELEASE_ALL);
@@ -1054,9 +1055,9 @@ static void vo_x11_set_wm_icon(struct vo_x11_state *x11)
for (int n = 0; n < num_icons; n++) {
*cur++ = icon_w[n];
*cur++ = icon_h[n];
uint32_t *src = icon_data[n];
for (int i = 0; i < icon_h[n] * icon_w[n]; i++)
*cur++ = src[i];
uint8_t *s = icon_data[n];
for (int i = 0; i < icon_h[n] * icon_w[n]; i++, s += 4)
*cur++ = s[0] | (s[1] << 8) | (s[2] << 16) | ((unsigned)s[3] << 24);
}
XChangeProperty(x11->display, x11->window, x11->XA_NET_WM_ICON,
+13
View File
@@ -8,7 +8,20 @@ __all__ = ["check_pthreads", "check_iconv", "check_lua", "check_oss_4front",
pthreads_program = load_fragment('pthreads.c')
def check_pthread_flag(ctx, dependency_identifier):
checks = [
check_cc(fragment = pthreads_program, cflags = '-pthread'),
check_cc(fragment = pthreads_program, cflags = '-pthread',
linkflags = '-pthread') ]
for fn in checks:
if fn(ctx, dependency_identifier):
return True
return False
def check_pthreads(ctx, dependency_identifier):
if check_pthread_flag(ctx, dependency_identifier):
return True
platform_cflags = {
'linux': '-D_REENTRANT',
'freebsd': '-D_THREAD_SAFE',
+2 -2
View File
@@ -3,7 +3,7 @@ __cdrom_devices_map__ = {
'cygwin': 'D:',
'darwin': '/dev/disk1',
'freebsd': '/dev/cd0',
'openbsd': '/dev/rcd0r',
'openbsd': '/dev/rcd0c',
'default': '/dev/cdrom'
}
@@ -12,7 +12,7 @@ __dvd_devices_map__ = {
'cygwin': 'D:',
'darwin': '/dev/rdiskN',
'freebsd': '/dev/cd0',
'openbsd': '/dev/rcd0r',
'openbsd': '/dev/rcd0c',
'default': '/dev/dvd'
}
+1 -1
View File
@@ -3,5 +3,5 @@
int main(void)
{
struct v4l2_ext_controls ext;
return ext.controls->value;
return !!&ext.controls->value;
}
+4 -2
View File
@@ -4,9 +4,11 @@ def __get_version__(ctx):
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=ctx.srcnode.abspath())
process.wait()
(version, err) = process.communicate()
return version.strip().decode('utf-8').encode('ascii', 'ignore')
version = version.strip()
if not isinstance(version, str):
version = version.decode('utf-8')
return version
def __get_build_date__():
import time
+2 -6
View File
@@ -187,11 +187,6 @@ iconv support use --disable-iconv.",
'name': 'setmode',
'desc': 'setmode()',
'func': check_statement('io.h', 'setmode(0, 0)')
}, {
'name': 'sys-sysinfo-h',
'desc': 'sys/sysinfo.h',
'func': check_statement('sys/sysinfo.h',
'struct sysinfo s_info; s_info.mem_unit=0; sysinfo(&s_info)')
}, {
'name': '--libguess',
'desc': 'libguess support',
@@ -716,6 +711,7 @@ radio_and_tv_features = [
}, {
'name': '--tv-v4l2',
'desc': 'Video4Linux2 TV interface',
'deps': [ 'tv' ],
'func': check_cc(header_name=['sys/time.h', 'linux/videodev2.h'])
}, {
'name': '--libv4l2',
@@ -818,7 +814,7 @@ def configure(ctx):
ctx.load('detections.devices')
if ctx.env.DEST_OS in ('freebsd', 'openbsd'):
ctx.env.CFLAGS += ['-I/usr/local/include']
ctx.env.CFLAGS += ['-I.', '-I..', '-I/usr/local/include']
ctx.env.LINKFLAGS += ['-L/usr/local/lib']
if ctx.env.DEST_OS == 'netbsd':