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
_______________________________________________
Libav-user mailing list
Libav-user@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to