tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }