Index: media/cast/video_sender/video_sender_unittest.cc |
diff --git a/media/cast/video_sender/video_sender_unittest.cc b/media/cast/video_sender/video_sender_unittest.cc |
deleted file mode 100644 |
index 8c4d366331bb4604f623aa4f797f5e838e99f7f5..0000000000000000000000000000000000000000 |
--- a/media/cast/video_sender/video_sender_unittest.cc |
+++ /dev/null |
@@ -1,525 +0,0 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include <stdint.h> |
- |
-#include <vector> |
- |
-#include "base/bind.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/test/simple_test_tick_clock.h" |
-#include "media/base/video_frame.h" |
-#include "media/cast/cast_environment.h" |
-#include "media/cast/logging/simple_event_subscriber.h" |
-#include "media/cast/test/fake_single_thread_task_runner.h" |
-#include "media/cast/test/fake_video_encode_accelerator.h" |
-#include "media/cast/test/utility/default_config.h" |
-#include "media/cast/test/utility/video_utility.h" |
-#include "media/cast/transport/cast_transport_config.h" |
-#include "media/cast/transport/cast_transport_sender_impl.h" |
-#include "media/cast/transport/pacing/paced_sender.h" |
-#include "media/cast/video_sender/video_sender.h" |
-#include "testing/gmock/include/gmock/gmock.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-namespace media { |
-namespace cast { |
- |
-namespace { |
-static const uint8 kPixelValue = 123; |
-static const int kWidth = 320; |
-static const int kHeight = 240; |
- |
-using testing::_; |
-using testing::AtLeast; |
- |
-void CreateVideoEncodeAccelerator( |
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
- scoped_ptr<VideoEncodeAccelerator> fake_vea, |
- const ReceiveVideoEncodeAcceleratorCallback& callback) { |
- callback.Run(task_runner, fake_vea.Pass()); |
-} |
- |
-void CreateSharedMemory( |
- size_t size, const ReceiveVideoEncodeMemoryCallback& callback) { |
- scoped_ptr<base::SharedMemory> shm(new base::SharedMemory()); |
- if (!shm->CreateAndMapAnonymous(size)) { |
- NOTREACHED(); |
- return; |
- } |
- callback.Run(shm.Pass()); |
-} |
- |
-class TestPacketSender : public transport::PacketSender { |
- public: |
- TestPacketSender() |
- : number_of_rtp_packets_(0), |
- number_of_rtcp_packets_(0), |
- paused_(false) {} |
- |
- // A singular packet implies a RTCP packet. |
- virtual bool SendPacket(transport::PacketRef packet, |
- const base::Closure& cb) OVERRIDE { |
- if (paused_) { |
- stored_packet_ = packet; |
- callback_ = cb; |
- return false; |
- } |
- if (Rtcp::IsRtcpPacket(&packet->data[0], packet->data.size())) { |
- ++number_of_rtcp_packets_; |
- } else { |
- // Check that at least one RTCP packet was sent before the first RTP |
- // packet. This confirms that the receiver will have the necessary lip |
- // sync info before it has to calculate the playout time of the first |
- // frame. |
- if (number_of_rtp_packets_ == 0) |
- EXPECT_LE(1, number_of_rtcp_packets_); |
- ++number_of_rtp_packets_; |
- } |
- return true; |
- } |
- |
- int number_of_rtp_packets() const { return number_of_rtp_packets_; } |
- |
- int number_of_rtcp_packets() const { return number_of_rtcp_packets_; } |
- |
- void SetPause(bool paused) { |
- paused_ = paused; |
- if (!paused && stored_packet_) { |
- SendPacket(stored_packet_, callback_); |
- callback_.Run(); |
- } |
- } |
- |
- private: |
- int number_of_rtp_packets_; |
- int number_of_rtcp_packets_; |
- bool paused_; |
- base::Closure callback_; |
- transport::PacketRef stored_packet_; |
- |
- DISALLOW_COPY_AND_ASSIGN(TestPacketSender); |
-}; |
- |
-class PeerVideoSender : public VideoSender { |
- public: |
- PeerVideoSender( |
- scoped_refptr<CastEnvironment> cast_environment, |
- const VideoSenderConfig& video_config, |
- const CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
- const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb, |
- transport::CastTransportSender* const transport_sender) |
- : VideoSender(cast_environment, |
- video_config, |
- create_vea_cb, |
- create_video_encode_mem_cb, |
- transport_sender) {} |
- using VideoSender::OnReceivedCastFeedback; |
-}; |
-} // namespace |
- |
-class VideoSenderTest : public ::testing::Test { |
- protected: |
- VideoSenderTest() { |
- testing_clock_ = new base::SimpleTestTickClock(); |
- testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); |
- task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_); |
- cast_environment_ = |
- new CastEnvironment(scoped_ptr<base::TickClock>(testing_clock_).Pass(), |
- task_runner_, |
- task_runner_, |
- task_runner_); |
- last_pixel_value_ = kPixelValue; |
- net::IPEndPoint dummy_endpoint; |
- transport_sender_.reset(new transport::CastTransportSenderImpl( |
- NULL, |
- testing_clock_, |
- dummy_endpoint, |
- base::Bind(&UpdateCastTransportStatus), |
- transport::BulkRawEventsCallback(), |
- base::TimeDelta(), |
- task_runner_, |
- &transport_)); |
- } |
- |
- virtual ~VideoSenderTest() {} |
- |
- virtual void TearDown() OVERRIDE { |
- video_sender_.reset(); |
- task_runner_->RunTasks(); |
- } |
- |
- static void UpdateCastTransportStatus(transport::CastTransportStatus status) { |
- EXPECT_EQ(transport::TRANSPORT_VIDEO_INITIALIZED, status); |
- } |
- |
- void InitEncoder(bool external) { |
- VideoSenderConfig video_config; |
- video_config.ssrc = 1; |
- video_config.incoming_feedback_ssrc = 2; |
- video_config.rtcp_c_name = "video_test@10.1.1.1"; |
- video_config.rtp_payload_type = 127; |
- video_config.use_external_encoder = external; |
- video_config.width = kWidth; |
- video_config.height = kHeight; |
- video_config.max_bitrate = 5000000; |
- video_config.min_bitrate = 1000000; |
- video_config.start_bitrate = 1000000; |
- video_config.max_qp = 56; |
- video_config.min_qp = 0; |
- video_config.max_frame_rate = 30; |
- video_config.max_number_of_video_buffers_used = 1; |
- video_config.codec = transport::CODEC_VIDEO_VP8; |
- |
- if (external) { |
- scoped_ptr<VideoEncodeAccelerator> fake_vea( |
- new test::FakeVideoEncodeAccelerator(task_runner_)); |
- video_sender_.reset( |
- new PeerVideoSender(cast_environment_, |
- video_config, |
- base::Bind(&CreateVideoEncodeAccelerator, |
- task_runner_, |
- base::Passed(&fake_vea)), |
- base::Bind(&CreateSharedMemory), |
- transport_sender_.get())); |
- } else { |
- video_sender_.reset( |
- new PeerVideoSender(cast_environment_, |
- video_config, |
- CreateDefaultVideoEncodeAcceleratorCallback(), |
- CreateDefaultVideoEncodeMemoryCallback(), |
- transport_sender_.get())); |
- } |
- ASSERT_EQ(STATUS_VIDEO_INITIALIZED, video_sender_->InitializationResult()); |
- } |
- |
- scoped_refptr<media::VideoFrame> GetNewVideoFrame() { |
- gfx::Size size(kWidth, kHeight); |
- scoped_refptr<media::VideoFrame> video_frame = |
- media::VideoFrame::CreateFrame( |
- VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); |
- PopulateVideoFrame(video_frame, last_pixel_value_++); |
- return video_frame; |
- } |
- |
- scoped_refptr<media::VideoFrame> GetLargeNewVideoFrame() { |
- gfx::Size size(kWidth, kHeight); |
- scoped_refptr<media::VideoFrame> video_frame = |
- media::VideoFrame::CreateFrame( |
- VideoFrame::I420, size, gfx::Rect(size), size, base::TimeDelta()); |
- PopulateVideoFrameWithNoise(video_frame); |
- return video_frame; |
- } |
- |
- void RunTasks(int during_ms) { |
- task_runner_->Sleep(base::TimeDelta::FromMilliseconds(during_ms)); |
- } |
- |
- base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. |
- TestPacketSender transport_; |
- scoped_ptr<transport::CastTransportSenderImpl> transport_sender_; |
- scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; |
- scoped_ptr<PeerVideoSender> video_sender_; |
- scoped_refptr<CastEnvironment> cast_environment_; |
- int last_pixel_value_; |
- |
- DISALLOW_COPY_AND_ASSIGN(VideoSenderTest); |
-}; |
- |
-TEST_F(VideoSenderTest, BuiltInEncoder) { |
- InitEncoder(false); |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- |
- const base::TimeTicks capture_time = testing_clock_->NowTicks(); |
- video_sender_->InsertRawVideoFrame(video_frame, capture_time); |
- |
- task_runner_->RunTasks(); |
- EXPECT_LE(1, transport_.number_of_rtp_packets()); |
- EXPECT_LE(1, transport_.number_of_rtcp_packets()); |
-} |
- |
-TEST_F(VideoSenderTest, ExternalEncoder) { |
- InitEncoder(true); |
- task_runner_->RunTasks(); |
- |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- |
- const base::TimeTicks capture_time = testing_clock_->NowTicks(); |
- video_sender_->InsertRawVideoFrame(video_frame, capture_time); |
- |
- task_runner_->RunTasks(); |
- |
- // We need to run the task to cleanup the GPU instance. |
- video_sender_.reset(NULL); |
- task_runner_->RunTasks(); |
-} |
- |
-TEST_F(VideoSenderTest, RtcpTimer) { |
- InitEncoder(false); |
- |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- |
- const base::TimeTicks capture_time = testing_clock_->NowTicks(); |
- video_sender_->InsertRawVideoFrame(video_frame, capture_time); |
- |
- // Make sure that we send at least one RTCP packet. |
- base::TimeDelta max_rtcp_timeout = |
- base::TimeDelta::FromMilliseconds(1 + kDefaultRtcpIntervalMs * 3 / 2); |
- |
- RunTasks(max_rtcp_timeout.InMilliseconds()); |
- EXPECT_LE(1, transport_.number_of_rtp_packets()); |
- EXPECT_LE(1, transport_.number_of_rtcp_packets()); |
- // Build Cast msg and expect RTCP packet. |
- RtcpCastMessage cast_feedback(1); |
- cast_feedback.media_ssrc_ = 2; |
- cast_feedback.ack_frame_id_ = 0; |
- video_sender_->OnReceivedCastFeedback(cast_feedback); |
- RunTasks(max_rtcp_timeout.InMilliseconds()); |
- EXPECT_LE(1, transport_.number_of_rtcp_packets()); |
-} |
- |
-TEST_F(VideoSenderTest, ResendTimer) { |
- InitEncoder(false); |
- |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- |
- const base::TimeTicks capture_time = testing_clock_->NowTicks(); |
- video_sender_->InsertRawVideoFrame(video_frame, capture_time); |
- |
- // ACK the key frame. |
- RtcpCastMessage cast_feedback(1); |
- cast_feedback.media_ssrc_ = 2; |
- cast_feedback.ack_frame_id_ = 0; |
- video_sender_->OnReceivedCastFeedback(cast_feedback); |
- |
- video_frame = GetNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, capture_time); |
- |
- base::TimeDelta max_resend_timeout = |
- base::TimeDelta::FromMilliseconds(1 + kDefaultRtpMaxDelayMs); |
- |
- // Make sure that we do a re-send. |
- RunTasks(max_resend_timeout.InMilliseconds()); |
- // Should have sent at least 3 packets. |
- EXPECT_LE( |
- 3, |
- transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets()); |
-} |
- |
-TEST_F(VideoSenderTest, LogAckReceivedEvent) { |
- InitEncoder(false); |
- SimpleEventSubscriber event_subscriber; |
- cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber); |
- |
- int num_frames = 10; |
- for (int i = 0; i < num_frames; i++) { |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- |
- const base::TimeTicks capture_time = testing_clock_->NowTicks(); |
- video_sender_->InsertRawVideoFrame(video_frame, capture_time); |
- RunTasks(33); |
- } |
- |
- task_runner_->RunTasks(); |
- |
- RtcpCastMessage cast_feedback(1); |
- cast_feedback.ack_frame_id_ = num_frames - 1; |
- |
- video_sender_->OnReceivedCastFeedback(cast_feedback); |
- |
- std::vector<FrameEvent> frame_events; |
- event_subscriber.GetFrameEventsAndReset(&frame_events); |
- |
- ASSERT_TRUE(!frame_events.empty()); |
- EXPECT_EQ(FRAME_ACK_RECEIVED, frame_events.rbegin()->type); |
- EXPECT_EQ(VIDEO_EVENT, frame_events.rbegin()->media_type); |
- EXPECT_EQ(num_frames - 1u, frame_events.rbegin()->frame_id); |
- |
- cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber); |
-} |
- |
-TEST_F(VideoSenderTest, StopSendingInTheAbsenceOfAck) { |
- InitEncoder(false); |
- // Send a stream of frames and don't ACK; by default we shouldn't have more |
- // than 4 frames in flight. |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- |
- // Send 3 more frames and record the number of packets sent. |
- for (int i = 0; i < 3; ++i) { |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- } |
- const int number_of_packets_sent = transport_.number_of_rtp_packets(); |
- |
- // Send 3 more frames - they should not be encoded, as we have not received |
- // any acks. |
- for (int i = 0; i < 3; ++i) { |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- } |
- |
- // We expect a frame to be retransmitted because of duplicated ACKs. |
- // Only one packet of the frame is re-transmitted. |
- EXPECT_EQ(number_of_packets_sent + 1, |
- transport_.number_of_rtp_packets()); |
- |
- // Start acking and make sure we're back to steady-state. |
- RtcpCastMessage cast_feedback(1); |
- cast_feedback.media_ssrc_ = 2; |
- cast_feedback.ack_frame_id_ = 0; |
- video_sender_->OnReceivedCastFeedback(cast_feedback); |
- EXPECT_LE( |
- 4, |
- transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets()); |
- |
- // Empty the pipeline. |
- RunTasks(100); |
- // Should have sent at least 7 packets. |
- EXPECT_LE( |
- 7, |
- transport_.number_of_rtp_packets() + transport_.number_of_rtcp_packets()); |
-} |
- |
-TEST_F(VideoSenderTest, DuplicateAckRetransmit) { |
- InitEncoder(false); |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- RtcpCastMessage cast_feedback(1); |
- cast_feedback.media_ssrc_ = 2; |
- cast_feedback.ack_frame_id_ = 0; |
- |
- // Send 3 more frames but don't ACK. |
- for (int i = 0; i < 3; ++i) { |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- } |
- const int number_of_packets_sent = transport_.number_of_rtp_packets(); |
- |
- // Send duplicated ACKs and mix some invalid NACKs. |
- for (int i = 0; i < 10; ++i) { |
- RtcpCastMessage ack_feedback(1); |
- ack_feedback.media_ssrc_ = 2; |
- ack_feedback.ack_frame_id_ = 0; |
- RtcpCastMessage nack_feedback(1); |
- nack_feedback.media_ssrc_ = 2; |
- nack_feedback.missing_frames_and_packets_[255] = PacketIdSet(); |
- video_sender_->OnReceivedCastFeedback(ack_feedback); |
- video_sender_->OnReceivedCastFeedback(nack_feedback); |
- } |
- EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets()); |
- |
- // Re-transmit one packet because of duplicated ACKs. |
- for (int i = 0; i < 3; ++i) { |
- RtcpCastMessage ack_feedback(1); |
- ack_feedback.media_ssrc_ = 2; |
- ack_feedback.ack_frame_id_ = 0; |
- video_sender_->OnReceivedCastFeedback(ack_feedback); |
- } |
- EXPECT_EQ(number_of_packets_sent + 1, transport_.number_of_rtp_packets()); |
-} |
- |
-TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) { |
- InitEncoder(false); |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- RtcpCastMessage cast_feedback(1); |
- cast_feedback.media_ssrc_ = 2; |
- cast_feedback.ack_frame_id_ = 0; |
- |
- // Send 2 more frames but don't ACK. |
- for (int i = 0; i < 2; ++i) { |
- scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- } |
- // Pause the transport |
- transport_.SetPause(true); |
- |
- // Insert one more video frame. |
- video_frame = GetLargeNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- |
- const int number_of_packets_sent = transport_.number_of_rtp_packets(); |
- |
- // Send duplicated ACKs and mix some invalid NACKs. |
- for (int i = 0; i < 10; ++i) { |
- RtcpCastMessage ack_feedback(1); |
- ack_feedback.media_ssrc_ = 2; |
- ack_feedback.ack_frame_id_ = 0; |
- RtcpCastMessage nack_feedback(1); |
- nack_feedback.media_ssrc_ = 2; |
- nack_feedback.missing_frames_and_packets_[255] = PacketIdSet(); |
- video_sender_->OnReceivedCastFeedback(ack_feedback); |
- video_sender_->OnReceivedCastFeedback(nack_feedback); |
- } |
- EXPECT_EQ(number_of_packets_sent, transport_.number_of_rtp_packets()); |
- |
- // Re-transmit one packet because of duplicated ACKs. |
- for (int i = 0; i < 3; ++i) { |
- RtcpCastMessage ack_feedback(1); |
- ack_feedback.media_ssrc_ = 2; |
- ack_feedback.ack_frame_id_ = 0; |
- video_sender_->OnReceivedCastFeedback(ack_feedback); |
- } |
- |
- transport_.SetPause(false); |
- RunTasks(100); |
- EXPECT_LT(number_of_packets_sent + 1, transport_.number_of_rtp_packets()); |
-} |
- |
-TEST_F(VideoSenderTest, AcksCancelRetransmits) { |
- InitEncoder(false); |
- transport_.SetPause(true); |
- scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- |
- // Frame should be in buffer, waiting. Now let's ack it. |
- RtcpCastMessage cast_feedback(1); |
- cast_feedback.media_ssrc_ = 2; |
- cast_feedback.ack_frame_id_ = 0; |
- video_sender_->OnReceivedCastFeedback(cast_feedback); |
- |
- transport_.SetPause(false); |
- RunTasks(33); |
- EXPECT_EQ(0, transport_.number_of_rtp_packets()); |
-} |
- |
-TEST_F(VideoSenderTest, NAcksCancelRetransmits) { |
- InitEncoder(false); |
- transport_.SetPause(true); |
- // Send two video frames. |
- scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- video_frame = GetLargeNewVideoFrame(); |
- video_sender_->InsertRawVideoFrame(video_frame, testing_clock_->NowTicks()); |
- RunTasks(33); |
- |
- // Frames should be in buffer, waiting. Now let's ack the first one and nack |
- // one packet in the second one. |
- RtcpCastMessage cast_feedback(1); |
- cast_feedback.media_ssrc_ = 2; |
- cast_feedback.ack_frame_id_ = 0; |
- PacketIdSet missing_packets; |
- missing_packets.insert(0); |
- cast_feedback.missing_frames_and_packets_[1] = missing_packets; |
- video_sender_->OnReceivedCastFeedback(cast_feedback); |
- |
- transport_.SetPause(false); |
- RunTasks(33); |
- // Only one packet should be retransmitted. |
- EXPECT_EQ(1, transport_.number_of_rtp_packets()); |
-} |
- |
-} // namespace cast |
-} // namespace media |