ref: 02410659cd1e637bb6f345508213741b64c81fad
parent: 48c5d470e78436a6abde1c14c183f1a9d30f04de
parent: a3ef7d5a5086b2aa2832ff92b23fa6b6b0664c98
author: hkuang <[email protected]>
date: Thu Aug 14 10:55:09 EDT 2014
Merge "Add VP9 frame-parallel unit test." into frame_parallel
--- a/test/codec_factory.h
+++ b/test/codec_factory.h
@@ -35,6 +35,10 @@
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const = 0;
+ virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
+ const vpx_codec_flags_t flags,
+ unsigned long deadline) const = 0; // NOLINT
+
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
unsigned long deadline,
const unsigned long init_flags,
@@ -72,6 +76,10 @@
VP8Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: Decoder(cfg, deadline) {}
+ VP8Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
+ unsigned long deadline) // NOLINT
+ : Decoder(cfg, flag, deadline) {}
+
protected:
virtual vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP8_DECODER
@@ -104,8 +112,14 @@
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const {
+ return CreateDecoder(cfg, 0, deadline);
+ }
+
+ virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
+ const vpx_codec_flags_t flags,
+ unsigned long deadline) const { // NOLINT
#if CONFIG_VP8_DECODER
- return new VP8Decoder(cfg, deadline);
+ return new VP8Decoder(cfg, flags, deadline);
#else
return NULL;
#endif
@@ -154,6 +168,10 @@
VP9Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
: Decoder(cfg, deadline) {}
+ VP9Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
+ unsigned long deadline) // NOLINT
+ : Decoder(cfg, flag, deadline) {}
+
protected:
virtual vpx_codec_iface_t* CodecInterface() const {
#if CONFIG_VP9_DECODER
@@ -186,8 +204,14 @@
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
unsigned long deadline) const {
+ return CreateDecoder(cfg, 0, deadline);
+ }
+
+ virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
+ const vpx_codec_flags_t flags,
+ unsigned long deadline) const { // NOLINT
#if CONFIG_VP9_DECODER
- return new VP9Decoder(cfg, deadline);
+ return new VP9Decoder(cfg, flags, deadline);
#else
return NULL;
#endif
--- a/test/decode_test_driver.cc
+++ b/test/decode_test_driver.cc
@@ -40,8 +40,7 @@
}
void DecoderTest::RunLoop(CompressedVideoSource *video) {
- vpx_codec_dec_cfg_t dec_cfg = {0};
- Decoder* const decoder = codec_->CreateDecoder(dec_cfg, 0);
+ Decoder* const decoder = codec_->CreateDecoder(cfg_, flags_);
ASSERT_TRUE(decoder != NULL);
const char *codec_name = decoder->GetDecoderName();
const bool is_vp8 = strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0;
@@ -93,5 +92,13 @@
}
delete decoder;
+}
+
+void DecoderTest::set_cfg(const vpx_codec_dec_cfg_t &dec_cfg) {
+ memcpy(&cfg_, &dec_cfg, sizeof(cfg_));
+}
+
+void DecoderTest::set_flags(const vpx_codec_flags_t flags) {
+ flags_ = flags;
}
} // namespace libvpx_test
--- a/test/decode_test_driver.h
+++ b/test/decode_test_driver.h
@@ -41,10 +41,16 @@
class Decoder {
public:
Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
- : cfg_(cfg), deadline_(deadline), init_done_(false) {
+ : cfg_(cfg), flags_(0), deadline_(deadline), init_done_(false) {
memset(&decoder_, 0, sizeof(decoder_));
}
+ Decoder(vpx_codec_dec_cfg_t cfg, const vpx_codec_flags_t flag,
+ unsigned long deadline) // NOLINT
+ : cfg_(cfg), flags_(flag), deadline_(deadline), init_done_(false) {
+ memset(&decoder_, 0, sizeof(decoder_));
+ }
+
virtual ~Decoder() {
vpx_codec_destroy(&decoder_);
}
@@ -102,7 +108,7 @@
if (!init_done_) {
const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_,
CodecInterface(),
- &cfg_, 0);
+ &cfg_, flags_);
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
init_done_ = true;
}
@@ -110,6 +116,7 @@
vpx_codec_ctx_t decoder_;
vpx_codec_dec_cfg_t cfg_;
+ vpx_codec_flags_t flags_;
unsigned int deadline_;
bool init_done_;
};
@@ -120,6 +127,9 @@
// Main decoding loop
virtual void RunLoop(CompressedVideoSource *video);
+ virtual void set_cfg(const vpx_codec_dec_cfg_t &dec_cfg);
+ virtual void set_flags(const vpx_codec_flags_t flags);
+
// Hook to be called before decompressing every frame.
virtual void PreDecodeFrameHook(const CompressedVideoSource& video,
Decoder *decoder) {}
@@ -137,11 +147,15 @@
const unsigned int frame_number) {}
protected:
- explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {}
+ explicit DecoderTest(const CodecFactory *codec) : codec_(codec), flags_(0) {
+ memset(&cfg_, 0, sizeof(cfg_));
+ }
virtual ~DecoderTest() {}
const CodecFactory *codec_;
+ vpx_codec_dec_cfg_t cfg_;
+ vpx_codec_flags_t flags_;
};
} // namespace libvpx_test
--- a/test/test_vector_test.cc
+++ b/test/test_vector_test.cc
@@ -12,6 +12,7 @@
#include <cstdlib>
#include <string>
#include "third_party/googletest/src/include/gtest/gtest.h"
+#include "../tools_common.h"
#include "./vpx_config.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
@@ -26,10 +27,24 @@
namespace {
+enum DecodeMode {
+ kSerialMode,
+ kFrameParallMode
+};
+
+const int kDecodeMode = 0;
+const int kThreads = 1;
+const int kFileName = 2;
+
+typedef std::tr1::tuple<int, int, const char *> DecodeParam;
+
class TestVectorTest : public ::libvpx_test::DecoderTest,
- public ::libvpx_test::CodecTestWithParam<const char*> {
+ public ::libvpx_test::CodecTestWithParam<DecodeParam> {
protected:
- TestVectorTest() : DecoderTest(GET_PARAM(0)), md5_file_(NULL) {}
+ TestVectorTest()
+ : DecoderTest(GET_PARAM(0)),
+ md5_file_(NULL) {
+ }
virtual ~TestVectorTest() {
if (md5_file_)
@@ -71,9 +86,26 @@
// checksums match the correct md5 data, then the test is passed. Otherwise,
// the test failed.
TEST_P(TestVectorTest, MD5Match) {
- const std::string filename = GET_PARAM(1);
+ const DecodeParam input = GET_PARAM(1);
+ const std::string filename = std::tr1::get<kFileName>(input);
+ const int threads = std::tr1::get<kThreads>(input);
+ const int mode = std::tr1::get<kDecodeMode>(input);
libvpx_test::CompressedVideoSource *video = NULL;
+ vpx_codec_flags_t flags = 0;
+ vpx_codec_dec_cfg_t cfg = {0};
+ char str[256];
+ if (mode == kFrameParallMode) {
+ flags |= VPX_CODEC_USE_FRAME_THREADING;
+ }
+
+ cfg.threads = threads;
+
+ snprintf(str, sizeof(str) / sizeof(str[0]) - 1,
+ "file: %s mode: %s threads: %d",
+ filename.c_str(), mode == 0 ? "Serial" : "Parallel", threads);
+ SCOPED_TRACE(str);
+
// Open compressed video file.
if (filename.substr(filename.length() - 3, 3) == "ivf") {
video = new libvpx_test::IVFVideoSource(filename);
@@ -92,18 +124,53 @@
const std::string md5_filename = filename + ".md5";
OpenMD5File(md5_filename);
+ // Set decode config and flags.
+ set_cfg(cfg);
+ set_flags(flags);
+
// Decode frame, and check the md5 matching.
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
delete video;
}
-VP8_INSTANTIATE_TEST_CASE(TestVectorTest,
- ::testing::ValuesIn(libvpx_test::kVP8TestVectors,
- libvpx_test::kVP8TestVectors +
- libvpx_test::kNumVP8TestVectors));
-VP9_INSTANTIATE_TEST_CASE(TestVectorTest,
- ::testing::ValuesIn(libvpx_test::kVP9TestVectors,
- libvpx_test::kVP9TestVectors +
- libvpx_test::kNumVP9TestVectors));
+// Test VP8 decode in serial mode with single thread.
+// NOTE: VP8 only support serial mode.
+INSTANTIATE_TEST_CASE_P(
+ VP8, TestVectorTest,
+ ::testing::Combine(
+ ::testing::Values(
+ static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP8)),
+ ::testing::Combine(
+ ::testing::Values(0), // Serial Mode.
+ ::testing::Values(1), // Single thread.
+ ::testing::ValuesIn(libvpx_test::kVP8TestVectors,
+ libvpx_test::kVP8TestVectors +
+ libvpx_test::kNumVP8TestVectors))));
+// Test VP9 decode in serial mode with single thread.
+INSTANTIATE_TEST_CASE_P(
+ VP9, TestVectorTest,
+ ::testing::Combine(
+ ::testing::Values(
+ static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
+ ::testing::Combine(
+ ::testing::Values(0), // Serial Mode.
+ ::testing::Values(1), // Single thread.
+ ::testing::ValuesIn(libvpx_test::kVP9TestVectors,
+ libvpx_test::kVP9TestVectors +
+ libvpx_test::kNumVP9TestVectors))));
+
+
+// Test VP9 decode in frame parallel mode with different number of threads.
+INSTANTIATE_TEST_CASE_P(
+ VP9MultiThreadedFrameParallel, TestVectorTest,
+ ::testing::Combine(
+ ::testing::Values(
+ static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP9)),
+ ::testing::Combine(
+ ::testing::Values(1), // Frame Parallel mode.
+ ::testing::Values(2, 3, 4), // With 2, 3, 4 threads.
+ ::testing::ValuesIn(libvpx_test::kVP9TestVectors,
+ libvpx_test::kVP9TestVectors +
+ libvpx_test::kNumVP9TestVectors))));
} // namespace