View Full Version : sws_scale issue
koliva
22nd January 2013, 12:28
Hi all,
Here is a part of my code,
convertCtx = sws_getContext(aWidth, aHeight, PIX_FMT_RGB24, aWidth, aHeight, PIX_FMT_YUV420P, SCALING_ALGORITHM, NULL, NULL, NULL);
x264_picture_alloc(&pic_in, X264_CSP_I420, aWidth, aHeight);
srcstride = aWidth*3;
sws_scale(convertCtx, &bits, &srcstride, 0, aHeight, pic_in.img.plane, pic_in.img.i_stride);
In the code, I fisrt convert the RGB frame to YUV 4:2:0 and send it for encoding.
This code works perfect for for example 1024x768 resolution input frames but not for example 1366x768. It gives an error "Warning: data is not aligned!". I am guessing that it is just because 1366 is not divisible by 4. I thought that I can fix it by playing with the srcstride parameter but it won't help. Could you please guide me how to fix this properly?
paradoxical
23rd January 2013, 20:29
It's quite simple. You need to pass in buffers that are aligned to the width that the function expects. Obviously just changing the stride parameter isn't going to do anything.
koliva
24th January 2013, 09:41
It's quite simple. You need to pass in buffers that are aligned to the width that the function expects. Obviously just changing the stride parameter isn't going to do anything.
The buffer contains already the padding in it. For example, 1366x768 resolution image, bytes per line is 4100 instead of 4098. I never thought about it but do you think that I need to keep the bytes per line as it is, which is 4098?
Another question, what does the stride parameter do then?
paradoxical
24th January 2013, 18:01
The buffer contains already the padding in it. For example, 1366x768 resolution image, bytes per line is 4100 instead of 4098. I never thought about it but do you think that I need to keep the bytes per line as it is, which is 4098?
As I said, you need to figure out what alignment the function expects and then make your buffers a multiple of that alignment. sws_scale requires 16-bit aligned buffers. Neither 4100 or 4098 are 16-bit aligned. I hate to sound rude, but this seriously only took me 5 seconds to figure out and I've never used the swscale API ever before. Read the ffmpeg docs (http://ffmpeg.org/doxygen/trunk) which also link to the source code (http://ffmpeg.org/doxygen/trunk/swscale_8c_source.html#l00331) This is exactly how I figured out your issue.
Another question, what does the stride parameter do then?
It's tells the function the length of each plane of the source/destination images (again something straight from the doc (http://ffmpeg.org/doxygen/trunk/group__lsws.html#gae531c9754c9205d90ad6800015046d74)). And the reason you don't simply change the stride parameter is because if your buffers are smaller than what you're telling sws_scale what the stride is, then you have the potential of a buffer overrun occurring that is going to cause memory corruption and/or crash your program.
koliva
28th January 2013, 14:16
I guess you are talking about the following code segment. I should have figured this out before asking. Thanks for the lesson.
420 if ( (uintptr_t)dst[0]%16 || (uintptr_t)dst[1]%16 || (uintptr_t)dst[2]%16
421 || (uintptr_t)src[0]%16 || (uintptr_t)src[1]%16 || (uintptr_t)src[2]%16
422 || dstStride[0]%16 || dstStride[1]%16 || dstStride[2]%16 || dstStride[3]%16
423 || srcStride[0]%16 || srcStride[1]%16 || srcStride[2]%16 || srcStride[3]%16
424 ) {
425 static int warnedAlready=0;
426 int cpu_flags = av_get_cpu_flags();
427 if (HAVE_MMXEXT && (cpu_flags & AV_CPU_FLAG_SSE2) && !warnedAlready){
428 av_log(c, AV_LOG_WARNING, "Warning: data is not aligned! This can lead to a speedloss\n");
429 warnedAlready=1;
430 }
431 }
paradoxical
28th January 2013, 15:20
Yes, that is exactly the spot. Definitely reference the docs, they mostly have good function documentation. Plus they link to the source code for searching error messages such as in this case. Good luck with your continued work. :)
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.