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 { |