From: <jpg...@us...> - 2008-07-01 15:52:34
|
Revision: 1438 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1438&view=rev Author: jpgrayson Date: 2008-07-01 08:52:43 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Updates to stresstest to allow for simple commands to be passed to it via stdin. Modified Paths: -------------- trunk/simpleclient/stresstest/file.c trunk/simpleclient/stresstest/file.h trunk/simpleclient/stresstest/stresstest.c Modified: trunk/simpleclient/stresstest/file.c =================================================================== --- trunk/simpleclient/stresstest/file.c 2008-07-01 15:42:30 UTC (rev 1437) +++ trunk/simpleclient/stresstest/file.c 2008-07-01 15:52:43 UTC (rev 1438) @@ -1,11 +1,12 @@ #include <string.h> #include <stdlib.h> #include <stdio.h> -#include "file.h" #include <oggz/oggz.h> #include <theora/theora.h> +#include "file.h" + #ifdef __GNUC__ void mylog(const char * fmt, ...) __attribute__ ((format (printf, 1, 2))); #else @@ -211,7 +212,8 @@ { if ( serialno == audio_stream->serialno ) { - audio_stream->page_ts = ogg_page_granulepos(og) * 1000 / + audio_stream->page_ts = + ogg_page_granulepos((ogg_page *)og) * 1000 / SPEEX_SAMPLING_RATE; audio_stream->page_count = 0; } @@ -221,7 +223,7 @@ return 0; } -void +int load_ogg_file(const char *filename) { OGGZ *oggz; @@ -230,6 +232,7 @@ if ( oggz == NULL ) { mylog("Error opening ogg file\n"); + return -1; } mylog("Successfully opened ogg file %s\n", filename); @@ -243,28 +246,30 @@ oggz_run(oggz); oggz_close(oggz); + + return 0; } -static ogg_packet * get_next_op(struct ogg_stream *os) +static ogg_packet * get_next_op(struct ogg_stream *os, struct timeval tv) { - ogg_packet *op; - struct timeval tv; - long time_now; + ogg_packet *op = 0; + long time_now; - if ( os == NULL ) + if ( !os ) return NULL; - gettimeofday(&tv, NULL); time_now = tv.tv_sec * 1000 + tv.tv_usec / 1000; - if ( os->current == NULL ) + if ( !os->current ) { + if ( !os->first ) + return NULL; + // point to the beginning of the stream and reset the time base os->base_ts = time_now; os->current = os->first; } - op = NULL; if ( os->current->timestamp < time_now - os->base_ts ) { op = os->current->op; @@ -274,14 +279,14 @@ return op; } -ogg_packet * get_next_audio_op() +ogg_packet * get_next_audio_op(struct timeval now) { - return get_next_op(audio_stream); + return get_next_op(audio_stream, now); } -ogg_packet * get_next_video_op() +ogg_packet * get_next_video_op(struct timeval now) { - return get_next_op(video_stream); + return get_next_op(video_stream, now); } int audio_is_eos() Modified: trunk/simpleclient/stresstest/file.h =================================================================== --- trunk/simpleclient/stresstest/file.h 2008-07-01 15:42:30 UTC (rev 1437) +++ trunk/simpleclient/stresstest/file.h 2008-07-01 15:52:43 UTC (rev 1438) @@ -1,15 +1,21 @@ #ifndef __FILE_H__ #define __FILE_H__ +#ifdef WIN32 +#include <windows.h> +#else +#include <time.h> +#endif + #include <ogg/ogg.h> -#define SPEEX_FRAME_DURATION 20 -#define SPEEX_SAMPLING_RATE 8000 +static const int SPEEX_FRAME_DURATION = 20; +static const int SPEEX_SAMPLING_RATE = 8000; -void load_ogg_file(const char *filename); +int load_ogg_file(const char *filename); -ogg_packet * get_next_audio_op(); -ogg_packet * get_next_video_op(); +ogg_packet * get_next_audio_op(struct timeval now); +ogg_packet * get_next_video_op(struct timeval now); int audio_is_eos(); int video_is_eos(); Modified: trunk/simpleclient/stresstest/stresstest.c =================================================================== --- trunk/simpleclient/stresstest/stresstest.c 2008-07-01 15:42:30 UTC (rev 1437) +++ trunk/simpleclient/stresstest/stresstest.c 2008-07-01 15:52:43 UTC (rev 1438) @@ -29,16 +29,31 @@ #include "file.h" #ifdef WIN32 -// Only under windows... +#include <process.h> +typedef uintptr_t a_thread; +#define STDCALL __stdcall +#define snprintf _snprintf #undef main +#else +#include <pthread.h> +typedef pthread_t a_thread; +#define STDCALL #endif -#define MAX_CALLS 1 +static const char STRESS_CMD_UNMUTE_AUDIO[] = "unmute_audio"; +static const char STRESS_CMD_MUTE_AUDIO[] = "mute_audio"; +static const char STRESS_CMD_UNMUTE_VIDEO[] = "unmute_video"; +static const char STRESS_CMD_MUTE_VIDEO[] = "mute_video"; +static const char STRESS_CMD_SHOW_STATE[] = "show_state"; +static const char STRESS_CMD_QUIT[] = "quit"; -#define TEST_OK 0 -#define TEST_NO_CONNECTION -1 -#define TEST_NO_MEDIA -2 -#define TEST_UNKNOWN_ERROR -99 +enum +{ + TEST_OK = 0, + TEST_NO_CONNECTION = -1, + TEST_NO_MEDIA = -2, + TEST_UNKNOWN_ERROR = -99, +}; static const int format = IAXC_FORMAT_H263 | @@ -63,6 +78,7 @@ static int connect_timeout_ms = 5000; static int video_frames_count = 0; static int audio_frames_count = 0; +static int audio_sent_count = 0; static struct timeval start_time; @@ -91,8 +107,54 @@ va_end(ap); } +static int +create_thread(a_thread *thread, + unsigned int (STDCALL * thread_func)(void *), + void *args, unsigned int *thread_id) +{ + int ret = 0; +#ifdef WIN32 + *thread = (uintptr_t)_beginthreadex(NULL, 0, thread_func, + (void *)args, 0, thread_id); + + if ( thread == 0 ) + ret = errno; +#else + void * (*func)(void *) = (void * (*)(void *))thread_func; + + ret = pthread_create(thread, NULL, func, args); +#endif + + return ret; +} + +static struct timeval +get_now(void) +{ + struct timeval tv; +#ifdef WIN32 + FILETIME ft; + LARGE_INTEGER li; + __int64 t; + static int tzflag; + const __int64 EPOCHFILETIME = 116444736000000000i64; + + GetSystemTimeAsFileTime(&ft); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + t = li.QuadPart; /* In 100-nanosecond intervals */ + t -= EPOCHFILETIME; /* Offset to the Epoch time */ + t /= 10; /* In microseconds */ + tv.tv_sec = (long)(t / 1000000); + tv.tv_usec = (long)(t % 1000000); +#else + gettimeofday(&tv, 0); +#endif + return tv; +} + /* routine used to shutdown and close nicely.*/ -void hangup_and_exit(int code) +void hangup_call() { mylog("Dump call\n"); iaxc_dump_call(); @@ -102,8 +164,6 @@ iaxc_stop_processing_thread(); mylog("Calling iaxc_shutdown...\n"); iaxc_shutdown(); - mylog("Exiting with code %d\n", code); - exit(code); } void signal_handler(int signum) @@ -117,7 +177,6 @@ void fatal_error(char *err) { mylog("FATAL ERROR: %s\n", err); - exit(TEST_UNKNOWN_ERROR); } int levels_callback(float input, float output) { @@ -188,12 +247,12 @@ void usage() { - printf("Usage: stresstest <options>\n\n" + printf("Usage: stresstest <options> <dial_string>\n\n" "available options:\n" " -F <codec> <framerate> <bitrate> <width> <height> <fragsize> set video parameters\n" " -o <filename> media file to run\n" - " -v stop sending video\n" - " -a stop sending audio\n" + " -a start with audio muted\n" + " -v start with video 'muted'\n" " -l run file in a loop\n" " -n dump periodic netstats to log file\n" " -t <TIMEOUT> terminate call after TIMEOUT seconds\n" @@ -253,12 +312,88 @@ return (t1->tv_sec - t0->tv_sec) * 1000L + (t1->tv_usec - t0->tv_usec) / 1000L; } +unsigned int STDCALL check_for_command(void *param) +{ + int *cmd_thread_ready = (int *)param; + + *cmd_thread_ready = 1; + + while ( 1 ) + { + char data[512]; + char *str; + + if ( fgets(data, sizeof(data), stdin) ) + { + + data[sizeof(data) - 1] = 0; + + if ( !(str = strtok(data, "\n")) ) + { + mylog("WARNING: invalid input\n"); + } + else if ( !strncmp(str, STRESS_CMD_UNMUTE_AUDIO, + strlen(STRESS_CMD_UNMUTE_AUDIO)) ) + { + // mylog("got command to unmute audio\n"); + send_audio = 1; + } + else if ( !strncmp(str, STRESS_CMD_MUTE_AUDIO, + strlen(STRESS_CMD_MUTE_AUDIO)) ) + { + // mylog("got command to mute audio\n"); + send_audio = 0; + } + else if ( !strncmp(str, STRESS_CMD_UNMUTE_VIDEO, + strlen(STRESS_CMD_UNMUTE_VIDEO)) ) + { + // mylog("got command to unmute video\n"); + send_video = 1; + } + else if ( !strncmp(str, STRESS_CMD_MUTE_VIDEO, + strlen(STRESS_CMD_MUTE_VIDEO)) ) + { + // mylog("got command to mute video\n"); + send_video = 0; + } + else if ( !strncmp(str, STRESS_CMD_SHOW_STATE, + strlen(STRESS_CMD_SHOW_STATE)) ) + { + mylog("got command to show state:\n"); + mylog("running = %d call_established = %d\n", + running, call_established); + mylog("send_video = %d send audio = %d\n", + send_video, send_audio); + mylog("audio frames recvd = %d video frames recvd = %d\n", + audio_frames_count, video_frames_count); + mylog("audio frames sent = %d\n\n", audio_sent_count); + } + else if ( !strncmp(str, STRESS_CMD_QUIT, + strlen(STRESS_CMD_QUIT)) ) + { + mylog("got command to quit\n"); + running = 0; + } + else + { + mylog("invalid input: '%s'\n", str); + } + } + } + + return 0; +} + int main(int argc, char **argv) { int i; char *dest = NULL; char *ogg_file = NULL; int loop = 0; + a_thread command_thread = 0; + unsigned int command_thread_id; + int ret = -1; + int cmd_thread_ready = 0; /* install signal handler to catch CRTL-Cs */ signal(SIGINT, signal_handler); @@ -331,24 +466,34 @@ if ( dest == NULL ) { mylog("No destination, quitting\n"); - return -1; + goto exit; } if ( ogg_file ) - load_ogg_file(ogg_file); + { + if ( load_ogg_file(ogg_file) ) + { + mylog("Failed loading ogg file. Quitting.\n"); + goto exit; + } + } else mylog("No media file, running dry\n"); // Get start time for timeouts - gettimeofday(&start_time, NULL); + start_time = get_now(); // Initialize iaxclient iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); iaxc_set_test_mode(1); - if (iaxc_initialize(MAX_CALLS)) + if (iaxc_initialize(1)) + { fatal_error("cannot initialize iaxclient!"); + ret = TEST_UNKNOWN_ERROR; + goto exit; + } iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX); iaxc_video_bypass_jitter(0); @@ -358,42 +503,71 @@ // Crank the engine if ( iaxc_start_processing_thread() < 0 ) + { fatal_error("failed iaxc_start_processing_thread()\n"); + ret = TEST_UNKNOWN_ERROR; + goto exit; + } + // spin a thread to check for commands from stdin + if ( ret = create_thread(&command_thread, + &check_for_command, + (void *)&cmd_thread_ready, &command_thread_id) ) + { + mylog("failed creating command thread\n"); + goto exit; + } + else + { + while ( !cmd_thread_ready ) + iaxc_millisleep(10); + } + // Dial out if ( iaxc_call(dest) < 0 ) + { fatal_error("failed iaxc_call()"); + ret = TEST_UNKNOWN_ERROR; + goto exit; + } // Wait for the call to be established; while ( !call_established && running ) { struct timeval now; - gettimeofday(&now, NULL); + now = get_now(); if ( connect_timeout_ms > 0 && msecdiff(&start_time, &now) > connect_timeout_ms ) - hangup_and_exit(TEST_NO_CONNECTION); + { + hangup_call(); + ret = TEST_NO_CONNECTION; + goto exit; + } iaxc_millisleep(5); } running = 1; while ( running ) { - struct timeval now; + struct timeval now = get_now(); // We only need this if we actually want to send something - if ( ogg_file && ( send_audio || send_video ) ) + if ( ogg_file ) { ogg_packet *op; - op = get_next_audio_op(); + op = get_next_audio_op(now); if ( !loop && audio_is_eos() ) break; if ( send_audio && op != NULL && op->bytes > 0 ) + { iaxc_push_audio(op->packet, op->bytes, SPEEX_SAMPLING_RATE * SPEEX_FRAME_DURATION / 1000); + audio_sent_count++; + } - op = get_next_video_op(); + op = get_next_video_op(now); if ( !loop && video_is_eos() ) break; if ( send_video && op != NULL && op->bytes > 0 ) @@ -404,7 +578,6 @@ iaxc_millisleep(5); // Exit after a positive timeout - gettimeofday(&now, NULL); if ( call_timeout_ms > 0 && msecdiff(&start_time, &now) > call_timeout_ms ) running = 0; @@ -414,8 +587,14 @@ audio_frames_count, video_frames_count); if ( audio_frames_count == 0 && video_frames_count == 0 ) - hangup_and_exit(TEST_NO_MEDIA); + ret = TEST_NO_MEDIA; else - hangup_and_exit(TEST_OK); - return 0; + ret = TEST_OK; + + hangup_call(); + +exit: + mylog("Exiting with code %d\n", ret); + + return ret; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |