[FFmpeg-devel] [PATCH v2 0/2] fftools/resman: remove redundant includes, use inflate loop
ffmpegagent
ffmpegagent at gmail.com
Sat May 31 06:58:43 EEST 2025
and other cosmetic fixes.
As per review by Ramiro Polla in message: "Re: [FFmpeg-devel]
[FFmpeg-cvslog] fftools/resources: Add resource manager files with
build-time compression"
V2
* Use two-pass decompression to return resources in actual-size memory
buffers
(in response to comment by Kieran)
.
softworkz (2):
fftools/resman: remove unused includes, fix declaration
fftools/resman: uncompress to actual-size memory buffers
fftools/resources/resman.c | 56 ++++++++++++++++++++++++++------------
fftools/resources/resman.h | 10 +------
2 files changed, 39 insertions(+), 27 deletions(-)
base-commit: 27c5e4b39afb272638ab907a710e7db4f867266d
Published-As: https://github.com/ffstaging/FFmpeg/releases/tag/pr-ffstaging-90%2Fsoftworkz%2Fsubmit_resman_fixes-v2
Fetch-It-Via: git fetch https://github.com/ffstaging/FFmpeg pr-ffstaging-90/softworkz/submit_resman_fixes-v2
Pull-Request: https://github.com/ffstaging/FFmpeg/pull/90
Range-diff vs v1:
1: 4d7af186ce = 1: 4d7af186ce fftools/resman: remove unused includes, fix declaration
2: 48fc3a6810 ! 2: 32cd61ebd4 fftools/resman: use inflate loop with increasing buffer size
@@ Metadata
Author: softworkz <softworkz at hotmail.com>
## Commit message ##
- fftools/resman: use inflate loop with increasing buffer size
+ fftools/resman: uncompress to actual-size memory buffers
Signed-off-by: softworkz <softworkz at hotmail.com>
## fftools/resources/resman.c ##
-@@ fftools/resources/resman.c: static int decompress_gzip(ResourceManagerContext *ctx, uint8_t *in, unsigned in
- memset(&strm, 0, sizeof(strm));
+@@ fftools/resources/resman.c: static ResourceManagerContext *resman_ctx = NULL;
+
+ static int decompress_gzip(ResourceManagerContext *ctx, uint8_t *in, unsigned in_len, char **out, size_t *out_len)
+ {
+- z_stream strm;
+- unsigned chunk = 65534;
++ z_stream strm = { 0 };
++ uint8_t dummy[4096];
++ size_t uncompressed_size;
+ int ret;
+ uint8_t *buf;
+
+ *out = NULL;
+- memset(&strm, 0, sizeof(strm));
++
++ // 15 + 16 tells zlib to detect GZIP or zlib automatically
++ ret = inflateInit2(&strm, 15 + 16);
++ if (ret != Z_OK) {
++ av_log(ctx, AV_LOG_ERROR, "Error during zlib initialization: %s\n", strm.msg);
++ return AVERROR(ENOSYS);
++ }
++
++ strm.avail_in = in_len;
++ strm.next_in = in;
++
++ do {
++ strm.avail_out = sizeof(dummy);
++ strm.next_out = dummy;
++
++ ret = inflate(&strm, Z_NO_FLUSH);
++ if (ret != Z_OK && ret != Z_STREAM_END) {
++ av_log(ctx, AV_LOG_ERROR, "Inflate failed (1): %d, %s\n", ret, strm.msg);
++ inflateEnd(&strm);
++ return AVERROR(EINVAL);
++ }
++ } while (ret != Z_STREAM_END);
++
++ uncompressed_size = strm.total_out;
// Allocate output buffer with extra byte for null termination
- buf = av_mallocz(chunk + 1);
-+ buf = av_realloc(NULL, chunk + 1);
++ buf = av_mallocz(uncompressed_size + 1);
if (!buf) {
av_log(ctx, AV_LOG_ERROR, "Failed to allocate decompression buffer\n");
++ inflateEnd(&strm);
return AVERROR(ENOMEM);
-@@ fftools/resources/resman.c: static int decompress_gzip(ResourceManagerContext *ctx, uint8_t *in, unsigned in
+ }
+
+- // 15 + 16 tells zlib to detect GZIP or zlib automatically
+- ret = inflateInit2(&strm, 15 + 16);
++ ret = inflateReset(&strm);
+ if (ret != Z_OK) {
+- av_log(ctx, AV_LOG_ERROR, "Error during zlib initialization: %s\n", strm.msg);
++ av_log(ctx, AV_LOG_ERROR, "inflateReset failed: %s\n", strm.msg);
+ av_free(buf);
+ return AVERROR(ENOSYS);
+ }
strm.avail_in = in_len;
strm.next_in = in;
- strm.avail_out = chunk;
-- strm.next_out = buf;
++ strm.avail_out = uncompressed_size;
+ strm.next_out = buf;
-- ret = inflate(&strm, Z_FINISH);
-- if (ret != Z_OK && ret != Z_STREAM_END) {
+ ret = inflate(&strm, Z_FINISH);
+ if (ret != Z_OK && ret != Z_STREAM_END) {
- av_log(ctx, AV_LOG_ERROR, "Inflate failed: %d, %s\n", ret, strm.msg);
-- inflateEnd(&strm);
-- av_free(buf);
++ av_log(ctx, AV_LOG_ERROR, "Inflate failed (2): %d, %s\n", ret, strm.msg);
+ inflateEnd(&strm);
+ av_free(buf);
- return (ret == Z_STREAM_END) ? Z_OK : ((ret == Z_OK) ? Z_BUF_ERROR : ret);
-- }
-+ do {
-+ strm.avail_out = chunk - strm.total_out;
-+ strm.next_out = buf + strm.total_out;
++ return AVERROR(EINVAL);
+ }
- if (strm.avail_out == 0) {
- // TODO: Error or loop decoding?
- av_log(ctx, AV_LOG_WARNING, "Decompression buffer may be too small\n");
- }
-+ ret = inflate(&strm, Z_FINISH);
-+ if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR) {
-+ av_log(ctx, AV_LOG_ERROR, "Inflate failed: %d, %s\n", ret, strm.msg);
-+ inflateEnd(&strm);
-+ av_free(buf);
-+ return AVERROR(EINVAL);
-+ }
-+
-+ if (strm.avail_out == 0) {
-+ chunk *= 8;
-+ uint8_t *tmp_buf = av_realloc(buf, chunk + 1);
-+ if (!tmp_buf) {
-+ inflateEnd(&strm);
-+ av_free(buf);
-+ return AVERROR(ENOMEM);
-+ }
-+
-+ buf = tmp_buf;
-+ }
-+ } while (ret != Z_STREAM_END);
++ av_assert0(strm.avail_out == 0);
- *out_len = chunk - strm.avail_out;
+- *out_len = chunk - strm.avail_out;
++ *out_len = uncompressed_size;
buf[*out_len] = 0; // Ensure null termination
+
+ inflateEnd(&strm);
--
ffmpeg-codebot
More information about the ffmpeg-devel
mailing list