diff options
-rw-r--r-- | src/libmpeg2/decode.c | 1 | ||||
-rw-r--r-- | src/xine-engine/video_out.h | 3 | ||||
-rw-r--r-- | src/xine-utils/color.c | 238 | ||||
-rw-r--r-- | src/xine-utils/xineutils.h | 4 |
4 files changed, 180 insertions, 66 deletions
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c index 5f4aa0338..0f2c1d0bd 100644 --- a/src/libmpeg2/decode.c +++ b/src/libmpeg2/decode.c @@ -487,6 +487,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code, picture->current_frame->pts = mpeg2dec->pts; picture->current_frame->top_field_first = picture->top_field_first; picture->current_frame->repeat_first_field = picture->repeat_first_field; + picture->current_frame->progressive_frame = picture->progressive_frame; #ifdef LOG printf ("libmpeg2: decoding frame %d, type %s\n", diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h index faef454ea..63f08fc19 100644 --- a/src/xine-engine/video_out.h +++ b/src/xine-engine/video_out.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: video_out.h,v 1.88 2003/05/31 18:33:32 miguelfreitas Exp $ + * $Id: video_out.h,v 1.89 2003/06/03 03:33:16 miguelfreitas Exp $ * * * xine version of video_out.h @@ -115,6 +115,7 @@ struct vo_frame_s { /* info that can be used for interlaced output (e.g. tv-out) */ int top_field_first; int repeat_first_field; + int progressive_frame; /* pan/scan offset */ int pan_scan_x; diff --git a/src/xine-utils/color.c b/src/xine-utils/color.c index b115d37c3..28cdc6879 100644 --- a/src/xine-utils/color.c +++ b/src/xine-utils/color.c @@ -61,7 +61,7 @@ * instructions), these macros will automatically map to those special * instructions. * - * $Id: color.c,v 1.16 2003/06/02 00:03:58 miguelfreitas Exp $ + * $Id: color.c,v 1.17 2003/06/03 03:33:16 miguelfreitas Exp $ */ #include "xine_internal.h" @@ -147,7 +147,7 @@ void (*yv12_to_yuy2) unsigned char *u_src, int u_src_pitch, unsigned char *v_src, int v_src_pitch, unsigned char *yuy2_map, int yuy2_pitch, - int width, int height); + int width, int height, int progressive); /* @@ -662,14 +662,15 @@ void yuv411_to_yv12_c /***************************************************************************** * I420_YUY2: planar YUV 4:2:0 to packed YUYV 4:2:2 - * conversion routine from Videolan project + * original conversion routine from Videolan project + * changed to support interlaced frames. no filter/interpolation yet. *****************************************************************************/ void yv12_to_yuy2_c (unsigned char *y_src, int y_src_pitch, unsigned char *u_src, int u_src_pitch, unsigned char *v_src, int v_src_pitch, unsigned char *yuy2_map, int yuy2_pitch, - int width, int height) { + int width, int height, int progressive) { uint8_t *p_line1, *p_line2 = yuy2_map; uint8_t *p_y1, *p_y2 = y_src; @@ -683,38 +684,122 @@ void yv12_to_yuy2_c const int i_source_v_margin = v_src_pitch - width/2; const int i_dest_margin = yuy2_pitch - width*2; - for( i_y = height / 2 ; i_y-- ; ) - { - p_line1 = p_line2; - p_line2 += yuy2_pitch; - p_y1 = p_y2; - p_y2 += y_src_pitch; + if( progressive ) { + + for( i_y = height / 2 ; i_y-- ; ) + { + p_line1 = p_line2; + p_line2 += yuy2_pitch; + + p_y1 = p_y2; + p_y2 += y_src_pitch; + + for( i_x = width / 8 ; i_x-- ; ) + { + C_YUV420_YUYV( ); + C_YUV420_YUYV( ); + C_YUV420_YUYV( ); + C_YUV420_YUYV( ); + } + + p_y2 += i_source_margin; + p_u += i_source_u_margin; + p_v += i_source_v_margin; + p_line2 += i_dest_margin; + } - for( i_x = width / 8 ; i_x-- ; ) - { - C_YUV420_YUYV( ); - C_YUV420_YUYV( ); - C_YUV420_YUYV( ); - C_YUV420_YUYV( ); - } + } else { + + for( i_y = height / 4 ; i_y-- ; ) + { + p_line1 = p_line2; + p_line2 += 2 * yuy2_pitch; + + p_y1 = p_y2; + p_y2 += 2 * y_src_pitch; + + for( i_x = width / 8 ; i_x-- ; ) + { + C_YUV420_YUYV( ); + C_YUV420_YUYV( ); + C_YUV420_YUYV( ); + C_YUV420_YUYV( ); + } + + p_y2 += i_source_margin + y_src_pitch; + p_u += i_source_u_margin + u_src_pitch; + p_v += i_source_v_margin + v_src_pitch; + p_line2 += i_dest_margin + yuy2_pitch; + } + + p_line2 = yuy2_map + yuy2_pitch; + p_y2 = y_src + y_src_pitch; + p_u = u_src + u_src_pitch; + p_v = v_src + v_src_pitch; + + for( i_y = height / 4 ; i_y-- ; ) + { + p_line1 = p_line2; + p_line2 += 2 * yuy2_pitch; + + p_y1 = p_y2; + p_y2 += 2 * y_src_pitch; + + for( i_x = width / 8 ; i_x-- ; ) + { + C_YUV420_YUYV( ); + C_YUV420_YUYV( ); + C_YUV420_YUYV( ); + C_YUV420_YUYV( ); + } + + p_y2 += i_source_margin + y_src_pitch; + p_u += i_source_u_margin + u_src_pitch; + p_v += i_source_v_margin + v_src_pitch; + p_line2 += i_dest_margin + yuy2_pitch; + } - p_y1 += i_source_margin; - p_y2 += i_source_margin; - p_u += i_source_u_margin; - p_v += i_source_v_margin; - p_line1 += i_dest_margin; - p_line2 += i_dest_margin; } } +#ifdef ARCH_X86 + +#define MMX_YUV420_YUYV( ) \ +do { \ + __asm__ __volatile__(".align 8 \n\t" \ + "movq (%0), %%mm0 \n\t" /* Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 */ \ + "movd (%1), %%mm1 \n\t" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ \ + "movd (%2), %%mm2 \n\t" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ \ + "punpcklbw %%mm2, %%mm1 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ + "movq %%mm0, %%mm2 \n\t" /* y7 y6 y5 y4 y3 y2 y1 y0 */ \ + "punpcklbw %%mm1, %%mm2 \n\t" /* v1 y3 u1 y2 v0 y1 u0 y0 */ \ + : \ + : "r" (p_y1), "r" (p_u), "r" (p_v) ); \ + __asm__ __volatile__(".align 8 \n\t" \ + "movq %%mm2, (%0) \n\t" /* Store low YUYV */ \ + "punpckhbw %%mm1, %%mm0 \n\t" /* v3 y7 u3 y6 v2 y5 u2 y4 */ \ + "movq %%mm0, 8(%0) \n\t" /* Store high YUYV */ \ + "movq (%2), %%mm0 \n\t" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ + "movq %%mm0, %%mm2 \n\t" /* Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ + "punpcklbw %%mm1, %%mm2 \n\t" /* v1 Y3 u1 Y2 v0 Y1 u0 Y0 */ \ + "movq %%mm2, (%1) \n\t" /* Store low YUYV */ \ + "punpckhbw %%mm1, %%mm0 \n\t" /* v3 Y7 u3 Y6 v2 Y5 u2 Y4 */ \ + "movq %%mm0, 8(%1) \n\t" /* Store high YUYV */ \ + : \ + : "r" (p_line1), "r" (p_line2), "r" (p_y2) ); \ + p_line1 += 16; p_line2 += 16; p_y1 += 8; p_y2 += 8; p_u += 4; p_v += 4; \ +} while(0) + +#endif + void yv12_to_yuy2_mmx (unsigned char *y_src, int y_src_pitch, unsigned char *u_src, int u_src_pitch, unsigned char *v_src, int v_src_pitch, unsigned char *yuy2_map, int yuy2_pitch, - int width, int height) { + int width, int height, int progressive ) { #ifdef ARCH_X86 uint8_t *p_line1, *p_line2 = yuy2_map; uint8_t *p_y1, *p_y2 = y_src; @@ -728,47 +813,74 @@ void yv12_to_yuy2_mmx const int i_source_v_margin = v_src_pitch - width/2; const int i_dest_margin = yuy2_pitch - width*2; - for( i_y = height / 2; i_y-- ; ) - { - p_line1 = p_line2; - p_line2 += yuy2_pitch; - - p_y1 = p_y2; - p_y2 += y_src_pitch; - - for( i_x = width / 8 ; i_x-- ; ) - { - __asm__ __volatile__(".align 8 \n\t" - "movq (%0), %%mm0 \n\t" /* Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 */ - "movd (%1), %%mm1 \n\t" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ - "movd (%2), %%mm2 \n\t" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ - "punpcklbw %%mm2, %%mm1 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ - "movq %%mm0, %%mm2 \n\t" /* y7 y6 y5 y4 y3 y2 y1 y0 */ - "punpcklbw %%mm1, %%mm2 \n\t" /* v1 y3 u1 y2 v0 y1 u0 y0 */ - : - : "r" (p_y1), "r" (p_u), "r" (p_v) ); - __asm__ __volatile__(".align 8 \n\t" - "movq %%mm2, (%0) \n\t" /* Store low YUYV */ - "punpckhbw %%mm1, %%mm0 \n\t" /* v3 y7 u3 y6 v2 y5 u2 y4 */ - "movq %%mm0, 8(%0) \n\t" /* Store high YUYV */ - "movq (%2), %%mm0 \n\t" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ - "movq %%mm0, %%mm2 \n\t" /* Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ - "punpcklbw %%mm1, %%mm2 \n\t" /* v1 Y3 u1 Y2 v0 Y1 u0 Y0 */ - "movq %%mm2, (%1) \n\t" /* Store low YUYV */ - "punpckhbw %%mm1, %%mm0 \n\t" /* v3 Y7 u3 Y6 v2 Y5 u2 Y4 */ - "movq %%mm0, 8(%1) \n\t" /* Store high YUYV */ - : - : "r" (p_line1), "r" (p_line2), "r" (p_y2) ); - p_line1 += 16; p_line2 += 16; p_y1 += 8; p_y2 += 8; p_u += 4; p_v += 4; \ - } + if( progressive ) { + + for( i_y = height / 2; i_y-- ; ) + { + p_line1 = p_line2; + p_line2 += yuy2_pitch; + + p_y1 = p_y2; + p_y2 += y_src_pitch; + + for( i_x = width / 8 ; i_x-- ; ) + { + MMX_YUV420_YUYV( ); + } + + p_y2 += i_source_margin; + p_u += i_source_u_margin; + p_v += i_source_v_margin; + p_line2 += i_dest_margin; + } + + } else { + + for( i_y = height / 4 ; i_y-- ; ) + { + p_line1 = p_line2; + p_line2 += 2 * yuy2_pitch; + + p_y1 = p_y2; + p_y2 += 2 * y_src_pitch; + + for( i_x = width / 8 ; i_x-- ; ) + { + MMX_YUV420_YUYV( ); + } + + p_y2 += i_source_margin + y_src_pitch; + p_u += i_source_u_margin + u_src_pitch; + p_v += i_source_v_margin + v_src_pitch; + p_line2 += i_dest_margin + yuy2_pitch; + } + + p_line2 = yuy2_map + yuy2_pitch; + p_y2 = y_src + y_src_pitch; + p_u = u_src + u_src_pitch; + p_v = v_src + v_src_pitch; + + for( i_y = height / 4 ; i_y-- ; ) + { + p_line1 = p_line2; + p_line2 += 2 * yuy2_pitch; + + p_y1 = p_y2; + p_y2 += 2 * y_src_pitch; + + for( i_x = width / 8 ; i_x-- ; ) + { + MMX_YUV420_YUYV( ); + } + + p_y2 += i_source_margin + y_src_pitch; + p_u += i_source_u_margin + u_src_pitch; + p_v += i_source_v_margin + v_src_pitch; + p_line2 += i_dest_margin + yuy2_pitch; + } - p_y1 += i_source_margin; - p_y2 += i_source_margin; - p_u += i_source_u_margin; - p_v += i_source_v_margin; - p_line1 += i_dest_margin; - p_line2 += i_dest_margin; } + emms(); #endif diff --git a/src/xine-utils/xineutils.h b/src/xine-utils/xineutils.h index fee9f6e3f..5ef3c3e08 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.51 2003/05/31 13:54:27 miguelfreitas Exp $ + * $Id: xineutils.h,v 1.52 2003/06/03 03:33:16 miguelfreitas Exp $ * */ #ifndef XINEUTILS_H @@ -776,7 +776,7 @@ extern void (*yv12_to_yuy2) unsigned char *u_src, int u_src_pitch, unsigned char *v_src, int v_src_pitch, unsigned char *yuy2_map, int yuy2_pitch, - int width, int height); + int width, int height, int progressive); #define SCALEFACTOR 65536 #define CENTERSAMPLE 128 |