mediastreamer2_tester_windows.cpp 8.24 KB
Newer Older
Ghislain MARY's avatar
Ghislain MARY committed
1
#include <string>
2
#include <collection.h>
Ghislain MARY's avatar
Ghislain MARY committed
3 4

#include "mediastreamer2_tester_windows.h"
5
#include "mswinrtvid.h"
Ghislain MARY's avatar
Ghislain MARY committed
6 7 8

using namespace ms2_tester_runtime_component;
using namespace Platform;
9
using namespace Platform::Collections;
Ghislain MARY's avatar
Ghislain MARY committed
10
using namespace Windows::Foundation;
Ghislain MARY's avatar
Ghislain MARY committed
11
using namespace Windows::Storage;
Ghislain MARY's avatar
Ghislain MARY committed
12
using namespace Windows::System::Threading;
13
using namespace Windows::UI::ViewManagement;
Ghislain MARY's avatar
Ghislain MARY committed
14

15
#define MAX_TRACE_SIZE		2048
Ghislain MARY's avatar
Ghislain MARY committed
16 17
#define MAX_SUITE_NAME_SIZE	128
#define MAX_WRITABLE_DIR_SIZE 1024
18 19
#define MAX_FILEPATH_SIZE	2048
#define MAX_DEVICE_NAME_SIZE 256
Ghislain MARY's avatar
Ghislain MARY committed
20 21 22

static OutputTraceListener^ sTraceListener;

Ghislain MARY's avatar
Ghislain MARY committed
23 24
MS2Tester^ MS2Tester::_instance = ref new MS2Tester();

Ghislain MARY's avatar
Ghislain MARY committed
25 26
static void nativeOutputTraceHandler(int lev, const char *fmt, va_list args)
{
27 28 29 30 31
	wchar_t wstr[MAX_TRACE_SIZE];
	std::string str;
	str.resize(MAX_TRACE_SIZE);
	vsnprintf((char *)str.c_str(), MAX_TRACE_SIZE, fmt, args);
	mbstowcs(wstr, str.c_str(), MAX_TRACE_SIZE - 1);
Ghislain MARY's avatar
Ghislain MARY committed
32 33
	if (sTraceListener) {
		String^ msg = ref new String(wstr);
Ghislain MARY's avatar
Ghislain MARY committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
		String^ l;
		switch (lev) {
		case ORTP_FATAL:
		case ORTP_ERROR:
			l = ref new String(L"Error");
			break;
		case ORTP_WARNING:
			l = ref new String(L"Warning");
			break;
		case ORTP_MESSAGE:
			l = ref new String(L"Message");
			break;
		default:
			l = ref new String(L"Debug");
			break;
		}
		sTraceListener->outputTrace(l, msg);
Ghislain MARY's avatar
Ghislain MARY committed
51
	}
52 53
	OutputDebugStringW(wstr);
	OutputDebugStringW(L"\n");
Ghislain MARY's avatar
Ghislain MARY committed
54 55
}

Ghislain MARY's avatar
Ghislain MARY committed
56
static void ms2NativeOutputTraceHandler(OrtpLogLevel lev, const char *fmt, va_list args)
Ghislain MARY's avatar
Ghislain MARY committed
57 58 59 60 61 62
{
	nativeOutputTraceHandler((int)lev, fmt, args);
}


MS2Tester::MS2Tester()
63
	: _deviceRotation(0)
Ghislain MARY's avatar
Ghislain MARY committed
64
{
65
	mediastreamer2_tester_before_all(nativeOutputTraceHandler);
Ghislain MARY's avatar
Ghislain MARY committed
66 67 68 69 70 71 72 73
	bc_tester_set_resource_dir_prefix("Assets");
}

MS2Tester::~MS2Tester()
{
	mediastreamer2_tester_uninit();
}

74 75 76 77 78 79 80 81
void MS2Tester::setWritableDirectory(StorageFolder^ folder)
{
	char writable_dir[MAX_WRITABLE_DIR_SIZE] = { 0 };
	const wchar_t *wwritable_dir = folder->Path->Data();
	wcstombs(writable_dir, wwritable_dir, sizeof(writable_dir));
	bc_tester_set_writable_dir_prefix(writable_dir);
}

Ghislain MARY's avatar
Ghislain MARY committed
82 83 84 85 86
void MS2Tester::setOutputTraceListener(OutputTraceListener^ traceListener)
{
	sTraceListener = traceListener;
}

Ghislain MARY's avatar
Ghislain MARY committed
87 88 89 90 91 92 93 94 95 96 97
void MS2Tester::init(bool verbose)
{
	if (verbose) {
		ortp_set_log_level_mask(ORTP_MESSAGE | ORTP_WARNING | ORTP_ERROR | ORTP_FATAL);
	}
	else {
		ortp_set_log_level_mask(ORTP_ERROR | ORTP_FATAL);
	}
}

bool MS2Tester::run(Platform::String^ suiteName, Platform::String^ caseName, Platform::Boolean verbose)
Ghislain MARY's avatar
Ghislain MARY committed
98 99 100 101 102 103 104 105 106
{
	std::wstring all(L"ALL");
	std::wstring wssuitename = suiteName->Data();
	std::wstring wscasename = caseName->Data();
	char csuitename[MAX_SUITE_NAME_SIZE] = { 0 };
	char ccasename[MAX_SUITE_NAME_SIZE] = { 0 };
	wcstombs(csuitename, wssuitename.c_str(), sizeof(csuitename));
	wcstombs(ccasename, wscasename.c_str(), sizeof(ccasename));

Ghislain MARY's avatar
Ghislain MARY committed
107 108 109 110
	init(verbose);
	ortp_set_log_handler(ms2NativeOutputTraceHandler);
	return bc_tester_run_tests(wssuitename == all ? 0 : csuitename, wscasename == all ? 0 : ccasename) != 0;
}
Ghislain MARY's avatar
Ghislain MARY committed
111

Ghislain MARY's avatar
Ghislain MARY committed
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
void MS2Tester::runAllToXml()
{
	auto workItem = ref new WorkItemHandler([this](IAsyncAction ^workItem) {
		char *xmlFile = bc_tester_file("MS2Windows10.xml");
		char *logFile = bc_tester_file("MS2Windows10.log");
		char *args[] = { "--xml-file", xmlFile };
		bc_tester_parse_args(2, args, 0);
		init(true);
		FILE *f = fopen(logFile, "w");
		ortp_set_log_file(f);
		bc_tester_start();
		bc_tester_uninit();
		fclose(f);
		free(xmlFile);
		free(logFile);
	});
	_asyncAction = ThreadPool::RunAsync(workItem);
Ghislain MARY's avatar
Ghislain MARY committed
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
}

unsigned int MS2Tester::nbTestSuites()
{
	return bc_tester_nb_suites();
}

unsigned int MS2Tester::nbTests(Platform::String^ suiteName)
{
	std::wstring suitename = suiteName->Data();
	char cname[MAX_SUITE_NAME_SIZE] = { 0 };
	wcstombs(cname, suitename.c_str(), sizeof(cname));
	return bc_tester_nb_tests(cname);
}

Platform::String^ MS2Tester::testSuiteName(int index)
{
	const char *cname = bc_tester_suite_name(index);
	wchar_t wcname[MAX_SUITE_NAME_SIZE];
	mbstowcs(wcname, cname, sizeof(wcname));
	return ref new String(wcname);
}

Platform::String^ MS2Tester::testName(Platform::String^ suiteName, int testIndex)
{
	std::wstring suitename = suiteName->Data();
	char csuitename[MAX_SUITE_NAME_SIZE] = { 0 };
	wcstombs(csuitename, suitename.c_str(), sizeof(csuitename));
	const char *cname = bc_tester_test_name(csuitename, testIndex);
	wchar_t wcname[MAX_SUITE_NAME_SIZE];
	mbstowcs(wcname, cname, sizeof(wcname));
	return ref new String(wcname);
}
162

163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
Windows::Foundation::Collections::IVector<Platform::String^>^ MS2Tester::VideoDevices::get()
{
	wchar_t wcname[MAX_DEVICE_NAME_SIZE];
	Vector<Platform::String^>^ devices = ref new Vector<Platform::String^>();
	const MSList *elem = ms_web_cam_manager_get_list(ms_web_cam_manager_get());
	for (int i = 0; elem != NULL; elem = elem->next, i++) {
		const char *id = ms_web_cam_get_string_id((MSWebCam *)elem->data);
		memset(wcname, 0, sizeof(wcname));
		mbstowcs(wcname, id, sizeof(wcname));
		devices->Append(ref new String(wcname));
	}
	return devices;
}

void MS2Tester::initVideo()
178 179 180 181 182 183 184 185
{
	ortp_init();
	ms_base_init();
	ortp_set_log_level_mask(ORTP_MESSAGE | ORTP_WARNING | ORTP_ERROR | ORTP_FATAL);
	ortp_set_log_handler(ms2NativeOutputTraceHandler);
	ms_voip_init();
	ms_plugins_init();
	rtp_profile_set_payload(&av_profile, 102, &payload_type_h264);
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
	rtp_profile_set_payload(&av_profile, 103, &payload_type_vp8);
	Platform::String^ appFolder = Windows::ApplicationModel::Package::Current->InstalledLocation->Path;
	Platform::String^ psPath = Platform::String::Concat(appFolder, ref new Platform::String(L"\\Assets\\Images\\nowebcamCIF.jpg"));
	std::wstring wsPath = psPath->Data();
	char cPath[MAX_FILEPATH_SIZE] = { 0 };
	wcstombs(cPath, wsPath.c_str(), sizeof(cPath));
	ms_static_image_set_default_image(cPath);
}

void MS2Tester::uninitVideo()
{
	ms_exit();
}

#define PLATFORM_STRING_TO_C_STRING(x) \
	memset(cst, 0, sizeof(cst)); \
	wst = x->Data(); \
	wcstombs(cst, wst.c_str(), sizeof(cst))


void MS2Tester::startVideoStream(Platform::Object^ CaptureElement, Platform::Object^ MediaElement, Platform::String^ camera, Platform::String^ codec, Platform::String^ videoSize, unsigned int frameRate, unsigned int bitRate)
{
208 209 210
	ms_filter_enable_statistics(TRUE);
	ms_filter_reset_statistics();

211 212 213 214
	MSVideoSize vsize = { MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H };
	int payload = 102;
	char cst[1024];
	std::wstring wst;
215
	MSWebCamManager *manager = ms_web_cam_manager_get();
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
	PLATFORM_STRING_TO_C_STRING(camera);
	MSWebCam *cam = ms_web_cam_manager_get_cam(manager, cst);
	PLATFORM_STRING_TO_C_STRING(codec);
	if (strcmp(cst, "VP8") == 0) payload = 103;
	PLATFORM_STRING_TO_C_STRING(videoSize);
	if (strcmp(cst, "720P") == 0) {
		vsize.width = MS_VIDEO_SIZE_720P_W;
		vsize.height = MS_VIDEO_SIZE_720P_H;
	} else if (strcmp(cst, "VGA") == 0) {
		vsize.width = MS_VIDEO_SIZE_VGA_W;
		vsize.height = MS_VIDEO_SIZE_VGA_H;
	} else if (strcmp(cst, "CIF") == 0) {
		vsize.width = MS_VIDEO_SIZE_CIF_W;
		vsize.height = MS_VIDEO_SIZE_CIF_H;
	} else if (strcmp(cst, "QVGA") == 0) {
		vsize.width = MS_VIDEO_SIZE_QVGA_W;
		vsize.height = MS_VIDEO_SIZE_QVGA_H;
	} else if (strcmp(cst, "QCIF") == 0) {
		vsize.width = MS_VIDEO_SIZE_QCIF_W;
		vsize.height = MS_VIDEO_SIZE_QCIF_H;
	}
	PayloadType *pt = rtp_profile_get_payload(&av_profile, payload);
	pt->normal_bitrate = bitRate * 1000;
239 240 241 242 243 244
	_videoStream = video_stream_new(20000, 0, FALSE);
	RefToPtrProxy<Platform::Object^> *previewWindowId = new RefToPtrProxy<Platform::Object^>(CaptureElement);
	video_stream_set_native_preview_window_id(_videoStream, previewWindowId);
	RefToPtrProxy<Platform::Object^> *nativeWindowId = new RefToPtrProxy<Platform::Object^>(MediaElement);
	video_stream_set_native_window_id(_videoStream, nativeWindowId);
	video_stream_set_display_filter_name(_videoStream, "MSWinRTDis");
245 246 247
	video_stream_use_video_preset(_videoStream, "custom");
	video_stream_set_sent_video_size(_videoStream, vsize);
	video_stream_set_fps(_videoStream, frameRate);
248
	video_stream_set_device_rotation(_videoStream, _deviceRotation);
249
	video_stream_start(_videoStream, &av_profile, "127.0.0.1", 20000, NULL, 0, payload, 0, cam);
250 251 252 253 254 255 256 257
}

void MS2Tester::stopVideoStream()
{
	ms_filter_log_statistics();
	video_stream_stop(_videoStream);
	_videoStream = NULL;
}
258 259 260 261 262 263 264 265 266

void MS2Tester::setOrientation(int degrees)
{
	_deviceRotation = degrees;
	if (_videoStream != NULL) {
		video_stream_set_device_rotation(_videoStream, _deviceRotation);
		video_stream_update_video_params(_videoStream);
	}
}