Showing the changes to test/decoder_test.cpp (1 of 10 files). Show all
Unified · Split
| @@ -1,12 +1,6 @@ | |||
| 1 | #include <gtest/gtest.h> | 1 | #include <gtest/gtest.h> |
| 2 | #include <stdint.h> | ||
| 3 | #include <limits.h> | ||
| 4 | #include <fstream> | ||
| 5 | |||
| 6 | #include "codec_api.h" | ||
| 7 | |||
| 8 | #include "utils/BufferedData.h" | ||
| 9 | #include "utils/HashFunctions.h" | 2 | #include "utils/HashFunctions.h" |
| 3 | #include "BaseDecoderTest.h" | ||
| 10 | 4 | ||
| 11 | static void UpdateHashFromPlane(SHA_CTX* ctx, const uint8_t* plane, | 5 | static void UpdateHashFromPlane(SHA_CTX* ctx, const uint8_t* plane, |
| 12 | int width, int height, int stride) { | 6 | int width, int height, int stride) { |
| @@ -16,168 +10,55 @@ static void UpdateHashFromPlane(SHA_CTX* ctx, const uint8_t* plane, · 3 unmodified lines | |||
| 16 | } | 10 | } |
| 17 | } | 11 | } |
| 18 | 12 | ||
| 19 | /** | ||
| 20 | * @return frame size (>= 0), or -1 for memory allocation error. | ||
| 21 | */ | ||
| 22 | static int ReadFrame(std::ifstream* file, BufferedData* buf) { | ||
| 23 | // start code of a frame is {0, 0, 0, 1} | ||
| 24 | int zeroCount = 0; | ||
| 25 | char b; | ||
| 26 | |||
| 27 | for (;;) { | ||
| 28 | file->read(&b, 1); | ||
| 29 | if (file->gcount() != 1) { | ||
| 30 | break; | ||
| 31 | } | ||
| 32 | if (!buf->Push(b)) { | ||
| 33 | return -1; | ||
| 34 | } | ||
| 35 | |||
| 36 | if (buf->Length() <= 4) { | ||
| 37 | continue; | ||
| 38 | } | ||
| 39 | 13 | ||
| 40 | if (zeroCount < 3) { | 14 | class DecoderInitTest : public ::testing::Test, public BaseDecoderTest { |
| 41 | zeroCount = b != 0 ? 0 : zeroCount + 1; | ||
| 42 | } else { | ||
| 43 | if (b == 1) { | ||
| 44 | if (file->seekg(-4, file->cur).good()) { | ||
| 45 | return buf->Length() - 4; | ||
| 46 | } else { | ||
| 47 | // seeking fails | ||
| 48 | return -1; | ||
| 49 | } | ||
| 50 | } else if (b == 0) { | ||
| 51 | zeroCount = 3; | ||
| 52 | } else { | ||
| 53 | zeroCount = 0; | ||
| 54 | } | ||
| 55 | } | ||
| 56 | } | ||
| 57 | return buf->Length(); | ||
| 58 | } | ||
| 59 | |||
| 60 | /** | ||
| 61 | * @return true if a frame is decoded successfully, otherwise false. | ||
| 62 | */ | ||
| 63 | static bool DecodeAndProcess(ISVCDecoder* decoder, const uint8_t* src, | ||
| 64 | int sliceSize, SHA_CTX* ctx) { | ||
| 65 | void* data[3]; | ||
| 66 | SBufferInfo bufInfo; | ||
| 67 | memset(data, 0, sizeof(data)); | ||
| 68 | memset(&bufInfo, 0, sizeof(SBufferInfo)); | ||
| 69 | |||
| 70 | DECODING_STATE rv = decoder->DecodeFrame2(src, sliceSize, data, &bufInfo); | ||
| 71 | if (rv != dsErrorFree) { | ||
| 72 | return false; | ||
| 73 | } | ||
| 74 | |||
| 75 | if (bufInfo.iBufferStatus == 1) { | ||
| 76 | // y plane | ||
| 77 | UpdateHashFromPlane(ctx, static_cast<uint8_t*>(data[0]), | ||
| 78 | bufInfo.UsrData.sSystemBuffer.iWidth, | ||
| 79 | bufInfo.UsrData.sSystemBuffer.iHeight, | ||
| 80 | bufInfo.UsrData.sSystemBuffer.iStride[0]); | ||
| 81 | // u plane | ||
| 82 | UpdateHashFromPlane(ctx, static_cast<uint8_t*>(data[1]), | ||
| 83 | bufInfo.UsrData.sSystemBuffer.iWidth / 2, | ||
| 84 | bufInfo.UsrData.sSystemBuffer.iHeight / 2, | ||
| 85 | bufInfo.UsrData.sSystemBuffer.iStride[1]); | ||
| 86 | // v plane | ||
| 87 | UpdateHashFromPlane(ctx, static_cast<uint8_t*>(data[2]), | ||
| 88 | bufInfo.UsrData.sSystemBuffer.iWidth / 2, | ||
| 89 | bufInfo.UsrData.sSystemBuffer.iHeight / 2, | ||
| 90 | bufInfo.UsrData.sSystemBuffer.iStride[1]); | ||
| 91 | } | ||
| 92 | return true; | ||
| 93 | } | ||
| 94 | |||
| 95 | static void CompareFileToHash(ISVCDecoder* decoder, | ||
| 96 | const char* fileName, const char* hashStr) { | ||
| 97 | std::ifstream file(fileName, std::ios::in | std::ios::binary); | ||
| 98 | ASSERT_TRUE(file.is_open()); | ||
| 99 | |||
| 100 | unsigned char digest[SHA_DIGEST_LENGTH]; | ||
| 101 | SHA_CTX ctx; | ||
| 102 | SHA1_Init(&ctx); | ||
| 103 | |||
| 104 | BufferedData buf; | ||
| 105 | int sliceSize; | ||
| 106 | |||
| 107 | while ((sliceSize = ReadFrame(&file, &buf)) > 0) { | ||
| 108 | if (DecodeAndProcess(decoder, buf.data(), sliceSize, &ctx)) { | ||
| 109 | buf.Clear(); | ||
| 110 | } else { | ||
| 111 | SHA1_Final(digest, &ctx); | ||
| 112 | FAIL() << "unable to decode frame"; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | if (sliceSize < 0) { | ||
| 117 | SHA1_Final(digest, &ctx); | ||
| 118 | FAIL() << "unable to allocate memory"; | ||
| 119 | } | ||
| 120 | |||
| 121 | int32_t iEndOfStreamFlag = 1; | ||
| 122 | decoder->SetOption(DECODER_OPTION_END_OF_STREAM, &iEndOfStreamFlag); | ||
| 123 | |||
| 124 | // Get pending last frame | ||
| 125 | if (!DecodeAndProcess(decoder, NULL, 0, &ctx)) { | ||
| 126 | SHA1_Final(digest, &ctx); | ||
| 127 | FAIL() << "unable to decode last frame"; | ||
| 128 | } | ||
| 129 | |||
| 130 | SHA1_Final(digest, &ctx); | ||
| 131 | ASSERT_TRUE(CompareHash(digest, hashStr)); | ||
| 132 | } | ||
| 133 | |||
| 134 | class DecoderInitTest : public ::testing::Test { | ||
| 135 | public: | 15 | public: |
| 136 | DecoderInitTest() : decoder_(NULL) {} | ||
| 137 | |||
| 138 | virtual void SetUp() { | 16 | virtual void SetUp() { |
| 139 | long rv = CreateDecoder(&decoder_); | 17 | BaseDecoderTest::SetUp(); |
| 140 | ASSERT_EQ(0, rv); | ||
| 141 | ASSERT_TRUE(decoder_ != NULL); | ||
| 142 | |||
| 143 | SDecodingParam decParam; | ||
| 144 | memset(&decParam, 0, sizeof(SDecodingParam)); | ||
| 145 | decParam.iOutputColorFormat = videoFormatI420; | ||
| 146 | decParam.uiTargetDqLayer = UCHAR_MAX; | ||
| 147 | decParam.uiEcActiveFlag = 1; | ||
| 148 | decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT; | ||
| 149 | |||
| 150 | rv = decoder_->Initialize(&decParam, INIT_TYPE_PARAMETER_BASED); | ||
| 151 | ASSERT_EQ(0, rv); | ||
| 152 | } | 18 | } |
| 153 | |||
| 154 | virtual void TearDown() { | 19 | virtual void TearDown() { |
| 155 | if (decoder_ != NULL) { | 20 | BaseDecoderTest::TearDown(); |
| 156 | decoder_->Uninitialize(); | ||
| 157 | DestroyDecoder(decoder_); | ||
| 158 | } | ||
| 159 | } | 21 | } |
| 160 | |||
| 161 | protected: | ||
| 162 | ISVCDecoder* decoder_; | ||
| 163 | }; | 22 | }; |
| 164 | 23 | ||
| 165 | 24 | TEST_F(DecoderInitTest, JustInit) {} | |
| 166 | TEST_F(DecoderInitTest, JustInit) { | ||
| 167 | } | ||
| 168 | 25 | ||
| 169 | struct FileParam { | 26 | struct FileParam { |
| 170 | const char* fileName; | 27 | const char* fileName; |
| 171 | const char* hashStr; | 28 | const char* hashStr; |
| 172 | }; | 29 | }; |
| 173 | 30 | ||
| 174 | class DecoderOutputTest : public DecoderInitTest, | 31 | class DecoderOutputTest : public ::testing::WithParamInterface<FileParam>, |
| 175 | public ::testing::WithParamInterface<FileParam> { | 32 | public DecoderInitTest, public BaseDecoderTest::Callback { |
| 33 | public: | ||
| 34 | virtual void SetUp() { | ||
| 35 | DecoderInitTest::SetUp(); | ||
| 36 | if (HasFatalFailure()) { | ||
| 37 | return; | ||
| 38 | } | ||
| 39 | SHA1_Init(&ctx_); | ||
| 40 | } | ||
| 41 | virtual void onDecodeFrame(const Frame& frame) { | ||
| 42 | const Plane& y = frame.y; | ||
| 43 | const Plane& u = frame.u; | ||
| 44 | const Plane& v = frame.v; | ||
| 45 | UpdateHashFromPlane(&ctx_, y.data, y.width, y.height, y.stride); | ||
| 46 | UpdateHashFromPlane(&ctx_, u.data, u.width, u.height, u.stride); | ||
| 47 | UpdateHashFromPlane(&ctx_, v.data, v.width, v.height, v.stride); | ||
| 48 | } | ||
| 49 | protected: | ||
| 50 | SHA_CTX ctx_; | ||
| 176 | }; | 51 | }; |
| 177 | 52 | ||
| 178 | TEST_P(DecoderOutputTest, CompareOutput) { | 53 | TEST_P(DecoderOutputTest, CompareOutput) { |
| 179 | FileParam p = GetParam(); | 54 | FileParam p = GetParam(); |
| 180 | CompareFileToHash(decoder_, p.fileName, p.hashStr); | 55 | DecodeFile(p.fileName, this); |
| 56 | |||
| 57 | unsigned char digest[SHA_DIGEST_LENGTH]; | ||
| 58 | SHA1_Final(digest, &ctx_); | ||
| 59 | if (!HasFatalFailure()) { | ||
| 60 | ASSERT_TRUE(CompareHash(digest, p.hashStr)); | ||
| 61 | } | ||
| 181 | } | 62 | } |
| 182 | 63 | ||
| 183 | static const FileParam kFileParamArray[] = { | 64 | static const FileParam kFileParamArray[] = { |