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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 } | 218 } |
219 ~VideoImageGenerator() override {} | 219 ~VideoImageGenerator() override {} |
220 | 220 |
221 protected: | 221 protected: |
222 bool onGetPixels(const SkImageInfo& info, | 222 bool onGetPixels(const SkImageInfo& info, |
223 void* pixels, | 223 void* pixels, |
224 size_t row_bytes, | 224 size_t row_bytes, |
225 SkPMColor ctable[], | 225 SkPMColor ctable[], |
226 int* ctable_count) override { | 226 int* ctable_count) override { |
227 // If skia couldn't do the YUV conversion on GPU, we will on CPU. | 227 // If skia couldn't do the YUV conversion on GPU, we will on CPU. |
228 SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( | 228 SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(frame_.get(), pixels, |
229 frame_.get(), SkCanvasVideoRenderer::ConvertingSize::VISUAL, pixels, | 229 row_bytes); |
230 row_bytes); | |
231 return true; | 230 return true; |
232 } | 231 } |
233 | 232 |
234 bool onQueryYUV8(SkYUVSizeInfo* sizeInfo, | 233 bool onQueryYUV8(SkYUVSizeInfo* sizeInfo, |
235 SkYUVColorSpace* color_space) const override { | 234 SkYUVColorSpace* color_space) const override { |
236 if (!media::IsYuvPlanar(frame_->format()) || | 235 if (!media::IsYuvPlanar(frame_->format()) || |
237 // TODO(rileya): Skia currently doesn't support YUVA conversion. Remove | 236 // TODO(rileya): Skia currently doesn't support YUVA conversion. Remove |
238 // this case once it does. As-is we will fall back on the pure-software | 237 // this case once it does. As-is we will fall back on the pure-software |
239 // path in this case. | 238 // path in this case. |
240 frame_->format() == PIXEL_FORMAT_YV12A) { | 239 frame_->format() == PIXEL_FORMAT_YV12A) { |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 for (int x = 0; x < width; x++) { | 515 for (int x = 0; x < width; x++) { |
517 dst[x] = src[x] >> shift; | 516 dst[x] = src[x] >> shift; |
518 } | 517 } |
519 src += video_frame->stride(plane) / 2; | 518 src += video_frame->stride(plane) / 2; |
520 dst += ret->stride(plane); | 519 dst += ret->stride(plane); |
521 } | 520 } |
522 } | 521 } |
523 return ret; | 522 return ret; |
524 } | 523 } |
525 | 524 |
526 const uint8_t* FrameData(const VideoFrame* video_frame, | |
527 SkCanvasVideoRenderer::ConvertingSize size_type, | |
528 size_t plane) { | |
529 if (size_type == SkCanvasVideoRenderer::ConvertingSize::VISUAL) | |
530 return video_frame->visible_data(plane); | |
531 DCHECK(size_type == SkCanvasVideoRenderer::ConvertingSize::CODED); | |
532 return video_frame->data(plane); | |
533 } | |
534 | |
535 // We take the upper 8 bits of 16-bit data and convert it as luminance to ARGB. | 525 // We take the upper 8 bits of 16-bit data and convert it as luminance to ARGB. |
536 // We loose the precision here, but it is important not to render Y16 as RG_88. | 526 // We loose the precision here, but it is important not to render Y16 as RG_88. |
537 // To get the full precision use float textures with WebGL1 and e.g. R16UI or | 527 // To get the full precision use float textures with WebGL1 and e.g. R16UI or |
538 // R32F textures with WebGL2. | 528 // R32F textures with WebGL2. |
539 void ConvertY16ToARGB(const VideoFrame* video_frame, | 529 void ConvertY16ToARGB(const VideoFrame* video_frame, |
540 SkCanvasVideoRenderer::ConvertingSize size_type, | |
541 void* argb_pixels, | 530 void* argb_pixels, |
542 size_t argb_row_bytes) { | 531 size_t argb_row_bytes) { |
543 const uint8_t* row_head = | 532 const uint8_t* row_head = video_frame->visible_data(0); |
544 FrameData(video_frame, size_type, VideoFrame::kYPlane); | |
545 uint8_t* out = static_cast<uint8_t*>(argb_pixels); | 533 uint8_t* out = static_cast<uint8_t*>(argb_pixels); |
546 const size_t stride = video_frame->stride(0); | 534 const size_t stride = video_frame->stride(0); |
547 gfx::Size frame_size = video_frame->coded_size(); | 535 for (int i = 0; i < video_frame->visible_rect().height(); ++i) { |
548 if (size_type == SkCanvasVideoRenderer::ConvertingSize::VISUAL) | |
549 frame_size = video_frame->visible_rect().size(); | |
550 for (int i = 0; i < frame_size.height(); ++i) { | |
551 uint32_t* rgba = reinterpret_cast<uint32_t*>(out); | 536 uint32_t* rgba = reinterpret_cast<uint32_t*>(out); |
552 const uint8_t* row_end = row_head + frame_size.width() * 2; | 537 const uint8_t* row_end = row_head + video_frame->visible_rect().width() * 2; |
553 for (const uint8_t* row = row_head; row < row_end; ++row) { | 538 for (const uint8_t* row = row_head; row < row_end; ++row) { |
554 uint32_t gray_value = *++row; | 539 uint32_t gray_value = *++row; |
555 *rgba++ = SkColorSetRGB(gray_value, gray_value, gray_value); | 540 *rgba++ = SkColorSetRGB(gray_value, gray_value, gray_value); |
556 } | 541 } |
557 out += argb_row_bytes; | 542 out += argb_row_bytes; |
558 row_head += stride; | 543 row_head += stride; |
559 } | 544 } |
560 } | 545 } |
561 | 546 |
562 } // namespace | 547 } // anonymous namespace |
563 | 548 |
564 // static | 549 // static |
565 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( | 550 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( |
566 const VideoFrame* video_frame, | 551 const VideoFrame* video_frame, |
567 ConvertingSize size_type, | |
568 void* rgb_pixels, | 552 void* rgb_pixels, |
569 size_t row_bytes) { | 553 size_t row_bytes) { |
570 if (!video_frame->IsMappable()) { | 554 if (!video_frame->IsMappable()) { |
571 NOTREACHED() << "Cannot extract pixels from non-CPU frame formats."; | 555 NOTREACHED() << "Cannot extract pixels from non-CPU frame formats."; |
572 return; | 556 return; |
573 } | 557 } |
574 | 558 |
575 gfx::Size frame_size = video_frame->coded_size(); | |
576 if (size_type == SkCanvasVideoRenderer::ConvertingSize::VISUAL) | |
577 frame_size = video_frame->visible_rect().size(); | |
578 | |
579 switch (video_frame->format()) { | 559 switch (video_frame->format()) { |
580 case PIXEL_FORMAT_YV12: | 560 case PIXEL_FORMAT_YV12: |
581 case PIXEL_FORMAT_I420: | 561 case PIXEL_FORMAT_I420: |
582 if (CheckColorSpace(video_frame, COLOR_SPACE_JPEG)) { | 562 if (CheckColorSpace(video_frame, COLOR_SPACE_JPEG)) { |
583 LIBYUV_J420_TO_ARGB( | 563 LIBYUV_J420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), |
584 FrameData(video_frame, size_type, VideoFrame::kYPlane), | 564 video_frame->stride(VideoFrame::kYPlane), |
585 video_frame->stride(VideoFrame::kYPlane), | 565 video_frame->visible_data(VideoFrame::kUPlane), |
586 FrameData(video_frame, size_type, VideoFrame::kUPlane), | 566 video_frame->stride(VideoFrame::kUPlane), |
587 video_frame->stride(VideoFrame::kUPlane), | 567 video_frame->visible_data(VideoFrame::kVPlane), |
588 FrameData(video_frame, size_type, VideoFrame::kVPlane), | 568 video_frame->stride(VideoFrame::kVPlane), |
589 video_frame->stride(VideoFrame::kVPlane), | 569 static_cast<uint8_t*>(rgb_pixels), row_bytes, |
590 static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(), | 570 video_frame->visible_rect().width(), |
591 frame_size.height()); | 571 video_frame->visible_rect().height()); |
592 } else if (CheckColorSpace(video_frame, COLOR_SPACE_HD_REC709)) { | 572 } else if (CheckColorSpace(video_frame, COLOR_SPACE_HD_REC709)) { |
593 LIBYUV_H420_TO_ARGB( | 573 LIBYUV_H420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), |
594 FrameData(video_frame, size_type, VideoFrame::kYPlane), | 574 video_frame->stride(VideoFrame::kYPlane), |
595 video_frame->stride(VideoFrame::kYPlane), | 575 video_frame->visible_data(VideoFrame::kUPlane), |
596 FrameData(video_frame, size_type, VideoFrame::kUPlane), | 576 video_frame->stride(VideoFrame::kUPlane), |
597 video_frame->stride(VideoFrame::kUPlane), | 577 video_frame->visible_data(VideoFrame::kVPlane), |
598 FrameData(video_frame, size_type, VideoFrame::kVPlane), | 578 video_frame->stride(VideoFrame::kVPlane), |
599 video_frame->stride(VideoFrame::kVPlane), | 579 static_cast<uint8_t*>(rgb_pixels), row_bytes, |
600 static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(), | 580 video_frame->visible_rect().width(), |
601 frame_size.height()); | 581 video_frame->visible_rect().height()); |
602 } else { | 582 } else { |
603 LIBYUV_I420_TO_ARGB( | 583 LIBYUV_I420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), |
604 FrameData(video_frame, size_type, VideoFrame::kYPlane), | 584 video_frame->stride(VideoFrame::kYPlane), |
605 video_frame->stride(VideoFrame::kYPlane), | 585 video_frame->visible_data(VideoFrame::kUPlane), |
606 FrameData(video_frame, size_type, VideoFrame::kUPlane), | 586 video_frame->stride(VideoFrame::kUPlane), |
607 video_frame->stride(VideoFrame::kUPlane), | 587 video_frame->visible_data(VideoFrame::kVPlane), |
608 FrameData(video_frame, size_type, VideoFrame::kVPlane), | 588 video_frame->stride(VideoFrame::kVPlane), |
609 video_frame->stride(VideoFrame::kVPlane), | 589 static_cast<uint8_t*>(rgb_pixels), row_bytes, |
610 static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(), | 590 video_frame->visible_rect().width(), |
611 frame_size.height()); | 591 video_frame->visible_rect().height()); |
612 } | 592 } |
613 break; | 593 break; |
614 case PIXEL_FORMAT_YV16: | 594 case PIXEL_FORMAT_YV16: |
615 LIBYUV_I422_TO_ARGB( | 595 LIBYUV_I422_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), |
616 FrameData(video_frame, size_type, VideoFrame::kYPlane), | 596 video_frame->stride(VideoFrame::kYPlane), |
617 video_frame->stride(VideoFrame::kYPlane), | 597 video_frame->visible_data(VideoFrame::kUPlane), |
618 FrameData(video_frame, size_type, VideoFrame::kUPlane), | 598 video_frame->stride(VideoFrame::kUPlane), |
619 video_frame->stride(VideoFrame::kUPlane), | 599 video_frame->visible_data(VideoFrame::kVPlane), |
620 FrameData(video_frame, size_type, VideoFrame::kVPlane), | 600 video_frame->stride(VideoFrame::kVPlane), |
621 video_frame->stride(VideoFrame::kVPlane), | 601 static_cast<uint8_t*>(rgb_pixels), row_bytes, |
622 static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(), | 602 video_frame->visible_rect().width(), |
623 frame_size.height()); | 603 video_frame->visible_rect().height()); |
624 break; | 604 break; |
625 | 605 |
626 case PIXEL_FORMAT_YV12A: | 606 case PIXEL_FORMAT_YV12A: |
627 LIBYUV_I420ALPHA_TO_ARGB( | 607 LIBYUV_I420ALPHA_TO_ARGB( |
628 FrameData(video_frame, size_type, VideoFrame::kYPlane), | 608 video_frame->visible_data(VideoFrame::kYPlane), |
629 video_frame->stride(VideoFrame::kYPlane), | 609 video_frame->stride(VideoFrame::kYPlane), |
630 FrameData(video_frame, size_type, VideoFrame::kUPlane), | 610 video_frame->visible_data(VideoFrame::kUPlane), |
631 video_frame->stride(VideoFrame::kUPlane), | 611 video_frame->stride(VideoFrame::kUPlane), |
632 FrameData(video_frame, size_type, VideoFrame::kVPlane), | 612 video_frame->visible_data(VideoFrame::kVPlane), |
633 video_frame->stride(VideoFrame::kVPlane), | 613 video_frame->stride(VideoFrame::kVPlane), |
634 FrameData(video_frame, size_type, VideoFrame::kAPlane), | 614 video_frame->visible_data(VideoFrame::kAPlane), |
635 video_frame->stride(VideoFrame::kAPlane), | 615 video_frame->stride(VideoFrame::kAPlane), |
636 static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(), | 616 static_cast<uint8_t*>(rgb_pixels), row_bytes, |
637 frame_size.height(), | 617 video_frame->visible_rect().width(), |
| 618 video_frame->visible_rect().height(), |
638 1); // 1 = enable RGB premultiplication by Alpha. | 619 1); // 1 = enable RGB premultiplication by Alpha. |
639 break; | 620 break; |
640 | 621 |
641 case PIXEL_FORMAT_YV24: | 622 case PIXEL_FORMAT_YV24: |
642 LIBYUV_I444_TO_ARGB( | 623 LIBYUV_I444_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), |
643 FrameData(video_frame, size_type, VideoFrame::kYPlane), | 624 video_frame->stride(VideoFrame::kYPlane), |
644 video_frame->stride(VideoFrame::kYPlane), | 625 video_frame->visible_data(VideoFrame::kUPlane), |
645 FrameData(video_frame, size_type, VideoFrame::kUPlane), | 626 video_frame->stride(VideoFrame::kUPlane), |
646 video_frame->stride(VideoFrame::kUPlane), | 627 video_frame->visible_data(VideoFrame::kVPlane), |
647 FrameData(video_frame, size_type, VideoFrame::kVPlane), | 628 video_frame->stride(VideoFrame::kVPlane), |
648 video_frame->stride(VideoFrame::kVPlane), | 629 static_cast<uint8_t*>(rgb_pixels), row_bytes, |
649 static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(), | 630 video_frame->visible_rect().width(), |
650 frame_size.height()); | 631 video_frame->visible_rect().height()); |
651 break; | 632 break; |
652 | 633 |
653 case PIXEL_FORMAT_YUV420P9: | 634 case PIXEL_FORMAT_YUV420P9: |
654 case PIXEL_FORMAT_YUV422P9: | 635 case PIXEL_FORMAT_YUV422P9: |
655 case PIXEL_FORMAT_YUV444P9: | 636 case PIXEL_FORMAT_YUV444P9: |
656 case PIXEL_FORMAT_YUV420P10: | 637 case PIXEL_FORMAT_YUV420P10: |
657 case PIXEL_FORMAT_YUV422P10: | 638 case PIXEL_FORMAT_YUV422P10: |
658 case PIXEL_FORMAT_YUV444P10: | 639 case PIXEL_FORMAT_YUV444P10: |
659 case PIXEL_FORMAT_YUV420P12: | 640 case PIXEL_FORMAT_YUV420P12: |
660 case PIXEL_FORMAT_YUV422P12: | 641 case PIXEL_FORMAT_YUV422P12: |
661 case PIXEL_FORMAT_YUV444P12: { | 642 case PIXEL_FORMAT_YUV444P12: { |
662 scoped_refptr<VideoFrame> temporary_frame = | 643 scoped_refptr<VideoFrame> temporary_frame = |
663 DownShiftHighbitVideoFrame(video_frame); | 644 DownShiftHighbitVideoFrame(video_frame); |
664 ConvertVideoFrameToRGBPixels(temporary_frame.get(), size_type, rgb_pixels, | 645 ConvertVideoFrameToRGBPixels(temporary_frame.get(), rgb_pixels, |
665 row_bytes); | 646 row_bytes); |
666 break; | 647 break; |
667 } | 648 } |
668 | 649 |
669 case PIXEL_FORMAT_Y16: | 650 case PIXEL_FORMAT_Y16: |
670 ConvertY16ToARGB(video_frame, size_type, rgb_pixels, row_bytes); | 651 ConvertY16ToARGB(video_frame, rgb_pixels, row_bytes); |
671 break; | 652 break; |
672 | 653 |
673 case PIXEL_FORMAT_NV12: | 654 case PIXEL_FORMAT_NV12: |
674 case PIXEL_FORMAT_NV21: | 655 case PIXEL_FORMAT_NV21: |
675 case PIXEL_FORMAT_UYVY: | 656 case PIXEL_FORMAT_UYVY: |
676 case PIXEL_FORMAT_YUY2: | 657 case PIXEL_FORMAT_YUY2: |
677 case PIXEL_FORMAT_ARGB: | 658 case PIXEL_FORMAT_ARGB: |
678 case PIXEL_FORMAT_XRGB: | 659 case PIXEL_FORMAT_XRGB: |
679 case PIXEL_FORMAT_RGB24: | 660 case PIXEL_FORMAT_RGB24: |
680 case PIXEL_FORMAT_RGB32: | 661 case PIXEL_FORMAT_RGB32: |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 last_image_->bounds().contains(visible_rect)) { | 822 last_image_->bounds().contains(visible_rect)) { |
842 last_image_ = last_image_->makeSubset(visible_rect); | 823 last_image_ = last_image_->makeSubset(visible_rect); |
843 } | 824 } |
844 } | 825 } |
845 | 826 |
846 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { | 827 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { |
847 return last_image_dimensions_for_testing_; | 828 return last_image_dimensions_for_testing_; |
848 } | 829 } |
849 | 830 |
850 } // namespace media | 831 } // namespace media |
OLD | NEW |