diff --git a/src/system_wrappers/interface/thread_wrapper.h b/src/system_wrappers/interface/thread_wrapper.h index eccf3c2399..72a06e8bdd 100644 --- a/src/system_wrappers/interface/thread_wrapper.h +++ b/src/system_wrappers/interface/thread_wrapper.h @@ -21,7 +21,9 @@ namespace webrtc { // function. #define ThreadObj void* -// Callback function that the spawned thread will enter once spawned +// Callback function that the spawned thread will enter once spawned. +// A return value of false is interpreted as that the function has no +// more work to do and that the thread can be released. typedef bool(*ThreadRunFunction)(ThreadObj); enum ThreadPriority diff --git a/src/video_engine/main/interface/vie_capture.h b/src/video_engine/main/interface/vie_capture.h index 8ed47c929e..7c7d14a76b 100644 --- a/src/video_engine/main/interface/vie_capture.h +++ b/src/video_engine/main/interface/vie_capture.h @@ -98,9 +98,12 @@ struct ViEVideoFrameI420 unsigned short height; }; -// This class declares an abstract interface to be used when using an external -// capture device. The user implemented derived class is registered using -// AllocateExternalCaptureDevice and is released using ReleaseCaptureDevice. +// This class declares an abstract interface to be used when implementing +// a user-defined capture device. This interface is not meant to be +// implemented by the user. Instead, the user should call AllocateCaptureDevice +// in the ViECapture interface, which will create a suitable implementation. +// The user should then call IncomingFrame in this interface to deliver +// captured frames to the system. class WEBRTC_DLLEXPORT ViEExternalCapture { public: diff --git a/src/video_engine/main/test/AutoTest/automated/vie_api_integration_test.cc b/src/video_engine/main/test/AutoTest/automated/vie_api_integration_test.cc index 1db4f04b5b..08160940f5 100644 --- a/src/video_engine/main/test/AutoTest/automated/vie_api_integration_test.cc +++ b/src/video_engine/main/test/AutoTest/automated/vie_api_integration_test.cc @@ -13,7 +13,6 @@ */ #include "gtest/gtest.h" - #include "vie_integration_test_base.h" #include "vie_autotest.h" @@ -57,4 +56,5 @@ TEST_F(ViEApiIntegrationTest, RunsRenderTestWithoutErrors) { TEST_F(ViEApiIntegrationTest, RunsRtpRtcpTestWithoutErrors) { ASSERT_EQ(0, tests_->ViERtpRtcpAPITest()); } -} + +} // namespace diff --git a/src/video_engine/main/test/AutoTest/automated/vie_extended_integration_test.cc b/src/video_engine/main/test/AutoTest/automated/vie_extended_integration_test.cc index b1b5e87627..6a84d7ca23 100644 --- a/src/video_engine/main/test/AutoTest/automated/vie_extended_integration_test.cc +++ b/src/video_engine/main/test/AutoTest/automated/vie_extended_integration_test.cc @@ -13,7 +13,6 @@ */ #include "gtest/gtest.h" - #include "vie_integration_test_base.h" #include "vie_autotest.h" @@ -57,4 +56,5 @@ TEST_F(ViEExtendedIntegrationTest, RunsRenderTestWithoutErrors) { TEST_F(ViEExtendedIntegrationTest, RunsRtpRtcpTestWithoutErrors) { ASSERT_EQ(0, tests_->ViERtpRtcpExtendedTest()); } -} + +} // namespace diff --git a/src/video_engine/main/test/AutoTest/automated/vie_standard_integration_test.cc b/src/video_engine/main/test/AutoTest/automated/vie_standard_integration_test.cc index 0611e1ebf2..5ce3e59541 100644 --- a/src/video_engine/main/test/AutoTest/automated/vie_standard_integration_test.cc +++ b/src/video_engine/main/test/AutoTest/automated/vie_standard_integration_test.cc @@ -15,8 +15,8 @@ * to verify any video output - it only checks for direct errors. */ +#include "gflags/gflags.h" #include "gtest/gtest.h" - #include "vie_autotest.h" #include "vie_autotest_window_manager_interface.h" #include "vie_integration_test_base.h" @@ -24,13 +24,45 @@ namespace { +// Define flag validators for our flags: +static bool ValidatePath(const char* flag_name, const std::string& value) { + return !value.empty(); +} + +static bool ValidateDimension(const char* flag_name, WebRtc_Word32 value) { + if (value <= 0) { + return false; + } + return true; +} + +// Define the flags themselves: +DEFINE_string(i420_test_video_path, "", "Path to an i420-coded raw video file" + " to use for the test. This file is fed into the fake camera" + " and will therefore be what the camera 'sees'."); +static const bool dummy1 = + google::RegisterFlagValidator(&FLAGS_i420_test_video_path, + &ValidatePath); + +DEFINE_int32(i420_test_video_width, 0, "The width of the provided video."); +static const bool dummy2 = + google::RegisterFlagValidator(&FLAGS_i420_test_video_width, + &ValidateDimension); +DEFINE_int32(i420_test_video_height, 0, "The height of the provided video."); +static const bool dummy3 = + google::RegisterFlagValidator(&FLAGS_i420_test_video_height, + &ValidateDimension); + class ViEStandardIntegrationTest: public ViEIntegrationTest { }; TEST_F(ViEStandardIntegrationTest, RunsBaseTestWithoutErrors) { - ASSERT_EQ(0, tests_->ViEBaseStandardTest()); + tests_->ViEAutomatedBaseStandardTest(FLAGS_i420_test_video_path, + FLAGS_i420_test_video_width, + FLAGS_i420_test_video_height); } +// These tests still require a physical camera: TEST_F(ViEStandardIntegrationTest, RunsCaptureTestWithoutErrors) { ASSERT_EQ(0, tests_->ViECaptureStandardTest()); } @@ -62,4 +94,5 @@ TEST_F(ViEStandardIntegrationTest, RunsRenderTestWithoutErrors) { TEST_F(ViEStandardIntegrationTest, RunsRtpRctpTestWithoutErrors) { ASSERT_EQ(0, tests_->ViERtpRtcpStandardTest()); } -} + +} // namespace diff --git a/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.cc b/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.cc new file mode 100644 index 0000000000..00e6657aba --- /dev/null +++ b/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.cc @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2011 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 "vie_file_capture_device.h" + +#include "common_types.h" +#include "critical_section_wrapper.h" +#include "event_wrapper.h" +#include "module_common_types.h" +#include "vie_autotest_defines.h" +#include "vie_capture.h" +#include "tick_util.h" + +// This class ensures we are not exceeding the max FPS. +class FramePacemaker { + public: + explicit FramePacemaker(uint32_t max_fps) + : time_per_frame_ms_(1000 / max_fps) { + frame_start_ = webrtc::TickTime::MillisecondTimestamp(); + } + + void SleepIfNecessary(webrtc::EventWrapper* sleeper) { + uint64_t now = webrtc::TickTime::MillisecondTimestamp(); + if (now - frame_start_ < time_per_frame_ms_) { + sleeper->Wait(time_per_frame_ms_ - (now - frame_start_)); + } + } + + private: + uint64_t frame_start_; + uint64_t time_per_frame_ms_; +}; + +ViEFileCaptureDevice::ViEFileCaptureDevice( + webrtc::ViEExternalCapture* input_sink) + : input_sink_(input_sink), + input_file_(NULL) { + mutex_ = webrtc::CriticalSectionWrapper::CreateCriticalSection(); +} + +ViEFileCaptureDevice::~ViEFileCaptureDevice() { + delete mutex_; +} + +bool ViEFileCaptureDevice::OpenI420File(const std::string& path, + int width, + int height) { + webrtc::CriticalSectionScoped cs(*mutex_); + assert(input_file_ == NULL); + + input_file_ = std::fopen(path.c_str(), "rb"); + if (input_file_ == NULL) { + return false; + } + + frame_length_ = 3 * width * height / 2; + width_ = width; + height_ = height; + return true; +} + +void ViEFileCaptureDevice::ReadFileFor(uint64_t time_slice_ms, + uint32_t max_fps) { + webrtc::CriticalSectionScoped cs(*mutex_); + assert(input_file_ != NULL); + + webrtc::VideoFrame sourceFrame; + sourceFrame.VerifyAndAllocate(frame_length_); + unsigned char* frame_buffer = new unsigned char[frame_length_]; + + webrtc::EventWrapper* sleeper = webrtc::EventWrapper::Create(); + + uint64_t start_time_ms = webrtc::TickTime::MillisecondTimestamp(); + uint64_t elapsed_ms = 0; + + while (elapsed_ms < time_slice_ms) { + FramePacemaker pacemaker(max_fps); + std::fread(frame_buffer, 1, frame_length_, input_file_); + + if (std::feof(input_file_)) { + std::rewind(input_file_); + } + input_sink_->IncomingFrame(frame_buffer, frame_length_, width_, + height_, webrtc::kVideoI420, + webrtc::TickTime::MillisecondTimestamp()); + + pacemaker.SleepIfNecessary(sleeper); + elapsed_ms = webrtc::TickTime::MillisecondTimestamp() - start_time_ms; + } + + delete sleeper; + delete[] frame_buffer; +} + +void ViEFileCaptureDevice::CloseFile() { + webrtc::CriticalSectionScoped cs(*mutex_); + assert(input_file_ != NULL); + + std::fclose(input_file_); +} diff --git a/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.h b/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.h new file mode 100644 index 0000000000..b00076759a --- /dev/null +++ b/src/video_engine/main/test/AutoTest/helpers/vie_file_capture_device.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 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. + */ + +#ifndef SRC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_HELPERS_VIE_FILE_CAPTURE_DEVICE_H_ +#define SRC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_HELPERS_VIE_FILE_CAPTURE_DEVICE_H_ + +#include + +#include + +#include "typedefs.h" + +namespace webrtc { +class CriticalSectionWrapper; +class EventWrapper; +class ViEExternalCapture; +} + +/** + * This class opens a i420 file and feeds it into a ExternalCapture instance, + * thereby acting as a faked capture device with deterministic input. + */ +class ViEFileCaptureDevice { + public: + // The input sink is where to send the I420 video frames. + explicit ViEFileCaptureDevice(webrtc::ViEExternalCapture* input_sink); + virtual ~ViEFileCaptureDevice(); + + // Opens the provided I420 file and interprets it according to the provided + // width and height. Returns false if the file doesn't exist. + bool OpenI420File(const std::string& path, int width, int height); + + // Reads the previously opened file for at most time_slice_ms milliseconds, + // after which it will return. It will make sure to sleep accordingly so we + // do not send more than max_fps cap (we may send less, though). + void ReadFileFor(uint64_t time_slice_ms, uint32_t max_fps); + + // Closes the opened input file. + void CloseFile(); + + private: + webrtc::ViEExternalCapture* input_sink_; + + std::FILE* input_file_; + webrtc::CriticalSectionWrapper* mutex_; + + WebRtc_UWord32 frame_length_; + WebRtc_UWord8* frame_buffer_; + WebRtc_UWord32 width_; + WebRtc_UWord32 height_; +}; + +#endif // SRC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_HELPERS_VIE_FILE_CAPTURE_DEVICE_H_ diff --git a/src/video_engine/main/test/AutoTest/interface/vie_autotest.h b/src/video_engine/main/test/AutoTest/interface/vie_autotest.h index 0c189fc45f..62723551c1 100644 --- a/src/video_engine/main/test/AutoTest/interface/vie_autotest.h +++ b/src/video_engine/main/test/AutoTest/interface/vie_autotest.h @@ -60,6 +60,11 @@ public: int ViEBaseExtendedTest(); int ViEBaseAPITest(); + // This is a variant of the base standard test, meant to run in GTest. + void ViEAutomatedBaseStandardTest(const std::string& pathToTestI420Video, + int width, + int height); + // vie_autotest_capture.cc int ViECaptureStandardTest(); int ViECaptureExtendedTest(); @@ -108,12 +113,16 @@ private: // If this operation fails, device_id is assigned a negative value // and number_of_errors is incremented. void FindCaptureDeviceOnSystem(webrtc::ViECapture* capture, - WebRtc_UWord8* device_name, + unsigned char* device_name, const unsigned int kDeviceNameLength, int* device_id, int* number_of_errors, webrtc::VideoCaptureModule** device_video); + webrtc::ViERender *RenderInBothWindows(webrtc::VideoEngine * ptrViE, + int & numberOfErrors, int captureId, + int videoChannel); + void PrintAudioCodec(const webrtc::CodecInst audioCodec); void PrintVideoCodec(const webrtc::VideoCodec videoCodec); diff --git a/src/video_engine/main/test/AutoTest/source/vie_autotest_base.cc b/src/video_engine/main/test/AutoTest/source/vie_autotest_base.cc index cf7c4c124d..2486f1d527 100644 --- a/src/video_engine/main/test/AutoTest/source/vie_autotest_base.cc +++ b/src/video_engine/main/test/AutoTest/source/vie_autotest_base.cc @@ -12,11 +12,13 @@ // vie_autotest_base.cc // -#include "vie_autotest.h" +#include "gtest/gtest.h" +#include "thread_wrapper.h" +#include "vie_autotest.h" #include "vie_autotest_defines.h" -#include "engine_configurations.h" #include "video_capture_factory.h" +#include "vie_file_capture_device.h" class BaseObserver : public webrtc::ViEBaseObserver { public: @@ -29,302 +31,362 @@ class BaseObserver : public webrtc::ViEBaseObserver { unsigned int cpu_load_; }; -int ViEAutoTest::ViEBaseStandardTest() { - ViETest::Log(" "); - ViETest::Log("========================================"); - ViETest::Log(" ViEBase Standard Test"); - - // *************************************************************** - // Begin create/initialize WebRTC Video Engine for testing - // *************************************************************** - - int error = 0; - int numberOfErrors = 0; - - ViETest::Log("Starting a loopback call..."); - - webrtc::VideoEngine* ptrViE = NULL; - ptrViE = webrtc::VideoEngine::Create(); - numberOfErrors += ViETest::TestError(ptrViE != NULL, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); +webrtc::VideoEngine *InitializeVideoEngine(int & numberOfErrors) { + ViETest::Log("Starting a loopback call..."); + webrtc::VideoEngine *ptrViE = webrtc::VideoEngine::Create(); + numberOfErrors += ViETest::TestError(ptrViE != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); #ifdef WEBRTC_ANDROID - error = ptrViE->SetTraceFile("/sdcard/ViEBaseStandardTest_trace.txt"); - numberOfErrors += ViETest::TestError(error == 0, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); + int error = ptrViE->SetTraceFile("/sdcard/ViEBaseStandardTest_trace.txt"); + numberOfErrors += ViETest::TestError(error == 0, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); #else - error = ptrViE->SetTraceFile("ViEBaseStandardTest_trace.txt"); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + int error = ptrViE->SetTraceFile("ViEBaseStandardTest_trace.txt"); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); #endif - webrtc::ViEBase *ptrViEBase = webrtc::ViEBase::GetInterface(ptrViE); - numberOfErrors += ViETest::TestError(ptrViEBase != NULL, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - error = ptrViEBase->Init(); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + return ptrViE; +} + +webrtc::ViEBase *InitializeViEBase(webrtc::VideoEngine * ptrViE, + int & numberOfErrors) { + webrtc::ViEBase *ptrViEBase = webrtc::ViEBase::GetInterface(ptrViE); + numberOfErrors += ViETest::TestError(ptrViEBase != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + int error = ptrViEBase->Init(); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + return ptrViEBase; +} + +webrtc::ViECapture *InitializeChannel(webrtc::ViEBase * ptrViEBase, + int & videoChannel, + int & numberOfErrors, + webrtc::VideoEngine * ptrViE) { + int error = ptrViEBase->CreateChannel(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + + webrtc::ViECapture *ptrViECapture = webrtc::ViECapture::GetInterface(ptrViE); + numberOfErrors += ViETest::TestError(ptrViECapture != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + return ptrViECapture; +} + +void ConnectCaptureDevice(webrtc::ViECapture * ptrViECapture, + int captureId, + int videoChannel, + int & numberOfErrors) { + int error = ptrViECapture->ConnectCaptureDevice(captureId, videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); +} + +webrtc::ViERTP_RTCP *ConfigureRtpRtcp(webrtc::VideoEngine * ptrViE, + int & numberOfErrors, + int videoChannel) { + webrtc::ViERTP_RTCP *ptrViERtpRtcp = + webrtc::ViERTP_RTCP::GetInterface(ptrViE); + numberOfErrors += ViETest::TestError(ptrViE != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + int error = ptrViERtpRtcp-> + SetRTCPStatus(videoChannel, webrtc::kRtcpCompound_RFC4585); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERtpRtcp-> + SetKeyFrameRequestMethod(videoChannel, + webrtc::kViEKeyFrameRequestPliRtcp); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERtpRtcp->SetTMMBRStatus(videoChannel, true); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + return ptrViERtpRtcp; +} + +webrtc::ViERender *ViEAutoTest::RenderInBothWindows( + webrtc::VideoEngine * ptrViE, int & numberOfErrors, + int captureId, int videoChannel) { + webrtc::ViERender *ptrViERender = webrtc::ViERender::GetInterface(ptrViE); + numberOfErrors += ViETest::TestError(ptrViERender != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + int error = ptrViERender->RegisterVideoRenderModule(*_vrm1); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERender->AddRenderer(captureId, _window1, 0, 0.0, + 0.0, 1.0, 1.0); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERender->StartRender(captureId); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERender->RegisterVideoRenderModule(*_vrm2); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERender->AddRenderer(videoChannel, _window2, 1, 0.0, + 0.0, 1.0, 1.0); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERender->StartRender(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + return ptrViERender; +} + +webrtc::ViENetwork *TestCallSetup(webrtc::ViECodec * ptrViECodec, + int & numberOfErrors, + int videoChannel, + webrtc::VideoEngine * ptrViE, + webrtc::ViEBase * ptrViEBase, + const WebRtc_UWord8 *deviceName) { + int error; + webrtc::VideoCodec videoCodec; + memset(&videoCodec, 0, sizeof(webrtc::VideoCodec)); + for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++) { + error = ptrViECodec->GetCodec(idx, videoCodec); + numberOfErrors += ViETest::TestError(error == 0, + "ERROR: %s at line %d", __FUNCTION__, __LINE__); - // *************************************************************** - // Engine ready. Begin testing class - // *************************************************************** - int videoChannel = -1; - error = ptrViEBase->CreateChannel(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - webrtc::ViECapture *ptrViECapture = - webrtc::ViECapture::GetInterface(ptrViE); - numberOfErrors += ViETest::TestError(ptrViECapture != NULL, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - - webrtc::VideoCaptureModule* vcpm(NULL); - const unsigned int KMaxDeviceNameLength = 128; - WebRtc_UWord8 deviceName[KMaxDeviceNameLength]; - memset(deviceName, 0, KMaxDeviceNameLength); - - int captureId; - - FindCaptureDeviceOnSystem(ptrViECapture, - deviceName, - KMaxDeviceNameLength, - &captureId, - &numberOfErrors, - &vcpm); - - error = ptrViECapture->ConnectCaptureDevice(captureId, videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViECapture->StartCapture(captureId); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - webrtc::ViERTP_RTCP *ptrViERtpRtcp = - webrtc::ViERTP_RTCP::GetInterface(ptrViE); - numberOfErrors += ViETest::TestError(ptrViE != NULL, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - error = ptrViERtpRtcp->SetRTCPStatus(videoChannel, - webrtc::kRtcpCompound_RFC4585); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViERtpRtcp-> - SetKeyFrameRequestMethod(videoChannel, - webrtc::kViEKeyFrameRequestPliRtcp); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViERtpRtcp->SetTMMBRStatus(videoChannel, true); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - webrtc::ViERender *ptrViERender = webrtc::ViERender::GetInterface(ptrViE); - numberOfErrors += ViETest::TestError(ptrViERender != NULL, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - error = ptrViERender->RegisterVideoRenderModule(*_vrm1); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViERender->AddRenderer(captureId, _window1, 0, 0.0, - 0.0, 1.0, 1.0); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViERender->StartRender(captureId); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViERender->RegisterVideoRenderModule(*_vrm2); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViERender->AddRenderer(videoChannel, _window2, 1, 0.0, 0.0, - 1.0, 1.0); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViERender->StartRender(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - webrtc::ViECodec *ptrViECodec = webrtc::ViECodec::GetInterface(ptrViE); - numberOfErrors += ViETest::TestError(ptrViECodec != NULL, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - webrtc::VideoCodec videoCodec; - memset(&videoCodec, 0, sizeof(webrtc::VideoCodec)); - for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++) { - error = ptrViECodec->GetCodec(idx, videoCodec); - numberOfErrors += ViETest::TestError(error == 0, - "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - // try to keep the test frame size small when I420 - if (videoCodec.codecType == webrtc::kVideoCodecI420) { - videoCodec.width = 176; - videoCodec.height = 144; - error = ptrViECodec->SetSendCodec(videoChannel, videoCodec); - numberOfErrors += ViETest::TestError(error == 0, - "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - } - - error = ptrViECodec->SetReceiveCodec(videoChannel, videoCodec); - numberOfErrors += ViETest::TestError(error == 0, - "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - } - webrtc::ViENetwork *ptrViENetwork = - webrtc::ViENetwork::GetInterface(ptrViE); - numberOfErrors += ViETest::TestError(ptrViENetwork != NULL, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - char version[1024] = ""; - error = ptrViEBase->GetVersion(version); - ViETest::Log("\nUsing WebRTC Video Engine version: %s", version); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - const char *ipAddress = "127.0.0.1"; - unsigned short rtpPortListen = 6000; - unsigned short rtpPortSend = 6000; - rtpPortListen = 6100; - rtpPortSend = 6100; - error = ptrViENetwork->SetLocalReceiver(videoChannel, rtpPortListen); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViEBase->StartReceive(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViENetwork->SetSendDestination(videoChannel, - ipAddress, rtpPortSend); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViEBase->StartSend(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - error = ptrViERender->MirrorRenderStream(captureId, true, false, true); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - // Call started - ViETest::Log("Call started"); - ViETest::Log( - "You should see a mirrored local preview from camera %s" - " in window 1 and the remote video in window 2.", deviceName); - - // *************************************************************** - // Finished initializing engine. Begin testing - // *************************************************************** - - AutoTestSleep(KAutoTestSleepTimeMs); - - // *************************************************************** - // Testing finished. Tear down Video Engine - // *************************************************************** - - // Shut down - error = ptrViEBase->StopReceive(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - error = ptrViERender->StopRender(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - error = ptrViERender->RemoveRenderer(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - error = ptrViERender->DeRegisterVideoRenderModule(*_vrm2); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - int remainingInterfaces = 0; - - error = ptrViEBase->StopSend(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - error = ptrViERender->RemoveRenderer(captureId); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - error = ptrViERender->DeRegisterVideoRenderModule(*_vrm1); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - error = ptrViECapture->StopCapture(captureId); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - error = ptrViECapture->DisconnectCaptureDevice(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - error = ptrViECapture->ReleaseCaptureDevice(captureId); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - vcpm->Release(); - vcpm = NULL; - - remainingInterfaces = ptrViECapture->Release(); - numberOfErrors += ViETest::TestError(remainingInterfaces == 0, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - - error = ptrViEBase->DeleteChannel(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - - remainingInterfaces = ptrViECodec->Release(); - numberOfErrors += ViETest::TestError(remainingInterfaces == 0, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - - remainingInterfaces = ptrViERtpRtcp->Release(); - numberOfErrors += ViETest::TestError(remainingInterfaces == 0, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - - remainingInterfaces = ptrViERender->Release(); - numberOfErrors += ViETest::TestError(remainingInterfaces == 0, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - - remainingInterfaces = ptrViENetwork->Release(); - numberOfErrors += ViETest::TestError(remainingInterfaces == 0, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - - remainingInterfaces = ptrViEBase->Release(); - numberOfErrors += ViETest::TestError(remainingInterfaces == 0, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - - bool deleted = webrtc::VideoEngine::Delete(ptrViE); - numberOfErrors += ViETest::TestError(deleted == true, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - - if (numberOfErrors > 0) { - // Test failed - ViETest::Log(" "); - ViETest::Log(" ERROR ViEBase Standard Test FAILED!"); - ViETest::Log(" Number of errors: %d", numberOfErrors); - ViETest::Log("========================================"); - ViETest::Log(" "); - return numberOfErrors; + // try to keep the test frame size small when I420 + if (videoCodec.codecType == webrtc::kVideoCodecI420) { + videoCodec.width = 176; + videoCodec.height = 144; + error = ptrViECodec->SetSendCodec(videoChannel, videoCodec); + numberOfErrors += ViETest::TestError(error == 0, + "ERROR: %s at line %d", + __FUNCTION__, __LINE__); } + error = ptrViECodec->SetReceiveCodec(videoChannel, videoCodec); + numberOfErrors += ViETest::TestError(error == 0, + "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + } + webrtc::ViENetwork *ptrViENetwork = + webrtc::ViENetwork::GetInterface(ptrViE); + numberOfErrors += ViETest::TestError(ptrViENetwork != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + char version[1024] = ""; + error = ptrViEBase->GetVersion(version); + ViETest::Log("\nUsing WebRTC Video Engine version: %s", version); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + const char *ipAddress = "127.0.0.1"; + WebRtc_UWord16 rtpPortListen = 6000; + WebRtc_UWord16 rtpPortSend = 6000; + rtpPortListen = 6100; + rtpPortSend = 6100; + error = ptrViENetwork->SetLocalReceiver(videoChannel, rtpPortListen); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViEBase->StartReceive(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViENetwork->SetSendDestination(videoChannel, ipAddress, + rtpPortSend); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViEBase->StartSend(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + + // Call started + ViETest::Log("Call started"); + ViETest::Log("You should see a local preview from camera %s" + " in window 1 and the remote video in window 2.", deviceName); + return ptrViENetwork; +} + +void StopEverything(webrtc::ViEBase * ptrViEBase, + int videoChannel, + int & numberOfErrors, + webrtc::ViERender * ptrViERender, + int captureId, + webrtc::ViECapture * ptrViECapture, + webrtc::VideoRender* vrm1, + webrtc::VideoRender* vrm2) { + int error = ptrViEBase->StopReceive(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERender->StopRender(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERender->RemoveRenderer(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERender->DeRegisterVideoRenderModule(*vrm2); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViEBase->StopSend(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERender->RemoveRenderer(captureId); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViERender->DeRegisterVideoRenderModule(*vrm1); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViECapture->DisconnectCaptureDevice(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + error = ptrViECapture->ReleaseCaptureDevice(captureId); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); +} + +void ReleaseEverything(webrtc::ViECapture *ptrViECapture, + int& numberOfErrors, + webrtc::ViEBase *ptrViEBase, + int videoChannel, + webrtc::ViECodec *ptrViECodec, + webrtc::ViERTP_RTCP *ptrViERtpRtcp, + webrtc::ViERender *ptrViERender, + webrtc::ViENetwork *ptrViENetwork, + webrtc::VideoEngine *ptrViE) { + int remainingInterfaces = ptrViECapture->Release(); + numberOfErrors += ViETest::TestError(remainingInterfaces == 0, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + int error2 = ptrViEBase->DeleteChannel(videoChannel); + numberOfErrors += ViETest::TestError(error2 == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + remainingInterfaces = ptrViECodec->Release(); + numberOfErrors += ViETest::TestError(remainingInterfaces == 0, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + remainingInterfaces = ptrViERtpRtcp->Release(); + numberOfErrors += ViETest::TestError(remainingInterfaces == 0, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + remainingInterfaces = ptrViERender->Release(); + numberOfErrors += ViETest::TestError(remainingInterfaces == 0, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + remainingInterfaces = ptrViENetwork->Release(); + numberOfErrors += ViETest::TestError(remainingInterfaces == 0, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + remainingInterfaces = ptrViEBase->Release(); + numberOfErrors += ViETest::TestError(remainingInterfaces == 0, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + bool deleted = webrtc::VideoEngine::Delete(ptrViE); + numberOfErrors += ViETest::TestError(deleted == true, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); +} + +int ViEAutoTest::ViEBaseStandardTest() { + ViETest::Log(" "); + ViETest::Log("========================================"); + ViETest::Log(" ViEBase Standard Test"); + + // *************************************************************** + // Begin create/initialize WebRTC Video Engine for testing + // *************************************************************** + + int numberOfErrors = 0; + + webrtc::VideoEngine* ptrViE = InitializeVideoEngine(numberOfErrors); + webrtc::ViEBase *ptrViEBase = InitializeViEBase(ptrViE, numberOfErrors); + + // *************************************************************** + // Engine ready. Set up the test case: + // *************************************************************** + int videoChannel = -1; + webrtc::ViECapture *ptrViECapture = + InitializeChannel(ptrViEBase, videoChannel, numberOfErrors, ptrViE); + + webrtc::VideoCaptureModule* vcpm(NULL); + const unsigned int kMaxDeviceNameLength = 128; + WebRtc_UWord8 deviceName[kMaxDeviceNameLength]; + memset(deviceName, 0, kMaxDeviceNameLength); + int captureId; + + FindCaptureDeviceOnSystem(ptrViECapture, + deviceName, + kMaxDeviceNameLength, + &captureId, + &numberOfErrors, + &vcpm); + + ConnectCaptureDevice(ptrViECapture, captureId, videoChannel, numberOfErrors); + int error = ptrViECapture->StartCapture(captureId); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + + webrtc::ViERTP_RTCP *ptrViERtpRtcp = + ConfigureRtpRtcp(ptrViE, numberOfErrors, videoChannel); + webrtc::ViERender *ptrViERender = + RenderInBothWindows(ptrViE, numberOfErrors, captureId, videoChannel); + + webrtc::ViECodec *ptrViECodec = webrtc::ViECodec::GetInterface(ptrViE); + numberOfErrors += ViETest::TestError(ptrViECodec != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + + // *************************************************************** + // Set up the call and wait. + // *************************************************************** + + webrtc::ViENetwork *ptrViENetwork = + TestCallSetup(ptrViECodec, numberOfErrors, videoChannel, + ptrViE, ptrViEBase, deviceName); + + AutoTestSleep(KAutoTestSleepTimeMs); + + // *************************************************************** + // Testing finished. Tear down Video Engine + // *************************************************************** + + error = ptrViECapture->StopCapture(captureId); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + + StopEverything(ptrViEBase, videoChannel, numberOfErrors, ptrViERender, + captureId, ptrViECapture, _vrm1, _vrm2); + + vcpm->Release(); + vcpm = NULL; + + ReleaseEverything(ptrViECapture, numberOfErrors, ptrViEBase, videoChannel, + ptrViECodec, ptrViERtpRtcp, ptrViERender, ptrViENetwork, + ptrViE); + + if (numberOfErrors > 0) { + // Test failed ViETest::Log(" "); - ViETest::Log(" ViEBase Standard Test PASSED!"); + ViETest::Log(" ERROR ViEBase Standard Test FAILED!"); + ViETest::Log(" Number of errors: %d", numberOfErrors); ViETest::Log("========================================"); ViETest::Log(" "); - return 0; + return numberOfErrors; + } + + ViETest::Log(" "); + ViETest::Log(" ViEBase Standard Test PASSED!"); + ViETest::Log("========================================"); + ViETest::Log(" "); + return 0; } int ViEAutoTest::ViEBaseExtendedTest() { - // Start with standard test - ViEBaseAPITest(); - ViEBaseStandardTest(); + // Start with standard test + ViEBaseAPITest(); + ViEBaseStandardTest(); - ViETest::Log(" "); - ViETest::Log("========================================"); - ViETest::Log(" ViEBase Extended Test"); + ViETest::Log(" "); + ViETest::Log("========================================"); + ViETest::Log(" ViEBase Extended Test"); // *************************************************************** // Test BaseObserver @@ -349,190 +411,277 @@ int ViEAutoTest::ViEBaseExtendedTest() { ViETest::Log("========================================"); ViETest::Log(" "); - return 0; + return 0; } int ViEAutoTest::ViEBaseAPITest() { - ViETest::Log(" "); - ViETest::Log("========================================"); - ViETest::Log(" ViEBase API Test"); + ViETest::Log(" "); + ViETest::Log("========================================"); + ViETest::Log(" ViEBase API Test"); - // *************************************************************** - // Begin create/initialize WebRTC Video Engine for testing - // *************************************************************** + // *************************************************************** + // Begin create/initialize WebRTC Video Engine for testing + // *************************************************************** + int error = 0; + int numberOfErrors = 0; - int error = 0; - int numberOfErrors = 0; + webrtc::VideoEngine* ptrViE = NULL; + webrtc::ViEBase* ptrViEBase = NULL; - webrtc::VideoEngine* ptrViE = NULL; - webrtc::ViEBase* ptrViEBase = NULL; + // Get the ViEBase API + ptrViEBase = webrtc::ViEBase::GetInterface(ptrViE); + numberOfErrors += ViETest::TestError(ptrViEBase == NULL); - // Get the ViEBase API - ptrViEBase = webrtc::ViEBase::GetInterface(ptrViE); - numberOfErrors += ViETest::TestError(ptrViEBase == NULL); - - ptrViE = webrtc::VideoEngine::Create(); - numberOfErrors += ViETest::TestError(ptrViE != NULL, "VideoEngine::Create"); + ptrViE = webrtc::VideoEngine::Create(); + numberOfErrors += ViETest::TestError(ptrViE != NULL, "VideoEngine::Create"); #ifdef WEBRTC_ANDROID - error = ptrViE->SetTraceFile("/sdcard/WebRTC/ViEBaseAPI_trace.txt"); - numberOfErrors += ViETest::TestError(error == 0, "SetTraceFile error"); + error = ptrViE->SetTraceFile("/sdcard/WebRTC/ViEBaseAPI_trace.txt"); + numberOfErrors += ViETest::TestError(error == 0, "SetTraceFile error"); #else - error = ptrViE->SetTraceFile("ViEBaseAPI_trace.txt"); - numberOfErrors += ViETest::TestError(error == 0, "SetTraceFile error"); + error = ptrViE->SetTraceFile("ViEBaseAPI_trace.txt"); + numberOfErrors += ViETest::TestError(error == 0, "SetTraceFile error"); #endif - ptrViEBase = webrtc::ViEBase::GetInterface(ptrViE); - numberOfErrors += ViETest::TestError(ptrViEBase != NULL); + ptrViEBase = webrtc::ViEBase::GetInterface(ptrViE); + numberOfErrors += ViETest::TestError(ptrViEBase != NULL); - // *************************************************************** - // Engine ready. Begin testing class - // *************************************************************** + // *************************************************************** + // Engine ready. Begin testing class + // *************************************************************** - char version[1024] = ""; - error = ptrViEBase->GetVersion(version); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + char version[1024] = ""; + error = ptrViEBase->GetVersion(version); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - error = ptrViEBase->LastError(); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + error = ptrViEBase->LastError(); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - // Create without init - int videoChannel = -1; - error = ptrViEBase->CreateChannel(videoChannel); - numberOfErrors += ViETest::TestError(error != 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + // Create without init + int videoChannel = -1; + error = ptrViEBase->CreateChannel(videoChannel); + numberOfErrors += ViETest::TestError(error != 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - error = ptrViEBase->Init(); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + error = ptrViEBase->Init(); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - error = ptrViEBase->CreateChannel(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + error = ptrViEBase->CreateChannel(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - int videoChannel2 = -1; - error = ptrViEBase->CreateChannel(videoChannel2); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); - numberOfErrors += ViETest::TestError(videoChannel != videoChannel2, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); + int videoChannel2 = -1; + error = ptrViEBase->CreateChannel(videoChannel2); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + numberOfErrors += ViETest::TestError(videoChannel != videoChannel2, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); - error = ptrViEBase->DeleteChannel(videoChannel2); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + error = ptrViEBase->DeleteChannel(videoChannel2); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - // Channel doesn't exist - error = ptrViEBase->CreateChannel(videoChannel2, videoChannel + 1); - numberOfErrors += ViETest::TestError(error == -1, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + // Channel doesn't exist + error = ptrViEBase->CreateChannel(videoChannel2, videoChannel + 1); + numberOfErrors += ViETest::TestError(error == -1, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - // Channel doesn't exist - error = ptrViEBase->CreateChannel(videoChannel2, videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + // Channel doesn't exist + error = ptrViEBase->CreateChannel(videoChannel2, videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - // VoiceEngine - webrtc::VoiceEngine* ptrVoE = NULL; - webrtc::VoEBase* ptrVoEBase = NULL; - int audioChannel = -1; + // VoiceEngine + webrtc::VoiceEngine* ptrVoE = NULL; + webrtc::VoEBase* ptrVoEBase = NULL; + int audioChannel = -1; - ptrVoE = webrtc::VoiceEngine::Create(); - numberOfErrors += ViETest::TestError(ptrVoE != NULL, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); + ptrVoE = webrtc::VoiceEngine::Create(); + numberOfErrors += ViETest::TestError(ptrVoE != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); - ptrVoEBase = webrtc::VoEBase::GetInterface(ptrVoE); - numberOfErrors += ViETest::TestError(ptrVoEBase != NULL, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); + ptrVoEBase = webrtc::VoEBase::GetInterface(ptrVoE); + numberOfErrors += ViETest::TestError(ptrVoEBase != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); - error = ptrVoEBase->Init(); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + error = ptrVoEBase->Init(); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - audioChannel = ptrVoEBase->CreateChannel(); - numberOfErrors += ViETest::TestError(audioChannel != -1, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); + audioChannel = ptrVoEBase->CreateChannel(); + numberOfErrors += ViETest::TestError(audioChannel != -1, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); - // Connect before setting VoE - error = ptrViEBase->ConnectAudioChannel(videoChannel, audioChannel); - numberOfErrors += ViETest::TestError(error != 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + // Connect before setting VoE + error = ptrViEBase->ConnectAudioChannel(videoChannel, audioChannel); + numberOfErrors += ViETest::TestError(error != 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - error = ptrViEBase->SetVoiceEngine(ptrVoE); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + error = ptrViEBase->SetVoiceEngine(ptrVoE); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - error = ptrViEBase->ConnectAudioChannel(videoChannel, audioChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + error = ptrViEBase->ConnectAudioChannel(videoChannel, audioChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - // *************************************************************** - // Testing finished. Tear down Video Engine - // *************************************************************** + // *************************************************************** + // Testing finished. Tear down Video Engine + // *************************************************************** + error = ptrViEBase->DisconnectAudioChannel(videoChannel + 5); + numberOfErrors += ViETest::TestError(error != 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - error = ptrViEBase->DisconnectAudioChannel(videoChannel + 5); - numberOfErrors += ViETest::TestError(error != 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + error = ptrViEBase->DisconnectAudioChannel(videoChannel); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - error = ptrViEBase->DisconnectAudioChannel(videoChannel); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + error = ptrViEBase->SetVoiceEngine(NULL); + numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); - error = ptrViEBase->SetVoiceEngine(NULL); - numberOfErrors += ViETest::TestError(error == 0, "ERROR: %s at line %d", - __FUNCTION__, __LINE__); + webrtc::ViEBase* ptrViEBase2 = webrtc::ViEBase::GetInterface(ptrViE); + numberOfErrors += ViETest::TestError(ptrViEBase2 != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); - webrtc::ViEBase* ptrViEBase2 = webrtc::ViEBase::GetInterface(ptrViE); - numberOfErrors += ViETest::TestError(ptrViEBase2 != NULL, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); + int remainingInterfaces = ptrViEBase->Release(); + numberOfErrors += ViETest::TestError(remainingInterfaces == 1, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); - int remainingInterfaces = ptrViEBase->Release(); - numberOfErrors += ViETest::TestError(remainingInterfaces == 1, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); + bool vieDeleted = webrtc::VideoEngine::Delete(ptrViE); + numberOfErrors += ViETest::TestError(vieDeleted == false, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); - bool vieDeleted = webrtc::VideoEngine::Delete(ptrViE); - numberOfErrors += ViETest::TestError(vieDeleted == false, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); + remainingInterfaces = ptrViEBase->Release(); + numberOfErrors += ViETest::TestError(remainingInterfaces == 0, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); - remainingInterfaces = ptrViEBase->Release(); - numberOfErrors += ViETest::TestError(remainingInterfaces == 0, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - - vieDeleted = webrtc::VideoEngine::Delete(ptrViE); - numberOfErrors += ViETest::TestError(vieDeleted == true, - "ERROR: %s at line %d", __FUNCTION__, - __LINE__); - - if (numberOfErrors > 0) { - ViETest::Log(" "); - ViETest::Log(" ERROR ViEBase API Test FAILED! "); - ViETest::Log(" Number of errors: %d", numberOfErrors); - ViETest::Log("========================================"); - ViETest::Log(" "); - - return numberOfErrors; - } + vieDeleted = webrtc::VideoEngine::Delete(ptrViE); + numberOfErrors += ViETest::TestError(vieDeleted == true, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + if (numberOfErrors > 0) { ViETest::Log(" "); - ViETest::Log(" ViEBase API Test PASSED!"); + ViETest::Log(" ERROR ViEBase API Test FAILED! "); + ViETest::Log(" Number of errors: %d", numberOfErrors); ViETest::Log("========================================"); ViETest::Log(" "); - return 0; + return numberOfErrors; + } + + ViETest::Log(" "); + ViETest::Log(" ViEBase API Test PASSED!"); + ViETest::Log("========================================"); + ViETest::Log(" "); + + return 0; +} + +// This callback gets used in the automated test case below: +bool StreamVideoFileRepeatedlyIntoCaptureDevice(void* data) { + ViEFileCaptureDevice* file_capture_device = + reinterpret_cast(data); + + WebRtc_UWord64 time_slice_ms = 1500; + WebRtc_UWord64 max_fps = 30; + file_capture_device->ReadFileFor(time_slice_ms, max_fps); + + return true; +} + +void ViEAutoTest::ViEAutomatedBaseStandardTest( + const std::string& pathToTestI420Video, int width, int height) { + int ignoredNumberOfErrors; + + // Initialize the test: + webrtc::VideoEngine* ptrViE = + InitializeVideoEngine(ignoredNumberOfErrors); + webrtc::ViEBase *ptrViEBase = + InitializeViEBase(ptrViE, ignoredNumberOfErrors); + + int videoChannel = -1; + webrtc::ViECapture *ptrViECapture = + InitializeChannel(ptrViEBase, videoChannel, + ignoredNumberOfErrors, ptrViE); + + int captureId; + webrtc::ViEExternalCapture* externalCapture; + int error = ptrViECapture->AllocateExternalCaptureDevice(captureId, + externalCapture); + ViETest::TestError(error == 0, "ERROR: %s at line %d", + __FUNCTION__, __LINE__); + + ViEFileCaptureDevice capturer(externalCapture); + if (!capturer.OpenI420File(pathToTestI420Video, width, height)) { + // No point in continuing if we have no proper video source + ViETest::TestError(false, "ERROR: %s at line %d: " + "Could not open input video %s: aborting test...", + __FUNCTION__, __LINE__, pathToTestI420Video.c_str()); + return; + } + + // Set up a thread which runs the fake camera. Note that the capturer is + // handed off to the other thread - it should not be touched in this + // method until the other thread is stopped! + webrtc::ThreadWrapper* thread = webrtc::ThreadWrapper::CreateThread( + StreamVideoFileRepeatedlyIntoCaptureDevice, &capturer); + unsigned int id; + thread->Start(id); + + // Apparently, we need to connect external capture devices, but we should + // not start them since the external device is not a proper device. + ConnectCaptureDevice(ptrViECapture, captureId, videoChannel, + ignoredNumberOfErrors); + + webrtc::ViERTP_RTCP *ptrViERtpRtcp = + ConfigureRtpRtcp(ptrViE, ignoredNumberOfErrors, videoChannel); + webrtc::ViERender *ptrViERender = + RenderInBothWindows(ptrViE, ignoredNumberOfErrors, + captureId, videoChannel); + + webrtc::ViECodec *ptrViECodec = webrtc::ViECodec::GetInterface(ptrViE); + ignoredNumberOfErrors += + ViETest::TestError(ptrViECodec != NULL, + "ERROR: %s at line %d", __FUNCTION__, + __LINE__); + + // Run the test itself: + const WebRtc_UWord8* deviceName = + reinterpret_cast("Fake Capture Device"); + webrtc::ViENetwork *ptrViENetwork = + TestCallSetup(ptrViECodec, ignoredNumberOfErrors, videoChannel, + ptrViE, ptrViEBase, deviceName); + + AutoTestSleep(KAutoTestSleepTimeMs); + + // Done, clean up + thread->Stop(); + capturer.CloseFile(); + + StopEverything(ptrViEBase, videoChannel, ignoredNumberOfErrors, ptrViERender, + captureId, ptrViECapture, _vrm1, _vrm2); + + ReleaseEverything(ptrViECapture, ignoredNumberOfErrors, ptrViEBase, + videoChannel, ptrViECodec, ptrViERtpRtcp, ptrViERender, + ptrViENetwork, ptrViE); } void ViEAutoTest::FindCaptureDeviceOnSystem( webrtc::ViECapture* capture, - WebRtc_UWord8* device_name, + unsigned char* device_name, unsigned int device_name_length, int* device_id, int* number_of_errors, diff --git a/src/video_engine/main/test/AutoTest/source/vie_autotest_linux.cc b/src/video_engine/main/test/AutoTest/source/vie_autotest_linux.cc index c6625bbf55..7670694a76 100644 --- a/src/video_engine/main/test/AutoTest/source/vie_autotest_linux.cc +++ b/src/video_engine/main/test/AutoTest/source/vie_autotest_linux.cc @@ -11,15 +11,14 @@ // // vie_autotest_linux.cc // - -#include "gtest/gtest.h" -#include - #include "vie_autotest_linux.h" +#include + +#include "gflags/gflags.h" +#include "gtest/gtest.h" #include "vie_autotest_defines.h" #include "vie_autotest_main.h" - #include "engine_configurations.h" #include "critical_section_wrapper.h" #include "thread_wrapper.h" @@ -30,123 +29,131 @@ ViEAutoTestWindowManager::ViEAutoTestWindowManager() } ViEAutoTestWindowManager::~ViEAutoTestWindowManager() { - TerminateWindows(); + TerminateWindows(); } void* ViEAutoTestWindowManager::GetWindow1() { - return reinterpret_cast(_hwnd1); + return reinterpret_cast(_hwnd1); } void* ViEAutoTestWindowManager::GetWindow2() { - return reinterpret_cast(_hwnd2); + return reinterpret_cast(_hwnd2); } int ViEAutoTestWindowManager::TerminateWindows() { - if (_hdsp1) { - ViEDestroyWindow(&_hwnd1, _hdsp1); - _hdsp1 = NULL; - } - if (_hdsp2) { - ViEDestroyWindow(&_hwnd2, _hdsp2); - _hdsp2 = NULL; - } - return 0; + if (_hdsp1) { + ViEDestroyWindow(&_hwnd1, _hdsp1); + _hdsp1 = NULL; + } + if (_hdsp2) { + ViEDestroyWindow(&_hwnd2, _hdsp2); + _hdsp2 = NULL; + } + return 0; } int ViEAutoTestWindowManager::CreateWindows(AutoTestRect window1Size, AutoTestRect window2Size, void* window1Title, void* window2Title) { - ViECreateWindow(&_hwnd1, &_hdsp1, window1Size.origin.x, - window1Size.origin.y, window1Size.size.width, - window1Size.size.height, - reinterpret_cast(window1Title)); - ViECreateWindow(&_hwnd2, &_hdsp2, window2Size.origin.x, - window2Size.origin.y, window2Size.size.width, - window2Size.size.height, - reinterpret_cast(window2Title)); + ViECreateWindow(&_hwnd1, &_hdsp1, window1Size.origin.x, + window1Size.origin.y, window1Size.size.width, + window1Size.size.height, + reinterpret_cast(window1Title)); + ViECreateWindow(&_hwnd2, &_hdsp2, window2Size.origin.x, + window2Size.origin.y, window2Size.size.width, + window2Size.size.height, + reinterpret_cast(window2Title)); - return 0; + return 0; } int ViEAutoTestWindowManager::ViECreateWindow(Window *outWindow, Display **outDisplay, int xpos, int ypos, int width, int height, char* title) { - int screen; - XEvent evnt; - XSetWindowAttributes xswa; // window attribute struct - XVisualInfo vinfo; // screen visual info struct - unsigned long mask; // attribute mask + int screen; + 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 connection handle to xserver + Display* _display = XOpenDisplay(NULL); - // get screen number - screen = DefaultScreen(_display); + // get screen number + screen = DefaultScreen(_display); - // put desired visual info for the screen in vinfo - // TODO(unknown): more display settings should be allowed - 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; + // put desired visual info for the screen in vinfo + // TODO(unknown): more display settings should be allowed + 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; + // value mask for attributes + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - Window _window = XCreateWindow(_display, DefaultRootWindow(_display), xpos, - ypos, width, height, 0, vinfo.depth, - InputOutput, vinfo.visual, mask, &xswa); + Window _window = XCreateWindow(_display, DefaultRootWindow(_display), xpos, + ypos, width, height, 0, vinfo.depth, + InputOutput, vinfo.visual, mask, &xswa); - // Set window name - XStoreName(_display, _window, title); - XSetIconName(_display, _window, title); + // Set window name + XStoreName(_display, _window, title); + XSetIconName(_display, _window, title); - // make x report events for mask - XSelectInput(_display, _window, StructureNotifyMask); + // make x report events for mask + XSelectInput(_display, _window, StructureNotifyMask); - // map the window to the display - XMapWindow(_display, _window); + // 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); + // wait for map event + do { + XNextEvent(_display, &evnt); + } while (evnt.type != MapNotify || evnt.xmap.event != _window); - *outWindow = _window; - *outDisplay = _display; - return 0; + *outWindow = _window; + *outDisplay = _display; + return 0; } int ViEAutoTestWindowManager::ViEDestroyWindow(Window *window, Display *display) { - XUnmapWindow(display, *window); - XDestroyWindow(display, *window); - XSync(display, false); - return 0; + XUnmapWindow(display, *window); + XDestroyWindow(display, *window); + XSync(display, false); + return 0; } bool ViEAutoTestWindowManager::SetTopmostWindow() { - return 0; + return 0; } int main(int argc, char** argv) { - // This command-line flag is a transitory solution until we - // managed to rewrite all tests to GUnit tests. This flag is - // currently only supported in Linux. - if (argc == 2 && std::string(argv[1]) == "--automated") { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); - } + // This command-line flag is a transitory solution until we + // manage to rewrite all tests to GUnit tests. This flag is + // currently only supported in Linux. + if (argc > 1 && std::string(argv[1]) == "--automated") { + // Let GTest and GFlags handle flags from now on + argc -= 1; + argv += 1; - // Default: run in classic interactive mode. - ViEAutoTestMain autoTest; - autoTest.UseAnswerFile("answers.txt"); - return autoTest.BeginOSIndependentTesting(); + // Initialize the testing framework + testing::InitGoogleTest(&argc, argv); + // Parse remaining flags: + google::ParseCommandLineFlags(&argc, &argv, true); + // Run tests + return RUN_ALL_TESTS(); + } + + // Default: run in classic interactive mode. + ViEAutoTestMain autoTest; + autoTest.UseAnswerFile("answers.txt"); + return autoTest.BeginOSIndependentTesting(); } diff --git a/src/video_engine/main/test/AutoTest/vie_auto_test.gypi b/src/video_engine/main/test/AutoTest/vie_auto_test.gypi index a7e5af754f..2634c97338 100644 --- a/src/video_engine/main/test/AutoTest/vie_auto_test.gypi +++ b/src/video_engine/main/test/AutoTest/vie_auto_test.gypi @@ -17,6 +17,7 @@ '<(webrtc_root)/modules/modules.gyp:video_capture_module', '<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine_core', '<(webrtc_root)/../testing/gtest.gyp:gtest', + '<(webrtc_root)/../third_party/google-gflags/google-gflags.gyp:google-gflags', 'video_engine_core', ], 'include_dirs': [ @@ -44,6 +45,7 @@ # Helper classes 'helpers/vie_window_creator.cc', + 'helpers/vie_file_capture_device.cc', # New, fully automated tests 'automated/vie_api_integration_test.cc',