Merge "Add VP9 frame-parallel unit test." into frame_parallel
This commit is contained in:
commit
02410659cd
@ -35,6 +35,10 @@ class CodecFactory {
|
|||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
unsigned long deadline) const = 0;
|
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,
|
virtual Encoder* CreateEncoder(vpx_codec_enc_cfg_t cfg,
|
||||||
unsigned long deadline,
|
unsigned long deadline,
|
||||||
const unsigned long init_flags,
|
const unsigned long init_flags,
|
||||||
@ -72,6 +76,10 @@ class VP8Decoder : public Decoder {
|
|||||||
VP8Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
VP8Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
||||||
: Decoder(cfg, 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:
|
protected:
|
||||||
virtual vpx_codec_iface_t* CodecInterface() const {
|
virtual vpx_codec_iface_t* CodecInterface() const {
|
||||||
#if CONFIG_VP8_DECODER
|
#if CONFIG_VP8_DECODER
|
||||||
@ -104,8 +112,14 @@ class VP8CodecFactory : public CodecFactory {
|
|||||||
|
|
||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
unsigned long deadline) const {
|
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
|
#if CONFIG_VP8_DECODER
|
||||||
return new VP8Decoder(cfg, deadline);
|
return new VP8Decoder(cfg, flags, deadline);
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -154,6 +168,10 @@ class VP9Decoder : public Decoder {
|
|||||||
VP9Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
VP9Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
||||||
: Decoder(cfg, 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:
|
protected:
|
||||||
virtual vpx_codec_iface_t* CodecInterface() const {
|
virtual vpx_codec_iface_t* CodecInterface() const {
|
||||||
#if CONFIG_VP9_DECODER
|
#if CONFIG_VP9_DECODER
|
||||||
@ -186,8 +204,14 @@ class VP9CodecFactory : public CodecFactory {
|
|||||||
|
|
||||||
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
virtual Decoder* CreateDecoder(vpx_codec_dec_cfg_t cfg,
|
||||||
unsigned long deadline) const {
|
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
|
#if CONFIG_VP9_DECODER
|
||||||
return new VP9Decoder(cfg, deadline);
|
return new VP9Decoder(cfg, flags, deadline);
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,8 +40,7 @@ vpx_codec_err_t Decoder::DecodeFrame(const uint8_t *cxdata, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DecoderTest::RunLoop(CompressedVideoSource *video) {
|
void DecoderTest::RunLoop(CompressedVideoSource *video) {
|
||||||
vpx_codec_dec_cfg_t dec_cfg = {0};
|
Decoder* const decoder = codec_->CreateDecoder(cfg_, flags_);
|
||||||
Decoder* const decoder = codec_->CreateDecoder(dec_cfg, 0);
|
|
||||||
ASSERT_TRUE(decoder != NULL);
|
ASSERT_TRUE(decoder != NULL);
|
||||||
const char *codec_name = decoder->GetDecoderName();
|
const char *codec_name = decoder->GetDecoderName();
|
||||||
const bool is_vp8 = strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0;
|
const bool is_vp8 = strncmp(kVP8Name, codec_name, sizeof(kVP8Name) - 1) == 0;
|
||||||
@ -94,4 +93,12 @@ void DecoderTest::RunLoop(CompressedVideoSource *video) {
|
|||||||
|
|
||||||
delete decoder;
|
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
|
} // namespace libvpx_test
|
||||||
|
@ -41,7 +41,13 @@ class DxDataIterator {
|
|||||||
class Decoder {
|
class Decoder {
|
||||||
public:
|
public:
|
||||||
Decoder(vpx_codec_dec_cfg_t cfg, unsigned long deadline)
|
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_));
|
memset(&decoder_, 0, sizeof(decoder_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +108,7 @@ class Decoder {
|
|||||||
if (!init_done_) {
|
if (!init_done_) {
|
||||||
const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_,
|
const vpx_codec_err_t res = vpx_codec_dec_init(&decoder_,
|
||||||
CodecInterface(),
|
CodecInterface(),
|
||||||
&cfg_, 0);
|
&cfg_, flags_);
|
||||||
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
|
ASSERT_EQ(VPX_CODEC_OK, res) << DecodeError();
|
||||||
init_done_ = true;
|
init_done_ = true;
|
||||||
}
|
}
|
||||||
@ -110,6 +116,7 @@ class Decoder {
|
|||||||
|
|
||||||
vpx_codec_ctx_t decoder_;
|
vpx_codec_ctx_t decoder_;
|
||||||
vpx_codec_dec_cfg_t cfg_;
|
vpx_codec_dec_cfg_t cfg_;
|
||||||
|
vpx_codec_flags_t flags_;
|
||||||
unsigned int deadline_;
|
unsigned int deadline_;
|
||||||
bool init_done_;
|
bool init_done_;
|
||||||
};
|
};
|
||||||
@ -120,6 +127,9 @@ class DecoderTest {
|
|||||||
// Main decoding loop
|
// Main decoding loop
|
||||||
virtual void RunLoop(CompressedVideoSource *video);
|
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.
|
// Hook to be called before decompressing every frame.
|
||||||
virtual void PreDecodeFrameHook(const CompressedVideoSource& video,
|
virtual void PreDecodeFrameHook(const CompressedVideoSource& video,
|
||||||
Decoder *decoder) {}
|
Decoder *decoder) {}
|
||||||
@ -137,11 +147,15 @@ class DecoderTest {
|
|||||||
const unsigned int frame_number) {}
|
const unsigned int frame_number) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit DecoderTest(const CodecFactory *codec) : codec_(codec) {}
|
explicit DecoderTest(const CodecFactory *codec) : codec_(codec), flags_(0) {
|
||||||
|
memset(&cfg_, 0, sizeof(cfg_));
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~DecoderTest() {}
|
virtual ~DecoderTest() {}
|
||||||
|
|
||||||
const CodecFactory *codec_;
|
const CodecFactory *codec_;
|
||||||
|
vpx_codec_dec_cfg_t cfg_;
|
||||||
|
vpx_codec_flags_t flags_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace libvpx_test
|
} // namespace libvpx_test
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "third_party/googletest/src/include/gtest/gtest.h"
|
#include "third_party/googletest/src/include/gtest/gtest.h"
|
||||||
|
#include "../tools_common.h"
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
#include "test/codec_factory.h"
|
#include "test/codec_factory.h"
|
||||||
#include "test/decode_test_driver.h"
|
#include "test/decode_test_driver.h"
|
||||||
@ -26,10 +27,24 @@
|
|||||||
|
|
||||||
namespace {
|
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,
|
class TestVectorTest : public ::libvpx_test::DecoderTest,
|
||||||
public ::libvpx_test::CodecTestWithParam<const char*> {
|
public ::libvpx_test::CodecTestWithParam<DecodeParam> {
|
||||||
protected:
|
protected:
|
||||||
TestVectorTest() : DecoderTest(GET_PARAM(0)), md5_file_(NULL) {}
|
TestVectorTest()
|
||||||
|
: DecoderTest(GET_PARAM(0)),
|
||||||
|
md5_file_(NULL) {
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~TestVectorTest() {
|
virtual ~TestVectorTest() {
|
||||||
if (md5_file_)
|
if (md5_file_)
|
||||||
@ -71,8 +86,25 @@ class TestVectorTest : public ::libvpx_test::DecoderTest,
|
|||||||
// checksums match the correct md5 data, then the test is passed. Otherwise,
|
// checksums match the correct md5 data, then the test is passed. Otherwise,
|
||||||
// the test failed.
|
// the test failed.
|
||||||
TEST_P(TestVectorTest, MD5Match) {
|
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;
|
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.
|
// Open compressed video file.
|
||||||
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
if (filename.substr(filename.length() - 3, 3) == "ivf") {
|
||||||
@ -92,18 +124,53 @@ TEST_P(TestVectorTest, MD5Match) {
|
|||||||
const std::string md5_filename = filename + ".md5";
|
const std::string md5_filename = filename + ".md5";
|
||||||
OpenMD5File(md5_filename);
|
OpenMD5File(md5_filename);
|
||||||
|
|
||||||
|
// Set decode config and flags.
|
||||||
|
set_cfg(cfg);
|
||||||
|
set_flags(flags);
|
||||||
|
|
||||||
// Decode frame, and check the md5 matching.
|
// Decode frame, and check the md5 matching.
|
||||||
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
|
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
|
||||||
delete video;
|
delete video;
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8_INSTANTIATE_TEST_CASE(TestVectorTest,
|
// Test VP8 decode in serial mode with single thread.
|
||||||
::testing::ValuesIn(libvpx_test::kVP8TestVectors,
|
// NOTE: VP8 only support serial mode.
|
||||||
libvpx_test::kVP8TestVectors +
|
INSTANTIATE_TEST_CASE_P(
|
||||||
libvpx_test::kNumVP8TestVectors));
|
VP8, TestVectorTest,
|
||||||
VP9_INSTANTIATE_TEST_CASE(TestVectorTest,
|
::testing::Combine(
|
||||||
::testing::ValuesIn(libvpx_test::kVP9TestVectors,
|
::testing::Values(
|
||||||
libvpx_test::kVP9TestVectors +
|
static_cast<const libvpx_test::CodecFactory *>(&libvpx_test::kVP8)),
|
||||||
libvpx_test::kNumVP9TestVectors));
|
::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
|
} // namespace
|
||||||
|
Loading…
Reference in New Issue
Block a user