diff options
Diffstat (limited to 'dom/media/gtest/TestVPXDecoding.cpp')
-rw-r--r-- | dom/media/gtest/TestVPXDecoding.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/dom/media/gtest/TestVPXDecoding.cpp b/dom/media/gtest/TestVPXDecoding.cpp new file mode 100644 index 000000000..d14c4d24e --- /dev/null +++ b/dom/media/gtest/TestVPXDecoding.cpp @@ -0,0 +1,103 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" +#include "mozilla/ArrayUtils.h" +#include "nsTArray.h" +#include "VPXDecoder.h" + +#include <stdio.h> + +using namespace mozilla; + +static void +ReadVPXFile(const char* aPath, nsTArray<uint8_t>& aBuffer) +{ + FILE* f = fopen(aPath, "rb"); + ASSERT_NE(f, (FILE *) nullptr); + + int r = fseek(f, 0, SEEK_END); + ASSERT_EQ(r, 0); + + long size = ftell(f); + ASSERT_NE(size, -1); + aBuffer.SetLength(size); + + r = fseek(f, 0, SEEK_SET); + ASSERT_EQ(r, 0); + + size_t got = fread(aBuffer.Elements(), 1, size, f); + ASSERT_EQ(got, size_t(size)); + + r = fclose(f); + ASSERT_EQ(r, 0); +} + +static +vpx_codec_iface_t* +ParseIVFConfig(nsTArray<uint8_t>& data, vpx_codec_dec_cfg_t& config) +{ + if (data.Length() < 32 + 12) { + // Not enough data for file & first frame headers. + return nullptr; + } + if (data[0] != 'D' || data[1] != 'K' || data[2] != 'I' || data[3] != 'F') { + // Expect 'DKIP' + return nullptr; + } + if (data[4] != 0 || data[5] != 0) { + // Expect version==0. + return nullptr; + } + if (data[8] != 'V' || data[9] != 'P' + || (data[10] != '8' && data[10] != '9') + || data[11] != '0') { + // Expect 'VP80' or 'VP90'. + return nullptr; + } + config.w = uint32_t(data[12]) || (uint32_t(data[13]) << 8); + config.h = uint32_t(data[14]) || (uint32_t(data[15]) << 8); + vpx_codec_iface_t* codec = (data[10] == '8') + ? vpx_codec_vp8_dx() + : vpx_codec_vp9_dx(); + // Remove headers, to just leave raw VPx data to be decoded. + data.RemoveElementsAt(0, 32 + 12); + return codec; +} + +struct TestFileData { + const char* mFilename; + vpx_codec_err_t mDecodeResult; +}; +static const TestFileData testFiles[] = { + { "test_case_1224361.vp8.ivf", VPX_CODEC_OK }, + { "test_case_1224363.vp8.ivf", VPX_CODEC_CORRUPT_FRAME }, + { "test_case_1224369.vp8.ivf", VPX_CODEC_CORRUPT_FRAME } +}; + +TEST(libvpx, test_cases) +{ + for (size_t test = 0; test < ArrayLength(testFiles); ++test) { + nsTArray<uint8_t> data; + ReadVPXFile(testFiles[test].mFilename, data); + ASSERT_GT(data.Length(), 0u); + + vpx_codec_dec_cfg_t config; + vpx_codec_iface_t* dx = ParseIVFConfig(data, config); + ASSERT_TRUE(dx); + config.threads = 2; + + vpx_codec_ctx_t ctx; + PodZero(&ctx); + vpx_codec_err_t r = vpx_codec_dec_init(&ctx, dx, &config, 0); + ASSERT_EQ(VPX_CODEC_OK, r); + + r = vpx_codec_decode(&ctx, data.Elements(), data.Length(), nullptr, 0); + // This test case is known to be corrupt. + EXPECT_EQ(testFiles[test].mDecodeResult, r); + + r = vpx_codec_destroy(&ctx); + EXPECT_EQ(VPX_CODEC_OK, r); + } +} |