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

Side by Side Diff: media/base/yuv_convert.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: add enum to mojom 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
« no previous file with comments | « media/base/yuv_convert.h ('k') | media/base/yuv_convert_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // This webpage shows layout of YV12 and other YUV formats 5 // This webpage shows layout of YV12 and other YUV formats
6 // http://www.fourcc.org/yuv.php 6 // http://www.fourcc.org/yuv.php
7 // The actual conversion is best described here 7 // The actual conversion is best described here
8 // http://en.wikipedia.org/wiki/YUV 8 // http://en.wikipedia.org/wiki/YUV
9 // An article on optimizing YUV conversion using tables instead of multiplies 9 // An article on optimizing YUV conversion using tables instead of multiplies
10 // http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf 10 // http://lestourtereaux.free.fr/papers/data/yuvrgb.pdf
11 // 11 //
12 // YV12 is a full plane of Y and a half height, half width chroma planes 12 // YV12 is a full plane of Y and a half height, half width chroma planes
13 // YV16 is a full plane of Y and a full height, half width chroma planes 13 // YV16 is a full plane of Y and a full height, half width chroma planes
14 // 14 //
15 // ARGB pixel format is output, which on little endian is stored as BGRA. 15 // ARGB pixel format is output, which on little endian is stored as BGRA.
16 // The alpha is set to 255, allowing the application to use RGBA or RGB32. 16 // The alpha is set to 255, allowing the application to use RGBA or RGB32.
17 17
18 #include "media/base/yuv_convert.h" 18 #include "media/base/yuv_convert.h"
19 19
20 #include "base/cpu.h" 20 #include "base/cpu.h"
21 #include "base/lazy_instance.h"
21 #include "base/logging.h" 22 #include "base/logging.h"
23 #include "base/macros.h"
24 #include "base/memory/aligned_memory.h"
22 #include "base/memory/scoped_ptr.h" 25 #include "base/memory/scoped_ptr.h"
23 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 26 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
24 #include "build/build_config.h" 27 #include "build/build_config.h"
25 #include "media/base/simd/convert_rgb_to_yuv.h" 28 #include "media/base/simd/convert_rgb_to_yuv.h"
26 #include "media/base/simd/convert_yuv_to_rgb.h" 29 #include "media/base/simd/convert_yuv_to_rgb.h"
27 #include "media/base/simd/filter_yuv.h" 30 #include "media/base/simd/filter_yuv.h"
28 #include "media/base/simd/yuv_to_rgb_table.h"
29 31
30 #if defined(ARCH_CPU_X86_FAMILY) 32 #if defined(ARCH_CPU_X86_FAMILY)
31 #if defined(COMPILER_MSVC) 33 #if defined(COMPILER_MSVC)
32 #include <intrin.h> 34 #include <intrin.h>
33 #else 35 #else
34 #include <mmintrin.h> 36 #include <mmintrin.h>
35 #endif 37 #endif
36 #endif 38 #endif
37 39
38 // Assembly functions are declared without namespace. 40 // Assembly functions are declared without namespace.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 int, 80 int,
79 int, 81 int,
80 int, 82 int,
81 YUVType); 83 YUVType);
82 84
83 typedef void (*ConvertYUVToRGB32RowProc)(const uint8*, 85 typedef void (*ConvertYUVToRGB32RowProc)(const uint8*,
84 const uint8*, 86 const uint8*,
85 const uint8*, 87 const uint8*,
86 uint8*, 88 uint8*,
87 ptrdiff_t, 89 ptrdiff_t,
88 const int16[1024][4]); 90 const int16*);
89 91
90 typedef void (*ConvertYUVAToARGBRowProc)(const uint8*, 92 typedef void (*ConvertYUVAToARGBRowProc)(const uint8*,
91 const uint8*, 93 const uint8*,
92 const uint8*, 94 const uint8*,
93 const uint8*, 95 const uint8*,
94 uint8*, 96 uint8*,
95 ptrdiff_t, 97 ptrdiff_t,
96 const int16[1024][4]); 98 const int16*);
97 99
98 typedef void (*ScaleYUVToRGB32RowProc)(const uint8*, 100 typedef void (*ScaleYUVToRGB32RowProc)(const uint8*,
99 const uint8*, 101 const uint8*,
100 const uint8*, 102 const uint8*,
101 uint8*, 103 uint8*,
102 ptrdiff_t, 104 ptrdiff_t,
103 ptrdiff_t, 105 ptrdiff_t,
104 const int16[1024][4]); 106 const int16*);
105 107
106 static FilterYUVRowsProc g_filter_yuv_rows_proc_ = NULL; 108 static FilterYUVRowsProc g_filter_yuv_rows_proc_ = NULL;
107 static ConvertYUVToRGB32RowProc g_convert_yuv_to_rgb32_row_proc_ = NULL; 109 static ConvertYUVToRGB32RowProc g_convert_yuv_to_rgb32_row_proc_ = NULL;
108 static ScaleYUVToRGB32RowProc g_scale_yuv_to_rgb32_row_proc_ = NULL; 110 static ScaleYUVToRGB32RowProc g_scale_yuv_to_rgb32_row_proc_ = NULL;
109 static ScaleYUVToRGB32RowProc g_linear_scale_yuv_to_rgb32_row_proc_ = NULL; 111 static ScaleYUVToRGB32RowProc g_linear_scale_yuv_to_rgb32_row_proc_ = NULL;
110 static ConvertRGBToYUVProc g_convert_rgb32_to_yuv_proc_ = NULL; 112 static ConvertRGBToYUVProc g_convert_rgb32_to_yuv_proc_ = NULL;
111 static ConvertRGBToYUVProc g_convert_rgb24_to_yuv_proc_ = NULL; 113 static ConvertRGBToYUVProc g_convert_rgb24_to_yuv_proc_ = NULL;
112 static ConvertYUVToRGB32Proc g_convert_yuv_to_rgb32_proc_ = NULL; 114 static ConvertYUVToRGB32Proc g_convert_yuv_to_rgb32_proc_ = NULL;
113 static ConvertYUVAToARGBProc g_convert_yuva_to_argb_proc_ = NULL; 115 static ConvertYUVAToARGBProc g_convert_yuva_to_argb_proc_ = NULL;
114 116
117 static const int kYUVToRGBTableSize = 256 * 4 * 4 * sizeof(int16);
118
119 // base::AlignedMemory has a private operator new(), so wrap it in a struct so
120 // that we can put it in a LazyInstance::Leaky.
121 struct YUVToRGBTableWrapper {
122 base::AlignedMemory<kYUVToRGBTableSize, 16> table;
123 };
124
125 typedef base::LazyInstance<YUVToRGBTableWrapper>::Leaky
126 YUVToRGBTable;
127 static YUVToRGBTable g_table_rec601 = LAZY_INSTANCE_INITIALIZER;
128 static YUVToRGBTable g_table_jpeg = LAZY_INSTANCE_INITIALIZER;
129 static YUVToRGBTable g_table_rec709 = LAZY_INSTANCE_INITIALIZER;
130 static const int16* g_table_rec601_ptr = NULL;
131 static const int16* g_table_jpeg_ptr = NULL;
132 static const int16* g_table_rec709_ptr = NULL;
133
115 // Empty SIMD registers state after using them. 134 // Empty SIMD registers state after using them.
116 void EmptyRegisterStateStub() {} 135 void EmptyRegisterStateStub() {}
117 #if defined(MEDIA_MMX_INTRINSICS_AVAILABLE) 136 #if defined(MEDIA_MMX_INTRINSICS_AVAILABLE)
118 void EmptyRegisterStateIntrinsic() { _mm_empty(); } 137 void EmptyRegisterStateIntrinsic() { _mm_empty(); }
119 #endif 138 #endif
120 typedef void (*EmptyRegisterStateProc)(); 139 typedef void (*EmptyRegisterStateProc)();
121 static EmptyRegisterStateProc g_empty_register_state_proc_ = NULL; 140 static EmptyRegisterStateProc g_empty_register_state_proc_ = NULL;
122 141
123 // Get the appropriate value to bitshift by for vertical indices. 142 // Get the appropriate value to bitshift by for vertical indices.
124 int GetVerticalShift(YUVType type) { 143 int GetVerticalShift(YUVType type) {
125 switch (type) { 144 switch (type) {
126 case YV16: 145 case YV16:
127 return 0; 146 return 0;
128 case YV12: 147 case YV12:
129 case YV12J: 148 case YV12J:
149 case YV12HD:
130 return 1; 150 return 1;
131 } 151 }
132 NOTREACHED(); 152 NOTREACHED();
133 return 0; 153 return 0;
134 } 154 }
135 155
136 const int16 (&GetLookupTable(YUVType type))[1024][4] { 156 const int16* GetLookupTable(YUVType type) {
137 switch (type) { 157 switch (type) {
138 case YV12: 158 case YV12:
139 case YV16: 159 case YV16:
140 return kCoefficientsRgbY; 160 return g_table_rec601_ptr;
141 case YV12J: 161 case YV12J:
142 return kCoefficientsRgbY_JPEG; 162 return g_table_jpeg_ptr;
163 case YV12HD:
164 return g_table_rec709_ptr;
143 } 165 }
144 NOTREACHED(); 166 NOTREACHED();
145 return kCoefficientsRgbY; 167 return NULL;
168 }
169
170 // Populates a pre-allocated lookup table from a YUV->RGB matrix.
171 const int16* PopulateYUVToRGBTable(const double matrix[3][3],
172 bool full_range,
173 int16* table) {
174 // We'll have 4 sub-tables that lie contiguous in memory, one for each of Y,
175 // U, V and A.
176 const int kNumTables = 4;
177 // Each table has 256 rows (for all possible 8-bit values).
178 const int kNumRows = 256;
179 // Each row has 4 columns, for contributions to each of R, G, B and A.
180 const int kNumColumns = 4;
181 // Each element is a fixed-point (10.6) 16-bit signed value.
182 const int kElementSize = sizeof(int16);
183
184 // Sanity check that our constants here match the size of the statically
185 // allocated tables.
186 COMPILE_ASSERT(
187 kNumTables * kNumRows * kNumColumns * kElementSize == kYUVToRGBTableSize,
188 "YUV lookup table size doesn't match expectation.");
189
190 // Y needs an offset of -16 for color ranges that ignore the lower 16 values,
191 // U and V get -128 to put them in [-128, 127] from [0, 255].
192 int offsets[3] = {(full_range ? 0 : -16), -128, -128};
193
194 for (int i = 0; i < kNumRows; ++i) {
195 // Y, U, and V contributions to each of R, G, B and A.
196 for (int j = 0; j < 3; ++j) {
197 #if defined(OS_ANDROID)
198 // Android is RGBA.
199 table[(j * kNumRows + i) * kNumColumns + 0] =
200 matrix[j][0] * 64 * (i + offsets[j]) + 0.5;
201 table[(j * kNumRows + i) * kNumColumns + 1] =
202 matrix[j][1] * 64 * (i + offsets[j]) + 0.5;
203 table[(j * kNumRows + i) * kNumColumns + 2] =
204 matrix[j][2] * 64 * (i + offsets[j]) + 0.5;
205 #else
206 // Other platforms are BGRA.
207 table[(j * kNumRows + i) * kNumColumns + 0] =
208 matrix[j][2] * 64 * (i + offsets[j]) + 0.5;
209 table[(j * kNumRows + i) * kNumColumns + 1] =
210 matrix[j][1] * 64 * (i + offsets[j]) + 0.5;
211 table[(j * kNumRows + i) * kNumColumns + 2] =
212 matrix[j][0] * 64 * (i + offsets[j]) + 0.5;
213 #endif
214 // Alpha contributions from Y and V are always 0. U is set such that
215 // all values result in a full '255' alpha value.
216 table[(j * kNumRows + i) * kNumColumns + 3] = (j == 1) ? 256 * 64 - 1 : 0;
217 }
218 // And YUVA alpha is passed through as-is.
219 for (int k = 0; k < kNumTables; ++k)
220 table[((kNumTables - 1) * kNumRows + i) * kNumColumns + k] = i;
221 }
222
223 return table;
146 } 224 }
147 225
148 void InitializeCPUSpecificYUVConversions() { 226 void InitializeCPUSpecificYUVConversions() {
149 CHECK(!g_filter_yuv_rows_proc_); 227 CHECK(!g_filter_yuv_rows_proc_);
150 CHECK(!g_convert_yuv_to_rgb32_row_proc_); 228 CHECK(!g_convert_yuv_to_rgb32_row_proc_);
151 CHECK(!g_scale_yuv_to_rgb32_row_proc_); 229 CHECK(!g_scale_yuv_to_rgb32_row_proc_);
152 CHECK(!g_linear_scale_yuv_to_rgb32_row_proc_); 230 CHECK(!g_linear_scale_yuv_to_rgb32_row_proc_);
153 CHECK(!g_convert_rgb32_to_yuv_proc_); 231 CHECK(!g_convert_rgb32_to_yuv_proc_);
154 CHECK(!g_convert_rgb24_to_yuv_proc_); 232 CHECK(!g_convert_rgb24_to_yuv_proc_);
155 CHECK(!g_convert_yuv_to_rgb32_proc_); 233 CHECK(!g_convert_yuv_to_rgb32_proc_);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 #endif 274 #endif
197 275
198 base::CPU cpu; 276 base::CPU cpu;
199 if (cpu.has_ssse3()) { 277 if (cpu.has_ssse3()) {
200 g_convert_rgb24_to_yuv_proc_ = &ConvertRGB24ToYUV_SSSE3; 278 g_convert_rgb24_to_yuv_proc_ = &ConvertRGB24ToYUV_SSSE3;
201 279
202 // TODO(hclam): Add ConvertRGB32ToYUV_SSSE3 when the cyan problem is solved. 280 // TODO(hclam): Add ConvertRGB32ToYUV_SSSE3 when the cyan problem is solved.
203 // See: crbug.com/100462 281 // See: crbug.com/100462
204 } 282 }
205 #endif 283 #endif
284
285 // Initialize YUV conversion lookup tables.
286
287 // SD Rec601 YUV->RGB matrix, see http://www.fourcc.org/fccyvrgb.php
288 const double kRec601ConvertMatrix[3][3] = {
289 {1.164, 1.164, 1.164}, {0.0, -0.391, 2.018}, {1.596, -0.813, 0.0},
290 };
291
292 // JPEG table, values from above link.
293 const double kJPEGConvertMatrix[3][3] = {
294 {1.0, 1.0, 1.0}, {0.0, -0.34414, 1.772}, {1.402, -0.71414, 0.0},
295 };
296
297 // Rec709 "HD" color space, values from:
298 // http://www.equasys.de/colorconversion.html
299 const double kRec709ConvertMatrix[3][3] = {
300 {1.164, 1.164, 1.164}, {0.0, -0.213, 2.112}, {1.793, -0.533, 0.0},
301 };
302
303 PopulateYUVToRGBTable(kRec601ConvertMatrix, false,
304 g_table_rec601.Get().table.data_as<int16>());
305 PopulateYUVToRGBTable(kJPEGConvertMatrix, true,
306 g_table_jpeg.Get().table.data_as<int16>());
307 PopulateYUVToRGBTable(kRec709ConvertMatrix, false,
308 g_table_rec709.Get().table.data_as<int16>());
309 g_table_rec601_ptr = g_table_rec601.Get().table.data_as<int16>();
310 g_table_rec709_ptr = g_table_rec709.Get().table.data_as<int16>();
311 g_table_jpeg_ptr = g_table_jpeg.Get().table.data_as<int16>();
206 } 312 }
207 313
208 // Empty SIMD registers state after using them. 314 // Empty SIMD registers state after using them.
209 void EmptyRegisterState() { g_empty_register_state_proc_(); } 315 void EmptyRegisterState() { g_empty_register_state_proc_(); }
210 316
211 // 16.16 fixed point arithmetic 317 // 16.16 fixed point arithmetic
212 const int kFractionBits = 16; 318 const int kFractionBits = 16;
213 const int kFractionMax = 1 << kFractionBits; 319 const int kFractionMax = 1 << kFractionBits;
214 const int kFractionMask = ((1 << kFractionBits) - 1); 320 const int kFractionMask = ((1 << kFractionBits) - 1);
215 321
(...skipping 11 matching lines...) Expand all
227 int rgb_pitch, 333 int rgb_pitch,
228 YUVType yuv_type, 334 YUVType yuv_type,
229 Rotate view_rotate, 335 Rotate view_rotate,
230 ScaleFilter filter) { 336 ScaleFilter filter) {
231 // Handle zero sized sources and destinations. 337 // Handle zero sized sources and destinations.
232 if ((yuv_type == YV12 && (source_width < 2 || source_height < 2)) || 338 if ((yuv_type == YV12 && (source_width < 2 || source_height < 2)) ||
233 (yuv_type == YV16 && (source_width < 2 || source_height < 1)) || 339 (yuv_type == YV16 && (source_width < 2 || source_height < 1)) ||
234 width == 0 || height == 0) 340 width == 0 || height == 0)
235 return; 341 return;
236 342
343 const int16* lookup_table = GetLookupTable(yuv_type);
344
237 // 4096 allows 3 buffers to fit in 12k. 345 // 4096 allows 3 buffers to fit in 12k.
238 // Helps performance on CPU with 16K L1 cache. 346 // Helps performance on CPU with 16K L1 cache.
239 // Large enough for 3830x2160 and 30" displays which are 2560x1600. 347 // Large enough for 3830x2160 and 30" displays which are 2560x1600.
240 const int kFilterBufferSize = 4096; 348 const int kFilterBufferSize = 4096;
241 // Disable filtering if the screen is too big (to avoid buffer overflows). 349 // Disable filtering if the screen is too big (to avoid buffer overflows).
242 // This should never happen to regular users: they don't have monitors 350 // This should never happen to regular users: they don't have monitors
243 // wider than 4096 pixels. 351 // wider than 4096 pixels.
244 // TODO(fbarchard): Allow rotated videos to filter. 352 // TODO(fbarchard): Allow rotated videos to filter.
245 if (source_width > kFilterBufferSize || view_rotate) 353 if (source_width > kFilterBufferSize || view_rotate)
246 filter = FILTER_NONE; 354 filter = FILTER_NONE;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 ubuf[uv_source_width] = ubuf[uv_source_width - 1]; 478 ubuf[uv_source_width] = ubuf[uv_source_width - 1];
371 vbuf[uv_source_width] = vbuf[uv_source_width - 1]; 479 vbuf[uv_source_width] = vbuf[uv_source_width - 1];
372 } else { 480 } else {
373 // Offset by 1/2 pixel for center sampling. 481 // Offset by 1/2 pixel for center sampling.
374 int source_y = (source_y_subpixel + (kFractionMax / 2)) >> kFractionBits; 482 int source_y = (source_y_subpixel + (kFractionMax / 2)) >> kFractionBits;
375 y_ptr = y_buf + source_y * y_pitch; 483 y_ptr = y_buf + source_y * y_pitch;
376 u_ptr = u_buf + (source_y >> y_shift) * uv_pitch; 484 u_ptr = u_buf + (source_y >> y_shift) * uv_pitch;
377 v_ptr = v_buf + (source_y >> y_shift) * uv_pitch; 485 v_ptr = v_buf + (source_y >> y_shift) * uv_pitch;
378 } 486 }
379 if (source_dx == kFractionMax) { // Not scaled 487 if (source_dx == kFractionMax) { // Not scaled
380 g_convert_yuv_to_rgb32_row_proc_( 488 g_convert_yuv_to_rgb32_row_proc_(y_ptr, u_ptr, v_ptr, dest_pixel, width,
381 y_ptr, u_ptr, v_ptr, dest_pixel, width, kCoefficientsRgbY); 489 lookup_table);
382 } else { 490 } else {
383 if (filter & FILTER_BILINEAR_H) { 491 if (filter & FILTER_BILINEAR_H) {
384 g_linear_scale_yuv_to_rgb32_row_proc_(y_ptr, 492 g_linear_scale_yuv_to_rgb32_row_proc_(y_ptr, u_ptr, v_ptr, dest_pixel,
385 u_ptr, 493 width, source_dx,
386 v_ptr, 494 lookup_table);
387 dest_pixel,
388 width,
389 source_dx,
390 kCoefficientsRgbY);
391 } else { 495 } else {
392 g_scale_yuv_to_rgb32_row_proc_(y_ptr, 496 g_scale_yuv_to_rgb32_row_proc_(y_ptr, u_ptr, v_ptr, dest_pixel, width,
393 u_ptr, 497 source_dx, lookup_table);
394 v_ptr,
395 dest_pixel,
396 width,
397 source_dx,
398 kCoefficientsRgbY);
399 } 498 }
400 } 499 }
401 } 500 }
402 501
403 g_empty_register_state_proc_(); 502 g_empty_register_state_proc_();
404 } 503 }
405 504
406 // Scale a frame of YV12 to 32 bit ARGB for a specific rectangle. 505 // Scale a frame of YV12 to 32 bit ARGB for a specific rectangle.
407 void ScaleYUVToRGB32WithRect(const uint8* y_buf, 506 void ScaleYUVToRGB32WithRect(const uint8* y_buf,
408 const uint8* u_buf, 507 const uint8* u_buf,
(...skipping 13 matching lines...) Expand all
422 // This routine doesn't currently support up-scaling. 521 // This routine doesn't currently support up-scaling.
423 CHECK_LE(dest_width, source_width); 522 CHECK_LE(dest_width, source_width);
424 CHECK_LE(dest_height, source_height); 523 CHECK_LE(dest_height, source_height);
425 524
426 // Sanity-check the destination rectangle. 525 // Sanity-check the destination rectangle.
427 DCHECK(dest_rect_left >= 0 && dest_rect_right <= dest_width); 526 DCHECK(dest_rect_left >= 0 && dest_rect_right <= dest_width);
428 DCHECK(dest_rect_top >= 0 && dest_rect_bottom <= dest_height); 527 DCHECK(dest_rect_top >= 0 && dest_rect_bottom <= dest_height);
429 DCHECK(dest_rect_right > dest_rect_left); 528 DCHECK(dest_rect_right > dest_rect_left);
430 DCHECK(dest_rect_bottom > dest_rect_top); 529 DCHECK(dest_rect_bottom > dest_rect_top);
431 530
531 const int16* lookup_table = GetLookupTable(YV12);
532
432 // Fixed-point value of vertical and horizontal scale down factor. 533 // Fixed-point value of vertical and horizontal scale down factor.
433 // Values are in the format 16.16. 534 // Values are in the format 16.16.
434 int y_step = kFractionMax * source_height / dest_height; 535 int y_step = kFractionMax * source_height / dest_height;
435 int x_step = kFractionMax * source_width / dest_width; 536 int x_step = kFractionMax * source_width / dest_width;
436 537
437 // Determine the coordinates of the rectangle in 16.16 coords. 538 // Determine the coordinates of the rectangle in 16.16 coords.
438 // NB: Our origin is the *center* of the top/left pixel, NOT its top/left. 539 // NB: Our origin is the *center* of the top/left pixel, NOT its top/left.
439 // If we're down-scaling by more than a factor of two, we start with a 50% 540 // If we're down-scaling by more than a factor of two, we start with a 50%
440 // fraction to avoid degenerating to point-sampling - we should really just 541 // fraction to avoid degenerating to point-sampling - we should really just
441 // fix the fraction at 50% for all pixels in that case. 542 // fix the fraction at 50% for all pixels in that case.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 uint8 fraction = (source_top & kFractionMask) >> 8; 627 uint8 fraction = (source_top & kFractionMask) >> 8;
527 g_filter_yuv_rows_proc_( 628 g_filter_yuv_rows_proc_(
528 y_temp + source_y_left, y0_ptr, y1_ptr, source_y_width, fraction); 629 y_temp + source_y_left, y0_ptr, y1_ptr, source_y_width, fraction);
529 g_filter_yuv_rows_proc_( 630 g_filter_yuv_rows_proc_(
530 u_temp + source_uv_left, u0_ptr, u1_ptr, source_uv_width, fraction); 631 u_temp + source_uv_left, u0_ptr, u1_ptr, source_uv_width, fraction);
531 g_filter_yuv_rows_proc_( 632 g_filter_yuv_rows_proc_(
532 v_temp + source_uv_left, v0_ptr, v1_ptr, source_uv_width, fraction); 633 v_temp + source_uv_left, v0_ptr, v1_ptr, source_uv_width, fraction);
533 634
534 // Perform horizontal interpolation and color space conversion. 635 // Perform horizontal interpolation and color space conversion.
535 // TODO(hclam): Use the MMX version after more testing. 636 // TODO(hclam): Use the MMX version after more testing.
536 LinearScaleYUVToRGB32RowWithRange_C(y_temp, 637 LinearScaleYUVToRGB32RowWithRange_C(y_temp, u_temp, v_temp, rgb_buf,
537 u_temp, 638 dest_rect_width, source_left, x_step,
538 v_temp, 639 lookup_table);
539 rgb_buf,
540 dest_rect_width,
541 source_left,
542 x_step,
543 kCoefficientsRgbY);
544 } else { 640 } else {
545 // If the frame is too large then we linear scale a single row. 641 // If the frame is too large then we linear scale a single row.
546 LinearScaleYUVToRGB32RowWithRange_C(y0_ptr, 642 LinearScaleYUVToRGB32RowWithRange_C(y0_ptr, u0_ptr, v0_ptr, rgb_buf,
547 u0_ptr, 643 dest_rect_width, source_left, x_step,
548 v0_ptr, 644 lookup_table);
549 rgb_buf,
550 dest_rect_width,
551 source_left,
552 x_step,
553 kCoefficientsRgbY);
554 } 645 }
555 646
556 // Advance vertically in the source and destination image. 647 // Advance vertically in the source and destination image.
557 source_top += y_step; 648 source_top += y_step;
558 rgb_buf += rgb_pitch; 649 rgb_buf += rgb_pitch;
559 } 650 }
560 651
561 g_empty_register_state_proc_(); 652 g_empty_register_state_proc_();
562 } 653 }
563 654
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 width, 777 width,
687 height, 778 height,
688 ystride, 779 ystride,
689 uvstride, 780 uvstride,
690 astride, 781 astride,
691 rgbstride, 782 rgbstride,
692 yuv_type); 783 yuv_type);
693 } 784 }
694 785
695 } // namespace media 786 } // namespace media
OLDNEW
« no previous file with comments | « media/base/yuv_convert.h ('k') | media/base/yuv_convert_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698