summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
authorJerome Jiang <jianj@google.com>2021-09-28 16:59:21 -0700
committerJerome Jiang <jianj@google.com>2022-01-27 13:12:29 -0800
commit8a0af65f34bdf43fc63b4ce4ac9393aceab0abbf (patch)
tree979b3be617ece8ed83081b4fd86f1ac86836ca26 /vp9
parentc56ab7d0c6f3fb215d571db3dacc0cc908c1b53c (diff)
downloadlibvpx-8a0af65f34bdf43fc63b4ce4ac9393aceab0abbf.tar
libvpx-8a0af65f34bdf43fc63b4ce4ac9393aceab0abbf.tar.gz
libvpx-8a0af65f34bdf43fc63b4ce4ac9393aceab0abbf.tar.bz2
libvpx-8a0af65f34bdf43fc63b4ce4ac9393aceab0abbf.zip
Use background segmentation mask with ROI
RTC sample encoder vpx_temporal_svc_encoder can take mask files as input when ROI_MAP is set to 1. Uses ROI and segmentation of vp9 to skip background encoding when source_sad is low and the correspond block in previous frame is also skipped. Change-Id: I8590e6f9a88cecfa1d7f375d4cc480f0f2af87b6
Diffstat (limited to 'vp9')
-rw-r--r--vp9/common/vp9_seg_common.h5
-rw-r--r--vp9/encoder/vp9_aq_cyclicrefresh.c4
-rw-r--r--vp9/encoder/vp9_encodeframe.c42
-rw-r--r--vp9/encoder/vp9_encoder.c19
4 files changed, 55 insertions, 15 deletions
diff --git a/vp9/common/vp9_seg_common.h b/vp9/common/vp9_seg_common.h
index b63e4f499..5e71c2fca 100644
--- a/vp9/common/vp9_seg_common.h
+++ b/vp9/common/vp9_seg_common.h
@@ -25,6 +25,11 @@ extern "C" {
#define PREDICTION_PROBS 3
+// Segment ID used to skip background encoding
+#define BACKGROUND_SEG_SKIP_ID 3
+// Number of frames that don't skip after a key frame
+#define FRAMES_NO_SKIPPING_AFTER_KEY 20
+
// Segment level features.
typedef enum {
SEG_LVL_ALT_Q = 0, // Use alternate Quantizer ....
diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.c b/vp9/encoder/vp9_aq_cyclicrefresh.c
index f06fe4726..e336179e9 100644
--- a/vp9/encoder/vp9_aq_cyclicrefresh.c
+++ b/vp9/encoder/vp9_aq_cyclicrefresh.c
@@ -497,7 +497,9 @@ void vp9_cyclic_refresh_update_parameters(VP9_COMP *const cpi) {
rc->avg_frame_low_motion < thresh_low_motion &&
rc->frames_since_key > 40) ||
(!cpi->use_svc && rc->avg_frame_qindex[INTER_FRAME] > qp_max_thresh &&
- rc->frames_since_key > 20)) {
+ rc->frames_since_key > 20) ||
+ (cpi->roi.enabled && cpi->roi.skip[BACKGROUND_SEG_SKIP_ID] &&
+ rc->frames_since_key > FRAMES_NO_SKIPPING_AFTER_KEY)) {
cr->apply_cyclic_refresh = 0;
return;
}
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 131c4887f..fc4089865 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -5513,16 +5513,6 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, ThreadData *td,
x->arf_frame_usage = 0;
x->lastgolden_frame_usage = 0;
- if (seg->enabled) {
- const uint8_t *const map =
- seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
- int segment_id = get_segment_id(cm, map, BLOCK_64X64, mi_row, mi_col);
- seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
- if (seg_skip) {
- partition_search_type = FIXED_PARTITION;
- }
- }
-
if (cpi->compute_source_sad_onepass && cpi->sf.use_source_sad) {
int shift = cpi->Source->y_stride * (mi_row << 3) + (mi_col << 3);
int sb_offset2 = ((cm->mi_cols + 7) >> 3) * (mi_row >> 3) + (mi_col >> 3);
@@ -5534,6 +5524,38 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, ThreadData *td,
partition_search_type = REFERENCE_PARTITION;
}
+ if (seg->enabled) {
+ const uint8_t *const map =
+ seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
+ int segment_id = get_segment_id(cm, map, BLOCK_64X64, mi_row, mi_col);
+ seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
+
+ if (cpi->roi.enabled && cpi->roi.skip[BACKGROUND_SEG_SKIP_ID] &&
+ cpi->rc.frames_since_key > FRAMES_NO_SKIPPING_AFTER_KEY &&
+ x->content_state_sb > kLowSadLowSumdiff) {
+ // For ROI with skip, force segment = 0 (no skip) over whole
+ // superblock to avoid artifacts if temporal change in source_sad is
+ // not 0.
+ int xi, yi;
+ const int bw = num_8x8_blocks_wide_lookup[BLOCK_64X64];
+ const int bh = num_8x8_blocks_high_lookup[BLOCK_64X64];
+ const int xmis = VPXMIN(cm->mi_cols - mi_col, bw);
+ const int ymis = VPXMIN(cm->mi_rows - mi_row, bh);
+ const int block_index = mi_row * cm->mi_cols + mi_col;
+ set_mode_info_offsets(cm, x, xd, mi_row, mi_col);
+ for (yi = 0; yi < ymis; yi++)
+ for (xi = 0; xi < xmis; xi++) {
+ int map_offset = block_index + yi * cm->mi_cols + xi;
+ cpi->segmentation_map[map_offset] = 0;
+ }
+ set_segment_index(cpi, x, mi_row, mi_col, BLOCK_64X64, 0);
+ seg_skip = 0;
+ }
+ if (seg_skip) {
+ partition_search_type = FIXED_PARTITION;
+ }
+ }
+
// Set the partition type of the 64X64 block
switch (partition_search_type) {
case VAR_BASED_PARTITION:
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 7e80835f6..ac0efced7 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -618,7 +618,7 @@ static void apply_roi_map(VP9_COMP *cpi) {
}
if (skip[i] != 0) {
vp9_enable_segfeature(seg, i, SEG_LVL_SKIP);
- vp9_set_segdata(seg, i, SEG_LVL_SKIP, skip[i]);
+ vp9_set_segdata(seg, i, SEG_LVL_SKIP, 0);
}
if (ref_frame[i] >= 0) {
int valid_ref = 1;
@@ -4137,11 +4137,22 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
vp9_alt_ref_aq_setup_map(cpi->alt_ref_aq, cpi);
} else {
#endif
- if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
+ // If ROI is enabled and skip feature is used for segmentation, apply cyclic
+ // refresh but not apply ROI for skip for the first 20 frames (defined by
+ // FRAMES_NO_SKIPPING_AFTER_KEY) after key frame to improve quality.
+ if (cpi->roi.enabled && !frame_is_intra_only(cm)) {
+ if (cpi->roi.skip[BACKGROUND_SEG_SKIP_ID]) {
+ if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
+ vp9_cyclic_refresh_setup(cpi);
+ if (cpi->rc.frames_since_key > FRAMES_NO_SKIPPING_AFTER_KEY)
+ apply_roi_map(cpi);
+ } else {
+ apply_roi_map(cpi);
+ }
+ } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
vp9_cyclic_refresh_setup(cpi);
- } else if (cpi->roi.enabled && !frame_is_intra_only(cm)) {
- apply_roi_map(cpi);
}
+
#if !CONFIG_REALTIME_ONLY
}
#endif