examples: Improved both SRTP examples along with building them
These examples need a version of uvgRTP which has the cryptolib included.
This commit is contained in:
parent
5d2f0ccaff
commit
31d8b8b6b7
|
@ -1,21 +1,47 @@
|
|||
#include <uvgrtp/lib.hh>
|
||||
#include <climits>
|
||||
|
||||
#define PAYLOAD_MAXLEN 256
|
||||
#define KEY_SIZE 16
|
||||
#define SALT_SIZE 14
|
||||
|
||||
/* Key and salt for the SRTP session of sender and receiver
|
||||
*
|
||||
* NOTE: uvgRTP only supports 128 bit keys and 112 bit salts */
|
||||
uint8_t key[KEY_SIZE] = { 0 };
|
||||
uint8_t salt[SALT_SIZE] = { 0 };
|
||||
// This example includes both sending and receiving SRTP streams.
|
||||
// Normally these are done on separate machines
|
||||
|
||||
void thread_func(void)
|
||||
constexpr char SENDER_ADDRESS[] = "127.0.0.1";
|
||||
constexpr uint16_t LOCAL_PORT = 8888;
|
||||
|
||||
constexpr char RECEIVER_ADDRESS[] = "127.0.0.1";
|
||||
constexpr uint16_t REMOTE_PORT = 8890;
|
||||
|
||||
enum Key_length{SRTP_128 = 128, SRTP_196 = 196, SRTP_256 = 256};
|
||||
|
||||
constexpr Key_length KEY_SIZE = SRTP_256;
|
||||
constexpr int KEY_SIZE_BYTES = KEY_SIZE/8;
|
||||
|
||||
constexpr int SALT_SIZE = 112;
|
||||
constexpr int SALT_SIZE_BYTES = SALT_SIZE/8;
|
||||
|
||||
constexpr auto EXAMPLE_DURATION = std::chrono::milliseconds(10000);
|
||||
|
||||
constexpr int FRAME_RATE = 30; // fps
|
||||
constexpr int SEND_TEST_PACKETS = (EXAMPLE_DURATION.count() - 1000)/1000*FRAME_RATE;
|
||||
constexpr int PACKET_INTERVAL_MS = 1000/FRAME_RATE;
|
||||
constexpr int RECEIVER_WAIT_TIME_MS = 100;
|
||||
|
||||
void process_frame(uvgrtp::frame::rtp_frame *frame)
|
||||
{
|
||||
std::string payload = std::string((char*)frame->payload, frame->payload_len);
|
||||
|
||||
std::cout << "Received SRTP frame. Payload: " << payload << std::endl;
|
||||
|
||||
/* When we receive a frame, the ownership of the frame belongs to us and
|
||||
* when we're done with it, we need to deallocate the frame */
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
}
|
||||
|
||||
void receive_func(uint8_t key[KEY_SIZE_BYTES], uint8_t salt[SALT_SIZE_BYTES])
|
||||
{
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::context ctx;
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
uvgrtp::session *receiver_session = ctx.create_session(SENDER_ADDRESS);
|
||||
|
||||
/* Enable SRTP and let user manage keys */
|
||||
unsigned flags = RCE_SRTP | RCE_SRTP_KMNGMNT_USER;
|
||||
|
@ -24,63 +50,131 @@ void thread_func(void)
|
|||
*
|
||||
* If 192- or 256-bit key size is specified in the flags, add_srtp_ctx() expects
|
||||
* the key paramter to be 24 or 32 bytes long, respectively. */
|
||||
if (0)
|
||||
flags |= RCE_SRTP_KEYSIZE_192;
|
||||
flags |= RCE_SRTP_KEYSIZE_256;
|
||||
|
||||
/* See sending.cc for more details about create_stream() */
|
||||
uvgrtp::media_stream *recv = sess->create_stream(8889, 8888, RTP_FORMAT_GENERIC, flags);
|
||||
uvgrtp::media_stream *recv = receiver_session->create_stream(REMOTE_PORT, LOCAL_PORT,
|
||||
RTP_FORMAT_GENERIC, flags);
|
||||
|
||||
/* Before anything else can be done,
|
||||
* add_srtp_ctx() must be called with the SRTP key and salt.
|
||||
*
|
||||
* All calls to "recv" that try to modify and or/use the newly
|
||||
* created media stream before calling add_srtp_ctx() will fail */
|
||||
recv->add_srtp_ctx(key, salt);
|
||||
// Receive frames by pulling for EXAMPLE_DURATION milliseconds
|
||||
if (recv)
|
||||
{
|
||||
/* Before anything else can be done,
|
||||
* add_srtp_ctx() must be called with the SRTP key and salt.
|
||||
*
|
||||
* All calls to "recv" that try to modify and or/use the newly
|
||||
* created media stream before calling add_srtp_ctx() will fail */
|
||||
recv->add_srtp_ctx(key, salt);
|
||||
|
||||
for (;;) {
|
||||
auto frame = recv->pull_frame();
|
||||
fprintf(stderr, "Message: '%s'\n", frame->payload);
|
||||
std::cout << "Start receiving frames for " << EXAMPLE_DURATION.count() << " ms" << std::endl;
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
|
||||
/* the frame must be destroyed manually */
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
uvgrtp::frame::rtp_frame *frame = nullptr;
|
||||
while (std::chrono::steady_clock::now() - start < EXAMPLE_DURATION)
|
||||
{
|
||||
/* You can specify a timeout for the operation and if the a frame is not received
|
||||
* within that time limit, pull_frame() returns a nullptr
|
||||
*
|
||||
* The parameter tells how long time a frame is waited in milliseconds */
|
||||
|
||||
frame = recv->pull_frame(RECEIVER_WAIT_TIME_MS);
|
||||
if (frame)
|
||||
{
|
||||
process_frame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
receiver_session->destroy_stream(recv);
|
||||
}
|
||||
|
||||
if (receiver_session)
|
||||
{
|
||||
ctx.destroy_session(receiver_session);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uvgrtp::context ctx;
|
||||
|
||||
if (!ctx.crypto_enabled())
|
||||
{
|
||||
std::cerr << "Cannot run SRTP example if crypto is not included in uvgRTP!"
|
||||
<< std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Key and salt for the SRTP session of sender and receiver
|
||||
*
|
||||
* NOTE: uvgRTP supports 128, 196 and 256 bit keys and 112 bit salts */
|
||||
uint8_t key[KEY_SIZE_BYTES] = { 0 };
|
||||
uint8_t salt[SALT_SIZE_BYTES] = { 0 };
|
||||
|
||||
/* initialize SRTP key and salt */
|
||||
for (int i = 0; i < KEY_SIZE; ++i)
|
||||
for (int i = 0; i < KEY_SIZE_BYTES; ++i)
|
||||
key[i] = i;
|
||||
|
||||
for (int i = 0; i < SALT_SIZE; ++i)
|
||||
for (int i = 0; i < SALT_SIZE_BYTES; ++i)
|
||||
salt[i] = i * 2;
|
||||
|
||||
std::cout << "Starting uvgRTP SRTP user provided encryption key example. Using key:"
|
||||
<< key << " and salt: " << salt << std::endl;
|
||||
|
||||
/* Create separate thread for the receiver */
|
||||
new std::thread(thread_func);
|
||||
std::thread receiver(receive_func, key, salt);
|
||||
|
||||
receiver.detach();
|
||||
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::context ctx;
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
|
||||
uvgrtp::session *sender_session = ctx.create_session(RECEIVER_ADDRESS);
|
||||
|
||||
/* Enable SRTP and let user manage keys */
|
||||
unsigned flags = RCE_SRTP | RCE_SRTP_KMNGMNT_USER;
|
||||
unsigned flags = RCE_SRTP | RCE_SRTP_KMNGMNT_USER | RCE_SRTP_KEYSIZE_256;
|
||||
|
||||
/* See sending.cc for more details about create_stream() */
|
||||
uvgrtp::media_stream *send = sess->create_stream(8888, 8889, RTP_FORMAT_GENERIC, flags);
|
||||
uvgrtp::media_stream *send = sender_session->create_stream(LOCAL_PORT, REMOTE_PORT,
|
||||
RTP_FORMAT_GENERIC, flags);
|
||||
|
||||
/* Before anything else can be done,
|
||||
* add_srtp_ctx() must be called with the SRTP key and salt.
|
||||
*
|
||||
* All calls to "send" that try to modify and or/use the newly
|
||||
* created media stream before calling add_srtp_ctx() will fail */
|
||||
send->add_srtp_ctx(key, salt);
|
||||
if (send)
|
||||
{
|
||||
/* Before anything else can be done,
|
||||
* add_srtp_ctx() must be called with the SRTP key and salt.
|
||||
*
|
||||
* All calls to "send" that try to modify and or/use the newly
|
||||
* created media stream before calling add_srtp_ctx() will fail
|
||||
* if SRTP is enabled */
|
||||
send->add_srtp_ctx(key, salt);
|
||||
|
||||
/* All media is now encrypted/decrypted automatically */
|
||||
char *message = (char *)"Hello, world!";
|
||||
size_t msg_len = strlen(message);
|
||||
/* All media is now encrypted/decrypted automatically */
|
||||
char *message = (char *)"Hello, world!";
|
||||
size_t msg_len = strlen(message);
|
||||
|
||||
for (;;) {
|
||||
send->push_frame((uint8_t *)message, msg_len, RTP_NO_FLAGS);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
for (unsigned int i = 0; i < SEND_TEST_PACKETS; ++i)
|
||||
{
|
||||
std::cout << "Sending frame " << i + 1 << '/' << SEND_TEST_PACKETS << std::endl;
|
||||
|
||||
if (send->push_frame((uint8_t *)message, msg_len, RTP_NO_FLAGS) != RTP_OK)
|
||||
{
|
||||
std::cerr << "Failed to send frame" << std::endl;
|
||||
}
|
||||
|
||||
// wait until it is time to send the next frame. 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 = (i + 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);
|
||||
}
|
||||
}
|
||||
|
||||
sender_session->destroy_stream(send);
|
||||
}
|
||||
|
||||
if (sender_session)
|
||||
ctx.destroy_session(sender_session);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -68,13 +68,12 @@ selectSRTPUser {
|
|||
TARGET = SRTPUser
|
||||
SOURCES += \
|
||||
srtp_user.cc \
|
||||
}
|
||||
|
||||
selectSRTPZRTP {
|
||||
message("Building ZRTP + SRTP example.")
|
||||
TARGET = Timestamp
|
||||
SOURCES += \
|
||||
custom_timestamps.cc \
|
||||
win32-msvc{
|
||||
LIBS += -lcryptlib
|
||||
} else {
|
||||
LIBS += -lcryptopp
|
||||
}
|
||||
}
|
||||
|
||||
selectZRTPMultistream {
|
||||
|
@ -82,6 +81,12 @@ selectZRTPMultistream {
|
|||
TARGET = ZRTPMultistream
|
||||
SOURCES += \
|
||||
zrtp_multistream.cc \
|
||||
|
||||
win32-msvc{
|
||||
LIBS += -lcryptlib
|
||||
} else {
|
||||
LIBS += -lcryptopp
|
||||
}
|
||||
}
|
||||
|
||||
DISTFILES += \
|
||||
|
@ -95,18 +100,16 @@ LIBS += -luvgrtp
|
|||
|
||||
win32-msvc{
|
||||
message("Detected MSVC compiler")
|
||||
# find the libraries if uvgrtp has been built according to instructions
|
||||
# find the libraries if uvgrtp has been built using CMake instructions
|
||||
CONFIG(debug, debug|release) {
|
||||
LIBRARY_FOLDER = -L$$PWD/../../build/Debug
|
||||
UVGRTP_LIB_FOLDER = -L$$PWD/../../build/Debug
|
||||
} else:CONFIG(release, debug|release) {
|
||||
LIBRARY_FOLDER = -L$$PWD/../../build/Release
|
||||
UVGRTP_LIB_FOLDER = -L$$PWD/../../build/Release
|
||||
}
|
||||
|
||||
LIBS += -lws2_32
|
||||
LIBS += -ladvapi32
|
||||
|
||||
LIBS += $${LIBRARY_FOLDER}
|
||||
message("Using library folder:" $${LIBRARY_FOLDER})
|
||||
LIBS += $${UVGRTP_LIB_FOLDER}
|
||||
message("Using the following folder for uvgRTP library:" $${UVGRTP_LIB_FOLDER})
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,62 +2,250 @@
|
|||
#include <climits>
|
||||
#include <cstring>
|
||||
|
||||
void thread_func(void)
|
||||
{
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::context ctx;
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
constexpr char SENDER_ADDRESS[] = "127.0.0.1";
|
||||
constexpr uint16_t SENDER_VIDEO_PORT = 8888;
|
||||
constexpr uint16_t SENDER_AUDIO_PORT = 8890;
|
||||
|
||||
/* Enable SRTP and use ZRTP to manage keys */
|
||||
unsigned flags = RCE_SRTP | RCE_SRTP_KMNGMNT_ZRTP;
|
||||
constexpr char RECEIVER_ADDRESS[] = "127.0.0.1";
|
||||
constexpr uint16_t RECEIVER_VIDEO_PORT = 7776;
|
||||
constexpr uint16_t RECEIVER_AUDIO_PORT = 7778;
|
||||
|
||||
/* Keys creates using Diffie-Hellman mode */
|
||||
uvgrtp::media_stream *video = sess->create_stream(8889, 8888, RTP_FORMAT_GENERIC, flags);
|
||||
constexpr int VIDEO_PAYLOAD_SIZE = 4000;
|
||||
constexpr int AUDIO_PAYLOAD_SIZE = 100;
|
||||
|
||||
/* Keys created using Multistream mode */
|
||||
uvgrtp::media_stream *audio = sess->create_stream(7778, 7777, RTP_FORMAT_GENERIC, flags);
|
||||
constexpr auto EXAMPLE_RUN_TIME_S = std::chrono::seconds(10);
|
||||
constexpr auto RECEIVER_WAIT_TIME_MS = std::chrono::milliseconds(50);
|
||||
|
||||
constexpr auto AUDIO_FRAME_INTERVAL_MS = std::chrono::milliseconds(20);
|
||||
|
||||
constexpr auto VIDEO_FRAME_INTERVAL_MS = std::chrono::milliseconds(1000/60); // 60 fps video
|
||||
|
||||
void audio_receiver(uvgrtp::session* receiver_session, int flags, std::shared_ptr<std::mutex> print_mutex);
|
||||
void video_receiver(uvgrtp::session* receiver_session, int flags, std::shared_ptr<std::mutex> print_mutex);
|
||||
|
||||
void audio_sender(uvgrtp::session* sender_session, int flags, std::shared_ptr<std::mutex> print_mutex);
|
||||
void video_sender(uvgrtp::session* sender_session, int flags, std::shared_ptr<std::mutex> print_mutex);
|
||||
|
||||
for (;;) {
|
||||
auto frame = video->pull_frame();
|
||||
fprintf(stderr, "Message: '%s'\n", frame->payload);
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
|
||||
frame = audio->pull_frame();
|
||||
fprintf(stderr, "Message: '%s'\n", frame->payload);
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
std::cout << "Starting uvgRTP SRTP together with ZRTP example" << std::endl;
|
||||
|
||||
/* Enable SRTP and use ZRTP to manage keys for both sender and receiver*/
|
||||
unsigned rce_flags = RCE_SRTP | RCE_SRTP_KMNGMNT_ZRTP;
|
||||
|
||||
uvgrtp::context receiver_ctx;
|
||||
|
||||
if (!receiver_ctx.crypto_enabled())
|
||||
{
|
||||
std::cerr << "Cannot run SRTP example if crypto is not included in uvgRTP!"
|
||||
<< std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
uvgrtp::session *receiver_session = receiver_ctx.create_session(SENDER_ADDRESS);
|
||||
|
||||
std::shared_ptr<std::mutex> print_mutex = std::shared_ptr<std::mutex> (new std::mutex);
|
||||
|
||||
/* Create separate thread for the receiver
|
||||
*
|
||||
* Because we're using ZRTP for SRTP key management,
|
||||
* the receiver and sender must communicate with each other
|
||||
* before the actual media communication starts */
|
||||
new std::thread(thread_func);
|
||||
std::thread a_receiver(audio_receiver, receiver_session, rce_flags, print_mutex);
|
||||
std::thread v_receiver(video_receiver, receiver_session, rce_flags, print_mutex);
|
||||
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::context ctx;
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
uvgrtp::context sender_ctx;
|
||||
uvgrtp::session *sender_session = sender_ctx.create_session(RECEIVER_ADDRESS);
|
||||
|
||||
/* Enable SRTP and use ZRTP to manage keys */
|
||||
unsigned flags = RCE_SRTP | RCE_SRTP_KMNGMNT_ZRTP;
|
||||
std::thread a_sender(audio_sender, sender_session, rce_flags, print_mutex);
|
||||
std::thread v_sender(video_sender, sender_session, rce_flags, print_mutex);
|
||||
|
||||
/* Initialize ZRTP and negotiate the keys used to encrypt the media */
|
||||
uvgrtp::media_stream *video = sess->create_stream(8888, 8889, RTP_FORMAT_GENERIC, flags);
|
||||
// wait until all threads have ended
|
||||
|
||||
if (a_receiver.joinable())
|
||||
{
|
||||
a_receiver.join();
|
||||
}
|
||||
if (v_receiver.joinable())
|
||||
{
|
||||
v_receiver.join();
|
||||
}
|
||||
if (a_sender.joinable())
|
||||
{
|
||||
a_sender.join();
|
||||
}
|
||||
if (v_sender.joinable())
|
||||
{
|
||||
v_sender.join();
|
||||
}
|
||||
|
||||
if (sender_session)
|
||||
sender_ctx.destroy_session(sender_session);
|
||||
|
||||
if (receiver_session)
|
||||
sender_ctx.destroy_session(receiver_session);
|
||||
|
||||
std::cout << "ZRTP example finished" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void audio_receiver(uvgrtp::session* receiver_session, int flags, std::shared_ptr<std::mutex> print_mutex)
|
||||
{
|
||||
/* Keys created using Multistream mode */
|
||||
uvgrtp::media_stream *receiver_audio_strm =
|
||||
receiver_session->create_stream(RECEIVER_AUDIO_PORT, SENDER_AUDIO_PORT,
|
||||
RTP_FORMAT_GENERIC, flags);
|
||||
|
||||
if (receiver_audio_strm)
|
||||
{
|
||||
uvgrtp::frame::rtp_frame *frame = nullptr;
|
||||
|
||||
std::cout << "Start receiving audio frames for " << EXAMPLE_RUN_TIME_S.count()
|
||||
<< " seconds" << std::endl;
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
|
||||
while (std::chrono::steady_clock::now() - start < EXAMPLE_RUN_TIME_S)
|
||||
{
|
||||
/* You can specify a timeout for the operation and if the a frame is not received
|
||||
* within that time limit, pull_frame() returns a nullptr
|
||||
*
|
||||
* The parameter tells how long time a frame is waited in milliseconds */
|
||||
|
||||
frame = receiver_audio_strm->pull_frame(RECEIVER_WAIT_TIME_MS.count());
|
||||
|
||||
if (frame)
|
||||
{
|
||||
print_mutex->lock();
|
||||
std::cout << "Received an audio frame. Payload size: " << frame->payload_len << std::endl;
|
||||
print_mutex->unlock();
|
||||
|
||||
// Process audio frame here
|
||||
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
receiver_session->destroy_stream(receiver_audio_strm);
|
||||
}
|
||||
}
|
||||
|
||||
void video_receiver(uvgrtp::session* receiver_session, int flags, std::shared_ptr<std::mutex> print_mutex)
|
||||
{
|
||||
/* Keys creates using Diffie-Hellman mode */
|
||||
uvgrtp::media_stream *receiver_video_strm =
|
||||
receiver_session->create_stream(RECEIVER_VIDEO_PORT, SENDER_VIDEO_PORT,
|
||||
RTP_FORMAT_H266, flags);
|
||||
|
||||
if (receiver_video_strm)
|
||||
{
|
||||
uvgrtp::frame::rtp_frame *frame = nullptr;
|
||||
|
||||
std::cout << "Start receiving audio frames for " << EXAMPLE_RUN_TIME_S.count()
|
||||
<< " seconds" << std::endl;
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
|
||||
while (std::chrono::steady_clock::now() - start < EXAMPLE_RUN_TIME_S)
|
||||
{
|
||||
/* You can specify a timeout for the operation and if the a frame is not received
|
||||
* within that time limit, pull_frame() returns a nullptr
|
||||
*
|
||||
* The parameter tells how long time a frame is waited in milliseconds */
|
||||
|
||||
frame = receiver_video_strm->pull_frame(RECEIVER_WAIT_TIME_MS.count());
|
||||
|
||||
if (frame)
|
||||
{
|
||||
print_mutex->lock();
|
||||
std::cout << "Received a video frame. Payload size: " << frame->payload_len << std::endl;
|
||||
print_mutex->unlock();
|
||||
|
||||
// Process video frame here
|
||||
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
receiver_session->destroy_stream(receiver_video_strm);
|
||||
}
|
||||
}
|
||||
|
||||
void audio_sender(uvgrtp::session* sender_session, int flags, std::shared_ptr<std::mutex> print_mutex)
|
||||
{
|
||||
/* The first call to create_stream() creates keys for the session using Diffie-Hellman
|
||||
* key exchange and all subsequent calls to create_stream() initialize keys for the
|
||||
* stream using Multistream mode */
|
||||
uvgrtp::media_stream *audio = sess->create_stream(7777, 7778, RTP_FORMAT_GENERIC, flags);
|
||||
uvgrtp::media_stream *sender_audio_strm = sender_session->create_stream(SENDER_AUDIO_PORT,
|
||||
RECEIVER_AUDIO_PORT,
|
||||
RTP_FORMAT_GENERIC, flags);
|
||||
|
||||
char *message = (char *)"Hello, world!";
|
||||
size_t msg_len = strlen(message);
|
||||
if (sender_audio_strm)
|
||||
{
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
|
||||
for (;;) {
|
||||
video->push_frame((uint8_t *)message, msg_len, RTP_NO_FLAGS);
|
||||
audio->push_frame((uint8_t *)message, msg_len, RTP_NO_FLAGS);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
for (int i = 0; std::chrono::steady_clock::now() < (start + EXAMPLE_RUN_TIME_S); ++i)
|
||||
{
|
||||
print_mutex->lock();
|
||||
std::cout << "Sending audio frame" << std::endl;
|
||||
print_mutex->unlock();
|
||||
|
||||
std::unique_ptr<uint8_t[]> dummy_audio_frame = std::unique_ptr<uint8_t[]>(new uint8_t[AUDIO_PAYLOAD_SIZE]);
|
||||
|
||||
if (sender_audio_strm->push_frame(std::move(dummy_audio_frame), AUDIO_PAYLOAD_SIZE, RTP_NO_FLAGS) != RTP_OK)
|
||||
{
|
||||
std::cerr << "Failed to send audio frame" << std::endl;
|
||||
}
|
||||
|
||||
// wait until it is time to send the next frame. 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 = (i + 1)*std::chrono::milliseconds(AUDIO_FRAME_INTERVAL_MS);
|
||||
if (next_frame_time > time_since_start)
|
||||
{
|
||||
std::this_thread::sleep_for(next_frame_time - time_since_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void video_sender(uvgrtp::session* sender_session, int flags, std::shared_ptr<std::mutex> print_mutex)
|
||||
{
|
||||
/* Initialize ZRTP and negotiate the keys used to encrypt the media */
|
||||
uvgrtp::media_stream *sender_video_strm = sender_session->create_stream(SENDER_VIDEO_PORT,
|
||||
RECEIVER_VIDEO_PORT,
|
||||
RTP_FORMAT_H266, flags);
|
||||
|
||||
if (sender_video_strm)
|
||||
{
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
|
||||
for (int i = 0; std::chrono::steady_clock::now() < (start + EXAMPLE_RUN_TIME_S); ++i)
|
||||
{
|
||||
print_mutex->lock();
|
||||
std::cout << "Sending video frame" << std::endl;
|
||||
print_mutex->unlock();
|
||||
|
||||
std::unique_ptr<uint8_t[]> dummy_audio_frame =
|
||||
std::unique_ptr<uint8_t[]>(new uint8_t[VIDEO_PAYLOAD_SIZE]);
|
||||
|
||||
if (sender_video_strm->push_frame(std::move(dummy_audio_frame),
|
||||
VIDEO_PAYLOAD_SIZE, RTP_NO_FLAGS) != RTP_OK)
|
||||
{
|
||||
std::cerr << "Failed to send video frame" << std::endl;
|
||||
}
|
||||
|
||||
// wait until it is time to send the next frame. 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 = (i + 1)*std::chrono::milliseconds(VIDEO_FRAME_INTERVAL_MS);
|
||||
if (next_frame_time > time_since_start)
|
||||
{
|
||||
std::this_thread::sleep_for(next_frame_time - time_since_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue