| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "media/filters/skcanvas_video_renderer.h" | 5 #include "media/filters/skcanvas_video_renderer.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "media/base/video_frame.h" | 8 #include "media/base/video_frame.h" |
| 9 #include "media/base/yuv_convert.h" | 9 #include "media/base/yuv_convert.h" |
| 10 #include "third_party/skia/include/core/SkCanvas.h" | 10 #include "third_party/skia/include/core/SkCanvas.h" |
| 11 #include "third_party/skia/include/core/SkDevice.h" | 11 #include "third_party/skia/include/core/SkDevice.h" |
| 12 | 12 |
| 13 namespace media { | 13 namespace media { |
| 14 | 14 |
| 15 static bool IsEitherYV12OrYV16(media::VideoFrame::Format format) { | 15 static bool IsEitherYV12OrYV16(media::VideoFrame::Format format) { |
| 16 return format == media::VideoFrame::YV12 || format == media::VideoFrame::YV16; | 16 return format == media::VideoFrame::YV12 || |
| 17 format == media::VideoFrame::YV16 || |
| 18 format == media::VideoFrame::YV12J; |
| 17 } | 19 } |
| 18 | 20 |
| 19 static bool IsEitherYV12OrYV16OrNative(media::VideoFrame::Format format) { | 21 static bool IsEitherYV12OrYV16OrNative(media::VideoFrame::Format format) { |
| 20 return IsEitherYV12OrYV16(format) || | 22 return IsEitherYV12OrYV16(format) || |
| 21 format == media::VideoFrame::NATIVE_TEXTURE; | 23 format == media::VideoFrame::NATIVE_TEXTURE; |
| 22 } | 24 } |
| 23 | 25 |
| 24 static bool IsEitherYV12OrYV12AOrYV16(media::VideoFrame::Format format) { | 26 static bool IsEitherYV12OrYV12AOrYV16(media::VideoFrame::Format format) { |
| 25 return IsEitherYV12OrYV16(format) || | 27 return IsEitherYV12OrYV16(format) || |
| 26 format == media::VideoFrame::YV12A; | 28 format == media::VideoFrame::YV12A; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 static void FastPaint( | 75 static void FastPaint( |
| 74 const scoped_refptr<media::VideoFrame>& video_frame, | 76 const scoped_refptr<media::VideoFrame>& video_frame, |
| 75 SkCanvas* canvas, | 77 SkCanvas* canvas, |
| 76 const SkRect& dest_rect) { | 78 const SkRect& dest_rect) { |
| 77 DCHECK(IsEitherYV12OrYV16(video_frame->format())) << video_frame->format(); | 79 DCHECK(IsEitherYV12OrYV16(video_frame->format())) << video_frame->format(); |
| 78 DCHECK_EQ(video_frame->stride(media::VideoFrame::kUPlane), | 80 DCHECK_EQ(video_frame->stride(media::VideoFrame::kUPlane), |
| 79 video_frame->stride(media::VideoFrame::kVPlane)); | 81 video_frame->stride(media::VideoFrame::kVPlane)); |
| 80 | 82 |
| 81 const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(true); | 83 const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(true); |
| 82 media::YUVType yuv_type = media::YV16; | 84 media::YUVType yuv_type = media::YV16; |
| 85 media::YUVRange yuv_range = media::YUV_RANGE_RESTRICTED; |
| 83 int y_shift = 0; | 86 int y_shift = 0; |
| 84 if (video_frame->format() == media::VideoFrame::YV12 || | 87 if (video_frame->format() == media::VideoFrame::YV12 || |
| 85 video_frame->format() == media::VideoFrame::YV12A) { | 88 video_frame->format() == media::VideoFrame::YV12A) { |
| 86 yuv_type = media::YV12; | 89 yuv_type = media::YV12; |
| 90 yuv_range = media::YUV_RANGE_RESTRICTED; |
| 87 y_shift = 1; | 91 y_shift = 1; |
| 88 } | 92 } |
| 89 | 93 |
| 94 if (video_frame->format() == media::VideoFrame::YV12J) { |
| 95 yuv_type = media::YV12; |
| 96 yuv_range = media::YUV_RANGE_FULL; |
| 97 y_shift = 1; |
| 98 } |
| 99 |
| 90 // Transform the destination rectangle to local coordinates. | 100 // Transform the destination rectangle to local coordinates. |
| 91 const SkMatrix& local_matrix = canvas->getTotalMatrix(); | 101 const SkMatrix& local_matrix = canvas->getTotalMatrix(); |
| 92 SkRect local_dest_rect; | 102 SkRect local_dest_rect; |
| 93 local_matrix.mapRect(&local_dest_rect, dest_rect); | 103 local_matrix.mapRect(&local_dest_rect, dest_rect); |
| 94 | 104 |
| 95 // After projecting the destination rectangle to local coordinates, round | 105 // After projecting the destination rectangle to local coordinates, round |
| 96 // the projected rectangle to integer values, this will give us pixel values | 106 // the projected rectangle to integer values, this will give us pixel values |
| 97 // of the rectangle. | 107 // of the rectangle. |
| 98 SkIRect local_dest_irect, local_dest_irect_saved; | 108 SkIRect local_dest_irect, local_dest_irect_saved; |
| 99 local_dest_rect.round(&local_dest_irect); | 109 local_dest_rect.round(&local_dest_irect); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 frame_clip_v, | 174 frame_clip_v, |
| 165 dest_rect_pointer, | 175 dest_rect_pointer, |
| 166 frame_clip_width, | 176 frame_clip_width, |
| 167 frame_clip_height, | 177 frame_clip_height, |
| 168 local_dest_irect.width(), | 178 local_dest_irect.width(), |
| 169 local_dest_irect.height(), | 179 local_dest_irect.height(), |
| 170 video_frame->stride(media::VideoFrame::kYPlane), | 180 video_frame->stride(media::VideoFrame::kYPlane), |
| 171 video_frame->stride(media::VideoFrame::kUPlane), | 181 video_frame->stride(media::VideoFrame::kUPlane), |
| 172 bitmap.rowBytes(), | 182 bitmap.rowBytes(), |
| 173 yuv_type, | 183 yuv_type, |
| 184 yuv_range, |
| 174 media::ROTATE_0, | 185 media::ROTATE_0, |
| 175 media::FILTER_BILINEAR); | 186 media::FILTER_BILINEAR); |
| 176 bitmap.unlockPixels(); | 187 bitmap.unlockPixels(); |
| 177 } | 188 } |
| 178 | 189 |
| 179 // Converts a VideoFrame containing YUV data to a SkBitmap containing RGB data. | 190 // Converts a VideoFrame containing YUV data to a SkBitmap containing RGB data. |
| 180 // | 191 // |
| 181 // |bitmap| will be (re)allocated to match the dimensions of |video_frame|. | 192 // |bitmap| will be (re)allocated to match the dimensions of |video_frame|. |
| 182 static void ConvertVideoFrameToBitmap( | 193 static void ConvertVideoFrameToBitmap( |
| 183 const scoped_refptr<media::VideoFrame>& video_frame, | 194 const scoped_refptr<media::VideoFrame>& video_frame, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 210 // in Y, U and V planes. | 221 // in Y, U and V planes. |
| 211 y_offset = (video_frame->stride(media::VideoFrame::kYPlane) * | 222 y_offset = (video_frame->stride(media::VideoFrame::kYPlane) * |
| 212 video_frame->visible_rect().y()) + | 223 video_frame->visible_rect().y()) + |
| 213 video_frame->visible_rect().x(); | 224 video_frame->visible_rect().x(); |
| 214 // For format YV12, there is one U, V value per 2x2 block. | 225 // For format YV12, there is one U, V value per 2x2 block. |
| 215 // For format YV16, there is one U, V value per 2x1 block. | 226 // For format YV16, there is one U, V value per 2x1 block. |
| 216 uv_offset = (video_frame->stride(media::VideoFrame::kUPlane) * | 227 uv_offset = (video_frame->stride(media::VideoFrame::kUPlane) * |
| 217 (video_frame->visible_rect().y() >> y_shift)) + | 228 (video_frame->visible_rect().y() >> y_shift)) + |
| 218 (video_frame->visible_rect().x() >> 1); | 229 (video_frame->visible_rect().x() >> 1); |
| 219 } | 230 } |
| 231 |
| 232 media::YUVRange yuv_range = video_frame->format() == media::VideoFrame::YV12J |
| 233 ? media::YUV_RANGE_FULL |
| 234 : media::YUV_RANGE_RESTRICTED; |
| 235 |
| 220 switch (video_frame->format()) { | 236 switch (video_frame->format()) { |
| 221 case media::VideoFrame::YV12: | 237 case media::VideoFrame::YV12: |
| 238 case media::VideoFrame::YV12J: |
| 222 media::ConvertYUVToRGB32( | 239 media::ConvertYUVToRGB32( |
| 223 video_frame->data(media::VideoFrame::kYPlane) + y_offset, | 240 video_frame->data(media::VideoFrame::kYPlane) + y_offset, |
| 224 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, | 241 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, |
| 225 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, | 242 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, |
| 226 static_cast<uint8*>(bitmap->getPixels()), | 243 static_cast<uint8*>(bitmap->getPixels()), |
| 227 video_frame->visible_rect().width(), | 244 video_frame->visible_rect().width(), |
| 228 video_frame->visible_rect().height(), | 245 video_frame->visible_rect().height(), |
| 229 video_frame->stride(media::VideoFrame::kYPlane), | 246 video_frame->stride(media::VideoFrame::kYPlane), |
| 230 video_frame->stride(media::VideoFrame::kUPlane), | 247 video_frame->stride(media::VideoFrame::kUPlane), |
| 231 bitmap->rowBytes(), | 248 bitmap->rowBytes(), |
| 232 media::YV12); | 249 media::YV12, |
| 250 yuv_range); |
| 233 break; | 251 break; |
| 234 | 252 |
| 235 case media::VideoFrame::YV16: | 253 case media::VideoFrame::YV16: |
| 236 media::ConvertYUVToRGB32( | 254 media::ConvertYUVToRGB32( |
| 237 video_frame->data(media::VideoFrame::kYPlane) + y_offset, | 255 video_frame->data(media::VideoFrame::kYPlane) + y_offset, |
| 238 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, | 256 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, |
| 239 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, | 257 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, |
| 240 static_cast<uint8*>(bitmap->getPixels()), | 258 static_cast<uint8*>(bitmap->getPixels()), |
| 241 video_frame->visible_rect().width(), | 259 video_frame->visible_rect().width(), |
| 242 video_frame->visible_rect().height(), | 260 video_frame->visible_rect().height(), |
| 243 video_frame->stride(media::VideoFrame::kYPlane), | 261 video_frame->stride(media::VideoFrame::kYPlane), |
| 244 video_frame->stride(media::VideoFrame::kUPlane), | 262 video_frame->stride(media::VideoFrame::kUPlane), |
| 245 bitmap->rowBytes(), | 263 bitmap->rowBytes(), |
| 246 media::YV16); | 264 media::YV16, |
| 265 yuv_range); |
| 247 break; | 266 break; |
| 248 | 267 |
| 249 case media::VideoFrame::YV12A: | 268 case media::VideoFrame::YV12A: |
| 250 media::ConvertYUVAToARGB( | 269 media::ConvertYUVAToARGB( |
| 251 video_frame->data(media::VideoFrame::kYPlane) + y_offset, | 270 video_frame->data(media::VideoFrame::kYPlane) + y_offset, |
| 252 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, | 271 video_frame->data(media::VideoFrame::kUPlane) + uv_offset, |
| 253 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, | 272 video_frame->data(media::VideoFrame::kVPlane) + uv_offset, |
| 254 video_frame->data(media::VideoFrame::kAPlane), | 273 video_frame->data(media::VideoFrame::kAPlane), |
| 255 static_cast<uint8*>(bitmap->getPixels()), | 274 static_cast<uint8*>(bitmap->getPixels()), |
| 256 video_frame->visible_rect().width(), | 275 video_frame->visible_rect().width(), |
| 257 video_frame->visible_rect().height(), | 276 video_frame->visible_rect().height(), |
| 258 video_frame->stride(media::VideoFrame::kYPlane), | 277 video_frame->stride(media::VideoFrame::kYPlane), |
| 259 video_frame->stride(media::VideoFrame::kUPlane), | 278 video_frame->stride(media::VideoFrame::kUPlane), |
| 260 video_frame->stride(media::VideoFrame::kAPlane), | 279 video_frame->stride(media::VideoFrame::kAPlane), |
| 261 bitmap->rowBytes(), | 280 bitmap->rowBytes(), |
| 262 media::YV12); | 281 media::YV12, |
| 282 yuv_range); |
| 263 break; | 283 break; |
| 264 | 284 |
| 265 case media::VideoFrame::NATIVE_TEXTURE: | 285 case media::VideoFrame::NATIVE_TEXTURE: |
| 266 DCHECK_EQ(video_frame->format(), media::VideoFrame::NATIVE_TEXTURE); | 286 DCHECK_EQ(video_frame->format(), media::VideoFrame::NATIVE_TEXTURE); |
| 267 video_frame->ReadPixelsFromNativeTexture(*bitmap); | 287 video_frame->ReadPixelsFromNativeTexture(*bitmap); |
| 268 break; | 288 break; |
| 269 | 289 |
| 270 default: | 290 default: |
| 271 NOTREACHED(); | 291 NOTREACHED(); |
| 272 break; | 292 break; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 ConvertVideoFrameToBitmap(video_frame, &last_frame_); | 335 ConvertVideoFrameToBitmap(video_frame, &last_frame_); |
| 316 last_frame_timestamp_ = video_frame->GetTimestamp(); | 336 last_frame_timestamp_ = video_frame->GetTimestamp(); |
| 317 } | 337 } |
| 318 | 338 |
| 319 // Do a slower paint using |last_frame_|. | 339 // Do a slower paint using |last_frame_|. |
| 320 paint.setFilterBitmap(true); | 340 paint.setFilterBitmap(true); |
| 321 canvas->drawBitmapRect(last_frame_, NULL, dest, &paint); | 341 canvas->drawBitmapRect(last_frame_, NULL, dest, &paint); |
| 322 } | 342 } |
| 323 | 343 |
| 324 } // namespace media | 344 } // namespace media |
| OLD | NEW |