1 // Copyright 2013 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 <vector> 6 7 #include "base/bind.h" 8 #include "base/memory/ref_counted.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "media/base/video_frame.h" 11 #include "media/cast/cast_defines.h" 12 #include "media/cast/cast_environment.h" 13 #include "media/cast/test/fake_task_runner.h" 14 #include "media/cast/test/video_utility.h" 15 #include "media/cast/video_sender/video_encoder.h" 16 #include "testing/gmock/include/gmock/gmock.h" 17 18 namespace media { 19 namespace cast { 20 21 using testing::_; 22 23 namespace { 24 class TestVideoEncoderCallback : 25 public base::RefCountedThreadSafe<TestVideoEncoderCallback> { 26 public: 27 TestVideoEncoderCallback() {} 28 29 void SetExpectedResult(bool expected_key_frame, 30 uint8 expected_frame_id, 31 uint8 expected_last_referenced_frame_id, 32 const base::TimeTicks& expected_capture_time) { 33 expected_key_frame_ = expected_key_frame; 34 expected_frame_id_ = expected_frame_id; 35 expected_last_referenced_frame_id_ = expected_last_referenced_frame_id; 36 expected_capture_time_ = expected_capture_time; 37 } 38 39 void DeliverEncodedVideoFrame(scoped_ptr<EncodedVideoFrame> encoded_frame, 40 const base::TimeTicks& capture_time) { 41 EXPECT_EQ(expected_key_frame_, encoded_frame->key_frame); 42 EXPECT_EQ(expected_frame_id_, encoded_frame->frame_id); 43 EXPECT_EQ(expected_last_referenced_frame_id_, 44 encoded_frame->last_referenced_frame_id); 45 EXPECT_EQ(expected_capture_time_, capture_time); 46 } 47 48 protected: 49 virtual ~TestVideoEncoderCallback() {} 50 51 private: 52 friend class base::RefCountedThreadSafe<TestVideoEncoderCallback>; 53 54 bool expected_key_frame_; 55 uint8 expected_frame_id_; 56 uint8 expected_last_referenced_frame_id_; 57 base::TimeTicks expected_capture_time_; 58 }; 59 } // namespace 60 61 class VideoEncoderTest : public ::testing::Test { 62 protected: 63 VideoEncoderTest() 64 : test_video_encoder_callback_(new TestVideoEncoderCallback()) { 65 video_config_.sender_ssrc = 1; 66 video_config_.incoming_feedback_ssrc = 2; 67 video_config_.rtp_payload_type = 127; 68 video_config_.use_external_encoder = false; 69 video_config_.width = 320; 70 video_config_.height = 240; 71 video_config_.max_bitrate = 5000000; 72 video_config_.min_bitrate = 1000000; 73 video_config_.start_bitrate = 2000000; 74 video_config_.max_qp = 56; 75 video_config_.min_qp = 0; 76 video_config_.max_frame_rate = 30; 77 video_config_.max_number_of_video_buffers_used = 3; 78 video_config_.codec = kVp8; 79 gfx::Size size(video_config_.width, video_config_.height); 80 video_frame_ = media::VideoFrame::CreateFrame(VideoFrame::I420, 81 size, gfx::Rect(size), size, base::TimeDelta()); 82 PopulateVideoFrame(video_frame_, 123); 83 } 84 85 virtual ~VideoEncoderTest() {} 86 87 virtual void SetUp() { 88 task_runner_ = new test::FakeTaskRunner(&testing_clock_); 89 cast_environment_ = new CastEnvironment(&testing_clock_, task_runner_, 90 task_runner_, task_runner_, task_runner_, task_runner_, 91 GetDefaultCastLoggingConfig()); 92 } 93 94 void Configure(uint8 max_unacked_frames) { 95 video_encoder_.reset(new VideoEncoder(cast_environment_, video_config_, 96 max_unacked_frames)); 97 video_encoder_controller_ = video_encoder_.get(); 98 } 99 100 base::SimpleTestTickClock testing_clock_; 101 scoped_refptr<TestVideoEncoderCallback> test_video_encoder_callback_; 102 VideoSenderConfig video_config_; 103 scoped_refptr<test::FakeTaskRunner> task_runner_; 104 scoped_ptr<VideoEncoder> video_encoder_; 105 VideoEncoderController* video_encoder_controller_; 106 scoped_refptr<media::VideoFrame> video_frame_; 107 108 scoped_refptr<CastEnvironment> cast_environment_; 109 }; 110 111 TEST_F(VideoEncoderTest, EncodePattern30fpsRunningOutOfAck) { 112 Configure(3); 113 114 VideoEncoder::FrameEncodedCallback frame_encoded_callback = 115 base::Bind(&TestVideoEncoderCallback::DeliverEncodedVideoFrame, 116 test_video_encoder_callback_.get()); 117 118 base::TimeTicks capture_time; 119 capture_time += base::TimeDelta::FromMilliseconds(33); 120 test_video_encoder_callback_->SetExpectedResult(true, 0, 0, capture_time); 121 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 122 frame_encoded_callback)); 123 task_runner_->RunTasks(); 124 125 capture_time += base::TimeDelta::FromMilliseconds(33); 126 video_encoder_controller_->LatestFrameIdToReference(0); 127 test_video_encoder_callback_->SetExpectedResult(false, 1, 0, capture_time); 128 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 129 frame_encoded_callback)); 130 task_runner_->RunTasks(); 131 132 capture_time += base::TimeDelta::FromMilliseconds(33); 133 video_encoder_controller_->LatestFrameIdToReference(1); 134 test_video_encoder_callback_->SetExpectedResult(false, 2, 1, capture_time); 135 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 136 frame_encoded_callback)); 137 task_runner_->RunTasks(); 138 139 video_encoder_controller_->LatestFrameIdToReference(2); 140 141 for (int i = 3; i < 6; ++i) { 142 capture_time += base::TimeDelta::FromMilliseconds(33); 143 test_video_encoder_callback_->SetExpectedResult(false, i, 2, capture_time); 144 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 145 frame_encoded_callback)); 146 task_runner_->RunTasks(); 147 } 148 } 149 150 // TODO(pwestin): Re-enabled after redesign the encoder to control number of 151 // frames in flight. 152 TEST_F(VideoEncoderTest,DISABLED_EncodePattern60fpsRunningOutOfAck) { 153 video_config_.max_number_of_video_buffers_used = 1; 154 Configure(6); 155 156 base::TimeTicks capture_time; 157 VideoEncoder::FrameEncodedCallback frame_encoded_callback = 158 base::Bind(&TestVideoEncoderCallback::DeliverEncodedVideoFrame, 159 test_video_encoder_callback_.get()); 160 161 capture_time += base::TimeDelta::FromMilliseconds(33); 162 test_video_encoder_callback_->SetExpectedResult(true, 0, 0, capture_time); 163 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 164 frame_encoded_callback)); 165 task_runner_->RunTasks(); 166 167 video_encoder_controller_->LatestFrameIdToReference(0); 168 capture_time += base::TimeDelta::FromMilliseconds(33); 169 test_video_encoder_callback_->SetExpectedResult(false, 1, 0, capture_time); 170 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 171 frame_encoded_callback)); 172 task_runner_->RunTasks(); 173 174 video_encoder_controller_->LatestFrameIdToReference(1); 175 capture_time += base::TimeDelta::FromMilliseconds(33); 176 test_video_encoder_callback_->SetExpectedResult(false, 2, 0, capture_time); 177 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 178 frame_encoded_callback)); 179 task_runner_->RunTasks(); 180 181 video_encoder_controller_->LatestFrameIdToReference(2); 182 183 for (int i = 3; i < 9; ++i) { 184 capture_time += base::TimeDelta::FromMilliseconds(33); 185 test_video_encoder_callback_->SetExpectedResult(false, i, 2, capture_time); 186 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 187 frame_encoded_callback)); 188 task_runner_->RunTasks(); 189 } 190 } 191 192 // TODO(pwestin): Re-enabled after redesign the encoder to control number of 193 // frames in flight. 194 TEST_F(VideoEncoderTest, DISABLED_EncodePattern60fps200msDelayRunningOutOfAck) { 195 Configure(12); 196 197 base::TimeTicks capture_time; 198 VideoEncoder::FrameEncodedCallback frame_encoded_callback = 199 base::Bind(&TestVideoEncoderCallback::DeliverEncodedVideoFrame, 200 test_video_encoder_callback_.get()); 201 202 capture_time += base::TimeDelta::FromMilliseconds(33); 203 test_video_encoder_callback_->SetExpectedResult(true, 0, 0, capture_time); 204 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 205 frame_encoded_callback)); 206 task_runner_->RunTasks(); 207 208 video_encoder_controller_->LatestFrameIdToReference(0); 209 capture_time += base::TimeDelta::FromMilliseconds(33); 210 test_video_encoder_callback_->SetExpectedResult(false, 1, 0, capture_time); 211 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 212 frame_encoded_callback)); 213 task_runner_->RunTasks(); 214 215 video_encoder_controller_->LatestFrameIdToReference(1); 216 capture_time += base::TimeDelta::FromMilliseconds(33); 217 test_video_encoder_callback_->SetExpectedResult(false, 2, 0, capture_time); 218 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 219 frame_encoded_callback)); 220 task_runner_->RunTasks(); 221 222 video_encoder_controller_->LatestFrameIdToReference(2); 223 capture_time += base::TimeDelta::FromMilliseconds(33); 224 test_video_encoder_callback_->SetExpectedResult(false, 3, 0, capture_time); 225 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 226 frame_encoded_callback)); 227 task_runner_->RunTasks(); 228 229 video_encoder_controller_->LatestFrameIdToReference(3); 230 capture_time += base::TimeDelta::FromMilliseconds(33); 231 test_video_encoder_callback_->SetExpectedResult(false, 4, 0, capture_time); 232 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 233 frame_encoded_callback)); 234 task_runner_->RunTasks(); 235 236 video_encoder_controller_->LatestFrameIdToReference(4); 237 238 for (int i = 5; i < 17; ++i) { 239 test_video_encoder_callback_->SetExpectedResult(false, i, 4, capture_time); 240 EXPECT_TRUE(video_encoder_->EncodeVideoFrame(video_frame_, capture_time, 241 frame_encoded_callback)); 242 task_runner_->RunTasks(); 243 } 244 } 245 246 } // namespace cast 247 } // namespace media 248