1 // Copyright 2008 Google Inc. All Rights Reserved,
2 //
3 // Author: Ronghua Wu (ronghuawu@google.com)
4 
5 #include <string>
6 
7 #include "talk/base/gunit.h"
8 #include "talk/session/phone/webrtcpassthroughrender.h"
9 #include "talk/session/phone/testutils.h"
10 
11 class WebRtcPassthroughRenderTest : public testing::Test {
12  public:
13   class ExternalRenderer : public webrtc::VideoRenderCallback {
14    public:
ExternalRenderer()15     ExternalRenderer() : frame_num_(0) {
16     }
17 
~ExternalRenderer()18     virtual ~ExternalRenderer() {
19     }
20 
RenderFrame(const WebRtc_UWord32 stream_id,webrtc::VideoFrame & videoFrame)21     virtual WebRtc_Word32 RenderFrame(
22         const WebRtc_UWord32 stream_id,
23         webrtc::VideoFrame& videoFrame) {
24       ++frame_num_;
25       LOG(INFO) << "RenderFrame stream_id: " << stream_id
26                 << " frame_num: " << frame_num_;
27       return 0;
28     }
29 
frame_num() const30     int frame_num() const {
31       return frame_num_;
32     }
33 
34    private:
35     int frame_num_;
36   };
37 
WebRtcPassthroughRenderTest()38   WebRtcPassthroughRenderTest()
39       : renderer_(new cricket::WebRtcPassthroughRender()) {
40   }
41 
~WebRtcPassthroughRenderTest()42   ~WebRtcPassthroughRenderTest() {
43   }
44 
AddIncomingRenderStream(int stream_id)45   webrtc::VideoRenderCallback* AddIncomingRenderStream(int stream_id) {
46     return renderer_->AddIncomingRenderStream(stream_id, 0, 0, 0, 0, 0);
47   }
48 
HasIncomingRenderStream(int stream_id)49   bool HasIncomingRenderStream(int stream_id) {
50     return renderer_->HasIncomingRenderStream(stream_id);
51   }
52 
DeleteIncomingRenderStream(int stream_id)53   bool DeleteIncomingRenderStream(int stream_id) {
54     return (renderer_->DeleteIncomingRenderStream(stream_id) == 0);
55   }
56 
AddExternalRenderCallback(int stream_id,webrtc::VideoRenderCallback * renderer)57   bool AddExternalRenderCallback(int stream_id,
58                                  webrtc::VideoRenderCallback* renderer) {
59     return (renderer_->AddExternalRenderCallback(stream_id, renderer) == 0);
60   }
61 
StartRender(int stream_id)62   bool StartRender(int stream_id) {
63     return (renderer_->StartRender(stream_id) == 0);
64   }
65 
StopRender(int stream_id)66   bool StopRender(int stream_id) {
67     return (renderer_->StopRender(stream_id) == 0);
68   }
69 
70  private:
71   talk_base::scoped_ptr<cricket::WebRtcPassthroughRender> renderer_;
72 };
73 
TEST_F(WebRtcPassthroughRenderTest,Streams)74 TEST_F(WebRtcPassthroughRenderTest, Streams) {
75   const int stream_id1 = 1234;
76   const int stream_id2 = 5678;
77   webrtc::VideoRenderCallback* stream = NULL;
78   // Add a new stream
79   stream = AddIncomingRenderStream(stream_id1);
80   EXPECT_TRUE(stream != NULL);
81   EXPECT_TRUE(HasIncomingRenderStream(stream_id1));
82   // Tried to add a already existed stream should return null
83   stream =AddIncomingRenderStream(stream_id1);
84   EXPECT_TRUE(stream == NULL);
85   stream = AddIncomingRenderStream(stream_id2);
86   EXPECT_TRUE(stream != NULL);
87   EXPECT_TRUE(HasIncomingRenderStream(stream_id2));
88   // Remove the stream
89   EXPECT_TRUE(DeleteIncomingRenderStream(stream_id2));
90   EXPECT_TRUE(!HasIncomingRenderStream(stream_id2));
91   // Add back the removed stream
92   stream = AddIncomingRenderStream(stream_id2);
93   EXPECT_TRUE(stream != NULL);
94   EXPECT_TRUE(HasIncomingRenderStream(stream_id2));
95 }
96 
TEST_F(WebRtcPassthroughRenderTest,Renderer)97 TEST_F(WebRtcPassthroughRenderTest, Renderer) {
98   webrtc::VideoFrame frame;
99   const int stream_id1 = 1234;
100   const int stream_id2 = 5678;
101   webrtc::VideoRenderCallback* stream1 = NULL;
102   webrtc::VideoRenderCallback* stream2 = NULL;
103   // Add two new stream
104   stream1 = AddIncomingRenderStream(stream_id1);
105   EXPECT_TRUE(stream1 != NULL);
106   EXPECT_TRUE(HasIncomingRenderStream(stream_id1));
107   stream2 = AddIncomingRenderStream(stream_id2);
108   EXPECT_TRUE(stream2 != NULL);
109   EXPECT_TRUE(HasIncomingRenderStream(stream_id2));
110   // Register the external renderer
111   WebRtcPassthroughRenderTest::ExternalRenderer renderer1;
112   WebRtcPassthroughRenderTest::ExternalRenderer renderer2;
113   AddExternalRenderCallback(stream_id1, &renderer1);
114   AddExternalRenderCallback(stream_id2, &renderer2);
115   int test_frame_num = 10;
116   // RenderFrame without starting the render
117   for (int i = 0; i < test_frame_num; ++i) {
118     stream1->RenderFrame(stream_id1, frame);
119   }
120   EXPECT_EQ(0, renderer1.frame_num());
121   // Start the render and test again.
122   EXPECT_TRUE(StartRender(stream_id1));
123   for (int i = 0; i < test_frame_num; ++i) {
124     stream1->RenderFrame(stream_id1, frame);
125   }
126   EXPECT_EQ(test_frame_num, renderer1.frame_num());
127   // Stop the render and test again.
128   EXPECT_TRUE(StopRender(stream_id1));
129   for (int i = 0; i < test_frame_num; ++i) {
130     stream1->RenderFrame(stream_id1, frame);
131   }
132   // The frame number should not have changed.
133   EXPECT_EQ(test_frame_num, renderer1.frame_num());
134 
135   // Test on stream2 with a differnt number.
136   EXPECT_TRUE(StartRender(stream_id2));
137   test_frame_num = 30;
138   for (int i = 0; i < test_frame_num; ++i) {
139     stream2->RenderFrame(stream_id2, frame);
140   }
141   EXPECT_EQ(test_frame_num, renderer2.frame_num());
142 }
143