OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 | |
5 #include <stdint.h> | |
6 #include <string.h> | |
Pawel Osciak
2016/07/28 01:48:08
Is string.h needed?
emircan
2016/07/28 19:35:45
Removed.
| |
7 | |
8 #include "base/bind.h" | |
9 #include "base/memory/ptr_util.h" | |
10 #include "base/single_thread_task_runner.h" | |
11 #include "base/synchronization/waitable_event.h" | |
12 #include "base/threading/thread.h" | |
13 #include "content/renderer/media/gpu/rtc_video_encoder.h" | |
14 #include "media/renderers/mock_gpu_video_accelerator_factories.h" | |
15 #include "media/video/mock_video_encode_accelerator.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 #include "third_party/webrtc/modules/video_coding/include/video_codec_interface. h" | |
18 | |
19 using ::testing::_; | |
20 using ::testing::Invoke; | |
21 using ::testing::Return; | |
22 using ::testing::SaveArg; | |
23 using ::testing::Values; | |
24 using ::testing::WithArgs; | |
25 | |
26 namespace content { | |
27 | |
28 namespace { | |
29 | |
30 const unsigned short kInputFrameWidth = 345; | |
31 const unsigned short kInputFrameHeight = 234; | |
32 | |
33 } // anonymous namespace | |
34 | |
35 class RTCVideoEncoderTest | |
36 : public ::testing::TestWithParam<webrtc::VideoCodecType> { | |
37 public: | |
38 RTCVideoEncoderTest() | |
39 : mock_gpu_factories_( | |
40 new media::MockGpuVideoAcceleratorFactories(nullptr)), | |
41 vea_thread_("vea_thread"), | |
42 idle_waiter_(base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
43 base::WaitableEvent::InitialState::NOT_SIGNALED) {} | |
44 | |
45 void SetUp() override { | |
46 DVLOG(3) << __FUNCTION__; | |
47 ASSERT_TRUE(vea_thread_.Start()); | |
48 vea_task_runner_ = vea_thread_.task_runner(); | |
49 mock_vea_ = new media::MockVideoEncodeAccelerator(); | |
50 | |
51 EXPECT_CALL(*mock_gpu_factories_.get(), GetTaskRunner()) | |
52 .WillRepeatedly(Return(vea_task_runner_)); | |
53 EXPECT_CALL(*mock_gpu_factories_.get(), DoCreateVideoEncodeAccelerator()) | |
54 .WillRepeatedly(Return(mock_vea_)); | |
55 EXPECT_CALL(*mock_vea_, Initialize(_, _, _, _, _)) | |
56 .WillOnce(Invoke(this, &RTCVideoEncoderTest::Initialize)); | |
57 EXPECT_CALL(*mock_vea_, UseOutputBitstreamBuffer(_)).Times(3); | |
58 EXPECT_CALL(*mock_vea_, Destroy()).Times(1); | |
59 } | |
60 | |
61 void TearDown() override { | |
62 DVLOG(3) << __FUNCTION__; | |
63 EXPECT_TRUE(vea_thread_.IsRunning()); | |
64 RunUntilIdle(); | |
65 rtc_encoder_->Release(); | |
66 RunUntilIdle(); | |
67 vea_thread_.Stop(); | |
68 } | |
69 | |
70 void CreateEncoder(webrtc::VideoCodecType codec_type) { | |
71 DVLOG(3) << __FUNCTION__; | |
72 rtc_encoder_ = base::WrapUnique( | |
73 new RTCVideoEncoder(codec_type, mock_gpu_factories_.get())); | |
74 } | |
75 | |
76 webrtc::VideoCodec GetDefaultCodec() { | |
77 webrtc::VideoCodec codec; | |
tommi (sloooow) - chröme
2016/07/28 07:40:40
skip memset and just do:
webrtc::VideoCodec codec
emircan
2016/07/28 19:35:45
Done.
| |
78 memset(&codec, 0, sizeof(codec)); | |
79 codec.width = kInputFrameWidth; | |
80 codec.height = kInputFrameHeight; | |
81 codec.codecType = webrtc::kVideoCodecVP8; | |
82 codec.startBitrate = 100; | |
Pawel Osciak
2016/07/28 01:48:08
Could this be a constant defined together with the
emircan
2016/07/28 19:35:45
Done.
| |
83 return codec; | |
84 } | |
85 | |
86 bool Initialize(media::VideoPixelFormat input_format, | |
87 const gfx::Size& input_visible_size, | |
88 media::VideoCodecProfile output_profile, | |
89 uint32_t initial_bitrate, | |
90 media::VideoEncodeAccelerator::Client* client) { | |
91 client->RequireBitstreamBuffers(0, input_visible_size, 12345); | |
Pawel Osciak
2016/07/28 01:48:08
Perhaps we could use input_visible_size_.GetArea()
emircan
2016/07/28 19:35:45
Done.
| |
92 return true; | |
93 } | |
94 | |
95 void RunUntilIdle() { | |
96 DVLOG(3) << __FUNCTION__; | |
97 vea_task_runner_->PostTask(FROM_HERE, | |
98 base::Bind(&base::WaitableEvent::Signal, | |
99 base::Unretained(&idle_waiter_))); | |
100 idle_waiter_.Wait(); | |
101 } | |
102 | |
103 void VerifyEncodeFrame(const scoped_refptr<media::VideoFrame>& frame, | |
Pawel Osciak
2016/07/28 01:48:08
Perhaps s/Encode/Encoded/ ?
emircan
2016/07/28 19:35:45
Done.
| |
104 bool force_keyframe) { | |
105 EXPECT_EQ(kInputFrameWidth, frame->visible_rect().width()); | |
106 EXPECT_EQ(kInputFrameHeight, frame->visible_rect().height()); | |
107 } | |
108 | |
109 protected: | |
110 std::unique_ptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_; | |
111 media::MockVideoEncodeAccelerator* mock_vea_; | |
112 std::unique_ptr<RTCVideoEncoder> rtc_encoder_; | |
113 base::Thread vea_thread_; | |
tommi (sloooow) - chröme
2016/07/28 07:40:40
encoder_thread_?
emircan
2016/07/28 19:35:45
Done.
| |
114 | |
115 private: | |
116 scoped_refptr<base::SingleThreadTaskRunner> vea_task_runner_; | |
tommi (sloooow) - chröme
2016/07/28 07:40:40
needed? or is vea_thread_.task_runner() enough?
emircan
2016/07/28 19:35:45
Done.
| |
117 base::WaitableEvent idle_waiter_; | |
118 }; | |
119 | |
120 TEST_P(RTCVideoEncoderTest, CreateAndInitSucceeds) { | |
121 const webrtc::VideoCodecType codec_type = GetParam(); | |
122 CreateEncoder(codec_type); | |
123 webrtc::VideoCodec codec = GetDefaultCodec(); | |
124 codec.codecType = codec_type; | |
125 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_encoder_->InitEncode(&codec, 1, 12345)); | |
126 } | |
127 | |
128 TEST_F(RTCVideoEncoderTest, EncodeScaledFrame) { | |
129 const webrtc::VideoCodecType codec_type = webrtc::kVideoCodecVP8; | |
130 CreateEncoder(codec_type); | |
131 webrtc::VideoCodec codec = GetDefaultCodec(); | |
132 rtc_encoder_->InitEncode(&codec, 1, 12345); | |
Pawel Osciak
2016/07/28 01:48:08
Should we check return values from InitEncode() an
emircan
2016/07/28 19:35:45
I was checking it in the previous test, but it def
| |
133 | |
134 EXPECT_CALL(*mock_vea_, Encode(_, _)) | |
135 .Times(2) | |
136 .WillRepeatedly(Invoke(this, &RTCVideoEncoderTest::VerifyEncodeFrame)); | |
137 | |
138 const auto& buffer = | |
139 webrtc::I420Buffer::Create(kInputFrameWidth, kInputFrameHeight); | |
Pawel Osciak
2016/07/28 01:48:08
Would it be possible to prefill buffers with one c
emircan
2016/07/28 19:35:45
I prefill the buffers with black and verify it in
Pawel Osciak
2016/08/02 05:53:20
Patterns would be preferable, we could maybe have
emircan
2016/08/02 18:04:44
I changed the color to a custom one. I will refrai
| |
140 std::vector<webrtc::FrameType> frame_types; | |
141 rtc_encoder_->Encode( | |
142 webrtc::VideoFrame(buffer, 0, 0, webrtc::kVideoRotation_0), nullptr, | |
143 &frame_types); | |
144 | |
145 const auto& scaled_buffer = | |
146 webrtc::I420Buffer::Create(2 * kInputFrameWidth, 2 * kInputFrameHeight); | |
147 rtc_encoder_->Encode( | |
148 webrtc::VideoFrame(scaled_buffer, 0, 0, webrtc::kVideoRotation_0), | |
149 nullptr, &frame_types); | |
150 } | |
151 | |
152 INSTANTIATE_TEST_CASE_P(CodecProfiles, | |
153 RTCVideoEncoderTest, | |
154 Values(webrtc::kVideoCodecVP8, | |
155 webrtc::kVideoCodecH264)); | |
156 } // namespace content | |
OLD | NEW |