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