| OLD | NEW | 
|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include <stdint.h> |  | 
| 6 |  | 
| 7 #include "base/bind.h" | 5 #include "base/bind.h" | 
| 8 #include "base/memory/ref_counted.h" | 6 #include "base/memory/ref_counted.h" | 
| 9 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" | 
| 10 #include "base/test/simple_test_tick_clock.h" | 8 #include "base/test/simple_test_tick_clock.h" | 
| 11 #include "media/cast/audio_receiver/audio_receiver.h" | 9 #include "media/cast/audio_receiver/audio_receiver.h" | 
| 12 #include "media/cast/cast_defines.h" | 10 #include "media/cast/cast_defines.h" | 
| 13 #include "media/cast/cast_environment.h" | 11 #include "media/cast/cast_environment.h" | 
| 14 #include "media/cast/logging/simple_event_subscriber.h" | 12 #include "media/cast/logging/simple_event_subscriber.h" | 
| 15 #include "media/cast/rtcp/test_rtcp_packet_builder.h" | 13 #include "media/cast/rtcp/test_rtcp_packet_builder.h" | 
| 16 #include "media/cast/test/fake_single_thread_task_runner.h" | 14 #include "media/cast/test/fake_single_thread_task_runner.h" | 
| 17 #include "media/cast/transport/pacing/mock_paced_packet_sender.h" | 15 #include "media/cast/transport/pacing/mock_paced_packet_sender.h" | 
| 18 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" | 
| 19 | 17 | 
| 20 namespace media { | 18 namespace media { | 
| 21 namespace cast { | 19 namespace cast { | 
| 22 | 20 | 
| 23 static const int64 kStartMillisecond = INT64_C(12345678900000); | 21 using ::testing::_; | 
| 24 | 22 | 
| 25 namespace { | 23 namespace { | 
|  | 24 | 
|  | 25 const int64 kStartMillisecond = INT64_C(12345678900000); | 
|  | 26 const uint32 kFirstFrameId = 1234; | 
|  | 27 | 
| 26 class FakeAudioClient { | 28 class FakeAudioClient { | 
| 27  public: | 29  public: | 
| 28   FakeAudioClient() : num_called_(0) {} | 30   FakeAudioClient() : num_called_(0) {} | 
| 29   virtual ~FakeAudioClient() {} | 31   virtual ~FakeAudioClient() {} | 
| 30 | 32 | 
| 31   void SetNextExpectedResult(uint8 expected_frame_id, | 33   void SetNextExpectedResult(uint32 expected_frame_id, | 
| 32                              const base::TimeTicks& expected_playout_time) { | 34                              const base::TimeTicks& expected_playout_time) { | 
| 33     expected_frame_id_ = expected_frame_id; | 35     expected_frame_id_ = expected_frame_id; | 
| 34     expected_playout_time_ = expected_playout_time; | 36     expected_playout_time_ = expected_playout_time; | 
| 35   } | 37   } | 
| 36 | 38 | 
| 37   void DeliverEncodedAudioFrame( | 39   void DeliverEncodedAudioFrame( | 
| 38       scoped_ptr<transport::EncodedAudioFrame> audio_frame, | 40       scoped_ptr<transport::EncodedAudioFrame> audio_frame, | 
| 39       const base::TimeTicks& playout_time) { | 41       const base::TimeTicks& playout_time) { | 
| 40     ASSERT_FALSE(!audio_frame) | 42     ASSERT_FALSE(!audio_frame) | 
| 41         << "If at shutdown: There were unsatisfied requests enqueued."; | 43         << "If at shutdown: There were unsatisfied requests enqueued."; | 
| 42     EXPECT_EQ(expected_frame_id_, audio_frame->frame_id); | 44     EXPECT_EQ(expected_frame_id_, audio_frame->frame_id); | 
| 43     EXPECT_EQ(transport::kPcm16, audio_frame->codec); | 45     EXPECT_EQ(transport::kPcm16, audio_frame->codec); | 
| 44     EXPECT_EQ(expected_playout_time_, playout_time); | 46     EXPECT_EQ(expected_playout_time_, playout_time); | 
| 45     num_called_++; | 47     num_called_++; | 
| 46   } | 48   } | 
| 47 | 49 | 
| 48   int number_times_called() const { return num_called_; } | 50   int number_times_called() const { return num_called_; } | 
| 49 | 51 | 
| 50  private: | 52  private: | 
| 51   int num_called_; | 53   int num_called_; | 
| 52   uint8 expected_frame_id_; | 54   uint32 expected_frame_id_; | 
| 53   base::TimeTicks expected_playout_time_; | 55   base::TimeTicks expected_playout_time_; | 
| 54 | 56 | 
| 55   DISALLOW_COPY_AND_ASSIGN(FakeAudioClient); | 57   DISALLOW_COPY_AND_ASSIGN(FakeAudioClient); | 
| 56 }; | 58 }; | 
|  | 59 | 
| 57 }  // namespace | 60 }  // namespace | 
| 58 | 61 | 
| 59 class AudioReceiverTest : public ::testing::Test { | 62 class AudioReceiverTest : public ::testing::Test { | 
| 60  protected: | 63  protected: | 
| 61   AudioReceiverTest() { | 64   AudioReceiverTest() { | 
| 62     // Configure the audio receiver to use PCM16. | 65     // Configure the audio receiver to use PCM16. | 
| 63     audio_config_.rtp_payload_type = 127; | 66     audio_config_.rtp_payload_type = 127; | 
| 64     audio_config_.frequency = 16000; | 67     audio_config_.frequency = 16000; | 
| 65     audio_config_.channels = 1; | 68     audio_config_.channels = 1; | 
| 66     audio_config_.codec = transport::kPcm16; | 69     audio_config_.codec = transport::kPcm16; | 
| 67     audio_config_.use_external_decoder = false; | 70     audio_config_.use_external_decoder = true; | 
| 68     audio_config_.feedback_ssrc = 1234; | 71     audio_config_.feedback_ssrc = 1234; | 
| 69     testing_clock_ = new base::SimpleTestTickClock(); | 72     testing_clock_ = new base::SimpleTestTickClock(); | 
| 70     testing_clock_->Advance( | 73     testing_clock_->Advance( | 
| 71         base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 74         base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 
| 72     task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_); | 75     task_runner_ = new test::FakeSingleThreadTaskRunner(testing_clock_); | 
| 73 | 76 | 
| 74     cast_environment_ = new CastEnvironment( | 77     cast_environment_ = new CastEnvironment( | 
| 75         scoped_ptr<base::TickClock>(testing_clock_).Pass(), | 78         scoped_ptr<base::TickClock>(testing_clock_).Pass(), | 
| 76         task_runner_, | 79         task_runner_, | 
| 77         task_runner_, | 80         task_runner_, | 
| 78         task_runner_); | 81         task_runner_); | 
| 79   } |  | 
| 80 | 82 | 
| 81   void Configure(bool use_external_decoder) { |  | 
| 82     audio_config_.use_external_decoder = use_external_decoder; |  | 
| 83     receiver_.reset(new AudioReceiver(cast_environment_, audio_config_, | 83     receiver_.reset(new AudioReceiver(cast_environment_, audio_config_, | 
| 84                                       &mock_transport_)); | 84                                       &mock_transport_)); | 
| 85   } | 85   } | 
| 86 | 86 | 
| 87   virtual ~AudioReceiverTest() {} | 87   virtual ~AudioReceiverTest() {} | 
| 88 | 88 | 
| 89   virtual void SetUp() { | 89   virtual void SetUp() { | 
| 90     payload_.assign(kMaxIpPacketSize, 0); | 90     payload_.assign(kMaxIpPacketSize, 0); | 
| 91     rtp_header_.is_key_frame = true; | 91     rtp_header_.is_key_frame = true; | 
| 92     rtp_header_.frame_id = 0; | 92     rtp_header_.frame_id = kFirstFrameId; | 
| 93     rtp_header_.packet_id = 0; | 93     rtp_header_.packet_id = 0; | 
| 94     rtp_header_.max_packet_id = 0; | 94     rtp_header_.max_packet_id = 0; | 
| 95     rtp_header_.is_reference = false; | 95     rtp_header_.is_reference = false; | 
| 96     rtp_header_.reference_frame_id = 0; | 96     rtp_header_.reference_frame_id = 0; | 
| 97     rtp_header_.webrtc.header.timestamp = 0; | 97     rtp_header_.webrtc.header.timestamp = 0; | 
| 98   } | 98   } | 
| 99 | 99 | 
| 100   void FeedOneFrameIntoReceiver() { | 100   void FeedOneFrameIntoReceiver() { | 
| 101     receiver_->OnReceivedPayloadData( | 101     receiver_->OnReceivedPayloadData( | 
| 102         payload_.data(), payload_.size(), rtp_header_); | 102         payload_.data(), payload_.size(), rtp_header_); | 
| 103   } | 103   } | 
| 104 | 104 | 
| 105   AudioReceiverConfig audio_config_; | 105   AudioReceiverConfig audio_config_; | 
| 106   std::vector<uint8> payload_; | 106   std::vector<uint8> payload_; | 
| 107   RtpCastHeader rtp_header_; | 107   RtpCastHeader rtp_header_; | 
| 108   base::SimpleTestTickClock* testing_clock_;  // Owned by CastEnvironment. | 108   base::SimpleTestTickClock* testing_clock_;  // Owned by CastEnvironment. | 
| 109   transport::MockPacedPacketSender mock_transport_; | 109   transport::MockPacedPacketSender mock_transport_; | 
| 110   scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; | 110   scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; | 
| 111   scoped_refptr<CastEnvironment> cast_environment_; | 111   scoped_refptr<CastEnvironment> cast_environment_; | 
| 112   FakeAudioClient fake_audio_client_; | 112   FakeAudioClient fake_audio_client_; | 
| 113 | 113 | 
| 114   // Important for the AudioReceiver to be declared last, since its dependencies | 114   // Important for the AudioReceiver to be declared last, since its dependencies | 
| 115   // must remain alive until after its destruction. | 115   // must remain alive until after its destruction. | 
| 116   scoped_ptr<AudioReceiver> receiver_; | 116   scoped_ptr<AudioReceiver> receiver_; | 
| 117 }; | 117 }; | 
| 118 | 118 | 
| 119 TEST_F(AudioReceiverTest, GetOnePacketEncodedframe) { | 119 TEST_F(AudioReceiverTest, GetOnePacketEncodedFrame) { | 
| 120   SimpleEventSubscriber event_subscriber; | 120   SimpleEventSubscriber event_subscriber; | 
| 121   cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber); | 121   cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber); | 
| 122 | 122 | 
| 123   Configure(true); | 123   EXPECT_CALL(mock_transport_, SendRtcpPacket(_)).Times(1); | 
| 124   EXPECT_CALL(mock_transport_, SendRtcpPacket(testing::_)).Times(1); |  | 
| 125 | 124 | 
| 126   // Enqueue a request for an audio frame. | 125   // Enqueue a request for an audio frame. | 
| 127   receiver_->GetEncodedAudioFrame( | 126   receiver_->GetEncodedAudioFrame( | 
| 128       base::Bind(&FakeAudioClient::DeliverEncodedAudioFrame, | 127       base::Bind(&FakeAudioClient::DeliverEncodedAudioFrame, | 
| 129                  base::Unretained(&fake_audio_client_))); | 128                  base::Unretained(&fake_audio_client_))); | 
| 130 | 129 | 
| 131   // The request should not be satisfied since no packets have been received. | 130   // The request should not be satisfied since no packets have been received. | 
| 132   task_runner_->RunTasks(); | 131   task_runner_->RunTasks(); | 
| 133   EXPECT_EQ(0, fake_audio_client_.number_times_called()); | 132   EXPECT_EQ(0, fake_audio_client_.number_times_called()); | 
| 134 | 133 | 
| 135   // Deliver one audio frame to the receiver and expect to get one frame back. | 134   // Deliver one audio frame to the receiver and expect to get one frame back. | 
| 136   fake_audio_client_.SetNextExpectedResult(0, testing_clock_->NowTicks()); | 135   fake_audio_client_.SetNextExpectedResult(kFirstFrameId, | 
|  | 136                                            testing_clock_->NowTicks()); | 
| 137   FeedOneFrameIntoReceiver(); | 137   FeedOneFrameIntoReceiver(); | 
| 138   task_runner_->RunTasks(); | 138   task_runner_->RunTasks(); | 
| 139   EXPECT_EQ(1, fake_audio_client_.number_times_called()); | 139   EXPECT_EQ(1, fake_audio_client_.number_times_called()); | 
| 140 | 140 | 
| 141   std::vector<FrameEvent> frame_events; | 141   std::vector<FrameEvent> frame_events; | 
| 142   event_subscriber.GetFrameEventsAndReset(&frame_events); | 142   event_subscriber.GetFrameEventsAndReset(&frame_events); | 
| 143 | 143 | 
| 144   ASSERT_TRUE(!frame_events.empty()); | 144   ASSERT_TRUE(!frame_events.empty()); | 
| 145   EXPECT_EQ(kAudioAckSent, frame_events.begin()->type); | 145   EXPECT_EQ(kAudioAckSent, frame_events.begin()->type); | 
| 146   EXPECT_EQ(rtp_header_.frame_id, frame_events.begin()->frame_id); | 146   EXPECT_EQ(rtp_header_.frame_id, frame_events.begin()->frame_id); | 
| 147   EXPECT_EQ(rtp_header_.webrtc.header.timestamp, | 147   EXPECT_EQ(rtp_header_.webrtc.header.timestamp, | 
| 148             frame_events.begin()->rtp_timestamp); | 148             frame_events.begin()->rtp_timestamp); | 
| 149 | 149 | 
| 150   cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber); | 150   cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber); | 
| 151 } | 151 } | 
| 152 | 152 | 
| 153 TEST_F(AudioReceiverTest, MultiplePendingGetCalls) { | 153 TEST_F(AudioReceiverTest, MultiplePendingGetCalls) { | 
| 154   Configure(true); | 154   EXPECT_CALL(mock_transport_, SendRtcpPacket(_)) | 
| 155   EXPECT_CALL(mock_transport_, SendRtcpPacket(testing::_)) |  | 
| 156       .WillRepeatedly(testing::Return(true)); | 155       .WillRepeatedly(testing::Return(true)); | 
| 157 | 156 | 
| 158   // Enqueue a request for an audio frame. | 157   // Enqueue a request for an audio frame. | 
| 159   const AudioFrameEncodedCallback frame_encoded_callback = | 158   const AudioFrameEncodedCallback frame_encoded_callback = | 
| 160       base::Bind(&FakeAudioClient::DeliverEncodedAudioFrame, | 159       base::Bind(&FakeAudioClient::DeliverEncodedAudioFrame, | 
| 161                  base::Unretained(&fake_audio_client_)); | 160                  base::Unretained(&fake_audio_client_)); | 
| 162   receiver_->GetEncodedAudioFrame(frame_encoded_callback); | 161   receiver_->GetEncodedAudioFrame(frame_encoded_callback); | 
| 163   task_runner_->RunTasks(); | 162   task_runner_->RunTasks(); | 
| 164   EXPECT_EQ(0, fake_audio_client_.number_times_called()); | 163   EXPECT_EQ(0, fake_audio_client_.number_times_called()); | 
| 165 | 164 | 
| 166   // Receive one audio frame and expect to see the first request satisfied. | 165   // Receive one audio frame and expect to see the first request satisfied. | 
| 167   fake_audio_client_.SetNextExpectedResult(0, testing_clock_->NowTicks()); | 166   fake_audio_client_.SetNextExpectedResult(kFirstFrameId, | 
|  | 167                                            testing_clock_->NowTicks()); | 
| 168   FeedOneFrameIntoReceiver(); | 168   FeedOneFrameIntoReceiver(); | 
| 169   task_runner_->RunTasks(); | 169   task_runner_->RunTasks(); | 
| 170   EXPECT_EQ(1, fake_audio_client_.number_times_called()); | 170   EXPECT_EQ(1, fake_audio_client_.number_times_called()); | 
| 171 | 171 | 
| 172   TestRtcpPacketBuilder rtcp_packet; | 172   TestRtcpPacketBuilder rtcp_packet; | 
| 173 | 173 | 
| 174   uint32 ntp_high; | 174   uint32 ntp_high; | 
| 175   uint32 ntp_low; | 175   uint32 ntp_low; | 
| 176   ConvertTimeTicksToNtp(testing_clock_->NowTicks(), &ntp_high, &ntp_low); | 176   ConvertTimeTicksToNtp(testing_clock_->NowTicks(), &ntp_high, &ntp_low); | 
| 177   rtcp_packet.AddSrWithNtp(audio_config_.feedback_ssrc, ntp_high, ntp_low, | 177   rtcp_packet.AddSrWithNtp(audio_config_.feedback_ssrc, ntp_high, ntp_low, | 
| 178                            rtp_header_.webrtc.header.timestamp); | 178                            rtp_header_.webrtc.header.timestamp); | 
| 179 | 179 | 
| 180   testing_clock_->Advance(base::TimeDelta::FromMilliseconds(20)); | 180   testing_clock_->Advance(base::TimeDelta::FromMilliseconds(20)); | 
| 181 | 181 | 
| 182   receiver_->IncomingPacket(rtcp_packet.GetPacket().Pass()); | 182   receiver_->IncomingPacket(rtcp_packet.GetPacket().Pass()); | 
| 183 | 183 | 
| 184   // Enqueue a second request for an audio frame, but it should not be | 184   // Enqueue a second request for an audio frame, but it should not be | 
| 185   // fulfilled yet. | 185   // fulfilled yet. | 
| 186   receiver_->GetEncodedAudioFrame(frame_encoded_callback); | 186   receiver_->GetEncodedAudioFrame(frame_encoded_callback); | 
| 187   task_runner_->RunTasks(); | 187   task_runner_->RunTasks(); | 
| 188   EXPECT_EQ(1, fake_audio_client_.number_times_called()); | 188   EXPECT_EQ(1, fake_audio_client_.number_times_called()); | 
| 189 | 189 | 
| 190   // Receive one audio frame out-of-order: Make sure that we are not continuous | 190   // Receive one audio frame out-of-order: Make sure that we are not continuous | 
| 191   // and that the RTP timestamp represents a time in the future. | 191   // and that the RTP timestamp represents a time in the future. | 
| 192   rtp_header_.is_key_frame = false; | 192   rtp_header_.is_key_frame = false; | 
| 193   rtp_header_.frame_id = 2; | 193   rtp_header_.frame_id = kFirstFrameId + 2; | 
| 194   rtp_header_.is_reference = true; | 194   rtp_header_.is_reference = true; | 
| 195   rtp_header_.reference_frame_id = 0; | 195   rtp_header_.reference_frame_id = 0; | 
| 196   rtp_header_.webrtc.header.timestamp = 960; | 196   rtp_header_.webrtc.header.timestamp = 960; | 
| 197   fake_audio_client_.SetNextExpectedResult( | 197   fake_audio_client_.SetNextExpectedResult( | 
| 198       2, testing_clock_->NowTicks() + base::TimeDelta::FromMilliseconds(100)); | 198       kFirstFrameId + 2, | 
|  | 199       testing_clock_->NowTicks() + base::TimeDelta::FromMilliseconds(100)); | 
| 199   FeedOneFrameIntoReceiver(); | 200   FeedOneFrameIntoReceiver(); | 
| 200 | 201 | 
| 201   // Frame 2 should not come out at this point in time. | 202   // Frame 2 should not come out at this point in time. | 
| 202   task_runner_->RunTasks(); | 203   task_runner_->RunTasks(); | 
| 203   EXPECT_EQ(1, fake_audio_client_.number_times_called()); | 204   EXPECT_EQ(1, fake_audio_client_.number_times_called()); | 
| 204 | 205 | 
| 205   // Enqueue a third request for an audio frame. | 206   // Enqueue a third request for an audio frame. | 
| 206   receiver_->GetEncodedAudioFrame(frame_encoded_callback); | 207   receiver_->GetEncodedAudioFrame(frame_encoded_callback); | 
| 207   task_runner_->RunTasks(); | 208   task_runner_->RunTasks(); | 
| 208   EXPECT_EQ(1, fake_audio_client_.number_times_called()); | 209   EXPECT_EQ(1, fake_audio_client_.number_times_called()); | 
| 209 | 210 | 
| 210   // After 100 ms has elapsed, Frame 2 is emitted (to satisfy the second | 211   // After 100 ms has elapsed, Frame 2 is emitted (to satisfy the second | 
| 211   // request) because a decision was made to skip over the no-show Frame 1. | 212   // request) because a decision was made to skip over the no-show Frame 1. | 
| 212   testing_clock_->Advance(base::TimeDelta::FromMilliseconds(100)); | 213   testing_clock_->Advance(base::TimeDelta::FromMilliseconds(100)); | 
| 213   task_runner_->RunTasks(); | 214   task_runner_->RunTasks(); | 
| 214   EXPECT_EQ(2, fake_audio_client_.number_times_called()); | 215   EXPECT_EQ(2, fake_audio_client_.number_times_called()); | 
| 215 | 216 | 
| 216   // Receive Frame 3 and expect it to fulfill the third request immediately. | 217   // Receive Frame 3 and expect it to fulfill the third request immediately. | 
| 217   rtp_header_.frame_id = 3; | 218   rtp_header_.frame_id = kFirstFrameId + 3; | 
| 218   rtp_header_.is_reference = false; | 219   rtp_header_.is_reference = false; | 
| 219   rtp_header_.reference_frame_id = 0; | 220   rtp_header_.reference_frame_id = 0; | 
| 220   rtp_header_.webrtc.header.timestamp = 1280; | 221   rtp_header_.webrtc.header.timestamp = 1280; | 
| 221   fake_audio_client_.SetNextExpectedResult(3, testing_clock_->NowTicks()); | 222   fake_audio_client_.SetNextExpectedResult(kFirstFrameId + 3, | 
|  | 223                                            testing_clock_->NowTicks()); | 
| 222   FeedOneFrameIntoReceiver(); | 224   FeedOneFrameIntoReceiver(); | 
| 223   task_runner_->RunTasks(); | 225   task_runner_->RunTasks(); | 
| 224   EXPECT_EQ(3, fake_audio_client_.number_times_called()); | 226   EXPECT_EQ(3, fake_audio_client_.number_times_called()); | 
| 225 | 227 | 
| 226   // Move forward another 100 ms and run any pending tasks (there should be | 228   // Move forward another 100 ms and run any pending tasks (there should be | 
| 227   // none).  Expect no additional frames where emitted. | 229   // none).  Expect no additional frames where emitted. | 
| 228   testing_clock_->Advance(base::TimeDelta::FromMilliseconds(100)); | 230   testing_clock_->Advance(base::TimeDelta::FromMilliseconds(100)); | 
| 229   task_runner_->RunTasks(); | 231   task_runner_->RunTasks(); | 
| 230   EXPECT_EQ(3, fake_audio_client_.number_times_called()); | 232   EXPECT_EQ(3, fake_audio_client_.number_times_called()); | 
| 231 } | 233 } | 
| 232 | 234 | 
| 233 }  // namespace cast | 235 }  // namespace cast | 
| 234 }  // namespace media | 236 }  // namespace media | 
| OLD | NEW | 
|---|