1// Copyright 2014 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/sender/video_encoder_impl.h" 14#include "media/cast/test/fake_single_thread_task_runner.h" 15#include "media/cast/test/utility/default_config.h" 16#include "media/cast/test/utility/video_utility.h" 17#include "testing/gmock/include/gmock/gmock.h" 18 19namespace media { 20namespace cast { 21 22using testing::_; 23 24namespace { 25class TestVideoEncoderCallback 26 : public base::RefCountedThreadSafe<TestVideoEncoderCallback> { 27 public: 28 explicit TestVideoEncoderCallback(bool multiple_buffer_mode) 29 : multiple_buffer_mode_(multiple_buffer_mode), 30 count_frames_delivered_(0) {} 31 32 int count_frames_delivered() const { 33 return count_frames_delivered_; 34 } 35 36 void SetExpectedResult(uint32 expected_frame_id, 37 uint32 expected_last_referenced_frame_id, 38 const base::TimeTicks& expected_capture_time) { 39 expected_frame_id_ = expected_frame_id; 40 expected_last_referenced_frame_id_ = expected_last_referenced_frame_id; 41 expected_capture_time_ = expected_capture_time; 42 } 43 44 void DeliverEncodedVideoFrame( 45 scoped_ptr<EncodedFrame> encoded_frame) { 46 if (expected_frame_id_ != expected_last_referenced_frame_id_) { 47 EXPECT_EQ(EncodedFrame::DEPENDENT, encoded_frame->dependency); 48 } else if (!multiple_buffer_mode_) { 49 EXPECT_EQ(EncodedFrame::KEY, encoded_frame->dependency); 50 } 51 EXPECT_EQ(expected_frame_id_, encoded_frame->frame_id); 52 EXPECT_EQ(expected_last_referenced_frame_id_, 53 encoded_frame->referenced_frame_id) 54 << "frame id: " << expected_frame_id_; 55 EXPECT_LT(0u, encoded_frame->rtp_timestamp); 56 EXPECT_EQ(expected_capture_time_, encoded_frame->reference_time); 57 EXPECT_FALSE(encoded_frame->data.empty()); 58 ++count_frames_delivered_; 59 } 60 61 private: 62 friend class base::RefCountedThreadSafe<TestVideoEncoderCallback>; 63 virtual ~TestVideoEncoderCallback() {} 64 65 const bool multiple_buffer_mode_; 66 int count_frames_delivered_; 67 68 uint32 expected_frame_id_; 69 uint32 expected_last_referenced_frame_id_; 70 base::TimeTicks expected_capture_time_; 71 72 DISALLOW_COPY_AND_ASSIGN(TestVideoEncoderCallback); 73}; 74} // namespace 75 76class VideoEncoderImplTest : public ::testing::Test { 77 protected: 78 VideoEncoderImplTest() { 79 video_config_ = GetDefaultVideoSenderConfig(); 80 video_config_.codec = CODEC_VIDEO_VP8; 81 gfx::Size size(video_config_.width, video_config_.height); 82 video_frame_ = media::VideoFrame::CreateFrame( 83 VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); 84 PopulateVideoFrame(video_frame_.get(), 123); 85 } 86 87 virtual ~VideoEncoderImplTest() {} 88 89 virtual void SetUp() OVERRIDE { 90 testing_clock_ = new base::SimpleTestTickClock(); 91 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); 92 task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_); 93 cast_environment_ = 94 new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(), 95 task_runner_, 96 task_runner_, 97 task_runner_); 98 } 99 100 virtual void TearDown() OVERRIDE { 101 video_encoder_.reset(); 102 task_runner_->RunTasks(); 103 } 104 105 void CreateEncoder() { 106 test_video_encoder_callback_ = new TestVideoEncoderCallback( 107 video_config_.max_number_of_video_buffers_used != 1); 108 video_encoder_.reset(new VideoEncoderImpl( 109 cast_environment_, video_config_, 110 0 /* useless arg to be removed in later change */)); 111 } 112 113 base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. 114 scoped_refptr<TestVideoEncoderCallback> test_video_encoder_callback_; 115 VideoSenderConfig video_config_; 116 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; 117 scoped_ptr<VideoEncoder> video_encoder_; 118 scoped_refptr<media::VideoFrame> video_frame_; 119 120 scoped_refptr<CastEnvironment> cast_environment_; 121 122 DISALLOW_COPY_AND_ASSIGN(VideoEncoderImplTest); 123}; 124 125TEST_F(VideoEncoderImplTest, GeneratesKeyFrameThenOnlyDeltaFrames) { 126 CreateEncoder(); 127 128 VideoEncoder::FrameEncodedCallback frame_encoded_callback = 129 base::Bind(&TestVideoEncoderCallback::DeliverEncodedVideoFrame, 130 test_video_encoder_callback_.get()); 131 132 EXPECT_EQ(0, test_video_encoder_callback_->count_frames_delivered()); 133 134 test_video_encoder_callback_->SetExpectedResult( 135 0, 0, testing_clock_->NowTicks()); 136 EXPECT_TRUE(video_encoder_->EncodeVideoFrame( 137 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback)); 138 task_runner_->RunTasks(); 139 140 for (uint32 frame_id = 1; frame_id < 10; ++frame_id) { 141 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(33)); 142 test_video_encoder_callback_->SetExpectedResult( 143 frame_id, frame_id - 1, testing_clock_->NowTicks()); 144 EXPECT_TRUE(video_encoder_->EncodeVideoFrame( 145 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback)); 146 task_runner_->RunTasks(); 147 } 148 149 EXPECT_EQ(10, test_video_encoder_callback_->count_frames_delivered()); 150} 151 152TEST_F(VideoEncoderImplTest, 153 FramesDoNotDependOnUnackedFramesInMultiBufferMode) { 154 video_config_.max_number_of_video_buffers_used = 3; 155 CreateEncoder(); 156 157 VideoEncoder::FrameEncodedCallback frame_encoded_callback = 158 base::Bind(&TestVideoEncoderCallback::DeliverEncodedVideoFrame, 159 test_video_encoder_callback_.get()); 160 161 EXPECT_EQ(0, test_video_encoder_callback_->count_frames_delivered()); 162 163 test_video_encoder_callback_->SetExpectedResult( 164 0, 0, testing_clock_->NowTicks()); 165 EXPECT_TRUE(video_encoder_->EncodeVideoFrame( 166 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback)); 167 task_runner_->RunTasks(); 168 169 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(33)); 170 video_encoder_->LatestFrameIdToReference(0); 171 test_video_encoder_callback_->SetExpectedResult( 172 1, 0, testing_clock_->NowTicks()); 173 EXPECT_TRUE(video_encoder_->EncodeVideoFrame( 174 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback)); 175 task_runner_->RunTasks(); 176 177 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(33)); 178 video_encoder_->LatestFrameIdToReference(1); 179 test_video_encoder_callback_->SetExpectedResult( 180 2, 1, testing_clock_->NowTicks()); 181 EXPECT_TRUE(video_encoder_->EncodeVideoFrame( 182 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback)); 183 task_runner_->RunTasks(); 184 185 video_encoder_->LatestFrameIdToReference(2); 186 187 for (uint32 frame_id = 3; frame_id < 10; ++frame_id) { 188 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(33)); 189 test_video_encoder_callback_->SetExpectedResult( 190 frame_id, 2, testing_clock_->NowTicks()); 191 EXPECT_TRUE(video_encoder_->EncodeVideoFrame( 192 video_frame_, testing_clock_->NowTicks(), frame_encoded_callback)); 193 task_runner_->RunTasks(); 194 } 195 196 EXPECT_EQ(10, test_video_encoder_callback_->count_frames_delivered()); 197} 198 199} // namespace cast 200} // namespace media 201