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 void ConvertY16ToARGB(const VideoFrame* video_frame, | |
xhwang
2016/10/27 16:59:18
Please add a comment to summarize what we are doin
aleksandar.stojiljkovic
2016/10/27 19:12:23
Done.
| |
526 void* argb_pixels, | |
527 size_t argb_row_bytes) { | |
528 const uint8_t* source = | |
529 reinterpret_cast<const uint8_t*>(video_frame->visible_data(0)); | |
xhwang
2016/10/27 16:59:18
why do you need the cast?
xhwang
2016/10/27 16:59:18
It seems these functions only convert the visible
aleksandar.stojiljkovic
2016/10/27 19:12:23
Done.
aleksandar.stojiljkovic
2016/10/27 19:12:23
Almost all of the functionality in the file is bas
| |
530 uint8_t* out = reinterpret_cast<uint8_t*>(argb_pixels); | |
531 const size_t stride = video_frame->stride(0); | |
532 for (int i = 0; i < video_frame->visible_rect().height(); ++i) { | |
533 const uint8_t* row = source; | |
534 uint32_t* rgba = reinterpret_cast<uint32_t*>(out); | |
535 for (const uint8_t* row_end = row + video_frame->row_bytes(0); | |
536 row < row_end; ++row) { | |
xhwang
2016/10/27 16:59:18
This for-loop is confusing. Does it make sense to
aleksandar.stojiljkovic
2016/10/27 19:12:23
Done. That was strange looking loop - after all th
| |
537 // We loose the precision here and take only upper 8 bits of 16 bit data. | |
538 // It is important not to render Y16 as RG_88. To get the full precision | |
539 // use float textures with WebGL1 and e.g. R16UI or R32F textures with | |
540 // WebGL2. | |
541 uint32_t green = *++row; | |
xhwang
2016/10/27 16:59:18
why this is "green"? Should it be something like "
aleksandar.stojiljkovic
2016/10/27 19:12:23
Done.
| |
542 *rgba++ = SkColorSetARGB(0xFF, green, green, green); | |
hubbe
2016/10/27 17:25:03
I wonder if it would be helpful to do an inverse-g
aleksandar.stojiljkovic
2016/10/27 19:12:23
Important to keep the values; some developers migh
| |
543 } | |
544 out += argb_row_bytes; | |
545 source += stride; | |
546 } | |
547 } | |
523 } | 548 } |
xhwang
2016/10/27 16:59:18
Can this compile?
aleksandar.stojiljkovic
2016/10/27 19:12:22
Yes - it is closing // anonymous namespace. Added
| |
524 | 549 |
525 // static | 550 // static |
526 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( | 551 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( |
527 const VideoFrame* video_frame, | 552 const VideoFrame* video_frame, |
528 void* rgb_pixels, | 553 void* rgb_pixels, |
529 size_t row_bytes) { | 554 size_t row_bytes) { |
530 if (!video_frame->IsMappable()) { | 555 if (!video_frame->IsMappable()) { |
531 NOTREACHED() << "Cannot extract pixels from non-CPU frame formats."; | 556 NOTREACHED() << "Cannot extract pixels from non-CPU frame formats."; |
532 return; | 557 return; |
533 } | 558 } |
534 if (!media::IsYuvPlanar(video_frame->format())) { | |
535 NOTREACHED() << "Non YUV formats are not supported"; | |
536 return; | |
537 } | |
538 | 559 |
539 switch (video_frame->format()) { | 560 switch (video_frame->format()) { |
540 case PIXEL_FORMAT_YV12: | 561 case PIXEL_FORMAT_YV12: |
541 case PIXEL_FORMAT_I420: | 562 case PIXEL_FORMAT_I420: |
542 if (CheckColorSpace(video_frame, COLOR_SPACE_JPEG)) { | 563 if (CheckColorSpace(video_frame, COLOR_SPACE_JPEG)) { |
543 LIBYUV_J420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), | 564 LIBYUV_J420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), |
544 video_frame->stride(VideoFrame::kYPlane), | 565 video_frame->stride(VideoFrame::kYPlane), |
545 video_frame->visible_data(VideoFrame::kUPlane), | 566 video_frame->visible_data(VideoFrame::kUPlane), |
546 video_frame->stride(VideoFrame::kUPlane), | 567 video_frame->stride(VideoFrame::kUPlane), |
547 video_frame->visible_data(VideoFrame::kVPlane), | 568 video_frame->visible_data(VideoFrame::kVPlane), |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
620 case PIXEL_FORMAT_YUV420P12: | 641 case PIXEL_FORMAT_YUV420P12: |
621 case PIXEL_FORMAT_YUV422P12: | 642 case PIXEL_FORMAT_YUV422P12: |
622 case PIXEL_FORMAT_YUV444P12: { | 643 case PIXEL_FORMAT_YUV444P12: { |
623 scoped_refptr<VideoFrame> temporary_frame = | 644 scoped_refptr<VideoFrame> temporary_frame = |
624 DownShiftHighbitVideoFrame(video_frame); | 645 DownShiftHighbitVideoFrame(video_frame); |
625 ConvertVideoFrameToRGBPixels(temporary_frame.get(), rgb_pixels, | 646 ConvertVideoFrameToRGBPixels(temporary_frame.get(), rgb_pixels, |
626 row_bytes); | 647 row_bytes); |
627 break; | 648 break; |
628 } | 649 } |
629 | 650 |
651 case PIXEL_FORMAT_Y16: | |
652 ConvertY16ToARGB(video_frame, rgb_pixels, row_bytes); | |
653 break; | |
654 | |
630 case PIXEL_FORMAT_NV12: | 655 case PIXEL_FORMAT_NV12: |
631 case PIXEL_FORMAT_NV21: | 656 case PIXEL_FORMAT_NV21: |
632 case PIXEL_FORMAT_UYVY: | 657 case PIXEL_FORMAT_UYVY: |
633 case PIXEL_FORMAT_YUY2: | 658 case PIXEL_FORMAT_YUY2: |
634 case PIXEL_FORMAT_ARGB: | 659 case PIXEL_FORMAT_ARGB: |
635 case PIXEL_FORMAT_XRGB: | 660 case PIXEL_FORMAT_XRGB: |
636 case PIXEL_FORMAT_RGB24: | 661 case PIXEL_FORMAT_RGB24: |
637 case PIXEL_FORMAT_RGB32: | 662 case PIXEL_FORMAT_RGB32: |
638 case PIXEL_FORMAT_MJPEG: | 663 case PIXEL_FORMAT_MJPEG: |
639 case PIXEL_FORMAT_MT21: | 664 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: | 665 case PIXEL_FORMAT_Y8: |
645 case PIXEL_FORMAT_Y16: | |
646 case PIXEL_FORMAT_UNKNOWN: | 666 case PIXEL_FORMAT_UNKNOWN: |
647 NOTREACHED(); | 667 NOTREACHED() << "Only YUV formats and Y16 are supported."; |
648 } | 668 } |
649 } | 669 } |
650 | 670 |
651 // static | 671 // static |
652 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 672 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
653 gpu::gles2::GLES2Interface* gl, | 673 gpu::gles2::GLES2Interface* gl, |
654 VideoFrame* video_frame, | 674 VideoFrame* video_frame, |
655 unsigned int texture, | 675 unsigned int texture, |
656 unsigned int internal_format, | 676 unsigned int internal_format, |
657 unsigned int type, | 677 unsigned int type, |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
803 last_image_->bounds().contains(visible_rect)) { | 823 last_image_->bounds().contains(visible_rect)) { |
804 last_image_ = last_image_->makeSubset(visible_rect); | 824 last_image_ = last_image_->makeSubset(visible_rect); |
805 } | 825 } |
806 } | 826 } |
807 | 827 |
808 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { | 828 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { |
809 return last_image_dimensions_for_testing_; | 829 return last_image_dimensions_for_testing_; |
810 } | 830 } |
811 | 831 |
812 } // namespace media | 832 } // namespace media |
OLD | NEW |