[Libav-user] sws_scale has weird behavior when not resizing

Alexandre Millette amillett at matrox.com
Thu Jul 12 17:29:38 CEST 2012


Hello all.

I'm working on a C++ video player using libav.
Upon testing with various video formats and files, I've encountered a 
problem with a small MPEG4/mp4v file (190x240).
The issue is that a small green band (6 px in width) will appear on the 
right side of the frames.

This is what I've gathered so far:
- The YUV420 frame read in the stream is ok.
- The RGB32 frame output by sws_scale (there is no resize, the function 
is used only for conversion purpose) has the green band, so the problem 
comes from sws_scale.
- The green color comes from the original allocation of the YUV frame 
(data to 0 equals to a green shade).
- If sws_scale is used also as a resizing device (say converting YUV420 
190x240 to RGB32 191x240), there is no colored band, but the frame is of 
course 1 pixel wider than intended (frame accuracy is an important 
feature of the project, so this is not acceptable).
- When trying a sws_scale resize&convert on only the first frame, the 
other frames will still have a band to the right, but it will be the 
pixels from the first frame, not green. I can only assume that it is 
because the RGB32 frame is not entirely overwritten by the function.

After all this exposition, my question:
Why is sws_scale behavior different when not resizing? What should be 
changed in order to produce the same result but without the resizing?

As a precision, resizing up and down each frame is not a viable solution 
since performance is an issue (besides it would seem wrong).

Here's some very simplified code to help:

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;
img_convert_ctx = sws_getContext(w, h, PIX_FMT_YUV420P,
   w, h, PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);
int ret = sws_scale(img_convert_ctx, lpFrame->data,
   lpFrame->linesize, 0, h,
   lpFrameRGB->data, lpFrameRGB->linesize);
// Here lpFrameRGB contains the green bar
// This can be prevented by changing the fourth
// parameter of sws_getContext to w+1

Thank you,
Alex M


More information about the Libav-user mailing list