common: Improve comments in example codes
This commit is contained in:
parent
a11b9e4563
commit
4bbabba8c0
|
@ -11,10 +11,10 @@ Below is a very simple example usage of uvgRTP:
|
|||
|
||||
int main(void)
|
||||
{
|
||||
uvg_rtp::context ctx;
|
||||
uvg_rtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
uvgrtp::context ctx;
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
|
||||
uvg_rtp::media_stream *strm = sess->create_stream(8888, 8888, RTP_FORMAT_GENERIC, RTP_NO_FLAGS);
|
||||
uvgrtp::media_stream *strm = sess->create_stream(8888, 8888, RTP_FORMAT_GENERIC, RTP_NO_FLAGS);
|
||||
|
||||
char *message = (char *)"Hello, world!";
|
||||
size_t msg_len = strlen(message);
|
||||
|
@ -23,7 +23,7 @@ int main(void)
|
|||
strm->push_frame((uint8_t *)message, msg_len, RTP_NO_FLAGS);
|
||||
auto frame = strm->pull_frame();
|
||||
fprintf(stderr, "Message: '%s'\n", frame->payload);
|
||||
uvg_rtp::frame::dealloc_frame(frame);
|
||||
uvgrtp::frame::dealloc_frame(frame);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -34,7 +34,7 @@ int main(void)
|
|||
|
||||
[How to create a simple RTP receiver (hooking)](receiving_hook.cc)
|
||||
|
||||
NOTE: The hook should **not** be used for media processing. It should be used as interface between application and library where the frame handout happens.
|
||||
NOTE: The hook should **not** be used for media processing. It should be used as interface between application and library where the frame hand-off happens.
|
||||
|
||||
[How to create a simple RTP receiver (polling)](receiving_poll.cc)
|
||||
|
||||
|
|
|
@ -4,11 +4,10 @@
|
|||
|
||||
int main(void)
|
||||
{
|
||||
/* To use the library, one must create a global RTP context object */
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::context ctx;
|
||||
|
||||
/* Each new IP address requires a separate RTP session.
|
||||
* This session object contains all media streams and an RTCP object (if enabled) */
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
|
||||
/* Some of the functionality of uvgRTP can be enabled/disabled using RCE_* flags.
|
||||
|
@ -18,8 +17,8 @@ int main(void)
|
|||
* and prepends a 4-byte HEVC start code (0x00000001) before each NAL unit */
|
||||
unsigned flags =
|
||||
RCE_RTCP | /* enable RTCP */
|
||||
RCE_NO_SYSTEM_CALL_CLUSTERING | /* disable System Call Clustering */
|
||||
RCE_H26X_PREPEND_SC; /* prepend start code to each returned HEVC frame */
|
||||
RCE_NO_SYSTEM_CALL_CLUSTERING | /* disable system call clustering */
|
||||
RCE_H26X_PREPEND_SC; /* prepend a start code before each NAL unit */
|
||||
|
||||
uvgrtp::media_stream *hevc = sess->create_stream(8888, 8889, RTP_FORMAT_H265, flags);
|
||||
|
||||
|
|
|
@ -7,11 +7,10 @@ int main(void)
|
|||
/* To use the library, one must create a global RTP context object */
|
||||
uvgrtp::context ctx;
|
||||
|
||||
/* Each new IP address requires a separate RTP session.
|
||||
* This session object contains all media streams and an RTCP object (if enabled) */
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
|
||||
/* Create MediaStream and RTCP for the session */
|
||||
/* Create MediaStream and enable RTCP for the stream */
|
||||
uvgrtp::media_stream *hevc = sess->create_stream(8888, 8889, RTP_FORMAT_H265, RCE_RTCP);
|
||||
|
||||
uint8_t *buffer = new uint8_t[PAYLOAD_MAXLEN];
|
||||
|
@ -24,19 +23,12 @@ int main(void)
|
|||
*
|
||||
* The first parameter is NTP time associated with the corresponding RTP timestamp,
|
||||
* second parameter is clock rate and the third parameter is RTP timestamp for t = 0
|
||||
* (it can be zero or some random number, does not matter)
|
||||
*
|
||||
* NOTE: dummy data passed as NTP timestamp */
|
||||
hevc->get_rtcp()->set_ts_info(1337, clock_rate, timestamp);
|
||||
|
||||
/* You can also use uvgRTP's cross-platform clock interface to get current NTP timestamp */
|
||||
if (0)
|
||||
hevc->get_rtcp()->set_ts_info(uvgrtp::clock::ntp::now(), clock_rate, timestamp);
|
||||
* (it can be zero or some random number, does not matter) */
|
||||
hevc->get_rtcp()->set_ts_info(uvgrtp::clock::ntp::now(), clock_rate, timestamp);
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
/* If needed, custom timestamps can be given to push_frame().
|
||||
*
|
||||
* This overrides uvgRTP's own calculations and uses the given timestamp for all RTP packets of "buffer" */
|
||||
/* The timestamp is given as the third parameter and it should be advanced
|
||||
* in accordance with the media stream clock rate. For example, for HEVC, the clock rate is 90000. */
|
||||
if (hevc->push_frame(buffer, PAYLOAD_MAXLEN, clock_rate * timestamp++, RTP_NO_FLAGS) != RTP_OK)
|
||||
fprintf(stderr, "Failed to send RTP frame!");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
#include <uvgrtp/lib.hh>
|
||||
#include <uvgrtp/formats/rawvideo.hh>
|
||||
|
||||
#define PAYLOAD_MAXLEN 4096
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uvgrtp::context ctx;
|
||||
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
uvgrtp::media_stream *rwv = sess->create_stream(8888, 8889, RTP_FORMAT_RAW_VIDEO, RTP_NO_FLAGS);
|
||||
|
||||
uvgrtp::formats::rwv_config conf = {
|
||||
.pixfmt = uvgrtp::formats::RWV_FMT_YUV420,
|
||||
.progressive = false, /* progressive */
|
||||
.width = 640,
|
||||
.height = 480,
|
||||
.depth = 8 /* bit depth */
|
||||
};
|
||||
|
||||
rwv->configure_ctx(&conf);
|
||||
|
||||
for (;;) {
|
||||
auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[PAYLOAD_MAXLEN]);
|
||||
|
||||
if (rwv->push_frame(std::move(buffer), PAYLOAD_MAXLEN, RTP_NO_FLAGS) != RTP_OK)
|
||||
fprintf(stderr, "Failed to send RTP frame!");
|
||||
}
|
||||
|
||||
/* Session must be destroyed manually */
|
||||
ctx.destroy_session(sess);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -3,11 +3,6 @@
|
|||
|
||||
void receive_hook(void *arg, uvgrtp::frame::rtp_frame *frame)
|
||||
{
|
||||
if (!frame) {
|
||||
fprintf(stderr, "invalid frame received!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now we own the frame. Here you could give the frame to the application
|
||||
* if f.ex "arg" was some application-specific pointer
|
||||
*
|
||||
|
@ -19,35 +14,21 @@ void receive_hook(void *arg, uvgrtp::frame::rtp_frame *frame)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
/* To use the library, one must create a global RTP context object */
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::context ctx;
|
||||
|
||||
/* Each new IP address requires a separate RTP session.
|
||||
* This session object contains all media streams and an RTCP object (if enabled) */
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
|
||||
/* Each RTP session has one or more media streams. These media streams are bidirectional
|
||||
* and they require both source and destination ports for the connection. One must also
|
||||
* specify the media format for the stream and any configuration flags if needed
|
||||
*
|
||||
* If ZRTP is enabled, the first media stream instance does a Diffie-Hellman key exchange
|
||||
* with remote and rest of the media streams use Multistream mode. ZRTP requires that both
|
||||
* source and destination ports are known so it can perform the key exchange
|
||||
*
|
||||
* First port is source port aka the port that we listen to and second port is the port
|
||||
* that remote listens to
|
||||
*
|
||||
* This same object is used for both sending and receiving media
|
||||
*
|
||||
* In this example, we have one media stream with remote participant: HEVC */
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::media_stream *hevc = sess->create_stream(8888, 8889, RTP_FORMAT_H265, 0);
|
||||
|
||||
/* Receive hook can be installed and the receiver will call this hook when an RTP frame is received
|
||||
/* Receive hook can be installed and uvgRTP will call this hook when an RTP frame is received
|
||||
*
|
||||
* This is a non-blocking operation
|
||||
*
|
||||
* If necessary, receive hook can be given an argument and this argument is supplied to
|
||||
* receive hook every time the hook is called. This argument could a pointer to application-
|
||||
* the receive hook every time the hook is called. This argument could a pointer to application-
|
||||
* specfic object if the application needs to be called inside the hook
|
||||
*
|
||||
* If it's not needed, it should be set to nullptr */
|
||||
|
|
|
@ -3,27 +3,13 @@
|
|||
|
||||
int main(void)
|
||||
{
|
||||
/* To use the library, one must create a global RTP context object */
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::context ctx;
|
||||
|
||||
/* Each new IP address requires a separate RTP session.
|
||||
* This session object contains all media streams and an RTCP object (if enabled) */
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
|
||||
/* Each RTP session has one or more media streams. These media streams are bidirectional
|
||||
* and they require both source and destination ports for the connection. One must also
|
||||
* specify the media format for the stream and any configuration flags if needed
|
||||
*
|
||||
* If ZRTP is enabled, the first media stream instance shall do a Diffie-Hellman key exchange
|
||||
* with remote and rest of the media streams use Multistream mode. ZRTP requires that both
|
||||
* source and destination ports are known so it can perform the key exchange
|
||||
*
|
||||
* First port is source port aka the port that we listen to and second port is the port
|
||||
* that remote listens to
|
||||
*
|
||||
* This same object is used for both sending and receiving media
|
||||
*
|
||||
* In this example, we have one media stream with remote participant: HEVC */
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::media_stream *hevc = sess->create_stream(8888, 8889, RTP_FORMAT_H265, 0);
|
||||
|
||||
/* pull_frame() will block until a frame is received.
|
||||
|
@ -31,13 +17,21 @@ int main(void)
|
|||
* If that is not acceptable, a separate thread for the reader should be created */
|
||||
uvgrtp::frame::rtp_frame *frame = nullptr;
|
||||
|
||||
while ((frame = hevc->pull_frame()) != nullptr) {
|
||||
while (!(frame = hevc->pull_frame())) {
|
||||
/* 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);
|
||||
}
|
||||
|
||||
ctx.destroy_session(sess);
|
||||
/* You can also specify for 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 = hevc->pull_frame(200);
|
||||
|
||||
/* Frame must be freed manually */
|
||||
uvgrtp::frame::dealloc_frame(frame);
|
||||
|
||||
ctx.destroy_session(sess);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -9,15 +9,26 @@ void receiver_hook(uvgrtp::frame::rtcp_receiver_report *frame)
|
|||
{
|
||||
LOG_INFO("Received an RTCP Receiver Report");
|
||||
|
||||
for (auto& block : frame->report_blocks) {
|
||||
fprintf(stderr, "ssrc: %x\n", block.ssrc);
|
||||
fprintf(stderr, "fraction: %u\n", block.fraction);
|
||||
fprintf(stderr, "lost: %d\n", block.lost);
|
||||
fprintf(stderr, "last_seq: %u\n", block.last_seq);
|
||||
fprintf(stderr, "jitter: %u\n", block.jitter);
|
||||
fprintf(stderr, "lsr: %u\n", block.lsr);
|
||||
fprintf(stderr, "dlsr (ms): %u\n", uvgrtp::clock::jiffies_to_ms(block.dlsr));
|
||||
}
|
||||
|
||||
/* RTCP frames can be deallocated using delete */
|
||||
delete frame;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* See rtp/sending.cc for more information about session initialization */
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::context ctx;
|
||||
|
||||
/* See sending.cc for more details */
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
|
||||
/* For s1, RTCP runner is using port 7778 and for s2 port 8889 */
|
||||
|
|
|
@ -7,28 +7,24 @@ int main(void)
|
|||
/* To use the library, one must create a global RTP context object */
|
||||
uvgrtp::context ctx;
|
||||
|
||||
/* Each new IP address requires a separate RTP session.
|
||||
* This session object contains all media streams and an RTCP object (if enabled) */
|
||||
/* Each new IP address requires a separate RTP session */
|
||||
uvgrtp::session *sess = ctx.create_session("127.0.0.1");
|
||||
|
||||
/* Each RTP session has one or more media streams. These media streams are bidirectional
|
||||
* and they require both source and destination ports for the connection. One must also
|
||||
* specify the media format for the stream and any configuration flags if needed
|
||||
* specify the media format for the stream and any configuration flags if needed.
|
||||
*
|
||||
* If ZRTP is enabled, the first media stream instance shall do a Diffie-Hellman key exchange
|
||||
* with remote and rest of the media streams use Multistream mode. ZRTP requires that both
|
||||
* source and destination ports are known so it can perform the key exchange
|
||||
* See configuration.cc for more details about configuration.
|
||||
*
|
||||
* First port is source port aka the port that we listen to and second port is the port
|
||||
* that remote listens to
|
||||
*
|
||||
* This same object is used for both sending and receiving media
|
||||
*
|
||||
* In this example, we have one media stream with remote participant: hevc */
|
||||
uvgrtp::media_stream *hevc = sess->create_stream(8888, 8889, RTP_FORMAT_H265, 0);
|
||||
* In this example, we have one media stream with the remote participant: H265 */
|
||||
uvgrtp::media_stream *hevc = sess->create_stream(8888, 8889, RTP_FORMAT_H265, RTP_NO_FLAGS);
|
||||
|
||||
uint8_t *buffer = new uint8_t[PAYLOAD_MAXLEN];
|
||||
uint32_t timestamp = 0;
|
||||
uint8_t *buffer = new uint8_t[PAYLOAD_MAXLEN];
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
if (hevc->push_frame(buffer, PAYLOAD_MAXLEN, RTP_NO_FLAGS) != RTP_OK)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <uvgrtp/lib.hh>
|
||||
#include <climits>
|
||||
|
||||
#define PAYLOAD_MAXLEN 4096
|
||||
#define PAYLOAD_MAXLEN (0xffff - 0x1000)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
@ -29,8 +29,32 @@ int main(void)
|
|||
*
|
||||
* uvgRTP fragments all generic input frames that are larger than 1500 and in the receiving end,
|
||||
* it will reconstruct the full sent frame from fragments when all fragments have been received */
|
||||
auto custom_media = std::unique_ptr<uint8_t[]>(new uint8_t[PAYLOAD_MAXLEN]);
|
||||
auto media = std::unique_ptr<uint8_t[]>(new uint8_t[PAYLOAD_MAXLEN]);
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
while (true) {
|
||||
int size = (rand() % PAYLOAD_MAXLEN) + 1;
|
||||
|
||||
for (int i = 0; i < size; ++i)
|
||||
media[i] = (i + size) % CHAR_MAX;
|
||||
|
||||
if (send->push_frame(media.get(), size, RTP_NO_FLAGS) != RTP_OK) {
|
||||
fprintf(stderr, "Failed to send frame!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto frame = recv->pull_frame();
|
||||
|
||||
if (memcmp(frame->payload, media.get(), size))
|
||||
LOG_ERROR("frame is corrupted!");
|
||||
|
||||
fprintf(stderr, "received frame of size %u, rand %d\n", frame->payload_len, size);
|
||||
|
||||
uvgrtp::frame::dealloc_frame(frame);
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < PAYLOAD_MAXLEN; ++i)
|
||||
custom_media[i] = i % CHAR_MAX;
|
||||
|
||||
|
@ -62,6 +86,7 @@ int main(void)
|
|||
|
||||
/* the frame must be destroyed manually */
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
#endif
|
||||
|
||||
/* Session must be destroyed manually */
|
||||
ctx.destroy_session(sess);
|
||||
|
|
|
@ -20,6 +20,13 @@ void thread_func(void)
|
|||
/* Enable SRTP and let user manage keys */
|
||||
unsigned flags = RCE_SRTP | RCE_SRTP_KMNGMNT_USER;
|
||||
|
||||
/* With user-managed keys, you have the option to use 192- and 256-bit keys.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/* See sending.cc for more details about create_stream() */
|
||||
uvgrtp::media_stream *recv = sess->create_stream(8889, 8888, RTP_FORMAT_GENERIC, flags);
|
||||
|
||||
|
|
|
@ -12,17 +12,17 @@ void thread_func(void)
|
|||
unsigned flags = RCE_SRTP | RCE_SRTP_KMNGMNT_ZRTP;
|
||||
|
||||
/* Keys creates using Diffie-Hellman mode */
|
||||
uvgrtp::media_stream *recv1 = sess->create_stream(8889, 8888, RTP_FORMAT_GENERIC, flags);
|
||||
uvgrtp::media_stream *video = sess->create_stream(8889, 8888, RTP_FORMAT_GENERIC, flags);
|
||||
|
||||
/* Keys created using Multistream mode */
|
||||
uvgrtp::media_stream *recv2 = sess->create_stream(7778, 7777, RTP_FORMAT_GENERIC, flags);
|
||||
uvgrtp::media_stream *audio = sess->create_stream(7778, 7777, RTP_FORMAT_GENERIC, flags);
|
||||
|
||||
for (;;) {
|
||||
auto frame = recv1->pull_frame();
|
||||
auto frame = video->pull_frame();
|
||||
fprintf(stderr, "Message: '%s'\n", frame->payload);
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
|
||||
frame = recv2->pull_frame();
|
||||
frame = audio->pull_frame();
|
||||
fprintf(stderr, "Message: '%s'\n", frame->payload);
|
||||
(void)uvgrtp::frame::dealloc_frame(frame);
|
||||
}
|
||||
|
@ -45,19 +45,19 @@ int main(void)
|
|||
unsigned flags = RCE_SRTP | RCE_SRTP_KMNGMNT_ZRTP;
|
||||
|
||||
/* Initialize ZRTP and negotiate the keys used to encrypt the media */
|
||||
uvgrtp::media_stream *send1 = sess->create_stream(8888, 8889, RTP_FORMAT_GENERIC, flags);
|
||||
uvgrtp::media_stream *video = sess->create_stream(8888, 8889, RTP_FORMAT_GENERIC, flags);
|
||||
|
||||
/* 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 *send2 = sess->create_stream(7777, 7778, RTP_FORMAT_GENERIC, flags);
|
||||
uvgrtp::media_stream *audio = sess->create_stream(7777, 7778, RTP_FORMAT_GENERIC, flags);
|
||||
|
||||
char *message = (char *)"Hello, world!";
|
||||
size_t msg_len = strlen(message);
|
||||
|
||||
for (;;) {
|
||||
send1->push_frame((uint8_t *)message, msg_len, RTP_NO_FLAGS);
|
||||
send2->push_frame((uint8_t *)message, msg_len, RTP_NO_FLAGS);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue