[Libav-user] sws_scale has weird behavior when not resizing
Alexandre Millette
amillett at matrox.com
Mon Jul 16 18:15:06 CEST 2012
Hi again.
TL;DR: use the SWS_ACCURATE_RND flag.
I have solve my issue (or rather found a workaround) and thought it
might help some people:
> Also I am not sure what would be the proper way to handle this
situation.
> Sure I can round the width of the frame to the nearest greater
multiple of
> 8 and add one to it, but I'm afraid that in some situation it may
bust the
> line size and cause an exception. Plus it doesn't seem right to use such
> magic numbers..
The problem only occurs when sws_scale does no resizing, that is when
the source and destination sizes are the same. By looking at the
sws_getContext source code, I have found that one flag,
SWS_ACCURATE_RND, among other things, force the function to not use it's
no-resizing algorithm. So we can prevent the issue by setting this flag.
I am not quite sure of the exact usage of this flag, but I know VLC used
to have it set for quality issues (that could be related to my own
issue) but have since removed it from some builds (like their android's)
because of performance problems. I have personally seen no difference in
performance with the flag, but I have still decided to use it only when
need be, that is when the width and height are not multiples of 8.
Here's a glimpse of my code now:
AVCodecContext* mpCodecCtx;
AVFrame* lpFrame;
AVFrame* lpFrameRGB;
static struct SwsContext* img_convert_ctx = 0;
// ...
// mpCodecCtx is opened normally
// lpFrame is allocated and returned by avcodec_decode_video2
// lpFrameRGB is allocated and filled by avpicture_fill
int w = mpCodecCtx->width;
int h = mpCodecCtx->height;
int SwsFlags = SWS_FAST_BILINEAR;
if ((w & 0x7) || (h & 0x7))
SwsFlags |= SWS_ACCURATE_RND;
img_convert_ctx = sws_getContext(w, h, PIX_FMT_YUV420P,
w, h, PIX_FMT_RGB32, SwsFlags, NULL, NULL, NULL);
int ret = sws_scale(img_convert_ctx, lpFrame->data,
lpFrame->linesize, 0, h,
lpFrameRGB->data, lpFrameRGB->linesize);
On a somewhat related note, can the sws_scale behavior that I was seeing
be considered a bug?
If so, how should I open a ticket for it to be fix?
Alex M
More information about the Libav-user
mailing list