Index: webrtc/modules/video_render/test/testAPI/testAPI.cc |
diff --git a/webrtc/modules/video_render/test/testAPI/testAPI.cc b/webrtc/modules/video_render/test/testAPI/testAPI.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cea2f6b56fe0bc33d99c812ea5543621218ee45b |
--- /dev/null |
+++ b/webrtc/modules/video_render/test/testAPI/testAPI.cc |
@@ -0,0 +1,645 @@ |
+/* |
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
+ * |
+ * Use of this source code is governed by a BSD-style license |
+ * that can be found in the LICENSE file in the root of the source |
+ * tree. An additional intellectual property rights grant can be found |
+ * in the file PATENTS. All contributing project authors may |
+ * be found in the AUTHORS file in the root of the source tree. |
+ */ |
+ |
+#include "webrtc/modules/video_render/test/testAPI/testAPI.h" |
+ |
+#include <stdio.h> |
+ |
+#if defined(_WIN32) |
+#include <tchar.h> |
+#include <windows.h> |
+#include <assert.h> |
+#include <fstream> |
+#include <iostream> |
+#include <string> |
+#include <windows.h> |
+#include <ddraw.h> |
+ |
+#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) |
+ |
+#include <X11/Xlib.h> |
+#include <X11/Xutil.h> |
+#include <iostream> |
+#include <sys/time.h> |
+ |
+#endif |
+ |
+#include "webrtc/common_types.h" |
+#include "webrtc/modules/include/module_common_types.h" |
+#include "webrtc/modules/utility/include/process_thread.h" |
+#include "webrtc/modules/video_render/video_render.h" |
+#include "webrtc/modules/video_render/video_render_defines.h" |
+#include "webrtc/system_wrappers/include/sleep.h" |
+#include "webrtc/system_wrappers/include/tick_util.h" |
+#include "webrtc/system_wrappers/include/trace.h" |
+ |
+using namespace webrtc; |
+ |
+void GetTestVideoFrame(VideoFrame* frame, uint8_t startColor); |
+int TestSingleStream(VideoRender* renderModule); |
+int TestFullscreenStream(VideoRender* &renderModule, |
+ void* window, |
+ const VideoRenderType videoRenderType); |
+int TestBitmapText(VideoRender* renderModule); |
+int TestMultipleStreams(VideoRender* renderModule); |
+int TestExternalRender(VideoRender* renderModule); |
+ |
+#define TEST_FRAME_RATE 30 |
+#define TEST_TIME_SECOND 5 |
+#define TEST_FRAME_NUM (TEST_FRAME_RATE*TEST_TIME_SECOND) |
+#define TEST_STREAM0_START_COLOR 0 |
+#define TEST_STREAM1_START_COLOR 64 |
+#define TEST_STREAM2_START_COLOR 128 |
+#define TEST_STREAM3_START_COLOR 192 |
+ |
+#if defined(WEBRTC_LINUX) |
+ |
+#define GET_TIME_IN_MS timeGetTime() |
+ |
+unsigned long timeGetTime() |
+{ |
+ struct timeval tv; |
+ struct timezone tz; |
+ unsigned long val; |
+ |
+ gettimeofday(&tv, &tz); |
+ val= tv.tv_sec*1000+ tv.tv_usec/1000; |
+ return(val); |
+} |
+ |
+#elif defined(WEBRTC_MAC) |
+ |
+#include <unistd.h> |
+ |
+#define GET_TIME_IN_MS timeGetTime() |
+ |
+unsigned long timeGetTime() |
+{ |
+ return 0; |
+} |
+ |
+#else |
+ |
+#define GET_TIME_IN_MS ::timeGetTime() |
+ |
+#endif |
+ |
+using namespace std; |
+ |
+#if defined(_WIN32) |
+LRESULT CALLBACK WebRtcWinProc( HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) |
+{ |
+ switch(uMsg) |
+ { |
+ case WM_DESTROY: |
+ break; |
+ case WM_COMMAND: |
+ break; |
+ } |
+ return DefWindowProc(hWnd,uMsg,wParam,lParam); |
+} |
+ |
+int WebRtcCreateWindow(HWND &hwndMain,int winNum, int width, int height) |
+{ |
+ HINSTANCE hinst = GetModuleHandle(0); |
+ WNDCLASSEX wcx; |
+ wcx.hInstance = hinst; |
+ wcx.lpszClassName = TEXT("VideoRenderTest"); |
+ wcx.lpfnWndProc = (WNDPROC)WebRtcWinProc; |
+ wcx.style = CS_DBLCLKS; |
+ wcx.hIcon = LoadIcon (NULL, IDI_APPLICATION); |
+ wcx.hIconSm = LoadIcon (NULL, IDI_APPLICATION); |
+ wcx.hCursor = LoadCursor (NULL, IDC_ARROW); |
+ wcx.lpszMenuName = NULL; |
+ wcx.cbSize = sizeof (WNDCLASSEX); |
+ wcx.cbClsExtra = 0; |
+ wcx.cbWndExtra = 0; |
+ wcx.hbrBackground = GetSysColorBrush(COLOR_3DFACE); |
+ |
+ // Register our window class with the operating system. |
+ // If there is an error, exit program. |
+ if ( !RegisterClassEx (&wcx) ) |
+ { |
+ MessageBox( 0, TEXT("Failed to register window class!"),TEXT("Error!"), MB_OK|MB_ICONERROR ); |
+ return 0; |
+ } |
+ |
+ // Create the main window. |
+ hwndMain = CreateWindowEx( |
+ 0, // no extended styles |
+ TEXT("VideoRenderTest"), // class name |
+ TEXT("VideoRenderTest Window"), // window name |
+ WS_OVERLAPPED |WS_THICKFRAME, // overlapped window |
+ 800, // horizontal position |
+ 0, // vertical position |
+ width, // width |
+ height, // height |
+ (HWND) NULL, // no parent or owner window |
+ (HMENU) NULL, // class menu used |
+ hinst, // instance handle |
+ NULL); // no window creation data |
+ |
+ if (!hwndMain) |
+ return -1; |
+ |
+ // Show the window using the flag specified by the program |
+ // that started the application, and send the application |
+ // a WM_PAINT message. |
+ |
+ ShowWindow(hwndMain, SW_SHOWDEFAULT); |
+ UpdateWindow(hwndMain); |
+ return 0; |
+} |
+ |
+#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) |
+ |
+int WebRtcCreateWindow(Window *outWindow, Display **outDisplay, int winNum, int width, int height) // unsigned char* title, int titleLength) |
+ |
+{ |
+ int screen, xpos = 10, ypos = 10; |
+ XEvent evnt; |
+ XSetWindowAttributes xswa; // window attribute struct |
+ XVisualInfo vinfo; // screen visual info struct |
+ unsigned long mask; // attribute mask |
+ |
+ // get connection handle to xserver |
+ Display* _display = XOpenDisplay( NULL ); |
+ |
+ // get screen number |
+ screen = DefaultScreen(_display); |
+ |
+ // put desired visual info for the screen in vinfo |
+ if( XMatchVisualInfo(_display, screen, 24, TrueColor, &vinfo) != 0 ) |
+ { |
+ //printf( "Screen visual info match!\n" ); |
+ } |
+ |
+ // set window attributes |
+ xswa.colormap = XCreateColormap(_display, DefaultRootWindow(_display), vinfo.visual, AllocNone); |
+ xswa.event_mask = StructureNotifyMask | ExposureMask; |
+ xswa.background_pixel = 0; |
+ xswa.border_pixel = 0; |
+ |
+ // value mask for attributes |
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; |
+ |
+ switch( winNum ) |
+ { |
+ case 0: |
+ xpos = 200; |
+ ypos = 200; |
+ break; |
+ case 1: |
+ xpos = 300; |
+ ypos = 200; |
+ break; |
+ default: |
+ break; |
+ } |
+ |
+ // create a subwindow for parent (defroot) |
+ Window _window = XCreateWindow(_display, DefaultRootWindow(_display), |
+ xpos, ypos, |
+ width, |
+ height, |
+ 0, vinfo.depth, |
+ InputOutput, |
+ vinfo.visual, |
+ mask, &xswa); |
+ |
+ // Set window name |
+ if( winNum == 0 ) |
+ { |
+ XStoreName(_display, _window, "VE MM Local Window"); |
+ XSetIconName(_display, _window, "VE MM Local Window"); |
+ } |
+ else if( winNum == 1 ) |
+ { |
+ XStoreName(_display, _window, "VE MM Remote Window"); |
+ XSetIconName(_display, _window, "VE MM Remote Window"); |
+ } |
+ |
+ // make x report events for mask |
+ XSelectInput(_display, _window, StructureNotifyMask); |
+ |
+ // map the window to the display |
+ XMapWindow(_display, _window); |
+ |
+ // wait for map event |
+ do |
+ { |
+ XNextEvent(_display, &evnt); |
+ } |
+ while (evnt.type != MapNotify || evnt.xmap.event != _window); |
+ |
+ *outWindow = _window; |
+ *outDisplay = _display; |
+ |
+ return 0; |
+} |
+#endif // WEBRTC_LINUX |
+ |
+// Note: Mac code is in testApi_mac.mm. |
+ |
+class MyRenderCallback: public VideoRenderCallback |
+{ |
+public: |
+ MyRenderCallback() : |
+ _cnt(0) |
+ { |
+ } |
+ ; |
+ ~MyRenderCallback() |
+ { |
+ } |
+ ; |
+ virtual int32_t RenderFrame(const uint32_t streamId, |
+ const VideoFrame& videoFrame) { |
+ _cnt++; |
+ if (_cnt % 100 == 0) |
+ { |
+ printf("Render callback %d \n",_cnt); |
+ } |
+ return 0; |
+ } |
+ int32_t _cnt; |
+}; |
+ |
+void GetTestVideoFrame(VideoFrame* frame, uint8_t startColor) { |
+ // changing color |
+ static uint8_t color = startColor; |
+ |
+ memset(frame->buffer(kYPlane), color, frame->allocated_size(kYPlane)); |
+ memset(frame->buffer(kUPlane), color, frame->allocated_size(kUPlane)); |
+ memset(frame->buffer(kVPlane), color, frame->allocated_size(kVPlane)); |
+ |
+ ++color; |
+} |
+ |
+int TestSingleStream(VideoRender* renderModule) { |
+ int error = 0; |
+ // Add settings for a stream to render |
+ printf("Add stream 0 to entire window\n"); |
+ const int streamId0 = 0; |
+ VideoRenderCallback* renderCallback0 = renderModule->AddIncomingRenderStream(streamId0, 0, 0.0f, 0.0f, 1.0f, 1.0f); |
+ assert(renderCallback0 != NULL); |
+ |
+ printf("Start render\n"); |
+ error = renderModule->StartRender(streamId0); |
+ if (error != 0) { |
+ // TODO(phoglund): This test will not work if compiled in release mode. |
+ // This rather silly construct here is to avoid compilation errors when |
+ // compiling in release. Release => no asserts => unused 'error' variable. |
+ assert(false); |
+ } |
+ |
+ // Loop through an I420 file and render each frame |
+ const int width = 352; |
+ const int half_width = (width + 1) / 2; |
+ const int height = 288; |
+ |
+ VideoFrame videoFrame0; |
+ videoFrame0.CreateEmptyFrame(width, height, width, half_width, half_width); |
+ |
+ const uint32_t renderDelayMs = 500; |
+ |
+ for (int i=0; i<TEST_FRAME_NUM; i++) { |
+ GetTestVideoFrame(&videoFrame0, TEST_STREAM0_START_COLOR); |
+ // Render this frame with the specified delay |
+ videoFrame0.set_render_time_ms(TickTime::MillisecondTimestamp() |
+ + renderDelayMs); |
+ renderCallback0->RenderFrame(streamId0, videoFrame0); |
+ SleepMs(1000/TEST_FRAME_RATE); |
+ } |
+ |
+ |
+ // Shut down |
+ printf("Closing...\n"); |
+ error = renderModule->StopRender(streamId0); |
+ assert(error == 0); |
+ |
+ error = renderModule->DeleteIncomingRenderStream(streamId0); |
+ assert(error == 0); |
+ |
+ return 0; |
+} |
+ |
+int TestFullscreenStream(VideoRender* &renderModule, |
+ void* window, |
+ const VideoRenderType videoRenderType) { |
+ VideoRender::DestroyVideoRender(renderModule); |
+ renderModule = VideoRender::CreateVideoRender(12345, window, true, videoRenderType); |
+ |
+ TestSingleStream(renderModule); |
+ |
+ VideoRender::DestroyVideoRender(renderModule); |
+ renderModule = VideoRender::CreateVideoRender(12345, window, false, videoRenderType); |
+ |
+ return 0; |
+} |
+ |
+int TestBitmapText(VideoRender* renderModule) { |
+#if defined(WIN32) |
+ |
+ int error = 0; |
+ // Add settings for a stream to render |
+ printf("Add stream 0 to entire window\n"); |
+ const int streamId0 = 0; |
+ VideoRenderCallback* renderCallback0 = renderModule->AddIncomingRenderStream(streamId0, 0, 0.0f, 0.0f, 1.0f, 1.0f); |
+ assert(renderCallback0 != NULL); |
+ |
+ printf("Adding Bitmap\n"); |
+ DDCOLORKEY ColorKey; // black |
+ ColorKey.dwColorSpaceHighValue = RGB(0, 0, 0); |
+ ColorKey.dwColorSpaceLowValue = RGB(0, 0, 0); |
+ HBITMAP hbm = (HBITMAP)LoadImage(NULL, |
+ (LPCTSTR)_T("renderStartImage.bmp"), |
+ IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); |
+ renderModule->SetBitmap(hbm, 0, &ColorKey, 0.0f, 0.0f, 0.3f, |
+ 0.3f); |
+ |
+ printf("Adding Text\n"); |
+ renderModule->SetText(1, (uint8_t*) "WebRtc Render Demo App", 20, |
+ RGB(255, 0, 0), RGB(0, 0, 0), 0.25f, 0.1f, 1.0f, |
+ 1.0f); |
+ |
+ printf("Start render\n"); |
+ error = renderModule->StartRender(streamId0); |
+ assert(error == 0); |
+ |
+ // Loop through an I420 file and render each frame |
+ const int width = 352; |
+ const int half_width = (width + 1) / 2; |
+ const int height = 288; |
+ |
+ VideoFrame videoFrame0; |
+ videoFrame0.CreateEmptyFrame(width, height, width, half_width, half_width); |
+ |
+ const uint32_t renderDelayMs = 500; |
+ |
+ for (int i=0; i<TEST_FRAME_NUM; i++) { |
+ GetTestVideoFrame(&videoFrame0, TEST_STREAM0_START_COLOR); |
+ // Render this frame with the specified delay |
+ videoFrame0.set_render_time_ms(TickTime::MillisecondTimestamp() + |
+ renderDelayMs); |
+ renderCallback0->RenderFrame(streamId0, videoFrame0); |
+ SleepMs(1000/TEST_FRAME_RATE); |
+ } |
+ // Sleep and let all frames be rendered before closing |
+ SleepMs(renderDelayMs*2); |
+ |
+ |
+ // Shut down |
+ printf("Closing...\n"); |
+ ColorKey.dwColorSpaceHighValue = RGB(0,0,0); |
+ ColorKey.dwColorSpaceLowValue = RGB(0,0,0); |
+ renderModule->SetBitmap(NULL, 0, &ColorKey, 0.0f, 0.0f, 0.0f, 0.0f); |
+ renderModule->SetText(1, NULL, 20, RGB(255,255,255), |
+ RGB(0,0,0), 0.0f, 0.0f, 0.0f, 0.0f); |
+ |
+ error = renderModule->StopRender(streamId0); |
+ assert(error == 0); |
+ |
+ error = renderModule->DeleteIncomingRenderStream(streamId0); |
+ assert(error == 0); |
+#endif |
+ |
+ return 0; |
+} |
+ |
+int TestMultipleStreams(VideoRender* renderModule) { |
+ int error = 0; |
+ |
+ // Add settings for a stream to render |
+ printf("Add stream 0\n"); |
+ const int streamId0 = 0; |
+ VideoRenderCallback* renderCallback0 = |
+ renderModule->AddIncomingRenderStream(streamId0, 0, 0.0f, 0.0f, 0.45f, 0.45f); |
+ assert(renderCallback0 != NULL); |
+ printf("Add stream 1\n"); |
+ const int streamId1 = 1; |
+ VideoRenderCallback* renderCallback1 = |
+ renderModule->AddIncomingRenderStream(streamId1, 0, 0.55f, 0.0f, 1.0f, 0.45f); |
+ assert(renderCallback1 != NULL); |
+ printf("Add stream 2\n"); |
+ const int streamId2 = 2; |
+ VideoRenderCallback* renderCallback2 = |
+ renderModule->AddIncomingRenderStream(streamId2, 0, 0.0f, 0.55f, 0.45f, 1.0f); |
+ assert(renderCallback2 != NULL); |
+ printf("Add stream 3\n"); |
+ const int streamId3 = 3; |
+ VideoRenderCallback* renderCallback3 = |
+ renderModule->AddIncomingRenderStream(streamId3, 0, 0.55f, 0.55f, 1.0f, 1.0f); |
+ assert(renderCallback3 != NULL); |
+ error = renderModule->StartRender(streamId0); |
+ if (error != 0) { |
+ // TODO(phoglund): This test will not work if compiled in release mode. |
+ // This rather silly construct here is to avoid compilation errors when |
+ // compiling in release. Release => no asserts => unused 'error' variable. |
+ assert(false); |
+ } |
+ error = renderModule->StartRender(streamId1); |
+ assert(error == 0); |
+ error = renderModule->StartRender(streamId2); |
+ assert(error == 0); |
+ error = renderModule->StartRender(streamId3); |
+ assert(error == 0); |
+ |
+ // Loop through an I420 file and render each frame |
+ const int width = 352; |
+ const int half_width = (width + 1) / 2; |
+ const int height = 288; |
+ |
+ VideoFrame videoFrame0; |
+ videoFrame0.CreateEmptyFrame(width, height, width, half_width, half_width); |
+ VideoFrame videoFrame1; |
+ videoFrame1.CreateEmptyFrame(width, height, width, half_width, half_width); |
+ VideoFrame videoFrame2; |
+ videoFrame2.CreateEmptyFrame(width, height, width, half_width, half_width); |
+ VideoFrame videoFrame3; |
+ videoFrame3.CreateEmptyFrame(width, height, width, half_width, half_width); |
+ |
+ const uint32_t renderDelayMs = 500; |
+ |
+ // Render frames with the specified delay. |
+ for (int i=0; i<TEST_FRAME_NUM; i++) { |
+ GetTestVideoFrame(&videoFrame0, TEST_STREAM0_START_COLOR); |
+ |
+ videoFrame0.set_render_time_ms(TickTime::MillisecondTimestamp() + |
+ renderDelayMs); |
+ renderCallback0->RenderFrame(streamId0, videoFrame0); |
+ |
+ GetTestVideoFrame(&videoFrame1, TEST_STREAM1_START_COLOR); |
+ videoFrame1.set_render_time_ms(TickTime::MillisecondTimestamp() + |
+ renderDelayMs); |
+ renderCallback1->RenderFrame(streamId1, videoFrame1); |
+ |
+ GetTestVideoFrame(&videoFrame2, TEST_STREAM2_START_COLOR); |
+ videoFrame2.set_render_time_ms(TickTime::MillisecondTimestamp() + |
+ renderDelayMs); |
+ renderCallback2->RenderFrame(streamId2, videoFrame2); |
+ |
+ GetTestVideoFrame(&videoFrame3, TEST_STREAM3_START_COLOR); |
+ videoFrame3.set_render_time_ms(TickTime::MillisecondTimestamp() + |
+ renderDelayMs); |
+ renderCallback3->RenderFrame(streamId3, videoFrame3); |
+ |
+ SleepMs(1000/TEST_FRAME_RATE); |
+ } |
+ |
+ // Shut down |
+ printf("Closing...\n"); |
+ error = renderModule->StopRender(streamId0); |
+ assert(error == 0); |
+ error = renderModule->DeleteIncomingRenderStream(streamId0); |
+ assert(error == 0); |
+ error = renderModule->StopRender(streamId1); |
+ assert(error == 0); |
+ error = renderModule->DeleteIncomingRenderStream(streamId1); |
+ assert(error == 0); |
+ error = renderModule->StopRender(streamId2); |
+ assert(error == 0); |
+ error = renderModule->DeleteIncomingRenderStream(streamId2); |
+ assert(error == 0); |
+ error = renderModule->StopRender(streamId3); |
+ assert(error == 0); |
+ error = renderModule->DeleteIncomingRenderStream(streamId3); |
+ assert(error == 0); |
+ |
+ return 0; |
+} |
+ |
+int TestExternalRender(VideoRender* renderModule) { |
+ int error = 0; |
+ MyRenderCallback *externalRender = new MyRenderCallback(); |
+ |
+ const int streamId0 = 0; |
+ VideoRenderCallback* renderCallback0 = |
+ renderModule->AddIncomingRenderStream(streamId0, 0, 0.0f, 0.0f, |
+ 1.0f, 1.0f); |
+ assert(renderCallback0 != NULL); |
+ error = renderModule->AddExternalRenderCallback(streamId0, externalRender); |
+ if (error != 0) { |
+ // TODO(phoglund): This test will not work if compiled in release mode. |
+ // This rather silly construct here is to avoid compilation errors when |
+ // compiling in release. Release => no asserts => unused 'error' variable. |
+ assert(false); |
+ } |
+ |
+ error = renderModule->StartRender(streamId0); |
+ assert(error == 0); |
+ |
+ const int width = 352; |
+ const int half_width = (width + 1) / 2; |
+ const int height = 288; |
+ VideoFrame videoFrame0; |
+ videoFrame0.CreateEmptyFrame(width, height, width, half_width, half_width); |
+ |
+ const uint32_t renderDelayMs = 500; |
+ int frameCount = TEST_FRAME_NUM; |
+ for (int i=0; i<frameCount; i++) { |
+ videoFrame0.set_render_time_ms(TickTime::MillisecondTimestamp() + |
+ renderDelayMs); |
+ renderCallback0->RenderFrame(streamId0, videoFrame0); |
+ SleepMs(33); |
+ } |
+ |
+ // Sleep and let all frames be rendered before closing |
+ SleepMs(2*renderDelayMs); |
+ |
+ // Shut down |
+ printf("Closing...\n"); |
+ error = renderModule->StopRender(streamId0); |
+ assert(error == 0); |
+ error = renderModule->DeleteIncomingRenderStream(streamId0); |
+ assert(error == 0); |
+ assert(frameCount == externalRender->_cnt); |
+ |
+ delete externalRender; |
+ externalRender = NULL; |
+ |
+ return 0; |
+} |
+ |
+void RunVideoRenderTests(void* window, VideoRenderType windowType) { |
+ int myId = 12345; |
+ |
+ // Create the render module |
+ printf("Create render module\n"); |
+ VideoRender* renderModule = NULL; |
+ renderModule = VideoRender::CreateVideoRender(myId, |
+ window, |
+ false, |
+ windowType); |
+ assert(renderModule != NULL); |
+ |
+ // ##### Test single stream rendering #### |
+ printf("#### TestSingleStream ####\n"); |
+ if (TestSingleStream(renderModule) != 0) { |
+ printf ("TestSingleStream failed\n"); |
+ } |
+ |
+ // ##### Test fullscreen rendering #### |
+ printf("#### TestFullscreenStream ####\n"); |
+ if (TestFullscreenStream(renderModule, window, windowType) != 0) { |
+ printf ("TestFullscreenStream failed\n"); |
+ } |
+ |
+ // ##### Test bitmap and text #### |
+ printf("#### TestBitmapText ####\n"); |
+ if (TestBitmapText(renderModule) != 0) { |
+ printf ("TestBitmapText failed\n"); |
+ } |
+ |
+ // ##### Test multiple streams #### |
+ printf("#### TestMultipleStreams ####\n"); |
+ if (TestMultipleStreams(renderModule) != 0) { |
+ printf ("TestMultipleStreams failed\n"); |
+ } |
+ |
+ // ##### Test multiple streams #### |
+ printf("#### TestExternalRender ####\n"); |
+ if (TestExternalRender(renderModule) != 0) { |
+ printf ("TestExternalRender failed\n"); |
+ } |
+ |
+ delete renderModule; |
+ renderModule = NULL; |
+ |
+ printf("VideoRender unit tests passed.\n"); |
+} |
+ |
+// Note: The Mac main is implemented in testApi_mac.mm. |
+#if defined(_WIN32) |
+int _tmain(int argc, _TCHAR* argv[]) |
+#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) |
+int main(int argc, char* argv[]) |
+#endif |
+#if !defined(WEBRTC_MAC) && !defined(WEBRTC_ANDROID) |
+{ |
+ // Create a window for testing. |
+ void* window = NULL; |
+#if defined (_WIN32) |
+ HWND testHwnd; |
+ WebRtcCreateWindow(testHwnd, 0, 352, 288); |
+ window = (void*)testHwnd; |
+ VideoRenderType windowType = kRenderWindows; |
+#elif defined(WEBRTC_LINUX) |
+ Window testWindow; |
+ Display* display; |
+ WebRtcCreateWindow(&testWindow, &display, 0, 352, 288); |
+ VideoRenderType windowType = kRenderX11; |
+ window = (void*)testWindow; |
+#endif // WEBRTC_LINUX |
+ |
+ RunVideoRenderTests(window, windowType); |
+ return 0; |
+} |
+#endif // !WEBRTC_MAC |