Chromium Code Reviews| Index: media/filters/vp9_parser_unittest.cc |
| diff --git a/media/filters/vp9_parser_unittest.cc b/media/filters/vp9_parser_unittest.cc |
| index 25915e73229a3e38385a31d1458a701763df233b..1bf4666132adef8bb36e721230193e7d2c07154a 100644 |
| --- a/media/filters/vp9_parser_unittest.cc |
| +++ b/media/filters/vp9_parser_unittest.cc |
| @@ -2,7 +2,19 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +// For each sample vp9 test video, $filename, there is a file of golden value |
| +// of frame entropy, named $filename.context. These values are dumped from |
| +// libvpx. |
| +// |
| +// The syntax of these context dump is described as following. For every |
|
Pawel Osciak
2016/08/04 10:20:20
s/following/follows/
kcwu
2016/08/05 11:38:48
Done.
|
| +// frames, there are corresponding data in context file, |
|
Pawel Osciak
2016/08/04 10:20:20
s/frames/frame/
kcwu
2016/08/05 11:38:48
Done.
|
| +// 1. [initial] [current] [should_update=0], or |
| +// 2. [initial] [current] [should_update=1] [update] |
| +// The first two are expected frame entropy, fhdr->initial_frame_context and |
| +// fhdr->frame_context. |
| +// If |should_update| is true, it follows by the frame context to update. |
| #include <stdint.h> |
| +#include <string.h> |
| #include "base/files/memory_mapped_file.h" |
| #include "base/logging.h" |
| @@ -15,8 +27,14 @@ namespace media { |
| class Vp9ParserTest : public ::testing::Test { |
| protected: |
| - void SetUp() override { |
| - base::FilePath file_path = GetTestDataFilePath("test-25fps.vp9"); |
| + void TearDown() override { |
| + stream_.reset(); |
| + vp9_parser_.reset(); |
| + context_file_.Close(); |
| + } |
| + |
| + void Initialize(const std::string& filename, bool parsing_compressed_header) { |
| + base::FilePath file_path = GetTestDataFilePath(filename); |
| stream_.reset(new base::MemoryMappedFile()); |
| ASSERT_TRUE(stream_->Initialize(file_path)) << "Couldn't open stream file: " |
| @@ -26,29 +44,56 @@ class Vp9ParserTest : public ::testing::Test { |
| ASSERT_TRUE(ivf_parser_.Initialize(stream_->data(), stream_->length(), |
| &ivf_file_header)); |
| ASSERT_EQ(ivf_file_header.fourcc, 0x30395056u); // VP90 |
| + |
| + vp9_parser_.reset(new Vp9Parser(parsing_compressed_header)); |
| + |
| + if (parsing_compressed_header) { |
| + base::FilePath context_path = GetTestDataFilePath(filename + ".context"); |
| + context_file_.Initialize(context_path, |
| + base::File::FLAG_OPEN | base::File::FLAG_READ); |
| + ASSERT_TRUE(context_file_.IsValid()); |
| + } |
| } |
| - void TearDown() override { stream_.reset(); } |
| + bool ReadShouldContextUpdate() { |
| + char should_update; |
| + int read_num = context_file_.ReadAtCurrentPos(&should_update, 1); |
| + CHECK_EQ(1, read_num); |
| + return static_cast<bool>(should_update); |
|
Pawel Osciak
2016/08/04 10:20:20
return should_update == 1?
kcwu
2016/08/05 11:38:48
Done.
|
| + } |
| - bool ParseNextFrame(struct Vp9FrameHeader* frame_hdr); |
| + void ReadContext(Vp9FrameContext* frame_context) { |
| + ASSERT_EQ( |
| + static_cast<int>(sizeof(*frame_context)), |
| + context_file_.ReadAtCurrentPos(reinterpret_cast<char*>(frame_context), |
| + sizeof(*frame_context))); |
| + } |
| + |
| + bool ParseNextFrame( |
| + struct Vp9FrameHeader* frame_hdr, |
| + Vp9FrameContextManager::ContextRefreshCallback* context_refresh_cb); |
| - const Vp9Segmentation& GetSegmentation() const { |
| - return vp9_parser_.GetSegmentation(); |
| + const Vp9SegmentationParams& GetSegmentation() const { |
| + return vp9_parser_->GetSegmentation(); |
| } |
| - const Vp9LoopFilter& GetLoopFilter() const { |
| - return vp9_parser_.GetLoopFilter(); |
| + const Vp9LoopFilterParams& GetLoopFilter() const { |
| + return vp9_parser_->GetLoopFilter(); |
| } |
| IvfParser ivf_parser_; |
| std::unique_ptr<base::MemoryMappedFile> stream_; |
| - Vp9Parser vp9_parser_; |
| + std::unique_ptr<Vp9Parser> vp9_parser_; |
| + base::File context_file_; |
| }; |
| -bool Vp9ParserTest::ParseNextFrame(Vp9FrameHeader* fhdr) { |
| +bool Vp9ParserTest::ParseNextFrame( |
| + Vp9FrameHeader* fhdr, |
| + Vp9FrameContextManager::ContextRefreshCallback* context_refresh_cb) { |
| while (1) { |
| - Vp9Parser::Result res = vp9_parser_.ParseNextFrame(fhdr); |
| + Vp9Parser::Result res = |
| + vp9_parser_->ParseNextFrame(fhdr, context_refresh_cb); |
| if (res == Vp9Parser::kEOStream) { |
| IvfFrameHeader ivf_frame_header; |
| const uint8_t* ivf_payload; |
| @@ -56,7 +101,7 @@ bool Vp9ParserTest::ParseNextFrame(Vp9FrameHeader* fhdr) { |
| if (!ivf_parser_.ParseNextFrame(&ivf_frame_header, &ivf_payload)) |
| return false; |
| - vp9_parser_.SetStream(ivf_payload, ivf_frame_header.frame_size); |
| + vp9_parser_->SetStream(ivf_payload, ivf_frame_header.frame_size); |
| continue; |
| } |
| @@ -64,14 +109,17 @@ bool Vp9ParserTest::ParseNextFrame(Vp9FrameHeader* fhdr) { |
| } |
| } |
| -TEST_F(Vp9ParserTest, StreamFileParsing) { |
| +TEST_F(Vp9ParserTest, StreamFileParsingWithoutCompressedHeader) { |
| + Initialize("test-25fps.vp9", false); |
| + |
| // Number of frames in the test stream to be parsed. |
| - const int num_frames = 250; |
| + const int num_expected_frames = 269; |
| int num_parsed_frames = 0; |
| - while (num_parsed_frames < num_frames) { |
| + // Allow to parse double frames in order to detect extra frames parsed. |
|
Pawel Osciak
2016/08/04 10:20:20
s/double/twice as many/
s/extra/any extra/
kcwu
2016/08/05 11:38:48
Done.
|
| + while (num_parsed_frames < num_expected_frames * 2) { |
| Vp9FrameHeader fhdr; |
| - if (!ParseNextFrame(&fhdr)) |
| + if (!ParseNextFrame(&fhdr, nullptr)) |
| break; |
| ++num_parsed_frames; |
| @@ -80,13 +128,89 @@ TEST_F(Vp9ParserTest, StreamFileParsing) { |
| DVLOG(1) << "Number of successfully parsed frames before EOS: " |
| << num_parsed_frames; |
| - EXPECT_EQ(num_frames, num_parsed_frames); |
| + EXPECT_EQ(num_expected_frames, num_parsed_frames); |
| +} |
| + |
| +TEST_F(Vp9ParserTest, StreamFileParsingWithCompressedHeader) { |
| + Initialize("test-25fps.vp9", true); |
| + |
| + // Number of frames in the test stream to be parsed. |
| + const int num_expected_frames = 269; |
| + int num_parsed_frames = 0; |
| + |
| + // Allow to parse double frames in order to detect extra frames parsed. |
| + while (num_parsed_frames < num_expected_frames * 2) { |
| + Vp9FrameHeader fhdr; |
| + Vp9FrameContextManager::ContextRefreshCallback context_refresh_cb; |
| + if (!ParseNextFrame(&fhdr, &context_refresh_cb)) |
| + break; |
| + |
| + Vp9FrameContext frame_context; |
| + ReadContext(&frame_context); |
| + EXPECT_TRUE(memcmp(&frame_context, &fhdr.initial_frame_context, |
| + sizeof(frame_context)) == 0); |
| + ReadContext(&frame_context); |
| + EXPECT_TRUE(memcmp(&frame_context, &fhdr.frame_context, |
| + sizeof(frame_context)) == 0); |
| + |
| + // test-25fps.vp9 doesn't need frame update from driver. |
| + EXPECT_TRUE(context_refresh_cb.is_null()); |
| + ASSERT_FALSE(ReadShouldContextUpdate()); |
| + |
| + ++num_parsed_frames; |
| + } |
| + |
| + DVLOG(1) << "Number of successfully parsed frames before EOS: " |
| + << num_parsed_frames; |
| + |
| + EXPECT_EQ(num_expected_frames, num_parsed_frames); |
| +} |
| + |
| +TEST_F(Vp9ParserTest, StreamFileParsingWithContextUpdate) { |
| + Initialize("bear-vp9.ivf", true); |
| + |
| + // Number of frames in the test stream to be parsed. |
| + const int num_expected_frames = 82; |
| + int num_parsed_frames = 0; |
| + |
| + // Allow to parse double frames in order to detect extra frames parsed. |
| + while (num_parsed_frames < num_expected_frames * 2) { |
| + Vp9FrameHeader fhdr; |
| + Vp9FrameContextManager::ContextRefreshCallback context_refresh_cb; |
| + if (!ParseNextFrame(&fhdr, &context_refresh_cb)) |
| + break; |
| + |
| + Vp9FrameContext frame_context; |
| + ReadContext(&frame_context); |
| + EXPECT_TRUE(memcmp(&frame_context, &fhdr.initial_frame_context, |
| + sizeof(frame_context)) == 0); |
| + ReadContext(&frame_context); |
| + EXPECT_TRUE(memcmp(&frame_context, &fhdr.frame_context, |
| + sizeof(frame_context)) == 0); |
| + |
| + int should_update = ReadShouldContextUpdate(); |
| + if (context_refresh_cb.is_null()) { |
| + EXPECT_FALSE(should_update); |
| + } else { |
| + EXPECT_TRUE(should_update); |
| + ReadContext(&frame_context); |
| + context_refresh_cb.Run(frame_context); |
| + } |
| + |
| + ++num_parsed_frames; |
| + } |
| + |
| + DVLOG(1) << "Number of successfully parsed frames before EOS: " |
| + << num_parsed_frames; |
| + |
| + EXPECT_EQ(num_expected_frames, num_parsed_frames); |
| } |
| TEST_F(Vp9ParserTest, VerifyFirstFrame) { |
| + Initialize("test-25fps.vp9", false); |
| Vp9FrameHeader fhdr; |
| - ASSERT_TRUE(ParseNextFrame(&fhdr)); |
| + ASSERT_TRUE(ParseNextFrame(&fhdr, nullptr)); |
| EXPECT_EQ(0, fhdr.profile); |
| EXPECT_FALSE(fhdr.show_existing_frame); |
| @@ -96,65 +220,66 @@ TEST_F(Vp9ParserTest, VerifyFirstFrame) { |
| EXPECT_EQ(8, fhdr.bit_depth); |
| EXPECT_EQ(Vp9ColorSpace::UNKNOWN, fhdr.color_space); |
| - EXPECT_FALSE(fhdr.yuv_range); |
| + EXPECT_FALSE(fhdr.color_range); |
| EXPECT_EQ(1, fhdr.subsampling_x); |
| EXPECT_EQ(1, fhdr.subsampling_y); |
| - EXPECT_EQ(320u, fhdr.width); |
| - EXPECT_EQ(240u, fhdr.height); |
| - EXPECT_EQ(320u, fhdr.display_width); |
| - EXPECT_EQ(240u, fhdr.display_height); |
| + EXPECT_EQ(320u, fhdr.frame_width); |
| + EXPECT_EQ(240u, fhdr.frame_height); |
| + EXPECT_EQ(320u, fhdr.render_width); |
| + EXPECT_EQ(240u, fhdr.render_height); |
| EXPECT_TRUE(fhdr.refresh_frame_context); |
| EXPECT_TRUE(fhdr.frame_parallel_decoding_mode); |
| - EXPECT_EQ(0, fhdr.frame_context_idx); |
| + EXPECT_EQ(0, fhdr.frame_context_idx_backup); |
| - const Vp9LoopFilter& lf = GetLoopFilter(); |
| - EXPECT_EQ(9, lf.filter_level); |
| - EXPECT_EQ(0, lf.sharpness_level); |
| - EXPECT_TRUE(lf.mode_ref_delta_enabled); |
| - EXPECT_TRUE(lf.mode_ref_delta_update); |
| + const Vp9LoopFilterParams& lf = GetLoopFilter(); |
| + EXPECT_EQ(9, lf.level); |
| + EXPECT_EQ(0, lf.sharpness); |
| + EXPECT_TRUE(lf.delta_enabled); |
| + EXPECT_TRUE(lf.delta_update); |
| EXPECT_TRUE(lf.update_ref_deltas[0]); |
| EXPECT_EQ(1, lf.ref_deltas[0]); |
| EXPECT_EQ(-1, lf.ref_deltas[2]); |
| EXPECT_EQ(-1, lf.ref_deltas[3]); |
| const Vp9QuantizationParams& qp = fhdr.quant_params; |
| - EXPECT_EQ(65, qp.base_qindex); |
| - EXPECT_FALSE(qp.y_dc_delta); |
| - EXPECT_FALSE(qp.uv_dc_delta); |
| - EXPECT_FALSE(qp.uv_ac_delta); |
| + EXPECT_EQ(65, qp.base_q_idx); |
| + EXPECT_FALSE(qp.delta_q_y_dc); |
| + EXPECT_FALSE(qp.delta_q_uv_dc); |
| + EXPECT_FALSE(qp.delta_q_uv_ac); |
| EXPECT_FALSE(qp.IsLossless()); |
| - const Vp9Segmentation& seg = GetSegmentation(); |
| + const Vp9SegmentationParams& seg = GetSegmentation(); |
| EXPECT_FALSE(seg.enabled); |
| - EXPECT_EQ(0, fhdr.log2_tile_cols); |
| - EXPECT_EQ(0, fhdr.log2_tile_rows); |
| + EXPECT_EQ(0, fhdr.tile_cols_log2); |
| + EXPECT_EQ(0, fhdr.tile_rows_log2); |
| - EXPECT_EQ(120u, fhdr.first_partition_size); |
| + EXPECT_EQ(120u, fhdr.header_size_in_bytes); |
| EXPECT_EQ(18u, fhdr.uncompressed_header_size); |
| } |
| TEST_F(Vp9ParserTest, VerifyInterFrame) { |
| + Initialize("test-25fps.vp9", false); |
| Vp9FrameHeader fhdr; |
| // To verify the second frame. |
| for (int i = 0; i < 2; i++) |
| - ASSERT_TRUE(ParseNextFrame(&fhdr)); |
| + ASSERT_TRUE(ParseNextFrame(&fhdr, nullptr)); |
| EXPECT_EQ(Vp9FrameHeader::INTERFRAME, fhdr.frame_type); |
| EXPECT_FALSE(fhdr.show_frame); |
| EXPECT_FALSE(fhdr.intra_only); |
| - EXPECT_FALSE(fhdr.reset_context); |
| + EXPECT_FALSE(fhdr.reset_frame_context); |
| EXPECT_TRUE(fhdr.RefreshFlag(2)); |
| - EXPECT_EQ(0, fhdr.frame_refs[0]); |
| - EXPECT_EQ(1, fhdr.frame_refs[1]); |
| - EXPECT_EQ(2, fhdr.frame_refs[2]); |
| + EXPECT_EQ(0, fhdr.ref_frame_idx[0]); |
| + EXPECT_EQ(1, fhdr.ref_frame_idx[1]); |
| + EXPECT_EQ(2, fhdr.ref_frame_idx[2]); |
| EXPECT_TRUE(fhdr.allow_high_precision_mv); |
| - EXPECT_EQ(Vp9InterpFilter::EIGHTTAP, fhdr.interp_filter); |
| + EXPECT_EQ(Vp9InterpolationFilter::EIGHTTAP, fhdr.interpolation_filter); |
| - EXPECT_EQ(48u, fhdr.first_partition_size); |
| + EXPECT_EQ(48u, fhdr.header_size_in_bytes); |
| EXPECT_EQ(11u, fhdr.uncompressed_header_size); |
| } |