Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avifenc using high amount of memory #1111

Open
GyllieGyllie opened this issue Sep 16, 2022 · 11 comments
Open

avifenc using high amount of memory #1111

GyllieGyllie opened this issue Sep 16, 2022 · 11 comments

Comments

@GyllieGyllie
Copy link

GyllieGyllie commented Sep 16, 2022

We are running avifenc on AWS Lambda to convert single frame png images to a single AVIF image.
It works fine for most but we have some group of images where it just exits with no feedback at all.
We recompiled everything yesterday on the latest commit from the default branch.

Command ran that fails

./avifenc -j all -d 8 --minalpha 24 --maxalpha 28 --output /tmp/out/hat_300.avif /tmp/in/hat_9/hat_0.png /tmp/in/hat_9/hat_1.png /tmp/in/hat_9/hat_2.png /tmp/in/hat_9/hat_3.png /tmp/in/hat_9/hat_4.png /tmp/in/hat_9/hat_5.png /tmp/in/hat_9/hat_6.png /tmp/in/hat_9/hat_7.png /tmp/in/hat_9/hat_8.png /tmp/in/hat_9/hat_9.png

We also tried to run the same command on another EC2 instance we have where we can see this

Successfully loaded: hat_0.png
AVIF to be written: (Lossy)
 * Resolution     : 2160x2160
 * Bit Depth      : 8
 * Format         : YUV444
 * Alpha          : Not premultiplied
 * Range          : Full
 * Color Primaries: 1
 * Transfer Char. : 13
 * Matrix Coeffs. : 6
 * ICC Profile    : Absent
 * XMP Metadata   : Absent
 * Exif Metadata  : Absent
 * Transformations: None
 * Progressive    : Unavailable
Encoding with AV1 codec 'aom' speed [6], color QP [24 (Medium) <-> 26 (Medium)], alpha QP [24 (Medium) <-> 28 (Medium)], tileRowsLog2 [0], tileColsLog2 [0], 2 worker thread(s), please wait...
 * Encoding frame 1 [1/30 ts]: hat_0.png
 Killed

When finding the reason it says

[   98.773385] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/,task=avifenc,pid=1191,uid=1000
[   98.775138] Out of memory: Killed process 1191 (avifenc) total-vm:533556kB, anon-rss:334252kB, file-rss:8kB, shmem-rss:0kB, UID:1000 pgtables:732kB oom_score_adj:0

The instance has 0.5GB ram, on lambda we have it set to 1GB. The images themselves are each ~250KB in size and 2160x2160px

@GyllieGyllie
Copy link
Author

Ok after more debugging it seems the issue is most likely the RAM usage. When we upgraded the EC2 instance to have 4GB we were able to convert it but the memory usage is spiking to almost 2GB. Is it normal that the memory usage is soo high for random images or is there a specific reason?

https://i.rigner.ovh/M6Ko0mkD.mp4

@GyllieGyllie GyllieGyllie changed the title avifenc exits with no feedback and no generated file avifenc using high amount of memory Sep 16, 2022
@jzern
Copy link
Collaborator

jzern commented Sep 16, 2022

Thanks for the report and investigation. The resolution of the images are one of the main components to memory usage and with animations the encoder will keep extra image-sized buffers to use as references.

What were the sizes of the images in this case?
It looks like the encoder was killed by the kernel due to the memory usage rather than avifenc seeing an allocation failure.

@GyllieGyllie
Copy link
Author

The images were 2160x2160. The issue was indeed that the kernel killed the process as it was trying to use more memory than available.

My main concern still is why it's using so much memory for so few files while files with same size are not needed that much memory.

@aentwist
Copy link

aentwist commented Jul 9, 2024

I have a large image coming in at around 375MB, about 40,000 x 30,000. This thing spikes to 9GB of RAM usage before dying. I can't get it to work :(

avifenc -c aom --min 31 --max 31 --minalpha 31 --maxalpha 31 -s 0 s13b-map.png s13b-map.avif

@wantehchang
Copy link
Collaborator

Hi @aentwist, could you share s13b-map.png with me? I'll take a look.

Note that a three-channel, 40,000 x 30,000 image is 3.35GB uncompressed. So if we have two copies of the uncompressed image in memory, that's 6.7GB already. The aom_codec_encode() function called by avifenc copies the input image before compressing it.

@vrabaud
Copy link
Collaborator

vrabaud commented Jul 10, 2024

avifenc limits decoding to AVIF_DEFAULT_IMAGE_SIZE_LIMIT, cf

AVIF_DEFAULT_IMAGE_SIZE_LIMIT,

libaom also limits the max_area to 1<<30: https://aomedia.googlesource.com/aom/+/6fb5bfdf30282eebf47db5ca6f0dfecedcd0853c/av1/av1_cx_iface.c#675

I tried with an image of:

  • 35000 by 25000, and I get an libaom error: "Memory allocation error: Failed to allocate lag buffers"
  • 28000 by 20000, and RAM usage peaks at 10GB and 30 cores are used

I you use the "-autotiling" option, less RAM will be used. For now, that limits to 8 tiles though, cf

const int threads = 8;

but we could probably remove that lock as we limit to 32 tiles above anyway.

@aentwist
Copy link

aentwist commented Jul 10, 2024

Yeah I realized this image isn't really the best fit for this issue, because such an unusually large image comes with other problems. As for the RAM, it is over my head how a 375MB PNG expands to 3.5GB, but given that, the explanation of the RAM sounds fairly reasonable. My objective was only a nice-to-have so I just gave up on the conversion. Good luck should you decide to pursue this optimization.

https://github.com/aentwist/image-of-unusual-size

@msalsbery
Copy link

As for the RAM, it is over my head how a 375MB PNG expands to 3.5GB

40000 x 30000 x 3

😉

@wantehchang
Copy link
Collaborator

Hi @aentwist,

I have downloaded the s13b-map.png image. You can delete it now. Thanks!

The actual image size is 38464 x 28832. In addition to the high amount of memory, it may cause integer overflows in our code. So I will need to run our code under the Undefined Behavior Sanitizer and fix the integer overflows. (As Vincent noted, our code currently imposes a maximum image size of 2^30 to avoid the known integer overflows.)

@wantehchang
Copy link
Collaborator

I found that the s13b-map.png image has an alpha channel, so the uncompressed image size is 38464 x 28832 x 4.

1480c1 pushed a commit to m-ab-s/aom that referenced this issue Jul 12, 2024
Fix signed and unsigned integer overflows when encoding a frame of size
38464 x 28832.

For more information, see
AOMediaCodec/libavif#1111 (comment).

Change-Id: I78131498a198c5bd157bbb9fcdf5042ae71affc9
@wantehchang
Copy link
Collaborator

Let's use this issue for the high memory usage problem when encoding an AVIF image sequence (i.e., AVIF animation) that @GyllieGyllie originally reported.

I filed #2271 for the support of large image size that @aentwist reported in #1111 (comment).

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

No branches or pull requests

6 participants