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

Unified Diff: media/base/yuv_convert.cc

Issue 113407: ScaleYV12 optimization.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 7 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/yuv_convert.cc
===================================================================
--- media/base/yuv_convert.cc (revision 16299)
+++ media/base/yuv_convert.cc (working copy)
@@ -73,72 +73,150 @@
#define DCHECK(a)
#endif
+// Header for low level row functions.
#include "media/base/yuv_row.h"
namespace media {
-
-// Convert a frame of YV12 (aka YUV420) to 32 bit ARGB.
-void ConvertYV12ToRGB32(const uint8* y_buf,
+// Convert a frame of YUV to 32 bit ARGB.
+void ConvertYUVToRGB32(const uint8* y_buf,
const uint8* u_buf,
const uint8* v_buf,
uint8* rgb_buf,
- size_t width,
- size_t height,
+ int width,
+ int height,
int y_pitch,
int uv_pitch,
- int rgb_pitch) {
- // Image must be multiple of 2 in width.
- DCHECK((width & 1) == 0);
- // Check alignment. Use memalign to allocate the buffer if you hit this
- // check:
- DCHECK((reinterpret_cast<uintptr_t>(rgb_buf) & 7) == 0);
+ int rgb_pitch,
+ YUVType yuv_type) {
+ unsigned int y_shift = yuv_type;
#ifdef _OPENMP
#pragma omp parallel for
#endif
- for (int y = 0; y < static_cast<int>(height); ++y) {
- uint8* d1 = rgb_buf + y * rgb_pitch;
+ for (int y = 0; y < height; ++y) {
+ uint8* rgb_row = rgb_buf + y * rgb_pitch;
const uint8* y_ptr = y_buf + y * y_pitch;
- const uint8* u_ptr = u_buf + y/2 * uv_pitch;
- const uint8* v_ptr = v_buf + y/2 * uv_pitch;
+ const uint8* u_ptr = u_buf + (y >> y_shift) * uv_pitch;
+ const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch;
- ConvertYV12ToRGB32Row(y_ptr,
- u_ptr,
- v_ptr,
- d1,
- width);
+ FastConvertYUVToRGB32Row(y_ptr,
+ u_ptr,
+ v_ptr,
+ rgb_row,
+ width);
}
EMMS();
}
-// Convert a frame of YV16 (aka YUV422) to 32 bit ARGB.
-void ConvertYV16ToRGB32(const uint8* y_buf,
- const uint8* u_buf,
- const uint8* v_buf,
- uint8* rgb_buf,
- size_t width,
- size_t height,
- int y_pitch,
- int uv_pitch,
- int rgb_pitch) {
- // Image must be multiple of 2 in width.
- DCHECK((width & 1) == 0);
- // Check alignment. Use memalign to allocate the buffer if you hit this
- // check:
- DCHECK((reinterpret_cast<uintptr_t>(rgb_buf) & 7) == 0);
+// Scale a frame of YUV to 32 bit ARGB.
+void ScaleYUVToRGB32(const uint8* y_buf,
+ const uint8* u_buf,
+ const uint8* v_buf,
+ uint8* rgb_buf,
+ int width,
+ int height,
+ int scaled_width,
+ int scaled_height,
+ int y_pitch,
+ int uv_pitch,
+ int rgb_pitch,
+ YUVType yuv_type,
+ Rotate view_rotate) {
+ unsigned int y_shift = yuv_type;
+ // Diagram showing origin and direction of source sampling.
+ // ->0 4<-
+ // 7 3
+ //
+ // 6 5
+ // ->1 2<-
+ // Rotations that start at right side of image.
+ if ((view_rotate == ROTATE_180) ||
+ (view_rotate == ROTATE_270) ||
+ (view_rotate == MIRROR_ROTATE_0) ||
+ (view_rotate == MIRROR_ROTATE_90)) {
+ y_buf += width - 1;
+ u_buf += width / 2 - 1;
+ v_buf += width / 2 - 1;
+ width = -width;
+ }
+ // Rotations that start at bottom of image.
+ if ((view_rotate == ROTATE_90) ||
+ (view_rotate == ROTATE_180) ||
+ (view_rotate == MIRROR_ROTATE_90) ||
+ (view_rotate == MIRROR_ROTATE_180)) {
+ y_buf += (height - 1) * y_pitch;
+ u_buf += ((height >> y_shift) - 1) * uv_pitch;
+ v_buf += ((height >> y_shift) - 1) * uv_pitch;
+ height = -height;
+ }
+
+ // Handle zero sized destination.
+ if (scaled_width == 0 || scaled_height == 0)
+ return;
+ int scaled_dx = width * 16 / scaled_width;
+ int scaled_dy = height * 16 / scaled_height;
+
+ int scaled_dx_uv = scaled_dx;
+
+ if ((view_rotate == ROTATE_90) ||
+ (view_rotate == ROTATE_270)) {
+ int tmp = scaled_height;
+ scaled_height = scaled_width;
+ scaled_width = tmp;
+ tmp = height;
+ height = width;
+ width = tmp;
+ int original_dx = scaled_dx;
+ int original_dy = scaled_dy;
+ scaled_dx = ((original_dy >> 4) * y_pitch) << 4;
+ scaled_dx_uv = ((original_dy >> 4) * uv_pitch) << 4;
+ scaled_dy = original_dx;
+ if (view_rotate == ROTATE_90) {
+ y_pitch = -1;
+ uv_pitch = -1;
+ height = -height;
+ } else {
+ y_pitch = 1;
+ uv_pitch = 1;
+ }
+ }
+
#ifdef _OPENMP
#pragma omp parallel for
#endif
- for (int y = 0; y < static_cast<int>(height); ++y) {
- uint8* d1 = rgb_buf + y * rgb_pitch;
- const uint8* y_ptr = y_buf + y * y_pitch;
- const uint8* u_ptr = u_buf + y * uv_pitch;
- const uint8* v_ptr = v_buf + y * uv_pitch;
+ for (int y = 0; y < scaled_height; ++y) {
+ uint8* dest_pixel = rgb_buf + y * rgb_pitch;
+ int scaled_y = (y * height / scaled_height);
+ const uint8* y_ptr = y_buf + scaled_y * y_pitch;
+ const uint8* u_ptr = u_buf + (scaled_y >> y_shift) * uv_pitch;
+ const uint8* v_ptr = v_buf + (scaled_y >> y_shift) * uv_pitch;
- ConvertYV12ToRGB32Row(y_ptr,
- u_ptr,
- v_ptr,
- d1,
- width);
+#if USE_MMX
+ if (scaled_width == (width * 2)) {
+ DoubleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+ dest_pixel, scaled_width);
+ } else if ((scaled_dx & 15) == 0) { // Scaling by integer scale factor.
+ if (scaled_dx_uv == scaled_dx) { // Not rotated.
+ if (scaled_dx == 16) { // Not scaled
+ FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+ dest_pixel, scaled_width);
+ } else { // Simple scale down. ie half
+ ConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+ dest_pixel, scaled_width, scaled_dx >> 4);
+ }
+ } else {
+ RotateConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+ dest_pixel, scaled_width,
+ scaled_dx >> 4, scaled_dx_uv >> 4);
+ }
+#else
+ if (scaled_dx == 16) { // Not scaled
+ FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+ dest_pixel, scaled_width);
+#endif
+ } else {
+ ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
+ dest_pixel, scaled_width, scaled_dx);
+ }
}
EMMS();
}
« 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