Opened 6 years ago
Last modified 20 months 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 , 6 years ago
comment:2 by , 6 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 , 6 years ago
| Summary: | swsscale crops image on yuv2rgb → swscale crops image on yuv2rgb |
|---|
comment:4 by , 20 months 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?