Remove LZ4 compression — negligible benefit on delta data
Delta-compressed entity/playerState bitstreams have minimal redundancy for LZ4 to exploit. The per-block 8-byte header overhead was comparable to the compression savings. Removed: lz4.h include, SVD_WriteBlock/ReadBlock functions, SVDEMO_FLAG_COMPRESSED, demo.compressed field, svdemo_compress cvar, lz4.c from build. Direct size+data writes replace block I/O. Demo format v3 (flags field reserved, always 0). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fe628a2cc4
commit
74e2fc39c8
3 changed files with 15 additions and 74 deletions
|
|
@ -997,8 +997,6 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="server\sv_netdemo.c">
|
||||
</ClCompile>
|
||||
<ClCompile Include="server\lz4.c">
|
||||
</ClCompile>
|
||||
<ClCompile Include="server\sv_world.c">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug TA DEMO|Win32'">Disabled</Optimization>
|
||||
<BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug TA DEMO|Win32'">true</BrowseInformation>
|
||||
|
|
|
|||
|
|
@ -623,7 +623,6 @@ void SV_Init (void) {
|
|||
|
||||
// server-side demo settings
|
||||
Cvar_Get ("svdemo_autorecord", "0", CVAR_ARCHIVE);
|
||||
Cvar_Get ("svdemo_compress", "1", CVAR_ARCHIVE);
|
||||
Cvar_Get ("svdemo_pauseEmpty", "1", CVAR_ARCHIVE);
|
||||
|
||||
// initialize bot cvars so they are listed and can be set before loading the botlib
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ snapshot pipeline delivers them to a spectator client.
|
|||
*/
|
||||
|
||||
#include "server.h"
|
||||
#include "lz4.h"
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// File format
|
||||
|
|
@ -55,7 +54,6 @@ snapshot pipeline delivers them to a spectator client.
|
|||
#define SVDEMO_MAX_MAPNAME 64
|
||||
|
||||
// header flags
|
||||
#define SVDEMO_FLAG_COMPRESSED 1 // per-frame data is LZ4 compressed
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// State
|
||||
|
|
@ -81,7 +79,6 @@ typedef struct {
|
|||
// recording
|
||||
fileHandle_t recordFile;
|
||||
qboolean recording;
|
||||
qboolean compressed; // LZ4 compression enabled
|
||||
char *lastConfigstrings[MAX_CONFIGSTRINGS]; // for delta detection
|
||||
svdEntityState_t prevEntities[MAX_GENTITIES]; // previous frame for delta
|
||||
svdPlayerState_t prevPlayers[MAX_CLIENTS]; // previous frame player states
|
||||
|
|
@ -131,58 +128,6 @@ static short SVD_ReadShort( fileHandle_t f ) {
|
|||
return v;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// LZ4 block I/O: writes [uncompressed_size][compressed_size][data]
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
static void SVD_WriteBlock( fileHandle_t f, const byte *data, int len ) {
|
||||
if ( demo.compressed && len > 0 ) {
|
||||
int bound = LZ4_compressBound( len );
|
||||
static byte compBuf[MAX_GENTITIES * 300];
|
||||
int compLen;
|
||||
|
||||
compLen = LZ4_compress_default( (const char *)data, (char *)compBuf, len, bound );
|
||||
if ( compLen > 0 ) {
|
||||
SVD_WriteInt( f, len ); // original size
|
||||
SVD_WriteInt( f, compLen ); // compressed size
|
||||
FS_Write( compBuf, compLen, f );
|
||||
return;
|
||||
}
|
||||
// fall through to uncompressed on failure
|
||||
}
|
||||
SVD_WriteInt( f, len ); // original size
|
||||
SVD_WriteInt( f, 0 ); // 0 = not compressed
|
||||
FS_Write( data, len, f );
|
||||
}
|
||||
|
||||
static int SVD_ReadBlock( fileHandle_t f, byte *buf, int bufSize ) {
|
||||
int origLen, compLen;
|
||||
|
||||
origLen = SVD_ReadInt( f );
|
||||
compLen = SVD_ReadInt( f );
|
||||
|
||||
if ( origLen <= 0 || origLen > bufSize ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( compLen > 0 ) {
|
||||
// compressed
|
||||
static byte compBuf[MAX_GENTITIES * 300];
|
||||
if ( compLen > (int)sizeof(compBuf) ) {
|
||||
return -1;
|
||||
}
|
||||
FS_Read( compBuf, compLen, f );
|
||||
if ( LZ4_decompress_safe( (const char *)compBuf, (char *)buf, compLen, bufSize ) != origLen ) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// uncompressed
|
||||
FS_Read( buf, origLen, f );
|
||||
}
|
||||
|
||||
return origLen;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Write header
|
||||
// ---------------------------------------------------------------
|
||||
|
|
@ -193,7 +138,7 @@ static void SVD_WriteHeader( fileHandle_t f ) {
|
|||
|
||||
SVD_WriteInt( f, SVDEMO_MAGIC );
|
||||
SVD_WriteInt( f, SVDEMO_VERSION );
|
||||
SVD_WriteInt( f, demo.compressed ? SVDEMO_FLAG_COMPRESSED : 0 );
|
||||
SVD_WriteInt( f, 0 ); // flags (reserved)
|
||||
SVD_WriteInt( f, sv_maxclients->integer );
|
||||
SVD_WriteInt( f, sv_fps->integer );
|
||||
|
||||
|
|
@ -294,8 +239,9 @@ static void SVD_WriteFrame( fileHandle_t f ) {
|
|||
// end of entities marker
|
||||
MSG_WriteBits( &msg, (MAX_GENTITIES - 1), GENTITYNUM_BITS );
|
||||
|
||||
// write entity message to file (optionally LZ4 compressed)
|
||||
SVD_WriteBlock( f, msg.data, msg.cursize );
|
||||
// write entity message to file
|
||||
SVD_WriteInt( f, msg.cursize );
|
||||
FS_Write( msg.data, msg.cursize, f );
|
||||
|
||||
// write player states (delta compressed)
|
||||
{
|
||||
|
|
@ -346,7 +292,8 @@ static void SVD_WriteFrame( fileHandle_t f ) {
|
|||
MSG_WriteBits( &psmsg, MAX_CLIENTS - 1, 6 );
|
||||
MSG_WriteBits( &psmsg, 0, 1 );
|
||||
|
||||
SVD_WriteBlock( f, psmsg.data, psmsg.cursize );
|
||||
SVD_WriteInt( f, psmsg.cursize );
|
||||
FS_Write( psmsg.data, psmsg.cursize, f );
|
||||
}
|
||||
|
||||
// configstring changes
|
||||
|
|
@ -417,10 +364,8 @@ static qboolean SVD_StartRecording( const char *demoname ) {
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
Com_Printf( "Recording server demo to %s%s\n", path,
|
||||
Cvar_VariableIntegerValue("svdemo_compress") ? " (LZ4)" : "" );
|
||||
Com_Printf( "Recording server demo to %s\n", path );
|
||||
demo.recording = qtrue;
|
||||
demo.compressed = Cvar_VariableIntegerValue("svdemo_compress") ? qtrue : qfalse;
|
||||
|
||||
// clear delta state for fresh recording
|
||||
Com_Memset( demo.prevEntities, 0, sizeof(demo.prevEntities) );
|
||||
|
|
@ -567,10 +512,7 @@ static qboolean SVD_ReadHeader( fileHandle_t f ) {
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
{
|
||||
int flags = SVD_ReadInt( f );
|
||||
demo.compressed = ( flags & SVDEMO_FLAG_COMPRESSED ) ? qtrue : qfalse;
|
||||
}
|
||||
SVD_ReadInt( f ); // flags (reserved)
|
||||
|
||||
demo.playMaxClients = SVD_ReadInt( f );
|
||||
demo.playFps = SVD_ReadInt( f );
|
||||
|
|
@ -661,11 +603,12 @@ static qboolean SVD_ReadFrame( fileHandle_t f ) {
|
|||
}
|
||||
}
|
||||
|
||||
// read entity message (optionally LZ4 compressed)
|
||||
blockLen = SVD_ReadBlock( f, msgBuf, sizeof(msgBuf) );
|
||||
if ( blockLen <= 0 ) {
|
||||
// read entity message
|
||||
blockLen = SVD_ReadInt( f );
|
||||
if ( blockLen <= 0 || blockLen > (int)sizeof(msgBuf) ) {
|
||||
return qfalse;
|
||||
}
|
||||
FS_Read( msgBuf, blockLen, f );
|
||||
MSG_Init( &msg, msgBuf, sizeof(msgBuf) );
|
||||
msg.cursize = blockLen;
|
||||
|
||||
|
|
@ -735,8 +678,9 @@ static qboolean SVD_ReadFrame( fileHandle_t f ) {
|
|||
static byte psBuf[MAX_CLIENTS * 600]; // worst case: full playerState from baseline
|
||||
int psMsgLen;
|
||||
|
||||
psMsgLen = SVD_ReadBlock( f, psBuf, sizeof(psBuf) );
|
||||
if ( psMsgLen > 0 ) {
|
||||
psMsgLen = SVD_ReadInt( f );
|
||||
if ( psMsgLen > 0 && psMsgLen <= (int)sizeof(psBuf) ) {
|
||||
FS_Read( psBuf, psMsgLen, f );
|
||||
MSG_Init( &psmsg, psBuf, sizeof(psBuf) );
|
||||
psmsg.cursize = psMsgLen;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue