Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
aom-rav1e
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Xiph.Org
aom-rav1e
Commits
43479c6c
Commit
43479c6c
authored
Nov 30, 2016
by
David Barker
Committed by
Debargha Mukherjee
Dec 01, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve ALL_ZERO flag handling with global motion
Change-Id: I9b2465807c2dd6e356807f3f3555394b382918ad
parent
691a6901
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
99 additions
and
42 deletions
+99
-42
av1/common/mvref_common.c
av1/common/mvref_common.c
+45
-19
av1/decoder/decodemv.c
av1/decoder/decodemv.c
+14
-2
av1/encoder/bitstream.c
av1/encoder/bitstream.c
+5
-0
av1/encoder/encoder.c
av1/encoder/encoder.c
+4
-0
av1/encoder/rdopt.c
av1/encoder/rdopt.c
+31
-21
No files found.
av1/common/mvref_common.c
View file @
43479c6c
...
...
@@ -499,7 +499,8 @@ static void find_mv_refs_idx(const AV1_COMMON *cm, const MACROBLOCKD *xd,
MODE_INFO
*
mi
,
MV_REFERENCE_FRAME
ref_frame
,
int_mv
*
mv_ref_list
,
int
block
,
int
mi_row
,
int
mi_col
,
find_mv_refs_sync
sync
,
void
*
const
data
,
int16_t
*
mode_context
)
{
void
*
const
data
,
int16_t
*
mode_context
,
int_mv
zeromv
)
{
const
int
*
ref_sign_bias
=
cm
->
ref_frame_sign_bias
;
int
i
,
refmv_count
=
0
;
#if !CONFIG_REF_MV
...
...
@@ -661,7 +662,7 @@ Done:
if
(
mode_context
)
mode_context
[
ref_frame
]
=
counter_to_context
[
context_counter
];
for
(
i
=
refmv_count
;
i
<
MAX_MV_REF_CANDIDATES
;
++
i
)
mv_ref_list
[
i
].
as_int
=
0
;
mv_ref_list
[
i
].
as_int
=
zeromv
.
as_int
;
}
#if CONFIG_EXT_INTER
...
...
@@ -745,11 +746,12 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
int_mv
*
mv_ref_list
,
int
mi_row
,
int
mi_col
,
find_mv_refs_sync
sync
,
void
*
const
data
,
int16_t
*
mode_context
)
{
int_mv
zeromv
[
2
];
#if CONFIG_REF_MV
#if !CONFIG_GLOBAL_MOTION
int
idx
;
int
idx
,
all_zero
=
1
;
#endif
int
all_zero
=
1
;
#if CONFIG_GLOBAL_MOTION
MV_REFERENCE_FRAME
rf
[
2
];
#endif
#if CONFIG_EXT_INTER
av1_update_mv_context
(
xd
,
mi
,
ref_frame
,
mv_ref_list
,
-
1
,
mi_row
,
mi_col
,
...
...
@@ -759,33 +761,51 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
mode_context
);
#endif // CONFIG_REF_MV
#endif // CONFIG_EXT_INTER
#if CONFIG_GLOBAL_MOTION
av1_set_ref_frame
(
rf
,
ref_frame
);
zeromv
[
0
].
as_int
=
gm_get_motion_vector
(
&
cm
->
global_motion
[
rf
[
0
]]).
as_int
;
zeromv
[
1
].
as_int
=
(
rf
[
1
]
!=
NONE
)
?
gm_get_motion_vector
(
&
cm
->
global_motion
[
rf
[
1
]]).
as_int
:
0
;
#else
zeromv
[
0
].
as_int
=
zeromv
[
1
].
as_int
=
0
;
#endif
#if CONFIG_REF_MV
if
(
ref_frame
<=
ALTREF_FRAME
)
find_mv_refs_idx
(
cm
,
xd
,
mi
,
ref_frame
,
mv_ref_list
,
-
1
,
mi_row
,
mi_col
,
sync
,
data
,
mode_context
);
#else
find_mv_refs_idx
(
cm
,
xd
,
mi
,
ref_frame
,
mv_ref_list
,
-
1
,
mi_row
,
mi_col
,
sync
,
data
,
mode_context
);
#endif // CONFIG_REF_MV
find_mv_refs_idx
(
cm
,
xd
,
mi
,
ref_frame
,
mv_ref_list
,
-
1
,
mi_row
,
mi_col
,
sync
,
data
,
mode_context
,
zeromv
[
0
]);
#if CONFIG_REF_MV
setup_ref_mv_list
(
cm
,
xd
,
ref_frame
,
ref_mv_count
,
ref_mv_stack
,
mv_ref_list
,
-
1
,
mi_row
,
mi_col
,
mode_context
);
#if CONFIG_GLOBAL_MOTION
if
((
*
ref_mv_count
>=
2
)
||
(
ref_frame
<=
ALTREF_FRAME
))
all_zero
=
0
;
#else
/* Note: If global motion is enabled, then we want to set the ALL_ZERO flag
iff all of the MVs we could generate with NEARMV/NEARESTMV are equivalent
to the global motion vector.
Note: For the following to work properly, the encoder can't throw away
any global motion models after calling this function, even if they are
unused. Instead we rely on the recode loop: If any non-IDENTITY model
is unused, the whole frame will be re-encoded without it.
The problem is that, otherwise, we can end up in the following situation:
* Encoder has a global motion model with nonzero translational part,
and all candidate MVs are zero. So the ALL_ZERO flag is unset.
* Encoder throws away global motion because it is never used.
* Decoder sees that there is no global motion and all candidate MVs are
zero, so sets the ALL_ZERO flag.
* This leads to an encode/decode mismatch.
*/
if
(
*
ref_mv_count
>=
2
)
{
for
(
idx
=
0
;
idx
<
AOMMIN
(
3
,
*
ref_mv_count
);
++
idx
)
{
if
(
ref_mv_stack
[
idx
].
this_mv
.
as_int
!=
0
)
all_zero
=
0
;
if
(
ref_mv_stack
[
idx
].
this_mv
.
as_int
!=
zeromv
[
0
].
as_int
)
all_zero
=
0
;
if
(
ref_frame
>
ALTREF_FRAME
)
if
(
ref_mv_stack
[
idx
].
comp_mv
.
as_int
!=
0
)
all_zero
=
0
;
if
(
ref_mv_stack
[
idx
].
comp_mv
.
as_int
!=
zeromv
[
1
].
as_int
)
all_zero
=
0
;
}
}
else
if
(
ref_frame
<=
ALTREF_FRAME
)
{
for
(
idx
=
0
;
idx
<
MAX_MV_REF_CANDIDATES
;
++
idx
)
if
(
mv_ref_list
[
idx
].
as_int
!=
0
)
all_zero
=
0
;
if
(
mv_ref_list
[
idx
].
as_int
!=
zeromv
[
0
].
as_int
)
all_zero
=
0
;
}
#endif
if
(
all_zero
)
mode_context
[
ref_frame
]
|=
(
1
<<
ALL_ZERO_FLAG_OFFSET
);
#endif
...
...
@@ -818,6 +838,7 @@ void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
MODE_INFO
*
const
mi
=
xd
->
mi
[
0
];
b_mode_info
*
bmi
=
mi
->
bmi
;
int
n
;
int_mv
zeromv
;
#if CONFIG_REF_MV
CANDIDATE_MV
tmp_mv
;
uint8_t
idx
;
...
...
@@ -828,8 +849,13 @@ void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
assert
(
MAX_MV_REF_CANDIDATES
==
2
);
#if CONFIG_GLOBAL_MOTION
zeromv
.
as_int
=
gm_get_motion_vector
(
&
cm
->
global_motion
[
ref
]).
as_int
;
#else
zeromv
.
as_int
=
0
;
#endif
find_mv_refs_idx
(
cm
,
xd
,
mi
,
mi
->
mbmi
.
ref_frame
[
ref
],
mv_list
,
block
,
mi_row
,
mi_col
,
NULL
,
NULL
,
NULL
);
mi_col
,
NULL
,
NULL
,
NULL
,
zeromv
);
#if CONFIG_REF_MV
scan_blk_mbmi
(
cm
,
xd
,
mi_row
,
mi_col
,
block
,
rf
,
-
1
,
0
,
ref_mv_stack
,
...
...
av1/decoder/decodemv.c
View file @
43479c6c
...
...
@@ -1479,14 +1479,26 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
if
(
xd
->
ref_mv_count
[
ref_frame
]
<
2
)
{
MV_REFERENCE_FRAME
rf
[
2
];
int_mv
zeromv
[
2
];
av1_set_ref_frame
(
rf
,
ref_frame
);
#if CONFIG_GLOBAL_MOTION
zeromv
[
0
].
as_int
=
gm_get_motion_vector
(
&
cm
->
global_motion
[
rf
[
0
]]).
as_int
;
zeromv
[
1
].
as_int
=
(
rf
[
1
]
!=
NONE
)
?
gm_get_motion_vector
(
&
cm
->
global_motion
[
rf
[
1
]]).
as_int
:
0
;
#else
zeromv
[
0
].
as_int
=
zeromv
[
1
].
as_int
=
0
;
#endif
for
(
ref
=
0
;
ref
<
2
;
++
ref
)
{
lower_mv_precision
(
&
ref_mvs
[
rf
[
ref
]][
0
].
as_mv
,
allow_hp
);
lower_mv_precision
(
&
ref_mvs
[
rf
[
ref
]][
1
].
as_mv
,
allow_hp
);
}
if
(
ref_mvs
[
rf
[
0
]][
0
].
as_int
!=
0
||
ref_mvs
[
rf
[
0
]][
1
].
as_int
!=
0
||
ref_mvs
[
rf
[
1
]][
0
].
as_int
!=
0
||
ref_mvs
[
rf
[
1
]][
1
].
as_int
!=
0
)
if
(
ref_mvs
[
rf
[
0
]][
0
].
as_int
!=
zeromv
[
0
].
as_int
||
ref_mvs
[
rf
[
0
]][
1
].
as_int
!=
zeromv
[
0
].
as_int
||
ref_mvs
[
rf
[
1
]][
0
].
as_int
!=
zeromv
[
1
].
as_int
||
ref_mvs
[
rf
[
1
]][
1
].
as_int
!=
zeromv
[
1
].
as_int
)
inter_mode_ctx
[
ref_frame
]
&=
~
(
1
<<
ALL_ZERO_FLAG_OFFSET
);
}
}
...
...
av1/encoder/bitstream.c
View file @
43479c6c
...
...
@@ -4094,9 +4094,14 @@ static void write_global_motion(AV1_COMP *cpi, aom_writer *w) {
AV1_COMMON
*
const
cm
=
&
cpi
->
common
;
int
frame
;
for
(
frame
=
LAST_FRAME
;
frame
<=
ALTREF_FRAME
;
++
frame
)
{
#if !CONFIG_REF_MV
// With ref-mv, clearing unused global motion models here is
// unsafe, and we need to rely on the recode loop to do it
// instead. See av1_find_mv_refs for details.
if
(
!
cpi
->
global_motion_used
[
frame
])
{
set_default_gmparams
(
&
cm
->
global_motion
[
frame
]);
}
#endif
write_global_motion_params
(
&
cm
->
global_motion
[
frame
],
cm
->
fc
->
global_motion_types_prob
,
w
);
/*
...
...
av1/encoder/encoder.c
View file @
43479c6c
...
...
@@ -2889,7 +2889,11 @@ static int recode_loop_test_global_motion(AV1_COMP *cpi) {
if
(
cm
->
global_motion
[
i
].
wmtype
!=
IDENTITY
&&
cpi
->
global_motion_used
[
i
]
<
MIN_GLOBAL_MOTION_BLKS
)
{
set_default_gmparams
(
&
cm
->
global_motion
[
i
]);
#if CONFIG_REF_MV
recode
=
1
;
#else
recode
|=
(
cpi
->
global_motion_used
[
i
]
>
0
);
#endif
}
}
return
recode
;
...
...
av1/encoder/rdopt.c
View file @
43479c6c
...
...
@@ -8611,10 +8611,13 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
MV_REFERENCE_FRAME rf[2];
av1_set_ref_frame(rf, ref_frame);
if (mbmi_ext->ref_mvs[rf[0]][0].as_int != 0 ||
mbmi_ext->ref_mvs[rf[0]][1].as_int != 0 ||
mbmi_ext->ref_mvs[rf[1]][0].as_int != 0 ||
mbmi_ext->ref_mvs[rf[1]][1].as_int != 0)
if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
frame_mv[ZEROMV][rf[0]].as_int ||
mbmi_ext->ref_mvs[rf[0]][1].as_int !=
frame_mv[ZEROMV][rf[0]].as_int ||
mbmi_ext->ref_mvs[rf[1]][0].as_int !=
frame_mv[ZEROMV][rf[1]].as_int ||
mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
}
}
...
...
@@ -9969,27 +9972,34 @@ PALETTE_EXIT:
}
#if CONFIG_REF_MV
if (best_mbmode.ref_frame[0] > INTRA_FRAME && best_mbmode.mv[0].as_int == 0 &&
#if CONFIG_EXT_INTER
(best_mbmode.ref_frame[1] <= INTRA_FRAME)
#else
(best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)
#endif // CONFIG_EXT_INTER
) {
{
int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
best_mbmode.mode = ZEROMV
;
int_mv zeromv[2]
;
#if CONFIG_GLOBAL_MOTION
best_mbmode.mv[0].as_int =
gm_get_motion_vector(&cm->global_motion[best_mbmode.ref_frame[0]])
.as_int;
if (best_mbmode.ref_frame[1] != NONE)
best_mbmode.mv[1].as_int =
gm_get_motion_vector(&cm->global_motion[best_mbmode.ref_frame[1]])
.as_int;
#endif
const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
best_mbmode.ref_frame[1] };
zeromv[0].as_int =
gm_get_motion_vector(&cm->global_motion[refs[0]]).as_int;
zeromv[1].as_int =
gm_get_motion_vector(&cm->global_motion[refs[1]]).as_int;
lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
#else
zeromv[0].as_int = zeromv[1].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
best_mbmode.mv[0].as_int == zeromv[0].as_int &&
#if CONFIG_EXT_INTER
(best_mbmode.ref_frame[1] <= INTRA_FRAME)
#else
(best_mbmode.ref_frame[1] == NONE ||
best_mbmode.mv[1].as_int == zeromv[1].as_int)
#endif // CONFIG_EXT_INTER
) {
best_mbmode.mode = ZEROMV;
}
}
}
#endif
...
...
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