diff options
author | Martin Herkt <lachs0r@srsfckn.biz> | 2016-08-15 15:19:29 +0200 |
---|---|---|
committer | Martin Herkt <lachs0r@srsfckn.biz> | 2016-08-15 15:19:29 +0200 |
commit | fd1bc95b4865ff789780c2213eefbdf77f0d4d1f (patch) | |
tree | 639e098e46cf1b77ecea7df95d7b968c25e1d0c9 /video | |
parent | 1e00bcc14c9b0d9beb8e152f958fc0db4bc6d31b (diff) | |
parent | d7a7e9a8c861c4a9881fcef5cf69c746742b8b88 (diff) | |
download | mpv-fd1bc95b4865ff789780c2213eefbdf77f0d4d1f.tar.bz2 mpv-fd1bc95b4865ff789780c2213eefbdf77f0d4d1f.tar.xz |
Merge branch 'master' into release/current
Diffstat (limited to 'video')
43 files changed, 523 insertions, 442 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 5962f883cd..eb63e58e92 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -126,6 +126,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_videotoolbox; +extern const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox_copy; extern const struct vd_lavc_hwdec mp_vd_lavc_vaapi; extern const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy; extern const struct vd_lavc_hwdec mp_vd_lavc_dxva2; @@ -158,6 +159,7 @@ static const struct vd_lavc_hwdec *const hwdec_list[] = { #endif #if HAVE_VIDEOTOOLBOX_HWACCEL &mp_vd_lavc_videotoolbox, + &mp_vd_lavc_videotoolbox_copy, #endif #if HAVE_VAAPI_HWACCEL &mp_vd_lavc_vaapi, diff --git a/video/decode/videotoolbox.c b/video/decode/videotoolbox.c index c69d5e89e6..c6f1a472bf 100644 --- a/video/decode/videotoolbox.c +++ b/video/decode/videotoolbox.c @@ -24,14 +24,16 @@ #include "common/msg.h" #include "video/mp_image.h" #include "video/decode/lavc.h" +#include "video/mp_image_pool.h" #include "config.h" +struct priv { + struct mp_image_pool *sw_pool; +}; -static int probe(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, +static int probe_copy(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, const char *codec) { - if (!hwdec_devices_load(ctx->hwdec_devs, HWDEC_VIDEOTOOLBOX)) - return HWDEC_ERR_NO_CTX; switch (mp_codec_to_av_codec_id(codec)) { case AV_CODEC_ID_H264: case AV_CODEC_ID_H263: @@ -45,8 +47,19 @@ static int probe(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, return 0; } +static int probe(struct lavc_ctx *ctx, struct vd_lavc_hwdec *hwdec, + const char *codec) +{ + if (!hwdec_devices_load(ctx->hwdec_devs, HWDEC_VIDEOTOOLBOX)) + return HWDEC_ERR_NO_CTX; + return probe_copy(ctx, hwdec, codec); +} + static int init(struct lavc_ctx *ctx) { + struct priv *p = talloc_ptrtype(NULL, p); + p->sw_pool = talloc_steal(p, mp_image_pool_new(17)); + ctx->hwdec_priv = p; return 0; } @@ -82,15 +95,10 @@ static void print_videotoolbox_error(struct mp_log *log, int lev, char *message, mp_msg(log, lev, "%s: %d\n", message, error_code); } -static int init_decoder(struct lavc_ctx *ctx, int w, int h) +static int init_decoder_common(struct lavc_ctx *ctx, int w, int h, AVVideotoolboxContext *vtctx) { av_videotoolbox_default_free(ctx->avctx); - AVVideotoolboxContext *vtctx = av_videotoolbox_alloc_context(); - - struct mp_vt_ctx *vt = hwdec_devices_load(ctx->hwdec_devs, HWDEC_VIDEOTOOLBOX); - vtctx->cv_pix_fmt_type = vt->get_vt_fmt(vt); - int err = av_videotoolbox_default_init2(ctx->avctx, vtctx); if (err < 0) { print_videotoolbox_error(ctx->log, MSGL_ERR, "failed to init videotoolbox decoder", err); @@ -100,17 +108,99 @@ static int init_decoder(struct lavc_ctx *ctx, int w, int h) return 0; } +static int init_decoder(struct lavc_ctx *ctx, int w, int h) +{ + AVVideotoolboxContext *vtctx = av_videotoolbox_alloc_context(); + struct mp_vt_ctx *vt = hwdec_devices_load(ctx->hwdec_devs, HWDEC_VIDEOTOOLBOX); + vtctx->cv_pix_fmt_type = vt->get_vt_fmt(vt); + + return init_decoder_common(ctx, w, h, vtctx); +} + +static int init_decoder_copy(struct lavc_ctx *ctx, int w, int h) +{ + return init_decoder_common(ctx, w, h, NULL); +} + static void uninit(struct lavc_ctx *ctx) { if (ctx->avctx) av_videotoolbox_default_free(ctx->avctx); + + struct priv *p = ctx->hwdec_priv; + if (!p) + return; + + talloc_free(p->sw_pool); + p->sw_pool = NULL; + + talloc_free(p); + ctx->hwdec_priv = NULL; +} + +static int mp_imgfmt_from_cvpixelformat(uint32_t cvpixfmt) +{ + switch (cvpixfmt) { + case kCVPixelFormatType_420YpCbCr8Planar: return IMGFMT_420P; + case kCVPixelFormatType_422YpCbCr8: return IMGFMT_UYVY; + case kCVPixelFormatType_32BGRA: return IMGFMT_RGB0; + case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: return IMGFMT_NV12; + } + return 0; +} + +static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *hw_image) +{ + if (hw_image->imgfmt != IMGFMT_VIDEOTOOLBOX) + return hw_image; + + struct priv *p = ctx->hwdec_priv; + struct mp_image *image = NULL; + CVPixelBufferRef pbuf = (CVPixelBufferRef)hw_image->planes[3]; + CVPixelBufferLockBaseAddress(pbuf, kCVPixelBufferLock_ReadOnly); + size_t width = CVPixelBufferGetWidth(pbuf); + size_t height = CVPixelBufferGetHeight(pbuf); + uint32_t cvpixfmt = CVPixelBufferGetPixelFormatType(pbuf); + int pixfmt = mp_imgfmt_from_cvpixelformat(cvpixfmt); + if (!pixfmt) + goto unlock; + + struct mp_image img = {0}; + mp_image_setfmt(&img, pixfmt); + mp_image_set_size(&img, width, height); + + if (CVPixelBufferIsPlanar(pbuf)) { + int planes = CVPixelBufferGetPlaneCount(pbuf); + for (int i = 0; i < planes; i++) { + img.planes[i] = CVPixelBufferGetBaseAddressOfPlane(pbuf, i); + img.stride[i] = CVPixelBufferGetBytesPerRowOfPlane(pbuf, i); + } + } else { + img.planes[0] = CVPixelBufferGetBaseAddress(pbuf); + img.stride[0] = CVPixelBufferGetBytesPerRow(pbuf); + } + + mp_image_copy_attributes(&img, hw_image); + + image = mp_image_pool_new_copy(p->sw_pool, &img); + +unlock: + CVPixelBufferUnlockBaseAddress(pbuf, kCVPixelBufferLock_ReadOnly); + + if (image) { + talloc_free(hw_image); + return image; + } else { + return hw_image; + } } static struct mp_image *process_image(struct lavc_ctx *ctx, struct mp_image *img) { if (img->imgfmt == IMGFMT_VIDEOTOOLBOX) { CVPixelBufferRef pbuf = (CVPixelBufferRef)img->planes[3]; - img->params.hw_subfmt = CVPixelBufferGetPixelFormatType(pbuf); + uint32_t cvpixfmt = CVPixelBufferGetPixelFormatType(pbuf); + img->params.hw_subfmt = mp_imgfmt_from_cvpixelformat(cvpixfmt); } return img; } @@ -124,3 +214,15 @@ const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox = { .init_decoder = init_decoder, .process_image = process_image, }; + +const struct vd_lavc_hwdec mp_vd_lavc_videotoolbox_copy = { + .type = HWDEC_VIDEOTOOLBOX_COPY, + .copying = true, + .image_format = IMGFMT_VIDEOTOOLBOX, + .probe = probe_copy, + .init = init, + .uninit = uninit, + .init_decoder = init_decoder_copy, + .process_image = copy_image, + .delay_queue = HWDEC_DELAY_QUEUE_COUNT, +}; diff --git a/video/filter/refqueue.c b/video/filter/refqueue.c index 04de3124a4..6b2e5a2110 100644 --- a/video/filter/refqueue.c +++ b/video/filter/refqueue.c @@ -75,15 +75,6 @@ bool mp_refqueue_should_deint(struct mp_refqueue *q) !(q->flags & MP_MODE_INTERLACED_ONLY); } -// Whether the current output frame is marked as interlaced. -bool mp_refqueue_is_interlaced(struct mp_refqueue *q) -{ - if (!mp_refqueue_has_output(q)) - return false; - - return q->queue[q->pos]->fields & MP_IMGFIELD_INTERLACED; -} - // Whether the current output frame (field) is the top field, bottom field // otherwise. (Assumes the caller forces deinterlacing.) bool mp_refqueue_is_top_field(struct mp_refqueue *q) diff --git a/video/filter/refqueue.h b/video/filter/refqueue.h index ef23bee906..bb23506ac2 100644 --- a/video/filter/refqueue.h +++ b/video/filter/refqueue.h @@ -27,7 +27,6 @@ enum { void mp_refqueue_set_mode(struct mp_refqueue *q, int flags); bool mp_refqueue_should_deint(struct mp_refqueue *q); -bool mp_refqueue_is_interlaced(struct mp_refqueue *q); bool mp_refqueue_is_top_field(struct mp_refqueue *q); bool mp_refqueue_top_field_first(struct mp_refqueue *q); bool mp_refqueue_is_second_field(struct mp_refqueue *q); diff --git a/video/filter/vf_d3d11vpp.c b/video/filter/vf_d3d11vpp.c index 6faf712a67..7a52565782 100644 --- a/video/filter/vf_d3d11vpp.c +++ b/video/filter/vf_d3d11vpp.c @@ -29,7 +29,12 @@ #include "video/mp_image_pool.h" // missing in MinGW +#define D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BLEND 0x1 #define D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BOB 0x2 +#define D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_ADAPTIVE 0x4 +#define D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_MOTION_COMPENSATION 0x8 +#define D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_INVERSE_TELECINE 0x10 +#define D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_FRAME_RATE_CONVERSION 0x20 struct vf_priv_s { ID3D11Device *vo_dev; @@ -57,6 +62,7 @@ struct vf_priv_s { int deint_enabled; int interlaced_only; + int mode; }; static void release_tex(void *arg) @@ -159,8 +165,8 @@ static int recreate_video_proc(struct vf_instance *vf) if (FAILED(hr)) goto fail; - MP_VERBOSE(vf, "Found %d rate conversion caps.\n", - (int)caps.RateConversionCapsCount); + MP_VERBOSE(vf, "Found %d rate conversion caps. Looking for caps=0x%x.\n", + (int)caps.RateConversionCapsCount, p->mode); int rindex = -1; for (int n = 0; n < caps.RateConversionCapsCount; n++) { @@ -170,8 +176,7 @@ static int recreate_video_proc(struct vf_instance *vf) if (FAILED(hr)) goto fail; MP_VERBOSE(vf, " - %d: 0x%08x\n", n, (unsigned)rcaps.ProcessorCaps); - if (rcaps.ProcessorCaps & D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BOB) - { + if (rcaps.ProcessorCaps & p->mode) { MP_VERBOSE(vf, " (matching)\n"); if (rindex < 0) rindex = n; @@ -179,10 +184,12 @@ static int recreate_video_proc(struct vf_instance *vf) } if (rindex < 0) { - MP_WARN(vf, "No video deinterlacing processor found.\n"); + MP_WARN(vf, "No fitting video processor found, picking #0.\n"); rindex = 0; } + // TOOD: so, how do we select which rate conversion mode the processor uses? + hr = ID3D11VideoDevice_CreateVideoProcessor(p->video_dev, p->vp_enum, rindex, &p->video_proc); if (FAILED(hr)) { @@ -262,7 +269,7 @@ static int render(struct vf_instance *vf) mp_image_copy_attributes(out, in); D3D11_VIDEO_FRAME_FORMAT d3d_frame_format; - if (!mp_refqueue_is_interlaced(p->queue)) { + if (!mp_refqueue_should_deint(p->queue)) { d3d_frame_format = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE; } else if (mp_refqueue_top_field_first(p->queue)) { d3d_frame_format = D3D11_VIDEO_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST; @@ -282,7 +289,7 @@ static int render(struct vf_instance *vf) goto cleanup; } - if (!mp_refqueue_is_interlaced(p->queue)) { + if (!mp_refqueue_should_deint(p->queue)) { d3d_frame_format = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE; } else if (mp_refqueue_is_top_field(p->queue)) { d3d_frame_format = D3D11_VIDEO_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST; @@ -518,6 +525,13 @@ fail: static const m_option_t vf_opts_fields[] = { OPT_FLAG("deint", deint_enabled, 0), OPT_FLAG("interlaced-only", interlaced_only, 0), + OPT_CHOICE("mode", mode, 0, + ({"blend", D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BLEND}, + {"bob", D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BOB}, + {"adaptive", D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_ADAPTIVE}, + {"mocomp", D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_MOTION_COMPENSATION}, + {"ivctc", D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_INVERSE_TELECINE}, + {"none", 0})), {0} }; @@ -530,6 +544,7 @@ const vf_info_t vf_info_d3d11vpp = { .priv_defaults = &(const struct vf_priv_s) { .deint_enabled = 1, .interlaced_only = 1, + .mode = D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BOB, }, .options = vf_opts_fields, }; diff --git a/video/filter/vf_vavpp.c b/video/filter/vf_vavpp.c index b24f886241..ad669ac159 100644 --- a/video/filter/vf_vavpp.c +++ b/video/filter/vf_vavpp.c @@ -169,7 +169,7 @@ static struct mp_image *render(struct vf_instance *vf) mp_image_copy_attributes(img, in); unsigned int flags = va_get_colorspace_flag(p->params.color.space); - if (!mp_refqueue_is_interlaced(p->queue)) { + if (!mp_refqueue_should_deint(p->queue)) { flags |= VA_FRAME_PICTURE; } else if (mp_refqueue_is_top_field(p->queue)) { flags |= VA_TOP_FIELD; diff --git a/video/hwdec.h b/video/hwdec.h index 5d563c983b..4d99076f16 100644 --- a/video/hwdec.h +++ b/video/hwdec.h @@ -12,6 +12,7 @@ enum hwdec_type { HWDEC_AUTO_COPY, HWDEC_VDPAU, HWDEC_VIDEOTOOLBOX, + HWDEC_VIDEOTOOLBOX_COPY, HWDEC_VAAPI, HWDEC_VAAPI_COPY, HWDEC_DXVA2, diff --git a/video/mp_image.c b/video/mp_image.c index a4ce6d1cc5..531565f837 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -512,7 +512,7 @@ char *mp_image_params_to_str_buf(char *b, size_t bs, mp_snprintf_cat(b, bs, " [%d:%d]", p->p_w, p->p_h); mp_snprintf_cat(b, bs, " %s", mp_imgfmt_to_name(p->imgfmt)); if (p->hw_subfmt) - mp_snprintf_cat(b, bs, "[%llu]", (unsigned long long)(p->hw_subfmt)); + mp_snprintf_cat(b, bs, "[%s]", mp_imgfmt_to_name(p->hw_subfmt)); mp_snprintf_cat(b, bs, " %s/%s", m_opt_choice_str(mp_csp_names, p->color.space), m_opt_choice_str(mp_csp_levels_names, p->color.levels)); diff --git a/video/mp_image.h b/video/mp_image.h index dfbe4ee0ba..13e364ae24 100644 --- a/video/mp_image.h +++ b/video/mp_image.h @@ -39,8 +39,7 @@ // usually copy the whole struct, so that fields added later will be preserved. struct mp_image_params { enum mp_imgfmt imgfmt; // pixel format - uint64_t hw_subfmt; // underlying format for some hwaccel pixfmts - // (will use the HW API's format identifiers) + enum mp_imgfmt hw_subfmt; // underlying format for some hwaccel pixfmts int w, h; // image dimensions int p_w, p_h; // define pixel aspect ratio (undefined: 0/0) struct mp_colorspace color; diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m index 21e1246b1c..557e28e4f1 100644 --- a/video/out/cocoa_common.m +++ b/video/out/cocoa_common.m @@ -90,8 +90,6 @@ struct vo_cocoa_state { uint32_t old_dwidth; uint32_t old_dheight; - NSData *icc_wnd_profile; - NSData *icc_fs_profile; id fs_icc_changed_ns_observer; pthread_mutex_t lock; @@ -421,7 +419,6 @@ static void vo_cocoa_update_screen_info(struct vo *vo, struct mp_rect *out_rc) return; vo_cocoa_update_screens_pointers(vo); - vo_cocoa_update_screen_fps(vo); if (out_rc) { NSRect r = [s->current_screen frame]; @@ -584,6 +581,7 @@ static void cocoa_screen_reconfiguration_observer( struct vo *vo = ctx; MP_WARN(vo, "detected display mode change, updating screen info\n"); vo_cocoa_update_screen_info(vo, NULL); + vo_cocoa_update_screen_fps(vo); } } @@ -614,6 +612,7 @@ int vo_cocoa_config_window(struct vo *vo) run_on_main_thread(vo, ^{ struct mp_rect screenrc; vo_cocoa_update_screen_info(vo, &screenrc); + vo_cocoa_update_screen_fps(vo); struct vo_win_geometry geo; vo_calc_window_geometry(vo, &screenrc, &geo); @@ -953,6 +952,7 @@ int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg) - (void)windowDidChangeScreen:(NSNotification *)notification { vo_cocoa_update_screen_info(self.vout, NULL); + vo_cocoa_update_screen_fps(self.vout); } - (void)didChangeWindowedScreenProfile:(NSScreen *)screen diff --git a/video/out/opengl/context.h b/video/out/opengl/context.h index df842bc8a1..a546e00be0 100644 --- a/video/out/opengl/context.h +++ b/video/out/opengl/context.h @@ -63,6 +63,11 @@ struct mpgl_driver { // This behaves exactly like vo_driver.control(). int (*control)(struct MPGLContext *ctx, int *events, int request, void *arg); + // These behave exactly like vo_driver.wakeup/wait_events. They are + // optional. + void (*wakeup)(struct MPGLContext *ctx); + void (*wait_events)(struct MPGLContext *ctx, int64_t until_time_us); + // Destroy the GL context and possibly the underlying VO backend. void (*uninit)(struct MPGLContext *ctx); }; diff --git a/video/out/opengl/context_angle.c b/video/out/opengl/context_angle.c index 28515f431f..ebc803fdb1 100644 --- a/video/out/opengl/context_angle.c +++ b/video/out/opengl/context_angle.c @@ -15,6 +15,7 @@ * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ +#include <initguid.h> #include <windows.h> #include <EGL/egl.h> #include <EGL/eglext.h> @@ -33,11 +34,15 @@ #define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002 #endif +// Windows 8 enum value, not present in mingw-w64 headers +#define DXGI_ADAPTER_FLAG_SOFTWARE (2) + struct priv { EGLDisplay egl_display; EGLContext egl_context; EGLSurface egl_surface; bool use_es2; + bool sw_adapter_msg_shown; PFNEGLPOSTSUBBUFFERNVPROC eglPostSubBufferNV; }; @@ -104,6 +109,15 @@ static bool create_context_egl(MPGLContext *ctx, EGLConfig config, int version) return true; } +static void show_sw_adapter_msg(struct MPGLContext *ctx) +{ + struct priv *p = ctx->priv; + if (p->sw_adapter_msg_shown) + return; + MP_WARN(ctx->vo, "Using a software adapter\n"); + p->sw_adapter_msg_shown = true; +} + static void d3d_init(struct MPGLContext *ctx) { HRESULT hr; @@ -111,6 +125,7 @@ static void d3d_init(struct MPGLContext *ctx) struct vo *vo = ctx->vo; IDXGIDevice *dxgi_dev = NULL; IDXGIAdapter *dxgi_adapter = NULL; + IDXGIAdapter1 *dxgi_adapter1 = NULL; IDXGIFactory *dxgi_factory = NULL; PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT = @@ -147,6 +162,25 @@ static void d3d_init(struct MPGLContext *ctx) goto done; } + // Windows 8 can choose a software adapter even if mpv didn't ask for + // one. If this is the case, show a warning message. + hr = IDXGIAdapter_QueryInterface(dxgi_adapter, &IID_IDXGIAdapter1, + (void**)&dxgi_adapter1); + if (SUCCEEDED(hr)) { + DXGI_ADAPTER_DESC1 desc; + hr = IDXGIAdapter1_GetDesc1(dxgi_adapter1, &desc); + if (SUCCEEDED(hr)) { + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + show_sw_adapter_msg(ctx); + + // If the primary display adapter is a software adapter, the + // DXGI_ADAPTER_FLAG_SOFTWARE won't be set, but the device IDs + // should still match the Microsoft Basic Render Driver + if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c) + show_sw_adapter_msg(ctx); + } + } + hr = IDXGIAdapter_GetParent(dxgi_adapter, &IID_IDXGIFactory, (void**)&dxgi_factory); if (FAILED(hr)) { @@ -168,6 +202,8 @@ done: IDXGIDevice_Release(dxgi_dev); if (dxgi_adapter) IDXGIAdapter_Release(dxgi_adapter); + if (dxgi_adapter1) + IDXGIAdapter1_Release(dxgi_adapter1); if (dxgi_factory) IDXGIFactory_Release(dxgi_factory); } @@ -204,31 +240,39 @@ static int angle_init(struct MPGLContext *ctx, int flags) } EGLint d3d_types[] = {EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE}; + EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, + EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE}; + EGLint d3d_dev_types[] = {EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE}; for (int i = 0; i < MP_ARRAY_SIZE(d3d_types); i++) { EGLint display_attributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, d3d_types[i], EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, + d3d_dev_types[i], EGL_NONE, }; p->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, display_attributes); - if (p->egl_display != EGL_NO_DISPLAY) - break; + if (p->egl_display == EGL_NO_DISPLAY) + continue; + + if (!eglInitialize(p->egl_display, NULL, NULL)) { + p->egl_display = EGL_NO_DISPLAY; + continue; + } + + if (d3d_dev_types[i] == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE) + show_sw_adapter_msg(ctx); + break; } if (p->egl_display == EGL_NO_DISPLAY) { MP_FATAL(vo, "Couldn't get display\n"); goto fail; } - if (!eglInitialize(p->egl_display, NULL, NULL)) { - MP_FATAL(vo, "Couldn't initialize EGL\n"); - goto fail; - } - const char *exts = eglQueryString(p->egl_display, EGL_EXTENSIONS); if (exts) MP_DBG(ctx->vo, "EGL extensions: %s\n", exts); diff --git a/video/out/opengl/context_wayland.c b/video/out/opengl/context_wayland.c index e74132bcf2..efb6128b92 100644 --- a/video/out/opengl/context_wayland.c +++ b/video/out/opengl/context_wayland.c @@ -59,9 +59,7 @@ static void egl_resize(struct vo_wayland_state *wl) /* set size for mplayer */ wl->vo->dwidth = scale*wl->window.width; wl->vo->dheight = scale*wl->window.height; - wl->vo->want_redraw = true; - wl->window.events = 0; } static int egl_create_context(struct vo_wayland_state *wl, @@ -207,8 +205,7 @@ static void waylandgl_swap_buffers(MPGLContext *ctx) if (!wl->frame.callback) vo_wayland_request_frame(ctx->vo, NULL, NULL); - if (!vo_wayland_wait_frame(ctx->vo)) - MP_DBG(wl, "discarding frame callback\n"); + vo_wayland_wait_events(ctx->vo, 0); eglSwapBuffers(wl->egl_context.egl.dpy, wl->egl_context.egl_surface); } @@ -225,6 +222,16 @@ static int waylandgl_control(MPGLContext *ctx, int *events, int request, return r; } +static void wayland_wakeup(struct MPGLContext *ctx) +{ + vo_wayland_wakeup(ctx->vo); +} + +static void wayland_wait_events(struct MPGLContext *ctx, int64_t until_time_us) +{ + vo_wayland_wait_events(ctx->vo, until_time_us); +} + static int waylandgl_init(struct MPGLContext *ctx, int flags) { if (!vo_wayland_init(ctx->vo)) @@ -239,5 +246,7 @@ const struct mpgl_driver mpgl_driver_wayland = { .reconfig = waylandgl_reconfig, .swap_buffers = waylandgl_swap_buffers, .control = waylan |