[FFmpeg-devel] [PATCH] pgssubdec: fix subpicture output colorspace and range

wm4 nfxjfg at googlemail.com
Sat Apr 23 13:18:44 CEST 2016


On Fri, 22 Apr 2016 23:06:37 +0300
Jan Ekström <jeebjp at gmail.com> wrote:

> Functionality used before didn't widen the values from limited to
> full range. Additionally, now the decoder uses BT.709 where it
> should be used according to the video resolution.
> 
> Default for not yet set colorimetry is BT.709 due to most observed
> HDMV content being HD.
> 
> BT.709 coefficients were gathered from the first two parts of BT.709
> to BT.2020 conversion guide in ARIB STD-B62 (Pt. 1, Chapter 6.2.2).
> 
> Based on a patch by Carl Eugen Hoyos.
> ---
>  libavcodec/pgssubdec.c | 20 ++++++++++++++++++--
>  libavutil/colorspace.h | 10 ++++++++++
>  2 files changed, 28 insertions(+), 2 deletions(-)
> 
> diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
> index 07a2a78..4145f1c 100644
> --- a/libavcodec/pgssubdec.c
> +++ b/libavcodec/pgssubdec.c
> @@ -96,6 +96,7 @@ typedef struct PGSSubContext {
>      PGSSubPalettes     palettes;
>      PGSSubObjects      objects;
>      int forced_subs_only;
> +    int hdtv;
>  } PGSSubContext;
>  
>  static void flush_cache(AVCodecContext *avctx)
> @@ -136,6 +137,9 @@ static PGSSubPalette * find_palette(int id, PGSSubPalettes *palettes)
>  
>  static av_cold int init_decoder(AVCodecContext *avctx)
>  {
> +    PGSSubContext *ctx = avctx->priv_data;
> +    ctx->hdtv          = -1;
> +
>      avctx->pix_fmt     = AV_PIX_FMT_PAL8;
>  
>      return 0;
> @@ -354,8 +358,14 @@ static int parse_palette_segment(AVCodecContext *avctx,
>          cb        = bytestream_get_byte(&buf);
>          alpha     = bytestream_get_byte(&buf);
>  
> -        YUV_TO_RGB1(cb, cr);
> -        YUV_TO_RGB2(r, g, b, y);
> +        /* Default to HDTV (-1 or 1) */
> +        if (ctx->hdtv) {
> +            YUV_TO_RGB1_CCIR_BT709(cb, cr);
> +        } else {
> +            YUV_TO_RGB1_CCIR(cb, cr);
> +        }
> +
> +        YUV_TO_RGB2_CCIR(r, g, b, y);
>  
>          ff_dlog(avctx, "Color %d := (%d,%d,%d,%d)\n", color_id, r, g, b, alpha);
>  
> @@ -388,6 +398,12 @@ static int parse_presentation_segment(AVCodecContext *avctx,
>      int w = bytestream_get_be16(&buf);
>      int h = bytestream_get_be16(&buf);
>  
> +    // Set colorimetry according to resolution
> +    if (h > 576)
> +        ctx->hdtv = 1;
> +    else
> +        ctx->hdtv = 0;
> +
>      ctx->presentation.pts = pts;
>  
>      ff_dlog(avctx, "Video Dimensions %dx%d\n",
> diff --git a/libavutil/colorspace.h b/libavutil/colorspace.h
> index 826ffd5..7d3f711 100644
> --- a/libavutil/colorspace.h
> +++ b/libavutil/colorspace.h
> @@ -41,6 +41,16 @@
>      b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
>  }
>  
> +#define YUV_TO_RGB1_CCIR_BT709(cb1, cr1)\
> +{\
> +    cb = (cb1) - 128;\
> +    cr = (cr1) - 128;\
> +    r_add = FIX(1.5747*255.0/224.0) * cr + ONE_HALF;\
> +    g_add = - FIX(0.1873*255.0/224.0) * cb - FIX(0.4682*255.0/224.0) * cr + \
> +            ONE_HALF;\
> +    b_add = FIX(1.8556*255.0/224.0) * cb + ONE_HALF;\
> +}
> +
>  #define YUV_TO_RGB2_CCIR(r, g, b, y1)\
>  {\
>      y = ((y1) - 16) * FIX(255.0/219.0);\

This still has the problem that the palette could be read before the
resolution is known.


More information about the ffmpeg-devel mailing list