Opened 4 years ago
Last modified 4 weeks ago
#8871 new defect
swscale crops image on yuv2rgb
Reported by: | xlp | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | swscale |
Version: | unspecified | Keywords: | |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
Summary of the bug:
swscale leaves a small right portion of the image out on yuv2rgb conversion. aka "crops it", so a bar of the destination-image on right side stays unwritten. this seems to effect only certain resolutions/linesizes - below is one given that seems to cause issues
How to reproduce:
// HAS NO ISSUES // int32_t width = 1600; // int32_t height = 900; // int srcLinesize[8] = {1664, 832, 832, 0, 0, 0, 0, 0}; // HAS ISSUES int32_t width = 1220; int32_t height = 1200; int srcLinesize[8] = {1280, 640, 640, 0, 0, 0, 0, 0}; struct SwsContext* sws_scaler_ctx = sws_getContext(width, height, AV_PIX_FMT_YUV420P, width, height, AV_PIX_FMT_RGB0, SWS_FAST_BILINEAR, 0, 0, 0); size_t destBufferSize = width * 4 * height; uint8_t* destBuffer = (uint8_t*) malloc(destBufferSize); memset(destBuffer, 0x00, destBufferSize); uint8_t* destLines[4] = {destBuffer, 0, 0, 0}; int destData[4] = {width * 4, 0, 0, 0}; // Make a dummy source with green footage uint8_t* srcData[8]; for (int i = 0; i < 8; i++) { if (srcLinesize[i] > 0) { size_t srcBufferSize = srcLinesize[i]*height; srcData[i] = (uint8_t*) malloc(srcBufferSize); memset(srcData[i], 0x00, srcBufferSize); } else { srcData[i] = 0x00; } } sws_scale(sws_scaler_ctx, (const uint8_t* const*)srcData, srcLinesize, 0, height, destLines, destData);
Produced Result:
Green area with unwritten gap at the right side (here in the size of 4x1200)
Expected result:
Completely green area, as the provided YUV source contains
Change History (4)
comment:1 by , 4 years ago
comment:2 by , 4 years ago
Yes i've tried running the mp4 (which initially caused the issue on my side) thru ffmpeg -i source.mp4 frame%05d.png
, to find that the issue is not present there.
comment:3 by , 4 years ago
Summary: | swsscale crops image on yuv2rgb → swscale crops image on yuv2rgb |
---|
comment:4 by , 4 weeks ago
The problem here, and the reason it is not reproducible with just ffmpeg
, is that the dst buffer stride is not aligned to a multiple of 8, which breaks the unscaled special converters.
This seems to fall into a general class of bugs revolving around calling libswscale directly with unaligned buffers,
It seems that the only general fix to such issues is to either avoid the use of asm entirely for unaligned buffers, or just print a big scary warning and issue a memcpy from a suitably aligned internal buffer.
I am leaning towards the latter, as a definitive fix for these issues, all of which have in common that they can only happen when one deliberately ignores best practices around image buffer alignment.
Is the issue not reproducible with
ffmpeg
, the application?