Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: content/common/gpu/media/video_encode_accelerator_unittest.cc

Issue 1286983002: Save both original frame and output frame into files if the absolute differences is larger than the… Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address review comments Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | content/content_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 13 matching lines...) Expand all
24 #include "base/threading/thread_checker.h" 24 #include "base/threading/thread_checker.h"
25 #include "base/time/time.h" 25 #include "base/time/time.h"
26 #include "base/timer/timer.h" 26 #include "base/timer/timer.h"
27 #include "content/common/gpu/media/video_accelerator_unittest_helpers.h" 27 #include "content/common/gpu/media/video_accelerator_unittest_helpers.h"
28 #include "media/base/bind_to_current_loop.h" 28 #include "media/base/bind_to_current_loop.h"
29 #include "media/base/bitstream_buffer.h" 29 #include "media/base/bitstream_buffer.h"
30 #include "media/base/decoder_buffer.h" 30 #include "media/base/decoder_buffer.h"
31 #include "media/base/test_data_util.h" 31 #include "media/base/test_data_util.h"
32 #include "media/base/video_decoder.h" 32 #include "media/base/video_decoder.h"
33 #include "media/base/video_frame.h" 33 #include "media/base/video_frame.h"
34 #include "media/base/yuv_convert.h"
34 #include "media/filters/ffmpeg_glue.h" 35 #include "media/filters/ffmpeg_glue.h"
35 #include "media/filters/ffmpeg_video_decoder.h" 36 #include "media/filters/ffmpeg_video_decoder.h"
36 #include "media/filters/h264_parser.h" 37 #include "media/filters/h264_parser.h"
37 #include "media/filters/ivf_parser.h" 38 #include "media/filters/ivf_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 // Status has been defined as int in Xlib.h. 51 // Status has been defined as int in Xlib.h.
50 #undef Status 52 #undef Status
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 void AddDecodeBuffer(const scoped_refptr<media::DecoderBuffer>& buffer); 610 void AddDecodeBuffer(const scoped_refptr<media::DecoderBuffer>& buffer);
609 // Flush the decoder. 611 // Flush the decoder.
610 void Flush(); 612 void Flush();
611 613
612 private: 614 private:
613 void InitializeCB(bool success); 615 void InitializeCB(bool success);
614 void DecodeDone(media::VideoDecoder::Status status); 616 void DecodeDone(media::VideoDecoder::Status status);
615 void FlushDone(media::VideoDecoder::Status status); 617 void FlushDone(media::VideoDecoder::Status status);
616 void VerifyOutputFrame(const scoped_refptr<media::VideoFrame>& output_frame); 618 void VerifyOutputFrame(const scoped_refptr<media::VideoFrame>& output_frame);
617 void Decode(); 619 void Decode();
620 void SaveFrameToFile(const scoped_refptr<media::VideoFrame>& frame,
621 const base::FilePath& filename);
618 622
619 enum State { UNINITIALIZED, INITIALIZED, DECODING, ERROR }; 623 enum State { UNINITIALIZED, INITIALIZED, DECODING, ERROR };
620 624
621 const media::VideoCodecProfile profile_; 625 const media::VideoCodecProfile profile_;
622 scoped_ptr<media::FFmpegVideoDecoder> decoder_; 626 scoped_ptr<media::FFmpegVideoDecoder> decoder_;
623 media::VideoDecoder::DecodeCB decode_cb_; 627 media::VideoDecoder::DecodeCB decode_cb_;
624 // Decode callback of an EOS buffer. 628 // Decode callback of an EOS buffer.
625 media::VideoDecoder::DecodeCB eos_decode_cb_; 629 media::VideoDecoder::DecodeCB eos_decode_cb_;
626 // Callback of Flush(). Called after all frames are decoded. 630 // Callback of Flush(). Called after all frames are decoded.
627 const base::Closure flush_complete_cb_; 631 const base::Closure flush_complete_cb_;
628 const base::Closure decode_error_cb_; 632 const base::Closure decode_error_cb_;
629 State decoder_state_; 633 State decoder_state_;
630 std::queue<scoped_refptr<media::VideoFrame>> original_frames_; 634 std::queue<scoped_refptr<media::VideoFrame>> original_frames_;
631 std::queue<scoped_refptr<media::DecoderBuffer>> decode_buffers_; 635 std::queue<scoped_refptr<media::DecoderBuffer>> decode_buffers_;
636
637 int frame_id_;
632 }; 638 };
633 639
634 VideoFrameQualityValidator::VideoFrameQualityValidator( 640 VideoFrameQualityValidator::VideoFrameQualityValidator(
635 const media::VideoCodecProfile profile, 641 const media::VideoCodecProfile profile,
636 const base::Closure& flush_complete_cb, 642 const base::Closure& flush_complete_cb,
637 const base::Closure& decode_error_cb) 643 const base::Closure& decode_error_cb)
638 : profile_(profile), 644 : profile_(profile),
639 decoder_(new media::FFmpegVideoDecoder(base::MessageLoop::current() 645 decoder_(new media::FFmpegVideoDecoder(base::MessageLoop::current()
640 ->task_runner())), 646 ->task_runner())),
641 decode_cb_(base::Bind(&VideoFrameQualityValidator::DecodeDone, 647 decode_cb_(base::Bind(&VideoFrameQualityValidator::DecodeDone,
642 base::Unretained(this))), 648 base::Unretained(this))),
643 eos_decode_cb_(base::Bind(&VideoFrameQualityValidator::FlushDone, 649 eos_decode_cb_(base::Bind(&VideoFrameQualityValidator::FlushDone,
644 base::Unretained(this))), 650 base::Unretained(this))),
645 flush_complete_cb_(flush_complete_cb), 651 flush_complete_cb_(flush_complete_cb),
646 decode_error_cb_(decode_error_cb), 652 decode_error_cb_(decode_error_cb),
647 decoder_state_(UNINITIALIZED) { 653 decoder_state_(UNINITIALIZED),
654 frame_id_(0) {
648 // Allow decoding of individual NALU. Entire frames are required by default. 655 // Allow decoding of individual NALU. Entire frames are required by default.
649 decoder_->set_decode_nalus(true); 656 decoder_->set_decode_nalus(true);
650 } 657 }
651 658
652 void VideoFrameQualityValidator::Initialize(const gfx::Size& coded_size, 659 void VideoFrameQualityValidator::Initialize(const gfx::Size& coded_size,
653 const gfx::Rect& visible_size) { 660 const gfx::Rect& visible_size) {
654 media::FFmpegGlue::InitializeFFmpeg(); 661 media::FFmpegGlue::InitializeFFmpeg();
655 662
656 gfx::Size natural_size(visible_size.size()); 663 gfx::Size natural_size(visible_size.size());
657 // The default output format of ffmpeg video decoder is YV12. 664 // The default output format of ffmpeg video decoder is YV12.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 else 740 else
734 decoder_->Decode(next_buffer, decode_cb_); 741 decoder_->Decode(next_buffer, decode_cb_);
735 } 742 }
736 } 743 }
737 744
738 void VideoFrameQualityValidator::VerifyOutputFrame( 745 void VideoFrameQualityValidator::VerifyOutputFrame(
739 const scoped_refptr<media::VideoFrame>& output_frame) { 746 const scoped_refptr<media::VideoFrame>& output_frame) {
740 scoped_refptr<media::VideoFrame> original_frame = original_frames_.front(); 747 scoped_refptr<media::VideoFrame> original_frame = original_frames_.front();
741 original_frames_.pop(); 748 original_frames_.pop();
742 gfx::Size visible_size = original_frame->visible_rect().size(); 749 gfx::Size visible_size = original_frame->visible_rect().size();
750 frame_id_++;
743 751
744 int planes[] = {media::VideoFrame::kYPlane, media::VideoFrame::kUPlane, 752 int planes[] = {media::VideoFrame::kYPlane, media::VideoFrame::kUPlane,
745 media::VideoFrame::kVPlane}; 753 media::VideoFrame::kVPlane};
746 double difference = 0; 754 double difference = 0;
747 for (int plane : planes) { 755 for (int plane : planes) {
748 uint8_t* original_plane = original_frame->data(plane); 756 uint8_t* original_plane = original_frame->data(plane);
749 uint8_t* output_plane = output_frame->data(plane); 757 uint8_t* output_plane = output_frame->data(plane);
750 758
751 size_t rows = 759 size_t rows =
752 media::VideoFrame::Rows(plane, kInputFormat, visible_size.height()); 760 media::VideoFrame::Rows(plane, kInputFormat, visible_size.height());
753 size_t columns = 761 size_t columns =
754 media::VideoFrame::Columns(plane, kInputFormat, visible_size.width()); 762 media::VideoFrame::Columns(plane, kInputFormat, visible_size.width());
755 size_t stride = original_frame->stride(plane); 763 size_t stride = original_frame->stride(plane);
756 764
757 for (size_t i = 0; i < rows; i++) 765 for (size_t i = 0; i < rows; i++)
758 for (size_t j = 0; j < columns; j++) 766 for (size_t j = 0; j < columns; j++)
759 difference += std::abs(original_plane[stride * i + j] - 767 difference += std::abs(original_plane[stride * i + j] -
760 output_plane[stride * i + j]); 768 output_plane[stride * i + j]);
761 } 769 }
762 // Divide the difference by the size of frame. 770 // Divide the difference by the size of frame.
763 difference /= media::VideoFrame::AllocationSize(kInputFormat, visible_size); 771 difference /= media::VideoFrame::AllocationSize(kInputFormat, visible_size);
764 EXPECT_TRUE(difference <= kDecodeSimilarityThreshold) 772
765 << "differrence = " << difference << " > decode similarity threshold"; 773 // Save both origin and output frames to files if its difference is larger
774 // than kDecodeSimilarityThreshold
775 if (difference >= kDecodeSimilarityThreshold) {
776 ADD_FAILURE() << "differrence = " << difference
777 << " > decode similarity threshold";
778 std::string filename =
779 base::StringPrintf("%.4d_origin_frame.png", frame_id_);
780 SaveFrameToFile(original_frame, base::FilePath::FromUTF8Unsafe(filename));
781 filename = base::StringPrintf("%.4d_output_frame.png", frame_id_);
782 SaveFrameToFile(output_frame, base::FilePath::FromUTF8Unsafe(filename));
783 }
784 }
785
786 void VideoFrameQualityValidator::SaveFrameToFile(
787 const scoped_refptr<media::VideoFrame>& frame,
788 const base::FilePath& filename) {
789 const int RGB32_BYTES_PER_PIXEL = 4;
790 size_t row_bytes = frame->visible_rect().width() * RGB32_BYTES_PER_PIXEL;
791 uint8* rgb_pixels = reinterpret_cast<uint8*>(
792 base::AlignedAlloc(row_bytes * frame->coded_size().height() +
793 media::VideoFrame::kFrameSizePadding,
794 media::VideoFrame::kFrameAddressAlignment));
795 media::ConvertYUVToRGB32(
796 frame->data(media::VideoFrame::kYPlane),
797 frame->data(media::VideoFrame::kUPlane),
798 frame->data(media::VideoFrame::kVPlane), rgb_pixels,
799 frame->visible_rect().width(), frame->visible_rect().height(),
800 frame->stride(media::VideoFrame::kYPlane),
801 frame->stride(media::VideoFrame::kUPlane), row_bytes, media::YV12);
802
803 std::vector<unsigned char> png_output;
804 LOG_ASSERT(gfx::PNGCodec::Encode(
805 rgb_pixels, gfx::PNGCodec::FORMAT_RGBA, frame->coded_size(),
806 base::checked_cast<int>(row_bytes), true,
807 std::vector<gfx::PNGCodec::Comment>(), &png_output));
808 base::WriteFile(filename, reinterpret_cast<char*>(&png_output[0]),
809 base::checked_cast<int>(png_output.size()));
810 base::AlignedFree(rgb_pixels);
Owen Lin 2015/09/04 07:03:56 move to the line above WriteFile.
766 } 811 }
767 812
768 class VEAClient : public VideoEncodeAccelerator::Client { 813 class VEAClient : public VideoEncodeAccelerator::Client {
769 public: 814 public:
770 VEAClient(TestStream* test_stream, 815 VEAClient(TestStream* test_stream,
771 ClientStateNotification<ClientState>* note, 816 ClientStateNotification<ClientState>* note,
772 bool save_to_file, 817 bool save_to_file,
773 unsigned int keyframe_period, 818 unsigned int keyframe_period,
774 bool force_bitrate, 819 bool force_bitrate,
775 bool test_perf, 820 bool test_perf,
(...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 1810
1766 content::g_env = 1811 content::g_env =
1767 reinterpret_cast<content::VideoEncodeAcceleratorTestEnvironment*>( 1812 reinterpret_cast<content::VideoEncodeAcceleratorTestEnvironment*>(
1768 testing::AddGlobalTestEnvironment( 1813 testing::AddGlobalTestEnvironment(
1769 new content::VideoEncodeAcceleratorTestEnvironment( 1814 new content::VideoEncodeAcceleratorTestEnvironment(
1770 test_stream_data.Pass(), log_path, run_at_fps, 1815 test_stream_data.Pass(), log_path, run_at_fps,
1771 needs_encode_latency, verify_all_output))); 1816 needs_encode_latency, verify_all_output)));
1772 1817
1773 return RUN_ALL_TESTS(); 1818 return RUN_ALL_TESTS();
1774 } 1819 }
OLDNEW
« no previous file with comments | « no previous file | content/content_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698