summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDiogo Franco (Kovensky) <diogomfranco@gmail.com>2015-04-09 20:42:14 +0900
committerDiogo Franco (Kovensky) <diogomfranco@gmail.com>2015-04-09 20:42:14 +0900
commit35e9d75083eef3ffbaa463dd0a38e170730d31f0 (patch)
tree728d523940c0829eff7aba26fd1b6f882a34dcdc
parent4a84cd37f3833b6751eae1448f6b40d88e0b6aad (diff)
parent7a65c44922d5be4a67be4e4c3f4fd47cb06c5e00 (diff)
downloadmpv-35e9d75083eef3ffbaa463dd0a38e170730d31f0.tar.bz2
mpv-35e9d75083eef3ffbaa463dd0a38e170730d31f0.tar.xz
Merge branch 'master' into release/0.9
All commits are bugfixes anyway, so just taking everything. * master: sub: don't truncate timestamps to int sub: unprefer libavcodec's MicroDVD converter manpage: lua: clarify timer usage audio: automatically deatch filters if spdif prevents their use audio: change a detail about filter insertion ao_alsa: change log output audio: avoid one more redundant audio filter reinit ao_coreaudio: do not error if retrieving info for verbose mode fails travis: re-enable OSX video/out: fix screenshot image formats vdpau: don't use a transparent image format for screenshots screenshot: use GPU readback only for hardware decoded images manpage: remove confusing statement screenshots: select best image format the encoder supports
-rw-r--r--.travis.yml2
-rw-r--r--DOCS/man/lua.rst17
-rw-r--r--DOCS/man/options.rst3
-rw-r--r--audio/filter/af.c34
-rw-r--r--audio/filter/af.h3
-rw-r--r--audio/filter/af_scaletempo.c5
-rw-r--r--audio/mixer.c4
-rw-r--r--audio/out/ao_alsa.c27
-rw-r--r--audio/out/ao_coreaudio_utils.c12
-rw-r--r--player/audio.c23
-rw-r--r--player/screenshot.c2
-rw-r--r--sub/dec_sub.c4
-rw-r--r--video/image_writer.c58
-rw-r--r--video/out/vo_direct3d.c2
-rw-r--r--video/out/vo_rpi.c2
-rw-r--r--video/out/vo_vdpau.c2
-rw-r--r--video/vdpau.c2
17 files changed, 115 insertions, 87 deletions
diff --git a/.travis.yml b/.travis.yml
index 31a5492e17..dab4b6d631 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@ language: c
os:
- linux
-# - osx
+ - osx
env:
matrix:
- LIBAV=libav-stable
diff --git a/DOCS/man/lua.rst b/DOCS/man/lua.rst
index d8912dac2b..4700b90cb2 100644
--- a/DOCS/man/lua.rst
+++ b/DOCS/man/lua.rst
@@ -356,6 +356,23 @@ The ``mp`` module is preloaded, although it can be loaded manually with
(``true``). This value is used when the timer expires (but before
the timer callback function fn is run).
+ Note that these are method, and you have to call them using ``:`` instead
+ of ``.`` (Refer to http://www.lua.org/manual/5.2/manual.html#3.4.9 .)
+
+ Example:
+
+ ::
+
+ seconds = 0
+ timer = mp.add_periodic_timer(1, function()
+ print("called every second")
+ # stop it after 10 seconds
+ seconds = seconds + 1
+ if seconds >= 10 then
+ timer:kill()
+ end
+ end)
+
``mp.get_opt(key)``
Return a setting from the ``--script-opts`` option. It's up to the user and
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index e86bb812d1..b380db9ffb 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -887,8 +887,7 @@ Audio
delay the audio, and negative values delay the video.
``--no-audio``
- Do not play sound. With some demuxers this may not work. In those cases
- you can try ``--ao=null`` instead.
+ Do not play sound.
``--mute=<auto|yes|no>``
Set startup audio mute status. ``auto`` (default) will not change the mute
diff --git a/audio/filter/af.c b/audio/filter/af.c
index 2889e87bb7..8d29e332a8 100644
--- a/audio/filter/af.c
+++ b/audio/filter/af.c
@@ -561,6 +561,23 @@ static int af_reinit(struct af_stream *s)
retry++;
continue;
}
+ // If the format conversion is (probably) caused by spdif, then
+ // (as a feature) drop the filter, instead of failing hard.
+ int fmt_in1 = af->prev->data->format;
+ int fmt_in2 = in.format;
+ if (af_fmt_is_valid(fmt_in1) && af_fmt_is_valid(fmt_in2)) {
+ bool spd1 = AF_FORMAT_IS_IEC61937(fmt_in1);
+ bool spd2 = AF_FORMAT_IS_IEC61937(fmt_in2);
+ if (spd1 != spd2) {
+ MP_WARN(af, "Filter %s apparently cannot be used due to "
+ "spdif passthrough - removing it.\n",
+ af->info->name);
+ struct af_instance *aft = af->prev;
+ af_remove(s, af);
+ af = aft->next;
+ break;
+ }
+ }
goto negotiate_error;
}
case AF_DETACH: { // Filter is redundant and wants to be unloaded
@@ -689,8 +706,14 @@ int af_init(struct af_stream *s)
to the stream s. The filter will be inserted somewhere nice in the
list of filters. The return value is a pointer to the new filter,
If the filter couldn't be added the return value is NULL. */
-struct af_instance *af_add(struct af_stream *s, char *name, char **args)
+struct af_instance *af_add(struct af_stream *s, char *name, char *label,
+ char **args)
{
+ assert(label);
+
+ if (af_find_by_label(s, label))
+ return NULL;
+
struct af_instance *new;
// Insert the filter somewhere nice
if (af_is_conversion_filter(s->first->next))
@@ -699,17 +722,14 @@ struct af_instance *af_add(struct af_stream *s, char *name, char **args)
new = af_prepend(s, s->first->next, name, args);
if (!new)
return NULL;
+ new->label = talloc_strdup(new, label);
// Reinitalize the filter list
if (af_reinit(s) != AF_OK) {
- af_remove(s, new);
- if (af_reinit(s) != AF_OK) {
- af_uninit(s);
- af_init(s);
- }
+ af_remove_by_label(s, label);
return NULL;
}
- return new;
+ return af_find_by_label(s, label);
}
struct af_instance *af_find_by_label(struct af_stream *s, char *label)
diff --git a/audio/filter/af.h b/audio/filter/af.h
index 4c67208123..65a30f7dd1 100644
--- a/audio/filter/af.h
+++ b/audio/filter/af.h
@@ -141,7 +141,8 @@ struct af_stream *af_new(struct mpv_global *global);
void af_destroy(struct af_stream *s);
int af_init(struct af_stream *s);
void af_uninit(struct af_stream *s);
-struct af_instance *af_add(struct af_stream *s, char *name, char **args);
+struct af_instance *af_add(struct af_stream *s, char *name, char *label,
+ char **args);
int af_remove_by_label(struct af_stream *s, char *label);
struct af_instance *af_find_by_label(struct af_stream *s, char *label);
struct af_instance *af_control_any_rev(struct af_stream *s, int cmd, void *arg);
diff --git a/audio/filter/af_scaletempo.c b/audio/filter/af_scaletempo.c
index 1f187a98bc..ad8e520601 100644
--- a/audio/filter/af_scaletempo.c
+++ b/audio/filter/af_scaletempo.c
@@ -303,11 +303,6 @@ static int control(struct af_instance *af, int cmd, void *arg)
int nch = data->nch;
int use_int = 0;
- if (AF_FORMAT_IS_SPECIAL(data->format)) {
- MP_ERR(af, "Changing speed is not supported with spdif formats.\n");
- return AF_ERROR;
- }
-
mp_audio_force_interleaved_format(data);
mp_audio_copy_config(af->data, data);
diff --git a/audio/mixer.c b/audio/mixer.c
index 0eb9c86453..7ae7ed458d 100644
--- a/audio/mixer.c
+++ b/audio/mixer.c
@@ -135,7 +135,7 @@ static void setvolume_internal(struct mixer *mixer, float l, float r)
if (gain == 1.0)
return;
MP_VERBOSE(mixer, "Inserting volume filter.\n");
- if (!(af_add(mixer->af, "volume", NULL)
+ if (!(af_add(mixer->af, "volume", "softvol", NULL)
&& af_control_any_rev(mixer->af, AF_CONTROL_SET_VOLUME, &gain)))
MP_ERR(mixer, "No volume control available.\n");
}
@@ -222,7 +222,7 @@ void mixer_setbalance(struct mixer *mixer, float val)
if (val == 0)
return;
- if (!(af_pan_balance = af_add(mixer->af, "pan", NULL))) {
+ if (!(af_pan_balance = af_add(mixer->af, "pan", "autopan", NULL))) {
MP_ERR(mixer, "No balance control available.\n");
return;
}
diff --git a/audio/out/ao_alsa.c b/audio/out/ao_alsa.c
index f84a781e8a..b60c8363f1 100644
--- a/audio/out/ao_alsa.c
+++ b/audio/out/ao_alsa.c
@@ -376,6 +376,7 @@ static int try_open_device(struct ao *ao, const char *device)
IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER,
map_iec958_srate(ao->samplerate));
const char *ac3_device = append_params(tmp, device, params);
+ MP_VERBOSE(ao, "opening device '%s' => '%s'\n", device, ac3_device);
int err = snd_pcm_open
(&p->alsa, ac3_device, SND_PCM_STREAM_PLAYBACK, 0);
talloc_free(tmp);
@@ -383,6 +384,7 @@ static int try_open_device(struct ao *ao, const char *device)
return 0;
}
+ MP_VERBOSE(ao, "opening device '%s'\n", device);
return snd_pcm_open(&p->alsa, device, SND_PCM_STREAM_PLAYBACK, 0);
}
@@ -408,23 +410,14 @@ static int init_device(struct ao *ao)
struct priv *p = ao->priv;
int err;
- if (!p->cfg_ni)
- ao->format = af_fmt_from_planar(ao->format);
-
const char *device = "default";
- if (AF_FORMAT_IS_IEC61937(ao->format)) {
+ if (AF_FORMAT_IS_IEC61937(ao->format))
device = "iec958";
- MP_VERBOSE(ao, "playing AC3/iec61937/iec958, %i channels\n",
- ao->channels.num);
- }
if (ao->device)
device = ao->device;
if (p->cfg_device && p->cfg_device[0])
device = p->cfg_device;
- MP_VERBOSE(ao, "using device: %s\n", device);
- MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
-
err = try_open_device(ao, device);
CHECK_ALSA_ERROR("Playback open error");
@@ -551,8 +544,11 @@ static int init_device(struct ao *ao)
err = snd_pcm_set_chmap(p->alsa, alsa_chmap);
if (err == -ENXIO) {
- MP_WARN(ao, "Device does not support requested channel map (%s)\n",
- mp_chmap_to_str(&dev_chmap));
+ // I consider this an ALSA bug: the channel map was reported as
+ // supported, but we still can't set it. It happens virtually
+ // always with dmix, though.
+ MP_VERBOSE(ao, "Device does not support requested channel map (%s)\n",
+ mp_chmap_to_str(&dev_chmap));
} else {
CHECK_ALSA_WARN("Channel map setup failed");
}
@@ -607,6 +603,7 @@ static int init_device(struct ao *ao)
// the number of channels to 2 either, because the hw params
// are already set! So just fuck it and reopen the device with
// the chmap "cleaned out" of NA entries.
+ MP_VERBOSE(ao, "Working around braindead ALSA behavior.\n");
err = snd_pcm_close(p->alsa);
p->alsa = NULL;
CHECK_ALSA_ERROR("pcm close error");
@@ -678,6 +675,12 @@ alsa_error:
static int init(struct ao *ao)
{
+ struct priv *p = ao->priv;
+ if (!p->cfg_ni)
+ ao->format = af_fmt_from_planar(ao->format);
+
+ MP_VERBOSE(ao, "using ALSA version: %s\n", snd_asoundlib_version());
+
int r = init_device(ao);
if (r == INIT_BRAINDEATH)
r = init_device(ao); // retry with normalized channel layout
diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c
index 64d98e5ece..8485011722 100644
--- a/audio/out/ao_coreaudio_utils.c
+++ b/audio/out/ao_coreaudio_utils.c
@@ -117,12 +117,12 @@ OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device)
if (mp_msg_test(ao->log, MSGL_V)) {
char *desc;
err = CA_GET_STR(*device, kAudioObjectPropertyName, &desc);
- CHECK_CA_ERROR("could not get selected audio device name");
-
- MP_VERBOSE(ao, "selected audio output device: %s (%" PRIu32 ")\n",
- desc, *device);
-
- talloc_free(desc);
+ CHECK_CA_WARN("could not get selected audio device name");
+ if (err == noErr) {
+ MP_VERBOSE(ao, "selected audio output device: %s (%" PRIu32 ")\n",
+ desc, *device);
+ talloc_free(desc);
+ }
}
coreaudio_error:
diff --git a/player/audio.c b/player/audio.c
index ba692e3955..6f91f8ee32 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -43,23 +43,6 @@
#include "core.h"
#include "command.h"
-static int try_filter(struct MPContext *mpctx,
- char *name, char *label, char **args)
-{
- struct dec_audio *d_audio = mpctx->d_audio;
-
- if (af_find_by_label(d_audio->afilter, label))
- return 0;
-
- struct af_instance *af = af_add(d_audio->afilter, name, args);
- if (!af)
- return -1;
-
- af->label = talloc_strdup(af, label);
-
- return 1;
-}
-
static int update_playback_speed_filters(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
@@ -90,7 +73,7 @@ static int update_playback_speed_filters(struct MPContext *mpctx)
char *filter = method == AF_CONTROL_SET_PLAYBACK_SPEED
? "scaletempo" : "lavrresample";
- if (try_filter(mpctx, filter, "playback-speed", NULL) < 0)
+ if (af_add(afs, filter, "playback-speed", NULL) < 0)
return -1;
// Try again.
if (!af_control_any_rev(afs, method, &speed))
@@ -260,8 +243,6 @@ void reinit_audio_chain(struct MPContext *mpctx)
}
if (!mpctx->ao) {
- afs->initialized = 0; // do it again
-
mp_chmap_remove_useless_channels(&afs->output.channels,
&opts->audio_output_channels);
mp_audio_set_channels(&afs->output, &afs->output.channels);
@@ -281,6 +262,8 @@ void reinit_audio_chain(struct MPContext *mpctx)
mp_audio_buffer_reinit(mpctx->ao_buffer, &fmt);
afs->output = fmt;
+ if (!mp_audio_config_equals(&afs->output, &afs->filter_output))
+ afs->initialized = 0;
mpctx->ao_decoder_fmt = talloc(NULL, struct mp_audio);
*mpctx->ao_decoder_fmt = in_format;
diff --git a/player/screenshot.c b/player/screenshot.c
index 27ef468544..4e80934494 100644
--- a/player/screenshot.c
+++ b/player/screenshot.c
@@ -349,7 +349,7 @@ static struct mp_image *screenshot_get(struct MPContext *mpctx, int mode)
if (image && mpctx->d_video && mpctx->d_video->hwdec_info) {
struct mp_hwdec_ctx *ctx = mpctx->d_video->hwdec_info->hwctx;
struct mp_image *nimage = NULL;
- if (ctx && ctx->download_image)
+ if (ctx && ctx->download_image && (image->fmt.flags & MP_IMGFLAG_HWACCEL))
nimage = ctx->download_image(ctx, image, NULL);
if (nimage) {
talloc_free(image);
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index 0a26e6f6a5..eb96131be7 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -49,8 +49,8 @@ static const struct sd_functions *const sd_list[] = {
&sd_movtext,
&sd_srt,
&sd_lavf_srt,
- &sd_lavc_conv,
&sd_microdvd,
+ &sd_lavc_conv,
NULL
};
@@ -344,7 +344,7 @@ static void multiply_timings(struct packet_list *subs, double factor)
}
}
-#define MS_TS(f_ts) ((int)((f_ts) * 1000 + 0.5))
+#define MS_TS(f_ts) ((long long)((f_ts) * 1000 + 0.5))
// Remove overlaps and fill gaps between adjacent subtitle packets. This is done
// by adjusting the duration of the earlier packet. If the gaps or overlap are
diff --git a/video/image_writer.c b/video/image_writer.c
index ab00b5bb01..939b435787 100644
--- a/video/image_writer.c
+++ b/video/image_writer.c
@@ -221,22 +221,42 @@ static int write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp)
#endif
+static int get_target_format(struct image_writer_ctx *ctx, int srcfmt)
+{
+ if (!ctx->writer->lavc_codec)
+ goto unknown;
+
+ struct AVCodec *codec = avcodec_find_encoder(ctx->writer->lavc_codec);
+ if (!codec)
+ goto unknown;
+
+ const enum AVPixelFormat *pix_fmts = codec->pix_fmts;
+ if (!pix_fmts)
+ goto unknown;
+
+ int current = 0;
+ for (int n = 0; pix_fmts[n] != AV_PIX_FMT_NONE; n++) {
+ int fmt = pixfmt2imgfmt(pix_fmts[n]);
+ if (!fmt)
+ continue;
+ current = current ? mp_imgfmt_select_best(current, fmt, srcfmt) : fmt;
+ }
+
+ if (!current)
+ goto unknown;
+
+ return current;
+
+unknown:
+ return IMGFMT_RGB24;
+}
+
static const struct img_writer img_writers[] = {
{ "png", write_lavc, .lavc_codec = AV_CODEC_ID_PNG },
{ "ppm", write_lavc, .lavc_codec = AV_CODEC_ID_PPM },
- { "pgm", write_lavc,
- .lavc_codec = AV_CODEC_ID_PGM,
- .pixfmts = (const int[]) { IMGFMT_Y8, 0 },
- },
- { "pgmyuv", write_lavc,
- .lavc_codec = AV_CODEC_ID_PGMYUV,
- .pixfmts = (const int[]) { IMGFMT_420P, 0 },
- },
- { "tga", write_lavc,
- .lavc_codec = AV_CODEC_ID_TARGA,
- .pixfmts = (const int[]) { IMGFMT_BGR24, IMGFMT_BGRA, IMGFMT_RGB555,
- IMGFMT_Y8, 0},
- },
+ { "pgm", write_lavc, .lavc_codec = AV_CODEC_ID_PGM },
+ { "pgmyuv", write_lavc, .lavc_codec = AV_CODEC_ID_PGMYUV },
+ { "tga", write_lavc, .lavc_codec = AV_CODEC_ID_TARGA },
#if HAVE_JPEG
{ "jpg", write_jpeg },
{ "jpeg", write_jpeg },
@@ -280,17 +300,7 @@ int write_image(struct mp_image *image, const struct image_writer_opts *opts,
const struct img_writer *writer = get_writer(opts);
struct image_writer_ctx ctx = { log, opts, writer };
- int destfmt = IMGFMT_RGB24;
-
- if (writer->pixfmts) {
- destfmt = writer->pixfmts[0]; // default to first pixel format
- for (const int *fmt = writer->pixfmts; *fmt; fmt++) {
- if (*fmt == image->imgfmt) {
- destfmt = *fmt;
- break;
- }
- }
- }
+ int destfmt = get_target_format(&ctx, image->imgfmt);
// Caveat: no colorspace/levels conversion done if pixel formats equal
// it's unclear what colorspace/levels the target wants
diff --git a/video/out/vo_direct3d.c b/video/out/vo_direct3d.c
index ac72efe2f8..b9e1b92326 100644
--- a/video/out/vo_direct3d.c
+++ b/video/out/vo_direct3d.c
@@ -1517,7 +1517,7 @@ static mp_image_t *get_window_screenshot(d3d_priv *priv)
if (width < 1 || height < 1)
goto error_exit;
- image = mp_image_alloc(IMGFMT_BGR32, width, height);
+ image = mp_image_alloc(IMGFMT_BGR0, width, height);
if (!image)
goto error_exit;
diff --git a/video/out/vo_rpi.c b/video/out/vo_rpi.c
index e197477987..48827b8a67 100644
--- a/video/out/vo_rpi.c
+++ b/video/out/vo_rpi.c
@@ -421,7 +421,7 @@ static struct mp_image *take_screenshot(struct vo *vo)
{
struct priv *p = vo->priv;
- struct mp_image *img = mp_image_alloc(IMGFMT_BGRA, p->w, p->h);
+ struct mp_image *img = mp_image_alloc(IMGFMT_BGR0, p->w, p->h);
if (!img)
return NULL;
diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c
index c0deea8178..f482b83236 100644
--- a/video/out/vo_vdpau.c
+++ b/video/out/vo_vdpau.c
@@ -831,7 +831,7 @@ static struct mp_image *read_output_surface(struct vo *vo,
if (!vo->params)
return NULL;
- struct mp_image *image = mp_image_alloc(IMGFMT_BGR32, width, height);
+ struct mp_image *image = mp_image_alloc(IMGFMT_BGR0, width, height);
if (!image)
return NULL;
diff --git a/video/vdpau.c b/video/vdpau.c
index 4ff3d6905a..2fd75a2970 100644
--- a/video/vdpau.c
+++ b/video/vdpau.c
@@ -70,7 +70,7 @@ static struct mp_image *download_image(struct mp_hwdec_ctx *hwctx,
mpi, &in) < 0)
goto error;
- res = mp_image_pool_get(swpool, IMGFMT_BGR32, ctx->getimg_w, ctx->getimg_h);
+ res = mp_image_pool_get(swpool, IMGFMT_BGR0, ctx->getimg_w, ctx->getimg_h);
if (!res)
goto error;