diff options
author | Mike Melanson <mike@multimedia.cx> | 2002-07-20 04:20:56 +0000 |
---|---|---|
committer | Mike Melanson <mike@multimedia.cx> | 2002-07-20 04:20:56 +0000 |
commit | 5625e25c27b9c59d3f4cf4926bbfccfaf17258ce (patch) | |
tree | cbbde664cc9374016631c5560e77d64f962b6552 | |
parent | 517fe0fd3ae90d02d1a0a152e57a792c3a655868 (diff) | |
download | xine-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.c | 34 | ||||
-rw-r--r-- | src/xine-utils/xineutils.h | 13 |
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; \ |