@@ -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
@@ -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.
@@ -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
@@ -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.

@@ -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.
@@ -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);
}
@@ -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);
@@ -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);
@@ -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.
@@ -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");
@@ -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"

@@ -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,
@@ -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
@@ -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
@@ -436,7 +436,7 @@ static struct mux_stream *encode_lavc_add_stream(struct encode_lavc_context *ctx
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,14 +476,16 @@ 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;
}

pkt = NULL;

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;
@@ -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);
@@ -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)
@@ -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)
@@ -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