10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Copyright 2008 Google Inc.
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org//
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Author: Ronghua Wu (ronghuawu@google.com)
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <string>
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/media/base/testutils.h"
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/media/webrtc/webrtcpassthroughrender.h"
9cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/gunit.h"
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass WebRtcPassthroughRenderTest : public testing::Test {
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public:
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  class ExternalRenderer : public webrtc::VideoRenderCallback {
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   public:
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ExternalRenderer() : frame_num_(0) {
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    virtual ~ExternalRenderer() {
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    virtual int32_t RenderFrame(const uint32_t stream_id,
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                webrtc::I420VideoFrame& videoFrame) {
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ++frame_num_;
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(INFO) << "RenderFrame stream_id: " << stream_id
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                << " frame_num: " << frame_num_;
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return 0;
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int frame_num() const {
300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return frame_num_;
310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   private:
340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int frame_num_;
350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  };
360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  WebRtcPassthroughRenderTest()
380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      : renderer_(new cricket::WebRtcPassthroughRender()) {
390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ~WebRtcPassthroughRenderTest() {
420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  webrtc::VideoRenderCallback* AddIncomingRenderStream(int stream_id) {
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return renderer_->AddIncomingRenderStream(stream_id, 0, 0, 0, 0, 0);
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool HasIncomingRenderStream(int stream_id) {
490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return renderer_->HasIncomingRenderStream(stream_id);
500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool DeleteIncomingRenderStream(int stream_id) {
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return (renderer_->DeleteIncomingRenderStream(stream_id) == 0);
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool AddExternalRenderCallback(int stream_id,
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 webrtc::VideoRenderCallback* renderer) {
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return (renderer_->AddExternalRenderCallback(stream_id, renderer) == 0);
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool StartRender(int stream_id) {
620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return (renderer_->StartRender(stream_id) == 0);
630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool StopRender(int stream_id) {
660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return (renderer_->StopRender(stream_id) == 0);
670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private:
702a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<cricket::WebRtcPassthroughRender> renderer_;
710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org};
720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(WebRtcPassthroughRenderTest, Streams) {
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const int stream_id1 = 1234;
750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const int stream_id2 = 5678;
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const int stream_id3 = 9012;  // A stream that doesn't exist.
770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  webrtc::VideoRenderCallback* stream = NULL;
780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Add a new stream
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stream = AddIncomingRenderStream(stream_id1);
800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(stream != NULL);
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(HasIncomingRenderStream(stream_id1));
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Tried to add a already existed stream should return null
830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stream =AddIncomingRenderStream(stream_id1);
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(stream == NULL);
850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stream = AddIncomingRenderStream(stream_id2);
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(stream != NULL);
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(HasIncomingRenderStream(stream_id2));
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Remove the stream
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_FALSE(DeleteIncomingRenderStream(stream_id3));
900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(DeleteIncomingRenderStream(stream_id2));
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(!HasIncomingRenderStream(stream_id2));
920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Add back the removed stream
930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stream = AddIncomingRenderStream(stream_id2);
940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(stream != NULL);
950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(HasIncomingRenderStream(stream_id2));
960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(WebRtcPassthroughRenderTest, Renderer) {
990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  webrtc::I420VideoFrame frame;
1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const int stream_id1 = 1234;
1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const int stream_id2 = 5678;
1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const int stream_id3 = 9012;  // A stream that doesn't exist.
1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  webrtc::VideoRenderCallback* stream1 = NULL;
1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  webrtc::VideoRenderCallback* stream2 = NULL;
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Add two new stream
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stream1 = AddIncomingRenderStream(stream_id1);
1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(stream1 != NULL);
1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(HasIncomingRenderStream(stream_id1));
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stream2 = AddIncomingRenderStream(stream_id2);
1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(stream2 != NULL);
1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(HasIncomingRenderStream(stream_id2));
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Register the external renderer
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  WebRtcPassthroughRenderTest::ExternalRenderer renderer1;
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  WebRtcPassthroughRenderTest::ExternalRenderer renderer2;
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_FALSE(AddExternalRenderCallback(stream_id3, &renderer1));
1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(AddExternalRenderCallback(stream_id1, &renderer1));
1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(AddExternalRenderCallback(stream_id2, &renderer2));
1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  int test_frame_num = 10;
1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // RenderFrame without starting the render
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (int i = 0; i < test_frame_num; ++i) {
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stream1->RenderFrame(stream_id1, frame);
1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(0, renderer1.frame_num());
1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Start the render and test again.
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_FALSE(StartRender(stream_id3));
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(StartRender(stream_id1));
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (int i = 0; i < test_frame_num; ++i) {
1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stream1->RenderFrame(stream_id1, frame);
1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(test_frame_num, renderer1.frame_num());
1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Stop the render and test again.
1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_FALSE(StopRender(stream_id3));
1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(StopRender(stream_id1));
1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (int i = 0; i < test_frame_num; ++i) {
1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stream1->RenderFrame(stream_id1, frame);
1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // The frame number should not have changed.
1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(test_frame_num, renderer1.frame_num());
1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Test on stream2 with a differnt number.
1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(StartRender(stream_id2));
1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  test_frame_num = 30;
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (int i = 0; i < test_frame_num; ++i) {
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stream2->RenderFrame(stream_id2, frame);
1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(test_frame_num, renderer2.frame_num());
1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
148