From 768448305292f50c72533597c25992b70e8e42ac Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Wed, 19 Oct 2016 11:54:47 -0700 Subject: demux_lavf: set title on hearing and visual impaired tracks --- demux/demux_lavf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 0188801aba..7857934642 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -699,6 +699,10 @@ static void handle_new_stream(demuxer_t *demuxer, int i) AVDictionaryEntry *title = av_dict_get(st->metadata, "title", NULL, 0); if (title && title->value) sh->title = talloc_strdup(sh, title->value); + if (!sh->title && st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED) + sh->title = talloc_asprintf(sh, "visual impaired"); + if (!sh->title && st->disposition & AV_DISPOSITION_HEARING_IMPAIRED) + sh->title = talloc_asprintf(sh, "hearing impaired"); AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); if (lang && lang->value) sh->lang = talloc_strdup(sh, lang->value); -- cgit v1.2.3 From dd02369c3223fda5bcb2658b15404d43232bb38f Mon Sep 17 00:00:00 2001 From: rr- Date: Thu, 13 Oct 2016 01:30:45 +0200 Subject: vo_tct: introduce modern caca alternative --- DOCS/man/vo.rst | 15 ++++ video/out/vo.c | 2 + video/out/vo_tct.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++ wscript_build.py | 1 + 4 files changed, 252 insertions(+) create mode 100644 video/out/vo_tct.c diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst index 34302f9a3f..fde62b4999 100644 --- a/DOCS/man/vo.rst +++ b/DOCS/man/vo.rst @@ -387,6 +387,21 @@ Available video output drivers are: .. note:: This driver is a joke. +``tct`` + Color Unicode art video output driver that works on a text console. + Depends on support of true color by modern terminals to display the images + at full color range. + + ``--vo-tct-algo=`` + Select how to write the pixels to the terminal. + + half-blocks + Uses unicode LOWER HALF BLOCK character to achieve higher vertical + resolution. (Default.) + plain + Uses spaces. Causes vertical resolution to drop twofolds, but in + theory works in more places. + ``image`` Output each frame into an image file in the current directory. Each file takes the frame number padded with leading zeros as name. diff --git a/video/out/vo.c b/video/out/vo.c index 4b28aadaa1..46908d2d59 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -59,6 +59,7 @@ extern const struct vo_driver video_out_sdl; extern const struct vo_driver video_out_vaapi; extern const struct vo_driver video_out_wayland; extern const struct vo_driver video_out_rpi; +extern const struct vo_driver video_out_tct; const struct vo_driver *const video_out_drivers[] = { @@ -89,6 +90,7 @@ const struct vo_driver *const video_out_drivers[] = &video_out_null, // should not be auto-selected &video_out_image, + &video_out_tct, #if HAVE_CACA &video_out_caca, #endif diff --git a/video/out/vo_tct.c b/video/out/vo_tct.c new file mode 100644 index 0000000000..22354c5283 --- /dev/null +++ b/video/out/vo_tct.c @@ -0,0 +1,234 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see . + */ + +#include +#include +#include +#include + +#include "options/m_config.h" +#include "config.h" +#include "vo.h" +#include "sub/osd.h" +#include "video/sws_utils.h" +#include "video/mp_image.h" + +#define IMGFMT IMGFMT_BGR24 + +#define ALGO_PLAIN 1 +#define ALGO_HALF_BLOCKS 2 +#define ESC_HIDE_CURSOR "\e[?25l" +#define ESC_RESTORE_CURSOR "\e[?25h" +#define ESC_CLEAR_SCREEN "\e[2J" +#define ESC_CLEAR_COLORS "\e[0m" +#define ESC_GOTOXY "\e[%d;%df" +#define ESC_COLOR_BACKGROUND "\e[48;2;%d;%d;%dm" +#define ESC_COLOR_FOREGROUND "\e[38;2;%d;%d;%dm" + +struct vo_tct_opts { + int algo; +}; + +#define OPT_BASE_STRUCT struct vo_tct_opts +static const struct m_sub_options vo_tct_conf = { + .opts = (const m_option_t[]) { + OPT_CHOICE("vo-tct-algo", algo, 0, + ({"plain", ALGO_PLAIN}, + {"half-blocks", ALGO_HALF_BLOCKS})), + {0} + }, + .defaults = &(const struct vo_tct_opts) { + .algo = ALGO_HALF_BLOCKS, + }, + .size = sizeof(struct vo_tct_opts), +}; + +struct priv { + struct vo_tct_opts *opts; + size_t buffer_size; + char *buffer; + int swidth; + int sheight; + struct mp_image *frame; + struct mp_rect src; + struct mp_rect dst; + struct mp_sws_context *sws; +}; + +static void write_plain( + const int dwidth, const int dheight, + const int swidth, const int sheight, + const unsigned char *source, const int source_stride) +{ + assert(source); + const int tx = (dwidth - swidth) / 2; + const int ty = (dheight - sheight) / 2; + for (int y = 0; y < sheight; y++) { + const unsigned char *row = source + y * source_stride; + printf(ESC_GOTOXY, ty + y, tx); + for (int x = 0; x < swidth; x++) { + unsigned char b = *row++; + unsigned char g = *row++; + unsigned char r = *row++; + printf(ESC_COLOR_BACKGROUND, r, g, b); + printf(" "); + } + printf(ESC_CLEAR_COLORS); + } + printf("\n"); +} + +static void write_half_blocks( + const int dwidth, const int dheight, + const int swidth, const int sheight, + unsigned char *source, int source_stride) +{ + assert(source); + const int tx = (dwidth - swidth) / 2; + const int ty = (dheight - sheight) / 2; + for (int y = 0; y < sheight * 2; y += 2) { + const unsigned char *row_up = source + y * source_stride; + const unsigned char *row_down = source + (y + 1) * source_stride; + printf(ESC_GOTOXY, ty + y / 2, tx); + for (int x = 0; x < swidth; x++) { + unsigned char b_up = *row_up++; + unsigned char g_up = *row_up++; + unsigned char r_up = *row_up++; + unsigned char b_down = *row_down++; + unsigned char g_down = *row_down++; + unsigned char r_down = *row_down++; + printf(ESC_COLOR_BACKGROUND, r_up, g_up, b_up); + printf(ESC_COLOR_FOREGROUND, r_down, g_down, b_down); + printf("▄"); + } + printf(ESC_CLEAR_COLORS); + } + printf("\n"); +} + +static int reconfig(struct vo *vo, struct mp_image_params *params) +{ + struct priv *p = vo->priv; + + struct winsize winsize; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize); + vo->dwidth = winsize.ws_col; + vo->dheight = winsize.ws_row; + + struct mp_osd_res osd; + vo_get_src_dst_rects(vo, &p->src, &p->dst, &osd); + p->swidth = p->dst.x1 - p->dst.x0; + p->sheight = p->dst.y1 - p->dst.y0; + + if (p->buffer) + free(p->buffer); + + mp_sws_set_from_cmdline(p->sws, vo->opts->sws_opts); + p->sws->src = *params; + p->sws->dst = (struct mp_image_params) { + .imgfmt = IMGFMT, + .w = p->swidth, + .h = p->sheight, + .p_w = 1, + .p_h = 1, + }; + + const int mul = (p->opts->algo == ALGO_PLAIN ? 1 : 2); + p->frame = mp_image_alloc(IMGFMT, p->swidth, p->sheight * mul); + if (!p->frame) + return -1; + + if (mp_sws_reinit(p->sws) < 0) + return -1; + + printf(ESC_HIDE_CURSOR); + printf(ESC_CLEAR_SCREEN); + vo->want_redraw = true; + return 0; +} + +static void draw_image(struct vo *vo, mp_image_t *mpi) +{ + struct priv *p = vo->priv; + struct mp_image src = *mpi; + // XXX: pan, crop etc. + mp_sws_scale(p->sws, p->frame, &src); + talloc_free(mpi); +} + +static void flip_page(struct vo *vo) +{ + struct priv *p = vo->priv; + if (p->opts->algo == ALGO_PLAIN) { + write_plain( + vo->dwidth, vo->dheight, p->swidth, p->sheight, + p->frame->planes[0], p->frame->stride[0]); + } else { + write_half_blocks( + vo->dwidth, vo->dheight, p->swidth, p->sheight, + p->frame->planes[0], p->frame->stride[0]); + } + fflush(stdout); +} + +static void uninit(struct vo *vo) +{ + printf(ESC_RESTORE_CURSOR); + printf(ESC_CLEAR_SCREEN); + printf(ESC_GOTOXY, 0, 0); + struct priv *p = vo->priv; + if (p->buffer) + talloc_free(p->buffer); + if (p->sws) + talloc_free(p->sws); +} + +static int preinit(struct vo *vo) +{ + // most terminal characters aren't 1:1, so we default to 2:1. + // if user passes their own value of choice, it'll be scaled accordingly. + vo->monitor_par = vo->opts->monitor_pixel_aspect * 2; + + struct priv *p = vo->priv; + p->opts = mp_get_config_group(vo, vo->global, &vo_tct_conf); + p->sws = mp_sws_alloc(vo); + return 0; +} + +static int query_format(struct vo *vo, int format) +{ + return format == IMGFMT; +} + +static int control(struct vo *vo, uint32_t request, void *data) +{ + return VO_NOTIMPL; +} + +const struct vo_driver video_out_tct = { + .name = "tct", + .description = "true-color terminals", + .preinit = preinit, + .query_format = query_format, + .reconfig = reconfig, + .control = control, + .draw_image = draw_image, + .flip_page = flip_page, + .uninit = uninit, + .priv_size = sizeof(struct priv), + .global_opts = &vo_tct_conf, +}; diff --git a/wscript_build.py b/wscript_build.py index cfab785ec0..e05bbe8d11 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -375,6 +375,7 @@ def build(ctx): ( "video/out/vo_opengl.c", "gl" ), ( "video/out/vo_opengl_cb.c", "gl" ), ( "video/out/vo_sdl.c", "sdl2" ), + ( "video/out/vo_tct.c", "posix" ), ( "video/out/vo_vaapi.c", "vaapi-x11" ), ( "video/out/vo_vdpau.c", "vdpau" ), ( "video/out/vo_wayland.c", "wayland" ), -- cgit v1.2.3 From 6b18d4dba527301d96b810d97f774dac03c6fb46 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 20 Oct 2016 16:43:02 +0200 Subject: video: add --hwdec=vdpau-copy mode At this point, all other hwaccels provide -copy modes, and vdpau is the exception with not having one. Although there is vf_vdpaurb, it's less convenient in certain situations, and exposes some issues with the filter chain code as well. --- DOCS/man/options.rst | 7 +++-- options/options.c | 1 + video/decode/vd_lavc.c | 2 ++ video/decode/vdpau.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++- video/hwdec.h | 1 + 5 files changed, 82 insertions(+), 4 deletions(-) diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 374cdaf1a5..b898082e13 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -610,6 +610,7 @@ Video :yes: exactly the same as ``auto`` :auto-copy: enable best hw decoder with copy-back (see below) :vdpau: requires ``--vo=vdpau`` or ``--vo=opengl`` (Linux only) + :vdpau-copy: copies video back into system RAM (Linux with some GPUs only) :vaapi: requires ``--vo=opengl`` or ``--vo=vaapi`` (Linux only) :vaapi-copy: copies video back into system RAM (Linux with Intel GPUs only) :videotoolbox: requires ``--vo=opengl`` (OS X 10.8 and up only) @@ -651,10 +652,10 @@ Video primarily implemented on the CPU. Some exceptions are ``vdpaupp``, ``vdpaurb`` and ``vavpp``. See `VIDEO FILTERS`_ for more details. - The ``vaapi-copy`` and ``dxva2-copy`` modes allow you to use hardware + The ``...-copy`` modes (e.g. ``dxva2-copy``) allow you to use hardware decoding with any VO, backend or filter. Because these copy the decoded - video back to system RAM, they're likely less efficient than the ``vaapi`` - or ``dxva2`` modes respectively. + video back to system RAM, they're likely less efficient than the direct + modes (like e.g. ``dxva2``). .. note:: diff --git a/options/options.c b/options/options.c index 3b071e3b47..f97ce5362b 100644 --- a/options/options.c +++ b/options/options.c @@ -93,6 +93,7 @@ const struct m_opt_choice_alternatives mp_hwdec_names[] = { {"yes" , HWDEC_AUTO}, {"auto-copy", HWDEC_AUTO_COPY}, {"vdpau", HWDEC_VDPAU}, + {"vdpau-copy", HWDEC_VDPAU_COPY}, {"videotoolbox",HWDEC_VIDEOTOOLBOX}, {"videotoolbox-copy",HWDEC_VIDEOTOOLBOX_COPY}, {"vaapi", HWDEC_VAAPI}, diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 12e60483ee..72209f5048 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -125,6 +125,7 @@ const struct m_sub_options vd_lavc_conf = { }; extern const struct vd_lavc_hwdec mp_vd_lavc_vdpau; +extern const struct vd_lavc_hwdec mp_vd_lavc_vdpau_copy; extern const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox; extern const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox_copy; extern const struct vd_lavc_hwdec mp_vd_lavc_vaapi; @@ -177,6 +178,7 @@ static const struct vd_lavc_hwdec *const hwdec_list[] = { #endif #if HAVE_VDPAU_HWACCEL &mp_vd_lavc_vdpau, + &mp_vd_lavc_vdpau_copy, #endif #if HAVE_VIDEOTOOLBOX_HWACCEL &mp_vd_lavc_videotoolbox, diff --git a/video/decode/vdpau.c b/video/decode/vdpau.c index 0003182dcb..a86f5d1edf 100644 --- a/video/decode/vdpau.c +++ b/video/decode/vdpau.c @@ -21,6 +21,7 @@ #include "lavc.h" #include "common/common.h" +#include "video/mp_image_pool.h" #include "video/vdpau.h" #include "video/hwdec.h" @@ -28,6 +29,9 @@ struct priv { struct mp_log *log; struct mp_vdpau_ctx *mpvdp; uint64_t preemption_counter; + // vdpau-copy + Display *display; + struct mp_image_pool *sw_pool; }; static int init_decoder(struct lavc_ctx *ctx, int w, int h) @@ -76,9 +80,16 @@ static void uninit(struct lavc_ctx *ctx) { struct priv *p = ctx->hwdec_priv; + if (p->display) { + // for copy path: we own this stuff + mp_vdpau_destroy(p->mpvdp); + XCloseDisplay(p->display); + } + talloc_free(p); - av_freep(&ctx->avctx->hwaccel_context); + if (ctx->avctx) + av_freep(&ctx->avctx->hwaccel_context); } static int init(struct lavc_ctx *ctx) @@ -102,6 +113,56 @@ static int probe(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, return 0; } +static int init_copy(struct lavc_ctx *ctx) +{ + struct priv *p = talloc_ptrtype(NULL, p); + *p = (struct priv) { + .log = mp_log_new(p, ctx->log, "vdpau"), + }; + + p->display = XOpenDisplay(NULL); + if (!p->display) + goto error; + + p->mpvdp = mp_vdpau_create_device_x11(p->log, p->display, true); + if (!p->mpvdp) + goto error; + + p->sw_pool = talloc_steal(p, mp_image_pool_new(17)); + + ctx->hwdec_priv = p; + + mp_vdpau_handle_preemption(p->mpvdp, &p->preemption_counter); + return 0; + +error: + if (p->display) + XCloseDisplay(p->display); + talloc_free(p); + return -1; +} + +static int probe_copy(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, + const char *codec) +{ + assert(!ctx->hwdec_priv); + int r = init_copy(ctx); + if (ctx->hwdec_priv) + uninit(ctx); + ctx->hwdec_priv = NULL; + + return r < 0 ? HWDEC_ERR_NO_CTX : 0; +} + +static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *img) +{ + struct priv *p = ctx->hwdec_priv; + struct mp_hwdec_ctx *hwctx = &p->mpvdp->hwctx; + struct mp_image *out = hwctx->download_image(hwctx, img, p->sw_pool); + talloc_free(img); + return out; +} + const struct vd_lavc_hwdec mp_vd_lavc_vdpau = { .type = HWDEC_VDPAU, .image_format = IMGFMT_VDPAU, @@ -112,3 +173,15 @@ const struct vd_lavc_hwdec mp_vd_lavc_vdpau = { .allocate_image = allocate_image, .process_image = update_format, }; + +const struct vd_lavc_hwdec mp_vd_lavc_vdpau_copy = { + .type = HWDEC_VDPAU_COPY, + .copying = true, + .image_format = IMGFMT_VDPAU, + .probe = probe_copy, + .init = init_copy, + .uninit = uninit, + .init_decoder = init_decoder, + .allocate_image = allocate_image, + .process_image = copy_image, +}; diff --git a/video/hwdec.h b/video/hwdec.h index 34b65fe15c..857d07c894 100644 --- a/video/hwdec.h +++ b/video/hwdec.h @@ -11,6 +11,7 @@ enum hwdec_type { HWDEC_AUTO, HWDEC_AUTO_COPY, HWDEC_VDPAU, + HWDEC_VDPAU_COPY, HWDEC_VIDEOTOOLBOX, HWDEC_VIDEOTOOLBOX_COPY, HWDEC_VAAPI, -- cgit v1.2.3 From 5da510b5fc26800598aa5bbd2c30ccf2f21cf662 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 20 Oct 2016 16:45:48 +0200 Subject: vf_vdpaurb: deprecate this filter --- DOCS/man/vf.rst | 2 ++ video/filter/vf_vdpaurb.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/DOCS/man/vf.rst b/DOCS/man/vf.rst index 10f30c65ef..fd155bb91d 100644 --- a/DOCS/man/vf.rst +++ b/DOCS/man/vf.rst @@ -807,6 +807,8 @@ Available filters are: Apply high quality VDPAU scaling (needs capable hardware). ``vdpaurb`` + This filter is deprecated. Use ``--hwdec=vdpau-copy`` instead. + VDPAU video read back. Works with ``--vo=vdpau`` and ``--vo=opengl`` only. This filter will read back frames decoded by VDPAU so that other filters, which are not normally compatible with VDPAU, can be used like normal. diff --git a/video/filter/vf_vdpaurb.c b/video/filter/vf_vdpaurb.c index 2e6da79766..59067b54bf 100644 --- a/video/filter/vf_vdpaurb.c +++ b/video/filter/vf_vdpaurb.c @@ -87,6 +87,9 @@ static int vf_open(vf_instance_t *vf) { struct vf_priv_s *p = vf->priv; + MP_WARN(vf, "This filter is deprecated and will be removed.\n"); + MP_WARN(vf, "Use --hwdec=vdpau-copy instead.\n"); + vf->filter_ext = filter_ext; vf->filter = NULL; vf->reconfig = reconfig; -- cgit v1.2.3 From 4bd3e51fbe61ae83bc9f6674646962d24ea1e075 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Wed, 19 Oct 2016 12:07:05 -0700 Subject: opengl: compile against iOS OpenGLES implementation --- video/out/opengl/common.h | 3 +++ video/out/opengl/header_fixes.h | 17 +++++++++++++++++ wscript | 6 +++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/video/out/opengl/common.h b/video/out/opengl/common.h index 5abe839b8d..afb5b61f7e 100644 --- a/video/out/opengl/common.h +++ b/video/out/opengl/common.h @@ -36,6 +36,9 @@ #include #include #include +#elif HAVE_IOS_GL +#include +#include #elif HAVE_ANDROID_GL #include #else diff --git a/video/out/opengl/header_fixes.h b/video/out/opengl/header_fixes.h index 9953f7e497..9a7108dcda 100644 --- a/video/out/opengl/header_fixes.h +++ b/video/out/opengl/header_fixes.h @@ -92,6 +92,23 @@ #define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB #endif +#if HAVE_IOS_GL +#define GL_WRITE_ONLY GL_WRITE_ONLY_OES +#define GL_TEXTURE_1D 0x0DE0 +#define GL_R16 0x822A +#define GL_RG16 0x822C +#define GL_RGB10 0x8052 +#define GL_RGB16 0x8054 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_LUMINANCE8 GL_LUMINANCE8_EXT +#define GL_LUMINANCE8_ALPHA8 GL_LUMINANCE8_ALPHA8_EXT +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#endif + // GL_ARB_timer_query and EXT_disjoint_timer_query #ifndef GL_TIME_ELAPSED // Same as GL_TIME_ELAPSED_EXT diff --git a/wscript b/wscript index 7dea08b8db..b309e32cd3 100644 --- a/wscript +++ b/wscript @@ -811,10 +811,14 @@ video_output_features = [ 'desc': 'Android OpenGL ES support', 'deps': ['android'], 'func': check_statement('GLES3/gl3.h', '(void)GL_RGB32F'), # arbitrary OpenGL ES 3.0 symbol + } , { + 'name': '--ios-gl', + 'desc': 'iOS OpenGL ES support', + 'func': check_statement('OpenGLES/ES3/glext.h', '(void)GL_RGB32F'), # arbitrary OpenGL ES 3.0 symbol } , { 'name': '--any-gl', 'desc': 'Any OpenGL (ES) support', - 'deps_any': ['standard-gl', 'android-gl', 'cocoa'], + 'deps_any': ['standard-gl', 'android-gl', 'ios-gl', 'cocoa'], 'func': check_true } , { 'name': '--plain-gl', -- cgit v1.2.3 From 26458419a79339a186028cb26d842f3b9fa9eb23 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Wed, 19 Oct 2016 13:40:10 -0700 Subject: wscript: videotoolbox is available on iOS even though IOSurface is not --- wscript | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wscript b/wscript index b309e32cd3..ccdf3a9fdc 100644 --- a/wscript +++ b/wscript @@ -660,7 +660,9 @@ video_output_features = [ 'desc': 'OpenGL Cocoa Backend', 'deps': [ 'cocoa' ], 'groups': [ 'gl' ], - 'func': check_true + 'func': check_statement('IOSurface/IOSurface.h', + 'IOSurfaceRef surface;', + framework='IOSurface') } , { 'name': '--gl-x11', 'desc': 'OpenGL X11 Backend', @@ -868,7 +870,6 @@ hwaccel_features = [ check_headers('VideoToolbox/VideoToolbox.h'), check_statement('libavcodec/videotoolbox.h', 'av_videotoolbox_alloc_context()', - framework='IOSurface', use='libav')), } , { 'name': '--videotoolbox-gl', -- cgit v1.2.3 From ee2ba599e7b0aa002dc7257458c19bdb64fd6252 Mon Sep 17 00:00:00 2001 From: "Dmitrij D. Czarkoff" Date: Thu, 20 Oct 2016 16:51:21 +0200 Subject: build: don't rely on "__thread" being always available with GCC Thread-local storage in GCC is platform-specific, and some platforms that are otherwise perfectly capable of running mpv may lack TLS support in GCC. This change adds a test for GCC variant of TLS and relies on its result instead of assumption. Provided that LLVM's `__thread` support is similar to GCC, the test is called "GCC/LLVM TLS". Signed-off-by: wm4 --- video/out/opengl/context.c | 2 +- wscript | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/video/out/opengl/context.c b/video/out/opengl/context.c index 0f5b61e37c..fb3471cd3b 100644 --- a/video/out/opengl/context.c +++ b/video/out/opengl/context.c @@ -125,7 +125,7 @@ int mpgl_validate_backend_opt(struct mp_log *log, const struct m_option *opt, #if HAVE_C11_TLS #define MP_TLS _Thread_local -#elif defined(__GNUC__) +#elif HAVE_GCC_TLS #define MP_TLS __thread #endif diff --git a/wscript b/wscript index ccdf3a9fdc..9fa00b01f0 100644 --- a/wscript +++ b/wscript @@ -185,6 +185,10 @@ main_dependencies = [ 'name': 'c11-tls', 'desc': 'C11 TLS support', 'func': check_statement('stddef.h', 'static _Thread_local int x = 0'), + }, { + 'name': 'gcc-tls', + 'desc': 'GCC TLS support', + 'func': check_statement('stddef.h', 'static __thread int x = 0'), }, { 'name': 'librt', 'desc': 'linking with -lrt', -- cgit v1.2.3 From cc9e8e7e3d64ca3673481618d896eeae8afb4992 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 20 Oct 2016 18:30:47 +0200 Subject: vo: vo_tct is now available on non-POSIX Fixes Windows build. --- video/out/vo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/video/out/vo.c b/video/out/vo.c index 46908d2d59..142f549aa0 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -90,7 +90,9 @@ const struct vo_driver *const video_out_drivers[] = &video_out_null, // should not be auto-selected &video_out_image, +#if HAVE_POSIX &video_out_tct, +#endif #if HAVE_CACA &video_out_caca, #endif -- cgit v1.2.3 From 773d52162e92530d5d0639caa804c56f42f0e8ab Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 20 Oct 2016 19:54:06 +0200 Subject: build: add required failure message for libavfilter check If req==True, a fmsg must be set (apparently). Fixes #3692, probably. --- wscript | 1 + 1 file changed, 1 insertion(+) diff --git a/wscript b/wscript index 9fa00b01f0..b347364d2c 100644 --- a/wscript +++ b/wscript @@ -430,6 +430,7 @@ FFmpeg/Libav libraries. You need at least {0}. Aborting.".format(libav_versions_ 'desc': 'libavfilter', 'func': check_pkg_config('libavfilter', '>= 5.0.0'), 'req': True, + 'fmsg': 'libavfilter is a required dependency.', }, { 'name': '--libavdevice', 'desc': 'libavdevice', -- cgit v1.2.3 From a6da4faac5e3f3f3f521760f78bef91721c22778 Mon Sep 17 00:00:00 2001 From: Ricardo Constantino Date: Thu, 20 Oct 2016 19:02:32 +0100 Subject: osc: fix crash after reaching a certain position in limited lists Don't try to display more items than there are in the chapter/playlist. Fixes #3691 --- player/lua/osc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/player/lua/osc.lua b/player/lua/osc.lua index ff7d9120ed..fec1eb07cb 100644 --- a/player/lua/osc.lua +++ b/player/lua/osc.lua @@ -672,7 +672,7 @@ function limited_list(prop, pos) end end - for i=min+1, max do + for i=min+1, math.min(max, count) do local item = proplist[i] item.current = (i-1 == pos) and true or nil table.insert(temp, item) -- cgit v1.2.3 From ea03ae157f081a898f5de40d1f8f82371f9df05d Mon Sep 17 00:00:00 2001 From: Ricardo Constantino Date: Fri, 21 Oct 2016 15:25:18 +0100 Subject: TOOLS/appveyor-install: install uchardet release instead --- TOOLS/appveyor-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TOOLS/appveyor-install.sh b/TOOLS/appveyor-install.sh index 37d74f5201..b0d276eab7 100755 --- a/TOOLS/appveyor-install.sh +++ b/TOOLS/appveyor-install.sh @@ -29,7 +29,7 @@ pacman -S --noconfirm --needed \ $MINGW_PACKAGE_PREFIX-libjpeg-turbo \ $MINGW_PACKAGE_PREFIX-lua51 \ $MINGW_PACKAGE_PREFIX-rubberband \ - $MINGW_PACKAGE_PREFIX-uchardet-git + $MINGW_PACKAGE_PREFIX-uchardet # Delete unused packages to reduce space used in the Appveyor cache pacman -Sc --noconfirm -- cgit v1.2.3 From 183af9d72eac25efc4b6a6a92249963cec5793f0 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Thu, 20 Oct 2016 11:20:23 -0700 Subject: player: speed up audio/video re-sync when there is a huge delay when there is a huge delay between audio/video sync, it can take a really long time to converge back. this speeds up the resync time by increasing the max_change allowed per iteration. Signed-off-by: wm4 --- player/video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/player/video.c b/player/video.c index ff72f92d8e..21babe016e 100644 --- a/player/video.c +++ b/player/video.c @@ -729,8 +729,9 @@ static void adjust_sync(struct MPContext *mpctx, double v_pts, double frame_time double av_delay = a_pts - v_pts; double change = av_delay * 0.1; + double factor = fabs(av_delay) < 0.3 ? 0.1 : 0.4; double max_change = opts->default_max_pts_correction >= 0 ? - opts->default_max_pts_correction : frame_time * 0.1; + opts->default_max_pts_correction : frame_time * factor; if (change < -max_change) change = -max_change; else if (change > max_change) -- cgit v1.2.3 From 7cd32ec29e9641362f4a14e4e1284040f9af9930 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Thu, 20 Oct 2016 11:11:56 -0700 Subject: audio: force pts_reset only when pts jumps forward more than 5s i've seen several mpegts samples where pts jumps backwards and repeats itself. this usually happens on live tv streams from cable providers, particularly when the stream switches from one advertisement to another. --- player/audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/player/audio.c b/player/audio.c index 3f173f140d..5c393f3d3a 100644 --- a/player/audio.c +++ b/player/audio.c @@ -840,8 +840,8 @@ static int filter_audio(struct MPContext *mpctx, struct mp_audio_buffer *outbuf, // Attempt to detect jumps in PTS. Even for the lowest sample rates // and with worst container rounded timestamp, this should be a // margin more than enough. - double desync = fabs(mpa->pts - ao_c->pts); - if (ao_c->pts != MP_NOPTS_VALUE && desync > 0.1) { + double desync = mpa->pts - ao_c->pts; + if (ao_c->pts != MP_NOPTS_VALUE && fabs(desync) > 0.1) { MP_WARN(ao_c, "Invalid audio PTS: %f -> %f\n", ao_c->pts, mpa->pts); if (desync >= 5) -- cgit v1.2.3 From 8b00d82b79393d0c09b1084c913e4067b9d8eaf5 Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Thu, 20 Oct 2016 11:43:17 -0700 Subject: player: guard against MPSEEK_RELATIVE when current pts is unknown in very rare circumstances, doing a relative seek like +1s will end up doing an absolute seek to 00:01. this guards against that possibility. so far i've only ever seen this issue when using --ad=lavc:ac3_at and doing several relative seeks in quick succession. this is likely either a bug in the audiotoolbox decoder in ffmpeg, or simply due to inherent latency in that hardware decoder which causes brief periods of time where the current audio pts is unknown. --- player/playloop.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/player/playloop.c b/player/playloop.c index 18a51f33d0..934b8ff0d9 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -249,6 +249,8 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek) bool hr_seek_very_exact = seek.exact == MPSEEK_VERY_EXACT; double current_time = get_current_time(mpctx); + if (current_time == MP_NOPTS_VALUE && seek.type == MPSEEK_RELATIVE) + return; if (current_time == MP_NOPTS_VALUE) current_time = 0; double seek_pts = MP_NOPTS_VALUE; -- cgit v1.2.3 From d38baa65cabdcc576e966fac7128242fb010abe5 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Thu, 20 Oct 2016 21:03:04 +0200 Subject: build: Set a default error message for #3692 This change will prevent annoying exceptions from appearing when error messages are missing. --- waftools/dependencies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waftools/dependencies.py b/waftools/dependencies.py index c1f3fdb022..87f236b362 100644 --- a/waftools/dependencies.py +++ b/waftools/dependencies.py @@ -119,7 +119,7 @@ the autodetection check failed.".format(self.identifier) if self.enabled_option() == False: return if self.attributes.get('req', False): - raise ConfigurationError(self.attributes['fmsg']) + raise ConfigurationError(self.attributes.get('fmsg', 'Unsatisfied requirement')) def skip(self, reason='disabled', color='YELLOW'): self.ctx.end_msg(self.__message__(reason), color) -- cgit v1.2.3 From b8b3163b859ab01cb5b2254e6c78fd63208d2f66 Mon Sep 17 00:00:00 2001 From: Rodger Combs Date: Fri, 21 Oct 2016 01:51:17 -0500 Subject: wscript: rebuild on library header changes In particular, libav/version.h changing should trigger a rebuild --- wscript | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wscript b/wscript index b347364d2c..0ce644b9de 100644 --- a/wscript +++ b/wscript @@ -4,10 +4,14 @@ import sys, os, re sys.path.insert(0, os.path.join(os.getcwd(), 'waftools')) sys.path.insert(0, os.getcwd()) from waflib.Configure import conf +from waflib.Tools import c_preproc from waflib import Utils from waftools.checks.generic import * from waftools.checks.custom import * +c_preproc.go_absolute=True # enable system folders +c_preproc.standard_includes.append('/usr/local/include') + build_options = [ { 'name': '--cplayer', -- cgit v1.2.3 From 61a51c57a9aae865930b4cc69a1480218e374404 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 21 Oct 2016 15:54:57 +0200 Subject: demux: don't try to refresh unselected streams This could cause nonsensical queue overflow warnings, but was otherwise probably harmless. --- demux/demux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demux/demux.c b/demux/demux.c index 3af0651dae..6041ada753 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -503,7 +503,7 @@ static double get_refresh_seek_pts(struct demux_internal *in) // Streams which didn't have any packets yet will return all packets, // other streams return packets only starting from the last position. if (ds->last_pos != -1 || ds->last_dts != MP_NOPTS_VALUE) - ds->refreshing = true; + ds->refreshing |= ds->selected; } // Seek back to player's current position, with a small offset added. -- cgit v1.2.3 From f64de3ea6659e6fe459700d1d03917990eb9d84a Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 21 Oct 2016 17:07:07 +0200 Subject: player: don't leave buffering during underflow Don't leave the buffering state while the demuxer is still marked as having underflowed. It's unclear why this hasn't been done before - with the logic being complicated as it is, maybe there was a reason for this. This is actually still not very reliable, but should be better than what was before: on stream switching decoders can read packets all while the demuxer is executing a refresh seek, which creates the underrun situation - but nothing really totally guarantees that the underrun state remains stable when the demuxer is back at the current demuxer position. Anyway, it's an improvement. The rest of the touched condition is not changed, just moved around for cosmetic reasons. --- player/playloop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/player/playloop.c b/player/playloop.c index 934b8ff0d9..4616db0744 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -608,8 +608,8 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx) if (mpctx->restart_complete && c.size > 0) { if (mpctx->paused && mpctx->paused_for_cache) { - if (!opts->cache_pausing || s.ts_duration >= mpctx->cache_wait_time - || s.idle) + if (!s.underrun && (!opts->cache_pausing || s.idle || + s.ts_duration >= mpctx->cache_wait_time)) { double elapsed_time = now - mpctx->cache_stop_time; if (elapsed_time > mpctx->cache_wait_time) { -- cgit v1.2.3 From 202f6953980a76e534a6e99136305407cb66e200 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 21 Oct 2016 17:23:26 +0200 Subject: vo_opengl: partially re-enable glFlush() calls It turns out the glFlush() call really helps in some cases, though only in audio timing mode (where we render, then wait for a while, then display the frame). Add a --opengl-early-flush=auto mode, which does exactly that. It's unclear whether this is fine on OSX (strange things going on there), but it should be. See #3670. --- DOCS/man/options.rst | 9 ++++++--- video/out/opengl/video.c | 9 +++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index b898082e13..45c0bca2f1 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -4598,10 +4598,13 @@ The following video options are currently all specific to ``--vo=opengl`` and we may have to deal with additional padding, which can be tested with these options). Could be removed any time. -``--opengl-early-flush=`` +``--opengl-early-flush=`` Call ``glFlush()`` after rendering a frame and before attempting to display - it (default: no). Can fix stuttering in some cases, in other cases probably - causes it. For testing - could be removed any time. + it (default: auto). Can fix stuttering in some cases, in other cases + probably causes it. The ``auto`` mode will call ``glFlush()`` only if + the renderer is going to wait for a while after rendering, instead of + flipping GL front and backbuffers immediately (i.e. it doesn't call it + in display-sync mode). Miscellaneous ------------- diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c index 9461153615..dadfe705ff 100644 --- a/video/out/opengl/video.c +++ b/video/out/opengl/video.c @@ -322,6 +322,7 @@ static const struct gl_video_opts gl_video_opts_def = { .target_brightness = 250, .hdr_tone_mapping = TONE_MAPPING_HABLE, .tone_mapping_param = NAN, + .early_flush = -1, }; static int validate_scaler_opt(struct mp_log *log, const m_option_t *opt, @@ -412,7 +413,8 @@ const struct m_sub_options gl_video_conf = { OPT_INTRANGE("opengl-tex-pad-x", tex_pad_x, 0, 0, 4096), OPT_INTRANGE("opengl-tex-pad-y", tex_pad_y, 0, 0, 4096), OPT_SUBSTRUCT("", icc_opts, mp_icc_conf, 0), - OPT_FLAG("opengl-early-flush", early_flush, 0), + OPT_CHOICE("opengl-early-flush", early_flush, 0, + ({"no", 0}, {"yes", 1}, {"auto", -1})), {0} }, @@ -2849,8 +2851,11 @@ done: // The playloop calls this last before waiting some time until it decides // to call flip_page(). Tell OpenGL to start execution of the GPU commands // while we sleep (this happens asynchronously). - if (p->opts.early_flush) + if ((p->opts.early_flush == -1 && !frame->display_synced) || + p->opts.early_flush == 1) + { gl->Flush(); + } p->frames_rendered++; -- cgit v1.2.3 From 9ea9bdf130a4f4f9669c0406dc26bf3713dee62c Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 21 Oct 2016 17:35:40 +0200 Subject: vo_opengl: context_rpi: fix stdatomic usage atomic_bool is not supported with e.g. atomic_fetch_and. Fixes #3699. Untested. --- video/out/opengl/context_rpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/video/out/opengl/context_rpi.c b/video/out/opengl/context_rpi.c index 96c8199ef4..fa19a6c205 100644 --- a/video/out/opengl/context_rpi.c +++ b/video/out/opengl/context_rpi.c @@ -42,7 +42,7 @@ struct priv { EGL_DISPMANX_WINDOW_T egl_window; int x, y, w, h; double display_fps; - atomic_bool reload_display; + atomic_int reload_display; int win_params[4]; }; -- cgit v1.2.3 From 5f544c1081b9fe70739555e77fe8c70afb9ae4b8 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 21 Oct 2016 18:50:40 +0200 Subject: manpage: fix a renamed option name --- DOCS/man/vo.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst index fde62b4999..039411a40c 100644 --- a/DOCS/man/vo.rst +++ b/DOCS/man/vo.rst @@ -159,7 +159,7 @@ Available video output drivers are: means timing is somewhat less accurate than without compositing, but with the composited mode behavior of the NVIDIA driver, there is no hard playback speed limit even without the disabled logic. Enabled by - default, use ``no-composite-detect`` to disable. + default, use ``--vo-vdpau-composite-detect=no`` to disable. ``--vo-vdpau-queuetime-windowed=`` and ``queuetime-fs=`` Use VDPAU's presentation queue functionality to queue future video frame changes at most this many milliseconds in advance (default: 50). -- cgit v1.2.3 From 082340b467703d7734e185f0c4c2334d06f853a3 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 21 Oct 2016 19:09:15 +0200 Subject: options: handle legacy no-* sub-options These accidentally did nothing. They must be handled explicitly. Example: --vo=vdpau:no-composite-detect (Can't wait to get rid of this crap.) --- options/m_config.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/options/m_config.c b/options/m_config.c index 576527c0c5..9733dac3cd 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -269,16 +269,27 @@ struct m_config *m_config_from_obj_desc_noalloc(void *talloc_ctx, return m_config_new(talloc_ctx, log, 0, desc->priv_defaults, desc->options); } +static struct m_config_option *m_config_find_negation_opt(struct m_config *config, + struct bstr *name); + static int m_config_set_obj_params(struct m_config *config, struct mp_log *log, struct mpv_global *global, struct m_obj_desc *desc, char **args) { for (int n = 0; args && args[n * 2 + 0]; n++) { - const char *opt = args[n * 2 + 0]; + bstr opt = bstr0(args[n * 2 + 0]); const char *val = args[n * 2 + 1]; - struct m_config_option *co = m_config_get_co(config, bstr0(opt)); - if (!co) - continue; + struct m_config_option *co = m_config_get_co(config, opt); + if (!co) { + co = m_config_find_negation_opt(config, &opt); + if (!co) + continue; + + if (val && val[0]) + return -1; // no parameter allowed + + val = "no"; + } struct m_config *target = config; bool is_legacy = co->opt->type == &m_option_type_subopt_legacy; bool force_legacy = !!desc->legacy_prefix; @@ -289,16 +300,18 @@ static int m_config_set_obj_params(struct m_config *config, struct mp_log *log, if (is_legacy) { newopt = co->opt->priv; } else { - snprintf(tmp, sizeof(tmp), "%s-%s", desc->legacy_prefix, opt); + snprintf(tmp, sizeof(tmp), "%s-%.*s", desc->legacy_prefix, + BSTR_P(opt)); newopt = tmp; } assert(global); target = mp_get_root_config(global); mp_warn(log, "Using suboptions is deprecated. Use the global '--%s' " - "option instead of '%s' suboption.\n", newopt, opt); - opt = newopt; + "option instead of '%.*s' suboption.\n", newopt, + BSTR_P(opt)); + opt = bstr0(newopt); } - if (m_config_set_option(target, bstr0(opt), bstr0(val)) < 0) + if (m_config_set_option(target, opt, bstr0(val)) < 0) return -1; } -- cgit v1.2.3 From 11b8cbcce7efd02bee5c7427a4fa157bf20199e4 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 22 Oct 2016 15:33:20 +0200 Subject: command: fix reset-on-next-file=all and tv-freq option The tv-freq options and properties use different types, thus must be treated as incompatible. Fixes an assertion with reset-on-next-file=all, which tries to set the option. Fixes #3708. --- player/command.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/player/command.c b/player/command.c index 1fa4695a91..0d5106227c 100644 --- a/player/command.c +++ b/player/command.c @@ -287,10 +287,11 @@ int mp_on_set_option(void *ctx, struct m_config_option *co, void *data, int flag // OK, is handled separately: playlist // OK, does not conflict on low level: audio-file, sub-file, external-file // OK, different value ranges, but happens to work for now: volume, edition + // Incompatible: tv-freq // All the other properties are deprecated in their current form. static const char *const no_property[] = { "demuxer", "idle", "length", "audio-samplerate", "audio-channels", - "audio-format", "fps", "cache", "playlist-pos", "chapter", + "audio-format", "fps", "cache", "playlist-pos", "chapter", "tv-freq", NULL }; -- cgit v1.2.3 From bf5c4c42fa4366b707234e8feb5036ca3c03f056 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 22 Oct 2016 16:02:52 +0200 Subject: command: silence deprecation warnings with --reset-on-next-file=all --reset-on-next-file=all triggers m_config_backup_all_opts(), which backups all options (even deprecated ones). Later, when the option values are reset with m_config_restore_backups(), mp_on_set_option() is called, which in turn calls mp_property_do_silent(), which in turn will call mp_property_generic_option() and m_config_get_co(), which triggers the deprecation message. Unfortunately there's no good way to determine whether an option has actually changed (there's no option value compare operation), so the deprecated options have to be set no matter what. On the other hand, we can't pass through additional flags through the property layer. So we add a dumb global flag to silence the deprecation warnings in these cases. Fortunately m_config_get_co_raw() works to silence the warnings. m_config_get_co() also resolves aliases (deprecated and non-deprecated), but aliased options are handled differently by the option-property bridge, so we don't need to do that here, so the only purpose of it is to trigger a warning for deprecated (non-alias) options. --- player/command.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/player/command.c b/player/command.c index 0d5106227c..ea0df509e1 100644 --- a/player/command.c +++ b/player/command.c @@ -104,6 +104,8 @@ struct command_ctx { char *cur_ipc; char *cur_ipc_input; + + int silence_option_deprecations; }; struct overlay { @@ -342,8 +344,13 @@ static int mp_property_generic_option(void *ctx, struct m_property *prop, MPContext *mpctx = ctx; const char *optname = prop->name; int flags = M_SETOPT_RUNTIME; - struct m_config_option *opt = m_config_get_co(mpctx->mconfig, - bstr0(optname)); + struct m_config_option *opt; + if (mpctx->command_ctx->silence_option_deprecations) { + // This case is specifically for making --reset-on-next-file=all silent. + opt = m_config_get_co_raw(mpctx->mconfig, bstr0(optname)); + } else { + opt = m_config_get_co(mpctx->mconfig, bstr0(optname)); + } if (!opt) return M_PROPERTY_UNKNOWN; @@ -4154,7 +4161,9 @@ static int mp_property_do_silent(const char *name, int action, void *val, struct MPContext *ctx) { struct command_ctx *cmd = ctx->command_ctx; + cmd->silence_option_deprecations += 1; int r = m_property_do(ctx->log, cmd->properties, name, action, val, ctx); + cmd->silence_option_deprecations -= 1; if (r == M_PROPERTY_OK && is_property_set(action, val)) mp_notify_property(ctx, (char *)name); return r; -- cgit v1.2.3 From 1bf474e19afac869f643de0f51befdaed2872d23 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 22 Oct 2016 16:39:24 +0200 Subject: options: make --load-scripts runtime changeable Just that actually changing it at runtime won't do anything. This deals with a nasty initialization order issue with encoding. Encoding is initialized after options have initialized, but before --load-scripts is checked and executed. Encoding initialization accesses FFmpeg API, thus it has to run after FFmpeg is initialized (which also implies it's initialized after options/logging init). On the other hand, it sets the encoding builtin profile, which possibly sets --load-scripts to "no". That failed at this point because --load-scripts was marked as fixed. Just marking it as not fixed gets rid of the headache, even if it's not perfectly orthodox. --- options/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/options/options.c b/options/options.c index f97ce5362b..7a4deae776 100644 --- a/options/options.c +++ b/options/options.c @@ -302,7 +302,7 @@ const m_option_t mp_opts[] = { OPT_FLAG("ytdl", lua_load_ytdl, UPDATE_BUILTIN_SCRIPTS), OPT_STRING("ytdl-format", lua_ytdl_format, 0), OPT_KEYVALUELIST("ytdl-raw-options", lua_ytdl_raw_options, 0), - OPT_FLAG("load-scripts", auto_load_scripts, M_OPT_FIXED), + OPT_FLAG("load-scripts", auto_load_scripts, 0), #endif // ------------------------- stream options -------------------- -- cgit v1.2.3 From 3a78eefc88ecb354d1415f43bbf19d57caa31918 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 22 Oct 2016 17:17:04 +0200 Subject: demux_mkv: don't recursively resolve timeline for opened reference files Instead, resolve all references and so on in the top-level timeline. --- demux/demux.c | 22 ++++++++++++---------- demux/demux.h | 1 + demux/demux_mkv_timeline.c | 1 + 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/demux/demux.c b/demux/demux.c index 6041ada753..5072eb9f05 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -1287,16 +1287,18 @@ static struct demuxer *open_given_type(struct mpv_global *global, demux_changed(in->d_thread, DEMUX_EVENT_ALL); demux_update(demuxer); stream_control(demuxer->stream, STREAM_CTRL_SET_READAHEAD, &(int){false}); - struct timeline *tl = timeline_load(global, log, demuxer); - if (tl) { - struct demuxer_params params2 = {0}; - params2.timeline = tl; - struct demuxer *sub = open_given_type(global, log, - &demuxer_desc_timeline, stream, - ¶ms2, DEMUX_CHECK_FORCE); - if (sub) - return sub; - timeline_destroy(tl); + if (!(params && params->disable_timeline)) { + struct timeline *tl = timeline_load(global, log, demuxer); + if (tl) { + struct demuxer_params params2 = {0}; + params2.timeline = tl; + struct demuxer *sub = + open_given_type(global, log, &demuxer_desc_timeline, stream, + ¶ms2, DEMUX_CHECK_FORCE); + if (sub) + return sub; + timeline_destroy(tl); + } } return demuxer; } diff --git a/demux/demux.h b/demux/demux.h index 39c2600257..18f52d463d 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -161,6 +161,7 @@ struct demuxer_params { int matroska_wanted_segment; bool *matroska_was_valid; struct timeline *timeline; + bool disable_timeline; // -- demux_open_url() only int stream_flags; bool allow_capture; diff --git a/demux/demux_mkv_timeline.c b/demux/demux_mkv_timeline.c index 30d669c77f..6e18fd2562 100644 --- a/demux/demux_mkv_timeline.c +++ b/demux/demux_mkv_timeline.c @@ -170,6 +170,7 @@ static bool check_file_seg(struct tl_ctx *ctx, char *filename, int segment) .matroska_wanted_uids = ctx->uids, .matroska_wanted_segment = segment, .matroska_was_valid = &was_valid, + .disable_timeline = true, .disable_cache = true, }; struct mp_cancel *cancel = ctx->tl->cancel; -- cgit v1.2.3 From 18681a7dd26cacac9a9df9aac696d5c4f172b34d Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Sat, 22 Oct 2016 18:55:31 +0300 Subject: demux_mkv: fix ordered chapter sources with ordered editions Commit f72a900892 (and others) added support for ordered editions that recursively refer to other ordered editions. However, this recursion code incorrectly activated if the source files had ordered chapters even if the main file only wanted to use them as raw video, resulting in broken timeline info overall. Ordered chapters can specify a ChapterSegmentEditionUID value if they want to use a specific edition from a source file. Otherwise the source is supposed to be used as a raw video file. The code checked demuxer->matroska_data.num_ordered_chapters for an opened source file to see whether it was using a recursive ordered edition, but demux_mkv could enable a default ordered edition for the file using the normal playback rules even if the main file had not specified any ChapterSegmentEditionUID. Thus this incorrectly enabled recursion if a source file had a default edition using ordered chapters. Check demuxer->matroska_data.uid.edition instead, and ensure it's never set if a file is opened without ChapterSegmentEditionUID. Also fix what seems like a memory leak in demux_mkv.c. Signed-off-by: wm4 --- demux/demux_mkv.c | 1 + demux/demux_mkv_timeline.c | 30 +++++++++++++++++------------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 95eab29ec9..b9e723a53c 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -862,6 +862,7 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer) if (wanted_edition_uid) { MP_ERR(demuxer, "Unable to find expected edition uid: %"PRIu64"\n", wanted_edition_uid); + talloc_free(parse_ctx.talloc_ctx); return -1; } else { selected_edition = 0; diff --git a/demux/demux_mkv_timeline.c b/demux/demux_mkv_timeline.c index 6e18fd2562..15f9a5d594 100644 --- a/demux/demux_mkv_timeline.c +++ b/demux/demux_mkv_timeline.c @@ -188,27 +188,31 @@ static bool check_file_seg(struct tl_ctx *ctx, char *filename, int segment) if (ctx->sources[i]) continue; /* Accept the source if the segment uid matches and the edition - * either matches or isn't specified. */ + * either matches or isn't specified. */ if (!memcmp(uid->segment, m->uid.segment, 16) && (!uid->edition || uid->edition == m->uid.edition)) { MP_INFO(ctx, "Match for source %d: %s\n", i, d->filename); - for (int j = 0; j < m->num_ordered_chapters; j++) { - struct matroska_chapter *c = m->ordered_chapters + j; + if (!uid->edition) { + m->uid.edition = 0; + } else { + for (int j = 0; j < m->num_ordered_chapters; j++) { + struct matroska_chapter *c = m->ordered_chapters + j; - if (!c->has_segment_uid) - continue; + if (!c->has_segment_uid) + continue; - if (has_source_request(ctx, &c->uid)) - continue; + if (has_source_request(ctx, &c->uid)) + continue; - /* Set the requested segment. */ - MP_TARRAY_GROW(NULL, ctx->uids, ctx->num_sources); - ctx->uids[ctx->num_sources] = c->uid; + /* Set the requested segment. */ + MP_TARRAY_GROW(NULL, ctx->uids, ctx->num_sources); + ctx->uids[ctx->num_sources] = c->uid; - /* Add a new source slot. */ - MP_TARRAY_APPEND(NULL, ctx->sources, ctx->num_sources, NULL); + /* Add a new source slot. */ + MP_TARRAY_APPEND(NULL, ctx->sources, ctx->num_sources, NULL); + } } if (stream_wants_cache(d->stream, ctx->opts->stream_cache)) { @@ -379,7 +383,7 @@ static void build_timeline_loop(struct tl_ctx *ctx, /* If we're the source or it's a non-ordered edition reference, * just add a timeline part from the source. */ - if (current_source == j || !linked_m->num_ordered_chapters) { + if (current_source == j || !linked_m->uid.edition) { uint64_t source_full_length = demuxer_get_time_length(linked_source) * 1e9; uint64_t source_length = source_full_length - c->start; -- cgit v1.2.3 From d0b997d5287966245a4f368af64e2b0c72bd3a1a Mon Sep 17 00:00:00 2001 From: Aman Gupta Date: Thu, 20 Oct 2016 11:19:43 -0700 Subject: player: make --start-time work with --rebase-start-time=no --- player/loadfile.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/player/loadfile.c b/player/loadfile.c index ec8ddd6004..6ea4479d7a 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -1139,6 +1139,9 @@ reopen_file: startpos = start; } if (startpos != MP_NOPTS_VALUE) { + if (!opts->rebase_start_time) { + startpos += mpctx->demuxer->start_time; + } queue_seek(mpctx, MPSEEK_ABSOLUTE, startpos, MPSEEK_DEFAULT, 0); execute_queued_seek(mpctx); } -- cgit v1.2.3 From 61ff2408e395eb723c9adc7e2d13d205f496836e Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 23 Oct 2016 17:38:58 +0200 Subject: manpage: document ytdl:// --- DOCS/man/mpv.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/DOCS/man/mpv.rst b/DOCS/man/mpv.rst index f4876ac00e..4ceae1ca27 100644 --- a/DOCS/man/mpv.rst +++ b/DOCS/man/mpv.rst @@ -646,6 +646,15 @@ PROTOCOLS either aliases to documented protocols, or are just redirections to protocols implemented and documented in FFmpeg. +``ytdl://...`` + By default, the youtube-dl hook script (enabled by default for mpv CLI) + only looks at http URLs. Prefixing an URL with ``ytdl://`` forces it to + be always processed by the script. This can also be used to invoke special + youtube-dl functionality like playing a video by ID or invoking search. + + Keep in mind that you can't pass youtube-dl command line options by this, + and you have to use ``--ytdl-raw-options`` instead. + ``-`` Play data from stdin. -- cgit v1.2.3 From 6e143ffec327b3f3afdd682aea14c5d15628fbe8 Mon Sep 17 00:00:00 2001 From: Ricardo Constantino Date: Sun, 23 Oct 2016 17:21:08 +0100 Subject: man/osc: reorder a few options for better visibility Also document pre-0.21.0 defaults. --- DOCS/man/osc.rst | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/DOCS/man/osc.rst b/DOCS/man/osc.rst index 20f7fbf7e6..ce6471d014 100644 --- a/DOCS/man/osc.rst +++ b/DOCS/man/osc.rst @@ -147,6 +147,31 @@ Example:: Configurable Options ~~~~~~~~~~~~~~~~~~~~ +``layout`` + | Default: bottombar + | The layout for the OSC. Currently available are: box, slimbox, + bottombar and topbar. Default pre-0.21.0 was 'box'. + +``seekbarstyle`` + | Default: bar + | Sets the style of the seekbar, slider (diamond marker) or bar (fill). + Default pre-0.21.0 was 'slider'. + +``deadzonesize`` + | Default: 1.0 + | Size of the deadzone. The deadzone is an area that makes the mouse act + like leaving the window. Movement there won't make the OSC show up and + it will hide immediately if the mouse enters it. The deadzone starts + at the window border opposite to the OSC and the size controls how much + of the window it will span. Values between 0.0 and 1.0, where 0 means the + OSC will always popup with mouse movement in the window, and 1 means the + OSC will only show up when the mouse hovers it. Default pre-0.21.0 was 0. + +``minmousemove`` + | Default: 0 + | Minimum amount of pixels the mouse has to move between ticks to make + the OSC show up. Default pre-0.21.0 was 3. + ``showwindowed`` | Default: yes | Enable the OSC when windowed @@ -197,30 +222,6 @@ Configurable Options | Default: 200 | Duration of fade out in ms, 0 = no fade -``deadzonesize`` - | Default: 1 - | Size of the deadzone. The deadzone is an area that makes the mouse act - like leaving the window. Movement there won't make the OSC show up and - it will hide immediately if the mouse enters it. The deadzone starts - at the window border opposite to the OSC and the size controls how much - of the window it will span. Values between 0 and 1, where 0 means the - OSC will always popup with mouse movement in the window, and 1 means the - OSC will only show up when the mouse hovers it. - -``minmousemove`` - | Default: 0 - | Minimum amount of pixels the mouse has to move between ticks to make - the OSC show up - -``layout`` - | Default: bottombar - | The layout for the OSC. Currently available are: box, slimbox, - bottombar and topbar. - -``seekbarstyle`` - | Default: bar - | Sets the style of the seekbar, slider (diamond marker) or bar (fill) - ``tooltipborder`` | Default: 1 | Size of the tooltip outline when using bottombar or topbar layouts -- cgit v1.2.3 From 02d2c2cc9722dbda832917118bd4190a38e70f5a Mon Sep 17 00:00:00 2001 From: "Avi Halachmi (:avih)" Date: Sat, 22 Oct 2016 02:38:32 +0300 Subject: vo_tct: optional custom size, support non-posix with 80x25 default Also, replace the UTF8 half block char at the source code with C escape. --- DOCS/man/vo.rst | 6 +++++- video/out/vo.c | 2 -- video/out/vo_tct.c | 36 +++++++++++++++++++++++++++++++----- wscript_build.py | 2 +- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst index 039411a40c..9575948eea 100644 --- a/DOCS/man/vo.rst +++ b/DOCS/man/vo.rst @@ -390,7 +390,7 @@ Available video output drivers are: ``tct`` Color Unicode art video output driver that works on a text console. Depends on support of true color by modern terminals to display the images - at full color range. + at full color range. On Windows it requires an ansi terminal such as mintty. ``--vo-tct-algo=`` Select how to write the pixels to the terminal. @@ -402,6 +402,10 @@ Available video output drivers are: Uses spaces. Causes vertical resolution to drop twofolds, but in theory works in more places. + ``--vo-tct-width=`` ``--vo-tct-height=`` + Assume the terminal has the specified character width and/or height. + These default to 80x25 if the terminal size cannot be determined. + ``image`` Output each frame into an image file in the current directory. Each file takes the frame number padded with leading zeros as name. diff --git a/video/out/vo.c b/video/out/vo.c index 142f549aa0..46908d2d59 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -90,9 +90,7 @@ const struct vo_driver *const video_out_drivers[] = &video_out_null, // should not be auto-selected &video_out_image, -#if HAVE_POSIX &video_out_tct, -#endif #if HAVE_CACA &video_out_caca, #endif diff --git a/video/out/vo_tct.c b/video/out/vo_tct.c index 22354c5283..c72a66e940 100644 --- a/video/out/vo_tct.c +++ b/video/out/vo_tct.c @@ -17,7 +17,12 @@ #include #include +#include + +#if HAVE_POSIX #include +#endif + #include #include "options/m_config.h" @@ -38,9 +43,13 @@ #define ESC_GOTOXY "\e[%d;%df" #define ESC_COLOR_BACKGROUND "\e[48;2;%d;%d;%dm" #define ESC_COLOR_FOREGROUND "\e[38;2;%d;%d;%dm" +#define DEFAULT_WIDTH 80 +#define DEFAULT_HEIGHT 25 struct vo_tct_opts { int algo; + int width; // 0 -> default + int height; // 0 -> default }; #define OPT_BASE_STRUCT struct vo_tct_opts @@ -49,6 +58,8 @@ static const struct m_sub_options vo_tct_conf = { OPT_CHOICE("vo-tct-algo", algo, 0, ({"plain", ALGO_PLAIN}, {"half-blocks", ALGO_HALF_BLOCKS})), + OPT_INT("vo-tct-width", width, 0), + OPT_INT("vo-tct-height", height, 0), {0} }, .defaults = &(const struct vo_tct_opts) { @@ -113,21 +124,36 @@ static void write_half_blocks( unsigned char r_down = *row_down++; printf(ESC_COLOR_BACKGROUND, r_up, g_up, b_up); printf(ESC_COLOR_FOREGROUND, r_down, g_down, b_down); - printf("▄"); + printf("\xe2\x96\x84"); // UTF8 bytes of U+2584 (lower half block) } printf(ESC_CLEAR_COLORS); } printf("\n"); } +static void get_win_size(struct vo *vo, int *out_width, int *out_height) { + struct priv *p = vo->priv; +#if HAVE_POSIX + struct winsize winsize; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize); + *out_width = winsize.ws_col; + *out_height = winsize.ws_row; +#else + *out_width = DEFAULT_WIDTH; + *out_height = DEFAULT_HEIGHT; +#endif + + if (p->opts->width > 0