summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac11
-rw-r--r--src/video_out/video_out_vdpau.c4
-rw-r--r--src/video_out/yuv2rgb_mmx.c209
-rw-r--r--src/xine-engine/video_out.c28
4 files changed, 242 insertions, 10 deletions
diff --git a/configure.ac b/configure.ac
index f5cb7685f..30f03c3af 100644
--- a/configure.ac
+++ b/configure.ac
@@ -994,6 +994,17 @@ AC_DEFINE_UNQUOTED([LIBX11_SO], "${x_lib_location:-libX11.$acl_cv_shlibext}", [T
x_lib_location="`ls -1 "${x_libraries:-/usr/local/lib}/libXv.$acl_cv_shlibext"* "${x_libraries:-/usr/lib}/libXv.$acl_cv_shlibext"* 2>/dev/null | sed -e \"${soname_script}\"`"
AC_DEFINE_UNQUOTED([LIBXV_SO], "${x_lib_location:-libXv.$acl_cv_shlibext}", [The soname of libXv, needed for dlopen()])
+dnl Does X11 need XLockDisplay () to prevent deadlocks?
+AC_MSG_CHECKING([for thread safe X11])
+x_is_thread_safe=no
+if test -n "$PKG_CONFIG" ; then
+ if "$PKG_CONFIG" --atleast-version 1.9 xcb && "$PKG_CONFIG" --atleast-version 1.4.99.901 x11 ; then
+ x_is_thread_safe=yes
+ AC_DEFINE([HAVE_THREAD_SAFE_X11], [1], [Define this if x11 does without XLockDisplay ().])
+ fi
+fi
+AC_MSG_RESULT([$x_is_thread_safe])
+
dnl _FILE_OFFSET_BITS (AC_SYS_LARGEFILE; ac_cv_sys_file_offset_bits)
dnl _LARGE_FILES (AC_SYS_LARGEFILE; ac_cv_sys_large_files)
dnl _LARGEFILE_SOURCE (AC_FUNC_SEEKO; ac_cv_sys_largfile_source)
diff --git a/src/video_out/video_out_vdpau.c b/src/video_out/video_out_vdpau.c
index 4b4cc7d2e..19a8361b9 100644
--- a/src/video_out/video_out_vdpau.c
+++ b/src/video_out/video_out_vdpau.c
@@ -59,9 +59,9 @@
#define NUM_FRAMES_BACK 1
+#ifndef HAVE_THREAD_SAFE_X11
#define LOCKDISPLAY /*define this if you have a buggy libX11/xcb*/
-//#undef LOCKDISPLAY
-
+#endif
#define DEINT_BOB 1
#define DEINT_HALF_TEMPORAL 2
diff --git a/src/video_out/yuv2rgb_mmx.c b/src/video_out/yuv2rgb_mmx.c
index da6114a52..7279d1528 100644
--- a/src/video_out/yuv2rgb_mmx.c
+++ b/src/video_out/yuv2rgb_mmx.c
@@ -393,6 +393,81 @@ static inline void mmx_unpack_24rgb (uint8_t * image, int cpu)
* mm6 -> GB, mm7 -> AR pixel 0-3
*/
+ movq_r2r (mm1, mm6);
+ punpcklbw_r2r (mm2, mm6);
+
+ movq_r2r (mm0, mm7);
+ punpcklbw_r2r (mm7, mm7);
+
+ punpcklwd_r2r (mm7, mm6);
+ movq_r2r (mm6, mm5);
+ pand_m2r (mmx_hirgb, mm5);
+ pand_m2r (mmx_lorgb, mm6);
+ psrlq_i2r (8, mm5);
+ por_r2r(mm6, mm5); /* mm5 = 0x0000B1G1R1B0G0R0 */
+
+ movq_r2r (mm1, mm6);
+ punpcklbw_r2r (mm2, mm6);
+ punpckhwd_r2r (mm7, mm6); /* mm6 = 0x??B3G3R3??B2G2R2 */
+
+ movq_r2r (mm6, mm4);
+ psllq_i2r (48, mm4);
+ por_r2r(mm4, mm5); /* mm5 = 0xG2R2B1G1R1B0G0R0 */
+ movntq (mm5, *image);
+
+ movq_r2r (mm6, mm3);
+ pand_m2r (mmx_hirgb, mm3);
+ pand_m2r (mmx_lorgb, mm6);
+ psrlq_i2r (8, mm3);
+ por_r2r(mm6, mm3); /* mm3 = 0x0000B3G3R3B2G2R2 */
+ psrlq_i2r (16, mm3); /* mm3 = 0x00000000B3G3R3B2 */
+
+ movq_r2r (mm1, mm4);
+ punpckhbw_r2r (mm2, mm4);
+ movq_r2r (mm0, mm5);
+ punpckhbw_r2r (mm3, mm5);
+ punpcklwd_r2r (mm5, mm4);
+
+ movq_r2r (mm4, mm6);
+ pand_m2r (mmx_hirgb, mm6);
+ pand_m2r (mmx_lorgb, mm4);
+ psrlq_i2r (8, mm6);
+ por_r2r(mm4, mm6); /* mm6 = 0x0000B5G5R5B4G4R4 */
+
+ movq_r2r (mm6, mm4);
+ psllq_i2r (32, mm4); /* mm4 = 0xR5B4G4R400000000 */
+ por_r2r(mm4, mm3); /* mm4 = 0xR5B4G4R4B3G3R3B2 */
+ movntq (mm3, *(image+8));
+
+ psrlq_i2r (32, mm6); /* mm6 = 0x000000000000B5G5 */
+
+ movq_r2r (mm1, mm4);
+ punpckhbw_r2r (mm2, mm4);
+ punpckhwd_r2r (mm5, mm4);
+
+ movq_r2r (mm4, mm3);
+ pand_m2r (mmx_hirgb, mm3);
+ pand_m2r (mmx_lorgb, mm4);
+ psrlq_i2r (8, mm3);
+ por_r2r (mm4, mm3); /* mm3 = 0x0000B7G7R7B6G6R6 */
+ psllq_i2r (16, mm3); /* mm3 = 0xB7G7R7B6G6R60000 */
+ por_r2r (mm3, mm6); /* mm6 = 0xB7G7R7B6G6R6B5G5 */
+
+ movntq (mm6, *(image+16));
+}
+
+static inline void mmx_unpack_24bgr (uint8_t * image, int cpu)
+{
+ static mmx_t mmx_hirgb = {0x00ffffff00000000ULL};
+ static mmx_t mmx_lorgb = {0x0000000000ffffffULL};
+
+ /*
+ * convert RGB plane to RGB packed format,
+ * mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0,
+ * mm4 -> GB, mm5 -> AR pixel 4-7,
+ * mm6 -> GB, mm7 -> AR pixel 0-3
+ */
+
movq_r2r (mm0, mm6);
punpcklbw_r2r (mm2, mm6);
@@ -793,6 +868,118 @@ static inline void yuv420_rgb24 (yuv2rgb_t *this,
}
}
+static inline void yuv420_bgr24 (yuv2rgb_t *this,
+ uint8_t * image, uint8_t * py,
+ uint8_t * pu, uint8_t * pv, int cpu)
+{
+ int i, height, dst_height;
+ int rgb_stride = this->rgb_stride;
+ int y_stride = this->y_stride;
+ int uv_stride = this->uv_stride;
+ int width = this->source_width;
+ uint8_t *img;
+
+ /* rgb_stride -= 4 * this->dest_width; */
+ width >>= 3;
+
+ if (!this->do_scale) {
+ height = this->next_slice (this, &image);
+ y_stride -= 8 * width;
+ uv_stride -= 4 * width;
+
+ do {
+ i = width; img = image;
+ do {
+ mmx_yuv2rgb (py, pu, pv, this->table_mmx);
+ mmx_unpack_24bgr (img, cpu);
+ py += 8;
+ pu += 4;
+ pv += 4;
+ img += 24;
+ } while (--i);
+
+ py += y_stride;
+ image += rgb_stride;
+ if (height & 1) {
+ pu += uv_stride;
+ pv += uv_stride;
+ } else {
+ pu -= 4 * width;
+ pv -= 4 * width;
+ }
+ } while (--height);
+ } else {
+
+ scale_line_func_t scale_line = this->scale_line;
+ uint8_t *y_buf, *u_buf, *v_buf;
+ int dy = 0;
+
+ scale_line (pu, this->u_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line (pv, this->v_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line (py, this->y_buffer,
+ this->dest_width, this->step_dx);
+
+ dst_height = this->next_slice (this, &image);
+
+ for (height = 0;; ) {
+
+ y_buf = this->y_buffer;
+ u_buf = this->u_buffer;
+ v_buf = this->v_buffer;
+
+
+ i = this->dest_width >> 3; img=image;
+ do {
+ /* printf ("i : %d\n",i); */
+
+ mmx_yuv2rgb (y_buf, u_buf, v_buf, this->table_mmx);
+ mmx_unpack_24bgr (img, cpu);
+ y_buf += 8;
+ u_buf += 4;
+ v_buf += 4;
+ img += 24;
+ } while (--i);
+
+ dy += this->step_dy;
+ image += rgb_stride;
+
+ while (--dst_height > 0 && dy < 32768) {
+
+ xine_fast_memcpy (image, image-rgb_stride, this->dest_width*3);
+
+ dy += this->step_dy;
+ image += rgb_stride;
+ }
+
+ if (dst_height <= 0)
+ break;
+
+ do {
+ dy -= 32768;
+ py += y_stride;
+
+ scale_line (py, this->y_buffer,
+ this->dest_width, this->step_dx);
+
+ if (height & 1) {
+ pu += uv_stride;
+ pv += uv_stride;
+
+ scale_line (pu, this->u_buffer,
+ this->dest_width >> 1, this->step_dx);
+ scale_line (pv, this->v_buffer,
+ this->dest_width >> 1, this->step_dx);
+ }
+ height++;
+ } while( dy>=32768 );
+
+ }
+
+ }
+}
+
static inline void yuv420_argb32 (yuv2rgb_t *this,
uint8_t * image, uint8_t * py,
uint8_t * pu, uint8_t * pv, int cpu)
@@ -1072,6 +1259,13 @@ static void mmx_rgb24 (yuv2rgb_t *this, uint8_t * image,
emms(); /* re-initialize x86 FPU after MMX use */
}
+static void mmx_bgr24 (yuv2rgb_t *this, uint8_t * image,
+ uint8_t * py, uint8_t * pu, uint8_t * pv)
+{
+ yuv420_bgr24 (this, image, py, pu, pv, CPU_MMX);
+ emms(); /* re-initialize x86 FPU after MMX use */
+}
+
static void mmx_argb32 (yuv2rgb_t *this, uint8_t * image,
uint8_t * py, uint8_t * pu, uint8_t * pv)
{
@@ -1112,8 +1306,16 @@ void yuv2rgb_init_mmxext (yuv2rgb_factory_t *this) {
void yuv2rgb_init_mmx (yuv2rgb_factory_t *this) {
- if (this->swapped)
- return; /*no swapped pixel output upto now*/
+ if (this->swapped) switch (this->mode) {
+ case MODE_24_RGB:
+ this->yuv2rgb_fun = mmx_bgr24;
+ break;
+ case MODE_24_BGR:
+ this->yuv2rgb_fun = mmx_rgb24;
+ break;
+ default:
+ return; /* other swapped formats not yet */
+ }
switch (this->mode) {
case MODE_15_RGB:
@@ -1125,6 +1327,9 @@ void yuv2rgb_init_mmx (yuv2rgb_factory_t *this) {
case MODE_24_RGB:
this->yuv2rgb_fun = mmx_rgb24;
break;
+ case MODE_24_BGR:
+ this->yuv2rgb_fun = mmx_bgr24;
+ break;
case MODE_32_RGB:
this->yuv2rgb_fun = mmx_argb32;
break;
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 043578dad..8f6791fa8 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -516,11 +516,28 @@ static int vo_grab_grab_video_frame (xine_grab_video_frame_t *frame_gen) {
}
}
+ /* get pixel aspect ratio */
+ double sar = 1.0;
+ {
+ int sarw = vo_frame->width - vo_frame->crop_left - vo_frame->crop_right;
+ int sarh = vo_frame->height - vo_frame->crop_top - vo_frame->crop_bottom;
+ if ((vo_frame->ratio > 0.0) && (sarw > 0) && (sarh > 0))
+ sar = vo_frame->ratio * sarh / sarw;
+ }
+
/* if caller does not specify frame size we return the actual size of grabbed frame */
- if (frame->grab_frame.width <= 0)
- frame->grab_frame.width = width;
- if (frame->grab_frame.height <= 0)
- frame->grab_frame.height = height;
+ if ((frame->grab_frame.width <= 0) && (frame->grab_frame.height <= 0)) {
+ if (sar > 1.0) {
+ frame->grab_frame.width = sar * width + 0.5;
+ frame->grab_frame.height = height;
+ } else {
+ frame->grab_frame.width = width;
+ frame->grab_frame.height = (double)height / sar + 0.5;
+ }
+ } else if (frame->grab_frame.width <= 0)
+ frame->grab_frame.width = frame->grab_frame.height * width * sar / height + 0.5;
+ else if (frame->grab_frame.height <= 0)
+ frame->grab_frame.height = (frame->grab_frame.width * height) / (sar * width) + 0.5;
/* allocate grab frame image buffer */
if (frame->grab_frame.width != frame->grab_width || frame->grab_frame.height != frame->grab_height) {
@@ -578,9 +595,8 @@ static int vo_grab_grab_video_frame (xine_grab_video_frame_t *frame_gen) {
}
/* convert YUV to RGB image taking possible scaling into account */
- /* FIXME: have to swap U and V planes to get correct colors for YV12 frames?? */
if(format == XINE_IMGFMT_YV12)
- frame->yuv2rgb->yuv2rgb_fun(frame->yuv2rgb, frame->grab_frame.img, base[0], base[2], base[1]);
+ frame->yuv2rgb->yuv2rgb_fun(frame->yuv2rgb, frame->grab_frame.img, base[0], base[1], base[2]);
else
frame->yuv2rgb->yuy22rgb_fun(frame->yuv2rgb, frame->grab_frame.img, base[0]);