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

Side by Side Diff: media/player/view.h

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/player/resource.h ('k') | media/test/data/bali.yv12.640_360.rgb » ('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. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 // View.h : Paints the current movie frame (with scaling) to the display. 5 // View.h : Paints the current movie frame (with scaling) to the display.
6 // TODO(fbarchard): Consider rewriting as view.cc and view.h 6 // TODO(fbarchard): Consider rewriting as view.cc and view.h
7 7
8 #ifndef MEDIA_PLAYER_VIEW_H_ 8 #ifndef MEDIA_PLAYER_VIEW_H_
9 #define MEDIA_PLAYER_VIEW_H_ 9 #define MEDIA_PLAYER_VIEW_H_
10 10
11 // Enable timing code by turning on TESTING macro. 11 // Enable timing code by turning on TESTING macro.
12 // #define TESTING 1 12 // #define TESTING 1
13 13
14 #ifdef TESTING 14 #ifdef TESTING
15 #define _CRT_SECURE_NO_WARNINGS 15 #define _CRT_SECURE_NO_WARNINGS
16 #include <windows.h> 16 #include <windows.h>
17 #include <stdio.h> 17 #include <stdio.h>
18 #include <process.h> 18 #include <process.h>
19 #include <string.h> 19 #include <string.h>
20 #endif 20 #endif
21 21
22 // Enable swscaler.
23 // TODO(fbarchard): Include header and change bilinear to point sampling.
24 // #define TEST_SWSCALER 1
25
22 #include <atlscrl.h> 26 #include <atlscrl.h>
23 27
24 #include "base/basictypes.h" 28 #include "base/basictypes.h"
25 #include "media/base/buffers.h" 29 #include "media/base/buffers.h"
26 #include "media/base/factory.h" 30 #include "media/base/factory.h"
27 #include "media/base/filters.h" 31 #include "media/base/filters.h"
28 #include "media/base/yuv_convert.h" 32 #include "media/base/yuv_convert.h"
29 #include "media/base/yuv_scale.h"
30 #include "media/player/movie.h" 33 #include "media/player/movie.h"
31 #include "media/player/wtl_renderer.h" 34 #include "media/player/wtl_renderer.h"
32 35
33 #ifdef TESTING 36 #ifdef TESTING
34 // Fetch current time as milliseconds. 37 // Fetch current time as milliseconds.
35 // Return as double for high duration and precision. 38 // Return as double for high duration and precision.
36 static inline double GetTime() { 39 static inline double GetTime() {
37 LARGE_INTEGER perf_time, perf_hz; 40 LARGE_INTEGER perf_time, perf_hz;
38 QueryPerformanceFrequency(&perf_hz); // May change with speed step. 41 QueryPerformanceFrequency(&perf_hz); // May change with speed step.
39 QueryPerformanceCounter(&perf_time); 42 QueryPerformanceCounter(&perf_time);
40 return perf_time.QuadPart * 1000.0 / perf_hz.QuadPart; // Convert to ms. 43 return perf_time.QuadPart * 1000.0 / perf_hz.QuadPart; // Convert to ms.
41 } 44 }
42 #endif 45 #endif
43 46
44 class WtlVideoWindow : public CScrollWindowImpl<WtlVideoWindow> { 47 class WtlVideoWindow : public CScrollWindowImpl<WtlVideoWindow> {
45 public: 48 public:
46 DECLARE_WND_CLASS_EX(NULL, 0, -1) 49 DECLARE_WND_CLASS_EX(NULL, 0, -1)
47 50
48 BEGIN_MSG_MAP(WtlVideoWindow) 51 BEGIN_MSG_MAP(WtlVideoWindow)
49 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) 52 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
50 CHAIN_MSG_MAP(CScrollWindowImpl<WtlVideoWindow>); 53 CHAIN_MSG_MAP(CScrollWindowImpl<WtlVideoWindow>);
51 END_MSG_MAP() 54 END_MSG_MAP()
52 55
53 WtlVideoWindow() { 56 WtlVideoWindow() {
54 size_.cx = 0; 57 size_.cx = 0;
55 size_.cy = 0; 58 size_.cy = 0;
56 view_size_ = 1; 59 view_size_ = 2; // Normal size.
57 view_rotate_ = media::ROTATE_0; 60 view_rotate_ = media::ROTATE_0;
58 renderer_ = new WtlVideoRenderer(this); 61 renderer_ = new WtlVideoRenderer(this);
59 last_frame_ = NULL; 62 last_frame_ = NULL;
60 hbmp_ = NULL; 63 hbmp_ = NULL;
61 } 64 }
62 65
63 BOOL PreTranslateMessage(MSG* /*msg*/) { 66 BOOL PreTranslateMessage(MSG* /*msg*/) {
64 return FALSE; 67 return FALSE;
65 } 68 }
66 69
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 } 157 }
155 int clipped_height = frame_in.height; 158 int clipped_height = frame_in.height;
156 if (dibheight < clipped_height) { 159 if (dibheight < clipped_height) {
157 clipped_height = dibheight; 160 clipped_height = dibheight;
158 } 161 }
159 162
160 int scaled_width = clipped_width; 163 int scaled_width = clipped_width;
161 int scaled_height = clipped_height; 164 int scaled_height = clipped_height;
162 switch (view_size_) { 165 switch (view_size_) {
163 case 0: 166 case 0:
167 scaled_width = clipped_width / 4;
168 scaled_height = clipped_height / 4;
169 break;
170
171 case 1:
164 scaled_width = clipped_width / 2; 172 scaled_width = clipped_width / 2;
165 scaled_height = clipped_height / 2; 173 scaled_height = clipped_height / 2;
166 break; 174 break;
167 175
168 case 1: 176 case 2:
169 default: // Assume 1:1 for stray view sizes 177 default: // Assume 1:1 for stray view sizes.
170 scaled_width = clipped_width; 178 scaled_width = clipped_width;
171 scaled_height = clipped_height; 179 scaled_height = clipped_height;
172 break; 180 break;
173 181
174 case 2: 182 case 3: // Double.
175 scaled_width = clipped_width; 183 scaled_width = clipped_width;
176 scaled_height = clipped_height; 184 scaled_height = clipped_height;
177 clipped_width = scaled_width / 2; 185 clipped_width = scaled_width / 2;
178 clipped_height = scaled_height / 2; 186 clipped_height = scaled_height / 2;
179 break; 187 break;
188
189 case 4: // Triple.
190 scaled_width = clipped_width;
191 scaled_height = clipped_height;
192 clipped_width = scaled_width / 3;
193 clipped_height = scaled_height / 3;
194 break;
195
196 case 5: // Quadruple.
197 scaled_width = clipped_width;
198 scaled_height = clipped_height;
199 clipped_width = scaled_width / 4;
200 clipped_height = scaled_height / 4;
201 break;
180 } 202 }
181 203
182 // Append each frame to end of file. 204 // Append each frame to end of file.
183 bool enable_dump_yuv_file = media::Movie::get()->GetDumpYuvFileEnable(); 205 bool enable_dump_yuv_file = media::Movie::get()->GetDumpYuvFileEnable();
184 if (enable_dump_yuv_file) { 206 if (enable_dump_yuv_file) {
185 DumpYUV(frame_in); 207 DumpYUV(frame_in);
186 } 208 }
187 209
188 #ifdef TESTING 210 #ifdef TESTING
189 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); 211 double yuv_time_start = GetTime(); // Start timer.
190 double yuvtimestart = GetTime(); // Start timer.
191 #endif 212 #endif
192 213
193 bool enable_draw = media::Movie::get()->GetDrawEnable(); 214 bool enable_draw = media::Movie::get()->GetDrawEnable();
194 if (enable_draw) { 215 if (enable_draw) {
216 #ifdef TEST_SWSCALER
195 bool enable_swscaler = media::Movie::get()->GetSwscalerEnable(); 217 bool enable_swscaler = media::Movie::get()->GetSwscalerEnable();
196 if (enable_swscaler) { 218 if (enable_swscaler) {
197 uint8* data_out[3]; 219 uint8* data_out[3];
198 int stride_out[3]; 220 int stride_out[3];
199 data_out[0] = movie_dib_bits; 221 data_out[0] = movie_dib_bits;
200 data_out[1] = NULL; 222 data_out[1] = NULL;
201 data_out[2] = NULL; 223 data_out[2] = NULL;
202 stride_out[0] = dibrowbytes; 224 stride_out[0] = dibrowbytes;
203 stride_out[1] = 0; 225 stride_out[1] = 0;
204 stride_out[2] = 0; 226 stride_out[2] = 0;
205 227
206 /*
207 if (!sws_context_) { 228 if (!sws_context_) {
208 DCHECK(frame_in.format == VideoSurface::YV12); 229 DCHECK(frame_in.format == VideoSurface::YV12);
209 int outtype = bm.bmBitsPixel == 32 ? PIX_FMT_RGB32 : PIX_FMT_RGB24;
210 sws_context_ = sws_getContext(frame_in.width, frame_in.height, 230 sws_context_ = sws_getContext(frame_in.width, frame_in.height,
211 PIX_FMT_YUV420P, width_, height_, 231 PIX_FMT_YUV420P, width_, height_,
212 outtype, SWS_FAST_BILINEAR, 232 PIX_FMT_RGB32, SWS_FAST_BILINEAR,
213 NULL, NULL, NULL); 233 NULL, NULL, NULL);
214 DCHECK(sws_context_); 234 DCHECK(sws_context_);
215 } 235 }
216 236
217 sws_scale(sws_context_, frame_in.data, frame_in.strides, 0, 237 sws_scale(sws_context_, frame_in.data, frame_in.strides, 0,
218 height_, data_out, stride_out); 238 height_, data_out, stride_out);
219 */
220 } else { 239 } else {
240 #endif
221 DCHECK(bm.bmBitsPixel == 32); 241 DCHECK(bm.bmBitsPixel == 32);
222 DrawYUV(frame_in, 242 DrawYUV(frame_in,
223 movie_dib_bits, 243 movie_dib_bits,
224 dibrowbytes, 244 dibrowbytes,
225 clipped_width, 245 clipped_width,
226 clipped_height, 246 clipped_height,
227 scaled_width, 247 scaled_width,
228 scaled_height); 248 scaled_height);
249 #ifdef TEST_SWSCALER
229 } 250 }
251 #endif
230 } 252 }
231 #ifdef TESTING 253 #ifdef TESTING
232 double yuvtimeend = GetTime(); // Start timer. 254 double yuv_time_end = GetTime();
233 SSetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); 255 static int yuv_time_count = 0;
234 static int yuvtimecount = 0; 256 static double yuv_time_sum = 0.;
235 static double yuvtimesum = 0; 257 if (!yuv_time_count)
236 yuvtimesum += yuvtimeend - yuvtimestart; 258 yuv_time_sum = 0.;
237 ++yuvtimecount; 259 yuv_time_sum += (yuv_time_end - yuv_time_start);
260 ++yuv_time_count;
238 261
239 char outputbuf[512]; 262 char outputbuf[512];
240 snprintf(outputbuf, sizeof(outputbuf), "yuv %.2fms avg %.2fms\n", 263 _snprintf_s(outputbuf, sizeof(outputbuf), "test %f", yuv_time_end);
241 yuvtimeend - yuvtimestart, yuvtimesum / yuvtimecount); 264 _snprintf_s(outputbuf, sizeof(outputbuf),
265 "yuv %5.2f ms avg %5.2f ms\n",
266 yuv_time_end - yuv_time_start,
267 yuv_time_sum / yuv_time_count);
242 OutputDebugStringA(outputbuf); 268 OutputDebugStringA(outputbuf);
243 #endif 269 #endif
244 } 270 }
245 271
246 void DoPaint(CDCHandle dc) { 272 void DoPaint(CDCHandle dc) {
247 AllocateVideoBitmap(dc); 273 AllocateVideoBitmap(dc);
248 if (!bmp_.IsNull()) { 274 if (!bmp_.IsNull()) {
249 scoped_refptr<media::VideoFrame> frame; 275 scoped_refptr<media::VideoFrame> frame;
250 renderer_->GetCurrentFrame(&frame); 276 renderer_->GetCurrentFrame(&frame);
251 if (frame.get()) { 277 if (frame.get()) {
(...skipping 14 matching lines...) Expand all
266 #endif 292 #endif
267 CDC dcMem; 293 CDC dcMem;
268 dcMem.CreateCompatibleDC(dc); 294 dcMem.CreateCompatibleDC(dc);
269 HBITMAP hBmpOld = hbmp_ ? hbmp_: dcMem.SelectBitmap(bmp_); 295 HBITMAP hBmpOld = hbmp_ ? hbmp_: dcMem.SelectBitmap(bmp_);
270 dc.BitBlt(0, 0, size_.cx, size_.cy, dcMem, 0, 0, SRCCOPY); 296 dc.BitBlt(0, 0, size_.cx, size_.cy, dcMem, 0, 0, SRCCOPY);
271 dcMem.SelectBitmap(hBmpOld); 297 dcMem.SelectBitmap(hBmpOld);
272 #ifdef TESTING 298 #ifdef TESTING
273 double paint_time_end = GetTime(); 299 double paint_time_end = GetTime();
274 static int paint_count = 0; 300 static int paint_count = 0;
275 static double paint_time_sum = 0; 301 static double paint_time_sum = 0;
276 paint_time_sum += paint_time_end-paint_time_start; 302 paint_time_sum += paint_time_end - paint_time_start;
277 ++paint_count; 303 ++paint_count;
278 char outputbuf[512]; 304 char outputbuf[512];
279 snprintf(outputbuf, sizeof(outputbuf), 305 _snprintf_s(outputbuf, sizeof(outputbuf),
280 "paint time %5.2fms blit %5.2fms avg %5.2fms\n", 306 "paint time %5.2f ms blit %5.2f ms avg %5.2f ms\n",
281 paint_time_start-paint_time_previous, 307 paint_time_start - paint_time_previous,
282 paint_time_end-paint_time_start, 308 paint_time_end - paint_time_start,
283 paint_time_sum/paint_count); 309 paint_time_sum / paint_count);
284 OutputDebugStringA(outputbuf); 310 OutputDebugStringA(outputbuf);
285 311
286 paint_time_previous = paint_time_start; 312 paint_time_previous = paint_time_start;
287 #endif 313 #endif
288 } 314 }
289 } // End of DoPaint function. 315 } // End of DoPaint function.
290 316
291 void SetViewSize(int view_size) { 317 void SetViewSize(int view_size) {
292 view_size_ = view_size; 318 view_size_ = view_size;
293 } 319 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 void SetBitmap(HBITMAP hbmp) { 375 void SetBitmap(HBITMAP hbmp) {
350 hbmp_ = hbmp; 376 hbmp_ = hbmp;
351 } 377 }
352 378
353 CBitmap bmp_; // Used by mainfrm.h. 379 CBitmap bmp_; // Used by mainfrm.h.
354 SIZE size_; // Used by WtlVideoWindow. 380 SIZE size_; // Used by WtlVideoWindow.
355 scoped_refptr<WtlVideoRenderer> renderer_; // Used by WtlVideoWindow. 381 scoped_refptr<WtlVideoRenderer> renderer_; // Used by WtlVideoWindow.
356 382
357 private: 383 private:
358 HBITMAP hbmp_; // For Images 384 HBITMAP hbmp_; // For Images
359 int view_size_; // View Size. 0=0.5, 1=normal, 2=2x, 3=fit, 4=full 385 // View Size: 0=1/4, 1=0.5, 2=normal, 3=2x, 4=3x, 5=4x, 3=fit, 4=full.
386 int view_size_;
360 387
361 // View Rotate 0-5 for ID_VIEW_ROTATE0 to ID_VIEW_MIRROR_VERTICAL 388 // View Rotate 0-5 for ID_VIEW_ROTATE0 to ID_VIEW_MIRROR_VERTICAL
362 media::Rotate view_rotate_; 389 media::Rotate view_rotate_;
363 390
364 // Draw a frame of YUV to an RGB buffer with scaling. 391 // Draw a frame of YUV to an RGB buffer with scaling.
365 // Handles different YUV formats. 392 // Handles different YUV formats.
366 void DrawYUV(const media::VideoSurface &frame_in, 393 void DrawYUV(const media::VideoSurface &frame_in,
367 uint8 *movie_dib_bits, 394 uint8 *movie_dib_bits,
368 int dibrowbytes, 395 int dibrowbytes,
369 int clipped_width, 396 int clipped_width,
370 int clipped_height, 397 int clipped_height,
371 int scaled_width, 398 int scaled_width,
372 int scaled_height) { 399 int scaled_height) {
373 if (frame_in.format == media::VideoSurface::YV16) { 400 media::YUVType yuv_type = (frame_in.format == media::VideoSurface::YV12) ?
374 // Temporary cast, til we use uint8 for VideoFrame. 401 media::YV12 : media::YV16;
375 media::ScaleYV16ToRGB32(frame_in.data[0], 402
376 frame_in.data[1], 403 // Simple convert is not necessary for performance, but allows
377 frame_in.data[2], 404 // easier alternative implementations.
378 movie_dib_bits, 405 if ((view_rotate_ == media::ROTATE_0) && // Not scaled or rotated
379 clipped_width, clipped_height, 406 (view_size_ == 2)) {
380 scaled_width, scaled_height, 407 media::ConvertYUVToRGB32(frame_in.data[0],
381 frame_in.strides[0], 408 frame_in.data[1],
382 frame_in.strides[1], 409 frame_in.data[2],
383 dibrowbytes, 410 movie_dib_bits,
384 view_rotate_); 411 scaled_width, scaled_height,
412 frame_in.strides[0],
413 frame_in.strides[1],
414 dibrowbytes,
415 yuv_type);
385 } else { 416 } else {
386 // Temporary cast, til we use uint8 for VideoFrame. 417 media::ScaleYUVToRGB32(frame_in.data[0],
387 media::ScaleYV12ToRGB32(frame_in.data[0], 418 frame_in.data[1],
388 frame_in.data[1], 419 frame_in.data[2],
389 frame_in.data[2], 420 movie_dib_bits,
390 movie_dib_bits, 421 clipped_width, clipped_height,
391 clipped_width, clipped_height, 422 scaled_width, scaled_height,
392 scaled_width, scaled_height, 423 frame_in.strides[0],
393 frame_in.strides[0], 424 frame_in.strides[1],
394 frame_in.strides[1], 425 dibrowbytes,
395 dibrowbytes, 426 yuv_type,
396 view_rotate_); 427 view_rotate_);
397 } 428 }
398 } 429 }
399 430
400 // Diagnostic function to write out YUV in format compatible with PYUV tool. 431 // Diagnostic function to write out YUV in format compatible with PYUV tool.
401 void DumpYUV(const media::VideoSurface &frame_in) { 432 void DumpYUV(const media::VideoSurface &frame_in) {
402 FILE * file_yuv = fopen("raw.yuv", "ab+"); // Open for append binary. 433 FILE * file_yuv = fopen("raw.yuv", "ab+"); // Open for append binary.
403 if (file_yuv != NULL) { 434 if (file_yuv != NULL) {
404 fseek(file_yuv, 0, SEEK_END); 435 fseek(file_yuv, 0, SEEK_END);
405 const size_t frame_size = frame_in.width * frame_in.height; 436 const size_t frame_size = frame_in.width * frame_in.height;
406 for (size_t y = 0; y < frame_in.height; ++y) 437 for (size_t y = 0; y < frame_in.height; ++y)
407 fwrite(frame_in.data[0]+frame_in.strides[0]*y, 438 fwrite(frame_in.data[0]+frame_in.strides[0]*y,
408 frame_in.width, sizeof(uint8), file_yuv); 439 frame_in.width, sizeof(uint8), file_yuv);
409 for (size_t y = 0; y < frame_in.height/2; ++y) 440 for (size_t y = 0; y < frame_in.height/2; ++y)
410 fwrite(frame_in.data[1]+frame_in.strides[1]*y, 441 fwrite(frame_in.data[1]+frame_in.strides[1]*y,
411 frame_in.width/2, sizeof(uint8), file_yuv); 442 frame_in.width/2, sizeof(uint8), file_yuv);
412 for (size_t y = 0; y < frame_in.height/2; ++y) 443 for (size_t y = 0; y < frame_in.height/2; ++y)
413 fwrite(frame_in.data[2]+frame_in.strides[2]*y, 444 fwrite(frame_in.data[2]+frame_in.strides[2]*y,
414 frame_in.width/2, sizeof(uint8), file_yuv); 445 frame_in.width/2, sizeof(uint8), file_yuv);
415 fclose(file_yuv); 446 fclose(file_yuv);
416 447
417 #if TESTING 448 #if TESTING
418 static int frame_dump_count = 0; 449 static int frame_dump_count = 0;
419 char outputbuf[512]; 450 char outputbuf[512];
420 snprintf(outputbuf, sizeof(outputbuf), "yuvdump %4d %dx%d stride %d\n", 451 _snprintf_s(outputbuf, sizeof(outputbuf), "yuvdump %4d %dx%d stride %d\n",
421 frame_dump_count, frame_in.width, frame_in.height, 452 frame_dump_count, frame_in.width, frame_in.height,
422 frame_in.strides[0]); 453 frame_in.strides[0]);
423 OutputDebugStringA(outputbuf); 454 OutputDebugStringA(outputbuf);
424 ++frame_dump_count; 455 ++frame_dump_count;
425 #endif 456 #endif
426 } 457 }
427 } 458 }
428 459
429 media::VideoFrame* last_frame_; 460 media::VideoFrame* last_frame_;
430 base::TimeDelta last_timestamp_; 461 base::TimeDelta last_timestamp_;
431 462
432 DISALLOW_COPY_AND_ASSIGN(WtlVideoWindow); 463 DISALLOW_COPY_AND_ASSIGN(WtlVideoWindow);
433 }; 464 };
434 465
435 #endif // MEDIA_PLAYER_VIEW_H_ 466 #endif // MEDIA_PLAYER_VIEW_H_
436 467
OLDNEW
« no previous file with comments | « media/player/resource.h ('k') | media/test/data/bali.yv12.640_360.rgb » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698