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

Side by Side Diff: webkit/glue/media/video_renderer_impl.cc

Issue 1226001: Merged VideoSurface, VideoFrame and VideoFrameImpl in VideoFrame. (Closed)
Patch Set: Created 10 years, 9 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
« no previous file with comments | « media/tools/player_x11/x11_video_renderer.cc ('k') | no next file » | 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) 2010 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 "media/base/buffers.h" 5 #include "media/base/video_frame.h"
6 #include "media/base/yuv_convert.h" 6 #include "media/base/yuv_convert.h"
7 #include "webkit/glue/media/video_renderer_impl.h" 7 #include "webkit/glue/media/video_renderer_impl.h"
8 #include "webkit/glue/webmediaplayer_impl.h" 8 #include "webkit/glue/webmediaplayer_impl.h"
9 9
10 namespace webkit_glue { 10 namespace webkit_glue {
11 11
12 VideoRendererImpl::VideoRendererImpl(WebMediaPlayerImpl::Proxy* proxy) 12 VideoRendererImpl::VideoRendererImpl(WebMediaPlayerImpl::Proxy* proxy)
13 : proxy_(proxy), 13 : proxy_(proxy),
14 last_converted_frame_(NULL) { 14 last_converted_frame_(NULL) {
15 // TODO(hclam): decide whether to do the following line in this thread or 15 // TODO(hclam): decide whether to do the following line in this thread or
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 122
123 void VideoRendererImpl::SlowPaint(media::VideoFrame* video_frame, 123 void VideoRendererImpl::SlowPaint(media::VideoFrame* video_frame,
124 skia::PlatformCanvas* canvas, 124 skia::PlatformCanvas* canvas,
125 const gfx::Rect& dest_rect) { 125 const gfx::Rect& dest_rect) {
126 // 1. Convert YUV frame to RGB. 126 // 1. Convert YUV frame to RGB.
127 base::TimeDelta timestamp = video_frame->GetTimestamp(); 127 base::TimeDelta timestamp = video_frame->GetTimestamp();
128 if (video_frame != last_converted_frame_ || 128 if (video_frame != last_converted_frame_ ||
129 timestamp != last_converted_timestamp_) { 129 timestamp != last_converted_timestamp_) {
130 last_converted_frame_ = video_frame; 130 last_converted_frame_ = video_frame;
131 last_converted_timestamp_ = timestamp; 131 last_converted_timestamp_ = timestamp;
132 media::VideoSurface frame_in; 132 DCHECK(video_frame->format() == media::VideoFrame::YV12 ||
133 if (video_frame->Lock(&frame_in)) { 133 video_frame->format() == media::VideoFrame::YV16);
134 DCHECK(frame_in.format == media::VideoSurface::YV12 || 134 DCHECK(video_frame->stride(media::VideoFrame::kUPlane) ==
135 frame_in.format == media::VideoSurface::YV16); 135 video_frame->stride(media::VideoFrame::kVPlane));
136 DCHECK(frame_in.strides[media::VideoSurface::kUPlane] == 136 DCHECK(video_frame->planes() == media::VideoFrame::kNumYUVPlanes);
137 frame_in.strides[media::VideoSurface::kVPlane]); 137 bitmap_.lockPixels();
138 DCHECK(frame_in.planes == media::VideoSurface::kNumYUVPlanes); 138 media::YUVType yuv_type =
139 bitmap_.lockPixels(); 139 (video_frame->format() == media::VideoFrame::YV12) ?
140 media::YUVType yuv_type = (frame_in.format == media::VideoSurface::YV12) ? 140 media::YV12 : media::YV16;
141 media::YV12 : media::YV16; 141 media::ConvertYUVToRGB32(video_frame->data(media::VideoFrame::kYPlane),
142 media::ConvertYUVToRGB32(frame_in.data[media::VideoSurface::kYPlane], 142 video_frame->data(media::VideoFrame::kUPlane),
143 frame_in.data[media::VideoSurface::kUPlane], 143 video_frame->data(media::VideoFrame::kVPlane),
144 frame_in.data[media::VideoSurface::kVPlane], 144 static_cast<uint8*>(bitmap_.getPixels()),
145 static_cast<uint8*>(bitmap_.getPixels()), 145 video_frame->width(),
146 frame_in.width, 146 video_frame->height(),
147 frame_in.height, 147 video_frame->stride(media::VideoFrame::kYPlane),
148 frame_in.strides[media::VideoSurface::kYPlane], 148 video_frame->stride(media::VideoFrame::kUPlane),
149 frame_in.strides[media::VideoSurface::kUPlane], 149 bitmap_.rowBytes(),
150 bitmap_.rowBytes(), 150 yuv_type);
151 yuv_type); 151 bitmap_.unlockPixels();
152 bitmap_.unlockPixels();
153 video_frame->Unlock();
154 } else {
155 NOTREACHED();
156 }
157 } 152 }
158 153
159 // 2. Paint the bitmap to canvas. 154 // 2. Paint the bitmap to canvas.
160 SkMatrix matrix; 155 SkMatrix matrix;
161 matrix.setTranslate(static_cast<SkScalar>(dest_rect.x()), 156 matrix.setTranslate(static_cast<SkScalar>(dest_rect.x()),
162 static_cast<SkScalar>(dest_rect.y())); 157 static_cast<SkScalar>(dest_rect.y()));
163 if (dest_rect.width() != video_size_.width() || 158 if (dest_rect.width() != video_size_.width() ||
164 dest_rect.height() != video_size_.height()) { 159 dest_rect.height() != video_size_.height()) {
165 matrix.preScale(SkIntToScalar(dest_rect.width()) / 160 matrix.preScale(SkIntToScalar(dest_rect.width()) /
166 SkIntToScalar(video_size_.width()), 161 SkIntToScalar(video_size_.width()),
167 SkIntToScalar(dest_rect.height()) / 162 SkIntToScalar(dest_rect.height()) /
168 SkIntToScalar(video_size_.height())); 163 SkIntToScalar(video_size_.height()));
169 } 164 }
170 canvas->drawBitmapMatrix(bitmap_, matrix, NULL); 165 canvas->drawBitmapMatrix(bitmap_, matrix, NULL);
171 } 166 }
172 167
173 void VideoRendererImpl::FastPaint(media::VideoFrame* video_frame, 168 void VideoRendererImpl::FastPaint(media::VideoFrame* video_frame,
174 skia::PlatformCanvas* canvas, 169 skia::PlatformCanvas* canvas,
175 const gfx::Rect& dest_rect) { 170 const gfx::Rect& dest_rect) {
176 media::VideoSurface frame_in; 171 DCHECK(video_frame->format() == media::VideoFrame::YV12 ||
177 if (video_frame->Lock(&frame_in)) { 172 video_frame->format() == media::VideoFrame::YV16);
178 DCHECK(frame_in.format == media::VideoSurface::YV12 || 173 DCHECK(video_frame->stride(media::VideoFrame::kUPlane) ==
179 frame_in.format == media::VideoSurface::YV16); 174 video_frame->stride(media::VideoFrame::kVPlane));
180 DCHECK(frame_in.strides[media::VideoSurface::kUPlane] == 175 DCHECK(video_frame->planes() == media::VideoFrame::kNumYUVPlanes);
181 frame_in.strides[media::VideoSurface::kVPlane]); 176 const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(true);
182 DCHECK(frame_in.planes == media::VideoSurface::kNumYUVPlanes); 177 media::YUVType yuv_type = (video_frame->format() == media::VideoFrame::YV12) ?
183 const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(true); 178 media::YV12 : media::YV16;
184 media::YUVType yuv_type = (frame_in.format == media::VideoSurface::YV12) ? 179 int y_shift = yuv_type; // 1 for YV12, 0 for YV16.
185 media::YV12 : media::YV16;
186 int y_shift = yuv_type; // 1 for YV12, 0 for YV16.
187 180
188 // Create a rectangle backed by SkScalar. 181 // Create a rectangle backed by SkScalar.
189 SkRect scalar_dest_rect; 182 SkRect scalar_dest_rect;
190 scalar_dest_rect.iset(dest_rect.x(), dest_rect.y(), 183 scalar_dest_rect.iset(dest_rect.x(), dest_rect.y(),
191 dest_rect.right(), dest_rect.bottom()); 184 dest_rect.right(), dest_rect.bottom());
192 185
193 // Transform the destination rectangle to local coordinates. 186 // Transform the destination rectangle to local coordinates.
194 const SkMatrix& local_matrix = canvas->getTotalMatrix(); 187 const SkMatrix& local_matrix = canvas->getTotalMatrix();
195 SkRect local_dest_rect; 188 SkRect local_dest_rect;
196 local_matrix.mapRect(&local_dest_rect, scalar_dest_rect); 189 local_matrix.mapRect(&local_dest_rect, scalar_dest_rect);
197 190
198 // After projecting the destination rectangle to local coordinates, round 191 // After projecting the destination rectangle to local coordinates, round
199 // the projected rectangle to integer values, this will give us pixel values 192 // the projected rectangle to integer values, this will give us pixel values
200 // of the rectangle. 193 // of the rectangle.
201 SkIRect local_dest_irect, local_dest_irect_saved; 194 SkIRect local_dest_irect, local_dest_irect_saved;
202 local_dest_rect.round(&local_dest_irect); 195 local_dest_rect.round(&local_dest_irect);
203 local_dest_rect.round(&local_dest_irect_saved); 196 local_dest_rect.round(&local_dest_irect_saved);
204 197
205 // Only does the paint if the destination rect intersects with the clip 198 // Only does the paint if the destination rect intersects with the clip
206 // rect. 199 // rect.
207 if (local_dest_irect.intersect(canvas->getTotalClip().getBounds())) { 200 if (local_dest_irect.intersect(canvas->getTotalClip().getBounds())) {
208 // At this point |local_dest_irect| contains the rect that we should draw 201 // At this point |local_dest_irect| contains the rect that we should draw
209 // to within the clipping rect. 202 // to within the clipping rect.
210 203
211 // Calculate the address for the top left corner of destination rect in 204 // Calculate the address for the top left corner of destination rect in
212 // the canvas that we will draw to. The address is obtained by the base 205 // the canvas that we will draw to. The address is obtained by the base
213 // address of the canvas shifted by "left" and "top" of the rect. 206 // address of the canvas shifted by "left" and "top" of the rect.
214 uint8* dest_rect_pointer = static_cast<uint8*>(bitmap.getPixels()) + 207 uint8* dest_rect_pointer = static_cast<uint8*>(bitmap.getPixels()) +
215 local_dest_irect.fTop * bitmap.rowBytes() + 208 local_dest_irect.fTop * bitmap.rowBytes() +
216 local_dest_irect.fLeft * 4; 209 local_dest_irect.fLeft * 4;
217 210
218 // Project the clip rect to the original video frame, obtains the 211 // Project the clip rect to the original video frame, obtains the
219 // dimensions of the projected clip rect, "left" and "top" of the rect. 212 // dimensions of the projected clip rect, "left" and "top" of the rect.
220 // The math here are all integer math so we won't have rounding error and 213 // The math here are all integer math so we won't have rounding error and
221 // write outside of the canvas. 214 // write outside of the canvas.
222 // We have the assumptions of dest_rect.width() and dest_rect.height() 215 // We have the assumptions of dest_rect.width() and dest_rect.height()
223 // being non-zero, these are valid assumptions since finding intersection 216 // being non-zero, these are valid assumptions since finding intersection
224 // above rejects empty rectangle so we just do a DCHECK here. 217 // above rejects empty rectangle so we just do a DCHECK here.
225 DCHECK_NE(0, dest_rect.width()); 218 DCHECK_NE(0, dest_rect.width());
226 DCHECK_NE(0, dest_rect.height()); 219 DCHECK_NE(0, dest_rect.height());
227 size_t frame_clip_width = local_dest_irect.width() * 220 size_t frame_clip_width = local_dest_irect.width() *
228 frame_in.width / 221 video_frame->width() / local_dest_irect_saved.width();
229 local_dest_irect_saved.width(); 222 size_t frame_clip_height = local_dest_irect.height() *
230 size_t frame_clip_height = local_dest_irect.height() * 223 video_frame->height() / local_dest_irect_saved.height();
231 frame_in.height /
232 local_dest_irect_saved.height();
233 224
234 // Project the "left" and "top" of the final destination rect to local 225 // Project the "left" and "top" of the final destination rect to local
235 // coordinates of the video frame, use these values to find the offsets 226 // coordinates of the video frame, use these values to find the offsets
236 // in the video frame to start reading. 227 // in the video frame to start reading.
237 size_t frame_clip_left = (local_dest_irect.fLeft - 228 size_t frame_clip_left =
238 local_dest_irect_saved.fLeft) * 229 (local_dest_irect.fLeft - local_dest_irect_saved.fLeft) *
239 frame_in.width / 230 video_frame->width() / local_dest_irect_saved.width();
240 local_dest_irect_saved.width(); 231 size_t frame_clip_top =
241 size_t frame_clip_top = (local_dest_irect.fTop - 232 (local_dest_irect.fTop - local_dest_irect_saved.fTop) *
242 local_dest_irect_saved.fTop) * 233 video_frame->height() / local_dest_irect_saved.height();
243 frame_in.height /
244 local_dest_irect_saved.height();
245 234
246 // Use the "left" and "top" of the destination rect to locate the offset 235 // Use the "left" and "top" of the destination rect to locate the offset
247 // in Y, U and V planes. 236 // in Y, U and V planes.
248 size_t y_offset = frame_in.strides[media::VideoSurface::kYPlane] * 237 size_t y_offset = video_frame->stride(media::VideoFrame::kYPlane) *
249 frame_clip_top + frame_clip_left; 238 frame_clip_top + frame_clip_left;
250 // For format YV12, there is one U, V value per 2x2 block. 239 // For format YV12, there is one U, V value per 2x2 block.
251 // For format YV16, there is one u, V value per 2x1 block. 240 // For format YV16, there is one u, V value per 2x1 block.
252 size_t uv_offset = (frame_in.strides[media::VideoSurface::kUPlane] * 241 size_t uv_offset = (video_frame->stride(media::VideoFrame::kUPlane) *
253 (frame_clip_top >> y_shift)) + 242 (frame_clip_top >> y_shift)) + (frame_clip_left >> 1);
254 (frame_clip_left >> 1); 243 uint8* frame_clip_y =
255 uint8* frame_clip_y = frame_in.data[media::VideoSurface::kYPlane] + 244 video_frame->data(media::VideoFrame::kYPlane) + y_offset;
256 y_offset; 245 uint8* frame_clip_u =
257 uint8* frame_clip_u = frame_in.data[media::VideoSurface::kUPlane] + 246 video_frame->data(media::VideoFrame::kUPlane) + uv_offset;
258 uv_offset; 247 uint8* frame_clip_v =
259 uint8* frame_clip_v = frame_in.data[media::VideoSurface::kVPlane] + 248 video_frame->data(media::VideoFrame::kVPlane) + uv_offset;
260 uv_offset; 249 bitmap.lockPixels();
261 bitmap.lockPixels();
262 250
263 // TODO(hclam): do rotation and mirroring here. 251 // TODO(hclam): do rotation and mirroring here.
264 media::ScaleYUVToRGB32(frame_clip_y, 252 media::ScaleYUVToRGB32(frame_clip_y,
265 frame_clip_u, 253 frame_clip_u,
266 frame_clip_v, 254 frame_clip_v,
267 dest_rect_pointer, 255 dest_rect_pointer,
268 frame_clip_width, 256 frame_clip_width,
269 frame_clip_height, 257 frame_clip_height,
270 local_dest_irect.width(), 258 local_dest_irect.width(),
271 local_dest_irect.height(), 259 local_dest_irect.height(),
272 frame_in.strides[media::VideoSurface::kYPlane], 260 video_frame->stride(media::VideoFrame::kYPlane),
273 frame_in.strides[media::VideoSurface::kUPlane], 261 video_frame->stride(media::VideoFrame::kUPlane),
274 bitmap.rowBytes(), 262 bitmap.rowBytes(),
275 yuv_type, 263 yuv_type,
276 media::ROTATE_0); 264 media::ROTATE_0);
277 bitmap.unlockPixels(); 265 bitmap.unlockPixels();
278 }
279 video_frame->Unlock();
280 } else {
281 NOTREACHED();
282 } 266 }
283 } 267 }
284 268
285 void VideoRendererImpl::TransformToSkIRect(const SkMatrix& matrix, 269 void VideoRendererImpl::TransformToSkIRect(const SkMatrix& matrix,
286 const gfx::Rect& src_rect, 270 const gfx::Rect& src_rect,
287 SkIRect* dest_rect) { 271 SkIRect* dest_rect) {
288 // Transform destination rect to local coordinates. 272 // Transform destination rect to local coordinates.
289 SkRect transformed_rect; 273 SkRect transformed_rect;
290 SkRect skia_dest_rect; 274 SkRect skia_dest_rect;
291 skia_dest_rect.iset(src_rect.x(), src_rect.y(), 275 skia_dest_rect.iset(src_rect.x(), src_rect.y(),
292 src_rect.right(), src_rect.bottom()); 276 src_rect.right(), src_rect.bottom());
293 matrix.mapRect(&transformed_rect, skia_dest_rect); 277 matrix.mapRect(&transformed_rect, skia_dest_rect);
294 transformed_rect.round(dest_rect); 278 transformed_rect.round(dest_rect);
295 } 279 }
296 280
297 } // namespace webkit_glue 281 } // namespace webkit_glue
OLDNEW
« no previous file with comments | « media/tools/player_x11/x11_video_renderer.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698