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

Side by Side Diff: media/base/yuv_convert.cc

Issue 1518027: Incorrect chroma on the right border fixed. (Closed)
Patch Set: fixed wrong chroma on the bottom Created 10 years, 8 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 | « no previous file | no next file » | 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 ybuf += 4; 127 ybuf += 4;
128 } while (ybuf < end); 128 } while (ybuf < end);
129 } 129 }
130 } 130 }
131 131
132 #endif // USE_SSE 132 #endif // USE_SSE
133 #else // no MMX or SSE 133 #else // no MMX or SSE
134 // C version blends 4 pixels at a time. 134 // C version blends 4 pixels at a time.
135 static void FilterRows(uint8* ybuf, const uint8* y0_ptr, const uint8* y1_ptr, 135 static void FilterRows(uint8* ybuf, const uint8* y0_ptr, const uint8* y1_ptr,
136 int width, int scaled_y_fraction) { 136 int width, int scaled_y_fraction) {
137 int y0_fraction = 65536 - scaled_y_fraction; 137 int y0_fraction = kFractionMax - scaled_y_fraction;
138 int y1_fraction = scaled_y_fraction; 138 int y1_fraction = scaled_y_fraction;
139 uint8* end = ybuf + width; 139 uint8* end = ybuf + width;
140 if (ybuf < end) { 140 if (ybuf < end) {
141 do { 141 do {
142 ybuf[0] = (y0_ptr[0] * (y0_fraction) + y1_ptr[0] * (y1_fraction)) >> 16; 142 ybuf[0] = (y0_ptr[0] * (y0_fraction) + y1_ptr[0] * (y1_fraction)) >> 16;
143 ybuf[1] = (y0_ptr[1] * (y0_fraction) + y1_ptr[1] * (y1_fraction)) >> 16; 143 ybuf[1] = (y0_ptr[1] * (y0_fraction) + y1_ptr[1] * (y1_fraction)) >> 16;
144 ybuf[2] = (y0_ptr[2] * (y0_fraction) + y1_ptr[2] * (y1_fraction)) >> 16; 144 ybuf[2] = (y0_ptr[2] * (y0_fraction) + y1_ptr[2] * (y1_fraction)) >> 16;
145 ybuf[3] = (y0_ptr[3] * (y0_fraction) + y1_ptr[3] * (y1_fraction)) >> 16; 145 ybuf[3] = (y0_ptr[3] * (y0_fraction) + y1_ptr[3] * (y1_fraction)) >> 16;
146 y0_ptr += 4; 146 y0_ptr += 4;
147 y1_ptr += 4; 147 y1_ptr += 4;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 } 232 }
233 233
234 // Need padding because FilterRows() may write up to 15 extra pixels 234 // Need padding because FilterRows() may write up to 15 extra pixels
235 // after the end for SSE2 version. 235 // after the end for SSE2 version.
236 uint8 ybuf[kFilterBufferSize + 16]; 236 uint8 ybuf[kFilterBufferSize + 16];
237 uint8 ubuf[kFilterBufferSize / 2 + 16]; 237 uint8 ubuf[kFilterBufferSize / 2 + 16];
238 uint8 vbuf[kFilterBufferSize / 2 + 16]; 238 uint8 vbuf[kFilterBufferSize / 2 + 16];
239 int yscale_fixed = (height << kFractionBits) / scaled_height; 239 int yscale_fixed = (height << kFractionBits) / scaled_height;
240 for (int y = 0; y < scaled_height; ++y) { 240 for (int y = 0; y < scaled_height; ++y) {
241 uint8* dest_pixel = rgb_buf + y * rgb_pitch; 241 uint8* dest_pixel = rgb_buf + y * rgb_pitch;
242 int scaled_y = (y * yscale_fixed); 242 int source_y_subpixel = (y * yscale_fixed);
243 int source_y = source_y_subpixel >> kFractionBits;
fbarchard 2010/04/14 06:21:42 source... ya thats a better name
243 244
244 const uint8* y0_ptr = y_buf + (scaled_y >> kFractionBits) * y_pitch; 245 const uint8* y0_ptr = y_buf + source_y * y_pitch;
245 const uint8* y1_ptr = y0_ptr + y_pitch; 246 const uint8* y1_ptr = y0_ptr + y_pitch;
246 247
247 const uint8* u0_ptr = u_buf + 248 const uint8* u0_ptr = u_buf + (source_y >> y_shift) * uv_pitch;
248 ((scaled_y >> kFractionBits) >> y_shift) * uv_pitch;
249 const uint8* u1_ptr = u0_ptr + uv_pitch; 249 const uint8* u1_ptr = u0_ptr + uv_pitch;
250 const uint8* v0_ptr = v_buf + 250 const uint8* v0_ptr = v_buf + (source_y >> y_shift) * uv_pitch;
251 ((scaled_y >> kFractionBits) >> y_shift) * uv_pitch;
252 const uint8* v1_ptr = v0_ptr + uv_pitch; 251 const uint8* v1_ptr = v0_ptr + uv_pitch;
253 252
254 int scaled_y_fraction = scaled_y & (kFractionMax - 1); 253 int scaled_y_fraction = source_y_subpixel & (kFractionMax - 1);
255 int scaled_uv_fraction = (scaled_y >> y_shift) & (kFractionMax - 1); 254 int scaled_uv_fraction = (source_y_subpixel >> y_shift) & (kFractionMax - 1) ;
256 255
257 const uint8* y_ptr = y0_ptr; 256 const uint8* y_ptr = y0_ptr;
258 const uint8* u_ptr = u0_ptr; 257 const uint8* u_ptr = u0_ptr;
259 const uint8* v_ptr = v0_ptr; 258 const uint8* v_ptr = v0_ptr;
260 // Apply vertical filtering if necessary. 259 // Apply vertical filtering if necessary.
261 // TODO(fbarchard): Remove memcpy when not necessary. 260 // TODO(fbarchard): Remove memcpy when not necessary.
262 if (filter == media::FILTER_BILINEAR) { 261 if (filter == media::FILTER_BILINEAR) {
263 if (yscale_fixed != kFractionMax && 262 if (yscale_fixed != kFractionMax &&
264 scaled_y_fraction && ((y + 1) < scaled_height)) { 263 scaled_y_fraction && ((source_y + 1) < height)) {
265 FilterRows(ybuf, y0_ptr, y1_ptr, width, scaled_y_fraction); 264 FilterRows(ybuf, y0_ptr, y1_ptr, width, scaled_y_fraction);
266 } else { 265 } else {
267 memcpy(ybuf, y0_ptr, width); 266 memcpy(ybuf, y0_ptr, width);
268 } 267 }
269 y_ptr = ybuf; 268 y_ptr = ybuf;
270 ybuf[width] = ybuf[width-1]; 269 ybuf[width] = ybuf[width-1];
271 int uv_width = (width + 1) / 2; 270 int uv_width = (width + 1) / 2;
272 if (yscale_fixed != kFractionMax && 271 if (yscale_fixed != kFractionMax &&
273 scaled_uv_fraction && 272 scaled_uv_fraction &&
274 (((y >> y_shift) + 1) < (scaled_height >> y_shift))) { 273 (((source_y >> y_shift) + 1) < (height >> y_shift))) {
fbarchard 2010/04/14 06:21:42 is this the error you referred to?
275 FilterRows(ubuf, u0_ptr, u1_ptr, uv_width, scaled_uv_fraction); 274 FilterRows(ubuf, u0_ptr, u1_ptr, uv_width, scaled_uv_fraction);
276 FilterRows(vbuf, v0_ptr, v1_ptr, uv_width, scaled_uv_fraction); 275 FilterRows(vbuf, v0_ptr, v1_ptr, uv_width, scaled_uv_fraction);
277 } else { 276 } else {
278 memcpy(ubuf, u0_ptr, uv_width); 277 memcpy(ubuf, u0_ptr, uv_width);
279 memcpy(vbuf, v0_ptr, uv_width); 278 memcpy(vbuf, v0_ptr, uv_width);
280 } 279 }
281 u_ptr = ubuf; 280 u_ptr = ubuf;
282 v_ptr = vbuf; 281 v_ptr = vbuf;
283 ubuf[(width + 1) / 2] = ybuf[(width + 1) / 2 -1]; 282 ubuf[uv_width] = ubuf[uv_width - 1];
fbarchard 2010/04/14 06:21:42 good catch!
284 vbuf[(width + 1) / 2] = vbuf[(width + 1) / 2 -1]; 283 vbuf[uv_width] = vbuf[uv_width - 1];
285 } 284 }
286 if (scaled_dx == kFractionMax) { // Not scaled 285 if (scaled_dx == kFractionMax) { // Not scaled
287 FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr, 286 FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
288 dest_pixel, scaled_width); 287 dest_pixel, scaled_width);
289 } else { 288 } else {
290 if (filter == FILTER_BILINEAR) 289 if (filter == FILTER_BILINEAR)
291 LinearScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr, 290 LinearScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
292 dest_pixel, scaled_width, scaled_dx); 291 dest_pixel, scaled_width, scaled_dx);
293 else 292 else
294 ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr, 293 ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
295 dest_pixel, scaled_width, scaled_dx); 294 dest_pixel, scaled_width, scaled_dx);
296 } 295 }
297 } 296 }
298 297
299 // MMX used for FastConvertYUVToRGB32Row requires emms instruction. 298 // MMX used for FastConvertYUVToRGB32Row requires emms instruction.
300 EMMS(); 299 EMMS();
301 } 300 }
302 301
303 } // namespace media 302 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698