225 lines
5.6 KiB
Diff
225 lines
5.6 KiB
Diff
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
index 48e69a7..9162ffb 100644
|
|
--- a/src/Makefile.am
|
|
+++ b/src/Makefile.am
|
|
@@ -1,6 +1,7 @@
|
|
AM_CFLAGS = \
|
|
-I$(top_srcdir)/include \
|
|
-DVDPAU_MODULEDIR="\"$(moduledir)\"" \
|
|
+ -DVDPAU_SYSCONFDIR="\"$(sysconfdir)\"" \
|
|
$(X11_CFLAGS) \
|
|
$(XEXT_CFLAGS)
|
|
|
|
@@ -26,3 +27,6 @@ libvdpauincludedir = $(includedir)/vdpau
|
|
libvdpauinclude_HEADERS = \
|
|
$(top_srcdir)/include/vdpau/vdpau.h \
|
|
$(top_srcdir)/include/vdpau/vdpau_x11.h
|
|
+
|
|
+libvdpausysconfdir=$(sysconfdir)
|
|
+libvdpausysconf_DATA = vdpau_wrapper.cfg
|
|
diff --git a/src/vdpau_wrapper.c b/src/vdpau_wrapper.c
|
|
index 23de3d4..c955745 100644
|
|
--- a/src/vdpau_wrapper.c
|
|
+++ b/src/vdpau_wrapper.c
|
|
@@ -210,6 +210,163 @@ static void _vdp_close_driver(void)
|
|
_vdp_imp_device_create_x11_proc = NULL;
|
|
}
|
|
|
|
+static VdpGetProcAddress * _imp_get_proc_address;
|
|
+static VdpVideoSurfacePutBitsYCbCr * _imp_vid_put_bits_y_cb_cr;
|
|
+static VdpPresentationQueueSetBackgroundColor * _imp_pq_set_bg_color;
|
|
+static int _inited_fixes;
|
|
+static int _running_under_flash;
|
|
+static int _enable_flash_uv_swap = 1;
|
|
+static int _disable_flash_pq_bg_color = 1;
|
|
+
|
|
+static VdpStatus vid_put_bits_y_cb_cr_swapped(
|
|
+ VdpVideoSurface surface,
|
|
+ VdpYCbCrFormat source_ycbcr_format,
|
|
+ void const * const * source_data,
|
|
+ uint32_t const * source_pitches
|
|
+)
|
|
+{
|
|
+ void const * data_reordered[3];
|
|
+ void const * const * data;
|
|
+
|
|
+ if (source_ycbcr_format == VDP_YCBCR_FORMAT_YV12) {
|
|
+ data_reordered[0] = source_data[0];
|
|
+ data_reordered[1] = source_data[2];
|
|
+ data_reordered[2] = source_data[1];
|
|
+ /*
|
|
+ * source_pitches[1] and source_pitches[2] should be equal,
|
|
+ * so no need to re-order.
|
|
+ */
|
|
+ data = data_reordered;
|
|
+ }
|
|
+ else {
|
|
+ data = source_data;
|
|
+ }
|
|
+
|
|
+ return _imp_vid_put_bits_y_cb_cr(
|
|
+ surface,
|
|
+ source_ycbcr_format,
|
|
+ data,
|
|
+ source_pitches
|
|
+ );
|
|
+}
|
|
+
|
|
+static VdpStatus pq_set_bg_color_noop(
|
|
+ VdpPresentationQueue presentation_queue,
|
|
+ VdpColor * const background_color
|
|
+)
|
|
+{
|
|
+ return VDP_STATUS_OK;
|
|
+}
|
|
+
|
|
+static VdpStatus vdp_wrapper_get_proc_address(
|
|
+ VdpDevice device,
|
|
+ VdpFuncId function_id,
|
|
+ /* output parameters follow */
|
|
+ void * * function_pointer
|
|
+)
|
|
+{
|
|
+ VdpStatus status;
|
|
+
|
|
+ status = _imp_get_proc_address(device, function_id, function_pointer);
|
|
+ if (status != VDP_STATUS_OK) {
|
|
+ return status;
|
|
+ }
|
|
+
|
|
+ if (_running_under_flash) {
|
|
+ switch (function_id) {
|
|
+ case VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR:
|
|
+ if (_enable_flash_uv_swap) {
|
|
+ _imp_vid_put_bits_y_cb_cr = *function_pointer;
|
|
+ *function_pointer = vid_put_bits_y_cb_cr_swapped;
|
|
+ }
|
|
+ break;
|
|
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR:
|
|
+ if (_disable_flash_pq_bg_color) {
|
|
+ _imp_pq_set_bg_color = *function_pointer;
|
|
+ *function_pointer = pq_set_bg_color_noop;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return VDP_STATUS_OK;
|
|
+}
|
|
+
|
|
+static void init_running_under_flash(void)
|
|
+{
|
|
+ FILE *fp;
|
|
+ char buffer[1024];
|
|
+ int ret, i;
|
|
+
|
|
+ fp = fopen("/proc/self/cmdline", "r");
|
|
+ if (!fp) {
|
|
+ return;
|
|
+ }
|
|
+ ret = fread(buffer, 1, sizeof(buffer) - 1, fp);
|
|
+ fclose(fp);
|
|
+ if (ret < 0) {
|
|
+ return;
|
|
+ }
|
|
+ /*
|
|
+ * Sometimes the file contains null between arguments. Wipe these out so
|
|
+ * strstr doesn't stop early.
|
|
+ */
|
|
+ for (i = 0; i < ret; i++) {
|
|
+ if (buffer[i] == '\0') {
|
|
+ buffer[i] = 'x';
|
|
+ }
|
|
+ }
|
|
+ buffer[ret] = '\0';
|
|
+
|
|
+ if (strstr(buffer, "libflashplayer") != NULL) {
|
|
+ _running_under_flash = 1;
|
|
+ }
|
|
+}
|
|
+
|
|
+void init_config(void)
|
|
+{
|
|
+ FILE *fp;
|
|
+ char buffer[1024];
|
|
+ int ret;
|
|
+
|
|
+ fp = fopen(VDPAU_SYSCONFDIR "/vdpau_wrapper.cfg", "r");
|
|
+ if (!fp) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ while (fgets(buffer, sizeof(buffer), fp) != NULL) {
|
|
+ char * equals = strchr(buffer, '=');
|
|
+ char * param;
|
|
+
|
|
+ if (equals == NULL) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ *equals = '\0';
|
|
+ param = equals + 1;
|
|
+
|
|
+ if (!strcmp(buffer, "enable_flash_uv_swap")) {
|
|
+ _enable_flash_uv_swap = atoi(param);
|
|
+ }
|
|
+ else if (!strcmp(buffer, "disable_flash_pq_bg_color")) {
|
|
+ _disable_flash_pq_bg_color = atoi(param);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void init_fixes(void)
|
|
+{
|
|
+ if (_inited_fixes) {
|
|
+ return;
|
|
+ }
|
|
+ _inited_fixes = 1;
|
|
+
|
|
+ init_running_under_flash();
|
|
+ init_config();
|
|
+}
|
|
+
|
|
VdpStatus vdp_device_create_x11(
|
|
Display * display,
|
|
int screen,
|
|
@@ -220,6 +377,8 @@ VdpStatus vdp_device_create_x11(
|
|
{
|
|
VdpStatus status;
|
|
|
|
+ init_fixes();
|
|
+
|
|
if (!_vdp_imp_device_create_x11_proc) {
|
|
status = _vdp_open_driver(display, screen);
|
|
if (status != VDP_STATUS_OK) {
|
|
@@ -228,10 +387,17 @@ VdpStatus vdp_device_create_x11(
|
|
}
|
|
}
|
|
|
|
- return _vdp_imp_device_create_x11_proc(
|
|
+ status = _vdp_imp_device_create_x11_proc(
|
|
display,
|
|
screen,
|
|
device,
|
|
- get_proc_address
|
|
+ &_imp_get_proc_address
|
|
);
|
|
+ if (status != VDP_STATUS_OK) {
|
|
+ return status;
|
|
+ }
|
|
+
|
|
+ *get_proc_address = vdp_wrapper_get_proc_address;
|
|
+
|
|
+ return VDP_STATUS_OK;
|
|
}
|
|
diff --git a/src/vdpau_wrapper.cfg b/src/vdpau_wrapper.cfg
|
|
new file mode 100644
|
|
index 0000000..21d5b8c
|
|
--- /dev/null
|
|
+++ b/src/vdpau_wrapper.cfg
|
|
@@ -0,0 +1,2 @@
|
|
+enable_flash_uv_swap=1
|
|
+disable_flash_pq_bg_color=1
|