| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
| 6 #include "media/base/simd/convert_rgb_to_yuv.h" | 6 #include "media/base/simd/convert_rgb_to_yuv.h" |
| 7 #include "media/base/simd/yuv_to_rgb_table.h" | 7 #include "media/base/simd/yuv_to_rgb_table.h" |
| 8 | 8 |
| 9 #if defined(COMPILER_MSVC) | 9 #if defined(COMPILER_MSVC) |
| 10 #include <intrin.h> | 10 #include <intrin.h> |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 }; | 43 }; |
| 44 #endif | 44 #endif |
| 45 | 45 |
| 46 #undef INT16_FIX | 46 #undef INT16_FIX |
| 47 | 47 |
| 48 // This is the final offset for the conversion from signed yuv values to | 48 // This is the final offset for the conversion from signed yuv values to |
| 49 // unsigned values. It is arranged so that offset of 16 is applied to Y | 49 // unsigned values. It is arranged so that offset of 16 is applied to Y |
| 50 // components and 128 is added to UV components for 2 pixels. | 50 // components and 128 is added to UV components for 2 pixels. |
| 51 SIMD_ALIGNED(const int32 kYOffset[4]) = {16, 16, 16, 16}; | 51 SIMD_ALIGNED(const int32 kYOffset[4]) = {16, 16, 16, 16}; |
| 52 | 52 |
| 53 static inline int Clamp(int value) { | 53 static inline uint8 Clamp(int value) { |
| 54 if (value < 0) | 54 if (value < 0) |
| 55 return 0; | 55 return 0; |
| 56 if (value > 255) | 56 if (value > 255) |
| 57 return 255; | 57 return 255; |
| 58 return value; | 58 return static_cast<uint8>(value); |
| 59 } | 59 } |
| 60 | 60 |
| 61 static inline int RGBToY(int r, int g, int b) { | 61 static inline uint8 RGBToY(int r, int g, int b) { |
| 62 int y = ConvertRGBAToYUV_kTable[0] * b + | 62 int y = ConvertRGBAToYUV_kTable[0] * b + |
| 63 ConvertRGBAToYUV_kTable[1] * g + | 63 ConvertRGBAToYUV_kTable[1] * g + |
| 64 ConvertRGBAToYUV_kTable[2] * r; | 64 ConvertRGBAToYUV_kTable[2] * r; |
| 65 y >>= FIX_SHIFT; | 65 y >>= FIX_SHIFT; |
| 66 return Clamp(y + 16); | 66 return Clamp(y + 16); |
| 67 } | 67 } |
| 68 | 68 |
| 69 static inline int RGBToU(int r, int g, int b, int shift) { | 69 static inline uint8 RGBToU(int r, int g, int b, int shift) { |
| 70 int u = ConvertRGBAToYUV_kTable[8] * b + | 70 int u = ConvertRGBAToYUV_kTable[8] * b + |
| 71 ConvertRGBAToYUV_kTable[9] * g + | 71 ConvertRGBAToYUV_kTable[9] * g + |
| 72 ConvertRGBAToYUV_kTable[10] * r; | 72 ConvertRGBAToYUV_kTable[10] * r; |
| 73 u >>= FIX_SHIFT + shift; | 73 u >>= FIX_SHIFT + shift; |
| 74 return Clamp(u + 128); | 74 return Clamp(u + 128); |
| 75 } | 75 } |
| 76 | 76 |
| 77 static inline int RGBToV(int r, int g, int b, int shift) { | 77 static inline uint8 RGBToV(int r, int g, int b, int shift) { |
| 78 int v = ConvertRGBAToYUV_kTable[16] * b + | 78 int v = ConvertRGBAToYUV_kTable[16] * b + |
| 79 ConvertRGBAToYUV_kTable[17] * g + | 79 ConvertRGBAToYUV_kTable[17] * g + |
| 80 ConvertRGBAToYUV_kTable[18] * r; | 80 ConvertRGBAToYUV_kTable[18] * r; |
| 81 v >>= FIX_SHIFT + shift; | 81 v >>= FIX_SHIFT + shift; |
| 82 return Clamp(v + 128); | 82 return Clamp(v + 128); |
| 83 } | 83 } |
| 84 | 84 |
| 85 #define CONVERT_Y(rgb_buf, y_buf) \ | 85 #define CONVERT_Y(rgb_buf, y_buf) \ |
| 86 b = *rgb_buf++; \ | 86 b = *rgb_buf++; \ |
| 87 g = *rgb_buf++; \ | 87 g = *rgb_buf++; \ |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 _mm_load_si128( | 262 _mm_load_si128( |
| 263 reinterpret_cast<const __m128i*>(ConvertRGBAToYUV_kTable + 8))); | 263 reinterpret_cast<const __m128i*>(ConvertRGBAToYUV_kTable + 8))); |
| 264 u_a_b = _mm_add_epi32(_mm_shuffle_epi32(u_a_b, ((3 << 2) | 1)), | 264 u_a_b = _mm_add_epi32(_mm_shuffle_epi32(u_a_b, ((3 << 2) | 1)), |
| 265 _mm_shuffle_epi32(u_a_b, (2 << 2))); | 265 _mm_shuffle_epi32(u_a_b, (2 << 2))); |
| 266 // Right shift 14 because of 12 from fixed point and 2 from subsampling. | 266 // Right shift 14 because of 12 from fixed point and 2 from subsampling. |
| 267 u_a_b = _mm_srai_epi32(u_a_b, FIX_SHIFT + 2); | 267 u_a_b = _mm_srai_epi32(u_a_b, FIX_SHIFT + 2); |
| 268 __m128i uv_offset = _mm_slli_epi32(y_offset, 3); | 268 __m128i uv_offset = _mm_slli_epi32(y_offset, 3); |
| 269 u_a_b = _mm_add_epi32(u_a_b, uv_offset); | 269 u_a_b = _mm_add_epi32(u_a_b, uv_offset); |
| 270 u_a_b = _mm_packs_epi32(u_a_b, u_a_b); | 270 u_a_b = _mm_packs_epi32(u_a_b, u_a_b); |
| 271 u_a_b = _mm_packus_epi16(u_a_b, u_a_b); | 271 u_a_b = _mm_packus_epi16(u_a_b, u_a_b); |
| 272 *reinterpret_cast<uint16*>(u_buf) = _mm_extract_epi16(u_a_b, 0); | 272 *reinterpret_cast<uint16*>(u_buf) = |
| 273 static_cast<uint16>(_mm_extract_epi16(u_a_b, 0)); |
| 273 u_buf += 2; | 274 u_buf += 2; |
| 274 | 275 |
| 275 __m128i v_a_b = _mm_madd_epi16( | 276 __m128i v_a_b = _mm_madd_epi16( |
| 276 rgb_abef_cdgh, | 277 rgb_abef_cdgh, |
| 277 _mm_load_si128( | 278 _mm_load_si128( |
| 278 reinterpret_cast<const __m128i*>(ConvertRGBAToYUV_kTable + 16))); | 279 reinterpret_cast<const __m128i*>(ConvertRGBAToYUV_kTable + 16))); |
| 279 v_a_b = _mm_add_epi32(_mm_shuffle_epi32(v_a_b, ((3 << 2) | 1)), | 280 v_a_b = _mm_add_epi32(_mm_shuffle_epi32(v_a_b, ((3 << 2) | 1)), |
| 280 _mm_shuffle_epi32(v_a_b, (2 << 2))); | 281 _mm_shuffle_epi32(v_a_b, (2 << 2))); |
| 281 v_a_b = _mm_srai_epi32(v_a_b, FIX_SHIFT + 2); | 282 v_a_b = _mm_srai_epi32(v_a_b, FIX_SHIFT + 2); |
| 282 v_a_b = _mm_add_epi32(v_a_b, uv_offset); | 283 v_a_b = _mm_add_epi32(v_a_b, uv_offset); |
| 283 v_a_b = _mm_packs_epi32(v_a_b, v_a_b); | 284 v_a_b = _mm_packs_epi32(v_a_b, v_a_b); |
| 284 v_a_b = _mm_packus_epi16(v_a_b, v_a_b); | 285 v_a_b = _mm_packus_epi16(v_a_b, v_a_b); |
| 285 *reinterpret_cast<uint16*>(v_buf) = _mm_extract_epi16(v_a_b, 0); | 286 *reinterpret_cast<uint16*>(v_buf) = |
| 287 static_cast<uint16>(_mm_extract_epi16(v_a_b, 0)); |
| 286 v_buf += 2; | 288 v_buf += 2; |
| 287 | 289 |
| 288 rgb_buf_1 += 16; | 290 rgb_buf_1 += 16; |
| 289 rgb_buf_2 += 16; | 291 rgb_buf_2 += 16; |
| 290 | 292 |
| 291 // Move forward by 4 pixels. | 293 // Move forward by 4 pixels. |
| 292 width -= 4; | 294 width -= 4; |
| 293 } | 295 } |
| 294 | 296 |
| 295 // Just use C code to convert the remaining pixels. | 297 // Just use C code to convert the remaining pixels. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 ++vplane; | 403 ++vplane; |
| 402 width -= 2; | 404 width -= 2; |
| 403 } | 405 } |
| 404 | 406 |
| 405 // Handle the last pixel in the last row. | 407 // Handle the last pixel in the last row. |
| 406 if (width) | 408 if (width) |
| 407 ConvertRGBToYUV_V1H1(rgbframe, yplane, uplane, vplane); | 409 ConvertRGBToYUV_V1H1(rgbframe, yplane, uplane, vplane); |
| 408 } | 410 } |
| 409 | 411 |
| 410 } // namespace media | 412 } // namespace media |
| OLD | NEW |