Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1134)

Unified Diff: media/base/simd/convert_row_rgb.inc

Issue 7003082: Implements RGB to YV12 conversion in YASM. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/base/simd/convert_row_rgb.inc
===================================================================
--- media/base/simd/convert_row_rgb.inc (revision 0)
+++ media/base/simd/convert_row_rgb.inc (revision 0)
@@ -0,0 +1,507 @@
+; Copyright (c) 2011 The Chromium Authors. All rights reserved.
+; Use of this source code is governed by a BSD-style license that can be
+; found in the LICENSE file.
+
+;
+; void media::simd::ConvertRGBAtoYUVRow(const uint8* rgba,
+; uint8* y,
+; uint8* u,
+; uint8* v,
+; int width);
+; void media::simd::ConvertRGBtoYUVRow(const uint8* rgb,
+; uint8* y,
+; uint8* u,
+; uint8* v,
+; int width);
+;
+; Converts a row of RGBA (RGB) pixels to the YUV (4:1:1) colorspace. This
+; function reads RGBA (RGB) pixels from right to left, convert their colorspace
+; to YUV, and write the converted pixels to the output buffers. The following
+; code snippetre presents the rough structure of this fucntion.
+;
+; if (width & 1) {
+; --width;
+; convert_one_pixel(rgba, y, u, v, width);
+; }
+; if (width & 2) {
+; width -= 2;
+; convert_two_pixels(rgba, y, u, v, width);
+; }
+; while (width) {
+; width -= 4;
+; convert_four_pixels(rgba, y, u, v, width);
+; }
+;
+; This function has pseudo-code snippets to describe its behaviors. For
+; simplicity, they use the following notations.
+;
+; #define B(n) rgba[n * PIXELSIZE + 0];
+; #define G(n) rgba[n * PIXELSIZE + 1];
+; #define R(n) rgba[n * PIXELSIZE + 2];
+; #define A(n) PIXELSIZE == 4 ? rgba[n * PIXELSIZE + 3] : 0;
+; #define FIX(n) (n * (1 << SHIFT_BITS) + 0.5)
+; #define ToByte(n) ((n < 0) ? 0 : (n > 255 ? 255 : n))
+;
+; union {
+; int32 d[4];
+; int16 w[8];
+; int8 b[16];
+; } xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
+;
+
+; Input Parameters
+%ifdef __x86_64__
+%ifdef WIN64
+%define PARAM_RGBA(r) rcx
+%define PARAM_Y(r) rdx
+%define PARAM_U(r) r8
+%define PARAM_V(r) r9
+%define PARAM_WIDTH(r) INT [(r) + SIZEOF_POINTER * 2]
+%else
+%define PARAM_RGBA(r) rdi
+%define PARAM_Y(r) rsi
+%define PARAM_U(r) rdx
+%define PARAM_V(r) rcx
+%define PARAM_WIDTH(r) r8
+%endif
+%else
+%define PARAM_RGBA(r) POINTER [(r) + SIZEOF_POINTER * 2]
+%define PARAM_Y(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 1]
+%define PARAM_U(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 2]
+%define PARAM_V(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 3]
+%define PARAM_WIDTH(r) INT [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 4]
+%endif ; __x86_64__
+
rbultje 2011/06/10 18:26:33 So what you're doing here is providing compatibili
+; Local variables used in this function.
+%define INT_WIDTH32 eax
+%define INT_WIDTH8 al
+
+%define INT_PIXEL32 ebx
+%define INT_PIXEL16 bx
+%define INT_PIXEL8 bl
+
+%ifdef __x86_64__
+%define INT_WIDTH rax
+%define INT_PIXEL rbx
rbultje 2011/06/10 18:26:33 There's an issue here: width is defined as int, wh
+%define PTR_RGBA PARAM_RGBA(_EBP_)
+%define PTR_Y PARAM_Y(_EBP_)
+%define PTR_U PARAM_U(_EBP_)
+%define PTR_V PARAM_V(_EBP_)
+%else
+%define INT_WIDTH eax
+%define INT_PIXEL ebx
+%define PTR_RGBA ecx
+%define PTR_Y edx
+%define PTR_U esi
+%define PTR_V edi
+%endif
+
+%define XMM_TABLE_Y xmm7
+%define XMM_TABLE_0_5 xmm6
+%define XMM_TABLE_UV xmm5
+%define XMM_ZERO xmm4
+
+; SECTION SEG_TEXT
+; CPU PENTIUM4
+
+ align 16
+ global EXTN(SYMBOL_NAME) PRIVATE
+
+EXTN(SYMBOL_NAME):
+ push _EBP_
+ mov _EBP_, _ESP_
+
+ ; Save the resisters used in this function. We do not need to save eax, ecx,
+ ; or edx even though this function uses them. (Callers save them.)
+ push _EBX_
+ push _ESI_
+ push _EDI_
+
+ ; Copy the tables used in this function to xmm5, xmm6, and xmm7.
+ lea _EAX_, [SIMD_ConvertRGBAToYUVRow_kTable]
+ movdqa XMM_TABLE_Y, XMMWORD [_EAX_ + 16 * 0]
+ movdqa XMM_TABLE_0_5, XMMWORD [_EAX_ + 16 * 1]
+ movdqa XMM_TABLE_UV, XMMWORD [_EAX_ + 16 * 2]
+
+ ; Copy the input parameters to registers. (We can use the input pointers on
+ ; x86-64 since we do not change them.)
+ mov INT_WIDTH, PARAM_WIDTH(_EBP_)
+%ifndef __x86_64__
+ mov PTR_RGBA, PARAM_RGBA(_EBP_)
+ mov PTR_Y, PARAM_Y(_EBP_)
+ mov PTR_U, PARAM_U(_EBP_)
+ mov PTR_V, PARAM_V(_EBP_)
+%endif
+
+.convert_one_pixel:
+ ; Divide the input width by two so it represents the offsets for u[] and v[].
+ ; When the width is odd. Wee read the rightmost RGBA pixel and convert its
+ ; colorspace to YUV. This code stores one Y pixel, one U pixel, and one V
+ ; pixel.
+ sar INT_WIDTH, 1
+ jnc .convert_two_pixels
+
+ ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
+%if PIXELSIZE == 4
+ movd xmm0, DWORD [PTR_RGBA + INT_WIDTH * 4 * 2]
+%elif PIXELSIZE == 3
+ movd xmm1, INT_WIDTH
+ lea INT_WIDTH, [INT_WIDTH + INT_WIDTH * 2]
+ movzx INT_PIXEL32, BYTE [PTR_RGBA + INT_WIDTH * 2 + 2]
+ shl INT_PIXEL32, 16
+ mov INT_PIXEL16, WORD [PTR_RGBA + INT_WIDTH * 2]
+ movd xmm0, INT_PIXEL32
+ movd INT_WIDTH, xmm1
+%else
+%error unsupported pixel size.
+%endif
+ pxor XMM_ZERO, XMM_ZERO
+ punpcklbw xmm0, XMM_ZERO
+
+ ; xmm2.d[0] = FIX(0.098) * B(0) + FIX(0.504) * G(0);
+ ; xmm2.d[1] = FIX(0.257) * R(0) + FIX(0.000) * A(0);
+ movdqa xmm2, xmm0
+ pmaddwd xmm2, XMM_TABLE_Y
+
+ ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1] + FIX(0.5)) / FIX(1) + 16;
+ pshufd xmm4, xmm2, 10001000B
+ pshufd xmm2, xmm2, 11011101B
+ paddd xmm2, xmm4
+
+ paddd xmm2, XMM_TABLE_0_5
+ psrad xmm2, SHIFT_BITS
+ movdqa xmm3, XMM_TABLE_0_5
+ psrad xmm3, SHIFT_BITS - 5
+ paddd xmm2, xmm3
+
+ ; y[0] = ToByte(xmm2.d[0]);
+ packssdw xmm2, xmm2
+ packuswb xmm2, xmm2
+ movd INT_PIXEL32, xmm2
+ mov BYTE [PTR_Y + INT_WIDTH * 2], INT_PIXEL8
+
+ ; Calculate u[0] from xmm0.
+ ; xmm1.d[0] = FIX(0.439) * B(0) + -FIX(0.291) * G(0);
+ ; xmm1.d[1] = -FIX(0.148) * R(0) + FIX(0.000) * A(0);
+ movdqa xmm1, xmm0
+ pshufd xmm2, XMM_TABLE_UV, 01000100B
+ pmaddwd xmm1, xmm2
+
+ ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
+ pshufd xmm2, xmm1, 11011101B
+ pshufd xmm1, xmm1, 10001000B
+ paddd xmm1, xmm2
+ paddd xmm1, XMM_TABLE_0_5
+ psrad xmm1, SHIFT_BITS
+%if SHIFT_BITS == 8
+ paddd xmm1, XMM_TABLE_0_5
+%else
+ movdqa xmm3, XMM_TABLE_0_5
+ psrad xmm3, SHIFT_BITS - 8
+ paddd xmm1, xmm3
+%endif
+
+ ; u[0] = ToByte(xmm1.d[0]);
+ packssdw xmm1, xmm1
+ packuswb xmm1, xmm1
+ movd INT_PIXEL32, xmm1
+ mov BYTE [PTR_U + INT_WIDTH], INT_PIXEL8
+
+ ; Calculate v[0] from xmm0.
+ ; xmm0.d[0] = -FIX(0.071) * B(0) + -FIX(0.368) * G(0);
+ ; xmm0.d[1] = FIX(0.439) * R(0) + FIX(0.000) * A(0);
+ pshufd xmm2, XMM_TABLE_UV, 11101110B
+ pmaddwd xmm0, xmm2
+
+ ; xmm0.d[0] = (xmm0.d[0] + xmm0.d[1] + FIX(0.5)) / FIX(1) + 128;
+ pshufd xmm2, xmm0, 11011101B
+ pshufd xmm1, xmm0, 10001000B
+ paddd xmm0, xmm2
+ paddd xmm0, XMM_TABLE_0_5
+ psrad xmm0, SHIFT_BITS
+%if SHIFT_BITS == 8
+ paddd xmm0, XMM_TABLE_0_5
+%else
+ movdqa xmm3, XMM_TABLE_0_5
+ psrad xmm3, SHIFT_BITS - 8
+ paddd xmm0, xmm3
+%endif
+
+ ; v[0] = ToByte(xmm0.d[0]);
+ packssdw xmm0, xmm0
+ packuswb xmm0, xmm0
+ movd INT_PIXEL32, xmm0
+ mov BYTE [PTR_V + INT_WIDTH], INT_PIXEL8
+
+.convert_two_pixels:
+ ; If the input width is not a multiple of four, read the rightmost two RGBA
+ ; pixels and convert their colorspace to YUV. This code stores two Y pixels,
+ ; one U pixel, and one V pixel.
+ test INT_WIDTH8, 2 / 2
+ jz .convert_four_pixels
+ sub INT_WIDTH8, 2 / 2
+
+ ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
+ ; xmm0.w[4] = B(1); xmm0.w[5] = G(1); xmm0.w[6] = R(1); xmm0.w[7] = A(1);
+%if PIXELSIZE == 4
+ movq xmm0, MMWORD [PTR_RGBA + INT_WIDTH * 4 * 2]
+%elif PIXELSIZE == 3
+ mov _EBX_, INT_WIDTH
+ lea _EBX_, [_EBX_ + _EBX_ * 2]
+ movd xmm0, DWORD [PTR_RGBA + _EBX_ * 2]
+ pinsrw xmm0, WORD [PTR_RGBA + _EBX_ * 2 + 4], 3
+ movdqa xmm1, xmm0
+ psrldq xmm1, 3
+ pslldq xmm1, 3
+ pxor xmm0, xmm1
+ pslldq xmm1, 1
+ por xmm0, xmm1
+%else
+%error unsupported pixel size.
+%endif
+ pxor XMM_ZERO, XMM_ZERO
+ punpcklbw xmm0, XMM_ZERO
+
+ ; xmm2.d[0] = FIX(0.098) * B(0) + FIX(0.504) * G(0);
+ ; xmm2.d[1] = FIX(0.257) * R(0) + FIX(0.000) * A(0) ;
+ ; xmm2.d[2] = FIX(0.098) * B(1) + FIX(0.504) * G(1);
+ ; xmm2.d[3] = FIX(0.257) * R(1) + FIX(0.000) * A(1);
+ movdqa xmm2, xmm0
+ pmaddwd xmm2, XMM_TABLE_Y
+
+ ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1] + FIX(0.5)) / FIX(1) + 16;
+ ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3] + FIX(0.5)) / FIX(1) + 16;
+ pshufd xmm4, xmm2, 10001000B
+ pshufd xmm2, xmm2, 11011101B
+ paddd xmm2, xmm4
+
+ paddd xmm2, XMM_TABLE_0_5
+ psrld xmm2, SHIFT_BITS
+ movdqa xmm3, XMM_TABLE_0_5
+ psrld xmm3, SHIFT_BITS - 5
+ paddd xmm2, xmm3
+
+ ; y[0] = ToByte(xmm2.d[0]); y[1] = ToByte(xmm2.d[1]);
+ packssdw xmm2, xmm2
+ packuswb xmm2, xmm2
+ movd INT_PIXEL32, xmm2
+ mov WORD [PTR_Y + INT_WIDTH * 2], INT_PIXEL16
+
+ ; Calculate u[0] from xmm0.
+ ; xmm1.d[0] = FIX(0.439) * B(0) + -FIX(0.291) * G(0);
+ ; xmm1.d[1] = -FIX(0.148) * R(0) + FIX(0.000) * A(0);
+ movdqa xmm1, xmm0
+ pshufd xmm2, XMM_TABLE_UV, 01000100B
+ pmaddwd xmm1, xmm2
+
+ ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
+ pshufd xmm2, xmm1, 11011101B
+ pshufd xmm1, xmm1, 10001000B
+ paddd xmm1, xmm2
+ paddd xmm1, XMM_TABLE_0_5
+ psrad xmm1, SHIFT_BITS
+%if SHIFT_BITS == 8
+ paddd xmm1, XMM_TABLE_0_5
+%else
+ movdqa xmm3, XMM_TABLE_0_5
+ psrad xmm3, SHIFT_BITS - 8
+ paddd xmm1, xmm3
+%endif
+
+ ; u[0] = ToByte(xmm1.d[0]);
+ packssdw xmm1, xmm1
+ packuswb xmm1, xmm1
+ movd INT_PIXEL32, xmm1
+ mov BYTE [PTR_U + INT_WIDTH], INT_PIXEL8
+
+ ; Calculate v[0] from xmm0.
+ ; xmm0.d[0] = -FIX(0.071) * B(0) + -FIX(0.368) * G(0);
+ ; xmm0.d[1] = FIX(0.439) * R(0) + FIX(0.000) * A(0);
+ pshufd xmm2, XMM_TABLE_UV, 11101110B
+ pmaddwd xmm0, xmm2
+
+ ; xmm0.d[0] = (xmm0.d[0] + xmm0.d[1] + FIX(0.5)) / FIX(1) + 128;
+ pshufd xmm2, xmm0, 11011101B
+ pshufd xmm0, xmm0, 10001000B
+ paddd xmm0, xmm2
+ paddd xmm0, XMM_TABLE_0_5
+ psrad xmm0, SHIFT_BITS
+%if SHIFT_BITS == 8
+ paddd xmm0, XMM_TABLE_0_5
+%else
+ movdqa xmm3, XMM_TABLE_0_5
+ psrad xmm3, SHIFT_BITS - 8
+ paddd xmm0, xmm3
+%endif
+
+ ; v[0] = ToByte(xmm0.d[0]);
+ packssdw xmm0, xmm0
+ packuswb xmm0, xmm0
+ movd INT_PIXEL32, xmm0
+ mov BYTE [PTR_V + INT_WIDTH], INT_PIXEL8
+
+.convert_four_pixels:
+ ; Read four RGBA pixels and convert their colorspace to YUV. This code stores
+ ; four Y pixels, two U pixels, and two V pixels.
+ test INT_WIDTH32, INT_WIDTH32
+ jz .convert_finish
+ sub INT_WIDTH32, 4 / 2
+
+ ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
+ ; xmm0.w[4] = B(1); xmm0.w[5] = G(1); xmm0.w[6] = R(1); xmm0.w[7] = A(1);
+ ; xmm1.w[0] = B(2); xmm1.w[1] = G(2); xmm1.w[2] = R(2); xmm1.w[3] = A(2);
+ ; xmm1.w[4] = B(3); xmm1.w[5] = G(3); xmm1.w[6] = R(3); xmm1.w[7] = A(3);
+%if PIXELSIZE == 4
+ movdqu xmm0, XMMWORD [PTR_RGBA + INT_WIDTH * 4 * 2]
+%elif PIXELSIZE == 3
+ mov _EBX_, INT_WIDTH
+ lea _EBX_, [_EBX_ + _EBX_ * 2]
+ movq xmm0, MMWORD [PTR_RGBA + _EBX_ * 2]
+ movd xmm1, DWORD [PTR_RGBA + _EBX_ * 2 + 8]
+ shufps xmm0, xmm1, 01000100B
+ movdqa xmm1, xmm0
+ psrldq xmm1, 6
+ pslldq xmm1, 6
+ pxor xmm0, xmm1
+
+ movdqa xmm2, xmm0
+ psrldq xmm2, 3
+ pslldq xmm2, 3
+ pxor xmm0, xmm2
+ pslldq xmm2, 1
+ por xmm0, xmm2
+
+ movdqa xmm3, xmm1
+ psrldq xmm3, 6 + 3
+ pslldq xmm3, 6 + 3
+ pxor xmm1, xmm3
+ pslldq xmm3, 1
+ por xmm1, xmm3
+
+ pslldq xmm1, 2
+ por xmm0, xmm1
+%else
+%error unsupported pixel size.
+%endif
+ movdqa xmm1, xmm0
+ pxor XMM_ZERO, XMM_ZERO
+ punpckhbw xmm1, XMM_ZERO
+ punpcklbw xmm0, XMM_ZERO
+
+ ; xmm2.d[0] = FIX(0.098) * B(0) + FIX(0.504) * G(0);
+ ; xmm2.d[1] = FIX(0.257) * R(0) + FIX(0.000) * A(0);
+ ; xmm2.d[2] = FIX(0.098) * B(1) + FIX(0.504) * G(1);
+ ; xmm2.d[3] = FIX(0.257) * R(1) + FIX(0.000) * A(1);
+ ; xmm3.d[0] = FIX(0.098) * B(2) + FIX(0.504) * G(2);
+ ; xmm3.d[1] = FIX(0.257) * R(2) + FIX(0.000) * A(2);
+ ; xmm3.d[2] = FIX(0.098) * B(3) + FIX(0.504) * G(3);
+ ; xmm3.d[3] = FIX(0.257) * R(3) + FIX(0.000) * A(3);
+ movdqa xmm2, xmm0
+ movdqa xmm3, xmm1
+ pmaddwd xmm2, XMM_TABLE_Y
+ pmaddwd xmm3, XMM_TABLE_Y
+
+ ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1] + FIX(0.5)) / FIX(1) + 16;
+ ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3] + FIX(0.5)) / FIX(1) + 16;
+ ; xmm2.d[2] = (xmm3.d[0] + xmm3.d[1] + FIX(0.5)) / FIX(1) + 16;
+ ; xmm2.d[3] = (xmm3.d[2] + xmm3.d[3] + FIX(0.5)) / FIX(1) + 16;
+ movdqa xmm4, xmm2
+ shufps xmm4, xmm3, 10001000B
+ shufps xmm2, xmm3, 11011101B
+ paddd xmm2, xmm4
+
+ paddd xmm2, XMM_TABLE_0_5
+ psrad xmm2, SHIFT_BITS
+ movdqa xmm3, XMM_TABLE_0_5
+ psrad xmm3, SHIFT_BITS - 5
+ paddd xmm2, xmm3
+
+ ; y[0] = ToByte(xmm2.d[0]); y[1] = ToByte(xmm2.d[1]);
+ ; y[2] = ToByte(xmm2.d[2]); y[3] = ToByte(xmm2.d[3]);
+ packssdw xmm2, xmm2
+ packuswb xmm2, xmm2
+ movd DWORD [PTR_Y + INT_WIDTH * 2], xmm2
+
+ ; Retrieve (R(0), G(0), B(0), A(0)) and (R(2), G(2), B(2), A(2)) from xmm1
+ ; and xmm1.
+ ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
+ ; xmm0.w[4] = B(2); xmm0.w[5] = G(2); xmm0.w[6] = R(2); xmm0.w[7] = A(2);
+ shufps xmm0, xmm1, 01000100B
+
+ ; Calculate u[0] and u[2] from xmm0.
+ ; xmm1.d[0] = FIX(0.439) * B(0) + -FIX(0.291) * G(0);
+ ; xmm1.d[1] = -FIX(0.148) * R(0) + FIX(0.000) * A(0);
+ ; xmm1.d[2] = FIX(0.439) * B(2) + -FIX(0.291) * G(2);
+ ; xmm1.d[3] = -FIX(0.148) * R(2) + FIX(0.000) * A(2);
+ movdqa xmm1, xmm0
+ pshufd xmm2, XMM_TABLE_UV, 01000100B
+ pmaddwd xmm1, xmm2
+
+ ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
+ ; xmm1.d[1] = (xmm1.d[2] + xmm1.d[3] + FIX(0.5)) / FIX(1) + 128;
+ pshufd xmm2, xmm1, 11011101B
+ pshufd xmm1, xmm1, 10001000B
+ paddd xmm1, xmm2
+ paddd xmm1, XMM_TABLE_0_5
+ psrad xmm1, SHIFT_BITS
+%if SHIFT_BITS == 8
+ paddd xmm1, XMM_TABLE_0_5
+%else
+ movdqa xmm3, XMM_TABLE_0_5
+ psrad xmm3, SHIFT_BITS - 8
+ paddd xmm1, xmm3
+%endif
+
+ ; u[0] = ToByte(xmm1.d[0]); u[1] = ToByte(xmm1.d[1]);
+ packssdw xmm1, xmm1
+ packuswb xmm1, xmm1
+ movd INT_PIXEL32, xmm1
+ mov WORD [PTR_U + INT_WIDTH], INT_PIXEL16
+
+ ; Calculate v[0] and v[2] from xmm0.
+ ; xmm1.d[0] = -FIX(0.071) * B(0) + -FIX(0.368) * G(0);
+ ; xmm1.d[1] = FIX(0.439) * R(0) + FIX(0.000) * A(0);
+ ; xmm1.d[2] = -FIX(0.071) * B(2) + -FIX(0.368) * G(2);
+ ; xmm1.d[3] = FIX(0.439) * R(2) + FIX(0.000) * A(2);
+ movdqa xmm1, xmm0
+ pshufd xmm2, XMM_TABLE_UV, 11101110B
+ pmaddwd xmm1, xmm2
+
+ ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
+ ; xmm1.d[1] = (xmm1.d[2] + xmm1.d[3] + FIX(0.5)) / FIX(1) + 128;
+ pshufd xmm2, xmm1, 11011101B
+ pshufd xmm1, xmm1, 10001000B
+ paddd xmm1, xmm2
+ paddd xmm1, XMM_TABLE_0_5
+ psrad xmm1, SHIFT_BITS
+%if SHIFT_BITS == 8
+ paddd xmm1, XMM_TABLE_0_5
+%else
+ movdqa xmm3, XMM_TABLE_0_5
+ psrad xmm3, SHIFT_BITS - 8
+ paddd xmm1, xmm3
+%endif
+
+ ; v[0] = ToByte(xmm1.d[0]); v[1] = ToByte(xmm1.d[1]);
+ packssdw xmm1, xmm1
+ packuswb xmm1, xmm1
+ movd INT_PIXEL32, xmm1
+ mov WORD [PTR_V + INT_WIDTH], INT_PIXEL16
+
+ jmp .convert_four_pixels
+
+.convert_finish:
+ ; Restore the registers used in this function, the stack frame, and the stack
+ ; pointer.
+ pop _EDI_
+ pop _ESI_
+ pop _EBX_
+
+ mov _ESP_, _EBP_
+ pop _EBP_
+
+ ret
+
+ ; For some reason, the OS X linker does not honor the request to align the
+ ; segment unless we do this.
+ align 16
Property changes on: media\base\simd\convert_row_rgb.inc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698