Made it possible to run video_capture tests on mac.

Abstracted out a suitable main from vie_auto_test and put it into testsupport.
Cleaned up unused vie_auto_test mac code.

BUG=

Review URL: https://webrtc-codereview.appspot.com/723004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2572 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
phoglund@webrtc.org 2012-08-08 08:27:46 +00:00
parent 743e5cf6b7
commit 54e22eb977
10 changed files with 169 additions and 500 deletions

View File

@ -142,13 +142,13 @@
'webrtc_utility',
'<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(webrtc_root)/test/test.gyp:test_support_main',
],
'include_dirs': [
'../interface',
],
'sources': [
'../test/video_capture_unittest.cc',
'../test/video_capture_main_mac.mm',
],
'conditions': [
# DEFINE PLATFORM SPECIFIC INCLUDE AND CFLAGS
@ -168,13 +168,23 @@
],
}],
['OS=="mac"', {
'dependencies': [
# Link with a special main for mac so we can use the webcam.
'<(webrtc_root)/test/test.gyp:test_support_main_threaded_mac',
],
'xcode_settings': {
# TODO(andrew): CoreAudio and AudioToolbox shouldn't be needed.
'OTHER_LDFLAGS': [
'-framework Foundation -framework AppKit -framework Cocoa -framework OpenGL -framework CoreVideo -framework CoreAudio -framework AudioToolbox',
],
},
}],
}], # OS=="mac"
['OS!="mac"', {
'dependencies': [
# Otherwise, use the regular main.
'<(webrtc_root)/test/test.gyp:test_support_main',
],
}], # OS!="mac"
] # conditions
},
],

View File

@ -0,0 +1,17 @@
/*
* 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 "gtest/gtest.h"
#include "testsupport/mac/run_threaded_main_mac.h"
int ImplementThisToRunYourTest(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -60,6 +60,23 @@
'run_all_unittests.cc',
],
},
{
# Depend on this target when you want to have test_support and a special
# main for mac which will run your test on a worker thread and consume
# events on the main thread. Useful if you want to access a webcam.
# This main will provide all the scaffolding and objective-c black magic
# for you. All you need to do is to implement a function in the
# run_threaded_main_mac.h file (ImplementThisToRunYourTest).
'target_name': 'test_support_main_threaded_mac',
'type': 'static_library',
'dependencies': [
'test_support',
],
'sources': [
'testsupport/mac/run_threaded_main_mac.h',
'testsupport/mac/run_threaded_main_mac.mm',
],
},
{
'target_name': 'test_support_unittests',
'type': 'executable',

View File

@ -0,0 +1,22 @@
/*
* 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.
*/
/**
* This file and its corresponding .mm file implement a main function on Mac.
* It's useful if you need to access a webcam in your Mac application. The code
* forks a worker thread which runs the below ImplementThisToRunYourTest
* function, and uses the main thread to pump messages. That way we can run our
* code in a regular sequential fashion and still pump events, which are
* necessary to access the webcam for instance.
*/
// Implement this method to do whatever you want to do in the worker thread.
// The argc and argv variables are the unmodified command line from main.
int ImplementThisToRunYourTest(int argc, char** argv);

View File

@ -0,0 +1,90 @@
/*
* 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.
*/
#import "run_threaded_main_mac.h"
#import <Cocoa/Cocoa.h>
// This class passes parameter from main to the worked thread and back.
@interface AutoTestInWorkerThread : NSObject {
int argc_;
char** argv_;
int result_;
bool done_;
}
- (void)setDone:(bool)done;
- (bool)done;
- (void)setArgc:(int)argc argv:(char**)argv;
- (int) result;
- (void)runTest:(NSObject*)ignored;
@end
@implementation AutoTestInWorkerThread
- (void)setDone:(bool)done {
done_ = done;
}
- (bool)done {
return done_;
}
- (void)setArgc:(int)argc argv:(char**)argv {
argc_ = argc;
argv_ = argv;
}
- (void)runTest:(NSObject*)ignored {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
result_ = ImplementThisToRunYourTest(argc_, argv_);
done_ = true;
[pool release];
return;
}
- (int)result {
return result_;
}
@end
int main(int argc, char * argv[]) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
int result = 0;
AutoTestInWorkerThread* tests = [[AutoTestInWorkerThread alloc] init];
[tests setArgc:argc argv:argv];
[tests setDone:false];
[NSThread detachNewThreadSelector:@selector(runTest:)
toTarget:tests
withObject:nil];
NSRunLoop* main_run_loop = [NSRunLoop mainRunLoop];
NSDate *loop_until = [NSDate dateWithTimeIntervalSinceNow:0.1];
bool runloop_ok = true;
while (![tests done] && runloop_ok) {
runloop_ok = [main_run_loop runMode:NSDefaultRunLoopMode
beforeDate:loop_until];
loop_until = [NSDate dateWithTimeIntervalSinceNow:0.1];
}
result = [tests result];
[pool release];
return result;
}

View File

@ -1,63 +0,0 @@
/*
* 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 "EngineConfigurations.h"
#if defined(CARBON_RENDERING)
#ifndef WEBRTC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_INTERFACE_VIE_AUTOTEST_MAC_CARBON_H_
#define WEBRTC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_INTERFACE_VIE_AUTOTEST_MAC_CARBON_H_
#include "vie_autotest_window_manager_interface.h"
// #define HIVIEWREF_MODE 1
#include <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
class ViEAutoTestWindowManager: public ViEAutoTestWindowManagerInterface
{
public:
ViEAutoTestWindowManager();
virtual ~ViEAutoTestWindowManager();
virtual void* GetWindow1();
virtual void* GetWindow2();
virtual int CreateWindows(AutoTestRect window1Size,
AutoTestRect window2Size, char* window1Title,
char* window2Title);
virtual int TerminateWindows();
virtual bool SetTopmostWindow();
// event handler static methods
static pascal OSStatus HandleWindowEvent (EventHandlerCallRef nextHandler,
EventRef theEvent, void* userData);
static pascal OSStatus HandleHIViewEvent (EventHandlerCallRef nextHandler,
EventRef theEvent, void* userData);
private:
WindowRef* _carbonWindow1;
WindowRef* _carbonWindow2;
HIViewRef* _hiView1;
HIViewRef* _hiView2;
EventHandlerRef _carbonWindow1EventHandlerRef;
EventHandlerRef _carbonWindow2EventHandlerRef;
EventHandlerRef _carbonHIView1EventHandlerRef;
EventHandlerRef _carbonHIView2EventHandlerRef;
};
@interface AutoTestClass : NSObject
{
}
-(void)autoTestWithArg:(NSString*)answerFile;
@end
#endif // WEBRTC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_INTERFACE_VIE_AUTOTEST_MAC_CARBON_H_
#endif CARBON_RENDERING

View File

@ -66,20 +66,5 @@ class ViEAutoTestWindowManager: public ViEAutoTestWindowManagerInterface {
TestCocoaUi* cocoa_ui_;
};
@interface AutoTestInWorkerThread : NSObject {
int argc_;
char** argv_;
int result_;
bool done_;
}
- (void)setDone:(bool)done;
- (bool)done;
- (void)setArgc:(int)argc argv:(char**)argv;
- (int) result;
- (void)autoTestWithArg:(NSObject*)ignored;
@end
#endif // WEBRTC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_INTERFACE_VIE_AUTOTEST_MAC_COCOA_H_
#endif // COCOA_RENDERING

View File

@ -1,355 +0,0 @@
/*
* 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 "engine_configurations.h"
#if defined(CARBON_RENDERING)
#include "vie_autotest_mac_carbon.h"
#include "vie_autotest_defines.h"
#include "vie_autotest.h"
#include "vie_autotest_main.h"
ViEAutoTestWindowManager::ViEAutoTestWindowManager() :
_carbonWindow1(new WindowRef()),
_carbonWindow2(new WindowRef()),
_hiView1(new HIViewRef()),
_hiView2(new HIViewRef())
{
}
ViEAutoTestWindowManager::~ViEAutoTestWindowManager()
{
if (_carbonWindow1EventHandlerRef)
RemoveEventHandler(_carbonWindow1EventHandlerRef);
if (_carbonWindow2EventHandlerRef)
RemoveEventHandler(_carbonWindow2EventHandlerRef);
if (_carbonHIView1EventHandlerRef)
RemoveEventHandler(_carbonHIView1EventHandlerRef);
if (_carbonHIView2EventHandlerRef)
RemoveEventHandler(_carbonHIView2EventHandlerRef);
delete _carbonWindow1;
delete _carbonWindow2;
delete _hiView1;
delete _hiView2;
}
int ViEAutoTestWindowManager::CreateWindows(AutoTestRect window1Size,
AutoTestRect window2Size,
char* window1Title,
char* window2Title)
{
WindowAttributes windowAttributes = kWindowStandardDocumentAttributes
| kWindowStandardHandlerAttribute | kWindowCompositingAttribute;
Rect windowContentRect;
static const EventTypeSpec
windowEventTypes[] = { kEventClassWindow, kEventWindowBoundsChanged,
kEventClassWindow, kEventWindowBoundsChanging, kEventClassWindow,
kEventWindowZoomed, kEventClassWindow, kEventWindowExpanded,
kEventClassWindow, kEventWindowClickResizeRgn, kEventClassWindow,
kEventWindowClickDragRgn };
// ************* Window 1 and Event Handler ***********************
SetRect(&windowContentRect, window1Size.origin.x, window1Size.origin.y,
window1Size.origin.x + window1Size.size.width, window1Size.origin.y
+ window1Size.size.height);
CreateNewWindow(kDocumentWindowClass, windowAttributes, &windowContentRect,
_carbonWindow1);
SetWindowTitleWithCFString(*_carbonWindow1, CFSTR("Carbon Window 1"));
ShowWindow(*_carbonWindow1);
InitCursor();
InstallWindowEventHandler(*_carbonWindow1,
NewEventHandlerUPP(HandleWindowEvent),
GetEventTypeCount(windowEventTypes),
windowEventTypes, (void*) this,
&_carbonWindow1EventHandlerRef);
// ************* Window 2 and Event Handler ***********************
SetRect(&windowContentRect, window2Size.origin.x, window2Size.origin.y,
window2Size.origin.x + window2Size.size.width, window2Size.origin.y
+ window2Size.size.height);
CreateNewWindow(kDocumentWindowClass, windowAttributes, &windowContentRect,
_carbonWindow2);
SetWindowTitleWithCFString(*_carbonWindow2, CFSTR("Carbon Window 2"));
ShowWindow(*_carbonWindow2);
InitCursor();
InstallWindowEventHandler(*_carbonWindow2,
NewEventHandlerUPP(HandleWindowEvent),
GetEventTypeCount(windowEventTypes),
windowEventTypes, (void*) this,
&_carbonWindow2EventHandlerRef);
#if defined(HIVIEWREF_MODE)
OSStatus status;
static const EventTypeSpec hiviewEventTypes[] = { kEventClassControl,
kEventControlBoundsChanged, kEventClassControl, kEventControlDraw };
HIRect hiView1Rect = { 10, 10, 200, 200 };
status = HICreateCustomView(&hiView1Rect, &_hiView1);
status = HIViewAddSubview(&_carbonWindow1, _hiView1);
HIViewSetZOrder(_hiView1, kHIViewZOrderAbove, NULL);
HIViewSetVisible(_hiView1, true);
HIViewInstallEventHandler(_hiView1, NewEventHandlerUPP(HandleHIViewEvent),
GetEventTypeCount(hiviewEventTypes),
hiviewEventTypes, (void *) this,
&_carbonHIView1EventHandlerRef);
HIRect hiView2Rect = { 10, 10, 200, 200 };
status = HICreateCustomView(&hiView2Rect, &_hiView2);
status = HIViewAddSubview(&_carbonWindow2, _hiView2);
HIViewSetZOrder(_hiView2, kHIViewZOrderAbove, NULL);
HIViewSetVisible(_hiView2, true);
HIViewInstallEventHandler(_hiView2, NewEventHandlerUPP(HandleHIViewEvent),
GetEventTypeCount(hiviewEventTypes),
hiviewEventTypes, (void *) this,
&_carbonHIView2EventHandlerRef);
#endif
return 0;
}
pascal OSStatus ViEAutoTestWindowManager::HandleWindowEvent(
EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
{
WindowRef windowRef = NULL;
int eventType = GetEventKind(theEvent);
// see https://dcs.sourcerepo.com/dcs/tox_view/trunk/tox/libraries/
// i686-win32/include/quicktime/CarbonEvents.h for a list of codes
GetEventParameter(theEvent, kEventParamDirectObject, typeWindowRef, NULL,
sizeof(WindowRef), NULL, &windowRef);
ViEAutoTestWindowManager* obj = (ViEAutoTestWindowManager*) (userData);
if (windowRef == obj->GetWindow1())
{
// event was triggered on window 1
}
else if (windowRef == obj->GetWindow2())
{
// event was triggered on window 2
}
if (kEventWindowBoundsChanged == eventType)
{
}
else if (kEventWindowBoundsChanging == eventType)
{
}
else if (kEventWindowZoomed == eventType)
{
}
else if (kEventWindowExpanding == eventType)
{
}
else if (kEventWindowExpanded == eventType)
{
}
else if (kEventWindowClickResizeRgn == eventType)
{
}
else if (kEventWindowClickDragRgn == eventType)
{
}
else
{
}
return noErr;
}
pascal OSStatus ViEAutoTestWindowManager::HandleHIViewEvent(
EventHandlerCallRef nextHandler, EventRef theEvent, void* userData)
{
HIViewRef hiviewRef = NULL;
// see https://dcs.sourcerepo.com/dcs/tox_view/trunk/tox/libraries/
// i686-win32/include/quicktime/CarbonEvents.h for a list of codes
int eventType = GetEventKind(theEvent);
OSStatus status = noErr;
status = GetEventParameter(theEvent, kEventParamDirectObject,
typeControlRef, NULL, sizeof(ControlRef), NULL,
&hiviewRef);
if (GetEventClass(theEvent) == kEventClassControl)
{
if (GetEventKind(theEvent) == kEventControlDraw)
{
ViEAutoTestWindowManager* obj =
(ViEAutoTestWindowManager*) (userData);
CGContextRef context;
status = GetEventParameter(theEvent, kEventParamCGContextRef,
typeCGContextRef, NULL, sizeof(context),
NULL, &context);
HIRect viewBounds;
HIViewRef* ptrHIViewRef =
static_cast<HIViewRef*> (obj->GetWindow1());
if (hiviewRef == *ptrHIViewRef)
{
// color hiview1
CGContextSetRGBFillColor(context, 1, 0, 0, 1);
HIViewGetBounds(hiviewRef, &viewBounds);
CGContextFillRect(context, viewBounds);
}
ptrHIViewRef = static_cast<HIViewRef*> (obj->GetWindow1());
if (hiviewRef == *ptrHIViewRef)
{
CGContextSetRGBFillColor(context, 0, 1, 0, 1);
HIViewGetBounds(hiviewRef, &viewBounds);
CGContextFillRect(context, viewBounds);
}
}
}
/*
VideoRenderAGL* obj = (VideoRenderAGL*)(userData);
WindowRef parentWindow = HIViewGetWindow(hiviewRef);
bool updateUI = true;
if(kEventControlBoundsChanged == eventType){
}
else if(kEventControlDraw == eventType){
}
else{
updateUI = false;
}
if(true == updateUI){
obj->ParentWindowResized(parentWindow);
obj->UpdateClipping();
obj->RenderOffScreenBuffers();
}
*/
return status;
}
int ViEAutoTestWindowManager::TerminateWindows()
{
return 0;
}
void* ViEAutoTestWindowManager::GetWindow1()
{
#if defined(HIVIEWREF_MODE)
return (void*)_hiView1;
#else
return (void*) _carbonWindow1;
#endif
}
void* ViEAutoTestWindowManager::GetWindow2()
{
#if defined(HIVIEWREF_MODE)
return (void*)_hiView2;
#else
return (void*) _carbonWindow2;
#endif
}
bool ViEAutoTestWindowManager::SetTopmostWindow()
{
return true;
}
/*
int main (int argc, const char * argv[])
{
ViEAutoTestMain autoTest;
if(argc > 1){
autoTest.UseAnswerFile(argv[1]);
}
int success = autoTest.BeginOSIndependentTesting();
}
*/
int main(int argc, const char * argv[])
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
// We have to run the test in a secondary thread because we need to run a
// runloop, which blocks.
if (argc > 1)
{
AutoTestClass * autoTestClass = [[AutoTestClass alloc]init];
[NSThread detachNewThreadSelector:@selector(autoTestWithArg:)
toTarget:autoTestClass withObject:[NSString stringWithFormat:@"%s",
argv[1]]];
}
else
{
AutoTestClass* autoTestClass = [[AutoTestClass alloc]init];
[NSThread detachNewThreadSelector:@selector(autoTestWithArg:)
toTarget:autoTestClass withObject:nil];
}
// process OS events. Blocking call
[[NSRunLoop currentRunLoop]run];
[pool release];
}
@implementation AutoTestClass
-(void)autoTestWithArg:(NSString*)answerFile;
{
// TODO(phoglund): Rewrite this file to work with the new way of running
// vie_auto_test. The file doesn't seem to be used at the moment though.
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
ViEAutoTestMain autoTest;
if(NSOrderedSame != [answerFile compare:@""])
{
char answerFileUTF8[1024] = "";
strcpy(answerFileUTF8, (char*)[answerFileUTF8 UTF8]);
autoTest.UseAnswerFile(answerFileUTF8);
}
int success = autoTest.BeginOSIndependentTesting();
[pool release];
return;
}
// TODO: move window creation to Obj-c class so GUI commands can be run on the
// main NSThread
// -(void)createWindow1:(AutoTestRect)window1Size
// AndWindow2:(AutoTestRect)window2Size WithTitle1:(char*)window1Title
// AndTitle2:(char*)window2Title{
@end
#endif

View File

@ -10,8 +10,9 @@
#include "engine_configurations.h"
#if defined(COCOA_RENDERING)
#import "cocoa_render_view.h"
#import "testsupport/mac/run_threaded_main_mac.h"
#include "video_engine/test/auto_test/interface/vie_autotest_main.h"
#include "vie_autotest_mac_cocoa.h"
#include "vie_autotest_defines.h"
#include "vie_autotest.h"
@ -131,67 +132,10 @@ bool ViEAutoTestWindowManager::SetTopmostWindow() {
return true;
}
int main(int argc, char * argv[]) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
int result = 0;
AutoTestInWorkerThread* tests = [[AutoTestInWorkerThread alloc] init];
[tests setArgc:argc argv:argv];
[tests setDone:false];
[NSThread detachNewThreadSelector:@selector(autoTestWithArg:)
toTarget:tests
withObject:nil];
NSRunLoop* main_run_loop = [NSRunLoop mainRunLoop];
NSDate *loop_until = [NSDate dateWithTimeIntervalSinceNow:0.1];
bool runloop_ok = true;
while (![tests done] && runloop_ok) {
runloop_ok = [main_run_loop runMode:NSDefaultRunLoopMode
beforeDate:loop_until];
loop_until = [NSDate dateWithTimeIntervalSinceNow:0.1];
}
result = [tests result];
[pool release];
return result;
// This is acts as our "main" for mac. The actual (reusable) main is defined in
// testsupport/mac/run_threaded_main_mac.mm.
int ImplementThisToRunYourTest(int argc, char** argv) {
ViEAutoTestMain auto_test;
return auto_test.RunTests(argc, argv);
}
@implementation AutoTestInWorkerThread
- (void)setDone:(bool)done {
done_ = done;
}
- (bool)done {
return done_;
}
- (void)setArgc:(int)argc argv:(char**)argv {
argc_ = argc;
argv_ = argv;
}
- (void)autoTestWithArg:(NSObject*)ignored {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
ViEAutoTestMain auto_test;
result_ = auto_test.RunTests(argc_, argv_);
done_ = true;
[pool release];
return;
}
- (int)result {
return result_;
}
@end
#endif

View File

@ -37,7 +37,6 @@
'interface/vie_autotest.h',
'interface/vie_autotest_defines.h',
'interface/vie_autotest_linux.h',
'interface/vie_autotest_mac_carbon.h',
'interface/vie_autotest_mac_cocoa.h',
'interface/vie_autotest_main.h',
'interface/vie_autotest_window_manager_interface.h',
@ -92,7 +91,6 @@
'source/vie_window_manager_factory_linux.cc',
# Mac
'source/vie_autotest_cocoa_mac.mm',
'source/vie_autotest_carbon_mac.cc',
'source/vie_window_manager_factory_mac.mm',
# Windows
'source/vie_autotest_win.cc',
@ -114,6 +112,10 @@
],
}],
['OS=="mac"', {
'dependencies': [
# Use a special main for mac so we can access the webcam.
'<(webrtc_root)/test/test.gyp:test_support_main_threaded_mac',
],
'xcode_settings': {
'OTHER_LDFLAGS': [
'-framework Foundation -framework AppKit -framework Cocoa -framework OpenGL -framework CoreVideo -framework CoreAudio -framework AudioToolbox',