Commit 090f680b authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

media/gpu/VDA unittest: Enable video frame validator in evey TestSimpleDecode test case

This enables VideoFrameValidator in evey TestSimpleDecode test case, that is,
the test case except TestDecodeTimeMedia (performance test) and NoCrash.

Because an input stream is decoded repeatedly, the index in display order of
video frame on PictureReady() needs to be passed to VideoFrameValidator.
It seems there is no good way to get the frame index from Picture. So I just
count up the index on PictureReady() and reset it to 0 on NotifyResetDone().
This seems a hacky way and only works with the current VDA unittest, which
always rewind to the beginning of the stream and does not jump to the middle of
the stream.

BUG=chromium:856562
TEST=VDA unittest on eve with frame validator
$ ./video_decode_accelerator_unittest --test_video_data=test-25fps.h264:320:240:250:258:35:150:1 --ozone-platform=gbm  --test_import --frame_validator

Change-Id: I8fbbf165254f4e26c69f8da27b41ff3b9f395224
Reviewed-on: https://chromium-review.googlesource.com/c/1304286
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604171}
parent 798f1b32
...@@ -48,19 +48,29 @@ VideoFrameValidator::VideoFrameValidator( ...@@ -48,19 +48,29 @@ VideoFrameValidator::VideoFrameValidator(
VideoFrameValidator::~VideoFrameValidator() {} VideoFrameValidator::~VideoFrameValidator() {}
void VideoFrameValidator::EvaluateVideoFrame( void VideoFrameValidator::EvaluateVideoFrame(
scoped_refptr<VideoFrame> video_frame) { scoped_refptr<VideoFrame> video_frame,
size_t frame_index) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
std::string expected_md5; std::string expected_md5;
LOG_IF(FATAL, frame_index_ >= md5_of_frames_.size()) LOG_IF(FATAL, frame_index >= md5_of_frames_.size())
<< "Frame number is over than the number of read md5 values in file."; << "Frame number is over than the number of read md5 values in file.";
expected_md5 = md5_of_frames_[frame_index_]; expected_md5 = md5_of_frames_[frame_index];
std::string computed_md5 = ComputeMD5FromVideoFrame(std::move(video_frame)); auto standard_frame = CreateStandardizedFrame(video_frame);
if (!standard_frame) {
LOG(ERROR) << "Failed to create standardized frame.";
return;
}
std::string computed_md5 = ComputeMD5FromVideoFrame(standard_frame);
if (computed_md5 != expected_md5) { if (computed_md5 != expected_md5) {
mismatched_frames_.push_back( mismatched_frames_.push_back(
MismatchedFrameInfo{frame_index_, computed_md5, expected_md5}); MismatchedFrameInfo{frame_index, computed_md5, expected_md5});
}
if (!prefix_output_yuv_.empty()) {
// Output yuv.
LOG_IF(WARNING, !WriteI420ToFile(frame_index, standard_frame.get()))
<< "Failed to write yuv into file.";
} }
frame_index_++;
} }
std::vector<VideoFrameValidator::MismatchedFrameInfo> std::vector<VideoFrameValidator::MismatchedFrameInfo>
...@@ -68,34 +78,27 @@ VideoFrameValidator::GetMismatchedFramesInfo() const { ...@@ -68,34 +78,27 @@ VideoFrameValidator::GetMismatchedFramesInfo() const {
return mismatched_frames_; return mismatched_frames_;
} }
std::string VideoFrameValidator::ComputeMD5FromVideoFrame( scoped_refptr<VideoFrame> VideoFrameValidator::CreateStandardizedFrame(
scoped_refptr<VideoFrame> video_frame) const { scoped_refptr<VideoFrame> video_frame) const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto mapped_frame = video_frame_mapper_->Map(std::move(video_frame)); auto mapped_frame = video_frame_mapper_->Map(std::move(video_frame));
if (!mapped_frame) { if (!mapped_frame) {
LOG(FATAL) << "Failed to map decoded picture."; LOG(FATAL) << "Failed to map decoded picture.";
return std::string(); return nullptr;
} }
auto i420_frame = CreateI420Frame(mapped_frame.get()); return CreateI420Frame(mapped_frame.get());
if (!i420_frame) { }
LOG(ERROR) << "Failed to convert to I420";
return std::string();
}
std::string VideoFrameValidator::ComputeMD5FromVideoFrame(
scoped_refptr<VideoFrame> video_frame) const {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
base::MD5Context context; base::MD5Context context;
base::MD5Init(&context); base::MD5Init(&context);
VideoFrame::HashFrameForTesting(&context, i420_frame); VideoFrame::HashFrameForTesting(&context, video_frame);
base::MD5Digest digest; base::MD5Digest digest;
base::MD5Final(&digest, &context); base::MD5Final(&digest, &context);
auto md5_string = MD5DigestToBase16(digest); return MD5DigestToBase16(digest);
if (!prefix_output_yuv_.empty()) {
// Output yuv.
LOG_IF(WARNING, !WriteI420ToFile(frame_index_, i420_frame.get()))
<< "Failed to write yuv into file.";
}
return md5_string;
} }
scoped_refptr<VideoFrame> VideoFrameValidator::CreateI420Frame( scoped_refptr<VideoFrame> VideoFrameValidator::CreateI420Frame(
......
...@@ -55,10 +55,9 @@ class VideoFrameValidator { ...@@ -55,10 +55,9 @@ class VideoFrameValidator {
// This checks if |video_frame|'s pixel content is as expected. // This checks if |video_frame|'s pixel content is as expected.
// A client of VideoFrameValidator would call this function on each frame in // A client of VideoFrameValidator would call this function on each frame in
// PictureReady(). // PictureReady().
// The client MUST pass video frames in display order. // |frame_index| is the index of video frame in display order.
// TODO(crbug.com/856562): Specify frame index and compare the index-th video void EvaluateVideoFrame(scoped_refptr<VideoFrame> video_frame,
// frame, so that a client can call this in any order. size_t frame_index);
void EvaluateVideoFrame(scoped_refptr<VideoFrame> video_frame);
// Returns information of frames that don't match golden md5 values. // Returns information of frames that don't match golden md5 values.
// If there is no mismatched frame, returns an empty vector. // If there is no mismatched frame, returns an empty vector.
...@@ -69,13 +68,17 @@ class VideoFrameValidator { ...@@ -69,13 +68,17 @@ class VideoFrameValidator {
std::vector<std::string> md5_of_frames, std::vector<std::string> md5_of_frames,
std::unique_ptr<VideoFrameMapper> video_frame_mapper); std::unique_ptr<VideoFrameMapper> video_frame_mapper);
// This maps |video_frame|, converts it to I420 format and computes the MD5 // This maps |video_frame|, converts it to I420 format.
// value of the converted I420 video frame. // Returns the resulted I420 frame on success, and otherwise return nullptr.
// |video_frame| is unchanged in this method. // |video_frame| is unchanged in this method.
scoped_refptr<VideoFrame> CreateStandardizedFrame(
scoped_refptr<VideoFrame> video_frame) const;
// Returns md5 values of video frame represented by |video_frame|.
std::string ComputeMD5FromVideoFrame( std::string ComputeMD5FromVideoFrame(
scoped_refptr<VideoFrame> video_frame) const; scoped_refptr<VideoFrame> video_frame) const;
// Create VideoFrame with I420 format from |src_frame|. // Creates VideoFrame with I420 format from |src_frame|.
scoped_refptr<VideoFrame> CreateI420Frame( scoped_refptr<VideoFrame> CreateI420Frame(
const VideoFrame* const src_frame) const; const VideoFrame* const src_frame) const;
...@@ -86,9 +89,6 @@ class VideoFrameValidator { ...@@ -86,9 +89,6 @@ class VideoFrameValidator {
// The results of invalid frame data. // The results of invalid frame data.
std::vector<MismatchedFrameInfo> mismatched_frames_; std::vector<MismatchedFrameInfo> mismatched_frames_;
// Current frame index to be evaluated.
size_t frame_index_ = 0;
// Prefix of saved yuv files. // Prefix of saved yuv files.
const base::FilePath prefix_output_yuv_; const base::FilePath prefix_output_yuv_;
......
...@@ -365,6 +365,7 @@ class GLRenderingVDAClient ...@@ -365,6 +365,7 @@ class GLRenderingVDAClient
size_t num_queued_fragments_; size_t num_queued_fragments_;
size_t num_decoded_frames_; size_t num_decoded_frames_;
size_t num_done_bitstream_buffers_; size_t num_done_bitstream_buffers_;
size_t frame_index_;
base::TimeTicks initialize_done_ticks_; base::TimeTicks initialize_done_ticks_;
GLenum texture_target_; GLenum texture_target_;
VideoPixelFormat pixel_format_; VideoPixelFormat pixel_format_;
...@@ -426,6 +427,7 @@ GLRenderingVDAClient::GLRenderingVDAClient( ...@@ -426,6 +427,7 @@ GLRenderingVDAClient::GLRenderingVDAClient(
num_queued_fragments_(0), num_queued_fragments_(0),
num_decoded_frames_(0), num_decoded_frames_(0),
num_done_bitstream_buffers_(0), num_done_bitstream_buffers_(0),
frame_index_(0),
texture_target_(0), texture_target_(0),
pixel_format_(PIXEL_FORMAT_UNKNOWN), pixel_format_(PIXEL_FORMAT_UNKNOWN),
next_picture_buffer_id_(1), next_picture_buffer_id_(1),
...@@ -604,7 +606,9 @@ void GLRenderingVDAClient::PictureReady(const Picture& picture) { ...@@ -604,7 +606,9 @@ void GLRenderingVDAClient::PictureReady(const Picture& picture) {
if (video_frame_validator_) { if (video_frame_validator_) {
auto video_frame = texture_it->second->CreateVideoFrame(visible_rect); auto video_frame = texture_it->second->CreateVideoFrame(visible_rect);
ASSERT_NE(video_frame.get(), nullptr); ASSERT_NE(video_frame.get(), nullptr);
video_frame_validator_->EvaluateVideoFrame(std::move(video_frame)); video_frame_validator_->EvaluateVideoFrame(std::move(video_frame),
frame_index_);
frame_index_++;
} }
rendering_helper_->ConsumeVideoFrame(config_.window_id, rendering_helper_->ConsumeVideoFrame(config_.window_id,
std::move(video_frame_texture)); std::move(video_frame_texture));
...@@ -706,6 +710,7 @@ void GLRenderingVDAClient::NotifyResetDone() { ...@@ -706,6 +710,7 @@ void GLRenderingVDAClient::NotifyResetDone() {
if (decoder_deleted()) if (decoder_deleted())
return; return;
frame_index_ = 0;
switch (reset_point_) { switch (reset_point_) {
case DONE_RESET_AFTER_FIRST_CONFIG_INFO: case DONE_RESET_AFTER_FIRST_CONFIG_INFO:
case MID_STREAM_RESET: case MID_STREAM_RESET:
...@@ -1201,10 +1206,7 @@ TEST_P(VideoDecodeAcceleratorParamTest, MAYBE_TestSimpleDecode) { ...@@ -1201,10 +1206,7 @@ TEST_P(VideoDecodeAcceleratorParamTest, MAYBE_TestSimpleDecode) {
notes_.resize(num_concurrent_decoders); notes_.resize(num_concurrent_decoders);
clients_.resize(num_concurrent_decoders); clients_.resize(num_concurrent_decoders);
// TODO(crbug.com/856562): Use Frame Validator in every test case, not bool use_video_frame_validator = g_frame_validator && g_test_import;
// limited to thumbnail test case.
bool use_video_frame_validator =
render_as_thumbnails && g_frame_validator && g_test_import;
if (use_video_frame_validator) { if (use_video_frame_validator) {
LOG(INFO) << "Using Frame Validator.."; LOG(INFO) << "Using Frame Validator..";
#if !defined(OS_CHROMEOS) #if !defined(OS_CHROMEOS)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment