Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Guillaume Martres
aom-rav1e
Commits
7cbeb910
Commit
7cbeb910
authored
Mar 27, 2014
by
Marco Paniconi
Committed by
Gerrit Code Review
Mar 27, 2014
Browse files
Merge "aq_mode=3: Set target seg_map in sb-block order."
parents
2b06bf20
fc0b3318
Changes
1
Hide whitespace changes
Inline
Side-by-side
vp9/encoder/vp9_aq_cyclicrefresh.c
View file @
7cbeb910
...
...
@@ -20,17 +20,18 @@
#include
"vp9/encoder/vp9_segmentation.h"
struct
CYCLIC_REFRESH
{
// Target percentage of blocks per frame that are cyclicly refreshed.
int
max_mbs_perframe
;
// Percentage of super-blocks per frame that are targeted as candidates
// for cyclic refresh.
int
max_sbs_perframe
;
// Maximum q-delta as percentage of base q.
int
max_qdelta_perc
;
// Block size below which we don't apply cyclic refresh.
BLOCK_SIZE
min_block_size
;
//
Macro
block starting index
(unit of 8x8)
for cycling through the frame.
int
m
b_index
;
//
Super
block starting index for cycling through the frame.
int
s
b_index
;
// Controls how long a block will need to wait to be refreshed again.
int
time_for_refresh
;
// Actual number of blocks that were applied delta-q (segment 1).
// Actual number of
(8x8)
blocks that were applied delta-q (segment 1).
int
num_seg_blocks
;
// Actual encoding bits for segment 1.
int
actual_seg_bits
;
...
...
@@ -77,7 +78,13 @@ static int apply_cyclic_refresh_bitrate(const VP9_COMMON *cm,
const
int
number_blocks
=
cm
->
mi_rows
*
cm
->
mi_cols
;
// The condition below corresponds to turning off at target bitrates:
// ~24kbps for CIF, 72kbps for VGA (at 30fps).
return
rc
->
av_per_frame_bandwidth
>=
factor
*
number_blocks
;
// Also turn off at very small frame sizes, to avoid too large fraction of
// superblocks to be refreshed per frame. Threshold below is less than QCIF.
if
(
rc
->
av_per_frame_bandwidth
<
factor
*
number_blocks
||
number_blocks
/
64
<
5
)
return
0
;
else
return
1
;
}
// Check if this coding block, of size bsize, should be considered for refresh
...
...
@@ -184,19 +191,18 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) {
vpx_memset
(
seg_map
,
0
,
cm
->
mi_rows
*
cm
->
mi_cols
);
vp9_disable_segmentation
(
&
cm
->
seg
);
if
(
cm
->
frame_type
==
KEY_FRAME
)
cr
->
m
b_index
=
0
;
cr
->
s
b_index
=
0
;
return
;
}
else
{
const
int
mbs_in_frame
=
cm
->
mi_rows
*
cm
->
mi_cols
;
int
qindex_delta
=
0
;
int
i
,
x
,
y
,
block_count
;
int
mi
_row
,
mi
_col
,
qindex2
;
int
i
,
block_count
,
bl_index
,
sb_rows
,
sb_cols
,
sbs_in_frame
;
int
x
mi
s
,
y
mi
s
,
x
,
y
,
qindex2
;
// Rate target ratio to set q delta.
const
float
rate_ratio_qdelta
=
2
.
0
;
vp9_clear_system_state
();
// Some of these parameters may be set via codec-control function later.
cr
->
max_
m
bs_perframe
=
10
;
cr
->
max_
s
bs_perframe
=
10
;
cr
->
max_qdelta_perc
=
50
;
cr
->
min_block_size
=
BLOCK_16X16
;
cr
->
time_for_refresh
=
1
;
...
...
@@ -248,52 +254,62 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) {
cr
->
rdmult
=
vp9_compute_rd_mult
(
cpi
,
qindex2
);
vp9_set_segdata
(
seg
,
1
,
SEG_LVL_ALT_Q
,
qindex_delta
);
// Number of target macroblocks to get the q delta (segment 1).
block_count
=
cr
->
max_mbs_perframe
*
mbs_in_frame
/
100
;
// Set the segmentation map: cycle through the macroblocks, starting at
sb_cols
=
(
cm
->
mi_cols
+
MI_BLOCK_SIZE
-
1
)
/
MI_BLOCK_SIZE
;
sb_rows
=
(
cm
->
mi_rows
+
MI_BLOCK_SIZE
-
1
)
/
MI_BLOCK_SIZE
;
sbs_in_frame
=
sb_cols
*
sb_rows
;
// Number of target superblocks to get the q delta (segment 1).
block_count
=
cr
->
max_sbs_perframe
*
sbs_in_frame
/
100
;
// Set the segmentation map: cycle through the superblocks, starting at
// cr->mb_index, and stopping when either block_count blocks have been found
// to be refreshed, or we have passed through whole frame.
// Note the setting of seg_map below is done in two steps (one over 8x8)
// and then another over SB, in order to keep the value constant over SB.
// TODO(marpan): Do this in one pass in SB order.
assert
(
cr
->
mb_index
<
mbs_in_frame
);
i
=
cr
->
mb_index
;
assert
(
cr
->
sb_index
<
sbs_in_frame
);
i
=
cr
->
sb_index
;
do
{
// If the macroblock is as a candidate for clean up then mark it
// for possible boost/refresh (segment 1). The segment id may get reset to
// 0 later if the macroblock gets coded anything other than ZEROMV.
if
(
cr
->
map
[
i
]
==
0
)
{
seg_map
[
i
]
=
1
;
block_count
--
;
}
else
if
(
cr
->
map
[
i
]
<
0
)
{
cr
->
map
[
i
]
++
;
}
i
++
;
if
(
i
==
mbs_in_frame
)
{
i
=
0
;
int
sum_map
=
0
;
// Get the mi_row/mi_col corresponding to superblock index i.
int
sb_row_index
=
(
i
/
sb_cols
);
int
sb_col_index
=
i
-
sb_row_index
*
sb_cols
;
int
mi_row
=
sb_row_index
*
MI_BLOCK_SIZE
;
int
mi_col
=
sb_col_index
*
MI_BLOCK_SIZE
;
assert
(
mi_row
>=
0
&&
mi_row
<
cm
->
mi_rows
);
assert
(
mi_col
>=
0
&&
mi_col
<
cm
->
mi_cols
);
bl_index
=
mi_row
*
cm
->
mi_cols
+
mi_col
;
// Loop through all 8x8 blocks in superblock and update map.
xmis
=
MIN
(
cm
->
mi_cols
-
mi_col
,
num_8x8_blocks_wide_lookup
[
BLOCK_64X64
]);
ymis
=
MIN
(
cm
->
mi_rows
-
mi_row
,
num_8x8_blocks_high_lookup
[
BLOCK_64X64
]);
for
(
y
=
0
;
y
<
ymis
;
y
++
)
{
for
(
x
=
0
;
x
<
xmis
;
x
++
)
{
const
int
bl_index2
=
bl_index
+
y
*
cm
->
mi_cols
+
x
;
// If the block is as a candidate for clean up then mark it
// for possible boost/refresh (segment 1). The segment id may get
// reset to 0 later if block gets coded anything other than ZEROMV.
if
(
cr
->
map
[
bl_index2
]
==
0
)
{
seg_map
[
bl_index2
]
=
1
;
sum_map
++
;
}
else
if
(
cr
->
map
[
bl_index2
]
<
0
)
{
cr
->
map
[
bl_index2
]
++
;
}
}
}
}
while
(
block_count
&&
i
!=
cr
->
mb_index
);
cr
->
mb_index
=
i
;
// Enforce constant segment map over superblock.
for
(
mi_row
=
0
;
mi_row
<
cm
->
mi_rows
;
mi_row
+=
MI_BLOCK_SIZE
)
for
(
mi_col
=
0
;
mi_col
<
cm
->
mi_cols
;
mi_col
+=
MI_BLOCK_SIZE
)
{
const
int
bl_index
=
mi_row
*
cm
->
mi_cols
+
mi_col
;
const
int
xmis
=
MIN
(
cm
->
mi_cols
-
mi_col
,
num_8x8_blocks_wide_lookup
[
BLOCK_64X64
]);
const
int
ymis
=
MIN
(
cm
->
mi_rows
-
mi_row
,
num_8x8_blocks_high_lookup
[
BLOCK_64X64
]);
int
sum_map
=
0
;
// Enforce constant segment over superblock.
// If segment is partial over superblock, reset to either all 1 or 0.
if
(
sum_map
>
0
&&
sum_map
<
xmis
*
ymis
)
{
const
int
new_value
=
(
sum_map
>=
xmis
*
ymis
/
2
);
for
(
y
=
0
;
y
<
ymis
;
y
++
)
for
(
x
=
0
;
x
<
xmis
;
x
++
)
sum_map
+=
seg_map
[
bl_index
+
y
*
cm
->
mi_cols
+
x
];
// If segment is partial over superblock, reset.
if
(
sum_map
>
0
&&
sum_map
<
xmis
*
ymis
)
{
const
int
new_value
=
(
sum_map
>=
xmis
*
ymis
/
2
);
for
(
y
=
0
;
y
<
ymis
;
y
++
)
for
(
x
=
0
;
x
<
xmis
;
x
++
)
seg_map
[
bl_index
+
y
*
cm
->
mi_cols
+
x
]
=
new_value
;
}
seg_map
[
bl_index
+
y
*
cm
->
mi_cols
+
x
]
=
new_value
;
}
i
++
;
if
(
i
==
sbs_in_frame
)
{
i
=
0
;
}
if
(
sum_map
>=
xmis
*
ymis
/
2
)
block_count
--
;
}
while
(
block_count
&&
i
!=
cr
->
sb_index
);
cr
->
sb_index
=
i
;
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment