summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Melanson <mike@multimedia.cx>2002-07-20 04:20:56 +0000
committerMike Melanson <mike@multimedia.cx>2002-07-20 04:20:56 +0000
commit5625e25c27b9c59d3f4cf4926bbfccfaf17258ce (patch)
treecbbde664cc9374016631c5560e77d64f962b6552
parent517fe0fd3ae90d02d1a0a152e57a792c3a655868 (diff)
downloadxine-lib-5625e25c27b9c59d3f4cf4926bbfccfaf17258ce.tar.gz
xine-lib-5625e25c27b9c59d3f4cf4926bbfccfaf17258ce.tar.bz2
added FINISH_LINE() color utility macro and fixed right-edge green stripe
problem in MMX YUV 4:4:4 -> YUY2 converter CVS patchset: 2324 CVS date: 2002/07/20 04:20:56
-rw-r--r--src/xine-utils/color.c34
-rw-r--r--src/xine-utils/xineutils.h13
2 files changed, 35 insertions, 12 deletions
diff --git a/src/xine-utils/color.c b/src/xine-utils/color.c
index eb7e0d616..8696c31dd 100644
--- a/src/xine-utils/color.c
+++ b/src/xine-utils/color.c
@@ -50,6 +50,12 @@
*
* The extra 2 samples are necessary for the final conversion. The extra
* 2 samples are simply mirrored from the last 2 samples on the line.
+ * This library provides a macro called FINISH_LINE() to mirror the last
+ * 2 samples in each color plane. To use it, call the macro with the YUV
+ * planes structure and the index of the first byte on the row. For
+ * example, in the above example, call FINISH_LINE() with a yuv_planes
+ * structure and the index 10 in order to finish (mirror the last 2 samples)
+ * on the second line.
*
* When an image has been fully decoded into the yuv_planes_t structure,
* call yuv444_to_yuy2() with the structure and the final (pre-allocated)
@@ -70,7 +76,7 @@
* instructions), these macros will automatically map to those special
* instructions.
*
- * $Id: color.c,v 1.4 2002/07/15 21:42:34 esnel Exp $
+ * $Id: color.c,v 1.5 2002/07/20 04:20:56 tmmm Exp $
*/
#include "xine_internal.h"
@@ -318,13 +324,12 @@ void yuv444_to_yuy2_mmx(yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int p
int secondary_samples;
int rewind_bytes;
int toss_out_shift;
+ int row_inc = (pitch - 2 * yuv_planes->row_width);
width_mod = yuv_planes->row_width % 6;
secondary_samples = width_mod / 2;
rewind_bytes = 6 - width_mod;
toss_out_shift = rewind_bytes * 8;
-//printf ("width_mod = %d, secondary_samples = %d, rewind_bytes = %d, toss_out_shift = %d\n",
-// width_mod, secondary_samples, rewind_bytes, toss_out_shift);
/* set up some MMX registers: mm0 = 0, mm7 = color filter */
pxor_r2r(mm0, mm0);
@@ -353,7 +358,7 @@ void yuv444_to_yuy2_mmx(yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int p
/* account for extra 2 samples */
source_plane += 2;
- dest_plane += (pitch - 2*yuv_planes->row_width);
+ dest_plane += row_inc;
}
/* figure out the U samples */
@@ -384,7 +389,6 @@ void yuv444_to_yuy2_mmx(yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int p
psrlq_i2r(16, mm1); /* toss out 2 U samples and loop again */
}
-
}
/* special case time: secondary samples */
@@ -393,8 +397,12 @@ void yuv444_to_yuy2_mmx(yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int p
movq_m2r(*source_plane, mm1); /* load 8 U samples */
source_plane += 8;
- /* toss out 2 U samples before starting */
- psrlq_i2r(toss_out_shift, mm1);
+ /* toss out 1-2 U samples before starting */
+ /* (psrlq_m2r does not work like I expect it to, so this looks weird) */
+ if (toss_out_shift == 16)
+ psrlq_i2r(16, mm1);
+ else
+ psrlq_i2r(32, mm1);
for (k = 0; k < secondary_samples; k++)
{
@@ -416,7 +424,7 @@ void yuv444_to_yuy2_mmx(yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int p
} else
source_plane += 2;
- dest_plane += (pitch - 2*yuv_planes->row_width);
+ dest_plane += row_inc;
}
/* figure out the V samples */
@@ -455,8 +463,12 @@ void yuv444_to_yuy2_mmx(yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int p
movq_m2r(*source_plane, mm1); /* load 8 V samples */
source_plane += 8;
- /* toss out 2 V samples before starting */
- psrlq_i2r(toss_out_shift, mm1);
+ /* toss out 1-2 V samples before starting */
+ /* (psrlq_m2r does not work like I expect it to, so this looks weird) */
+ if (toss_out_shift == 16)
+ psrlq_i2r(16, mm1);
+ else
+ psrlq_i2r(32, mm1);
for (k = 0; k < secondary_samples; k++)
{
@@ -478,7 +490,7 @@ void yuv444_to_yuy2_mmx(yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int p
} else
source_plane += 2;
- dest_plane += (pitch - 2*yuv_planes->row_width);
+ dest_plane += row_inc;
}
/* be a good MMX citizen and empty MMX state */
diff --git a/src/xine-utils/xineutils.h b/src/xine-utils/xineutils.h
index cb3a8139b..09680ff2c 100644
--- a/src/xine-utils/xineutils.h
+++ b/src/xine-utils/xineutils.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xineutils.h,v 1.18 2002/07/15 21:42:34 esnel Exp $
+ * $Id: xineutils.h,v 1.19 2002/07/20 04:20:56 tmmm Exp $
*
*/
#ifndef XINEUTILS_H
@@ -753,6 +753,17 @@ extern void (*yuv444_to_yuy2)
(unsigned char) \
((v_r_table[r] + v_g_table[g] + v_b_table[b]) / SCALEFACTOR + CENTERSAMPLE)
+#define FINISH_LINE(yuv_planes, row_ptr) \
+ yuv_planes.u[row_ptr + yuv_planes.row_width] = \
+ yuv_planes.u[row_ptr + yuv_planes.row_width - 1]; \
+ yuv_planes.u[row_ptr + yuv_planes.row_width + 1] = \
+ yuv_planes.u[row_ptr + yuv_planes.row_width - 2]; \
+ \
+ yuv_planes.v[row_ptr + yuv_planes.row_width] = \
+ yuv_planes.v[row_ptr + yuv_planes.row_width - 1]; \
+ yuv_planes.v[row_ptr + yuv_planes.row_width + 1] = \
+ yuv_planes.v[row_ptr + yuv_planes.row_width - 2];
+
#define UNPACK_BGR15(packed_pixel, r, g, b) \
b = (packed_pixel & 0x7C00) >> 7; \
g = (packed_pixel & 0x03E0) >> 2; \