swscaler warning : deprecated pixel format used
Asked Answered
A

2

19

I want to perform a color space conversion of my video frame before converting it to an opengl texture with the following code:

struct SwsContext * pSwsCtx = sws_getCachedContext(NULL,width, height, codec->pix_fmt, width, height, AV_PIX_FMT_RGBA, SWS_POINT, NULL, NULL, NULL);

Each time the sws_getCachedContext() function is called I got the following warning:

[swscaler @ 0x10506fa00] deprecated pixel format used, make sure you did set range correctly

Here is my ffmpeg output for version information:

ffmpeg version 2.2 Copyright (c) 2000-2014 the FFmpeg developers
  built on Mar 26 2014 15:29:01 with Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/2.2 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --enable-avresample --enable-vda --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libfaac --enable-libmp3lame --enable-libxvid
  libavutil      52. 66.100 / 52. 66.100
  libavcodec     55. 52.102 / 55. 52.102
  libavformat    55. 33.100 / 55. 33.100
  libavdevice    55. 10.100 / 55. 10.100
  libavfilter     4.  2.100 /  4.  2.100
  libavresample   1.  2.  0 /  1.  2.  0
  libswscale      2.  5.102 /  2.  5.102
  libswresample   0. 18.100 /  0. 18.100
  libpostproc    52.  3.100 / 52.  3.100
Hyper fast Audio and Video encoder

Any idea to disable this warning? How to set the color range correctly?

All answered 14/4, 2014 at 18:39 Comment(3)
How recent is your ffmpeg? trac.ffmpeg.org/ticket/3242 trac.ffmpeg.org/ticket/3094Galbraith
Did you get the same on sws_getContext ?Necroscopy
@Necroscopy I get the same with sws_getContextAll
C
13

It seems you're trying to read AV_PIX_FMT_YUVJXXXP frames which are deprecated (see the libav doc). You can use this workaround to manage it :

AVPixelFormat pixFormat;
switch (_videoStream->codec->pix_fmt) {
case AV_PIX_FMT_YUVJ420P :
    pixFormat = AV_PIX_FMT_YUV420P;
    break;
case AV_PIX_FMT_YUVJ422P  :
    pixFormat = AV_PIX_FMT_YUV422P;
    break;
case AV_PIX_FMT_YUVJ444P   :
    pixFormat = AV_PIX_FMT_YUV444P;
    break;
case AV_PIX_FMT_YUVJ440P :
    pixFormat = AV_PIX_FMT_YUV440P;
    break;
default:
    pixFormat = _videoStream->codec->codec->pix_fmts;
    break;
}
Chryso answered 22/4, 2014 at 10:24 Comment(5)
My video stream AVPixelFormat is AV_PIX_FMT_YUVJ420P. Using the above workaround, It gets converted to AV_PIX_FMT_YUV420P. "[swscaler @ 0dd9e620] deprecated pixel format used, make sure you did set range correctly". How can I resolve it?Fitly
yes. I get RTSP video stream, decode it using FFMpeg and then convert it to cv::MAT.Fitly
@Fitly you should post another question with more code, I can't help you with just thisChryso
Thanks for your suggestion Thomas; I posted this problem as another question with sample code at #30938188Fitly
@ThomasAyoub what are the implications of using this W/A - indeed it will eliminate the warning, but about the conversion per-se to RGB ?Kith
S
14

It is long time since the question was asked, but as I hit the same problem then I looked at it and tried to find also the answer to the second part (How to set the color range correctly?). I am extending the Thomas Ayoub's answer:

AVCodecContext* pCodecCtx = _videoStream->codec;
AVPixelFormat pixFormat;
bool changeColorspaceDetails = false;
switch (pCodecCtx->pix_fmt)
  {
    case AV_PIX_FMT_YUVJ420P:
      pixFormat = AV_PIX_FMT_YUV420P;
      changeColorspaceDetails = true;
      break;
    case AV_PIX_FMT_YUVJ422P:
      pixFormat = AV_PIX_FMT_YUV422P;
      changeColorspaceDetails = true;
      break;
    case AV_PIX_FMT_YUVJ444P:
      pixFormat = AV_PIX_FMT_YUV444P;
      changeColorspaceDetails = true;
      break;
    case AV_PIX_FMT_YUVJ440P:
      pixFormat = AV_PIX_FMT_YUV440P;
      changeColorspaceDetails = true;
      break;
    default:
      pixFormat = pCodecCtx->pix_fmt;
  }
// initialize SWS context for software scaling
SwsContext *swsCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pixFormat, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BILINEAR, NULL, NULL, NULL);

if (changeColorspaceDetails)
{
    // change the range of input data by first reading the current color space and then setting it's range as yuvj.
    int dummy[4];
    int srcRange, dstRange;
    int brightness, contrast, saturation;
    sws_getColorspaceDetails(swsCtx, (int**)&dummy, &srcRange, (int**)&dummy, &dstRange, &brightness, &contrast, &saturation);
    const int* coefs = sws_getCoefficients(SWS_CS_DEFAULT);
    srcRange = 1; // this marks that values are according to yuvj
    sws_setColorspaceDetails(swsCtx, coefs, srcRange, coefs, dstRange,
                               brightness, contrast, saturation);
}

What is it about the ranges? The YUV pixel format has values in ranges: Y 16..235, UV 16..240. The YUVJ is extended one and all YUV are 0 ... 255. So setting

srcRange = 1

forces the libav to use extended input data range. If you do not make any changes in the range then probably you only experience exaggerated contrast. It should still scale the input data to RGB color space.

Solferino answered 12/12, 2017 at 12:44 Comment(4)
I very much prefer your answer because it explains the differences in formats and how to fully navigate them.Phantasmal
One tweak: if (pixFormat != pCodecCtx->pix_fmt) srcRange = 1; would make it only treat the src range as 0..255 if the stream pixel format is YUVJ, right?Kex
Raptor007: you are right. Updated the answer so that the range is changed only in cases the pixel format was changed.Solferino
This is a helpful answer, but it does not explain why the table and inverse table are being set to sws_getCoefficients(SWS_CS_DEFAULT) as opposed to dummy. Why are we not using the prexisting table and inverse table? Are they invalidated when the srcRange changes?Dispensatory
C
13

It seems you're trying to read AV_PIX_FMT_YUVJXXXP frames which are deprecated (see the libav doc). You can use this workaround to manage it :

AVPixelFormat pixFormat;
switch (_videoStream->codec->pix_fmt) {
case AV_PIX_FMT_YUVJ420P :
    pixFormat = AV_PIX_FMT_YUV420P;
    break;
case AV_PIX_FMT_YUVJ422P  :
    pixFormat = AV_PIX_FMT_YUV422P;
    break;
case AV_PIX_FMT_YUVJ444P   :
    pixFormat = AV_PIX_FMT_YUV444P;
    break;
case AV_PIX_FMT_YUVJ440P :
    pixFormat = AV_PIX_FMT_YUV440P;
    break;
default:
    pixFormat = _videoStream->codec->codec->pix_fmts;
    break;
}
Chryso answered 22/4, 2014 at 10:24 Comment(5)
My video stream AVPixelFormat is AV_PIX_FMT_YUVJ420P. Using the above workaround, It gets converted to AV_PIX_FMT_YUV420P. "[swscaler @ 0dd9e620] deprecated pixel format used, make sure you did set range correctly". How can I resolve it?Fitly
yes. I get RTSP video stream, decode it using FFMpeg and then convert it to cv::MAT.Fitly
@Fitly you should post another question with more code, I can't help you with just thisChryso
Thanks for your suggestion Thomas; I posted this problem as another question with sample code at #30938188Fitly
@ThomasAyoub what are the implications of using this W/A - indeed it will eliminate the warning, but about the conversion per-se to RGB ?Kith

© 2022 - 2024 — McMap. All rights reserved.