TestVPXDecoding.cpp (2864B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include <stdio.h> 8 9 #include "VPXDecoder.h" 10 #include "gtest/gtest.h" 11 #include "nsTArray.h" 12 13 using namespace mozilla; 14 15 static void ReadVPXFile(const char* aPath, nsTArray<uint8_t>& aBuffer) { 16 FILE* f = fopen(aPath, "rb"); 17 ASSERT_NE(f, (FILE*)nullptr); 18 19 int r = fseek(f, 0, SEEK_END); 20 ASSERT_EQ(r, 0); 21 22 long size = ftell(f); 23 ASSERT_NE(size, -1); 24 aBuffer.SetLength(size); 25 26 r = fseek(f, 0, SEEK_SET); 27 ASSERT_EQ(r, 0); 28 29 size_t got = fread(aBuffer.Elements(), 1, size, f); 30 ASSERT_EQ(got, size_t(size)); 31 32 r = fclose(f); 33 ASSERT_EQ(r, 0); 34 } 35 36 static vpx_codec_iface_t* ParseIVFConfig(nsTArray<uint8_t>& data, 37 vpx_codec_dec_cfg_t& config) { 38 if (data.Length() < 32 + 12) { 39 // Not enough data for file & first frame headers. 40 return nullptr; 41 } 42 if (data[0] != 'D' || data[1] != 'K' || data[2] != 'I' || data[3] != 'F') { 43 // Expect 'DKIP' 44 return nullptr; 45 } 46 if (data[4] != 0 || data[5] != 0) { 47 // Expect version==0. 48 return nullptr; 49 } 50 if (data[8] != 'V' || data[9] != 'P' || 51 (data[10] != '8' && data[10] != '9') || data[11] != '0') { 52 // Expect 'VP80' or 'VP90'. 53 return nullptr; 54 } 55 config.w = uint32_t(data[12]) || (uint32_t(data[13]) << 8); 56 config.h = uint32_t(data[14]) || (uint32_t(data[15]) << 8); 57 vpx_codec_iface_t* codec = 58 (data[10] == '8') ? vpx_codec_vp8_dx() : vpx_codec_vp9_dx(); 59 // Remove headers, to just leave raw VPx data to be decoded. 60 data.RemoveElementsAt(0, 32 + 12); 61 return codec; 62 } 63 64 struct TestFileData { 65 const char* mFilename; 66 vpx_codec_err_t mDecodeResult; 67 }; 68 static const TestFileData testFiles[] = { 69 {"test_case_1224361.vp8.ivf", VPX_CODEC_OK}, 70 {"test_case_1224363.vp8.ivf", VPX_CODEC_CORRUPT_FRAME}, 71 {"test_case_1224369.vp8.ivf", VPX_CODEC_CORRUPT_FRAME}}; 72 73 TEST(libvpx, test_cases) 74 { 75 for (size_t test = 0; test < std::size(testFiles); ++test) { 76 nsTArray<uint8_t> data; 77 ReadVPXFile(testFiles[test].mFilename, data); 78 ASSERT_GT(data.Length(), 0u); 79 80 vpx_codec_dec_cfg_t config; 81 vpx_codec_iface_t* dx = ParseIVFConfig(data, config); 82 ASSERT_TRUE(dx); 83 config.threads = 2; 84 85 vpx_codec_ctx_t ctx; 86 PodZero(&ctx); 87 vpx_codec_err_t r = vpx_codec_dec_init(&ctx, dx, &config, 0); 88 ASSERT_EQ(VPX_CODEC_OK, r); 89 90 r = vpx_codec_decode(&ctx, data.Elements(), data.Length(), nullptr, 0); 91 // This test case is known to be corrupt. 92 EXPECT_EQ(testFiles[test].mDecodeResult, r); 93 94 r = vpx_codec_destroy(&ctx); 95 EXPECT_EQ(VPX_CODEC_OK, r); 96 } 97 }