Skip to content

Commit 00235ad

Browse files
committed
Support passing through user data per frame
This is guarded under `#if VVENC_USE_UNSTABLE_API` and disabled by default due to requiring breaking changes to the ABI. It can only be unguarded when the major version is bumped to v2. Closes #480
1 parent 9169430 commit 00235ad

File tree

11 files changed

+61
-2
lines changed

11 files changed

+61
-2
lines changed

CMakeLists.txt

+9
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ set( VVENC_INSTALL_FULLFEATURE_APP OFF CACHE BOOL "Install the full-f
179179

180180
set( VVENC_ENABLE_WERROR ON CACHE BOOL "Treat warnings as errors (-Werror or /WX)" )
181181

182+
set( VVENC_ENABLE_UNSTABLE_API OFF CACHE BOOL "Enable unstable API" )
183+
182184
if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
183185
CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
184186

@@ -290,6 +292,13 @@ if( VVENC_ENABLE_WERROR )
290292
add_compile_options( "$<$<CXX_COMPILER_ID:MSVC>:/WX>" )
291293
endif()
292294

295+
set( VVENC_USE_UNSTABLE_API 0 )
296+
if( VVENC_ENABLE_UNSTABLE_API )
297+
set( VVENC_USE_UNSTABLE_API 1 )
298+
endif()
299+
300+
configure_file( include/vvenc/vvenc.h.in ${CMAKE_BINARY_DIR}/vvenc/vvenc.h @ONLY )
301+
293302
if( VVENC_ENABLE_X86_SIMD )
294303
if( ( UNIX OR MINGW ) AND VVENC_OPT_TARGET_ARCH )
295304
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=${VVENC_OPT_TARGET_ARCH} -mtune=${VVENC_OPT_TARGET_ARCH}" )

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ ifneq ($(enable-werror),)
8282
CONFIG_OPTIONS += -DVVENC_ENABLE_WERROR=$(enable-werror)
8383
endif
8484

85+
ifneq ($(enable-unstable-api),)
86+
CONFIG_OPTIONS += -DVVENC_ENABLE_UNSTABLE_API=$(enable-unstable-api)
87+
endif
88+
8589
ifeq ($(j),)
8690
# Query cmake for the number of cores
8791
NUM_JOBS := $(shell cmake -P cmake/modules/vvencNumCores.cmake)

cmake/modules/vvencInstall.cmake

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ endmacro( install_exe_pdb )
6060
target_include_directories( vvenc SYSTEM INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> )
6161

6262
# install headers
63-
install( FILES ${CMAKE_BINARY_DIR}/vvenc/version.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/vvenc )
64-
install( DIRECTORY include/vvenc DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
63+
install( DIRECTORY ${CMAKE_BINARY_DIR}/vvenc DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
64+
install( DIRECTORY include/vvenc DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} PATTERN "*.in" EXCLUDE )
6565

6666
# install targets
6767
install_targets( Release )

include/vvenc/vvenc.h renamed to include/vvenc/vvenc.h.in

+8
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ POSSIBILITY OF SUCH DAMAGE.
5858
#define VVENC_NAMESPACE_BEGIN
5959
#define VVENC_NAMESPACE_END
6060

61+
#define VVENC_USE_UNSTABLE_API @VVENC_USE_UNSTABLE_API@
62+
6163
#ifdef __cplusplus
6264
extern "C" {
6365
#endif
@@ -135,6 +137,9 @@ typedef struct vvencYUVBuffer
135137
uint64_t sequenceNumber; // sequence number of the picture
136138
uint64_t cts; // composition time stamp in TicksPerSecond
137139
bool ctsValid; // composition time stamp valid flag (true: valid, false: CTS not set)
140+
#if VVENC_USE_UNSTABLE_API
141+
void* userData; // user data to be returned in corresponding access unit
142+
#endif
138143
}vvencYUVBuffer;
139144

140145
/* vvenc_YUVBuffer_alloc:
@@ -196,6 +201,9 @@ typedef struct vvencAccessUnit
196201
int status; // additional info (see Status)
197202
int essentialBytes; // number of bytes in nalus of type SLICE_*, DCI, VPS, SPS, PPS, PREFIX_APS, SUFFIX_APS
198203
char infoString[VVENC_MAX_STRING_LEN]; // debug info from inside the encoder
204+
#if VVENC_USE_UNSTABLE_API
205+
void* userData; // user data passed in corresponding input YUV buffer
206+
#endif
199207
} vvencAccessUnit;
200208

201209
/* vvenc_accessUnit_alloc:

source/Lib/CommonLib/Nal.h

+2
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ class AccessUnitList : public std::list<NALUnitEBSP*> // NOTE: Should not inheri
178178
rap = false;
179179
refPic = false;
180180
InfoString.clear();
181+
userData = nullptr;
181182

182183
for( AccessUnitList::iterator it = this->begin(); it != this->end(); it++ )
183184
{
@@ -202,6 +203,7 @@ class AccessUnitList : public std::list<NALUnitEBSP*> // NOTE: Should not inheri
202203
bool rap; ///< random access point flag
203204
bool refPic; ///< reference picture
204205
std::string InfoString;
206+
void* userData; ///< user data passed in corresponding input YUV buffer
205207
};
206208

207209

source/Lib/CommonLib/Picture.h

+2
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ struct Picture : public UnitArea
293293
std::vector<uint8_t> m_alfCtuAlternative[ MAX_NUM_COMP ];
294294
std::vector<std::atomic<int>>* m_tileColsDone = nullptr;
295295

296+
void* userData;
297+
296298
public:
297299
Slice* allocateNewSlice();
298300
Slice* swapSliceObject( Slice* p, uint32_t i );

source/Lib/EncoderLib/EncGOP.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -2455,6 +2455,7 @@ void EncGOP::xWritePicture( Picture& pic, AccessUnitList& au, bool isEncodeLtRef
24552455
au.poc = pic.poc;
24562456
au.temporalLayer = pic.TLayer;
24572457
au.refPic = pic.isReferenced;
2458+
au.userData = pic.userData;
24582459
if( ! pic.slices.empty() )
24592460
{
24602461
au.sliceType = pic.slices[ 0 ]->sliceType;

source/Lib/EncoderLib/EncStage.h

+6
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class PicShared
8282
bool m_isLead;
8383
bool m_isTrail;
8484
bool m_ctsValid;
85+
void* m_userData;
8586

8687
public:
8788
PicShared()
@@ -99,6 +100,7 @@ class PicShared
99100
, m_isLead ( false )
100101
, m_isTrail ( false )
101102
, m_ctsValid ( false )
103+
, m_userData ( nullptr )
102104
{
103105
std::fill_n( m_prevShared, NUM_QPA_PREV_FRAMES, nullptr );
104106
std::fill_n( m_minNoiseLevels, QPA_MAX_NOISE_LEVELS, 255u );
@@ -150,6 +152,9 @@ class PicShared
150152
std::fill_n( m_prevShared, NUM_QPA_PREV_FRAMES, nullptr );
151153
std::fill_n( m_minNoiseLevels, QPA_MAX_NOISE_LEVELS, 255u );
152154
m_gopEntry.setDefaultGOPEntry();
155+
#if VVENC_USE_UNSTABLE_API
156+
m_userData = yuvInBuf->userData;
157+
#endif
153158
}
154159

155160
void shareData( Picture* pic )
@@ -165,6 +170,7 @@ class PicShared
165170
pic->cts = m_cts;
166171
pic->ctsValid = m_ctsValid;
167172
pic->gopEntry = &m_gopEntry;
173+
pic->userData = m_userData;
168174
incUsed();
169175
}
170176

source/Lib/vvenc/vvenc.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ VVENC_DECL void vvenc_accessUnit_reset(vvencAccessUnit *accessUnit )
193193
accessUnit->poc = 0;
194194
accessUnit->status = 0;
195195
accessUnit->essentialBytes = 0;
196+
#if VVENC_USE_UNSTABLE_API
197+
accessUnit->userData = nullptr;
198+
#endif
196199

197200
memset( accessUnit->infoString, 0, sizeof( accessUnit->infoString ) );
198201
accessUnit->infoString[0] ='\0';

source/Lib/vvenc/vvencimpl.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,9 @@ int VVEncImpl::xCopyAu( vvencAccessUnit& rcAccessUnit, const vvenc::AccessUnitLi
761761
rcAccessUnit.temporalLayer = rcAuList.temporalLayer;
762762
rcAccessUnit.poc = rcAuList.poc;
763763
rcAccessUnit.status = rcAuList.status;
764+
#if VVENC_USE_UNSTABLE_API
765+
rcAccessUnit.userData = rcAuList.userData;
766+
#endif
764767

765768
if ( !rcAuList.InfoString.empty() )
766769
{

test/vvenclibtest/vvenclibtest.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ POSSIBILITY OF SUCH DAMAGE.
5454
#include <cstring>
5555
#include <vector>
5656
#include <tuple>
57+
#include <unordered_set>
5758

5859
#include "vvenc/version.h"
5960
#include "vvenc/vvenc.h"
@@ -924,6 +925,10 @@ static int runEncoder( vvenc_config& c, uint64_t framesToEncode, bool emulateMis
924925
uint64_t framesRcvd = 0;
925926
uint64_t numMissingFrames = emulateMissingFrames ? 10 : 0;
926927

928+
#if VVENC_USE_UNSTABLE_API
929+
std::unordered_set<int> userDataSet;
930+
#endif
931+
927932
while( !eof || !encodeDone )
928933
{
929934
vvencYUVBuffer* inputPtr = nullptr;
@@ -932,6 +937,9 @@ static int runEncoder( vvenc_config& c, uint64_t framesToEncode, bool emulateMis
932937
inputPtr = yuvPicture;
933938
yuvPicture->cts = (c.m_TicksPerSecond > 0) ? (ctsOffset + (framesRcvd * (uint64_t)c.m_TicksPerSecond * (uint64_t)c.m_FrameScale / (uint64_t)c.m_FrameRate)) : (ctsOffset + framesRcvd);
934939
yuvPicture->ctsValid = true;
940+
#if VVENC_USE_UNSTABLE_API
941+
yuvPicture->userData = new int(framesRcvd);
942+
#endif
935943
framesRcvd++;
936944

937945
if( emulateMissingFrames && framesRcvd == framesToEncode>>1 )
@@ -964,6 +972,11 @@ static int runEncoder( vvenc_config& c, uint64_t framesToEncode, bool emulateMis
964972
}
965973
}
966974
lastDts = AU->dts;
975+
#if VVENC_USE_UNSTABLE_API
976+
int* userData = static_cast<int*>(AU->userData);
977+
userDataSet.insert( *userData);
978+
delete userData;
979+
#endif
967980
}
968981

969982
if ( auCount > 0 && (!AU || ( AU && AU->payloadUsedSize == 0 )) )
@@ -984,6 +997,14 @@ static int runEncoder( vvenc_config& c, uint64_t framesToEncode, bool emulateMis
984997
goto fail;
985998
}
986999

1000+
#if VVENC_USE_UNSTABLE_API
1001+
if (userDataSet.size() != framesToEncode)
1002+
{
1003+
//std::cout << "expecting " << framesToEncode << " unique user data values, but got " << userDataSet.size() << std::endl;
1004+
goto fail;
1005+
}
1006+
#endif
1007+
9871008
vvenc_YUVBuffer_free( yuvPicture, true );
9881009
vvenc_accessUnit_free( AU, true );
9891010
vvenc_encoder_close( enc );

0 commit comments

Comments
 (0)