From cf0d31e8fb3088d04f5f97b676ac8ece65b24a6b Mon Sep 17 00:00:00 2001 From: aktamilbe <59253707+aktamilbe@users.noreply.github.com> Date: Thu, 31 Jul 2025 14:49:24 +0100 Subject: [PATCH 01/11] RDKEMW-5197 : Add Advance PQ Params Plugin changes --- AVOutput/AVOutput.cpp | 19 +- AVOutput/AVOutputTV.cpp | 5100 +++++++++++++++++++++++---------- AVOutput/AVOutputTV.h | 256 +- AVOutput/AVOutputTVHelper.cpp | 1287 ++++++++- AVOutput/CHANGELOG.md | 3 + 5 files changed, 5062 insertions(+), 1603 deletions(-) diff --git a/AVOutput/AVOutput.cpp b/AVOutput/AVOutput.cpp index fc8dd79f..a1ecc207 100644 --- a/AVOutput/AVOutput.cpp +++ b/AVOutput/AVOutput.cpp @@ -22,10 +22,27 @@ #include "UtilsIarm.h" #include "UtilsSearchRDKProfile.h" +#define API_VERSION_NUMBER_MAJOR 1 +#define API_VERSION_NUMBER_MINOR 1 +#define API_VERSION_NUMBER_PATCH 0 + namespace WPEFramework { namespace Plugin { - SERVICE_REGISTRATION(AVOutput,1, 0); + static Plugin::Metadata metadata( + // Version (Major, Minor, Patch) + API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH, + // Preconditions + {}, + // Terminations + {}, + // Controls + {} + ); + + + SERVICE_REGISTRATION(AVOutput, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); + AVOutput::AVOutput() { diff --git a/AVOutput/AVOutputTV.cpp b/AVOutput/AVOutputTV.cpp index b686669c..34ff9c82 100644 --- a/AVOutput/AVOutputTV.cpp +++ b/AVOutput/AVOutputTV.cpp @@ -358,6 +358,55 @@ namespace Plugin { registerMethod("resetAutoBacklightMode", &AVOutputTV::resetAutoBacklightMode, this); registerMethod("getAutoBacklightModeCaps", &AVOutputTV::getAutoBacklightModeCaps, this); + registerMethod("getBacklightCapsV2", &AVOutputTV::getBacklightCapsV2, this); + registerMethod("getBrightnessCapsV2", &AVOutputTV::getBrightnessCapsV2, this); + registerMethod("getContrastCapsV2", &AVOutputTV::getContrastCapsV2, this); + registerMethod("getSharpnessCapsV2", &AVOutputTV::getSharpnessCapsV2, this); + registerMethod("getSaturationCapsV2", &AVOutputTV::getSaturationCapsV2, this); + registerMethod("getHueCapsV2", &AVOutputTV::getHueCapsV2, this); + registerMethod("getLowLatencyStateCapsV2", &AVOutputTV::getLowLatencyStateCapsV2, this); + registerMethod("getColorTemperatureCapsV2", &AVOutputTV::getColorTemperatureCapsV2, this); + registerMethod("getBacklightDimmingModeCapsV2", &AVOutputTV::getBacklightDimmingModeCapsV2, this); + registerMethod("getZoomModeCapsV2", &AVOutputTV::getZoomModeCapsV2, this); + registerMethod("getDolbyVisionCalibrationCaps", &AVOutputTV::getDolbyVisionCalibrationCaps, this); + registerMethod("getPictureModeCapsV2", &AVOutputTV::getPictureModeCapsV2, this); + registerMethod("getAutoBacklightModeCapsV2", &AVOutputTV::getAutoBacklightModeCapsV2, this); + registerMethod("getCMSCapsV2", &AVOutputTV::getCMSCapsV2, this); + registerMethod("get2PointWBCapsV2", &AVOutputTV::get2PointWBCapsV2, this); + registerMethod("getSDRGammaCaps", &AVOutputTV::getSDRGammaCaps, this); + + registerMethod("getPrecisionDetailCaps", &AVOutputTV::getPrecisionDetailCaps, this); + registerMethod("getPrecisionDetail", &AVOutputTV::getPrecisionDetail, this); + registerMethod("setPrecisionDetail", &AVOutputTV::setPrecisionDetail, this); + registerMethod("resetPrecisionDetail", &AVOutputTV::resetPrecisionDetail, this); + + registerMethod("getLocalContrastEnhancementCaps", &AVOutputTV::getLocalContrastEnhancementCaps, this); + registerMethod("getLocalContrastEnhancement", &AVOutputTV::getLocalContrastEnhancement, this); + registerMethod("setLocalContrastEnhancement", &AVOutputTV::setLocalContrastEnhancement, this); + registerMethod("resetLocalContrastEnhancement", &AVOutputTV::resetLocalContrastEnhancement, this); + + registerMethod("getMPEGNoiseReductionCaps", &AVOutputTV::getMPEGNoiseReductionCaps, this); + registerMethod("getMPEGNoiseReduction", &AVOutputTV::getMPEGNoiseReduction, this); + registerMethod("setMPEGNoiseReduction", &AVOutputTV::setMPEGNoiseReduction, this); + registerMethod("resetMPEGNoiseReduction", &AVOutputTV::resetMPEGNoiseReduction, this); + + registerMethod("getDigitalNoiseReductionCaps", &AVOutputTV::getDigitalNoiseReductionCaps, this); + registerMethod("getDigitalNoiseReduction", &AVOutputTV::getDigitalNoiseReduction, this); + registerMethod("setDigitalNoiseReduction", &AVOutputTV::setDigitalNoiseReduction, this); + registerMethod("resetDigitalNoiseReduction", &AVOutputTV::resetDigitalNoiseReduction, this); + + registerMethod("getMEMCCaps", &AVOutputTV::getMEMCCaps, this); + registerMethod("getMEMC", &AVOutputTV::getMEMC, this); + registerMethod("setMEMC", &AVOutputTV::setMEMC, this); + registerMethod("resetMEMC", &AVOutputTV::resetMEMC, this); + + registerMethod("getAISuperResolutionCaps", &AVOutputTV::getAISuperResolutionCaps, this); + registerMethod("getAISuperResolution", &AVOutputTV::getAISuperResolution, this); + registerMethod("setAISuperResolution", &AVOutputTV::setAISuperResolution, this); + registerMethod("resetAISuperResolution", &AVOutputTV::resetAISuperResolution, this); + + registerMethod("getMultiPointWBCaps", &AVOutputTV::getMultiPointWBCaps, this); + LOGINFO("Exit\n"); } @@ -459,399 +508,1584 @@ namespace Plugin { LOGINFO("Exit\n"); } - uint32_t AVOutputTV::getZoomModeCaps(const JsonObject& parameters, JsonObject& response) + // Shared zoom mode mappings + static const std::unordered_map zoomModeReverseMap = { + {tvDisplayMode_16x9, "TV 16X9 STRETCH"}, + {tvDisplayMode_4x3, "TV 4X3 PILLARBOX"}, + {tvDisplayMode_NORMAL, "TV NORMAL"}, + {tvDisplayMode_DIRECT, "TV DIRECT"}, + {tvDisplayMode_AUTO, "TV AUTO"}, + {tvDisplayMode_ZOOM, "TV ZOOM"}, + {tvDisplayMode_FULL, "TV FULL"} + }; + static const std::unordered_map zoomModeMap = { + {"TV 16X9 STRETCH", tvDisplayMode_16x9}, + {"TV 4X3 PILLARBOX", tvDisplayMode_4x3}, + {"TV NORMAL", tvDisplayMode_NORMAL}, + {"TV DIRECT", tvDisplayMode_DIRECT}, + {"TV AUTO", tvDisplayMode_AUTO}, + {"TV ZOOM", tvDisplayMode_ZOOM}, + {"TV FULL", tvDisplayMode_FULL} + }; + static const std::unordered_map dimmingModeReverseMap = { + { tvDimmingMode_Fixed, "Fixed" }, + { tvDimmingMode_Local, "Local" }, + { tvDimmingMode_Global, "Global" } + }; + static const std::unordered_map dimmingModeMap = { + { "Fixed", tvDimmingMode_Fixed }, + { "Local", tvDimmingMode_Local }, + { "Global", tvDimmingMode_Global } + }; + + bool AVOutputTV::getPQParamFromContext(const JsonObject& parameters, + const std::string& paramName, + tvPQParameterIndex_t paramType, + int& outValue) { - LOGINFO("Entry"); - capVectors_t info; - - JsonArray rangeArray; - JsonArray pqmodeArray; - JsonArray formatArray; - JsonArray sourceArray; - - unsigned int index = 0; - - tvError_t ret = getParamsCaps("AspectRatio",info); - - if(ret != tvERROR_NONE) { - returnResponse(false); - } - else { - for (index = 0; index < info.rangeVector.size(); index++) { - rangeArray.Add(info.rangeVector[index]); + tvConfigContext_t validContext = getValidContextFromGetParameters(parameters, paramName); + if ((validContext.videoSrcType == VIDEO_SOURCE_ALL && + validContext.videoFormatType == VIDEO_FORMAT_NONE && + validContext.pq_mode == PQ_MODE_INVALID)) + { + LOGWARN("No Valid context for get %s", paramName.c_str()); + return false; } - response["options"]=rangeArray; + paramIndex_t indexInfo + { + .sourceIndex = static_cast(validContext.videoSrcType), + .pqmodeIndex = static_cast(validContext.pq_mode), + .formatIndex = static_cast(validContext.videoFormatType) + }; - if (info.pqmodeVector.front().compare("none") != 0) { - for (index = 0; index < info.pqmodeVector.size(); index++) { - pqmodeArray.Add(info.pqmodeVector[index]); - } - response["pictureModeInfo"]=pqmodeArray; - } - if ((info.sourceVector.front()).compare("none") != 0) { - for (index = 0; index < info.sourceVector.size(); index++) { - sourceArray.Add(info.sourceVector[index]); - } - response["videoSourceInfo"]=sourceArray; - } - if ((info.formatVector.front()).compare("none") != 0) { - for (index = 0; index < info.formatVector.size(); index++) { - formatArray.Add(info.formatVector[index]); - } - response["videoFormatInfo"]=formatArray; - } - LOGINFO("Exit\n"); - returnResponse(true); + int value = 0; + tvError_t err = static_cast(getLocalparam(paramName.c_str(), indexInfo, value, paramType)); + if (err == tvERROR_NONE) { + outValue = value; + return true; } + + LOGERR("getLocalparam failed for %s with error code %d", paramName.c_str(), err); + return false; } - uint32_t AVOutputTV::setZoomMode(const JsonObject& parameters, JsonObject& response) + bool AVOutputTV::getEnumPQParamString( + const JsonObject& parameters, + const std::string& paramName, + tvPQParameterIndex_t pqType, + const std::unordered_map& enumToStrMap, + std::string& outStr) { - LOGINFO("Entry\n"); - std::string value; - tvDisplayMode_t mode = tvDisplayMode_16x9; - capDetails_t inputInfo; + LOGINFO("getEnumPQParamString Entry for %s\n", paramName.c_str()); + tvConfigContext_t validContext = getValidContextFromGetParameters(parameters, paramName); + if ((validContext.videoSrcType == VIDEO_SOURCE_ALL && + validContext.videoFormatType == VIDEO_FORMAT_NONE && + validContext.pq_mode == PQ_MODE_INVALID)) + { + LOGWARN("No valid context for get %s", paramName.c_str()); + return false; + } - value = parameters.HasLabel("zoomMode") ? parameters["zoomMode"].String() : ""; - returnIfParamNotFound(parameters,"zoomMode"); + paramIndex_t indexInfo { + .sourceIndex = static_cast(validContext.videoSrcType), + .pqmodeIndex = static_cast(validContext.pq_mode), + .formatIndex = static_cast(validContext.videoFormatType) + }; - if (validateInputParameter("AspectRatio",value) != 0) { - LOGERR("%s: Range validation failed for AspectRatio\n", __FUNCTION__); - returnResponse(false); + int paramValue = 0; + int err = getLocalparam(paramName, indexInfo, paramValue, pqType); + if (err != 0) { + LOGERR("Failed to get %s from localparam", paramName.c_str()); + return false; } - if (parsingSetInputArgument(parameters,"AspectRatio",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); + auto it = enumToStrMap.find(paramValue); + if (it != enumToStrMap.end()) { + outStr = it->second; + LOGINFO("%s = %s", paramName.c_str(), outStr.c_str()); + return true; + } else { + LOGERR("Enum value %d not found in map for %s", paramValue, paramName.c_str()); + return false; } + } + bool AVOutputTV::setCMSParam(const JsonObject& parameters) + { + LOGINFO("Entry: setCMSParam"); - if( !isCapablityCheckPassed( "AspectRatio",inputInfo )) { - LOGERR("%s: CapablityCheck failed for AspectRatio\n", __FUNCTION__); - returnResponse(false); - } + std::string colorStr = parameters.HasLabel("color") ? parameters["color"].String() : ""; + std::string componentStr = parameters.HasLabel("component") ? parameters["component"].String() : ""; + std::string levelStr = parameters.HasLabel("level") ? parameters["level"].String() : ""; - if(!value.compare("TV 16X9 STRETCH")) { - mode = tvDisplayMode_16x9; - } - else if (!value.compare("TV 4X3 PILLARBOX")) { - mode = tvDisplayMode_4x3; - } - else if (!value.compare("TV NORMAL")) { - mode = tvDisplayMode_NORMAL; - } - else if (!value.compare("TV DIRECT")) { - mode = tvDisplayMode_DIRECT; - } - else if (!value.compare("TV AUTO")) { - mode = tvDisplayMode_AUTO; - } - else if (!value.compare("TV ZOOM")) { - mode = tvDisplayMode_ZOOM; + if (colorStr.empty() || componentStr.empty() || levelStr.empty()) { + LOGERR("Missing color/component/level"); + return false; } + + int level = 0; + try { + level = std::stoi(levelStr); + } catch (...) { + LOGERR("Invalid level value: %s", levelStr.c_str()); + return false; + } + + int maxCap = 0; + if (componentStr == "Hue") + maxCap = m_maxCmsHue; + else if (componentStr == "Saturation") + maxCap = m_maxCmsSaturation; + else if (componentStr == "Luma") + maxCap = m_maxCmsLuma; else { - returnResponse(false); + LOGERR("Invalid component: %s", componentStr.c_str()); + return false; } - m_videoZoomMode = mode; - tvError_t ret = setAspectRatioZoomSettings (mode); - if(ret != tvERROR_NONE) { - returnResponse(false); + if (level < 0 || level > maxCap) { + LOGERR("Level out of range: %d (0-%d)", level, maxCap); + return false; } - else { - //Save DisplayMode to localstore and ssm_data - int retval=updateAVoutputTVParam("set","AspectRatio",inputInfo,PQ_PARAM_ASPECT_RATIO,mode); - - if(retval != 0) { - LOGERR("Failed to Save DisplayMode to ssm_data\n"); - returnResponse(false); - } - tr181ErrorCode_t err = setLocalParam(rfc_caller_id, AVOUTPUT_ASPECTRATIO_RFC_PARAM, value.c_str()); - if ( err != tr181Success ) { - LOGERR("setLocalParam for %s Failed : %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, getTR181ErrorString(err)); - returnResponse(false); - } - else { - LOGINFO("setLocalParam for %s Successful, Value: %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, value.c_str()); - } - LOGINFO("Exit : SetAspectRatio() value : %s\n",value.c_str()); - returnResponse(true); + tvDataComponentColor_t colorEnum; + if (getCMSColorEnumFromString(colorStr, colorEnum) != 0) { + LOGERR("Invalid color: %s", colorStr.c_str()); + return false; } - } - uint32_t AVOutputTV::getZoomMode(const JsonObject& parameters, JsonObject& response) - { - LOGINFO("Entry\n"); - tvDisplayMode_t mode; + if( isSetRequiredForParam(parameters, "CMS") ) { + LOGINFO("Proceed with SetCMSState \n"); + tvError_t ret = SetCMSState(true); + if(ret != tvERROR_NONE) { + LOGWARN("CMS enable failed\n"); + return false; + } + if (componentStr == "Hue") + ret = SetCurrentComponentHue(colorEnum, level); + else if (componentStr == "Saturation") + ret = SetCurrentComponentSaturation(colorEnum, level); + else if (componentStr == "Luma") + ret = SetCurrentComponentLuma(colorEnum, level); - tvError_t ret = getUserSelectedAspectRatio (&mode); + if (ret != tvERROR_NONE) { + LOGERR("HAL set failed for %s", componentStr.c_str()); + return false; + } + } - if(ret != tvERROR_NONE) { - returnResponse(false); + try { + int retVal = updateAVoutputTVParamV2("set", "CMS", parameters, PQ_PARAM_CMS, level); + if (retVal < 0) { + LOGERR("setCMSParam: Failed to save CMS param, return code: %d", retVal); + return false; + } + } catch (const std::exception& e) { + LOGERR("Exception in updateAVoutputTVParamV2: %s", e.what()); + return false; + } catch (...) { + LOGERR("Unknown exception in updateAVoutputTVParamV2"); + return false; } - else { - switch(mode) { - case tvDisplayMode_16x9: - LOGINFO("Aspect Ratio: TV 16X9 STRETCH\n"); - response["zoomMode"] = "TV 16X9 STRETCH"; - break; - case tvDisplayMode_4x3: - LOGINFO("Aspect Ratio: TV 4X3 PILLARBOX\n"); - response["zoomMode"] = "TV 4X3 PILLARBOX"; - break; + LOGINFO("Exit: setCMSParam success"); + return true; + } - case tvDisplayMode_NORMAL: - LOGINFO("Aspect Ratio: TV Normal\n"); - response["zoomMode"] = "TV NORMAL"; - break; - case tvDisplayMode_AUTO: - LOGINFO("Aspect Ratio: TV AUTO\n"); - response["zoomMode"] = "TV AUTO"; - break; + bool AVOutputTV::setEnumPQParam(const JsonObject& parameters, + const std::string& inputKey, + const std::string& paramName, + const std::unordered_map& valueMap, + tvPQParameterIndex_t paramType, + std::function halSetter) + { + if (!parameters.HasLabel(inputKey.c_str())) { + LOGERR("Missing input field: %s", inputKey.c_str()); + return false; + } - case tvDisplayMode_DIRECT: - LOGINFO("Aspect Ratio: TV DIRECT\n"); - response["zoomMode"] = "TV DIRECT"; - break; + std::string value = parameters[inputKey.c_str()].String(); + auto it = valueMap.find(value); + if (it == valueMap.end()) { + LOGERR("Invalid value '%s' for parameter: %s", value.c_str(), inputKey.c_str()); + return false; + } - case tvDisplayMode_ZOOM: - LOGINFO("Aspect Ratio: TV ZOOM\n"); - response["zoomMode"] = "TV ZOOM"; - break; + int intVal = it->second; - default: - LOGINFO("Aspect Ratio: TV AUTO\n"); - response["zoomMode"] = "TV AUTO"; - break; + // Only call HAL for current system context + if (isSetRequiredForParam(parameters, paramName)) { + LOGINFO("Calling HAL for %s = %s intVal %d", paramName.c_str(), value.c_str(), intVal); + tvError_t ret = halSetter(intVal); + if (ret != tvERROR_NONE) { + LOGERR("HAL setter failed for %s", paramName.c_str()); + return false; } - returnResponse(true); } + + // Persist the parameter contextually + int result = updateAVoutputTVParamV2("set", paramName, parameters, paramType, intVal); + if (result != 0) { + LOGERR("Persistence failed for %s", paramName.c_str()); + return false; + } + + LOGINFO("setEnumPQParam successful: %s = %s", paramName.c_str(), value.c_str()); + return true; } - uint32_t AVOutputTV::resetZoomMode(const JsonObject& parameters, JsonObject& response) + bool AVOutputTV::setIntPQParam(const JsonObject& parameters, const std::string& paramName, + tvPQParameterIndex_t pqType, tvSetFunction halSetter, int maxCap) { - LOGINFO("Entry\n"); - capDetails_t inputInfo; + LOGINFO("Entry: %s\n", paramName.c_str()); + int paramValue = 0; tvError_t ret = tvERROR_NONE; + std::string value = ""; + std::string lowerParamName = paramName; + std::transform(lowerParamName.begin(), lowerParamName.end(), lowerParamName.begin(), ::tolower); - if (parsingSetInputArgument(parameters, "AspectRatio",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); + if (!parameters.HasLabel(lowerParamName.c_str())) { + LOGERR("%s: Missing parameter: %s", __FUNCTION__, lowerParamName.c_str()); + return false; } - if( !isCapablityCheckPassed( "AspectRatio",inputInfo )) { - LOGERR("%s: CapablityCheck failed for AspectRatio\n", __FUNCTION__); - returnResponse(false); - } + value = parameters[lowerParamName.c_str()].String(); - tr181ErrorCode_t err = clearLocalParam(rfc_caller_id,AVOUTPUT_ASPECTRATIO_RFC_PARAM); - if ( err != tr181Success ) { - LOGERR("clearLocalParam for %s Failed : %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, getTR181ErrorString(err)); - ret = tvERROR_GENERAL; - } - else { - ret = setDefaultAspectRatio(inputInfo.pqmode,inputInfo.source,inputInfo.format); - } - if(ret != tvERROR_NONE) { - returnResponse(false); - } - else { - LOGINFO("Exit : resetDefaultAspectRatio()\n"); - returnResponse(true); + try { + paramValue = std::stoi(value); + } catch (const std::exception& e) { + LOGERR("Invalid %s value: %s. Exception: %s", paramName.c_str(), value.c_str(), e.what()); + return false; } - } - uint32_t AVOutputTV::getVideoFormat(const JsonObject& parameters, JsonObject& response) - { - LOGINFO("Entry\n"); - tvVideoFormatType_t videoFormat; - tvError_t ret = GetCurrentVideoFormat(&videoFormat); - if(ret != tvERROR_NONE) { - response["currentVideoFormat"] = "NONE"; - returnResponse(false); - } - else { - response["currentVideoFormat"] = getVideoFormatTypeToString(videoFormat); - LOGINFO("Exit: getVideoFormat :%d success \n",videoFormat); - returnResponse(true); + if (paramValue < 0 || paramValue > maxCap) { + LOGERR("Input value %d is out of range (0 - %d) for %s", paramValue, maxCap, paramName.c_str()); + return false; } - } - uint32_t AVOutputTV::getVideoResolution(const JsonObject& parameters, JsonObject& response) - { - LOGINFO("Entry\n"); - tvResolutionParam_t videoResolution; - tvError_t ret = GetCurrentVideoResolution(&videoResolution); - if(ret != tvERROR_NONE) { - response["currentVideoResolution"] = "NONE"; - returnResponse(false); + if (isSetRequiredForParam(parameters, paramName)) { + LOGINFO("Proceed with set%s\n", paramName.c_str()); + ret = halSetter(paramValue); + LOGINFO("halsetter ret %d \n", ret); + if (ret != tvERROR_NONE){ + LOGERR("Failed to set %s\n", paramName.c_str()); + return false; + } } - else { - response["currentVideoResolution"] = getVideoResolutionTypeToString(videoResolution); - LOGINFO("Exit: getVideoResolution :%d success \n",videoResolution.resolutionValue); - returnResponse(true); + LOGINFO("Calling updateAVOutputTVParamV2 \n"); + int retval = updateAVoutputTVParamV2("set", paramName, parameters, pqType, paramValue); + if (retval != 0) { + LOGERR("Failed to Save %s to ssm_data. retval: %d\n", paramName.c_str(), retval); + return false; } - } - uint32_t AVOutputTV::getVideoFrameRate(const JsonObject& parameters, JsonObject& response) - { - LOGINFO("Entry\n"); - tvVideoFrameRate_t videoFramerate; - tvError_t ret = GetCurrentVideoFrameRate(&videoFramerate); - if(ret != tvERROR_NONE) { - response["currentVideoFrameRate"] = "NONE"; - returnResponse(false); - } - else { - response["currentVideoFrameRate"] = getVideoFrameRateTypeToString(videoFramerate); - LOGINFO("Exit: videoFramerate :%d success \n",videoFramerate); - returnResponse(true); - } + LOGINFO("Exit: set%s successful to value: %d\n", paramName.c_str(), paramValue); + return true; } - uint32_t AVOutputTV::getBacklight(const JsonObject& parameters, JsonObject& response) + uint32_t AVOutputTV::getPQCapabilityWithContext( + const std::function& getCapsFunc, + const JsonObject& parameters, + JsonObject& response) { - LOGINFO("Entry"); + int max_value = 0; + tvContextCaps_t* context_caps = nullptr; - capDetails_t inputInfo; - std::string key; - paramIndex_t indexInfo; - int backlight = 0,err = 0; + // Call the HAL function + tvError_t result = getCapsFunc(&context_caps, &max_value); + LOGWARN("AVOutputPlugins: %s: result: %d", __FUNCTION__, result); - if (parsingGetInputArgument(parameters, "Backlight",inputInfo) != 0) { - LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); + if (result != tvERROR_NONE) { + response["platformSupport"] = false; returnResponse(false); } - if (isPlatformSupport("Backlight") != 0) { - returnResponse(false); - } + response["platformSupport"] = true; - if (getParamIndex("Backlight", inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); + if (max_value > 0) { + JsonObject rangeInfo; + rangeInfo["from"] = 0; + rangeInfo["to"] = max_value; + response["rangeInfo"] = rangeInfo; } - err = getLocalparam("Backlight",indexInfo,backlight, PQ_PARAM_BACKLIGHT); - if( err == 0 ) { - response["backlight"] = backlight; - LOGINFO("Exit : Backlight Value: %d \n", backlight); - returnResponse(true); - } - else { - returnResponse(false); - } + response["context"] = parseContextCaps(context_caps); + + returnResponse(true); } - uint32_t AVOutputTV::setBacklight(const JsonObject& parameters, JsonObject& response) - { - LOGINFO("Entry\n"); - std::string value; - capDetails_t inputInfo; - int backlight = 0; - tvError_t ret = tvERROR_NONE; + JsonObject AVOutputTV::parseContextCaps(tvContextCaps_t* context_caps) { + JsonObject contextObj; + if (context_caps && context_caps->num_contexts > 0) { + for (size_t i = 0; i < context_caps->num_contexts; ++i) { + int pqMode = context_caps->contexts[i].pq_mode; + int videoFormat = context_caps->contexts[i].videoFormatType; + int videoSource = context_caps->contexts[i].videoSrcType; - value = parameters.HasLabel("backlight") ? parameters["backlight"].String() : ""; - returnIfParamNotFound(parameters,"backlight"); - backlight = std::stoi(value); + auto pqModeIt = AVOutputTV::pqModeMap.find(pqMode); + auto videoFormatIt = AVOutputTV::videoFormatMap.find(videoFormat); + auto videoSrcIt = AVOutputTV::videoSrcMap.find(videoSource); - if (validateIntegerInputParameter("Backlight",backlight) != 0) { - LOGERR("Failed in Backlight range validation:%s", __FUNCTION__); - returnResponse(false); - } + if (pqModeIt != AVOutputTV::pqModeMap.end() && + videoFormatIt != AVOutputTV::videoFormatMap.end() && + videoSrcIt != AVOutputTV::videoSrcMap.end()) { - if (parsingSetInputArgument(parameters,"Backlight",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + const char* pqModeStr = pqModeIt->second.c_str(); + const char* videoFormatStr = videoFormatIt->second.c_str(); + const char* videoSrcStr = videoSrcIt->second.c_str(); - if (isPlatformSupport("Backlight") != 0 ) { - returnResponse(false); - } + if (!contextObj.HasLabel(pqModeStr)) { + contextObj[pqModeStr] = JsonObject(); + } + JsonObject pqModeObj = contextObj[pqModeStr].Object(); - if( !isCapablityCheckPassed( "Backlight" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for Backlight\n", __FUNCTION__); - returnResponse(false); + if (!pqModeObj.HasLabel(videoFormatStr)) { + pqModeObj[videoFormatStr] = JsonArray(); + } + JsonArray formatArray = pqModeObj[videoFormatStr].Array(); + // **Manually check for existence before adding** + bool exists = false; + for (size_t j = 0; j < formatArray.Length(); ++j) { + if (strcmp(formatArray[j].String().c_str(), videoSrcStr) == 0) { + exists = true; + break; + } + } + if (!exists) { + formatArray.Add(videoSrcStr); + } + // Update objects + pqModeObj[videoFormatStr] = formatArray; + contextObj[pqModeStr] = pqModeObj; + } + } } + return contextObj; + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with setBacklight\n"); - ret = SetBacklight(backlight); - } + uint32_t AVOutputTV::getBacklightCapsV2(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this]( tvContextCaps_t** context_caps, int* max_backlight) { + return GetBacklightCaps(max_backlight, context_caps); + }, parameters, response); + } - if(ret != tvERROR_NONE) { - LOGERR("Failed to set Backlight\n"); - returnResponse(false); - } - else { - int retval= updateAVoutputTVParam("set","Backlight",inputInfo,PQ_PARAM_BACKLIGHT,backlight); - if(retval != 0 ) { - LOGERR("Failed to Save Backlight to ssm_data\n"); - returnResponse(false); - } - LOGINFO("Exit : setBacklight successful to value: %d\n", backlight); - returnResponse(true); - } + uint32_t AVOutputTV::getBrightnessCapsV2(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this]( tvContextCaps_t** context_caps, int* max_brightness) { + return GetBrightnessCaps(max_brightness, context_caps); + }, + parameters, response); + } + uint32_t AVOutputTV::getContrastCapsV2(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this](tvContextCaps_t** context_caps, int* max_contrast) { + return GetContrastCaps(max_contrast, context_caps); + }, + parameters, response); } - uint32_t AVOutputTV::resetBacklight(const JsonObject& parameters, JsonObject& response) + uint32_t AVOutputTV::getSharpnessCapsV2(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this](tvContextCaps_t** context_caps, int* max_sharpness) { + return GetSharpnessCaps(max_sharpness, context_caps); + }, + parameters, response); + } + + uint32_t AVOutputTV::getSaturationCapsV2(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this](tvContextCaps_t** context_caps, int* max_saturation) { + return GetSaturationCaps(max_saturation, context_caps); + }, + parameters, response); + } + + uint32_t AVOutputTV::getHueCapsV2(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this]( tvContextCaps_t** context_caps, int* max_hue) { + return GetHueCaps(max_hue, context_caps); + }, + parameters, response); + } + + uint32_t AVOutputTV::getPrecisionDetailCaps(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this](tvContextCaps_t** context_caps, int* max_precision) { + return GetPrecisionDetailCaps(max_precision, context_caps); + }, + parameters, response); + } + + uint32_t AVOutputTV::getLocalContrastEnhancementCaps(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this](tvContextCaps_t** context_caps, int* max_val) { + return GetLocalContrastEnhancementCaps(max_val, context_caps); + }, + parameters, response); + } + + uint32_t AVOutputTV::getMPEGNoiseReductionCaps(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this](tvContextCaps_t** context_caps, int* max_val) { + return GetMPEGNoiseReductionCaps(max_val, context_caps); + }, + parameters, response); + } + + uint32_t AVOutputTV::getDigitalNoiseReductionCaps(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this](tvContextCaps_t** context_caps, int* max_val) { + return GetDigitalNoiseReductionCaps(max_val, context_caps); + }, + parameters, response); + } + + uint32_t AVOutputTV::getAISuperResolutionCaps(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this](tvContextCaps_t** context_caps, int* max_val) { + return GetAISuperResolutionCaps(max_val, context_caps); + }, + parameters, response); + } + + uint32_t AVOutputTV::getMultiPointWBCaps(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry"); + + int num_hal_matrix_points = 0; + int rgb_min = 0, rgb_max = 0; + int num_ui_matrix_points = 0; + double* ui_matrix_positions = nullptr; + tvContextCaps_t* context_caps = nullptr; + + tvError_t ret = GetMultiPointWBCaps( + &num_hal_matrix_points, + &rgb_min, + &rgb_max, + &num_ui_matrix_points, + &ui_matrix_positions, + &context_caps + ); + + if (ret != tvERROR_NONE) { + LOGWARN("GetMultiPointWBCaps failed: %s", getErrorString(ret).c_str()); + response["platformSupport"] = false; + returnResponse(false); + } + response["platformSupport"] = true; + + response["numHalMatrixPoints"] = num_hal_matrix_points; + response["rgbMin"] = rgb_min; + response["rgbMax"] = rgb_max; + response["numUiMatrixPoints"] = num_ui_matrix_points; + + // Add UI matrix positions + JsonArray uiPosArray; + for (int i = 0; i < num_ui_matrix_points; ++i) { + uiPosArray.Add(ui_matrix_positions[i]); + } + response["uiMatrixPositions"] = uiPosArray; + response["context"] = parseContextCaps(context_caps); + LOGINFO("Exit\n"); + returnResponse(true); + } + + uint32_t AVOutputTV::getMEMCCaps(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this](tvContextCaps_t** context_caps, int* max_val) { + return GetMEMCCaps(max_val, context_caps); + }, + parameters, response); + } + + uint32_t AVOutputTV::getLowLatencyStateCapsV2(const JsonObject& parameters, JsonObject& response) { + return getPQCapabilityWithContext([this](tvContextCaps_t** context_caps, int* max_latency) { + return GetLowLatencyStateCaps(max_latency, context_caps); + }, + parameters, response); + } + + // Forward lookup: string → enum + const std::unordered_map colorTempMap = { + {"Standard", tvColorTemp_STANDARD}, + {"Warm", tvColorTemp_WARM}, + {"Cold", tvColorTemp_COLD}, + {"UserDefined", tvColorTemp_USER}, + {"Supercold", tvColorTemp_SUPERCOLD}, + {"BoostStandard", tvColorTemp_BOOST_STANDARD}, + {"BoostWarm", tvColorTemp_BOOST_WARM}, + {"BoostCold", tvColorTemp_BOOST_COLD}, + {"BoostUserDefined", tvColorTemp_BOOST_USER}, + {"BoostSupercold", tvColorTemp_BOOST_SUPERCOLD} + }; + + // Reverse lookup: enum → string + const std::unordered_map colorTempReverseMap = { + {tvColorTemp_STANDARD, "Standard"}, + {tvColorTemp_WARM, "Warm"}, + {tvColorTemp_COLD, "Cold"}, + {tvColorTemp_USER, "UserDefined"}, + {tvColorTemp_SUPERCOLD, "Supercold"}, + {tvColorTemp_BOOST_STANDARD, "BoostStandard"}, + {tvColorTemp_BOOST_WARM, "BoostWarm"}, + {tvColorTemp_BOOST_COLD, "BoostCold"}, + {tvColorTemp_BOOST_USER, "BoostUserDefined"}, + {tvColorTemp_BOOST_SUPERCOLD, "BoostSupercold"} + }; + + uint32_t AVOutputTV::getColorTemperatureCapsV2(const JsonObject& parameters, JsonObject& response) { + tvColorTemp_t* color_temp = nullptr; + size_t num_color_temp = 0; + tvContextCaps_t* context_caps = nullptr; + + tvError_t err = GetColorTemperatureCaps(&color_temp, &num_color_temp, &context_caps); + if (err != tvERROR_NONE) { + response["platformSupport"] = false; + return err; + } + + response["platformSupport"] = true; + + JsonArray optionsArray; + for (size_t i = 0; i < num_color_temp; ++i) { + auto it = colorTempReverseMap.find(color_temp[i]); + if (it != colorTempReverseMap.end()) { + optionsArray.Add(it->second); + } + } + response["options"] = optionsArray; + response["context"] = parseContextCaps(context_caps); + + + returnResponse(true); + } + + uint32_t AVOutputTV::getSDRGammaCaps(const JsonObject& parameters, JsonObject& response) + { + tvSdrGamma_t* sdr_gamma = nullptr; + size_t num_sdr_gamma = 0; + tvContextCaps_t* context_caps = nullptr; + + tvError_t err = GetSdrGammaCaps(&sdr_gamma, &num_sdr_gamma, &context_caps); + if (err != tvERROR_NONE) { + response["platformSupport"] = false; + return err; + } + + response["platformSupport"] = true; + + JsonArray optionsArray; + for (size_t i = 0; i < num_sdr_gamma; ++i) { + switch (sdr_gamma[i]) { + case tvSdrGamma_1_8: optionsArray.Add("1.8"); break; + case tvSdrGamma_1_9: optionsArray.Add("1.9"); break; + case tvSdrGamma_2_0: optionsArray.Add("2.0"); break; + case tvSdrGamma_2_1: optionsArray.Add("2.1"); break; + case tvSdrGamma_2_2: optionsArray.Add("2.2"); break; + case tvSdrGamma_2_3: optionsArray.Add("2.3"); break; + case tvSdrGamma_2_4: optionsArray.Add("2.4"); break; + case tvSdrGamma_BT_1886: optionsArray.Add("BT.1886"); break; + default: break; + } + } + response["options"] = optionsArray; + + response["context"] = parseContextCaps(context_caps); + + returnResponse(true); + } + + uint32_t AVOutputTV::getBacklightDimmingModeCapsV2(const JsonObject& parameters, JsonObject& response) + { + tvDimmingMode_t* dimming_mode = nullptr; + size_t num_dimming_mode = 0; + tvContextCaps_t* context_caps = nullptr; + + tvError_t err = GetTVDimmingModeCaps(&dimming_mode, &num_dimming_mode, &context_caps); + if (err != tvERROR_NONE) { + response["platformSupport"] = false; + return err; + } + + response["platformSupport"] = true; + + JsonArray optionsArray; + for (size_t i = 0; i < num_dimming_mode; ++i) { + auto it = dimmingModeReverseMap.find(dimming_mode[i]); + if (it != dimmingModeReverseMap.end()) { + optionsArray.Add(it->second); + } + } + response["options"] = optionsArray; + + response["context"] = parseContextCaps(context_caps); + + returnResponse(true); + } + + uint32_t AVOutputTV::getZoomModeCapsV2(const JsonObject& parameters, JsonObject& response) + { + JsonArray optionsArray; + for (size_t i = 0; i < m_numAspectRatio; ++i) { + auto it = zoomModeReverseMap.find(m_aspectRatio[i]); + if (it != zoomModeReverseMap.end()) { + optionsArray.Add(it->second); + } + } + + bool platformSupport = (optionsArray.Length() > 0); + + response["platformSupport"] = platformSupport; + response["options"] = optionsArray; + response["context"] = parseContextCaps(m_aspectRatioCaps); + + returnResponse(platformSupport); + } + + uint32_t AVOutputTV::getPictureModeCapsV2(const JsonObject& parameters, JsonObject& response) + { + JsonArray optionsArray; + for (size_t i = 0; i < m_numPictureModes; ++i) { + auto it = pqModeMap.find(m_pictureModes[i]); + if (it != pqModeMap.end()) { + optionsArray.Add(it->second); + } + } + + bool platformSupport = (optionsArray.Length() > 0); + + response["platformSupport"] = platformSupport; + response["options"] = optionsArray; + response["context"] = parseContextCaps(m_pictureModeCaps); + + returnResponse(platformSupport); + } + + uint32_t AVOutputTV::getAutoBacklightModeCapsV2(const JsonObject& parameters, JsonObject& response) + { + JsonArray optionsArray; + for (size_t i = 0; i < m_numBacklightModes; ++i) { + switch (m_backlightModes[i]) { + case tvBacklightMode_MANUAL: + optionsArray.Add("Manual"); + break; + case tvBacklightMode_AMBIENT: + optionsArray.Add("Ambient"); + break; + case tvBacklightMode_ECO: + optionsArray.Add("Eco"); + break; + default: + LOGINFO("Unknown backlightMode option\n"); + break; + } + } + + bool platformSupport = (optionsArray.Length() > 0); + + response["platformSupport"] = platformSupport; + response["options"] = optionsArray; + response["context"] = parseContextCaps(m_backlightModeCaps); + + returnResponse(platformSupport); + } + + + uint32_t AVOutputTV::getDolbyVisionCalibrationCaps(const JsonObject& parameters, JsonObject& response) + { + returnResponse(true); + } + + + uint32_t AVOutputTV::getZoomModeCaps(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry"); + capVectors_t info; + + JsonArray rangeArray; + JsonArray pqmodeArray; + JsonArray formatArray; + JsonArray sourceArray; + + unsigned int index = 0; + + tvError_t ret = getParamsCaps("AspectRatio",info); + + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + for (index = 0; index < info.rangeVector.size(); index++) { + rangeArray.Add(info.rangeVector[index]); + } + + response["options"]=rangeArray; + + if (info.pqmodeVector.front().compare("none") != 0) { + for (index = 0; index < info.pqmodeVector.size(); index++) { + pqmodeArray.Add(info.pqmodeVector[index]); + } + response["pictureModeInfo"]=pqmodeArray; + } + if ((info.sourceVector.front()).compare("none") != 0) { + for (index = 0; index < info.sourceVector.size(); index++) { + sourceArray.Add(info.sourceVector[index]); + } + response["videoSourceInfo"]=sourceArray; + } + if ((info.formatVector.front()).compare("none") != 0) { + for (index = 0; index < info.formatVector.size(); index++) { + formatArray.Add(info.formatVector[index]); + } + response["videoFormatInfo"]=formatArray; + } + LOGINFO("Exit\n"); + returnResponse(true); + } + } + + uint32_t AVOutputTV::setZoomMode(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry\n"); + if(m_aspectRatioStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + std::string value; + tvDisplayMode_t mode = tvDisplayMode_16x9; + capDetails_t inputInfo; + + + value = parameters.HasLabel("zoomMode") ? parameters["zoomMode"].String() : ""; + returnIfParamNotFound(parameters,"zoomMode"); + + if (validateInputParameter("AspectRatio",value) != 0) { + LOGERR("%s: Range validation failed for AspectRatio\n", __FUNCTION__); + returnResponse(false); + } + + if (parsingSetInputArgument(parameters,"AspectRatio",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } + + if( !isCapablityCheckPassed( "AspectRatio",inputInfo )) { + LOGERR("%s: CapablityCheck failed for AspectRatio\n", __FUNCTION__); + returnResponse(false); + } + + if(!value.compare("TV 16X9 STRETCH")) { + mode = tvDisplayMode_16x9; + } + else if (!value.compare("TV 4X3 PILLARBOX")) { + mode = tvDisplayMode_4x3; + } + else if (!value.compare("TV NORMAL")) { + mode = tvDisplayMode_NORMAL; + } + else if (!value.compare("TV DIRECT")) { + mode = tvDisplayMode_DIRECT; + } + else if (!value.compare("TV AUTO")) { + mode = tvDisplayMode_AUTO; + } + else if (!value.compare("TV ZOOM")) { + mode = tvDisplayMode_ZOOM; + } + else { + returnResponse(false); + } + m_videoZoomMode = mode; + tvError_t ret = setAspectRatioZoomSettings (mode); + + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + //Save DisplayMode to localstore and ssm_data + int retval=updateAVoutputTVParam("set","AspectRatio",inputInfo,PQ_PARAM_ASPECT_RATIO,mode); + + if(retval != 0) { + LOGERR("Failed to Save DisplayMode to ssm_data\n"); + returnResponse(false); + } + + tr181ErrorCode_t err = setLocalParam(rfc_caller_id, AVOUTPUT_ASPECTRATIO_RFC_PARAM, value.c_str()); + if ( err != tr181Success ) { + LOGERR("setLocalParam for %s Failed : %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, getTR181ErrorString(err)); + returnResponse(false); + } + else { + LOGINFO("setLocalParam for %s Successful, Value: %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, value.c_str()); + } + LOGINFO("Exit : SetAspectRatio() value : %s\n",value.c_str()); + returnResponse(true); + } + } + else + { + std::string value = parameters.HasLabel("zoomMode") ? parameters["zoomMode"].String() : ""; + returnIfParamNotFound(parameters, "zoomMode"); + + auto it = zoomModeMap.find(value); + if (it == zoomModeMap.end()) { + LOGERR("Invalid zoom mode: %s. Not in supported options.", value.c_str()); + returnResponse(false); + } + tvDisplayMode_t mode = it->second; + tvError_t ret = setAspectRatioZoomSettings(mode); + if (ret != tvERROR_NONE) { + returnResponse(false); + } + else + { + // Save DisplayMode to local store and ssm_data + int retval = updateAVoutputTVParamV2("set", "AspectRatio", parameters, PQ_PARAM_ASPECT_RATIO, mode); + if (retval != 0) { + LOGERR("Failed to Save DisplayMode to ssm_data\n"); + returnResponse(false); + } + tr181ErrorCode_t err = setLocalParam(rfc_caller_id, AVOUTPUT_ASPECTRATIO_RFC_PARAM, value.c_str()); + if (err != tr181Success) { + LOGERR("setLocalParam for %s Failed : %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, getTR181ErrorString(err)); + returnResponse(false); + } else { + LOGINFO("setLocalParam for %s Successful, Value: %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, value.c_str()); + } + LOGINFO("Exit : SetAspectRatio() value : %s\n", value.c_str()); + returnResponse(true); + } + } + } + + uint32_t AVOutputTV::getZoomMode(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry\n"); + tvDisplayMode_t mode; + + tvError_t ret = getUserSelectedAspectRatio (&mode); + + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + switch(mode) { + case tvDisplayMode_16x9: + LOGINFO("Aspect Ratio: TV 16X9 STRETCH\n"); + response["zoomMode"] = "TV 16X9 STRETCH"; + break; + + case tvDisplayMode_4x3: + LOGINFO("Aspect Ratio: TV 4X3 PILLARBOX\n"); + response["zoomMode"] = "TV 4X3 PILLARBOX"; + break; + + case tvDisplayMode_NORMAL: + LOGINFO("Aspect Ratio: TV Normal\n"); + response["zoomMode"] = "TV NORMAL"; + break; + + case tvDisplayMode_AUTO: + LOGINFO("Aspect Ratio: TV AUTO\n"); + response["zoomMode"] = "TV AUTO"; + break; + + case tvDisplayMode_DIRECT: + LOGINFO("Aspect Ratio: TV DIRECT\n"); + response["zoomMode"] = "TV DIRECT"; + break; + + case tvDisplayMode_ZOOM: + LOGINFO("Aspect Ratio: TV ZOOM\n"); + response["zoomMode"] = "TV ZOOM"; + break; + + default: + LOGINFO("Aspect Ratio: TV AUTO\n"); + response["zoomMode"] = "TV AUTO"; + break; + } + returnResponse(true); + } + } + + uint32_t AVOutputTV::resetZoomMode(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry\n"); + capDetails_t inputInfo; + tvError_t ret = tvERROR_NONE; + + if (parsingSetInputArgument(parameters, "AspectRatio",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } + + if( !isCapablityCheckPassed( "AspectRatio",inputInfo )) { + LOGERR("%s: CapablityCheck failed for AspectRatio\n", __FUNCTION__); + returnResponse(false); + } + + tr181ErrorCode_t err = clearLocalParam(rfc_caller_id,AVOUTPUT_ASPECTRATIO_RFC_PARAM); + if ( err != tr181Success ) { + LOGERR("clearLocalParam for %s Failed : %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, getTR181ErrorString(err)); + ret = tvERROR_GENERAL; + } + else { + ret = setDefaultAspectRatio(inputInfo.pqmode,inputInfo.source,inputInfo.format); + } + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetDefaultAspectRatio()\n"); + returnResponse(true); + } + } + + uint32_t AVOutputTV::getVideoFormat(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry\n"); + tvVideoFormatType_t videoFormat; + tvError_t ret = GetCurrentVideoFormat(&videoFormat); + if(ret != tvERROR_NONE) { + response["currentVideoFormat"] = "NONE"; + returnResponse(false); + } + else { + response["currentVideoFormat"] = getVideoFormatTypeToString(videoFormat); + LOGINFO("Exit: getVideoFormat :%d success \n",videoFormat); + returnResponse(true); + } + } + + uint32_t AVOutputTV::getVideoResolution(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry\n"); + tvResolutionParam_t videoResolution; + tvError_t ret = GetCurrentVideoResolution(&videoResolution); + if(ret != tvERROR_NONE) { + response["currentVideoResolution"] = "NONE"; + returnResponse(false); + } + else { + response["currentVideoResolution"] = getVideoResolutionTypeToString(videoResolution); + LOGINFO("Exit: getVideoResolution :%d success \n",videoResolution.resolutionValue); + returnResponse(true); + } + } + + uint32_t AVOutputTV::getVideoFrameRate(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry\n"); + tvVideoFrameRate_t videoFramerate; + tvError_t ret = GetCurrentVideoFrameRate(&videoFramerate); + if(ret != tvERROR_NONE) { + response["currentVideoFrameRate"] = "NONE"; + returnResponse(false); + } + else { + response["currentVideoFrameRate"] = getVideoFrameRateTypeToString(videoFramerate); + LOGINFO("Exit: videoFramerate :%d success \n",videoFramerate); + returnResponse(true); + } + } + + uint32_t AVOutputTV::resetPrecisionDetail(const JsonObject& parameters, JsonObject& response) + { + bool success = resetPQParamToDefault(parameters, "PrecisionDetail", + PQ_PARAM_PRECISION_DETAIL, SetPrecisionDetail); + returnResponse(success); + } + + uint32_t AVOutputTV::resetLocalContrastEnhancement(const JsonObject& parameters, JsonObject& response) + { + bool success = resetPQParamToDefault(parameters, "LocalContrastEnhancement", + PQ_PARAM_LOCAL_CONTRAST_ENHANCEMENT, SetLocalContrastEnhancement); + returnResponse(success); + } + + uint32_t AVOutputTV::resetMPEGNoiseReduction(const JsonObject& parameters, JsonObject& response) + { + bool success = resetPQParamToDefault(parameters, "MPEGNoiseReduction", + PQ_PARAM_MPEG_NOISE_REDUCTION, SetMPEGNoiseReduction); + returnResponse(success); + } + + uint32_t AVOutputTV::resetDigitalNoiseReduction(const JsonObject& parameters, JsonObject& response) + { + bool success = resetPQParamToDefault(parameters, "DigitalNoiseReduction", + PQ_PARAM_DIGITAL_NOISE_REDUCTION, SetDigitalNoiseReduction); + returnResponse(success); + } + + uint32_t AVOutputTV::resetMEMC(const JsonObject& parameters, JsonObject& response) + { + bool success = resetPQParamToDefault(parameters, "MEMC", + PQ_PARAM_MEMC, SetMEMC); + returnResponse(success); + } + + uint32_t AVOutputTV::resetAISuperResolution(const JsonObject& parameters, JsonObject& response) + { + bool success= resetPQParamToDefault(parameters,"AISuperResolution", + PQ_PARAM_AI_SUPER_RESOLUTION, SetAISuperResolution); + returnResponse(success); + } + + uint32_t AVOutputTV::getPrecisionDetail(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry"); + int precisionDetail = 0; + bool success = getPQParamFromContext(parameters, + "PrecisionDetail", + PQ_PARAM_PRECISION_DETAIL, + precisionDetail); + if (success) { + response["precisionDetail"] = precisionDetail; + } + returnResponse(success); + } + + uint32_t AVOutputTV::getLocalContrastEnhancement(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry"); + int localContraseEnhancement = 0; + bool success = getPQParamFromContext(parameters, + "LocalContrastEnhancement", + PQ_PARAM_LOCAL_CONTRAST_ENHANCEMENT, + localContraseEnhancement); + if (success) { + response["localContrastEnhancement"] = localContraseEnhancement; + } + returnResponse(success); + } + + uint32_t AVOutputTV::getMPEGNoiseReduction(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry"); + int MPEGNoiseReduction = 0; + bool success = getPQParamFromContext(parameters, + "MPEGNoiseReduction", + PQ_PARAM_MPEG_NOISE_REDUCTION, + MPEGNoiseReduction); + if (success) { + response["mpegNoiseReduction"] = MPEGNoiseReduction; + } + returnResponse(success); + } + + uint32_t AVOutputTV::getDigitalNoiseReduction(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry"); + int digitalNoiseReduction = 0; + bool success = getPQParamFromContext(parameters, + "DigitalNoiseReduction", + PQ_PARAM_DIGITAL_NOISE_REDUCTION, + digitalNoiseReduction); + if (success) { + response["digitalNoiseReduction"] = digitalNoiseReduction; + } + returnResponse(success); + } + + uint32_t AVOutputTV::getMEMC(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry"); + int MEMC = 0; + bool success = getPQParamFromContext(parameters, + "MEMC", + PQ_PARAM_MEMC, + MEMC); + if (success) { + response["memc"] = MEMC; + } + returnResponse(success); + } + + uint32_t AVOutputTV::getAISuperResolution(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry"); + int aiSuperResolution = 0; + bool success = getPQParamFromContext(parameters, + "AISuperResolution", + PQ_PARAM_AI_SUPER_RESOLUTION, + aiSuperResolution); + if (success) { + response["aiSuperResolution"] = aiSuperResolution; + } + returnResponse(success); + } + + uint32_t AVOutputTV::setContextPQParam(const JsonObject& parameters, JsonObject& response, + const std::string& inputParamName, + const std::string& tr181ParamName, + int maxAllowedValue, + tvPQParameterIndex_t pqParamType, + std::function halSetter) + { + LOGINFO("Entry"); + + if (!parameters.HasLabel(inputParamName.c_str())) { + LOGERR("Missing parameter: %s", inputParamName.c_str()); + returnResponse(false); + } + + std::string valueStr = parameters[inputParamName.c_str()].String(); + int value = std::stoi(valueStr); + + if (value < 0 || value > maxAllowedValue) { + LOGERR("Input value %d is out of range for %s", value, inputParamName.c_str()); + returnResponse(false); + } + + // Get current context + tvVideoSrcType_t currentSrc = VIDEO_SOURCE_IP; + tvVideoFormatType_t currentFmt = VIDEO_FORMAT_SDR; + tvPQModeIndex_t currentPQMode = PQ_MODE_STANDARD; + + GetCurrentVideoSource(¤tSrc); + GetCurrentVideoFormat(¤tFmt); + if (currentFmt == VIDEO_FORMAT_NONE) + currentFmt = VIDEO_FORMAT_SDR; + + char picMode[PIC_MODE_NAME_MAX] = {0}; + if (getCurrentPictureMode(picMode)) + { + auto it = pqModeReverseMap.find(picMode); + if (it != pqModeReverseMap.end()) + { + currentPQMode = static_cast(it->second); + } + else + { + LOGERR("Unknown picture mode"); + } + } + else + { + LOGERR("Failed to get current picture mode"); + } + + LOGINFO("currentPQMode: %d, currentFmt: %d, currentSrc: %d", currentPQMode, currentFmt, currentSrc); + + if (isSetRequiredForParam(parameters, tr181ParamName)) { + tvError_t ret = halSetter(currentSrc, currentPQMode, currentFmt, value); + if (ret != tvERROR_NONE) { + LOGERR("HAL setter failed for %s", inputParamName.c_str()); + returnResponse(false); + } + } + + // Persist + int retval = updateAVoutputTVParamV2("set", tr181ParamName, parameters, pqParamType, value); + if (retval != 0) { + LOGERR("Failed to save %s to ssm_data", inputParamName.c_str()); + returnResponse(false); + } + + LOGINFO("Exit: %s set successfully to %d", inputParamName.c_str(), value); + returnResponse(true); + } + + uint32_t AVOutputTV::setAISuperResolution(const JsonObject& parameters, JsonObject& response) + { + return setContextPQParam( + parameters, response, + "aiSuperResolution", + "AISuperResolution", + m_maxAISuperResolution, + PQ_PARAM_AI_SUPER_RESOLUTION, + [](tvVideoSrcType_t src, tvPQModeIndex_t mode, tvVideoFormatType_t fmt, int val) { + return SetAISuperResolution(src, mode, fmt, val); + } + ); + } + + uint32_t AVOutputTV::setMEMC(const JsonObject& parameters, JsonObject& response) + { + return setContextPQParam( + parameters, response, + "memc", "MEMC", + m_maxMEMC, + PQ_PARAM_MEMC, + [](tvVideoSrcType_t src, tvPQModeIndex_t mode, tvVideoFormatType_t fmt, int val) { + return SetMEMC(src, mode, fmt, val); + } + ); + } + + uint32_t AVOutputTV::setPrecisionDetail(const JsonObject& parameters, JsonObject& response) + { + return setContextPQParam( + parameters, response, + "precisionDetail", "PrecisionDetail", + m_maxPrecisionDetail, + PQ_PARAM_PRECISION_DETAIL, + [](tvVideoSrcType_t src, tvPQModeIndex_t mode, tvVideoFormatType_t fmt, int val) { + return SetPrecisionDetail(src, mode, fmt, val); + } + ); + } + + uint32_t AVOutputTV::setLocalContrastEnhancement(const JsonObject& parameters, JsonObject& response) + { + return setContextPQParam( + parameters, response, + "localContrastEnhancement", "LocalContrastEnhancement", + m_maxLocalContrastEnhancement, + PQ_PARAM_LOCAL_CONTRAST_ENHANCEMENT, + [](tvVideoSrcType_t src, tvPQModeIndex_t mode, tvVideoFormatType_t fmt, int val) { + return SetLocalContrastEnhancement(src, mode, fmt, val); + } + ); + } + + uint32_t AVOutputTV::setMPEGNoiseReduction(const JsonObject& parameters, JsonObject& response) + { + return setContextPQParam( + parameters, response, + "mpegNoiseReduction", "MPEGNoiseReduction", + m_maxMPEGNoiseReduction, + PQ_PARAM_MPEG_NOISE_REDUCTION, + [](tvVideoSrcType_t src, tvPQModeIndex_t mode, tvVideoFormatType_t fmt, int val) { + return SetMPEGNoiseReduction(src, mode, fmt, val); + } + ); + } + + uint32_t AVOutputTV::setDigitalNoiseReduction(const JsonObject& parameters, JsonObject& response) + { + return setContextPQParam( + parameters, response, + "digitalNoiseReduction", "DigitalNoiseReduction", + m_maxDigitalNoiseReduction, + PQ_PARAM_DIGITAL_NOISE_REDUCTION, + [](tvVideoSrcType_t src, tvPQModeIndex_t mode, tvVideoFormatType_t fmt, int val) { + return SetDigitalNoiseReduction(src, mode, fmt, val); + } + ); + } + + uint32_t AVOutputTV::getBacklight(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry"); + if(m_backlightStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + std::string key; + paramIndex_t indexInfo; + int backlight = 0,err = 0; + + if (parsingGetInputArgument(parameters, "Backlight",inputInfo) != 0) { + LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); + returnResponse(false); + } + + if (isPlatformSupport("Backlight") != 0) { + returnResponse(false); + } + + if (getParamIndex("Backlight", inputInfo,indexInfo) == -1) { + LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); + returnResponse(false); + } + + err = getLocalparam("Backlight",indexInfo,backlight, PQ_PARAM_BACKLIGHT); + if( err == 0 ) { + response["backlight"] = backlight; + LOGINFO("Exit : Backlight Value: %d \n", backlight); + returnResponse(true); + } + else { + returnResponse(false); + } + } + else + { + int backlight = 0; + bool success = getPQParamFromContext(parameters, + "Backlight", + PQ_PARAM_BACKLIGHT, + backlight); + if (success) { + response["backlight"] = backlight; + } + returnResponse(success); + + } + } + + uint32_t AVOutputTV::setBacklight(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry\n"); + if(m_backlightStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + std::string value; + capDetails_t inputInfo; + int backlight = 0; + tvError_t ret = tvERROR_NONE; + + value = parameters.HasLabel("backlight") ? parameters["backlight"].String() : ""; + returnIfParamNotFound(parameters,"backlight"); + backlight = std::stoi(value); + + if (validateIntegerInputParameter("Backlight",backlight) != 0) { + LOGERR("Failed in Backlight range validation:%s", __FUNCTION__); + returnResponse(false); + } + + if (parsingSetInputArgument(parameters,"Backlight",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } + + if (isPlatformSupport("Backlight") != 0 ) { + returnResponse(false); + } + + if( !isCapablityCheckPassed( "Backlight" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for Backlight\n", __FUNCTION__); + returnResponse(false); + } + + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with setBacklight\n"); + ret = SetBacklight(backlight); + } + + if(ret != tvERROR_NONE) { + LOGERR("Failed to set Backlight\n"); + returnResponse(false); + } + else { + int retval= updateAVoutputTVParam("set","Backlight",inputInfo,PQ_PARAM_BACKLIGHT,backlight); + if(retval != 0 ) { + LOGERR("Failed to Save Backlight to ssm_data\n"); + returnResponse(false); + } + LOGINFO("Exit : setBacklight successful to value: %d\n", backlight); + returnResponse(true); + } + } + else + { + bool success = setIntPQParam(parameters, "Backlight", PQ_PARAM_BACKLIGHT, SetBacklight, m_maxBacklight); + returnResponse(success); + } + + } + bool AVOutputTV::resetEnumPQParamToDefault( + const JsonObject& parameters, + const std::string& paramName, + tvPQParameterIndex_t pqIndex, + const std::unordered_map& valueMap, + std::function&)> halSetter) { - LOGINFO("Entry\n"); + LOGINFO("Entry: %s\n", paramName.c_str()); + capDetails_t inputInfo; - int backlight=0; paramIndex_t indexInfo; + int intVal = 0; tvError_t ret = tvERROR_NONE; - if (parsingSetInputArgument(parameters, "Backlight",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); + // Step 1: Save reset state using V2 persistence + LOGINFO("Updating AVOutputTVParamV2 for: %s\n", paramName.c_str()); + int retval = updateAVoutputTVParamV2("reset", paramName, parameters, pqIndex, intVal); + if (retval != 0) { + LOGERR("Failed to reset %s via updateAVoutputTVParamV2. retval: %d\n", paramName.c_str(), retval); + return false; } - if (isPlatformSupport("Backlight") != 0) { - returnResponse(false); - } + // Step 2: Apply value from persisted config to HAL if needed + if (isSetRequiredForParam(parameters, paramName)) { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; - if( !isCapablityCheckPassed( "Backlight",inputInfo )) { - LOGERR("%s: CapablityCheck failed for Backlight\n", __FUNCTION__); - returnResponse(false); + if (getParamIndex(paramName, inputInfo, indexInfo) == 0 && + getLocalparam(paramName, indexInfo, intVal, pqIndex) == 0) + { + LOGINFO("%s: getLocalparam success for %s [format=%d, source=%d, mode=%d] → value=%d\n", + __FUNCTION__, paramName.c_str(), indexInfo.formatIndex, + indexInfo.sourceIndex, indexInfo.pqmodeIndex, intVal); + + if (valueMap.find(intVal) == valueMap.end()) { + LOGERR("%s: Invalid enum value %d for %s\n", __FUNCTION__, intVal, paramName.c_str()); + return false; + } + + ret = halSetter(intVal, valueMap); + if (ret != tvERROR_NONE) { + LOGERR("%s: HAL setter failed for value %d\n", paramName.c_str(), intVal); + return false; + } + } + else { + LOGERR("%s: Failed to get local param for %s\n", __FUNCTION__, paramName.c_str()); + return false; + } } - int retval= updateAVoutputTVParam("reset","Backlight",inputInfo,PQ_PARAM_BACKLIGHT,backlight); - if(retval != 0 ) { - LOGERR("Failed to reset Backlight\n"); - returnResponse(false); + LOGINFO("Exit: resetEnumPQParamToDefault for %s successful (value: %d)\n", paramName.c_str(), intVal); + return true; + } + + bool AVOutputTV::resetPQParamToDefault(const JsonObject& parameters, + const std::string& paramName, + tvPQParameterIndex_t pqIndex, + tvSetFunctionV2 halSetter) + { + LOGINFO("Entry: %s\n", paramName.c_str()); + + capDetails_t inputInfo; + paramIndex_t indexInfo; + int level = 0; + tvError_t ret = tvERROR_NONE; + + // Save reset state using V2 path + LOGINFO("Updating AVOutputTVParamV2 for: %s\n", paramName.c_str()); + int retval = updateAVoutputTVParamV2("reset", paramName, parameters, pqIndex, level); + if (retval != 0) + { + LOGERR("Failed to update %s via updateAVoutputTVParamV2. retval: %d\n", paramName.c_str(), retval); + return false; } - else { - if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { - inputInfo.pqmode = "Current"; - inputInfo.source = "Current"; - inputInfo.format = "Current"; - getParamIndex("Backlight", inputInfo,indexInfo); - int err = getLocalparam("Backlight",indexInfo,backlight, PQ_PARAM_BACKLIGHT); - if( err == 0 ) { - LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,backlight); - ret = SetBacklight(backlight); - } - else { - LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); - ret = tvERROR_GENERAL; + + // If update succeeded, apply value from local config to HAL + if (isSetRequiredForParam(parameters, paramName)) + { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + + if (getParamIndex(paramName, inputInfo, indexInfo) == 0 && + getLocalparam(paramName, indexInfo, level, pqIndex) == 0) + { + LOGINFO("%s: getLocalparam success for %s: format=%d, source=%d, mode=%d, value=%d\n", + __FUNCTION__, paramName.c_str(), indexInfo.formatIndex, + indexInfo.sourceIndex, indexInfo.pqmodeIndex, level); + if (halSetter) { + ret = halSetter( + static_cast(indexInfo.sourceIndex), + static_cast(indexInfo.pqmodeIndex), + static_cast(indexInfo.formatIndex), + level); + LOGINFO("%s halSetter return value: %d\n", paramName.c_str(), ret); + } else { + LOGERR("halSetter is null for %s\n", paramName.c_str()); + return false; } } + else + { + LOGERR("%s: Failed to get local param for %s\n", __FUNCTION__, paramName.c_str()); + return false; + } } - if(ret != tvERROR_NONE) { - returnResponse(false); + LOGINFO("Exit: reset%s successful to value: %d\n", paramName.c_str(), level); + return true; + } + + bool AVOutputTV::resetPQParamToDefault(const JsonObject& parameters, + const std::string& paramName, + tvPQParameterIndex_t pqIndex, + tvSetFunction halSetter) + { + LOGINFO("Entry: %s\n", paramName.c_str()); + + capDetails_t inputInfo; + paramIndex_t indexInfo; + int level = 0; + tvError_t ret = tvERROR_NONE; + + // Save reset state using V2 path + LOGINFO("Updating AVOutputTVParamV2 for: %s\n", paramName.c_str()); + int retval = updateAVoutputTVParamV2("reset", paramName, parameters, pqIndex, level); + if (retval != 0) + { + LOGERR("Failed to update %s via updateAVoutputTVParamV2. retval: %d\n", paramName.c_str(), retval); + return false; } - else { - LOGINFO("Exit : resetBacklight Successful to value : %d \n",backlight); - returnResponse(true); + + // If update succeeded, apply value from local config to HAL + if (isSetRequiredForParam(parameters, paramName)) + { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + + if (getParamIndex(paramName, inputInfo, indexInfo) == 0 && + getLocalparam(paramName, indexInfo, level, pqIndex) == 0) + { + LOGINFO("%s: getLocalparam success for %s: format=%d, source=%d, mode=%d, value=%d\n", + __FUNCTION__, paramName.c_str(), indexInfo.formatIndex, + indexInfo.sourceIndex, indexInfo.pqmodeIndex, level); + ret = halSetter(level); + LOGINFO("%s halSetter return value: %d\n", paramName.c_str(), ret); + } + else + { + LOGERR("%s: Failed to get local param for %s\n", __FUNCTION__, paramName.c_str()); + return false; + } + } + + LOGINFO("Exit: reset%s successful to value: %d\n", paramName.c_str(), level); + return true; + } + + uint32_t AVOutputTV::resetBacklight(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry\n"); + if(m_backlightStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + int backlight=0; + paramIndex_t indexInfo; + tvError_t ret = tvERROR_NONE; + + if (parsingSetInputArgument(parameters, "Backlight",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } + + if (isPlatformSupport("Backlight") != 0) { + returnResponse(false); + } + + if( !isCapablityCheckPassed( "Backlight",inputInfo )) { + LOGERR("%s: CapablityCheck failed for Backlight\n", __FUNCTION__); + returnResponse(false); + } + + int retval= updateAVoutputTVParam("reset","Backlight",inputInfo,PQ_PARAM_BACKLIGHT,backlight); + if(retval != 0 ) { + LOGERR("Failed to reset Backlight\n"); + returnResponse(false); + } + else { + if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + getParamIndex("Backlight", inputInfo,indexInfo); + int err = getLocalparam("Backlight",indexInfo,backlight, PQ_PARAM_BACKLIGHT); + if( err == 0 ) { + LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,backlight); + ret = SetBacklight(backlight); + } + else { + LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); + ret = tvERROR_GENERAL; + } + } + } + + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetBacklight Successful to value : %d \n",backlight); + returnResponse(true); + } + } + else + { + bool success= resetPQParamToDefault(parameters, "Backlight", PQ_PARAM_BACKLIGHT, SetBacklight); + returnResponse(success); } } @@ -904,79 +2138,99 @@ namespace Plugin { uint32_t AVOutputTV::getBrightness(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry"); + if(m_brightnessStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int brightness = 0; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int brightness = 0; - - if (parsingGetInputArgument(parameters, "Brightness",inputInfo) != 0) { - LOGERR("%s: Failed to parse argument\n", __FUNCTION__); - returnResponse(false); - } + if (parsingGetInputArgument(parameters, "Brightness",inputInfo) != 0) { + LOGERR("%s: Failed to parse argument\n", __FUNCTION__); + returnResponse(false); + } - if (getParamIndex("Brightness", inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); - } + if (getParamIndex("Brightness", inputInfo,indexInfo) == -1) { + LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); + returnResponse(false); + } - int err = getLocalparam("Brightness",indexInfo,brightness, PQ_PARAM_BRIGHTNESS); - if( err == 0 ) { - response["brightness"] = brightness; - LOGINFO("Exit : Brightness Value: %d \n", brightness); - returnResponse(true); + int err = getLocalparam("Brightness",indexInfo,brightness, PQ_PARAM_BRIGHTNESS); + if( err == 0 ) { + response["brightness"] = brightness; + LOGINFO("Exit : Brightness Value: %d \n", brightness); + returnResponse(true); + } + else { + returnResponse(false); + } } - else { - returnResponse(false); + else + { + int brightness = 0; + bool success = getPQParamFromContext(parameters, + "Brightness", + PQ_PARAM_BRIGHTNESS, + brightness); + if (success) { + response["brightness"] = brightness; + } + returnResponse(success); } } uint32_t AVOutputTV::setBrightness(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_brightnessStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + std::string value; + capDetails_t inputInfo; + int brightness = 0; + tvError_t ret = tvERROR_NONE; - std::string value; - capDetails_t inputInfo; - int brightness = 0; - tvError_t ret = tvERROR_NONE; - - value = parameters.HasLabel("brightness") ? parameters["brightness"].String() : ""; - returnIfParamNotFound(parameters,"brightness"); - brightness = stoi(value); + value = parameters.HasLabel("brightness") ? parameters["brightness"].String() : ""; + returnIfParamNotFound(parameters,"brightness"); + brightness = stoi(value); - if (validateIntegerInputParameter("Brightness",brightness) != 0) { - LOGERR("Failed in Brightness range validation:%s", __FUNCTION__); - returnResponse(false); - } + if (validateIntegerInputParameter("Brightness",brightness) != 0) { + LOGERR("Failed in Brightness range validation:%s", __FUNCTION__); + returnResponse(false); + } - if (parsingSetInputArgument(parameters, "Brightness",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "Brightness",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "Brightness",inputInfo )) { - LOGERR("%s: CapablityCheck failed for Brightness\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "Brightness",inputInfo )) { + LOGERR("%s: CapablityCheck failed for Brightness\n", __FUNCTION__); + returnResponse(false); + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with %s \n",__FUNCTION__); - ret = SetBrightness(brightness); - } + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with %s \n",__FUNCTION__); + ret = SetBrightness(brightness); + } - if(ret != tvERROR_NONE) { - LOGERR("Failed to set Brightness\n"); - returnResponse(false); - } - else { - int retval= updateAVoutputTVParam("set","Brightness",inputInfo,PQ_PARAM_BRIGHTNESS,brightness); - if(retval != 0 ) { - LOGERR("Failed to Save Brightness to ssm_data\n"); + if(ret != tvERROR_NONE) { + LOGERR("Failed to set Brightness\n"); returnResponse(false); } - LOGINFO("Exit : setBrightness successful to value: %d\n", brightness); - returnResponse(true); + else { + int retval= updateAVoutputTVParam("set","Brightness",inputInfo,PQ_PARAM_BRIGHTNESS,brightness); + if(retval != 0 ) { + LOGERR("Failed to Save Brightness to ssm_data\n"); + returnResponse(false); + } + LOGINFO("Exit : setBrightness successful to value: %d\n", brightness); + returnResponse(true); + } + } + else + { + bool success = setIntPQParam(parameters, "Brightness", PQ_PARAM_BRIGHTNESS, SetBrightness, m_maxBrightness); + returnResponse(success); } - } @@ -984,54 +2238,60 @@ namespace Plugin { { LOGINFO("Entry\n"); + if(m_brightnessStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + std::string value; + capDetails_t inputInfo; + paramIndex_t indexInfo; + int brightness=0; + tvError_t ret = tvERROR_NONE; + + if (parsingSetInputArgument(parameters, "Brightness",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - std::string value; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int brightness=0; - tvError_t ret = tvERROR_NONE; - - if (parsingSetInputArgument(parameters, "Brightness",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } - - if( !isCapablityCheckPassed( "Brightness",inputInfo )) { - LOGERR("%s: CapablityCheck failed for Brightness\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "Brightness",inputInfo )) { + LOGERR("%s: CapablityCheck failed for Brightness\n", __FUNCTION__); + returnResponse(false); + } - int retval= updateAVoutputTVParam("reset","Brightness",inputInfo,PQ_PARAM_BRIGHTNESS,brightness); - if(retval != 0 ) { - LOGWARN("Failed to reset Brightness\n"); - returnResponse(false); - } - else { - if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { - inputInfo.pqmode = "Current"; - inputInfo.source = "Current"; - inputInfo.format = "Current"; - getParamIndex("Brightness", inputInfo,indexInfo); - int err = getLocalparam("Brightness",indexInfo,brightness, PQ_PARAM_BRIGHTNESS); - if( err == 0 ) { - LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,brightness); - ret = SetBrightness(brightness); - } - else { - LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); - ret = tvERROR_GENERAL; + int retval= updateAVoutputTVParam("reset","Brightness",inputInfo,PQ_PARAM_BRIGHTNESS,brightness); + if(retval != 0 ) { + LOGWARN("Failed to reset Brightness\n"); + returnResponse(false); + } + else { + if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + getParamIndex("Brightness", inputInfo,indexInfo); + int err = getLocalparam("Brightness",indexInfo,brightness, PQ_PARAM_BRIGHTNESS); + if( err == 0 ) { + LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,brightness); + ret = SetBrightness(brightness); + } + else { + LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); + ret = tvERROR_GENERAL; + } } } - } - if(ret != tvERROR_NONE) { - returnResponse(false); + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetBrightness Successful to value : %d \n",brightness); + returnResponse(true); + } } - else { - LOGINFO("Exit : resetBrightness Successful to value : %d \n",brightness); - returnResponse(true); + else + { + bool success = resetPQParamToDefault(parameters, "Brightness", PQ_PARAM_BRIGHTNESS, SetBrightness); + returnResponse(success); } - } uint32_t AVOutputTV::getBrightnessCaps(const JsonObject& parameters, JsonObject& response) @@ -1082,133 +2342,161 @@ namespace Plugin { uint32_t AVOutputTV::getContrast(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry"); + if(m_contrastStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int contrast = 0; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int contrast = 0; + if (parsingGetInputArgument(parameters, "Contrast",inputInfo) != 0) { + LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); + returnResponse(false); + } - if (parsingGetInputArgument(parameters, "Contrast",inputInfo) != 0) { - LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); - returnResponse(false); - } + if (getParamIndex("Contrast",inputInfo,indexInfo) == -1) { + LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); + returnResponse(false); + } - if (getParamIndex("Contrast",inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); + int err = getLocalparam("Contrast",indexInfo,contrast, PQ_PARAM_CONTRAST); + if( err == 0 ) { + response["contrast"] = contrast; + LOGINFO("Exit : Contrast Value: %d \n", contrast); + returnResponse(true); + } + else { + returnResponse(false); + } } + else + { + int contrast = 0; + bool success = getPQParamFromContext(parameters, + "Contrast", + PQ_PARAM_CONTRAST, + contrast); + if (success) { + response["contrast"] = contrast; + } + returnResponse(success); - int err = getLocalparam("Contrast",indexInfo,contrast, PQ_PARAM_CONTRAST); - if( err == 0 ) { - response["contrast"] = contrast; - LOGINFO("Exit : Contrast Value: %d \n", contrast); - returnResponse(true); - } - else { - returnResponse(false); } } uint32_t AVOutputTV::setContrast(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_contrastStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + int contrast = 0; + tvError_t ret = tvERROR_NONE; + std::string value; - capDetails_t inputInfo; - int contrast = 0; - tvError_t ret = tvERROR_NONE; - std::string value; - - value = parameters.HasLabel("contrast") ? parameters["contrast"].String() : ""; - returnIfParamNotFound(parameters,"contrast"); - contrast = std::stoi(value); + value = parameters.HasLabel("contrast") ? parameters["contrast"].String() : ""; + returnIfParamNotFound(parameters,"contrast"); + contrast = std::stoi(value); - if (validateIntegerInputParameter("Contrast", contrast) != 0) { - LOGERR("Failed in contrast range validation:%s", __FUNCTION__); - returnResponse(false); - } + if (validateIntegerInputParameter("Contrast", contrast) != 0) { + LOGERR("Failed in contrast range validation:%s", __FUNCTION__); + returnResponse(false); + } - if (parsingSetInputArgument(parameters, "Contrast",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "Contrast",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "Contrast" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for Contrast\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "Contrast" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for Contrast\n", __FUNCTION__); + returnResponse(false); + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with %s \n",__FUNCTION__); - ret = SetContrast(contrast); - } + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with %s \n",__FUNCTION__); + ret = SetContrast(contrast); + } - if(ret != tvERROR_NONE) { - LOGERR("Failed to set Contrast\n"); - returnResponse(false); - } - else { - int retval= updateAVoutputTVParam("set","Contrast",inputInfo,PQ_PARAM_CONTRAST,contrast); - if(retval != 0 ) { - LOGERR("Failed to Save Contrast to ssm_data\n"); + if(ret != tvERROR_NONE) { + LOGERR("Failed to set Contrast\n"); returnResponse(false); } - LOGINFO("Exit : setContrast successful to value: %d\n", contrast); - returnResponse(true); + else { + int retval= updateAVoutputTVParam("set","Contrast",inputInfo,PQ_PARAM_CONTRAST,contrast); + if(retval != 0 ) { + LOGERR("Failed to Save Contrast to ssm_data\n"); + returnResponse(false); + } + LOGINFO("Exit : setContrast successful to value: %d\n", contrast); + returnResponse(true); + } + } + else + { + bool success = setIntPQParam(parameters, "Contrast", PQ_PARAM_CONTRAST, SetContrast, m_maxContrast); + returnResponse(success); } - } uint32_t AVOutputTV::resetContrast(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_contrastStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int contrast=0; + tvError_t ret = tvERROR_NONE; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int contrast=0; - tvError_t ret = tvERROR_NONE; - - if (parsingSetInputArgument(parameters, "Contrast",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "Contrast",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "Contrast" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for Contrast\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "Contrast" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for Contrast\n", __FUNCTION__); + returnResponse(false); + } - int retval= updateAVoutputTVParam("reset","Contrast",inputInfo,PQ_PARAM_CONTRAST,contrast); + int retval= updateAVoutputTVParam("reset","Contrast",inputInfo,PQ_PARAM_CONTRAST,contrast); - if(retval != 0 ) { - LOGWARN("Failed to reset Contrast\n"); - returnResponse(false); - } - else { - if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { - inputInfo.pqmode = "Current"; - inputInfo.source = "Current"; - inputInfo.format = "Current"; - getParamIndex("Contrast", inputInfo,indexInfo); - int err = getLocalparam("Contrast",indexInfo,contrast, PQ_PARAM_CONTRAST); - if( err == 0 ) { - LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,contrast); - ret = SetContrast(contrast); - } - else { - LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); - ret = tvERROR_GENERAL; + if(retval != 0 ) { + LOGWARN("Failed to reset Contrast\n"); + returnResponse(false); + } + else { + if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + getParamIndex("Contrast", inputInfo,indexInfo); + int err = getLocalparam("Contrast",indexInfo,contrast, PQ_PARAM_CONTRAST); + if( err == 0 ) { + LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,contrast); + ret = SetContrast(contrast); + } + else { + LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); + ret = tvERROR_GENERAL; + } } } - } - if(ret != tvERROR_NONE) { - returnResponse(false); - } - else { - LOGINFO("Exit : resetContrast Successful to value : %d \n",contrast); - returnResponse(true); + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetContrast Successful to value : %d \n",contrast); + returnResponse(true); + } } + else + { + bool success= resetPQParamToDefault(parameters, "Contrast", PQ_PARAM_CONTRAST, SetContrast); + returnResponse(success); + } } uint32_t AVOutputTV::getContrastCaps(const JsonObject& parameters, JsonObject& response) @@ -1260,133 +2548,160 @@ namespace Plugin { uint32_t AVOutputTV::getSaturation(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry"); + if(m_saturationStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int saturation = 0; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int saturation = 0; + if (parsingGetInputArgument(parameters, "Saturation",inputInfo) != 0) { + LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); + returnResponse(false); + } - if (parsingGetInputArgument(parameters, "Saturation",inputInfo) != 0) { - LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); - returnResponse(false); - } + if (getParamIndex("Saturation", inputInfo,indexInfo) == -1) { + LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); + returnResponse(false); + } - if (getParamIndex("Saturation", inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); + int err = getLocalparam("Saturation",indexInfo,saturation, PQ_PARAM_SATURATION); + if( err == 0 ) { + response["saturation"] = saturation; + LOGINFO("Exit : Saturation Value: %d \n", saturation); + returnResponse(true); + } + else { + returnResponse(false); + } } + else + { + int saturation = 0; + bool success = getPQParamFromContext(parameters, + "Saturation", + PQ_PARAM_SATURATION, + saturation); + if (success) { + response["saturation"] = saturation; + } + returnResponse(success); - int err = getLocalparam("Saturation",indexInfo,saturation, PQ_PARAM_SATURATION); - if( err == 0 ) { - response["saturation"] = saturation; - LOGINFO("Exit : Saturation Value: %d \n", saturation); - returnResponse(true); - } - else { - returnResponse(false); } } uint32_t AVOutputTV::setSaturation(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_saturationStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + std::string value; + int saturation = 0; + tvError_t ret = tvERROR_NONE; - capDetails_t inputInfo; - std::string value; - int saturation = 0; - tvError_t ret = tvERROR_NONE; - - value = parameters.HasLabel("saturation") ? parameters["saturation"].String() : ""; - returnIfParamNotFound(parameters,"saturation"); - saturation = std::stoi(value); + value = parameters.HasLabel("saturation") ? parameters["saturation"].String() : ""; + returnIfParamNotFound(parameters,"saturation"); + saturation = std::stoi(value); - if (validateIntegerInputParameter("Saturation",saturation) != 0) { - LOGERR("Failed in saturation range validation:%s", __FUNCTION__); - returnResponse(false); - } + if (validateIntegerInputParameter("Saturation",saturation) != 0) { + LOGERR("Failed in saturation range validation:%s", __FUNCTION__); + returnResponse(false); + } - if (parsingSetInputArgument(parameters, "Saturation",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "Saturation",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "Saturation" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for Saturation\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "Saturation" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for Saturation\n", __FUNCTION__); + returnResponse(false); + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with %s\n",__FUNCTION__); - ret = SetSaturation(saturation); - } + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with %s\n",__FUNCTION__); + ret = SetSaturation(saturation); + } - if(ret != tvERROR_NONE) { - LOGERR("Failed to set Saturation\n"); - returnResponse(false); - } - else { - int retval= updateAVoutputTVParam("set","Saturation",inputInfo,PQ_PARAM_SATURATION,saturation); - if(retval != 0 ) { - LOGERR("Failed to Save Saturation to ssm_data\n"); + if(ret != tvERROR_NONE) { + LOGERR("Failed to set Saturation\n"); returnResponse(false); } - LOGINFO("Exit : setSaturation successful to value: %d\n", saturation); - returnResponse(true); + else { + int retval= updateAVoutputTVParam("set","Saturation",inputInfo,PQ_PARAM_SATURATION,saturation); + if(retval != 0 ) { + LOGERR("Failed to Save Saturation to ssm_data\n"); + returnResponse(false); + } + LOGINFO("Exit : setSaturation successful to value: %d\n", saturation); + returnResponse(true); + } + } + else + { + bool success = setIntPQParam(parameters, "Saturation", PQ_PARAM_SATURATION, SetSaturation, m_maxSaturation); + returnResponse(success); } - } uint32_t AVOutputTV::resetSaturation(const JsonObject& parameters, JsonObject& response) { - LOGINFO("Entry\n"); + if(m_saturationStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int saturation=0; + tvError_t ret = tvERROR_NONE; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int saturation=0; - tvError_t ret = tvERROR_NONE; - - if (parsingSetInputArgument(parameters, "Saturation", inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "Saturation", inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "Saturation", inputInfo )) { - LOGERR("%s: CapablityCheck failed for Saturation\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "Saturation", inputInfo )) { + LOGERR("%s: CapablityCheck failed for Saturation\n", __FUNCTION__); + returnResponse(false); + } - int retval= updateAVoutputTVParam("reset","Saturation",inputInfo,PQ_PARAM_SATURATION,saturation); + int retval= updateAVoutputTVParam("reset","Saturation",inputInfo,PQ_PARAM_SATURATION,saturation); - if(retval != 0 ) { - LOGERR("Failed to reset Saturation\n"); - returnResponse(false); - } - else { - if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { - inputInfo.pqmode = "Current"; - inputInfo.source = "Current"; - inputInfo.format = "Current"; - getParamIndex("Saturation",inputInfo,indexInfo); - int err = getLocalparam("Saturation",indexInfo, saturation, PQ_PARAM_SATURATION); - if( err == 0 ) { - LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,saturation); - ret = SetSaturation(saturation); - } - else { - LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); - ret = tvERROR_GENERAL; + if(retval != 0 ) { + LOGERR("Failed to reset Saturation\n"); + returnResponse(false); + } + else { + if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + getParamIndex("Saturation",inputInfo,indexInfo); + int err = getLocalparam("Saturation",indexInfo, saturation, PQ_PARAM_SATURATION); + if( err == 0 ) { + LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,saturation); + ret = SetSaturation(saturation); + } + else { + LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); + ret = tvERROR_GENERAL; + } } } - } - if(ret != tvERROR_NONE) { - returnResponse(false); - } - else { - LOGINFO("Exit : resetSaturation Successful to value : %d \n",saturation); - returnResponse(true); + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetSaturation Successful to value : %d \n",saturation); + returnResponse(true); + } } + else + { + bool success= resetPQParamToDefault(parameters, "Saturation", PQ_PARAM_SATURATION, SetSaturation); + returnResponse(success); + } } uint32_t AVOutputTV::getSaturationCaps(const JsonObject& parameters, JsonObject& response) @@ -1439,131 +2754,160 @@ namespace Plugin { uint32_t AVOutputTV::getSharpness(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry"); + if(m_sharpnessStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int sharpness = 0; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int sharpness = 0; + if (parsingGetInputArgument(parameters, "Sharpness",inputInfo) != 0) { + LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); + returnResponse(false); + } - if (parsingGetInputArgument(parameters, "Sharpness",inputInfo) != 0) { - LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); - returnResponse(false); - } + if (getParamIndex("Sharpness",inputInfo,indexInfo) == -1) { + LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); + returnResponse(false); + } - if (getParamIndex("Sharpness",inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); + int err = getLocalparam("Sharpness",indexInfo,sharpness, PQ_PARAM_SHARPNESS); + if( err == 0 ) { + response["sharpness"] = sharpness; + LOGINFO("Exit : Sharpness Value: %d \n", sharpness); + returnResponse(true); + } + else { + returnResponse(false); + } } + else + { + int sharpness = 0; + bool success = getPQParamFromContext(parameters, + "Sharpness", + PQ_PARAM_SHARPNESS, + sharpness); + if (success) { + response["sharpness"] = sharpness; + } + returnResponse(success); - int err = getLocalparam("Sharpness",indexInfo,sharpness, PQ_PARAM_SHARPNESS); - if( err == 0 ) { - response["sharpness"] = sharpness; - LOGINFO("Exit : Sharpness Value: %d \n", sharpness); - returnResponse(true); - } - else { - returnResponse(false); } } uint32_t AVOutputTV::setSharpness(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_sharpnessStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + int sharpness = 0; + tvError_t ret = tvERROR_NONE; + std::string value; - capDetails_t inputInfo; - int sharpness = 0; - tvError_t ret = tvERROR_NONE; - std::string value; - - value = parameters.HasLabel("sharpness") ? parameters["sharpness"].String() : ""; - returnIfParamNotFound(parameters,"sharpness"); - sharpness = std::stoi(value); + value = parameters.HasLabel("sharpness") ? parameters["sharpness"].String() : ""; + returnIfParamNotFound(parameters,"sharpness"); + sharpness = std::stoi(value); - if (validateIntegerInputParameter("Sharpness",sharpness) != 0) { - LOGERR("Failed in sharpness range validation:%s", __FUNCTION__); - returnResponse(false); - } + if (validateIntegerInputParameter("Sharpness",sharpness) != 0) { + LOGERR("Failed in sharpness range validation:%s", __FUNCTION__); + returnResponse(false); + } - if (parsingSetInputArgument(parameters, "Sharpness", inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "Sharpness", inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "Sharpness", inputInfo )) { - LOGERR("%s: CapablityCheck failed for Sharpness\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "Sharpness", inputInfo )) { + LOGERR("%s: CapablityCheck failed for Sharpness\n", __FUNCTION__); + returnResponse(false); + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with %s\n",__FUNCTION__); - ret = SetSharpness(sharpness); - } + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with %s\n",__FUNCTION__); + ret = SetSharpness(sharpness); + } - if(ret != tvERROR_NONE) { - LOGERR("Failed to set Sharpness\n"); - returnResponse(false); - } - else { - int retval= updateAVoutputTVParam("set","Sharpness",inputInfo,PQ_PARAM_SHARPNESS,sharpness); - if(retval != 0 ) { - LOGERR("Failed to Save Sharpness to ssm_data\n"); + if(ret != tvERROR_NONE) { + LOGERR("Failed to set Sharpness\n"); returnResponse(false); } - LOGINFO("Exit : setSharpness successful to value: %d\n", sharpness); - returnResponse(true); + else { + int retval= updateAVoutputTVParam("set","Sharpness",inputInfo,PQ_PARAM_SHARPNESS,sharpness); + if(retval != 0 ) { + LOGERR("Failed to Save Sharpness to ssm_data\n"); + returnResponse(false); + } + LOGINFO("Exit : setSharpness successful to value: %d\n", sharpness); + returnResponse(true); + } + } + else + { + bool success = setIntPQParam(parameters, "Sharpness", PQ_PARAM_SHARPNESS, SetSharpness, m_maxSharpness); + returnResponse(success); } - } uint32_t AVOutputTV::resetSharpness(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_sharpnessStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int sharpness=0; + tvError_t ret = tvERROR_NONE; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int sharpness=0; - tvError_t ret = tvERROR_NONE; - - if (parsingSetInputArgument(parameters, "Sharpness",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "Sharpness",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "Sharpness" , inputInfo)) { - LOGERR("%s: CapablityCheck failed for Sharpness\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "Sharpness" , inputInfo)) { + LOGERR("%s: CapablityCheck failed for Sharpness\n", __FUNCTION__); + returnResponse(false); + } - int retval= updateAVoutputTVParam("reset","Sharpness", inputInfo,PQ_PARAM_SHARPNESS,sharpness); + int retval= updateAVoutputTVParam("reset","Sharpness", inputInfo,PQ_PARAM_SHARPNESS,sharpness); - if(retval != 0 ) { - LOGERR("Failed to reset Sharpness\n"); - returnResponse(false); - } - else { - if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { - inputInfo.pqmode = "Current"; - inputInfo.source = "Current"; - inputInfo.format = "Current"; - getParamIndex("Sharpness",inputInfo,indexInfo); - int err = getLocalparam("Sharpness",indexInfo, sharpness, PQ_PARAM_SHARPNESS); - if( err == 0 ) { - LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,sharpness); - ret = SetSharpness(sharpness); - } - else { - LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); - ret = tvERROR_GENERAL; + if(retval != 0 ) { + LOGERR("Failed to reset Sharpness\n"); + returnResponse(false); + } + else { + if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + getParamIndex("Sharpness",inputInfo,indexInfo); + int err = getLocalparam("Sharpness",indexInfo, sharpness, PQ_PARAM_SHARPNESS); + if( err == 0 ) { + LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,sharpness); + ret = SetSharpness(sharpness); + } + else { + LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); + ret = tvERROR_GENERAL; + } } } - } - if(ret != tvERROR_NONE) { - returnResponse(false); + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetSharpness Successful to value : %d \n",sharpness); + returnResponse(true); + } } - else { - LOGINFO("Exit : resetSharpness Successful to value : %d \n",sharpness); - returnResponse(true); + else + { + bool success= resetPQParamToDefault(parameters, "Sharpness", PQ_PARAM_SHARPNESS, SetSharpness); + returnResponse(success); + } } @@ -1617,131 +2961,160 @@ namespace Plugin { uint32_t AVOutputTV::getHue(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry"); + if(m_hueStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int hue = 0; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int hue = 0; + if (parsingGetInputArgument(parameters, "Hue", inputInfo) != 0) { + LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); + returnResponse(false); + } - if (parsingGetInputArgument(parameters, "Hue", inputInfo) != 0) { - LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); - returnResponse(false); - } + if (getParamIndex("Hue",inputInfo,indexInfo) == -1) { + LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); + returnResponse(false); + } - if (getParamIndex("Hue",inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); + int err = getLocalparam("Hue",indexInfo,hue, PQ_PARAM_HUE); + if( err == 0 ) { + response["hue"] = hue; + LOGINFO("Exit : Hue Value: %d \n", hue); + returnResponse(true); + } + else { + returnResponse(false); + } } + else + { + int hue = 0; + bool success = getPQParamFromContext(parameters, + "Hue", + PQ_PARAM_HUE, + hue); + if (success) { + response["hue"] = hue; + } + returnResponse(success); - int err = getLocalparam("Hue",indexInfo,hue, PQ_PARAM_HUE); - if( err == 0 ) { - response["hue"] = hue; - LOGINFO("Exit : Hue Value: %d \n", hue); - returnResponse(true); - } - else { - returnResponse(false); } } uint32_t AVOutputTV::setHue(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_hueStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + int hue = 0; + tvError_t ret = tvERROR_NONE; + std::string value; - capDetails_t inputInfo; - int hue = 0; - tvError_t ret = tvERROR_NONE; - std::string value; - - value = parameters.HasLabel("hue") ? parameters["hue"].String() : ""; - returnIfParamNotFound(parameters,"hue"); - hue = std::stoi(value); + value = parameters.HasLabel("hue") ? parameters["hue"].String() : ""; + returnIfParamNotFound(parameters,"hue"); + hue = std::stoi(value); - if (validateIntegerInputParameter("Hue",hue) != 0) { - LOGERR("Failed in hue range validation:%s", __FUNCTION__); - returnResponse(false); - } + if (validateIntegerInputParameter("Hue",hue) != 0) { + LOGERR("Failed in hue range validation:%s", __FUNCTION__); + returnResponse(false); + } - if (parsingSetInputArgument(parameters, "Hue",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "Hue",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "Hue", inputInfo )) { - LOGERR("%s: CapablityCheck failed for Hue\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "Hue", inputInfo )) { + LOGERR("%s: CapablityCheck failed for Hue\n", __FUNCTION__); + returnResponse(false); + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with %s\n",__FUNCTION__); - ret = SetHue(hue); - } + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with %s\n",__FUNCTION__); + ret = SetHue(hue); + } - if(ret != tvERROR_NONE) { - LOGERR("Failed to set Hue\n"); - returnResponse(false); - } - else { - int retval= updateAVoutputTVParam("set","Hue",inputInfo,PQ_PARAM_HUE,hue); - if(retval != 0 ) { - LOGERR("Failed to Save Hue to ssm_data\n"); + if(ret != tvERROR_NONE) { + LOGERR("Failed to set Hue\n"); returnResponse(false); } - LOGINFO("Exit : setHue successful to value: %d\n", hue); - returnResponse(true); + else { + int retval= updateAVoutputTVParam("set","Hue",inputInfo,PQ_PARAM_HUE,hue); + if(retval != 0 ) { + LOGERR("Failed to Save Hue to ssm_data\n"); + returnResponse(false); + } + LOGINFO("Exit : setHue successful to value: %d\n", hue); + returnResponse(true); + } + } + else + { + bool success = setIntPQParam(parameters, "Hue", PQ_PARAM_HUE, SetHue, m_maxHue); + returnResponse(success); } - } uint32_t AVOutputTV::resetHue(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_hueStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int hue=0; + tvError_t ret = tvERROR_NONE; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int hue=0; - tvError_t ret = tvERROR_NONE; - - if (parsingSetInputArgument(parameters, "Hue",inputInfo)!= 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "Hue",inputInfo)!= 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "Hue" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for Hue\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "Hue" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for Hue\n", __FUNCTION__); + returnResponse(false); + } - int retval= updateAVoutputTVParam("reset","Hue", inputInfo,PQ_PARAM_HUE,hue); + int retval= updateAVoutputTVParam("reset","Hue", inputInfo,PQ_PARAM_HUE,hue); - if(retval != 0 ) { - LOGERR("Failed to reset Hue\n"); - returnResponse(false); - } - else { - if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { - inputInfo.pqmode = "Current"; - inputInfo.source = "Current"; - inputInfo.format = "Current"; - getParamIndex("Hue",inputInfo,indexInfo); - int err = getLocalparam("Hue",indexInfo, hue, PQ_PARAM_HUE); - if( err == 0 ) { - LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,hue); - ret = SetHue(hue); - } - else { - LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); - ret = tvERROR_GENERAL; + if(retval != 0 ) { + LOGERR("Failed to reset Hue\n"); + returnResponse(false); + } + else { + if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + getParamIndex("Hue",inputInfo,indexInfo); + int err = getLocalparam("Hue",indexInfo, hue, PQ_PARAM_HUE); + if( err == 0 ) { + LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex,hue); + ret = SetHue(hue); + } + else { + LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); + ret = tvERROR_GENERAL; + } } } - } - if(ret != tvERROR_NONE) { - returnResponse(false); + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetHue Successful to value : %d \n",hue); + returnResponse(true); + } } - else { - LOGINFO("Exit : resetHue Successful to value : %d \n",hue); - returnResponse(true); + else + { + bool success= resetPQParamToDefault(parameters, "Hue", PQ_PARAM_HUE, SetHue); + returnResponse(success); + } } @@ -1795,110 +3168,146 @@ namespace Plugin { uint32_t AVOutputTV::getColorTemperature(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry"); + if(m_colorTempStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int colortemp = 0; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int colortemp = 0; - - if (parsingGetInputArgument(parameters, "ColorTemperature", inputInfo) != 0) { - LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); - returnResponse(false); - } - - if (getParamIndex("ColorTemperature",inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); - } - - int err = getLocalparam("ColorTemp",indexInfo,colortemp,PQ_PARAM_COLOR_TEMPERATURE); - if( err == 0 ) { - switch(colortemp) { - case tvColorTemp_STANDARD: - LOGINFO("Color Temp Value: Standard\n"); - response["colorTemperature"] = "Standard"; - break; - - case tvColorTemp_WARM: - LOGINFO("Color Temp Value: Warm\n"); - response["colorTemperature"] = "Warm"; - break; - - case tvColorTemp_COLD: - LOGINFO("Color Temp Value: Cold\n"); - response["colorTemperature"] = "Cold"; - break; + if (parsingGetInputArgument(parameters, "ColorTemperature", inputInfo) != 0) { + LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); + returnResponse(false); + } - case tvColorTemp_USER: - LOGINFO("Color Temp Value: User Defined\n"); - response["colorTemperature"] = "UserDefined"; - break; + if (getParamIndex("ColorTemperature",inputInfo,indexInfo) == -1) { + LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); + returnResponse(false); + } - default: - LOGINFO("Color Temp Value: Standard\n"); - response["colorTemperature"] = "Standard"; - break; + int err = getLocalparam("ColorTemp",indexInfo,colortemp,PQ_PARAM_COLOR_TEMPERATURE); + if( err == 0 ) { + switch(colortemp) { + case tvColorTemp_STANDARD: + LOGINFO("Color Temp Value: Standard\n"); + response["colorTemperature"] = "Standard"; + break; + + case tvColorTemp_WARM: + LOGINFO("Color Temp Value: Warm\n"); + response["colorTemperature"] = "Warm"; + break; + + case tvColorTemp_COLD: + LOGINFO("Color Temp Value: Cold\n"); + response["colorTemperature"] = "Cold"; + break; + + case tvColorTemp_USER: + LOGINFO("Color Temp Value: User Defined\n"); + response["colorTemperature"] = "UserDefined"; + break; + + default: + LOGINFO("Color Temp Value: Standard\n"); + response["colorTemperature"] = "Standard"; + break; + } + LOGINFO("Exit : ColorTemperature Value: %d \n", colortemp); + returnResponse(true); + } + else { + returnResponse(false); } - LOGINFO("Exit : ColorTemperature Value: %d \n", colortemp); - returnResponse(true); } - else { - returnResponse(false); + else + { + std::string outMode; + if (getEnumPQParamString(parameters, "ColorTemp", + PQ_PARAM_COLOR_TEMPERATURE, colorTempReverseMap, outMode)) { + response["colorTemperature"] = outMode; + returnResponse(true); + } else { + returnResponse(false); + } + } } uint32_t AVOutputTV::setColorTemperature(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_colorTempStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + std::string value; + tvColorTemp_t colortemp = tvColorTemp_MAX; + tvError_t ret = tvERROR_NONE; + + value = parameters.HasLabel("colorTemperature") ? parameters["colorTemperature"].String() : ""; + returnIfParamNotFound(parameters,"colorTemperature"); + if(!value.compare("Standard")) { + colortemp = tvColorTemp_STANDARD; + } + else if (!value.compare("Warm")) { + colortemp = tvColorTemp_WARM; + } + else if (!value.compare("Cold")) { + colortemp = tvColorTemp_COLD; + } + else if (!value.compare("UserDefined")) { + colortemp = tvColorTemp_USER; + } + else { + returnResponse(false); + } - capDetails_t inputInfo; - std::string value; - tvColorTemp_t colortemp = tvColorTemp_MAX; - tvError_t ret = tvERROR_NONE; - - value = parameters.HasLabel("colorTemperature") ? parameters["colorTemperature"].String() : ""; - returnIfParamNotFound(parameters,"colorTemperature"); - if(!value.compare("Standard")) { - colortemp = tvColorTemp_STANDARD; - } - else if (!value.compare("Warm")) { - colortemp = tvColorTemp_WARM; - } - else if (!value.compare("Cold")) { - colortemp = tvColorTemp_COLD; - } - else if (!value.compare("UserDefined")) { - colortemp = tvColorTemp_USER; - } - else { - returnResponse(false); - } - - if (parsingSetInputArgument(parameters, "ColorTemperature",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "ColorTemperature",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "ColorTemperature", inputInfo )) { - LOGERR("%s: CapablityCheck failed for colorTemperature\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "ColorTemperature", inputInfo )) { + LOGERR("%s: CapablityCheck failed for colorTemperature\n", __FUNCTION__); + returnResponse(false); + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with %s\n",__FUNCTION__); - ret = SetColorTemperature((tvColorTemp_t)colortemp); - } + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with %s\n",__FUNCTION__); + ret = SetColorTemperature((tvColorTemp_t)colortemp); + } - if(ret != tvERROR_NONE) { - LOGERR("Failed to set ColorTemperature\n"); - returnResponse(false); + if(ret != tvERROR_NONE) { + LOGERR("Failed to set ColorTemperature\n"); + returnResponse(false); + } + else { + int retval= updateAVoutputTVParam("set","ColorTemp", inputInfo,PQ_PARAM_COLOR_TEMPERATURE,(int)colortemp); + if(retval != 0 ) { + LOGERR("Failed to Save ColorTemperature to ssm_data\n"); + returnResponse(false); + } + LOGINFO("Exit : setColorTemperature successful to value: %d\n", colortemp); + returnResponse(true); + } } - else { - int retval= updateAVoutputTVParam("set","ColorTemp", inputInfo,PQ_PARAM_COLOR_TEMPERATURE,(int)colortemp); - if(retval != 0 ) { - LOGERR("Failed to Save ColorTemperature to ssm_data\n"); + else + { + bool success = setEnumPQParam( + parameters, + "colorTemperature", + "ColorTemp", + colorTempMap, + PQ_PARAM_COLOR_TEMPERATURE, + [](int val) { + return SetColorTemperature(static_cast(val)); + }); + + if (!success) { + LOGERR("setColorTemperature failed"); returnResponse(false); } - LOGINFO("Exit : setColorTemperature successful to value: %d\n", colortemp); + + LOGINFO("setColorTemperature: Success"); returnResponse(true); } } @@ -1907,52 +3316,67 @@ namespace Plugin { { LOGINFO("Entry\n"); + if(m_colorTempStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int colortemp=0; + tvError_t ret = tvERROR_NONE; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int colortemp=0; - tvError_t ret = tvERROR_NONE; - - if (parsingSetInputArgument(parameters, "ColorTemperature", inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "ColorTemperature", inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "ColorTemperature", inputInfo )) { - LOGERR("%s: CapablityCheck failed for colorTemperature\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "ColorTemperature", inputInfo )) { + LOGERR("%s: CapablityCheck failed for colorTemperature\n", __FUNCTION__); + returnResponse(false); + } - int retval= updateAVoutputTVParam("reset","ColorTemp", inputInfo,PQ_PARAM_COLOR_TEMPERATURE,colortemp); + int retval= updateAVoutputTVParam("reset","ColorTemp", inputInfo,PQ_PARAM_COLOR_TEMPERATURE,colortemp); - if(retval != 0 ) { - LOGERR("Failed to reset ColorTemperature\n"); - returnResponse(false); - } - else { - if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { - inputInfo.pqmode = "Current"; - inputInfo.source = "Current"; - inputInfo.format = "Current"; - getParamIndex("ColorTemperature",inputInfo,indexInfo); - int err = getLocalparam("ColorTemp",indexInfo, colortemp, PQ_PARAM_COLOR_TEMPERATURE); - if( err == 0 ) { - LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex, colortemp); - ret = SetColorTemperature((tvColorTemp_t)colortemp); - } - else { - LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); - ret = tvERROR_GENERAL; + if(retval != 0 ) { + LOGERR("Failed to reset ColorTemperature\n"); + returnResponse(false); + } + else { + if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + getParamIndex("ColorTemperature",inputInfo,indexInfo); + int err = getLocalparam("ColorTemp",indexInfo, colortemp, PQ_PARAM_COLOR_TEMPERATURE); + if( err == 0 ) { + LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex, colortemp); + ret = SetColorTemperature((tvColorTemp_t)colortemp); + } + else { + LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); + ret = tvERROR_GENERAL; + } } } - } - if(ret != tvERROR_NONE) { - returnResponse(false); + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetColorTemperature Successful to value : %d \n",colortemp); + returnResponse(true); + } } - else { - LOGINFO("Exit : resetColorTemperature Successful to value : %d \n",colortemp); - returnResponse(true); + else + { + bool success = resetEnumPQParamToDefault( + parameters, + "ColorTemp", + PQ_PARAM_COLOR_TEMPERATURE, + colorTempReverseMap, + [](int val, const std::unordered_map&) { + return SetColorTemperature(static_cast(val)); + }); + + returnResponse(success); } } @@ -2007,161 +3431,229 @@ namespace Plugin { { LOGINFO("Entry"); - capDetails_t inputInfo; - paramIndex_t indexInfo; - int dimmingMode = 0; - - if (parsingGetInputArgument(parameters, "DimmingMode", inputInfo) != 0) { - LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); - returnResponse(false); - } - - if (isPlatformSupport("DimmingMode") != 0) { - returnResponse(false); - } + if(m_dimmingModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int dimmingMode = 0; + if (parsingGetInputArgument(parameters, "DimmingMode", inputInfo) != 0) { + LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); + returnResponse(false); + } + if (isPlatformSupport("DimmingMode") != 0) { + returnResponse(false); + } - if (getParamIndex("DimmingMode",inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); - } + if (getParamIndex("DimmingMode",inputInfo,indexInfo) == -1) { + LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); + returnResponse(false); + } - int err = getLocalparam("DimmingMode",indexInfo,dimmingMode, PQ_PARAM_DIMMINGMODE); - if( err == 0 ) { - switch(dimmingMode) { - case tvDimmingMode_Fixed: - LOGINFO("DimmingMode Value: Fixed\n"); - response["DimmingMode"] = "fixed"; - break; + int err = getLocalparam("DimmingMode",indexInfo,dimmingMode, PQ_PARAM_DIMMINGMODE); + if( err == 0 ) { + switch(dimmingMode) { + case tvDimmingMode_Fixed: + LOGINFO("DimmingMode Value: Fixed\n"); + response["dimmingMode"] = "Fixed"; + break; - case tvDimmingMode_Local: - LOGINFO("DimmingMode Value: Local\n"); - response["DimmingMode"] = "local"; - break; + case tvDimmingMode_Local: + LOGINFO("DimmingMode Value: Local\n"); + response["dimmingMode"] = "Local"; + break; - case tvDimmingMode_Global: - LOGINFO("DimmingMode Value: Global\n"); - response["DimmingMode"] = "global"; - break; + case tvDimmingMode_Global: + LOGINFO("DimmingMode Value: Global\n"); + response["dimmingMode"] = "Global"; + break; + } + LOGINFO("Exit : DimmingMode Value: %d \n", dimmingMode); + returnResponse(true); + } + else { + returnResponse(false); } - LOGINFO("Exit : DimmingMode Value: %d \n", dimmingMode); - returnResponse(true); } - else { - returnResponse(false); + else + { + std::string mode; + if (getEnumPQParamString(parameters, "DimmingMode", + PQ_PARAM_DIMMINGMODE, dimmingModeReverseMap, mode)) { + response["dimmingMode"] = mode; + returnResponse(true); + } else { + returnResponse(false); + } } } uint32_t AVOutputTV::setBacklightDimmingMode(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_dimmingModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { - capDetails_t inputInfo; - int dimmingMode = 0; - tvError_t ret = tvERROR_NONE; - std::string value; + capDetails_t inputInfo; + int dimmingMode = 0; + tvError_t ret = tvERROR_NONE; + std::string value; - value = parameters.HasLabel("DimmingMode") ? parameters["DimmingMode"].String() : ""; - returnIfParamNotFound(parameters,"DimmingMode"); + value = parameters.HasLabel("dimmingMode") ? parameters["dimmingMode"].String() : ""; + returnIfParamNotFound(parameters,"dimmingMode"); - if (validateInputParameter("DimmingMode",value) != 0) { - LOGERR("%s: Range validation failed for DimmingMode\n", __FUNCTION__); - returnResponse(false); - } - dimmingMode = getDimmingModeIndex(value); + if (validateInputParameter("DimmingMode",value) != 0) { + LOGERR("%s: Range validation failed for DimmingMode\n", __FUNCTION__); + returnResponse(false); + } + dimmingMode = getDimmingModeIndex(value); - if (parsingSetInputArgument(parameters, "DimmingMode",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "DimmingMode",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if (isPlatformSupport("DimmingMode") != 0) { - returnResponse(false); - } + if( !isCapablityCheckPassed( "DimmingMode" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for DimmingMode\n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "DimmingMode" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for DimmingMode\n", __FUNCTION__); - returnResponse(false); - } + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with %s\n",__FUNCTION__); + ret = SetTVDimmingMode(value.c_str()); + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with %s\n",__FUNCTION__); - ret = SetTVDimmingMode(value.c_str()); - } + if(ret != tvERROR_NONE) { + LOGERR("Failed to set DimmingMode\n"); + returnResponse(false); + } + else { + int retval= updateAVoutputTVParam("set","DimmingMode",inputInfo,PQ_PARAM_DIMMINGMODE,(int)dimmingMode); + if(retval != 0 ) { + LOGERR("Failed to Save DimmingMode to ssm_data\n"); + returnResponse(false); + } - if(ret != tvERROR_NONE) { - LOGERR("Failed to set DimmingMode\n"); - returnResponse(false); + LOGINFO("Exit : setDimmingMode successful to value: %d\n", dimmingMode); + returnResponse(true); + } } - else { - int retval= updateAVoutputTVParam("set","DimmingMode",inputInfo,PQ_PARAM_DIMMINGMODE,(int)dimmingMode); - if(retval != 0 ) { - LOGERR("Failed to Save DimmingMode to ssm_data\n"); + else + { + int dimmingMode = 0; + tvError_t ret = tvERROR_NONE; + std::string value; + + value = parameters.HasLabel("dimmingMode") ? parameters["dimmingMode"].String() : ""; + returnIfParamNotFound(parameters,"dimmingMode"); + + dimmingMode = getDimmingModeIndex(value); + if (dimmingMode < 0 || dimmingMode > tvDimmingMode_MAX) { + LOGERR("Input value %d is out of range (0 - %d) for DimmingMode", dimmingMode, tvDimmingMode_MAX); returnResponse(false); } - - LOGINFO("Exit : setDimmingMode successful to value: %d\n", dimmingMode); - returnResponse(true); + if( isSetRequiredForParam(parameters, "DimmingMode" ) ) { + LOGINFO("Proceed with %s\n",__FUNCTION__); + ret = SetTVDimmingMode(value.c_str()); + } + if(ret != tvERROR_NONE) { + LOGERR("Failed to set DimmingMode\n"); + returnResponse(false); + } + else + { + // Update the TV parameter + int retval = updateAVoutputTVParamV2("set", "DimmingMode", parameters, PQ_PARAM_DIMMINGMODE, (int)dimmingMode); + if (retval != 0) { + LOGERR("Failed to Save DimmingMode to ssm_data. retval: %d \n", retval); + returnResponse(false); + } + LOGINFO("Exit : setDimmingMode successful to value: %d \n", dimmingMode); + returnResponse(true); + } } } uint32_t AVOutputTV::resetBacklightDimmingMode(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_dimmingModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { - capDetails_t inputInfo; - paramIndex_t indexInfo; - std::string dimmingMode; - int dMode=0; - tvError_t ret = tvERROR_NONE; + capDetails_t inputInfo; + paramIndex_t indexInfo; + std::string dimmingMode; + int dMode=0; + tvError_t ret = tvERROR_NONE; - if (parsingSetInputArgument(parameters, "DimmingMode", inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "DimmingMode", inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "DimmingMode" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for DimmingMode\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "DimmingMode" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for DimmingMode\n", __FUNCTION__); + returnResponse(false); + } - if (isPlatformSupport("DimmingMode") != 0) { - returnResponse(false); - } + if (isPlatformSupport("DimmingMode") != 0) { + returnResponse(false); + } - int retval= updateAVoutputTVParam("reset","DimmingMode", inputInfo,PQ_PARAM_DIMMINGMODE,dMode); + int retval= updateAVoutputTVParam("reset","DimmingMode", inputInfo,PQ_PARAM_DIMMINGMODE,dMode); - if(retval != 0 ) { - LOGERR("Failed to reset ldim\n"); - returnResponse(false); - } + if(retval != 0 ) { + LOGERR("Failed to reset ldim\n"); + returnResponse(false); + } - else { - if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { - inputInfo.pqmode = "Current"; - inputInfo.source = "Current"; - inputInfo.format = "Current"; - getParamIndex("DimmingMode",inputInfo,indexInfo); - int err = getLocalparam("DimmingMode",indexInfo, dMode, PQ_PARAM_DIMMINGMODE); - if( err == 0 ) { - LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex, dMode); - getDimmingModeStringFromEnum(dMode,dimmingMode); - ret = SetTVDimmingMode(dimmingMode.c_str()); - } - else { - LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); - ret = tvERROR_GENERAL; + else { + if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + getParamIndex("DimmingMode",inputInfo,indexInfo); + int err = getLocalparam("DimmingMode",indexInfo, dMode, PQ_PARAM_DIMMINGMODE); + if( err == 0 ) { + LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex, dMode); + getDimmingModeStringFromEnum(dMode,dimmingMode); + ret = SetTVDimmingMode(dimmingMode.c_str()); + } + else { + LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); + ret = tvERROR_GENERAL; + } } } - } - if(ret != tvERROR_NONE) { - returnResponse(false); + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetBacklightDimmingMode Successful to value : %s \n",dimmingMode.c_str()); + returnResponse(true); + } } - else { - LOGINFO("Exit : resetBacklightDimmingMode Successful to value : %s \n",dimmingMode.c_str()); - returnResponse(true); + else + { + bool success = resetEnumPQParamToDefault( + parameters, + "DimmingMode", + PQ_PARAM_DIMMINGMODE, + dimmingModeReverseMap, + [](int val, const std::unordered_map& enumMap) -> tvError_t { + auto it = enumMap.find(val); + if (it != enumMap.end()) { + return SetTVDimmingMode(it->second.c_str()); + } else { + LOGERR("Invalid enum value: %d for DimmingMode\n", val); + return tvERROR_GENERAL; + } + }); + + returnResponse(success); + } } @@ -2574,199 +4066,529 @@ namespace Plugin { } } + bool AVOutputTV::getPictureModeV2(const JsonObject& parameters, std::string& outMode) + { + LOGINFO("Entry"); + + tvVideoSrcType_t source = VIDEO_SOURCE_IP; + tvVideoFormatType_t format = VIDEO_FORMAT_SDR; + + // Parse videoSource + if (!parameters.HasLabel("videoSource") || parameters["videoSource"].String() == "Current") { + GetCurrentVideoSource(&source); + } else { + std::string srcStr = parameters["videoSource"].String(); + if (videoSrcReverseMap.count(srcStr)) { + source = static_cast(videoSrcReverseMap.at(srcStr)); + } else { + LOGERR("Invalid videoSource: %s", srcStr.c_str()); + return false; + } + } + + // Parse videoFormat + if (!parameters.HasLabel("videoFormat") || parameters["videoFormat"].String() == "Current") { + GetCurrentVideoFormat(&format); + if (format == VIDEO_FORMAT_NONE) format = VIDEO_FORMAT_SDR; + } else { + std::string fmtStr = parameters["videoFormat"].String(); + if (videoFormatReverseMap.count(fmtStr)) { + format = static_cast(videoFormatReverseMap.at(fmtStr)); + } else { + LOGERR("Invalid videoFormat: %s", fmtStr.c_str()); + return false; + } + } + + // Directly use TR-181 to fetch active picture mode + std::string tr181_param_name = std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM) + + "." + convertSourceIndexToStringV2(source) + + ".Format." + convertVideoFormatToStringV2(format) + + ".PictureModeString"; + + LOGINFO("TR181 Param Name = %s", tr181_param_name.c_str()); + + TR181_ParamData_t param = {0}; + tr181ErrorCode_t err = getLocalParam(rfc_caller_id, tr181_param_name.c_str(), ¶m); + if (err != tr181Success) { + LOGERR("getLocalParam failed: %d", err); + return false; + } + + outMode = param.value; + LOGINFO("Exit: PictureMode = %s", outMode.c_str()); + return true; + } + uint32_t AVOutputTV::getPictureMode(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); - capDetails_t inputInfo; - paramIndex_t indexInfo; - std::string tr181_param_name; - TR181_ParamData_t param = {0}; - tr181ErrorCode_t err = tr181Success; + std::string pictureModeStr; + if (m_pictureModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + TR181_ParamData_t param = {0}; + + if (parsingGetInputArgument(parameters, "PictureMode", inputInfo) != 0) { + LOGERR("%s: Failed to parse input argument", __FUNCTION__); + returnResponse(false); + } + + if (getParamIndex("PictureMode", inputInfo, indexInfo) == -1) { + LOGERR("%s: getParamIndex failed", __FUNCTION__); + returnResponse(false); + } + + std::string tr181_param_name = std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM) + + "." + convertSourceIndexToString(indexInfo.sourceIndex) + + ".Format." + convertVideoFormatToString(indexInfo.formatIndex) + + ".PictureModeString"; + + tr181ErrorCode_t err = getLocalParam(rfc_caller_id, tr181_param_name.c_str(), ¶m); + if (err != tr181Success) { + returnResponse(false); + } + + pictureModeStr = param.value; + } + else + { + if (!getPictureModeV2(parameters, pictureModeStr)) { + returnResponse(false); + } + } + response["pictureMode"] = pictureModeStr; + LOGINFO("Exit: getPictureMode() : %s", pictureModeStr.c_str()); + returnResponse(true); + } + + bool AVOutputTV::setPictureModeV2(const JsonObject& parameters) + { + LOGINFO("Entry %s", __FUNCTION__); + + if (!parameters.HasLabel("pictureMode")) { + LOGERR("Missing 'pictureMode' in parameters."); + return false; + } + + std::string mode = parameters["pictureMode"].String(); + + // Validate against m_pictureModes + int modeIndex = -1; + for (size_t i = 0; i < m_numPictureModes; ++i) { + auto it = pqModeMap.find(m_pictureModes[i]); + if (it != pqModeMap.end()) { + if (it->second == mode) { + modeIndex = static_cast(i); + LOGINFO("Matched pictureMode '%s' at index %d", mode.c_str(), modeIndex); + break; + } + } else { + LOGERR("pqModeMap does not contain m_pictureModes[%zu] = %d", i, m_pictureModes[i]); + } + } + + if (modeIndex == -1) { + LOGERR("Invalid pictureMode: %s", mode.c_str()); + return false; + } + + // Extract videoSource + std::vector sources; + if (parameters.HasLabel("videoSource")) { + const JsonArray& sourceParam = parameters["videoSource"].Array(); + for (uint32_t i = 0; i < sourceParam.Length(); ++i) { + std::string source = sourceParam[i].Value(); + if (!source.empty()) { + sources.push_back(source); + } + } + } else { + sources.push_back("Global"); + LOGINFO("videoSource not provided, defaulting to 'Global'"); + } + + // Extract videoFormat + std::vector formats; + if (parameters.HasLabel("videoFormat")) { + const JsonArray& formatParam = parameters["videoFormat"].Array(); + for (uint32_t i = 0; i < formatParam.Length(); ++i) { + std::string format = formatParam[i].Value(); + if (!format.empty()) { + formats.push_back(format); + } + } + } else { + formats.push_back("Global"); + LOGINFO("videoFormat not provided, defaulting to 'Global'"); + } + + // Expand 'Global' sources + if (std::find(sources.begin(), sources.end(), "Global") != sources.end()) { + std::unordered_set sourceSet; + for (size_t j = 0; j < m_pictureModeCaps->num_contexts; ++j) { + if (m_pictureModeCaps->contexts[j].pq_mode == m_pictureModes[modeIndex]) { + std::string srcStr = convertSourceIndexToStringV2(m_pictureModeCaps->contexts[j].videoSrcType); + sourceSet.insert(srcStr); + } + } + sources.insert(sources.end(), sourceSet.begin(), sourceSet.end()); + } + + // Expand 'Global' formats + if (std::find(formats.begin(), formats.end(), "Global") != formats.end()) { + std::unordered_set formatSet; + for (size_t j = 0; j < m_pictureModeCaps->num_contexts; ++j) { + if (m_pictureModeCaps->contexts[j].pq_mode == m_pictureModes[modeIndex]) { + std::string fmtStr = convertVideoFormatToStringV2(m_pictureModeCaps->contexts[j].videoFormatType); + formatSet.insert(fmtStr); + } + } + formats.insert(formats.end(), formatSet.begin(), formatSet.end()); + } + + // Get current context + tvVideoSrcType_t currentSrc = VIDEO_SOURCE_IP; + tvVideoFormatType_t currentFmt = VIDEO_FORMAT_SDR; + GetCurrentVideoSource(¤tSrc); + GetCurrentVideoFormat(¤tFmt); + if (currentFmt == VIDEO_FORMAT_NONE) + currentFmt = VIDEO_FORMAT_SDR; + + LOGINFO("Current video source: %s, format: %s", + convertSourceIndexToStringV2(currentSrc).c_str(), + convertVideoFormatToStringV2(currentFmt).c_str()); + + bool contextHandled = false; + + // Iterate through contexts and apply mode + for (size_t i = 0; i < m_pictureModeCaps->num_contexts; ++i) { + const tvConfigContext_t& ctx = m_pictureModeCaps->contexts[i]; + + if (ctx.pq_mode != m_pictureModes[modeIndex]) + continue; + + if (!isValidFormat(formats, ctx.videoFormatType)) + continue; + + if (!isValidSource(sources, ctx.videoSrcType)) + continue; + + std::string srcStr = convertSourceIndexToStringV2(ctx.videoSrcType); + std::string fmtStr = convertVideoFormatToStringV2(ctx.videoFormatType); + + if (ctx.videoSrcType == currentSrc && ctx.videoFormatType == currentFmt) { + if (SetTVPictureMode(mode.c_str()) != tvERROR_NONE) { + LOGERR("SetTVPictureMode failed for mode: %s", mode.c_str()); + return false; + } + } +//TODO:: Revisit this logic. Have to revert if HAL call fails. + std::string tr181Param = std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM) + "." + + srcStr + ".Format." + fmtStr + ".PictureModeString"; + + tr181ErrorCode_t err = setLocalParam(rfc_caller_id, tr181Param.c_str(), mode.c_str()); + if (err != tr181Success) { + LOGERR("setLocalParam failed: %s => %s", tr181Param.c_str(), getTR181ErrorString(err)); + continue; + } + else { + LOGINFO("setLocalParam for %s Successful, Value: %s\n", AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM, mode.c_str()); + int pqmodeindex = (int)getPictureModeIndex(mode); + SaveSourcePictureMode(ctx.videoSrcType, ctx.videoFormatType, pqmodeindex); + } + + contextHandled = true; + } + + if (!contextHandled) { + LOGERR("No valid context found to apply pictureMode: %s", mode.c_str()); + return false; + } + + LOGINFO("Exit %s: PictureMode '%s' applied successfully.", __FUNCTION__, mode.c_str()); + return true; + } + + + uint32_t AVOutputTV::setPictureMode(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry\n"); + if (m_pictureModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + char prevmode[PIC_MODE_NAME_MAX]={0}; + std::string value; + GetTVPictureMode(prevmode); + + tvError_t ret = tvERROR_NONE; + value = parameters.HasLabel("pictureMode") ? parameters["pictureMode"].String() : ""; + returnIfParamNotFound(parameters,"pictureMode"); + + // As only source need to validate, so pqmode and formate passing as currrent + if (parsingSetInputArgument(parameters, "PictureMode",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } + + if (validateInputParameter("PictureMode",value) != 0) { + LOGERR("%s: Range validation failed for PictureMode\n", __FUNCTION__); + returnResponse(false); + } + if( !isCapablityCheckPassed( "PictureMode" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for PictureMode\n", __FUNCTION__); + returnResponse(false); + } + + if( isSetRequired("Current",inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with SetTVPictureMode\n"); + ret = SetTVPictureMode(value.c_str()); + } + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + valueVectors_t values; + inputInfo.pqmode = "Current"; - if (parsingGetInputArgument(parameters, "PictureMode",inputInfo) != 0) { - LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); - returnResponse(false); - } + getSaveConfig("PictureMode" ,inputInfo, values); + + for (int sourceType : values.sourceValues) { + tvVideoSrcType_t source = (tvVideoSrcType_t)sourceType; + for (int formatType : values.formatValues) { + tvVideoFormatType_t format = (tvVideoFormatType_t)formatType; + std::string tr181_param_name = ""; + tr181_param_name += std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); + // framing Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.AVOutput.Source.source_index[x].Format.format_index[x].PictureModeString.value + tr181_param_name += "."+convertSourceIndexToString(source)+"."+"Format."+ + convertVideoFormatToString(format)+"."+"PictureModeString"; + tr181ErrorCode_t err = setLocalParam(rfc_caller_id, tr181_param_name.c_str(), value.c_str()); + if ( err != tr181Success ) { + LOGERR("setLocalParam for %s Failed : %s\n", AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM, getTR181ErrorString(err)); + returnResponse(false); + } + else { + LOGINFO("setLocalParam for %s Successful, Value: %s\n", AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM, value.c_str()); + int pqmodeindex = (int)getPictureModeIndex(value); + SaveSourcePictureMode(source, format, pqmodeindex); + } + } + } - if (getParamIndex("PictureMode",inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); - } + //Filmmaker mode telemetry + if(!strncmp(value.c_str(),"filmmaker",strlen(value.c_str())) && strncmp(prevmode,"filmmaker",strlen(prevmode))) { + LOGINFO("%s mode has been enabled",value.c_str()); + } + else if(!strncmp(prevmode,"filmmaker",strlen(prevmode)) && strncmp(value.c_str(),"filmmaker",strlen(value.c_str()))) { + LOGINFO("%s mode has been disabled",prevmode); + } - tr181_param_name += std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); - tr181_param_name += "." + convertSourceIndexToString(indexInfo.sourceIndex) + "." + "Format."+convertVideoFormatToString(indexInfo.formatIndex)+"."+"PictureModeString"; - err = getLocalParam(rfc_caller_id, tr181_param_name.c_str(), ¶m); + LOGINFO("Broadcasting the low latency change event \n"); - if ( tr181Success != err ) { - returnResponse(false); + if(m_isDalsEnabled) { + //GameModebroadcast + if(!strncmp(value.c_str(),"game",strlen(value.c_str())) && strncmp(prevmode,"game",strlen(prevmode))) { + broadcastLowLatencyModeChangeEvent(1); + } + else if(!strncmp(prevmode,"game",strlen(prevmode)) && strncmp(value.c_str(),"game",strlen(value.c_str()))) { + broadcastLowLatencyModeChangeEvent(0); + } + } + + LOGINFO("Exit : Value : %s \n",value.c_str()); + returnResponse(true); + } } else { - std::string s; - s+=param.value; - response["pictureMode"] = s; - LOGINFO("Exit : getPictureMode() : %s\n",s.c_str()); - returnResponse(true); + bool success = false; + try { + success = setPictureModeV2(parameters); + } catch (const std::exception& e) { + LOGERR("Exception in setPictureModeV2: %s", e.what()); + } catch (...) { + LOGERR("Unknown exception in setPictureModeV2"); + } + returnResponse(success); } } - - uint32_t AVOutputTV::setPictureMode(const JsonObject& parameters, JsonObject& response) + bool AVOutputTV::resetPictureModeV2(const JsonObject& parameters) { - LOGINFO("Entry\n"); - capDetails_t inputInfo; - char prevmode[PIC_MODE_NAME_MAX]={0}; - std::string value; - GetTVPictureMode(prevmode); - - tvError_t ret = tvERROR_NONE; - value = parameters.HasLabel("pictureMode") ? parameters["pictureMode"].String() : ""; - returnIfParamNotFound(parameters,"pictureMode"); + LOGINFO("Entry %s\n", __FUNCTION__); + + auto extractList = [](const JsonObject& params, const std::string& key) -> std::vector { + std::vector result; + if (params.HasLabel(key.c_str())) { + const JsonArray& array = params[key.c_str()].Array(); + for (uint32_t i = 0; i < array.Length(); ++i) { + result.push_back(array[i].Value()); + } + } else { + result.push_back("Global"); + } + return result; + }; - // As only source need to validate, so pqmode and formate passing as currrent - if (parsingSetInputArgument(parameters, "PictureMode",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + std::vector sources = extractList(parameters, "videoSource"); + std::vector formats = extractList(parameters, "videoFormat"); - if (validateInputParameter("PictureMode",value) != 0) { - LOGERR("%s: Range validation failed for PictureMode\n", __FUNCTION__); - returnResponse(false); - } - if( !isCapablityCheckPassed( "PictureMode" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for PictureMode\n", __FUNCTION__); - returnResponse(false); - } + auto expandGlobal = [](std::vector& vec, const std::unordered_set& fullSet) { + if (std::find(vec.begin(), vec.end(), "Global") != vec.end()) { + vec.erase(std::remove(vec.begin(), vec.end(), "Global"), vec.end()); + vec.insert(vec.end(), fullSet.begin(), fullSet.end()); + } + std::unordered_set unique(vec.begin(), vec.end()); + vec.assign(unique.begin(), unique.end()); + }; + + // Expand "Global" values + std::unordered_set allSources, allFormats; + for (size_t j = 0; j < m_pictureModeCaps->num_contexts; ++j) { + allSources.insert(convertSourceIndexToStringV2(m_pictureModeCaps->contexts[j].videoSrcType)); + allFormats.insert(convertVideoFormatToStringV2(m_pictureModeCaps->contexts[j].videoFormatType)); + } + expandGlobal(sources, allSources); + expandGlobal(formats, allFormats); + + // Get current source & format + tvVideoSrcType_t currentSrc = VIDEO_SOURCE_IP; + tvVideoFormatType_t currentFmt = VIDEO_FORMAT_SDR; + GetCurrentVideoSource(¤tSrc); + GetCurrentVideoFormat(¤tFmt); + if (currentFmt == VIDEO_FORMAT_NONE) + currentFmt = VIDEO_FORMAT_SDR; + + bool contextHandled = false; + + for (size_t i = 0; i < m_pictureModeCaps->num_contexts; ++i) { + const tvConfigContext_t& ctx = m_pictureModeCaps->contexts[i]; + + if (!isValidSource(sources, ctx.videoSrcType) || !isValidFormat(formats, ctx.videoFormatType)) + continue; + + std::string tr181Param = std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM) + "." + + convertSourceIndexToStringV2(ctx.videoSrcType) + ".Format." + + convertVideoFormatToStringV2(ctx.videoFormatType) + ".PictureModeString"; + + // Clear override + tr181ErrorCode_t err = clearLocalParam(rfc_caller_id, tr181Param.c_str()); + if (err != tr181Success) { + LOGERR("clearLocalParam failed for %s: %s", tr181Param.c_str(), getTR181ErrorString(err)); + continue; + } - if( isSetRequired("Current",inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with SetTVPictureMode\n"); - ret = SetTVPictureMode(value.c_str()); - } - if(ret != tvERROR_NONE) { - returnResponse(false); - } - else { - valueVectors_t values; - inputInfo.pqmode = "Current"; + // Read saved TR-181 value + TR181_ParamData_t param = {0}; + err = getLocalParam(rfc_caller_id, tr181Param.c_str(), ¶m); + if (err != tr181Success || strlen(param.value) == 0) { + LOGWARN("getLocalParam failed or empty for %s", tr181Param.c_str()); + continue; + } - getSaveConfig("PictureMode" ,inputInfo, values); + // Apply to hardware if current context matches + if (ctx.videoSrcType == currentSrc && ctx.videoFormatType == currentFmt) { - for (int sourceType : values.sourceValues) { - tvVideoSrcType_t source = (tvVideoSrcType_t)sourceType; - for (int formatType : values.formatValues) { - tvVideoFormatType_t format = (tvVideoFormatType_t)formatType; - std::string tr181_param_name = ""; - tr181_param_name += std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); - // framing Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.AVOutput.Source.source_index[x].Format.format_index[x].PictureModeString.value - tr181_param_name += "."+convertSourceIndexToString(source)+"."+"Format."+ - convertVideoFormatToString(format)+"."+"PictureModeString"; - tr181ErrorCode_t err = setLocalParam(rfc_caller_id, tr181_param_name.c_str(), value.c_str()); - if ( err != tr181Success ) { - LOGERR("setLocalParam for %s Failed : %s\n", AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM, getTR181ErrorString(err)); - returnResponse(false); - } - else { - LOGINFO("setLocalParam for %s Successful, Value: %s\n", AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM, value.c_str()); - int pqmodeindex = (int)getPictureModeIndex(value); - SaveSourcePictureMode(source, format, pqmodeindex); - } + tvError_t ret = SetTVPictureMode(param.value); + if (ret != tvERROR_NONE) { + LOGERR("SetTVPictureMode failed for %s", param.value); + continue; } } - //Filmmaker mode telemetry - if(!strncmp(value.c_str(),"filmmaker",strlen(value.c_str())) && strncmp(prevmode,"filmmaker",strlen(prevmode))) { - LOGINFO("%s mode has been enabled",value.c_str()); - } - else if(!strncmp(prevmode,"filmmaker",strlen(prevmode)) && strncmp(value.c_str(),"filmmaker",strlen(value.c_str()))) { - LOGINFO("%s mode has been disabled",prevmode); - } - - LOGINFO("Broadcasting the low latency change event \n"); - - if(m_isDalsEnabled) { - //GameModebroadcast - if(!strncmp(value.c_str(),"game",strlen(value.c_str())) && strncmp(prevmode,"game",strlen(prevmode))) { - broadcastLowLatencyModeChangeEvent(1); - } - else if(!strncmp(prevmode,"game",strlen(prevmode)) && strncmp(value.c_str(),"game",strlen(value.c_str()))) { - broadcastLowLatencyModeChangeEvent(0); - } - } + // Save to internal config + int pqmodeIndex = static_cast(getPictureModeIndex(param.value)); + SaveSourcePictureMode(ctx.videoSrcType, ctx.videoFormatType, pqmodeIndex); + contextHandled = true; + } - LOGINFO("Exit : Value : %s \n",value.c_str()); - returnResponse(true); + if (!contextHandled) { + LOGERR("No valid pictureMode context matched to reset.\n"); + return false; } + + LOGINFO("resetPictureModeV2: Exit - PictureMode reset successfully.\n"); + return true; } uint32_t AVOutputTV::resetPictureMode(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); - tr181ErrorCode_t err = tr181Success; - TR181_ParamData_t param = {0}; + if (m_pictureModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + tr181ErrorCode_t err = tr181Success; + TR181_ParamData_t param = {0}; - valueVectors_t values; - capDetails_t inputInfo; + valueVectors_t values; + capDetails_t inputInfo; - // As only source need to validate, so pqmode and formate passing as currrent - if (parsingSetInputArgument(parameters, "PictureMode",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + // As only source need to validate, so pqmode and formate passing as currrent + if (parsingSetInputArgument(parameters, "PictureMode",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "PictureMode",inputInfo )) { - LOGERR("%s: CapablityCheck failed for PictureMode\n", __FUNCTION__); - returnResponse(false); - } - inputInfo.pqmode = "Current"; - getSaveConfig("PictureMode", inputInfo, values); + if( !isCapablityCheckPassed( "PictureMode",inputInfo )) { + LOGERR("%s: CapablityCheck failed for PictureMode\n", __FUNCTION__); + returnResponse(false); + } + inputInfo.pqmode = "Current"; + getSaveConfig("PictureMode", inputInfo, values); - for (int source : values.sourceValues) { - tvVideoSrcType_t sourceType = (tvVideoSrcType_t)source; - for (int format : values.formatValues) { - tvVideoFormatType_t formatType = (tvVideoFormatType_t)format; - std::string tr181_param_name = ""; - tr181_param_name += std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); - tr181_param_name += "."+convertSourceIndexToString(sourceType)+"."+"Format."+ - convertVideoFormatToString(formatType)+"."+"PictureModeString"; + for (int source : values.sourceValues) { + tvVideoSrcType_t sourceType = (tvVideoSrcType_t)source; + for (int format : values.formatValues) { + tvVideoFormatType_t formatType = (tvVideoFormatType_t)format; + std::string tr181_param_name = ""; + tr181_param_name += std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); + tr181_param_name += "."+convertSourceIndexToString(sourceType)+"."+"Format."+ + convertVideoFormatToString(formatType)+"."+"PictureModeString"; - err = clearLocalParam(rfc_caller_id, tr181_param_name.c_str()); - if ( err != tr181Success ) { - LOGWARN("clearLocalParam for %s Failed : %s\n", tr181_param_name.c_str(), getTR181ErrorString(err)); - returnResponse(false); - } - else { - err = getLocalParam(rfc_caller_id, tr181_param_name.c_str(), ¶m); - if ( tr181Success == err ) { - //get curren source and if matches save for that alone - tvVideoSrcType_t current_source = VIDEO_SOURCE_IP; - GetCurrentVideoSource(¤t_source); - - tvVideoFormatType_t current_format = VIDEO_FORMAT_NONE; - GetCurrentVideoFormat(¤t_format); - if( current_format == VIDEO_FORMAT_NONE) { - current_format = VIDEO_FORMAT_SDR; - } + err = clearLocalParam(rfc_caller_id, tr181_param_name.c_str()); + if ( err != tr181Success ) { + LOGWARN("clearLocalParam for %s Failed : %s\n", tr181_param_name.c_str(), getTR181ErrorString(err)); + returnResponse(false); + } + else { + err = getLocalParam(rfc_caller_id, tr181_param_name.c_str(), ¶m); + if ( tr181Success == err ) { + //get curren source and if matches save for that alone + tvVideoSrcType_t current_source = VIDEO_SOURCE_IP; + GetCurrentVideoSource(¤t_source); + + tvVideoFormatType_t current_format = VIDEO_FORMAT_NONE; + GetCurrentVideoFormat(¤t_format); + if( current_format == VIDEO_FORMAT_NONE) { + current_format = VIDEO_FORMAT_SDR; + } - if (current_source == sourceType && current_format == formatType) { + if (current_source == sourceType && current_format == formatType) { - tvError_t ret = SetTVPictureMode(param.value); - if(ret != tvERROR_NONE) { - LOGWARN("Picture Mode set failed: %s\n",getErrorString(ret).c_str()); - returnResponse(false); - } - else { - LOGINFO("Exit : Picture Mode reset successfully, value: %s\n", param.value); + tvError_t ret = SetTVPictureMode(param.value); + if(ret != tvERROR_NONE) { + LOGWARN("Picture Mode set failed: %s\n",getErrorString(ret).c_str()); + returnResponse(false); + } + else { + LOGINFO("Exit : Picture Mode reset successfully, value: %s\n", param.value); + } } + int pqmodeindex = (int)getPictureModeIndex(param.value); + SaveSourcePictureMode(sourceType, formatType, pqmodeindex); + } + else { + LOGWARN("getLocalParam for %s failed\n", AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); + returnResponse(false); } - int pqmodeindex = (int)getPictureModeIndex(param.value); - SaveSourcePictureMode(sourceType, formatType, pqmodeindex); - } - else { - LOGWARN("getLocalParam for %s failed\n", AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); - returnResponse(false); } } } + returnResponse(true); + } + else + { + bool success = resetPictureModeV2(parameters); + returnResponse(success); } - returnResponse(true) } uint32_t AVOutputTV::signalFilmMakerMode(const JsonObject& parameters, JsonObject& response) @@ -2793,87 +4615,148 @@ namespace Plugin { uint32_t AVOutputTV::setLowLatencyState(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_lowLatencyStateStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + std::string value; + capDetails_t inputInfo; + int lowLatencyIndex = 0,prevLowLatencyIndex = 0; + tvError_t ret = tvERROR_NONE; - std::string value; - capDetails_t inputInfo; - int lowLatencyIndex = 0,prevLowLatencyIndex = 0; - tvError_t ret = tvERROR_NONE; + ret = GetLowLatencyState(&prevLowLatencyIndex); + if(ret != tvERROR_NONE) { + LOGERR("Get previous low latency state failed\n"); + returnResponse(false); + } - ret = GetLowLatencyState(&prevLowLatencyIndex); - if(ret != tvERROR_NONE) { - LOGERR("Get previous low latency state failed\n"); - returnResponse(false); - } + value = parameters.HasLabel("LowLatencyState") ? parameters["LowLatencyState"].String() : ""; + returnIfParamNotFound(parameters,"LowLatencyState"); + lowLatencyIndex = std::stoi(value); - value = parameters.HasLabel("LowLatencyState") ? parameters["LowLatencyState"].String() : ""; - returnIfParamNotFound(parameters,"LowLatencyState"); - lowLatencyIndex = std::stoi(value); + if (validateIntegerInputParameter("LowLatencyState",lowLatencyIndex) != 0) { + LOGERR("Failed in Brightness range validation:%s", __FUNCTION__); + returnResponse(false); + } - if (validateIntegerInputParameter("LowLatencyState",lowLatencyIndex) != 0) { - LOGERR("Failed in Brightness range validation:%s", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "LowLatencyState",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if (parsingSetInputArgument(parameters, "LowLatencyState",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "LowLatencyState" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for LowLatencyState\n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "LowLatencyState" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for LowLatencyState\n", __FUNCTION__); - returnResponse(false); - } + int retval= updateAVoutputTVParam("set","LowLatencyState",inputInfo,PQ_PARAM_LOWLATENCY_STATE,lowLatencyIndex); + if(retval != 0 ) { + LOGERR("Failed to SaveLowLatency to ssm_data\n"); + returnResponse(false); + } else { - int retval= updateAVoutputTVParam("set","LowLatencyState",inputInfo,PQ_PARAM_LOWLATENCY_STATE,lowLatencyIndex); - if(retval != 0 ) { - LOGERR("Failed to SaveLowLatency to ssm_data\n"); - returnResponse(false); - } else { + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with setLowLatencyState\n"); + ret = SetLowLatencyState( lowLatencyIndex ); + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with setLowLatencyState\n"); - ret = SetLowLatencyState( lowLatencyIndex ); + if(ret != tvERROR_NONE) { + LOGERR("Failed to set low latency. Fallback to previous state %d\n", prevLowLatencyIndex); + retval=updateAVoutputTVParam("set","LowLatencyState",inputInfo,PQ_PARAM_LOWLATENCY_STATE,prevLowLatencyIndex); + if(retval != 0 ){ + LOGERR("Fallback to previous low latency state %d failed.\n", prevLowLatencyIndex); + } + returnResponse(false); + } + + LOGINFO("Exit : setLowLatency successful to value: %d\n", lowLatencyIndex); + returnResponse(true); } + } + else + { + std::string value; + int lowLatencyIndex = 0,prevLowLatencyIndex = 0; + tvError_t ret = tvERROR_NONE; + ret = GetLowLatencyState(&prevLowLatencyIndex); if(ret != tvERROR_NONE) { - LOGERR("Failed to set low latency. Fallback to previous state %d\n", prevLowLatencyIndex); - retval=updateAVoutputTVParam("set","LowLatencyState",inputInfo,PQ_PARAM_LOWLATENCY_STATE,prevLowLatencyIndex); - if(retval != 0 ){ - LOGERR("Fallback to previous low latency state %d failed.\n", prevLowLatencyIndex); - } + LOGERR("Get previous low latency state failed\n"); returnResponse(false); } - LOGINFO("Exit : setLowLatency successful to value: %d\n", lowLatencyIndex); - returnResponse(true); + value = parameters.HasLabel("LowLatencyState") ? parameters["LowLatencyState"].String() : ""; + returnIfParamNotFound(parameters,"LowLatencyState"); + lowLatencyIndex = std::stoi(value); + if (lowLatencyIndex < 0 || lowLatencyIndex > m_maxlowLatencyState) { + LOGERR("Input value %d is out of range (0 - %d) for LowLatencyState", lowLatencyIndex, m_maxlowLatencyState); + returnResponse(false); + } + + int retval= updateAVoutputTVParamV2("set","LowLatencyState",parameters,PQ_PARAM_LOWLATENCY_STATE,lowLatencyIndex); + if(retval != 0 ) { + LOGERR("Failed to SaveLowLatency to ssm_data\n"); + returnResponse(false); + } + else + { + if(isSetRequiredForParam(parameters, "LowLatencyState")) + { + LOGINFO("Proceed with setLowLatencyState\n"); + ret = SetLowLatencyState( lowLatencyIndex ); + } + if(ret != tvERROR_NONE) { + LOGERR("Failed to set low latency. Fallback to previous state %d\n", prevLowLatencyIndex); + retval=updateAVoutputTVParamV2("set","LowLatencyState",parameters,PQ_PARAM_LOWLATENCY_STATE, prevLowLatencyIndex); + if(retval != 0 ){ + LOGERR("Fallback to previous low latency state %d failed.\n", prevLowLatencyIndex); + } + returnResponse(false); + } + + LOGINFO("Exit : setLowLatency successful to value: %d\n", lowLatencyIndex); + returnResponse(true); + } } } uint32_t AVOutputTV::getLowLatencyState(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry"); + if(m_lowLatencyStateStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int lowlatencystate = 0; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int lowlatencystate = 0; - - if (parsingGetInputArgument(parameters, "LowLatencyState",inputInfo) != 0) { - LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); - returnResponse(false); - } - if (getParamIndex("LowLatencyState",inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); - } + if (parsingGetInputArgument(parameters, "LowLatencyState",inputInfo) != 0) { + LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); + returnResponse(false); + } + if (getParamIndex("LowLatencyState",inputInfo,indexInfo) == -1) { + LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); + returnResponse(false); + } - int err = getLocalparam("LowLatencyState", indexInfo ,lowlatencystate, PQ_PARAM_LOWLATENCY_STATE); - if( err == 0 ) { - response["lowLatencyState"] = std::to_string(lowlatencystate); - LOGINFO("Exit : LowLatencyState Value: %d \n", lowlatencystate); - returnResponse(true); + int err = getLocalparam("LowLatencyState", indexInfo ,lowlatencystate, PQ_PARAM_LOWLATENCY_STATE); + if( err == 0 ) { + response["lowLatencyState"] = std::to_string(lowlatencystate); + LOGINFO("Exit : LowLatencyState Value: %d \n", lowlatencystate); + returnResponse(true); + } + else { + returnResponse(false); + } } - else { - returnResponse(false); + else + { + int lowlatencystate = 0; + if (getPQParamFromContext(parameters, "LowLatencyState", PQ_PARAM_LOWLATENCY_STATE, lowlatencystate)) { + response["lowLatencyState"] = std::to_string(lowlatencystate); + LOGINFO("Exit : LowLatencyState Value: %d", lowlatencystate); + returnResponse(true); + } else { + LOGERR("Failed to get LowLatencyState"); + returnResponse(false); + } } } @@ -2977,245 +4860,377 @@ namespace Plugin { uint32_t AVOutputTV::getCMS(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry"); + if(m_cmsStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int level = 0; + tvPQParameterIndex_t tvPQEnum; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int level = 0; - tvPQParameterIndex_t tvPQEnum; + inputInfo.color = parameters.HasLabel("color") ? parameters["color"].String() : ""; + inputInfo.component = parameters.HasLabel("component") ? parameters["component"].String() : ""; - inputInfo.color = parameters.HasLabel("color") ? parameters["color"].String() : ""; - inputInfo.component = parameters.HasLabel("component") ? parameters["component"].String() : ""; - - if( inputInfo.color.empty() || inputInfo.component.empty() ) { - LOGERR("%s : Color/Component param not found!!!\n",__FUNCTION__); - returnResponse(false); - } + if( inputInfo.color.empty() || inputInfo.component.empty() ) { + LOGERR("%s : Color/Component param not found!!!\n",__FUNCTION__); + returnResponse(false); + } - if (isPlatformSupport("CMS") != 0) { - returnResponse(false); - } + if (isPlatformSupport("CMS") != 0) { + returnResponse(false); + } - if (parsingGetInputArgument(parameters, "CMS", inputInfo) != 0) { - LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); - returnResponse(false); - } + if (parsingGetInputArgument(parameters, "CMS", inputInfo) != 0) { + LOGINFO("%s: Failed to parse argument\n", __FUNCTION__); + returnResponse(false); + } - if (getParamIndex("CMS",inputInfo,indexInfo) == -1) { - LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); - returnResponse(false); - } + if (getParamIndex("CMS",inputInfo,indexInfo) == -1) { + LOGERR("%s: getParamIndex failed to get \n", __FUNCTION__); + returnResponse(false); + } - if ( convertCMSParamToPQEnum(inputInfo.component,inputInfo.color,tvPQEnum) != 0 ) { - LOGINFO("%s: Component/Color Param Not Found \n",__FUNCTION__); - returnResponse(false); - } + if ( convertCMSParamToPQEnum(inputInfo.component,inputInfo.color,tvPQEnum) != 0 ) { + LOGINFO("%s: Component/Color Param Not Found \n",__FUNCTION__); + returnResponse(false); + } - int err = getLocalparam("CMS",indexInfo,level,tvPQEnum); - if( err == 0 ) { - response["level"] = level; - LOGINFO("Exit : params Value: %d \n", level); - returnResponse(true); + int err = getLocalparam("CMS",indexInfo,level,tvPQEnum); + if( err == 0 ) { + response["level"] = level; + LOGINFO("Exit : params Value: %d \n", level); + returnResponse(true); + } + else { + returnResponse(false); + } } - else { - returnResponse(false); + else + { + // Extract color and component from input parameters + std::string color = parameters.HasLabel("color") ? parameters["color"].String() : ""; + std::string component = parameters.HasLabel("component") ? parameters["component"].String() : ""; + + if (color.empty() || component.empty()) { + LOGERR("%s: Missing color/component parameter", __FUNCTION__); + returnResponse(false); + } + + tvPQParameterIndex_t pqEnum; + if (convertCMSParamToPQEnum(component, color, pqEnum) != 0) { + LOGERR("%s: Invalid color/component combination", __FUNCTION__); + returnResponse(false); + } + + // Get valid context from parameters using your existing context helper + tvConfigContext_t validContext = getValidContextFromGetParameters(parameters, "CMS"); + + if ((validContext.videoSrcType == VIDEO_SOURCE_ALL && + validContext.videoFormatType == VIDEO_FORMAT_NONE && + validContext.pq_mode == PQ_MODE_INVALID)) + { + LOGERR("No valid context found for CMS get"); + returnResponse(false); + } + + // Prepare paramIndex from context + paramIndex_t indexInfo = { + .sourceIndex = static_cast(validContext.videoSrcType), + .pqmodeIndex = static_cast(validContext.pq_mode), + .formatIndex = static_cast(validContext.videoFormatType) + }; + + int level = 0; + int err = getLocalparam("CMS", indexInfo, level, pqEnum); + if (err == 0) { + response["level"] = level; + LOGINFO("Exit: getCMS success, value: %d", level); + returnResponse(true); + } else { + LOGERR("Failed to get CMS param from local storage"); + returnResponse(false); + } } } uint32_t AVOutputTV::setCMS(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_cmsStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + int level = 0,retVal = 0; + tvPQParameterIndex_t tvPQEnum; + tvDataComponentColor_t colorEnum=tvDataColor_NONE; + std::string color,component; + tvError_t ret = tvERROR_NONE; + std::string value; + + inputInfo.color = parameters.HasLabel("color") ? parameters["color"].String() : ""; + inputInfo.component = parameters.HasLabel("component") ? parameters["component"].String() : ""; + if( inputInfo.color.empty() || inputInfo.component.empty() ) { + LOGERR("%s : Color/Component param not found!!!\n",__FUNCTION__); + returnResponse(false); + } - capDetails_t inputInfo; - int level = 0,retVal = 0; - tvPQParameterIndex_t tvPQEnum; - tvDataComponentColor_t colorEnum=tvDataColor_NONE; - std::string color,component; - tvError_t ret = tvERROR_NONE; - std::string value; - - inputInfo.color = parameters.HasLabel("color") ? parameters["color"].String() : ""; - inputInfo.component = parameters.HasLabel("component") ? parameters["component"].String() : ""; + if (isPlatformSupport("CMS") != 0) { + returnResponse(false); + } - if( inputInfo.color.empty() || inputInfo.component.empty() ) { - LOGERR("%s : Color/Component param not found!!!\n",__FUNCTION__); - returnResponse(false); - } + value = parameters.HasLabel("level") ? parameters["level"].String() : ""; + returnIfParamNotFound(parameters,"level"); + level = std::stoi(value); - if (isPlatformSupport("CMS") != 0) { - returnResponse(false); - } + if (validateCMSParameter(inputInfo.component,level) != 0) { + LOGERR("%s: CMS Failed in range validation", __FUNCTION__); + returnResponse(false); + } - value = parameters.HasLabel("level") ? parameters["level"].String() : ""; - returnIfParamNotFound(parameters,"level"); - level = std::stoi(value); + if (parsingSetInputArgument(parameters,"CMS",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if (validateCMSParameter(inputInfo.component,level) != 0) { - LOGERR("%s: CMS Failed in range validation", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "CMS",inputInfo )) { + LOGERR("%s: CapablityCheck failed for CMS\n", __FUNCTION__); + returnResponse(false); + } - if (parsingSetInputArgument(parameters,"CMS",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if ( convertCMSParamToPQEnum(inputInfo.component,inputInfo.color,tvPQEnum) != 0 ) { + LOGERR("%s: %s/%s Param Not Found \n",__FUNCTION__,inputInfo.component.c_str(),inputInfo.color.c_str()); + returnResponse(false); + } - if( !isCapablityCheckPassed( "CMS",inputInfo )) { - LOGERR("%s: CapablityCheck failed for CMS\n", __FUNCTION__); - returnResponse(false); - } + retVal = getCMSColorEnumFromString(inputInfo.color,colorEnum); + if( retVal == -1) { + LOGERR("%s: Invalid Color : %s\n",__FUNCTION__,inputInfo.color.c_str()); + returnResponse(false); + } - if ( convertCMSParamToPQEnum(inputInfo.component,inputInfo.color,tvPQEnum) != 0 ) { - LOGERR("%s: %s/%s Param Not Found \n",__FUNCTION__,inputInfo.component.c_str(),inputInfo.color.c_str()); - returnResponse(false); - } + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with %s\n",__FUNCTION__); + tvError_t ret = SetCMSState(true); + if(ret != tvERROR_NONE) { + LOGWARN("CMS enable failed\n"); + returnResponse(false); + } - retVal = getCMSColorEnumFromString(inputInfo.color,colorEnum); - if( retVal == -1) { - LOGERR("%s: Invalid Color : %s\n",__FUNCTION__,inputInfo.color.c_str()); - returnResponse(false); - } + if(inputInfo.component.compare("Saturation") == 0) + ret = SetCurrentComponentSaturation(colorEnum, level); + else if(inputInfo.component.compare("Hue") == 0 ) + ret = SetCurrentComponentHue(colorEnum,level); + else if( inputInfo.component.compare("Luma") == 0 ) + ret = SetCurrentComponentLuma(colorEnum,level); + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with %s\n",__FUNCTION__); - tvError_t ret = SetCMSState(true); if(ret != tvERROR_NONE) { - LOGWARN("CMS enable failed\n"); + LOGERR("Failed to set CMS\n"); returnResponse(false); } - - if(inputInfo.component.compare("Saturation") == 0) - ret = SetCurrentComponentSaturation(colorEnum, level); - else if(inputInfo.component.compare("Hue") == 0 ) - ret = SetCurrentComponentHue(colorEnum,level); - else if( inputInfo.component.compare("Luma") == 0 ) - ret = SetCurrentComponentLuma(colorEnum,level); - - } + else { + std::string cmsParam; + cmsParam = inputInfo.color+"."+inputInfo.component; - if(ret != tvERROR_NONE) { - LOGERR("Failed to set CMS\n"); - returnResponse(false); + retVal= updateAVoutputTVParam("set","CMS",inputInfo,tvPQEnum,level); + if(retVal != 0 ) { + LOGERR("%s : Failed to Save CMS %s/%s(%s) to ssm_data\n",__FUNCTION__,inputInfo.component.c_str(),inputInfo.color.c_str(),cmsParam.c_str()); + returnResponse(false); + } + LOGINFO("Exit : setCMS %s/%s successful to value: %d\n", inputInfo.component.c_str(),inputInfo.color.c_str(),level); + returnResponse(true); + } } - else { - std::string cmsParam; - cmsParam = inputInfo.color+"."+inputInfo.component; - - retVal= updateAVoutputTVParam("set","CMS",inputInfo,tvPQEnum,level); - if(retVal != 0 ) { - LOGERR("%s : Failed to Save CMS %s/%s(%s) to ssm_data\n",__FUNCTION__,inputInfo.component.c_str(),inputInfo.color.c_str(),cmsParam.c_str()); + else + { + bool status = setCMSParam(parameters); + if (status) { + LOGINFO("setCMS success"); + returnResponse(true); + } else { + LOGERR("setCMS failed"); returnResponse(false); } - LOGINFO("Exit : setCMS %s/%s successful to value: %d\n", inputInfo.component.c_str(),inputInfo.color.c_str(),level); - returnResponse(true); } } uint32_t AVOutputTV::resetCMS(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_cmsStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + int retVal = 0; + std::string color,component; + tvError_t ret = tvERROR_NONE; + JsonArray sourceArray; + JsonArray pqmodeArray; + JsonArray formatArray; + JsonArray colorArray; + JsonArray componentArray; + + if (isPlatformSupport("CMS") != 0) { + returnResponse(false); + } - capDetails_t inputInfo; - int retVal = 0; - std::string color,component; - tvError_t ret = tvERROR_NONE; - JsonArray sourceArray; - JsonArray pqmodeArray; - JsonArray formatArray; - JsonArray colorArray; - JsonArray componentArray; - - if (isPlatformSupport("CMS") != 0) { - returnResponse(false); - } - - pqmodeArray = parameters.HasLabel("pictureMode") ? parameters["pictureMode"].Array() : JsonArray(); - for (int i = 0; i < pqmodeArray.Length(); ++i) { - inputInfo.pqmode += pqmodeArray[i].String(); - if (i != (pqmodeArray.Length() - 1) ) { - inputInfo.pqmode += ","; + pqmodeArray = parameters.HasLabel("pictureMode") ? parameters["pictureMode"].Array() : JsonArray(); + for (int i = 0; i < pqmodeArray.Length(); ++i) { + inputInfo.pqmode += pqmodeArray[i].String(); + if (i != (pqmodeArray.Length() - 1) ) { + inputInfo.pqmode += ","; + } } - } - sourceArray = parameters.HasLabel("videoSource") ? parameters["videoSource"].Array() : JsonArray(); - for (int i = 0; i < sourceArray.Length(); ++i) { - inputInfo.source += sourceArray[i].String(); - if (i != (sourceArray.Length() - 1) ) { - inputInfo.source += ","; - } - } + sourceArray = parameters.HasLabel("videoSource") ? parameters["videoSource"].Array() : JsonArray(); + for (int i = 0; i < sourceArray.Length(); ++i) { + inputInfo.source += sourceArray[i].String(); + if (i != (sourceArray.Length() - 1) ) { + inputInfo.source += ","; + } + } - formatArray = parameters.HasLabel("videoFormat") ? parameters["videoFormat"].Array() : JsonArray(); - for (int i = 0; i < formatArray.Length(); ++i) { - inputInfo.format += formatArray[i].String(); - if (i != (formatArray.Length() - 1) ) { - inputInfo.format += ","; + formatArray = parameters.HasLabel("videoFormat") ? parameters["videoFormat"].Array() : JsonArray(); + for (int i = 0; i < formatArray.Length(); ++i) { + inputInfo.format += formatArray[i].String(); + if (i != (formatArray.Length() - 1) ) { + inputInfo.format += ","; + } } - } - colorArray = parameters.HasLabel("color") ? parameters["color"].Array() : JsonArray(); - for (int i = 0; i < colorArray.Length(); ++i) { - inputInfo.color += colorArray[i].String(); - if (i != (colorArray.Length() - 1) ) { - inputInfo.color += ","; + colorArray = parameters.HasLabel("color") ? parameters["color"].Array() : JsonArray(); + for (int i = 0; i < colorArray.Length(); ++i) { + inputInfo.color += colorArray[i].String(); + if (i != (colorArray.Length() - 1) ) { + inputInfo.color += ","; + } } - } - componentArray = parameters.HasLabel("component") ? parameters["component"].Array() : JsonArray(); - for (int i = 0; i < componentArray.Length(); ++i) { - inputInfo.component += componentArray[i].String(); - if (i != (componentArray.Length() - 1) ) { - inputInfo.component += ","; + componentArray = parameters.HasLabel("component") ? parameters["component"].Array() : JsonArray(); + for (int i = 0; i < componentArray.Length(); ++i) { + inputInfo.component += componentArray[i].String(); + if (i != (componentArray.Length() - 1) ) { + inputInfo.component += ","; + } + } + if (inputInfo.source.empty()) { + inputInfo.source = "Global"; + } + if (inputInfo.pqmode.empty()) { + inputInfo.pqmode = "Global"; + } + if (inputInfo.format.empty()) { + inputInfo.format = "Global"; + } + if (inputInfo.color.empty()) { + inputInfo.color = "Global"; + } + if (inputInfo.component.empty()) { + inputInfo.component = "Global"; } - } - if (inputInfo.source.empty()) { - inputInfo.source = "Global"; - } - if (inputInfo.pqmode.empty()) { - inputInfo.pqmode = "Global"; - } - if (inputInfo.format.empty()) { - inputInfo.format = "Global"; - } - if (inputInfo.color.empty()) { - inputInfo.color = "Global"; - } - if (inputInfo.component.empty()) { - inputInfo.component = "Global"; - } - if (convertToValidInputParameter("CMS", inputInfo) != 0) { - LOGERR("%s: Failed to convert the input paramters. \n", __FUNCTION__); - returnResponse(false); - } + if (convertToValidInputParameter("CMS", inputInfo) != 0) { + LOGERR("%s: Failed to convert the input paramters. \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "CMS" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for CMS\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "CMS" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for CMS\n", __FUNCTION__); + returnResponse(false); + } + + if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { + LOGINFO("Proceed with %s\n",__FUNCTION__); + tvError_t ret = SetCMSState(false); + if(ret != tvERROR_NONE) { + LOGWARN("CMS disable failed\n"); + returnResponse(false); + } + } - if( isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format) ) { - LOGINFO("Proceed with %s\n",__FUNCTION__); - tvError_t ret = SetCMSState(false); if(ret != tvERROR_NONE) { - LOGWARN("CMS disable failed\n"); + LOGERR("%s : Failed to setCMSState\n",__FUNCTION__); returnResponse(false); - } - } - - if(ret != tvERROR_NONE) { - LOGERR("%s : Failed to setCMSState\n",__FUNCTION__); - returnResponse(false); + } + else { + int cms = 0; + retVal= updateAVoutputTVParam("reset","CMS",inputInfo,PQ_PARAM_CMS_SATURATION_RED,cms); + if(retVal != 0 ) { + LOGERR("%s : Failed to Save CMS %s/%s to ssm_data\n",__FUNCTION__,inputInfo.component.c_str(),inputInfo.color.c_str() ); + returnResponse(false); + } + returnResponse(true); + } } - else { + else + { + if (isSetRequiredForParam(parameters, "CMS")) { + LOGINFO("Proceed with SetCMSState \n"); + tvError_t ret = SetCMSState(false); + if(ret != tvERROR_NONE) { + LOGWARN("CMS disable failed\n"); + returnResponse(false); + } + } int cms = 0; - retVal= updateAVoutputTVParam("reset","CMS",inputInfo,PQ_PARAM_CMS_SATURATION_RED,cms); + int retVal= updateAVoutputTVParamV2("reset","CMS",parameters,PQ_PARAM_CMS,cms); if(retVal != 0 ) { - LOGERR("%s : Failed to Save CMS %s/%s to ssm_data\n",__FUNCTION__,inputInfo.component.c_str(),inputInfo.color.c_str() ); + LOGERR("%s : Failed to Save CMS to ssm_data\n",__FUNCTION__); returnResponse(false); } returnResponse(true); } } + uint32_t AVOutputTV::getCMSCapsV2(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry: getCMSCapsV2"); + + int max_hue = 0, max_saturation = 0, max_luma = 0; + tvDataComponentColor_t* colorArray = nullptr; + tvComponentType_t* componentArray = nullptr; + size_t num_color = 0, num_component = 0; + tvContextCaps_t* context_caps = nullptr; + + tvError_t ret = GetCMSCaps(&max_hue, &max_saturation, &max_luma, + &colorArray, &componentArray, + &num_color, &num_component, &context_caps); + + if (ret != tvERROR_NONE) { + LOGERR("GetCMSCaps failed with error: %d", ret); + response["platformSupport"] = false; + returnResponse(false); + } + response["platformSupport"] = true; + + // Range Info + JsonObject rangeHue, rangeSaturation, rangeLuma; + rangeHue["from"] = 0; + rangeHue["to"] = max_hue; + rangeSaturation["from"] = 0; + rangeSaturation["to"] = max_saturation; + rangeLuma["from"] = 0; + rangeLuma["to"] = max_luma; + + response["rangeHue"] = rangeHue; + response["rangeSaturation"] = rangeSaturation; + response["rangeLuma"] = rangeLuma; + + // Color Info + JsonArray colorJson; + for (size_t i = 0; i < num_color; ++i) { + colorJson.Add(getCMSColorStringFromEnum(colorArray[i])); + } + response["color"] = colorJson; + + // Component Info + JsonArray componentJson; + for (size_t i = 0; i < num_component; ++i) { + componentJson.Add(getCMSComponentStringFromEnum(componentArray[i])); + } + response["component"] = componentJson; + response["context"] = parseContextCaps(context_caps); + + LOGINFO("Exit: getCMSCapsV2"); + returnResponse(true); + } + uint32_t AVOutputTV::getCMSCaps(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry"); @@ -3334,7 +5349,7 @@ namespace Plugin { capDetails_t inputInfo; tvError_t ret = tvERROR_NONE; std::string value; - int retval = 0; + int retval = 0; value = parameters.HasLabel("HDRMode") ? parameters["HDRMode"].String() : ""; returnIfParamNotFound(parameters,"HDRMode"); @@ -3670,6 +5685,59 @@ namespace Plugin { } } + uint32_t AVOutputTV::get2PointWBCapsV2(const JsonObject& parameters, JsonObject& response) + { + LOGINFO("Entry: get2PointWBCapsV2"); + + int min_gain = 0, min_offset = 0, max_gain = 0, max_offset = 0; + tvWBColor_t* colorArray = nullptr; + tvWBControl_t* controlArray = nullptr; + size_t num_color = 0, num_control = 0; + tvContextCaps_t* context_caps = nullptr; + + tvError_t ret = GetCustom2PointWhiteBalanceCaps(&min_gain, &min_offset, &max_gain, &max_offset, + &colorArray, &controlArray, + &num_color, &num_control, &context_caps); + + if (ret != tvERROR_NONE) { + LOGERR("GetCustom2PointWhiteBalanceCaps failed with error: %d", ret); + response["platformSupport"] = false; + returnResponse(false); + } + + response["platformSupport"] = true; + + // Range Info + JsonObject rangeGain, rangeOffset; + rangeGain["from"] = min_gain; + rangeGain["to"] = max_gain; + rangeOffset["from"] = min_offset; + rangeOffset["to"] = max_offset; + + response["rangeGain"] = rangeGain; + response["rangeOffset"] = rangeOffset; + + // Control Info + JsonArray controlJson; + for (size_t i = 0; i < num_control; ++i) { + controlJson.Add(getWBControlStringFromEnum(controlArray[i])); + } + response["control"] = controlJson; + + // Color Info + JsonArray colorJson; + for (size_t i = 0; i < num_color; ++i) { + colorJson.Add(getWBColorStringFromEnum(colorArray[i])); + } + response["color"] = colorJson; + response["context"] = parseContextCaps(context_caps); + + + LOGINFO("Exit: get2PointWBCapsV2"); + returnResponse(true); + } + + uint32_t AVOutputTV::get2PointWBCaps(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); @@ -3796,83 +5864,113 @@ namespace Plugin { uint32_t AVOutputTV::setAutoBacklightMode(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); - std::string value; - tvBacklightMode_t mode = tvBacklightMode_AMBIENT; - capDetails_t inputInfo; - + if(m_backlightModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + std::string value; + tvBacklightMode_t mode = tvBacklightMode_AMBIENT; + capDetails_t inputInfo; - value = parameters.HasLabel("mode") ? parameters["mode"].String() : ""; - returnIfParamNotFound(parameters,"mode"); + value = parameters.HasLabel("mode") ? parameters["mode"].String() : ""; + returnIfParamNotFound(parameters,"mode"); - if (validateInputParameter("AutoBacklightMode",value) != 0) { - LOGERR("%s: Range validation failed for AutoBacklightMode\n", __FUNCTION__); - returnResponse(false); - } + if (validateInputParameter("AutoBacklightMode",value) != 0) { + LOGERR("%s: Range validation failed for AutoBacklightMode\n", __FUNCTION__); + returnResponse(false); + } - if (isPlatformSupport("AutoBacklightMode") != 0) { - returnResponse(false); - } + if (isPlatformSupport("AutoBacklightMode") != 0) { + returnResponse(false); + } - if (parsingSetInputArgument(parameters,"AutoBacklightMode",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters,"AutoBacklightMode",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "AutoBacklightMode",inputInfo )) { - LOGERR("%s: CapablityCheck failed for AutoBacklightMode\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "AutoBacklightMode",inputInfo )) { + LOGERR("%s: CapablityCheck failed for AutoBacklightMode\n", __FUNCTION__); + returnResponse(false); + } - if(!value.compare("Manual")) { - mode = tvBacklightMode_MANUAL; - } - else if (!value.compare("Ambient")) { - mode = tvBacklightMode_AMBIENT; - } - else { - returnResponse(false); - } - - tvError_t ret = SetCurrentBacklightMode (mode); + if(!value.compare("Manual")) { + mode = tvBacklightMode_MANUAL; + } + else if (!value.compare("Ambient")) { + mode = tvBacklightMode_AMBIENT; + } + else { + returnResponse(false); + } - if(ret != tvERROR_NONE) { - returnResponse(false); - } - else { - //Save AutoBacklightMode to localstore + tvError_t ret = SetCurrentBacklightMode (mode); - tr181ErrorCode_t err = setLocalParam(rfc_caller_id, AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, value.c_str()); - if ( err != tr181Success ) { - LOGERR("setLocalParam for %s Failed : %s\n", AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, getTR181ErrorString(err)); + if(ret != tvERROR_NONE) { returnResponse(false); } else { - LOGINFO("setLocalParam for %s Successful, Value: %s\n", AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, value.c_str()); + //Save AutoBacklightMode to localstore + + tr181ErrorCode_t err = setLocalParam(rfc_caller_id, AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, value.c_str()); + if ( err != tr181Success ) { + LOGERR("setLocalParam for %s Failed : %s\n", AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, getTR181ErrorString(err)); + returnResponse(false); + } + else { + LOGINFO("setLocalParam for %s Successful, Value: %s\n", AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, value.c_str()); + } + LOGINFO("Exit : SetAutoBacklightMode() value : %s\n",value.c_str()); + returnResponse(true); } - LOGINFO("Exit : SetAutoBacklightMode() value : %s\n",value.c_str()); - returnResponse(true); + } + else + { + bool success = false; + success = setEnumPQParam( + parameters, + "mode", + "BacklightMode", + backlightModeReverseMap, + PQ_PARAM_BACKLIGHT_MODE, + [](int val) { + return SetCurrentBacklightMode(static_cast(val)); + }); + + returnResponse(success); } } uint32_t AVOutputTV::getAutoBacklightMode(const JsonObject& parameters, JsonObject& response) { + if(m_backlightModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + TR181_ParamData_t param; - TR181_ParamData_t param; - - if (isPlatformSupport("AutoBacklightMode") != 0) { - returnResponse(false); - } + if (isPlatformSupport("AutoBacklightMode") != 0) { + returnResponse(false); + } - tr181ErrorCode_t err = getLocalParam(rfc_caller_id, AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, ¶m); - if (err!= tr181Success) { - returnResponse(false); + tr181ErrorCode_t err = getLocalParam(rfc_caller_id, AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, ¶m); + if (err!= tr181Success) { + returnResponse(false); + } + else { + std::string s; + s+=param.value; + response["mode"] = s; + LOGINFO("Exit getAutoBacklightMode(): %s\n",s.c_str()); + returnResponse(true); + } } - else { - std::string s; - s+=param.value; - response["mode"] = s; - LOGINFO("Exit getAutoBacklightMode(): %s\n",s.c_str()); - returnResponse(true); + else + { + std::string mode; + if (getEnumPQParamString(parameters, "BacklightMode", + PQ_PARAM_BACKLIGHT_MODE, backlightModeMap, mode)) { + response["mode"] = mode; + returnResponse(true); + } else { + returnResponse(false); + } } } @@ -3880,63 +5978,77 @@ namespace Plugin { uint32_t AVOutputTV::resetAutoBacklightMode(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_backlightModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + tvError_t ret = tvERROR_NONE; - tvError_t ret = tvERROR_NONE; - - if (isPlatformSupport("AutoBacklightMode") != 0) { - returnResponse(false); - } - - tr181ErrorCode_t err = clearLocalParam(rfc_caller_id,AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM); - if ( err != tr181Success ) { - LOGWARN("clearLocalParam for %s Failed : %s\n", AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, getTR181ErrorString(err)); - ret = tvERROR_GENERAL; - } - else { - LOGINFO("clearLocalParam for %s Successful\n", AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM); - - TR181_ParamData_t param; - memset(¶m, 0, sizeof(param)); + if (isPlatformSupport("AutoBacklightMode") != 0) { + returnResponse(false); + } - tr181ErrorCode_t err = getLocalParam(rfc_caller_id, AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM,¶m); + tr181ErrorCode_t err = clearLocalParam(rfc_caller_id,AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM); if ( err != tr181Success ) { - LOGWARN("getLocalParam for %s Failed : %s\n", AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, getTR181ErrorString(err)); + LOGWARN("clearLocalParam for %s Failed : %s\n", AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, getTR181ErrorString(err)); ret = tvERROR_GENERAL; } else { - tvBacklightMode_t blMode = tvBacklightMode_NONE; + LOGINFO("clearLocalParam for %s Successful\n", AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM); - if(!std::string(param.value).compare("none")) { - blMode = tvBacklightMode_NONE; - } - else if (!std::string(param.value).compare("Manual")){ - blMode = tvBacklightMode_MANUAL; - } - else if (!std::string(param.value).compare("Ambient")){ - blMode = tvBacklightMode_AMBIENT; - } - else if (!std::string(param.value).compare("Eco")){ - blMode = tvBacklightMode_ECO; - } - else { - blMode = tvBacklightMode_NONE; - } - ret = SetCurrentBacklightMode(blMode); - if(ret != tvERROR_NONE) { - LOGWARN("Autobacklight Mode set failed: %s\n",getErrorString(ret).c_str()); + TR181_ParamData_t param; + memset(¶m, 0, sizeof(param)); + + tr181ErrorCode_t err = getLocalParam(rfc_caller_id, AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM,¶m); + if ( err != tr181Success ) { + LOGWARN("getLocalParam for %s Failed : %s\n", AVOUTPUT_AUTO_BACKLIGHT_MODE_RFC_PARAM, getTR181ErrorString(err)); + ret = tvERROR_GENERAL; } else { - LOGINFO("Exit : Autobacklight Mode set successfully, value: %s\n", param.value); + tvBacklightMode_t blMode = tvBacklightMode_NONE; + + if(!std::string(param.value).compare("none")) { + blMode = tvBacklightMode_NONE; + } + else if (!std::string(param.value).compare("Manual")){ + blMode = tvBacklightMode_MANUAL; + } + else if (!std::string(param.value).compare("Ambient")){ + blMode = tvBacklightMode_AMBIENT; + } + else if (!std::string(param.value).compare("Eco")){ + blMode = tvBacklightMode_ECO; + } + else { + blMode = tvBacklightMode_NONE; + } + ret = SetCurrentBacklightMode(blMode); + if(ret != tvERROR_NONE) { + LOGWARN("Autobacklight Mode set failed: %s\n",getErrorString(ret).c_str()); + } + else { + LOGINFO("Exit : Autobacklight Mode set successfully, value: %s\n", param.value); + } } - } - } - if(ret != tvERROR_NONE) - { - returnResponse(false); + } + if(ret != tvERROR_NONE) + { + returnResponse(false); + } + else + { + returnResponse(true); + } } else { - returnResponse(true); + bool success = resetEnumPQParamToDefault( + parameters, + "BacklightMode", + PQ_PARAM_BACKLIGHT_MODE, + backlightModeMap, + [](int value, const std::unordered_map&) -> tvError_t { + return SetCurrentBacklightMode(static_cast(value)); + }); + returnResponse(success); } } @@ -3951,7 +6063,7 @@ namespace Plugin { returnResponse(false); } else { - response["currentVideoSource"] = convertSourceIndexToString(currentSource); + response["currentVideoSource"] = convertSourceIndexToStringV2(currentSource); LOGINFO("Exit: getVideoSource :%d success \n", currentSource); returnResponse(true); } diff --git a/AVOutput/AVOutputTV.h b/AVOutput/AVOutputTV.h index 612aebf8..e383b330 100644 --- a/AVOutput/AVOutputTV.h +++ b/AVOutput/AVOutputTV.h @@ -74,7 +74,6 @@ #define CREATE_DIRTY(__X__) (__X__+=STRING_DIRTY) #define CAPABLITY_FILE_NAME "pq_capabilities.ini" - class CIniFile { std::string m_path; @@ -204,6 +203,13 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(getHDRMode) DECLARE_JSON_RPC_METHOD(get2PointWB) DECLARE_JSON_RPC_METHOD(getAutoBacklightMode) + DECLARE_JSON_RPC_METHOD(getAISuperResolution) + DECLARE_JSON_RPC_METHOD(getPrecisionDetail) + DECLARE_JSON_RPC_METHOD(getLocalContrastEnhancement) + DECLARE_JSON_RPC_METHOD(getMPEGNoiseReduction) + DECLARE_JSON_RPC_METHOD(getDigitalNoiseReduction) + DECLARE_JSON_RPC_METHOD(getMEMC) + /*Get Capability API's*/ @@ -227,6 +233,29 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(get2PointWBCaps) DECLARE_JSON_RPC_METHOD(getHDRModeCaps) DECLARE_JSON_RPC_METHOD(getAutoBacklightModeCaps) + DECLARE_JSON_RPC_METHOD(getBacklightCapsV2) + DECLARE_JSON_RPC_METHOD(getBrightnessCapsV2) + DECLARE_JSON_RPC_METHOD(getContrastCapsV2) + DECLARE_JSON_RPC_METHOD(getSharpnessCapsV2) + DECLARE_JSON_RPC_METHOD(getSaturationCapsV2) + DECLARE_JSON_RPC_METHOD(getHueCapsV2) + DECLARE_JSON_RPC_METHOD(getPrecisionDetailCaps) + DECLARE_JSON_RPC_METHOD(getLowLatencyStateCapsV2) + DECLARE_JSON_RPC_METHOD(getColorTemperatureCapsV2) + DECLARE_JSON_RPC_METHOD(getSDRGammaCaps) + DECLARE_JSON_RPC_METHOD(getBacklightDimmingModeCapsV2) + DECLARE_JSON_RPC_METHOD(getZoomModeCapsV2) + DECLARE_JSON_RPC_METHOD(getCMSCapsV2) + DECLARE_JSON_RPC_METHOD(get2PointWBCapsV2) + DECLARE_JSON_RPC_METHOD(getDolbyVisionCalibrationCaps) + DECLARE_JSON_RPC_METHOD(getPictureModeCapsV2) + DECLARE_JSON_RPC_METHOD(getAutoBacklightModeCapsV2) + DECLARE_JSON_RPC_METHOD(getLocalContrastEnhancementCaps) + DECLARE_JSON_RPC_METHOD(getMPEGNoiseReductionCaps) + DECLARE_JSON_RPC_METHOD(getDigitalNoiseReductionCaps) + DECLARE_JSON_RPC_METHOD(getAISuperResolutionCaps) + DECLARE_JSON_RPC_METHOD(getMEMCCaps) + DECLARE_JSON_RPC_METHOD(getMultiPointWBCaps) /*Set API's*/ DECLARE_JSON_RPC_METHOD(setBacklight) @@ -247,6 +276,12 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(set2PointWB ) DECLARE_JSON_RPC_METHOD(signalFilmMakerMode) DECLARE_JSON_RPC_METHOD(setAutoBacklightMode) + DECLARE_JSON_RPC_METHOD(setAISuperResolution) + DECLARE_JSON_RPC_METHOD(setPrecisionDetail) + DECLARE_JSON_RPC_METHOD(setLocalContrastEnhancement) + DECLARE_JSON_RPC_METHOD(setMPEGNoiseReduction) + DECLARE_JSON_RPC_METHOD(setDigitalNoiseReduction) + DECLARE_JSON_RPC_METHOD(setMEMC) /*Reset API's*/ DECLARE_JSON_RPC_METHOD(resetBacklight) @@ -265,6 +300,14 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(resetCMS) DECLARE_JSON_RPC_METHOD(reset2PointWB) DECLARE_JSON_RPC_METHOD(resetAutoBacklightMode) + DECLARE_JSON_RPC_METHOD(resetAISuperResolution) + DECLARE_JSON_RPC_METHOD(resetPrecisionDetail) + DECLARE_JSON_RPC_METHOD(resetLocalContrastEnhancement) + DECLARE_JSON_RPC_METHOD(resetMPEGNoiseReduction) + DECLARE_JSON_RPC_METHOD(resetDigitalNoiseReduction) + DECLARE_JSON_RPC_METHOD(resetMEMC) + + private: @@ -340,8 +383,12 @@ class AVOutputTV : public AVOutputBase { tvError_t getParamsCaps(std::string param, capVectors_t &vecInfo); int GetPanelID(char *panelid); int ReadCapablitiesFromConf(std::string param, capDetails_t& info); + void getDimmingModeStringFromEnum(int value, std::string &toStore); void getColorTempStringFromEnum(int value, std::string &toStore); + void getDisplayModeStringFromEnum(int value, std::string &toStore); + void getBacklightModeStringFromEnum(int value, std::string &toStore); + int getCurrentPictureMode(char *picMode); int getDolbyParamToSync(int sourceIndex, int formatIndex, int& value); tvDolbyMode_t GetDolbyVisionEnumFromModeString(const char* modeString); @@ -372,6 +419,93 @@ class AVOutputTV : public AVOutputBase { void broadcastLowLatencyModeChangeEvent(bool lowLatencyMode); tvError_t setAspectRatioZoomSettings(tvDisplayMode_t mode); tvError_t setDefaultAspectRatio(std::string pqmode="none",std::string format="none",std::string source="none"); + template + static int getEnumFromString(const std::map& reverseMap, const std::string& key, T defaultVal) { + auto it = reverseMap.find(key); + return (it != reverseMap.end()) ? it->second : defaultVal; + } + + static const std::map pqModeMap; + static const std::map videoFormatMap; + static const std::map videoSrcMap; + static const std::unordered_map backlightModeMap; + + static std::unordered_map pqModeReverseMap; + static std::unordered_map videoFormatReverseMap; + static std::unordered_map videoSrcReverseMap; + static bool reverseMapsInitialized; + static void initializeReverseMaps(); + static const std::unordered_map backlightModeReverseMap; + + uint32_t getPQCapabilityWithContext( + const std::function& getCapsFunc, + const JsonObject& parameters, + JsonObject& response); + JsonObject parseContextCaps(tvContextCaps_t* context_caps); + // Helper functions to extract modes/sources/formats from parameters + std::vector extractPQModes(const JsonObject& parameters); + std::vector extractVideoSources(const JsonObject& parameters); + std::vector extractVideoFormats(const JsonObject& parameters); + static bool isGlobalParam(const JsonArray& arr); + JsonArray getJsonArrayIfArray(const JsonObject& obj, const std::string& key); + int updateAVoutputTVParamV2(std::string action, std::string tr181ParamName, + const JsonObject& parameters, tvPQParameterIndex_t pqParamIndex, int level); + std::vector getValidContextsFromParameters(const JsonObject& parameters,const std::string& tr181ParamName ); + typedef tvError_t (*tvSetFunction)(int); + bool resetPQParamToDefault(const JsonObject& parameters, + const std::string& paramName, + tvPQParameterIndex_t pqIndex, + tvSetFunction halSetter); + typedef tvError_t (*tvSetFunctionV2)(tvVideoSrcType_t, tvPQModeIndex_t,tvVideoFormatType_t,int); + bool resetPQParamToDefault(const JsonObject& parameters, + const std::string& paramName, + tvPQParameterIndex_t pqIndex, + tvSetFunctionV2 halSetter); + bool resetEnumPQParamToDefault(const JsonObject& parameters, + const std::string& paramName, + tvPQParameterIndex_t pqIndex, + const std::unordered_map& valueMap, + std::function&)> halSetter); + tvConfigContext_t getValidContextFromGetParameters(const JsonObject& parameters, const std::string& paramName); + bool getPQParamFromContext(const JsonObject& parameters, + const std::string& paramName, + tvPQParameterIndex_t paramType, + int& outValue); + bool getEnumPQParamString( + const JsonObject& parameters, + const std::string& paramName, + tvPQParameterIndex_t pqType, + const std::unordered_map& enumToStrMap, + std::string& outStr); + bool setIntPQParam(const JsonObject& parameters, const std::string& paramName, + tvPQParameterIndex_t pqType, tvSetFunction halSetter, int maxCap); + bool setEnumPQParam(const JsonObject& parameters, + const std::string& inputKey, + const std::string& paramName, + const std::unordered_map& valueMap, + tvPQParameterIndex_t paramType, + std::function halSetter); + uint32_t setContextPQParam(const JsonObject& parameters, JsonObject& response, + const std::string& inputParamName, + const std::string& tr181ParamName, + int maxAllowedValue, + tvPQParameterIndex_t pqParamType, + std::function halSetter); + bool setPictureModeV2(const JsonObject& parameters); + bool getPictureModeV2(const JsonObject& parameters, std::string& outMode); + std::string getCurrentPictureModeAsString(); + std::string getCurrentVideoFormatAsString(); + std::string getCurrentVideoSourceAsString(); + bool isSetRequiredForParam(const JsonObject& parameters, const std::string& paramName); + tvContextCaps_t* getCapsForParam(const std::string& paramName); + bool isValidSource(const std::vector& sourceArray, tvVideoSrcType_t sourceIndex); + bool isValidFormat(const std::vector& formatArray, tvVideoFormatType_t formatIndex); + tvError_t updateAVoutputTVParamToHALV2(std::string forParam, paramIndex_t indexInfo, int value, bool setNotDelete); + bool resetPictureModeV2(const JsonObject& parameters); + int syncAvoutputTVPQModeParamsToHALV2(std::string pqmode, std::string source, std::string format); + std::string getCMSNameFromEnum(tvDataComponentColor_t colorEnum); + void syncCMSParamsV2(); + public: int m_currentHdmiInResoluton; @@ -380,6 +514,125 @@ class AVOutputTV : public AVOutputBase { char rfc_caller_id[RFC_BUFF_MAX]; bool appUsesGlobalBackLightFactor; int pic_mode_index[PIC_MODES_SUPPORTED_MAX]; + + + int m_maxBacklight = 0; + tvContextCaps_t* m_backlightCaps = nullptr; + tvError_t m_backlightStatus = tvERROR_NONE; + + int m_maxBrightness = 0; + tvContextCaps_t* m_brightnessCaps = nullptr; + tvError_t m_brightnessStatus = tvERROR_NONE; + + int m_maxContrast = 0; + tvContextCaps_t* m_contrastCaps = nullptr; + tvError_t m_contrastStatus = tvERROR_NONE; + + int m_maxSharpness = 0; + tvContextCaps_t* m_sharpnessCaps = nullptr; + tvError_t m_sharpnessStatus = tvERROR_NONE; + + int m_maxSaturation = 0; + tvContextCaps_t* m_saturationCaps = nullptr; + tvError_t m_saturationStatus = tvERROR_NONE; + + int m_maxHue = 0; + tvContextCaps_t* m_hueCaps = nullptr; + tvError_t m_hueStatus = tvERROR_NONE; + + int m_maxlowLatencyState = 0; + tvContextCaps_t* m_lowLatencyStateCaps = nullptr; + tvError_t m_lowLatencyStateStatus = tvERROR_NONE; + + int m_maxPrecisionDetail = 0; + tvContextCaps_t* m_precisionDetailCaps = nullptr; + tvError_t m_precisionDetailStatus = tvERROR_NONE; + + int m_maxLocalContrastEnhancement = 0; + tvContextCaps_t* m_localContrastEnhancementCaps = nullptr; + tvError_t m_localContrastEnhancementStatus = tvERROR_NONE; + + int m_maxMPEGNoiseReduction = 0; + tvContextCaps_t* m_MPEGNoiseReductionCaps = nullptr; + tvError_t m_MPEGNoiseReductionStatus = tvERROR_NONE; + + int m_maxDigitalNoiseReduction = 0; + tvContextCaps_t* m_digitalNoiseReductionCaps = nullptr; + tvError_t m_digitalNoiseReductionStatus = tvERROR_NONE; + + int m_maxAISuperResolution = 0; + tvContextCaps_t* m_AISuperResolutionCaps = nullptr; + tvError_t m_AISuperResolutionStatus = tvERROR_NONE; + + int m_maxMEMC = 0; + tvContextCaps_t* m_MEMCCaps = nullptr; + tvError_t m_MEMCStatus = tvERROR_NONE; + + tvColorTemp_t* m_colortemp = nullptr; + size_t m_numColortemp = 0; + tvContextCaps_t* m_colortempCaps = nullptr; + tvError_t m_colorTempStatus = tvERROR_NONE; + + tvDisplayMode_t* m_aspectRatio = nullptr; + size_t m_numAspectRatio = 0; + tvContextCaps_t* m_aspectRatioCaps = nullptr; + tvError_t m_aspectRatioStatus = tvERROR_NONE; + + tvDimmingMode_t* m_dimmingModes = nullptr; + size_t m_numdimmingModes = 0; + tvContextCaps_t* m_dimmingModeCaps = nullptr; + tvError_t m_dimmingModeStatus = tvERROR_NONE; + + tvPQModeIndex_t* m_pictureModes = nullptr; + size_t m_numPictureModes = 0; + tvContextCaps_t* m_pictureModeCaps = nullptr; + tvError_t m_pictureModeStatus = tvERROR_NONE; + + tvBacklightMode_t* m_backlightModes = nullptr; + size_t m_numBacklightModes = 0; + tvContextCaps_t* m_backlightModeCaps = nullptr; + tvError_t m_backlightModeStatus = tvERROR_NONE; + + tvSdrGamma_t* m_sdrGammaModes = nullptr; + size_t m_numsdrGammaModes = 0; + tvContextCaps_t* m_sdrGammaModeCaps = nullptr; + tvError_t m_sdrGammaModeStatus = tvERROR_NONE; + + int m_numHalMatrixPoints = 0; + int m_rgbMin = 0; + int m_rgbMax = 0; + int m_numUiMatrixPoints = 0; + double* m_uiMatrixPositions = nullptr; + tvContextCaps_t* m_multiPointWBCaps = nullptr; + tvError_t m_multiPointWBStatus = tvERROR_NONE; + + tvDVCalibrationSettings_t* m_minValues; + tvDVCalibrationSettings_t* m_maxValues; + tvContextCaps_t* m_DVCalibrationCaps = nullptr; + tvError_t m_DVCalibrationStatus = tvERROR_NONE; + + int m_maxCmsHue = 0; + int m_maxCmsSaturation = 0; + int m_maxCmsLuma = 0; + size_t m_numColor = 0; + size_t m_numComponent = 0; + tvDataComponentColor_t* m_cmsColorArr; + tvComponentType_t* m_cmsComponentArr; + std::vector m_cmsColorList; + std::vector m_cmsComponentList; + std::unordered_map m_cmsIndexMap; + tvContextCaps_t* m_cmsCaps = nullptr; + tvError_t m_cmsStatus = tvERROR_NONE; + + bool setCMSParam(const JsonObject& parameters); + + std::string convertPictureIndexToStringV2(int pqmode); + std::string convertVideoFormatToStringV2(int format); + std::string convertSourceIndexToStringV2(int source); + + uint32_t generateStorageIdentifierV2(std::string &key, std::string forParam, paramIndex_t info); + void generateStorageIdentifierCMSV2(std::string &key, std::string forParam, paramIndex_t info); + void generateStorageIdentifierWBV2(std::string &key, std::string forParam, paramIndex_t info); AVOutputTV(); ~AVOutputTV(); @@ -391,7 +644,6 @@ class AVOutputTV : public AVOutputBase { void NotifyFilmMakerModeChange(tvContentType_t mode); void NotifyVideoResolutionChange(tvResolutionParam_t resolution); void NotifyVideoFrameRateChange(tvVideoFrameRate_t frameRate); - //override API static void dsHdmiVideoModeEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); static void dsHdmiStatusEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index 6fbcbab0..41a32bb5 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -296,13 +296,13 @@ namespace Plugin { { tvDimmingMode_t index = tvDimmingMode_MAX; - if(mode.compare("Local") == 0 ) { + if(mode.compare("local") == 0 ) { index=tvDimmingMode_Local; } - else if(mode.compare("Fixed") == 0 ) { + else if(mode.compare("fixed") == 0 ) { index=tvDimmingMode_Fixed; } - else if(mode.compare("Global") == 0 ) { + else if(mode.compare("global") == 0 ) { index=tvDimmingMode_Global; } else { @@ -737,7 +737,7 @@ namespace Plugin { GetCurrentVideoSource(¤t_source); tr181_param_name += std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); - tr181_param_name += "."+convertSourceIndexToString(current_source)+"."+"Format."+convertVideoFormatToString(current_format)+"."+"PictureModeString"; + tr181_param_name += "."+convertSourceIndexToStringV2(current_source)+"."+"Format."+convertVideoFormatToStringV2(current_format)+"."+"PictureModeString"; tr181ErrorCode_t err = getLocalParam(rfc_caller_id, tr181_param_name.c_str(), ¶m); if ( tr181Success == err ) { ret = SetTVPictureMode(param.value); @@ -900,6 +900,59 @@ namespace Plugin { return ret; } + tvError_t AVOutputTV::updateAVoutputTVParamToHALV2(std::string forParam, paramIndex_t indexInfo, int value, bool setNotDelete) + { + tvError_t ret = tvERROR_NONE; + std::string key; + + // Generate storage key based on parameter type + if (forParam == "CMS") + generateStorageIdentifierCMS(key, forParam, indexInfo); + else if (forParam == "WhiteBalance") + generateStorageIdentifierWB(key, forParam, indexInfo); + else + generateStorageIdentifierV2(key, forParam, indexInfo); + + if (key.empty()) { + LOGERR("%s generateStorageIdentifier failed\n", __FUNCTION__); + return tvERROR_GENERAL; + } + + tr181ErrorCode_t err = tr181Success; + + if (setNotDelete) { + std::string toStore = std::to_string(value); + + // Map parameters to their string transformation logic (if applicable) + std::map> fnMap = { + {"ColorTemp", [this](int v, std::string& s) { getColorTempStringFromEnum(v, s); }}, + {"DimmingMode", [this](int v, std::string& s) { getDimmingModeStringFromEnum(v, s); }}, + {"AspectRatio", [this](int v, std::string& s) { getDisplayModeStringFromEnum(v, s); }}, + {"BacklightMode", [this](int v, std::string& s) { getBacklightModeStringFromEnum(v, s); }} + }; + + // If there's a custom string conversion for this parameter, apply it + auto it = fnMap.find(forParam); + if (it != fnMap.end()) { + it->second(value, toStore); + } + // Set the value using TR-181 + err = setLocalParam(rfc_caller_id, key.c_str(), toStore.c_str()); + } + else + { + // Delete the value using TR-181 + err = clearLocalParam(rfc_caller_id, key.c_str()); + } + + if (err != tr181Success) { + LOGERR("%s: %s for %s Failed : %s\n",__FUNCTION__, setNotDelete ? "Set" : "Delete", key.c_str(), getTR181ErrorString(err)); + ret = tvERROR_GENERAL; + } + + return ret; + } + tvError_t AVOutputTV::updateAVoutputTVParamToHAL(std::string forParam, paramIndex_t indexInfo, int value,bool setNotDelete) { tvError_t ret = tvERROR_NONE; @@ -913,7 +966,7 @@ namespace Plugin { generateStorageIdentifier(key,forParam,indexInfo); if(key.empty()) { - LOGERR("generateStorageIdentifierDirty failed\n"); + LOGERR("%s generateStorageIdentifierDirty failed\n", __FUNCTION__); ret = tvERROR_GENERAL; } else { @@ -932,7 +985,8 @@ namespace Plugin { err = setLocalParam(rfc_caller_id, key.c_str(),toStore.c_str()); } - else { + else + { err = clearLocalParam(rfc_caller_id, key.c_str()); } @@ -1136,139 +1190,330 @@ namespace Plugin { } return ret; } + void AVOutputTV::syncCMSParamsV2() { + JsonObject parameters; + + // Set default values to "none" to indicate all contexts (global sync) + parameters["pictureMode"] = "none"; + parameters["videoSource"] = "none"; + parameters["videoFormat"] = "none"; + + // Use "Global" to trigger syncing for all CMS components and colors + parameters["color"] = "Global"; + parameters["component"] = "Global"; + + // Dummy PQ index; unused for CMS sync but required by function signature + tvPQParameterIndex_t dummyPQIndex = PQ_PARAM_CMS_SATURATION_RED; + + int result = updateAVoutputTVParamV2("sync", "CMS", parameters, dummyPQIndex, 0); + if (result == 0) { + LOGINFO("%s: CMS sync completed successfully", __FUNCTION__); + } else { + LOGERR("%s: CMS sync encountered errors", __FUNCTION__); + } + } - tvError_t AVOutputTV::syncAvoutputTVParamsToHAL(std::string pqmode,std::string source,std::string format) + tvError_t AVOutputTV::syncAvoutputTVParamsToHAL(std::string pqmode, std::string source, std::string format) { - int level={0}; + int level = {0}; capDetails_t info; info.pqmode = pqmode; info.source = source; info.format = format; - LOGINFO("Entry %s : pqmode : %s source : %s format : %s\n",__FUNCTION__,pqmode.c_str(),source.c_str(),format.c_str()); - - if( !updateAVoutputTVParam("sync","Brightness",info,PQ_PARAM_BRIGHTNESS,level)) { - LOGINFO("Brightness Successfully sync to Drive Cache\n"); - } - else { - LOGERR("Brightness Sync to cache Failed !!!\n"); + JsonObject paramJson; + paramJson["pictureMode"] = info.pqmode; + paramJson["videoSource"] = info.source; + paramJson["videoFormat"] = info.format; + LOGINFO("Entry %s : pqmode : %s source : %s format : %s\n", __FUNCTION__, pqmode.c_str(), source.c_str(), format.c_str()); + + // Brightness + m_brightnessStatus = GetBrightnessCaps(&m_maxBrightness, &m_brightnessCaps); + LOGINFO("GetBrightnessCaps returned status: %d, max: %d", m_brightnessStatus, m_maxBrightness); + if (m_brightnessStatus == tvERROR_OPERATION_NOT_SUPPORTED) { + updateAVoutputTVParam("sync", "Brightness", info, PQ_PARAM_BRIGHTNESS, level); + } else { + updateAVoutputTVParamV2("sync", "Brightness", paramJson, PQ_PARAM_BRIGHTNESS,level); } - if( !updateAVoutputTVParam("sync","Contrast",info,PQ_PARAM_CONTRAST,level)) { - LOGINFO("Contrast Successfully Synced to Drive Cache\n"); - } - else { - LOGERR("Contrast Sync to cache Failed !!!\n"); + // Contrast + m_contrastStatus = GetContrastCaps(&m_maxContrast, &m_contrastCaps); + LOGINFO("GetContrastCaps returned status: %d, max: %d", m_contrastStatus, m_maxContrast); + if (m_contrastStatus == tvERROR_OPERATION_NOT_SUPPORTED) { + updateAVoutputTVParam("sync", "Contrast", info, PQ_PARAM_CONTRAST, level); + } else { + updateAVoutputTVParamV2("sync", "Contrast", paramJson, PQ_PARAM_CONTRAST,level); } - if( !updateAVoutputTVParam("sync","Sharpness",info,PQ_PARAM_SHARPNESS,level)) { - LOGINFO("Sharpness Successfully Synced to Drive Cache\n"); - } - else { - LOGERR("Sharpness Sync to cache Failed !!!\n"); + // Sharpness + m_sharpnessStatus = GetSharpnessCaps(&m_maxSharpness, &m_sharpnessCaps); + LOGINFO("GetSharpnessCaps returned status: %d, max: %d", m_sharpnessStatus, m_maxSharpness); + if (m_sharpnessStatus == tvERROR_OPERATION_NOT_SUPPORTED) { + updateAVoutputTVParam("sync", "Sharpness", info, PQ_PARAM_SHARPNESS, level); + } else { + updateAVoutputTVParamV2("sync", "Sharpness", paramJson, PQ_PARAM_SHARPNESS, level); } - if( !updateAVoutputTVParam("sync","Saturation",info,PQ_PARAM_SATURATION,level)) { - LOGINFO("Saturation Successfully Synced to Drive Cache\n"); + // Saturation + m_saturationStatus = GetSaturationCaps(&m_maxSaturation, &m_saturationCaps); + LOGINFO("GetSaturationCaps returned status: %d, max: %d", m_saturationStatus, m_maxSaturation); + if (m_saturationStatus == tvERROR_OPERATION_NOT_SUPPORTED) { + updateAVoutputTVParam("sync", "Saturation", info, PQ_PARAM_SATURATION, level); + } else { + updateAVoutputTVParamV2("sync", "Saturation", paramJson, PQ_PARAM_SATURATION,level); } - else { - LOGERR("Saturation Sync to cache Failed !!!\n"); + + // Hue + m_hueStatus = GetHueCaps(&m_maxHue, &m_hueCaps); + LOGINFO("GetHueCaps returned status: %d, max: %d", m_hueStatus, m_maxHue); + if (m_hueStatus == tvERROR_OPERATION_NOT_SUPPORTED) { + updateAVoutputTVParam("sync", "Hue", info, PQ_PARAM_HUE, level); + } else { + updateAVoutputTVParamV2("sync", "Hue", paramJson, PQ_PARAM_HUE, level); } - if( !updateAVoutputTVParam("sync","Hue",info,PQ_PARAM_HUE,level)) { - LOGINFO("Hue Successfully Synced to Drive Cache\n"); + // ColorTemperature + m_colorTempStatus = GetColorTemperatureCaps(&m_colortemp, &m_numColortemp, &m_colortempCaps); + LOGINFO("GetColorTemperatureCaps returned status: %d, numColortemp: %d", m_colorTempStatus, m_numColortemp); + if (m_colorTempStatus == tvERROR_OPERATION_NOT_SUPPORTED) { + updateAVoutputTVParam("sync", "ColorTemp", info, PQ_PARAM_COLOR_TEMPERATURE, level); + } else { + updateAVoutputTVParamV2("sync", "ColorTemp", paramJson, PQ_PARAM_COLOR_TEMPERATURE,level); } - else { - LOGERR("Hue Sync to cache Failed !!!\n"); + + // DimmingMode + m_dimmingModeStatus = GetTVDimmingModeCaps(&m_dimmingModes, &m_numdimmingModes, &m_dimmingModeCaps); + LOGINFO("GetTVDimmingModeCaps returned status: %d, numdimmingModes: %d", m_dimmingModeStatus, m_numdimmingModes); + if (m_dimmingModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) { + updateAVoutputTVParam("sync", "DimmingMode", info, PQ_PARAM_DIMMINGMODE, level); + } else { + updateAVoutputTVParamV2("sync", "DimmingMode", paramJson, PQ_PARAM_DIMMINGMODE,level); } - if( !updateAVoutputTVParam("sync","ColorTemp",info,PQ_PARAM_COLOR_TEMPERATURE,level)) { - LOGINFO("ColorTemp Successfully Synced to Drive Cache\n"); + // Backlight + LOGINFO("Calling GetBacklightCaps..."); + m_backlightStatus = GetBacklightCaps(&m_maxBacklight, &m_backlightCaps); + LOGINFO("GetBacklightCaps returned status: %d, maxBacklight: %d", m_backlightStatus, m_maxBacklight); + + if (m_backlightStatus == tvERROR_OPERATION_NOT_SUPPORTED) { + updateAVoutputTVParam("sync", "Backlight", info, PQ_PARAM_BACKLIGHT, level); + } else { + updateAVoutputTVParamV2("sync", "Backlight", paramJson, PQ_PARAM_BACKLIGHT, level); } - else { - LOGERR("ColorTemp Sync to cache Failed !!!\n"); + + //Ambient Bakclight Mode + m_backlightModeStatus = GetBacklightModeCaps(&m_backlightModes, &m_numBacklightModes, &m_backlightModeCaps); + if (m_backlightModeStatus == tvERROR_NONE) { + updateAVoutputTVParamV2("sync", "BacklightMode", paramJson, PQ_PARAM_BACKLIGHT_MODE, level); } - if( !updateAVoutputTVParam("sync","HDRMode",info,PQ_PARAM_DOLBY_MODE,level)) { - LOGINFO("HDRmode Successfully Synced to Drive Cache\n"); + + //AspectRatio + m_aspectRatioStatus = GetAspectRatioCaps(&m_aspectRatio, &m_numAspectRatio, &m_aspectRatioCaps); + + //LowLatencyState + m_lowLatencyStateStatus = GetLowLatencyStateCaps(&m_maxlowLatencyState, &m_lowLatencyStateCaps); + if (m_lowLatencyStateStatus == tvERROR_OPERATION_NOT_SUPPORTED) { + updateAVoutputTVParam("sync", "LowLatencyState", info, PQ_PARAM_LOWLATENCY_STATE, level); + } else { + updateAVoutputTVParamV2("sync", "LowLatencyState", paramJson, PQ_PARAM_LOWLATENCY_STATE, level); } - else { - LOGERR("HDRmode Sync to cache Failed !!!\n"); + // PrecisionDetail + m_precisionDetailStatus = GetPrecisionDetailCaps(&m_maxPrecisionDetail, &m_precisionDetailCaps); + if (m_localContrastEnhancementStatus == tvERROR_NONE) { + updateAVoutputTVParamV2("sync", "PrecisionDetails", paramJson, PQ_PARAM_PRECISION_DETAIL, level); } + //PictureMode + m_pictureModeStatus = GetTVPictureModeCaps(&m_pictureModes, &m_numPictureModes, &m_pictureModeCaps); - if( !updateAVoutputTVParam("sync","DimmingMode",info,PQ_PARAM_DIMMINGMODE,level)) { - LOGINFO("dimmingmode Successfully Synced to Drive Cache\n"); + // LocalContrastEnhancement + m_localContrastEnhancementStatus = GetLocalContrastEnhancementCaps(&m_maxLocalContrastEnhancement, &m_localContrastEnhancementCaps); + if (m_localContrastEnhancementStatus == tvERROR_NONE) { + updateAVoutputTVParamV2("sync", "LocalContrastEnhancement", paramJson, PQ_PARAM_LOCAL_CONTRAST_ENHANCEMENT, level); } - else { - LOGERR("dimmingmode Sync to cache Failed !!!\n"); + + // MPEGNoiseReduction + m_MPEGNoiseReductionStatus = GetMPEGNoiseReductionCaps(&m_maxMPEGNoiseReduction, &m_MPEGNoiseReductionCaps); + if (m_MPEGNoiseReductionStatus == tvERROR_NONE) { + updateAVoutputTVParamV2("sync", "MPEGNoiseReduction", paramJson, PQ_PARAM_MPEG_NOISE_REDUCTION, level); } - if( !updateAVoutputTVParam("sync","Backlight",info,PQ_PARAM_BACKLIGHT,level) ) { - LOGINFO("Backlight Successfully Synced to Drive Cache\n"); + // DigitalNoiseReduction + m_digitalNoiseReductionStatus = GetDigitalNoiseReductionCaps(&m_maxDigitalNoiseReduction, &m_digitalNoiseReductionCaps); + if (m_digitalNoiseReductionStatus == tvERROR_NONE) { + updateAVoutputTVParamV2("sync", "DigitalNoiseReduction", paramJson, PQ_PARAM_DIGITAL_NOISE_REDUCTION, level); } - else { - LOGERR("Backlight Sync to cache Failed !!!\n"); + + // AISuperResolution + m_AISuperResolutionStatus = GetAISuperResolutionCaps(&m_maxAISuperResolution, &m_AISuperResolutionCaps); + if (m_AISuperResolutionStatus == tvERROR_NONE) { + updateAVoutputTVParamV2("sync", "AISuperResolution", paramJson, PQ_PARAM_AI_SUPER_RESOLUTION,level); } - syncCMSParams(); //sync CMS + // MEMC + m_MEMCStatus = GetMEMCCaps(&m_maxMEMC, &m_MEMCCaps); + if (m_MEMCStatus == tvERROR_NONE) { + updateAVoutputTVParamV2("sync", "MEMC", paramJson, PQ_PARAM_MEMC, level); + } - syncWBParams(); + //Commented due to missing HAL implementation + /*m_cmsStatus = GetCMSCaps(&m_maxCmsHue, &m_maxCmsSaturation, &m_maxCmsLuma, + &m_cmsColorArr, &m_cmsComponentArr, + &m_numColor, &m_numComponent, &m_cmsCaps); + if (m_cmsStatus == tvERROR_NONE) { + for (size_t i = 0; i < m_numColor; i++) { + std::string colorStr = getCMSColorStringFromEnum(m_cmsColorArr[i]); + m_cmsColorList.push_back(colorStr); + } + for (size_t i = 0; i < m_numComponent; i++) { + std::string componentStr = getCMSComponentStringFromEnum(m_cmsComponentArr[i]); + m_cmsComponentList.push_back(componentStr); + } + syncCMSParamsV2(); + }*/ + if(m_cmsStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + syncCMSParams(); + } - info.format = "DV";//Sync only for Dolby + //syncWBParams(); Enable once Get2PointWBCaps is implemented - if( !updateAVoutputTVParam("sync","DolbyVisionMode",info,PQ_PARAM_DOLBY_MODE,level)) { - LOGINFO("dvmode Successfully Synced to Drive Cache\n"); - } - else { - LOGERR("dvmode Sync to cache Failed !!!\n"); + if(m_pictureModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + // Dolby Vision Mode + info.format = "DV"; // Sync only for Dolby + updateAVoutputTVParam("sync", "DolbyVisionMode", info, PQ_PARAM_DOLBY_MODE, level); } - LOGINFO("Exit %s : pqmode : %s source : %s format : %s\n",__FUNCTION__,pqmode.c_str(),source.c_str(),format.c_str()); + LOGINFO("Exit %s : pqmode : %s source : %s format : %s\n", __FUNCTION__, pqmode.c_str(), source.c_str(), format.c_str()); return tvERROR_NONE; } - - int AVOutputTV::syncAvoutputTVPQModeParamsToHAL(std::string pqmode, std::string source, std::string format) + int AVOutputTV::syncAvoutputTVPQModeParamsToHALV2(std::string pqmode, std::string source, std::string format) { - capDetails_t inputInfo; - valueVectors_t valueVectors; tr181ErrorCode_t err = tr181Success; TR181_ParamData_t param = {0}; - int ret = 0; + bool contextSynced = false; + + // Treat "none" as "Global" + if (source == "none") + source = "Global"; + if (format == "none") + format = "Global"; + + // Handle "Current" source/format substitution + if (source == "Current" || format == "Current") { + tvVideoSrcType_t currentSrc = VIDEO_SOURCE_IP; + tvVideoFormatType_t currentFmt = VIDEO_FORMAT_SDR; + GetCurrentVideoSource(¤tSrc); + GetCurrentVideoFormat(¤tFmt); + if (currentFmt == VIDEO_FORMAT_NONE) + currentFmt = VIDEO_FORMAT_SDR; + + if (source == "Current") + source = convertSourceIndexToStringV2(currentSrc); + if (format == "Current") + format = convertVideoFormatToStringV2(currentFmt); + } + if (m_pictureModeStatus == tvERROR_NONE) + { + for (size_t i = 0; i < m_pictureModeCaps->num_contexts; ++i) { + const tvConfigContext_t& ctx = m_pictureModeCaps->contexts[i]; - inputInfo.pqmode = pqmode; - inputInfo.source = source; - inputInfo.format = format; + std::string sourceStr = convertSourceIndexToStringV2(ctx.videoSrcType); + std::string formatStr = convertVideoFormatToStringV2(ctx.videoFormatType); + + // Filter by provided source/format + if (source != "Global" && source != sourceStr) + continue; + if (format != "Global" && format != formatStr) + continue; + + std::string tr181Param = std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM) + + "." + sourceStr + ".Format." + formatStr + ".PictureModeString"; + + err = getLocalParam(rfc_caller_id, tr181Param.c_str(), ¶m); + if (err != tr181Success) { + LOGWARN("Failed to getLocalParam for %s\n", tr181Param.c_str()); + continue; + } - ret = getSaveConfig("PictureMode", inputInfo, valueVectors); - - if (ret == 0 ) { - for (int source : valueVectors.sourceValues ) { - tvVideoSrcType_t sourceType = (tvVideoSrcType_t)source; - for (int format : valueVectors.formatValues ) { - tvVideoFormatType_t formatType = (tvVideoFormatType_t)format; - std::string tr181_param_name = ""; - tr181_param_name += std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); - tr181_param_name += "."+convertSourceIndexToString(sourceType)+"."+"Format."+ - convertVideoFormatToString(formatType)+"."+"PictureModeString"; - - err = getLocalParam(rfc_caller_id, tr181_param_name.c_str(), ¶m); - if ( tr181Success == err ) { - std::string local = param.value; - int pqmodeindex = (int)getPictureModeIndex(local); - - tvError_t tv_err = SaveSourcePictureMode(sourceType, formatType, pqmodeindex); - if (tv_err != tvERROR_NONE) { - LOGWARN("failed to SaveSourcePictureMode \n"); + std::string modeStr = param.value; + int modeIndex = -1; + for (size_t i = 0; i < m_numPictureModes; ++i) { + if (pqModeMap.at(m_pictureModes[i]) == modeStr) { + modeIndex = static_cast(i); + break; + } + } + + tvError_t tv_err = SaveSourcePictureMode(ctx.videoSrcType, ctx.videoFormatType, modeIndex); + if (tv_err != tvERROR_NONE) { + LOGWARN("Failed SaveSourcePictureMode for %s / %s\n", sourceStr.c_str(), formatStr.c_str()); + continue; + } + + contextSynced = true; + } + + if (!contextSynced) { + LOGWARN("No matching context synced for pqmode=%s source=%s format=%s\n", + pqmode.c_str(), source.c_str(), format.c_str()); + return -1; + } + return 0; + } + return -1; + } + + int AVOutputTV::syncAvoutputTVPQModeParamsToHAL(std::string pqmode, std::string source, std::string format) + { + if (m_pictureModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + valueVectors_t valueVectors; + tr181ErrorCode_t err = tr181Success; + TR181_ParamData_t param = {0}; + int ret = 0; + + inputInfo.pqmode = pqmode; + inputInfo.source = source; + inputInfo.format = format; + + ret = getSaveConfig("PictureMode", inputInfo, valueVectors); + + if (ret == 0 ) { + for (int source : valueVectors.sourceValues ) { + tvVideoSrcType_t sourceType = (tvVideoSrcType_t)source; + for (int format : valueVectors.formatValues ) { + tvVideoFormatType_t formatType = (tvVideoFormatType_t)format; + std::string tr181_param_name = ""; + tr181_param_name += std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); + tr181_param_name += "."+convertSourceIndexToString(sourceType)+"."+"Format."+ + convertVideoFormatToString(formatType)+"."+"PictureModeString"; + + err = getLocalParam(rfc_caller_id, tr181_param_name.c_str(), ¶m); + if ( tr181Success == err ) { + std::string local = param.value; + int pqmodeindex = (int)getPictureModeIndex(local); + + tvError_t tv_err = SaveSourcePictureMode(sourceType, formatType, pqmodeindex); + if (tv_err != tvERROR_NONE) { + LOGWARN("failed to SaveSourcePictureMode \n"); + return -1; + } + } + else { + LOGWARN("Failed to get the getLocalParam \n"); return -1; } } - else { - LOGWARN("Failed to get the getLocalParam \n"); - return -1; - } } } + return ret; + } + else + { + return syncAvoutputTVPQModeParamsToHALV2(pqmode,source,format); } - return ret; } uint32_t AVOutputTV::generateStorageIdentifier(std::string &key, std::string forParam, paramIndex_t info) @@ -1439,7 +1684,7 @@ namespace Plugin { } else if( forParam.compare("WhiteBalance") == 0 ) { generateStorageIdentifierWB(key,forParam,indexInfo); } else { - generateStorageIdentifier(key,forParam,indexInfo); + generateStorageIdentifierV2(key,forParam,indexInfo); } if(key.empty()) { @@ -1480,6 +1725,21 @@ namespace Plugin { } return 0; } + else if ( forParam.compare("BacklightMode") == 0 ) { + if (strncmp(param.value, "Manual", strlen(param.value)) == 0) { + value = tvBacklightMode_MANUAL; + } + else if (strncmp(param.value, "Ambient", strlen(param.value)) == 0) { + value = tvBacklightMode_AMBIENT; + } + else if (strncmp(param.value, "Eco", strlen(param.value)) == 0) { + value = tvBacklightMode_ECO; + } + else { + value = tvBacklightMode_MANUAL; // Default fallback + } + return 0; + } else if ( forParam.compare("DolbyVisionMode") == 0) { if (strncmp(param.value, "Dark", strlen(param.value)) == 0) { value = tvDolbyMode_Dark; @@ -1611,13 +1871,13 @@ namespace Plugin { void AVOutputTV::getDimmingModeStringFromEnum(int value, std::string &toStore) { - const char *color_temp_string[] = { + const char *dimmingmode_string[] = { [tvDimmingMode_Fixed] = "Fixed", [tvDimmingMode_Local] = "Local", [tvDimmingMode_Global] = "Global", }; toStore.clear(); - toStore+=color_temp_string[value]; + toStore+=dimmingmode_string[value]; } void AVOutputTV::getColorTempStringFromEnum(int value, std::string &toStore) @@ -1631,6 +1891,44 @@ namespace Plugin { toStore.clear(); toStore+=color_temp_string[value]; } + void AVOutputTV::getDisplayModeStringFromEnum(int value, std::string &toStore) + { + static const char* display_mode_string[] = { + [tvDisplayMode_4x3] = "TV 4X3 PILLARBOX", + [tvDisplayMode_16x9] = "TV 16X9 STRETCH", + [tvDisplayMode_FULL] = "TV FULL", + [tvDisplayMode_NORMAL] = "TV NORMAL", + [tvDisplayMode_AUTO] = "TV AUTO", + [tvDisplayMode_DIRECT] = "TV DIRECT", + [tvDisplayMode_ZOOM] = "TV ZOOM" + }; + + toStore.clear(); + if (value >= 0 && value < tvDisplayMode_MAX && display_mode_string[value]) { + toStore += display_mode_string[value]; + } else { + toStore += "TV AUTO"; + } + } + + void AVOutputTV::getBacklightModeStringFromEnum(int value, std::string& toStore) + { + toStore.clear(); + switch (static_cast(value)) { + case tvBacklightMode_MANUAL: + toStore = "Manual"; + break; + case tvBacklightMode_AMBIENT: + toStore = "Ambient"; + break; + case tvBacklightMode_ECO: + toStore = "Eco"; + break; + default: + toStore = "Unknown"; + break; + } + } int AVOutputTV::getCurrentPictureMode(char *picMode) { @@ -1652,15 +1950,14 @@ namespace Plugin { } tr181_param_name += std::string(AVOUTPUT_SOURCE_PICTUREMODE_STRING_RFC_PARAM); - tr181_param_name += "." + convertSourceIndexToString(currentSource) + "." + "Format."+convertVideoFormatToString(current_format)+"."+"PictureModeString"; + tr181_param_name += "." + convertSourceIndexToStringV2(currentSource) + "." + "Format."+convertVideoFormatToStringV2(current_format)+"."+"PictureModeString"; memset(¶m, 0, sizeof(param)); tr181ErrorCode_t err = getLocalParam(rfc_caller_id, tr181_param_name.c_str(), ¶m); if ( err == tr181Success ) { strncpy(picMode, param.value, strlen(param.value)+1); - picMode[strlen(param.value)] = '\0'; - LOGINFO("getLocalParam success, mode = %s\n", picMode); + //LOGINFO("getLocalParam success, mode = %s\n", picMode); return 1; } else { @@ -1804,7 +2101,7 @@ namespace Plugin { { tvError_t ret = tvERROR_GENERAL; #if !defined (HDMIIN_4K_ZOOM) - LOGERR("%s:mode selected is: %d", __FUNCTION__, m_videoZoomMode); + LOGINFO("%s:mode selected is: %d", __FUNCTION__, m_videoZoomMode); if (AVOutputTV::instance->m_isDisabledHdmiIn4KZoom) { if (!(AVOutputTV::instance->m_currentHdmiInResolutonm_currentHdmiInResoluton))) { @@ -1863,6 +2160,11 @@ namespace Plugin { inputInfo.source = source; inputInfo.format = format; + JsonObject paramJson; + paramJson["pictureMode"] = inputInfo.pqmode; + paramJson["videoSource"] = inputInfo.source; + paramJson["videoFormat"] = inputInfo.format; + memset(¶m, 0, sizeof(param)); tr181ErrorCode_t err = getLocalParam(rfc_caller_id, AVOUTPUT_ASPECTRATIO_RFC_PARAM, ¶m); if ( tr181Success == err ) { @@ -1907,14 +2209,17 @@ namespace Plugin { LOGERR("AspectRatio set failed: %s\n",getErrorString(ret).c_str()); } else { - //Save DisplayMode to ssm_data - int retval=updateAVoutputTVParam("set","ZoomMode",inputInfo,PQ_PARAM_ASPECT_RATIO,mode); - - if(retval != 0) { + if (m_aspectRatioStatus == tvERROR_OPERATION_NOT_SUPPORTED) { + int retval=updateAVoutputTVParam("set","ZoomMode",inputInfo,PQ_PARAM_ASPECT_RATIO,mode); + if(retval != 0) { LOGERR("Failed to Save DisplayMode to ssm_data\n"); ret = tvERROR_GENERAL; + } + LOGINFO("Aspect Ratio initialized successfully, value: %s\n", param.value); + } + else { + updateAVoutputTVParamV2("set", "ZoomMode", paramJson, PQ_PARAM_ASPECT_RATIO,mode); } - LOGINFO("Aspect Ratio initialized successfully, value: %s\n", param.value); } } @@ -2207,7 +2512,7 @@ namespace Plugin { case tvColorTemp_WARM: return "Warm"; case tvColorTemp_COLD: return "Cold"; case tvColorTemp_USER : return "UserDefined"; - default : return "Max"; + default : return "Standard"; } } @@ -2265,8 +2570,779 @@ namespace Plugin { } return 0; } +//JSON Based V2 Helpers + const std::map AVOutputTV::pqModeMap = { + {PQ_MODE_SPORTS, "Sports"}, + {PQ_MODE_THEATER, "Theater"}, + {PQ_MODE_GAME, "Game"}, + {PQ_MODE_IQ, "IQ"}, + {PQ_MODE_DARK, "Dark"}, + {PQ_MODE_BRIGHT, "Bright"}, + {PQ_MODE_AIPQ, "AI PQ"}, + {PQ_MODE_STANDARD, "Standard"}, + {PQ_MODE_VIVID, "Vivid"}, + {PQ_MODE_ENERGY_SAVING, "EnergySaving"}, + {PQ_MODE_CUSTOM, "Custom"} + }; + + const std::map AVOutputTV::videoFormatMap = { + {VIDEO_FORMAT_NONE, "None"}, + {VIDEO_FORMAT_SDR, "SDR"}, + {VIDEO_FORMAT_HDR10, "HDR10"}, + {VIDEO_FORMAT_HDR10PLUS, "HDR10Plus"}, + {VIDEO_FORMAT_DV, "DV"}, + {VIDEO_FORMAT_HLG, "HLG"} + }; + + const std::map AVOutputTV::videoSrcMap = { + {VIDEO_SOURCE_COMPOSITE1, "Composite1"}, + {VIDEO_SOURCE_HDMI1, "HDMI1"}, + {VIDEO_SOURCE_HDMI2, "HDMI2"}, + {VIDEO_SOURCE_HDMI3, "HDMI3"}, + {VIDEO_SOURCE_HDMI4, "HDMI4"}, + {VIDEO_SOURCE_IP, "IP"}, + {VIDEO_SOURCE_TUNER, "Tuner"} + }; + const std::unordered_map AVOutputTV::backlightModeMap = { + {tvBacklightMode_MANUAL, "Manual"}, + {tvBacklightMode_AMBIENT, "Ambient"}, + {tvBacklightMode_ECO, "Eco"} + }; + + std::unordered_map AVOutputTV::pqModeReverseMap; + std::unordered_map AVOutputTV::videoFormatReverseMap; + std::unordered_map AVOutputTV::videoSrcReverseMap; + bool AVOutputTV::reverseMapsInitialized = false; + + void AVOutputTV::initializeReverseMaps() { + if (reverseMapsInitialized) return; + + for (const auto& entry : pqModeMap) { + pqModeReverseMap[entry.second] = static_cast(entry.first); + } + for (const auto& entry : videoFormatMap) { + videoFormatReverseMap[entry.second] = static_cast(entry.first); + } + for (const auto& entry : videoSrcMap) { + videoSrcReverseMap[entry.second] = static_cast(entry.first); + } + reverseMapsInitialized = true; + } + + const std::unordered_map AVOutputTV::backlightModeReverseMap = []{ + std::unordered_map m; + for (const auto& pair : AVOutputTV::backlightModeMap) m[pair.second] = pair.first; + return m; + }(); + + std::string AVOutputTV::convertSourceIndexToStringV2(int source) { + auto it = videoSrcMap.find(source); + return (it != videoSrcMap.end()) ? it->second : ""; + } + + std::string AVOutputTV::convertVideoFormatToStringV2(int format) { + auto it = videoFormatMap.find(format); + return (it != videoFormatMap.end()) ? it->second : ""; + } + + std::string AVOutputTV::convertPictureIndexToStringV2(int pqmode) { + auto it = pqModeMap.find(pqmode); + return (it != pqModeMap.end()) ? it->second : ""; + } + uint32_t AVOutputTV::generateStorageIdentifierV2(std::string &key, std::string forParam, paramIndex_t info) + { + key += AVOUTPUT_GENERIC_STRING_RFC_PARAM; + key += STRING_SOURCE + convertSourceIndexToStringV2(info.sourceIndex) + "." + + STRING_PICMODE + convertPictureIndexToStringV2(info.pqmodeIndex) + "." + + STRING_FORMAT + convertVideoFormatToStringV2(info.formatIndex) + "." + + forParam; + return tvERROR_NONE; + } + + bool AVOutputTV::isValidSource(const std::vector& sourceArray, tvVideoSrcType_t sourceIndex) + { + // If "Current" is passed, match the current source + if (std::find(sourceArray.begin(), sourceArray.end(), "Current") != sourceArray.end()) { + tvVideoSrcType_t currentSource = VIDEO_SOURCE_IP; + GetCurrentVideoSource(¤tSource); + return (sourceIndex == currentSource); + } + + // Match against specific source strings + const std::string srcStr = convertSourceIndexToStringV2(sourceIndex); + return std::find(sourceArray.begin(), sourceArray.end(), srcStr) != sourceArray.end(); + } + + bool AVOutputTV::isValidFormat(const std::vector& formatArray, tvVideoFormatType_t formatIndex) + { + // If "Current" is passed, match the current format + if (std::find(formatArray.begin(), formatArray.end(), "Current") != formatArray.end()) { + tvVideoFormatType_t currentFormat = VIDEO_FORMAT_NONE; + GetCurrentVideoFormat(¤tFormat); + return (formatIndex == currentFormat); + } + + // Match against specific format strings + const std::string fmtStr = convertVideoFormatToStringV2(formatIndex); + return std::find(formatArray.begin(), formatArray.end(), fmtStr) != formatArray.end(); + } + + tvConfigContext_t AVOutputTV::getValidContextFromGetParameters(const JsonObject& parameters, const std::string& paramName) + { + tvConfigContext_t validContext = {PQ_MODE_INVALID, VIDEO_FORMAT_NONE, VIDEO_SOURCE_ALL}; + // Picture Mode + std::string pictureModeStr; + //"Current", empty string, or missing key as a cue to fetch system values + if (!parameters.HasLabel("pictureMode") || + (pictureModeStr = parameters["pictureMode"].String()).empty() || + pictureModeStr == "Current") + { + char picMode[PIC_MODE_NAME_MAX] = {0}; + getCurrentPictureMode(picMode); + std::string pictureModeStr(picMode); + LOGINFO("Current Picture Mode: %s", picMode); + validContext.pq_mode = static_cast( + pqModeReverseMap.count(pictureModeStr) ? pqModeReverseMap.at(pictureModeStr) : PQ_MODE_INVALID + ); + } + else + { + validContext.pq_mode = static_cast( + pqModeReverseMap.count(pictureModeStr) ? pqModeReverseMap.at(pictureModeStr) : PQ_MODE_INVALID + ); + } + // Video Format + std::string videoFormatStr; + if (!parameters.HasLabel("videoFormat") || + (videoFormatStr = parameters["videoFormat"].String()).empty() || + videoFormatStr == "Current") + { + GetCurrentVideoFormat(&validContext.videoFormatType); + } + else + { + validContext.videoFormatType = static_cast( + videoFormatReverseMap.count(videoFormatStr) ? videoFormatReverseMap.at(videoFormatStr) : VIDEO_FORMAT_NONE + ); + } + // Video Source + std::string videoSourceStr; + if (!parameters.HasLabel("videoSource") || + (videoSourceStr = parameters["videoSource"].String()).empty() || + videoSourceStr == "Current") + { + GetCurrentVideoSource(&validContext.videoSrcType); + } + else + { + validContext.videoSrcType = static_cast( + videoSrcReverseMap.count(videoSourceStr) ? videoSrcReverseMap.at(videoSourceStr) : VIDEO_SOURCE_ALL + ); + } + tvContextCaps_t* caps = getCapsForParam(paramName); + LOGINFO("Looking for context: PQMode=%d, Format=%d, Source=%d", + validContext.pq_mode, validContext.videoFormatType, validContext.videoSrcType); + // Match context if caps exist + if (caps && caps->num_contexts > 0) { + for (size_t i = 0; i < caps->num_contexts; ++i) { + const tvConfigContext_t& available = caps->contexts[i]; + + if (available.videoSrcType == validContext.videoSrcType && + available.videoFormatType == validContext.videoFormatType && + available.pq_mode == validContext.pq_mode) { + return available; // valid context found + } + } + } + LOGWARN("No valid context found for %s with provided parameters", paramName.c_str()); + validContext = {PQ_MODE_INVALID, VIDEO_FORMAT_NONE, VIDEO_SOURCE_ALL}; + return validContext; + } + + bool AVOutputTV::isGlobalParam(const JsonArray& arr) { + return (arr.Length() == 0) || + (arr.Length() == 1 && ( + arr[0].String() == "Global" || arr[0].String() == "none")); + } + + std::vector AVOutputTV::extractPQModes(const JsonObject& parameters) { + initializeReverseMaps(); + + std::vector pqModes; + if (!parameters.HasLabel("pictureMode")) { + return pqModes; + } + + JsonArray pqmodeArray = parameters["pictureMode"].Array(); + pqModes.reserve(pqmodeArray.Length()); // Pre-allocate + + for (uint32_t i = 0; i < pqmodeArray.Length(); ++i) { + std::string modeStr = pqmodeArray[i].String(); + + if (modeStr == "Current") { + char picMode[PIC_MODE_NAME_MAX] = {0}; + if (getCurrentPictureMode(picMode)) { + auto it = pqModeReverseMap.find(std::string(picMode)); + if (it != pqModeReverseMap.end()) { + pqModes.push_back(it->second); + } + } + } else { + auto it = pqModeReverseMap.find(modeStr); + if (it != pqModeReverseMap.end()) { + pqModes.push_back(it->second); + } + } + } + return pqModes; + } + + std::vector AVOutputTV::extractVideoSources(const JsonObject& parameters) { + initializeReverseMaps(); + + std::vector sources; + if (!parameters.HasLabel("videoSource")) { + return sources; + } + + JsonArray sourceArray = parameters["videoSource"].Array(); + sources.reserve(sourceArray.Length()); // Pre-allocate + + for (uint32_t i = 0; i < sourceArray.Length(); ++i) { + std::string srcStr = sourceArray[i].String(); + + if (srcStr == "Current") { + tvVideoSrcType_t sourceIndex = VIDEO_SOURCE_IP; + if (GetCurrentVideoSource(&sourceIndex) == tvERROR_NONE) { + sources.push_back(sourceIndex); + } + } else { + auto it = videoSrcReverseMap.find(srcStr); + if (it != videoSrcReverseMap.end()) { + sources.push_back(it->second); + } + } + } + return sources; + } + + std::vector AVOutputTV::extractVideoFormats(const JsonObject& parameters) { + initializeReverseMaps(); + + std::vector formats; + if (!parameters.HasLabel("videoFormat")) { + return formats; + } + + JsonArray formatArray = parameters["videoFormat"].Array(); + formats.reserve(formatArray.Length()); // Pre-allocate + + for (uint32_t i = 0; i < formatArray.Length(); ++i) { + std::string fmtStr = formatArray[i].String(); + + if (fmtStr == "Current") { + tvVideoFormatType_t formatIndex = VIDEO_FORMAT_NONE; + GetCurrentVideoFormat(&formatIndex); + if (formatIndex == VIDEO_FORMAT_NONE) { + formatIndex = VIDEO_FORMAT_SDR; + } + formats.push_back(formatIndex); + } else { + auto it = videoFormatReverseMap.find(fmtStr); + if (it != videoFormatReverseMap.end()) { + formats.push_back(it->second); + } + } + } + return formats; + } + + JsonArray AVOutputTV::getJsonArrayIfArray(const JsonObject& obj, const std::string& key) { + return (obj.HasLabel(key.c_str()) && obj[key.c_str()].Content() == JsonValue::type::ARRAY) + ? obj[key.c_str()].Array() + : JsonArray(); // returns empty array + } + + tvContextCaps_t* AVOutputTV::getCapsForParam(const std::string& paramName) + { + tvContextCaps_t* caps = nullptr; + if (paramName == "Backlight") caps = m_backlightCaps; + else if (paramName == "Brightness") caps = m_brightnessCaps; + else if (paramName == "Contrast") caps = m_contrastCaps; + else if (paramName == "Sharpness") caps = m_sharpnessCaps; + else if (paramName == "Saturation") caps = m_saturationCaps; + else if (paramName == "Hue") caps = m_hueCaps; + else if (paramName == "ColorTemp") caps = m_colortempCaps; + else if (paramName == "DimmingMode") caps = m_dimmingModeCaps; + else if (paramName == "PictureMode") caps = m_pictureModeCaps; + else if (paramName == "AspectRatio") caps = m_aspectRatioCaps; + else if (paramName == "LowLatencyState") caps = m_lowLatencyStateCaps; + else if (paramName == "PrecisionDetail") caps = m_precisionDetailCaps; + else if (paramName == "LocalContrastEnhancement") caps = m_localContrastEnhancementCaps; + else if (paramName == "MPEGNoiseReduction") caps = m_MPEGNoiseReductionCaps; + else if (paramName == "DigitalNoiseReduction") caps = m_digitalNoiseReductionCaps; + else if (paramName == "AISuperResolution") caps = m_AISuperResolutionCaps; + else if (paramName == "MEMC") caps = m_MEMCCaps; + else if (paramName == "BacklightMode") caps = m_backlightModeCaps; + else if (paramName == "CMS") caps = m_cmsCaps; + else { + LOGERR("Unknown ParamName: %s", paramName.c_str()); + return nullptr; + } + // Fallback to global pictureModeCaps if cap is empty + if (!caps || caps->num_contexts == 0) + caps = m_pictureModeCaps; + + return caps; + } + std::string AVOutputTV::getCurrentPictureModeAsString() { + char picMode[PIC_MODE_NAME_MAX] = {0}; + if (!getCurrentPictureMode(picMode)) { + LOGERR("Failed to get current picture mode"); + return ""; + } + return picMode; + } + + std::string AVOutputTV::getCurrentVideoSourceAsString() { + tvVideoSrcType_t sourceIndex = VIDEO_SOURCE_IP; + if (GetCurrentVideoSource(&sourceIndex) != tvERROR_NONE) { + LOGERR("GetCurrentVideoSource failed"); + return ""; + } + return convertSourceIndexToStringV2(sourceIndex); + } + + std::string AVOutputTV::getCurrentVideoFormatAsString() { + tvVideoFormatType_t formatIndex = VIDEO_FORMAT_NONE; + if (GetCurrentVideoFormat(&formatIndex) != tvERROR_NONE || formatIndex == VIDEO_FORMAT_NONE) { + formatIndex = VIDEO_FORMAT_SDR; + } + return convertVideoFormatToStringV2(formatIndex); + } - int AVOutputTV::ReadCapablitiesFromConf(std::string param, capDetails_t& info) + bool AVOutputTV::isSetRequiredForParam(const JsonObject& parameters, const std::string& paramName) + { + // Get current state once + const std::string curPicMode = getCurrentPictureModeAsString(); + const std::string curSource = getCurrentVideoSourceAsString(); + const std::string curFormat = getCurrentVideoFormatAsString(); + + // Helper to resolve a parameter to a list of effective values + auto resolveParam = [&](const std::string& label, const std::string& currentValue) -> std::vector { + std::vector result; + + if (!parameters.HasLabel(label.c_str())){ + result.push_back(currentValue); + return result; + } + + const auto& array = parameters[label.c_str()].Array(); + if (array.Length() == 0){ + result.push_back(currentValue); + return result; + } + + for (uint16_t i = 0; i < array.Length(); ++i) { + const std::string val = array[i].String(); + if (val == "Current" || val == "Global" || val == "none") { + result.push_back(currentValue); + } else { + result.push_back(val); + } + } + return result; + }; + + // Resolve all + const auto resolvedPicModes = resolveParam("pictureMode", curPicMode); + const auto resolvedFormats = resolveParam("videoFormat", curFormat); + const auto resolvedSources = resolveParam("videoSource", curSource); + + + // Check if current combination exists in resolved sets + for (const auto& pm : resolvedPicModes) { + if (pm != curPicMode) continue; + + for (const auto& fmt : resolvedFormats) { + if (fmt != curFormat) continue; + + for (const auto& src : resolvedSources) { + if (src == curSource) { + tvContextCaps_t* caps = getCapsForParam(paramName); + if (!caps) { + LOGERR("No caps found for param: %s", paramName.c_str()); + return false; + } + for (size_t i = 0; i < caps->num_contexts; ++i) { + const tvConfigContext_t& ctx = caps->contexts[i]; + std::string capPicMode = convertPictureIndexToStringV2(ctx.pq_mode); + std::string capSource = convertSourceIndexToStringV2(ctx.videoSrcType); + std::string capFormat = convertVideoFormatToStringV2(ctx.videoFormatType); + if ((capPicMode == curPicMode) && + (capSource == curSource) && + (capFormat == curFormat)) + { + // Log the matched combination + LOGINFO("isSetRequiredForParam: matched combination - pictureMode: %s, videoFormat: %s, videoSource: %s", + pm.c_str(), fmt.c_str(), src.c_str()); + return true; + } + } + } + } + } + } + + return false; + } + std::string AVOutputTV::getCMSNameFromEnum(tvDataComponentColor_t colorEnum) + { + switch (colorEnum) { + case tvDataColor_RED: return "Red"; + case tvDataColor_GREEN: return "Green"; + case tvDataColor_BLUE: return "Blue"; + case tvDataColor_CYAN: return "Cyan"; + case tvDataColor_YELLOW: return "Yellow"; + case tvDataColor_MAGENTA: return "Magenta"; + default: return "Unknown"; + } + } + std::vector AVOutputTV::getValidContextsFromParameters(const JsonObject& parameters, const std::string& tr181ParamName) + { + std::vector validContexts; + tvContextCaps_t* caps = getCapsForParam(tr181ParamName); + + if (caps == nullptr || caps->contexts == nullptr) { + LOGWARN("Caps or contexts is null for parameter: %s", tr181ParamName.c_str()); + return validContexts; + } + + // Create a hash set of available contexts for O(1) lookup instead of O(n) linear search + std::unordered_set availableContextsSet; + for (size_t i = 0; i < caps->num_contexts; ++i) { + const auto& ctx = caps->contexts[i]; + std::string key = std::to_string(ctx.pq_mode) + "_" + + std::to_string(ctx.videoFormatType) + "_" + + std::to_string(ctx.videoSrcType); + availableContextsSet.insert(key); + } + + JsonArray pqmodeArray = getJsonArrayIfArray(parameters, "pictureMode"); + JsonArray sourceArray = getJsonArrayIfArray(parameters, "videoSource"); + JsonArray formatArray = getJsonArrayIfArray(parameters, "videoFormat"); + + std::vector pqModes = extractPQModes(parameters); + std::vector sources = extractVideoSources(parameters); + std::vector formats = extractVideoFormats(parameters); + + // Handle global parameters - collect unique values to avoid duplicates + std::unordered_set pqModeSet(pqModes.begin(), pqModes.end()); + std::unordered_set sourceSet(sources.begin(), sources.end()); + std::unordered_set formatSet(formats.begin(), formats.end()); + + if (isGlobalParam(pqmodeArray)) { + for (size_t i = 0; i < caps->num_contexts; ++i) { + pqModeSet.insert(caps->contexts[i].pq_mode); + } + } + if (isGlobalParam(sourceArray)) { + for (size_t i = 0; i < caps->num_contexts; ++i) { + sourceSet.insert(caps->contexts[i].videoSrcType); + } + } + if (isGlobalParam(formatArray)) { + for (size_t i = 0; i < caps->num_contexts; ++i) { + formatSet.insert(caps->contexts[i].videoFormatType); + } + } + + if (pqModeSet.empty() || sourceSet.empty() || formatSet.empty()) { + LOGWARN("One or more parameter sets are empty: PQModes[%zu], Sources[%zu], Formats[%zu]", + pqModeSet.size(), sourceSet.size(), formatSet.size()); + return validContexts; + } + + std::unordered_set seenContexts; + validContexts.reserve(pqModeSet.size() * sourceSet.size() * formatSet.size()); // Pre-allocate memory + + // Generate contexts and check validity in single pass + for (const auto& pq : pqModeSet) { + for (const auto& fmt : formatSet) { + for (const auto& src : sourceSet) { + std::string contextKey = std::to_string(pq) + "_" + + std::to_string(fmt) + "_" + + std::to_string(src); + + if (seenContexts.find(contextKey) != seenContexts.end()) { + continue; + } + + if (availableContextsSet.find(contextKey) != availableContextsSet.end()) { + tvConfigContext_t testCtx = { pq, fmt, src }; + validContexts.push_back(testCtx); + seenContexts.insert(contextKey); + } + } + } + } + + // Sort only if we have results to sort + if (!validContexts.empty()) { + std::sort(validContexts.begin(), validContexts.end(), + [](const tvConfigContext_t& a, const tvConfigContext_t& b) { + return std::tie(a.pq_mode, a.videoFormatType, a.videoSrcType) < + std::tie(b.pq_mode, b.videoFormatType, b.videoSrcType); + }); + } + + return validContexts; + } + + int AVOutputTV::updateAVoutputTVParamV2(std::string action, std::string tr181ParamName, + const JsonObject& parameters, + tvPQParameterIndex_t pqParamIndex,int level) + { + LOGINFO("Entry %s: Action: %s, Param: %s, Level: %d", __FUNCTION__, action.c_str(), tr181ParamName.c_str(), level); + int ret = 0; + const bool isSet = (action == "set"); + const bool isReset = (action == "reset"); + const bool isSync = (action == "sync"); + + std::vector validContexts = getValidContextsFromParameters(parameters, tr181ParamName); + LOGINFO("%s: Number of validContexts = %zu", __FUNCTION__, validContexts.size()); + + if (validContexts.empty()) { + LOGWARN("%s: No valid contexts found for parameters", __FUNCTION__); + return (int)tvERROR_GENERAL; + } + if (tr181ParamName == "CMS") { + JsonArray colorArray = getJsonArrayIfArray(parameters, "color"); + JsonArray componentArray = getJsonArrayIfArray(parameters, "component"); + + std::vector colors, components; + + for (size_t i = 0; i < colorArray.Length(); ++i) + colors.emplace_back(colorArray[i].String()); + + for (size_t i = 0; i < componentArray.Length(); ++i) + components.emplace_back(componentArray[i].String()); + + if (colors.empty()) colors.push_back("Global"); + if (components.empty()) components.push_back("Global"); + + if (colors.size() == 1 && colors[0] == "Global") + colors = m_cmsColorList; + + if (components.size() == 1 && components[0] == "Global") + components = m_cmsComponentList; + + for (const auto& ctx : validContexts) { + for (const auto& colorStr : colors) { + for (const auto& componentStr : components) { + + tvPQParameterIndex_t pqIndex; + if (convertCMSParamToPQEnum(componentStr, colorStr, pqIndex) != 0) { + LOGERR("%s: convertCMSParamToPQEnum failed for color: %s, component: %s", + __FUNCTION__, colorStr.c_str(), componentStr.c_str()); + ret |= 1; + continue; + } + tvDataComponentColor_t colorValue = tvDataColor_NONE; + if ( getCMSColorEnumFromString(colorStr, colorValue ) == -1 ) { + LOGERR("%s : getCMSColorEnumFromString failed for color: %s", __FUNCTION__, colorStr.c_str()); + ret |= 2; + continue; + } + tvComponentType_t componentValue; + if ( getCMSComponentEnumFromString(componentStr, componentValue ) == -1 ) { + LOGERR("%s : getCMSComponentEnumFromString failed for component: %s", __FUNCTION__, componentStr.c_str()); + ret |= 4; + continue; + } + if (std::find(m_cmsColorList.begin(), m_cmsColorList.end(), colorStr) == m_cmsColorList.end()) { + LOGERR("%s: Color '%s' is not supported as per capabilities", __FUNCTION__, colorStr.c_str()); + ret |= 8; + continue; + } + if (std::find(m_cmsComponentList.begin(), m_cmsComponentList.end(), componentStr) == m_cmsComponentList.end()) { + LOGERR("%s: Component '%s' is not supported as per capabilities", __FUNCTION__, componentStr.c_str()); + ret |= 16; + continue; + } + paramIndex_t paramIndex; + paramIndex.sourceIndex = static_cast(ctx.videoSrcType); + paramIndex.pqmodeIndex = static_cast(ctx.pq_mode); + paramIndex.formatIndex = static_cast(ctx.videoFormatType); + paramIndex.componentIndex = static_cast(componentValue); + paramIndex.colorIndex = static_cast(colorValue); + paramIndex.colorTempIndex = 0; + paramIndex.controlIndex = 0; + + int value = 0; + if (isReset) { + ret |= updateAVoutputTVParamToHAL(tr181ParamName, paramIndex, 0, false); + level = 0; + } + + if (isSync || isReset) { + if (getLocalparam(tr181ParamName, paramIndex, value, pqIndex, isSync) == 0) { + level = value; + } else { + LOGWARN("%s: Skipping sync for color: %s, component: %s", + __FUNCTION__, colorStr.c_str(), componentStr.c_str()); + continue; + } + } + ret |= SaveCMS(static_cast(paramIndex.sourceIndex), + paramIndex.pqmodeIndex, + static_cast(paramIndex.formatIndex), + static_cast(paramIndex.componentIndex), + static_cast(paramIndex.colorIndex), + level); + + if (isSet) { + ret |= updateAVoutputTVParamToHAL(tr181ParamName, paramIndex, level, true); + } + } + } + } + LOGINFO("Exit: %s, Return Value: %d", __FUNCTION__, ret); + return (ret < 0) ? -1 : 0; + } + for (const auto& ctx : validContexts) + { + paramIndex_t paramIndex { + .sourceIndex = static_cast(ctx.videoSrcType), + .pqmodeIndex = static_cast(ctx.pq_mode), + .formatIndex = static_cast(ctx.videoFormatType) + }; + std::string pqStr = pqModeMap.count(ctx.pq_mode) ? pqModeMap.at(ctx.pq_mode) : std::to_string(ctx.pq_mode); + std::string fmtStr = videoFormatMap.count(ctx.videoFormatType) ? videoFormatMap.at(ctx.videoFormatType) : std::to_string(ctx.videoFormatType); + std::string srcStr = videoSrcMap.count(ctx.videoSrcType) ? videoSrcMap.at(ctx.videoSrcType) : std::to_string(ctx.videoSrcType); + + if (isSet) + { + ret |= updateAVoutputTVParamToHALV2(tr181ParamName, paramIndex, level, true); + } + else + { + if (isReset) + { + ret |= updateAVoutputTVParamToHALV2(tr181ParamName, paramIndex, level, false); + } + if(getLocalparam(tr181ParamName,paramIndex,level,pqParamIndex,isSync)) + { + continue; + } + } + switch (pqParamIndex) + { + case PQ_PARAM_BRIGHTNESS: + ret |= SaveBrightness((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,level); + break; + case PQ_PARAM_CONTRAST: + ret |= SaveContrast((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,level); + break; + case PQ_PARAM_SHARPNESS: + ret |= SaveSharpness((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,level); + break; + case PQ_PARAM_HUE: + ret |= SaveHue((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,level); + break; + case PQ_PARAM_SATURATION: + ret |= SaveSaturation((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,level); + break; + case PQ_PARAM_COLOR_TEMPERATURE: + ret |= SaveColorTemperature((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,(tvColorTemp_t)level); + break; + case PQ_PARAM_BACKLIGHT: + ret |= SaveBacklight((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,level); + break; + case PQ_PARAM_DIMMINGMODE: + ret |= SaveTVDimmingMode((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,(tvDimmingMode_t)level); + break; + case PQ_PARAM_LOWLATENCY_STATE: + ret |= SaveLowLatencyState((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,level); + break; + case PQ_PARAM_DOLBY_MODE: + ret |= SaveTVDolbyVisionMode((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,(tvDolbyMode_t)level); + break; + case PQ_PARAM_ASPECT_RATIO: + ret |= SaveAspectRatio((tvVideoSrcType_t)paramIndex.sourceIndex, paramIndex.pqmodeIndex,(tvVideoFormatType_t)paramIndex.formatIndex,(tvDisplayMode_t)level); + break; + case PQ_PARAM_PRECISION_DETAIL: + ret |= SetPrecisionDetail((tvVideoSrcType_t)paramIndex.sourceIndex, + (tvPQModeIndex_t)paramIndex.pqmodeIndex, + (tvVideoFormatType_t)paramIndex.formatIndex, + level); + break; + + case PQ_PARAM_LOCAL_CONTRAST_ENHANCEMENT: + ret |= SetLocalContrastEnhancement((tvVideoSrcType_t)paramIndex.sourceIndex, + (tvPQModeIndex_t)paramIndex.pqmodeIndex, + (tvVideoFormatType_t)paramIndex.formatIndex, + level); + break; + + case PQ_PARAM_MPEG_NOISE_REDUCTION: + ret |= SetMPEGNoiseReduction((tvVideoSrcType_t)paramIndex.sourceIndex, + (tvPQModeIndex_t)paramIndex.pqmodeIndex, + (tvVideoFormatType_t)paramIndex.formatIndex, + level); + break; + + case PQ_PARAM_DIGITAL_NOISE_REDUCTION: + ret |= SetDigitalNoiseReduction((tvVideoSrcType_t)paramIndex.sourceIndex, + (tvPQModeIndex_t)paramIndex.pqmodeIndex, + (tvVideoFormatType_t)paramIndex.formatIndex, + level); + break; + + case PQ_PARAM_AI_SUPER_RESOLUTION: + ret |= SetAISuperResolution((tvVideoSrcType_t)paramIndex.sourceIndex, + (tvPQModeIndex_t)paramIndex.pqmodeIndex, + (tvVideoFormatType_t)paramIndex.formatIndex, + level); + break; + + case PQ_PARAM_MEMC: + ret |= SetMEMC((tvVideoSrcType_t)paramIndex.sourceIndex, + (tvPQModeIndex_t)paramIndex.pqmodeIndex, + (tvVideoFormatType_t)paramIndex.formatIndex, + level); + break; + case PQ_PARAM_BACKLIGHT_MODE: + ret |= SaveBacklightMode((tvVideoSrcType_t)paramIndex.sourceIndex, + (tvPQModeIndex_t)paramIndex.pqmodeIndex, + (tvVideoFormatType_t)paramIndex.formatIndex, + static_cast(level)); + break; + case PQ_PARAM_HDR10_MODE: + case PQ_PARAM_HLG_MODE: + case PQ_PARAM_LDIM: + case PQ_PARAM_LOCALDIMMING_LEVEL: + + case PQ_PARAM_WB_GAIN_RED: + case PQ_PARAM_WB_GAIN_GREEN: + case PQ_PARAM_WB_GAIN_BLUE: + case PQ_PARAM_WB_OFFSET_RED: + case PQ_PARAM_WB_OFFSET_GREEN: + case PQ_PARAM_WB_OFFSET_BLUE: + // TODO: Add implementation + break; + + default: + // Prevent compiler warning for unhandled enums + LOGWARN("Unhandled PQ parameter index: %d", pqParamIndex); + break; + } + } + LOGINFO("Exit: %s, Return Value: %d", __FUNCTION__, ret); + return ret; + } + + int AVOutputTV::ReadCapablitiesFromConf(std::string param, capDetails_t& info) { int ret = 0; @@ -2372,7 +3448,6 @@ namespace Plugin { } return ret; } - bool AVOutputTV::checkCMSColorAndComponentCapability(const std::string capValue, const std::string inputValue) { // Parse capValue into a set std::set capSet; diff --git a/AVOutput/CHANGELOG.md b/AVOutput/CHANGELOG.md index e5f68a0f..774b8127 100644 --- a/AVOutput/CHANGELOG.md +++ b/AVOutput/CHANGELOG.md @@ -13,6 +13,9 @@ All notable changes to this RDK Service will be documented in this file. * **Security** in case of vulnerabilities. * Changes in CHANGELOG should be updated when commits are added to the main or release branches. There should be one CHANGELOG entry per JIRA Ticket. This is not enforced on sprint branches since there could be multiple changes for the same JIRA ticket during development. +## [1.2.0] - 2025-06-25 +### Added +- Advance PQ Params ## [1.1.2] - 2025-07-01 ### Fixed From cb1cc9845d89e37f147be5dfc831ddf5dae1f6c9 Mon Sep 17 00:00:00 2001 From: skk451 Date: Mon, 4 Aug 2025 11:08:32 +0100 Subject: [PATCH 02/11] Fix the lookup in syncAvoutputTVPQModeParamsToHALV2 --- AVOutput/AVOutputTVHelper.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index 41a32bb5..971de2a1 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -1438,11 +1438,13 @@ namespace Plugin { std::string modeStr = param.value; int modeIndex = -1; - for (size_t i = 0; i < m_numPictureModes; ++i) { - if (pqModeMap.at(m_pictureModes[i]) == modeStr) { - modeIndex = static_cast(i); - break; - } + initializeReverseMaps(); + auto it = pqModeReverseMap.find(modeStr); + if (it != pqModeReverseMap.end()) { + modeIndex = static_cast(it->second); + } else { + LOGWARN("Mode string %s not found in pqModeReverseMap", modeStr.c_str()); + continue; } tvError_t tv_err = SaveSourcePictureMode(ctx.videoSrcType, ctx.videoFormatType, modeIndex); From 431bb3c51edb9d4b166118c197d61c1ca346f868 Mon Sep 17 00:00:00 2001 From: skk451 Date: Tue, 5 Aug 2025 18:17:14 +0100 Subject: [PATCH 03/11] RDKEMW-5202: SDRGamma APIs addition --- AVOutput/AVOutputTV.cpp | 79 ++++++++++++++++++++ AVOutput/AVOutputTV.h | 11 ++- AVOutput/AVOutputTVHelper.cpp | 134 ++++++++++++++++++++++++++++++---- 3 files changed, 206 insertions(+), 18 deletions(-) diff --git a/AVOutput/AVOutputTV.cpp b/AVOutput/AVOutputTV.cpp index 34ff9c82..e282e27d 100644 --- a/AVOutput/AVOutputTV.cpp +++ b/AVOutput/AVOutputTV.cpp @@ -374,6 +374,9 @@ namespace Plugin { registerMethod("getCMSCapsV2", &AVOutputTV::getCMSCapsV2, this); registerMethod("get2PointWBCapsV2", &AVOutputTV::get2PointWBCapsV2, this); registerMethod("getSDRGammaCaps", &AVOutputTV::getSDRGammaCaps, this); + registerMethod("getSDRGamma", &AVOutputTV::getSDRGamma, this); + registerMethod("setSDRGamma", &AVOutputTV::setSDRGamma, this); + registerMethod("resetSDRGamma", &AVOutputTV::resetSDRGamma, this); registerMethod("getPrecisionDetailCaps", &AVOutputTV::getPrecisionDetailCaps, this); registerMethod("getPrecisionDetail", &AVOutputTV::getPrecisionDetail, this); @@ -1027,6 +1030,31 @@ namespace Plugin { {tvColorTemp_BOOST_SUPERCOLD, "BoostSupercold"} }; + // Forward lookup: string → enum + const std::unordered_map sdrGammaMap = { + {"1.8", tvSdrGamma_1_8}, + {"1.9", tvSdrGamma_1_9}, + {"2.0", tvSdrGamma_2_0}, + {"2.1", tvSdrGamma_2_1}, + {"2.2", tvSdrGamma_2_2}, + {"2.3", tvSdrGamma_2_3}, + {"2.4", tvSdrGamma_2_4}, + {"BT.1886", tvSdrGamma_BT_1886} + }; + + // Reverse lookup: enum → string + const std::unordered_map sdrGammaReverseMap = { + {tvSdrGamma_1_8, "1.8"}, + {tvSdrGamma_1_9, "1.9"}, + {tvSdrGamma_2_0, "2.0"}, + {tvSdrGamma_2_1, "2.1"}, + {tvSdrGamma_2_2, "2.2"}, + {tvSdrGamma_2_3, "2.3"}, + {tvSdrGamma_2_4, "2.4"}, + {tvSdrGamma_BT_1886, "BT.1886"} + }; + + uint32_t AVOutputTV::getColorTemperatureCapsV2(const JsonObject& parameters, JsonObject& response) { tvColorTemp_t* color_temp = nullptr; size_t num_color_temp = 0; @@ -3706,6 +3734,57 @@ namespace Plugin { } } + uint32_t AVOutputTV::getSDRGamma(const JsonObject& parameters, JsonObject& response) + { + std::string outMode; + + // Make a copy of parameters and inject videoFormat = "SDR" + JsonObject updatedParams; + JsonObject::Iterator it = parameters.Variants(); + while (it.Next()) { + updatedParams[it.Label()] = it.Current(); + } + updatedParams["videoFormat"] = "SDR"; + + if (getEnumPQParamString(updatedParams, "SDRGamma", + PQ_PARAM_SDR_GAMMA, sdrGammaReverseMap, outMode)) { + response["SDRGamma"] = outMode; + returnResponse(true); + } else { + LOGERR("Failed to retrieve SDRGamma value"); + returnResponse(false); + } + } + + uint32_t AVOutputTV::setSDRGamma(const JsonObject& parameters, JsonObject& response) + { + if (m_sdrGammaModeStatus != tvERROR_NONE) { + LOGERR("SDRGamma not supported"); + returnResponse(false); + } + return setContextPQParam( + parameters, response, + "sdrGamma", "SDRGamma", + tvSdrGamma_MAX, + PQ_PARAM_SDR_GAMMA, + [](tvVideoSrcType_t src, tvPQModeIndex_t mode, tvVideoFormatType_t /*fmt*/, int val) { + return SetSdrGamma(src, mode, static_cast(val)); + } + ); + } + uint32_t AVOutputTV::resetSDRGamma(const JsonObject& parameters, JsonObject& response) + { + bool success = resetPQParamToDefault( + parameters, + "SDRGamma", + PQ_PARAM_SDR_GAMMA, + [](tvVideoSrcType_t src, tvPQModeIndex_t mode, tvVideoFormatType_t /*fmt*/, int val) { + return SetSdrGamma(src, mode, static_cast(val)); + } + ); + returnResponse(success); + } + uint32_t AVOutputTV::getSupportedDolbyVisionModes(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); diff --git a/AVOutput/AVOutputTV.h b/AVOutput/AVOutputTV.h index e383b330..59a5f878 100644 --- a/AVOutput/AVOutputTV.h +++ b/AVOutput/AVOutputTV.h @@ -209,7 +209,7 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(getMPEGNoiseReduction) DECLARE_JSON_RPC_METHOD(getDigitalNoiseReduction) DECLARE_JSON_RPC_METHOD(getMEMC) - + DECLARE_JSON_RPC_METHOD(getSDRGamma) /*Get Capability API's*/ @@ -282,7 +282,7 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(setMPEGNoiseReduction) DECLARE_JSON_RPC_METHOD(setDigitalNoiseReduction) DECLARE_JSON_RPC_METHOD(setMEMC) - + DECLARE_JSON_RPC_METHOD(setSDRGamma) /*Reset API's*/ DECLARE_JSON_RPC_METHOD(resetBacklight) DECLARE_JSON_RPC_METHOD(resetBrightness ) @@ -306,7 +306,7 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(resetMPEGNoiseReduction) DECLARE_JSON_RPC_METHOD(resetDigitalNoiseReduction) DECLARE_JSON_RPC_METHOD(resetMEMC) - + DECLARE_JSON_RPC_METHOD(resetSDRGamma) private: @@ -597,6 +597,7 @@ class AVOutputTV : public AVOutputBase { size_t m_numsdrGammaModes = 0; tvContextCaps_t* m_sdrGammaModeCaps = nullptr; tvError_t m_sdrGammaModeStatus = tvERROR_NONE; + void getSdrGammaStringFromEnum(tvSdrGamma_t value, std::string& str); int m_numHalMatrixPoints = 0; int m_rgbMin = 0; @@ -629,10 +630,12 @@ class AVOutputTV : public AVOutputBase { std::string convertPictureIndexToStringV2(int pqmode); std::string convertVideoFormatToStringV2(int format); std::string convertSourceIndexToStringV2(int source); + static tvPQModeIndex_t convertPictureStringToIndexV2(const std::string& modeStr); + static tvVideoSrcType_t convertSourceStringToIndexV2(const std::string& srcStr); + static tvVideoFormatType_t convertVideoFormatStringToIndexV2(const std::string& fmtStr); uint32_t generateStorageIdentifierV2(std::string &key, std::string forParam, paramIndex_t info); void generateStorageIdentifierCMSV2(std::string &key, std::string forParam, paramIndex_t info); - void generateStorageIdentifierWBV2(std::string &key, std::string forParam, paramIndex_t info); AVOutputTV(); ~AVOutputTV(); diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index 971de2a1..6a27e158 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -908,8 +908,9 @@ namespace Plugin { // Generate storage key based on parameter type if (forParam == "CMS") generateStorageIdentifierCMS(key, forParam, indexInfo); - else if (forParam == "WhiteBalance") - generateStorageIdentifierWB(key, forParam, indexInfo); + else if (forParam.compare("WhiteBalance") == 0) { + generateStorageIdentifierWB(key, forParam, indexInfo); + } else generateStorageIdentifierV2(key, forParam, indexInfo); @@ -928,7 +929,8 @@ namespace Plugin { {"ColorTemp", [this](int v, std::string& s) { getColorTempStringFromEnum(v, s); }}, {"DimmingMode", [this](int v, std::string& s) { getDimmingModeStringFromEnum(v, s); }}, {"AspectRatio", [this](int v, std::string& s) { getDisplayModeStringFromEnum(v, s); }}, - {"BacklightMode", [this](int v, std::string& s) { getBacklightModeStringFromEnum(v, s); }} + {"BacklightMode", [this](int v, std::string& s) { getBacklightModeStringFromEnum(v, s); }}, + {"SDRGamma", [this](int v, std::string& s) { getSdrGammaStringFromEnum(static_cast(v), s); }} }; // If there's a custom string conversion for this parameter, apply it @@ -1319,7 +1321,7 @@ namespace Plugin { } // PrecisionDetail m_precisionDetailStatus = GetPrecisionDetailCaps(&m_maxPrecisionDetail, &m_precisionDetailCaps); - if (m_localContrastEnhancementStatus == tvERROR_NONE) { + if (m_precisionDetailStatus == tvERROR_NONE) { updateAVoutputTVParamV2("sync", "PrecisionDetails", paramJson, PQ_PARAM_PRECISION_DETAIL, level); } //PictureMode @@ -1354,7 +1356,11 @@ namespace Plugin { if (m_MEMCStatus == tvERROR_NONE) { updateAVoutputTVParamV2("sync", "MEMC", paramJson, PQ_PARAM_MEMC, level); } - + m_sdrGammaModeStatus = GetSdrGammaCaps(&m_sdrGammaModes, &m_numsdrGammaModes, &m_sdrGammaModeCaps); + if (m_sdrGammaModeStatus == tvERROR_NONE) { + updateAVoutputTVParamV2("sync", "SDRGamma", paramJson, PQ_PARAM_SDR_GAMMA, level); + } + //Commented due to missing HAL implementation /*m_cmsStatus = GetCMSCaps(&m_maxCmsHue, &m_maxCmsSaturation, &m_maxCmsLuma, &m_cmsColorArr, &m_cmsComponentArr, @@ -1539,8 +1545,6 @@ namespace Plugin { return tvERROR_NONE; } - - uint32_t AVOutputTV::generateStorageIdentifierDirty(std::string &key, std::string forParam,uint32_t contentFormat, int pqmode) { key+=std::string(AVOUTPUT_GENERIC_STRING_RFC_PARAM); @@ -1680,13 +1684,15 @@ namespace Plugin { { string key; TR181_ParamData_t param={0}; - - if( forParam.compare("CMS") == 0 ) { - generateStorageIdentifierCMS(key,forParam,indexInfo); - } else if( forParam.compare("WhiteBalance") == 0 ) { - generateStorageIdentifierWB(key,forParam,indexInfo); - } else { - generateStorageIdentifierV2(key,forParam,indexInfo); + + if (forParam.compare("CMS") == 0) { + generateStorageIdentifierCMS(key, forParam, indexInfo); + } + else if (forParam.compare("WhiteBalance") == 0) { + generateStorageIdentifierWB(key, forParam, indexInfo); + } + else { + generateStorageIdentifierV2(key, forParam, indexInfo); } if(key.empty()) { @@ -1778,6 +1784,33 @@ namespace Plugin { } return 0; } + else if (forParam.compare("SDRGamma") == 0) { + if (strncmp(param.value, "1.8", strlen(param.value)) == 0) { + value = tvSdrGamma_1_8; + } + else if (strncmp(param.value, "1.9", strlen(param.value)) == 0) { + value = tvSdrGamma_1_9; + } + else if (strncmp(param.value, "2.0", strlen(param.value)) == 0) { + value = tvSdrGamma_2_0; + } + else if (strncmp(param.value, "2.1", strlen(param.value)) == 0) { + value = tvSdrGamma_2_1; + } + else if (strncmp(param.value, "2.2", strlen(param.value)) == 0) { + value = tvSdrGamma_2_2; + } + else if (strncmp(param.value, "2.3", strlen(param.value)) == 0) { + value = tvSdrGamma_2_3; + } + else if (strncmp(param.value, "2.4", strlen(param.value)) == 0) { + value = tvSdrGamma_2_4; + } + else if (strncmp(param.value, "BT.1886", strlen(param.value)) == 0) { + value = tvSdrGamma_BT_1886; + } + return 0; + } else { value=std::stoi(param.value); return 0; @@ -1932,6 +1965,42 @@ namespace Plugin { } } + void AVOutputTV::getSdrGammaStringFromEnum(tvSdrGamma_t value, std::string& str) + { + switch (value) + { + case tvSdrGamma_1_8: + str = "1.8"; + break; + case tvSdrGamma_1_9: + str = "1.9"; + break; + case tvSdrGamma_2_0: + str = "2.0"; + break; + case tvSdrGamma_2_1: + str = "2.1"; + break; + case tvSdrGamma_2_2: + str = "2.2"; + break; + case tvSdrGamma_2_3: + str = "2.3"; + break; + case tvSdrGamma_2_4: + str = "2.4"; + break; + case tvSdrGamma_BT_1886: + str = "BT.1886"; + break; + case tvSdrGamma_INVALID: + default: + str = "Unknown"; + LOGERR("Invalid or unsupported SDR Gamma enum: %d", value); + break; + } + } + int AVOutputTV::getCurrentPictureMode(char *picMode) { tvError_t ret = tvERROR_NONE; @@ -2651,6 +2720,37 @@ namespace Plugin { auto it = pqModeMap.find(pqmode); return (it != pqModeMap.end()) ? it->second : ""; } + + tvPQModeIndex_t AVOutputTV::convertPictureStringToIndexV2(const std::string& modeStr) { + initializeReverseMaps(); + auto it = pqModeReverseMap.find(modeStr); + if (it != pqModeReverseMap.end()) { + return it->second; + } + LOGERR("Unknown Picture Mode string: %s", modeStr.c_str()); + return PQ_MODE_MAX; + } + + tvVideoSrcType_t AVOutputTV::convertSourceStringToIndexV2(const std::string& srcStr) { + initializeReverseMaps(); + auto it = videoSrcReverseMap.find(srcStr); + if (it != videoSrcReverseMap.end()) { + return it->second; + } + LOGERR("Unknown Video Source string: %s", srcStr.c_str()); + return VIDEO_SOURCE_MAX; + } + + tvVideoFormatType_t AVOutputTV::convertVideoFormatStringToIndexV2(const std::string& fmtStr) { + initializeReverseMaps(); + auto it = videoFormatReverseMap.find(fmtStr); + if (it != videoFormatReverseMap.end()) { + return it->second; + } + LOGERR("Unknown Video Format string: %s", fmtStr.c_str()); + return VIDEO_FORMAT_NONE; + } + uint32_t AVOutputTV::generateStorageIdentifierV2(std::string &key, std::string forParam, paramIndex_t info) { key += AVOUTPUT_GENERIC_STRING_RFC_PARAM; @@ -2887,6 +2987,7 @@ namespace Plugin { else if (paramName == "MEMC") caps = m_MEMCCaps; else if (paramName == "BacklightMode") caps = m_backlightModeCaps; else if (paramName == "CMS") caps = m_cmsCaps; + else if (paramName == "SDRGamma") caps = m_sdrGammaModeCaps; else { LOGERR("Unknown ParamName: %s", paramName.c_str()); return nullptr; @@ -3314,6 +3415,11 @@ namespace Plugin { (tvVideoFormatType_t)paramIndex.formatIndex, level); break; + case PQ_PARAM_SDR_GAMMA: + ret |= SetSdrGamma((tvVideoSrcType_t)paramIndex.sourceIndex, + (tvPQModeIndex_t)paramIndex.pqmodeIndex, + static_cast(level)); + break; case PQ_PARAM_BACKLIGHT_MODE: ret |= SaveBacklightMode((tvVideoSrcType_t)paramIndex.sourceIndex, (tvPQModeIndex_t)paramIndex.pqmodeIndex, From c93ff09cd5ce06e5057d29839bff822da4b107d1 Mon Sep 17 00:00:00 2001 From: aktamilbe <59253707+aktamilbe@users.noreply.github.com> Date: Thu, 7 Aug 2025 05:22:40 +0100 Subject: [PATCH 04/11] RDKEMW-5197 : Corrected DimmingMode index issues --- AVOutput/AVOutputTVHelper.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index 6a27e158..a0888ae5 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -296,13 +296,13 @@ namespace Plugin { { tvDimmingMode_t index = tvDimmingMode_MAX; - if(mode.compare("local") == 0 ) { + if(mode.compare("Local") == 0 ) { index=tvDimmingMode_Local; } - else if(mode.compare("fixed") == 0 ) { + else if(mode.compare("Fixed") == 0 ) { index=tvDimmingMode_Fixed; } - else if(mode.compare("global") == 0 ) { + else if(mode.compare("Global") == 0 ) { index=tvDimmingMode_Global; } else { @@ -1455,7 +1455,7 @@ namespace Plugin { tvError_t tv_err = SaveSourcePictureMode(ctx.videoSrcType, ctx.videoFormatType, modeIndex); if (tv_err != tvERROR_NONE) { - LOGWARN("Failed SaveSourcePictureMode for %s / %s\n", sourceStr.c_str(), formatStr.c_str()); + LOGWARN("Failed SaveSourcePictureMode for %s / %s : %d \n", sourceStr.c_str(), formatStr.c_str(),modeIndex); continue; } From c36377ef90fa31047b024c88745e0f878f23e05e Mon Sep 17 00:00:00 2001 From: skk451 Date: Thu, 7 Aug 2025 12:24:40 +0100 Subject: [PATCH 05/11] Fix zoomMode error and resetLowlatencystate failures --- AVOutput/AVOutputTV.cpp | 84 +++++++++++++++++++---------------- AVOutput/AVOutputTVHelper.cpp | 2 +- 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/AVOutput/AVOutputTV.cpp b/AVOutput/AVOutputTV.cpp index e282e27d..43ac8801 100644 --- a/AVOutput/AVOutputTV.cpp +++ b/AVOutput/AVOutputTV.cpp @@ -4842,51 +4842,59 @@ namespace Plugin { uint32_t AVOutputTV::resetLowLatencyState(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); + if(m_lowLatencyStateStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + paramIndex_t indexInfo; + int lowlatencystate=0; + tvError_t ret = tvERROR_NONE; - capDetails_t inputInfo; - paramIndex_t indexInfo; - int lowlatencystate=0; - tvError_t ret = tvERROR_NONE; - - if (parsingSetInputArgument(parameters, "LowLatencyState", inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "LowLatencyState", inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "LowLatencyState" , inputInfo )) { - LOGERR("%s: CapablityCheck failed for LowLatencyState\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "LowLatencyState" , inputInfo )) { + LOGERR("%s: CapablityCheck failed for LowLatencyState\n", __FUNCTION__); + returnResponse(false); + } - int retval= updateAVoutputTVParam("reset","LowLatencyState", inputInfo,PQ_PARAM_LOWLATENCY_STATE,lowlatencystate); - if(retval != 0 ) { - LOGERR("Failed to clear Lowlatency from ssmdata and localstore\n"); - returnResponse(false); - } - else { - if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { - inputInfo.pqmode = "Current"; - inputInfo.source = "Current"; - inputInfo.format = "Current"; - getParamIndex("LowLatencyState",inputInfo, indexInfo); - int err = getLocalparam("LowLatencyState",indexInfo, lowlatencystate, PQ_PARAM_LOWLATENCY_STATE); - if( err == 0 ) { - LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex, lowlatencystate); - ret = SetLowLatencyState(lowlatencystate); - } - else { - LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); - ret = tvERROR_GENERAL; + int retval= updateAVoutputTVParam("reset","LowLatencyState", inputInfo,PQ_PARAM_LOWLATENCY_STATE,lowlatencystate); + if(retval != 0 ) { + LOGERR("Failed to clear Lowlatency from ssmdata and localstore\n"); + returnResponse(false); + } + else { + if (isSetRequired(inputInfo.pqmode,inputInfo.source,inputInfo.format)) { + inputInfo.pqmode = "Current"; + inputInfo.source = "Current"; + inputInfo.format = "Current"; + getParamIndex("LowLatencyState",inputInfo, indexInfo); + int err = getLocalparam("LowLatencyState",indexInfo, lowlatencystate, PQ_PARAM_LOWLATENCY_STATE); + if( err == 0 ) { + LOGINFO("%s : getLocalparam success format :%d source : %d format : %d value : %d\n",__FUNCTION__,indexInfo.formatIndex, indexInfo.sourceIndex, indexInfo.pqmodeIndex, lowlatencystate); + ret = SetLowLatencyState(lowlatencystate); + } + else { + LOGERR("%s : GetLocalParam Failed \n",__FUNCTION__); + ret = tvERROR_GENERAL; + } } } - } - if(ret != tvERROR_NONE) { - returnResponse(false); + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetLowLatency Successful to value : %d \n",lowlatencystate); + returnResponse(true); + } } - else { - LOGINFO("Exit : resetLowLatency Successful to value : %d \n",lowlatencystate); - returnResponse(true); + else + { + bool success = resetPQParamToDefault(parameters, "LowLatencyState", + PQ_PARAM_LOWLATENCY_STATE, SetLowLatencyState); + returnResponse(success); } } diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index a0888ae5..df9a0c0c 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -2289,7 +2289,7 @@ namespace Plugin { LOGINFO("Aspect Ratio initialized successfully, value: %s\n", param.value); } else { - updateAVoutputTVParamV2("set", "ZoomMode", paramJson, PQ_PARAM_ASPECT_RATIO,mode); + updateAVoutputTVParamV2("set", "AspectRatio", paramJson, PQ_PARAM_ASPECT_RATIO,mode); } } From 33e92e9c47c2f65bd2b9e2701b5219e06fadb809 Mon Sep 17 00:00:00 2001 From: skk451 Date: Fri, 8 Aug 2025 07:11:06 +0100 Subject: [PATCH 06/11] RDKEMW-5201: Dolby end user calibration --- AVOutput/AVOutputTV.cpp | 165 +++++++++++++++- AVOutput/AVOutputTV.h | 31 ++- AVOutput/AVOutputTVHelper.cpp | 358 +++++++++++++++++++++++++++++++++- 3 files changed, 545 insertions(+), 9 deletions(-) diff --git a/AVOutput/AVOutputTV.cpp b/AVOutput/AVOutputTV.cpp index 43ac8801..12d0dcf9 100644 --- a/AVOutput/AVOutputTV.cpp +++ b/AVOutput/AVOutputTV.cpp @@ -368,11 +368,17 @@ namespace Plugin { registerMethod("getColorTemperatureCapsV2", &AVOutputTV::getColorTemperatureCapsV2, this); registerMethod("getBacklightDimmingModeCapsV2", &AVOutputTV::getBacklightDimmingModeCapsV2, this); registerMethod("getZoomModeCapsV2", &AVOutputTV::getZoomModeCapsV2, this); - registerMethod("getDolbyVisionCalibrationCaps", &AVOutputTV::getDolbyVisionCalibrationCaps, this); registerMethod("getPictureModeCapsV2", &AVOutputTV::getPictureModeCapsV2, this); registerMethod("getAutoBacklightModeCapsV2", &AVOutputTV::getAutoBacklightModeCapsV2, this); registerMethod("getCMSCapsV2", &AVOutputTV::getCMSCapsV2, this); registerMethod("get2PointWBCapsV2", &AVOutputTV::get2PointWBCapsV2, this); + + registerMethod("getDolbyVisionCalibrationCaps", &AVOutputTV::getDolbyVisionCalibrationCaps, this); + registerMethod("getDolbyVisionCalibration", &AVOutputTV::getDolbyVisionCalibration, this); + registerMethod("setDolbyVisionCalibration", &AVOutputTV::setDolbyVisionCalibration, this); + registerMethod("resetDolbyVisionCalibration", &AVOutputTV::resetDolbyVisionCalibration, this); + + registerMethod("getSDRGammaCaps", &AVOutputTV::getSDRGammaCaps, this); registerMethod("getSDRGamma", &AVOutputTV::getSDRGamma, this); registerMethod("setSDRGamma", &AVOutputTV::setSDRGamma, this); @@ -1215,6 +1221,48 @@ namespace Plugin { uint32_t AVOutputTV::getDolbyVisionCalibrationCaps(const JsonObject& parameters, JsonObject& response) { + tvDVCalibrationSettings_t* min_values = nullptr; + tvDVCalibrationSettings_t* max_values = nullptr; + tvDVCalibrationComponent_t* component = nullptr; + size_t num_component = 0; + tvContextCaps_t* context_caps = nullptr; + + if (GetDVCalibrationCaps(&min_values, &max_values, &component, &num_component, &context_caps) != tvERROR_NONE) { + returnResponse(false); + } + + response["platformSupport"] = true; + + // Add ranges + response["rangeTmax"] = JsonObject({{"from", min_values->Tmax}, {"to", max_values->Tmax}}); + response["rangeTmin"] = JsonObject({{"from", min_values->Tmin}, {"to", max_values->Tmin}}); + response["rangeTgamma"] = JsonObject({{"from", min_values->Tgamma}, {"to", max_values->Tgamma}}); + response["rangeRx"] = JsonObject({{"from", min_values->Rx}, {"to", max_values->Rx}}); + response["rangeRy"] = JsonObject({{"from", min_values->Ry}, {"to", max_values->Ry}}); + response["rangeGx"] = JsonObject({{"from", min_values->Gx}, {"to", max_values->Gx}}); + response["rangeGy"] = JsonObject({{"from", min_values->Gy}, {"to", max_values->Gy}}); + response["rangeBx"] = JsonObject({{"from", min_values->Bx}, {"to", max_values->Bx}}); + response["rangeBy"] = JsonObject({{"from", min_values->By}, {"to", max_values->By}}); + response["rangeWx"] = JsonObject({{"from", min_values->Wx}, {"to", max_values->Wx}}); + response["rangeWy"] = JsonObject({{"from", min_values->Wy}, {"to", max_values->Wy}}); + + // Add component list + JsonArray componentArr; + for (size_t i = 0; i < num_component; ++i) { + componentArr.Add(dvComponentToString(component[i])); // Add string mapping if component is enum + } + response["component"] = componentArr; + + // Add context information + response["context"] = parseContextCaps(context_caps); + + #if HAL_NOT_READY + delete min_values; + delete max_values; + delete[] component; + delete[] context_caps; + #endif + returnResponse(true); } @@ -5394,6 +5442,121 @@ namespace Plugin { returnResponse(true); } } + static const std::vector kDVCalibrationComponents = { + "tmax", "tmin", "tgamma", "rx", "ry", "gx", "gy", "bx", "by", "wx", "wy" + }; + uint32_t AVOutputTV::getDolbyVisionCalibration(const JsonObject& parameters, JsonObject& response) + { + if (!m_isDVCalibrationPlatformSupported) returnResponse(false); + + tvConfigContext_t ctx = getValidContextFromGetParameters(parameters, "DolbyVisionCalibration"); + if (ctx.pq_mode == PQ_MODE_INVALID) returnResponse(false); + + JsonObject calib; + paramIndex_t indexInfo = { static_cast(ctx.videoSrcType), + static_cast(ctx.pq_mode), + static_cast(ctx.videoFormatType) + }; + for (const auto& comp : kDVCalibrationComponents) { + double val = 0.0; + if (getDVCalibrationParam("DolbyVisionCalibration", indexInfo, val, comp) == tvERROR_NONE) { + calib[comp.c_str()] = val; + } + } + + std::string pq = convertPictureIndexToStringV2(indexInfo.pqmodeIndex); + std::string src = convertSourceIndexToStringV2(indexInfo.sourceIndex); + std::string fmt = convertVideoFormatToStringV2(indexInfo.formatIndex); + uint64_t ts = getLastDVCalibrationSetTimestamp(pq, src, fmt); + response = calib; + response["utcTimestamp"] = static_cast(ts); + response["success"] = true; + returnResponse(true); + } + + uint32_t AVOutputTV::setDolbyVisionCalibration(const JsonObject& parameters, JsonObject& response) + { + if (!m_isDVCalibrationPlatformSupported) { + LOGERR("DV Calibration not supported on this platform"); + returnResponse(false); + } + + // Extract valid contexts + std::vector contexts = getValidContextsFromParameters(parameters, "DolbyVisionCalibration"); + if (contexts.empty()) { + LOGERR("No valid context found for DV Calibration"); + returnResponse(false); + } + + // Validate and parse timestamp + if (!parameters.HasLabel("utcTimestamp")) { + LOGERR("Missing required parameter: utcTimestamp"); + returnResponse(false); + } + + Core::JSON::DecUInt64 tsField; + tsField.FromString(parameters["utcTimestamp"].Value().c_str()); + uint64_t timestamp = tsField.Value(); + + std::map overrideValues; + std::vector presentFields; + + // Collect override values + for (const auto& comp : kDVCalibrationComponents) { + const char* key = comp.c_str(); + if (parameters.HasLabel(key)) { + Core::JSON::DecUInt64 numField; + numField.FromString(parameters[key].Value().c_str()); + overrideValues[comp] = static_cast(numField.Value()); + presentFields.push_back(comp); + } + } + + // Validate that either all or only one component is present + if (presentFields.size() != 1 && presentFields.size() != kDVCalibrationComponents.size()) { + LOGERR("Must provide either exactly one or all DV calibration parameters"); + returnResponse(false); + } + + // Apply calibration update + tvError_t result = updateDVCalibration(contexts, presentFields, overrideValues, "set"); + + // Save timestamp per context + for (const auto& ctx : contexts) { + paramIndex_t index { + static_cast(ctx.videoSrcType), + static_cast(ctx.pq_mode), + static_cast(ctx.videoFormatType) + }; + setDVCalibrationTimestamp(index, timestamp); + } + + bool success = (result == tvERROR_NONE); + response["success"] = success; + returnResponse(success); + } + + uint32_t AVOutputTV::resetDolbyVisionCalibration(const JsonObject& parameters, JsonObject& response) + { + if (!m_isDVCalibrationPlatformSupported) returnResponse(false); + + std::vector contexts = getValidContextsFromParameters(parameters, "DolbyVisionCalibration"); + if (contexts.empty()) returnResponse(false); + + tvError_t ret = updateDVCalibration(contexts, kDVCalibrationComponents, {}, "reset"); + + uint64_t now = static_cast(time(nullptr)); + for (const auto& ctx : contexts) { + paramIndex_t idx = { + static_cast(ctx.videoSrcType), + static_cast(ctx.pq_mode), + static_cast(ctx.videoFormatType) + }; + setDVCalibrationTimestamp(idx, now); + } + response["success"] = (ret == tvERROR_NONE); + returnResponse(ret == tvERROR_NONE); + } uint32_t AVOutputTV::getHDRMode(const JsonObject& parameters, JsonObject& response) { diff --git a/AVOutput/AVOutputTV.h b/AVOutput/AVOutputTV.h index 59a5f878..88c71cb9 100644 --- a/AVOutput/AVOutputTV.h +++ b/AVOutput/AVOutputTV.h @@ -210,7 +210,7 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(getDigitalNoiseReduction) DECLARE_JSON_RPC_METHOD(getMEMC) DECLARE_JSON_RPC_METHOD(getSDRGamma) - + DECLARE_JSON_RPC_METHOD(getDolbyVisionCalibration) /*Get Capability API's*/ DECLARE_JSON_RPC_METHOD(getBacklightCaps) @@ -283,6 +283,7 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(setDigitalNoiseReduction) DECLARE_JSON_RPC_METHOD(setMEMC) DECLARE_JSON_RPC_METHOD(setSDRGamma) + DECLARE_JSON_RPC_METHOD(setDolbyVisionCalibration) /*Reset API's*/ DECLARE_JSON_RPC_METHOD(resetBacklight) DECLARE_JSON_RPC_METHOD(resetBrightness ) @@ -307,6 +308,7 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(resetDigitalNoiseReduction) DECLARE_JSON_RPC_METHOD(resetMEMC) DECLARE_JSON_RPC_METHOD(resetSDRGamma) + DECLARE_JSON_RPC_METHOD(resetDolbyVisionCalibration) private: @@ -607,10 +609,29 @@ class AVOutputTV : public AVOutputBase { tvContextCaps_t* m_multiPointWBCaps = nullptr; tvError_t m_multiPointWBStatus = tvERROR_NONE; - tvDVCalibrationSettings_t* m_minValues; - tvDVCalibrationSettings_t* m_maxValues; - tvContextCaps_t* m_DVCalibrationCaps = nullptr; - tvError_t m_DVCalibrationStatus = tvERROR_NONE; + + tvError_t m_dvCalibrationStatus = tvERROR_GENERAL; + tvDVCalibrationSettings_t* m_minDVCalibrationSettings = nullptr; + tvDVCalibrationSettings_t* m_maxDVCalibrationSettings = nullptr; + tvDVCalibrationComponent_t* m_dvCalibrationComponentArr = nullptr; + size_t m_numDVCalibrationComponent = 0; + tvContextCaps_t* m_dvCalibrationCaps = nullptr; + std::vector m_dvCalibrationComponentList; + bool m_isDVCalibrationPlatformSupported = false; + std::string dvComponentToString(tvDVCalibrationComponent_t comp); + tvDVCalibrationComponent_t getDVComponentEnumFromString(const std::string& str); + bool isDVCalibrationComponentValueInRange(tvDVCalibrationComponent_t comp, double val); + tvError_t setDVCalibrationParam(const std::string& forParam, const paramIndex_t& indexInfo, double value, const std::string& component); + tvError_t setDVCalibrationTimestamp(const paramIndex_t& indexInfo, uint64_t timestamp); + tvError_t getDVCalibrationParam(const std::string& forParam, const paramIndex_t& indexInfo, double& outValue, const std::string& component); + uint64_t getLastDVCalibrationSetTimestamp(const std::string& pqMode, const std::string& source, const std::string& format); + tvError_t updateDVCalibration(const std::vector& contexts, + const std::vector& components, + const std::map& overrideValues, + const std::string& action); + void syncDVCalibrationParams(); + uint32_t generateStorageIdentifierDV(std::string &key, const std::string &forParam, const paramIndex_t &info); + int m_maxCmsHue = 0; int m_maxCmsSaturation = 0; diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index df9a0c0c..3d66be3c 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -1192,6 +1192,41 @@ namespace Plugin { } return ret; } + + void AVOutputTV::syncDVCalibrationParams() + { + LOGINFO("syncDVCalibrationParams() Entry"); + + if (!m_dvCalibrationCaps || !m_minDVCalibrationSettings || !m_maxDVCalibrationSettings || + !m_dvCalibrationComponentArr || m_numDVCalibrationComponent == 0) + { + LOGERR("DV Calibration capability not initialized properly"); + return; + } + + std::vector contextList; + std::vector componentList; + + // Populate contexts from capability + for (size_t i = 0; i < m_dvCalibrationCaps->num_contexts; ++i) { + contextList.push_back(m_dvCalibrationCaps->contexts[i]); + } + + // Build component string list from array + componentList.clear(); + for (size_t j = 0; j < m_numDVCalibrationComponent; ++j) { + std::string compStr = dvComponentToString(m_dvCalibrationComponentArr[j]); + componentList.push_back(compStr); + } + + if (!contextList.empty() && !componentList.empty()) { + LOGINFO("Performing DV Calibration sync with %zu contexts and %zu components", contextList.size(), componentList.size()); + updateDVCalibration(contextList, componentList, {}, "sync"); + } + + LOGINFO("syncDVCalibrationParams() Done"); + } + void AVOutputTV::syncCMSParamsV2() { JsonObject parameters; @@ -1382,12 +1417,35 @@ namespace Plugin { } //syncWBParams(); Enable once Get2PointWBCaps is implemented + tvDVCalibrationSettings_t* minDV = nullptr; + tvDVCalibrationSettings_t* maxDV = nullptr; + tvDVCalibrationComponent_t* componentArr = nullptr; + size_t numComponents = 0; + tvContextCaps_t* contextCaps = nullptr; + m_dvCalibrationStatus = GetDVCalibrationCaps(&minDV, &maxDV, &componentArr, &numComponents, &contextCaps); + m_isDVCalibrationPlatformSupported = (m_dvCalibrationStatus == tvERROR_NONE); + + if (m_isDVCalibrationPlatformSupported) { + m_minDVCalibrationSettings = minDV; + m_maxDVCalibrationSettings = maxDV; + m_dvCalibrationComponentArr = componentArr; + m_numDVCalibrationComponent = numComponents; + m_dvCalibrationCaps = contextCaps; + + m_dvCalibrationComponentList.clear(); + for (size_t i = 0; i < m_numDVCalibrationComponent; ++i) { + std::string compStr = dvComponentToString(m_dvCalibrationComponentArr[i]); + m_dvCalibrationComponentList.push_back(compStr); + } + + syncDVCalibrationParams(); + } if(m_pictureModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) { - // Dolby Vision Mode - info.format = "DV"; // Sync only for Dolby - updateAVoutputTVParam("sync", "DolbyVisionMode", info, PQ_PARAM_DOLBY_MODE, level); + // Dolby Vision Mode + info.format = "DV"; // Sync only for Dolby + updateAVoutputTVParam("sync", "DolbyVisionMode", info, PQ_PARAM_DOLBY_MODE, level); } LOGINFO("Exit %s : pqmode : %s source : %s format : %s\n", __FUNCTION__, pqmode.c_str(), source.c_str(), format.c_str()); @@ -2760,7 +2818,45 @@ namespace Plugin { forParam; return tvERROR_NONE; } + uint32_t AVOutputTV::generateStorageIdentifierDV(std::string &key, const std::string &forParam, const paramIndex_t &info) + { + key.clear(); + key += AVOUTPUT_GENERIC_STRING_RFC_PARAM; + key += STRING_SOURCE + convertSourceIndexToStringV2(info.sourceIndex) + "."; + key += STRING_PICMODE + convertPictureIndexToStringV2(info.pqmodeIndex) + "."; + key += STRING_FORMAT + convertVideoFormatToStringV2(info.formatIndex) + "."; + if (info.componentIndex >= static_cast(tvDVCalibrationComponent_TMAX) && + info.componentIndex <= static_cast(tvDVCalibrationComponent_WY)) { + key += "Component." + dvComponentToString(static_cast(info.componentIndex)) + "."; + } else { + LOGERR("Invalid DV Calibration component index: %d", info.componentIndex); + return tvERROR_INVALID_PARAM; + } + key += forParam; + return tvERROR_NONE; + } + bool AVOutputTV::isDVCalibrationComponentValueInRange(tvDVCalibrationComponent_t comp, double val) + { + int minVal = 0, maxVal = 0; + switch (comp) { + case tvDVCalibrationComponent_TMAX: minVal = m_minDVCalibrationSettings->Tmax; maxVal = m_maxDVCalibrationSettings->Tmax; break; + case tvDVCalibrationComponent_TMIN: minVal = m_minDVCalibrationSettings->Tmin; maxVal = m_maxDVCalibrationSettings->Tmin; break; + case tvDVCalibrationComponent_TGAMMA: minVal = m_minDVCalibrationSettings->Tgamma; maxVal = m_maxDVCalibrationSettings->Tgamma; break; + case tvDVCalibrationComponent_RX: minVal = m_minDVCalibrationSettings->Rx; maxVal = m_maxDVCalibrationSettings->Rx; break; + case tvDVCalibrationComponent_RY: minVal = m_minDVCalibrationSettings->Ry; maxVal = m_maxDVCalibrationSettings->Ry; break; + case tvDVCalibrationComponent_GX: minVal = m_minDVCalibrationSettings->Gx; maxVal = m_maxDVCalibrationSettings->Gx; break; + case tvDVCalibrationComponent_GY: minVal = m_minDVCalibrationSettings->Gy; maxVal = m_maxDVCalibrationSettings->Gy; break; + case tvDVCalibrationComponent_BX: minVal = m_minDVCalibrationSettings->Bx; maxVal = m_maxDVCalibrationSettings->Bx; break; + case tvDVCalibrationComponent_BY: minVal = m_minDVCalibrationSettings->By; maxVal = m_maxDVCalibrationSettings->By; break; + case tvDVCalibrationComponent_WX: minVal = m_minDVCalibrationSettings->Wx; maxVal = m_maxDVCalibrationSettings->Wx; break; + case tvDVCalibrationComponent_WY: minVal = m_minDVCalibrationSettings->Wy; maxVal = m_maxDVCalibrationSettings->Wy; break; + default: + LOGERR("Unknown DV Calibration component enum: %d", comp); + return false; + } + return (val >= minVal && val <= maxVal); + } bool AVOutputTV::isValidSource(const std::vector& sourceArray, tvVideoSrcType_t sourceIndex) { // If "Current" is passed, match the current source @@ -2965,6 +3061,135 @@ namespace Plugin { : JsonArray(); // returns empty array } + tvError_t AVOutputTV::setDVCalibrationParam(const std::string& forParam, const paramIndex_t& indexInfo, double value, const std::string& component) + { + std::string key; + + // Fill componentIndex + paramIndex_t fullIndex = indexInfo; + fullIndex.componentIndex = static_cast(getDVComponentEnumFromString(component)); + + if (generateStorageIdentifierDV(key, forParam, fullIndex) != tvERROR_NONE || key.empty()) { + LOGERR("Failed to generate storage key for DV Calibration param: %s", component.c_str()); + return tvERROR_INVALID_PARAM; + } + + // Prepare string value with 6 digits precision + char valueStr[32] = {0}; + snprintf(valueStr, sizeof(valueStr), "%.6f", value); + + tr181ErrorCode_t err = setLocalParam(const_cast(rfc_caller_id), key.c_str(), valueStr); + if (err != tr181Success) { + LOGERR("setLocalParam failed for key=%s value=%.6f", key.c_str(), value); + return tvERROR_GENERAL; + } + + LOGINFO("DV Calibration param saved: %s = %.6f", key.c_str(), value); + return tvERROR_NONE; + } + + uint64_t AVOutputTV::getLastDVCalibrationSetTimestamp(const std::string& pqModeStr, + const std::string& videoSourceStr, + const std::string& videoFormatStr) + { + paramIndex_t indexInfo; + indexInfo.pqmodeIndex = convertPictureStringToIndexV2(pqModeStr); + indexInfo.sourceIndex = convertSourceStringToIndexV2(videoSourceStr); + indexInfo.formatIndex = convertVideoFormatStringToIndexV2(videoFormatStr); + + std::string key; + if (generateStorageIdentifierDV(key, "UtcTimestamp", indexInfo) != tvERROR_NONE) { + LOGERR("Failed to generate storage key for DV timestamp"); + return 0; + } + + TR181_ParamData_t param = {}; + tr181ErrorCode_t err = getLocalParam(rfc_caller_id, key.c_str(), ¶m); + + if (err == tr181Success && param.value && strlen(param.value) > 0) { + try { + return std::stoull(param.value); + } catch (const std::exception& e) { + LOGERR("Invalid timestamp value for key %s: %s", key.c_str(), e.what()); + return 0; + } + } else { + LOGINFO("DV calibration timestamp not set for key: %s", key.c_str()); + return 0; + } + } + + tvError_t AVOutputTV::getDVCalibrationParam(const std::string& forParam, + const paramIndex_t& indexInfo, + double& outValue, + const std::string& component) + { + std::string key; + paramIndex_t fullIndex = indexInfo; + + // Map string to component index + if (component == "tmax") fullIndex.componentIndex = tvDVCalibrationComponent_TMAX; + else if (component == "tmin") fullIndex.componentIndex = tvDVCalibrationComponent_TMIN; + else if (component == "tgamma")fullIndex.componentIndex = tvDVCalibrationComponent_TGAMMA; + else if (component == "rx") fullIndex.componentIndex = tvDVCalibrationComponent_RX; + else if (component == "ry") fullIndex.componentIndex = tvDVCalibrationComponent_RY; + else if (component == "gx") fullIndex.componentIndex = tvDVCalibrationComponent_GX; + else if (component == "gy") fullIndex.componentIndex = tvDVCalibrationComponent_GY; + else if (component == "bx") fullIndex.componentIndex = tvDVCalibrationComponent_BX; + else if (component == "by") fullIndex.componentIndex = tvDVCalibrationComponent_BY; + else if (component == "wx") fullIndex.componentIndex = tvDVCalibrationComponent_WX; + else if (component == "wy") fullIndex.componentIndex = tvDVCalibrationComponent_WY; + else { + LOGERR("Unknown DV calibration component: %s", component.c_str()); + return tvERROR_INVALID_PARAM; + } + + // Generate TR-181 key + if (generateStorageIdentifierDV(key, forParam, fullIndex) != tvERROR_NONE) { + LOGERR("Failed to generate key for component: %s", component.c_str()); + return tvERROR_GENERAL; + } + + // Fetch from TR-181 + TR181_ParamData_t param = {0}; + tr181ErrorCode_t err = getLocalParam(rfc_caller_id, key.c_str(), ¶m); + + if (err == tr181Success && strlen(param.value) > 0) { + try { + outValue = std::stod(param.value); + return tvERROR_NONE; + } catch (...) { + LOGWARN("Invalid numeric value for component %s in TR-181", component.c_str()); + } + } + + // Fallback to default values + tvDVCalibrationSettings_t defaults = {}; + if (GetDVCalibrationDefault( + static_cast(fullIndex.sourceIndex), + static_cast(fullIndex.pqmodeIndex), + static_cast(fullIndex.formatIndex), + &defaults) != tvERROR_NONE) + { + LOGERR("Failed to retrieve default DV calibration settings"); + return tvERROR_GENERAL; + } + + if (component == "tmax") outValue = defaults.Tmax; + else if (component == "tmin") outValue = defaults.Tmin; + else if (component == "tgamma") outValue = defaults.Tgamma; + else if (component == "rx") outValue = defaults.Rx; + else if (component == "ry") outValue = defaults.Ry; + else if (component == "gx") outValue = defaults.Gx; + else if (component == "gy") outValue = defaults.Gy; + else if (component == "bx") outValue = defaults.Bx; + else if (component == "by") outValue = defaults.By; + else if (component == "wx") outValue = defaults.Wx; + else if (component == "wy") outValue = defaults.Wy; + + return tvERROR_NONE; + } + tvContextCaps_t* AVOutputTV::getCapsForParam(const std::string& paramName) { tvContextCaps_t* caps = nullptr; @@ -2988,6 +3213,7 @@ namespace Plugin { else if (paramName == "BacklightMode") caps = m_backlightModeCaps; else if (paramName == "CMS") caps = m_cmsCaps; else if (paramName == "SDRGamma") caps = m_sdrGammaModeCaps; + else if (paramName == "DolbyVisionCalibration") caps = m_dvCalibrationCaps; else { LOGERR("Unknown ParamName: %s", paramName.c_str()); return nullptr; @@ -3024,6 +3250,60 @@ namespace Plugin { return convertVideoFormatToStringV2(formatIndex); } + std::string AVOutputTV::dvComponentToString(tvDVCalibrationComponent_t comp) { + switch (comp) { + case tvDVCalibrationComponent_TMAX: return "Tmax"; + case tvDVCalibrationComponent_TMIN: return "Tmin"; + case tvDVCalibrationComponent_TGAMMA: return "Tgamma"; + case tvDVCalibrationComponent_RX: return "Rx"; + case tvDVCalibrationComponent_RY: return "Ry"; + case tvDVCalibrationComponent_GX: return "Gx"; + case tvDVCalibrationComponent_GY: return "Gy"; + case tvDVCalibrationComponent_BX: return "Bx"; + case tvDVCalibrationComponent_BY: return "By"; + case tvDVCalibrationComponent_WX: return "Wx"; + case tvDVCalibrationComponent_WY: return "Wy"; + default: return "Unknown"; + } + } + tvDVCalibrationComponent_t AVOutputTV::getDVComponentEnumFromString(const std::string& str) { + if (str == "Tmax") return tvDVCalibrationComponent_TMAX; + if (str == "Tmin") return tvDVCalibrationComponent_TMIN; + if (str == "Tgamma") return tvDVCalibrationComponent_TGAMMA; + if (str == "Rx") return tvDVCalibrationComponent_RX; + if (str == "Ry") return tvDVCalibrationComponent_RY; + if (str == "Gx") return tvDVCalibrationComponent_GX; + if (str == "Gy") return tvDVCalibrationComponent_GY; + if (str == "Bx") return tvDVCalibrationComponent_BX; + if (str == "By") return tvDVCalibrationComponent_BY; + if (str == "Wx") return tvDVCalibrationComponent_WX; + if (str == "Wy") return tvDVCalibrationComponent_WY; + return tvDVCalibrationComponent_MAX; + } + + tvError_t AVOutputTV::setDVCalibrationTimestamp(const paramIndex_t& indexInfo, uint64_t timestamp) + { + std::string key; + if (generateStorageIdentifierDV(key, "UtcTimestamp", indexInfo) != tvERROR_NONE) { + LOGERR("Failed to generate TR-181 key for DV calibration timestamp"); + return tvERROR_GENERAL; + } + + // Convert timestamp to string + std::string toStore = std::to_string(timestamp); + + // Set the value using TR-181 key and string + tr181ErrorCode_t result = setLocalParam(rfc_caller_id, key.c_str(), toStore.c_str()); + if (result != tr181Success) { + LOGERR("setLocalParam failed for key: %s", key.c_str()); + return tvERROR_GENERAL; + } + + LOGINFO("DV calibration timestamp %" PRIu64 " saved successfully for %s", timestamp, key.c_str()); + return tvERROR_NONE; + } + + bool AVOutputTV::isSetRequiredForParam(const JsonObject& parameters, const std::string& paramName) { // Get current state once @@ -3099,6 +3379,78 @@ namespace Plugin { return false; } + + tvError_t AVOutputTV::updateDVCalibration(const std::vector& contexts, + const std::vector& components, + const std::map& overrideValues, + const std::string& action) + { + bool isSet = (action == "set"); + bool isReset = (action == "reset"); + bool isSync = (action == "sync"); + + tvError_t overallStatus = tvERROR_NONE; + + for (const auto& ctx : contexts) { + paramIndex_t indexInfo; + indexInfo.sourceIndex = ctx.videoSrcType; + indexInfo.pqmodeIndex = ctx.pq_mode; + indexInfo.formatIndex = ctx.videoFormatType; + + tvDVCalibrationSettings_t dvValues = {}; + + if (isReset) { + if (GetDVCalibrationDefault(ctx.videoSrcType, ctx.pq_mode, ctx.videoFormatType, &dvValues) != tvERROR_NONE) { + LOGERR("Failed to get default DV Calibration"); + overallStatus = tvERROR_GENERAL; + continue; + } + } else { + GetDVCalibration(ctx.videoSrcType, ctx.pq_mode, ctx.videoFormatType, &dvValues); + } + + for (const auto& comp : components) { + double val = 0.0; + + if (isSync || isReset) { + getDVCalibrationParam("DolbyVisionCalibration", indexInfo, val, comp); + } else if (isSet && overrideValues.find(comp) != overrideValues.end()) { + val = overrideValues.at(comp); + + tvDVCalibrationComponent_t compEnum = getDVComponentEnumFromString(comp); + if (!isDVCalibrationComponentValueInRange(compEnum, val)) { + LOGERR("Value %f out of range for component %s", val, comp.c_str()); + overallStatus = tvERROR_INVALID_PARAM; + continue; + } + } + + if (comp == "tmax") dvValues.Tmax = val; + else if (comp == "tmin") dvValues.Tmin = val; + else if (comp == "tgamma") dvValues.Tgamma = val; + else if (comp == "rx") dvValues.Rx = val; + else if (comp == "ry") dvValues.Ry = val; + else if (comp == "gx") dvValues.Gx = val; + else if (comp == "gy") dvValues.Gy = val; + else if (comp == "bx") dvValues.Bx = val; + else if (comp == "by") dvValues.By = val; + else if (comp == "wx") dvValues.Wx = val; + else if (comp == "wy") dvValues.Wy = val; + + if (isSet || isReset) { + setDVCalibrationParam("DolbyVisionCalibration", indexInfo, val, comp); + } + } + + if (SetDVCalibration(ctx.videoSrcType, ctx.pq_mode, ctx.videoFormatType, &dvValues) != tvERROR_NONE) { + LOGERR("SetDVCalibration failed for %d/%d/%d", ctx.videoSrcType, ctx.pq_mode, ctx.videoFormatType); + overallStatus = tvERROR_GENERAL; + } + } + + return overallStatus; + } + std::string AVOutputTV::getCMSNameFromEnum(tvDataComponentColor_t colorEnum) { switch (colorEnum) { From cfb040bd13423903d528265184319ff94e8235f7 Mon Sep 17 00:00:00 2001 From: skk451 Date: Wed, 13 Aug 2025 12:36:42 +0100 Subject: [PATCH 07/11] RDKEMW-5197: Make TV parameter updates non-blocking for multiple contexts - Rename updateAVoutputTVParamV2 to updateAVoutputTVParamV2Implementation - Add dispatcher logic: single context = immediate, multiple = queued - Introduce worker thread with queue for background parameter processing - Ensure operations complete within 1 second for responsive UI updates --- AVOutput/AVOutputTV.cpp | 15 ++++++-- AVOutput/AVOutputTV.h | 26 ++++++++++++-- AVOutput/AVOutputTVHelper.cpp | 68 +++++++++++++++++++++++++++++++++-- 3 files changed, 102 insertions(+), 7 deletions(-) diff --git a/AVOutput/AVOutputTV.cpp b/AVOutput/AVOutputTV.cpp index 12d0dcf9..9510bbe3 100644 --- a/AVOutput/AVOutputTV.cpp +++ b/AVOutput/AVOutputTV.cpp @@ -416,11 +416,22 @@ namespace Plugin { registerMethod("getMultiPointWBCaps", &AVOutputTV::getMultiPointWBCaps, this); + // Start worker thread for non-blocking updates + workerThread = std::thread(&AVOutputTV::paramUpdateWorker, this); + LOGINFO("Exit\n"); } AVOutputTV :: ~AVOutputTV() { + // Signal worker thread to stop + shouldStopWorker = true; + + queueCondition.notify_all(); + // Wait for worker thread to finish + if (workerThread.joinable()) { + workerThread.join(); + } DeinitializeIARM(); } @@ -1227,9 +1238,9 @@ namespace Plugin { size_t num_component = 0; tvContextCaps_t* context_caps = nullptr; - if (GetDVCalibrationCaps(&min_values, &max_values, &component, &num_component, &context_caps) != tvERROR_NONE) { + //if (GetDVCalibrationCaps(&min_values, &max_values, &component, &num_component, &context_caps) != tvERROR_NONE) { returnResponse(false); - } + // } response["platformSupport"] = true; diff --git a/AVOutput/AVOutputTV.h b/AVOutput/AVOutputTV.h index 88c71cb9..12d54ddb 100644 --- a/AVOutput/AVOutputTV.h +++ b/AVOutput/AVOutputTV.h @@ -25,6 +25,14 @@ #include #include +#include +#include +#include +#include +#include +#include +#include + #include "tvTypes.h" #include "tvSettings.h" #include @@ -450,8 +458,6 @@ class AVOutputTV : public AVOutputBase { std::vector extractVideoFormats(const JsonObject& parameters); static bool isGlobalParam(const JsonArray& arr); JsonArray getJsonArrayIfArray(const JsonObject& obj, const std::string& key); - int updateAVoutputTVParamV2(std::string action, std::string tr181ParamName, - const JsonObject& parameters, tvPQParameterIndex_t pqParamIndex, int level); std::vector getValidContextsFromParameters(const JsonObject& parameters,const std::string& tr181ParamName ); typedef tvError_t (*tvSetFunction)(int); bool resetPQParamToDefault(const JsonObject& parameters, @@ -508,6 +514,22 @@ class AVOutputTV : public AVOutputBase { std::string getCMSNameFromEnum(tvDataComponentColor_t colorEnum); void syncCMSParamsV2(); + // Thread pool for non-blocking parameter updates + std::queue> paramUpdateQueue; + std::mutex queueMutex; + std::condition_variable queueCondition; + std::thread workerThread; + std::atomic shouldStopWorker{false}; + // Worker thread function + void paramUpdateWorker(); + //dispatcher + int updateAVoutputTVParamV2(std::string action, std::string tr181ParamName, + const JsonObject& parameters, tvPQParameterIndex_t pqParamIndex, int level); + // Implementation function that does the actual work + int updateAVoutputTVParamV2Implementation(std::string action, std::string tr181ParamName, + const JsonObject& parameters, + tvPQParameterIndex_t pqParamIndex, int level); + public: int m_currentHdmiInResoluton; diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index 3d66be3c..165f8eb6 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -1357,7 +1357,7 @@ namespace Plugin { // PrecisionDetail m_precisionDetailStatus = GetPrecisionDetailCaps(&m_maxPrecisionDetail, &m_precisionDetailCaps); if (m_precisionDetailStatus == tvERROR_NONE) { - updateAVoutputTVParamV2("sync", "PrecisionDetails", paramJson, PQ_PARAM_PRECISION_DETAIL, level); + updateAVoutputTVParamV2("sync", "PrecisionDetail", paramJson, PQ_PARAM_PRECISION_DETAIL, level); } //PictureMode m_pictureModeStatus = GetTVPictureModeCaps(&m_pictureModes, &m_numPictureModes, &m_pictureModeCaps); @@ -1423,7 +1423,7 @@ namespace Plugin { size_t numComponents = 0; tvContextCaps_t* contextCaps = nullptr; - m_dvCalibrationStatus = GetDVCalibrationCaps(&minDV, &maxDV, &componentArr, &numComponents, &contextCaps); + //m_dvCalibrationStatus = GetDVCalibrationCaps(&minDV, &maxDV, &componentArr, &numComponents, &contextCaps); m_isDVCalibrationPlatformSupported = (m_dvCalibrationStatus == tvERROR_NONE); if (m_isDVCalibrationPlatformSupported) { @@ -3554,19 +3554,81 @@ namespace Plugin { return validContexts; } + + void AVOutputTV::paramUpdateWorker() { + while (!shouldStopWorker) { + std::unique_lock lock(queueMutex); + + // Wait for work or stop signal + queueCondition.wait(lock, [this] { + return !paramUpdateQueue.empty() || shouldStopWorker; + }); + + if (shouldStopWorker) { + break; + } + + // Process all queued updates + while (!paramUpdateQueue.empty() && !shouldStopWorker) { + auto task = paramUpdateQueue.front(); + paramUpdateQueue.pop(); + lock.unlock(); + // Execute the task + task(); + lock.lock(); + } + } + } + int AVOutputTV::updateAVoutputTVParamV2(std::string action, std::string tr181ParamName, + const JsonObject& parameters, + tvPQParameterIndex_t pqParamIndex, int level) + { +#if DEBUG + LOGINFO("Entry %s: Action: %s, Param: %s, Level: %d", __FUNCTION__, action.c_str(), tr181ParamName.c_str(), level); +#endif + std::vector validContexts = getValidContextsFromParameters(parameters, tr181ParamName); + if (validContexts.empty()) { + LOGWARN("%s: No valid contexts found for parameters", __FUNCTION__); + return (int)tvERROR_GENERAL; + } + if (validContexts.size() == 1){ +#if DEBUG + LOGINFO("Processing immediately"); +#endif + return updateAVoutputTVParamV2Implementation(action, tr181ParamName, parameters, pqParamIndex, level); + } else { +#if DEBUG + LOGINFO("Queuing for background processing - no current values involved"); +#endif + // Capture parameters by value for thread safety + std::lock_guard lock(queueMutex); + paramUpdateQueue.push([this, action, tr181ParamName, parameters, pqParamIndex, level]() { + updateAVoutputTVParamV2Implementation(action, tr181ParamName, parameters, pqParamIndex, level); + }); + queueCondition.notify_one(); + + // Return immediately - operation queued successfully + return 0; + } + } + + int AVOutputTV::updateAVoutputTVParamV2Implementation(std::string action, std::string tr181ParamName, const JsonObject& parameters, tvPQParameterIndex_t pqParamIndex,int level) { +#if DEBUG LOGINFO("Entry %s: Action: %s, Param: %s, Level: %d", __FUNCTION__, action.c_str(), tr181ParamName.c_str(), level); +#endif int ret = 0; const bool isSet = (action == "set"); const bool isReset = (action == "reset"); const bool isSync = (action == "sync"); std::vector validContexts = getValidContextsFromParameters(parameters, tr181ParamName); +#if DEBUG LOGINFO("%s: Number of validContexts = %zu", __FUNCTION__, validContexts.size()); - +#endif if (validContexts.empty()) { LOGWARN("%s: No valid contexts found for parameters", __FUNCTION__); return (int)tvERROR_GENERAL; From 9e6f1327800b3247d2b3da935cffbbb602e050cc Mon Sep 17 00:00:00 2001 From: aktamilbe <59253707+aktamilbe@users.noreply.github.com> Date: Mon, 18 Aug 2025 13:03:53 +0100 Subject: [PATCH 08/11] Revert "RDKEMW-5201: Dolby end user calibration" This reverts commit 33e92e9c47c2f65bd2b9e2701b5219e06fadb809. --- AVOutput/AVOutputTV.cpp | 165 +--------------- AVOutput/AVOutputTV.h | 31 +-- AVOutput/AVOutputTVHelper.cpp | 359 +--------------------------------- 3 files changed, 9 insertions(+), 546 deletions(-) diff --git a/AVOutput/AVOutputTV.cpp b/AVOutput/AVOutputTV.cpp index 9510bbe3..50ae2f07 100644 --- a/AVOutput/AVOutputTV.cpp +++ b/AVOutput/AVOutputTV.cpp @@ -368,17 +368,11 @@ namespace Plugin { registerMethod("getColorTemperatureCapsV2", &AVOutputTV::getColorTemperatureCapsV2, this); registerMethod("getBacklightDimmingModeCapsV2", &AVOutputTV::getBacklightDimmingModeCapsV2, this); registerMethod("getZoomModeCapsV2", &AVOutputTV::getZoomModeCapsV2, this); + registerMethod("getDolbyVisionCalibrationCaps", &AVOutputTV::getDolbyVisionCalibrationCaps, this); registerMethod("getPictureModeCapsV2", &AVOutputTV::getPictureModeCapsV2, this); registerMethod("getAutoBacklightModeCapsV2", &AVOutputTV::getAutoBacklightModeCapsV2, this); registerMethod("getCMSCapsV2", &AVOutputTV::getCMSCapsV2, this); registerMethod("get2PointWBCapsV2", &AVOutputTV::get2PointWBCapsV2, this); - - registerMethod("getDolbyVisionCalibrationCaps", &AVOutputTV::getDolbyVisionCalibrationCaps, this); - registerMethod("getDolbyVisionCalibration", &AVOutputTV::getDolbyVisionCalibration, this); - registerMethod("setDolbyVisionCalibration", &AVOutputTV::setDolbyVisionCalibration, this); - registerMethod("resetDolbyVisionCalibration", &AVOutputTV::resetDolbyVisionCalibration, this); - - registerMethod("getSDRGammaCaps", &AVOutputTV::getSDRGammaCaps, this); registerMethod("getSDRGamma", &AVOutputTV::getSDRGamma, this); registerMethod("setSDRGamma", &AVOutputTV::setSDRGamma, this); @@ -1232,48 +1226,6 @@ namespace Plugin { uint32_t AVOutputTV::getDolbyVisionCalibrationCaps(const JsonObject& parameters, JsonObject& response) { - tvDVCalibrationSettings_t* min_values = nullptr; - tvDVCalibrationSettings_t* max_values = nullptr; - tvDVCalibrationComponent_t* component = nullptr; - size_t num_component = 0; - tvContextCaps_t* context_caps = nullptr; - - //if (GetDVCalibrationCaps(&min_values, &max_values, &component, &num_component, &context_caps) != tvERROR_NONE) { - returnResponse(false); - // } - - response["platformSupport"] = true; - - // Add ranges - response["rangeTmax"] = JsonObject({{"from", min_values->Tmax}, {"to", max_values->Tmax}}); - response["rangeTmin"] = JsonObject({{"from", min_values->Tmin}, {"to", max_values->Tmin}}); - response["rangeTgamma"] = JsonObject({{"from", min_values->Tgamma}, {"to", max_values->Tgamma}}); - response["rangeRx"] = JsonObject({{"from", min_values->Rx}, {"to", max_values->Rx}}); - response["rangeRy"] = JsonObject({{"from", min_values->Ry}, {"to", max_values->Ry}}); - response["rangeGx"] = JsonObject({{"from", min_values->Gx}, {"to", max_values->Gx}}); - response["rangeGy"] = JsonObject({{"from", min_values->Gy}, {"to", max_values->Gy}}); - response["rangeBx"] = JsonObject({{"from", min_values->Bx}, {"to", max_values->Bx}}); - response["rangeBy"] = JsonObject({{"from", min_values->By}, {"to", max_values->By}}); - response["rangeWx"] = JsonObject({{"from", min_values->Wx}, {"to", max_values->Wx}}); - response["rangeWy"] = JsonObject({{"from", min_values->Wy}, {"to", max_values->Wy}}); - - // Add component list - JsonArray componentArr; - for (size_t i = 0; i < num_component; ++i) { - componentArr.Add(dvComponentToString(component[i])); // Add string mapping if component is enum - } - response["component"] = componentArr; - - // Add context information - response["context"] = parseContextCaps(context_caps); - - #if HAL_NOT_READY - delete min_values; - delete max_values; - delete[] component; - delete[] context_caps; - #endif - returnResponse(true); } @@ -5453,121 +5405,6 @@ namespace Plugin { returnResponse(true); } } - static const std::vector kDVCalibrationComponents = { - "tmax", "tmin", "tgamma", "rx", "ry", "gx", "gy", "bx", "by", "wx", "wy" - }; - uint32_t AVOutputTV::getDolbyVisionCalibration(const JsonObject& parameters, JsonObject& response) - { - if (!m_isDVCalibrationPlatformSupported) returnResponse(false); - - tvConfigContext_t ctx = getValidContextFromGetParameters(parameters, "DolbyVisionCalibration"); - if (ctx.pq_mode == PQ_MODE_INVALID) returnResponse(false); - - JsonObject calib; - paramIndex_t indexInfo = { static_cast(ctx.videoSrcType), - static_cast(ctx.pq_mode), - static_cast(ctx.videoFormatType) - }; - for (const auto& comp : kDVCalibrationComponents) { - double val = 0.0; - if (getDVCalibrationParam("DolbyVisionCalibration", indexInfo, val, comp) == tvERROR_NONE) { - calib[comp.c_str()] = val; - } - } - - std::string pq = convertPictureIndexToStringV2(indexInfo.pqmodeIndex); - std::string src = convertSourceIndexToStringV2(indexInfo.sourceIndex); - std::string fmt = convertVideoFormatToStringV2(indexInfo.formatIndex); - uint64_t ts = getLastDVCalibrationSetTimestamp(pq, src, fmt); - response = calib; - response["utcTimestamp"] = static_cast(ts); - response["success"] = true; - returnResponse(true); - } - - uint32_t AVOutputTV::setDolbyVisionCalibration(const JsonObject& parameters, JsonObject& response) - { - if (!m_isDVCalibrationPlatformSupported) { - LOGERR("DV Calibration not supported on this platform"); - returnResponse(false); - } - - // Extract valid contexts - std::vector contexts = getValidContextsFromParameters(parameters, "DolbyVisionCalibration"); - if (contexts.empty()) { - LOGERR("No valid context found for DV Calibration"); - returnResponse(false); - } - - // Validate and parse timestamp - if (!parameters.HasLabel("utcTimestamp")) { - LOGERR("Missing required parameter: utcTimestamp"); - returnResponse(false); - } - - Core::JSON::DecUInt64 tsField; - tsField.FromString(parameters["utcTimestamp"].Value().c_str()); - uint64_t timestamp = tsField.Value(); - - std::map overrideValues; - std::vector presentFields; - - // Collect override values - for (const auto& comp : kDVCalibrationComponents) { - const char* key = comp.c_str(); - if (parameters.HasLabel(key)) { - Core::JSON::DecUInt64 numField; - numField.FromString(parameters[key].Value().c_str()); - overrideValues[comp] = static_cast(numField.Value()); - presentFields.push_back(comp); - } - } - - // Validate that either all or only one component is present - if (presentFields.size() != 1 && presentFields.size() != kDVCalibrationComponents.size()) { - LOGERR("Must provide either exactly one or all DV calibration parameters"); - returnResponse(false); - } - - // Apply calibration update - tvError_t result = updateDVCalibration(contexts, presentFields, overrideValues, "set"); - - // Save timestamp per context - for (const auto& ctx : contexts) { - paramIndex_t index { - static_cast(ctx.videoSrcType), - static_cast(ctx.pq_mode), - static_cast(ctx.videoFormatType) - }; - setDVCalibrationTimestamp(index, timestamp); - } - - bool success = (result == tvERROR_NONE); - response["success"] = success; - returnResponse(success); - } - - uint32_t AVOutputTV::resetDolbyVisionCalibration(const JsonObject& parameters, JsonObject& response) - { - if (!m_isDVCalibrationPlatformSupported) returnResponse(false); - - std::vector contexts = getValidContextsFromParameters(parameters, "DolbyVisionCalibration"); - if (contexts.empty()) returnResponse(false); - - tvError_t ret = updateDVCalibration(contexts, kDVCalibrationComponents, {}, "reset"); - - uint64_t now = static_cast(time(nullptr)); - for (const auto& ctx : contexts) { - paramIndex_t idx = { - static_cast(ctx.videoSrcType), - static_cast(ctx.pq_mode), - static_cast(ctx.videoFormatType) - }; - setDVCalibrationTimestamp(idx, now); - } - response["success"] = (ret == tvERROR_NONE); - returnResponse(ret == tvERROR_NONE); - } uint32_t AVOutputTV::getHDRMode(const JsonObject& parameters, JsonObject& response) { diff --git a/AVOutput/AVOutputTV.h b/AVOutput/AVOutputTV.h index 12d54ddb..199d443a 100644 --- a/AVOutput/AVOutputTV.h +++ b/AVOutput/AVOutputTV.h @@ -218,7 +218,7 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(getDigitalNoiseReduction) DECLARE_JSON_RPC_METHOD(getMEMC) DECLARE_JSON_RPC_METHOD(getSDRGamma) - DECLARE_JSON_RPC_METHOD(getDolbyVisionCalibration) + /*Get Capability API's*/ DECLARE_JSON_RPC_METHOD(getBacklightCaps) @@ -291,7 +291,6 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(setDigitalNoiseReduction) DECLARE_JSON_RPC_METHOD(setMEMC) DECLARE_JSON_RPC_METHOD(setSDRGamma) - DECLARE_JSON_RPC_METHOD(setDolbyVisionCalibration) /*Reset API's*/ DECLARE_JSON_RPC_METHOD(resetBacklight) DECLARE_JSON_RPC_METHOD(resetBrightness ) @@ -316,7 +315,6 @@ class AVOutputTV : public AVOutputBase { DECLARE_JSON_RPC_METHOD(resetDigitalNoiseReduction) DECLARE_JSON_RPC_METHOD(resetMEMC) DECLARE_JSON_RPC_METHOD(resetSDRGamma) - DECLARE_JSON_RPC_METHOD(resetDolbyVisionCalibration) private: @@ -631,29 +629,10 @@ class AVOutputTV : public AVOutputBase { tvContextCaps_t* m_multiPointWBCaps = nullptr; tvError_t m_multiPointWBStatus = tvERROR_NONE; - - tvError_t m_dvCalibrationStatus = tvERROR_GENERAL; - tvDVCalibrationSettings_t* m_minDVCalibrationSettings = nullptr; - tvDVCalibrationSettings_t* m_maxDVCalibrationSettings = nullptr; - tvDVCalibrationComponent_t* m_dvCalibrationComponentArr = nullptr; - size_t m_numDVCalibrationComponent = 0; - tvContextCaps_t* m_dvCalibrationCaps = nullptr; - std::vector m_dvCalibrationComponentList; - bool m_isDVCalibrationPlatformSupported = false; - std::string dvComponentToString(tvDVCalibrationComponent_t comp); - tvDVCalibrationComponent_t getDVComponentEnumFromString(const std::string& str); - bool isDVCalibrationComponentValueInRange(tvDVCalibrationComponent_t comp, double val); - tvError_t setDVCalibrationParam(const std::string& forParam, const paramIndex_t& indexInfo, double value, const std::string& component); - tvError_t setDVCalibrationTimestamp(const paramIndex_t& indexInfo, uint64_t timestamp); - tvError_t getDVCalibrationParam(const std::string& forParam, const paramIndex_t& indexInfo, double& outValue, const std::string& component); - uint64_t getLastDVCalibrationSetTimestamp(const std::string& pqMode, const std::string& source, const std::string& format); - tvError_t updateDVCalibration(const std::vector& contexts, - const std::vector& components, - const std::map& overrideValues, - const std::string& action); - void syncDVCalibrationParams(); - uint32_t generateStorageIdentifierDV(std::string &key, const std::string &forParam, const paramIndex_t &info); - + tvDVCalibrationSettings_t* m_minValues; + tvDVCalibrationSettings_t* m_maxValues; + tvContextCaps_t* m_DVCalibrationCaps = nullptr; + tvError_t m_DVCalibrationStatus = tvERROR_NONE; int m_maxCmsHue = 0; int m_maxCmsSaturation = 0; diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index 165f8eb6..4b5ca818 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -1192,41 +1192,6 @@ namespace Plugin { } return ret; } - - void AVOutputTV::syncDVCalibrationParams() - { - LOGINFO("syncDVCalibrationParams() Entry"); - - if (!m_dvCalibrationCaps || !m_minDVCalibrationSettings || !m_maxDVCalibrationSettings || - !m_dvCalibrationComponentArr || m_numDVCalibrationComponent == 0) - { - LOGERR("DV Calibration capability not initialized properly"); - return; - } - - std::vector contextList; - std::vector componentList; - - // Populate contexts from capability - for (size_t i = 0; i < m_dvCalibrationCaps->num_contexts; ++i) { - contextList.push_back(m_dvCalibrationCaps->contexts[i]); - } - - // Build component string list from array - componentList.clear(); - for (size_t j = 0; j < m_numDVCalibrationComponent; ++j) { - std::string compStr = dvComponentToString(m_dvCalibrationComponentArr[j]); - componentList.push_back(compStr); - } - - if (!contextList.empty() && !componentList.empty()) { - LOGINFO("Performing DV Calibration sync with %zu contexts and %zu components", contextList.size(), componentList.size()); - updateDVCalibration(contextList, componentList, {}, "sync"); - } - - LOGINFO("syncDVCalibrationParams() Done"); - } - void AVOutputTV::syncCMSParamsV2() { JsonObject parameters; @@ -1417,35 +1382,11 @@ namespace Plugin { } //syncWBParams(); Enable once Get2PointWBCaps is implemented - tvDVCalibrationSettings_t* minDV = nullptr; - tvDVCalibrationSettings_t* maxDV = nullptr; - tvDVCalibrationComponent_t* componentArr = nullptr; - size_t numComponents = 0; - tvContextCaps_t* contextCaps = nullptr; - - //m_dvCalibrationStatus = GetDVCalibrationCaps(&minDV, &maxDV, &componentArr, &numComponents, &contextCaps); - m_isDVCalibrationPlatformSupported = (m_dvCalibrationStatus == tvERROR_NONE); - - if (m_isDVCalibrationPlatformSupported) { - m_minDVCalibrationSettings = minDV; - m_maxDVCalibrationSettings = maxDV; - m_dvCalibrationComponentArr = componentArr; - m_numDVCalibrationComponent = numComponents; - m_dvCalibrationCaps = contextCaps; - - m_dvCalibrationComponentList.clear(); - for (size_t i = 0; i < m_numDVCalibrationComponent; ++i) { - std::string compStr = dvComponentToString(m_dvCalibrationComponentArr[i]); - m_dvCalibrationComponentList.push_back(compStr); - } - - syncDVCalibrationParams(); - } if(m_pictureModeStatus == tvERROR_OPERATION_NOT_SUPPORTED) { - // Dolby Vision Mode - info.format = "DV"; // Sync only for Dolby - updateAVoutputTVParam("sync", "DolbyVisionMode", info, PQ_PARAM_DOLBY_MODE, level); + // Dolby Vision Mode + info.format = "DV"; // Sync only for Dolby + updateAVoutputTVParam("sync", "DolbyVisionMode", info, PQ_PARAM_DOLBY_MODE, level); } LOGINFO("Exit %s : pqmode : %s source : %s format : %s\n", __FUNCTION__, pqmode.c_str(), source.c_str(), format.c_str()); @@ -2818,45 +2759,7 @@ namespace Plugin { forParam; return tvERROR_NONE; } - uint32_t AVOutputTV::generateStorageIdentifierDV(std::string &key, const std::string &forParam, const paramIndex_t &info) - { - key.clear(); - key += AVOUTPUT_GENERIC_STRING_RFC_PARAM; - key += STRING_SOURCE + convertSourceIndexToStringV2(info.sourceIndex) + "."; - key += STRING_PICMODE + convertPictureIndexToStringV2(info.pqmodeIndex) + "."; - key += STRING_FORMAT + convertVideoFormatToStringV2(info.formatIndex) + "."; - if (info.componentIndex >= static_cast(tvDVCalibrationComponent_TMAX) && - info.componentIndex <= static_cast(tvDVCalibrationComponent_WY)) { - key += "Component." + dvComponentToString(static_cast(info.componentIndex)) + "."; - } else { - LOGERR("Invalid DV Calibration component index: %d", info.componentIndex); - return tvERROR_INVALID_PARAM; - } - key += forParam; - return tvERROR_NONE; - } - bool AVOutputTV::isDVCalibrationComponentValueInRange(tvDVCalibrationComponent_t comp, double val) - { - int minVal = 0, maxVal = 0; - switch (comp) { - case tvDVCalibrationComponent_TMAX: minVal = m_minDVCalibrationSettings->Tmax; maxVal = m_maxDVCalibrationSettings->Tmax; break; - case tvDVCalibrationComponent_TMIN: minVal = m_minDVCalibrationSettings->Tmin; maxVal = m_maxDVCalibrationSettings->Tmin; break; - case tvDVCalibrationComponent_TGAMMA: minVal = m_minDVCalibrationSettings->Tgamma; maxVal = m_maxDVCalibrationSettings->Tgamma; break; - case tvDVCalibrationComponent_RX: minVal = m_minDVCalibrationSettings->Rx; maxVal = m_maxDVCalibrationSettings->Rx; break; - case tvDVCalibrationComponent_RY: minVal = m_minDVCalibrationSettings->Ry; maxVal = m_maxDVCalibrationSettings->Ry; break; - case tvDVCalibrationComponent_GX: minVal = m_minDVCalibrationSettings->Gx; maxVal = m_maxDVCalibrationSettings->Gx; break; - case tvDVCalibrationComponent_GY: minVal = m_minDVCalibrationSettings->Gy; maxVal = m_maxDVCalibrationSettings->Gy; break; - case tvDVCalibrationComponent_BX: minVal = m_minDVCalibrationSettings->Bx; maxVal = m_maxDVCalibrationSettings->Bx; break; - case tvDVCalibrationComponent_BY: minVal = m_minDVCalibrationSettings->By; maxVal = m_maxDVCalibrationSettings->By; break; - case tvDVCalibrationComponent_WX: minVal = m_minDVCalibrationSettings->Wx; maxVal = m_maxDVCalibrationSettings->Wx; break; - case tvDVCalibrationComponent_WY: minVal = m_minDVCalibrationSettings->Wy; maxVal = m_maxDVCalibrationSettings->Wy; break; - default: - LOGERR("Unknown DV Calibration component enum: %d", comp); - return false; - } - return (val >= minVal && val <= maxVal); - } bool AVOutputTV::isValidSource(const std::vector& sourceArray, tvVideoSrcType_t sourceIndex) { // If "Current" is passed, match the current source @@ -3061,135 +2964,6 @@ namespace Plugin { : JsonArray(); // returns empty array } - tvError_t AVOutputTV::setDVCalibrationParam(const std::string& forParam, const paramIndex_t& indexInfo, double value, const std::string& component) - { - std::string key; - - // Fill componentIndex - paramIndex_t fullIndex = indexInfo; - fullIndex.componentIndex = static_cast(getDVComponentEnumFromString(component)); - - if (generateStorageIdentifierDV(key, forParam, fullIndex) != tvERROR_NONE || key.empty()) { - LOGERR("Failed to generate storage key for DV Calibration param: %s", component.c_str()); - return tvERROR_INVALID_PARAM; - } - - // Prepare string value with 6 digits precision - char valueStr[32] = {0}; - snprintf(valueStr, sizeof(valueStr), "%.6f", value); - - tr181ErrorCode_t err = setLocalParam(const_cast(rfc_caller_id), key.c_str(), valueStr); - if (err != tr181Success) { - LOGERR("setLocalParam failed for key=%s value=%.6f", key.c_str(), value); - return tvERROR_GENERAL; - } - - LOGINFO("DV Calibration param saved: %s = %.6f", key.c_str(), value); - return tvERROR_NONE; - } - - uint64_t AVOutputTV::getLastDVCalibrationSetTimestamp(const std::string& pqModeStr, - const std::string& videoSourceStr, - const std::string& videoFormatStr) - { - paramIndex_t indexInfo; - indexInfo.pqmodeIndex = convertPictureStringToIndexV2(pqModeStr); - indexInfo.sourceIndex = convertSourceStringToIndexV2(videoSourceStr); - indexInfo.formatIndex = convertVideoFormatStringToIndexV2(videoFormatStr); - - std::string key; - if (generateStorageIdentifierDV(key, "UtcTimestamp", indexInfo) != tvERROR_NONE) { - LOGERR("Failed to generate storage key for DV timestamp"); - return 0; - } - - TR181_ParamData_t param = {}; - tr181ErrorCode_t err = getLocalParam(rfc_caller_id, key.c_str(), ¶m); - - if (err == tr181Success && param.value && strlen(param.value) > 0) { - try { - return std::stoull(param.value); - } catch (const std::exception& e) { - LOGERR("Invalid timestamp value for key %s: %s", key.c_str(), e.what()); - return 0; - } - } else { - LOGINFO("DV calibration timestamp not set for key: %s", key.c_str()); - return 0; - } - } - - tvError_t AVOutputTV::getDVCalibrationParam(const std::string& forParam, - const paramIndex_t& indexInfo, - double& outValue, - const std::string& component) - { - std::string key; - paramIndex_t fullIndex = indexInfo; - - // Map string to component index - if (component == "tmax") fullIndex.componentIndex = tvDVCalibrationComponent_TMAX; - else if (component == "tmin") fullIndex.componentIndex = tvDVCalibrationComponent_TMIN; - else if (component == "tgamma")fullIndex.componentIndex = tvDVCalibrationComponent_TGAMMA; - else if (component == "rx") fullIndex.componentIndex = tvDVCalibrationComponent_RX; - else if (component == "ry") fullIndex.componentIndex = tvDVCalibrationComponent_RY; - else if (component == "gx") fullIndex.componentIndex = tvDVCalibrationComponent_GX; - else if (component == "gy") fullIndex.componentIndex = tvDVCalibrationComponent_GY; - else if (component == "bx") fullIndex.componentIndex = tvDVCalibrationComponent_BX; - else if (component == "by") fullIndex.componentIndex = tvDVCalibrationComponent_BY; - else if (component == "wx") fullIndex.componentIndex = tvDVCalibrationComponent_WX; - else if (component == "wy") fullIndex.componentIndex = tvDVCalibrationComponent_WY; - else { - LOGERR("Unknown DV calibration component: %s", component.c_str()); - return tvERROR_INVALID_PARAM; - } - - // Generate TR-181 key - if (generateStorageIdentifierDV(key, forParam, fullIndex) != tvERROR_NONE) { - LOGERR("Failed to generate key for component: %s", component.c_str()); - return tvERROR_GENERAL; - } - - // Fetch from TR-181 - TR181_ParamData_t param = {0}; - tr181ErrorCode_t err = getLocalParam(rfc_caller_id, key.c_str(), ¶m); - - if (err == tr181Success && strlen(param.value) > 0) { - try { - outValue = std::stod(param.value); - return tvERROR_NONE; - } catch (...) { - LOGWARN("Invalid numeric value for component %s in TR-181", component.c_str()); - } - } - - // Fallback to default values - tvDVCalibrationSettings_t defaults = {}; - if (GetDVCalibrationDefault( - static_cast(fullIndex.sourceIndex), - static_cast(fullIndex.pqmodeIndex), - static_cast(fullIndex.formatIndex), - &defaults) != tvERROR_NONE) - { - LOGERR("Failed to retrieve default DV calibration settings"); - return tvERROR_GENERAL; - } - - if (component == "tmax") outValue = defaults.Tmax; - else if (component == "tmin") outValue = defaults.Tmin; - else if (component == "tgamma") outValue = defaults.Tgamma; - else if (component == "rx") outValue = defaults.Rx; - else if (component == "ry") outValue = defaults.Ry; - else if (component == "gx") outValue = defaults.Gx; - else if (component == "gy") outValue = defaults.Gy; - else if (component == "bx") outValue = defaults.Bx; - else if (component == "by") outValue = defaults.By; - else if (component == "wx") outValue = defaults.Wx; - else if (component == "wy") outValue = defaults.Wy; - - return tvERROR_NONE; - } - tvContextCaps_t* AVOutputTV::getCapsForParam(const std::string& paramName) { tvContextCaps_t* caps = nullptr; @@ -3213,7 +2987,6 @@ namespace Plugin { else if (paramName == "BacklightMode") caps = m_backlightModeCaps; else if (paramName == "CMS") caps = m_cmsCaps; else if (paramName == "SDRGamma") caps = m_sdrGammaModeCaps; - else if (paramName == "DolbyVisionCalibration") caps = m_dvCalibrationCaps; else { LOGERR("Unknown ParamName: %s", paramName.c_str()); return nullptr; @@ -3250,60 +3023,6 @@ namespace Plugin { return convertVideoFormatToStringV2(formatIndex); } - std::string AVOutputTV::dvComponentToString(tvDVCalibrationComponent_t comp) { - switch (comp) { - case tvDVCalibrationComponent_TMAX: return "Tmax"; - case tvDVCalibrationComponent_TMIN: return "Tmin"; - case tvDVCalibrationComponent_TGAMMA: return "Tgamma"; - case tvDVCalibrationComponent_RX: return "Rx"; - case tvDVCalibrationComponent_RY: return "Ry"; - case tvDVCalibrationComponent_GX: return "Gx"; - case tvDVCalibrationComponent_GY: return "Gy"; - case tvDVCalibrationComponent_BX: return "Bx"; - case tvDVCalibrationComponent_BY: return "By"; - case tvDVCalibrationComponent_WX: return "Wx"; - case tvDVCalibrationComponent_WY: return "Wy"; - default: return "Unknown"; - } - } - tvDVCalibrationComponent_t AVOutputTV::getDVComponentEnumFromString(const std::string& str) { - if (str == "Tmax") return tvDVCalibrationComponent_TMAX; - if (str == "Tmin") return tvDVCalibrationComponent_TMIN; - if (str == "Tgamma") return tvDVCalibrationComponent_TGAMMA; - if (str == "Rx") return tvDVCalibrationComponent_RX; - if (str == "Ry") return tvDVCalibrationComponent_RY; - if (str == "Gx") return tvDVCalibrationComponent_GX; - if (str == "Gy") return tvDVCalibrationComponent_GY; - if (str == "Bx") return tvDVCalibrationComponent_BX; - if (str == "By") return tvDVCalibrationComponent_BY; - if (str == "Wx") return tvDVCalibrationComponent_WX; - if (str == "Wy") return tvDVCalibrationComponent_WY; - return tvDVCalibrationComponent_MAX; - } - - tvError_t AVOutputTV::setDVCalibrationTimestamp(const paramIndex_t& indexInfo, uint64_t timestamp) - { - std::string key; - if (generateStorageIdentifierDV(key, "UtcTimestamp", indexInfo) != tvERROR_NONE) { - LOGERR("Failed to generate TR-181 key for DV calibration timestamp"); - return tvERROR_GENERAL; - } - - // Convert timestamp to string - std::string toStore = std::to_string(timestamp); - - // Set the value using TR-181 key and string - tr181ErrorCode_t result = setLocalParam(rfc_caller_id, key.c_str(), toStore.c_str()); - if (result != tr181Success) { - LOGERR("setLocalParam failed for key: %s", key.c_str()); - return tvERROR_GENERAL; - } - - LOGINFO("DV calibration timestamp %" PRIu64 " saved successfully for %s", timestamp, key.c_str()); - return tvERROR_NONE; - } - - bool AVOutputTV::isSetRequiredForParam(const JsonObject& parameters, const std::string& paramName) { // Get current state once @@ -3379,78 +3098,6 @@ namespace Plugin { return false; } - - tvError_t AVOutputTV::updateDVCalibration(const std::vector& contexts, - const std::vector& components, - const std::map& overrideValues, - const std::string& action) - { - bool isSet = (action == "set"); - bool isReset = (action == "reset"); - bool isSync = (action == "sync"); - - tvError_t overallStatus = tvERROR_NONE; - - for (const auto& ctx : contexts) { - paramIndex_t indexInfo; - indexInfo.sourceIndex = ctx.videoSrcType; - indexInfo.pqmodeIndex = ctx.pq_mode; - indexInfo.formatIndex = ctx.videoFormatType; - - tvDVCalibrationSettings_t dvValues = {}; - - if (isReset) { - if (GetDVCalibrationDefault(ctx.videoSrcType, ctx.pq_mode, ctx.videoFormatType, &dvValues) != tvERROR_NONE) { - LOGERR("Failed to get default DV Calibration"); - overallStatus = tvERROR_GENERAL; - continue; - } - } else { - GetDVCalibration(ctx.videoSrcType, ctx.pq_mode, ctx.videoFormatType, &dvValues); - } - - for (const auto& comp : components) { - double val = 0.0; - - if (isSync || isReset) { - getDVCalibrationParam("DolbyVisionCalibration", indexInfo, val, comp); - } else if (isSet && overrideValues.find(comp) != overrideValues.end()) { - val = overrideValues.at(comp); - - tvDVCalibrationComponent_t compEnum = getDVComponentEnumFromString(comp); - if (!isDVCalibrationComponentValueInRange(compEnum, val)) { - LOGERR("Value %f out of range for component %s", val, comp.c_str()); - overallStatus = tvERROR_INVALID_PARAM; - continue; - } - } - - if (comp == "tmax") dvValues.Tmax = val; - else if (comp == "tmin") dvValues.Tmin = val; - else if (comp == "tgamma") dvValues.Tgamma = val; - else if (comp == "rx") dvValues.Rx = val; - else if (comp == "ry") dvValues.Ry = val; - else if (comp == "gx") dvValues.Gx = val; - else if (comp == "gy") dvValues.Gy = val; - else if (comp == "bx") dvValues.Bx = val; - else if (comp == "by") dvValues.By = val; - else if (comp == "wx") dvValues.Wx = val; - else if (comp == "wy") dvValues.Wy = val; - - if (isSet || isReset) { - setDVCalibrationParam("DolbyVisionCalibration", indexInfo, val, comp); - } - } - - if (SetDVCalibration(ctx.videoSrcType, ctx.pq_mode, ctx.videoFormatType, &dvValues) != tvERROR_NONE) { - LOGERR("SetDVCalibration failed for %d/%d/%d", ctx.videoSrcType, ctx.pq_mode, ctx.videoFormatType); - overallStatus = tvERROR_GENERAL; - } - } - - return overallStatus; - } - std::string AVOutputTV::getCMSNameFromEnum(tvDataComponentColor_t colorEnum) { switch (colorEnum) { From 52a9d920467d085478677c95d324d009bf441b9e Mon Sep 17 00:00:00 2001 From: skk451 Date: Wed, 20 Aug 2025 14:05:59 +0100 Subject: [PATCH 09/11] RDKEMW-5202: Handle the logic for setSDRGamma to set correct enum value --- AVOutput/AVOutputTV.cpp | 64 +++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/AVOutput/AVOutputTV.cpp b/AVOutput/AVOutputTV.cpp index 50ae2f07..48ba060b 100644 --- a/AVOutput/AVOutputTV.cpp +++ b/AVOutput/AVOutputTV.cpp @@ -1648,11 +1648,11 @@ namespace Plugin { } uint32_t AVOutputTV::setContextPQParam(const JsonObject& parameters, JsonObject& response, - const std::string& inputParamName, - const std::string& tr181ParamName, - int maxAllowedValue, - tvPQParameterIndex_t pqParamType, - std::function halSetter) + const std::string& inputParamName, + const std::string& tr181ParamName, + int maxAllowedValue, + tvPQParameterIndex_t pqParamType, + std::function halSetter) { LOGINFO("Entry"); @@ -1662,11 +1662,30 @@ namespace Plugin { } std::string valueStr = parameters[inputParamName.c_str()].String(); - int value = std::stoi(valueStr); + int enumValue = -1; - if (value < 0 || value > maxAllowedValue) { - LOGERR("Input value %d is out of range for %s", value, inputParamName.c_str()); - returnResponse(false); + // Handle special map-based params + if (pqParamType == PQ_PARAM_SDR_GAMMA) { + auto it = sdrGammaMap.find(valueStr); + if (it == sdrGammaMap.end()) { + LOGERR("Invalid SDRGamma value: %s", valueStr.c_str()); + returnResponse(false); + } + enumValue = it->second; + } + else { + // default: numeric parsing + try { + enumValue = std::stoi(valueStr); + } catch (const std::exception& e) { + LOGERR("Failed to parse %s as integer: %s", inputParamName.c_str(), e.what()); + returnResponse(false); + } + + if (enumValue < 0 || enumValue > maxAllowedValue) { + LOGERR("Input value %d is out of range for %s", enumValue, inputParamName.c_str()); + returnResponse(false); + } } // Get current context @@ -1680,41 +1699,36 @@ namespace Plugin { currentFmt = VIDEO_FORMAT_SDR; char picMode[PIC_MODE_NAME_MAX] = {0}; - if (getCurrentPictureMode(picMode)) - { + if (getCurrentPictureMode(picMode)) { auto it = pqModeReverseMap.find(picMode); - if (it != pqModeReverseMap.end()) - { + if (it != pqModeReverseMap.end()) { currentPQMode = static_cast(it->second); - } - else - { + } else { LOGERR("Unknown picture mode"); } - } - else - { + } else { LOGERR("Failed to get current picture mode"); } LOGINFO("currentPQMode: %d, currentFmt: %d, currentSrc: %d", currentPQMode, currentFmt, currentSrc); + // Call HAL if required if (isSetRequiredForParam(parameters, tr181ParamName)) { - tvError_t ret = halSetter(currentSrc, currentPQMode, currentFmt, value); + tvError_t ret = halSetter(currentSrc, currentPQMode, currentFmt, enumValue); if (ret != tvERROR_NONE) { LOGERR("HAL setter failed for %s", inputParamName.c_str()); returnResponse(false); } } - // Persist - int retval = updateAVoutputTVParamV2("set", tr181ParamName, parameters, pqParamType, value); + // Persist enum/int + int retval = updateAVoutputTVParamV2("set", tr181ParamName, parameters, pqParamType, enumValue); if (retval != 0) { - LOGERR("Failed to save %s to ssm_data", inputParamName.c_str()); + LOGERR("Failed to save %s to driver", inputParamName.c_str()); returnResponse(false); } - LOGINFO("Exit: %s set successfully to %d", inputParamName.c_str(), value); + LOGINFO("Exit: %s set successfully to %d", inputParamName.c_str(), enumValue); returnResponse(true); } @@ -3776,7 +3790,7 @@ namespace Plugin { return setContextPQParam( parameters, response, "sdrGamma", "SDRGamma", - tvSdrGamma_MAX, + tvSdrGamma_MAX-1, PQ_PARAM_SDR_GAMMA, [](tvVideoSrcType_t src, tvPQModeIndex_t mode, tvVideoFormatType_t /*fmt*/, int val) { return SetSdrGamma(src, mode, static_cast(val)); From df6525fe5e42b93b480f72d70bccb0cdb7c6fb52 Mon Sep 17 00:00:00 2001 From: skk451 Date: Wed, 3 Sep 2025 13:50:03 +0100 Subject: [PATCH 10/11] RDKEMW-5197: setZoomMode and resetZoomMode context based logic added. --- AVOutput/AVOutputTV.cpp | 113 +++++++++++++++++----------------- AVOutput/AVOutputTVHelper.cpp | 49 +++++++++++++-- 2 files changed, 102 insertions(+), 60 deletions(-) diff --git a/AVOutput/AVOutputTV.cpp b/AVOutput/AVOutputTV.cpp index 48ba060b..59f27f07 100644 --- a/AVOutput/AVOutputTV.cpp +++ b/AVOutput/AVOutputTV.cpp @@ -523,7 +523,7 @@ namespace Plugin { } // Shared zoom mode mappings - static const std::unordered_map zoomModeReverseMap = { + static const std::unordered_map zoomModeReverseMap = { {tvDisplayMode_16x9, "TV 16X9 STRETCH"}, {tvDisplayMode_4x3, "TV 4X3 PILLARBOX"}, {tvDisplayMode_NORMAL, "TV NORMAL"}, @@ -532,7 +532,7 @@ namespace Plugin { {tvDisplayMode_ZOOM, "TV ZOOM"}, {tvDisplayMode_FULL, "TV FULL"} }; - static const std::unordered_map zoomModeMap = { + static const std::unordered_map zoomModeMap = { {"TV 16X9 STRETCH", tvDisplayMode_16x9}, {"TV 4X3 PILLARBOX", tvDisplayMode_4x3}, {"TV NORMAL", tvDisplayMode_NORMAL}, @@ -1355,37 +1355,15 @@ namespace Plugin { } else { - std::string value = parameters.HasLabel("zoomMode") ? parameters["zoomMode"].String() : ""; - returnIfParamNotFound(parameters, "zoomMode"); - - auto it = zoomModeMap.find(value); - if (it == zoomModeMap.end()) { - LOGERR("Invalid zoom mode: %s. Not in supported options.", value.c_str()); - returnResponse(false); - } - tvDisplayMode_t mode = it->second; - tvError_t ret = setAspectRatioZoomSettings(mode); - if (ret != tvERROR_NONE) { - returnResponse(false); - } - else - { - // Save DisplayMode to local store and ssm_data - int retval = updateAVoutputTVParamV2("set", "AspectRatio", parameters, PQ_PARAM_ASPECT_RATIO, mode); - if (retval != 0) { - LOGERR("Failed to Save DisplayMode to ssm_data\n"); - returnResponse(false); - } - tr181ErrorCode_t err = setLocalParam(rfc_caller_id, AVOUTPUT_ASPECTRATIO_RFC_PARAM, value.c_str()); - if (err != tr181Success) { - LOGERR("setLocalParam for %s Failed : %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, getTR181ErrorString(err)); - returnResponse(false); - } else { - LOGINFO("setLocalParam for %s Successful, Value: %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, value.c_str()); - } - LOGINFO("Exit : SetAspectRatio() value : %s\n", value.c_str()); - returnResponse(true); - } + return setContextPQParam( + parameters, response, + "zoomMode", + "ZoomMode", + tvDisplayMode_MAX - 1, + PQ_PARAM_ASPECT_RATIO, + [this](tvVideoSrcType_t /*src*/, tvPQModeIndex_t /*mode*/, tvVideoFormatType_t /*fmt*/, int val) { + return setAspectRatioZoomSettings(static_cast(val));} + ); } } @@ -1443,33 +1421,48 @@ namespace Plugin { uint32_t AVOutputTV::resetZoomMode(const JsonObject& parameters, JsonObject& response) { LOGINFO("Entry\n"); - capDetails_t inputInfo; - tvError_t ret = tvERROR_NONE; + if(m_aspectRatioStatus == tvERROR_OPERATION_NOT_SUPPORTED) + { + capDetails_t inputInfo; + tvError_t ret = tvERROR_NONE; - if (parsingSetInputArgument(parameters, "AspectRatio",inputInfo) != 0) { - LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); - returnResponse(false); - } + if (parsingSetInputArgument(parameters, "AspectRatio",inputInfo) != 0) { + LOGERR("%s: Failed to parse the input arguments \n", __FUNCTION__); + returnResponse(false); + } - if( !isCapablityCheckPassed( "AspectRatio",inputInfo )) { - LOGERR("%s: CapablityCheck failed for AspectRatio\n", __FUNCTION__); - returnResponse(false); - } + if( !isCapablityCheckPassed( "AspectRatio",inputInfo )) { + LOGERR("%s: CapablityCheck failed for AspectRatio\n", __FUNCTION__); + returnResponse(false); + } - tr181ErrorCode_t err = clearLocalParam(rfc_caller_id,AVOUTPUT_ASPECTRATIO_RFC_PARAM); - if ( err != tr181Success ) { - LOGERR("clearLocalParam for %s Failed : %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, getTR181ErrorString(err)); - ret = tvERROR_GENERAL; - } - else { - ret = setDefaultAspectRatio(inputInfo.pqmode,inputInfo.source,inputInfo.format); - } - if(ret != tvERROR_NONE) { - returnResponse(false); + tr181ErrorCode_t err = clearLocalParam(rfc_caller_id,AVOUTPUT_ASPECTRATIO_RFC_PARAM); + if ( err != tr181Success ) { + LOGERR("clearLocalParam for %s Failed : %s\n", AVOUTPUT_ASPECTRATIO_RFC_PARAM, getTR181ErrorString(err)); + ret = tvERROR_GENERAL; + } + else { + ret = setDefaultAspectRatio(inputInfo.pqmode,inputInfo.source,inputInfo.format); + } + if(ret != tvERROR_NONE) { + returnResponse(false); + } + else { + LOGINFO("Exit : resetDefaultAspectRatio()\n"); + returnResponse(true); + } } - else { - LOGINFO("Exit : resetDefaultAspectRatio()\n"); - returnResponse(true); + else + { + bool success = resetEnumPQParamToDefault( + parameters, + "ZoomMode", + PQ_PARAM_ASPECT_RATIO, + zoomModeReverseMap, + [this](int intVal, const std::unordered_map& valueMap) -> tvError_t { + return setAspectRatioZoomSettings(static_cast(intVal)); + }); + returnResponse(success); } } @@ -1673,6 +1666,14 @@ namespace Plugin { } enumValue = it->second; } + else if (pqParamType == PQ_PARAM_ASPECT_RATIO) { + auto it = zoomModeMap.find(valueStr); + if (it == zoomModeMap.end()) { + LOGERR("Invalid ZoomMode value: %s", valueStr.c_str()); + returnResponse(false); + } + enumValue = it->second; + } else { // default: numeric parsing try { diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index 4b5ca818..0b566da9 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -928,7 +928,7 @@ namespace Plugin { std::map> fnMap = { {"ColorTemp", [this](int v, std::string& s) { getColorTempStringFromEnum(v, s); }}, {"DimmingMode", [this](int v, std::string& s) { getDimmingModeStringFromEnum(v, s); }}, - {"AspectRatio", [this](int v, std::string& s) { getDisplayModeStringFromEnum(v, s); }}, + {"ZoomMode", [this](int v, std::string& s) { getDisplayModeStringFromEnum(v, s); }}, {"BacklightMode", [this](int v, std::string& s) { getBacklightModeStringFromEnum(v, s); }}, {"SDRGamma", [this](int v, std::string& s) { getSdrGammaStringFromEnum(static_cast(v), s); }} }; @@ -1810,6 +1810,47 @@ namespace Plugin { } return 0; } + else if (forParam.compare("ZoomMode") == 0) { + if (strncmp(param.value, "TV 16X9 STRETCH", strlen(param.value)) == 0) { + value = tvDisplayMode_16x9; + } + else if (strncmp(param.value, "TV 4X3 PILLARBOX", strlen(param.value)) == 0) { + value = tvDisplayMode_4x3; + } + else if (strncmp(param.value, "TV NORMAL", strlen(param.value)) == 0) { + value = tvDisplayMode_NORMAL; + } + else if (strncmp(param.value, "TV DIRECT", strlen(param.value)) == 0) { + value = tvDisplayMode_DIRECT; + } + else if (strncmp(param.value, "TV AUTO", strlen(param.value)) == 0) { + value = tvDisplayMode_AUTO; + } + else if (strncmp(param.value, "TV ZOOM", strlen(param.value)) == 0) { + value = tvDisplayMode_ZOOM; + } + else if (strncmp(param.value, "TV FULL", strlen(param.value)) == 0) { + value = tvDisplayMode_FULL; + } + // Handle legacy formats without "TV" prefix + else if (strncmp(param.value, "16:9", strlen(param.value)) == 0) { + value = tvDisplayMode_16x9; + } + else if (strncmp(param.value, "4:3", strlen(param.value)) == 0) { + value = tvDisplayMode_4x3; + } + else if (strncmp(param.value, "Normal", strlen(param.value)) == 0) { + value = tvDisplayMode_NORMAL; + } + else if (strncmp(param.value, "Full", strlen(param.value)) == 0) { + value = tvDisplayMode_FULL; + } + else { + LOGWARN("Unknown ZoomMode value '%s', defaulting to TV AUTO", param.value); + value = tvDisplayMode_AUTO; + } + return 0; + } else { value=std::stoi(param.value); return 0; @@ -2196,7 +2237,7 @@ namespace Plugin { tvError_t AVOutputTV::setAspectRatioZoomSettings(tvDisplayMode_t mode) { tvError_t ret = tvERROR_GENERAL; - LOGERR("%s: mode selected is: %d", __FUNCTION__, m_videoZoomMode); + LOGINFO("%s: mode selected is: %d", __FUNCTION__, m_videoZoomMode); #if !defined (HDMIIN_4K_ZOOM) if (AVOutputTV::instance->m_isDisabledHdmiIn4KZoom) { if (AVOutputTV::instance->m_currentHdmiInResoluton Date: Wed, 10 Sep 2025 10:20:54 +0100 Subject: [PATCH 11/11] Fix for Reset resulting in black screen --- AVOutput/AVOutputTV.cpp | 6 +-- AVOutput/AVOutputTV.h | 9 ++-- AVOutput/AVOutputTVHelper.cpp | 84 +++++++++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 10 deletions(-) diff --git a/AVOutput/AVOutputTV.cpp b/AVOutput/AVOutputTV.cpp index 59f27f07..9a7e0671 100644 --- a/AVOutput/AVOutputTV.cpp +++ b/AVOutput/AVOutputTV.cpp @@ -1948,7 +1948,7 @@ namespace Plugin { inputInfo.source = "Current"; inputInfo.format = "Current"; - if (getParamIndex(paramName, inputInfo, indexInfo) == 0 && + if (getParamIndexV2(paramName, inputInfo, indexInfo) == 0 && getLocalparam(paramName, indexInfo, intVal, pqIndex) == 0) { LOGINFO("%s: getLocalparam success for %s [format=%d, source=%d, mode=%d] → value=%d\n", @@ -2004,7 +2004,7 @@ namespace Plugin { inputInfo.source = "Current"; inputInfo.format = "Current"; - if (getParamIndex(paramName, inputInfo, indexInfo) == 0 && + if (getParamIndexV2(paramName, inputInfo, indexInfo) == 0 && getLocalparam(paramName, indexInfo, level, pqIndex) == 0) { LOGINFO("%s: getLocalparam success for %s: format=%d, source=%d, mode=%d, value=%d\n", @@ -2061,7 +2061,7 @@ namespace Plugin { inputInfo.source = "Current"; inputInfo.format = "Current"; - if (getParamIndex(paramName, inputInfo, indexInfo) == 0 && + if (getParamIndexV2(paramName, inputInfo, indexInfo) == 0 && getLocalparam(paramName, indexInfo, level, pqIndex) == 0) { LOGINFO("%s: getLocalparam success for %s: format=%d, source=%d, mode=%d, value=%d\n", diff --git a/AVOutput/AVOutputTV.h b/AVOutput/AVOutputTV.h index 199d443a..1f329207 100644 --- a/AVOutput/AVOutputTV.h +++ b/AVOutput/AVOutputTV.h @@ -328,6 +328,7 @@ class AVOutputTV : public AVOutputBase { int getDolbyModeIndex(const char * dolbyMode); int getHDRModeIndex(const std::string HDRMode, const std::string format,tvDolbyMode_t &value); tvDimmingMode_t getDimmingModeIndex(string mode); + int getParamIndexV2(std::string param, capDetails_t& paramInfo, paramIndex_t& indexInfo); bool isIncluded(const std::set set1,const std::set set2); bool isSetRequired(std::string pqmode,std::string source,std::string format); @@ -428,14 +429,14 @@ class AVOutputTV : public AVOutputBase { tvError_t setAspectRatioZoomSettings(tvDisplayMode_t mode); tvError_t setDefaultAspectRatio(std::string pqmode="none",std::string format="none",std::string source="none"); template - static int getEnumFromString(const std::map& reverseMap, const std::string& key, T defaultVal) { + static int getEnumFromString(const std::unordered_map& reverseMap, const std::string& key, T defaultVal) { auto it = reverseMap.find(key); return (it != reverseMap.end()) ? it->second : defaultVal; } - static const std::map pqModeMap; - static const std::map videoFormatMap; - static const std::map videoSrcMap; + static const std::unordered_map pqModeMap; + static const std::unordered_map videoFormatMap; + static const std::unordered_map videoSrcMap; static const std::unordered_map backlightModeMap; static std::unordered_map pqModeReverseMap; diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index 0b566da9..81f0b6cf 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -132,6 +132,84 @@ namespace Plugin { return 0; } + int AVOutputTV::getParamIndexV2(std::string param, capDetails_t& paramInfo, paramIndex_t& indexInfo) + { + LOGINFO("Entry : %s param : %s pqmode : %s source : %s format : %s\n", + __FUNCTION__, param.c_str(), paramInfo.pqmode.c_str(), paramInfo.source.c_str(), paramInfo.format.c_str()); + initializeReverseMaps(); + if (paramInfo.source == "none" || paramInfo.source == "Current") { + tvVideoSrcType_t currentSource = VIDEO_SOURCE_IP; + GetCurrentVideoSource(¤tSource); + indexInfo.sourceIndex = static_cast(currentSource); + } else { + auto it = videoSrcReverseMap.find(paramInfo.source); + indexInfo.sourceIndex = (it != videoSrcReverseMap.end()) ? static_cast(it->second) : -1; + } + if (paramInfo.pqmode == "none" || paramInfo.pqmode == "Current") { + char picMode[PIC_MODE_NAME_MAX] = {0}; + if (!getCurrentPictureMode(picMode)) { + LOGERR("Failed to get the Current picture mode\n"); + indexInfo.pqmodeIndex = -1; + } else { + std::string local = picMode; + auto it = pqModeReverseMap.find(local); + indexInfo.pqmodeIndex = (it != pqModeReverseMap.end()) ? static_cast(it->second) : -1; + } + } else { + auto it = pqModeReverseMap.find(paramInfo.pqmode); + indexInfo.pqmodeIndex = (it != pqModeReverseMap.end()) ? static_cast(it->second) : -1; + } + if (paramInfo.format == "none" || paramInfo.format == "Current") { + tvVideoFormatType_t currentFormat = VIDEO_FORMAT_NONE; + GetCurrentVideoFormat(¤tFormat); + if (currentFormat == VIDEO_FORMAT_NONE) { + indexInfo.formatIndex = VIDEO_FORMAT_SDR; // Legacy default + } else { + indexInfo.formatIndex = static_cast(currentFormat); + } + } else { + auto it = videoFormatReverseMap.find(paramInfo.format); + indexInfo.formatIndex = (it != videoFormatReverseMap.end()) ? static_cast(it->second) : -1; + } + if (param == "CMS") { + tvDataComponentColor_t level = tvDataColor_NONE; + if (getCMSColorEnumFromString(paramInfo.color, level) == -1) { + LOGERR("%s : GetColorEnumFromString Failed!!! ", __FUNCTION__); + return -1; + } + indexInfo.colorIndex = level; + tvComponentType_t componentLevel; + if (getCMSComponentEnumFromString(paramInfo.component, componentLevel) == -1) { + LOGERR("%s : GetComponentEnumFromString Failed!!! ", __FUNCTION__); + return -1; + } + indexInfo.componentIndex = componentLevel; + LOGINFO("%s colorIndex : %d , componentIndex : %d\n", + __FUNCTION__, indexInfo.colorIndex, indexInfo.componentIndex); + } + if (param == "WhiteBalance") { + tvWBColor_t level; + if (getWBColorEnumFromString(paramInfo.color, level) == -1) { + LOGERR("%s : GetColorEnumFromString Failed!!! ", __FUNCTION__); + return -1; + } + indexInfo.colorIndex = level; + tvWBControl_t controlLevel; + if (getWBControlEnumFromString(paramInfo.control, controlLevel) == -1) { + LOGERR("%s : GetComponentEnumFromString Failed!!! ", __FUNCTION__); + return -1; + } + indexInfo.controlIndex = controlLevel; + LOGINFO("%s colorIndex : %d , controlIndex : %d\n", + __FUNCTION__, indexInfo.colorIndex, indexInfo.controlIndex); + } + if (indexInfo.sourceIndex == -1 || indexInfo.pqmodeIndex == -1 || indexInfo.formatIndex == -1) { + return -1; + } + LOGINFO("%s: Exit sourceIndex = %d pqmodeIndex = %d formatIndex = %d\n", + __FUNCTION__, indexInfo.sourceIndex, indexInfo.pqmodeIndex, indexInfo.formatIndex); + return 0; + } int AVOutputTV::getParamIndex(std::string param, capDetails_t& paramInfo, paramIndex_t& indexInfo) { @@ -2682,7 +2760,7 @@ namespace Plugin { return 0; } //JSON Based V2 Helpers - const std::map AVOutputTV::pqModeMap = { + const std::unordered_map AVOutputTV::pqModeMap = { {PQ_MODE_SPORTS, "Sports"}, {PQ_MODE_THEATER, "Theater"}, {PQ_MODE_GAME, "Game"}, @@ -2696,7 +2774,7 @@ namespace Plugin { {PQ_MODE_CUSTOM, "Custom"} }; - const std::map AVOutputTV::videoFormatMap = { + const std::unordered_map AVOutputTV::videoFormatMap = { {VIDEO_FORMAT_NONE, "None"}, {VIDEO_FORMAT_SDR, "SDR"}, {VIDEO_FORMAT_HDR10, "HDR10"}, @@ -2705,7 +2783,7 @@ namespace Plugin { {VIDEO_FORMAT_HLG, "HLG"} }; - const std::map AVOutputTV::videoSrcMap = { + const std::unordered_map AVOutputTV::videoSrcMap = { {VIDEO_SOURCE_COMPOSITE1, "Composite1"}, {VIDEO_SOURCE_HDMI1, "HDMI1"}, {VIDEO_SOURCE_HDMI2, "HDMI2"},