From ad9095978ab5f790d2121b231ab71a77cd703dcb Mon Sep 17 00:00:00 2001 From: Heikki Tampio Date: Tue, 21 Nov 2023 13:27:11 +0200 Subject: [PATCH] v3c: Clean up code, add documentation --- examples/v3c/v3c_util.cc | 43 +++++++++++++++++++++------------------- examples/v3c/v3c_util.hh | 10 +++++----- examples/v3c_receiver.cc | 42 ++++++++++++++++++++------------------- examples/v3c_sender.cc | 2 +- 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/examples/v3c/v3c_util.cc b/examples/v3c/v3c_util.cc index 5b4d2b2..05bee4e 100644 --- a/examples/v3c/v3c_util.cc +++ b/examples/v3c/v3c_util.cc @@ -70,7 +70,8 @@ bool mmap_v3c_file(char* cbuf, uint64_t len, v3c_file_map &mmap) if (vuh_t == V3C_VPS) { // Parameter set contains no NAL units, skip over std::cout << "-- Parameter set V3C unit" << std::endl; - unit.nal_infos.push_back({ ptr, combined_v3c_size }); + nal_info nalu = {ptr, combined_v3c_size, nullptr}; + unit.nal_infos.push_back(nalu); mmap.vps_units.push_back(unit); ptr += combined_v3c_size; std::cout << std::endl; @@ -113,9 +114,10 @@ bool mmap_v3c_file(char* cbuf, uint64_t len, v3c_file_map &mmap) v3c_ptr += nal_size_precision; switch (vuh_t) { case V3C_AD: - case V3C_CAD: - std::cout << " -- v3c_ptr: " << v3c_ptr << ", NALU size: " << combined_nal_size << std::endl; - break; + case V3C_CAD: { + uint8_t atlas_nalu_t = (cbuf[v3c_ptr] & 0b01111110) >> 1; + std::cout << " -- v3c_ptr: " << v3c_ptr << ", NALU size: " << combined_nal_size << ", Atlas NALU type: " << (uint32_t)atlas_nalu_t << std::endl; + break; } case V3C_OVD: case V3C_GVD: case V3C_AVD: @@ -123,7 +125,8 @@ bool mmap_v3c_file(char* cbuf, uint64_t len, v3c_file_map &mmap) uint8_t h265_nalu_t = (cbuf[v3c_ptr] & 0b01111110) >> 1; std::cout << " -- v3c_ptr: " << v3c_ptr << ", NALU size: " << combined_nal_size << ", HEVC NALU type: " << (uint32_t)h265_nalu_t << std::endl; } - unit.nal_infos.push_back({ v3c_ptr, combined_nal_size }); + nal_info nalu = { v3c_ptr, combined_nal_size, nullptr }; + unit.nal_infos.push_back({ v3c_ptr, combined_nal_size, nullptr }); v3c_ptr += combined_nal_size; } @@ -426,9 +429,9 @@ void create_v3c_unit(v3c_unit_info& current_unit, char* buf, uint64_t& ptr, uint } -uint64_t reconstruct_v3c_gop(bool hdr_byte, char* &buf, uint64_t& ptr, v3c_file_map& mmap, uint64_t index) +uint64_t reconstruct_v3c_gof(bool hdr_byte, char* &buf, uint64_t& ptr, v3c_file_map& mmap, uint64_t index) { - /* Calculate GoP size and intiialize the output buffer + /* Calculate GOF size and intiialize the output buffer * + 1 byte of Sample Stream Precision +----------------------------------------------------------------+ @@ -458,9 +461,9 @@ uint64_t reconstruct_v3c_gop(bool hdr_byte, char* &buf, uint64_t& ptr, v3c_file_ + NALs count (4 bytes of NAL Unit Size + x2 bytes of NAL unit payload) +----------------------------------------------------------------+ */ - uint64_t gop_size = 0; + uint64_t gof_size = 0; if (hdr_byte) { - gop_size++; // Sample Stream Precision + gof_size++; // Sample Stream Precision } // These sizes include the V3C unit size field, header and payload @@ -469,11 +472,11 @@ uint64_t reconstruct_v3c_gop(bool hdr_byte, char* &buf, uint64_t& ptr, v3c_file_ uint64_t ovd_size = V3C_SIZE_PRECISION + 4 + mmap.ovd_units.at(index).ptr + mmap.ovd_units.at(index).nal_infos.size() * VIDEO_NAL_SIZE_PRECISION; uint64_t gvd_size = V3C_SIZE_PRECISION + 4 + mmap.gvd_units.at(index).ptr + mmap.gvd_units.at(index).nal_infos.size() * VIDEO_NAL_SIZE_PRECISION; uint64_t avd_size = V3C_SIZE_PRECISION + 4 + mmap.avd_units.at(index).ptr + mmap.avd_units.at(index).nal_infos.size() * VIDEO_NAL_SIZE_PRECISION; - gop_size += vps_size + ad_size + ovd_size + gvd_size + avd_size; - std::cout << "Initializing GoP buffer of " << gop_size << " bytes" << std::endl; + gof_size += vps_size + ad_size + ovd_size + gvd_size + avd_size; + std::cout << "Initializing GOF buffer of " << gof_size << " bytes" << std::endl; - // Commented out because we want to write the whole file into the buffer, not GoP by GoP - //buf = new char[gop_size]; + // Commented out because we want to write the whole file into the buffer, not GOF by GOF + //buf = new char[gof_size]; // V3C Sample stream header if (hdr_byte) { @@ -513,10 +516,10 @@ uint64_t reconstruct_v3c_gop(bool hdr_byte, char* &buf, uint64_t& ptr, v3c_file_ current_unit = mmap.avd_units.at(index); create_v3c_unit(current_unit, buf, ptr, V3C_SIZE_PRECISION, VIDEO_NAL_SIZE_PRECISION); - return gop_size; + return gof_size; } -bool is_gop_ready(uint64_t index, v3c_file_map& mmap) +bool is_gof_ready(uint64_t index, v3c_file_map& mmap) { if (mmap.vps_units.size() < index+1) return false; @@ -570,11 +573,11 @@ void copy_rtp_payload(std::vector* units, uint64_t max_size, uvgr } } -uint64_t get_gop_size(bool hdr_byte, uint64_t index, v3c_file_map& mmap) +uint64_t get_gof_size(bool hdr_byte, uint64_t index, v3c_file_map& mmap) { - uint64_t gop_size = 0; + uint64_t gof_size = 0; if (hdr_byte) { - gop_size++; // Sample Stream Precision + gof_size++; // Sample Stream Precision } // These sizes include the V3C unit size field, header and payload @@ -583,6 +586,6 @@ uint64_t get_gop_size(bool hdr_byte, uint64_t index, v3c_file_map& mmap) uint64_t ovd_size = V3C_SIZE_PRECISION + 4 + mmap.ovd_units.at(index).ptr + mmap.ovd_units.at(index).nal_infos.size() * VIDEO_NAL_SIZE_PRECISION; uint64_t gvd_size = V3C_SIZE_PRECISION + 4 + mmap.gvd_units.at(index).ptr + mmap.gvd_units.at(index).nal_infos.size() * VIDEO_NAL_SIZE_PRECISION; uint64_t avd_size = V3C_SIZE_PRECISION + 4 + mmap.avd_units.at(index).ptr + mmap.avd_units.at(index).nal_infos.size() * VIDEO_NAL_SIZE_PRECISION; - gop_size += vps_size + ad_size + ovd_size + gvd_size + avd_size; - return gop_size; + gof_size += vps_size + ad_size + ovd_size + gvd_size + avd_size; + return gof_size; } \ No newline at end of file diff --git a/examples/v3c/v3c_util.hh b/examples/v3c/v3c_util.hh index 27c5cff..5dcf265 100644 --- a/examples/v3c/v3c_util.hh +++ b/examples/v3c/v3c_util.hh @@ -137,10 +137,10 @@ void copy_rtp_payload(std::vector* units, uint64_t max_size, uvgr // Combine a complete V3C unit from received NAL units void create_v3c_unit(v3c_unit_info& current_unit, char* buf, uint64_t& ptr, uint64_t v3c_precision, uint32_t nal_precision); -// Reconstruct a whole GoP from V3C Units -uint64_t reconstruct_v3c_gop(bool hdr_byte, char* &buf, uint64_t& ptr, v3c_file_map& mmap, uint64_t index); +// Reconstruct a whole GOF from V3C Units +uint64_t reconstruct_v3c_gof(bool hdr_byte, char* &buf, uint64_t& ptr, v3c_file_map& mmap, uint64_t index); -// Check if there is a complete GoP in the memory map -bool is_gop_ready(uint64_t index, v3c_file_map& mmap); +// Check if there is a complete GOF in the memory map +bool is_gof_ready(uint64_t index, v3c_file_map& mmap); -uint64_t get_gop_size(bool hdr_byte, uint64_t index, v3c_file_map& mmap); \ No newline at end of file +uint64_t get_gof_size(bool hdr_byte, uint64_t index, v3c_file_map& mmap); \ No newline at end of file diff --git a/examples/v3c_receiver.cc b/examples/v3c_receiver.cc index d38e8f3..8b5badf 100644 --- a/examples/v3c_receiver.cc +++ b/examples/v3c_receiver.cc @@ -27,14 +27,13 @@ constexpr int OVD_NALS = 35; constexpr int GVD_NALS = 131; constexpr int AVD_NALS = 131; -/* How many Groups of Pictures we are expecting to receive */ -constexpr int EXPECTED_GOPS = 10; +/* How many Groups of Frames we are expecting to receive */ +constexpr int EXPECTED_GOFS = 10; /* Path to the V3C file that we are receiving.This is included so that you can check that the reconstructed file is equal to the * original one */ std::string PATH = ""; - -std::string RESULT_FILENAME = "received_basketball.vpcc"; +std::string RESULT_FILENAME = "received.vpcc"; bool write_file(const char* data, size_t len, const std::string& filename); @@ -67,31 +66,31 @@ int main(void) streams.avd->configure_ctx(RCC_RING_BUFFER_SIZE, 40 * 1000 * 1000); std::cout << "Waiting incoming packets for " << RECEIVE_TIME_S.count() << " s" << std::endl; - uint64_t ngops = 0; + uint64_t ngofs = 0; uint64_t bytes = 0; uint64_t ptr = 0; bool hdb = true; - struct gop_info { + struct gof_info { uint64_t size = 0; char* buf = nullptr; }; - std::map gops_buf = {}; + std::map gofs_buf = {}; - while (ngops < EXPECTED_GOPS) { - if (is_gop_ready(ngops, mmap)) { - uint64_t gop_len = get_gop_size(hdb, ngops, mmap); - gop_info cur = {gop_len, new char[gop_len]}; - gops_buf.insert({ ngops, cur }); + while (ngofs < EXPECTED_GOFS) { + if (is_gof_ready(ngofs, mmap)) { + uint64_t gof_len = get_gof_size(hdb, ngofs, mmap); + gof_info cur = {gof_len, new char[gof_len]}; + gofs_buf.insert({ ngofs, cur }); ptr = 0; //Don't reset the ptr because we are writing the whole file into the buffer - bytes += reconstruct_v3c_gop(hdb, gops_buf.at(ngops).buf, ptr, mmap, ngops); - std::cout << "Full GoP received, num: " << ngops << std::endl; - ngops++; - hdb = false; // Only add the V3C Sample Stream header byte to only the first GoP + bytes += reconstruct_v3c_gof(hdb, gofs_buf.at(ngofs).buf, ptr, mmap, ngofs); + std::cout << "Full GOF received, num: " << ngofs << std::endl; + ngofs++; + hdb = false; // Only add the V3C Sample Stream header byte to only the first GOF } std::this_thread::sleep_for(std::chrono::milliseconds(10)); } std::cout << "output file size " << bytes << std::endl; - std::this_thread::sleep_for(RECEIVE_TIME_S); // lets this example run for some time + //std::this_thread::sleep_for(RECEIVE_TIME_S); // lets this example run for some time sess->destroy_stream(streams.vps); sess->destroy_stream(streams.ad); @@ -101,23 +100,26 @@ int main(void) ctx.destroy_session(sess); - char* out_buf = new char[bytes]; // Initialize to nullptr if you want to output the file GoP by GoP + char* out_buf = new char[bytes]; uint64_t ptr2 = 0; - // reconstruct file from gops - for (auto& p : gops_buf) { + // reconstruct file from gofs + for (auto& p : gofs_buf) { memcpy(&out_buf[ptr2], p.second.buf , p.second.size); ptr2 += p.second.size; } // compare files + for (auto i = 0; i < bytes; ++i) { if (original_buf[i] != out_buf[i]) { std::cout << "Difference at " << i << std::endl; //break; } } + /* std::cout << "Writing to file " << RESULT_FILENAME << std::endl; write_file(out_buf, bytes, RESULT_FILENAME); + */ std::cout << "Done" << std::endl; return EXIT_SUCCESS; diff --git a/examples/v3c_sender.cc b/examples/v3c_sender.cc index 18dfffc..d8ad339 100644 --- a/examples/v3c_sender.cc +++ b/examples/v3c_sender.cc @@ -127,6 +127,6 @@ void sender_func(uvgrtp::media_stream* stream, const char* cbuf, const std::vect } bytes_sent += i.size; } - std::this_thread::sleep_for(std::chrono::milliseconds(300)); + //std::this_thread::sleep_for(std::chrono::milliseconds(300)); } }