OLD | NEW |
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 #include "chrome/browser/renderer_host/video_layer_x.h" | 5 #include "chrome/browser/renderer_host/video_layer_x.h" |
6 | 6 |
7 #include "app/x11_util_internal.h" | 7 #include "app/x11_util_internal.h" |
8 #include "chrome/browser/renderer_host/render_process_host.h" | 8 #include "chrome/browser/renderer_host/render_process_host.h" |
9 #include "media/base/yuv_convert.h" | 9 #include "media/base/yuv_convert.h" |
10 | 10 |
| 11 |
| 12 // Assume that somewhere along the line, someone will do width * height * 4 |
| 13 // with signed numbers. If the maximum value is 2**31, then 2**31 / 4 = |
| 14 // 2**29 and floor(sqrt(2**29)) = 23170. |
| 15 |
| 16 // Max height and width for layers |
| 17 static const int kMaxVideoLayerSize = 23170; |
| 18 |
11 VideoLayerX::VideoLayerX(RenderWidgetHost* widget, | 19 VideoLayerX::VideoLayerX(RenderWidgetHost* widget, |
12 const gfx::Size& size, | 20 const gfx::Size& size, |
13 void* visual, | 21 void* visual, |
14 int depth) | 22 int depth) |
15 : VideoLayer(widget, size), | 23 : VideoLayer(widget, size), |
16 visual_(visual), | 24 visual_(visual), |
17 depth_(depth), | 25 depth_(depth), |
18 display_(x11_util::GetXDisplay()) { | 26 display_(x11_util::GetXDisplay()), |
| 27 rgb_frame_size_(0) { |
19 DCHECK(!size.IsEmpty()); | 28 DCHECK(!size.IsEmpty()); |
20 | 29 |
21 // Create our pixmap + GC representing an RGB version of a video frame. | 30 // Create our pixmap + GC representing an RGB version of a video frame. |
22 pixmap_ = XCreatePixmap(display_, x11_util::GetX11RootWindow(), | 31 pixmap_ = XCreatePixmap(display_, x11_util::GetX11RootWindow(), |
23 size.width(), size.height(), depth_); | 32 size.width(), size.height(), depth_); |
24 pixmap_gc_ = XCreateGC(display_, pixmap_, 0, NULL); | 33 pixmap_gc_ = XCreateGC(display_, pixmap_, 0, NULL); |
25 pixmap_bpp_ = x11_util::BitsPerPixelForPixmapDepth(display_, depth_); | 34 pixmap_bpp_ = x11_util::BitsPerPixelForPixmapDepth(display_, depth_); |
26 } | 35 } |
27 | 36 |
28 VideoLayerX::~VideoLayerX() { | 37 VideoLayerX::~VideoLayerX() { |
(...skipping 15 matching lines...) Expand all Loading... |
44 return; | 53 return; |
45 | 54 |
46 if (bitmap_rect.size() != size()) { | 55 if (bitmap_rect.size() != size()) { |
47 LOG(ERROR) << "Scaled video layer not supported."; | 56 LOG(ERROR) << "Scaled video layer not supported."; |
48 return; | 57 return; |
49 } | 58 } |
50 | 59 |
51 // Save location and size of destination bitmap. | 60 // Save location and size of destination bitmap. |
52 rgb_rect_ = bitmap_rect; | 61 rgb_rect_ = bitmap_rect; |
53 | 62 |
| 63 const int width = bitmap_rect.width(); |
| 64 const int height = bitmap_rect.height(); |
| 65 const size_t new_rgb_frame_size = static_cast<size_t>(width * height * 4); |
| 66 |
| 67 if (width <= 0 || width > kMaxVideoLayerSize || |
| 68 height <= 0 || height > kMaxVideoLayerSize) |
| 69 return; |
| 70 |
54 // Lazy allocate |rgb_frame_|. | 71 // Lazy allocate |rgb_frame_|. |
55 if (!rgb_frame_.get()) { | 72 if (!rgb_frame_.get() || rgb_frame_size_ < new_rgb_frame_size) { |
56 // TODO(scherkus): handle changing dimensions and re-allocating. | 73 // TODO(scherkus): handle changing dimensions and re-allocating. |
57 CHECK(size() == rgb_rect_.size()); | 74 CHECK(size() == rgb_rect_.size()); |
58 | 75 rgb_frame_.reset(new uint8[new_rgb_frame_size]); |
59 rgb_frame_.reset(new uint8[rgb_rect_.width() * rgb_rect_.height() * 4]); | 76 rgb_frame_size_ = new_rgb_frame_size; |
60 } | 77 } |
61 | 78 |
62 const int width = bitmap_rect.width(); | |
63 const int height = bitmap_rect.height(); | |
64 // Assume that somewhere along the line, someone will do width * height * 4 | |
65 // with signed numbers. If the maximum value is 2**31, then 2**31 / 4 = | |
66 // 2**29 and floor(sqrt(2**29)) = 23170. | |
67 if (width > 23170 || height > 23170) | |
68 return; | |
69 | |
70 TransportDIB* dib = process->GetTransportDIB(bitmap); | 79 TransportDIB* dib = process->GetTransportDIB(bitmap); |
71 if (!dib) | 80 if (!dib) |
72 return; | 81 return; |
73 | 82 |
74 // Perform colour space conversion. | 83 // Perform colour space conversion. |
75 const uint8* y_plane = reinterpret_cast<uint8*>(dib->memory()); | 84 const uint8* y_plane = reinterpret_cast<uint8*>(dib->memory()); |
76 const uint8* u_plane = y_plane + width * height; | 85 const uint8* u_plane = y_plane + width * height; |
77 const uint8* v_plane = u_plane + ((width * height) >> 2); | 86 const uint8* v_plane = u_plane + ((width * height) >> 2); |
78 media::ConvertYUVToRGB32(y_plane, | 87 media::ConvertYUVToRGB32(y_plane, |
79 u_plane, | 88 u_plane, |
(...skipping 12 matching lines...) Expand all Loading... |
92 } | 101 } |
93 | 102 |
94 void VideoLayerX::XShow(XID target) { | 103 void VideoLayerX::XShow(XID target) { |
95 if (rgb_rect_.IsEmpty()) | 104 if (rgb_rect_.IsEmpty()) |
96 return; | 105 return; |
97 | 106 |
98 XCopyArea(display_, pixmap_, target, static_cast<GC>(pixmap_gc_), | 107 XCopyArea(display_, pixmap_, target, static_cast<GC>(pixmap_gc_), |
99 0, 0, rgb_rect_.width(), rgb_rect_.height(), | 108 0, 0, rgb_rect_.width(), rgb_rect_.height(), |
100 rgb_rect_.x(), rgb_rect_.y()); | 109 rgb_rect_.x(), rgb_rect_.y()); |
101 } | 110 } |
OLD | NEW |