diff options
author | James Almer <jamrial@gmail.com> | 2020-10-20 18:20:24 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2020-10-28 11:26:25 -0300 |
commit | 5ed9f8c66c39af1d53e8b8339db81713d1585f4d (patch) | |
tree | 476638cb503595aec5dc7f7bf726655967733640 /libavcodec | |
parent | 5d1238f77fbd83e834b2f3066a60c29eb6f49ef8 (diff) | |
download | ffmpeg-5ed9f8c66c39af1d53e8b8339db81713d1585f4d.tar.gz |
avcodec/cbs_av1: infer segmentation parameters from reference frames
Partially implements setup_past_independence() and load_previous().
These ensures they are always set, even if the values were not coded
in the input bitstream and will not be coded in the output bitstream.
Reviewed-by: Mark Thompson <sw@jkqxz.net>
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/cbs_av1.h | 2 | ||||
-rw-r--r-- | libavcodec/cbs_av1_syntax_template.c | 29 |
2 files changed, 28 insertions, 3 deletions
diff --git a/libavcodec/cbs_av1.h b/libavcodec/cbs_av1.h index 97aeee9795..a2d78e736f 100644 --- a/libavcodec/cbs_av1.h +++ b/libavcodec/cbs_av1.h @@ -416,6 +416,8 @@ typedef struct AV1ReferenceFrameState { int8_t loop_filter_ref_deltas[AV1_TOTAL_REFS_PER_FRAME]; int8_t loop_filter_mode_deltas[2]; + uint8_t feature_enabled[AV1_MAX_SEGMENTS][AV1_SEG_LVL_MAX]; + int16_t feature_value[AV1_MAX_SEGMENTS][AV1_SEG_LVL_MAX]; } AV1ReferenceFrameState; typedef struct CodedBitstreamAV1Context { diff --git a/libavcodec/cbs_av1_syntax_template.c b/libavcodec/cbs_av1_syntax_template.c index 137da5a860..f351b1de24 100644 --- a/libavcodec/cbs_av1_syntax_template.c +++ b/libavcodec/cbs_av1_syntax_template.c @@ -743,8 +743,11 @@ static int FUNC(quantization_params)(CodedBitstreamContext *ctx, RWContext *rw, static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, AV1RawFrameHeader *current) { + CodedBitstreamAV1Context *priv = ctx->priv_data; static const uint8_t bits[AV1_SEG_LVL_MAX] = { 8, 6, 6, 6, 6, 3, 0, 0 }; static const uint8_t sign[AV1_SEG_LVL_MAX] = { 1, 1, 1, 1, 1, 0, 0, 0 }; + static const uint8_t default_feature_enabled[AV1_SEG_LVL_MAX] = { 0 }; + static const int16_t default_feature_value[AV1_SEG_LVL_MAX] = { 0 }; int i, j, err; flag(segmentation_enabled); @@ -763,9 +766,22 @@ static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, flag(segmentation_update_data); } - if (current->segmentation_update_data) { - for (i = 0; i < AV1_MAX_SEGMENTS; i++) { - for (j = 0; j < AV1_SEG_LVL_MAX; j++) { + for (i = 0; i < AV1_MAX_SEGMENTS; i++) { + const uint8_t *ref_feature_enabled; + const int16_t *ref_feature_value; + + if (current->primary_ref_frame == AV1_PRIMARY_REF_NONE) { + ref_feature_enabled = default_feature_enabled; + ref_feature_value = default_feature_value; + } else { + ref_feature_enabled = + priv->ref[current->ref_frame_idx[current->primary_ref_frame]].feature_enabled[i]; + ref_feature_value = + priv->ref[current->ref_frame_idx[current->primary_ref_frame]].feature_value[i]; + } + + for (j = 0; j < AV1_SEG_LVL_MAX; j++) { + if (current->segmentation_update_data) { flags(feature_enabled[i][j], 2, i, j); if (current->feature_enabled[i][j] && bits[j] > 0) { @@ -776,6 +792,9 @@ static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, } else { infer(feature_value[i][j], 0); } + } else { + infer(feature_enabled[i][j], ref_feature_enabled[j]); + infer(feature_value[i][j], ref_feature_value[j]); } } } @@ -1645,6 +1664,10 @@ update_refs: sizeof(current->loop_filter_ref_deltas)); memcpy(priv->ref[i].loop_filter_mode_deltas, current->loop_filter_mode_deltas, sizeof(current->loop_filter_mode_deltas)); + memcpy(priv->ref[i].feature_enabled, current->feature_enabled, + sizeof(current->feature_enabled)); + memcpy(priv->ref[i].feature_value, current->feature_value, + sizeof(current->feature_value)); } } |