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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« 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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 // excerpt from wiki: 9 // excerpt from wiki:
10 // These formulae are based on the NTSC standard; 10 // These formulae are based on the NTSC standard;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 #ifdef _OPENMP 66 #ifdef _OPENMP
67 #include <omp.h> 67 #include <omp.h>
68 #endif 68 #endif
69 69
70 #ifdef _DEBUG 70 #ifdef _DEBUG
71 #include "base/logging.h" 71 #include "base/logging.h"
72 #else 72 #else
73 #define DCHECK(a) 73 #define DCHECK(a)
74 #endif 74 #endif
75 75
76 // Header for low level row functions.
76 #include "media/base/yuv_row.h" 77 #include "media/base/yuv_row.h"
77 78
78 namespace media { 79 namespace media {
79 80 // Convert a frame of YUV to 32 bit ARGB.
80 // Convert a frame of YV12 (aka YUV420) to 32 bit ARGB. 81 void ConvertYUVToRGB32(const uint8* y_buf,
81 void ConvertYV12ToRGB32(const uint8* y_buf,
82 const uint8* u_buf, 82 const uint8* u_buf,
83 const uint8* v_buf, 83 const uint8* v_buf,
84 uint8* rgb_buf, 84 uint8* rgb_buf,
85 size_t width, 85 int width,
86 size_t height, 86 int height,
87 int y_pitch, 87 int y_pitch,
88 int uv_pitch, 88 int uv_pitch,
89 int rgb_pitch) { 89 int rgb_pitch,
90 // Image must be multiple of 2 in width. 90 YUVType yuv_type) {
91 DCHECK((width & 1) == 0); 91 unsigned int y_shift = yuv_type;
92 // Check alignment. Use memalign to allocate the buffer if you hit this
93 // check:
94 DCHECK((reinterpret_cast<uintptr_t>(rgb_buf) & 7) == 0);
95 #ifdef _OPENMP 92 #ifdef _OPENMP
96 #pragma omp parallel for 93 #pragma omp parallel for
97 #endif 94 #endif
98 for (int y = 0; y < static_cast<int>(height); ++y) { 95 for (int y = 0; y < height; ++y) {
99 uint8* d1 = rgb_buf + y * rgb_pitch; 96 uint8* rgb_row = rgb_buf + y * rgb_pitch;
100 const uint8* y_ptr = y_buf + y * y_pitch; 97 const uint8* y_ptr = y_buf + y * y_pitch;
101 const uint8* u_ptr = u_buf + y/2 * uv_pitch; 98 const uint8* u_ptr = u_buf + (y >> y_shift) * uv_pitch;
102 const uint8* v_ptr = v_buf + y/2 * uv_pitch; 99 const uint8* v_ptr = v_buf + (y >> y_shift) * uv_pitch;
103 100
104 ConvertYV12ToRGB32Row(y_ptr, 101 FastConvertYUVToRGB32Row(y_ptr,
105 u_ptr, 102 u_ptr,
106 v_ptr, 103 v_ptr,
107 d1, 104 rgb_row,
108 width); 105 width);
109 } 106 }
110 EMMS(); 107 EMMS();
111 } 108 }
112 109
113 // Convert a frame of YV16 (aka YUV422) to 32 bit ARGB. 110 // Scale a frame of YUV to 32 bit ARGB.
114 void ConvertYV16ToRGB32(const uint8* y_buf, 111 void ScaleYUVToRGB32(const uint8* y_buf,
115 const uint8* u_buf, 112 const uint8* u_buf,
116 const uint8* v_buf, 113 const uint8* v_buf,
117 uint8* rgb_buf, 114 uint8* rgb_buf,
118 size_t width, 115 int width,
119 size_t height, 116 int height,
120 int y_pitch, 117 int scaled_width,
121 int uv_pitch, 118 int scaled_height,
122 int rgb_pitch) { 119 int y_pitch,
123 // Image must be multiple of 2 in width. 120 int uv_pitch,
124 DCHECK((width & 1) == 0); 121 int rgb_pitch,
125 // Check alignment. Use memalign to allocate the buffer if you hit this 122 YUVType yuv_type,
126 // check: 123 Rotate view_rotate) {
127 DCHECK((reinterpret_cast<uintptr_t>(rgb_buf) & 7) == 0); 124 unsigned int y_shift = yuv_type;
125 // Diagram showing origin and direction of source sampling.
126 // ->0 4<-
127 // 7 3
128 //
129 // 6 5
130 // ->1 2<-
131 // Rotations that start at right side of image.
132 if ((view_rotate == ROTATE_180) ||
133 (view_rotate == ROTATE_270) ||
134 (view_rotate == MIRROR_ROTATE_0) ||
135 (view_rotate == MIRROR_ROTATE_90)) {
136 y_buf += width - 1;
137 u_buf += width / 2 - 1;
138 v_buf += width / 2 - 1;
139 width = -width;
140 }
141 // Rotations that start at bottom of image.
142 if ((view_rotate == ROTATE_90) ||
143 (view_rotate == ROTATE_180) ||
144 (view_rotate == MIRROR_ROTATE_90) ||
145 (view_rotate == MIRROR_ROTATE_180)) {
146 y_buf += (height - 1) * y_pitch;
147 u_buf += ((height >> y_shift) - 1) * uv_pitch;
148 v_buf += ((height >> y_shift) - 1) * uv_pitch;
149 height = -height;
150 }
151
152 // Handle zero sized destination.
153 if (scaled_width == 0 || scaled_height == 0)
154 return;
155 int scaled_dx = width * 16 / scaled_width;
156 int scaled_dy = height * 16 / scaled_height;
157
158 int scaled_dx_uv = scaled_dx;
159
160 if ((view_rotate == ROTATE_90) ||
161 (view_rotate == ROTATE_270)) {
162 int tmp = scaled_height;
163 scaled_height = scaled_width;
164 scaled_width = tmp;
165 tmp = height;
166 height = width;
167 width = tmp;
168 int original_dx = scaled_dx;
169 int original_dy = scaled_dy;
170 scaled_dx = ((original_dy >> 4) * y_pitch) << 4;
171 scaled_dx_uv = ((original_dy >> 4) * uv_pitch) << 4;
172 scaled_dy = original_dx;
173 if (view_rotate == ROTATE_90) {
174 y_pitch = -1;
175 uv_pitch = -1;
176 height = -height;
177 } else {
178 y_pitch = 1;
179 uv_pitch = 1;
180 }
181 }
182
128 #ifdef _OPENMP 183 #ifdef _OPENMP
129 #pragma omp parallel for 184 #pragma omp parallel for
130 #endif 185 #endif
131 for (int y = 0; y < static_cast<int>(height); ++y) { 186 for (int y = 0; y < scaled_height; ++y) {
132 uint8* d1 = rgb_buf + y * rgb_pitch; 187 uint8* dest_pixel = rgb_buf + y * rgb_pitch;
133 const uint8* y_ptr = y_buf + y * y_pitch; 188 int scaled_y = (y * height / scaled_height);
134 const uint8* u_ptr = u_buf + y * uv_pitch; 189 const uint8* y_ptr = y_buf + scaled_y * y_pitch;
135 const uint8* v_ptr = v_buf + y * uv_pitch; 190 const uint8* u_ptr = u_buf + (scaled_y >> y_shift) * uv_pitch;
191 const uint8* v_ptr = v_buf + (scaled_y >> y_shift) * uv_pitch;
136 192
137 ConvertYV12ToRGB32Row(y_ptr, 193 #if USE_MMX
138 u_ptr, 194 if (scaled_width == (width * 2)) {
139 v_ptr, 195 DoubleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
140 d1, 196 dest_pixel, scaled_width);
141 width); 197 } else if ((scaled_dx & 15) == 0) { // Scaling by integer scale factor.
198 if (scaled_dx_uv == scaled_dx) { // Not rotated.
199 if (scaled_dx == 16) { // Not scaled
200 FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
201 dest_pixel, scaled_width);
202 } else { // Simple scale down. ie half
203 ConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
204 dest_pixel, scaled_width, scaled_dx >> 4);
205 }
206 } else {
207 RotateConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
208 dest_pixel, scaled_width,
209 scaled_dx >> 4, scaled_dx_uv >> 4);
210 }
211 #else
212 if (scaled_dx == 16) { // Not scaled
213 FastConvertYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
214 dest_pixel, scaled_width);
215 #endif
216 } else {
217 ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
218 dest_pixel, scaled_width, scaled_dx);
219 }
142 } 220 }
143 EMMS(); 221 EMMS();
144 } 222 }
145 223
146 } // namespace media 224 } // 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