| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/base/criticalsection.h" | |
| 12 #include "webrtc/base/event.h" | |
| 13 #include "webrtc/base/thread_annotations.h" | |
| 14 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 11 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
| 15 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" | 12 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" |
| 16 #include "webrtc/test/frame_utils.h" | 13 #include "webrtc/modules/video_coding/codecs/test/video_codec_test.h" |
| 17 #include "webrtc/test/gtest.h" | |
| 18 #include "webrtc/test/testsupport/fileutils.h" | |
| 19 | 14 |
| 20 namespace webrtc { | 15 namespace webrtc { |
| 21 | 16 |
| 22 static const int kEncodeTimeoutMs = 100; | 17 class TestVp9Impl : public VideoCodecTest { |
| 23 static const int kDecodeTimeoutMs = 25; | 18 protected: |
| 24 // Set a start bitrate to get higher quality. | 19 VideoEncoder* CreateEncoder() override { return VP9Encoder::Create(); } |
| 25 static const int kStartBitrate = 300; | |
| 26 static const int kWidth = 172; // Width of the input image. | |
| 27 static const int kHeight = 144; // Height of the input image. | |
| 28 static const int kMaxFramerate = 30; // Arbitrary value. | |
| 29 | 20 |
| 30 class TestVp9Impl : public ::testing::Test { | 21 VideoDecoder* CreateDecoder() override { return VP9Decoder::Create(); } |
| 31 public: | |
| 32 TestVp9Impl() | |
| 33 : encode_complete_callback_(this), | |
| 34 decode_complete_callback_(this), | |
| 35 encoded_frame_event_(false /* manual reset */, | |
| 36 false /* initially signaled */), | |
| 37 decoded_frame_event_(false /* manual reset */, | |
| 38 false /* initially signaled */) {} | |
| 39 | 22 |
| 40 protected: | 23 VideoCodec codec_settings() override { |
| 41 class FakeEncodeCompleteCallback : public webrtc::EncodedImageCallback { | 24 VideoCodec codec_inst; |
| 42 public: | 25 codec_inst.codecType = webrtc::kVideoCodecVP9; |
| 43 explicit FakeEncodeCompleteCallback(TestVp9Impl* test) : test_(test) {} | 26 codec_inst.VP9()->numberOfTemporalLayers = 1; |
| 44 | 27 codec_inst.VP9()->numberOfSpatialLayers = 1; |
| 45 Result OnEncodedImage(const EncodedImage& frame, | 28 return codec_inst; |
| 46 const CodecSpecificInfo* codec_specific_info, | |
| 47 const RTPFragmentationHeader* fragmentation) { | |
| 48 rtc::CritScope lock(&test_->encoded_frame_section_); | |
| 49 test_->encoded_frame_ = rtc::Optional<EncodedImage>(frame); | |
| 50 test_->encoded_frame_event_.Set(); | |
| 51 return Result(Result::OK); | |
| 52 } | |
| 53 | |
| 54 private: | |
| 55 TestVp9Impl* const test_; | |
| 56 }; | |
| 57 | |
| 58 class FakeDecodeCompleteCallback : public webrtc::DecodedImageCallback { | |
| 59 public: | |
| 60 explicit FakeDecodeCompleteCallback(TestVp9Impl* test) : test_(test) {} | |
| 61 | |
| 62 int32_t Decoded(VideoFrame& frame) override { | |
| 63 RTC_NOTREACHED(); | |
| 64 return -1; | |
| 65 } | |
| 66 int32_t Decoded(VideoFrame& frame, int64_t decode_time_ms) override { | |
| 67 RTC_NOTREACHED(); | |
| 68 return -1; | |
| 69 } | |
| 70 void Decoded(VideoFrame& frame, | |
| 71 rtc::Optional<int32_t> decode_time_ms, | |
| 72 rtc::Optional<uint8_t> qp) override { | |
| 73 rtc::CritScope lock(&test_->decoded_frame_section_); | |
| 74 test_->decoded_frame_ = rtc::Optional<VideoFrame>(frame); | |
| 75 test_->decoded_qp_ = qp; | |
| 76 test_->decoded_frame_event_.Set(); | |
| 77 } | |
| 78 | |
| 79 private: | |
| 80 TestVp9Impl* const test_; | |
| 81 }; | |
| 82 | |
| 83 void SetUp() override { | |
| 84 // Using a QCIF image. Processing only one frame. | |
| 85 FILE* source_file_ = | |
| 86 fopen(test::ResourcePath("paris_qcif", "yuv").c_str(), "rb"); | |
| 87 ASSERT_TRUE(source_file_ != NULL); | |
| 88 rtc::scoped_refptr<VideoFrameBuffer> video_frame_buffer( | |
| 89 test::ReadI420Buffer(kWidth, kHeight, source_file_)); | |
| 90 input_frame_.reset(new VideoFrame(video_frame_buffer, kVideoRotation_0, 0)); | |
| 91 fclose(source_file_); | |
| 92 | |
| 93 encoder_.reset(VP9Encoder::Create()); | |
| 94 decoder_.reset(VP9Decoder::Create()); | |
| 95 encoder_->RegisterEncodeCompleteCallback(&encode_complete_callback_); | |
| 96 decoder_->RegisterDecodeCompleteCallback(&decode_complete_callback_); | |
| 97 | |
| 98 InitCodecs(); | |
| 99 } | 29 } |
| 100 | |
| 101 void InitCodecs() { | |
| 102 VideoCodec codec_inst_; | |
| 103 codec_inst_.startBitrate = kStartBitrate; | |
| 104 codec_inst_.codecType = webrtc::kVideoCodecVP9; | |
| 105 codec_inst_.maxFramerate = kMaxFramerate; | |
| 106 codec_inst_.width = kWidth; | |
| 107 codec_inst_.height = kHeight; | |
| 108 codec_inst_.VP9()->numberOfTemporalLayers = 1; | |
| 109 codec_inst_.VP9()->numberOfSpatialLayers = 1; | |
| 110 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | |
| 111 encoder_->InitEncode(&codec_inst_, 1 /* number of cores */, | |
| 112 0 /* max payload size (unused) */)); | |
| 113 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | |
| 114 decoder_->InitDecode(&codec_inst_, 1 /* number of cores */)); | |
| 115 } | |
| 116 | |
| 117 bool WaitForEncodedFrame(EncodedImage* frame) { | |
| 118 bool ret = encoded_frame_event_.Wait(kEncodeTimeoutMs); | |
| 119 EXPECT_TRUE(ret) << "Timed out while waiting for an encoded frame."; | |
| 120 // This becomes unsafe if there are multiple threads waiting for frames. | |
| 121 rtc::CritScope lock(&encoded_frame_section_); | |
| 122 EXPECT_TRUE(encoded_frame_); | |
| 123 if (encoded_frame_) { | |
| 124 *frame = std::move(*encoded_frame_); | |
| 125 encoded_frame_.reset(); | |
| 126 return true; | |
| 127 } else { | |
| 128 return false; | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 bool WaitForDecodedFrame(std::unique_ptr<VideoFrame>* frame, | |
| 133 rtc::Optional<uint8_t>* qp) { | |
| 134 bool ret = decoded_frame_event_.Wait(kDecodeTimeoutMs); | |
| 135 EXPECT_TRUE(ret) << "Timed out while waiting for a decoded frame."; | |
| 136 // This becomes unsafe if there are multiple threads waiting for frames. | |
| 137 rtc::CritScope lock(&decoded_frame_section_); | |
| 138 EXPECT_TRUE(decoded_frame_); | |
| 139 if (decoded_frame_) { | |
| 140 frame->reset(new VideoFrame(std::move(*decoded_frame_))); | |
| 141 *qp = decoded_qp_; | |
| 142 decoded_frame_.reset(); | |
| 143 return true; | |
| 144 } else { | |
| 145 return false; | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 std::unique_ptr<VideoFrame> input_frame_; | |
| 150 | |
| 151 std::unique_ptr<VideoEncoder> encoder_; | |
| 152 std::unique_ptr<VideoDecoder> decoder_; | |
| 153 | |
| 154 private: | |
| 155 FakeEncodeCompleteCallback encode_complete_callback_; | |
| 156 FakeDecodeCompleteCallback decode_complete_callback_; | |
| 157 | |
| 158 rtc::Event encoded_frame_event_; | |
| 159 rtc::CriticalSection encoded_frame_section_; | |
| 160 rtc::Optional<EncodedImage> encoded_frame_ GUARDED_BY(encoded_frame_section_); | |
| 161 | |
| 162 rtc::Event decoded_frame_event_; | |
| 163 rtc::CriticalSection decoded_frame_section_; | |
| 164 rtc::Optional<VideoFrame> decoded_frame_ GUARDED_BY(decoded_frame_section_); | |
| 165 rtc::Optional<uint8_t> decoded_qp_ GUARDED_BY(decoded_frame_section_); | |
| 166 }; | 30 }; |
| 167 | 31 |
| 168 TEST_F(TestVp9Impl, EncodeDecode) { | 32 TEST_F(TestVp9Impl, EncodeDecode) { |
| 169 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 33 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| 170 encoder_->Encode(*input_frame_, nullptr, nullptr)); | 34 encoder_->Encode(*input_frame_, nullptr, nullptr)); |
| 171 EncodedImage encoded_frame; | 35 EncodedImage encoded_frame; |
| 172 ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame)); | 36 ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame)); |
| 173 // First frame should be a key frame. | 37 // First frame should be a key frame. |
| 174 encoded_frame._frameType = kVideoFrameKey; | 38 encoded_frame._frameType = kVideoFrameKey; |
| 175 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, | 39 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 192 decoder_->Decode(encoded_frame, false, nullptr)); | 56 decoder_->Decode(encoded_frame, false, nullptr)); |
| 193 std::unique_ptr<VideoFrame> decoded_frame; | 57 std::unique_ptr<VideoFrame> decoded_frame; |
| 194 rtc::Optional<uint8_t> decoded_qp; | 58 rtc::Optional<uint8_t> decoded_qp; |
| 195 ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); | 59 ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); |
| 196 ASSERT_TRUE(decoded_frame); | 60 ASSERT_TRUE(decoded_frame); |
| 197 ASSERT_TRUE(decoded_qp); | 61 ASSERT_TRUE(decoded_qp); |
| 198 EXPECT_EQ(encoded_frame.qp_, *decoded_qp); | 62 EXPECT_EQ(encoded_frame.qp_, *decoded_qp); |
| 199 } | 63 } |
| 200 | 64 |
| 201 } // namespace webrtc | 65 } // namespace webrtc |
| OLD | NEW |