summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Osipenko <digetx@gmail.com>2018-01-04 17:56:15 +0300
committerDmitry Osipenko <digetx@gmail.com>2018-01-04 18:36:24 +0300
commit307c37e0c94a8d42aacb45dd7a2b03fa1e95dd13 (patch)
tree56a3dfeaf3a4ddae54087ff074bd107978f8eefd
parent683c81e6cdc9c705886a8f74b69be32cf5ad62ca (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.c2
-rw-r--r--src/surface_shared.c13
-rw-r--r--src/vdpau_tegra.c133
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;
}