Chromium Code Reviews| 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/renderers/skcanvas_video_renderer.h" | 5 #include "media/renderers/skcanvas_video_renderer.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "gpu/GLES2/gl2extchromium.h" | 10 #include "gpu/GLES2/gl2extchromium.h" |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 return; | 340 return; |
| 341 } | 341 } |
| 342 | 342 |
| 343 SkRect dest; | 343 SkRect dest; |
| 344 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); | 344 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); |
| 345 | 345 |
| 346 // Paint black rectangle if there isn't a frame available or the | 346 // Paint black rectangle if there isn't a frame available or the |
| 347 // frame has an unexpected format. | 347 // frame has an unexpected format. |
| 348 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || | 348 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || |
| 349 !(media::IsYuvPlanar(video_frame->format()) || | 349 !(media::IsYuvPlanar(video_frame->format()) || |
| 350 video_frame->format() == media::PIXEL_FORMAT_Y16 || | |
| 350 video_frame->HasTextures())) { | 351 video_frame->HasTextures())) { |
| 351 SkPaint blackWithAlphaPaint; | 352 SkPaint blackWithAlphaPaint; |
| 352 blackWithAlphaPaint.setAlpha(paint.getAlpha()); | 353 blackWithAlphaPaint.setAlpha(paint.getAlpha()); |
| 353 canvas->drawRect(dest, blackWithAlphaPaint); | 354 canvas->drawRect(dest, blackWithAlphaPaint); |
| 354 canvas->flush(); | 355 canvas->flush(); |
| 355 return; | 356 return; |
| 356 } | 357 } |
| 357 | 358 |
| 358 gpu::gles2::GLES2Interface* gl = context_3d.gl; | 359 gpu::gles2::GLES2Interface* gl = context_3d.gl; |
| 359 if (!UpdateLastImage(video_frame, context_3d)) | 360 if (!UpdateLastImage(video_frame, context_3d)) |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 513 for (int row = 0; row < video_frame->rows(plane); row++) { | 514 for (int row = 0; row < video_frame->rows(plane); row++) { |
| 514 for (int x = 0; x < width; x++) { | 515 for (int x = 0; x < width; x++) { |
| 515 dst[x] = src[x] >> shift; | 516 dst[x] = src[x] >> shift; |
| 516 } | 517 } |
| 517 src += video_frame->stride(plane) / 2; | 518 src += video_frame->stride(plane) / 2; |
| 518 dst += ret->stride(plane); | 519 dst += ret->stride(plane); |
| 519 } | 520 } |
| 520 } | 521 } |
| 521 return ret; | 522 return ret; |
| 522 } | 523 } |
| 524 | |
| 525 // We take the upper 8 bits of 16-bit data and convert it as luminance to ARGB. | |
| 526 // We loose the precision here, but it is important not to render Y16 as RG_88. | |
| 527 // To get the full precision use float textures with WebGL1 and e.g. R16UI or | |
| 528 // R32F textures with WebGL2. | |
| 529 void ConvertY16ToARGB(const VideoFrame* video_frame, | |
| 530 void* argb_pixels, | |
| 531 size_t argb_row_bytes) { | |
| 532 const uint8_t* row_head = video_frame->visible_data(0); | |
| 533 uint8_t* out = reinterpret_cast<uint8_t*>(argb_pixels); | |
|
xhwang
2016/10/28 16:54:17
static_cast?
aleksandar.stojiljkovic
2016/10/28 18:58:55
Done.
| |
| 534 const size_t stride = video_frame->stride(0); | |
| 535 for (int i = 0; i < video_frame->visible_rect().height(); ++i) { | |
| 536 uint32_t* rgba = reinterpret_cast<uint32_t*>(out); | |
| 537 const uint8_t* row_end = row_head + video_frame->visible_rect().width() * 2; | |
| 538 for (const uint8_t* row = row_head; row < row_end; ++row) { | |
| 539 uint32_t gray_value = *++row; | |
| 540 *rgba++ = SkColorSetARGB(0xFF, gray_value, gray_value, gray_value); | |
|
xhwang
2016/10/28 16:54:17
nit: There's a SkColorSetRGB() we can use.
aleksandar.stojiljkovic
2016/10/28 18:58:55
Done.
| |
| 541 } | |
| 542 out += argb_row_bytes; | |
|
xhwang
2016/10/28 16:54:17
shall we dcheck that |argb_row_bytes| is big enoug
aleksandar.stojiljkovic
2016/10/28 18:58:55
I wouldn't check it in our generator (other SkImag
| |
| 543 row_head += stride; | |
| 544 } | |
| 523 } | 545 } |
| 524 | 546 |
| 547 } // anonymous namespace | |
| 548 | |
| 525 // static | 549 // static |
| 526 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( | 550 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( |
| 527 const VideoFrame* video_frame, | 551 const VideoFrame* video_frame, |
| 528 void* rgb_pixels, | 552 void* rgb_pixels, |
| 529 size_t row_bytes) { | 553 size_t row_bytes) { |
| 530 if (!video_frame->IsMappable()) { | 554 if (!video_frame->IsMappable()) { |
| 531 NOTREACHED() << "Cannot extract pixels from non-CPU frame formats."; | 555 NOTREACHED() << "Cannot extract pixels from non-CPU frame formats."; |
| 532 return; | 556 return; |
| 533 } | 557 } |
| 534 if (!media::IsYuvPlanar(video_frame->format())) { | |
| 535 NOTREACHED() << "Non YUV formats are not supported"; | |
| 536 return; | |
| 537 } | |
| 538 | 558 |
| 539 switch (video_frame->format()) { | 559 switch (video_frame->format()) { |
| 540 case PIXEL_FORMAT_YV12: | 560 case PIXEL_FORMAT_YV12: |
| 541 case PIXEL_FORMAT_I420: | 561 case PIXEL_FORMAT_I420: |
| 542 if (CheckColorSpace(video_frame, COLOR_SPACE_JPEG)) { | 562 if (CheckColorSpace(video_frame, COLOR_SPACE_JPEG)) { |
| 543 LIBYUV_J420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), | 563 LIBYUV_J420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), |
| 544 video_frame->stride(VideoFrame::kYPlane), | 564 video_frame->stride(VideoFrame::kYPlane), |
| 545 video_frame->visible_data(VideoFrame::kUPlane), | 565 video_frame->visible_data(VideoFrame::kUPlane), |
| 546 video_frame->stride(VideoFrame::kUPlane), | 566 video_frame->stride(VideoFrame::kUPlane), |
| 547 video_frame->visible_data(VideoFrame::kVPlane), | 567 video_frame->visible_data(VideoFrame::kVPlane), |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 case PIXEL_FORMAT_YUV420P12: | 640 case PIXEL_FORMAT_YUV420P12: |
| 621 case PIXEL_FORMAT_YUV422P12: | 641 case PIXEL_FORMAT_YUV422P12: |
| 622 case PIXEL_FORMAT_YUV444P12: { | 642 case PIXEL_FORMAT_YUV444P12: { |
| 623 scoped_refptr<VideoFrame> temporary_frame = | 643 scoped_refptr<VideoFrame> temporary_frame = |
| 624 DownShiftHighbitVideoFrame(video_frame); | 644 DownShiftHighbitVideoFrame(video_frame); |
| 625 ConvertVideoFrameToRGBPixels(temporary_frame.get(), rgb_pixels, | 645 ConvertVideoFrameToRGBPixels(temporary_frame.get(), rgb_pixels, |
| 626 row_bytes); | 646 row_bytes); |
| 627 break; | 647 break; |
| 628 } | 648 } |
| 629 | 649 |
| 650 case PIXEL_FORMAT_Y16: | |
| 651 ConvertY16ToARGB(video_frame, rgb_pixels, row_bytes); | |
| 652 break; | |
| 653 | |
| 630 case PIXEL_FORMAT_NV12: | 654 case PIXEL_FORMAT_NV12: |
| 631 case PIXEL_FORMAT_NV21: | 655 case PIXEL_FORMAT_NV21: |
| 632 case PIXEL_FORMAT_UYVY: | 656 case PIXEL_FORMAT_UYVY: |
| 633 case PIXEL_FORMAT_YUY2: | 657 case PIXEL_FORMAT_YUY2: |
| 634 case PIXEL_FORMAT_ARGB: | 658 case PIXEL_FORMAT_ARGB: |
| 635 case PIXEL_FORMAT_XRGB: | 659 case PIXEL_FORMAT_XRGB: |
| 636 case PIXEL_FORMAT_RGB24: | 660 case PIXEL_FORMAT_RGB24: |
| 637 case PIXEL_FORMAT_RGB32: | 661 case PIXEL_FORMAT_RGB32: |
| 638 case PIXEL_FORMAT_MJPEG: | 662 case PIXEL_FORMAT_MJPEG: |
| 639 case PIXEL_FORMAT_MT21: | 663 case PIXEL_FORMAT_MT21: |
| 640 // TODO(dshwang): Use either I400ToARGB or J400ToARGB depending if we want | |
| 641 // BT.601 constrained range of 16 to 240, or JPEG full range BT.601 | |
| 642 // coefficients. Implement it when Y8/16 foramt is supported. | |
| 643 // crbug.com/624436 | |
| 644 case PIXEL_FORMAT_Y8: | 664 case PIXEL_FORMAT_Y8: |
| 645 case PIXEL_FORMAT_Y16: | |
| 646 case PIXEL_FORMAT_UNKNOWN: | 665 case PIXEL_FORMAT_UNKNOWN: |
| 647 NOTREACHED(); | 666 NOTREACHED() << "Only YUV formats and Y16 are supported."; |
| 648 } | 667 } |
| 649 } | 668 } |
| 650 | 669 |
| 651 // static | 670 // static |
| 652 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 671 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
| 653 gpu::gles2::GLES2Interface* gl, | 672 gpu::gles2::GLES2Interface* gl, |
| 654 VideoFrame* video_frame, | 673 VideoFrame* video_frame, |
| 655 unsigned int texture, | 674 unsigned int texture, |
| 656 unsigned int internal_format, | 675 unsigned int internal_format, |
| 657 unsigned int type, | 676 unsigned int type, |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 last_image_->bounds().contains(visible_rect)) { | 822 last_image_->bounds().contains(visible_rect)) { |
| 804 last_image_ = last_image_->makeSubset(visible_rect); | 823 last_image_ = last_image_->makeSubset(visible_rect); |
| 805 } | 824 } |
| 806 } | 825 } |
| 807 | 826 |
| 808 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { | 827 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { |
| 809 return last_image_dimensions_for_testing_; | 828 return last_image_dimensions_for_testing_; |
| 810 } | 829 } |
| 811 | 830 |
| 812 } // namespace media | 831 } // namespace media |
| OLD | NEW |