From 5be46cd0434a8765280be7b4a7c9cf2bd284b5db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Thu, 26 Sep 2013 22:22:05 +0200 Subject: [PATCH] Add RTP sender test --- test/ortp-send-simple.c | 146 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 test/ortp-send-simple.c diff --git a/test/ortp-send-simple.c b/test/ortp-send-simple.c new file mode 100644 index 0000000..7f27b18 --- /dev/null +++ b/test/ortp-send-simple.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include +#include +#include + + +struct IOMux *mux; + +#define errx(x, ...) do { fprintf(stderr, x, __VA_ARGS__); exit(1); } while(0) + +struct RTPSender { + FILE *file; + char remote_ip[48]; + uint16_t remote_port; + struct UCTimer timer; + uint32_t ts; + struct timespec last_ts; + RtpSession *rtp_sess; + RtpProfile *rtp_profile; + int accum_diff; + uint8_t frame[160]; +}; + + +//returns microsec +int diffts(const struct timespec *a, struct timespec *b) +{ + struct timespec diff; + diff.tv_sec = b->tv_sec - a->tv_sec; + diff.tv_nsec = b->tv_nsec - a->tv_nsec; + if (diff.tv_nsec < 0) { + diff.tv_sec--; + diff.tv_nsec += 1000000000; + } + + + return (int) (diff.tv_sec * 1000 + (diff.tv_nsec + 500)/1000); +} + +void timer_cb(struct UCTimers *timers, struct UCTimer *timer) +{ + struct RTPSender *s = CONTAINER_OF(timer, struct RTPSender, timer); + int rc; + ssize_t r; + struct timespec ts; + int diff; + int adjust; + + clock_gettime(CLOCK_MONOTONIC, &ts); + rc = rtp_session_send_with_ts(s->rtp_sess,s->frame, sizeof s->frame, s->ts); + if(rc < sizeof s->frame) { + printf("Error, short send of %d bytes\n", rc); + } + s->ts += 160; + + r = fread(s->frame,1, sizeof s->frame, s->file); + if (r <= 0) { + rtp_session_bye(s->rtp_sess, "Finished"); + return; + } + + diff = diffts(&s->last_ts, &ts); + diff -= 20000; + + s->accum_diff += diff; + + if (s->accum_diff > 500) + adjust = -1000; + else if (s->accum_diff < -500) + adjust = 1000; + else + adjust = s->accum_diff; + + if (s->accum_diff >= 20000 || s->accum_diff <= -20000) { + s->ts += 160; + printf("Skew ! accum_diff %d\n", s->accum_diff); + s->accum_diff -= 20000; + } + + + uc_timers_add(iomux_get_timers(mux), &s->timer, 0, 20 * 1000 + adjust); + + s->last_ts = ts; +} + +void init_sender(FILE* file, const char *remote_ip, uint16_t remote_port) +{ + struct RTPSender *s = calloc(1, sizeof *s); + + RtpSession *rtp_sess = rtp_session_new(RTP_SESSION_SENDONLY); + RtpProfile *rtp_prof = rtp_profile_new("pcmu8000"); + rtp_profile_set_payload(rtp_prof, 0, &payload_type_pcmu8000); + rtp_session_set_profile(rtp_sess, rtp_prof); + //rtp_session_set_local_addr("192.168.1.55", 0); + rtp_session_set_remote_addr(rtp_sess, remote_ip, remote_port); + rtp_session_set_blocking_mode(rtp_sess, FALSE); + + s->file = file; + strcpy(s->remote_ip, remote_ip); + s->remote_port = remote_port; + s->rtp_sess = rtp_sess; + s->rtp_profile = rtp_prof; + s->timer.callback = timer_cb; + clock_gettime(CLOCK_MONOTONIC, &s->last_ts); + uc_timers_add(iomux_get_timers(mux), &s->timer, 0, 20000); +} + +int main(int argc, char *argv[]) +{ + mux = iomux_create(IOMUX_TYPE_DEFAULT); + + FILE *file; + if(argc != 4) { + puts("Specify a file name, remote IP and remote port"); + return 1; + } + + if(strcmp(argv[1], "-") == 0) { + file = stdin; + } else { + file = fopen(argv[1], "rb"); + if(file == NULL) { + perror("Cannot open file"); + return 1; + } + } + + ortp_init(); + ortp_set_log_level_mask(ORTP_DEBUG| ORTP_MESSAGE| ORTP_WARNING| ORTP_ERROR|ORTP_FATAL); + init_sender(file ,argv[2], atoi(argv[3])); + + iomux_run(mux); + + + fclose(file); + ortp_exit(); + + return 0; +} + +//compile: +// gcc -Wall -g -O `pkg-config --cflags --libs ortp` ortp-send-simple.c