diff options
author | Dmitry Osipenko <digetx@gmail.com> | 2018-01-04 17:56:15 +0300 |
---|---|---|
committer | Dmitry Osipenko <digetx@gmail.com> | 2018-01-04 18:36:24 +0300 |
commit | 307c37e0c94a8d42aacb45dd7a2b03fa1e95dd13 (patch) | |
tree | 56a3dfeaf3a4ddae54087ff074bd107978f8eefd | |
parent | 683c81e6cdc9c705886a8f74b69be32cf5ad62ca (diff) |
Don't fail without Xv
Only one instance can grab Xv port at a time. Now multiple players could
be running simultaneously, they will be forced to use DRI output.
-rw-r--r-- | src/surface.c | 2 | ||||
-rw-r--r-- | src/surface_shared.c | 13 | ||||
-rw-r--r-- | src/vdpau_tegra.c | 133 |
3 files changed, 87 insertions, 61 deletions
diff --git a/src/surface.c b/src/surface.c index e632e58..d3deb02 100644 --- a/src/surface.c +++ b/src/surface.c @@ -221,7 +221,7 @@ int alloc_surface_data(tegra_surface *surf) } } - if (output) { + if (output && !tegra_vdpau_force_dri) { int format_id = -1; switch (rgba_format) { diff --git a/src/surface_shared.c b/src/surface_shared.c index 7770b8e..171e5be 100644 --- a/src/surface_shared.c +++ b/src/surface_shared.c @@ -28,6 +28,10 @@ static XvImage * create_video_xv(tegra_surface *video) uint32_t *pitches; uint32_t *offsets; + if (tegra_vdpau_force_dri) { + return NULL; + } + xv_img = XvCreateImage(video->dev->display, video->dev->xv_port, FOURCC_PASSTHROUGH_YV12, NULL, video->width, video->height); @@ -110,7 +114,7 @@ tegra_shared_surface *create_shared_surface(tegra_surface *disp, shared->dst_width = dst_width; shared->dst_height = dst_height; - if (!shared->xv_img) { + if (!shared->xv_img && !tegra_vdpau_force_dri) { free(shared); pthread_mutex_unlock(&disp->lock); @@ -165,8 +169,11 @@ void unref_shared_surface(tegra_shared_surface *shared) unref_surface(shared->video); unref_surface(shared->disp); - free(shared->xv_img->data); - XFree(shared->xv_img); + if (shared->xv_img) { + free(shared->xv_img->data); + XFree(shared->xv_img); + } + free(shared); } diff --git a/src/vdpau_tegra.c b/src/vdpau_tegra.c index 627651b..cbe60df 100644 --- a/src/vdpau_tegra.c +++ b/src/vdpau_tegra.c @@ -524,7 +524,10 @@ VdpStatus unref_device(tegra_device *dev) DebugMsg("device closed\n"); - XvUngrabPort(dev->display, dev->xv_port, CurrentTime); + if (dev->xv_port != -1) { + XvUngrabPort(dev->display, dev->xv_port, CurrentTime); + } + tegra_stream_destroy(dev->stream); drm_tegra_channel_close(dev->gr2d); drm_tegra_close(dev->drm); @@ -550,6 +553,73 @@ VdpStatus vdp_device_destroy(VdpDevice device) return unref_device(dev); } +static int initialize_xv(Display *display, tegra_device *dev) +{ + XvAdaptorInfo *adaptor_info = NULL; + XvImageFormatValues *fmt; + unsigned int ver, rel, req, ev, err; + unsigned int num_adaptors; + int num_formats; + int ret; + + ret = XvQueryExtension(display, &ver, &rel, &req, &ev, &err); + if (ret != Success) { + ErrorMsg("Xv is disabled in the Xorg driver\n"); + goto err_cleanup; + } + + ret = XvQueryAdaptors(display, DefaultRootWindow(display), + &num_adaptors, &adaptor_info); + if (ret != Success) { + goto err_cleanup; + } + + while (num_adaptors--) { + if (adaptor_info[num_adaptors].num_ports != 1) + continue; + + if (!(adaptor_info[num_adaptors].type & XvImageMask)) + continue; + + fmt = XvListImageFormats(display, adaptor_info[num_adaptors].base_id, + &num_formats); + + while (num_formats--) { + if (!strncmp(fmt[num_formats].guid, "PASSTHROUGH_YV12", 16) && + fmt[num_formats].id == FOURCC_PASSTHROUGH_YV12) { + XFree(fmt); + goto xv_detected; + } + } + + XFree(fmt); + } + + ErrorMsg("Opentegra Xv undetected\n"); + + goto err_cleanup; + +xv_detected: + ret = XvGrabPort(display, adaptor_info[num_adaptors].base_id, CurrentTime); + if (ret != Success) { + ErrorMsg("Xv port is busy\n"); + goto err_cleanup; + } + + dev->xv_port = adaptor_info[num_adaptors].base_id; + +err_cleanup: + if (adaptor_info) { + XvFreeAdaptorInfo(adaptor_info); + } + + if (ret != Success) { + dev->xv_port = -1; + } + + return ret; +} + EXPORTED VdpStatus vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device, @@ -558,14 +628,9 @@ EXPORTED VdpStatus vdp_imp_device_create_x11(Display *display, struct drm_tegra *drm = NULL; struct drm_tegra_channel *gr2d = NULL; struct tegra_stream *stream = NULL; - XvAdaptorInfo *adaptor_info = NULL; - XvImageFormatValues *fmt; VdpDevice i; drm_magic_t magic; char *debug_str; - unsigned int ver, rel, req, ev, err; - unsigned int num_adaptors; - int num_formats; int vde_fd = -1; int drm_fd = -1; int ret; @@ -625,53 +690,8 @@ EXPORTED VdpStatus vdp_imp_device_create_x11(Display *display, goto err_cleanup; } - ret = XvQueryExtension(display, &ver, &rel, &req, &ev, &err); - if (ret != Success) { - ErrorMsg("Xv is disabled in the Xorg driver\n"); - goto err_cleanup; - } - - ret = XvQueryAdaptors(display, DefaultRootWindow(display), - &num_adaptors, &adaptor_info); - if (ret != Success) { - goto err_cleanup; - } - - while (num_adaptors--) { - if (adaptor_info[num_adaptors].num_ports != 1) - continue; - - if (!(adaptor_info[num_adaptors].type & XvImageMask)) - continue; - - fmt = XvListImageFormats(display, adaptor_info[num_adaptors].base_id, - &num_formats); - - while (num_formats--) { - if (!strncmp(fmt[num_formats].guid, "PASSTHROUGH_YV12", 16) && - fmt[num_formats].id == FOURCC_PASSTHROUGH_YV12) { - goto xv_detected; - } - } - - XFree(fmt); - } - - ErrorMsg("Opentegra Xv undetected\n"); - - goto err_cleanup; - -xv_detected: pthread_mutex_lock(&global_lock); - XFree(fmt); - - ret = XvGrabPort(display, adaptor_info[num_adaptors].base_id, CurrentTime); - if (ret != Success) { - ErrorMsg("Xv port is busy\n"); - goto err_cleanup; - } - for (i = 0; i < MAX_DEVICES_NB; i++) { if (tegra_devices[i] == NULL) { tegra_devices[i] = calloc(1, sizeof(tegra_device)); @@ -688,7 +708,11 @@ xv_detected: pthread_mutex_init(&tegra_devices[i]->lock, NULL); atomic_set(&tegra_devices[i]->refcnt, 1); - tegra_devices[i]->xv_port = adaptor_info[num_adaptors].base_id; + if (initialize_xv(display, tegra_devices[i]) != Success) { + ErrorMsg("forcing DRI\n"); + tegra_vdpau_force_dri = true; + } + tegra_devices[i]->display = display; tegra_devices[i]->screen = screen; tegra_devices[i]->vde_fd = vde_fd; @@ -700,8 +724,6 @@ xv_detected: *device = i; *get_proc_address = vdp_get_proc_address; - XvFreeAdaptorInfo(adaptor_info); - return VDP_STATUS_OK; err_cleanup: @@ -711,8 +733,5 @@ err_cleanup: close(drm_fd); free(stream); - if (adaptor_info) - XvFreeAdaptorInfo(adaptor_info); - return VDP_STATUS_RESOURCES; } |