1aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org/* 2b0c97975894a5eebebf9d93147cdd941a3accb63fbarchard@google.com * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org * 4aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org * Use of this source code is governed by a BSD-style license 5aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org * that can be found in the LICENSE file in the root of the source 6aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org * tree. An additional intellectual property rights grant can be found 7cde587092fef0dbed2c35602f30b79e7b892e766fbarchard@google.com * in the file PATENTS. All contributing project authors may 8aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org */ 10aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 11a1280730c24b5c94ef16949777f65e597719488efbarchard@google.com#include "libyuv/convert.h" 12aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 13585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com#include "libyuv/basic_types.h" 14585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com#include "libyuv/cpu_id.h" 15b61497636a648c771ac55d184a80b17aca7414f5fbarchard@google.com#include "libyuv/planar_functions.h" 16b61497636a648c771ac55d184a80b17aca7414f5fbarchard@google.com#include "libyuv/rotate.h" 171d160cb99f2b05df80c4555bd769825ad1175dc9fbarchard@google.com#include "libyuv/scale.h" // For ScalePlane() 18142f6c4ed5eaeec0176f255e64bac8d8c70b42e1fbarchard@google.com#include "libyuv/row.h" 19aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 20fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com#ifdef __cplusplus 21a1280730c24b5c94ef16949777f65e597719488efbarchard@google.comnamespace libyuv { 22fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.comextern "C" { 23fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com#endif 24aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 2599a1298c54dc35348295165745521120818263b8fbarchard@google.com#define SUBSAMPLE(v, a, s) (v < 0) ? (-((-v + a) >> s)) : ((v + a) >> s) 2699a1298c54dc35348295165745521120818263b8fbarchard@google.comstatic __inline int Abs(int v) { 2799a1298c54dc35348295165745521120818263b8fbarchard@google.com return v >= 0 ? v : -v; 2899a1298c54dc35348295165745521120818263b8fbarchard@google.com} 2999a1298c54dc35348295165745521120818263b8fbarchard@google.com 3099a1298c54dc35348295165745521120818263b8fbarchard@google.com// Any I4xx To I420 format with mirroring. 3199a1298c54dc35348295165745521120818263b8fbarchard@google.comstatic int I4xxToI420(const uint8* src_y, int src_stride_y, 3299a1298c54dc35348295165745521120818263b8fbarchard@google.com const uint8* src_u, int src_stride_u, 3399a1298c54dc35348295165745521120818263b8fbarchard@google.com const uint8* src_v, int src_stride_v, 3499a1298c54dc35348295165745521120818263b8fbarchard@google.com uint8* dst_y, int dst_stride_y, 3599a1298c54dc35348295165745521120818263b8fbarchard@google.com uint8* dst_u, int dst_stride_u, 3699a1298c54dc35348295165745521120818263b8fbarchard@google.com uint8* dst_v, int dst_stride_v, 3799a1298c54dc35348295165745521120818263b8fbarchard@google.com int src_y_width, int src_y_height, 3899a1298c54dc35348295165745521120818263b8fbarchard@google.com int src_uv_width, int src_uv_height) { 3999a1298c54dc35348295165745521120818263b8fbarchard@google.com const int dst_y_width = Abs(src_y_width); 4099a1298c54dc35348295165745521120818263b8fbarchard@google.com const int dst_y_height = Abs(src_y_height); 4199a1298c54dc35348295165745521120818263b8fbarchard@google.com const int dst_uv_width = SUBSAMPLE(dst_y_width, 1, 1); 4299a1298c54dc35348295165745521120818263b8fbarchard@google.com const int dst_uv_height = SUBSAMPLE(dst_y_height, 1, 1); 43a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com if (src_y_width == 0 || src_y_height == 0 || 44a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com src_uv_width == 0 || src_uv_height == 0) { 45a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com return -1; 46a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com } 4799a1298c54dc35348295165745521120818263b8fbarchard@google.com ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, 4899a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_y, dst_stride_y, dst_y_width, dst_y_height, 4999a1298c54dc35348295165745521120818263b8fbarchard@google.com kFilterBilinear); 5099a1298c54dc35348295165745521120818263b8fbarchard@google.com ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, 5199a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_u, dst_stride_u, dst_uv_width, dst_uv_height, 5299a1298c54dc35348295165745521120818263b8fbarchard@google.com kFilterBilinear); 5399a1298c54dc35348295165745521120818263b8fbarchard@google.com ScalePlane(src_v, src_stride_v, src_uv_width, src_uv_height, 5499a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_v, dst_stride_v, dst_uv_width, dst_uv_height, 5599a1298c54dc35348295165745521120818263b8fbarchard@google.com kFilterBilinear); 5699a1298c54dc35348295165745521120818263b8fbarchard@google.com return 0; 5799a1298c54dc35348295165745521120818263b8fbarchard@google.com} 5899a1298c54dc35348295165745521120818263b8fbarchard@google.com 592d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// Copy I420 with optional flipping 6099a1298c54dc35348295165745521120818263b8fbarchard@google.com// TODO(fbarchard): Use Scale plane which supports mirroring, but ensure 6199a1298c54dc35348295165745521120818263b8fbarchard@google.com// is does row coalescing. 62fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 632d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.comint I420Copy(const uint8* src_y, int src_stride_y, 642d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com const uint8* src_u, int src_stride_u, 652d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com const uint8* src_v, int src_stride_v, 662d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_y, int dst_stride_y, 672d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_u, int dst_stride_u, 682d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_v, int dst_stride_v, 692d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com int width, int height) { 70a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int halfwidth = (width + 1) >> 1; 71a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int halfheight = (height + 1) >> 1; 722d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com if (!src_y || !src_u || !src_v || 732d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com !dst_y || !dst_u || !dst_v || 742d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com width <= 0 || height == 0) { 752d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com return -1; 761616c315e0313b61d922f0b75bd6704861b75a56fbarchard@google.com } 772d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com // Negative height means invert the image. 782d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com if (height < 0) { 792d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com height = -height; 80a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com halfheight = (height + 1) >> 1; 812d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_y = src_y + (height - 1) * src_stride_y; 822d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_u = src_u + (halfheight - 1) * src_stride_u; 832d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_v = src_v + (halfheight - 1) * src_stride_v; 842d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_stride_y = -src_stride_y; 852d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_stride_u = -src_stride_u; 862d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_stride_v = -src_stride_v; 872d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com } 882d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com 892d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com if (dst_y) { 902d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 912d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com } 92a8e4dcb5d5b2ef0334d46b4db0278efb87feaf6cfbarchard@google.com // Copy UV planes. 932d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, halfheight); 942d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, halfheight); 952d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com return 0; 961616c315e0313b61d922f0b75bd6704861b75a56fbarchard@google.com} 97032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com 98545a51c1d3c0d28a614b224375bbf00edf81c057fbarchard@google.com// 422 chroma is 1/2 width, 1x height 99545a51c1d3c0d28a614b224375bbf00edf81c057fbarchard@google.com// 420 chroma is 1/2 width, 1/2 height 100fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 1012d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.comint I422ToI420(const uint8* src_y, int src_stride_y, 102585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com const uint8* src_u, int src_stride_u, 103585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com const uint8* src_v, int src_stride_v, 1042d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_y, int dst_stride_y, 1052d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_u, int dst_stride_u, 1062d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_v, int dst_stride_v, 107585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com int width, int height) { 10899a1298c54dc35348295165745521120818263b8fbarchard@google.com const int src_uv_width = SUBSAMPLE(width, 1, 1); 10999a1298c54dc35348295165745521120818263b8fbarchard@google.com return I4xxToI420(src_y, src_stride_y, 11099a1298c54dc35348295165745521120818263b8fbarchard@google.com src_u, src_stride_u, 11199a1298c54dc35348295165745521120818263b8fbarchard@google.com src_v, src_stride_v, 11299a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_y, dst_stride_y, 11399a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_u, dst_stride_u, 11499a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_v, dst_stride_v, 11599a1298c54dc35348295165745521120818263b8fbarchard@google.com width, height, 11699a1298c54dc35348295165745521120818263b8fbarchard@google.com src_uv_width, height); 1171616c315e0313b61d922f0b75bd6704861b75a56fbarchard@google.com} 118aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 119545a51c1d3c0d28a614b224375bbf00edf81c057fbarchard@google.com// 444 chroma is 1x width, 1x height 120545a51c1d3c0d28a614b224375bbf00edf81c057fbarchard@google.com// 420 chroma is 1/2 width, 1/2 height 121fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 1222d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.comint I444ToI420(const uint8* src_y, int src_stride_y, 1231616c315e0313b61d922f0b75bd6704861b75a56fbarchard@google.com const uint8* src_u, int src_stride_u, 1241616c315e0313b61d922f0b75bd6704861b75a56fbarchard@google.com const uint8* src_v, int src_stride_v, 1252d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_y, int dst_stride_y, 1262d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_u, int dst_stride_u, 1272d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_v, int dst_stride_v, 1281616c315e0313b61d922f0b75bd6704861b75a56fbarchard@google.com int width, int height) { 12999a1298c54dc35348295165745521120818263b8fbarchard@google.com return I4xxToI420(src_y, src_stride_y, 13099a1298c54dc35348295165745521120818263b8fbarchard@google.com src_u, src_stride_u, 13199a1298c54dc35348295165745521120818263b8fbarchard@google.com src_v, src_stride_v, 13299a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_y, dst_stride_y, 13399a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_u, dst_stride_u, 13499a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_v, dst_stride_v, 13599a1298c54dc35348295165745521120818263b8fbarchard@google.com width, height, 13699a1298c54dc35348295165745521120818263b8fbarchard@google.com width, height); 137aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org} 138aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 1398536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.com// 411 chroma is 1/4 width, 1x height 1408536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.com// 420 chroma is 1/2 width, 1/2 height 141fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 1428536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.comint I411ToI420(const uint8* src_y, int src_stride_y, 1438536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.com const uint8* src_u, int src_stride_u, 1448536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.com const uint8* src_v, int src_stride_v, 1458536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.com uint8* dst_y, int dst_stride_y, 1468536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.com uint8* dst_u, int dst_stride_u, 1478536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.com uint8* dst_v, int dst_stride_v, 1488536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.com int width, int height) { 14999a1298c54dc35348295165745521120818263b8fbarchard@google.com const int src_uv_width = SUBSAMPLE(width, 3, 2); 15099a1298c54dc35348295165745521120818263b8fbarchard@google.com return I4xxToI420(src_y, src_stride_y, 15199a1298c54dc35348295165745521120818263b8fbarchard@google.com src_u, src_stride_u, 15299a1298c54dc35348295165745521120818263b8fbarchard@google.com src_v, src_stride_v, 15399a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_y, dst_stride_y, 15499a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_u, dst_stride_u, 15599a1298c54dc35348295165745521120818263b8fbarchard@google.com dst_v, dst_stride_v, 15699a1298c54dc35348295165745521120818263b8fbarchard@google.com width, height, 15799a1298c54dc35348295165745521120818263b8fbarchard@google.com src_uv_width, height); 1588536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.com} 1598536b2f389dea8f8b7177f4886d995e3315f12e8fbarchard@google.com 1602d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// I400 is greyscale typically used in MJPG 161fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 1622d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.comint I400ToI420(const uint8* src_y, int src_stride_y, 1632d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_y, int dst_stride_y, 1642d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_u, int dst_stride_u, 1652d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_v, int dst_stride_v, 166032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com int width, int height) { 167a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int halfwidth = (width + 1) >> 1; 168a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int halfheight = (height + 1) >> 1; 16925ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_y || !dst_y || !dst_u || !dst_v || 17025ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 17125ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 17225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 173032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com // Negative height means invert the image. 174032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com if (height < 0) { 175032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com height = -height; 176a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com halfheight = (height + 1) >> 1; 1772d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_y = src_y + (height - 1) * src_stride_y; 1782d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_stride_y = -src_stride_y; 1792d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com } 1802d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); 1812d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com SetPlane(dst_u, dst_stride_u, halfwidth, halfheight, 128); 1822d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com SetPlane(dst_v, dst_stride_v, halfwidth, halfheight, 128); 183032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com return 0; 184032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com} 185032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com 1862d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.comstatic void CopyPlane2(const uint8* src, int src_stride_0, int src_stride_1, 187b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com uint8* dst, int dst_stride, 1882d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com int width, int height) { 189a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 19019932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; 191b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#if defined(HAS_COPYROW_X86) 192b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com if (TestCpuFlag(kCpuHasX86) && IS_ALIGNED(width, 4)) { 19319932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com CopyRow = CopyRow_X86; 194b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 195b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#endif 19619932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com#if defined(HAS_COPYROW_SSE2) 197b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 32) && 198b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com IS_ALIGNED(src, 16) && 199b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com IS_ALIGNED(src_stride_0, 16) && IS_ALIGNED(src_stride_1, 16) && 200b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com IS_ALIGNED(dst, 16) && IS_ALIGNED(dst_stride, 16)) { 201b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com CopyRow = CopyRow_SSE2; 202b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 20319932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com#endif 204aa7988ff733b13d7bfd3c755bf0c18f93b9e8f6efbarchard@google.com#if defined(HAS_COPYROW_ERMS) 205aa7988ff733b13d7bfd3c755bf0c18f93b9e8f6efbarchard@google.com if (TestCpuFlag(kCpuHasERMS)) { 206aa7988ff733b13d7bfd3c755bf0c18f93b9e8f6efbarchard@google.com CopyRow = CopyRow_ERMS; 207b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 208b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#endif 209b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#if defined(HAS_COPYROW_NEON) 210b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) { 211b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com CopyRow = CopyRow_NEON; 21219932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com } 21319932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com#endif 21492352b70819e74fabec5be83807e7ab93e4df6c2fbarchard@google.com#if defined(HAS_COPYROW_MIPS) 21592352b70819e74fabec5be83807e7ab93e4df6c2fbarchard@google.com if (TestCpuFlag(kCpuHasMIPS)) { 21692352b70819e74fabec5be83807e7ab93e4df6c2fbarchard@google.com CopyRow = CopyRow_MIPS; 21792352b70819e74fabec5be83807e7ab93e4df6c2fbarchard@google.com } 21892352b70819e74fabec5be83807e7ab93e4df6c2fbarchard@google.com#endif 21919932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com 2202d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com // Copy plane 221a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 22219932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com CopyRow(src, dst, width); 223b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com CopyRow(src + src_stride_0, dst + dst_stride, width); 22419932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com src += src_stride_0 + src_stride_1; 225b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com dst += dst_stride * 2; 22619932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com } 22719932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com if (height & 1) { 22819932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com CopyRow(src, dst, width); 229585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com } 2302d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com} 2312d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com 2322d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// Support converting from FOURCC_M420 2332d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// Useful for bandwidth constrained transports like USB 1.0 and 2.0 and for 2342d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// easy conversion to I420. 2352d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// M420 format description: 2362d9fe08225ab28f62b515b2b914accc6a7b060fbfbarchard@google.com// M420 is row biplanar 420: 2 rows of Y and 1 row of UV. 2372d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// Chroma is half width / half height. (420) 23864ce0ab544591b1e26ae6d276932cacdb8137071fbarchard@google.com// src_stride_m420 is row planar. Normally this will be the width in pixels. 2392d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// The UV plane is half width, but 2 values, so src_stride_m420 applies to 2402d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// this as well as the two Y planes. 2412d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.comstatic int X420ToI420(const uint8* src_y, 2422d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com int src_stride_y0, int src_stride_y1, 2432d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com const uint8* src_uv, int src_stride_uv, 2442d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_y, int dst_stride_y, 2452d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_u, int dst_stride_u, 2462d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_v, int dst_stride_v, 2472d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com int width, int height) { 248a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 249a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int halfwidth = (width + 1) >> 1; 250a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int halfheight = (height + 1) >> 1; 251a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*SplitUVRow)(const uint8* src_uv, uint8* dst_u, uint8* dst_v, int pix) = 252a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com SplitUVRow_C; 25325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_y || !src_uv || 25425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org !dst_y || !dst_u || !dst_v || 25525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 25625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 25725ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 258032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com // Negative height means invert the image. 259032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com if (height < 0) { 260032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com height = -height; 261a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com halfheight = (height + 1) >> 1; 2622d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_y = dst_y + (height - 1) * dst_stride_y; 2632d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_u = dst_u + (halfheight - 1) * dst_stride_u; 2642d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_v = dst_v + (halfheight - 1) * dst_stride_v; 2652d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_stride_y = -dst_stride_y; 2662d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_stride_u = -dst_stride_u; 2672d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_stride_v = -dst_stride_v; 2682d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com } 269095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 2705ca144d2140755ab668916335cd927e5583dbb42fbarchard@google.com if (src_stride_y0 == width && 2715ca144d2140755ab668916335cd927e5583dbb42fbarchard@google.com src_stride_y1 == width && 2725ca144d2140755ab668916335cd927e5583dbb42fbarchard@google.com dst_stride_y == width) { 273095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com width *= height; 2745ca144d2140755ab668916335cd927e5583dbb42fbarchard@google.com height = 1; 275095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_y0 = src_stride_y1 = dst_stride_y = 0; 2765ca144d2140755ab668916335cd927e5583dbb42fbarchard@google.com } 277095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com // Coalesce rows. 278095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com if (src_stride_uv == halfwidth * 2 && 27987215c0871c6f491ab870378bfff2c3601a02973fbarchard@google.com dst_stride_u == halfwidth && 28087215c0871c6f491ab870378bfff2c3601a02973fbarchard@google.com dst_stride_v == halfwidth) { 281095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com halfwidth *= halfheight; 2825ca144d2140755ab668916335cd927e5583dbb42fbarchard@google.com halfheight = 1; 283095f33d870bdc68773db05e75484cc2ed1fe7550fbarchard@google.com src_stride_uv = dst_stride_u = dst_stride_v = 0; 2845ca144d2140755ab668916335cd927e5583dbb42fbarchard@google.com } 285f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com#if defined(HAS_SPLITUVROW_SSE2) 286e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && halfwidth >= 16) { 287f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com SplitUVRow = SplitUVRow_Any_SSE2; 288e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com if (IS_ALIGNED(halfwidth, 16)) { 289f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com SplitUVRow = SplitUVRow_Unaligned_SSE2; 290e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com if (IS_ALIGNED(src_uv, 16) && IS_ALIGNED(src_stride_uv, 16) && 291e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com IS_ALIGNED(dst_u, 16) && IS_ALIGNED(dst_stride_u, 16) && 292e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com IS_ALIGNED(dst_v, 16) && IS_ALIGNED(dst_stride_v, 16)) { 293f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com SplitUVRow = SplitUVRow_SSE2; 294db694edfc2dcdede9adad7febc4e4b7f9506eee8fbarchard@google.com } 295db694edfc2dcdede9adad7febc4e4b7f9506eee8fbarchard@google.com } 2962b9c21080362d7f1b45f7465847e939b1d270583fbarchard@google.com } 297db694edfc2dcdede9adad7febc4e4b7f9506eee8fbarchard@google.com#endif 298f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com#if defined(HAS_SPLITUVROW_AVX2) 299e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com if (TestCpuFlag(kCpuHasAVX2) && halfwidth >= 32) { 300f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com SplitUVRow = SplitUVRow_Any_AVX2; 301e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com if (IS_ALIGNED(halfwidth, 32)) { 302b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com SplitUVRow = SplitUVRow_AVX2; 303db694edfc2dcdede9adad7febc4e4b7f9506eee8fbarchard@google.com } 3042d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com } 305db694edfc2dcdede9adad7febc4e4b7f9506eee8fbarchard@google.com#endif 306f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com#if defined(HAS_SPLITUVROW_NEON) 307e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && halfwidth >= 16) { 308f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com SplitUVRow = SplitUVRow_Any_NEON; 309e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com if (IS_ALIGNED(halfwidth, 16)) { 3104a86a836fcde981b6c3fd3f4a216a3253a2d26bcfbarchard@google.com SplitUVRow = SplitUVRow_NEON; 311db694edfc2dcdede9adad7febc4e4b7f9506eee8fbarchard@google.com } 312db694edfc2dcdede9adad7febc4e4b7f9506eee8fbarchard@google.com } 313db694edfc2dcdede9adad7febc4e4b7f9506eee8fbarchard@google.com#endif 314f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com#if defined(HAS_SPLITUVROW_MIPS_DSPR2) 315e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com if (TestCpuFlag(kCpuHasMIPS_DSPR2) && halfwidth >= 16) { 316f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com SplitUVRow = SplitUVRow_Any_MIPS_DSPR2; 317e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com if (IS_ALIGNED(halfwidth, 16)) { 318f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com SplitUVRow = SplitUVRow_Unaligned_MIPS_DSPR2; 319e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com if (IS_ALIGNED(src_uv, 4) && IS_ALIGNED(src_stride_uv, 4) && 320e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com IS_ALIGNED(dst_u, 4) && IS_ALIGNED(dst_stride_u, 4) && 321e0d8648b6ab861cfcf03513439fad8ae39ba50c2fbarchard@google.com IS_ALIGNED(dst_v, 4) && IS_ALIGNED(dst_stride_v, 4)) { 322f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com SplitUVRow = SplitUVRow_MIPS_DSPR2; 323db694edfc2dcdede9adad7febc4e4b7f9506eee8fbarchard@google.com } 324db694edfc2dcdede9adad7febc4e4b7f9506eee8fbarchard@google.com } 325ca41005256d8b16fef98bc3383c44c4a3b79bb44fbarchard@google.com } 3262b9c21080362d7f1b45f7465847e939b1d270583fbarchard@google.com#endif 32782ca39582875374c0470473d0dcc6b697f6e5404mikhal@webrtc.org 3282d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com if (dst_y) { 329b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com if (src_stride_y0 == src_stride_y1) { 330b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com CopyPlane(src_y, src_stride_y0, dst_y, dst_stride_y, width, height); 331b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } else { 332b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com CopyPlane2(src_y, src_stride_y0, src_stride_y1, dst_y, dst_stride_y, 333b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com width, height); 334b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 335280f4fd8bb7d04ca1a5ecd0b6245a4f3726a9df3mikhal@webrtc.org } 3362d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com 337a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < halfheight; ++y) { 3382d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com // Copy a row of UV. 339f08ac6bb095348565b5259f2fab95f259ef47edefbarchard@google.com SplitUVRow(src_uv, dst_u, dst_v, halfwidth); 3402d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_u += dst_stride_u; 3412d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_v += dst_stride_v; 3422d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_uv += src_stride_uv; 343032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com } 344032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com return 0; 345032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com} 346032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com 3472d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// Convert NV12 to I420. 348fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 3492d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.comint NV12ToI420(const uint8* src_y, int src_stride_y, 3502d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com const uint8* src_uv, int src_stride_uv, 3512d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_y, int dst_stride_y, 3522d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_u, int dst_stride_u, 3532d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_v, int dst_stride_v, 354032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com int width, int height) { 3552d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com return X420ToI420(src_y, src_stride_y, src_stride_y, 3562d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_uv, src_stride_uv, 3572d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_y, dst_stride_y, 3582d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_u, dst_stride_u, 3592d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_v, dst_stride_v, 3602d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com width, height); 3612d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com} 3622d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com 36362a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com// Convert NV21 to I420. Same as NV12 but u and v pointers swapped. 36462a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.comLIBYUV_API 36562a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.comint NV21ToI420(const uint8* src_y, int src_stride_y, 36662a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com const uint8* src_vu, int src_stride_vu, 36762a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com uint8* dst_y, int dst_stride_y, 36862a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com uint8* dst_u, int dst_stride_u, 36962a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com uint8* dst_v, int dst_stride_v, 37062a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com int width, int height) { 37162a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com return X420ToI420(src_y, src_stride_y, src_stride_y, 37262a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com src_vu, src_stride_vu, 37362a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com dst_y, dst_stride_y, 37462a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com dst_v, dst_stride_v, 37562a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com dst_u, dst_stride_u, 37662a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com width, height); 37762a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com} 37862a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com 3792d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// Convert M420 to I420. 380fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 3812d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.comint M420ToI420(const uint8* src_m420, int src_stride_m420, 3822d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_y, int dst_stride_y, 3832d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_u, int dst_stride_u, 3842d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_v, int dst_stride_v, 3852d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com int width, int height) { 3862d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com return X420ToI420(src_m420, src_stride_m420, src_stride_m420 * 2, 3872d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_m420 + src_stride_m420 * 2, src_stride_m420 * 3, 3882d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_y, dst_stride_y, 3892d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_u, dst_stride_u, 3902d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_v, dst_stride_v, 3912d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com width, height); 3922d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com} 3932d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com 3942d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// Convert Q420 to I420. 3952d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com// Format is rows of YY/YUYV 396fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 3972d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.comint Q420ToI420(const uint8* src_y, int src_stride_y, 3982d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com const uint8* src_yuy2, int src_stride_yuy2, 3992d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_y, int dst_stride_y, 4002d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_u, int dst_stride_u, 4012d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com uint8* dst_v, int dst_stride_v, 4022d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com int width, int height) { 403a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 404a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int halfheight = (height + 1) >> 1; 405a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*CopyRow)(const uint8* src, uint8* dst, int width) = CopyRow_C; 406a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*YUY2ToUV422Row)(const uint8* src_yuy2, uint8* dst_u, uint8* dst_v, 407a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int pix) = YUY2ToUV422Row_C; 408a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*YUY2ToYRow)(const uint8* src_yuy2, uint8* dst_y, int pix) = 409a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com YUY2ToYRow_C; 41025ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_y || !src_yuy2 || 41125ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org !dst_y || !dst_u || !dst_v || 41225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 41325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 41425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 415032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com // Negative height means invert the image. 416032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com if (height < 0) { 417032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com height = -height; 418a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com halfheight = (height + 1) >> 1; 4192d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_y = dst_y + (height - 1) * dst_stride_y; 4202d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_u = dst_u + (halfheight - 1) * dst_stride_u; 4212d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_v = dst_v + (halfheight - 1) * dst_stride_v; 4222d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_stride_y = -dst_stride_y; 4232d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_stride_u = -dst_stride_u; 4242d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_stride_v = -dst_stride_v; 4252d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com } 426d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com // CopyRow for rows of just Y in Q420 copied to Y plane of I420. 42719932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com#if defined(HAS_COPYROW_NEON) 42862a961bee72e48e4fa14365bd7444c9280540b6ffbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) { 42919932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com CopyRow = CopyRow_NEON; 43019932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com } 431d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com#endif 432d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com#if defined(HAS_COPYROW_X86) 43319932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com if (IS_ALIGNED(width, 4)) { 43419932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com CopyRow = CopyRow_X86; 435d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com } 43619932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com#endif 437d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com#if defined(HAS_COPYROW_SSE2) 438d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 32) && 439d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com IS_ALIGNED(src_y, 16) && IS_ALIGNED(src_stride_y, 16) && 440d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 441d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com CopyRow = CopyRow_SSE2; 44219932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com } 44319932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com#endif 444aa7988ff733b13d7bfd3c755bf0c18f93b9e8f6efbarchard@google.com#if defined(HAS_COPYROW_ERMS) 445aa7988ff733b13d7bfd3c755bf0c18f93b9e8f6efbarchard@google.com if (TestCpuFlag(kCpuHasERMS)) { 446aa7988ff733b13d7bfd3c755bf0c18f93b9e8f6efbarchard@google.com CopyRow = CopyRow_ERMS; 447b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 448b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#endif 44992352b70819e74fabec5be83807e7ab93e4df6c2fbarchard@google.com#if defined(HAS_COPYROW_MIPS) 45092352b70819e74fabec5be83807e7ab93e4df6c2fbarchard@google.com if (TestCpuFlag(kCpuHasMIPS)) { 45192352b70819e74fabec5be83807e7ab93e4df6c2fbarchard@google.com CopyRow = CopyRow_MIPS; 45292352b70819e74fabec5be83807e7ab93e4df6c2fbarchard@google.com } 45392352b70819e74fabec5be83807e7ab93e4df6c2fbarchard@google.com#endif 45419932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com 455d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com#if defined(HAS_YUY2TOYROW_SSE2) 456bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 16) { 457bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com YUY2ToUV422Row = YUY2ToUV422Row_Any_SSE2; 458bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com YUY2ToYRow = YUY2ToYRow_Any_SSE2; 459d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com if (IS_ALIGNED(width, 16)) { 460d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com YUY2ToUV422Row = YUY2ToUV422Row_Unaligned_SSE2; 461d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com YUY2ToYRow = YUY2ToYRow_Unaligned_SSE2; 462d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com if (IS_ALIGNED(src_yuy2, 16) && IS_ALIGNED(src_stride_yuy2, 16)) { 463d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com YUY2ToUV422Row = YUY2ToUV422Row_SSE2; 464db11d893c275d17264afdd1f488bcd2e77aa867dfbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 465db11d893c275d17264afdd1f488bcd2e77aa867dfbarchard@google.com YUY2ToYRow = YUY2ToYRow_SSE2; 466db11d893c275d17264afdd1f488bcd2e77aa867dfbarchard@google.com } 467d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com } 468d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com } 469d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com } 470b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#endif 471b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#if defined(HAS_YUY2TOYROW_AVX2) 472b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com if (TestCpuFlag(kCpuHasAVX2) && width >= 32) { 473b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com YUY2ToUV422Row = YUY2ToUV422Row_Any_AVX2; 474b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com YUY2ToYRow = YUY2ToYRow_Any_AVX2; 475b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com if (IS_ALIGNED(width, 32)) { 476b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com YUY2ToUV422Row = YUY2ToUV422Row_AVX2; 477b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com YUY2ToYRow = YUY2ToYRow_AVX2; 478b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 479b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 480b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#endif 481b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#if defined(HAS_YUY2TOYROW_NEON) 482bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 483bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com YUY2ToYRow = YUY2ToYRow_Any_NEON; 484bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (width >= 16) { 485bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com YUY2ToUV422Row = YUY2ToUV422Row_Any_NEON; 486d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com } 487c74fe987257b082e0bb887290f97caf7ab3bad66fbarchard@google.com if (IS_ALIGNED(width, 16)) { 488d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com YUY2ToYRow = YUY2ToYRow_NEON; 489c74fe987257b082e0bb887290f97caf7ab3bad66fbarchard@google.com YUY2ToUV422Row = YUY2ToUV422Row_NEON; 490d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com } 491032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com } 4922b9c21080362d7f1b45f7465847e939b1d270583fbarchard@google.com#endif 4932b9c21080362d7f1b45f7465847e939b1d270583fbarchard@google.com 494a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 49519932f8dbc5ca3123d87b5b8369e7d7bf3469a97fbarchard@google.com CopyRow(src_y, dst_y, width); 4962d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com src_y += src_stride_y; 497d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com dst_y += dst_stride_y; 4982d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com 499d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com YUY2ToUV422Row(src_yuy2, dst_u, dst_v, width); 500d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com YUY2ToYRow(src_yuy2, dst_y, width); 501d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com src_yuy2 += src_stride_yuy2; 5022d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_y += dst_stride_y; 5032d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_u += dst_stride_u; 5042d11d43a6e21865b904705acce6535ae4c2d3caffbarchard@google.com dst_v += dst_stride_v; 505d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com } 506d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com if (height & 1) { 507d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com CopyRow(src_y, dst_y, width); 508d8a1435fe01177fdf2884067aca59896538f9dbdfbarchard@google.com YUY2ToUV422Row(src_yuy2, dst_u, dst_v, width); 509032b5f990f6673afee7d9a7ad3132ca46448d834fbarchard@google.com } 510280f4fd8bb7d04ca1a5ecd0b6245a4f3726a9df3mikhal@webrtc.org return 0; 511aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org} 512aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 513b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com// Convert YUY2 to I420. 514fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 515b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.comint YUY2ToI420(const uint8* src_yuy2, int src_stride_yuy2, 5169394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com uint8* dst_y, int dst_stride_y, 5179394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com uint8* dst_u, int dst_stride_u, 5189394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com uint8* dst_v, int dst_stride_v, 5199394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com int width, int height) { 520a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 521a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*YUY2ToUVRow)(const uint8* src_yuy2, int src_stride_yuy2, 5228798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int pix) = YUY2ToUVRow_C; 523a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*YUY2ToYRow)(const uint8* src_yuy2, 5248798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_y, int pix) = YUY2ToYRow_C; 525b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com // Negative height means invert the image. 526585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com if (height < 0) { 527585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com height = -height; 528b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2; 529b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_stride_yuy2 = -src_stride_yuy2; 530b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 531b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#if defined(HAS_YUY2TOYROW_SSE2) 532bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 16) { 533bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com YUY2ToUVRow = YUY2ToUVRow_Any_SSE2; 534bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com YUY2ToYRow = YUY2ToYRow_Any_SSE2; 535b5b27d131adf623aa98109fe4196cd492c2d8b60fbarchard@google.com if (IS_ALIGNED(width, 16)) { 536b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com YUY2ToUVRow = YUY2ToUVRow_Unaligned_SSE2; 537b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com YUY2ToYRow = YUY2ToYRow_Unaligned_SSE2; 538b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(src_yuy2, 16) && IS_ALIGNED(src_stride_yuy2, 16)) { 539b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com YUY2ToUVRow = YUY2ToUVRow_SSE2; 540b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 541b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com YUY2ToYRow = YUY2ToYRow_SSE2; 542b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 543b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 544b5b27d131adf623aa98109fe4196cd492c2d8b60fbarchard@google.com } 545b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 546b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#endif 547b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#if defined(HAS_YUY2TOYROW_AVX2) 548b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com if (TestCpuFlag(kCpuHasAVX2) && width >= 32) { 549b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com YUY2ToUVRow = YUY2ToUVRow_Any_AVX2; 550b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com YUY2ToYRow = YUY2ToYRow_Any_AVX2; 551b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com if (IS_ALIGNED(width, 32)) { 552b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com YUY2ToUVRow = YUY2ToUVRow_AVX2; 553b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com YUY2ToYRow = YUY2ToYRow_AVX2; 554b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 555b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 556b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#endif 557b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#if defined(HAS_YUY2TOYROW_NEON) 558bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 559bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com YUY2ToYRow = YUY2ToYRow_Any_NEON; 560bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (width >= 16) { 561bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com YUY2ToUVRow = YUY2ToUVRow_Any_NEON; 562dddf94c343c9a6413468a334e9fd965e4b1b3eb7fbarchard@google.com } 563c74fe987257b082e0bb887290f97caf7ab3bad66fbarchard@google.com if (IS_ALIGNED(width, 16)) { 564dddf94c343c9a6413468a334e9fd965e4b1b3eb7fbarchard@google.com YUY2ToYRow = YUY2ToYRow_NEON; 565c74fe987257b082e0bb887290f97caf7ab3bad66fbarchard@google.com YUY2ToUVRow = YUY2ToUVRow_NEON; 566dddf94c343c9a6413468a334e9fd965e4b1b3eb7fbarchard@google.com } 567dddf94c343c9a6413468a334e9fd965e4b1b3eb7fbarchard@google.com } 5689394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com#endif 5695808cb22ce60bf963e15bfb1a0958cb362f5efbcfbarchard@google.com 570a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 571b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com YUY2ToUVRow(src_yuy2, src_stride_yuy2, dst_u, dst_v, width); 572b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com YUY2ToYRow(src_yuy2, dst_y, width); 573b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com YUY2ToYRow(src_yuy2 + src_stride_yuy2, dst_y + dst_stride_y, width); 574b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_yuy2 += src_stride_yuy2 * 2; 575b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com dst_y += dst_stride_y * 2; 576b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com dst_u += dst_stride_u; 577b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com dst_v += dst_stride_v; 5789394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 579b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (height & 1) { 580c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com YUY2ToUVRow(src_yuy2, 0, dst_u, dst_v, width); 581c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com YUY2ToYRow(src_yuy2, dst_y, width); 582b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 583b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com return 0; 584b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com} 585b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com 586b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com// Convert UYVY to I420. 587fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 588b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.comint UYVYToI420(const uint8* src_uyvy, int src_stride_uyvy, 589b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com uint8* dst_y, int dst_stride_y, 590b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com uint8* dst_u, int dst_stride_u, 591b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com uint8* dst_v, int dst_stride_v, 592b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com int width, int height) { 593a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 594a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*UYVYToUVRow)(const uint8* src_uyvy, int src_stride_uyvy, 5958798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int pix) = UYVYToUVRow_C; 596a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*UYVYToYRow)(const uint8* src_uyvy, 5978798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_y, int pix) = UYVYToYRow_C; 598b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com // Negative height means invert the image. 599b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (height < 0) { 600b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com height = -height; 601b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy; 602b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_stride_uyvy = -src_stride_uyvy; 603b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 604b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#if defined(HAS_UYVYTOYROW_SSE2) 605bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 16) { 606bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com UYVYToUVRow = UYVYToUVRow_Any_SSE2; 607bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com UYVYToYRow = UYVYToYRow_Any_SSE2; 608b5b27d131adf623aa98109fe4196cd492c2d8b60fbarchard@google.com if (IS_ALIGNED(width, 16)) { 609b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com UYVYToUVRow = UYVYToUVRow_Unaligned_SSE2; 610b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com UYVYToYRow = UYVYToYRow_Unaligned_SSE2; 611b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(src_uyvy, 16) && IS_ALIGNED(src_stride_uyvy, 16)) { 612b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com UYVYToUVRow = UYVYToUVRow_SSE2; 613b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 614b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com UYVYToYRow = UYVYToYRow_SSE2; 615b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 616b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 617b5b27d131adf623aa98109fe4196cd492c2d8b60fbarchard@google.com } 6189394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 619b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#endif 620b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#if defined(HAS_UYVYTOYROW_AVX2) 621b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com if (TestCpuFlag(kCpuHasAVX2) && width >= 32) { 622b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com UYVYToUVRow = UYVYToUVRow_Any_AVX2; 623b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com UYVYToYRow = UYVYToYRow_Any_AVX2; 624b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com if (IS_ALIGNED(width, 32)) { 625b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com UYVYToUVRow = UYVYToUVRow_AVX2; 626b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com UYVYToYRow = UYVYToYRow_AVX2; 627b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 628b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com } 629b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#endif 630b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com#if defined(HAS_UYVYTOYROW_NEON) 631bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 632bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com UYVYToYRow = UYVYToYRow_Any_NEON; 633bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (width >= 16) { 634bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com UYVYToUVRow = UYVYToUVRow_Any_NEON; 635dddf94c343c9a6413468a334e9fd965e4b1b3eb7fbarchard@google.com } 636c74fe987257b082e0bb887290f97caf7ab3bad66fbarchard@google.com if (IS_ALIGNED(width, 16)) { 637dddf94c343c9a6413468a334e9fd965e4b1b3eb7fbarchard@google.com UYVYToYRow = UYVYToYRow_NEON; 638c74fe987257b082e0bb887290f97caf7ab3bad66fbarchard@google.com UYVYToUVRow = UYVYToUVRow_NEON; 639dddf94c343c9a6413468a334e9fd965e4b1b3eb7fbarchard@google.com } 640dddf94c343c9a6413468a334e9fd965e4b1b3eb7fbarchard@google.com } 641b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#endif 642dddf94c343c9a6413468a334e9fd965e4b1b3eb7fbarchard@google.com 643a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 644b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com UYVYToUVRow(src_uyvy, src_stride_uyvy, dst_u, dst_v, width); 645b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com UYVYToYRow(src_uyvy, dst_y, width); 646b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com UYVYToYRow(src_uyvy + src_stride_uyvy, dst_y + dst_stride_y, width); 647b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_uyvy += src_stride_uyvy * 2; 648585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com dst_y += dst_stride_y * 2; 649585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com dst_u += dst_stride_u; 650585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com dst_v += dst_stride_v; 65143575c8fa5a0f18b1ad9146cda3dfb1af13811f2mikhal@webrtc.org } 652585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com if (height & 1) { 653c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com UYVYToUVRow(src_uyvy, 0, dst_u, dst_v, width); 654c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com UYVYToYRow(src_uyvy, dst_y, width); 655c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com } 656c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com return 0; 657c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com} 658c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com 659bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com// Convert ARGB to I420. 660fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 661b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.comint ARGBToI420(const uint8* src_argb, int src_stride_argb, 662585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com uint8* dst_y, int dst_stride_y, 663585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com uint8* dst_u, int dst_stride_u, 664585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com uint8* dst_v, int dst_stride_v, 665585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com int width, int height) { 666a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 667a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 6688798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 669a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 670a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ARGBToYRow_C; 67125ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_argb || 67225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org !dst_y || !dst_u || !dst_v || 67325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 67425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 67525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 67625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 6779394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com if (height < 0) { 6789394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com height = -height; 679b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_argb = src_argb + (height - 1) * src_stride_argb; 680b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_stride_argb = -src_stride_argb; 6819394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 6827fa21d677cf82793be81d02e0a1fbcaf9f56cb99fbarchard@google.com#if defined(HAS_ARGBTOYROW_SSSE3) && defined(HAS_ARGBTOUVROW_SSSE3) 683bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 684bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 685bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToYRow = ARGBToYRow_Any_SSSE3; 686b5b27d131adf623aa98109fe4196cd492c2d8b60fbarchard@google.com if (IS_ALIGNED(width, 16)) { 687b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToUVRow = ARGBToUVRow_Unaligned_SSSE3; 688b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 689b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) { 690b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToUVRow = ARGBToUVRow_SSSE3; 691b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 692b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToYRow = ARGBToYRow_SSSE3; 693b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 694b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 695b5b27d131adf623aa98109fe4196cd492c2d8b60fbarchard@google.com } 696b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 697551d2b297e6a071fe58a8f2da2cb69cc0ec56ed8fbarchard@google.com#endif 6987fa21d677cf82793be81d02e0a1fbcaf9f56cb99fbarchard@google.com#if defined(HAS_ARGBTOYROW_AVX2) && defined(HAS_ARGBTOUVROW_AVX2) 699551d2b297e6a071fe58a8f2da2cb69cc0ec56ed8fbarchard@google.com if (TestCpuFlag(kCpuHasAVX2) && width >= 32) { 700551d2b297e6a071fe58a8f2da2cb69cc0ec56ed8fbarchard@google.com ARGBToUVRow = ARGBToUVRow_Any_AVX2; 701551d2b297e6a071fe58a8f2da2cb69cc0ec56ed8fbarchard@google.com ARGBToYRow = ARGBToYRow_Any_AVX2; 702551d2b297e6a071fe58a8f2da2cb69cc0ec56ed8fbarchard@google.com if (IS_ALIGNED(width, 32)) { 703b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com ARGBToUVRow = ARGBToUVRow_AVX2; 704b444bae883e97c1e4579f2e1148cf14f9c7c18fbfbarchard@google.com ARGBToYRow = ARGBToYRow_AVX2; 705551d2b297e6a071fe58a8f2da2cb69cc0ec56ed8fbarchard@google.com } 706551d2b297e6a071fe58a8f2da2cb69cc0ec56ed8fbarchard@google.com } 707551d2b297e6a071fe58a8f2da2cb69cc0ec56ed8fbarchard@google.com#endif 708551d2b297e6a071fe58a8f2da2cb69cc0ec56ed8fbarchard@google.com#if defined(HAS_ARGBTOYROW_NEON) 709bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 710bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToYRow = ARGBToYRow_Any_NEON; 7110908a701e90dc15d973784f6245131aa65a66f52fbarchard@google.com if (IS_ALIGNED(width, 8)) { 7120908a701e90dc15d973784f6245131aa65a66f52fbarchard@google.com ARGBToYRow = ARGBToYRow_NEON; 713522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com } 714522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com if (width >= 16) { 715522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGBToUVRow = ARGBToUVRow_Any_NEON; 716dd2d512e5afad7536e3a010c0193ca1b43c14985fbarchard@google.com if (IS_ALIGNED(width, 16)) { 717dd2d512e5afad7536e3a010c0193ca1b43c14985fbarchard@google.com ARGBToUVRow = ARGBToUVRow_NEON; 718dd2d512e5afad7536e3a010c0193ca1b43c14985fbarchard@google.com } 7190908a701e90dc15d973784f6245131aa65a66f52fbarchard@google.com } 7200908a701e90dc15d973784f6245131aa65a66f52fbarchard@google.com } 7219394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com#endif 722b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com 723a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 724b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width); 725b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToYRow(src_argb, dst_y, width); 726b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width); 727b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_argb += src_stride_argb * 2; 728b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com dst_y += dst_stride_y * 2; 729b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com dst_u += dst_stride_u; 730b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com dst_v += dst_stride_v; 7319394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 732b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (height & 1) { 733b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToUVRow(src_argb, 0, dst_u, dst_v, width); 734b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToYRow(src_argb, dst_y, width); 735b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 736b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com return 0; 737b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com} 738b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com 739bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com// Convert BGRA to I420. 740fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 741b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.comint BGRAToI420(const uint8* src_bgra, int src_stride_bgra, 742b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com uint8* dst_y, int dst_stride_y, 743b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com uint8* dst_u, int dst_stride_u, 744b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com uint8* dst_v, int dst_stride_v, 745b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com int width, int height) { 746a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 747a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*BGRAToUVRow)(const uint8* src_bgra0, int src_stride_bgra, 7488798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = BGRAToUVRow_C; 749a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*BGRAToYRow)(const uint8* src_bgra, uint8* dst_y, int pix) = 750a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com BGRAToYRow_C; 75125ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_bgra || 75225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org !dst_y || !dst_u || !dst_v || 75325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 75425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 75525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 75625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 757b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (height < 0) { 758b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com height = -height; 759b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_bgra = src_bgra + (height - 1) * src_stride_bgra; 760b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_stride_bgra = -src_stride_bgra; 761b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 762b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#if defined(HAS_BGRATOYROW_SSSE3) 763bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 764bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com BGRAToUVRow = BGRAToUVRow_Any_SSSE3; 765bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com BGRAToYRow = BGRAToYRow_Any_SSSE3; 766b5b27d131adf623aa98109fe4196cd492c2d8b60fbarchard@google.com if (IS_ALIGNED(width, 16)) { 767b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com BGRAToUVRow = BGRAToUVRow_Unaligned_SSSE3; 768b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com BGRAToYRow = BGRAToYRow_Unaligned_SSSE3; 769b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(src_bgra, 16) && IS_ALIGNED(src_stride_bgra, 16)) { 770b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com BGRAToUVRow = BGRAToUVRow_SSSE3; 771b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 772b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com BGRAToYRow = BGRAToYRow_SSSE3; 773b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 774b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 775b5b27d131adf623aa98109fe4196cd492c2d8b60fbarchard@google.com } 7769394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 777bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#elif defined(HAS_BGRATOYROW_NEON) 778bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 779bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com BGRAToYRow = BGRAToYRow_Any_NEON; 780bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 8)) { 781bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com BGRAToYRow = BGRAToYRow_NEON; 782bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 78395730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (width >= 16) { 78495730719503137a7db61a105bec02220f9ed159efbarchard@google.com BGRAToUVRow = BGRAToUVRow_Any_NEON; 78595730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (IS_ALIGNED(width, 16)) { 78695730719503137a7db61a105bec02220f9ed159efbarchard@google.com BGRAToUVRow = BGRAToUVRow_NEON; 78795730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 78895730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 789bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 790b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#endif 7919394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com 792a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 793b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com BGRAToUVRow(src_bgra, src_stride_bgra, dst_u, dst_v, width); 794b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com BGRAToYRow(src_bgra, dst_y, width); 795b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com BGRAToYRow(src_bgra + src_stride_bgra, dst_y + dst_stride_y, width); 796b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_bgra += src_stride_bgra * 2; 7979394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com dst_y += dst_stride_y * 2; 7989394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com dst_u += dst_stride_u; 7999394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com dst_v += dst_stride_v; 8009394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 8019394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com if (height & 1) { 802c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com BGRAToUVRow(src_bgra, 0, dst_u, dst_v, width); 803c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com BGRAToYRow(src_bgra, dst_y, width); 8049394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 8059394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com return 0; 806abe14f80ba16b62a04e94587a983c8bcbc7bb88amikhal@webrtc.org} 807abe14f80ba16b62a04e94587a983c8bcbc7bb88amikhal@webrtc.org 808bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com// Convert ABGR to I420. 809fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 810b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.comint ABGRToI420(const uint8* src_abgr, int src_stride_abgr, 811585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com uint8* dst_y, int dst_stride_y, 812585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com uint8* dst_u, int dst_stride_u, 813585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com uint8* dst_v, int dst_stride_v, 814585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com int width, int height) { 815a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 816a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ABGRToUVRow)(const uint8* src_abgr0, int src_stride_abgr, 8178798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = ABGRToUVRow_C; 818a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ABGRToYRow)(const uint8* src_abgr, uint8* dst_y, int pix) = 819a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ABGRToYRow_C; 82025ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org if (!src_abgr || 82125ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org !dst_y || !dst_u || !dst_v || 82225ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org width <= 0 || height == 0) { 82325ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org return -1; 82425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org } 82525ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 8269394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com if (height < 0) { 8279394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com height = -height; 828b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_abgr = src_abgr + (height - 1) * src_stride_abgr; 829b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_stride_abgr = -src_stride_abgr; 8309394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 8319394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com#if defined(HAS_ABGRTOYROW_SSSE3) 832bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 833bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ABGRToUVRow = ABGRToUVRow_Any_SSSE3; 834bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ABGRToYRow = ABGRToYRow_Any_SSSE3; 835b5b27d131adf623aa98109fe4196cd492c2d8b60fbarchard@google.com if (IS_ALIGNED(width, 16)) { 836b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ABGRToUVRow = ABGRToUVRow_Unaligned_SSSE3; 837b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ABGRToYRow = ABGRToYRow_Unaligned_SSSE3; 838b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(src_abgr, 16) && IS_ALIGNED(src_stride_abgr, 16)) { 839b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ABGRToUVRow = ABGRToUVRow_SSSE3; 840b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 841b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ABGRToYRow = ABGRToYRow_SSSE3; 842b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 843b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 844b5b27d131adf623aa98109fe4196cd492c2d8b60fbarchard@google.com } 8459394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 846bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#elif defined(HAS_ABGRTOYROW_NEON) 847bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 848bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ABGRToYRow = ABGRToYRow_Any_NEON; 849bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 8)) { 850bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ABGRToYRow = ABGRToYRow_NEON; 851bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 85295730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (width >= 16) { 85395730719503137a7db61a105bec02220f9ed159efbarchard@google.com ABGRToUVRow = ABGRToUVRow_Any_NEON; 85495730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (IS_ALIGNED(width, 16)) { 85595730719503137a7db61a105bec02220f9ed159efbarchard@google.com ABGRToUVRow = ABGRToUVRow_NEON; 85695730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 85795730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 858bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 859b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#endif 8609394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com 861a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 862b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ABGRToUVRow(src_abgr, src_stride_abgr, dst_u, dst_v, width); 863b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ABGRToYRow(src_abgr, dst_y, width); 864b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ABGRToYRow(src_abgr + src_stride_abgr, dst_y + dst_stride_y, width); 865b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_abgr += src_stride_abgr * 2; 8669394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com dst_y += dst_stride_y * 2; 8679394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com dst_u += dst_stride_u; 8689394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com dst_v += dst_stride_v; 8699394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 8709394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com if (height & 1) { 871c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com ABGRToUVRow(src_abgr, 0, dst_u, dst_v, width); 872c8c8047d434c7c2b86c6ddd8ef9507ff14bfb1f3fbarchard@google.com ABGRToYRow(src_abgr, dst_y, width); 8739394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 8749394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com return 0; 875abe14f80ba16b62a04e94587a983c8bcbc7bb88amikhal@webrtc.org} 876abe14f80ba16b62a04e94587a983c8bcbc7bb88amikhal@webrtc.org 877bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com// Convert RGBA to I420. 878fc7314e86bc7a1a88b38b815e881183521801ea9fbarchard@google.comLIBYUV_API 879d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.comint RGBAToI420(const uint8* src_rgba, int src_stride_rgba, 880d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com uint8* dst_y, int dst_stride_y, 881d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com uint8* dst_u, int dst_stride_u, 882d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com uint8* dst_v, int dst_stride_v, 883d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com int width, int height) { 884a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 885a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RGBAToUVRow)(const uint8* src_rgba0, int src_stride_rgba, 8868798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = RGBAToUVRow_C; 887a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RGBAToYRow)(const uint8* src_rgba, uint8* dst_y, int pix) = 888a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com RGBAToYRow_C; 889d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com if (!src_rgba || 890d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com !dst_y || !dst_u || !dst_v || 891d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com width <= 0 || height == 0) { 892d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com return -1; 893d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com } 894d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com // Negative height means invert the image. 895d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com if (height < 0) { 896d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com height = -height; 897d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com src_rgba = src_rgba + (height - 1) * src_stride_rgba; 898d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com src_stride_rgba = -src_stride_rgba; 899d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com } 900d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com#if defined(HAS_RGBATOYROW_SSSE3) 901bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 902bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGBAToUVRow = RGBAToUVRow_Any_SSSE3; 903bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGBAToYRow = RGBAToYRow_Any_SSSE3; 904d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com if (IS_ALIGNED(width, 16)) { 905d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com RGBAToUVRow = RGBAToUVRow_Unaligned_SSSE3; 906d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com RGBAToYRow = RGBAToYRow_Unaligned_SSSE3; 907d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com if (IS_ALIGNED(src_rgba, 16) && IS_ALIGNED(src_stride_rgba, 16)) { 908d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com RGBAToUVRow = RGBAToUVRow_SSSE3; 909d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 910d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com RGBAToYRow = RGBAToYRow_SSSE3; 911d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com } 912d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com } 913d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com } 914d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com } 915bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#elif defined(HAS_RGBATOYROW_NEON) 916bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 917bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGBAToYRow = RGBAToYRow_Any_NEON; 918bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 8)) { 919bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGBAToYRow = RGBAToYRow_NEON; 920bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 92195730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (width >= 16) { 92295730719503137a7db61a105bec02220f9ed159efbarchard@google.com RGBAToUVRow = RGBAToUVRow_Any_NEON; 92395730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (IS_ALIGNED(width, 16)) { 92495730719503137a7db61a105bec02220f9ed159efbarchard@google.com RGBAToUVRow = RGBAToUVRow_NEON; 92595730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 92695730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 927bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 928d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com#endif 929d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com 930a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 931d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com RGBAToUVRow(src_rgba, src_stride_rgba, dst_u, dst_v, width); 932d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com RGBAToYRow(src_rgba, dst_y, width); 933d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com RGBAToYRow(src_rgba + src_stride_rgba, dst_y + dst_stride_y, width); 934d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com src_rgba += src_stride_rgba * 2; 935d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com dst_y += dst_stride_y * 2; 936d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com dst_u += dst_stride_u; 937d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com dst_v += dst_stride_v; 938d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com } 939d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com if (height & 1) { 940d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com RGBAToUVRow(src_rgba, 0, dst_u, dst_v, width); 941d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com RGBAToYRow(src_rgba, dst_y, width); 942d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com } 943d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com return 0; 944d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com} 945d5a27f0533d42bd0e241b0a7887abe1a3d9c0633fbarchard@google.com 946bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com// Convert RGB24 to I420. 947d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.comLIBYUV_API 948b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.comint RGB24ToI420(const uint8* src_rgb24, int src_stride_rgb24, 949585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com uint8* dst_y, int dst_stride_y, 950585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com uint8* dst_u, int dst_stride_u, 951585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com uint8* dst_v, int dst_stride_v, 952585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com int width, int height) { 953a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 954a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#if defined(HAS_RGB24TOYROW_NEON) 955a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RGB24ToUVRow)(const uint8* src_rgb24, int src_stride_rgb24, 956a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = RGB24ToUVRow_C; 957a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RGB24ToYRow)(const uint8* src_rgb24, uint8* dst_y, int pix) = 958a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com RGB24ToYRow_C; 959a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#else 960a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 961a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com RGB24ToARGBRow_C; 962a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 9638798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 964a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 965a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ARGBToYRow_C; 966a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com // Allocate 2 rows of ARGB. 967a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com const int kRowSize = (width * 4 + 15) & ~15; 968a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com align_buffer_64(row, kRowSize * 2); 969a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#endif 970bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (!src_rgb24 || !dst_y || !dst_u || !dst_v || 971d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com width <= 0 || height == 0) { 972b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com return -1; 973b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 97425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 9759394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com if (height < 0) { 9769394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com height = -height; 977b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24; 978b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_stride_rgb24 = -src_stride_rgb24; 9799394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 98095730719503137a7db61a105bec02220f9ed159efbarchard@google.com 98195730719503137a7db61a105bec02220f9ed159efbarchard@google.com#if defined(HAS_RGB24TOYROW_NEON) 98295730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 98395730719503137a7db61a105bec02220f9ed159efbarchard@google.com RGB24ToYRow = RGB24ToYRow_Any_NEON; 98495730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (IS_ALIGNED(width, 8)) { 98595730719503137a7db61a105bec02220f9ed159efbarchard@google.com RGB24ToYRow = RGB24ToYRow_NEON; 98695730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 98795730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (width >= 16) { 98895730719503137a7db61a105bec02220f9ed159efbarchard@google.com RGB24ToUVRow = RGB24ToUVRow_Any_NEON; 98995730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (IS_ALIGNED(width, 16)) { 99095730719503137a7db61a105bec02220f9ed159efbarchard@google.com RGB24ToUVRow = RGB24ToUVRow_NEON; 99195730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 99295730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 99395730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 99495730719503137a7db61a105bec02220f9ed159efbarchard@google.com#else // HAS_RGB24TOYROW_NEON 995d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com 996ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com#if defined(HAS_RGB24TOARGBROW_SSSE3) 997bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 998bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3; 999bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 16)) { 1000bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB24ToARGBRow = RGB24ToARGBRow_SSSE3; 1001bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1002bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1003b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#endif 1004bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_ARGBTOUVROW_SSSE3) 1005bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1006bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 1007bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 16)) { 1008bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToUVRow = ARGBToUVRow_SSSE3; 1009bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1010bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1011bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif 1012bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_ARGBTOUVROW_SSSE3) 1013bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1014e5f3fd4cc870b9b22112b3b2f25af06e067c8b7dfbarchard@google.com ARGBToYRow = ARGBToYRow_Any_SSSE3; 1015b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com if (IS_ALIGNED(width, 16)) { 1016b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 1017b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 1018b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToYRow = ARGBToYRow_SSSE3; 1019b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 1020b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com } 10219394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 1022bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif // HAS_ARGBTOUVROW_SSSE3 1023bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif // HAS_RGB24TOYROW_NEON 1024aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 1025a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 1026bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_RGB24TOYROW_NEON) 102795730719503137a7db61a105bec02220f9ed159efbarchard@google.com RGB24ToUVRow(src_rgb24, src_stride_rgb24, dst_u, dst_v, width); 1028bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB24ToYRow(src_rgb24, dst_y, width); 1029bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB24ToYRow(src_rgb24 + src_stride_rgb24, dst_y + dst_stride_y, width); 1030bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#else 103195730719503137a7db61a105bec02220f9ed159efbarchard@google.com RGB24ToARGBRow(src_rgb24, row, width); 1032d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com RGB24ToARGBRow(src_rgb24 + src_stride_rgb24, row + kRowSize, width); 1033d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); 1034ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com ARGBToYRow(row, dst_y, width); 1035d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); 1036bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif 1037b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_rgb24 += src_stride_rgb24 * 2; 10389394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com dst_y += dst_stride_y * 2; 10399394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com dst_u += dst_stride_u; 10409394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com dst_v += dst_stride_v; 10419394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 10429394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com if (height & 1) { 1043bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_RGB24TOYROW_NEON) 104495730719503137a7db61a105bec02220f9ed159efbarchard@google.com RGB24ToUVRow(src_rgb24, 0, dst_u, dst_v, width); 1045bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB24ToYRow(src_rgb24, dst_y, width); 1046bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#else 104795730719503137a7db61a105bec02220f9ed159efbarchard@google.com RGB24ToARGBRow(src_rgb24, row, width); 104895730719503137a7db61a105bec02220f9ed159efbarchard@google.com ARGBToUVRow(row, 0, dst_u, dst_v, width); 1049ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com ARGBToYRow(row, dst_y, width); 1050bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif 10519394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com } 1052d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com#if !defined(HAS_RGB24TOYROW_NEON) 1053d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com free_aligned_buffer_64(row); 1054d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com#endif 10559394ed99fcc9802a068ba4a44c36aed79ce87157fbarchard@google.com return 0; 1056585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com} 1057585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com 1058bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com// Convert RAW to I420. 1059d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.comLIBYUV_API 1060b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.comint RAWToI420(const uint8* src_raw, int src_stride_raw, 10611c5136d0699d8705971d765902ae692759f15d21fbarchard@google.com uint8* dst_y, int dst_stride_y, 10621c5136d0699d8705971d765902ae692759f15d21fbarchard@google.com uint8* dst_u, int dst_stride_u, 10631c5136d0699d8705971d765902ae692759f15d21fbarchard@google.com uint8* dst_v, int dst_stride_v, 10641c5136d0699d8705971d765902ae692759f15d21fbarchard@google.com int width, int height) { 1065a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 1066a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#if defined(HAS_RAWTOYROW_NEON) 1067a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RAWToUVRow)(const uint8* src_raw, int src_stride_raw, 1068a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = RAWToUVRow_C; 1069a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RAWToYRow)(const uint8* src_raw, uint8* dst_y, int pix) = 1070a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com RAWToYRow_C; 1071a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#else 1072a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 1073a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com RAWToARGBRow_C; 1074a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 10758798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 1076a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 1077a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ARGBToYRow_C; 1078a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com // Allocate 2 rows of ARGB. 1079a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com const int kRowSize = (width * 4 + 15) & ~15; 1080a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com align_buffer_64(row, kRowSize * 2); 1081a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#endif 1082bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (!src_raw || !dst_y || !dst_u || !dst_v || 1083d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com width <= 0 || height == 0) { 1084b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com return -1; 1085b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 108625ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 1087585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com if (height < 0) { 1088585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com height = -height; 1089b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_raw = src_raw + (height - 1) * src_stride_raw; 1090b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_stride_raw = -src_stride_raw; 1091585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com } 109295730719503137a7db61a105bec02220f9ed159efbarchard@google.com 109395730719503137a7db61a105bec02220f9ed159efbarchard@google.com#if defined(HAS_RAWTOYROW_NEON) 109495730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 109595730719503137a7db61a105bec02220f9ed159efbarchard@google.com RAWToYRow = RAWToYRow_Any_NEON; 109695730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (IS_ALIGNED(width, 8)) { 109795730719503137a7db61a105bec02220f9ed159efbarchard@google.com RAWToYRow = RAWToYRow_NEON; 109895730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 109995730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (width >= 16) { 110095730719503137a7db61a105bec02220f9ed159efbarchard@google.com RAWToUVRow = RAWToUVRow_Any_NEON; 110195730719503137a7db61a105bec02220f9ed159efbarchard@google.com if (IS_ALIGNED(width, 16)) { 110295730719503137a7db61a105bec02220f9ed159efbarchard@google.com RAWToUVRow = RAWToUVRow_NEON; 110395730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 110495730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 110595730719503137a7db61a105bec02220f9ed159efbarchard@google.com } 110695730719503137a7db61a105bec02220f9ed159efbarchard@google.com#else // HAS_RAWTOYROW_NEON 1107d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com 1108ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com#if defined(HAS_RAWTOARGBROW_SSSE3) 1109bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1110bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RAWToARGBRow = RAWToARGBRow_Any_SSSE3; 1111bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 16)) { 1112bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RAWToARGBRow = RAWToARGBRow_SSSE3; 1113bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1114bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1115b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#endif 1116bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_ARGBTOUVROW_SSSE3) 1117bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1118bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 1119bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 16)) { 1120bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToUVRow = ARGBToUVRow_SSSE3; 1121bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1122bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1123bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif 1124bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_ARGBTOUVROW_SSSE3) 1125bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1126e5f3fd4cc870b9b22112b3b2f25af06e067c8b7dfbarchard@google.com ARGBToYRow = ARGBToYRow_Any_SSSE3; 1127b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com if (IS_ALIGNED(width, 16)) { 1128b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 1129b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 1130b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToYRow = ARGBToYRow_SSSE3; 1131b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 1132b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com } 1133585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com } 1134bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif // HAS_ARGBTOUVROW_SSSE3 1135bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif // HAS_RAWTOYROW_NEON 1136585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com 1137a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 1138bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_RAWTOYROW_NEON) 113995730719503137a7db61a105bec02220f9ed159efbarchard@google.com RAWToUVRow(src_raw, src_stride_raw, dst_u, dst_v, width); 1140bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RAWToYRow(src_raw, dst_y, width); 1141bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RAWToYRow(src_raw + src_stride_raw, dst_y + dst_stride_y, width); 1142bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#else 114395730719503137a7db61a105bec02220f9ed159efbarchard@google.com RAWToARGBRow(src_raw, row, width); 1144d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com RAWToARGBRow(src_raw + src_stride_raw, row + kRowSize, width); 1145d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); 1146ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com ARGBToYRow(row, dst_y, width); 1147d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); 1148bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif 1149b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_raw += src_stride_raw * 2; 1150585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com dst_y += dst_stride_y * 2; 1151585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com dst_u += dst_stride_u; 1152585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com dst_v += dst_stride_v; 1153585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com } 1154585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com if (height & 1) { 1155bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_RAWTOYROW_NEON) 115695730719503137a7db61a105bec02220f9ed159efbarchard@google.com RAWToUVRow(src_raw, 0, dst_u, dst_v, width); 1157bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RAWToYRow(src_raw, dst_y, width); 1158bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#else 115995730719503137a7db61a105bec02220f9ed159efbarchard@google.com RAWToARGBRow(src_raw, row, width); 116095730719503137a7db61a105bec02220f9ed159efbarchard@google.com ARGBToUVRow(row, 0, dst_u, dst_v, width); 1161ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com ARGBToYRow(row, dst_y, width); 1162bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif 1163585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com } 1164d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com#if !defined(HAS_RAWTOYROW_NEON) 1165d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com free_aligned_buffer_64(row); 1166d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com#endif 1167585a126140be298e60a4daa26140ead0e94eaaa1fbarchard@google.com return 0; 1168aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org} 1169aed1cc94c105736a5e6010e9c84cc32910b865d6mikhal@webrtc.org 1170bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com// Convert RGB565 to I420. 1171d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.comLIBYUV_API 1172b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.comint RGB565ToI420(const uint8* src_rgb565, int src_stride_rgb565, 1173a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com uint8* dst_y, int dst_stride_y, 1174a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com uint8* dst_u, int dst_stride_u, 1175a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com uint8* dst_v, int dst_stride_v, 1176a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int width, int height) { 1177a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 1178a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#if defined(HAS_RGB565TOYROW_NEON) 1179a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RGB565ToUVRow)(const uint8* src_rgb565, int src_stride_rgb565, 1180a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = RGB565ToUVRow_C; 1181a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RGB565ToYRow)(const uint8* src_rgb565, uint8* dst_y, int pix) = 1182a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com RGB565ToYRow_C; 1183a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#else 1184a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*RGB565ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 1185a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com RGB565ToARGBRow_C; 1186a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 11878798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 1188a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 1189a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ARGBToYRow_C; 1190a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com // Allocate 2 rows of ARGB. 1191a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com const int kRowSize = (width * 4 + 15) & ~15; 1192a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com align_buffer_64(row, kRowSize * 2); 1193a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#endif 1194bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (!src_rgb565 || !dst_y || !dst_u || !dst_v || 1195d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com width <= 0 || height == 0) { 1196b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com return -1; 1197b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 119825ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 1199a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com if (height < 0) { 1200a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com height = -height; 1201b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565; 1202b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_stride_rgb565 = -src_stride_rgb565; 1203a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 1204f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com 1205f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com#if defined(HAS_RGB565TOYROW_NEON) 1206f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 1207f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com RGB565ToYRow = RGB565ToYRow_Any_NEON; 1208f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com if (IS_ALIGNED(width, 8)) { 1209f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com RGB565ToYRow = RGB565ToYRow_NEON; 1210f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com } 1211f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com if (width >= 16) { 1212f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com RGB565ToUVRow = RGB565ToUVRow_Any_NEON; 1213f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com if (IS_ALIGNED(width, 16)) { 1214f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com RGB565ToUVRow = RGB565ToUVRow_NEON; 1215f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com } 1216f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com } 1217f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com } 1218f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com#else // HAS_RGB565TOYROW_NEON 1219d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com 1220ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com#if defined(HAS_RGB565TOARGBROW_SSE2) 1221bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 8) { 1222bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB565ToARGBRow = RGB565ToARGBRow_Any_SSE2; 1223bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 8)) { 1224bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB565ToARGBRow = RGB565ToARGBRow_SSE2; 1225bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1226bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1227b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#endif 1228bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_ARGBTOUVROW_SSSE3) 1229bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1230bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 1231bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (IS_ALIGNED(width, 16)) { 1232bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToUVRow = ARGBToUVRow_SSSE3; 1233bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1234bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com } 1235bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif 1236bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_ARGBTOUVROW_SSSE3) 1237bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1238e5f3fd4cc870b9b22112b3b2f25af06e067c8b7dfbarchard@google.com ARGBToYRow = ARGBToYRow_Any_SSSE3; 1239b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com if (IS_ALIGNED(width, 16)) { 1240b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 1241b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 1242b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToYRow = ARGBToYRow_SSSE3; 1243b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 1244b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com } 1245a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 1246bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif // HAS_ARGBTOUVROW_SSSE3 1247bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif // HAS_RGB565TOYROW_NEON 1248a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com 1249a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 1250bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_RGB565TOYROW_NEON) 1251f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com RGB565ToUVRow(src_rgb565, src_stride_rgb565, dst_u, dst_v, width); 1252bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB565ToYRow(src_rgb565, dst_y, width); 1253bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB565ToYRow(src_rgb565 + src_stride_rgb565, dst_y + dst_stride_y, width); 1254bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#else 1255f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com RGB565ToARGBRow(src_rgb565, row, width); 1256d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com RGB565ToARGBRow(src_rgb565 + src_stride_rgb565, row + kRowSize, width); 1257d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); 1258ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com ARGBToYRow(row, dst_y, width); 1259d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); 1260bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif 1261b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_rgb565 += src_stride_rgb565 * 2; 1262a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com dst_y += dst_stride_y * 2; 1263a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com dst_u += dst_stride_u; 1264a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com dst_v += dst_stride_v; 1265a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 1266a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com if (height & 1) { 1267bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#if defined(HAS_RGB565TOYROW_NEON) 1268f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com RGB565ToUVRow(src_rgb565, 0, dst_u, dst_v, width); 1269bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com RGB565ToYRow(src_rgb565, dst_y, width); 1270bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#else 1271f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com RGB565ToARGBRow(src_rgb565, row, width); 1272f1daa3db65a41d5d0766c8309ce5a2ef43bf8bb1fbarchard@google.com ARGBToUVRow(row, 0, dst_u, dst_v, width); 1273ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com ARGBToYRow(row, dst_y, width); 1274bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com#endif 1275a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 1276d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com#if !defined(HAS_RGB565TOYROW_NEON) 1277d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com free_aligned_buffer_64(row); 1278d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com#endif 1279a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com return 0; 1280a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com} 1281a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com 12821dee6250936424ced8722329369da75935d61580fbarchard@google.com// Convert ARGB1555 to I420. 1283d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.comLIBYUV_API 1284b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.comint ARGB1555ToI420(const uint8* src_argb1555, int src_stride_argb1555, 12858798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_y, int dst_stride_y, 12868798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, int dst_stride_u, 12878798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_v, int dst_stride_v, 12888798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int width, int height) { 1289a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 1290a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#if defined(HAS_ARGB1555TOYROW_NEON) 1291a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGB1555ToUVRow)(const uint8* src_argb1555, int src_stride_argb1555, 1292a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = ARGB1555ToUVRow_C; 1293a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGB1555ToYRow)(const uint8* src_argb1555, uint8* dst_y, int pix) = 1294a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ARGB1555ToYRow_C; 1295a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#else 1296a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGB1555ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 1297a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ARGB1555ToARGBRow_C; 1298a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 12998798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 1300a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 1301a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ARGBToYRow_C; 1302a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com // Allocate 2 rows of ARGB. 1303a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com const int kRowSize = (width * 4 + 15) & ~15; 1304a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com align_buffer_64(row, kRowSize * 2); 1305a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#endif 1306bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (!src_argb1555 || !dst_y || !dst_u || !dst_v || 1307d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com width <= 0 || height == 0) { 1308b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com return -1; 1309b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 131025ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 1311a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com if (height < 0) { 1312a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com height = -height; 1313b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555; 1314b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_stride_argb1555 = -src_stride_argb1555; 1315a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 1316522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com 1317522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com#if defined(HAS_ARGB1555TOYROW_NEON) 1318522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 1319522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB1555ToYRow = ARGB1555ToYRow_Any_NEON; 1320522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com if (IS_ALIGNED(width, 8)) { 1321522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB1555ToYRow = ARGB1555ToYRow_NEON; 1322522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com } 1323522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com if (width >= 16) { 1324522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB1555ToUVRow = ARGB1555ToUVRow_Any_NEON; 1325522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com if (IS_ALIGNED(width, 16)) { 1326522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB1555ToUVRow = ARGB1555ToUVRow_NEON; 1327522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com } 1328522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com } 1329522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com } 1330522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com#else // HAS_ARGB1555TOYROW_NEON 1331d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com 1332ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com#if defined(HAS_ARGB1555TOARGBROW_SSE2) 13331dee6250936424ced8722329369da75935d61580fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 8) { 13341dee6250936424ced8722329369da75935d61580fbarchard@google.com ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_SSE2; 13351dee6250936424ced8722329369da75935d61580fbarchard@google.com if (IS_ALIGNED(width, 8)) { 13361dee6250936424ced8722329369da75935d61580fbarchard@google.com ARGB1555ToARGBRow = ARGB1555ToARGBRow_SSE2; 13371dee6250936424ced8722329369da75935d61580fbarchard@google.com } 13381dee6250936424ced8722329369da75935d61580fbarchard@google.com } 1339b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#endif 13401dee6250936424ced8722329369da75935d61580fbarchard@google.com#if defined(HAS_ARGBTOUVROW_SSSE3) 1341bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1342bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 1343b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com if (IS_ALIGNED(width, 16)) { 1344b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToUVRow = ARGBToUVRow_SSSE3; 13451dee6250936424ced8722329369da75935d61580fbarchard@google.com } 13461dee6250936424ced8722329369da75935d61580fbarchard@google.com } 13471dee6250936424ced8722329369da75935d61580fbarchard@google.com#endif 13481dee6250936424ced8722329369da75935d61580fbarchard@google.com#if defined(HAS_ARGBTOUVROW_SSSE3) 13491dee6250936424ced8722329369da75935d61580fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 13501dee6250936424ced8722329369da75935d61580fbarchard@google.com ARGBToYRow = ARGBToYRow_Any_SSSE3; 13511dee6250936424ced8722329369da75935d61580fbarchard@google.com if (IS_ALIGNED(width, 16)) { 1352b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 1353b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 1354b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToYRow = ARGBToYRow_SSSE3; 1355b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 1356b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com } 1357a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 13581dee6250936424ced8722329369da75935d61580fbarchard@google.com#endif // HAS_ARGBTOUVROW_SSSE3 13591dee6250936424ced8722329369da75935d61580fbarchard@google.com#endif // HAS_ARGB1555TOYROW_NEON 1360a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com 1361a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 13621dee6250936424ced8722329369da75935d61580fbarchard@google.com#if defined(HAS_ARGB1555TOYROW_NEON) 1363522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB1555ToUVRow(src_argb1555, src_stride_argb1555, dst_u, dst_v, width); 13641dee6250936424ced8722329369da75935d61580fbarchard@google.com ARGB1555ToYRow(src_argb1555, dst_y, width); 136595730719503137a7db61a105bec02220f9ed159efbarchard@google.com ARGB1555ToYRow(src_argb1555 + src_stride_argb1555, dst_y + dst_stride_y, 136695730719503137a7db61a105bec02220f9ed159efbarchard@google.com width); 13671dee6250936424ced8722329369da75935d61580fbarchard@google.com#else 1368522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB1555ToARGBRow(src_argb1555, row, width); 1369d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGB1555ToARGBRow(src_argb1555 + src_stride_argb1555, row + kRowSize, 137095730719503137a7db61a105bec02220f9ed159efbarchard@google.com width); 1371d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); 1372ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com ARGBToYRow(row, dst_y, width); 1373d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); 13741dee6250936424ced8722329369da75935d61580fbarchard@google.com#endif 1375b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_argb1555 += src_stride_argb1555 * 2; 1376a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com dst_y += dst_stride_y * 2; 1377a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com dst_u += dst_stride_u; 1378a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com dst_v += dst_stride_v; 1379a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 1380a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com if (height & 1) { 13811dee6250936424ced8722329369da75935d61580fbarchard@google.com#if defined(HAS_ARGB1555TOYROW_NEON) 1382522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB1555ToUVRow(src_argb1555, 0, dst_u, dst_v, width); 13831dee6250936424ced8722329369da75935d61580fbarchard@google.com ARGB1555ToYRow(src_argb1555, dst_y, width); 13841dee6250936424ced8722329369da75935d61580fbarchard@google.com#else 1385522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB1555ToARGBRow(src_argb1555, row, width); 1386522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGBToUVRow(row, 0, dst_u, dst_v, width); 1387ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com ARGBToYRow(row, dst_y, width); 13881dee6250936424ced8722329369da75935d61580fbarchard@google.com#endif 1389a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 1390d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com#if !defined(HAS_ARGB1555TOYROW_NEON) 1391d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com free_aligned_buffer_64(row); 1392d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com#endif 1393a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com return 0; 1394a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com} 1395a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com 13961dee6250936424ced8722329369da75935d61580fbarchard@google.com// Convert ARGB4444 to I420. 1397d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.comLIBYUV_API 1398b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.comint ARGB4444ToI420(const uint8* src_argb4444, int src_stride_argb4444, 13998798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_y, int dst_stride_y, 14008798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, int dst_stride_u, 14018798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_v, int dst_stride_v, 14028798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com int width, int height) { 1403a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com int y; 1404a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#if defined(HAS_ARGB4444TOYROW_NEON) 1405a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGB4444ToUVRow)(const uint8* src_argb4444, int src_stride_argb4444, 1406a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = ARGB4444ToUVRow_C; 1407a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGB4444ToYRow)(const uint8* src_argb4444, uint8* dst_y, int pix) = 1408a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ARGB4444ToYRow_C; 1409a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#else 1410a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGB4444ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) = 1411a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ARGB4444ToARGBRow_C; 1412a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToUVRow)(const uint8* src_argb0, int src_stride_argb, 14138798e040758f2cd8f61342a3690446d72070bfb1fbarchard@google.com uint8* dst_u, uint8* dst_v, int width) = ARGBToUVRow_C; 1414a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com void (*ARGBToYRow)(const uint8* src_argb, uint8* dst_y, int pix) = 1415a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com ARGBToYRow_C; 1416a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com // Allocate 2 rows of ARGB. 1417a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com const int kRowSize = (width * 4 + 15) & ~15; 1418a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com align_buffer_64(row, kRowSize * 2); 1419a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com#endif 1420bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (!src_argb4444 || !dst_y || !dst_u || !dst_v || 1421d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com width <= 0 || height == 0) { 1422b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com return -1; 1423b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 142425ba0211486c7fccd3d5bd024ee1ccece4f56a1bmikhal@webrtc.org // Negative height means invert the image. 1425a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com if (height < 0) { 1426a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com height = -height; 1427b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444; 1428b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_stride_argb4444 = -src_stride_argb4444; 1429a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 1430522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com 1431522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com#if defined(HAS_ARGB4444TOYROW_NEON) 1432522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com if (TestCpuFlag(kCpuHasNEON) && width >= 8) { 1433522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB4444ToYRow = ARGB4444ToYRow_Any_NEON; 1434522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com if (IS_ALIGNED(width, 8)) { 1435522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB4444ToYRow = ARGB4444ToYRow_NEON; 1436522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com } 1437522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com if (width >= 16) { 1438522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB4444ToUVRow = ARGB4444ToUVRow_Any_NEON; 1439522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com if (IS_ALIGNED(width, 16)) { 1440522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB4444ToUVRow = ARGB4444ToUVRow_NEON; 1441522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com } 1442522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com } 1443522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com } 1444522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com#else // HAS_ARGB4444TOYROW_NEON 1445d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com 1446ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com#if defined(HAS_ARGB4444TOARGBROW_SSE2) 14471dee6250936424ced8722329369da75935d61580fbarchard@google.com if (TestCpuFlag(kCpuHasSSE2) && width >= 8) { 14481dee6250936424ced8722329369da75935d61580fbarchard@google.com ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_SSE2; 14491dee6250936424ced8722329369da75935d61580fbarchard@google.com if (IS_ALIGNED(width, 8)) { 14501dee6250936424ced8722329369da75935d61580fbarchard@google.com ARGB4444ToARGBRow = ARGB4444ToARGBRow_SSE2; 14511dee6250936424ced8722329369da75935d61580fbarchard@google.com } 14521dee6250936424ced8722329369da75935d61580fbarchard@google.com } 1453b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com#endif 14541dee6250936424ced8722329369da75935d61580fbarchard@google.com#if defined(HAS_ARGBTOUVROW_SSSE3) 1455bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 1456bdf7cb591452611090922e690d5104a7d8c6b1e5fbarchard@google.com ARGBToUVRow = ARGBToUVRow_Any_SSSE3; 1457b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com if (IS_ALIGNED(width, 16)) { 1458b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToUVRow = ARGBToUVRow_SSSE3; 14591dee6250936424ced8722329369da75935d61580fbarchard@google.com } 14601dee6250936424ced8722329369da75935d61580fbarchard@google.com } 14611dee6250936424ced8722329369da75935d61580fbarchard@google.com#endif 14621dee6250936424ced8722329369da75935d61580fbarchard@google.com#if defined(HAS_ARGBTOUVROW_SSSE3) 14631dee6250936424ced8722329369da75935d61580fbarchard@google.com if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) { 14641dee6250936424ced8722329369da75935d61580fbarchard@google.com ARGBToYRow = ARGBToYRow_Any_SSSE3; 14651dee6250936424ced8722329369da75935d61580fbarchard@google.com if (IS_ALIGNED(width, 16)) { 1466b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com ARGBToYRow = ARGBToYRow_Unaligned_SSSE3; 1467b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com if (IS_ALIGNED(dst_y, 16) && IS_ALIGNED(dst_stride_y, 16)) { 1468b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com ARGBToYRow = ARGBToYRow_SSSE3; 1469b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com } 1470b1dd02d66cbda3e0c571bf81c247f850cdb3e2fdfbarchard@google.com } 1471a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 14721dee6250936424ced8722329369da75935d61580fbarchard@google.com#endif // HAS_ARGBTOUVROW_SSSE3 14731dee6250936424ced8722329369da75935d61580fbarchard@google.com#endif // HAS_ARGB4444TOYROW_NEON 1474a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com 1475a2fbf9dee675e2334f824fa908b2c946fe18382bfbarchard@google.com for (y = 0; y < height - 1; y += 2) { 14761dee6250936424ced8722329369da75935d61580fbarchard@google.com#if defined(HAS_ARGB4444TOYROW_NEON) 1477522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB4444ToUVRow(src_argb4444, src_stride_argb4444, dst_u, dst_v, width); 14781dee6250936424ced8722329369da75935d61580fbarchard@google.com ARGB4444ToYRow(src_argb4444, dst_y, width); 1479522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB4444ToYRow(src_argb4444 + src_stride_argb4444, dst_y + dst_stride_y, 1480522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com width); 14811dee6250936424ced8722329369da75935d61580fbarchard@google.com#else 1482522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB4444ToARGBRow(src_argb4444, row, width); 1483d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGB4444ToARGBRow(src_argb4444 + src_stride_argb4444, row + kRowSize, 1484522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com width); 1485d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGBToUVRow(row, kRowSize, dst_u, dst_v, width); 1486ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com ARGBToYRow(row, dst_y, width); 1487d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com ARGBToYRow(row + kRowSize, dst_y + dst_stride_y, width); 14881dee6250936424ced8722329369da75935d61580fbarchard@google.com#endif 1489b95dbf24951d8b7118f680d75c7456a5f5d57bfffbarchard@google.com src_argb4444 += src_stride_argb4444 * 2; 1490a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com dst_y += dst_stride_y * 2; 1491a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com dst_u += dst_stride_u; 1492a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com dst_v += dst_stride_v; 1493a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 1494a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com if (height & 1) { 14951dee6250936424ced8722329369da75935d61580fbarchard@google.com#if defined(HAS_ARGB4444TOYROW_NEON) 1496522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB4444ToUVRow(src_argb4444, 0, dst_u, dst_v, width); 14971dee6250936424ced8722329369da75935d61580fbarchard@google.com ARGB4444ToYRow(src_argb4444, dst_y, width); 14981dee6250936424ced8722329369da75935d61580fbarchard@google.com#else 1499522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGB4444ToARGBRow(src_argb4444, row, width); 1500522d757c9257056020f058acc5a7c63e401ce019fbarchard@google.com ARGBToUVRow(row, 0, dst_u, dst_v, width); 1501ba1f52692605bbf8fedb8a915275c71fa186d291fbarchard@google.com ARGBToYRow(row, dst_y, width); 15021dee6250936424ced8722329369da75935d61580fbarchard@google.com#endif 1503a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com } 1504d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com#if !defined(HAS_ARGB4444TOYROW_NEON) 1505d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com free_aligned_buffer_64(row); 1506d9c9f37ac482ac958519e02db8b7c5b47bf1816afbarchard@google.com#endif 1507a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com return 0; 1508a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com} 1509a7d977ceae6215332f359ab289a93460a24dc1e0fbarchard@google.com 1510fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com#ifdef __cplusplus 1511fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com} // extern "C" 1512fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com} // namespace libyuv 1513fe5ff7ed5451496281697bda9cb85084c532926cfbarchard@google.com#endif 1514