in src/cdi/baseline_profiles_2_00.c [445:666]
static bool ParseBaselineVideoConfiguration(const CdiAvmConfig* config_ptr, CdiAvmBaselineConfigCommon* baseline_ptr)
{
bool ret = true;
CdiAvmBaselineConfig* baseline_config_ptr = (CdiAvmBaselineConfig*)baseline_ptr;
// Make a copy of the data array since CdiOsStrTokR is destructive. +1 for terminating NUL character.
char copy_str[sizeof(config_ptr->data) + 1];
memcpy(copy_str, config_ptr->data, config_ptr->data_size);
copy_str[config_ptr->data_size] = '\0';
CdiAvmVideoConfig* video_config_ptr = &baseline_config_ptr->video_config;
// Set non-zero, optional, default video configuration values.
video_config_ptr->par_width = 1;
video_config_ptr->par_height = 1;
// Break the string up into semicolon separated tokens.
int i = 0;
char* param_save_ptr = NULL;
for (char* param_ptr = copy_str ; ret && NULL != param_ptr ; i++) {
param_ptr = CdiOsStrTokR((i == 0) ? param_ptr : NULL, "; ", ¶m_save_ptr);
if (param_ptr != NULL) {
char* value_ptr = strchr(param_ptr, '=');
if (NULL != value_ptr) {
// Replace '=' with NUL character so ptr is terminated. Increment value_ptr so it points to the value
// which is already NUL terminated by CdiOsStrTokR().
*(value_ptr++) = '\0';
}
if (0 == CdiOsStrCaseCmp(param_ptr, "cdi_profile_version")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video profile version parameter value is missing");
ret = false;
} else {
if (!CdiAvmParseBaselineVersionString(value_ptr, &video_config_ptr->version)) {
CDI_LOG_THREAD(kLogError, "unable to parse video profile version parameter value [%s]",
value_ptr);
ret = false;
}
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "sampling")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video sampling parameter value is missing");
ret = false;
} else {
int key = CdiAvmKeyStringToEnum(kKeyAvmVideoSamplingType, value_ptr,
&video_config_ptr->version);
if (CDI_INVALID_ENUM_VALUE == key) {
CDI_LOG_THREAD(kLogError, "unknown video sampling value [%s]", value_ptr);
ret = false;
} else {
video_config_ptr->sampling = (CdiAvmVideoSampling)key;
}
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "depth")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video depth parameter value is missing");
ret = false;
} else {
int bit_depth = atoi(value_ptr);
switch (bit_depth) {
case 8:
video_config_ptr->depth = kCdiAvmVidBitDepth8;
break;
case 10:
video_config_ptr->depth = kCdiAvmVidBitDepth10;
break;
case 12:
video_config_ptr->depth = kCdiAvmVidBitDepth12;
break;
default:
CDI_LOG_THREAD(kLogError, "invalid video bit depth value [%s]", value_ptr);
ret = false;
break;
}
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "width")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video width parameter value is missing");
ret = false;
} else {
video_config_ptr->width = atoi(value_ptr);
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "height")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video height parameter value is missing");
ret = false;
} else {
video_config_ptr->height = atoi(value_ptr);
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "exactframerate")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video exactframerate parameter value is missing");
ret = false;
} else {
char* denominator_ptr = strchr(value_ptr, '/');
if (NULL != denominator_ptr) {
*(denominator_ptr++) = '\0';
video_config_ptr->frame_rate_den = atoi(denominator_ptr);
} else {
video_config_ptr->frame_rate_den = 1;
}
video_config_ptr->frame_rate_num = atoi(value_ptr);
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "colorimetry")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video colorimetry parameter value is missing");
ret = false;
} else {
int key = CdiAvmKeyStringToEnum(kKeyAvmVideoColorimetryType, value_ptr,
&video_config_ptr->version);
if (CDI_INVALID_ENUM_VALUE == key) {
CDI_LOG_THREAD(kLogError, "unknown video colorimetry value [%s]", value_ptr);
ret = false;
} else {
video_config_ptr->colorimetry = (CdiAvmColorimetry)key;
}
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "interlace")) {
if (NULL != value_ptr) {
CDI_LOG_THREAD(kLogWarning, "value for video interlace parameter ignored [%s]", value_ptr);
} else {
video_config_ptr->interlace = true;
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "segmented")) {
if (NULL != value_ptr) {
CDI_LOG_THREAD(kLogWarning, "value for video segmented parameter ignored [%s]", value_ptr);
} else {
video_config_ptr->segmented = true;
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "TCS")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video TCS parameter value is missing");
ret = false;
} else {
int key = CdiAvmKeyStringToEnum(kKeyAvmVideoTcsType, value_ptr,
&video_config_ptr->version);
if (CDI_INVALID_ENUM_VALUE == key) {
CDI_LOG_THREAD(kLogError, "unknown video TCS value [%s]", value_ptr);
ret = false;
} else {
video_config_ptr->tcs = (CdiAvmVideoTcs)key;
}
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "RANGE")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video RANGE parameter value is missing");
ret = false;
} else {
int key = CdiAvmKeyStringToEnum(kKeyAvmVideoRangeType, value_ptr,
&video_config_ptr->version);
if (CDI_INVALID_ENUM_VALUE == key) {
CDI_LOG_THREAD(kLogError, "unknown video RANGE value [%s]", value_ptr);
ret = false;
} else {
video_config_ptr->range = (CdiAvmVideoRange)key;
}
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "PAR")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video exactframerate parameter value is missing");
ret = false;
} else {
char* height_ptr = strchr(value_ptr, ':');
if (NULL != height_ptr) {
*(height_ptr++) = '\0';
video_config_ptr->par_height = atoi(height_ptr);
}
video_config_ptr->par_width = atoi(value_ptr);
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "alpha_included")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video alpha_included parameter value is missing");
ret = false;
} else {
if (0 == CdiOsStrCaseCmp(value_ptr, "enabled")) {
video_config_ptr->alpha_channel = kCdiAvmAlphaUsed;
} else if (0 != CdiOsStrCaseCmp(value_ptr, "disabled")) {
CDI_LOG_THREAD(kLogWarning, "invalid video alpha_included depth value [%s]", value_ptr);
}
}
} else if (0 == CdiOsStrCaseCmp(param_ptr, "partial_frame")) {
if (NULL == value_ptr) {
CDI_LOG_THREAD(kLogError, "video alpha_included parameter value is missing");
ret = false;
} else {
// Save address in original copy and length in case error message needs to be logged.
char* value_save_str = value_ptr - copy_str + (char*)config_ptr->data;
int value_save_length = strlen(value_ptr);
bool partial_frame_parsed = false;
char* height_ptr = strchr(value_ptr, 'x');
if (NULL != height_ptr) {
*(height_ptr++) = '\0';
char* hoffset_ptr = strchr(height_ptr, '+');
if (NULL != hoffset_ptr) {
*(hoffset_ptr++) = '\0';
char* voffset_ptr = strchr(hoffset_ptr, '+');
if (NULL != voffset_ptr) {
*(voffset_ptr++) = '\0';
video_config_ptr->horizontal_size = atoi(value_ptr);
video_config_ptr->vertical_size = atoi(height_ptr);
video_config_ptr->start_horizontal_pos = atoi(hoffset_ptr);
video_config_ptr->start_vertical_pos = atoi(voffset_ptr);
partial_frame_parsed = true;
}
}
}
if (!partial_frame_parsed) {
// Restore entire value back to its place in copy_str.
memcpy(value_ptr, value_save_str, value_save_length);
CDI_LOG_THREAD(kLogError, "invalid video partial_frame value [%s]", value_ptr);
ret = false;
}
}
} else {
CDI_LOG_THREAD(kLogWarning, "unknown parameter/value in video configuration string [%s]", param_ptr);
}
}
}
return ret;
}