[Libav-user] How to change color range on SwsContext

GRANGER Nicolas nicolas.granger at cea.fr
Thu Feb 27 11:03:29 EET 2020

Hi everyone,

I need to perform lossless encoding of grayscale videos, which involves
a color space conversion step: GRAY8->YUV420. Lossless conversion means
the full color range must be preserved which is not the case by default
with AV_PIX_FMT_YUV420P.

When creating an instance of SwsContext with parameters
AV_PIX_FMT_GRAY8 and AV_PIX_FMT_YUVJ420P, it works but issues a warning
that AV_PIX_FMT_YUVJ420P is deprecated.

I have tried to create a context with AV_PIX_FMT_YUV420P as the
destination color space and then override the color range but it fails
with operation not permitted (see example below). It can be done with
the command line tools (arguments: "-pix_fmt yuv420p -dst_range 1
-color_range 2") but how to reproduce it with the C API?


#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>

int main() {
    struct SwsContext* ctx = sws_getContext(
        800, 600, AV_PIX_FMT_GRAY8, 
        800, 600, AV_PIX_FMT_YUV420P, // works with AV_PIX_FMT_YUVJ420P

    // fix color ranges
    int dummy[4];
    int srcRange, dstRange;
    int brightness, contrast, saturation;
    sws_getColorspaceDetails(ctx, (int **)&dummy, &srcRange,
                           (int **)&dummy, &dstRange, &brightness,

    const int *coefs = sws_getCoefficients(SWS_CS_DEFAULT);

    int err = sws_setColorspaceDetails(
      ctx, coefs, srcRange, coefs, 1,
      brightness, contrast, saturation);

    if (err < 0)


    return 0;


More information about the Libav-user mailing list