diff options
author | arch1t3cht <arch1t3cht@gmail.com> | 2024-10-13 14:45:28 +0200 |
---|---|---|
committer | rcombs <rcombs@rcombs.me> | 2024-10-19 11:08:34 -0500 |
commit | 72e538112341ba7e5a167ca09fd98b627ed40454 (patch) | |
tree | 8ea0c8615fc4228f783dc2a2a6022b4da682db3e | |
parent | c98810ab47fa1cf339b16045e27fbe12b3a19951 (diff) | |
download | ffmpeg-72e538112341ba7e5a167ca09fd98b627ed40454.tar.gz |
avfilter/vf_subtitles: Respect YCbCr Matrix header
As specified in libass's ass_types.h, the colors or ASS_Images
should be converted to YCbCr using the matrix/range specified in
the track's YCbCrMatrix field (unless that field is set to YCBCR_NONE,
and defaulting to TV.601 if the header is missing).
This does not affect any subtitles generated or transcoded by ffmpeg,
since these contain a 'YCbCrMatrix: None' header.
Signed-off-by: arch1t3cht <arch1t3cht@gmail.com>
Signed-off-by: rcombs <rcombs@rcombs.me>
-rw-r--r-- | libavfilter/vf_subtitles.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c index d7f61d2f22..9eaaf2eb90 100644 --- a/libavfilter/vf_subtitles.c +++ b/libavfilter/vf_subtitles.c @@ -88,6 +88,40 @@ static const int ass_libavfilter_log_level_map[] = { [7] = AV_LOG_DEBUG, /* MSGL_DBG2 */ }; +static enum AVColorSpace ass_get_color_space(ASS_YCbCrMatrix ass_matrix, enum AVColorSpace inlink_space) { + switch (ass_matrix) { + case YCBCR_NONE: return inlink_space; + case YCBCR_SMPTE240M_TV: + case YCBCR_SMPTE240M_PC: return AVCOL_SPC_SMPTE240M; + case YCBCR_FCC_TV: + case YCBCR_FCC_PC: return AVCOL_SPC_FCC; + case YCBCR_BT709_TV: + case YCBCR_BT709_PC: return AVCOL_SPC_BT709; + case YCBCR_BT601_TV: + case YCBCR_BT601_PC: + case YCBCR_DEFAULT: + case YCBCR_UNKNOWN: + default: return AVCOL_SPC_SMPTE170M; + } +} + +static enum AVColorRange ass_get_color_range(ASS_YCbCrMatrix ass_matrix, enum AVColorRange inlink_range) { + switch (ass_matrix) { + case YCBCR_NONE: return inlink_range; + case YCBCR_SMPTE240M_PC: + case YCBCR_FCC_PC: + case YCBCR_BT709_PC: + case YCBCR_BT601_PC: return AVCOL_RANGE_JPEG; + case YCBCR_SMPTE240M_TV: + case YCBCR_FCC_TV: + case YCBCR_BT709_TV: + case YCBCR_BT601_TV: + case YCBCR_DEFAULT: + case YCBCR_UNKNOWN: + default: return AVCOL_RANGE_MPEG; + } +} + static void ass_log(int ass_level, const char *fmt, va_list args, void *ctx) { const int ass_level_clip = av_clip(ass_level, 0, @@ -150,7 +184,9 @@ static int config_input(AVFilterLink *inlink) { AssContext *ass = inlink->dst->priv; - ff_draw_init2(&ass->draw, inlink->format, inlink->colorspace, inlink->color_range, + ff_draw_init2(&ass->draw, inlink->format, + ass_get_color_space(ass->track->YCbCrMatrix, inlink->colorspace), + ass_get_color_range(ass->track->YCbCrMatrix, inlink->color_range), ass->alpha ? FF_DRAW_PROCESS_ALPHA : 0); ass_set_frame_size (ass->renderer, inlink->w, inlink->h); |