diff options
author | Alfred E. Heggestad <alfred.heggestad@gmail.com> | 2016-12-07 21:30:04 +0100 |
---|---|---|
committer | Alfred E. Heggestad <alfred.heggestad@gmail.com> | 2016-12-07 21:30:04 +0100 |
commit | 5b7bb10e612704862dd72fa337f29bd48d34cac5 (patch) | |
tree | 393fcaa08f29ab238e7b5b0634b9a3b146aeb88d /test | |
parent | 618120a71690ea84ec05e4ae1473a2df6f78dd99 (diff) |
test: added testcase for call with video
Diffstat (limited to 'test')
-rw-r--r-- | test/call.c | 51 | ||||
-rw-r--r-- | test/main.c | 1 | ||||
-rw-r--r-- | test/mock/mock_vidcodec.c | 200 | ||||
-rw-r--r-- | test/mock/mock_vidisp.c | 96 | ||||
-rw-r--r-- | test/mock/mock_vidsrc.c | 91 | ||||
-rw-r--r-- | test/srcs.mk | 3 | ||||
-rw-r--r-- | test/test.h | 27 |
7 files changed, 467 insertions, 2 deletions
diff --git a/test/call.c b/test/call.c index 75d8c9f..4744b8a 100644 --- a/test/call.c +++ b/test/call.c @@ -123,8 +123,8 @@ static void event_handler(struct ua *ua, enum ua_event ev, int err = 0; (void)prm; -#if 0 - re_printf("[ %s ] event: %s (%s)\n", +#if 1 + info("test: [ %s ] event: %s (%s)\n", ua_aor(ua), uag_event_str(ev), prm); #endif @@ -663,3 +663,50 @@ int test_call_dtmf(void) return err; } + + +int test_call_video(void) +{ + struct fixture fix, *f = &fix; + struct vidsrc *vidsrc = NULL; + struct vidisp *vidisp = NULL; + int err = 0; + + conf_config()->video.fps = 100; + + fixture_init(f); + + /* to enable video, we need one vidsrc and vidcodec */ + mock_vidcodec_register(); + err = mock_vidsrc_register(&vidsrc); + TEST_ERR(err); + err = mock_vidisp_register(&vidisp); + TEST_ERR(err); + + f->behaviour = BEHAVIOUR_ANSWER; + f->estab_action = ACTION_NOTHING; + + /* Make a call from A to B */ + err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_ON); + TEST_ERR(err); + + /* run main-loop with timeout, wait for events */ + err = re_main_timeout(10000); + TEST_ERR(err); + TEST_ERR(fix.err); + + /* verify that video was enabled for this call */ + ASSERT_EQ(1, fix.a.n_established); + ASSERT_EQ(1, fix.b.n_established); + + ASSERT_TRUE(call_has_video(ua_call(f->a.ua))); + ASSERT_TRUE(call_has_video(ua_call(f->b.ua))); + + out: + fixture_close(f); + mem_deref(vidisp); + mem_deref(vidsrc); + mock_vidcodec_unregister(); + + return err; +} diff --git a/test/main.c b/test/main.c index 3a5dd77..487303e 100644 --- a/test/main.c +++ b/test/main.c @@ -28,6 +28,7 @@ static const struct test tests[] = { TEST(test_call_multiple), TEST(test_call_max), TEST(test_call_dtmf), + TEST(test_call_video), TEST(test_cmd), TEST(test_cmd_long), TEST(test_contact), diff --git a/test/mock/mock_vidcodec.c b/test/mock/mock_vidcodec.c new file mode 100644 index 0000000..c93f648 --- /dev/null +++ b/test/mock/mock_vidcodec.c @@ -0,0 +1,200 @@ +/** + * @file mock/mock_vidcodec.c Mock video codec + * + * Copyright (C) 2010 - 2016 Creytiv.com + */ + +#include <string.h> +#include <re.h> +#include <rem.h> +#include <baresip.h> +#include "../test.h" + + +#define HDR_SIZE 12 + + +struct hdr { + enum vidfmt fmt; + unsigned width; + unsigned height; +}; + +struct videnc_state { + videnc_packet_h *pkth; + void *arg; +}; + +struct viddec_state { + struct vidframe *frame; +}; + + +static int hdr_decode(struct hdr *hdr, struct mbuf *mb) +{ + if (mbuf_get_left(mb) < HDR_SIZE) + return EBADMSG; + + hdr->fmt = ntohl(mbuf_read_u32(mb)); + hdr->width = ntohl(mbuf_read_u32(mb)); + hdr->height = ntohl(mbuf_read_u32(mb)); + + return 0; +} + + +static void decode_destructor(void *arg) +{ + struct viddec_state *vds = arg; + + mem_deref(vds->frame); +} + + +static int mock_encode_update(struct videnc_state **vesp, + const struct vidcodec *vc, + struct videnc_param *prm, const char *fmtp, + videnc_packet_h *pkth, void *arg) +{ + struct videnc_state *ves; + + if (!vesp || !vc || !prm || prm->pktsize < (HDR_SIZE + 1)) + return EINVAL; + + ves = *vesp; + + if (!ves) { + + ves = mem_zalloc(sizeof(*ves), NULL); + if (!ves) + return ENOMEM; + + *vesp = ves; + } + + ves->pkth = pkth; + ves->arg = arg; + + return 0; +} + + +static int mock_encode(struct videnc_state *ves, bool update, + const struct vidframe *frame) +{ + struct mbuf *hdr; + uint8_t payload[2] = {0,0}; + int err; + + if (!ves || !frame) + return EINVAL; + + hdr = mbuf_alloc(16); + + err = mbuf_write_u32(hdr, htonl(frame->fmt)); + err |= mbuf_write_u32(hdr, htonl(frame->size.w)); + err |= mbuf_write_u32(hdr, htonl(frame->size.h)); + if (err) + goto out; + + err = ves->pkth(true, hdr->buf, hdr->end, + payload, sizeof(payload), ves->arg); + if (err) + goto out; + + out: + mem_deref(hdr); + + return err; +} + + +static int mock_decode_update(struct viddec_state **vdsp, + const struct vidcodec *vc, const char *fmtp) +{ + struct viddec_state *vds; + int err = 0; + (void)vc; + (void)fmtp; + + if (!vdsp) + return EINVAL; + + vds = *vdsp; + + if (vds) + return 0; + + vds = mem_zalloc(sizeof(*vds), decode_destructor); + if (!vds) + return ENOMEM; + + if (err) + mem_deref(vds); + else + *vdsp = vds; + + return err; +} + + +static int mock_decode(struct viddec_state *vds, struct vidframe *frame, + bool *intra, bool marker, uint16_t seq, struct mbuf *mb) +{ + struct vidsz size; + struct hdr hdr; + int err, i; + + if (!vds || !frame || !intra || !mb) + return EINVAL; + + *intra = false; + + err = hdr_decode(&hdr, mb); + if (err) { + warning("mock_vidcodec: could not decode header (%m)\n", err); + return err; + } + + size.w = hdr.width; + size.h = hdr.height; + + if (!vds->frame) { + err = vidframe_alloc(&vds->frame, hdr.fmt, &size); + if (err) + goto out; + } + + for (i=0; i<4; i++) { + frame->data[i] = vds->frame->data[i]; + frame->linesize[i] = vds->frame->linesize[i]; + } + + frame->size.w = vds->frame->size.w; + frame->size.h = vds->frame->size.h; + frame->fmt = vds->frame->fmt; + + out: + return err; +} + + +static struct vidcodec vc_dummy = { + .name = "H266", + .encupdh = mock_encode_update, + .ench = mock_encode, + .decupdh = mock_decode_update, + .dech = mock_decode, +}; + + +void mock_vidcodec_register(void) +{ + vidcodec_register(&vc_dummy); +} + + +void mock_vidcodec_unregister(void) +{ + vidcodec_unregister(&vc_dummy); +} diff --git a/test/mock/mock_vidisp.c b/test/mock/mock_vidisp.c new file mode 100644 index 0000000..da554b0 --- /dev/null +++ b/test/mock/mock_vidisp.c @@ -0,0 +1,96 @@ +/** + * @file mock/mock_vidisp.c Mock video display + * + * Copyright (C) 2010 - 2016 Creytiv.com + */ +#include <re.h> +#include <rem.h> +#include <baresip.h> +#include "../test.h" + + +#define MAX_WIDTH 65536 +#define MAX_HEIGHT 65536 + + +struct vidisp_st { + const struct vidisp *vd; /* inheritance */ + unsigned n_frame; +}; + + +static void disp_destructor(void *arg) +{ + struct vidisp_st *st = arg; + (void)st; +} + + +static int mock_disp_alloc(struct vidisp_st **stp, const struct vidisp *vd, + struct vidisp_prm *prm, const char *dev, + vidisp_resize_h *resizeh, void *arg) +{ + struct vidisp_st *st; + (void)prm; + (void)dev; + (void)resizeh; + (void)arg; + + if (!stp || !vd) + return EINVAL; + + st = mem_zalloc(sizeof(*st), disp_destructor); + if (!st) + return ENOMEM; + + st->vd = vd; + + *stp = st; + + return 0; +} + + +static int mock_display(struct vidisp_st *st, const char *title, + const struct vidframe *frame) +{ + unsigned width, height; + + if (!st || !frame) + return EINVAL; + + width = frame->size.w; + height = frame->size.h; + + if (!vidframe_isvalid(frame)) { + warning("mock_vidisp: got invalid frame\n"); + return EPROTO; + } + + /* verify that the video frame is good */ + if (frame->fmt >= VID_FMT_N) + return EPROTO; + if (width == 0 || width > MAX_WIDTH) + return EPROTO; + if (height == 0 || height > MAX_HEIGHT) + return EPROTO; + if (frame->linesize[0] == 0) + return EPROTO; + + ++st->n_frame; + + if (st->n_frame >= 10) { + info("mock_vidisp: got %u frames -- stopping re_main\n", + st->n_frame); + re_cancel(); /* XXX use a callback handler instead */ + } + + return 0; +} + + +int mock_vidisp_register(struct vidisp **vidispp) +{ + return vidisp_register(vidispp, "mock-vidisp", + mock_disp_alloc, NULL, mock_display, NULL); +} diff --git a/test/mock/mock_vidsrc.c b/test/mock/mock_vidsrc.c new file mode 100644 index 0000000..526ab16 --- /dev/null +++ b/test/mock/mock_vidsrc.c @@ -0,0 +1,91 @@ +/** + * @file mock/mock_vidsrc.c Mock video source + * + * Copyright (C) 2010 - 2016 Creytiv.com + */ +#include <re.h> +#include <rem.h> +#include <baresip.h> +#include "../test.h" + + +struct vidsrc_st { + const struct vidsrc *vs; /* inheritance */ + + struct vidframe *frame; + struct tmr tmr; + int fps; + vidsrc_frame_h *frameh; + void *arg; +}; + + +static void tmr_handler(void *arg) +{ + struct vidsrc_st *st = arg; + + tmr_start(&st->tmr, 1000/st->fps, tmr_handler, st); + + if (st->frameh) + st->frameh(st->frame, st->arg); +} + + +static void vidsrc_destructor(void *arg) +{ + struct vidsrc_st *st = arg; + + tmr_cancel(&st->tmr); + mem_deref(st->frame); +} + + +static int mock_vidsrc_alloc(struct vidsrc_st **stp, const struct vidsrc *vs, + struct media_ctx **ctx, struct vidsrc_prm *prm, + const struct vidsz *size, const char *fmt, + const char *dev, vidsrc_frame_h *frameh, + vidsrc_error_h *errorh, void *arg) +{ + struct vidsrc_st *st; + int err = 0; + (void)ctx; + (void)fmt; + (void)dev; + (void)errorh; + + if (!stp || !prm || !size || !frameh) + return EINVAL; + + st = mem_zalloc(sizeof(*st), vidsrc_destructor); + if (!st) + return ENOMEM; + + st->vs = vs; + st->fps = prm->fps; + st->frameh = frameh; + st->arg = arg; + + err = vidframe_alloc(&st->frame, VID_FMT_YUV420P, size); + if (err) + goto out; + + tmr_start(&st->tmr, 0, tmr_handler, st); + + info("mock_vidsrc: new instance with size %u x %u (%d fps)\n", + size->w, size->h, prm->fps); + + out: + if (err) + mem_deref(st); + else + *stp = st; + + return err; +} + + +int mock_vidsrc_register(struct vidsrc **vidsrcp) +{ + return vidsrc_register(vidsrcp, "mock-vidsrc", + mock_vidsrc_alloc, NULL); +} diff --git a/test/srcs.mk b/test/srcs.mk index b992822..7960c58 100644 --- a/test/srcs.mk +++ b/test/srcs.mk @@ -34,6 +34,9 @@ TEST_SRCS += mock/cert.c endif TEST_SRCS += mock/mock_ausrc.c +TEST_SRCS += mock/mock_vidsrc.c +TEST_SRCS += mock/mock_vidcodec.c +TEST_SRCS += mock/mock_vidisp.c TEST_SRCS += test.c diff --git a/test/test.h b/test/test.h index bd41c82..0f6d203 100644 --- a/test/test.h +++ b/test/test.h @@ -92,6 +92,32 @@ struct ausrc; int mock_ausrc_register(struct ausrc **ausrcp); +/* + * Mock Video-source + */ + +struct vidsrc; + +int mock_vidsrc_register(struct vidsrc **vidsrcp); + + +/* + * Mock Video-codec + */ + +void mock_vidcodec_register(void); +void mock_vidcodec_unregister(void); + + +/* + * Mock Video-display + */ + +struct vidisp; + +int mock_vidisp_register(struct vidisp **vidispp); + + /* test cases */ int test_cmd(void); @@ -116,6 +142,7 @@ int test_call_rtp_timeout(void); int test_call_multiple(void); int test_call_max(void); int test_call_dtmf(void); +int test_call_video(void); #ifdef __cplusplus |