Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Programming and Hacking > Development
Register FAQ Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
Old 22nd January 2013, 12:28   #1  |  Link
koliva
Beginner
 
koliva's Avatar
 
Join Date: Jan 2009
Location: Europe
Posts: 125
sws_scale issue

Hi all,

Here is a part of my code,

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?

Last edited by koliva; 22nd January 2013 at 12:52.
koliva is offline   Reply With Quote
Old 23rd January 2013, 20:29   #2  |  Link
paradoxical
Guest
 
Posts: n/a
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.
  Reply With Quote
Old 24th January 2013, 09:41   #3  |  Link
koliva
Beginner
 
koliva's Avatar
 
Join Date: Jan 2009
Location: Europe
Posts: 125
Quote:
Originally Posted by paradoxical View Post
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?
koliva is offline   Reply With Quote
Old 24th January 2013, 18:01   #4  |  Link
paradoxical
Guest
 
Posts: n/a
Quote:
Originally Posted by koliva View Post
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 which also link to the source code This is exactly how I figured out your issue.

Quote:
Originally Posted by koliva View Post
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). 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.

Last edited by paradoxical; 24th January 2013 at 19:13.
  Reply With Quote
Old 28th January 2013, 14:16   #5  |  Link
koliva
Beginner
 
koliva's Avatar
 
Join Date: Jan 2009
Location: Europe
Posts: 125
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 }

Last edited by koliva; 28th January 2013 at 14:19.
koliva is offline   Reply With Quote
Old 28th January 2013, 15:20   #6  |  Link
paradoxical
Guest
 
Posts: n/a
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.
  Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 09:32.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.