Skip to content

Commit

Permalink
v3c: Divide more code into functions
Browse files Browse the repository at this point in the history
  • Loading branch information
tampsa committed Jan 12, 2024
1 parent 822f595 commit 3efbd09
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 230 deletions.
116 changes: 19 additions & 97 deletions examples/v3c_receiver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ void ovd_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame);
void gvd_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame);
void avd_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame);

void copy_rtp_payload(std::vector<v3c_unit_info> &units, uint64_t max_size, uvgrtp::frame::rtp_frame* frame);
uint64_t vps_count;

constexpr int VPS_NALS = 1;
Expand All @@ -48,69 +47,43 @@ std::string PATH = "C:\\Users\\ngheta\\Documents\\v3c_test_seq_2.vpcc";

int main(void)
{
std::cout << "Starting uvgRTP RTP receive hook example" << std::endl;
std::cout << "Starting uvgRTP V3C receive hook example" << std::endl;

/* Fetch the original file and its size */
uint64_t len = get_size(PATH);
std::cout << "File size " << len << std::endl;

char* original_buf = nullptr;
original_buf = get_cmem(PATH, len);
original_buf = get_cmem(PATH);

uvgrtp::context ctx;
uvgrtp::session* sess = ctx.create_session(LOCAL_ADDRESS, LOCAL_ADDRESS);
int flags = RCE_RECEIVE_ONLY | RCE_NO_H26X_PREPEND_SC;
int flags = RCE_RECEIVE_ONLY;

// Create the uvgRTP media streams with the correct RTP format
uvgrtp::media_stream* vps = sess->create_stream(8891, 8890, RTP_FORMAT_GENERIC, flags);
uvgrtp::media_stream* ad = sess->create_stream(8893, 8892, RTP_FORMAT_ATLAS, flags);
uvgrtp::media_stream* ovd = sess->create_stream(8895, 8894, RTP_FORMAT_H265, flags);
uvgrtp::media_stream* gvd = sess->create_stream(8897, 8896, RTP_FORMAT_H265, flags);
uvgrtp::media_stream* avd = sess->create_stream(8899, 8898, RTP_FORMAT_H265, flags);
avd->configure_ctx(RCC_RING_BUFFER_SIZE, 40*1000*1000);
v3c_streams streams = init_v3c_streams(sess, 8890, 8892, flags, true);
//avd->configure_ctx(RCC_RING_BUFFER_SIZE, 40*1000*1000);
v3c_file_map mmap = init_mmap();

char* out_buf = new char[len];
v3c_file_map mmap = {};


v3c_unit_header hdr = { V3C_AD };
hdr.ad = { 0, 0 };
v3c_unit_info unit = { hdr, {}, new char[40 * 1000 * 1000], 0, false };
mmap.ad_units.push_back(unit);

hdr = { V3C_OVD };
hdr.ovd = { 0, 0 };
unit = { hdr, {}, new char[40 * 1000 * 1000], 0, false };
mmap.ovd_units.push_back(unit);

hdr = { V3C_GVD };
hdr.gvd = { 0, 0 };
unit = { hdr, {}, new char[40 * 1000 * 1000], 0, false };
mmap.gvd_units.push_back(unit);

hdr = { V3C_AVD };
hdr.avd = { 0, 0 };
unit = { hdr, {}, new char[40 * 1000 * 1000], 0, false };
mmap.avd_units.push_back(unit);


vps->install_receive_hook(&mmap.vps_units, vps_receive_hook);
ad->install_receive_hook(&mmap.ad_units, ad_receive_hook);
ovd->install_receive_hook(&mmap.ovd_units, ovd_receive_hook);
gvd->install_receive_hook(&mmap.gvd_units, gvd_receive_hook);
avd->install_receive_hook(&mmap.avd_units, avd_receive_hook);
streams.vps->install_receive_hook(&mmap.vps_units, vps_receive_hook);
streams.ad->install_receive_hook(&mmap.ad_units, ad_receive_hook);
streams.ovd->install_receive_hook(&mmap.ovd_units, ovd_receive_hook);
streams.gvd->install_receive_hook(&mmap.gvd_units, gvd_receive_hook);
streams.avd->install_receive_hook(&mmap.avd_units, avd_receive_hook);


std::cout << "Waiting incoming packets for " << RECEIVE_TIME_S.count() << " s" << std::endl;
uint64_t ngops = 1;
uint64_t bytes = 0;
uint64_t ptr = 0;
bool hdb = true;
char* out_buf = new char[len];

while (ngops <= 1) {
if (is_gop_ready(ngops, mmap)) {
std::cout << "Full GoP received, num: " << ngops << std::endl;
bytes += reconstruct_v3c_gop(hdb, out_buf, ptr, mmap, ngops - 1);
std::cout << "File size " << bytes << std::endl;
std::cout << "GoP size " << bytes << std::endl;

ngops++;
hdb = false;
Expand All @@ -120,11 +93,11 @@ int main(void)

std::this_thread::sleep_for(RECEIVE_TIME_S); // lets this example run for some time

sess->destroy_stream(vps);
sess->destroy_stream(ad);
sess->destroy_stream(ovd);
sess->destroy_stream(gvd);
sess->destroy_stream(avd);
sess->destroy_stream(streams.vps);
sess->destroy_stream(streams.ad);
sess->destroy_stream(streams.ovd);
sess->destroy_stream(streams.gvd);
sess->destroy_stream(streams.avd);

ctx.destroy_session(sess);

Expand All @@ -141,50 +114,6 @@ int main(void)
return EXIT_SUCCESS;
}

void copy_rtp_payload(std::vector<v3c_unit_info> &units, uint64_t max_size, uvgrtp::frame::rtp_frame *frame)
{
if ((units.end() - 1)->nal_infos.size() == max_size) {
std::cout << "AD size == 35, adding new v3c_unit " << std::endl;
v3c_unit_header hdr = {(units.end()-1)->header.vuh_unit_type};
switch ((units.end()-1)->header.vuh_unit_type) {
case V3C_AD: {
hdr.ad = { (uint8_t)units.size(), 0 };
v3c_unit_info info = { hdr, {}, new char[400 * 1000], 0, false };
units.push_back(info);
break;
}
case V3C_OVD: {
hdr.ovd = { (uint8_t)units.size(), 0 };
v3c_unit_info info = { hdr, {}, new char[400 * 1000], 0, false };
units.push_back(info);
break;
}
case V3C_GVD: {
hdr.gvd = { (uint8_t)units.size(), 0, 0, 0 };
v3c_unit_info info = { hdr, {}, new char[400 * 1000], 0, false };
units.push_back(info);
break;
}
case V3C_AVD: {
hdr.avd = { (uint8_t)units.size(), 0 };
v3c_unit_info info = { hdr, {}, new char[40 * 1000 * 1000], 0, false };
units.push_back(info);
break;
}
}
}
auto &current = units.end() - 1;

if (current->nal_infos.size() <= max_size) {
memcpy(&current->buf[current->ptr], frame->payload, frame->payload_len);
current->nal_infos.push_back({ current->ptr, frame->payload_len });
current->ptr += frame->payload_len;
}
if (current->nal_infos.size() == max_size) {
current->ready = true;
}
}

void vps_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame)
{
std::cout << "Received VPS frame, size: " << frame->payload_len << " bytes" << std::endl;
Expand All @@ -203,31 +132,24 @@ void ad_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame)
std::vector<v3c_unit_info>* vec = (std::vector<v3c_unit_info>*)arg;

copy_rtp_payload(*vec, AD_NALS, frame);

//std::cout << "Done with AD frame, num: " << current->nal_infos.size() << std::endl;

(void)uvgrtp::frame::dealloc_frame(frame);
}
void ovd_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame)
{
//std::cout << "Received OVD frame, size: " << frame->payload_len << " bytes" << std::endl;
std::vector<v3c_unit_info>* vec = (std::vector<v3c_unit_info>*)arg;

copy_rtp_payload(*vec, OVD_NALS, frame);
(void)uvgrtp::frame::dealloc_frame(frame);
}
void gvd_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame)
{
//std::cout << "Received GVD frame, size: " << frame->payload_len << " bytes" << std::endl;
std::vector<v3c_unit_info>* vec = (std::vector<v3c_unit_info>*)arg;

copy_rtp_payload(*vec, GVD_NALS, frame);

(void)uvgrtp::frame::dealloc_frame(frame);
}
void avd_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame)
{
//std::cout << "Received AVD frame, size: " << frame->payload_len << " bytes" << std::endl;
std::vector<v3c_unit_info>* vec = (std::vector<v3c_unit_info>*)arg;

copy_rtp_payload(*vec, AVD_NALS, frame);
Expand Down
63 changes: 15 additions & 48 deletions examples/v3c_sender.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ std::string PATH = "C:\\Users\\ngheta\\Documents\\v3c_test_seq_2.vpcc";

void sender_func(uvgrtp::media_stream* stream, const char* cbuf, const std::vector<v3c_unit_info> &units, rtp_flags_t flags, int fmt);


int main(void)
{
std::cout << "Parsing V3C file" << std::endl;
Expand All @@ -36,45 +35,35 @@ int main(void)

/* Fetch the file and its size */
uint64_t len = get_size(PATH);
uint64_t ptr = 0;
char* cbuf = nullptr;
cbuf = get_cmem(PATH, len);
char* cbuf = get_cmem(PATH);

/* Map the locations and sizes of Atlas and video NAL units with the mmap_v3c_file function */
mmap_v3c_file(cbuf, len, mmap);

std::cout << "Sending Atlas NAL units via uvgRTP" << std::endl;
std::cout << "Sending V3C NAL units via uvgRTP" << std::endl;

/* Create the necessary uvgRTP media streams */
uvgrtp::context ctx;
uvgrtp::session* sess = ctx.create_session(REMOTE_ADDRESS, REMOTE_ADDRESS);
int flags = RCE_NO_FLAGS;

// Create the uvgRTP media streams with the correct RTP format
uvgrtp::media_stream* vps = sess->create_stream(8890, 8891, RTP_FORMAT_GENERIC, flags);
uvgrtp::media_stream* ad = sess->create_stream(8892, 8893, RTP_FORMAT_ATLAS, flags);
uvgrtp::media_stream* ovd = sess->create_stream(8894, 8895, RTP_FORMAT_H265, flags);
uvgrtp::media_stream* gvd = sess->create_stream(8896, 8897, RTP_FORMAT_H265, flags);
uvgrtp::media_stream* avd = sess->create_stream(8898, 8899, RTP_FORMAT_H265, flags);


uint64_t send_ptr = 0;
int flags = RCE_SEND_ONLY;
v3c_streams streams = init_v3c_streams(sess, 8892, 8890, flags, false);

/* Start sending data */
std::unique_ptr<std::thread> vps_thread =
std::unique_ptr<std::thread>(new std::thread(sender_func, vps, cbuf, mmap.vps_units, RTP_NO_FLAGS, V3C_VPS));
std::unique_ptr<std::thread>(new std::thread(sender_func, streams.vps, cbuf, mmap.vps_units, RTP_NO_FLAGS, V3C_VPS));

std::unique_ptr<std::thread> ad_thread =
std::unique_ptr<std::thread>(new std::thread(sender_func, ad, cbuf, mmap.ad_units, RTP_NO_FLAGS, V3C_AD));
std::unique_ptr<std::thread>(new std::thread(sender_func, streams.ad, cbuf, mmap.ad_units, RTP_NO_FLAGS, V3C_AD));

std::unique_ptr<std::thread> ovd_thread =
std::unique_ptr<std::thread>(new std::thread(sender_func, ovd, cbuf, mmap.ovd_units, RTP_NO_H26X_SCL, V3C_OVD));
std::unique_ptr<std::thread>(new std::thread(sender_func, streams.ovd, cbuf, mmap.ovd_units, RTP_NO_H26X_SCL, V3C_OVD));

std::unique_ptr<std::thread> gvd_thread =
std::unique_ptr<std::thread>(new std::thread(sender_func, gvd, cbuf, mmap.gvd_units, RTP_NO_H26X_SCL, V3C_GVD));
std::unique_ptr<std::thread>(new std::thread(sender_func, streams.gvd, cbuf, mmap.gvd_units, RTP_NO_H26X_SCL, V3C_GVD));

std::unique_ptr<std::thread> avd_thread =
std::unique_ptr<std::thread>(new std::thread(sender_func, avd, cbuf, mmap.avd_units, RTP_NO_H26X_SCL, V3C_AVD));
std::unique_ptr<std::thread>(new std::thread(sender_func, streams.avd, cbuf, mmap.avd_units, RTP_NO_H26X_SCL, V3C_AVD));

if (vps_thread && vps_thread->joinable())
{
Expand All @@ -97,11 +86,11 @@ int main(void)
avd_thread->join();
}

sess->destroy_stream(vps);
sess->destroy_stream(ad);
sess->destroy_stream(ovd);
sess->destroy_stream(gvd);
sess->destroy_stream(avd);
sess->destroy_stream(streams.vps);
sess->destroy_stream(streams.ad);
sess->destroy_stream(streams.ovd);
sess->destroy_stream(streams.gvd);
sess->destroy_stream(streams.avd);


std::cout << "Sending finished" << std::endl;
Expand All @@ -116,38 +105,16 @@ int main(void)

void sender_func(uvgrtp::media_stream* stream, const char* cbuf, const std::vector<v3c_unit_info> &units, rtp_flags_t flags, int fmt)
{
std::string filename = "results_" + std::to_string(fmt) + ".csv";
//std::ofstream myfile;
//myfile.open(filename);
//myfile << "Stream " + std::to_string(fmt) + ";;;Send time (microseconds) \n";
//myfile << "NAL number;NAL size(bytes);Cumulative bytes sent; Send time at 100 MBps;1 GBps; 10 GBps \n";
int index = 0;
uint64_t bytes_sent = 0;

for (auto& p : units) {
for (auto i : p.nal_infos) {
rtp_error_t ret = RTP_OK;
//std::cout << "Sending NAL unit in location " << i.location << " with size " << i.size << std::endl;
ret = stream->push_frame((uint8_t*)cbuf + i.location, i.size, flags);
if (ret == RTP_OK) {
index++;
bytes_sent += i.size;
double time_100m = bytes_sent / 100; // us so dont multiply *1000 * 1000;
double time_1g = bytes_sent / (1 * 1000); // us so dont multiply *1000 * 1000;
double time_10g = bytes_sent / (10 * 1000); // us so dont multiply *1000 * 1000;
std::string line = std::to_string(index) + ";" + std::to_string(i.size) + ";" + std::to_string(bytes_sent) + ";"
+ std::to_string(time_100m) + ";"
+ std::to_string(time_1g) + ";"
+ std::to_string(time_10g) + ";" + "\n";

//myfile << line;
}
else {
if (ret != RTP_OK) {
std::cout << "Failed to send RTP frame!" << std::endl;
}
}
}
//myfile.close();


}
Loading

0 comments on commit 3efbd09

Please sign in to comment.