Chromium Code Reviews| 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 |