BGRA to YUV420 FFmpeg giving bad output

843 views Asked by At

My purpose is a screen recorder. I am using the Windows DXGI API to receive screenshots and I'm encoding the screenshots into a video using libx264. Feeding BGRA images directly to libx264 is producing weird colors in the output video. So, to get correct colors, I am trying to convert the BGRA to YUV420p. To speed up encoding, I am also trying to downscale the BGRA image.

So I am getting an 1920x1080 BGRA image and I want to convert it to 1280x720 YUV420p. For this, I am using FFmpeg swscale library to do both the format conversion and downscaling.

The problem is that the output video is coming like 3 images in the same frame. Please see this video. https://i.stack.imgur.com/pmPGC.jpg

I tried just BGRA to YUV conversion without any downscaling and it is working fine. But BGRA to YUV with downscaling is giving this problem.

What is the cause for this problem? How do I fix it?

Here is my code snippet:

uint8_t* Image;
x264_picture_t picIn, picOut;
x264_picture_alloc(&picIn, X264_CSP_I420, 1280, 720);

SwsContext* sws = sws_getContext(1920, 1080, AV_PIX_FMT_BGRA, 1280, 720, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);

while (true)
{
    take_screenshot(&Image);

    AVFrame BGRA;
    BGRA.linesize[0] = 1280 * 4;
    BGRA.data[0] = Image;
    sws_scale(sws, BGRA.data, BGRA.linesize, 0, 1080, picIn.img.plane, picIn.img.i_stride);

    nal_size = x264_encoder_encode(h, &nals, &nal_count, &picIn, &picOut);
    save_to_flv(nals, nal_size, nal_count);
}

Here are my libx264 parameters:

        x264_param_default_preset(&param, preset, 0);
        param.i_csp = X264_CSP_I420;
        param.i_width = 1280;
        param.i_height = 720;
        param.i_fps_num = 30;
        param.i_fps_den = 1;
        param.rc.i_bitrate = 2500;
        param.i_bframe = 0;
        param.b_repeat_headers = 0;
        param.b_annexb = 1;     

        x264_param_apply_profile(&param, 0);
        h = x264_encoder_open(&param);
1

There are 1 answers

2
Alex Cohn On BEST ANSWER

Change BGRA.linesize[0] to be 1920*4. You see this 3 images pattern because

1240*3 == 1920*2