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..b396be8d95683fe27106b0029b7143cf3fc51d94 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_; |
+ |
+ 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); |
} |
@@ -652,6 +659,7 @@ VideoFrameQualityValidator::VideoFrameQualityValidator( |
void VideoFrameQualityValidator::Initialize(const gfx::Size& coded_size, |
const gfx::Rect& visible_size) { |
media::FFmpegGlue::InitializeFFmpeg(); |
+ media::InitializeCPUSpecificYUVConversions(); |
gfx::Size natural_size(visible_size.size()); |
// The default output format of ffmpeg video decoder is YV12. |
@@ -740,6 +748,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}; |
@@ -763,6 +772,42 @@ void VideoFrameQualityValidator::VerifyOutputFrame( |
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 |
+ // than kDecodeSimilarityThreshold |
+ if (difference >= kDecodeSimilarityThreshold) { |
+ 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)); |
Owen Lin
2015/09/04 03:34:47
Remove EXPECT_TRUE at l.773
Add the following line
|
+ } |
+} |
+ |
+void VideoFrameQualityValidator::SaveFrameToFile( |
+ const scoped_refptr<media::VideoFrame>& frame, |
+ const base::FilePath& filename) { |
+ size_t row_bytes = frame->visible_rect().width() * 4u; |
Owen Lin
2015/09/04 03:34:47
const int RGB32_BYTES_PER_PIXEL = 4;
|
+ uint8* rgb_pixels = reinterpret_cast<uint8*>( |
+ base::AlignedAlloc(row_bytes * frame->coded_size().height() + |
+ media::VideoFrame::kFrameSizePadding, |
+ 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); |
+ |
+ std::vector<unsigned char> png_output; |
+ CHECK(gfx::PNGCodec::Encode( |
Owen Lin
2015/09/04 03:34:47
LOG_ASSERT
|
+ rgb_pixels, gfx::PNGCodec::FORMAT_RGBA, frame->coded_size(), |
+ base::checked_cast<int>(row_bytes), true, |
+ std::vector<gfx::PNGCodec::Comment>(), &png_output)); |
+ base::WriteFile(filename, reinterpret_cast<char*>(&*png_output.begin()), |
Owen Lin
2015/09/04 03:34:47
&png_output[0]
|
+ base::checked_cast<int>(png_output.size())); |
+ base::AlignedFree(rgb_pixels); |
} |
class VEAClient : public VideoEncodeAccelerator::Client { |