diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 689a9b5..6f20a83 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,6 +12,7 @@ target_sources(${PROJECT_NAME} test_3_rtcp.cpp test_4_formats.cpp test_5_srtp_zrtp.cpp + test_common.hh ) if(MSVC) diff --git a/test/test_2_rtp.cpp b/test/test_2_rtp.cpp index 14c0d3e..cfa4c37 100644 --- a/test/test_2_rtp.cpp +++ b/test/test_2_rtp.cpp @@ -1,7 +1,9 @@ -#include "uvgrtp/lib.hh" -#include +#include "test_common.hh" +// TODO: 1) Test only sending, 2) test sending with different configuration, 3) test receiving with different configurations, and +// 4) test sending and receiving within same test while checking frame size + // parameters for this test. You can change these to suit your network environment constexpr uint16_t LOCAL_PORT = 9300; @@ -9,7 +11,6 @@ constexpr char REMOTE_ADDRESS[] = "127.0.0.1"; constexpr uint16_t REMOTE_PORT = 9302; void rtp_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame); -void cleanup(uvgrtp::context& ctx, uvgrtp::session* sess, uvgrtp::media_stream* ms); void process_rtp_frame(uvgrtp::frame::rtp_frame* frame); void test_wait(int time_ms, uvgrtp::media_stream* receiver) @@ -17,7 +18,8 @@ void test_wait(int time_ms, uvgrtp::media_stream* receiver) uvgrtp::frame::rtp_frame* frame = nullptr; auto start = std::chrono::high_resolution_clock::now(); frame = receiver->pull_frame(time_ms); - int actual_difference = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start).count(); + int actual_difference = + std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - start).count(); EXPECT_EQ(RTP_OK, rtp_errno); EXPECT_GE(actual_difference, time_ms); @@ -27,91 +29,6 @@ void test_wait(int time_ms, uvgrtp::media_stream* receiver) process_rtp_frame(frame); } - -class Test_receiver -{ -public: - Test_receiver(int expectedPackets): - receivedPackets_(0), - expectedPackets_(expectedPackets) - {} - - void receive() - { - ++receivedPackets_; - } - - bool gotAll() - { - return receivedPackets_ == expectedPackets_; - } - -private: - - int receivedPackets_; - int expectedPackets_; -}; - -// TODO: 1) Test only sending, 2) test sending with different configuration, 3) test receiving with different configurations, and -// 4) test sending and receiving within same test while checking frame size - -TEST(RTPTests, send_too_much) -{ - // Tests sending large amounts of data to make sure nothing breaks because of it - - // TODO: Everything should actually be received even in this case but it probably isn't at the moment - std::cout << "Starting RTP send too much test" << std::endl; - uvgrtp::context ctx; - uvgrtp::session* sess = ctx.create_session(REMOTE_ADDRESS); - - uvgrtp::media_stream* sender = nullptr; - uvgrtp::media_stream* receiver = nullptr; - - int flags = RTP_NO_FLAGS; - - EXPECT_NE(nullptr, sess); - if (sess) - { - sender = sess->create_stream(LOCAL_PORT, REMOTE_PORT, RTP_FORMAT_H265, flags); - receiver = sess->create_stream(REMOTE_PORT, LOCAL_PORT, RTP_FORMAT_H265, flags); - } - - EXPECT_NE(nullptr, receiver); - if (receiver) - { - std::cout << "Installing hook" << std::endl; - EXPECT_EQ(RTP_OK, receiver->install_receive_hook(nullptr, rtp_receive_hook)); - } - - EXPECT_NE(nullptr, sender); - if (sender) - { - std::cout << "Starting to send data" << std::endl; - int packets = 4000; - for (unsigned int i = 0; i < packets; ++i) - { - const int frame_size = 200000; - std::unique_ptr dummy_frame = std::unique_ptr(new uint8_t[frame_size]); - - if (sender->push_frame(std::move(dummy_frame), frame_size, RTP_NO_FLAGS) != RTP_OK) - { - std::cout << "Failed to send RTP frame!" << std::endl; - } - - if (i % (packets/10) == packets/10 - 1) - { - std::cout << "Sent " << (i + 1) * 100 / packets << " % of data" << std::endl; - } - } - - - sess->destroy_stream(sender); - sender = nullptr; - } - - cleanup(ctx, sess, receiver); -} - TEST(RTPTests, rtp_hook) { // Tests installing a hook to uvgRTP @@ -127,16 +44,10 @@ TEST(RTPTests, rtp_hook) receiver = sess->create_stream(LOCAL_PORT, REMOTE_PORT, RTP_FORMAT_H265, flags); } - if (receiver) - { - std::cout << "Installing hook" << std::endl; - EXPECT_EQ(RTP_OK, receiver->install_receive_hook(nullptr, rtp_receive_hook)); - } + add_hook(receiver, rtp_receive_hook); - EXPECT_NE(nullptr, sess); - EXPECT_NE(nullptr, receiver); - - cleanup(ctx, sess, receiver); + cleanup_ms(sess, receiver); + cleanup_sess(ctx, sess); } TEST(RTPTests, rtp_poll) @@ -148,7 +59,7 @@ TEST(RTPTests, rtp_poll) uvgrtp::media_stream* sender = nullptr; uvgrtp::media_stream* receiver = nullptr; - int flags = RTP_NO_FLAGS; + int flags = RCE_NO_FLAGS; EXPECT_NE(nullptr, sess); if (sess) @@ -164,19 +75,8 @@ TEST(RTPTests, rtp_poll) EXPECT_NE(nullptr, sender); if (sender) { - // TODO: This could be prettier by using functions const int frame_size = 1500; - - std::cout << "Sending " << test_packets << " test packets" << std::endl; - for (unsigned int i = 0; i < test_packets; ++i) - { - std::unique_ptr dummy_frame = std::unique_ptr(new uint8_t[frame_size]); - - if (sender->push_frame(std::move(dummy_frame), frame_size, RTP_NO_FLAGS) != RTP_OK) - { - std::cout << "Failed to send RTP frame!" << std::endl; - } - } + send_packets(sess, sender, test_packets, frame_size, 0); uvgrtp::frame::rtp_frame* received_frame = nullptr; @@ -204,17 +104,7 @@ TEST(RTPTests, rtp_poll) EXPECT_EQ(received_packets_no_timeout, test_packets); int received_packets_timout = 0; - std::cout << "Sending " << test_packets << " test packets" << std::endl; - - for (unsigned int i = 0; i < test_packets; ++i) - { - std::unique_ptr dummy_frame = std::unique_ptr(new uint8_t[frame_size]); - - if (sender->push_frame(std::move(dummy_frame), frame_size, RTP_NO_FLAGS) != RTP_OK) - { - std::cout << "Failed to send RTP frame!" << std::endl; - } - } + send_packets(sess, sender, test_packets, frame_size, 0); std::cout << "Start pulling data with 3 ms timout" << std::endl; @@ -241,17 +131,44 @@ TEST(RTPTests, rtp_poll) if (received_frame) process_rtp_frame(received_frame); - - - sess->destroy_stream(sender); - sender = nullptr; } - - std::cout << "Finished pulling data" << std::endl; - cleanup(ctx, sess, receiver); + cleanup_ms(sess, sender); + cleanup_ms(sess, receiver); + cleanup_sess(ctx, sess); +} + + + +TEST(RTPTests, send_too_much) +{ + // Tests sending large amounts of data to make sure nothing breaks because of it + + // TODO: Everything should actually be received even in this case but it probably isn't at the moment + std::cout << "Starting RTP send too much test" << std::endl; + uvgrtp::context ctx; + uvgrtp::session* sess = ctx.create_session(REMOTE_ADDRESS); + + uvgrtp::media_stream* sender = nullptr; + uvgrtp::media_stream* receiver = nullptr; + + int flags = RTP_NO_FLAGS; + + EXPECT_NE(nullptr, sess); + if (sess) + { + sender = sess->create_stream(LOCAL_PORT, REMOTE_PORT, RTP_FORMAT_H265, flags); + receiver = sess->create_stream(REMOTE_PORT, LOCAL_PORT, RTP_FORMAT_H265, flags); + } + + add_hook(receiver, rtp_receive_hook); + send_packets(sess, sender, 4000, 10000, 0); + + cleanup_ms(sess, sender); + cleanup_ms(sess, receiver); + cleanup_sess(ctx, sess); } void rtp_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame) @@ -265,19 +182,6 @@ void rtp_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame) process_rtp_frame(frame); } -void cleanup(uvgrtp::context& ctx, uvgrtp::session* sess, uvgrtp::media_stream* ms) -{ - if (ms) - { - sess->destroy_stream(ms); - } - - if (sess) - { - ctx.destroy_session(sess); - } -} - void process_rtp_frame(uvgrtp::frame::rtp_frame* frame) { diff --git a/test/test_3_rtcp.cpp b/test/test_3_rtcp.cpp index cdff26e..fd82fe6 100644 --- a/test/test_3_rtcp.cpp +++ b/test/test_3_rtcp.cpp @@ -1,5 +1,4 @@ -#include "uvgrtp/lib.hh" -#include +#include "test_common.hh" constexpr char LOCAL_INTERFACE[] = "127.0.0.1"; constexpr uint16_t LOCAL_PORT = 9200; @@ -15,13 +14,9 @@ constexpr int PACKET_INTERVAL_MS = 1000 / FRAME_RATE; void receiver_hook(uvgrtp::frame::rtcp_receiver_report* frame); void sender_hook(uvgrtp::frame::rtcp_sender_report* frame); - -void wait_until_next_frame(std::chrono::steady_clock::time_point& start, int frame_index); void cleanup(uvgrtp::context& ctx, uvgrtp::session* local_session, uvgrtp::session* remote_session, uvgrtp::media_stream* send, uvgrtp::media_stream* receive); - - TEST(RTCPTests, rtcp) { std::cout << "Starting uvgRTP RTCP tests" << std::endl; @@ -44,9 +39,6 @@ TEST(RTCPTests, rtcp) { remote_stream = remote_session->create_stream(REMOTE_PORT, LOCAL_PORT, RTP_FORMAT_GENERIC, flags); } - EXPECT_NE(nullptr, local_session); - EXPECT_NE(nullptr, remote_session); - EXPECT_NE(nullptr, local_stream); EXPECT_NE(nullptr, remote_stream); if (local_stream) @@ -59,31 +51,13 @@ TEST(RTCPTests, rtcp) { EXPECT_EQ(RTP_OK, remote_stream->get_rtcp()->install_sender_hook(sender_hook)); } - if (local_stream) - { - uint8_t buffer[PAYLOAD_LEN] = { 0 }; - memset(buffer, 'a', PAYLOAD_LEN); - - std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); - - for (unsigned int i = 0; i < SEND_TEST_PACKETS; ++i) - { - EXPECT_EQ(RTP_OK, local_stream->push_frame((uint8_t*)buffer, PAYLOAD_LEN, RTP_NO_FLAGS)); - - if (i % (SEND_TEST_PACKETS/10) == SEND_TEST_PACKETS/10 - 1) - { - std::cout << "Sent " << (i + 1) * 100 / SEND_TEST_PACKETS << " % of data" << std::endl; - } - - wait_until_next_frame(start, i); - } - } + send_packets(local_session, local_stream, SEND_TEST_PACKETS, PAYLOAD_LEN, PACKET_INTERVAL_MS); cleanup(ctx, local_session, remote_session, local_stream, remote_stream); } TEST(RTCP_reopen_receiver, rtcp) { - std::cout << "Starting uvgRTP RTCP tests" << std::endl; + std::cout << "Starting uvgRTP RTCP reopen receiver test" << std::endl; // Creation of RTP stream. See sending example for more details uvgrtp::context ctx; @@ -104,9 +78,6 @@ TEST(RTCP_reopen_receiver, rtcp) { remote_stream = remote_session->create_stream(REMOTE_PORT, LOCAL_PORT, RTP_FORMAT_GENERIC, flags); } - EXPECT_NE(nullptr, local_session); - EXPECT_NE(nullptr, remote_session); - EXPECT_NE(nullptr, local_stream); EXPECT_NE(nullptr, remote_stream); if (local_stream) @@ -121,34 +92,17 @@ TEST(RTCP_reopen_receiver, rtcp) { if (local_stream) { - uint8_t buffer[PAYLOAD_LEN] = { 0 }; - memset(buffer, 'a', PAYLOAD_LEN); + send_packets(local_session, local_stream, SEND_TEST_PACKETS/2, PAYLOAD_LEN, PACKET_INTERVAL_MS); - std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); - - for (unsigned int i = 0; i < SEND_TEST_PACKETS; ++i) + if (remote_stream) { - EXPECT_EQ(RTP_OK, local_stream->push_frame((uint8_t*)buffer, PAYLOAD_LEN, RTP_NO_FLAGS)); - - wait_until_next_frame(start, i); - - if (i % (SEND_TEST_PACKETS/10) == SEND_TEST_PACKETS/10 - 1) - { - std::cout << "Sent " << (i + 1) * 100 / SEND_TEST_PACKETS << " % of data" << std::endl; - } - - - if (i == SEND_TEST_PACKETS/2) - { - if (remote_stream) - { - std::cout << "Closing and reopening receiver for testing purposes" << std::endl; - remote_session->destroy_stream(remote_stream); - remote_stream = remote_session->create_stream(REMOTE_PORT, LOCAL_PORT, RTP_FORMAT_GENERIC, flags); - EXPECT_NE(nullptr, remote_stream); - } - } + std::cout << "Closing and reopening receiver for testing purposes" << std::endl; + remote_session->destroy_stream(remote_stream); + remote_stream = remote_session->create_stream(REMOTE_PORT, LOCAL_PORT, RTP_FORMAT_GENERIC, flags); + EXPECT_NE(nullptr, remote_stream); } + + send_packets(local_session, local_stream, SEND_TEST_PACKETS / 2, PAYLOAD_LEN, PACKET_INTERVAL_MS); } cleanup(ctx, local_session, remote_session, local_stream, remote_stream); @@ -179,9 +133,6 @@ TEST(RTCP_double_bind_test, rtcp) { remote_stream = remote_session->create_stream(LOCAL_PORT, REMOTE_PORT, RTP_FORMAT_GENERIC, flags); } - EXPECT_NE(nullptr, local_session); - EXPECT_NE(nullptr, remote_session); - EXPECT_NE(nullptr, local_stream); EXPECT_EQ(nullptr, remote_stream); cleanup(ctx, local_session, remote_session, local_stream, remote_stream); @@ -232,41 +183,13 @@ void sender_hook(uvgrtp::frame::rtcp_sender_report* frame) delete frame; } -void wait_until_next_frame(std::chrono::steady_clock::time_point& start, int frame_index) -{ - // wait until it is time to send the next frame. Simulates a steady sending pace - // and included only for demostration purposes since you can use uvgRTP to send - // packets as fast as desired - auto time_since_start = std::chrono::steady_clock::now() - start; - auto next_frame_time = (frame_index + 1) * std::chrono::milliseconds(PACKET_INTERVAL_MS); - if (next_frame_time > time_since_start) - { - std::this_thread::sleep_for(next_frame_time - time_since_start); - } -} - void cleanup(uvgrtp::context& ctx, uvgrtp::session* local_session, uvgrtp::session* remote_session, uvgrtp::media_stream* send, uvgrtp::media_stream* receive) { - if (send) - { - local_session->destroy_stream(send); - } - - if (receive) - { - remote_session->destroy_stream(receive); - } - - if (local_session) - { - // Session must be destroyed manually - ctx.destroy_session(local_session); - } - - if (remote_session) - { - // Session must be destroyed manually - ctx.destroy_session(remote_session); + cleanup_ms(local_session, send); + if (receive) { + cleanup_ms(remote_session, receive); } + cleanup_sess(ctx, local_session); + cleanup_sess(ctx, remote_session); } \ No newline at end of file diff --git a/test/test_4_formats.cpp b/test/test_4_formats.cpp index 096c2d0..5ab71fa 100644 --- a/test/test_4_formats.cpp +++ b/test/test_4_formats.cpp @@ -1,5 +1,4 @@ -#include "uvgrtp/lib.hh" -#include +#include "test_common.hh" constexpr uint16_t SEND_PORT = 9100; constexpr char LOCAL_ADDRESS[] = "127.0.0.1"; @@ -10,7 +9,6 @@ constexpr size_t PAYLOAD_LEN = 100; void format_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame); -void cleanup_formats(uvgrtp::context& ctx, uvgrtp::session* sess, uvgrtp::media_stream* ms); void process_format_frame(uvgrtp::frame::rtp_frame* frame); @@ -32,36 +30,12 @@ TEST(FormatTests, h264) receiver = sess->create_stream(RECEIVE_PORT, SEND_PORT, RTP_FORMAT_H264, flags); } - if (receiver) - { - std::cout << "Installing hook" << std::endl; - EXPECT_EQ(RTP_OK, receiver->install_receive_hook(nullptr, format_receive_hook)); - } + add_hook(receiver, format_receive_hook); + send_packets(sess, sender, AMOUNT_OF_TEST_PACKETS, PAYLOAD_LEN, 0); - if (sender) - { - for (int i = 0; i < AMOUNT_OF_TEST_PACKETS; ++i) - { - std::unique_ptr dummy_frame = std::unique_ptr(new uint8_t[PAYLOAD_LEN]); - - if ((i + 1) % 10 == 0 || i == 0) // print every 10 frames and first - std::cout << "Sending frame " << i + 1 << '/' << AMOUNT_OF_TEST_PACKETS << std::endl; - - if (sender->push_frame(std::move(dummy_frame), PAYLOAD_LEN, RTP_NO_FLAGS) != RTP_OK) - { - std::cout << "Failed to send RTP frame!" << std::endl; - } - } - - EXPECT_NE(nullptr, sender); - sess->destroy_stream(sender); - sender = nullptr; - } - - EXPECT_NE(nullptr, sess); - EXPECT_NE(nullptr, receiver); - - cleanup_formats(ctx, sess, receiver); + cleanup_ms(sess, sender); + cleanup_ms(sess, receiver); + cleanup_sess(ctx, sess); } TEST(FormatTests, h265) @@ -80,36 +54,12 @@ TEST(FormatTests, h265) receiver = sess->create_stream(RECEIVE_PORT, SEND_PORT, RTP_FORMAT_H265, flags); } - if (receiver) - { - std::cout << "Installing hook" << std::endl; - EXPECT_EQ(RTP_OK, receiver->install_receive_hook(nullptr, format_receive_hook)); - } + add_hook(receiver, format_receive_hook); + send_packets(sess, sender, AMOUNT_OF_TEST_PACKETS, PAYLOAD_LEN, 0); - if (sender) - { - for (int i = 0; i < AMOUNT_OF_TEST_PACKETS; ++i) - { - std::unique_ptr dummy_frame = std::unique_ptr(new uint8_t[PAYLOAD_LEN]); - - if ((i + 1) % 10 == 0 || i == 0) // print every 10 frames and first - std::cout << "Sending frame " << i + 1 << '/' << AMOUNT_OF_TEST_PACKETS << std::endl; - - if (sender->push_frame(std::move(dummy_frame), PAYLOAD_LEN, RTP_NO_FLAGS) != RTP_OK) - { - std::cout << "Failed to send RTP frame!" << std::endl; - } - } - - EXPECT_NE(nullptr, sender); - sess->destroy_stream(sender); - sender = nullptr; - } - - EXPECT_NE(nullptr, sess); - EXPECT_NE(nullptr, receiver); - - cleanup_formats(ctx, sess, receiver); + cleanup_ms(sess, sender); + cleanup_ms(sess, receiver); + cleanup_sess(ctx, sess); } TEST(FormatTests, h266) @@ -128,36 +78,12 @@ TEST(FormatTests, h266) receiver = sess->create_stream(RECEIVE_PORT, SEND_PORT, RTP_FORMAT_H266, flags); } - if (receiver) - { - std::cout << "Installing hook" << std::endl; - EXPECT_EQ(RTP_OK, receiver->install_receive_hook(nullptr, format_receive_hook)); - } + add_hook(receiver, format_receive_hook); + send_packets(sess, sender, AMOUNT_OF_TEST_PACKETS, PAYLOAD_LEN, 0); - if (sender) - { - for (int i = 0; i < AMOUNT_OF_TEST_PACKETS; ++i) - { - std::unique_ptr dummy_frame = std::unique_ptr(new uint8_t[PAYLOAD_LEN]); - - if ((i + 1) % 10 == 0 || i == 0) // print every 10 frames and first - std::cout << "Sending frame " << i + 1 << '/' << AMOUNT_OF_TEST_PACKETS << std::endl; - - if (sender->push_frame(std::move(dummy_frame), PAYLOAD_LEN, RTP_NO_FLAGS) != RTP_OK) - { - std::cout << "Failed to send RTP frame!" << std::endl; - } - } - - EXPECT_NE(nullptr, sender); - sess->destroy_stream(sender); - sender = nullptr; - } - - EXPECT_NE(nullptr, sess); - EXPECT_NE(nullptr, receiver); - - cleanup_formats(ctx, sess, receiver); + cleanup_ms(sess, sender); + cleanup_ms(sess, receiver); + cleanup_sess(ctx, sess); } void format_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame) @@ -165,19 +91,6 @@ void format_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame) process_format_frame(frame); } -void cleanup_formats(uvgrtp::context& ctx, uvgrtp::session* sess, uvgrtp::media_stream* ms) -{ - if (ms) - { - sess->destroy_stream(ms); - } - - if (sess) - { - ctx.destroy_session(sess); - } -} - void process_format_frame(uvgrtp::frame::rtp_frame* frame) { std::cout << "Receiving frame with seq: " << frame->header.seq diff --git a/test/test_5_srtp_zrtp.cpp b/test/test_5_srtp_zrtp.cpp index aa74f73..4bd43a2 100644 --- a/test/test_5_srtp_zrtp.cpp +++ b/test/test_5_srtp_zrtp.cpp @@ -1,5 +1,4 @@ -#include "uvgrtp/lib.hh" -#include +#include "test_common.hh" // network parameters of example @@ -35,29 +34,15 @@ TEST(EncryptionTests, no_send_user) receiver = user_initialization(ctx, SRTP_256, sender_session, send); - // All media is now encrypted/decrypted automatically - char* message = (char*)"Hello, world!"; - size_t msg_len = strlen(message); - - if (send) - { - auto start = std::chrono::steady_clock::now(); - for (unsigned int i = 0; i < 10; ++i) - { - EXPECT_EQ(RTP_OK, send->push_frame((uint8_t*)message, msg_len, RTP_NO_FLAGS)); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - } - - sender_session->destroy_stream(send); + send_packets(sender_session, send, 10, strlen((char*)"Hello, world!"), 10); + cleanup_ms(sender_session, send); if (receiver && receiver->joinable()) { receiver->join(); } - if (sender_session) - ctx.destroy_session(sender_session); + cleanup_sess(ctx, sender_session); } std::unique_ptr user_initialization(uvgrtp::context& ctx, Key_length sha, @@ -111,9 +96,6 @@ void receive_func(uint8_t key[KEY_SIZE_BYTES], uint8_t salt[SALT_SIZE_BYTES]) recv = receiver_session->create_stream(REMOTE_PORT, LOCAL_PORT, RTP_FORMAT_GENERIC, flags); } - EXPECT_NE(nullptr, receiver_session); - EXPECT_NE(nullptr, recv); - if (recv) { recv->add_srtp_ctx(key, salt); @@ -135,15 +117,8 @@ void receive_func(uint8_t key[KEY_SIZE_BYTES], uint8_t salt[SALT_SIZE_BYTES]) } } - if (recv) - { - receiver_session->destroy_stream(recv); - } - - if (receiver_session) - { - ctx.destroy_session(receiver_session); - } + cleanup_ms(receiver_session, recv); + cleanup_sess(ctx, receiver_session); } void process_frame(uvgrtp::frame::rtp_frame* frame) diff --git a/test/test_common.hh b/test/test_common.hh new file mode 100644 index 0000000..8832d3c --- /dev/null +++ b/test/test_common.hh @@ -0,0 +1,116 @@ +#pragma once + +#include +#include "uvgrtp/lib.hh" + +void wait_until_next_frame(std::chrono::steady_clock::time_point& start, + int frame_index, int packet_interval_ms); + +inline void send_packets(uvgrtp::session* sess, uvgrtp::media_stream* sender, + int packets, size_t size, int packet_interval_ms); +inline void add_hook(uvgrtp::media_stream* receiver, void (*hook)(void*, uvgrtp::frame::rtp_frame*)); + +inline void cleanup_sess(uvgrtp::context& ctx, uvgrtp::session* sess); +inline void cleanup_ms(uvgrtp::session* sess, uvgrtp::media_stream* ms); + +class Test_receiver +{ +public: + Test_receiver(int expectedPackets) : + receivedPackets_(0), + expectedPackets_(expectedPackets) + {} + + void receive() + { + ++receivedPackets_; + } + + bool gotAll() + { + return receivedPackets_ == expectedPackets_; + } + +private: + + int receivedPackets_; + int expectedPackets_; +}; + +inline void send_packets(uvgrtp::session* sess, uvgrtp::media_stream* sender, + int packets, size_t size, int packet_interval_ms) +{ + EXPECT_NE(nullptr, sess); + EXPECT_NE(nullptr, sender); + if (sess && sender) + { + std::cout << "Sending " << packets << " test packets with size " << size << std::endl; + + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); + for (unsigned int i = 0; i < packets; ++i) + { + std::unique_ptr dummy_frame = std::unique_ptr(new uint8_t[size]); + memset(dummy_frame.get(), 'a', size); + + if (sender->push_frame(std::move(dummy_frame), size, RTP_NO_FLAGS) != RTP_OK) + { + std::cout << "Failed to send test packet!" << std::endl; + } + + if (i % (packets / 10) == packets / 10 - 1) + { + std::cout << "Sent " << (i + 1) * 100 / packets << " % of data" << std::endl; + } + + if (packet_interval_ms > 0) + { + wait_until_next_frame(start, i, packet_interval_ms); + } + } + } +} + +inline void wait_until_next_frame(std::chrono::steady_clock::time_point& start, int frame_index, int packet_interval_ms) +{ + // wait until it is time to send the next frame. Simulates a steady sending pace + // and included only for demostration purposes since you can use uvgRTP to send + // packets as fast as desired + auto time_since_start = std::chrono::steady_clock::now() - start; + auto next_frame_time = (frame_index + 1) * std::chrono::milliseconds(packet_interval_ms); + if (next_frame_time > time_since_start) + { + std::this_thread::sleep_for(next_frame_time - time_since_start); + } +} + +inline void cleanup_sess(uvgrtp::context& ctx, uvgrtp::session* sess) +{ + EXPECT_NE(nullptr, sess); + if (sess) + { + // Session must be destroyed manually + ctx.destroy_session(sess); + } +} + +inline void cleanup_ms(uvgrtp::session* sess, uvgrtp::media_stream* ms) +{ + EXPECT_NE(nullptr, ms); + EXPECT_NE(nullptr, sess); + if (sess && ms) + { + sess->destroy_stream(ms); + } +} + + +inline void add_hook(uvgrtp::media_stream* receiver, + void (*hook)(void*, uvgrtp::frame::rtp_frame*)) +{ + EXPECT_NE(nullptr, receiver); + if (receiver) + { + std::cout << "Installing hook" << std::endl; + EXPECT_EQ(RTP_OK, receiver->install_receive_hook(nullptr, hook)); + } +} \ No newline at end of file