OLD | NEW |
---|---|
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 #include "chrome/renderer/media/video_renderer_impl.h" | 5 #include "chrome/renderer/media/video_renderer_impl.h" |
6 #include "media/base/buffers.h" | 6 #include "media/base/buffers.h" |
7 #include "media/base/yuv_convert.h" | 7 #include "media/base/yuv_convert.h" |
8 | 8 |
9 VideoRendererImpl::VideoRendererImpl(WebMediaPlayerImpl* delegate) | 9 VideoRendererImpl::VideoRendererImpl(WebMediaPlayerImpl* delegate) |
10 : delegate_(delegate), | 10 : delegate_(delegate), |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 skia::PlatformCanvas* canvas, | 102 skia::PlatformCanvas* canvas, |
103 const gfx::Rect& dest_rect) { | 103 const gfx::Rect& dest_rect) { |
104 // 1. Convert YUV frame to RGB. | 104 // 1. Convert YUV frame to RGB. |
105 base::TimeDelta timestamp = video_frame->GetTimestamp(); | 105 base::TimeDelta timestamp = video_frame->GetTimestamp(); |
106 if (video_frame != last_converted_frame_ || | 106 if (video_frame != last_converted_frame_ || |
107 timestamp != last_converted_timestamp_) { | 107 timestamp != last_converted_timestamp_) { |
108 last_converted_frame_ = video_frame; | 108 last_converted_frame_ = video_frame; |
109 last_converted_timestamp_ = timestamp; | 109 last_converted_timestamp_ = timestamp; |
110 media::VideoSurface frame_in; | 110 media::VideoSurface frame_in; |
111 if (video_frame->Lock(&frame_in)) { | 111 if (video_frame->Lock(&frame_in)) { |
112 // TODO(hclam): Support more video formats than just YV12. | 112 DCHECK(frame_in.format == media::VideoSurface::YV12 || |
113 DCHECK(frame_in.format == media::VideoSurface::YV12); | 113 frame_in.format == media::VideoSurface::YV16); |
114 DCHECK(frame_in.strides[media::VideoSurface::kUPlane] == | 114 DCHECK(frame_in.strides[media::VideoSurface::kUPlane] == |
115 frame_in.strides[media::VideoSurface::kVPlane]); | 115 frame_in.strides[media::VideoSurface::kVPlane]); |
116 DCHECK(frame_in.planes == media::VideoSurface::kNumYUVPlanes); | 116 DCHECK(frame_in.planes == media::VideoSurface::kNumYUVPlanes); |
117 bitmap_.lockPixels(); | 117 bitmap_.lockPixels(); |
118 media::YUVType yuv_type = (frame_in.format == media::VideoSurface::YV12) ? | |
119 media::YV12 : media::YV16; | |
118 media::ConvertYUVToRGB32(frame_in.data[media::VideoSurface::kYPlane], | 120 media::ConvertYUVToRGB32(frame_in.data[media::VideoSurface::kYPlane], |
119 frame_in.data[media::VideoSurface::kUPlane], | 121 frame_in.data[media::VideoSurface::kUPlane], |
120 frame_in.data[media::VideoSurface::kVPlane], | 122 frame_in.data[media::VideoSurface::kVPlane], |
121 static_cast<uint8*>(bitmap_.getPixels()), | 123 static_cast<uint8*>(bitmap_.getPixels()), |
122 frame_in.width, | 124 frame_in.width, |
123 frame_in.height, | 125 frame_in.height, |
124 frame_in.strides[media::VideoSurface::kYPlane], | 126 frame_in.strides[media::VideoSurface::kYPlane], |
125 frame_in.strides[media::VideoSurface::kUPlane], | 127 frame_in.strides[media::VideoSurface::kUPlane], |
126 bitmap_.rowBytes(), | 128 bitmap_.rowBytes(), |
127 media::YV12); | 129 yuv_type); |
128 bitmap_.unlockPixels(); | 130 bitmap_.unlockPixels(); |
129 video_frame->Unlock(); | 131 video_frame->Unlock(); |
130 } else { | 132 } else { |
131 NOTREACHED(); | 133 NOTREACHED(); |
132 } | 134 } |
133 } | 135 } |
134 | 136 |
135 // 2. Paint the bitmap to canvas. | 137 // 2. Paint the bitmap to canvas. |
136 SkMatrix matrix; | 138 SkMatrix matrix; |
137 matrix.setTranslate(static_cast<SkScalar>(dest_rect.x()), | 139 matrix.setTranslate(static_cast<SkScalar>(dest_rect.x()), |
138 static_cast<SkScalar>(dest_rect.y())); | 140 static_cast<SkScalar>(dest_rect.y())); |
139 if (dest_rect.width() != video_size_.width() || | 141 if (dest_rect.width() != video_size_.width() || |
140 dest_rect.height() != video_size_.height()) { | 142 dest_rect.height() != video_size_.height()) { |
141 matrix.preScale(SkIntToScalar(dest_rect.width()) / | 143 matrix.preScale(SkIntToScalar(dest_rect.width()) / |
142 SkIntToScalar(video_size_.width()), | 144 SkIntToScalar(video_size_.width()), |
143 SkIntToScalar(dest_rect.height()) / | 145 SkIntToScalar(dest_rect.height()) / |
144 SkIntToScalar(video_size_.height())); | 146 SkIntToScalar(video_size_.height())); |
145 } | 147 } |
146 canvas->drawBitmapMatrix(bitmap_, matrix, NULL); | 148 canvas->drawBitmapMatrix(bitmap_, matrix, NULL); |
147 } | 149 } |
148 | 150 |
149 void VideoRendererImpl::FastPaint(media::VideoFrame* video_frame, | 151 void VideoRendererImpl::FastPaint(media::VideoFrame* video_frame, |
150 skia::PlatformCanvas* canvas, | 152 skia::PlatformCanvas* canvas, |
151 const gfx::Rect& dest_rect) { | 153 const gfx::Rect& dest_rect) { |
152 media::VideoSurface frame_in; | 154 media::VideoSurface frame_in; |
153 if (video_frame->Lock(&frame_in)) { | 155 if (video_frame->Lock(&frame_in)) { |
154 // TODO(hclam): Support more video formats than just YV12. | 156 DCHECK(frame_in.format == media::VideoSurface::YV12 || |
155 DCHECK(frame_in.format == media::VideoSurface::YV12); | 157 frame_in.format == media::VideoSurface::YV16); |
156 DCHECK(frame_in.strides[media::VideoSurface::kUPlane] == | 158 DCHECK(frame_in.strides[media::VideoSurface::kUPlane] == |
157 frame_in.strides[media::VideoSurface::kVPlane]); | 159 frame_in.strides[media::VideoSurface::kVPlane]); |
158 DCHECK(frame_in.planes == media::VideoSurface::kNumYUVPlanes); | 160 DCHECK(frame_in.planes == media::VideoSurface::kNumYUVPlanes); |
159 const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(true); | 161 const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(true); |
162 media::YUVType yuv_type = (frame_in.format == media::VideoSurface::YV12) ? | |
scherkus (not reviewing)
2009/05/28 01:35:15
we really should consider consolidating these two
fbarchard
2009/05/28 02:23:32
it does stand out as weird.
My longer term plan is
| |
163 media::YV12 : media::YV16; | |
164 int y_shift = yuv_type; // 1 for YV12, 0 for YV16. | |
160 | 165 |
161 // Create a rectangle backed by SkScalar. | 166 // Create a rectangle backed by SkScalar. |
162 SkRect scalar_dest_rect; | 167 SkRect scalar_dest_rect; |
163 scalar_dest_rect.iset(dest_rect.x(), dest_rect.y(), | 168 scalar_dest_rect.iset(dest_rect.x(), dest_rect.y(), |
164 dest_rect.right(), dest_rect.bottom()); | 169 dest_rect.right(), dest_rect.bottom()); |
165 | 170 |
166 // Transform the destination rectangle to local coordinates. | 171 // Transform the destination rectangle to local coordinates. |
167 const SkMatrix& local_matrix = canvas->getTotalMatrix(); | 172 const SkMatrix& local_matrix = canvas->getTotalMatrix(); |
168 SkRect local_dest_rect; | 173 SkRect local_dest_rect; |
169 local_matrix.mapRect(&local_dest_rect, scalar_dest_rect); | 174 local_matrix.mapRect(&local_dest_rect, scalar_dest_rect); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
209 local_dest_irect_saved.fLeft) * | 214 local_dest_irect_saved.fLeft) * |
210 frame_in.width / dest_rect.width(); | 215 frame_in.width / dest_rect.width(); |
211 size_t frame_clip_top = (local_dest_irect.fTop - | 216 size_t frame_clip_top = (local_dest_irect.fTop - |
212 local_dest_irect_saved.fTop) * | 217 local_dest_irect_saved.fTop) * |
213 frame_in.height / dest_rect.height(); | 218 frame_in.height / dest_rect.height(); |
214 | 219 |
215 // Use the "left" and "top" of the destination rect to locate the offset | 220 // Use the "left" and "top" of the destination rect to locate the offset |
216 // in Y, U and V planes. | 221 // in Y, U and V planes. |
217 size_t y_offset = frame_in.strides[media::VideoSurface::kYPlane] * | 222 size_t y_offset = frame_in.strides[media::VideoSurface::kYPlane] * |
218 frame_clip_top + frame_clip_left; | 223 frame_clip_top + frame_clip_left; |
219 // Since the format is YV12, there is one U, V value per 2x2 block, thus | 224 // For format YV12, there is one U, V value per 2x2 block. |
220 // the math here. | 225 // For format YV16, there is one u, V value per 2x1 block. |
221 // TODO(hclam): handle formats other than YV12. | 226 size_t uv_offset = (frame_in.strides[media::VideoSurface::kUPlane] * |
222 size_t uv_offset = frame_in.strides[media::VideoSurface::kUPlane] * | 227 (frame_clip_top >> y_shift)) + |
223 (frame_clip_top / 2) + frame_clip_left / 2; | 228 (frame_clip_left >> 1); |
224 uint8* frame_clip_y = frame_in.data[media::VideoSurface::kYPlane] + | 229 uint8* frame_clip_y = frame_in.data[media::VideoSurface::kYPlane] + |
225 y_offset; | 230 y_offset; |
226 uint8* frame_clip_u = frame_in.data[media::VideoSurface::kUPlane] + | 231 uint8* frame_clip_u = frame_in.data[media::VideoSurface::kUPlane] + |
227 uv_offset; | 232 uv_offset; |
228 uint8* frame_clip_v = frame_in.data[media::VideoSurface::kVPlane] + | 233 uint8* frame_clip_v = frame_in.data[media::VideoSurface::kVPlane] + |
229 uv_offset; | 234 uv_offset; |
230 bitmap.lockPixels(); | 235 bitmap.lockPixels(); |
236 | |
231 // TODO(hclam): do rotation and mirroring here. | 237 // TODO(hclam): do rotation and mirroring here. |
232 media::ScaleYUVToRGB32(frame_clip_y, | 238 media::ScaleYUVToRGB32(frame_clip_y, |
233 frame_clip_u, | 239 frame_clip_u, |
234 frame_clip_v, | 240 frame_clip_v, |
235 dest_rect_pointer, | 241 dest_rect_pointer, |
236 frame_clip_width, | 242 frame_clip_width, |
237 frame_clip_height, | 243 frame_clip_height, |
238 local_dest_irect.width(), | 244 local_dest_irect.width(), |
239 local_dest_irect.height(), | 245 local_dest_irect.height(), |
240 frame_in.strides[media::VideoSurface::kYPlane], | 246 frame_in.strides[media::VideoSurface::kYPlane], |
241 frame_in.strides[media::VideoSurface::kUPlane], | 247 frame_in.strides[media::VideoSurface::kUPlane], |
242 bitmap.rowBytes(), | 248 bitmap.rowBytes(), |
243 media::YV12, | 249 yuv_type, |
244 media::ROTATE_0); | 250 media::ROTATE_0); |
245 bitmap.unlockPixels(); | 251 bitmap.unlockPixels(); |
246 } | 252 } |
247 video_frame->Unlock(); | 253 video_frame->Unlock(); |
248 } else { | 254 } else { |
249 NOTREACHED(); | 255 NOTREACHED(); |
250 } | 256 } |
251 } | 257 } |
252 | 258 |
253 void VideoRendererImpl::TransformToSkIRect(const SkMatrix& matrix, | 259 void VideoRendererImpl::TransformToSkIRect(const SkMatrix& matrix, |
254 const gfx::Rect& src_rect, | 260 const gfx::Rect& src_rect, |
255 SkIRect* dest_rect) { | 261 SkIRect* dest_rect) { |
256 // Transform destination rect to local coordinates. | 262 // Transform destination rect to local coordinates. |
257 SkRect transformed_rect; | 263 SkRect transformed_rect; |
258 SkRect skia_dest_rect; | 264 SkRect skia_dest_rect; |
259 skia_dest_rect.iset(src_rect.x(), src_rect.y(), | 265 skia_dest_rect.iset(src_rect.x(), src_rect.y(), |
260 src_rect.right(), src_rect.bottom()); | 266 src_rect.right(), src_rect.bottom()); |
261 matrix.mapRect(&transformed_rect, skia_dest_rect); | 267 matrix.mapRect(&transformed_rect, skia_dest_rect); |
262 transformed_rect.round(dest_rect); | 268 transformed_rect.round(dest_rect); |
263 } | 269 } |
OLD | NEW |