diff options
author | James Cowgill <jcowgill@debian.org> | 2018-10-03 09:34:22 +0100 |
---|---|---|
committer | James Cowgill <jcowgill@debian.org> | 2018-10-03 09:34:22 +0100 |
commit | 53c5af1f24eb774765dc0ec81c6457a6a2f84076 (patch) | |
tree | b3b785d0d7f8e1bbc050acd6f0c85868d333c8f3 | |
parent | 7fb3e8f1e88579eff44672d7fa3103f4b078303e (diff) | |
parent | a6680ec06c4f17bb7b60c18ebd611ef40c5c6d68 (diff) |
Update upstream source from tag 'upstream/0.29.1'
Update to upstream version '0.29.1'
with Debian dir 31f7cc19e4c61d2b1ab2b256ef78d996fe64b422
44 files changed, 303 insertions, 156 deletions
diff --git a/.travis.yml b/.travis.yml index ddc8c51..8e3d962 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,10 +27,12 @@ branches: - master - ci - coverity_scan + - /release\/.*$/ before_install: - docker pull $CONTAINER script: + - ./bootstrap.py - docker run --env CC --env TARGET -v $TRAVIS_BUILD_DIR:/build $CONTAINER /bin/sh -c "cd /build && $CI_SCRIPT" after_failure: cat ./build/config.log after_script: TOOLS/travis-rebuild-website diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index 625918b..c8d1954 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -19,6 +19,8 @@ Interface changes :: + --- mpv 0.29.1 --- + - add --cocoa-cb-sw-renderer to control the usage of Apple Software Renderer --- mpv 0.29.0 --- - drop --opensles-sample-rate, as --audio-samplerate should be used if desired - drop deprecated --videotoolbox-format, --ff-aid, --ff-vid, --ff-sid, diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 58e2b9c..2fcf685 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -350,7 +350,7 @@ List of Input Commands Print text to stdout. The string can contain properties (see `Property Expansion`_). -``show-text "<string>" [<duration>|- [<level>]]`` +``show-text "<string>" [<duration>|-1 [<level>]]`` Show text on the OSD. The string can contain properties, which are expanded as described in `Property Expansion`_. This can be used to show playback time, filename, and so on. diff --git a/DOCS/man/mpv.rst b/DOCS/man/mpv.rst index c99a30e..4ddcc68 100644 --- a/DOCS/man/mpv.rst +++ b/DOCS/man/mpv.rst @@ -210,11 +210,11 @@ Alt + and Alt - Alt+BACKSPACE Reset the pan/zoom settings. -F9 +F8 Show the playlist and the current position in it (useful only if a UI window is used, broken on the terminal). -F10 +F9 Show the list of audio and subtitle streams (useful only if a UI window is used, broken on the terminal). diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index e03f783..53d293e 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -540,19 +540,15 @@ Program Behavior If the script can't do anything with an URL, it will do nothing. - The `try_ytdl_first` script option accepts a boolean 'yes' or 'no', and if + The ``try_ytdl_first`` script option accepts a boolean 'yes' or 'no', and if 'yes' will try parsing the URL with youtube-dl first, instead of the default where it's only after mpv failed to open it. This mostly depends on whether most of your URLs need youtube-dl parsing. - The `exclude` script option accepts a ``|``-separated list of URL patterns + The ``exclude`` script option accepts a ``|``-separated list of URL patterns which mpv should not use with youtube-dl. The patterns are matched after the ``http(s)://`` part of the URL. - The `use_manifests` script option makes mpv use the master manifest URL for - formats like HLS and DASH, if available, allowing for video/audio selection - in runtime. It's disabled ("no") by default for performance reasons. - ``^`` matches the beginning of the URL, ``$`` matches its end, and you should use ``%`` before any of the characters ``^$()%|,.[]*+-?`` to match that character. @@ -567,6 +563,9 @@ Program Behavior See more lua patterns here: https://www.lua.org/manual/5.1/manual.html#5.4.1 + The ``use_manifests`` script option makes mpv use the master manifest URL for + formats like HLS and DASH, if available, allowing for video/audio selection + in runtime. It's disabled ("no") by default for performance reasons. ``--ytdl-format=<best|worst|mp4|webm|...>`` Video format/quality that is directly passed to youtube-dl. The possible @@ -4882,6 +4881,15 @@ The following video options are currently all specific to ``--vo=gpu`` and OS X only. +``--cocoa-cb-sw-renderer=<yes|no|auto>`` + Use the Apple Software Renderer when using cocoa-cb (default: auto). If set + to ``no`` the software renderer is never used and instead fails when a the + usual pixel format could not be created, ``yes`` will always only use the + software renderer, and ``auto`` only falls back to the software renderer + when the usual pixel format couldn't be created. + + OS X only. + ``--macos-title-bar-style=<dark|ultradark|light|mediumlight|auto>`` Sets the styling of the title bar (default: dark). OS X and cocoa-cb only @@ -5175,7 +5183,7 @@ The following video options are currently all specific to ``--vo=gpu`` and desaturating everything. Developed by John Hable for use in video games. Use this when you care about detail preservation more than color/brightness accuracy. This is roughly equivalent to - ``--hdr-tone-mapping=reinhard --tone-mapping-param=0.24``. If possible, + ``--tone-mapping=reinhard --tone-mapping-param=0.24``. If possible, you should also enable ``--hdr-compute-peak`` for the best results. (Default) gamma diff --git a/DOCS/man/vf.rst b/DOCS/man/vf.rst index d979337..92c642c 100644 --- a/DOCS/man/vf.rst +++ b/DOCS/man/vf.rst @@ -16,7 +16,7 @@ The exact syntax is: name is an arbitrary user-given name, which identifies the filter. This is only needed if you want to toggle the filter at runtime. - A ``!`` before the filter name means the filter is enabled by default. It + A ``!`` before the filter name means the filter is disabled by default. It will be skipped on filter creation. This is also useful for runtime filter toggling. diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst index 6772fa3..ccde336 100644 --- a/DOCS/man/vo.rst +++ b/DOCS/man/vo.rst @@ -502,7 +502,7 @@ Available video output drivers are: supports several layers) together with ``vo=gpu`` and ``gpu-context=drm``. (default: first overlay plane) - ``--drm-format=<xrgb8888,xrgb2101010>`` + ``--drm-format=<xrgb8888|xrgb2101010>`` Select the DRM format to use (default: xrgb8888). This allows you to choose the bit depth of the DRM mode. xrgb8888 is your usual 24 bit per pixel/8 bits per channel packed RGB format with 8 bits of padding. diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 5e60f9e..cfd178a 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,3 +1,44 @@ +Release 0.29.1 +============== + +A bug fix release for the 0.29 release branch. + +Fixes and Minor Enhancements +---------------------------- + +- af_rubberband: Fix for A-V drift on seeking. +- ao_alsa: Fixes to remove spam during pausing and end-of-file. +- ao_jack: Fix for mpv attempting to connect to non-standard devices such as MIDI. +- ao_openal: Drop support for Apple's bundled OpenAL due to lack of features to successfully build. +- ao_pulse: Fix for audio buffer length calculation. +- demux_lavf: Fix EDL playback of certain DASH streams. +- demux_lavf: Mark v4l streams as not seekable. +- demux_raw: Fix for gapless playback from raw audio input. +- drm_atomic: Fix to enable video output with devices without a video overlay plane. +- encode: Fix for crashes in case of failure to write to output. +- encode: Fix for encoding when utilizing lavfi-complex. +- Fix to strip HDR peak metadata if attached to SDR video (#6111) +- macOS: Capability to fall back on SW rendering for testing purposes. +- macOS: Fix for issues with the main menu. +- macOS: Fix for side by side split view. +- macOS: Fixes for crashes, most notably those happening on 10.14 (#5908, #6097, #6041, #6062). +- macOS: No longer let older, unsupported versions of the Swift build tools through configure. +- manpage: Misc fixups. +- stream_{smb,file}: Fix for partial writes to buffers. +- stream_libarchive: Fix hang when an out-of-bound seek happens. +- stream_smb: Fix for crashes due to libsmbclient and threading (#5936). +- vo_gpu: Fix for corruption when multiple compute shaders override each others' block sizes (#6083). +- ytdl_hook: Always load "ytdl://" URLs with ytdl_hook first. +- ytdl_hook: Fix audio streams not being picked up for some sites. + +Options and Commands +-------------------- + +Added +~~~~~ + +- `--cocoa-cb-sw-renderer` to control whether or not to fall back on software rendering on macOS. + Release 0.29.0 ============== @@ -1 +1 @@ -0.29.0 +0.29.1 diff --git a/audio/filter/af_rubberband.c b/audio/filter/af_rubberband.c index 6c8c773..c7b6317 100644 --- a/audio/filter/af_rubberband.c +++ b/audio/filter/af_rubberband.c @@ -167,6 +167,7 @@ static void process(struct mp_filter *f) if (eof) { mp_pin_in_write(f->ppins[1], MP_EOF_FRAME); rubberband_reset(p->rubber); + p->rubber_delay = 0; TA_FREEP(&p->pending); p->sent_final = false; return; @@ -263,6 +264,7 @@ static void reset(struct mp_filter *f) if (p->rubber) rubberband_reset(p->rubber); + p->rubber_delay = 0; p->sent_final = false; TA_FREEP(&p->pending); } diff --git a/audio/format.c b/audio/format.c index 8a13698..f56546a 100644 --- a/audio/format.c +++ b/audio/format.c @@ -55,12 +55,6 @@ bool af_fmt_is_int(int format) return format && !af_fmt_is_spdif(format) && !af_fmt_is_float(format); } -// false for interleaved and AF_FORMAT_UNKNOWN -bool af_fmt_is_planar(int format) -{ - return format && af_fmt_to_planar(format) == format; -} - bool af_fmt_is_spdif(int format) { return af_format_sample_alignment(format) > 1; @@ -79,23 +73,30 @@ static const int planar_formats[][2] = { {AF_FORMAT_DOUBLEP, AF_FORMAT_DOUBLE}, }; +bool af_fmt_is_planar(int format) +{ + for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) { + if (planar_formats[n][0] == format) + return true; + } + return false; +} + // Return the planar format corresponding to the given format. -// If the format is already planar, return it. -// Return 0 if there's no equivalent. +// If the format is already planar or if there's no equivalent, +// return it. int af_fmt_to_planar(int format) { for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) { if (planar_formats[n][1] == format) return planar_formats[n][0]; - if (planar_formats[n][0] == format) - return format; } - return 0; + return format; } // Return the interleaved format corresponding to the given format. -// If the format is already interleaved, return it. -// Always succeeds if format is actually planar; otherwise return 0. +// If the format is already interleaved or if there's no equivalent, +// return it. int af_fmt_from_planar(int format) { for (int n = 0; n < MP_ARRAY_SIZE(planar_formats); n++) { @@ -134,17 +135,6 @@ const char *af_fmt_to_str(int format) return "??"; } -int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int samplerate) -{ - assert(!af_fmt_is_planar(format)); - int bps = af_fmt_to_bytes(format); - int framelen = channels * bps; - int bytes = seconds * bps * samplerate; - if (bytes % framelen) - bytes += framelen - (bytes % framelen); - return bytes; -} - void af_fill_silence(void *dst, size_t bytes, int format) { memset(dst, af_fmt_is_unsigned(format) ? 0x80 : 0, bytes); diff --git a/audio/format.h b/audio/format.h index 0afc656..24e1c54 100644 --- a/audio/format.h +++ b/audio/format.h @@ -64,9 +64,6 @@ bool af_fmt_is_pcm(int format); int af_fmt_to_planar(int format); int af_fmt_from_planar(int format); -// Amount of bytes that contain audio of the given duration, aligned to frames. -int af_fmt_seconds_to_bytes(int format, float seconds, int channels, int samplerate); - void af_fill_silence(void *dst, size_t bytes, int format); void af_get_best_sample_formats(int src_format, int *out_formats); diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c index 32f08be..df78a67 100644 --- a/audio/out/ao_alsa.c +++ b/audio/out/ao_alsa.c @@ -940,12 +940,24 @@ static int get_space(struct ao *ao) { struct priv *p = ao->priv; + // in case of pausing or the device still being configured, + // just return our buffer size. + if (p->paused || snd_pcm_state(p->alsa) == SND_PCM_STATE_SETUP) + return p->buffersize; + snd_pcm_sframes_t space = snd_pcm_avail(p->alsa); if (space < 0) { - MP_ERR(ao, "Error received from snd_pcm_avail (%ld, %s)!\n", - space, snd_strerror(space)); - if (space == -EPIPE) // EOF + if (space == -EPIPE) { + MP_WARN(ao, "ALSA XRUN hit, attempting to recover...\n"); + int err = snd_pcm_prepare(p->alsa); + CHECK_ALSA_ERROR("Unable to recover from under/overrun!"); return p->buffersize; + } + + MP_ERR(ao, "Error received from snd_pcm_avail " + "(%ld, %s with ALSA state %s)!\n", + space, snd_strerror(space), + snd_pcm_state_name(snd_pcm_state(p->alsa))); // request a reload of the AO if device is not present, // then error out. diff --git a/audio/out/ao_jack.c b/audio/out/ao_jack.c index b5413f7..0d5a2da 100644 --- a/audio/out/ao_jack.c +++ b/audio/out/ao_jack.c @@ -143,7 +143,8 @@ connect_to_outports(struct ao *ao) if (!port_name) port_flags |= JackPortIsPhysical; - matching_ports = jack_get_ports(p->client, port_name, NULL, port_flags); + const char *port_type = JACK_DEFAULT_AUDIO_TYPE; // exclude MIDI ports + matching_ports = jack_get_ports(p->client, port_name, port_type, port_flags); if (!matching_ports || !matching_ports[0]) { MP_FATAL(ao, "no ports to connect to\n"); diff --git a/audio/out/ao_openal.c b/audio/out/ao_openal.c index c1f405b..53571b6 100644 --- a/audio/out/ao_openal.c +++ b/audio/out/ao_openal.c @@ -24,19 +24,6 @@ #include <stdlib.h> #include <stdio.h> #include <inttypes.h> - -#ifdef __APPLE__ -#ifndef AL_FORMAT_MONO_FLOAT32 -#define AL_FORMAT_MONO_FLOAT32 0x10010 -#endif -#ifndef AL_FORMAT_STEREO_FLOAT32 -#define AL_FORMAT_STEREO_FLOAT32 0x10011 -#endif -#ifndef AL_FORMAT_MONO_DOUBLE_EXT -#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012 -#endif -#include <OpenAL/MacOSX_OALExtensions.h> -#else #ifdef OPENAL_AL_H #include <OpenAL/alc.h> #include <OpenAL/al.h> @@ -46,7 +33,6 @@ #include <AL/al.h> #include <AL/alext.h> #endif -#endif // __APPLE__ #include "common/msg.h" diff --git a/audio/out/ao_pulse.c b/audio/out/ao_pulse.c index ed45ba6..e288841 100644 --- a/audio/out/ao_pulse.c +++ b/audio/out/ao_pulse.c @@ -454,11 +454,11 @@ static int init(struct ao *ao) pa_stream_set_write_callback(priv->stream, stream_request_cb, ao); pa_stream_set_latency_update_callback(priv->stream, stream_latency_update_cb, ao); - int buf_size = af_fmt_seconds_to_bytes(ao->format, priv->cfg_buffer / 1000.0, - ao->channels.num, ao->samplerate); + uint32_t buf_size = ao->samplerate * (priv->cfg_buffer / 1000.0) * + af_fmt_to_bytes(ao->format) * ao->channels.num; pa_buffer_attr bufattr = { .maxlength = -1, - .tlength = buf_size > 0 ? buf_size : (uint32_t)-1, + .tlength = buf_size > 0 ? buf_size : -1, .prebuf = -1, .minreq = -1, .fragsize = -1, diff --git a/ci/build-mingw64.sh b/ci/build-mingw64.sh index c60f70e..b957ae1 100755 --- a/ci/build-mingw64.sh +++ b/ci/build-mingw64.sh @@ -16,8 +16,7 @@ export RANLIB=$TARGET-ranlib export CFLAGS="-O2 -mtune=intel -g -ggdb -pipe -Wall --param=ssp-buffer-size=4 -mms-bitfields -fmessage-length=0 -D_FORTIFY_SOURCE=2 -fexceptions -fasynchronous-unwind-tables -fstack-protector-strong -fno-ident" export LDFLAGS="-Wl,--no-keep-memory -fstack-protector-strong" -./bootstrap.py -./waf configure \ +python3 ./waf configure \ --enable-static-build \ --enable-libmpv-shared \ --enable-lua \ @@ -32,4 +31,4 @@ export LDFLAGS="-Wl,--no-keep-memory -fstack-protector-strong" --enable-shaderc \ --enable-rubberband \ --enable-lcms2 -./waf build --verbose +python3 ./waf build --verbose diff --git a/ci/build-tumbleweed.sh b/ci/build-tumbleweed.sh index b7d6b56..5f1c3e4 100755 --- a/ci/build-tumbleweed.sh +++ b/ci/build-tumbleweed.sh @@ -1,8 +1,7 @@ #!/bin/sh set -e -./bootstrap.py -./waf configure \ +python3 ./waf configure \ --enable-cdda \ --enable-dvbin \ --enable-dvdnav \ @@ -14,4 +13,4 @@ set -e --enable-shaderc \ --enable-vulkan \ --enable-zsh-comp -./waf build --verbose +python3 ./waf build --verbose diff --git a/common/encode_lavc.c b/common/encode_lavc.c index d8e875c..7cf1875 100644 --- a/common/encode_lavc.c +++ b/common/encode_lavc.c @@ -436,7 +436,7 @@ done: return dst; } -// Write a packet. Callee will create new pkt refs as needed. +// Write a packet. This will take over ownership of `pkt` static void encode_lavc_add_packet(struct mux_stream *dst, AVPacket *pkt) { struct encode_lavc_context *ctx = dst->ctx; @@ -476,6 +476,7 @@ static void encode_lavc_add_packet(struct mux_stream *dst, AVPacket *pkt) if (av_interleaved_write_frame(p->muxer, pkt) < 0) { MP_ERR(p, "Writing packet failed.\n"); p->failed = true; + pkt = NULL; goto done; } @@ -483,7 +484,8 @@ static void encode_lavc_add_packet(struct mux_stream *dst, AVPacket *pkt) done: pthread_mutex_unlock(&ctx->lock); - av_packet_free(&pkt); + if (pkt) + av_packet_unref(pkt); } void encode_lavc_discontinuity(struct encode_lavc_context *ctx) @@ -949,7 +951,6 @@ bool encoder_encode(struct encoder_context *p, AVFrame *frame) break; encode_lavc_add_packet(p->mux_stream, &packet); - av_packet_unref(&packet); } return true; diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 83cce14..8603a6a 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -162,6 +162,8 @@ static const struct format_hack format_hacks[] = { {"mp4", .skipinfo = true, .fix_editlists = true}, {"matroska", .skipinfo = true}, + {"v4l2", .no_seek = true}, + // In theory, such streams might contain timestamps, but virtually none do. {"h264", .if_flags = AVFMT_NOTIMESTAMPS }, {"hevc", .if_flags = AVFMT_NOTIMESTAMPS }, @@ -428,6 +430,10 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check) int nsize = av_clip(avpd.buf_size * 2, INITIAL_PROBE_SIZE, PROBE_BUF_SIZE); bstr buf = stream_peek(s, nsize); + if (demuxer->params && demuxer->params->init_fragment.len) { + buf = demuxer->params->init_fragment; + buf.len = MPMIN(buf.len, nsize); + } if (buf.len <= avpd.buf_size) final_probe = true; memcpy(avpd.buf, buf.start, buf.len); diff --git a/demux/packet.c b/demux/packet.c index 155e4d7..98ca24d 100644 --- a/demux/packet.c +++ b/demux/packet.c @@ -110,8 +110,8 @@ struct demux_packet *new_demux_packet(size_t len) void demux_packet_shorten(struct demux_packet *dp, size_t len) { assert(len <= dp->len); - dp->len = len; - memset(dp->buffer + dp->len, 0, AV_INPUT_BUFFER_PADDING_SIZE); + av_shrink_packet(dp->avpacket, len); + dp->len = dp->avpacket->size; } void free_demux_packet(struct demux_packet *dp) diff --git a/osdep/macOS_mpv_helper.swift b/osdep/macOS_mpv_helper.swift index e1fb3cf..a1bb03f 100644 --- a/osdep/macOS_mpv_helper.swift +++ b/osdep/macOS_mpv_helper.swift @@ -45,6 +45,12 @@ class MPVHelper: NSObject { mpctx = UnsafeMutablePointer<MPContext>(mp_client_get_core(mpvHandle)) inputContext = mpctx!.pointee.input + if let app = NSApp as? Application { + let ptr = mp_get_config_group(mpctx!, mp_client_get_global(mpvHandle), + app.getMacOSConf()) + macOpts = UnsafeMutablePointer<macos_opts>(OpaquePointer(ptr))!.pointee + } + mpv_observe_property(mpvHandle, 0, "ontop", MPV_FORMAT_FLAG) mpv_observe_property(mpvHandle, 0, "border", MPV_FORMAT_FLAG) mpv_observe_property(mpvHandle, 0, "keepaspect-window", MPV_FORMAT_FLAG) diff --git a/osdep/macosx_application.h b/osdep/macosx_application.h index c04f479..0301e49 100644 --- a/osdep/macosx_application.h +++ b/osdep/macosx_application.h @@ -23,6 +23,7 @@ struct macos_opts { int macos_title_bar_style; int macos_fs_animation_duration; + int cocoa_cb_sw_renderer; }; // multithreaded wrapper for mpv_main diff --git a/osdep/macosx_application.m b/osdep/macosx_application.m index 66daa45..086d51f 100644 --- a/osdep/macosx_application.m +++ b/osdep/macosx_application.m @@ -49,11 +49,14 @@ const struct m_sub_options macos_conf = { OPT_CHOICE_OR_INT("macos-fs-animation-duration", macos_fs_animation_duration, 0, 0, 1000, ({"default", -1})), + OPT_CHOICE("cocoa-cb-sw-renderer", cocoa_cb_sw_renderer, 0, + ({"auto", -1}, {"no", 0}, {"yes", 1})), {0} }, .size = sizeof(struct macos_opts), .defaults = &(const struct macos_opts){ .macos_fs_animation_duration = -1, + .cocoa_cb_sw_renderer = -1, }, }; @@ -124,8 +127,9 @@ static const char macosx_icon[] = - (NSImage *)getMPVIcon { + // The C string contains a trailing null, so we strip it away NSData *icon_data = [NSData dataWithBytesNoCopy:(void *)macosx_icon - length:sizeof(macosx_icon) + length:sizeof(macosx_icon) - 1 freeWhenDone:NO]; return [[NSImage alloc] initWithData:icon_data]; } diff --git a/osdep/macosx_events.m b/osdep/macosx_events.m index 0d46c0e..a354378 100644 --- a/osdep/macosx_events.m +++ b/osdep/macosx_events.m @@ -375,7 +375,8 @@ void cocoa_set_mpv_handle(struct mpv_handle *ctx) - (void)restartMediaKeys { - CGEventTapEnable(self->_mk_tap_port, true); + if (self->_mk_tap_port) + CGEventTapEnable(self->_mk_tap_port, true); } - (void)setHighestPriotityMediaKeysTap @@ -410,10 +411,10 @@ void cocoa_set_mpv_handle(struct mpv_handle *ctx) tap_event_callback, self); - assert(self->_mk_tap_port != nil); - - NSMachPort *port = (NSMachPort *)self->_mk_tap_port; - [[NSRunLoop mainRunLoop] addPort:port forMode:NSRunLoopCommonModes]; + if (self->_mk_tap_port) { + NSMachPort *port = (NSMachPort *)self->_mk_tap_port; + [[NSRunLoop mainRunLoop] addPort:port forMode:NSRunLoopCommonModes]; + } }); } @@ -421,10 +422,12 @@ void cocoa_set_mpv_handle(struct mpv_handle *ctx) { dispatch_async(dispatch_get_main_queue(), ^{ NSMachPort *port = (NSMachPort *)self->_mk_tap_port; - CGEventTapEnable(self->_mk_tap_port, false); - [[NSRunLoop mainRunLoop] removePort:port forMode:NSRunLoopCommonModes]; - CFRelease(self->_mk_tap_port); - self->_mk_tap_port = nil; + if (port) { + CGEventTapEnable(self->_mk_tap_port, false); + [[NSRunLoop mainRunLoop] removePort:port forMode:NSRunLoopCommonModes]; + CFRelease(self->_mk_tap_port); + self->_mk_tap_port = nil; + } }); } diff --git a/osdep/macosx_menubar.m b/osdep/macosx_menubar.m index 931079a..558a33a 100644 --- a/osdep/macosx_menubar.m +++ b/osdep/macosx_menubar.m @@ -602,7 +602,7 @@ - (NSMenu *)mainMenu { NSMenu *mainMenu = [[NSMenu alloc] initWithTitle:@"MainMenu"]; - NSApp.servicesMenu = [NSMenu alloc]; + [NSApp setServicesMenu:[[NSMenu alloc] init]]; for(id mMenu in menuTree) { NSMenu *menu = [[NSMenu alloc] initWithTitle:mMenu[@"name"]]; @@ -633,7 +633,7 @@ } if ([subMenu[@"name"] isEqual:@"Services"]) { - iItem.submenu = NSApp.servicesMenu; + iItem.submenu = [NSApp servicesMenu]; } } } diff --git a/player/loadfile.c b/player/loadfile.c index 56aca7d..81fd52f 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -1296,21 +1296,21 @@ static void play_current_file(struct MPContext *mpctx) update_demuxer_properties(mpctx); + update_playback_speed(mpctx); + + reinit_video_chain(mpctx); + reinit_audio_chain(mpctx); + reinit_sub_all(mpctx); + if (mpctx->encode_lavc_ctx) { - if (mpctx->current_track[0][STREAM_VIDEO]) + if (mpctx->vo_chain) encode_lavc_expect_stream(mpctx->encode_lavc_ctx, STREAM_VIDEO); - if (mpctx->current_track[0][STREAM_AUDIO]) + if (mpctx->ao_chain) encode_lavc_expect_stream(mpctx->encode_lavc_ctx, STREAM_AUDIO); encode_lavc_set_metadata(mpctx->encode_lavc_ctx, mpctx->demuxer->metadata); } - update_playback_speed(mpctx); - - reinit_video_chain(mpctx); - reinit_audio_chain(mpctx); - reinit_sub_all(mpctx); - if (!mpctx->vo_chain && !mpctx->ao_chain && opts->stream_auto_sel) { MP_FATAL(mpctx, "No video or audio streams selected.\n"); mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY; diff --git a/player/lua/ytdl_hook.lua b/player/lua/ytdl_hook.lua index cd9b61a..9dd1dc3 100644 --- a/player/lua/ytdl_hook.lua +++ b/player/lua/ytdl_hook.lua @@ -314,8 +314,8 @@ local function add_single_video(json) if track.vcodec and track.vcodec ~= "none" then -- video track streamurl = edl_track or track.url - elseif track.acodec and track.acodec ~= "none" and track.vcodec == "none" then - -- audio track + elseif track.vcodec == "none" then + -- according to ytdl, if vcodec is None, it's audio mp.commandv("audio-add", edl_track or track.url, "auto", track.format_note or "") @@ -429,12 +429,7 @@ local function add_single_video(json) mp.set_property_native("file-local-options/stream-lavf-o", stream_opts) end -mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function () - local url = mp.get_property("stream-open-filename", "") - if not (url:find("ytdl://") == 1) and - not ((url:find("https?://") == 1) and not is_blacklisted(url)) then - return - end +function run_ytdl_hook(url) local start_time = os.clock() -- check for youtube-dl in mpv's config dir @@ -655,8 +650,29 @@ mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function () add_single_video(json) end msg.debug('script running time: '..os.clock()-start_time..' seconds') -end) +end +if (not o.try_ytdl_first) then + mp.add_hook("on_load", 10, function () + msg.verbose('ytdl:// hook') + local url = mp.get_property("stream-open-filename", "") + if not (url:find("ytdl://") == 1) then + msg.verbose('not a ytdl:// url') + return + end + run_ytdl_hook(url) + end) +end + +mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function() + msg.verbose('full hook') + local url = mp.get_property("stream-open-filename", "") + if not (url:find("ytdl://") == 1) and + not ((url:find("https?://") == 1) and not is_blacklisted(url)) then + return + end + run_ytdl_hook(url) +end) mp.add_hook("on_preloaded", 10, function () if next(chapter_list) ~= nil then diff --git a/stream/stream_file.c b/stream/stream_file.c index 5cf6355..a905780 100644 --- a/stream/stream_file.c +++ b/stream/stream_file.c @@ -121,16 +121,16 @@ static int fill_buffer(stream_t *s, char *buffer, int max_len) static int write_buffer(stream_t *s, char *buffer, int len) { struct priv *p = s->priv; - int r; - int wr = 0; - while (wr < len) { - r = write(p->fd, buffer, len); - if (r <= 0) + int r = len; + int wr; + while (r > 0) { + wr = write(p->fd, buffer, r); + if (wr <= 0) return -1; - wr += r; - buffer += r; + r -= wr; + buffer += wr; } - return len; + return len - r; } static int seek(stream_t *s, int64_t newpos) diff --git a/stream/stream_libarchive.c b/stream/stream_libarchive.c index bb25c6a..119af8e 100644 --- a/stream/stream_libarchive.c +++ b/stream/stream_libarchive.c @@ -432,8 +432,15 @@ static int archive_entry_seek(stream_t *s, int64_t newpos) int size = MPMIN(newpos - s->pos, sizeof(buffer)); locale_t oldlocale = uselocale(p->mpa->locale); int r = archive_read_data(p->mpa->arch, buffer, size); - if (r < 0) { - MP_ERR(s, "%s\n", archive_error_string(p->mpa->arch)); + if (r <= 0) { + if (r == 0 && newpos > p->entry_size) { + MP_ERR(s, "demuxer trying to seek beyond end of archive " + "entry\n"); + } else if (r == 0) { + MP_ERR(s, "end of archive entry reached while seeking\n"); + } else { + MP_ERR(s, "%s\n", archive_error_string(p->mpa->arch)); + } uselocale(oldlocale); if (mp_archive_check_fatal(p->mpa, r)) { mp_archive_free(p->mpa); diff --git a/stream/stream_smb.c b/stream/stream_smb.c index 4376f71..269974f 100644 --- a/stream/stream_smb.c +++ b/stream/stream_smb.c @@ -21,6 +21,7 @@ #include <libsmbclient.h> #include <unistd.h> +#include <pthread.h> #include "common/msg.h" #include "stream.h" @@ -31,6 +32,8 @@ #error GPL only #endif +static pthread_mutex_t smb_lock = PTHREAD_MUTEX_INITIALIZER; + struct priv { int fd; }; @@ -46,8 +49,10 @@ static int control(stream_t *s, int cmd, void *arg) { struct priv *p = s->priv; switch(cmd) { case STREAM_CTRL_GET_SIZE: { + pthread_mutex_lock(&smb_lock); off_t size = smbc_lseek(p->fd,0,SEEK_END); smbc_lseek(p->fd,s->pos,SEEK_SET); + pthread_mutex_unlock(&smb_lock); if(size != (off_t)-1) { *(int64_t *)arg = size; return 1; @@ -60,7 +65,10 @@ static int control(stream_t *s, int cmd, void *arg) { static int seek(stream_t *s,int64_t newpos) { struct priv *p = s->priv; - if(smbc_lseek(p->fd,newpos,SEEK_SET)<0) { + pthread_mutex_lock(&smb_lock); + off_t size = smbc_lseek(p->fd,newpos,SEEK_SET); + pthread_mutex_unlock(&smb_lock); + if(size<0) { return 0; } return 1; @@ -68,27 +76,33 @@ static int seek(stream_t *s,int64_t newpos) { static int fill_buffer(stream_t *s, char* buffer, int max_len){ struct priv *p = s->priv; + pthread_mutex_lock(&smb_lock); int r = smbc_read(p->fd,buffer,max_len); + pthread_mutex_unlock(&smb_lock); return (r <= 0) ? -1 : r; } static int write_buffer(stream_t *s, char* buffer, int len) { struct priv *p = s->priv; - int r; - int wr = 0; - while (wr < len) { - r = smbc_write(p->fd,buffer,len); - if (r <= 0) + int r = len; + int wr; + while (r > 0) { + pthread_mutex_lock(&smb_lock); + wr = smbc_write(p->fd,buffer,r); + pthread_mutex_unlock(&smb_lock); + if (wr <= 0) return -1; - wr += r; - buffer += r; + r -= wr; + buffer += wr; } - return len; + return len - r; } static void close_f(stream_t *s){ struct priv *p = s->priv; + pthread_mutex_lock(&smb_lock); smbc_close(p->fd); + pthread_mutex_unlock(&smb_lock); } static int open_f (stream_t *stream) @@ -110,13 +124,17 @@ static int open_f (stream_t *stream) return STREAM_ERROR; } + pthread_mutex_lock(&smb_lock); err = smbc_init(smb_auth_fn, 1); + pthread_mutex_unlock(&smb_lock); if (err < 0) { MP_ERR(stream, "Cannot init the libsmbclient library: %d\n",err); return STREAM_ERROR; } + pthread_mutex_lock(&smb_lock); fd = smbc_open(filename, m,0644); + pthread_mutex_unlock(&smb_lock); if (fd < 0) { MP_ERR(stream, "Could not open from LAN: '%s'\n", filename); return STREAM_ERROR; @@ -124,8 +142,10 @@ static int open_f (stream_t *stream) len = 0; if(!write) { + pthread_mutex_lock(&smb_lock); len = smbc_lseek(fd,0,SEEK_END); smbc_lseek (fd, 0, SEEK_SET); + pthread_mutex_unlock(&smb_lock); } if(len > 0 || write) { stream->seekable = true; diff --git a/video/mp_image.c b/video/mp_image.c index eadff83..92c3e57 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -812,6 +812,12 @@ void mp_image_params_guess_csp(struct mp_image_params *params) } } + if (!mp_trc_is_hdr(params->color.gamma)) { + // Some clips have leftover HDR metadata after conversion to SDR, so to + // avoid blowing up the tone mapping code, strip/sanitize it + params->color.sig_peak = 1.0; + } + if (params->chroma_location == MP_CHROMA_AUTO) { if (params->color.levels == MP_CSP_LEVELS_TV) params->chroma_location = MP_CHROMA_LEFT; diff --git a/video/out/cocoa-cb/events_view.swift b/video/out/cocoa-cb/events_view.swift index 7cc295f..5a84d27 100644 --- a/video/out/cocoa-cb/events_view.swift +++ b/video/out/cocoa-cb/events_view.swift @@ -233,7 +233,7 @@ class EventsView: NSView { topMargin = cocoaCB.window.titleBarHeight + 1 + menuBarHeight } - var vF = window!.screen!.frame + guard var vF = window?.screen?.frame else { return false } vF.size.height -= topMargin let vFW = window!.convertFromScreen(vF) diff --git a/video/out/cocoa-cb/video_layer.swift b/video/out/cocoa-cb/video_layer.swift index b389327..d6456ab 100644 --- a/video/out/cocoa-cb/video_layer.swift +++ b/video/out/cocoa-cb/video_layer.swift @@ -32,6 +32,7 @@ class VideoLayer: CAOpenGLLayer { var needsFlip: Bool = false var canDrawOffScreen: Bool = false var cglContext: CGLContextObj? = nil + var cglPixelFormat: CGLPixelFormatObj? = nil var surfaceSize: NSSize? enum Draw: Int { case normal = 1, atomic, atomicEnd } @@ -62,7 +63,8 @@ class VideoLayer: CAOpenGLLayer { autoresizingMask = [.layerWidthSizable, .layerHeightSizable] backgroundColor = NSColor.black.cgColor - CGLCreateContext(copyCGLPixelFormat(forDisplayMask: 0), nil, &cglContext) + cglPixelFormat = copyCGLPixelFormat(forDisplayMask: 0) + CGLCreateContext(cglPixelFormat!, nil, &cglContext) var i: GLint = 1 CGLSetParameter(cglContext!, kCGLCPSwapInterval, &i) CGLSetCurrentContext(cglContext!) @@ -147,6 +149,8 @@ class VideoLayer: CAOpenGLLayer { } override func copyCGLPixelFormat(forDisplayMask mask: UInt32) -> CGLPixelFormatObj { + if cglPixelFormat != nil { return cglPixelFormat! } + let glVersions: [CGLOpenGLProfile] = [ kCGLOGLPVersion_3_2_Core, kCGLOGLPVersion_Legacy @@ -157,6 +161,8 @@ class VideoLayer: CAOpenGLLayer { var npix: GLint = 0 verLoop : for ver in glVersions { + if mpv.macOpts!.cocoa_cb_sw_renderer == 1 { break } + var glAttributes: [CGLPixelFormatAttribute] = [ kCGLPFAOpenGLProfile, CGLPixelFormatAttribute(ver.rawValue), kCGLPFAAccelerated, @@ -177,9 +183,28 @@ class VideoLayer: CAOpenGLLayer { } } + if (err != kCGLNoError || pix == nil) && mpv.macOpts!.cocoa_cb_sw_renderer != 0 { + if mpv.macOpts!.cocoa_cb_sw_renderer == -1 { + let errS = String(cString: CGLErrorString(err)) + mpv.sendWarning("Couldn't create hardware accelerated CGL " + + "pixel format, falling back to software " + + "renderer: \(errS) (\(err.rawValue))") + } + + let glAttributes: [CGLPixelFormatAttribute] = [ + kCGLPFAOpenGLProfile, CGLPixelFormatAttribute(kCGLOGLPVersion_3_2_Core.rawValue), + kCGLPFARendererID, CGLPixelFormatAttribute(UInt32(kCGLRendererGenericFloatID)), + kCGLPFADoubleBuffer, + kCGLPFABackingStore, + _CGLPixelFormatAttribute(rawValue: 0) + ] + + err = CGLChoosePixelFormat(glAttributes, &pix, &npix) + } + if err != kCGLNoError || pix == nil { let errS = String(cString: CGLErrorString(err)) - mpv.sendError("Couldn't create CGL pixel format: \(errS) (\(err.rawValue))") + mpv.sendError("Couldn't create any CGL pixel format: \(errS) (\(err.rawValue))") exit(1) } return pix! diff --git a/video/out/cocoa-cb/window.swift b/video/out/cocoa-cb/window.swift index 907476f..b3e691b 100644 --- a/video/out/cocoa-cb/window.swift +++ b/video/out/cocoa-cb/window.swift @@ -309,7 +309,7 @@ class Window: NSWindow, NSWindowDelegate { } func endAnimation(_ newFrame: NSRect = NSZeroRect) { - if !NSEqualRects(newFrame, NSZeroRect) { + if !NSEqualRects(newFrame, NSZeroRect) && isAnimating { NSAnimationContext.runAnimationGroup({ (context) -> Void in context.duration = 0.01 self.animator().setFrame(newFrame, display: true) diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift index a4aae9f..790a07d 100644 --- a/video/out/cocoa_cb_common.swift +++ b/video/out/cocoa_cb_common.swift @@ -61,12 +61,6 @@ class CocoaCB: NSObject { if backendState == .uninitialized { backendState = .needsInit - if let app = NSApp as? Application { - let ptr = mp_get_config_group(mpv.mpctx!, vo.pointee.global, - app.getMacOSConf()) - mpv.macOpts = UnsafeMutablePointer<macos_opts>(OpaquePointer(ptr))!.pointee - } - view = EventsView(cocoaCB: self) view.layer = layer view.wantsLayer = true @@ -241,7 +235,9 @@ class CocoaCB: NSObject { func updateICCProfile() { mpv.setRenderICCProfile(window.screen!.colorSpace!) - layer.colorspace = window.screen!.colorSpace!.cgColorSpace! + if #available(macOS 10.11, *) { + layer.colorspace = window.screen!.colorSpace!.cgColorSpace! + } } func lmuToLux(_ v: UInt64) -> Int { diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m index abead0f..b4283bb 100644 --- a/video/out/cocoa_common.m +++ b/video/out/cocoa_common.m @@ -172,8 +172,10 @@ static void set_application_icon(NSApplication *app) NSBundle *bundle = [NSBundle mainBundle]; if ([bundle pathForResource:@"icon" ofType:@"icns"]) return; + + // The C string contains a trailing null, so we strip it away NSData *icon_data = [NSData dataWithBytesNoCopy:(void *)macosx_icon - length:sizeof(macosx_icon) + length:sizeof(macosx_icon) - 1 freeWhenDone:NO]; NSImage *icon = [[NSImage alloc] initWithData:icon_data]; [app setApplicationIconImage:icon]; diff --git a/video/out/drm_atomic.c b/video/out/drm_atomic.c index 5c6b3bb..f530d91 100644 --- a/video/out/drm_atomic.c +++ b/video/out/drm_atomic.c @@ -263,21 +263,16 @@ struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, mp_verbose(log, "Using default plane %d for video\n", overlay_id); ctx->video_plane = drm_object_create(log, ctx->fd, overlay_id, DRM_MODE_OBJECT_PLANE); } else { - mp_err(log, "Failed to find video plane with id=%d\n", video_plane_id); - goto fail; + mp_verbose(log, "Failed to find video plane with id=%d. drmprime-drm hwdec interop will not work\n", video_plane_id); } } else { mp_verbose(log, "Found video plane with ID %d\n", ctx->video_plane->id); } - mp_verbose(log, "Found Video plane with ID %d, OSD with ID %d\n", - ctx->video_plane->id, ctx->osd_plane->id); - drmModeFreePlaneResources(plane_res); drmModeFreeResources(res); return ctx; - fail: if (res) drmModeFreeResources(res); @@ -301,6 +296,9 @@ void drm_atomic_destroy_context(struct drm_atomic_context *ctx) static bool drm_atomic_save_plane_state(struct drm_object *plane, struct drm_atomic_plane_state *plane_state) { + if (!plane) + return true; + bool ret = true; if (0 > drm_object_get_property(plane, "FB_ID", &plane_state->fb_id)) @@ -333,6 +331,9 @@ static bool drm_atomic_restore_plane_state(drmModeAtomicReq *request, struct drm_object *plane, const struct drm_atomic_plane_state *plane_state) { + if (!plane) + return true; + bool ret = true; if (0 > drm_object_set_property(request, plane, "FB_ID", plane_state->fb_id)) diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c index 7594c2b..ebb63cc 100644 --- a/video/out/gpu/video.c +++ b/video/out/gpu/video.c @@ -1103,8 +1103,14 @@ static void cleanup_binds(struct gl_video *p) // Sets the appropriate compute shader metadata for an implicit compute pass // bw/bh: block size -static void pass_is_compute(struct gl_video *p, int bw, int bh) +static void pass_is_compute(struct gl_video *p, int bw, int bh, bool flexible) { + if (p->pass_compute.active && flexible) { + // Avoid overwriting existing block sizes when using a flexible pass + bw = p->pass_compute.block_w; + bh = p->pass_compute.block_h; + } + p->pass_compute = (struct compute_info){ .active = true, .block_w = bw, @@ -1248,7 +1254,7 @@ static void finish_pass_tex(struct gl_video *p, struct ra_tex **dst_tex, // If RA_CAP_PARALLEL_COMPUTE is set, try to prefer compute shaders // over fragment shaders wherever possible. if (!p->pass_compute.active && (p->ra->caps & RA_CAP_PARALLEL_COMPUTE)) - pass_is_compute(p, 16, 16); + pass_is_compute(p, 16, 16, true); if (p->pass_compute.active) { gl_sc_uniform_image2D_wo(p->sc, "out_image", *dst_tex); @@ -1744,7 +1750,7 @@ static void pass_dispatch_sample_polar(struct gl_video *p, struct scaler *scaler if (shmem_req > p->ra->max_shmem) goto fallback; - pass_is_compute(p, bw, bh); + pass_is_compute(p, bw, bh, false); pass_compute_polar(p->sc, scaler, img.components, bw, bh, iw, ih); return; @@ -2485,7 +2491,7 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool if (detect_peak) { pass_describe(p, "detect HDR peak"); - pass_is_compute(p, 8, 8); // 8x8 is good for performance + pass_is_compute(p, 8, 8, true); // 8x8 is good for performance gl_sc_ssbo(p->sc, "PeakDetect", p->hdr_peak_ssbo, "uint counter;" "uint frame_idx;" diff --git a/video/out/opengl/common.c b/video/out/opengl/common.c index 4b0cbcc..00692f0 100644 --- a/video/out/opengl/common.c +++ b/video/out/opengl/common.c @@ -42,7 +42,8 @@ static bool is_software_gl(GL *gl) strcmp(renderer, "Software Rasterizer") == 0 || strstr(renderer, "llvmpipe") || strcmp(vendor, "Microsoft Corporation") == 0 || - strcmp(renderer, "Mesa X11") == 0; + strcmp(renderer, "Mesa X11") == 0 || + strcmp(renderer, "Apple Software Renderer") == 0; } static void GLAPIENTRY dummy_glBindFramebuffer(GLenum target, GLuint framebuffer) diff --git a/video/out/opengl/hwdec_drmprime_drm.c b/video/out/opengl/hwdec_drmprime_drm.c index 5e09c5a..d4543b0 100644 --- a/video/out/opengl/hwdec_drmprime_drm.c +++ b/video/out/opengl/hwdec_drmprime_drm.c @@ -257,6 +257,10 @@ static int init(struct ra_hwdec *hw) mp_err(p->log, "Failed to retrieve DRM atomic context.\n"); goto err; } + if (!p->ctx->video_plane) { + mp_warn(p->log, "No video plane. You might need to specify it manually using --drm-video-plane-id\n"); + goto err; + } } else { mp_verbose(p->log, "Failed to retrieve DRM fd from native display.\n"); goto err; diff --git a/waftools/checks/custom.py b/waftools/checks/custom.py index d887df5..821bf9c 100644 --- a/waftools/checks/custom.py +++ b/waftools/checks/custom.py @@ -4,7 +4,7 @@ from waflib import Utils import os __all__ = ["check_pthreads", "check_iconv", "check_lua", - "check_cocoa", "check_openal", "check_wl_protocols"] + "check_cocoa", "check_wl_protocols", "check_swift"] pthreads_program = load_fragment('pthreads.c') @@ -112,13 +112,11 @@ def check_cocoa(ctx, dependency_identifier): return res -def check_openal(ctx, dependency_identifier): - checks = [ - check_pkg_config('openal', '>= 1.13'), - check_statement(['OpenAL/AL.h'], 'int i = AL_VERSION', framework='OpenAL') - ] - - for fn in checks: - if fn(ctx, dependency_identifier): +def check_swift(ctx, dependency_identifier): + if ctx.env.SWIFT_VERSION: + major = int(ctx.env.SWIFT_VERSION.split('.')[0]) + ctx.add_optional_message(dependency_identifier, + 'version found: ' + ctx.env.SWIFT_VERSION) + if major >= 3: return True return False diff --git a/waftools/detections/compiler_swift.py b/waftools/detections/compiler_swift.py index 9b0e06e..cf55149 100644 --- a/waftools/detections/compiler_swift.py +++ b/waftools/detections/compiler_swift.py @@ -11,8 +11,8 @@ def __add_swift_flags(ctx): ctx.env.SWIFT_FLAGS = ('-frontend -c -sdk %s -enable-objc-interop' ' -emit-objc-header -parse-as-library' ' -target x86_64-apple-macosx10.10') % (ctx.env.MACOS_SDK) - swift_version = __run([ctx.env.SWIFT, '-version']).split(' ')[3].split('.')[:2] - major, minor = [int(n) for n in swift_version] + ctx.env.SWIFT_VERSION = __run([ctx.env.SWIFT, '-version']).split(' ')[3] + major, minor = [int(n) for n in ctx.env.SWIFT_VERSION.split('.')[:2]] # the -swift-version parameter is only supported on swift 3.1 and newer if major >= 3 and minor >= 1 or major >= 4: @@ -169,6 +169,11 @@ main_dependencies = [ 'fmsg': 'Unable to find either POSIX or MinGW-w64 environment, ' \ 'or compiler does not work.', }, { + 'name': '--swift', + 'desc': 'macOS Swift build tools', + 'deps': 'os-darwin', + 'func': check_swift, + }, { 'name': '--uwp', 'desc': 'Universal Windows Platform', 'default': 'disable', @@ -506,7 +511,7 @@ audio_output_features = [ }, { 'name': '--openal', 'desc': 'OpenAL audio output', - 'func': check_openal, + 'func': check_pkg_config('openal', '>= 1.13'), 'default': 'disable' }, { 'name': '--opensles', @@ -912,7 +917,7 @@ standalone_features = [ }, { 'name': '--macos-cocoa-cb', 'desc': 'macOS opengl-cb backend', - 'deps': 'cocoa', + 'deps': 'cocoa && swift', 'func': check_true } ] |