convert transcoding unit test macros to functions

Change-Id: I409003397c7b510f79169e6069829b4bb949d12e
changes/79/21579/2
Richard Fuchs 8 years ago
parent 9f3f24f3ef
commit a2ed8e613a

@ -26,147 +26,178 @@ static void queue_dump(GString *s, GQueue *q) {
}
}
#define start() { \
printf("running test %s:%i\n", __FILE__, __LINE__); \
GHashTable *rtp_ts_ht = g_hash_table_new(g_direct_hash, g_direct_equal); \
GHashTable *rtp_seq_ht = g_hash_table_new(g_direct_hash, g_direct_equal); \
uint32_t ssrc_A = 1234; \
uint32_t ssrc_B = 2345; \
struct call call = {{0,},}; \
call.ssrc_hash = create_ssrc_hash_call(); \
struct sdp_ng_flags flags = {0,}; \
bencode_buffer_init(&call.buffer); \
struct call_media *media_A = call_media_new(&call); /* originator */ \
struct call_media *media_B = call_media_new(&call); /* output destination */ \
GQueue rtp_types = G_QUEUE_INIT; /* parsed from received SDP */ \
flags.codec_strip = g_hash_table_new_full(str_hash, str_equal, str_slice_free, NULL); \
flags.codec_mask = g_hash_table_new_full(str_hash, str_equal, str_slice_free, NULL)
// global variables used by tests
static GHashTable *rtp_ts_ht;
static GHashTable *rtp_seq_ht;
static uint32_t ssrc_A;
static uint32_t ssrc_B;
static struct call call;
static struct sdp_ng_flags flags;
static struct call_media *media_A;
static struct call_media *media_B;
static GQueue rtp_types;
#define start() __start(__FILE__, __LINE__)
static void __start(const char *file, int line) {
printf("running test %s:%i\n", file, line);
rtp_ts_ht = g_hash_table_new(g_direct_hash, g_direct_equal);
rtp_seq_ht = g_hash_table_new(g_direct_hash, g_direct_equal);
ssrc_A = 1234;
ssrc_B = 2345;
call = (struct call) {{0,},};
call.ssrc_hash = create_ssrc_hash_call();
flags = (struct sdp_ng_flags) {0,};
bencode_buffer_init(&call.buffer);
media_A = call_media_new(&call); // originator
media_B = call_media_new(&call); // output destination
g_queue_init(&rtp_types); // parsed from received SDP
flags.codec_strip = g_hash_table_new_full(str_hash, str_equal, str_slice_free, NULL);
flags.codec_mask = g_hash_table_new_full(str_hash, str_equal, str_slice_free, NULL);
}
#define transcode(codec) g_queue_push_tail(&flags.codec_transcode, sdup(#codec))
#define sdp_pt_fmt(num, codec, clockrate, fmt) { \
struct rtp_payload_type *pt = g_slice_alloc(sizeof(*pt)); \
*pt = (struct rtp_payload_type) { num, STR_CONST_INIT(#codec "/" #clockrate), STR_CONST_INIT(#codec), \
clockrate, STR_CONST_INIT(""), 1, STR_CONST_INIT(fmt), 0, 0, NULL }; \
g_queue_push_tail(&rtp_types, pt); \
}
#define sdp_pt_fmt(num, codec, clockrate, fmt) \
__sdp_pt_fmt(num, (str) STR_CONST_INIT(#codec), clockrate, (str) STR_CONST_INIT(#codec "/" #clockrate), \
(str) STR_CONST_INIT(fmt))
static void __sdp_pt_fmt(int num, str codec, int clockrate, str full_codec, str fmt) {
struct rtp_payload_type *pt = g_slice_alloc(sizeof(*pt));
*pt = (struct rtp_payload_type) { num, full_codec, codec,
clockrate, STR_CONST_INIT(""), 1, fmt, 0, 0, NULL };
g_queue_push_tail(&rtp_types, pt);
}
#define sdp_pt(num, codec, clockrate) sdp_pt_fmt(num, codec, clockrate, "")
#define offer() \
codec_rtp_payload_types(media_B, media_A, &rtp_types, \
flags.codec_strip, &flags.codec_offer, &flags.codec_transcode, \
flags.codec_mask); \
codec_handlers_update(media_B, media_A, &flags); \
g_queue_clear(&rtp_types); \
memset(&flags, 0, sizeof(flags))
#define answer() \
codec_rtp_payload_types(media_A, media_B, &rtp_types, \
flags.codec_strip, &flags.codec_offer, &flags.codec_transcode, \
flags.codec_mask); \
codec_handlers_update(media_A, media_B, &flags); \
#define expect(side, dir, codecs) { \
printf("running test %s:%i\n", __FILE__, __LINE__); \
GString *s = g_string_new(""); \
queue_dump(s, &media_ ## side->codecs_prefs_ ## dir); \
if (strcmp(s->str, codecs) != 0) { \
printf("test failed: %s:%i\n", __FILE__, __LINE__); \
printf("expected: %s\n", codecs); \
printf("received: %s\n", s->str); \
abort(); \
} \
printf("test ok: %s:%i\n", __FILE__, __LINE__); \
g_string_free(s, TRUE); \
static void offer() {
codec_rtp_payload_types(media_B, media_A, &rtp_types,
flags.codec_strip, &flags.codec_offer, &flags.codec_transcode,
flags.codec_mask);
codec_handlers_update(media_B, media_A, &flags);
g_queue_clear(&rtp_types);
memset(&flags, 0, sizeof(flags));
}
static void answer() {
codec_rtp_payload_types(media_A, media_B, &rtp_types,
flags.codec_strip, &flags.codec_offer, &flags.codec_transcode,
flags.codec_mask);
codec_handlers_update(media_A, media_B, &flags);
}
#define expect(side, dir, codecs) \
__expect(__FILE__, __LINE__, &media_ ## side->codecs_prefs_ ## dir, codecs)
static void __expect(const char *file, int line, GQueue *dumper, const char *codecs) {
printf("running test %s:%i\n", file, line);
GString *s = g_string_new("");
queue_dump(s, dumper);
if (strcmp(s->str, codecs) != 0) {
printf("test failed: %s:%i\n", file, line);
printf("expected: %s\n", codecs);
printf("received: %s\n", s->str);
abort();
}
printf("test ok: %s:%i\n", file, line);
g_string_free(s, TRUE);
}
#define packet_seq_ts(side, pt_in, pload, rtp_ts, rtp_seq, pt_out, pload_exp, ts_exp, fatal) \
__packet_seq_ts( __FILE__, __LINE__, media_ ## side, pt_in, (str) STR_CONST_INIT(pload), \
(str) STR_CONST_INIT(pload_exp), ssrc_ ## side, rtp_ts, rtp_seq, pt_out, \
ts_exp, fatal)
#define packet_seq_ts(side, pt_in, pload, rtp_ts, rtp_seq, pt_out, pload_exp, ts_exp, fatal) { \
printf("running test %s:%i\n", __FILE__, __LINE__); \
struct codec_handler *h = codec_handler_get(media_ ## side, pt_in); \
str pl = STR_CONST_INIT(pload); \
str pl_exp = STR_CONST_INIT(pload_exp); \
struct media_packet mp = { \
.media = media_ ## side, \
.ssrc_in = get_ssrc_ctx(ssrc_ ## side, call.ssrc_hash, SSRC_DIR_INPUT), \
}; \
mp.ssrc_out = get_ssrc_ctx(mp.ssrc_in->ssrc_map_out, call.ssrc_hash, SSRC_DIR_OUTPUT); \
int packet_len = sizeof(struct rtp_header) + pl.len; \
char *packet = malloc(packet_len); \
struct rtp_header *rtp = (void *) packet; \
*rtp = (struct rtp_header) { \
.m_pt = pt_in, \
.ssrc = ssrc_ ## side, \
.seq_num = htons(rtp_seq), \
.timestamp = htonl(rtp_ts), \
}; \
mp.rtp = rtp; \
mp.payload = pl; \
mp.payload.s = (packet + sizeof(struct rtp_header)); \
memcpy(mp.payload.s, pl.s, pl.len); \
mp.raw.s = packet; \
mp.raw.len = packet_len; \
h->func(h, &mp); \
if (pt_out == -1) { \
if (mp.packets_out.length != 0) { \
printf("test failed: %s:%i\n", __FILE__, __LINE__); \
printf("unexpected packet\n"); \
abort(); \
} \
} \
else { \
if (mp.packets_out.length != 1) { \
printf("test failed: %s:%i\n", __FILE__, __LINE__); \
printf("no packet\n"); \
abort(); \
} \
struct codec_packet *cp = g_queue_pop_head(&mp.packets_out); \
rtp = (void *) cp->s.s; \
if (rtp->m_pt != (unsigned char) pt_out) { \
printf("test failed: %s:%i\n", __FILE__, __LINE__); \
printf("expected: %i\n", pt_out); \
printf("received: %i\n", rtp->m_pt); \
abort(); \
} \
printf("packet contents: "); \
for (int i = sizeof(struct rtp_header); i < cp->s.len; i++) { \
unsigned char cc = cp->s.s[i]; \
printf("\\x%02x", cc); \
} \
printf("\n"); \
uint32_t ts = ntohl(rtp->timestamp); \
uint16_t seq = ntohs(rtp->seq_num); \
uint32_t ssrc = ntohl(rtp->ssrc); \
uint32_t ssrc_pt = ssrc ^ pt_out; \
ssrc_pt ^= pt_in << 8; /* XXX this is actually wrong and should be removed. it's a workaround for a bug */ \
printf("RTP SSRC %x seq %u TS %u PT %u\n", (unsigned int) ssrc, \
(unsigned int) seq, (unsigned int) ts, (unsigned int) rtp->m_pt); \
if (g_hash_table_contains(rtp_ts_ht, GUINT_TO_POINTER(ssrc_pt))) { \
uint32_t old_ts = GPOINTER_TO_UINT(g_hash_table_lookup(rtp_ts_ht, \
GUINT_TO_POINTER(ssrc_pt))); \
uint32_t diff = ts - old_ts; \
printf("RTP TS diff: %u\n", (unsigned int) diff); \
if (ts_exp != -1) \
assert(ts_exp == diff); \
} \
g_hash_table_insert(rtp_ts_ht, GUINT_TO_POINTER(ssrc_pt), GUINT_TO_POINTER(ts)); \
if (g_hash_table_contains(rtp_seq_ht, GUINT_TO_POINTER(ssrc_pt))) { \
uint32_t old_seq = GPOINTER_TO_UINT(g_hash_table_lookup(rtp_seq_ht, \
GUINT_TO_POINTER(ssrc_pt))); \
uint16_t diff = seq - old_seq; \
printf("RTP seq diff: %u\n", (unsigned int) diff); \
assert(diff == 1); \
} \
g_hash_table_insert(rtp_seq_ht, GUINT_TO_POINTER(ssrc_pt), GUINT_TO_POINTER(seq)); \
if (str_shift(&cp->s, sizeof(struct rtp_header))) \
abort(); \
if (pl_exp.len != cp->s.len) \
abort(); \
if (fatal && memcmp(pl_exp.s, cp->s.s, pl_exp.len)) \
abort(); \
} \
printf("test ok: %s:%i\n", __FILE__, __LINE__); \
free(packet); \
static void __packet_seq_ts(const char *file, int line, struct call_media *media, long long pt_in, str pload,
str pload_exp, uint32_t ssrc, long long rtp_ts, long long rtp_seq, long long pt_out,
long long ts_exp, int fatal)
{
printf("running test %s:%i\n", file, line);
struct codec_handler *h = codec_handler_get(media, pt_in);
str pl = pload;
str pl_exp = pload_exp;
struct media_packet mp = {
.media = media,
.ssrc_in = get_ssrc_ctx(ssrc, call.ssrc_hash, SSRC_DIR_INPUT),
};
mp.ssrc_out = get_ssrc_ctx(mp.ssrc_in->ssrc_map_out, call.ssrc_hash, SSRC_DIR_OUTPUT);
int packet_len = sizeof(struct rtp_header) + pl.len;
char *packet = malloc(packet_len);
struct rtp_header *rtp = (void *) packet;
*rtp = (struct rtp_header) {
.m_pt = pt_in,
.ssrc = ssrc,
.seq_num = htons(rtp_seq),
.timestamp = htonl(rtp_ts),
};
mp.rtp = rtp;
mp.payload = pl;
mp.payload.s = (packet + sizeof(struct rtp_header));
memcpy(mp.payload.s, pl.s, pl.len);
mp.raw.s = packet;
mp.raw.len = packet_len;
h->func(h, &mp);
if (pt_out == -1) {
if (mp.packets_out.length != 0) {
printf("test failed: %s:%i\n", file, line);
printf("unexpected packet\n");
abort();
}
}
else {
if (mp.packets_out.length != 1) {
printf("test failed: %s:%i\n", file, line);
printf("no packet\n");
abort();
}
struct codec_packet *cp = g_queue_pop_head(&mp.packets_out);
rtp = (void *) cp->s.s;
if (rtp->m_pt != (unsigned char) pt_out) {
printf("test failed: %s:%i\n", file, line);
printf("expected: %lli\n", pt_out);
printf("received: %i\n", rtp->m_pt);
abort();
}
printf("packet contents: ");
for (int i = sizeof(struct rtp_header); i < cp->s.len; i++) {
unsigned char cc = cp->s.s[i];
printf("\\x%02x", cc);
}
printf("\n");
uint32_t ts = ntohl(rtp->timestamp);
uint16_t seq = ntohs(rtp->seq_num);
uint32_t ssrc = ntohl(rtp->ssrc);
uint32_t ssrc_pt = ssrc ^ pt_out;
ssrc_pt ^= pt_in << 8; /* XXX this is actually wrong and should be removed. it's a workaround for a bug */
printf("RTP SSRC %x seq %u TS %u PT %u\n", (unsigned int) ssrc,
(unsigned int) seq, (unsigned int) ts, (unsigned int) rtp->m_pt);
if (g_hash_table_contains(rtp_ts_ht, GUINT_TO_POINTER(ssrc_pt))) {
uint32_t old_ts = GPOINTER_TO_UINT(g_hash_table_lookup(rtp_ts_ht,
GUINT_TO_POINTER(ssrc_pt)));
uint32_t diff = ts - old_ts;
printf("RTP TS diff: %u\n", (unsigned int) diff);
if (ts_exp != -1)
assert(ts_exp == diff);
}
g_hash_table_insert(rtp_ts_ht, GUINT_TO_POINTER(ssrc_pt), GUINT_TO_POINTER(ts));
if (g_hash_table_contains(rtp_seq_ht, GUINT_TO_POINTER(ssrc_pt))) {
uint32_t old_seq = GPOINTER_TO_UINT(g_hash_table_lookup(rtp_seq_ht,
GUINT_TO_POINTER(ssrc_pt)));
uint16_t diff = seq - old_seq;
printf("RTP seq diff: %u\n", (unsigned int) diff);
assert(diff == 1);
}
g_hash_table_insert(rtp_seq_ht, GUINT_TO_POINTER(ssrc_pt), GUINT_TO_POINTER(seq));
if (str_shift(&cp->s, sizeof(struct rtp_header)))
abort();
if (pl_exp.len != cp->s.len)
abort();
if (fatal && memcmp(pl_exp.s, cp->s.s, pl_exp.len))
abort();
}
printf("test ok: %s:%i\n", file, line);
free(packet);
}
#define packet(side, pt_in, pload, pt_out, pload_exp) \
@ -178,7 +209,10 @@ static void queue_dump(GString *s, GQueue *q) {
#define packet_seq_nf(side, pt_in, pload, rtp_ts, rtp_seq, pt_out, pload_exp) \
packet_seq_ts(side, pt_in, pload, rtp_ts, rtp_seq, pt_out, pload_exp, -1, 0)
#define end() } /* free/cleanup should go here */
static void end() {
g_hash_table_destroy(rtp_ts_ht);
g_hash_table_destroy(rtp_seq_ht);
}
#define PCMU_payload "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00"
#define PCMA_payload "\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a\x2b\x2a"

Loading…
Cancel
Save