uvgVPCCenc 1.0.0
uvgVPCCenc is an open-source real-time V-PCC encoder library written in C++ from scratch.
Loading...
Searching...
No Matches
uvgvpcc.hpp
Go to the documentation of this file.
1/*****************************************************************************
2 * This file is part of uvgVPCCenc V-PCC encoder.
3 *
4 * Copyright (c) 2024, Tampere University, ITU/ISO/IEC, project contributors
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without modification,
8 * are permitted provided that the following conditions are met:
9 *
10 * * Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright notice, this
14 * list of conditions and the following disclaimer in the documentation and/or
15 * other materials provided with the distribution.
16 *
17 * * Neither the name of the Tampere University or ITU/ISO/IEC nor the names of its
18 * contributors may be used to endorse or promote products derived from
19 * this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND ON
28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
31 ****************************************************************************/
32
33#pragma once
34
35#include <cstddef>
36#include <cstdint>
37#include <iostream>
38#include <memory>
39#include <queue>
40#include <semaphore>
41#include <sstream>
42#include <string>
43#include <vector>
44
45#include "../utils/utils.hpp"
46#include "../utils/parameters.hpp"
47
49
50// TODO(lf): why in include/uvgvpcc/ ? What about the related .cpp Why not "include/" only ?
51
52namespace uvgvpcc_enc {
53
54extern const Parameters* p_; // Const pointer to a non-const Parameter struct instance in parameters.cpp
55
56// A patch is a 3D object. Though, the word 'patch' can refer to the "2D version" of this patch
57struct Patch {
59 size_t patchPpi_; // viewId
60
61 size_t normalAxis_; // x
62 size_t tangentAxis_; // y
63 size_t bitangentAxis_; // z
64
65 size_t posU_; // u1_ minU_ // tangential shift
66 size_t posV_; // v1_ minV_ // bitangential shift
67 size_t posD_; // d1_ minD_ // depth shift
68
69 bool projectionMode_; // 0: related to the min depth value; 1: related to the max value
70
71 size_t sizeD_; // size for depth (TODO(lf): is it the real patch thickness or the maximum possible thickness?)
72
73 std::vector<uint8_t> patchOccupancyMap_; // patch occupancy map (boolean vector)
74
75 size_t widthInPixel_ = 0; // size for U // width of the patch occupancy map (in pixels)
76 size_t heightInPixel_ = 0; // size for V // height of the patch occupancy map (in pixels)
77
78 size_t widthInOccBlk_; // sizeU0_ // width of the patch occupancy map within the down-scaled frame occupancy map (in DS occupancy map blocks).
79 size_t heightInOccBlk_; // sizeV0_ // height of the patch occupancy map within the down-scaled frame occupancy map (in DS occupancy map blocks).
80
81 size_t omDSPosX_; // u0_ // location in down-scaled occupancy map // lf posBlkU
82 size_t omDSPosY_; // v0_ // location in down-scaled occupancy map
83
84 bool axisSwap_; // patch orientation // in canvas atlas (false default, true axis swap)
85
86 std::vector<typeGeometryInput> depthL1_; // depth value First layer // TODO(lf): Using the geo type here might lead to issue?
87 std::vector<typeGeometryInput> depthL2_; // depth value Second layer
88
89 // Index of the point in the PC for attribute retrieving during attribute map generation TODO(lf): use for Surface separation?
90 std::vector<size_t> depthPCidxL1_;
91 std::vector<size_t> depthPCidxL2_;
92
93
94 // inter packing //
95 size_t area_ = 0;
96
98 // Store the id of the best reference patch in the previous frame. Notice that even if the current patch is not
99 // matched, a reference patch id is still found. Then, this reference id will be used to check if the iou treshold
100 // is respected or not, then indicating if this patch is matched or not.
101
103 // Store not the id but the position in the list of patch of the best reference patch in the previous frame. Notice that even if
104 // the current patch is not matched, a reference patch id is still found. Then, this reference id will be used to check if the
105 // iou treshold is respected or not, then indicating if this patch is matched or not.
106 bool isMatched_ = false; // This patch match with a patch from the previous frame (the iou treshold is respected).
107 bool isLinkToAMegaPatch = false;
109
110 void setAxis(size_t normalAxis, size_t tangentAxis, size_t bitangentAxis, bool projectionMode) {
111 normalAxis_ = normalAxis;
112 tangentAxis_ = tangentAxis;
113 bitangentAxis_ = bitangentAxis;
114 projectionMode_ = projectionMode; // TODO(lf): projection mode optimization per patch
115 }
116
117 void setPatchPpi(size_t patchPpi) {
118 patchPpi_ = patchPpi;
119 // now set the other variables according to the viewId
120 switch (patchPpi_) {
121 case 0:
122 setAxis(0, 2, 1, 0);
123 break;
124 case 1:
125 setAxis(1, 2, 0, 0);
126 break;
127 case 2:
128 setAxis(2, 0, 1, 0);
129 break;
130 case 3:
131 setAxis(0, 2, 1, 1);
132 break;
133 case 4:
134 setAxis(1, 2, 0, 1);
135 break;
136 case 5:
137 setAxis(2, 0, 1, 1);
138 break;
139 default:
140 throw std::runtime_error("ViewId (" + std::to_string(patchPpi) + ") not allowed... exiting");
141 break;
142 }
143 }
144
145 std::string toString() const {
146 std::stringstream str;
147 str << "patchIndex=" << patchIndex_;
148 str << ", patchPpi=" << patchPpi_;
149 str << ", normalAxis=" << normalAxis_;
150 str << ", tangentAxis=" << tangentAxis_;
151 str << ", bitangentAxis=" << bitangentAxis_;
152 str << ", projectionMode=" << projectionMode_;
153 str << ", minU=" << posU_;
154 str << ", minV=" << posV_;
155 str << ", minD=" << posD_;
156 str << ", sizeD=" << sizeD_;
157 str << ", sizeU=" << widthInPixel_;
158 str << ", sizeV=" << heightInPixel_;
159 str << ", sizeUom=" << widthInOccBlk_;
160 str << ", sizeVom=" << heightInOccBlk_;
161 str << ", omDSPosX_=" << omDSPosX_;
162 str << ", omDSPosY_=" << omDSPosY_;
163 str << ", axisSwap=" << axisSwap_;
164 return str.str();
165 }
166};
167
168struct GOF;
169
170
171
172// TODO(lf): Avid using both constant sized and dynamic sized memory member within the same struct.
173struct Frame {
174 size_t frameId; // aka relative index (0 if first encoded frame)
175 size_t frameNumber; // aka number from the input frame file name
176 std::weak_ptr<GOF> gof;
177 std::shared_ptr<std::counting_semaphore<UINT16_MAX>> conccurentFrameSem;
178
179 std::string pointCloudPath;
180
182 std::vector<Vector3<typeGeometryInput>> pointsGeometry;
183 std::vector<Vector3<uint8_t>> pointsAttribute;
184
185 std::vector<Patch> patchList;
186 std::vector<size_t> patchPartition; // Associate a point index to the index of its patch
187
188 size_t mapHeight = 0; // TODO(lf): Will be a gof parameter ?
189 size_t mapHeightDS = 0;
190
191
192 std::vector<uint8_t> occupancyMap; // (boolean vector)
193 std::vector<uint8_t> occupancyMapDS; // Down-scaled occupancy map of the frame (boolean vector)
194
195 std::vector<uint8_t> geometryMapL1; // first layer
196 std::vector<uint8_t> geometryMapL2; // second layer
197
198 std::vector<uint8_t> attributeMapL1; // Store the three channels continuously (all R, then all G, than all B)
199 std::vector<uint8_t> attributeMapL2;
200
201 Frame(const size_t& frameId, const size_t& frameNumber, const std::string& pointCloudPath)
204 if (conccurentFrameSem) {
205 conccurentFrameSem->release();
206 }
207 };
208 void printInfo() const;
209};
210
211
212
213struct GOF {
214 std::vector<std::shared_ptr<Frame>> frames;
215 size_t nbFrames;
216 size_t gofId;
217
220
221 std::string baseNameOccupancy = "";
222 std::string baseNameOccupancyDS = "";
223 std::string baseNameGeometry = "";
224 std::string baseNameAttribute = "";
225
226 std::vector<uint8_t> bitstreamOccupancy;
227 std::vector<uint8_t> bitstreamGeometry;
228 std::vector<uint8_t> bitstreamAttribute;
229
231 const std::string gofIdStr = zeroPad(static_cast<int>(gofId), 3);
232 const std::string nbFramesStr = zeroPad(static_cast<int>(nbFrames), 3);
233
234 const std::string widthStr = std::to_string(param->mapWidth);
235 const std::string heightStr = std::to_string(mapHeightGOF);
236
237 const std::string widthOMStr = std::to_string(param->mapWidth / param->occupancyMapDSResolution);
238 const std::string heightOMStr = std::to_string(mapHeightGOF / param->occupancyMapDSResolution);
239
240
241 try {
243 baseNameOccupancy.replace(baseNameOccupancy.find("{GOFID}"), 7, gofIdStr)
244 .replace(baseNameOccupancy.find("{FRAMECOUNT}"), 12, nbFramesStr)
245 .replace(baseNameOccupancy.find("{WIDTH}"), 7, widthStr)
246 .replace(baseNameOccupancy.find("{HEIGHT}"), 8, heightStr);
247
249 baseNameOccupancyDS.replace(baseNameOccupancyDS.find("{GOFID}"), 7, gofIdStr)
250 .replace(baseNameOccupancyDS.find("{FRAMECOUNT}"), 12, nbFramesStr)
251 .replace(baseNameOccupancyDS.find("{WIDTH}"), 7, widthOMStr)
252 .replace(baseNameOccupancyDS.find("{HEIGHT}"), 8, heightOMStr);
253
255 baseNameGeometry.replace(baseNameGeometry.find("{GOFID}"), 7, gofIdStr)
256 .replace(baseNameGeometry.find("{FRAMECOUNT}"), 12, nbFramesStr)
257 .replace(baseNameGeometry.find("{WIDTH}"), 7, widthStr)
258 .replace(baseNameGeometry.find("{HEIGHT}"), 8, heightStr);
259
261 baseNameAttribute.replace(baseNameAttribute.find("{GOFID}"), 7, gofIdStr)
262 .replace(baseNameAttribute.find("{FRAMECOUNT}"), 12, nbFramesStr)
263 .replace(baseNameAttribute.find("{WIDTH}"), 7, widthStr)
264 .replace(baseNameAttribute.find("{HEIGHT}"), 8, heightStr);
265 } catch (const std::exception& e) {
266 throw std::runtime_error(
267 "\n# Catch an exception while completing the file base names :\n# " + std::string(e.what()) +
268 "\n# basenameOccupancyBlank : " + param->basenameOccupancyFiles + "\n# basenameOccupancy : " + baseNameOccupancy +
269 "\n# basenameOccupancyDSBlank : " + param->basenameOccupancyDSFiles + "\n# basenameOccupancy : " + baseNameOccupancyDS +
270 "\n# basenameGeometryBlank : " + param->basenameGeometryFiles + "\n# basenameGeometry : " + baseNameGeometry +
271 "\n# basenameAttributeBlank : " + param->basenameAttributeFiles + "\n# basenameAttribute : " + baseNameAttribute + "\n");
272 }
273 }
274};
275
277namespace API {
278
280struct v3c_chunk {
281 size_t len = 0; // Length of data in buffer
282 std::unique_ptr<char[]> data; // Actual data (char type can be used to describe a byte. No need for uint8_t or unsigned char types.)
283 std::vector<size_t> v3c_unit_sizes = {};
284
285 v3c_chunk() = default;
286 v3c_chunk(size_t len, std::unique_ptr<char[]> data) : len(len), data(std::move(data)) {}
287};
288
289// ht: A V3C unit stream is composed of only V3C units without parsing information in the bitstream itself. The parsing information is here given separately.
292 std::queue<v3c_chunk> v3c_chunks = {};
293 std::counting_semaphore<> available_chunks{0};
294 std::mutex io_mutex; // Locks production and consumption in the v3c_chunks queue
295};
296
297void initializeEncoder();
298void setParameter(const std::string& parameterName,const std::string& parameterValue);
299void encodeFrame(std::shared_ptr<Frame>& frame, v3c_unit_stream* output);
300void emptyFrameQueue();
301void stopEncoder();
302
303} // namespace API
304
305}; // namespace uvgvpcc_enc
void stopEncoder()
Insure a proper end of the encoder execution.
Definition uvgvpcc.cpp:598
void initializeEncoder()
Create the context of the uvgVPCCenc encoder. Parse the input parameters and verify if the given conf...
Definition uvgvpcc.cpp:466
void setParameter(const std::string &parameterName, const std::string &parameterValue)
The only way to modify the exposed uvgVPCCenc parameters is by calling this function.
Definition uvgvpcc.cpp:481
void emptyFrameQueue()
This function is called when all frames to be processed have been sent to the encoder....
Definition uvgvpcc.cpp:583
void encodeFrame(std::shared_ptr< Frame > &frame, v3c_unit_stream *output)
Entry point of the uvgVPCCenc library. Take as input a frame. Create all the jobs for processing this...
Definition uvgvpcc.cpp:496
Definition log.hpp:43
std::string zeroPad(size_t value, size_t width)
Definition utils.hpp:102
constexpr size_t INVALID_PATCH_INDEX
Definition utils.hpp:55
const Parameters * p_
Definition uvgvpcc.cpp:447
const size_t g_infinitenumber
Definition utils.hpp:52
Bitstream writing miscellaneous.
Definition uvgvpcc.hpp:280
std::unique_ptr< char[]> data
Definition uvgvpcc.hpp:282
v3c_chunk(size_t len, std::unique_ptr< char[]> data)
Definition uvgvpcc.hpp:286
size_t len
Definition uvgvpcc.hpp:281
std::vector< size_t > v3c_unit_sizes
Definition uvgvpcc.hpp:283
Definition uvgvpcc.hpp:290
std::queue< v3c_chunk > v3c_chunks
Definition uvgvpcc.hpp:292
std::counting_semaphore available_chunks
Definition uvgvpcc.hpp:293
std::mutex io_mutex
Definition uvgvpcc.hpp:294
size_t v3c_unit_size_precision_bytes
Definition uvgvpcc.hpp:291
Definition uvgvpcc.hpp:173
size_t mapHeight
Definition uvgvpcc.hpp:188
std::string pointCloudPath
Definition uvgvpcc.hpp:179
std::vector< uint8_t > attributeMapL2
Definition uvgvpcc.hpp:199
std::vector< size_t > patchPartition
Definition uvgvpcc.hpp:186
size_t pointCount
Definition uvgvpcc.hpp:181
std::weak_ptr< GOF > gof
Definition uvgvpcc.hpp:176
std::vector< uint8_t > geometryMapL2
Definition uvgvpcc.hpp:196
std::vector< uint8_t > occupancyMap
Definition uvgvpcc.hpp:192
Frame(const size_t &frameId, const size_t &frameNumber, const std::string &pointCloudPath)
Definition uvgvpcc.hpp:201
std::shared_ptr< std::counting_semaphore< UINT16_MAX > > conccurentFrameSem
Definition uvgvpcc.hpp:177
std::vector< uint8_t > geometryMapL1
Definition uvgvpcc.hpp:195
std::vector< uint8_t > attributeMapL1
Definition uvgvpcc.hpp:198
std::vector< Vector3< uint8_t > > pointsAttribute
Definition uvgvpcc.hpp:183
~Frame()
Definition uvgvpcc.hpp:203
std::vector< Patch > patchList
Definition uvgvpcc.hpp:185
size_t mapHeightDS
Definition uvgvpcc.hpp:189
size_t frameNumber
Definition uvgvpcc.hpp:175
std::vector< Vector3< typeGeometryInput > > pointsGeometry
Definition uvgvpcc.hpp:182
void printInfo() const
Definition uvgvpcc.cpp:450
size_t frameId
Definition uvgvpcc.hpp:174
std::vector< uint8_t > occupancyMapDS
Definition uvgvpcc.hpp:193
Definition uvgvpcc.hpp:213
std::vector< std::shared_ptr< Frame > > frames
Definition uvgvpcc.hpp:214
size_t mapHeightGOF
Definition uvgvpcc.hpp:218
std::string baseNameGeometry
Definition uvgvpcc.hpp:223
std::string baseNameAttribute
Definition uvgvpcc.hpp:224
std::vector< uint8_t > bitstreamAttribute
Definition uvgvpcc.hpp:228
std::vector< uint8_t > bitstreamGeometry
Definition uvgvpcc.hpp:227
size_t nbFrames
Definition uvgvpcc.hpp:215
size_t mapHeightDSGOF
Definition uvgvpcc.hpp:219
std::string baseNameOccupancy
Definition uvgvpcc.hpp:221
void completeFileBaseNames(const Parameters *param)
Definition uvgvpcc.hpp:230
std::string baseNameOccupancyDS
Definition uvgvpcc.hpp:222
size_t gofId
Definition uvgvpcc.hpp:216
std::vector< uint8_t > bitstreamOccupancy
Definition uvgvpcc.hpp:226
Definition parameters.hpp:48
std::string basenameGeometryFiles
Definition parameters.hpp:137
size_t mapWidth
Definition parameters.hpp:120
std::string basenameOccupancyDSFiles
Definition parameters.hpp:136
size_t occupancyMapDSResolution
Definition parameters.hpp:148
std::string basenameAttributeFiles
Definition parameters.hpp:138
std::string basenameOccupancyFiles
Definition parameters.hpp:135
Definition uvgvpcc.hpp:57
size_t posU_
Definition uvgvpcc.hpp:65
bool isLinkToAMegaPatch
Definition uvgvpcc.hpp:107
bool axisSwap_
Definition uvgvpcc.hpp:84
size_t widthInPixel_
Definition uvgvpcc.hpp:75
size_t patchIndex_
Definition uvgvpcc.hpp:58
size_t area_
Definition uvgvpcc.hpp:95
std::string toString() const
Definition uvgvpcc.hpp:145
size_t sizeD_
Definition uvgvpcc.hpp:71
std::vector< typeGeometryInput > depthL2_
Definition uvgvpcc.hpp:87
size_t heightInOccBlk_
Definition uvgvpcc.hpp:79
void setPatchPpi(size_t patchPpi)
Definition uvgvpcc.hpp:117
bool projectionMode_
Definition uvgvpcc.hpp:69
size_t omDSPosY_
Definition uvgvpcc.hpp:82
size_t posD_
Definition uvgvpcc.hpp:67
size_t bestMatchIdx
Definition uvgvpcc.hpp:102
size_t bitangentAxis_
Definition uvgvpcc.hpp:63
size_t normalAxis_
Definition uvgvpcc.hpp:61
std::vector< size_t > depthPCidxL2_
Definition uvgvpcc.hpp:91
size_t referencePatchId_
Definition uvgvpcc.hpp:97
std::vector< typeGeometryInput > depthL1_
Definition uvgvpcc.hpp:86
bool isMatched_
Definition uvgvpcc.hpp:106
size_t heightInPixel_
Definition uvgvpcc.hpp:76
std::vector< size_t > depthPCidxL1_
Definition uvgvpcc.hpp:90
size_t tangentAxis_
Definition uvgvpcc.hpp:62
size_t posV_
Definition uvgvpcc.hpp:66
std::vector< uint8_t > patchOccupancyMap_
Definition uvgvpcc.hpp:73
size_t unionPatchReferenceIdx
Definition uvgvpcc.hpp:108
size_t widthInOccBlk_
Definition uvgvpcc.hpp:78
void setAxis(size_t normalAxis, size_t tangentAxis, size_t bitangentAxis, bool projectionMode)
Definition uvgvpcc.hpp:110
size_t omDSPosX_
Definition uvgvpcc.hpp:81
size_t patchPpi_
Definition uvgvpcc.hpp:59