v3c: Add documentation to the examples
This commit is contained in:
parent
6efede67a1
commit
f417e828ae
|
@ -451,7 +451,8 @@ uint64_t reconstruct_v3c_gop(bool hdr_byte, char* &buf, uint64_t& ptr, v3c_file_
|
||||||
gop_size += vps_size + ad_size + ovd_size + gvd_size + avd_size;
|
gop_size += vps_size + ad_size + ovd_size + gvd_size + avd_size;
|
||||||
std::cout << "Initializing GoP buffer of " << gop_size << " bytes" << std::endl;
|
std::cout << "Initializing GoP buffer of " << gop_size << " bytes" << std::endl;
|
||||||
|
|
||||||
buf = new char[gop_size];
|
// Commented out because we want to write the whole file into the buffer, not GoP by GoP
|
||||||
|
//buf = new char[gop_size];
|
||||||
|
|
||||||
// V3C Sample stream header
|
// V3C Sample stream header
|
||||||
if (hdr_byte) {
|
if (hdr_byte) {
|
||||||
|
@ -495,15 +496,15 @@ uint64_t reconstruct_v3c_gop(bool hdr_byte, char* &buf, uint64_t& ptr, v3c_file_
|
||||||
|
|
||||||
bool is_gop_ready(uint64_t index, v3c_file_map& mmap)
|
bool is_gop_ready(uint64_t index, v3c_file_map& mmap)
|
||||||
{
|
{
|
||||||
if (mmap.vps_units.size() < index)
|
if (mmap.vps_units.size() < index+1)
|
||||||
return false;
|
return false;
|
||||||
if (mmap.ad_units.size() < index || !mmap.ad_units.at(index - 1).ready)
|
if (mmap.ad_units.size() < index+1 || !mmap.ad_units.at(index).ready)
|
||||||
return false;
|
return false;
|
||||||
if (mmap.ovd_units.size() < index || !mmap.ovd_units.at(index - 1).ready)
|
if (mmap.ovd_units.size() < index+1 || !mmap.ovd_units.at(index).ready)
|
||||||
return false;
|
return false;
|
||||||
if (mmap.gvd_units.size() < index || !mmap.gvd_units.at(index - 1).ready)
|
if (mmap.gvd_units.size() < index+1 || !mmap.gvd_units.at(index).ready)
|
||||||
return false;
|
return false;
|
||||||
if (mmap.avd_units.size() < index || !mmap.avd_units.at(index - 1).ready)
|
if (mmap.avd_units.size() < index+1 || !mmap.avd_units.at(index).ready)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -80,12 +80,15 @@ struct nal_info {
|
||||||
uint64_t size = 0; // Sie of the NAL unit
|
uint64_t size = 0; // Sie of the NAL unit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* A v3c_unit_info contains all the required information of a V3C unit
|
||||||
|
- nal_info struct holds the format(Atlas, H264, H265, H266), start position and size of the NAL unit
|
||||||
|
- With this info you can send the data via different uvgRTP media streams. */
|
||||||
struct v3c_unit_info {
|
struct v3c_unit_info {
|
||||||
v3c_unit_header header;
|
v3c_unit_header header;
|
||||||
std::vector<nal_info> nal_infos = {};
|
std::vector<nal_info> nal_infos = {};
|
||||||
char* buf;
|
char* buf; // (used on the receiving end)
|
||||||
uint64_t ptr = 0;
|
uint64_t ptr = 0; // (used on the receiving end)
|
||||||
bool ready = false;
|
bool ready = false; // (used on the receiving end)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct v3c_file_map {
|
struct v3c_file_map {
|
||||||
|
|
|
@ -18,14 +18,21 @@ void avd_receive_hook(void* arg, uvgrtp::frame::rtp_frame* frame);
|
||||||
|
|
||||||
uint64_t vps_count;
|
uint64_t vps_count;
|
||||||
|
|
||||||
constexpr int VPS_NALS = 1;
|
/* These values specify the amount of NAL units inside each type of V3C unit. These need to be known to be able to reconstruct the
|
||||||
|
* file after receiving. These might be different for you depending on your test file. The sending example has prints that show
|
||||||
|
* how many NAL units each V3C unit contain. Change these accordingly. */
|
||||||
|
constexpr int VPS_NALS = 2;
|
||||||
constexpr int AD_NALS = 35;
|
constexpr int AD_NALS = 35;
|
||||||
constexpr int OVD_NALS = 35;
|
constexpr int OVD_NALS = 35;
|
||||||
constexpr int GVD_NALS = 131;
|
constexpr int GVD_NALS = 131;
|
||||||
constexpr int AVD_NALS = 131;
|
constexpr int AVD_NALS = 131;
|
||||||
|
|
||||||
|
/* How many Groups of Pictures we are expecting to receive */
|
||||||
constexpr int EXPECTED_GOPS = 1;
|
constexpr int EXPECTED_GOPS = 1;
|
||||||
|
|
||||||
std::string PATH = "C:\\Users\\ngheta\\Documents\\v3c_test_seq_2.vpcc";
|
/* 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 = "";
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
@ -44,7 +51,8 @@ int main(void)
|
||||||
|
|
||||||
// Create the uvgRTP media streams with the correct RTP format
|
// Create the uvgRTP media streams with the correct RTP format
|
||||||
v3c_streams streams = init_v3c_streams(sess, 8890, 8892, flags, true);
|
v3c_streams streams = init_v3c_streams(sess, 8890, 8892, flags, true);
|
||||||
//avd->configure_ctx(RCC_RING_BUFFER_SIZE, 40*1000*1000);
|
|
||||||
|
// Initialize memory map
|
||||||
v3c_file_map mmap = init_mmap();
|
v3c_file_map mmap = init_mmap();
|
||||||
|
|
||||||
streams.vps->install_receive_hook(&mmap.vps_units, vps_receive_hook);
|
streams.vps->install_receive_hook(&mmap.vps_units, vps_receive_hook);
|
||||||
|
@ -52,18 +60,19 @@ int main(void)
|
||||||
streams.ovd->install_receive_hook(&mmap.ovd_units, ovd_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.gvd->install_receive_hook(&mmap.gvd_units, gvd_receive_hook);
|
||||||
streams.avd->install_receive_hook(&mmap.avd_units, avd_receive_hook);
|
streams.avd->install_receive_hook(&mmap.avd_units, avd_receive_hook);
|
||||||
|
streams.avd->configure_ctx(RCC_RING_BUFFER_SIZE, 40 * 1000 * 1000);
|
||||||
|
|
||||||
std::cout << "Waiting incoming packets for " << RECEIVE_TIME_S.count() << " s" << std::endl;
|
std::cout << "Waiting incoming packets for " << RECEIVE_TIME_S.count() << " s" << std::endl;
|
||||||
uint64_t ngops = 1;
|
uint64_t ngops = 0;
|
||||||
uint64_t bytes = 0;
|
uint64_t bytes = 0;
|
||||||
uint64_t ptr = 0;
|
uint64_t ptr = 0;
|
||||||
bool hdb = true;
|
bool hdb = true;
|
||||||
char* out_buf = nullptr;
|
char* out_buf = new char[len]; // Initialize to nullptr if you want to output the file GoP by GoP
|
||||||
|
|
||||||
while (ngops <= EXPECTED_GOPS) {
|
while (ngops <= EXPECTED_GOPS) {
|
||||||
if (is_gop_ready(ngops, mmap)) {
|
if (is_gop_ready(ngops, mmap)) {
|
||||||
bytes += reconstruct_v3c_gop(hdb, out_buf, ptr, mmap, ngops - 1);
|
//ptr = 0; Don't reset the ptr because we are writing the whole file into the buffer
|
||||||
|
bytes += reconstruct_v3c_gop(hdb, out_buf, ptr, mmap, ngops);
|
||||||
std::cout << "Full GoP received, num: " << ngops << std::endl;
|
std::cout << "Full GoP received, num: " << ngops << std::endl;
|
||||||
ngops++;
|
ngops++;
|
||||||
hdb = false; // Only add the V3C Sample Stream header byte to only the first GoP
|
hdb = false; // Only add the V3C Sample Stream header byte to only the first GoP
|
||||||
|
|
|
@ -10,30 +10,38 @@
|
||||||
|
|
||||||
constexpr char REMOTE_ADDRESS[] = "127.0.0.1";
|
constexpr char REMOTE_ADDRESS[] = "127.0.0.1";
|
||||||
|
|
||||||
std::string PATH = "C:\\Users\\ngheta\\Documents\\v3c_test_seq_2.vpcc";
|
// Path to the V3C file that you want to send
|
||||||
|
std::string PATH = "";
|
||||||
void sender_func(uvgrtp::media_stream* stream, const char* cbuf, const std::vector<v3c_unit_info> &units, rtp_flags_t flags, int fmt);
|
void sender_func(uvgrtp::media_stream* stream, const char* cbuf, const std::vector<v3c_unit_info> &units, rtp_flags_t flags, int fmt);
|
||||||
|
|
||||||
std::atomic<uint64_t> bytes_sent;
|
std::atomic<uint64_t> bytes_sent;
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
/* This example demonstrates sending V3C Sample Stream files via uvgRTP. The V3C Sample Stream contains a V3C Sample Stream
|
||||||
|
* header byte and multiple V3C Units with their sizes specified before each unit. A V3C Unit then contains a V3C header
|
||||||
|
* and Atlas or Video NAL units, depending on the V3C unit type.
|
||||||
|
*
|
||||||
|
* The process of sending a V3C Cample Stream file via uvgRTP contains the following steps:
|
||||||
|
* Parse file and extract locations and sizes of NAL units -> Send NAL units in separate uvgRTP media streams
|
||||||
|
* -> Receive NAL units -> Reconstruct V3C Sample Stream
|
||||||
|
*
|
||||||
|
* In this example there are in total 5 media streams, one for each component:
|
||||||
|
* 1. Parameter set stream
|
||||||
|
* 2. Atlas stream
|
||||||
|
* 3. Occupancy Video stream
|
||||||
|
* 4. Geometry Video stream
|
||||||
|
* 5. Attribute Video Stream
|
||||||
|
*
|
||||||
|
* There is also the possibility to have two more streams: Packed Video and Common Atlas Data. These are not included in
|
||||||
|
* this example as our test files don't have them. If you need these, it should be quite easy to implement them
|
||||||
|
*
|
||||||
|
* A few notes for users: This example expects there to be no packet loss. If some NAL units are lost in transmission,
|
||||||
|
* the reconstruction will not work.
|
||||||
|
* Please also read the documentation on v3c_receiver.cc before testing this example. */
|
||||||
|
|
||||||
std::cout << "Parsing V3C file" << std::endl;
|
std::cout << "Parsing V3C file" << std::endl;
|
||||||
|
|
||||||
/* A V3C Sample stream is divided into 4 types of 'sub-bitstreams' + parameters.
|
/* Note: Use RTP_NO_H26X_SCL when sending video frames, as there is no start codes in the video sub-streams */
|
||||||
- In v3c_file_map there are vectors of
|
|
||||||
- V3C unit infos
|
|
||||||
- v3c_unit_infos
|
|
||||||
- header
|
|
||||||
- nal_infos
|
|
||||||
- buf
|
|
||||||
- ptr
|
|
||||||
- ready
|
|
||||||
|
|
||||||
- The nal_infos holds nal_info structs
|
|
||||||
- nal_info struct holds the format(Atlas, H264, H265, H266), start position and size of the NAL unit
|
|
||||||
- With this info you can send the data via different uvgRTP media streams.
|
|
||||||
|
|
||||||
Note: Use RTP_NO_H26X_SCL when sending video frames, as there is no start codes in the video sub-streams */
|
|
||||||
bytes_sent = 0;
|
bytes_sent = 0;
|
||||||
v3c_file_map mmap;
|
v3c_file_map mmap;
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,7 @@ inline void test_packet_size(std::unique_ptr<uint8_t[]> test_packet, int packets
|
||||||
Test_receiver* tester = new Test_receiver(packets);
|
Test_receiver* tester = new Test_receiver(packets);
|
||||||
|
|
||||||
int interval_ms = 1000/framerate;
|
int interval_ms = 1000/framerate;
|
||||||
if (format == RTP_FORMAT_V3C) {
|
if (format == RTP_FORMAT_ATLAS) {
|
||||||
add_hook(tester, receiver, v3c_rtp_hook);
|
add_hook(tester, receiver, v3c_rtp_hook);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in New Issue