Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
external
libvpx
Commits
79590f18
Commit
79590f18
authored
Apr 30, 2013
by
Dmitry Kovalev
Committed by
Gerrit Code Review
Apr 30, 2013
Browse files
Merge "Cleaning up encoder segmentation code." into experimental
parents
d3764f7f
ee97da2c
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
120 additions
and
139 deletions
+120
-139
vp9/common/vp9_blockd.h
vp9/common/vp9_blockd.h
+1
-1
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_bitstream.c
+79
-84
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_encodeframe.c
+5
-7
vp9/encoder/vp9_mbgraph.c
vp9/encoder/vp9_mbgraph.c
+2
-2
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_onyx_if.c
+17
-19
vp9/encoder/vp9_rdopt.c
vp9/encoder/vp9_rdopt.c
+3
-4
vp9/encoder/vp9_segmentation.c
vp9/encoder/vp9_segmentation.c
+13
-22
No files found.
vp9/common/vp9_blockd.h
View file @
79590f18
...
...
@@ -376,7 +376,7 @@ typedef struct macroblockd {
PARTITION_CONTEXT
*
above_seg_context
;
PARTITION_CONTEXT
*
left_seg_context
;
/* 0
indicates segmentation at MB level is not enabled. Otherwise the individual bits indicate which features are active.
*/
/* 0
(disable) 1 (enable) segmentation
*/
unsigned
char
segmentation_enabled
;
/* 0 (do not update) 1 (update) the macroblock segmentation map. */
...
...
vp9/encoder/vp9_bitstream.c
View file @
79590f18
...
...
@@ -1767,16 +1767,91 @@ static void segment_reference_frames(VP9_COMP *cpi) {
}
}
void
vp9_pack_bitstream
(
VP9_COMP
*
cpi
,
unsigned
char
*
dest
,
unsigned
long
*
size
)
{
static
void
encode_segmentation
(
VP9_COMP
*
cpi
,
vp9_writer
*
w
)
{
int
i
,
j
;
VP9_COMMON
*
const
pc
=
&
cpi
->
common
;
MACROBLOCKD
*
const
xd
=
&
cpi
->
mb
.
e_mbd
;
vp9_write_bit
(
w
,
xd
->
segmentation_enabled
);
if
(
!
xd
->
segmentation_enabled
)
return
;
// Segmentation map
vp9_write_bit
(
w
,
xd
->
update_mb_segmentation_map
);
#if CONFIG_IMPLICIT_SEGMENTATION
vp9_write_bit
(
w
,
xd
->
allow_implicit_segment_update
);
#endif
if
(
xd
->
update_mb_segmentation_map
)
{
// Select the coding strategy (temporal or spatial)
vp9_choose_segmap_coding_method
(
cpi
);
// Write out probabilities used to decode unpredicted macro-block segments
for
(
i
=
0
;
i
<
MB_SEG_TREE_PROBS
;
i
++
)
{
const
int
prob
=
xd
->
mb_segment_tree_probs
[
i
];
if
(
prob
!=
MAX_PROB
)
{
vp9_write_bit
(
w
,
1
);
vp9_write_prob
(
w
,
prob
);
}
else
{
vp9_write_bit
(
w
,
0
);
}
}
// Write out the chosen coding method.
vp9_write_bit
(
w
,
pc
->
temporal_update
);
if
(
pc
->
temporal_update
)
{
for
(
i
=
0
;
i
<
PREDICTION_PROBS
;
i
++
)
{
const
int
prob
=
pc
->
segment_pred_probs
[
i
];
if
(
prob
!=
MAX_PROB
)
{
vp9_write_bit
(
w
,
1
);
vp9_write_prob
(
w
,
prob
);
}
else
{
vp9_write_bit
(
w
,
0
);
}
}
}
}
// Segmentation data
vp9_write_bit
(
w
,
xd
->
update_mb_segmentation_data
);
// segment_reference_frames(cpi);
if
(
xd
->
update_mb_segmentation_data
)
{
vp9_write_bit
(
w
,
xd
->
mb_segment_abs_delta
);
for
(
i
=
0
;
i
<
MAX_MB_SEGMENTS
;
i
++
)
{
for
(
j
=
0
;
j
<
SEG_LVL_MAX
;
j
++
)
{
const
int
data
=
vp9_get_segdata
(
xd
,
i
,
j
);
const
int
data_max
=
vp9_seg_feature_data_max
(
j
);
if
(
vp9_segfeature_active
(
xd
,
i
,
j
))
{
vp9_write_bit
(
w
,
1
);
if
(
vp9_is_segfeature_signed
(
j
))
{
if
(
data
<
0
)
{
vp9_encode_unsigned_max
(
w
,
-
data
,
data_max
);
vp9_write_bit
(
w
,
1
);
}
else
{
vp9_encode_unsigned_max
(
w
,
data
,
data_max
);
vp9_write_bit
(
w
,
0
);
}
}
else
{
vp9_encode_unsigned_max
(
w
,
data
,
data_max
);
}
}
else
{
vp9_write_bit
(
w
,
0
);
}
}
}
}
}
void
vp9_pack_bitstream
(
VP9_COMP
*
cpi
,
uint8_t
*
dest
,
unsigned
long
*
size
)
{
int
i
;
VP9_HEADER
oh
;
VP9_COMMON
*
const
pc
=
&
cpi
->
common
;
vp9_writer
header_bc
,
residual_bc
;
MACROBLOCKD
*
const
xd
=
&
cpi
->
mb
.
e_mbd
;
int
extra_bytes_packed
=
0
;
u
nsigned
char
*
cx_data
=
dest
;
u
int8_t
*
cx_data
=
dest
;
oh
.
show_frame
=
(
int
)
pc
->
show_frame
;
oh
.
type
=
(
int
)
pc
->
frame_type
;
...
...
@@ -2008,87 +2083,7 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
active_section
=
7
;
#endif
// Signal whether or not Segmentation is enabled
vp9_write_bit
(
&
header_bc
,
(
xd
->
segmentation_enabled
)
?
1
:
0
);
// Indicate which features are enabled
if
(
xd
->
segmentation_enabled
)
{
// Indicate whether or not the segmentation map is being updated.
vp9_write_bit
(
&
header_bc
,
(
xd
->
update_mb_segmentation_map
)
?
1
:
0
);
#if CONFIG_IMPLICIT_SEGMENTATION
vp9_write_bit
(
&
header_bc
,
(
xd
->
allow_implicit_segment_update
)
?
1
:
0
);
#endif
// If it is, then indicate the method that will be used.
if
(
xd
->
update_mb_segmentation_map
)
{
// Select the coding strategy (temporal or spatial)
vp9_choose_segmap_coding_method
(
cpi
);
// Send the tree probabilities used to decode unpredicted
// macro-block segments
for
(
i
=
0
;
i
<
MB_SEG_TREE_PROBS
;
i
++
)
{
const
int
prob
=
xd
->
mb_segment_tree_probs
[
i
];
if
(
prob
!=
255
)
{
vp9_write_bit
(
&
header_bc
,
1
);
vp9_write_prob
(
&
header_bc
,
prob
);
}
else
{
vp9_write_bit
(
&
header_bc
,
0
);
}
}
// Write out the chosen coding method.
vp9_write_bit
(
&
header_bc
,
(
pc
->
temporal_update
)
?
1
:
0
);
if
(
pc
->
temporal_update
)
{
for
(
i
=
0
;
i
<
PREDICTION_PROBS
;
i
++
)
{
const
int
prob
=
pc
->
segment_pred_probs
[
i
];
if
(
prob
!=
255
)
{
vp9_write_bit
(
&
header_bc
,
1
);
vp9_write_prob
(
&
header_bc
,
prob
);
}
else
{
vp9_write_bit
(
&
header_bc
,
0
);
}
}
}
}
vp9_write_bit
(
&
header_bc
,
(
xd
->
update_mb_segmentation_data
)
?
1
:
0
);
// segment_reference_frames(cpi);
if
(
xd
->
update_mb_segmentation_data
)
{
vp9_write_bit
(
&
header_bc
,
(
xd
->
mb_segment_abs_delta
)
?
1
:
0
);
// For each segments id...
for
(
i
=
0
;
i
<
MAX_MB_SEGMENTS
;
i
++
)
{
// For each segmentation codable feature...
for
(
j
=
0
;
j
<
SEG_LVL_MAX
;
j
++
)
{
const
int8_t
data
=
vp9_get_segdata
(
xd
,
i
,
j
);
const
int
data_max
=
vp9_seg_feature_data_max
(
j
);
// If the feature is enabled...
if
(
vp9_segfeature_active
(
xd
,
i
,
j
))
{
vp9_write_bit
(
&
header_bc
,
1
);
// Is the segment data signed..
if
(
vp9_is_segfeature_signed
(
j
))
{
// Encode the relevant feature data
if
(
data
<
0
)
{
vp9_encode_unsigned_max
(
&
header_bc
,
-
data
,
data_max
);
vp9_write_bit
(
&
header_bc
,
1
);
}
else
{
vp9_encode_unsigned_max
(
&
header_bc
,
data
,
data_max
);
vp9_write_bit
(
&
header_bc
,
0
);
}
}
else
{
// Unsigned data element so no sign bit needed
vp9_encode_unsigned_max
(
&
header_bc
,
data
,
data_max
);
}
}
else
{
vp9_write_bit
(
&
header_bc
,
0
);
}
}
}
}
}
encode_segmentation
(
cpi
,
&
header_bc
);
// Encode the common prediction model status flag probability updates for
// the reference frame
...
...
vp9/encoder/vp9_encodeframe.c
View file @
79590f18
...
...
@@ -639,13 +639,11 @@ static void set_offsets(VP9_COMP *cpi,
/* segment ID */
if
(
xd
->
segmentation_enabled
)
{
if
(
xd
->
update_mb_segmentation_map
)
{
mbmi
->
segment_id
=
find_seg_id
(
cpi
->
segmentation_map
,
bsize
,
mi_row
,
cm
->
mi_rows
,
mi_col
,
cm
->
mi_cols
);
}
else
{
mbmi
->
segment_id
=
find_seg_id
(
cm
->
last_frame_seg_map
,
bsize
,
mi_row
,
cm
->
mi_rows
,
mi_col
,
cm
->
mi_cols
);
}
uint8_t
*
map
=
xd
->
update_mb_segmentation_map
?
cpi
->
segmentation_map
:
cm
->
last_frame_seg_map
;
mbmi
->
segment_id
=
find_seg_id
(
map
,
bsize
,
mi_row
,
cm
->
mi_rows
,
mi_col
,
cm
->
mi_cols
);
assert
(
mbmi
->
segment_id
<=
(
MAX_MB_SEGMENTS
-
1
));
vp9_mb_init_quantizer
(
cpi
,
x
);
...
...
vp9/encoder/vp9_mbgraph.c
View file @
79590f18
...
...
@@ -419,10 +419,10 @@ static void separate_arf_mbs(VP9_COMP *cpi) {
cpi
->
static_mb_pct
=
0
;
cpi
->
seg0_cnt
=
ncnt
[
0
];
vp9_enable_segmentation
((
VP9_PTR
)
cpi
);
vp9_enable_segmentation
((
VP9_PTR
)
cpi
);
}
else
{
cpi
->
static_mb_pct
=
0
;
vp9_disable_segmentation
((
VP9_PTR
)
cpi
);
vp9_disable_segmentation
((
VP9_PTR
)
cpi
);
}
// Free localy allocated storage
...
...
vp9/encoder/vp9_onyx_if.c
View file @
79590f18
...
...
@@ -280,8 +280,7 @@ static void setup_features(VP9_COMP *cpi) {
MACROBLOCKD
*
xd
=
&
cpi
->
mb
.
e_mbd
;
// Set up default state for MB feature flags
xd
->
segmentation_enabled
=
0
;
// Default segmentation disabled
xd
->
segmentation_enabled
=
0
;
xd
->
update_mb_segmentation_map
=
0
;
xd
->
update_mb_segmentation_data
=
0
;
...
...
@@ -383,7 +382,7 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
xd
->
update_mb_segmentation_map
=
0
;
xd
->
update_mb_segmentation_data
=
0
;
#if CONFIG_IMPLICIT_SEGMENTATION
xd
->
allow_implicit_segment_update
=
0
;
xd
->
allow_implicit_segment_update
=
0
;
#endif
cpi
->
static_mb_pct
=
0
;
...
...
@@ -399,7 +398,7 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
xd
->
update_mb_segmentation_map
=
0
;
xd
->
update_mb_segmentation_data
=
0
;
#if CONFIG_IMPLICIT_SEGMENTATION
xd
->
allow_implicit_segment_update
=
0
;
xd
->
allow_implicit_segment_update
=
0
;
#endif
cpi
->
static_mb_pct
=
0
;
...
...
@@ -428,9 +427,9 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
xd
->
mb_segment_abs_delta
=
SEGMENT_DELTADATA
;
}
}
// All other frames if segmentation has been enabled
else
if
(
xd
->
segmentation_enabled
)
{
}
else
if
(
xd
->
segmentation_enabled
)
{
// All other frames if segmentation has been enabled
// First normal frame in a valid gf or alt ref group
if
(
cpi
->
common
.
frames_since_golden
==
0
)
{
// Set up segment features for normal frames in an arf group
...
...
@@ -454,10 +453,10 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
vp9_enable_segfeature
(
xd
,
1
,
SEG_LVL_REF_FRAME
);
vp9_enable_segfeature
(
xd
,
1
,
SEG_LVL_SKIP
);
}
}
// Disable segmentation and clear down features if alt ref
// is not active for this group
else
{
}
else
{
// Disable segmentation and clear down features if alt ref
// is not active for this group
vp9_disable_segmentation
((
VP9_PTR
)
cpi
);
vpx_memset
(
cpi
->
segmentation_map
,
0
,
cm
->
mi_rows
*
cm
->
mi_cols
);
...
...
@@ -467,12 +466,11 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
vp9_clearall_segfeatures
(
xd
);
}
}
}
else
if
(
cpi
->
is_src_frame_alt_ref
)
{
// Special case where we are coding over the top of a previous
// alt ref frame.
// Segment coding disabled for compred testing
// Special case where we are coding over the top of a previous
// alt ref frame.
// Segment coding disabled for compred testing
else
if
(
cpi
->
is_src_frame_alt_ref
)
{
// Enable ref frame features for segment 0 as well
vp9_enable_segfeature
(
xd
,
0
,
SEG_LVL_REF_FRAME
);
vp9_enable_segfeature
(
xd
,
1
,
SEG_LVL_REF_FRAME
);
...
...
@@ -490,9 +488,9 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
}
// Enable data udpate
xd
->
update_mb_segmentation_data
=
1
;
}
// All other frames.
else
{
}
else
{
// All other frames.
// No updates.. leave things as they are.
xd
->
update_mb_segmentation_map
=
0
;
xd
->
update_mb_segmentation_data
=
0
;
...
...
vp9/encoder/vp9_rdopt.c
View file @
79590f18
...
...
@@ -5604,10 +5604,9 @@ void vp9_pick_mode_inter_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
int64_t
intra_error
=
0
;
unsigned
char
*
segment_id
=
&
mbmi
->
segment_id
;
if
(
xd
->
segmentation_enabled
)
x
->
encode_breakout
=
cpi
->
segment_encode_breakout
[
*
segment_id
];
else
x
->
encode_breakout
=
cpi
->
oxcf
.
encode_breakout
;
x
->
encode_breakout
=
xd
->
segmentation_enabled
?
cpi
->
segment_encode_breakout
[
*
segment_id
]
:
cpi
->
oxcf
.
encode_breakout
;
// if (cpi->sf.RD)
// For now this codebase is limited to a single rd encode path
...
...
vp9/encoder/vp9_segmentation.c
View file @
79590f18
...
...
@@ -16,18 +16,15 @@
#include "vp9/common/vp9_tile_common.h"
void
vp9_enable_segmentation
(
VP9_PTR
ptr
)
{
VP9_COMP
*
cpi
=
(
VP9_COMP
*
)
(
ptr
)
;
VP9_COMP
*
cpi
=
(
VP9_COMP
*
)
ptr
;
// Set the appropriate feature bit
cpi
->
mb
.
e_mbd
.
segmentation_enabled
=
1
;
cpi
->
mb
.
e_mbd
.
update_mb_segmentation_map
=
1
;
cpi
->
mb
.
e_mbd
.
update_mb_segmentation_data
=
1
;
}
void
vp9_disable_segmentation
(
VP9_PTR
ptr
)
{
VP9_COMP
*
cpi
=
(
VP9_COMP
*
)(
ptr
);
// Clear the appropriate feature bit
VP9_COMP
*
cpi
=
(
VP9_COMP
*
)
ptr
;
cpi
->
mb
.
e_mbd
.
segmentation_enabled
=
0
;
}
...
...
@@ -246,10 +243,8 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
// Set default state for the segment tree probabilities and the
// temporal coding probabilities
vpx_memset
(
xd
->
mb_segment_tree_probs
,
255
,
sizeof
(
xd
->
mb_segment_tree_probs
));
vpx_memset
(
cm
->
segment_pred_probs
,
255
,
sizeof
(
cm
->
segment_pred_probs
));
vpx_memset
(
xd
->
mb_segment_tree_probs
,
255
,
sizeof
(
xd
->
mb_segment_tree_probs
));
vpx_memset
(
cm
->
segment_pred_probs
,
255
,
sizeof
(
cm
->
segment_pred_probs
));
vpx_memset
(
no_pred_segcounts
,
0
,
sizeof
(
no_pred_segcounts
));
vpx_memset
(
t_unpred_seg_counts
,
0
,
sizeof
(
t_unpred_seg_counts
));
...
...
@@ -257,7 +252,6 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
// First of all generate stats regarding how well the last segment map
// predicts this one
for
(
tile_col
=
0
;
tile_col
<
cm
->
tile_columns
;
tile_col
++
)
{
vp9_get_tile_col_offsets
(
cm
,
tile_col
);
mi_ptr
=
cm
->
mi
+
cm
->
cur_tile_mi_col_start
;
...
...
@@ -287,27 +281,24 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
// Add in the cost of the signalling for each prediction context
for
(
i
=
0
;
i
<
PREDICTION_PROBS
;
i
++
)
{
t_nopred_prob
[
i
]
=
get_binary_prob
(
temporal_predictor_count
[
i
][
0
],
temporal_predictor_count
[
i
][
1
]);
const
int
count0
=
temporal_predictor_count
[
i
][
0
];
const
int
count1
=
temporal_predictor_count
[
i
][
1
];
t_nopred_prob
[
i
]
=
get_binary_prob
(
count0
,
count1
);
// Add in the predictor signaling cost
t_pred_cost
+=
(
temporal_predictor_count
[
i
][
0
]
*
vp9_cost_zero
(
t_nopred_prob
[
i
]))
+
(
temporal_predictor_count
[
i
][
1
]
*
vp9_cost_one
(
t_nopred_prob
[
i
]));
t_pred_cost
+=
count0
*
vp9_cost_zero
(
t_nopred_prob
[
i
])
+
count1
*
vp9_cost_one
(
t_nopred_prob
[
i
]);
}
}
// Now choose which coding method to use.
if
(
t_pred_cost
<
no_pred_cost
)
{
cm
->
temporal_update
=
1
;
vpx_memcpy
(
xd
->
mb_segment_tree_probs
,
t_pred_tree
,
sizeof
(
t_pred_tree
));
vpx_memcpy
(
&
cm
->
segment_pred_probs
,
t_nopred_prob
,
sizeof
(
t_nopred_prob
));
vpx_memcpy
(
xd
->
mb_segment_tree_probs
,
t_pred_tree
,
sizeof
(
t_pred_tree
));
vpx_memcpy
(
cm
->
segment_pred_probs
,
t_nopred_prob
,
sizeof
(
t_nopred_prob
));
}
else
{
cm
->
temporal_update
=
0
;
vpx_memcpy
(
xd
->
mb_segment_tree_probs
,
no_pred_tree
,
sizeof
(
no_pred_tree
));
vpx_memcpy
(
xd
->
mb_segment_tree_probs
,
no_pred_tree
,
sizeof
(
no_pred_tree
));
}
}
Write
Preview
Markdown
is supported
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