From a4c079d1b30e79028bcd8b1b1850aabece37e400 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 26 Aug 2021 14:15:09 -0400 Subject: [PATCH] Add code to set colour ranges so that we can safely convert to YUV420p instead of YUVJ420P --- src/zm_monitor.cpp | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 60b02c2e9..66c91fe15 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -2593,11 +2593,33 @@ bool Monitor::Decode() { if (!convert_context) { AVPixelFormat imagePixFormat = (AVPixelFormat)(packet->image->AVPixFormat()); + AVPixelFormat inputPixFormat; + bool changeColorspaceDetails = false; + switch (input_frame->format) { + case AV_PIX_FMT_YUVJ420P: + inputPixFormat = AV_PIX_FMT_YUV420P; + changeColorspaceDetails = true; + break; + case AV_PIX_FMT_YUVJ422P: + inputPixFormat = AV_PIX_FMT_YUV422P; + changeColorspaceDetails = true; + break; + case AV_PIX_FMT_YUVJ444P: + inputPixFormat = AV_PIX_FMT_YUV444P; + changeColorspaceDetails = true; + break; + case AV_PIX_FMT_YUVJ440P: + inputPixFormat = AV_PIX_FMT_YUV440P; + changeColorspaceDetails = true; + break; + default: + inputPixFormat = (AVPixelFormat)input_frame->format; + } convert_context = sws_getContext( input_frame->width, input_frame->height, - (AVPixelFormat)input_frame->format, + inputPixFormat, camera_width, camera_height, imagePixFormat, SWS_BICUBIC, nullptr, nullptr, nullptr); @@ -2611,10 +2633,22 @@ bool Monitor::Decode() { } else { Debug(1, "Setup conversion context for %dx%d %s to %dx%d %s", input_frame->width, input_frame->height, - av_get_pix_fmt_name((AVPixelFormat)input_frame->format), + av_get_pix_fmt_name(inputPixFormat), camera_width, camera_height, av_get_pix_fmt_name(imagePixFormat) ); + 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(convert_context, (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(convert_context, coefs, srcRange, coefs, dstRange, + brightness, contrast, saturation); + } + } } if (convert_context) {