Added fake camera, rewrote one test to use it.
Wrote a "file capture device" which is a kind of fake capture device. It reads a YUV file from disk and pretends that it is what the "camera" is seeing. This makes is possible to run tests based on video input without having an actual physical camera. This is good because physical cameras are quite unreliable. Rewrote the standard mirrored preview loopback test so it can use the new file capture device. The old "classic" test is preserved. I tried to minimize duplication between the classic test case and the new one, which turned out to be quite painful. There are some rough edges left in in the code. Suggested improvements is to get rid of the error counting mechanism since the code seems to assume that TestError invocations cause hard asserts anyway. The code will segfault for certain errors if the hard asserts doesn't happen, which means the error counting mechanism is unnecessary. This, by the way, could be a problem for the new test since it doesn't cause hard asserts. Fixed comments for the thread wrapper and the external capture device interface. BUG= TEST= Review URL: http://webrtc-codereview.appspot.com/224003 git-svn-id: http://webrtc.googlecode.com/svn/trunk@801 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -21,7 +21,9 @@ namespace webrtc {
|
|||||||
// function.
|
// function.
|
||||||
#define ThreadObj void*
|
#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);
|
typedef bool(*ThreadRunFunction)(ThreadObj);
|
||||||
|
|
||||||
enum ThreadPriority
|
enum ThreadPriority
|
||||||
|
@ -98,9 +98,12 @@ struct ViEVideoFrameI420
|
|||||||
unsigned short height;
|
unsigned short height;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This class declares an abstract interface to be used when using an external
|
// This class declares an abstract interface to be used when implementing
|
||||||
// capture device. The user implemented derived class is registered using
|
// a user-defined capture device. This interface is not meant to be
|
||||||
// AllocateExternalCaptureDevice and is released using ReleaseCaptureDevice.
|
// 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
|
class WEBRTC_DLLEXPORT ViEExternalCapture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "vie_integration_test_base.h"
|
#include "vie_integration_test_base.h"
|
||||||
#include "vie_autotest.h"
|
#include "vie_autotest.h"
|
||||||
|
|
||||||
@ -57,4 +56,5 @@ TEST_F(ViEApiIntegrationTest, RunsRenderTestWithoutErrors) {
|
|||||||
TEST_F(ViEApiIntegrationTest, RunsRtpRtcpTestWithoutErrors) {
|
TEST_F(ViEApiIntegrationTest, RunsRtpRtcpTestWithoutErrors) {
|
||||||
ASSERT_EQ(0, tests_->ViERtpRtcpAPITest());
|
ASSERT_EQ(0, tests_->ViERtpRtcpAPITest());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} // namespace
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "vie_integration_test_base.h"
|
#include "vie_integration_test_base.h"
|
||||||
#include "vie_autotest.h"
|
#include "vie_autotest.h"
|
||||||
|
|
||||||
@ -57,4 +56,5 @@ TEST_F(ViEExtendedIntegrationTest, RunsRenderTestWithoutErrors) {
|
|||||||
TEST_F(ViEExtendedIntegrationTest, RunsRtpRtcpTestWithoutErrors) {
|
TEST_F(ViEExtendedIntegrationTest, RunsRtpRtcpTestWithoutErrors) {
|
||||||
ASSERT_EQ(0, tests_->ViERtpRtcpExtendedTest());
|
ASSERT_EQ(0, tests_->ViERtpRtcpExtendedTest());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} // namespace
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
* to verify any video output - it only checks for direct errors.
|
* to verify any video output - it only checks for direct errors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "gflags/gflags.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "vie_autotest.h"
|
#include "vie_autotest.h"
|
||||||
#include "vie_autotest_window_manager_interface.h"
|
#include "vie_autotest_window_manager_interface.h"
|
||||||
#include "vie_integration_test_base.h"
|
#include "vie_integration_test_base.h"
|
||||||
@ -24,13 +24,45 @@
|
|||||||
|
|
||||||
namespace {
|
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 {
|
class ViEStandardIntegrationTest: public ViEIntegrationTest {
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ViEStandardIntegrationTest, RunsBaseTestWithoutErrors) {
|
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) {
|
TEST_F(ViEStandardIntegrationTest, RunsCaptureTestWithoutErrors) {
|
||||||
ASSERT_EQ(0, tests_->ViECaptureStandardTest());
|
ASSERT_EQ(0, tests_->ViECaptureStandardTest());
|
||||||
}
|
}
|
||||||
@ -62,4 +94,5 @@ TEST_F(ViEStandardIntegrationTest, RunsRenderTestWithoutErrors) {
|
|||||||
TEST_F(ViEStandardIntegrationTest, RunsRtpRctpTestWithoutErrors) {
|
TEST_F(ViEStandardIntegrationTest, RunsRtpRctpTestWithoutErrors) {
|
||||||
ASSERT_EQ(0, tests_->ViERtpRtcpStandardTest());
|
ASSERT_EQ(0, tests_->ViERtpRtcpStandardTest());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} // namespace
|
||||||
|
@ -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_);
|
||||||
|
}
|
@ -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 <cstdio>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#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_
|
@ -60,6 +60,11 @@ public:
|
|||||||
int ViEBaseExtendedTest();
|
int ViEBaseExtendedTest();
|
||||||
int ViEBaseAPITest();
|
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
|
// vie_autotest_capture.cc
|
||||||
int ViECaptureStandardTest();
|
int ViECaptureStandardTest();
|
||||||
int ViECaptureExtendedTest();
|
int ViECaptureExtendedTest();
|
||||||
@ -108,12 +113,16 @@ private:
|
|||||||
// If this operation fails, device_id is assigned a negative value
|
// If this operation fails, device_id is assigned a negative value
|
||||||
// and number_of_errors is incremented.
|
// and number_of_errors is incremented.
|
||||||
void FindCaptureDeviceOnSystem(webrtc::ViECapture* capture,
|
void FindCaptureDeviceOnSystem(webrtc::ViECapture* capture,
|
||||||
WebRtc_UWord8* device_name,
|
unsigned char* device_name,
|
||||||
const unsigned int kDeviceNameLength,
|
const unsigned int kDeviceNameLength,
|
||||||
int* device_id,
|
int* device_id,
|
||||||
int* number_of_errors,
|
int* number_of_errors,
|
||||||
webrtc::VideoCaptureModule** device_video);
|
webrtc::VideoCaptureModule** device_video);
|
||||||
|
|
||||||
|
webrtc::ViERender *RenderInBothWindows(webrtc::VideoEngine * ptrViE,
|
||||||
|
int & numberOfErrors, int captureId,
|
||||||
|
int videoChannel);
|
||||||
|
|
||||||
void PrintAudioCodec(const webrtc::CodecInst audioCodec);
|
void PrintAudioCodec(const webrtc::CodecInst audioCodec);
|
||||||
void PrintVideoCodec(const webrtc::VideoCodec videoCodec);
|
void PrintVideoCodec(const webrtc::VideoCodec videoCodec);
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -11,15 +11,14 @@
|
|||||||
//
|
//
|
||||||
// vie_autotest_linux.cc
|
// vie_autotest_linux.cc
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "vie_autotest_linux.h"
|
#include "vie_autotest_linux.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "gflags/gflags.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
#include "vie_autotest_defines.h"
|
#include "vie_autotest_defines.h"
|
||||||
#include "vie_autotest_main.h"
|
#include "vie_autotest_main.h"
|
||||||
|
|
||||||
#include "engine_configurations.h"
|
#include "engine_configurations.h"
|
||||||
#include "critical_section_wrapper.h"
|
#include "critical_section_wrapper.h"
|
||||||
#include "thread_wrapper.h"
|
#include "thread_wrapper.h"
|
||||||
@ -30,123 +29,131 @@ ViEAutoTestWindowManager::ViEAutoTestWindowManager()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ViEAutoTestWindowManager::~ViEAutoTestWindowManager() {
|
ViEAutoTestWindowManager::~ViEAutoTestWindowManager() {
|
||||||
TerminateWindows();
|
TerminateWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ViEAutoTestWindowManager::GetWindow1() {
|
void* ViEAutoTestWindowManager::GetWindow1() {
|
||||||
return reinterpret_cast<void*>(_hwnd1);
|
return reinterpret_cast<void*>(_hwnd1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ViEAutoTestWindowManager::GetWindow2() {
|
void* ViEAutoTestWindowManager::GetWindow2() {
|
||||||
return reinterpret_cast<void*>(_hwnd2);
|
return reinterpret_cast<void*>(_hwnd2);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ViEAutoTestWindowManager::TerminateWindows() {
|
int ViEAutoTestWindowManager::TerminateWindows() {
|
||||||
if (_hdsp1) {
|
if (_hdsp1) {
|
||||||
ViEDestroyWindow(&_hwnd1, _hdsp1);
|
ViEDestroyWindow(&_hwnd1, _hdsp1);
|
||||||
_hdsp1 = NULL;
|
_hdsp1 = NULL;
|
||||||
}
|
}
|
||||||
if (_hdsp2) {
|
if (_hdsp2) {
|
||||||
ViEDestroyWindow(&_hwnd2, _hdsp2);
|
ViEDestroyWindow(&_hwnd2, _hdsp2);
|
||||||
_hdsp2 = NULL;
|
_hdsp2 = NULL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ViEAutoTestWindowManager::CreateWindows(AutoTestRect window1Size,
|
int ViEAutoTestWindowManager::CreateWindows(AutoTestRect window1Size,
|
||||||
AutoTestRect window2Size,
|
AutoTestRect window2Size,
|
||||||
void* window1Title,
|
void* window1Title,
|
||||||
void* window2Title) {
|
void* window2Title) {
|
||||||
ViECreateWindow(&_hwnd1, &_hdsp1, window1Size.origin.x,
|
ViECreateWindow(&_hwnd1, &_hdsp1, window1Size.origin.x,
|
||||||
window1Size.origin.y, window1Size.size.width,
|
window1Size.origin.y, window1Size.size.width,
|
||||||
window1Size.size.height,
|
window1Size.size.height,
|
||||||
reinterpret_cast<char*>(window1Title));
|
reinterpret_cast<char*>(window1Title));
|
||||||
ViECreateWindow(&_hwnd2, &_hdsp2, window2Size.origin.x,
|
ViECreateWindow(&_hwnd2, &_hdsp2, window2Size.origin.x,
|
||||||
window2Size.origin.y, window2Size.size.width,
|
window2Size.origin.y, window2Size.size.width,
|
||||||
window2Size.size.height,
|
window2Size.size.height,
|
||||||
reinterpret_cast<char*>(window2Title));
|
reinterpret_cast<char*>(window2Title));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ViEAutoTestWindowManager::ViECreateWindow(Window *outWindow,
|
int ViEAutoTestWindowManager::ViECreateWindow(Window *outWindow,
|
||||||
Display **outDisplay, int xpos,
|
Display **outDisplay, int xpos,
|
||||||
int ypos, int width, int height,
|
int ypos, int width, int height,
|
||||||
char* title) {
|
char* title) {
|
||||||
int screen;
|
int screen;
|
||||||
XEvent evnt;
|
XEvent evnt;
|
||||||
XSetWindowAttributes xswa; // window attribute struct
|
XSetWindowAttributes xswa; // window attribute struct
|
||||||
XVisualInfo vinfo; // screen visual info struct
|
XVisualInfo vinfo; // screen visual info struct
|
||||||
unsigned long mask; // attribute mask
|
unsigned long mask; // attribute mask
|
||||||
|
|
||||||
// get connection handle to xserver
|
// get connection handle to xserver
|
||||||
Display* _display = XOpenDisplay(NULL);
|
Display* _display = XOpenDisplay(NULL);
|
||||||
|
|
||||||
// get screen number
|
// get screen number
|
||||||
screen = DefaultScreen(_display);
|
screen = DefaultScreen(_display);
|
||||||
|
|
||||||
// put desired visual info for the screen in vinfo
|
// put desired visual info for the screen in vinfo
|
||||||
// TODO(unknown): more display settings should be allowed
|
// TODO(unknown): more display settings should be allowed
|
||||||
if (XMatchVisualInfo(_display, screen, 24, TrueColor, &vinfo) != 0) {
|
if (XMatchVisualInfo(_display, screen, 24, TrueColor, &vinfo) != 0) {
|
||||||
// printf( "Screen visual info match!\n" );
|
// printf( "Screen visual info match!\n" );
|
||||||
}
|
}
|
||||||
// set window attributes
|
// set window attributes
|
||||||
xswa.colormap = XCreateColormap(_display, DefaultRootWindow(_display),
|
xswa.colormap = XCreateColormap(_display, DefaultRootWindow(_display),
|
||||||
vinfo.visual, AllocNone);
|
vinfo.visual, AllocNone);
|
||||||
xswa.event_mask = StructureNotifyMask | ExposureMask;
|
xswa.event_mask = StructureNotifyMask | ExposureMask;
|
||||||
xswa.background_pixel = 0;
|
xswa.background_pixel = 0;
|
||||||
xswa.border_pixel = 0;
|
xswa.border_pixel = 0;
|
||||||
|
|
||||||
// value mask for attributes
|
// value mask for attributes
|
||||||
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
||||||
|
|
||||||
Window _window = XCreateWindow(_display, DefaultRootWindow(_display), xpos,
|
Window _window = XCreateWindow(_display, DefaultRootWindow(_display), xpos,
|
||||||
ypos, width, height, 0, vinfo.depth,
|
ypos, width, height, 0, vinfo.depth,
|
||||||
InputOutput, vinfo.visual, mask, &xswa);
|
InputOutput, vinfo.visual, mask, &xswa);
|
||||||
|
|
||||||
// Set window name
|
// Set window name
|
||||||
XStoreName(_display, _window, title);
|
XStoreName(_display, _window, title);
|
||||||
XSetIconName(_display, _window, title);
|
XSetIconName(_display, _window, title);
|
||||||
|
|
||||||
// make x report events for mask
|
// make x report events for mask
|
||||||
XSelectInput(_display, _window, StructureNotifyMask);
|
XSelectInput(_display, _window, StructureNotifyMask);
|
||||||
|
|
||||||
// map the window to the display
|
// map the window to the display
|
||||||
XMapWindow(_display, _window);
|
XMapWindow(_display, _window);
|
||||||
|
|
||||||
// wait for map event
|
// wait for map event
|
||||||
do {
|
do {
|
||||||
XNextEvent(_display, &evnt);
|
XNextEvent(_display, &evnt);
|
||||||
} while (evnt.type != MapNotify || evnt.xmap.event != _window);
|
} while (evnt.type != MapNotify || evnt.xmap.event != _window);
|
||||||
|
|
||||||
*outWindow = _window;
|
*outWindow = _window;
|
||||||
*outDisplay = _display;
|
*outDisplay = _display;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ViEAutoTestWindowManager::ViEDestroyWindow(Window *window,
|
int ViEAutoTestWindowManager::ViEDestroyWindow(Window *window,
|
||||||
Display *display) {
|
Display *display) {
|
||||||
XUnmapWindow(display, *window);
|
XUnmapWindow(display, *window);
|
||||||
XDestroyWindow(display, *window);
|
XDestroyWindow(display, *window);
|
||||||
XSync(display, false);
|
XSync(display, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ViEAutoTestWindowManager::SetTopmostWindow() {
|
bool ViEAutoTestWindowManager::SetTopmostWindow() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
// This command-line flag is a transitory solution until we
|
// This command-line flag is a transitory solution until we
|
||||||
// managed to rewrite all tests to GUnit tests. This flag is
|
// manage to rewrite all tests to GUnit tests. This flag is
|
||||||
// currently only supported in Linux.
|
// currently only supported in Linux.
|
||||||
if (argc == 2 && std::string(argv[1]) == "--automated") {
|
if (argc > 1 && std::string(argv[1]) == "--automated") {
|
||||||
testing::InitGoogleTest(&argc, argv);
|
// Let GTest and GFlags handle flags from now on
|
||||||
return RUN_ALL_TESTS();
|
argc -= 1;
|
||||||
}
|
argv += 1;
|
||||||
|
|
||||||
// Default: run in classic interactive mode.
|
// Initialize the testing framework
|
||||||
ViEAutoTestMain autoTest;
|
testing::InitGoogleTest(&argc, argv);
|
||||||
autoTest.UseAnswerFile("answers.txt");
|
// Parse remaining flags:
|
||||||
return autoTest.BeginOSIndependentTesting();
|
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();
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
'<(webrtc_root)/modules/modules.gyp:video_capture_module',
|
'<(webrtc_root)/modules/modules.gyp:video_capture_module',
|
||||||
'<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine_core',
|
'<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine_core',
|
||||||
'<(webrtc_root)/../testing/gtest.gyp:gtest',
|
'<(webrtc_root)/../testing/gtest.gyp:gtest',
|
||||||
|
'<(webrtc_root)/../third_party/google-gflags/google-gflags.gyp:google-gflags',
|
||||||
'video_engine_core',
|
'video_engine_core',
|
||||||
],
|
],
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
@ -44,6 +45,7 @@
|
|||||||
|
|
||||||
# Helper classes
|
# Helper classes
|
||||||
'helpers/vie_window_creator.cc',
|
'helpers/vie_window_creator.cc',
|
||||||
|
'helpers/vie_file_capture_device.cc',
|
||||||
|
|
||||||
# New, fully automated tests
|
# New, fully automated tests
|
||||||
'automated/vie_api_integration_test.cc',
|
'automated/vie_api_integration_test.cc',
|
||||||
|
Reference in New Issue
Block a user