OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <inttypes.h> | 5 #include <inttypes.h> |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <queue> | 8 #include <queue> |
9 #include <string> | 9 #include <string> |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... | |
25 #include "base/threading/thread_checker.h" | 25 #include "base/threading/thread_checker.h" |
26 #include "base/time/time.h" | 26 #include "base/time/time.h" |
27 #include "base/timer/timer.h" | 27 #include "base/timer/timer.h" |
28 #include "content/common/gpu/media/video_accelerator_unittest_helpers.h" | 28 #include "content/common/gpu/media/video_accelerator_unittest_helpers.h" |
29 #include "media/base/bind_to_current_loop.h" | 29 #include "media/base/bind_to_current_loop.h" |
30 #include "media/base/bitstream_buffer.h" | 30 #include "media/base/bitstream_buffer.h" |
31 #include "media/base/decoder_buffer.h" | 31 #include "media/base/decoder_buffer.h" |
32 #include "media/base/test_data_util.h" | 32 #include "media/base/test_data_util.h" |
33 #include "media/base/video_decoder.h" | 33 #include "media/base/video_decoder.h" |
34 #include "media/base/video_frame.h" | 34 #include "media/base/video_frame.h" |
35 #include "media/base/yuv_convert.h" | |
35 #include "media/filters/ffmpeg_glue.h" | 36 #include "media/filters/ffmpeg_glue.h" |
36 #include "media/filters/ffmpeg_video_decoder.h" | 37 #include "media/filters/ffmpeg_video_decoder.h" |
37 #include "media/filters/h264_parser.h" | 38 #include "media/filters/h264_parser.h" |
38 #include "media/video/fake_video_encode_accelerator.h" | 39 #include "media/video/fake_video_encode_accelerator.h" |
39 #include "media/video/video_encode_accelerator.h" | 40 #include "media/video/video_encode_accelerator.h" |
40 #include "testing/gtest/include/gtest/gtest.h" | 41 #include "testing/gtest/include/gtest/gtest.h" |
42 #include "ui/gfx/codec/png_codec.h" | |
41 | 43 |
42 #if defined(OS_CHROMEOS) | 44 #if defined(OS_CHROMEOS) |
43 #if defined(ARCH_CPU_ARMEL) || (defined(USE_OZONE) && defined(USE_V4L2_CODEC)) | 45 #if defined(ARCH_CPU_ARMEL) || (defined(USE_OZONE) && defined(USE_V4L2_CODEC)) |
44 #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" | 46 #include "content/common/gpu/media/v4l2_video_encode_accelerator.h" |
45 #endif | 47 #endif |
46 #if defined(ARCH_CPU_X86_FAMILY) | 48 #if defined(ARCH_CPU_X86_FAMILY) |
47 #include "content/common/gpu/media/vaapi_video_encode_accelerator.h" | 49 #include "content/common/gpu/media/vaapi_video_encode_accelerator.h" |
48 #include "content/common/gpu/media/vaapi_wrapper.h" | 50 #include "content/common/gpu/media/vaapi_wrapper.h" |
49 #endif // defined(ARCH_CPU_X86_FAMILY) | 51 #endif // defined(ARCH_CPU_X86_FAMILY) |
50 #else | 52 #else |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
608 const gfx::Rect& visible_size, | 610 const gfx::Rect& visible_size, |
609 const media::VideoCodecProfile profile); | 611 const media::VideoCodecProfile profile); |
610 // Push original frame to origin_frames_ queue | 612 // Push original frame to origin_frames_ queue |
611 void AddOriginFrame(scoped_refptr<media::VideoFrame> frame); | 613 void AddOriginFrame(scoped_refptr<media::VideoFrame> frame); |
612 void Decode(const scoped_refptr<media::DecoderBuffer>& buffer); | 614 void Decode(const scoped_refptr<media::DecoderBuffer>& buffer); |
613 | 615 |
614 private: | 616 private: |
615 void InitializeCB(bool success); | 617 void InitializeCB(bool success); |
616 void DecodeDone(media::VideoDecoder::Status status); | 618 void DecodeDone(media::VideoDecoder::Status status); |
617 void CheckOutputFrame(const scoped_refptr<media::VideoFrame>& output_frame); | 619 void CheckOutputFrame(const scoped_refptr<media::VideoFrame>& output_frame); |
618 | 620 void SaveFrameToFile(const scoped_refptr<media::VideoFrame>& frame, |
621 base::FilePath filename); | |
619 scoped_ptr<media::FFmpegVideoDecoder> decoder_; | 622 scoped_ptr<media::FFmpegVideoDecoder> decoder_; |
620 media::VideoDecoder::DecodeCB decode_cb_; | 623 media::VideoDecoder::DecodeCB decode_cb_; |
621 | 624 |
622 std::queue<scoped_refptr<media::VideoFrame>> origin_frames_; | 625 std::queue<scoped_refptr<media::VideoFrame>> origin_frames_; |
626 | |
627 int frame_id_; | |
623 }; | 628 }; |
624 | 629 |
625 VideoFrameQualityValidator::VideoFrameQualityValidator() | 630 VideoFrameQualityValidator::VideoFrameQualityValidator() |
626 : decoder_(new media::FFmpegVideoDecoder( | 631 : decoder_(new media::FFmpegVideoDecoder( |
627 base::MessageLoop::current()->task_runner())), | 632 base::MessageLoop::current()->task_runner())), |
628 decode_cb_(base::Bind(&VideoFrameQualityValidator::DecodeDone, | 633 decode_cb_(base::Bind(&VideoFrameQualityValidator::DecodeDone, |
629 base::Unretained(this))) { | 634 base::Unretained(this))), |
635 frame_id_(0) { | |
630 decoder_->set_decode_nalus(true); | 636 decoder_->set_decode_nalus(true); |
631 } | 637 } |
632 | 638 |
633 void VideoFrameQualityValidator::Initialize( | 639 void VideoFrameQualityValidator::Initialize( |
634 const gfx::Size& coded_size, | 640 const gfx::Size& coded_size, |
635 const gfx::Rect& visible_size, | 641 const gfx::Rect& visible_size, |
636 const media::VideoCodecProfile profile) { | 642 const media::VideoCodecProfile profile) { |
637 media::FFmpegGlue::InitializeFFmpeg(); | 643 media::FFmpegGlue::InitializeFFmpeg(); |
644 media::InitializeCPUSpecificYUVConversions(); | |
638 | 645 |
639 gfx::Size natural_size(visible_size.size()); | 646 gfx::Size natural_size(visible_size.size()); |
640 media::VideoDecoderConfig config; | 647 media::VideoDecoderConfig config; |
641 if (IsVP8(profile)) | 648 if (IsVP8(profile)) |
642 config.Initialize(media::kCodecVP8, media::VP8PROFILE_ANY, kInputFormat, | 649 config.Initialize(media::kCodecVP8, media::VP8PROFILE_ANY, kInputFormat, |
643 media::COLOR_SPACE_UNSPECIFIED, coded_size, visible_size, | 650 media::COLOR_SPACE_UNSPECIFIED, coded_size, visible_size, |
644 natural_size, NULL, 0, false, true); | 651 natural_size, NULL, 0, false, true); |
645 else if (IsH264(profile)) | 652 else if (IsH264(profile)) |
646 config.Initialize(media::kCodecH264, media::H264PROFILE_MAIN, kInputFormat, | 653 config.Initialize(media::kCodecH264, media::H264PROFILE_MAIN, kInputFormat, |
647 media::COLOR_SPACE_UNSPECIFIED, coded_size, visible_size, | 654 media::COLOR_SPACE_UNSPECIFIED, coded_size, visible_size, |
(...skipping 22 matching lines...) Expand all Loading... | |
670 | 677 |
671 void VideoFrameQualityValidator::Decode( | 678 void VideoFrameQualityValidator::Decode( |
672 const scoped_refptr<media::DecoderBuffer>& buffer) { | 679 const scoped_refptr<media::DecoderBuffer>& buffer) { |
673 decoder_->Decode(buffer, decode_cb_); | 680 decoder_->Decode(buffer, decode_cb_); |
674 } | 681 } |
675 | 682 |
676 void VideoFrameQualityValidator::CheckOutputFrame( | 683 void VideoFrameQualityValidator::CheckOutputFrame( |
677 const scoped_refptr<media::VideoFrame>& output_frame) { | 684 const scoped_refptr<media::VideoFrame>& output_frame) { |
678 scoped_refptr<media::VideoFrame> origin_frame = origin_frames_.front(); | 685 scoped_refptr<media::VideoFrame> origin_frame = origin_frames_.front(); |
679 origin_frames_.pop(); | 686 origin_frames_.pop(); |
687 frame_id_++; | |
680 | 688 |
681 gfx::Size visible_size = origin_frame->visible_rect().size(); | 689 gfx::Size visible_size = origin_frame->visible_rect().size(); |
682 int planes[] = {media::VideoFrame::kYPlane, | 690 int planes[] = {media::VideoFrame::kYPlane, |
683 media::VideoFrame::kUPlane, | 691 media::VideoFrame::kUPlane, |
684 media::VideoFrame::kVPlane}; | 692 media::VideoFrame::kVPlane}; |
685 double difference = 0; | 693 double difference = 0; |
686 for (int plane : planes) { | 694 for (int plane : planes) { |
687 uint8_t* origin_plane = origin_frame->data(plane); | 695 uint8_t* origin_plane = origin_frame->data(plane); |
688 uint8_t* output_plane = output_frame->data(plane); | 696 uint8_t* output_plane = output_frame->data(plane); |
689 | 697 |
690 size_t rows = | 698 size_t rows = |
691 media::VideoFrame::Rows(plane, kInputFormat, visible_size.height()); | 699 media::VideoFrame::Rows(plane, kInputFormat, visible_size.height()); |
692 size_t columns = | 700 size_t columns = |
693 media::VideoFrame::Columns(plane, kInputFormat, visible_size.width()); | 701 media::VideoFrame::Columns(plane, kInputFormat, visible_size.width()); |
694 size_t stride = origin_frame->stride(plane); | 702 size_t stride = origin_frame->stride(plane); |
695 | 703 |
696 for (size_t i = 0; i < rows; i++) | 704 for (size_t i = 0; i < rows; i++) |
697 for (size_t j = 0; j < columns; j++) | 705 for (size_t j = 0; j < columns; j++) |
698 difference += std::abs(origin_plane[stride * i + j] - | 706 difference += std::abs(origin_plane[stride * i + j] - |
699 output_plane[stride * i + j]); | 707 output_plane[stride * i + j]); |
700 } | 708 } |
701 // Divide the difference by the size of frame | 709 // Divide the difference by the size of frame |
702 difference /= media::VideoFrame::AllocationSize(kInputFormat, visible_size); | 710 difference /= media::VideoFrame::AllocationSize(kInputFormat, visible_size); |
711 | |
712 // Save both origin and output frames to files if its difference is larger | |
713 // than kDecodeSimilarityThreshold | |
703 CHECK(difference < kDecodeSimilarityThreshold) | 714 CHECK(difference < kDecodeSimilarityThreshold) |
Owen Lin
2015/08/12 08:07:48
I thought we will crash at CHECK and then no outpu
| |
704 << "differrence = " << difference << " > kDecodeSimilarityThreshold"; | 715 << "differrence = " << difference << " > kDecodeSimilarityThreshold"; |
716 if (difference >= kDecodeSimilarityThreshold) { | |
717 std::string filename = | |
718 base::StringPrintf("%.4d_origin_frame.png", frame_id_); | |
719 SaveFrameToFile(origin_frame, base::FilePath::FromUTF8Unsafe(filename)); | |
720 filename = base::StringPrintf("%.4d_output_frame.png", frame_id_); | |
721 SaveFrameToFile(output_frame, base::FilePath::FromUTF8Unsafe(filename)); | |
722 } | |
723 } | |
724 | |
725 void VideoFrameQualityValidator::SaveFrameToFile( | |
726 const scoped_refptr<media::VideoFrame>& frame, | |
727 base::FilePath filename) { | |
Owen Lin
2015/08/12 08:07:48
const base::FilePath &
| |
728 size_t row_bytes = frame->coded_size().width() * 4u; | |
Owen Lin
2015/08/12 08:07:48
use visible size for rgb_bytes.
| |
729 uint8* rgb_pixels = reinterpret_cast<uint8*>( | |
Owen Lin
2015/08/12 08:07:48
How do you free the rgb_pixels
| |
730 base::AlignedAlloc(row_bytes * frame->coded_size().height() + | |
731 media::VideoFrame::kFrameSizePadding, | |
732 media::VideoFrame::kFrameAddressAlignment)); | |
733 media::ConvertYUVToRGB32( | |
734 frame->data(media::VideoFrame::kYPlane), | |
735 frame->data(media::VideoFrame::kUPlane), | |
736 frame->data(media::VideoFrame::kVPlane), rgb_pixels, | |
737 frame->visible_rect().width(), frame->visible_rect().height(), | |
738 frame->stride(media::VideoFrame::kYPlane), | |
739 frame->stride(media::VideoFrame::kUPlane), row_bytes, media::YV12); | |
740 | |
741 std::vector<unsigned char> png_output; | |
742 bool success = gfx::PNGCodec::Encode( | |
743 rgb_pixels, gfx::PNGCodec::FORMAT_RGBA, frame->coded_size(), | |
744 base::checked_cast<int>(row_bytes), true, | |
745 std::vector<gfx::PNGCodec::Comment>(), &png_output); | |
746 if (success) { | |
Owen Lin
2015/08/12 08:07:48
CHECK(gfx::PNGCodec::...);
| |
747 base::WriteFile(filename, reinterpret_cast<char*>(&*png_output.begin()), | |
748 base::checked_cast<int>(png_output.size())); | |
749 } | |
705 } | 750 } |
706 | 751 |
707 class VEAClient : public VideoEncodeAccelerator::Client { | 752 class VEAClient : public VideoEncodeAccelerator::Client { |
708 public: | 753 public: |
709 VEAClient(TestStream* test_stream, | 754 VEAClient(TestStream* test_stream, |
710 ClientStateNotification<ClientState>* note, | 755 ClientStateNotification<ClientState>* note, |
711 bool save_to_file, | 756 bool save_to_file, |
712 unsigned int keyframe_period, | 757 unsigned int keyframe_period, |
713 bool force_bitrate, | 758 bool force_bitrate, |
714 bool test_perf, | 759 bool test_perf, |
(...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1662 | 1707 |
1663 content::g_env = | 1708 content::g_env = |
1664 reinterpret_cast<content::VideoEncodeAcceleratorTestEnvironment*>( | 1709 reinterpret_cast<content::VideoEncodeAcceleratorTestEnvironment*>( |
1665 testing::AddGlobalTestEnvironment( | 1710 testing::AddGlobalTestEnvironment( |
1666 new content::VideoEncodeAcceleratorTestEnvironment( | 1711 new content::VideoEncodeAcceleratorTestEnvironment( |
1667 test_stream_data.Pass(), log_path, run_at_fps, | 1712 test_stream_data.Pass(), log_path, run_at_fps, |
1668 needs_encode_latency, verify_output))); | 1713 needs_encode_latency, verify_output))); |
1669 | 1714 |
1670 return RUN_ALL_TESTS(); | 1715 return RUN_ALL_TESTS(); |
1671 } | 1716 } |
OLD | NEW |