Commit cc990c49 authored by David Flynn's avatar David Flynn
Browse files

attr/m47399: slice level signalling of QP deltas

This commit permits signalling a per-slice delta QP for luma and
chroma attribute components.  The delta is relative to the base
value derived from the APS.

NB: while syntax support and derivation processes are provided,
this commit does not contain any method to control the delta
QP value at the encoder.
parent aba3e735
......@@ -275,3 +275,6 @@ Attribute's luma quantization parameter.
### `--qpChromaOffset=INT-VALUE`
Attribute's chroma quantization quantization parameter relative to luma.
Only applies when `attribute=colour`.
### `--aps_slice_qp_deltas_present_flag=0|1`
Enables signalling of per-slice QP values.
......@@ -152,7 +152,7 @@ AttributeDecoder::decode(
{
int abhSize;
AttributeBrickHeader abh = parseAbh(attr_aps, payload, &abhSize);
Quantizers qstep = deriveQuantSteps(attr_aps);
Quantizers qstep = deriveQuantSteps(attr_aps, abh);
PCCResidualsDecoder decoder;
decoder.start(payload.data() + abhSize, payload.size() - abhSize);
......
......@@ -297,7 +297,7 @@ AttributeEncoder::encode(
PCCPointSet3& pointCloud,
PayloadBuffer* payload)
{
Quantizers qstep = deriveQuantSteps(attr_aps);
Quantizers qstep = deriveQuantSteps(attr_aps, abh);
PCCResidualsEncoder encoder;
encoder.start(int(pointCloud.getPointCount()));
......
......@@ -451,6 +451,10 @@ ParseParameters(int argc, char* argv[], Parameters& params)
("qpChromaOffset",
params_attr.aps.aps_chroma_qp_offset, 0,
"Attribute's chroma quantisation parameter offset (relative to luma)")
("aps_slice_qp_deltas_present_flag",
params_attr.aps.aps_slice_qp_deltas_present_flag, false,
"Enable signalling of per-slice QP values")
;
/* clang-format on */
......
......@@ -298,6 +298,8 @@ PCCTMC3Encoder3::compressPartition(
abh.attr_attr_parameter_set_id = attr_aps.aps_attr_parameter_set_id;
abh.attr_sps_attr_idx = attrIdx;
abh.attr_geom_slice_id = _sliceId;
abh.attr_qp_delta_luma = 0;
abh.attr_qp_delta_chroma = 0;
write(attr_aps, abh, &payload);
AttributeEncoder attrEncoder;
......
......@@ -245,6 +245,7 @@ struct AttributeParameterSet {
// NB: these parameters are shared by all transform implementations
int init_qp;
int aps_chroma_qp_offset;
bool aps_slice_qp_deltas_present_flag;
//--- raht parameters
int raht_depth;
......@@ -257,6 +258,8 @@ struct AttributeBrickHeader {
int attr_sps_attr_idx;
int attr_attr_parameter_set_id;
int attr_geom_slice_id;
int attr_qp_delta_luma;
int attr_qp_delta_chroma;
};
//============================================================================
......
......@@ -254,6 +254,7 @@ write(const AttributeParameterSet& aps)
bs.writeUe(aps.init_qp);
// todo(?): raht chroma qp support?
bs.writeSe(aps.aps_chroma_qp_offset);
bs.write(aps.aps_slice_qp_deltas_present_flag);
bool isLifting = aps.attr_encoding == AttributeEncoding::kLiftingTransform
|| aps.attr_encoding == AttributeEncoding::kPredictingTransform;
......@@ -302,6 +303,7 @@ parseAps(const PayloadBuffer& buf)
bs.readUe(&aps.init_qp);
// todo(?): raht chroma qp support?
bs.readSe(&aps.aps_chroma_qp_offset);
bs.read(&aps.aps_slice_qp_deltas_present_flag);
bool isLifting = aps.attr_encoding == AttributeEncoding::kLiftingTransform
|| aps.attr_encoding == AttributeEncoding::kPredictingTransform;
......@@ -421,6 +423,11 @@ write(
bs.writeUe(abh.attr_sps_attr_idx);
bs.writeUe(abh.attr_geom_slice_id);
if (aps.aps_slice_qp_deltas_present_flag) {
bs.writeSe(abh.attr_qp_delta_luma);
bs.writeSe(abh.attr_qp_delta_chroma);
}
bs.byteAlign();
}
......@@ -457,6 +464,11 @@ parseAbh(
bs.readUe(&abh.attr_sps_attr_idx);
bs.readUe(&abh.attr_geom_slice_id);
if (aps.aps_slice_qp_deltas_present_flag) {
bs.readSe(&abh.attr_qp_delta_luma);
bs.readSe(&abh.attr_qp_delta_chroma);
}
bs.byteAlign();
if (bytesRead)
......
......@@ -43,11 +43,17 @@ namespace pcc {
//============================================================================
Quantizers
deriveQuantSteps(const AttributeParameterSet& attr_aps)
deriveQuantSteps(
const AttributeParameterSet& attr_aps, const AttributeBrickHeader& abh)
{
int sliceQpLuma = attr_aps.init_qp;
int sliceQpChroma = attr_aps.init_qp + attr_aps.aps_chroma_qp_offset;
if (attr_aps.aps_slice_qp_deltas_present_flag) {
sliceQpLuma += abh.attr_qp_delta_luma;
sliceQpChroma += abh.attr_qp_delta_chroma;
}
int qpShiftLuma = sliceQpLuma / 6;
int qpShiftChroma = sliceQpChroma / 6;
......
......@@ -50,7 +50,8 @@ typedef std::array<int, 2> Quantizers;
//============================================================================
// Derive quantisation step sizes for each component given attribute
Quantizers deriveQuantSteps(const AttributeParameterSet& attr_aps);
Quantizers deriveQuantSteps(
const AttributeParameterSet& attr_aps, const AttributeBrickHeader& abh);
//============================================================================
......
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