| Index: media/filters/skcanvas_video_renderer.cc
 | 
| diff --git a/media/filters/skcanvas_video_renderer.cc b/media/filters/skcanvas_video_renderer.cc
 | 
| index b478a731b58541d5f8cc7394e05e01c06e2edf2c..94395bfdb94950749dd7fbde109a08a1b991bd7a 100644
 | 
| --- a/media/filters/skcanvas_video_renderer.cc
 | 
| +++ b/media/filters/skcanvas_video_renderer.cc
 | 
| @@ -21,6 +21,17 @@ static bool IsEitherYV12OrYV16OrNative(media::VideoFrame::Format format) {
 | 
|        format == media::VideoFrame::NATIVE_TEXTURE;
 | 
|  }
 | 
|  
 | 
| +static bool IsEitherYV12OrYV12AOrYV16(media::VideoFrame::Format format) {
 | 
| +  return IsEitherYV12OrYV16(format) ||
 | 
| +      format == media::VideoFrame::YV12A;
 | 
| +}
 | 
| +
 | 
| +static bool IsEitherYV12OrYV12AOrYV16OrNative(
 | 
| +    media::VideoFrame::Format format) {
 | 
| +  return IsEitherYV12OrYV16OrNative(format) ||
 | 
| +      format == media::VideoFrame::YV12A;
 | 
| +}
 | 
| +
 | 
|  // CanFastPaint is a helper method to determine the conditions for fast
 | 
|  // painting. The conditions are:
 | 
|  // 1. No skew in canvas matrix.
 | 
| @@ -70,7 +81,8 @@ static void FastPaint(
 | 
|    const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(true);
 | 
|    media::YUVType yuv_type = media::YV16;
 | 
|    int y_shift = 0;
 | 
| -  if (video_frame->format() == media::VideoFrame::YV12) {
 | 
| +  if (video_frame->format() == media::VideoFrame::YV12 ||
 | 
| +      video_frame->format() == media::VideoFrame::YV12A) {
 | 
|      yuv_type = media::YV12;
 | 
|      y_shift = 1;
 | 
|    }
 | 
| @@ -170,9 +182,9 @@ static void FastPaint(
 | 
|  static void ConvertVideoFrameToBitmap(
 | 
|      const scoped_refptr<media::VideoFrame>& video_frame,
 | 
|      SkBitmap* bitmap) {
 | 
| -  DCHECK(IsEitherYV12OrYV16OrNative(video_frame->format()))
 | 
| +  DCHECK(IsEitherYV12OrYV12AOrYV16OrNative(video_frame->format()))
 | 
|        << video_frame->format();
 | 
| -  if (IsEitherYV12OrYV16(video_frame->format())) {
 | 
| +  if (IsEitherYV12OrYV12AOrYV16(video_frame->format())) {
 | 
|      DCHECK_EQ(video_frame->stride(media::VideoFrame::kUPlane),
 | 
|                video_frame->stride(media::VideoFrame::kVPlane));
 | 
|    }
 | 
| @@ -189,45 +201,75 @@ static void ConvertVideoFrameToBitmap(
 | 
|    }
 | 
|  
 | 
|    bitmap->lockPixels();
 | 
| -  if (IsEitherYV12OrYV16(video_frame->format())) {
 | 
| -    media::YUVType yuv_type = media::YV16;
 | 
| -    int y_shift = 0;
 | 
| -    if (video_frame->format() == media::VideoFrame::YV12) {
 | 
| -      yuv_type = media::YV12;
 | 
| -      y_shift = 1;
 | 
| -    }
 | 
|  
 | 
| +  size_t y_offset = 0;
 | 
| +  size_t uv_offset = 0;
 | 
| +  if (IsEitherYV12OrYV12AOrYV16(video_frame->format())) {
 | 
| +    int y_shift = (video_frame->format() == media::VideoFrame::YV16) ? 0 : 1;
 | 
|      // Use the "left" and "top" of the destination rect to locate the offset
 | 
|      // in Y, U and V planes.
 | 
| -    size_t y_offset = (video_frame->stride(media::VideoFrame::kYPlane) *
 | 
| -                       video_frame->visible_rect().y()) +
 | 
| -                      video_frame->visible_rect().x();
 | 
| -
 | 
| +    y_offset = (video_frame->stride(media::VideoFrame::kYPlane) *
 | 
| +                video_frame->visible_rect().y()) +
 | 
| +                video_frame->visible_rect().x();
 | 
|      // For format YV12, there is one U, V value per 2x2 block.
 | 
|      // For format YV16, there is one U, V value per 2x1 block.
 | 
| -    size_t uv_offset = (video_frame->stride(media::VideoFrame::kUPlane) *
 | 
| -                        (video_frame->visible_rect().y() >> y_shift)) +
 | 
| -                       (video_frame->visible_rect().x() >> 1);
 | 
| -    uint8* frame_clip_y =
 | 
| -        video_frame->data(media::VideoFrame::kYPlane) + y_offset;
 | 
| -    uint8* frame_clip_u =
 | 
| -        video_frame->data(media::VideoFrame::kUPlane) + uv_offset;
 | 
| -    uint8* frame_clip_v =
 | 
| -        video_frame->data(media::VideoFrame::kVPlane) + uv_offset;
 | 
| -
 | 
| -    media::ConvertYUVToRGB32(frame_clip_y,
 | 
| -                             frame_clip_u,
 | 
| -                             frame_clip_v,
 | 
| -                             static_cast<uint8*>(bitmap->getPixels()),
 | 
| -                             video_frame->visible_rect().width(),
 | 
| -                             video_frame->visible_rect().height(),
 | 
| -                             video_frame->stride(media::VideoFrame::kYPlane),
 | 
| -                             video_frame->stride(media::VideoFrame::kUPlane),
 | 
| -                             bitmap->rowBytes(),
 | 
| -                             yuv_type);
 | 
| -  } else {
 | 
| -    DCHECK_EQ(video_frame->format(), media::VideoFrame::NATIVE_TEXTURE);
 | 
| -    video_frame->ReadPixelsFromNativeTexture(*bitmap);
 | 
| +    uv_offset = (video_frame->stride(media::VideoFrame::kUPlane) *
 | 
| +                (video_frame->visible_rect().y() >> y_shift)) +
 | 
| +                (video_frame->visible_rect().x() >> 1);
 | 
| +  }
 | 
| +  switch (video_frame->format()) {
 | 
| +    case media::VideoFrame::YV12:
 | 
| +      media::ConvertYUVToRGB32(
 | 
| +          video_frame->data(media::VideoFrame::kYPlane) + y_offset,
 | 
| +          video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
 | 
| +          video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
 | 
| +          static_cast<uint8*>(bitmap->getPixels()),
 | 
| +          video_frame->visible_rect().width(),
 | 
| +          video_frame->visible_rect().height(),
 | 
| +          video_frame->stride(media::VideoFrame::kYPlane),
 | 
| +          video_frame->stride(media::VideoFrame::kUPlane),
 | 
| +          bitmap->rowBytes(),
 | 
| +          media::YV12);
 | 
| +      break;
 | 
| +
 | 
| +    case media::VideoFrame::YV16:
 | 
| +      media::ConvertYUVToRGB32(
 | 
| +          video_frame->data(media::VideoFrame::kYPlane) + y_offset,
 | 
| +          video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
 | 
| +          video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
 | 
| +          static_cast<uint8*>(bitmap->getPixels()),
 | 
| +          video_frame->visible_rect().width(),
 | 
| +          video_frame->visible_rect().height(),
 | 
| +          video_frame->stride(media::VideoFrame::kYPlane),
 | 
| +          video_frame->stride(media::VideoFrame::kUPlane),
 | 
| +          bitmap->rowBytes(),
 | 
| +          media::YV16);
 | 
| +      break;
 | 
| +
 | 
| +    case media::VideoFrame::YV12A:
 | 
| +      media::ConvertYUVAToARGB(
 | 
| +          video_frame->data(media::VideoFrame::kYPlane) + y_offset,
 | 
| +          video_frame->data(media::VideoFrame::kUPlane) + uv_offset,
 | 
| +          video_frame->data(media::VideoFrame::kVPlane) + uv_offset,
 | 
| +          video_frame->data(media::VideoFrame::kAPlane),
 | 
| +          static_cast<uint8*>(bitmap->getPixels()),
 | 
| +          video_frame->visible_rect().width(),
 | 
| +          video_frame->visible_rect().height(),
 | 
| +          video_frame->stride(media::VideoFrame::kYPlane),
 | 
| +          video_frame->stride(media::VideoFrame::kUPlane),
 | 
| +          video_frame->stride(media::VideoFrame::kAPlane),
 | 
| +          bitmap->rowBytes(),
 | 
| +          media::YV12);
 | 
| +      break;
 | 
| +
 | 
| +    case media::VideoFrame::NATIVE_TEXTURE:
 | 
| +      DCHECK_EQ(video_frame->format(), media::VideoFrame::NATIVE_TEXTURE);
 | 
| +      video_frame->ReadPixelsFromNativeTexture(*bitmap);
 | 
| +      break;
 | 
| +
 | 
| +    default:
 | 
| +      NOTREACHED();
 | 
| +      break;
 | 
|    }
 | 
|    bitmap->notifyPixelsChanged();
 | 
|    bitmap->unlockPixels();
 | 
| @@ -255,7 +297,8 @@ void SkCanvasVideoRenderer::Paint(media::VideoFrame* video_frame,
 | 
|  
 | 
|    // Paint black rectangle if there isn't a frame available or the
 | 
|    // frame has an unexpected format.
 | 
| -  if (!video_frame || !IsEitherYV12OrYV16OrNative(video_frame->format())) {
 | 
| +  if (!video_frame ||
 | 
| +      !IsEitherYV12OrYV12AOrYV16OrNative(video_frame->format())) {
 | 
|      canvas->drawRect(dest, paint);
 | 
|      return;
 | 
|    }
 | 
| 
 |