Chromium Code Reviews| Index: content/common/gpu/media/video_encode_accelerator_unittest.cc |
| diff --git a/content/common/gpu/media/video_encode_accelerator_unittest.cc b/content/common/gpu/media/video_encode_accelerator_unittest.cc |
| index d94941cf5016a5e519ca98ce7b84ed7f5c777521..81730f4f8b807eb712473496b66d55e0f95240ad 100644 |
| --- a/content/common/gpu/media/video_encode_accelerator_unittest.cc |
| +++ b/content/common/gpu/media/video_encode_accelerator_unittest.cc |
| @@ -31,6 +31,7 @@ |
| #include "media/base/test_data_util.h" |
| #include "media/base/video_decoder.h" |
| #include "media/base/video_frame.h" |
| +#include "media/base/yuv_convert.h" |
| #include "media/filters/ffmpeg_glue.h" |
| #include "media/filters/ffmpeg_video_decoder.h" |
| #include "media/filters/h264_parser.h" |
| @@ -38,6 +39,7 @@ |
| #include "media/video/fake_video_encode_accelerator.h" |
| #include "media/video/video_encode_accelerator.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| +#include "ui/gfx/codec/png_codec.h" |
| #if defined(OS_CHROMEOS) |
| #if defined(ARCH_CPU_ARMEL) || (defined(USE_OZONE) && defined(USE_V4L2_CODEC)) |
| @@ -615,6 +617,8 @@ class VideoFrameQualityValidator { |
| void FlushDone(media::VideoDecoder::Status status); |
| void VerifyOutputFrame(const scoped_refptr<media::VideoFrame>& output_frame); |
| void Decode(); |
| + void SaveFrameToFile(const scoped_refptr<media::VideoFrame>& frame, |
| + const base::FilePath& filename); |
| enum State { UNINITIALIZED, INITIALIZED, DECODING, ERROR }; |
| @@ -629,6 +633,8 @@ class VideoFrameQualityValidator { |
| State decoder_state_; |
| std::queue<scoped_refptr<media::VideoFrame>> original_frames_; |
| std::queue<scoped_refptr<media::DecoderBuffer>> decode_buffers_; |
| + |
|
wuchengli
2015/09/04 11:59:44
Document if the id starts from 0. It's confusing l
|
| + int frame_id_; |
| }; |
| VideoFrameQualityValidator::VideoFrameQualityValidator( |
| @@ -644,7 +650,8 @@ VideoFrameQualityValidator::VideoFrameQualityValidator( |
| base::Unretained(this))), |
| flush_complete_cb_(flush_complete_cb), |
| decode_error_cb_(decode_error_cb), |
| - decoder_state_(UNINITIALIZED) { |
| + decoder_state_(UNINITIALIZED), |
| + frame_id_(0) { |
| // Allow decoding of individual NALU. Entire frames are required by default. |
| decoder_->set_decode_nalus(true); |
| } |
| @@ -740,6 +747,7 @@ void VideoFrameQualityValidator::VerifyOutputFrame( |
| scoped_refptr<media::VideoFrame> original_frame = original_frames_.front(); |
| original_frames_.pop(); |
| gfx::Size visible_size = original_frame->visible_rect().size(); |
| + frame_id_++; |
| int planes[] = {media::VideoFrame::kYPlane, media::VideoFrame::kUPlane, |
| media::VideoFrame::kVPlane}; |
| @@ -761,8 +769,46 @@ void VideoFrameQualityValidator::VerifyOutputFrame( |
| } |
| // Divide the difference by the size of frame. |
| difference /= media::VideoFrame::AllocationSize(kInputFormat, visible_size); |
| - EXPECT_TRUE(difference <= kDecodeSimilarityThreshold) |
| - << "differrence = " << difference << " > decode similarity threshold"; |
| + |
| + // Save both origin and output frames to files if its difference is larger |
|
wuchengli
2015/09/04 11:59:44
s/its/their/
|
| + // than kDecodeSimilarityThreshold |
|
wuchengli
2015/09/04 11:59:44
add . at the end.
|
| + if (difference >= kDecodeSimilarityThreshold) { |
| + ADD_FAILURE() << "differrence = " << difference |
| + << " > decode similarity threshold"; |
| + std::string filename = |
| + base::StringPrintf("%.4d_origin_frame.png", frame_id_); |
| + SaveFrameToFile(original_frame, base::FilePath::FromUTF8Unsafe(filename)); |
| + filename = base::StringPrintf("%.4d_output_frame.png", frame_id_); |
| + SaveFrameToFile(output_frame, base::FilePath::FromUTF8Unsafe(filename)); |
| + } |
| +} |
| + |
| +void VideoFrameQualityValidator::SaveFrameToFile( |
| + const scoped_refptr<media::VideoFrame>& frame, |
| + const base::FilePath& filename) { |
| + const int RGB32_BYTES_PER_PIXEL = 4; |
| + size_t row_bytes = frame->visible_rect().width() * RGB32_BYTES_PER_PIXEL; |
| + uint8* rgb_pixels = reinterpret_cast<uint8*>( |
| + base::AlignedAlloc(row_bytes * frame->coded_size().height() + |
|
wuchengli
2015/09/04 11:59:44
Why do we need the alignment?
|
| + media::VideoFrame::kFrameSizePadding, |
|
wuchengli
2015/09/04 11:59:44
Is this required?
|
| + media::VideoFrame::kFrameAddressAlignment)); |
| + media::ConvertYUVToRGB32( |
| + frame->data(media::VideoFrame::kYPlane), |
| + frame->data(media::VideoFrame::kUPlane), |
| + frame->data(media::VideoFrame::kVPlane), rgb_pixels, |
| + frame->visible_rect().width(), frame->visible_rect().height(), |
| + frame->stride(media::VideoFrame::kYPlane), |
| + frame->stride(media::VideoFrame::kUPlane), row_bytes, media::YV12); |
|
wuchengli
2015/09/04 11:59:44
Is the original frame also YV12? We should documen
|
| + |
| + std::vector<unsigned char> png_output; |
| + LOG_ASSERT(gfx::PNGCodec::Encode( |
| + rgb_pixels, gfx::PNGCodec::FORMAT_RGBA, frame->coded_size(), |
|
wuchengli
2015/09/04 11:59:43
why this is not visible_rect()?
|
| + base::checked_cast<int>(row_bytes), true, |
| + std::vector<gfx::PNGCodec::Comment>(), &png_output)); |
| + base::AlignedFree(rgb_pixels); |
| + base::WriteFile(filename, reinterpret_cast<char*>(&png_output[0]), |
| + base::checked_cast<int>(png_output.size())); |
| + |
|
wuchengli
2015/09/04 11:59:44
remove blank line
|
| } |
| class VEAClient : public VideoEncodeAccelerator::Client { |