From 28cc17e309fc6117370b38ec11d803dc36e8ef01 Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Mon, 19 Aug 2024 22:34:37 +0000 Subject: [PATCH 1/2] H264Libav: Handle colour space conversion The scaler is now informed of the colour space encoded into the stream so that it may do the proper conversion. --- common/rfb/H264LibavDecoderContext.cxx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/common/rfb/H264LibavDecoderContext.cxx b/common/rfb/H264LibavDecoderContext.cxx index 38210205f3..c3153fd155 100644 --- a/common/rfb/H264LibavDecoderContext.cxx +++ b/common/rfb/H264LibavDecoderContext.cxx @@ -217,6 +217,21 @@ void H264LibavDecoderContext::decode(const uint8_t* h264_in_buffer, frame->width, frame->height, AV_PIX_FMT_RGB32, 0, nullptr, nullptr, nullptr); + int inFull, outFull, brightness, contrast, saturation; + const int* inTable; + const int* outTable; + + sws_getColorspaceDetails(sws, (int**)&inTable, &inFull, (int**)&outTable, + &outFull, &brightness, &contrast, &saturation); + if (frame->colorspace != AVCOL_SPC_UNSPECIFIED) { + inTable = sws_getCoefficients(frame->colorspace); + } + if (frame->color_range != AVCOL_RANGE_UNSPECIFIED) { + inFull = frame->color_range == AVCOL_RANGE_JPEG; + } + sws_setColorspaceDetails(sws, inTable, inFull, outTable, outFull, brightness, + contrast, saturation); + if (rgbFrame && (rgbFrame->width != frame->width || rgbFrame->height != frame->height)) { av_frame_free(&rgbFrame); From c68714aee15f1e6c75d53c398ea9b9178f64fcfb Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Thu, 22 Aug 2024 21:26:59 +0000 Subject: [PATCH 2/2] H264Libav: Use nearest-neighbour sampling in scaler sws_getCachedContext will set a default sampling method if 0 is passed to the flags argument. This means that when it is called again, the flags argument will not match the flags in the context, so a new one will be allocated every time. To get around this problem, we assign an explicit sampling method, one that also happens to be more efficient and just as good for this use-case as the default one, which is bicubic interpolation. --- common/rfb/H264LibavDecoderContext.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/rfb/H264LibavDecoderContext.cxx b/common/rfb/H264LibavDecoderContext.cxx index c3153fd155..73bfb68c38 100644 --- a/common/rfb/H264LibavDecoderContext.cxx +++ b/common/rfb/H264LibavDecoderContext.cxx @@ -215,7 +215,7 @@ void H264LibavDecoderContext::decode(const uint8_t* h264_in_buffer, sws = sws_getCachedContext(sws, frame->width, frame->height, avctx->pix_fmt, frame->width, frame->height, AV_PIX_FMT_RGB32, - 0, nullptr, nullptr, nullptr); + SWS_POINT, nullptr, nullptr, nullptr); int inFull, outFull, brightness, contrast, saturation; const int* inTable;