How to Use sws_getContext in FFmpeg C API

This guide explains how to initialize a video scaling and pixel format conversion context using sws_getContext from FFmpeg’s libswscale library. You will learn the function's signature, what each parameter represents, how to implement it in a C application, and how to safely free the allocated resources once conversion is complete.


Understanding sws_getContext

The sws_getContext function configures and allocates an SwsContext structure, which handles software scaling and pixel format conversion (such as converting YUV420P to RGB24 or resizing a 1080p frame down to 720p).

Function Signature

#include <libswscale/swscale.h>

struct SwsContext *sws_getContext(
    int srcW, 
    int srcH, 
    enum AVPixelFormat srcFormat,
    int dstW, 
    int dstH, 
    enum AVPixelFormat dstFormat,
    int flags, 
    SwsFilter *srcFilter, 
    SwsFilter *dstFilter, 
    const double *param
);

Parameter Breakdown

  • srcW, srcH: Width and height of the source image in pixels.
  • srcFormat: Pixel format of the source image (e.g., AV_PIX_FMT_YUV420P).
  • dstW, dstH: Width and height of the destination image in pixels.
  • dstFormat: Pixel format of the destination image (e.g., AV_PIX_FMT_RGB24).
  • flags: The scaling algorithm and optimization flags (e.g., SWS_BILINEAR, SWS_BICUBIC, SWS_LANCZOS).
  • srcFilter: Optional custom filter applied to the source. Pass NULL for default behavior.
  • dstFilter: Optional custom filter applied to the destination. Pass NULL for default behavior.
  • param: Optional extra parameters for tuning specific scaling algorithms. Pass NULL to use default values.

Implementation Example

The following code demonstrates how to initialize the context, check for errors, and free the allocated memory:

#include <stdio.h>
#include <libavutil/pixfmt.h>
#include <libswscale/swscale.h>

int main(void) {
    // 1. Define source and destination parameters
    int src_width = 1920;
    int src_height = 1080;
    enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_YUV420P;

    int dst_width = 1280;
    int dst_height = 720;
    enum AVPixelFormat dst_pix_fmt = AV_PIX_FMT_RGB24;

    // 2. Initialize the SwsContext
    struct SwsContext *sws_ctx = sws_getContext(
        src_width,
        src_height,
        src_pix_fmt,
        dst_width,
        dst_height,
        dst_pix_fmt,
        SWS_BILINEAR, // Scaling algorithm
        NULL,         // Source filter
        NULL,         // Destination filter
        NULL          // Algorithm tuning parameters
    );

    // 3. Verify allocation
    if (!sws_ctx) {
        fprintf(stderr, "Error: Failed to initialize SwsContext.\n");
        return -1;
    }

    printf("SwsContext successfully initialized.\n");

    // Pass sws_ctx to sws_scale() to process frames here...

    // 4. Free the context when finished
    sws_freeContext(sws_ctx);

    return 0;
}

Key Considerations

  • Memory Cleanup: Every call to sws_getContext must eventually be paired with sws_freeContext to avoid memory leaks.
  • Performance: Calling sws_getContext inside a frame-processing loop is computationally expensive. Create the context once before processing frames, and reuse it for all frames with matching dimensions and pixel formats.
  • Dynamic Dimensions: If frame dimensions or pixel formats change dynamically between frames, consider using sws_getCachedContext instead. It reuses the existing context if the configuration matches, or reallocates it if parameters change.