diff --git a/.idea/artifacts/TerranBASIC.xml b/.idea/artifacts/TerranBASIC.xml index e40ceb8..6b36520 100644 --- a/.idea/artifacts/TerranBASIC.xml +++ b/.idea/artifacts/TerranBASIC.xml @@ -33,7 +33,6 @@ - @@ -59,8 +58,6 @@ - - @@ -122,6 +119,9 @@ + + + \ No newline at end of file diff --git a/lib/aircompressor-0.25-javadoc.jar b/lib/aircompressor-0.25-javadoc.jar deleted file mode 100644 index 2490c9f..0000000 Binary files a/lib/aircompressor-0.25-javadoc.jar and /dev/null differ diff --git a/lib/aircompressor-2.0.2-javadoc.jar b/lib/aircompressor-2.0.2-javadoc.jar new file mode 100644 index 0000000..5b935f8 Binary files /dev/null and b/lib/aircompressor-2.0.2-javadoc.jar differ diff --git a/lib/aircompressor-0.25-sources.jar b/lib/aircompressor-2.0.2-sources.jar similarity index 66% rename from lib/aircompressor-0.25-sources.jar rename to lib/aircompressor-2.0.2-sources.jar index 619c804..271e82e 100644 Binary files a/lib/aircompressor-0.25-sources.jar and b/lib/aircompressor-2.0.2-sources.jar differ diff --git a/lib/aircompressor-0.25.jar b/lib/aircompressor-2.0.2.jar similarity index 65% rename from lib/aircompressor-0.25.jar rename to lib/aircompressor-2.0.2.jar index 118a22e..660fede 100644 Binary files a/lib/aircompressor-0.25.jar and b/lib/aircompressor-2.0.2.jar differ diff --git a/video_encoder/Makefile b/video_encoder/Makefile index 71154f0..c3d269d 100644 --- a/video_encoder/Makefile +++ b/video_encoder/Makefile @@ -3,11 +3,11 @@ CC = gcc CFLAGS = -std=c99 -Wall -Wextra -O2 -D_GNU_SOURCE -LIBS = -lm -lz +LIBS = -lm -lzstd # Source files and targets -SOURCES = encoder_tev.c encoder_tev_xyb.c -TARGETS = encoder_tev encoder_tev_xyb +SOURCES = encoder_tev.c +TARGETS = encoder_tev # Build all encoders all: $(TARGETS) @@ -17,11 +17,6 @@ encoder_tev: encoder_tev.c rm -f encoder_tev $(CC) $(CFLAGS) -o $@ $< $(LIBS) -# Build XYB encoder -encoder_tev_xyb: encoder_tev_xyb.c - rm -f encoder_tev_xyb - $(CC) $(CFLAGS) -o $@ $< $(LIBS) - # Default target $(TARGETS): all @@ -40,8 +35,8 @@ install: $(TARGETS) # Check for required dependencies check-deps: @echo "Checking dependencies..." - @echo "libzstd no longer required - using gzip compression instead" - @pkg-config --exists zlib || (echo "Error: zlib-dev not found. Install with: sudo apt install zlib1g-dev" && exit 1) + @echo "Using Zstd compression for better efficiency" + @pkg-config --exists libzstd || (echo "Error: libzstd-dev not found. Install with: sudo apt install libzstd-dev" && exit 1) @echo "All dependencies found." # Help diff --git a/video_encoder/encoder_tev.c b/video_encoder/encoder_tev.c index 12ade4e..d278986 100644 --- a/video_encoder/encoder_tev.c +++ b/video_encoder/encoder_tev.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include @@ -63,6 +63,8 @@ int KEYFRAME_INTERVAL = 60; #define HALF_BLOCK_SIZE 8 #define HALF_BLOCK_SIZE_SQR 64 +#define ZSTD_COMPRESSON_LEVEL 15 + static float jpeg_quality_to_mult(int q) { return ((q < 50) ? 5000.f / q : 200.f - 2*q) / 100.f; } @@ -177,7 +179,7 @@ typedef struct { float *y_workspace, *co_workspace, *cg_workspace; float *dct_workspace; // DCT coefficients tev_block_t *block_data; // Encoded block data - uint8_t *compressed_buffer; // Gzip output + uint8_t *compressed_buffer; // Zstd output // Audio handling FILE *mp2_file; @@ -189,7 +191,7 @@ typedef struct { int target_audio_buffer_size; // Compression context - z_stream gzip_stream; + ZSTD_CCtx *zstd_context; // FFmpeg processes FILE *ffmpeg_video_pipe; @@ -1508,18 +1510,17 @@ static int alloc_encoder_buffers(tev_encoder_t *enc) { return -1; } - // Initialize gzip compression stream - enc->gzip_stream.zalloc = Z_NULL; - enc->gzip_stream.zfree = Z_NULL; - enc->gzip_stream.opaque = Z_NULL; - - int gzip_init_result = deflateInit2(&enc->gzip_stream, Z_DEFAULT_COMPRESSION, - Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); // 15+16 for gzip format - - if (gzip_init_result != Z_OK) { - fprintf(stderr, "Failed to initialize gzip compression\n"); + // Initialize Zstd compression context + enc->zstd_context = ZSTD_createCCtx(); + if (!enc->zstd_context) { + fprintf(stderr, "Failed to initialize Zstd compression\n"); return 0; } + + // Set reasonable compression level and memory limits + ZSTD_CCtx_setParameter(enc->zstd_context, ZSTD_c_compressionLevel, ZSTD_COMPRESSON_LEVEL); + ZSTD_CCtx_setParameter(enc->zstd_context, ZSTD_c_windowLog, 24); // 16MB window (should be plenty to hold an entire frame; interframe compression is unavailable) + ZSTD_CCtx_setParameter(enc->zstd_context, ZSTD_c_hashLog, 16); // Initialize previous frame to black memset(enc->previous_rgb, 0, pixels * 3); @@ -1531,7 +1532,7 @@ static int alloc_encoder_buffers(tev_encoder_t *enc) { static void free_encoder(tev_encoder_t *enc) { if (!enc) return; - deflateEnd(&enc->gzip_stream); + ZSTD_freeCCtx(enc->zstd_context); free(enc->current_rgb); free(enc->previous_rgb); @@ -1657,41 +1658,20 @@ static int encode_frame(tev_encoder_t *enc, FILE *output, int frame_num) { } } - // Compress block data using gzip (compatible with TSVM decoder) + // Compress block data using Zstd (compatible with TSVM decoder) size_t block_data_size = blocks_x * blocks_y * sizeof(tev_block_t); - // Initialize fresh gzip stream for each frame (since Z_FINISH terminates the stream) - z_stream frame_stream; - frame_stream.zalloc = Z_NULL; - frame_stream.zfree = Z_NULL; - frame_stream.opaque = Z_NULL; - - int init_result = deflateInit2(&frame_stream, Z_DEFAULT_COMPRESSION, - Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); // 15+16 for gzip format - - if (init_result != Z_OK) { - fprintf(stderr, "Failed to initialize gzip compression for frame\n"); + // Compress using Zstd with controlled memory usage + size_t compressed_size = ZSTD_compressCCtx(enc->zstd_context, + enc->compressed_buffer, block_data_size * 2, + enc->block_data, block_data_size, + ZSTD_COMPRESSON_LEVEL); + + if (ZSTD_isError(compressed_size)) { + fprintf(stderr, "Zstd compression failed: %s\n", ZSTD_getErrorName(compressed_size)); return 0; } - // Set up compression stream - frame_stream.next_in = (Bytef*)enc->block_data; - frame_stream.avail_in = block_data_size; - frame_stream.next_out = (Bytef*)enc->compressed_buffer; - frame_stream.avail_out = block_data_size * 2; - - int result = deflate(&frame_stream, Z_FINISH); - if (result != Z_STREAM_END) { - fprintf(stderr, "Gzip compression failed: %d\n", result); - deflateEnd(&frame_stream); - return 0; - } - - size_t compressed_size = frame_stream.total_out; - - // Clean up frame stream - deflateEnd(&frame_stream); - // Write frame packet header (rate control factor now per-block) uint8_t packet_type = is_keyframe ? TEV_PACKET_IFRAME : TEV_PACKET_PFRAME; uint32_t payload_size = compressed_size; // Rate control factor now per-block, not per-packet