Validate error checking code in decoder.

This patch adds a mechanism for insuring error checking on invalid files
by creating a unit test that runs the decoder and tests that the error
code matches what's expected on each frame in the decoder.

Disabled for now as this unit test will segfault with existing code.

Change-Id: I896f9686d9ebcbf027426933adfbea7b8c5d956e
This commit is contained in:
Jim Bankoski 2014-06-20 13:52:06 -07:00
Родитель 8a78dc4911
Коммит dc2f2ce594
5 изменённых файлов: 124 добавлений и 1 удалений

Просмотреть файл

@ -35,7 +35,8 @@ void DecoderTest::RunLoop(CompressedVideoSource *video) {
PreDecodeFrameHook(*video, decoder);
vpx_codec_err_t res_dec = decoder->DecodeFrame(video->cxdata(),
video->frame_size());
ASSERT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError();
if (!HandleDecodeResult(res_dec, *video, decoder))
break;
DxDataIterator dec_iter = decoder->GetDxData();
const vpx_image_t *img = NULL;

Просмотреть файл

@ -114,6 +114,14 @@ class DecoderTest {
virtual void PreDecodeFrameHook(const CompressedVideoSource& video,
Decoder *decoder) {}
// Hook to be called to handle decode result. Return true to continue.
virtual bool HandleDecodeResult(const vpx_codec_err_t res_dec,
const CompressedVideoSource& /* video */,
Decoder *decoder) {
EXPECT_EQ(VPX_CODEC_OK, res_dec) << decoder->DecodeError();
return VPX_CODEC_OK == res_dec;
}
// Hook to be called on every decompressed frame.
virtual void DecompressedFrameHook(const vpx_image_t& img,
const unsigned int frame_number) {}

107
test/invalid_file_test.cc Normal file
Просмотреть файл

@ -0,0 +1,107 @@
/*
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <cstdio>
#include <cstdlib>
#include <string>
#include <vector>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "./vpx_config.h"
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
#include "test/ivf_video_source.h"
#include "test/util.h"
#if CONFIG_WEBM_IO
#include "test/webm_video_source.h"
#endif
#include "vpx_mem/vpx_mem.h"
namespace {
class InvalidFileTest
: public ::libvpx_test::DecoderTest,
public ::libvpx_test::CodecTestWithParam<const char*> {
protected:
InvalidFileTest() : DecoderTest(GET_PARAM(0)), res_file_(NULL) {}
virtual ~InvalidFileTest() {
if (res_file_ != NULL)
fclose(res_file_);
}
void OpenResFile(const std::string &res_file_name_) {
res_file_ = libvpx_test::OpenTestDataFile(res_file_name_);
ASSERT_TRUE(res_file_ != NULL) << "Result file open failed. Filename: "
<< res_file_name_;
}
virtual bool HandleDecodeResult(
const vpx_codec_err_t res_dec,
const libvpx_test::CompressedVideoSource &video,
libvpx_test::Decoder *decoder) {
EXPECT_TRUE(res_file_ != NULL);
int expected_res_dec;
// Read integer result.
const int res = fscanf(res_file_, "%d", &expected_res_dec);
EXPECT_NE(res, EOF) << "Read result data failed";
// Check results match.
EXPECT_EQ(expected_res_dec, res_dec)
<< "Results don't match: frame number = " << video.frame_number();
return !HasFailure();
}
private:
FILE *res_file_;
};
TEST_P(InvalidFileTest, DISABLED_ReturnCode) {
const std::string filename = GET_PARAM(1);
libvpx_test::CompressedVideoSource *video = NULL;
// Open compressed video file.
if (filename.substr(filename.length() - 3, 3) == "ivf") {
video = new libvpx_test::IVFVideoSource(filename);
} else if (filename.substr(filename.length() - 4, 4) == "webm") {
#if CONFIG_WEBM_IO
video = new libvpx_test::WebMVideoSource(filename);
#else
fprintf(stderr, "WebM IO is disabled, skipping test vector %s\n",
filename.c_str());
return;
#endif
}
video->Init();
// Construct result file name. The file holds a list of expected integer
// results, one for each decoded frame. Any result that doesn't match
// the files list will cause a test failure.
const std::string res_filename = filename + ".res";
OpenResFile(res_filename);
// Decode frame, and check the md5 matching.
ASSERT_NO_FATAL_FAILURE(RunLoop(video));
delete video;
}
const char *const kVP9InvalidFileTests[] = {
"invalid-vp90-01.webm"
};
#define NELEMENTS(x) static_cast<int>(sizeof(x) / sizeof(x[0]))
VP9_INSTANTIATE_TEST_CASE(InvalidFileTest,
::testing::ValuesIn(kVP9InvalidFileTests,
kVP9InvalidFileTests +
NELEMENTS(kVP9InvalidFileTests)));
} // namespace

Просмотреть файл

@ -1,5 +1,7 @@
d5dfb0151c9051f8c85999255645d7a23916d3c0 hantro_collage_w352h288.yuv
b87815bf86020c592ccc7a846ba2e28ec8043902 hantro_odd.yuv
fe346136b9b8c1e6f6084cc106485706915795e4 invalid-vp90-01.webm
25751f5d3b05ff03f0719ad42cd625348eb8961e invalid-vp90-01.webm.res
b1f1c3ec79114b9a0651af24ce634afb44a9a419 rush_hour_444.y4m
5184c46ddca8b1fadd16742e8500115bc8f749da vp80-00-comprehensive-001.ivf
65bf1bbbced81b97bd030f376d1b7f61a224793f vp80-00-comprehensive-002.ivf

Просмотреть файл

@ -54,6 +54,7 @@ LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ../webmdec.h
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += webm_video_source.h
endif
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += invalid_file_test.cc
LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += test_vector_test.cc
# Currently we only support decoder perf tests for vp9. Also they read from WebM
@ -757,6 +758,10 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-segkey_adpq.webm.md5
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-fuzz-flicker.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += vp90-2-15-fuzz-flicker.webm.md5
# Invalid files for testing libvpx error checking.
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01.webm
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01.webm.res
ifeq ($(CONFIG_DECODE_PERF_TESTS),yes)
# BBB VP9 streams
LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += \