Coverage Report

Created: 2018-09-25 14:53

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