Skip to content

Allocate downsampling sample buffers on first use - #4054

Open
changyeon-jo wants to merge 1 commit into
cisco:masterfrom
changyeon-jo:lazy-downsample-buffers
Open

changyeon-jo wants to merge 1 commit into
cisco:masterfrom
changyeon-jo:lazy-downsample-buffers

Conversation

@changyeon-jo

@changyeon-jo changyeon-jo commented Oct 18, 2026 •

Copy link
Copy Markdown

Summary

CDownsampling allocates six intermediate sample buffers sized for 1920x1088 (about 6 MB in total) in its constructor, even when Process() is never called. An encoder with a single spatial layer and no input scaling never downsamples, but still pays for these buffers. This change allocates them on the first call to Process() instead.

Details

  • The constructor no longer calls AllocateSampleBuffer(); m_bNoSampleBuffer starts as false and the buffers stay NULL.
  • Process() allocates them right before they are first needed. If the allocation fails, m_bNoSampleBuffer is set as before, and the existing fallback path is used.
  • When downsampling is used, behaviour is unchanged: the buffers are allocated once, before the first use, and freed in the destructor as before.
  • Thread safety: CDownsampling::Process() is only reached through CVpFrameWork::Process(), which holds m_mutes, so the lazy allocation is serialized like the existing writes to the sample buffers. If it is never called, the destructor frees NULL pointers, which WelsFree() already handles.

With a single 320x240 spatial layer, peak encoder heap drops from about 7.5 MB to about 1.4 MB (measured with glibc mallinfo2()), with byte-identical output. This makes the encoder usable on targets with a few MB of RAM.

Testing

  • codec_unittest, built with USE_ASM=No on x86_64: 483 tests passed (39 disabled), same as without the change.
  • This includes the EncodeFile output hash tests with 2 and 4 spatial layers, which exercise the downsampler.

CDownsampling allocates six intermediate sample buffers sized for
1920x1088 (about 6 MB in total) in its constructor, whether or not
Process() is ever called. Encoders with a single spatial layer and no
input scaling never call it, yet always pay for these buffers, which is
significant on memory-constrained targets.

Allocate the buffers on the first call to Process() instead. Behaviour
is unchanged when downsampling is used, including the fallback when the
allocation fails.

Assisted-by: Antigravity:gemini-3-pro
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants