• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "base/bind.h"
6 #include "base/memory/ref_counted.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "media/cast/cast_defines.h"
10 #include "media/cast/cast_environment.h"
11 #include "media/cast/net/pacing/mock_paced_packet_sender.h"
12 #include "media/cast/test/fake_task_runner.h"
13 #include "media/cast/video_receiver/video_receiver.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 
16 static const int kPacketSize = 1500;
17 static const int64 kStartMillisecond = GG_INT64_C(12345678900000);
18 
19 namespace media {
20 namespace cast {
21 
22 using testing::_;
23 
24 namespace {
25 // Was thread counted thread safe.
26 class TestVideoReceiverCallback :
27     public base::RefCountedThreadSafe<TestVideoReceiverCallback> {
28  public:
TestVideoReceiverCallback()29   TestVideoReceiverCallback()
30       : num_called_(0) {}
31 
32   // TODO(mikhal): Set and check expectations.
DecodeComplete(const scoped_refptr<media::VideoFrame> & video_frame,const base::TimeTicks & render_time)33   void DecodeComplete(const scoped_refptr<media::VideoFrame>& video_frame,
34                       const base::TimeTicks& render_time) {
35     ++num_called_;
36   }
37 
FrameToDecode(scoped_ptr<EncodedVideoFrame> video_frame,const base::TimeTicks & render_time)38   void FrameToDecode(scoped_ptr<EncodedVideoFrame> video_frame,
39       const base::TimeTicks& render_time) {
40     EXPECT_TRUE(video_frame->key_frame);
41     EXPECT_EQ(kVp8, video_frame->codec);
42     ++num_called_;
43   }
44 
number_times_called() const45   int number_times_called() const { return num_called_;}
46 
47  protected:
~TestVideoReceiverCallback()48   virtual ~TestVideoReceiverCallback() {}
49 
50  private:
51   friend class base::RefCountedThreadSafe<TestVideoReceiverCallback>;
52 
53   int num_called_;
54 };
55 }  // namespace
56 
57 class PeerVideoReceiver : public VideoReceiver {
58  public:
PeerVideoReceiver(scoped_refptr<CastEnvironment> cast_environment,const VideoReceiverConfig & video_config,PacedPacketSender * const packet_sender)59   PeerVideoReceiver(scoped_refptr<CastEnvironment> cast_environment,
60                     const VideoReceiverConfig& video_config,
61                     PacedPacketSender* const packet_sender)
62       : VideoReceiver(cast_environment, video_config, packet_sender) {
63   }
64   using VideoReceiver::IncomingParsedRtpPacket;
65 };
66 
67 
68 class VideoReceiverTest : public ::testing::Test {
69  protected:
VideoReceiverTest()70   VideoReceiverTest() {
71     // Configure to use vp8 software implementation.
72     config_.codec = kVp8;
73     config_.use_external_decoder = false;
74     task_runner_ = new test::FakeTaskRunner(&testing_clock_);
75     cast_environment_ = new CastEnvironment(&testing_clock_, task_runner_,
76         task_runner_, task_runner_, task_runner_, task_runner_,
77         GetDefaultCastLoggingConfig());
78     receiver_.reset(new
79         PeerVideoReceiver(cast_environment_, config_, &mock_transport_));
80     testing_clock_.Advance(
81         base::TimeDelta::FromMilliseconds(kStartMillisecond));
82     video_receiver_callback_ = new TestVideoReceiverCallback();
83   }
84 
~VideoReceiverTest()85   virtual ~VideoReceiverTest() {}
86 
SetUp()87   virtual void SetUp() {
88     payload_.assign(kPacketSize, 0);
89 
90     // Always start with a key frame.
91     rtp_header_.is_key_frame = true;
92     rtp_header_.frame_id = 0;
93     rtp_header_.packet_id = 0;
94     rtp_header_.max_packet_id = 0;
95     rtp_header_.is_reference = false;
96     rtp_header_.reference_frame_id = 0;
97   }
98 
99   MockPacedPacketSender mock_transport_;
100   VideoReceiverConfig config_;
101   scoped_ptr<PeerVideoReceiver> receiver_;
102   std::vector<uint8> payload_;
103   RtpCastHeader rtp_header_;
104   base::SimpleTestTickClock testing_clock_;
105 
106   scoped_refptr<test::FakeTaskRunner> task_runner_;
107   scoped_refptr<CastEnvironment> cast_environment_;
108   scoped_refptr<TestVideoReceiverCallback> video_receiver_callback_;
109 };
110 
TEST_F(VideoReceiverTest,GetOnePacketEncodedframe)111 TEST_F(VideoReceiverTest, GetOnePacketEncodedframe) {
112   EXPECT_CALL(mock_transport_, SendRtcpPacket(_)).WillRepeatedly(
113       testing::Return(true));
114   receiver_->IncomingParsedRtpPacket(payload_.data(), payload_.size(),
115                                      rtp_header_);
116 
117   VideoFrameEncodedCallback frame_to_decode_callback =
118       base::Bind(&TestVideoReceiverCallback::FrameToDecode,
119                  video_receiver_callback_);
120 
121   receiver_->GetEncodedVideoFrame(frame_to_decode_callback);
122   task_runner_->RunTasks();
123   EXPECT_EQ(video_receiver_callback_->number_times_called(), 1);
124 }
125 
TEST_F(VideoReceiverTest,MultiplePackets)126 TEST_F(VideoReceiverTest, MultiplePackets) {
127   EXPECT_CALL(mock_transport_, SendRtcpPacket(_)).WillRepeatedly(
128       testing::Return(true));
129   rtp_header_.max_packet_id = 2;
130   receiver_->IncomingParsedRtpPacket(payload_.data(), payload_.size(),
131                                      rtp_header_);
132   ++rtp_header_.packet_id;
133   ++rtp_header_.webrtc.header.sequenceNumber;
134   receiver_->IncomingParsedRtpPacket(payload_.data(), payload_.size(),
135                                      rtp_header_);
136   ++rtp_header_.packet_id;
137   receiver_->IncomingParsedRtpPacket(payload_.data(), payload_.size(),
138                                      rtp_header_);
139 
140   VideoFrameEncodedCallback frame_to_decode_callback =
141       base::Bind(&TestVideoReceiverCallback::FrameToDecode,
142                  video_receiver_callback_);
143 
144   receiver_->GetEncodedVideoFrame(frame_to_decode_callback);
145 
146   task_runner_->RunTasks();
147   EXPECT_EQ(video_receiver_callback_->number_times_called(), 1);
148 }
149 
TEST_F(VideoReceiverTest,GetOnePacketRawframe)150 TEST_F(VideoReceiverTest, GetOnePacketRawframe) {
151   EXPECT_CALL(mock_transport_, SendRtcpPacket(_)).WillRepeatedly(
152       testing::Return(true));
153   receiver_->IncomingParsedRtpPacket(payload_.data(), payload_.size(),
154                                      rtp_header_);
155   // Decode error - requires legal input.
156   VideoFrameDecodedCallback frame_decoded_callback =
157       base::Bind(&TestVideoReceiverCallback::DecodeComplete,
158                  video_receiver_callback_);
159   receiver_->GetRawVideoFrame(frame_decoded_callback);
160   task_runner_->RunTasks();
161   EXPECT_EQ(video_receiver_callback_->number_times_called(), 0);
162 }
163 
164 // TODO(pwestin): add encoded frames.
165 
166 }  // namespace cast
167 }  // namespace media
168 
169 
170