summaryrefslogtreecommitdiffstats
path: root/dom/media/gtest/TestVPXDecoding.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/gtest/TestVPXDecoding.cpp')
-rw-r--r--dom/media/gtest/TestVPXDecoding.cpp103
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);
+ }
+}