You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

338 lines
9.8 KiB

/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */
/*
* This is an example of a stationary tracker. It only reports the initial
* position for all frames and is used for testing purposes.
* The main function of this example is to show the developers how to modify
* their trackers to work with the evaluation environment.
*
* Copyright (c) 2017, Luka Cehovin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the FreeBSD Project.
*
*/
#include <stdio.h>
#include <ctype.h>
#include <cstring>
#include <stdarg.h>
#include <stdexcept>
#include <iostream>
#include <map>
#include <string>
#include <fstream>
#include <sstream>
#include <streambuf>
#include <trax/client.hpp>
#include "getopt.h"
#if defined(__OS2__) || defined(__WINDOWS__) || defined(WIN32) || defined(WIN64) || defined(_MSC_VER)
#include <ctype.h>
#include <windows.h>
#define strcmpi _strcmpi
__inline void sleep(long time) {
Sleep(time * 1000);
}
#else
#ifdef _MAC_
#else
#include <unistd.h>
#endif
#include <signal.h>
#define strcmpi strcasecmp
#endif
using namespace std;
using namespace trax;
#ifndef TRAX_BUILD_DATE
#define TRAX_BUILD_DATE __DATE__
#endif
void print_help() {
cout << "TraX Test utility" << "\n\n";
cout << "Built on " << TRAX_BUILD_DATE << "\n";
cout << "Library version: " << trax_version() << "\n";
cout << "Protocol version: " << TRAX_VERSION << "\n\n";
cout << "Usage: traxtest [-h] [-d] \n";
cout << "\t [-e name=value] [-p name=value]\n";
cout << "\t [-t timeout] [-x] [-X]\n";
cout << "\t -- <command_part1> <command_part2> ...";
cout << "\n\nProgram arguments: \n";
cout << "\t-d\tEnable debug\n";
cout << "\t-e\tEnvironmental variable (multiple occurences allowed)\n";
cout << "\t-h\tPrint this help and exit\n";
cout << "\t-p\tTracker parameter (multiple occurences allowed)\n";
cout << "\t-t\tSet timeout period\n";
cout << "\t-x\tUse explicit streams, not standard ones.\n";
cout << "\t-X\tUse TCP/IP sockets instead of file streams.\n";
cout << "\n";
cout << "\n";
}
void configure_signals() {
#if defined(__OS2__) || defined(__WINDOWS__) || defined(WIN32) || defined(WIN64) || defined(_MSC_VER)
// TODO: anything to do here?
#else
struct sigaction sa;
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; //SA_NOCLDWAIT;
if (sigaction(SIGCHLD, &sa, 0) == -1) {
perror(0);
exit(1);
}
#endif
}
#ifndef MAX
#define MAX(a,b) ((a) > (b)) ? (a) : (b)
#endif
string get_temp_name(const string& file) {
#if defined(__OS2__) || defined(__WINDOWS__) || defined(WIN32) || defined(WIN64) || defined(_MSC_VER)
string result;
char chars[MAX_PATH];
if (GetTempPath(MAX_PATH, chars))
return string(chars) + string("\\") + file;
else
return string("C:\\Temp");
#else
if (getenv("TMPDIR"))
return string(getenv("TMPDIR")) + string("/") + file;
else
return string("/tmp/") + file;
#endif
}
#define tester_header_only
#include "tester_resources.c"
ConnectionMode connection = CONNECTION_DEFAULT;
VerbosityMode verbosity = VERBOSITY_DEFAULT;
void print_debug(const char *format, ...) {
if (verbosity != VERBOSITY_DEBUG)
return;
va_list args;
va_start(args, format);
fprintf(stdout, "CLIENT: ");
vfprintf(stdout, format, args);
va_end(args);
}
#define CMD_OPTIONS "hdt:p:e:xX"
int main(int argc, char** argv) {
int c;
opterr = 0;
int result = 0;
int timeout = 30;
string tracker_command;
Properties properties;
map<string, string> environment;
configure_signals();
try {
while ((c = getopt(argc, argv, CMD_OPTIONS)) != -1)
switch (c) {
case 'h':
print_help();
exit(0);
case 'd':
verbosity = VERBOSITY_DEBUG;
break;
case 'x':
connection = CONNECTION_EXPLICIT;
break;
case 'X':
connection = CONNECTION_SOCKETS;
break;
case 't':
timeout = MAX(0, atoi(optarg));
break;
case 'e': {
char* var = optarg;
char* ptr = strchr(var, '=');
if (!ptr) break;
environment[string(var, ptr - var)] = string(ptr + 1);
break;
}
case 'p': {
char* var = optarg;
char* ptr = strchr(var, '=');
if (!ptr) break;
string key(var, ptr - var);
string value(ptr + 1);
properties.set(key, value);
break;
}
default:
print_help();
throw std::runtime_error(string("Unknown switch -") + string(1, (char) optopt));
}
if (optind < argc) {
stringstream buffer;
for (int i = optind; i < argc; i++) {
buffer << " \"" << string(argv[i]) << "\" ";
}
tracker_command = buffer.str();
} else {
print_help();
exit(-1);
}
TrackerProcess tracker(tracker_command, environment, timeout, connection, verbosity);
tracker.query();
ImageList image;
int image_formats = tracker.metadata().image_formats();
if TRAX_SUPPORTS(image_formats, TRAX_IMAGE_BUFFER) {
size_t length;
char* buffer = NULL;
tester_copy_resource("static.jpg", &buffer, &length);
image.set(Image::create_buffer(length, buffer), TRAX_CHANNEL_COLOR);
free(buffer);
} else if TRAX_SUPPORTS(image_formats, TRAX_IMAGE_MEMORY) {
size_t length;
char* buffer = NULL;
tester_copy_resource("static.bin", &buffer, &length);
Image tmp = Image::create_memory(320, 240, TRAX_IMAGE_MEMORY_RGB);
char* dst = tmp.write_memory_row(0);
memcpy(dst, buffer, 320 * 240);
free(buffer);
image.set(tmp, TRAX_CHANNEL_COLOR);
} else if TRAX_SUPPORTS(image_formats, TRAX_IMAGE_PATH) {
size_t length;
char* buffer = NULL;
tester_copy_resource("static.jpg", &buffer, &length);
string temp_path = get_temp_name("trax_testing.jpg");
std::ofstream output(temp_path.c_str(), std::ios::out | std::ios::binary );
output.write(buffer, length);
image.set(Image::create_path(temp_path), TRAX_CHANNEL_COLOR);
free(buffer);
}
else
throw std::runtime_error("No supported image format allowed");
Region initialization_region = Region::create_rectangle(130, 80, 70, 110);
int frame = 0;
int initializations = 0;
while (initializations < 5) {
if (!tracker.ready()) {
throw std::runtime_error("Tracker process not alive anymore.");
}
if (!tracker.initialize(image, initialization_region, properties)) {
throw std::runtime_error("Unable to initialize tracker.");
}
initializations++;
frame = 0;
while (frame < 20) {
// Repeat while tracking the target.
Region status;
Properties additional;
bool result = tracker.wait(status, additional);
if (result) {
// Default option, the tracker returns a valid status.
Region storage;
} else {
if (tracker.ready()) {
// The tracker has requested termination of connection.
print_debug("Termination requested by tracker.\n");
break;
} else {
// In case of an error ...
throw std::runtime_error("Unable to contact tracker.");
}
}
Properties no_properties;
if (!tracker.frame(image, no_properties))
throw std::runtime_error("Unable to send new frame.");
frame++;
}
}
} catch (const std::runtime_error &e) {
fprintf(stderr, "Error: %s\n", e.what());
result = 1;
}
exit(result);
}