[FFmpeg-devel] [PATCH] pgssubdec: fix subpicture output colorspace and range
Hendrik Leppkes
h.leppkes at gmail.com
Sat Apr 23 13:53:00 CEST 2016
On Sat, Apr 23, 2016 at 1:18 PM, wm4 <nfxjfg at googlemail.com> wrote:
> 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.
The Blu-ray specification controls the order of segments, and this
should not happen on conformant streams.
Otherwise, I think Carl's suggestion might help, PGS subtitles are
generally from Blu-rays, which means most of it is HD, so swapping the
flag to detect SD conditions might make it act more "appropriate" in
absence of w/h.
- Hendrik
More information about the ffmpeg-devel
mailing list