Commit 0a90edeb authored by Sehoon Yea's avatar Sehoon Yea Committed by David Flynn
Browse files

attr/m49605: add inter component prediction for predicting coder

This adoption permits prediction of residuals between components of
the same attribute, coding the residual resulting from this second
prediction.
parent c963fede
...@@ -43,6 +43,7 @@ categories: ...@@ -43,6 +43,7 @@ categories:
- positionQuantizationScaleAdjustsDist2: 1 - positionQuantizationScaleAdjustsDist2: 1
- dist2: ${seq_dist2} - dist2: ${seq_dist2}
- intraLodPredictionEnabled: 1 - intraLodPredictionEnabled: 1
- interComponentPredictionEnabled: 1
## ##
# attribute coding -- reflectance # attribute coding -- reflectance
......
...@@ -39,6 +39,7 @@ categories: ...@@ -39,6 +39,7 @@ categories:
- positionQuantizationScaleAdjustsDist2: 1 - positionQuantizationScaleAdjustsDist2: 1
- dist2: ${seq_dist2} - dist2: ${seq_dist2}
- intraLodPredictionEnabled: 1 - intraLodPredictionEnabled: 1
- interComponentPredictionEnabled: 1
## ##
# attribute coding -- reflectance # attribute coding -- reflectance
......
...@@ -317,6 +317,10 @@ Neighbouring attribute value difference that enables choice of ...@@ -317,6 +317,10 @@ Neighbouring attribute value difference that enables choice of
single|multi predictors. Applies to transformType=2 only. single|multi predictors. Applies to transformType=2 only.
A value of -1 is replaced by 2**(bitdepth-2). A value of -1 is replaced by 2**(bitdepth-2).
### `--interComponentPredictionEnabled=0|1`
Controls the use of an in-loop inter-component prediction of attribute
residuals. Applies to `transformType=1` and `attribute=color` only.
### `--attributeSearchRange=INT-VALUE` ### `--attributeSearchRange=INT-VALUE`
Range for nearest neighbour search. Range for nearest neighbour search.
......
...@@ -403,12 +403,16 @@ AttributeDecoder::decodeColorsPred( ...@@ -403,12 +403,16 @@ AttributeDecoder::decodeColorsPred(
predictor.predictColor(pointCloud, indexesLOD); predictor.predictColor(pointCloud, indexesLOD);
int64_t clipMax = (1 << desc.attr_bitdepth) - 1; int64_t clipMax = (1 << desc.attr_bitdepth) - 1;
int64_t residual0 = 0;
for (int k = 0; k < 3; ++k) { for (int k = 0; k < 3; ++k) {
const auto& q = quant[std::min(k, 1)]; const auto& q = quant[std::min(k, 1)];
const int64_t residual = divExp2RoundHalfUp( const int64_t residual = divExp2RoundHalfUp(
q.scale(UIntToInt(values[k])), kFixedPointAttributeShift); q.scale(UIntToInt(values[k])), kFixedPointAttributeShift);
const int64_t recon = predictedColor[k] + residual; const int64_t recon = predictedColor[k] + residual + residual0;
color[k] = uint8_t(PCCClip(recon, int64_t(0), clipMax)); color[k] = uint8_t(PCCClip(recon, int64_t(0), clipMax));
if (!k && aps.inter_component_prediction_enabled_flag)
residual0 = residual;
} }
} }
} }
......
...@@ -699,6 +699,7 @@ AttributeEncoder::encodeColorsPred( ...@@ -699,6 +699,7 @@ AttributeEncoder::encodeColorsPred(
predictor.predictColor(pointCloud, indexesLOD); predictor.predictColor(pointCloud, indexesLOD);
Vec3<uint8_t> reconstructedColor; Vec3<uint8_t> reconstructedColor;
int64_t residual0 = 0;
for (int k = 0; k < 3; ++k) { for (int k = 0; k < 3; ++k) {
const auto& q = quant[std::min(k, 1)]; const auto& q = quant[std::min(k, 1)];
int64_t residual = color[k] - predictedColor[k]; int64_t residual = color[k] - predictedColor[k];
...@@ -707,6 +708,16 @@ AttributeEncoder::encodeColorsPred( ...@@ -707,6 +708,16 @@ AttributeEncoder::encodeColorsPred(
int64_t residualR = int64_t residualR =
divExp2RoundHalfUp(q.scale(residualQ), kFixedPointAttributeShift); divExp2RoundHalfUp(q.scale(residualQ), kFixedPointAttributeShift);
if (aps.inter_component_prediction_enabled_flag && k > 0) {
residual = residualR - residual0;
residualQ = q.quantize(residual << kFixedPointAttributeShift);
residualR = residual0
+ divExp2RoundHalfUp(q.scale(residualQ), kFixedPointAttributeShift);
}
if (k == 0)
residual0 = residualR;
values[k] = uint32_t(IntToUInt(long(residualQ))); values[k] = uint32_t(IntToUInt(long(residualQ)));
int64_t recon = predictedColor[k] + residualR; int64_t recon = predictedColor[k] + residualR;
......
...@@ -584,6 +584,11 @@ ParseParameters(int argc, char* argv[], Parameters& params) ...@@ -584,6 +584,11 @@ ParseParameters(int argc, char* argv[], Parameters& params)
params_attr.aps.intra_lod_prediction_enabled_flag, false, params_attr.aps.intra_lod_prediction_enabled_flag, false,
"Permits referring to points in same LoD") "Permits referring to points in same LoD")
("interComponentPredictionEnabled",
params_attr.aps.inter_component_prediction_enabled_flag, false,
"Use primary attribute component to predict values of subsequent "
"components")
("aps_scalable_enable_flag", ("aps_scalable_enable_flag",
params_attr.aps.scalable_lifting_enabled_flag, false, params_attr.aps.scalable_lifting_enabled_flag, false,
"Enable scalable attritube coding") "Enable scalable attritube coding")
......
...@@ -281,6 +281,7 @@ struct AttributeParameterSet { ...@@ -281,6 +281,7 @@ struct AttributeParameterSet {
int search_range; int search_range;
Vec3<double> lod_neigh_bias; Vec3<double> lod_neigh_bias;
bool intra_lod_prediction_enabled_flag; bool intra_lod_prediction_enabled_flag;
bool inter_component_prediction_enabled_flag;
// NB: derived from num_detail_levels_minus1 // NB: derived from num_detail_levels_minus1
int num_detail_levels; int num_detail_levels;
......
...@@ -299,6 +299,7 @@ write(const AttributeParameterSet& aps) ...@@ -299,6 +299,7 @@ write(const AttributeParameterSet& aps)
if (aps.attr_encoding == AttributeEncoding::kPredictingTransform) { if (aps.attr_encoding == AttributeEncoding::kPredictingTransform) {
bs.writeUe(aps.adaptive_prediction_threshold); bs.writeUe(aps.adaptive_prediction_threshold);
bs.write(aps.intra_lod_prediction_enabled_flag); bs.write(aps.intra_lod_prediction_enabled_flag);
bs.write(aps.inter_component_prediction_enabled_flag);
bs.writeUe(aps.max_num_direct_predictors); bs.writeUe(aps.max_num_direct_predictors);
} }
...@@ -359,6 +360,7 @@ parseAps(const PayloadBuffer& buf) ...@@ -359,6 +360,7 @@ parseAps(const PayloadBuffer& buf)
if (aps.attr_encoding == AttributeEncoding::kPredictingTransform) { if (aps.attr_encoding == AttributeEncoding::kPredictingTransform) {
bs.readUe(&aps.adaptive_prediction_threshold); bs.readUe(&aps.adaptive_prediction_threshold);
bs.read(&aps.intra_lod_prediction_enabled_flag); bs.read(&aps.intra_lod_prediction_enabled_flag);
bs.read(&aps.inter_component_prediction_enabled_flag);
bs.readUe(&aps.max_num_direct_predictors); bs.readUe(&aps.max_num_direct_predictors);
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment