vp8_decoder_unittest.cc 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <stdint.h>
  5. #include <string>
  6. #include "base/command_line.h"
  7. #include "base/files/file_util.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "media/base/test_data_util.h"
  10. #include "media/gpu/vp8_decoder.h"
  11. #include "testing/gmock/include/gmock/gmock.h"
  12. #include "testing/gtest/include/gtest/gtest.h"
  13. using ::testing::_;
  14. using ::testing::InSequence;
  15. using ::testing::Invoke;
  16. using ::testing::Mock;
  17. using ::testing::Return;
  18. namespace media {
  19. namespace {
  20. const std::string kNullFrame = "";
  21. const std::string kIFrame = "vp8-I-frame-320x240";
  22. const std::string kPFrame = "vp8-P-frame-320x240";
  23. const std::string kCorruptFrame = "vp8-corrupt-I-frame";
  24. constexpr gfx::Size kVideoSize(320, 240);
  25. constexpr size_t kRequiredNumOfPictures = 8u;
  26. class MockVP8Accelerator : public VP8Decoder::VP8Accelerator {
  27. public:
  28. MockVP8Accelerator() = default;
  29. MOCK_METHOD0(CreateVP8Picture, scoped_refptr<VP8Picture>());
  30. MOCK_METHOD2(SubmitDecode,
  31. bool(scoped_refptr<VP8Picture> pic,
  32. const Vp8ReferenceFrameVector& reference_frames));
  33. MOCK_METHOD1(OutputPicture, bool(scoped_refptr<VP8Picture> pic));
  34. };
  35. // Test VP8Decoder by feeding different VP8 frame sequences and making sure it
  36. // behaves as expected.
  37. class VP8DecoderTest : public ::testing::Test {
  38. public:
  39. VP8DecoderTest() = default;
  40. void SetUp() override;
  41. AcceleratedVideoDecoder::DecodeResult Decode(std::string input_frame_file);
  42. protected:
  43. void SkipFrame() { bitstream_id_++; }
  44. void CompleteToDecodeFirstIFrame();
  45. std::unique_ptr<VP8Decoder> decoder_;
  46. raw_ptr<MockVP8Accelerator> accelerator_ = nullptr;
  47. private:
  48. void DecodeFirstIFrame();
  49. int32_t bitstream_id_ = 0;
  50. };
  51. void VP8DecoderTest::SetUp() {
  52. auto mock_accelerator = std::make_unique<MockVP8Accelerator>();
  53. accelerator_ = mock_accelerator.get();
  54. decoder_.reset(new VP8Decoder(std::move(mock_accelerator)));
  55. // Sets default behaviors for mock methods for convenience.
  56. ON_CALL(*accelerator_, CreateVP8Picture())
  57. .WillByDefault(Return(new VP8Picture()));
  58. ON_CALL(*accelerator_, SubmitDecode(_, _)).WillByDefault(Return(true));
  59. ON_CALL(*accelerator_, OutputPicture(_)).WillByDefault(Return(true));
  60. DecodeFirstIFrame();
  61. }
  62. void VP8DecoderTest::DecodeFirstIFrame() {
  63. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kNullFrame));
  64. ASSERT_EQ(AcceleratedVideoDecoder::kConfigChange, Decode(kIFrame));
  65. EXPECT_EQ(8u, decoder_->GetBitDepth());
  66. EXPECT_EQ(kVideoSize, decoder_->GetPicSize());
  67. EXPECT_LE(kRequiredNumOfPictures, decoder_->GetRequiredNumOfPictures());
  68. }
  69. // DecodeFirstIFrame() allocates new surfaces so VP8Decoder::Decode() must be
  70. // called again to complete to decode the first frame.
  71. void VP8DecoderTest::CompleteToDecodeFirstIFrame() {
  72. {
  73. InSequence sequence;
  74. EXPECT_CALL(*accelerator_, CreateVP8Picture());
  75. EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
  76. EXPECT_CALL(*accelerator_, OutputPicture(_));
  77. }
  78. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kNullFrame));
  79. }
  80. AcceleratedVideoDecoder::DecodeResult VP8DecoderTest::Decode(
  81. std::string input_frame_file) {
  82. std::string bitstream;
  83. scoped_refptr<DecoderBuffer> buffer;
  84. if (!input_frame_file.empty()) {
  85. auto input_file = GetTestDataFilePath(input_frame_file);
  86. EXPECT_TRUE(base::ReadFileToString(input_file, &bitstream));
  87. buffer = DecoderBuffer::CopyFrom(
  88. reinterpret_cast<const uint8_t*>(bitstream.data()), bitstream.size());
  89. EXPECT_NE(buffer.get(), nullptr);
  90. decoder_->SetStream(bitstream_id_++, *buffer);
  91. }
  92. AcceleratedVideoDecoder::DecodeResult result = decoder_->Decode();
  93. if (input_frame_file.empty())
  94. return result;
  95. // Since |buffer| is destroyed in this function, Decode() must consume the
  96. // buffer by this Decode(). That happens if the return value is
  97. // kRanOutOfStreamData, kConfigChange , or kDecodeError (on failure).
  98. EXPECT_TRUE(result ==
  99. AcceleratedVideoDecoder::DecodeResult::kRanOutOfStreamData ||
  100. result == AcceleratedVideoDecoder::DecodeResult::kConfigChange ||
  101. result == AcceleratedVideoDecoder::DecodeResult::kDecodeError);
  102. if (result != AcceleratedVideoDecoder::DecodeResult::kDecodeError)
  103. EXPECT_EQ(8u, decoder_->GetBitDepth());
  104. return result;
  105. }
  106. // Test Cases
  107. TEST_F(VP8DecoderTest, DecodeSingleFrame) {
  108. CompleteToDecodeFirstIFrame();
  109. ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  110. ASSERT_TRUE(decoder_->Flush());
  111. }
  112. TEST_F(VP8DecoderTest, FailCreatePicture) {
  113. EXPECT_CALL(*accelerator_, CreateVP8Picture()).WillOnce(Return(nullptr));
  114. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfSurfaces, Decode(kNullFrame));
  115. ASSERT_TRUE(decoder_->Flush());
  116. }
  117. TEST_F(VP8DecoderTest, DecodeCorruptFrame) {
  118. CompleteToDecodeFirstIFrame();
  119. ASSERT_EQ(AcceleratedVideoDecoder::kDecodeError, Decode(kCorruptFrame));
  120. ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  121. ASSERT_TRUE(decoder_->Flush());
  122. }
  123. TEST_F(VP8DecoderTest, DecodeIAndPFrames) {
  124. CompleteToDecodeFirstIFrame();
  125. {
  126. InSequence sequence;
  127. EXPECT_CALL(*accelerator_, CreateVP8Picture());
  128. EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
  129. EXPECT_CALL(*accelerator_, OutputPicture(_));
  130. }
  131. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  132. ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  133. ASSERT_TRUE(decoder_->Flush());
  134. }
  135. TEST_F(VP8DecoderTest, DecodeIandMultiplePFrames) {
  136. CompleteToDecodeFirstIFrame();
  137. for (size_t i = 0; i < 5; i++) {
  138. {
  139. InSequence sequence;
  140. EXPECT_CALL(*accelerator_, CreateVP8Picture());
  141. EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
  142. EXPECT_CALL(*accelerator_, OutputPicture(_));
  143. }
  144. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  145. }
  146. ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  147. ASSERT_TRUE(decoder_->Flush());
  148. }
  149. TEST_F(VP8DecoderTest, DecodeMultipleIAndPFrames) {
  150. CompleteToDecodeFirstIFrame();
  151. for (size_t i = 0; i < 10; i++) {
  152. {
  153. InSequence sequence;
  154. EXPECT_CALL(*accelerator_, CreateVP8Picture());
  155. EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
  156. EXPECT_CALL(*accelerator_, OutputPicture(_));
  157. }
  158. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData,
  159. Decode((i % 3) == 0 ? kIFrame : kPFrame));
  160. }
  161. ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  162. ASSERT_TRUE(decoder_->Flush());
  163. }
  164. TEST_F(VP8DecoderTest, HaveSkippedFrames) {
  165. CompleteToDecodeFirstIFrame();
  166. SkipFrame();
  167. for (size_t i = 0; i < 5; i++) {
  168. // VP8Decoder::Decode() gives up decoding it and returns early.
  169. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  170. }
  171. ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  172. ASSERT_TRUE(decoder_->Flush());
  173. }
  174. // Verify that |decoder_| returns kDecodeError if too many kPFrames are received
  175. // while expecting a kIFrame.
  176. TEST_F(VP8DecoderTest, HaveSkippedFramesAtMaxNumOfSizeChangeFailures) {
  177. CompleteToDecodeFirstIFrame();
  178. SkipFrame();
  179. for (size_t i = 0;
  180. i < AcceleratedVideoDecoder::kVPxMaxNumOfSizeChangeFailures; i++) {
  181. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  182. }
  183. ASSERT_EQ(AcceleratedVideoDecoder::kDecodeError, Decode(kPFrame));
  184. ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  185. ASSERT_TRUE(decoder_->Flush());
  186. }
  187. // Verify that new kIFrame recovers |decoder_| to decode the frame when the
  188. // previous I frame is missing.
  189. TEST_F(VP8DecoderTest, RecoverFromSkippedFrames) {
  190. CompleteToDecodeFirstIFrame();
  191. SkipFrame();
  192. for (size_t i = 0; i < 5; i++)
  193. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  194. // The new I frame recovers to decode it correctly.
  195. {
  196. InSequence sequence;
  197. EXPECT_CALL(*accelerator_, CreateVP8Picture());
  198. EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
  199. EXPECT_CALL(*accelerator_, OutputPicture(_));
  200. }
  201. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kIFrame));
  202. for (size_t i = 0; i < 5; i++) {
  203. {
  204. InSequence sequence;
  205. EXPECT_CALL(*accelerator_, CreateVP8Picture());
  206. EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
  207. EXPECT_CALL(*accelerator_, OutputPicture(_));
  208. }
  209. ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  210. }
  211. ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  212. ASSERT_TRUE(decoder_->Flush());
  213. }
  214. } // namespace
  215. } // namespace media