blob: 8c5a340d9ede67778bc2072304fa94cfe14ea7df [file] [log] [blame]
#include "wcgCoef.h"
#include "hdrContext.h"
#include <unistd.h>
using namespace std;
void wcgCoef::parse_inoutGamut(
int hw_id,
int module_id,
struct wcgModule &wcg_module,
xmlDocPtr xml_doc,
xmlNodePtr xml_in)
{
IHdrHw *IHw = hwInfo->getIf(hw_id);
xmlNodePtr in = xml_in;
while (in != NULL) {
if (!xmlStrcmp(in->name, (const xmlChar *)"in")) {
xmlChar* in_gamut = xmlGetProp(in, (const xmlChar *)"gamut");
int in_gamut_id = stStrMap[string((char*)in_gamut)];
//ALOGD("in gamut(%s)", (char*)in_gamut);
xmlFree(in_gamut);
xmlNodePtr out = in->xmlChildrenNode;
while (out != NULL) {
if (!xmlStrcmp(out->name, (const xmlChar *)"out")) {
xmlChar* out_gamut = xmlGetProp(out, (const xmlChar *)"gamut");
int out_gamut_id = stStrMap[string((char*)out_gamut)];
//ALOGD("->out gamut(%s)", (char*)out_gamut);
xmlFree(out_gamut);
xmlNodePtr subMod = out->xmlChildrenNode;
while (subMod != NULL) {
string subModName = (char*)subMod->name;
if (IHw->hasSubMod(module_id, subModName)) {
xmlChar *key = xmlNodeListGetString(xml_doc,
subMod->xmlChildrenNode, 1);
std::vector<int> out_vec;
split(string((char*)key), ',', out_vec);
xmlFree(key);
struct gm tmp;
tmp.gmCoef = out_vec;
IHw->pack(subModName, module_id, out_vec, tmp.gmCoef_packed);
wcg_module.gmTable[in_gamut_id].out[out_gamut_id].data.insert(make_pair(subModName, tmp));
//wcg_module.gmTable[in_gamut_id].out[out_gamut_id].data[subModName].dump();
}
subMod = subMod->next;
}
}
out = out->next;
}
}
in = in->next;
}
}
void wcgCoef::parse_outTransfer(
int hw_id,
int module_id,
struct wcgModule &wcg_module,
xmlDocPtr xml_doc,
xmlNodePtr xml_out)
{
IHdrHw *IHw = hwInfo->getIf(hw_id);
xmlNodePtr out = xml_out;
while (out != NULL) {
if (!xmlStrcmp(out->name, (const xmlChar *)"transfer")) {
xmlChar* function = xmlGetProp(out, (const xmlChar *)"function");
if (tfStrMap.find(string((char*)function)) != tfStrMap.end()) {
int id = tfStrMap[string((char*)function)];
if (id >= wcg_module.oetfTable.capacity())
ALOGD("%s: transfer id exceeded its limit(function(%s), id(%d), limit(%lu)",
__func__, (char*)function, id, (unsigned long)wcg_module.oetfTable.capacity());
else {
xmlNodePtr subMod = out->xmlChildrenNode;
while (subMod != NULL) {
string subModName = (char*)subMod->name;
if (IHw->hasSubMod(module_id, subModName)) {
//ALOGD("function(%s), subModName(%s)", (char*)function, subModName.c_str());
xmlChar *key = xmlNodeListGetString(xml_doc,
subMod->xmlChildrenNode, 1);
std::vector<int> out_vec;
split(string((char*)key), ',', out_vec);
xmlFree(key);
struct oetf tmp;
tmp.oetfCoef = out_vec;
IHw->pack(subModName, module_id, out_vec, tmp.oetfCoef_packed);
wcg_module.oetfTable[id].data.insert(make_pair(subModName, tmp));
//wcg_module.oetfTable[id].data[subModName].dump();
}
subMod = subMod->next;
}
}
}
xmlFree(function);
}
out = out->next;
}
}
void wcgCoef::parse_inTransfer(
int hw_id,
int module_id,
struct wcgModule &wcg_module,
xmlDocPtr xml_doc,
xmlNodePtr xml_in)
{
IHdrHw *IHw = hwInfo->getIf(hw_id);
xmlNodePtr in = xml_in;
while (in != NULL) {
if (!xmlStrcmp(in->name, (const xmlChar *)"transfer")) {
xmlChar* function = xmlGetProp(in, (const xmlChar *)"function");
if (tfStrMap.find(string((char*)function)) != tfStrMap.end()) {
int id = tfStrMap[string((char*)function)];
if (id >= wcg_module.eotfTable.capacity())
ALOGD("%s: transfer id exceeded its limit(function(%s), id(%d), limit(%lu)",
__func__, (char*)function, id, (unsigned long)wcg_module.eotfTable.capacity());
else {
xmlNodePtr subMod = in->xmlChildrenNode;
while (subMod != NULL) {
string subModName = (char*)subMod->name;
if (IHw->hasSubMod(module_id, subModName)) {
//ALOGD("function(%s), subModName(%s)", (char*)function, subModName.c_str());
xmlChar *key = xmlNodeListGetString(xml_doc,
subMod->xmlChildrenNode, 1);
std::vector<int> in_vec;
split(string((char*)key), ',', in_vec);
xmlFree(key);
struct eotf tmp;
tmp.eotfCoef = in_vec;
IHw->pack(subModName, module_id, in_vec, tmp.eotfCoef_packed);
wcg_module.eotfTable[id].data.insert(make_pair(subModName, tmp));
//wcg_module.eotfTable[id].data[subModName].dump();
}
subMod = subMod->next;
}
}
}
xmlFree(function);
}
in = in->next;
}
}
void wcgCoef::parse_inoutTransfer(
int hw_id,
int module_id,
struct wcgModule &wcg_module,
xmlDocPtr xml_doc,
xmlNodePtr xml_option)
{
xmlNodePtr option = xml_option;
while (option != NULL) {
if (!xmlStrcmp(option->name, (const xmlChar *)"in"))
parse_inTransfer(hw_id, module_id, wcg_module,
xml_doc, option->xmlChildrenNode);
else if (!xmlStrcmp(option->name, (const xmlChar *)"out"))
parse_outTransfer(hw_id, module_id, wcg_module,
xml_doc, option->xmlChildrenNode);
option = option->next;
}
}
void wcgCoef::parse_inoutDataspace(
int hw_id,
int module_id,
struct wcgModule &wcg_module,
xmlDocPtr xml_doc,
xmlNodePtr xml_option)
{
xmlNodePtr option = xml_option;
IHdrHw *IHw = hwInfo->getIf(hw_id);
while (option != NULL) {
if (!xmlStrcmp(option->name, (const xmlChar *)"eq")) {
xmlNodePtr eqSubMod = option->xmlChildrenNode;
while (eqSubMod != NULL) {
string subModName = (char*)eqSubMod->name;
if (IHw->hasSubMod(module_id, subModName)) {
xmlChar *key = xmlNodeListGetString(xml_doc,
eqSubMod->xmlChildrenNode, 1);
std::vector<int> in;
split(string((char*)key), ',', in);
xmlFree(key);
struct modEn tmp;
tmp.modEnCoef = (bool)in[0];
IHw->pack(subModName, module_id, in, tmp.modEnCoef_packed);
//tmp.modEnCoef_packed.dump();
wcg_module.modEnTable[0].data.insert(make_pair(subModName, tmp));
}
eqSubMod = eqSubMod->next;
}
} else if (!xmlStrcmp(option->name, (const xmlChar *)"neq")) {
xmlNodePtr neqSubMod = option->xmlChildrenNode;
while (neqSubMod != NULL) {
string subModName = (char*)neqSubMod->name;
if (IHw->hasSubMod(module_id, subModName)) {
xmlChar *key = xmlNodeListGetString(xml_doc,
neqSubMod->xmlChildrenNode, 1);
std::vector<int> in;
split(string((char*)key), ',', in);
xmlFree(key);
struct modEn tmp;
tmp.modEnCoef = (bool)in[0];
IHw->pack(subModName, module_id, in, tmp.modEnCoef_packed);
//tmp.modEnCoef_packed.dump();
wcg_module.modEnTable[1].data.insert(make_pair(subModName, tmp));
}
neqSubMod = neqSubMod->next;
}
}
option = option->next;
}
}
void wcgCoef::parse_inoutCustom(
struct wcgModule &wcg_module,
xmlNodePtr xml_in)
{
xmlNodePtr in = xml_in;
while (in != NULL) {
if (!xmlStrcmp(in->name, (const xmlChar *)"in")) {
int in_gamut_id = stStrMap["UNSPECIFIED"];
int in_transfer_id = tfStrMap["UNSPECIFIED"];
int in_dataspace = HAL_DATASPACE_UNKNOWN;
xmlChar* in_gamut = xmlGetProp(in, (const xmlChar *)"gamut");
if (in_gamut) {
in_gamut_id = stStrMap[string((char*)in_gamut)];
xmlFree(in_gamut);
}
xmlChar* in_transfer = xmlGetProp(in, (const xmlChar *)"transfer");
if (in_transfer) {
in_transfer_id = tfStrMap[string((char*)in_transfer)];
xmlFree(in_transfer);
}
in_dataspace = (in_gamut_id << HAL_DATASPACE_STANDARD_SHIFT) |
(in_transfer_id << HAL_DATASPACE_TRANSFER_SHIFT);
xmlNodePtr out = in->xmlChildrenNode;
while (out != NULL && in_dataspace != HAL_DATASPACE_UNKNOWN) {
if (!xmlStrcmp(out->name, (const xmlChar *)"out")) {
int out_gamut_id = stStrMap["UNSPECIFIED"];
int out_transfer_id = tfStrMap["UNSPECIFIED"];
int out_capa_id = capStrMap["UNSPECIFIED"];
int out_dataspace = HAL_DATASPACE_UNKNOWN;
xmlChar* out_gamut = xmlGetProp(out, (const xmlChar *)"gamut");
if (out_gamut) {
out_gamut_id = stStrMap[string((char*)out_gamut)];
xmlFree(out_gamut);
}
xmlChar* out_transfer = xmlGetProp(out, (const xmlChar *)"transfer");
if (out_transfer) {
out_transfer_id = tfStrMap[string((char*)out_transfer)];
xmlFree(out_transfer);
}
xmlChar* out_capa = xmlGetProp(out, (const xmlChar *)"capa");
if (out_capa) {
out_capa_id = capStrMap[string((char*)out_capa)];
xmlFree(out_capa);
}
out_dataspace = (out_gamut_id << HAL_DATASPACE_STANDARD_SHIFT) |
(out_transfer_id << HAL_DATASPACE_TRANSFER_SHIFT);
wcg_module.customTable[in_dataspace] = {out_dataspace, out_capa_id};
}
out = out->next;
}
}
in = in->next;
}
}
void wcgCoef::parse_wcgMod(
int hw_id,
int module_id,
struct wcgModule &wcg_module,
xmlDocPtr xml_doc,
xmlNodePtr xml_module)
{
xmlNodePtr subInfo = xml_module;
while (subInfo != NULL) {
if (!xmlStrcmp(subInfo->name, (const xmlChar *)"inout-dataspace"))
parse_inoutDataspace(hw_id, module_id, wcg_module, xml_doc, subInfo->xmlChildrenNode);
else if (!xmlStrcmp(subInfo->name, (const xmlChar *)"inout-transfer"))
parse_inoutTransfer(hw_id, module_id, wcg_module, xml_doc, subInfo->xmlChildrenNode);
else if (!xmlStrcmp(subInfo->name, (const xmlChar *)"inout-gamut"))
parse_inoutGamut(hw_id, module_id, wcg_module, xml_doc, subInfo->xmlChildrenNode);
else if (!xmlStrcmp(subInfo->name, (const xmlChar *)"inout-custom"))
parse_inoutCustom(wcg_module, subInfo->xmlChildrenNode);
subInfo = subInfo->next;
}
}
void wcgCoef::parse_wcgMods(
int hw_id,
xmlDocPtr xml_doc,
xmlNodePtr xml_module)
{
xmlNodePtr module = xml_module;
xmlChar *module_id;
vector<int> wcgModIds;
while (module != NULL) {
struct wcgModule wcgMod;
if (xmlStrcmp(module->name, (const xmlChar *)"wcg-module")) {
module = module->next;
continue;
}
module_id = xmlGetProp(module, (const xmlChar *)"layer");
split(string((char*)module_id), ',', wcgModIds);
xmlFree(module_id);
for (auto &modId : wcgModIds) {
parse_wcgMod(hw_id, modId, wcgMod, xml_doc, module->xmlChildrenNode);
layerToWcgMod.insert(make_pair(modId, wcgMod));
}
module = module->next;
}
}
void wcgCoef::__parse__(int hw_id, struct hdrContext *ctx)
{
xmlDocPtr doc;
xmlNodePtr root;
std::string fn_default = filename + (std::string)".xml";
std::string fn_target = filename + ctx->target_name;
doc = xmlParseFile(fn_target.c_str());
if (doc == NULL) {
ALOGD("no document or can not parse the document(%s)",
fn_target.c_str());
doc = xmlParseFile(fn_default.c_str());
if (doc == NULL) {
ALOGD("no document or can not parse the default document(%s)",
fn_default.c_str());
goto ret;
}
}
root = xmlDocGetRootElement(doc);
if (root == NULL) {
ALOGE("empty document");
goto free_doc;
}
if (xmlStrcmp(root->name, (const xmlChar *)"WCG")) {
ALOGE("document of the wrong type, root node != WCG");
goto free_root;
}
parse_wcgMods(hw_id, doc, root->xmlChildrenNode);
free_root:
//xmlFree(root);
free_doc:
xmlFreeDoc(doc);
ret:
return;
}
void wcgCoef::parse(vector<struct supportedHdrHw> *list, struct hdrContext *ctx)
{
for (auto &item : *list) {
switch (item.id) {
case HDR_HW_DPU:
__parse__(HDR_HW_DPU, ctx);
break;
default:
ALOGE("hw(%d) not supported", item.id);
break;
}
}
}
void wcgCoef::init(hdrHwInfo *hwInfo, struct hdrContext *ctx)
{
capStrMap = mapStringToCapa();
tfStrMap.clear();
for (auto &tf : transferTable)
tfStrMap[tf.str] = tf.id;
stStrMap.clear();
for (auto &st : standardTable)
stStrMap[st.str] = st.id;
this->hwInfo = hwInfo;
parse(hwInfo->getListHdrHw(), ctx);
//this->dump();
}
int wcgCoef::coefBuildup(int layer_index, struct hdrContext *ctx)
{
int ret = HDR_ERR_NO;
int hw_id = ctx->hw_id;
struct wcgModule *module = &layerToWcgMod[layer_index];
auto *layer = &ctx->Layers[hw_id][layer_index];
auto *Target = &ctx->Target;
int input_dataspace = layer->dataspace & (HAL_DATASPACE_STANDARD_MASK | HAL_DATASPACE_TRANSFER_MASK);
int output_dataspace = Target->dataspace & (HAL_DATASPACE_STANDARD_MASK | HAL_DATASPACE_TRANSFER_MASK);
if (module->customTable.count(input_dataspace) &&
module->customTable[input_dataspace].capa == Target->hdr_capa) {
output_dataspace = module->customTable[input_dataspace].dataspace;
}
int input_transfer = (input_dataspace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
int input_gamut = (input_dataspace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
int output_transfer = (output_dataspace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
int output_gamut = (output_dataspace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
if (input_transfer == output_transfer && input_gamut == output_gamut) {
layer->setInActive();
for (auto iter = module->modEnTable[0].data.begin();
iter != module->modEnTable[0].data.end(); iter++) {
struct hdr_dat_node* dat = &iter->second.modEnCoef_packed;
dat->queue_and_group(
layer->shall,
layer->group[hw_id]);
}
} else {
layer->setActive();
for (auto iter = module->modEnTable[1].data.begin();
iter != module->modEnTable[1].data.end(); iter++) {
struct hdr_dat_node* dat = &iter->second.modEnCoef_packed;
dat->queue_and_group(
layer->shall,
layer->group[hw_id]);
}
for (auto iter = module->eotfTable[input_transfer].data.begin();
iter != module->eotfTable[input_transfer].data.end(); iter++) {
struct hdr_dat_node* dat = &iter->second.eotfCoef_packed;
dat->queue_and_group(
layer->shall,
layer->group[hw_id]);
}
for (auto iter = module->oetfTable[output_transfer].data.begin();
iter != module->oetfTable[output_transfer].data.end(); iter++) {
struct hdr_dat_node* dat = &iter->second.oetfCoef_packed;
dat->queue_and_group(
layer->shall,
layer->group[hw_id]);
}
for (auto iter = module->gmTable[input_gamut].out[output_gamut].data.begin();
iter != module->gmTable[input_gamut].out[output_gamut].data.end(); iter++) {
struct hdr_dat_node* dat = &iter->second.gmCoef_packed;
dat->queue_and_group(
layer->shall,
layer->group[hw_id]);
}
}
for (auto iter = layer->group[hw_id].begin(); iter != layer->group[hw_id].end(); iter++)
layer->shall.push_back(&iter->second);
return ret;
}