diff options
author | Diogo Franco (Kovensky) <diogomfranco@gmail.com> | 2015-04-09 20:42:14 +0900 |
---|---|---|
committer | Diogo Franco (Kovensky) <diogomfranco@gmail.com> | 2015-04-09 20:42:14 +0900 |
commit | 35e9d75083eef3ffbaa463dd0a38e170730d31f0 (patch) | |
tree | 728d523940c0829eff7aba26fd1b6f882a34dcdc | |
parent | 4a84cd37f3833b6751eae1448f6b40d88e0b6aad (diff) | |
parent | 7a65c44922d5be4a67be4e4c3f4fd47cb06c5e00 (diff) | |
download | mpv-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.yml | 2 | ||||
-rw-r--r-- | DOCS/man/lua.rst | 17 | ||||
-rw-r--r-- | DOCS/man/options.rst | 3 | ||||
-rw-r--r-- | audio/filter/af.c | 34 | ||||
-rw-r--r-- | audio/filter/af.h | 3 | ||||
-rw-r--r-- | audio/filter/af_scaletempo.c | 5 | ||||
-rw-r--r-- | audio/mixer.c | 4 | ||||
-rw-r--r-- | audio/out/ao_alsa.c | 27 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_utils.c | 12 | ||||
-rw-r--r-- | player/audio.c | 23 | ||||
-rw-r--r-- | player/screenshot.c | 2 | ||||
-rw-r--r-- | sub/dec_sub.c | 4 | ||||
-rw-r--r-- | video/image_writer.c | 58 | ||||
-rw-r--r-- | video/out/vo_direct3d.c | 2 | ||||
-rw-r--r-- | video/out/vo_rpi.c | 2 | ||||
-rw-r--r-- | video/out/vo_vdpau.c | 2 | ||||
-rw-r--r-- | video/vdpau.c | 2 |
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; |