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

Side by Side Diff: media/base/simd/convert_yuv_to_rgb_c.cc

Issue 591313008: Add support for Rec709 color space videos in software YUV convert path. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix matrix error Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/simd/convert_yuv_to_rgb.h" 5 #include "media/base/simd/convert_yuv_to_rgb.h"
6 #include "media/base/simd/yuv_to_rgb_table.h"
7 6
8 namespace media { 7 namespace media {
9 8
10 #define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x))) 9 #define packuswb(x) ((x) < 0 ? 0 : ((x) > 255 ? 255 : (x)))
11 #define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \ 10 #define paddsw(x, y) (((x) + (y)) < -32768 ? -32768 : \
12 (((x) + (y)) > 32767 ? 32767 : ((x) + (y)))) 11 (((x) + (y)) > 32767 ? 32767 : ((x) + (y))))
13 12
14 // On Android, pixel layout is RGBA (see skia/include/core/SkColorPriv.h); 13 // On Android, pixel layout is RGBA (see skia/include/core/SkColorPriv.h);
15 // however, other Chrome platforms use BGRA (see skia/config/SkUserConfig.h). 14 // however, other Chrome platforms use BGRA (see skia/config/SkUserConfig.h).
16 // Ideally, android should not use the functions here due to performance issue 15 // Ideally, android should not use the functions here due to performance issue
(...skipping 15 matching lines...) Expand all
32 #define B_INDEX 0 31 #define B_INDEX 0
33 #define G_INDEX 1 32 #define G_INDEX 1
34 #define R_INDEX 2 33 #define R_INDEX 2
35 #define A_INDEX 3 34 #define A_INDEX 3
36 #endif 35 #endif
37 36
38 static inline void ConvertYUVToRGB32_C(uint8 y, 37 static inline void ConvertYUVToRGB32_C(uint8 y,
39 uint8 u, 38 uint8 u,
40 uint8 v, 39 uint8 v,
41 uint8* rgb_buf, 40 uint8* rgb_buf,
42 const int16 convert_table[1024][4]) { 41 const int16* convert_table) {
43 int b = convert_table[256+u][B_INDEX]; 42 int b = convert_table[4 * (256 + u) + B_INDEX];
44 int g = convert_table[256+u][G_INDEX]; 43 int g = convert_table[4 * (256 + u) + G_INDEX];
45 int r = convert_table[256+u][R_INDEX]; 44 int r = convert_table[4 * (256 + u) + R_INDEX];
46 int a = convert_table[256+u][A_INDEX]; 45 int a = convert_table[4 * (256 + u) + A_INDEX];
47 46
48 b = paddsw(b, convert_table[512+v][B_INDEX]); 47 b = paddsw(b, convert_table[4 * (512 + v) + B_INDEX]);
49 g = paddsw(g, convert_table[512+v][G_INDEX]); 48 g = paddsw(g, convert_table[4 * (512 + v) + G_INDEX]);
50 r = paddsw(r, convert_table[512+v][R_INDEX]); 49 r = paddsw(r, convert_table[4 * (512 + v) + R_INDEX]);
51 a = paddsw(a, convert_table[512+v][A_INDEX]); 50 a = paddsw(a, convert_table[4 * (512 + v) + A_INDEX]);
52 51
53 b = paddsw(b, convert_table[y][B_INDEX]); 52 b = paddsw(b, convert_table[4 * y + B_INDEX]);
54 g = paddsw(g, convert_table[y][G_INDEX]); 53 g = paddsw(g, convert_table[4 * y + G_INDEX]);
55 r = paddsw(r, convert_table[y][R_INDEX]); 54 r = paddsw(r, convert_table[4 * y + R_INDEX]);
56 a = paddsw(a, convert_table[y][A_INDEX]); 55 a = paddsw(a, convert_table[4 * y + A_INDEX]);
57 56
58 b >>= 6; 57 b >>= 6;
59 g >>= 6; 58 g >>= 6;
60 r >>= 6; 59 r >>= 6;
61 a >>= 6; 60 a >>= 6;
62 61
63 *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b) << SK_B32_SHIFT) | 62 *reinterpret_cast<uint32*>(rgb_buf) = (packuswb(b) << SK_B32_SHIFT) |
64 (packuswb(g) << SK_G32_SHIFT) | 63 (packuswb(g) << SK_G32_SHIFT) |
65 (packuswb(r) << SK_R32_SHIFT) | 64 (packuswb(r) << SK_R32_SHIFT) |
66 (packuswb(a) << SK_A32_SHIFT); 65 (packuswb(a) << SK_A32_SHIFT);
67 } 66 }
68 67
69 static inline void ConvertYUVAToARGB_C(uint8 y, 68 static inline void ConvertYUVAToARGB_C(uint8 y,
70 uint8 u, 69 uint8 u,
71 uint8 v, 70 uint8 v,
72 uint8 a, 71 uint8 a,
73 uint8* rgb_buf, 72 uint8* rgb_buf,
74 const int16 convert_table[1024][4]) { 73 const int16* convert_table) {
75 int b = convert_table[256+u][0]; 74 int b = convert_table[4 * (256 + u) + 0];
76 int g = convert_table[256+u][1]; 75 int g = convert_table[4 * (256 + u) + 1];
77 int r = convert_table[256+u][2]; 76 int r = convert_table[4 * (256 + u) + 2];
78 77
79 b = paddsw(b, convert_table[512+v][0]); 78 b = paddsw(b, convert_table[4 * (512 + v) + 0]);
80 g = paddsw(g, convert_table[512+v][1]); 79 g = paddsw(g, convert_table[4 * (512 + v) + 1]);
81 r = paddsw(r, convert_table[512+v][2]); 80 r = paddsw(r, convert_table[4 * (512 + v) + 2]);
82 81
83 b = paddsw(b, convert_table[y][0]); 82 b = paddsw(b, convert_table[4 * y + 0]);
84 g = paddsw(g, convert_table[y][1]); 83 g = paddsw(g, convert_table[4 * y + 1]);
85 r = paddsw(r, convert_table[y][2]); 84 r = paddsw(r, convert_table[4 * y + 2]);
86 85
87 b >>= 6; 86 b >>= 6;
88 g >>= 6; 87 g >>= 6;
89 r >>= 6; 88 r >>= 6;
90 89
91 b = packuswb(b) * a >> 8; 90 b = packuswb(b) * a >> 8;
92 g = packuswb(g) * a >> 8; 91 g = packuswb(g) * a >> 8;
93 r = packuswb(r) * a >> 8; 92 r = packuswb(r) * a >> 8;
94 93
95 *reinterpret_cast<uint32*>(rgb_buf) = (b << SK_B32_SHIFT) | 94 *reinterpret_cast<uint32*>(rgb_buf) = (b << SK_B32_SHIFT) |
96 (g << SK_G32_SHIFT) | 95 (g << SK_G32_SHIFT) |
97 (r << SK_R32_SHIFT) | 96 (r << SK_R32_SHIFT) |
98 (a << SK_A32_SHIFT); 97 (a << SK_A32_SHIFT);
99 } 98 }
100 99
101 void ConvertYUVToRGB32Row_C(const uint8* y_buf, 100 void ConvertYUVToRGB32Row_C(const uint8* y_buf,
102 const uint8* u_buf, 101 const uint8* u_buf,
103 const uint8* v_buf, 102 const uint8* v_buf,
104 uint8* rgb_buf, 103 uint8* rgb_buf,
105 ptrdiff_t width, 104 ptrdiff_t width,
106 const int16 convert_table[1024][4]) { 105 const int16* convert_table) {
107 for (int x = 0; x < width; x += 2) { 106 for (int x = 0; x < width; x += 2) {
108 uint8 u = u_buf[x >> 1]; 107 uint8 u = u_buf[x >> 1];
109 uint8 v = v_buf[x >> 1]; 108 uint8 v = v_buf[x >> 1];
110 uint8 y0 = y_buf[x]; 109 uint8 y0 = y_buf[x];
111 ConvertYUVToRGB32_C(y0, u, v, rgb_buf, convert_table); 110 ConvertYUVToRGB32_C(y0, u, v, rgb_buf, convert_table);
112 if ((x + 1) < width) { 111 if ((x + 1) < width) {
113 uint8 y1 = y_buf[x + 1]; 112 uint8 y1 = y_buf[x + 1];
114 ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4, convert_table); 113 ConvertYUVToRGB32_C(y1, u, v, rgb_buf + 4, convert_table);
115 } 114 }
116 rgb_buf += 8; // Advance 2 pixels. 115 rgb_buf += 8; // Advance 2 pixels.
117 } 116 }
118 } 117 }
119 118
120 void ConvertYUVAToARGBRow_C(const uint8* y_buf, 119 void ConvertYUVAToARGBRow_C(const uint8* y_buf,
121 const uint8* u_buf, 120 const uint8* u_buf,
122 const uint8* v_buf, 121 const uint8* v_buf,
123 const uint8* a_buf, 122 const uint8* a_buf,
124 uint8* rgba_buf, 123 uint8* rgba_buf,
125 ptrdiff_t width, 124 ptrdiff_t width,
126 const int16 convert_table[1024][4]) { 125 const int16* convert_table) {
127 for (int x = 0; x < width; x += 2) { 126 for (int x = 0; x < width; x += 2) {
128 uint8 u = u_buf[x >> 1]; 127 uint8 u = u_buf[x >> 1];
129 uint8 v = v_buf[x >> 1]; 128 uint8 v = v_buf[x >> 1];
130 uint8 y0 = y_buf[x]; 129 uint8 y0 = y_buf[x];
131 uint8 a0 = a_buf[x]; 130 uint8 a0 = a_buf[x];
132 ConvertYUVAToARGB_C(y0, u, v, a0, rgba_buf, convert_table); 131 ConvertYUVAToARGB_C(y0, u, v, a0, rgba_buf, convert_table);
133 if ((x + 1) < width) { 132 if ((x + 1) < width) {
134 uint8 y1 = y_buf[x + 1]; 133 uint8 y1 = y_buf[x + 1];
135 uint8 a1 = a_buf[x + 1]; 134 uint8 a1 = a_buf[x + 1];
136 ConvertYUVAToARGB_C(y1, u, v, a1, rgba_buf + 4, convert_table); 135 ConvertYUVAToARGB_C(y1, u, v, a1, rgba_buf + 4, convert_table);
137 } 136 }
138 rgba_buf += 8; // Advance 2 pixels. 137 rgba_buf += 8; // Advance 2 pixels.
139 } 138 }
140 } 139 }
141 140
142 // 16.16 fixed point is used. A shift by 16 isolates the integer. 141 // 16.16 fixed point is used. A shift by 16 isolates the integer.
143 // A shift by 17 is used to further subsample the chrominence channels. 142 // A shift by 17 is used to further subsample the chrominence channels.
144 // & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits, 143 // & 0xffff isolates the fixed point fraction. >> 2 to get the upper 2 bits,
145 // for 1/65536 pixel accurate interpolation. 144 // for 1/65536 pixel accurate interpolation.
146 void ScaleYUVToRGB32Row_C(const uint8* y_buf, 145 void ScaleYUVToRGB32Row_C(const uint8* y_buf,
147 const uint8* u_buf, 146 const uint8* u_buf,
148 const uint8* v_buf, 147 const uint8* v_buf,
149 uint8* rgb_buf, 148 uint8* rgb_buf,
150 ptrdiff_t width, 149 ptrdiff_t width,
151 ptrdiff_t source_dx, 150 ptrdiff_t source_dx,
152 const int16 convert_table[1024][4]) { 151 const int16* convert_table) {
153 int x = 0; 152 int x = 0;
154 for (int i = 0; i < width; i += 2) { 153 for (int i = 0; i < width; i += 2) {
155 int y = y_buf[x >> 16]; 154 int y = y_buf[x >> 16];
156 int u = u_buf[(x >> 17)]; 155 int u = u_buf[(x >> 17)];
157 int v = v_buf[(x >> 17)]; 156 int v = v_buf[(x >> 17)];
158 ConvertYUVToRGB32_C(y, u, v, rgb_buf, convert_table); 157 ConvertYUVToRGB32_C(y, u, v, rgb_buf, convert_table);
159 x += source_dx; 158 x += source_dx;
160 if ((i + 1) < width) { 159 if ((i + 1) < width) {
161 y = y_buf[x >> 16]; 160 y = y_buf[x >> 16];
162 ConvertYUVToRGB32_C(y, u, v, rgb_buf+4, convert_table); 161 ConvertYUVToRGB32_C(y, u, v, rgb_buf+4, convert_table);
163 x += source_dx; 162 x += source_dx;
164 } 163 }
165 rgb_buf += 8; 164 rgb_buf += 8;
166 } 165 }
167 } 166 }
168 167
169 void LinearScaleYUVToRGB32Row_C(const uint8* y_buf, 168 void LinearScaleYUVToRGB32Row_C(const uint8* y_buf,
170 const uint8* u_buf, 169 const uint8* u_buf,
171 const uint8* v_buf, 170 const uint8* v_buf,
172 uint8* rgb_buf, 171 uint8* rgb_buf,
173 ptrdiff_t width, 172 ptrdiff_t width,
174 ptrdiff_t source_dx, 173 ptrdiff_t source_dx,
175 const int16 convert_table[1024][4]) { 174 const int16* convert_table) {
176 // Avoid point-sampling for down-scaling by > 2:1. 175 // Avoid point-sampling for down-scaling by > 2:1.
177 int source_x = 0; 176 int source_x = 0;
178 if (source_dx >= 0x20000) 177 if (source_dx >= 0x20000)
179 source_x += 0x8000; 178 source_x += 0x8000;
180 LinearScaleYUVToRGB32RowWithRange_C(y_buf, u_buf, v_buf, rgb_buf, width, 179 LinearScaleYUVToRGB32RowWithRange_C(y_buf, u_buf, v_buf, rgb_buf, width,
181 source_x, source_dx, convert_table); 180 source_x, source_dx, convert_table);
182 } 181 }
183 182
184 void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf, 183 void LinearScaleYUVToRGB32RowWithRange_C(const uint8* y_buf,
185 const uint8* u_buf, 184 const uint8* u_buf,
186 const uint8* v_buf, 185 const uint8* v_buf,
187 uint8* rgb_buf, 186 uint8* rgb_buf,
188 int dest_width, 187 int dest_width,
189 int x, 188 int x,
190 int source_dx, 189 int source_dx,
191 const int16 convert_table[1024][4]) { 190 const int16* convert_table) {
192 for (int i = 0; i < dest_width; i += 2) { 191 for (int i = 0; i < dest_width; i += 2) {
193 int y0 = y_buf[x >> 16]; 192 int y0 = y_buf[x >> 16];
194 int y1 = y_buf[(x >> 16) + 1]; 193 int y1 = y_buf[(x >> 16) + 1];
195 int u0 = u_buf[(x >> 17)]; 194 int u0 = u_buf[(x >> 17)];
196 int u1 = u_buf[(x >> 17) + 1]; 195 int u1 = u_buf[(x >> 17) + 1];
197 int v0 = v_buf[(x >> 17)]; 196 int v0 = v_buf[(x >> 17)];
198 int v1 = v_buf[(x >> 17) + 1]; 197 int v1 = v_buf[(x >> 17) + 1];
199 int y_frac = (x & 65535); 198 int y_frac = (x & 65535);
200 int uv_frac = ((x >> 1) & 65535); 199 int uv_frac = ((x >> 1) & 65535);
201 int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16; 200 int y = (y_frac * y1 + (y_frac ^ 65535) * y0) >> 16;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 u_ptr, 264 u_ptr,
266 v_ptr, 265 v_ptr,
267 a_ptr, 266 a_ptr,
268 rgba_row, 267 rgba_row,
269 width, 268 width,
270 GetLookupTable(yuv_type)); 269 GetLookupTable(yuv_type));
271 } 270 }
272 } 271 }
273 272
274 } // namespace media 273 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698