Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Xiph.Org
aom-rav1e
Commits
6fb10f2d
Commit
6fb10f2d
authored
Jun 25, 2013
by
Dmitry Kovalev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Renaming "nmv" to "mv".
Change-Id: I8299f55c3b930221e52c2237f2ddea65b94fd33b
parent
0441e0a2
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
62 additions
and
82 deletions
+62
-82
vp9/common/vp9_entropymv.c
vp9/common/vp9_entropymv.c
+1
-1
vp9/common/vp9_entropymv.h
vp9/common/vp9_entropymv.h
+2
-2
vp9/decoder/vp9_decodemv.c
vp9/decoder/vp9_decodemv.c
+13
-14
vp9/encoder/vp9_encodemv.c
vp9/encoder/vp9_encodemv.c
+46
-65
No files found.
vp9/common/vp9_entropymv.c
View file @
6fb10f2d
...
@@ -198,7 +198,7 @@ static void counts_to_context(nmv_component_counts *mvcomp, int usehp) {
...
@@ -198,7 +198,7 @@ static void counts_to_context(nmv_component_counts *mvcomp, int usehp) {
}
}
}
}
void
vp9_inc
rement_n
mv
(
const
MV
*
mv
,
const
MV
*
ref
,
nmv_context_counts
*
mvctx
,
void
vp9_inc
_
mv
(
const
MV
*
mv
,
const
MV
*
ref
,
nmv_context_counts
*
mvctx
,
int
usehp
)
{
int
usehp
)
{
const
MV_JOINT_TYPE
j
=
vp9_get_mv_joint
(
mv
);
const
MV_JOINT_TYPE
j
=
vp9_get_mv_joint
(
mv
);
mvctx
->
joints
[
j
]
++
;
mvctx
->
joints
[
j
]
++
;
...
...
vp9/common/vp9_entropymv.h
View file @
6fb10f2d
...
@@ -121,8 +121,8 @@ typedef struct {
...
@@ -121,8 +121,8 @@ typedef struct {
nmv_component_counts
comps
[
2
];
nmv_component_counts
comps
[
2
];
}
nmv_context_counts
;
}
nmv_context_counts
;
void
vp9_inc
rement_n
mv
(
const
MV
*
mv
,
const
MV
*
ref
,
nmv_context_counts
*
mvctx
,
void
vp9_inc
_
mv
(
const
MV
*
mv
,
const
MV
*
ref
,
nmv_context_counts
*
mvctx
,
int
usehp
);
int
usehp
);
extern
const
nmv_context
vp9_default_nmv_context
;
extern
const
nmv_context
vp9_default_nmv_context
;
void
vp9_counts_to_nmv_context
(
void
vp9_counts_to_nmv_context
(
nmv_context_counts
*
NMVcount
,
nmv_context_counts
*
NMVcount
,
...
...
vp9/decoder/vp9_decodemv.c
View file @
6fb10f2d
...
@@ -194,7 +194,7 @@ static int read_mv_component(vp9_reader *r,
...
@@ -194,7 +194,7 @@ static int read_mv_component(vp9_reader *r,
return
sign
?
-
mag
:
mag
;
return
sign
?
-
mag
:
mag
;
}
}
static
void
update_
n
mv
(
vp9_reader
*
r
,
vp9_prob
*
const
p
,
static
void
update_mv
(
vp9_reader
*
r
,
vp9_prob
*
const
p
,
const
vp9_prob
upd_p
)
{
const
vp9_prob
upd_p
)
{
if
(
vp9_read
(
r
,
upd_p
))
{
if
(
vp9_read
(
r
,
upd_p
))
{
#ifdef LOW_PRECISION_MV_UPDATE
#ifdef LOW_PRECISION_MV_UPDATE
...
@@ -205,8 +205,7 @@ static void update_nmv(vp9_reader *r, vp9_prob *const p,
...
@@ -205,8 +205,7 @@ static void update_nmv(vp9_reader *r, vp9_prob *const p,
}
}
}
}
static
void
read_nmvprobs
(
vp9_reader
*
r
,
nmv_context
*
mvctx
,
static
void
read_mv_probs
(
vp9_reader
*
r
,
nmv_context
*
mvc
,
int
usehp
)
{
int
usehp
)
{
int
i
,
j
,
k
;
int
i
,
j
,
k
;
#ifdef MV_GROUP_UPDATE
#ifdef MV_GROUP_UPDATE
...
@@ -214,33 +213,33 @@ static void read_nmvprobs(vp9_reader *r, nmv_context *mvctx,
...
@@ -214,33 +213,33 @@ static void read_nmvprobs(vp9_reader *r, nmv_context *mvctx,
return
;
return
;
#endif
#endif
for
(
j
=
0
;
j
<
MV_JOINTS
-
1
;
++
j
)
for
(
j
=
0
;
j
<
MV_JOINTS
-
1
;
++
j
)
update_
n
mv
(
r
,
&
mvc
tx
->
joints
[
j
],
VP9_NMV_UPDATE_PROB
);
update_mv
(
r
,
&
mvc
->
joints
[
j
],
VP9_NMV_UPDATE_PROB
);
for
(
i
=
0
;
i
<
2
;
++
i
)
{
for
(
i
=
0
;
i
<
2
;
++
i
)
{
update_
n
mv
(
r
,
&
mvc
tx
->
comps
[
i
].
sign
,
VP9_NMV_UPDATE_PROB
);
update_mv
(
r
,
&
mvc
->
comps
[
i
].
sign
,
VP9_NMV_UPDATE_PROB
);
for
(
j
=
0
;
j
<
MV_CLASSES
-
1
;
++
j
)
for
(
j
=
0
;
j
<
MV_CLASSES
-
1
;
++
j
)
update_
n
mv
(
r
,
&
mvc
tx
->
comps
[
i
].
classes
[
j
],
VP9_NMV_UPDATE_PROB
);
update_mv
(
r
,
&
mvc
->
comps
[
i
].
classes
[
j
],
VP9_NMV_UPDATE_PROB
);
for
(
j
=
0
;
j
<
CLASS0_SIZE
-
1
;
++
j
)
for
(
j
=
0
;
j
<
CLASS0_SIZE
-
1
;
++
j
)
update_
n
mv
(
r
,
&
mvc
tx
->
comps
[
i
].
class0
[
j
],
VP9_NMV_UPDATE_PROB
);
update_mv
(
r
,
&
mvc
->
comps
[
i
].
class0
[
j
],
VP9_NMV_UPDATE_PROB
);
for
(
j
=
0
;
j
<
MV_OFFSET_BITS
;
++
j
)
for
(
j
=
0
;
j
<
MV_OFFSET_BITS
;
++
j
)
update_
n
mv
(
r
,
&
mvc
tx
->
comps
[
i
].
bits
[
j
],
VP9_NMV_UPDATE_PROB
);
update_mv
(
r
,
&
mvc
->
comps
[
i
].
bits
[
j
],
VP9_NMV_UPDATE_PROB
);
}
}
for
(
i
=
0
;
i
<
2
;
++
i
)
{
for
(
i
=
0
;
i
<
2
;
++
i
)
{
for
(
j
=
0
;
j
<
CLASS0_SIZE
;
++
j
)
for
(
j
=
0
;
j
<
CLASS0_SIZE
;
++
j
)
for
(
k
=
0
;
k
<
3
;
++
k
)
for
(
k
=
0
;
k
<
3
;
++
k
)
update_
n
mv
(
r
,
&
mvc
tx
->
comps
[
i
].
class0_fp
[
j
][
k
],
VP9_NMV_UPDATE_PROB
);
update_mv
(
r
,
&
mvc
->
comps
[
i
].
class0_fp
[
j
][
k
],
VP9_NMV_UPDATE_PROB
);
for
(
j
=
0
;
j
<
3
;
++
j
)
for
(
j
=
0
;
j
<
3
;
++
j
)
update_
n
mv
(
r
,
&
mvc
tx
->
comps
[
i
].
fp
[
j
],
VP9_NMV_UPDATE_PROB
);
update_mv
(
r
,
&
mvc
->
comps
[
i
].
fp
[
j
],
VP9_NMV_UPDATE_PROB
);
}
}
if
(
usehp
)
{
if
(
usehp
)
{
for
(
i
=
0
;
i
<
2
;
++
i
)
{
for
(
i
=
0
;
i
<
2
;
++
i
)
{
update_
n
mv
(
r
,
&
mvc
tx
->
comps
[
i
].
class0_hp
,
VP9_NMV_UPDATE_PROB
);
update_mv
(
r
,
&
mvc
->
comps
[
i
].
class0_hp
,
VP9_NMV_UPDATE_PROB
);
update_
n
mv
(
r
,
&
mvc
tx
->
comps
[
i
].
hp
,
VP9_NMV_UPDATE_PROB
);
update_mv
(
r
,
&
mvc
->
comps
[
i
].
hp
,
VP9_NMV_UPDATE_PROB
);
}
}
}
}
}
}
...
@@ -397,7 +396,7 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) {
...
@@ -397,7 +396,7 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) {
}
}
}
}
read_
n
mvprobs
(
r
,
nmvc
,
xd
->
allow_high_precision_mv
);
read_mv
_
probs
(
r
,
nmvc
,
xd
->
allow_high_precision_mv
);
}
}
}
}
...
@@ -468,7 +467,7 @@ static INLINE void decode_mv(vp9_reader *r, MV *mv, const MV *ref,
...
@@ -468,7 +467,7 @@ static INLINE void decode_mv(vp9_reader *r, MV *mv, const MV *ref,
if
(
mv_joint_horizontal
(
j
))
if
(
mv_joint_horizontal
(
j
))
diff
.
col
=
read_mv_component
(
r
,
&
ctx
->
comps
[
1
],
usehp
);
diff
.
col
=
read_mv_component
(
r
,
&
ctx
->
comps
[
1
],
usehp
);
vp9_inc
rement_n
mv
(
&
diff
,
ref
,
counts
,
usehp
);
vp9_inc
_
mv
(
&
diff
,
ref
,
counts
,
usehp
);
mv
->
row
=
diff
.
row
+
ref
->
row
;
mv
->
row
=
diff
.
row
+
ref
->
row
;
mv
->
col
=
diff
.
col
+
ref
->
col
;
mv
->
col
=
diff
.
col
+
ref
->
col
;
...
...
vp9/encoder/vp9_encodemv.c
View file @
6fb10f2d
...
@@ -152,12 +152,8 @@ static int update_nmv_savings(const unsigned int ct[2],
...
@@ -152,12 +152,8 @@ static int update_nmv_savings(const unsigned int ct[2],
}
}
}
}
static
int
update_nmv
(
static
int
update_mv
(
vp9_writer
*
bc
,
const
unsigned
int
ct
[
2
],
vp9_writer
*
const
bc
,
vp9_prob
*
cur_p
,
vp9_prob
new_p
,
vp9_prob
upd_p
)
{
const
unsigned
int
ct
[
2
],
vp9_prob
*
const
cur_p
,
const
vp9_prob
new_p
,
const
vp9_prob
upd_p
)
{
#ifdef LOW_PRECISION_MV_UPDATE
#ifdef LOW_PRECISION_MV_UPDATE
vp9_prob
mod_p
=
new_p
|
1
;
vp9_prob
mod_p
=
new_p
|
1
;
...
@@ -394,6 +390,8 @@ void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer* const bc) {
...
@@ -394,6 +390,8 @@ void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer* const bc) {
unsigned
int
branch_ct_fp
[
2
][
4
-
1
][
2
];
unsigned
int
branch_ct_fp
[
2
][
4
-
1
][
2
];
unsigned
int
branch_ct_class0_hp
[
2
][
2
];
unsigned
int
branch_ct_class0_hp
[
2
][
2
];
unsigned
int
branch_ct_hp
[
2
][
2
];
unsigned
int
branch_ct_hp
[
2
][
2
];
nmv_context
*
mvc
=
&
cpi
->
common
.
fc
.
nmvc
;
#ifdef MV_GROUP_UPDATE
#ifdef MV_GROUP_UPDATE
int
savings
=
0
;
int
savings
=
0
;
#endif
#endif
...
@@ -475,63 +473,46 @@ void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer* const bc) {
...
@@ -475,63 +473,46 @@ void vp9_write_nmv_probs(VP9_COMP* const cpi, int usehp, vp9_writer* const bc) {
vp9_write_bit
(
bc
,
1
);
vp9_write_bit
(
bc
,
1
);
#endif
#endif
for
(
j
=
0
;
j
<
MV_JOINTS
-
1
;
++
j
)
{
for
(
j
=
0
;
j
<
MV_JOINTS
-
1
;
++
j
)
update_nmv
(
bc
,
branch_ct_joint
[
j
],
update_mv
(
bc
,
branch_ct_joint
[
j
],
&
mvc
->
joints
[
j
],
prob
.
joints
[
j
],
&
cpi
->
common
.
fc
.
nmvc
.
joints
[
j
],
VP9_NMV_UPDATE_PROB
);
prob
.
joints
[
j
],
VP9_NMV_UPDATE_PROB
);
}
for
(
i
=
0
;
i
<
2
;
++
i
)
{
for
(
i
=
0
;
i
<
2
;
++
i
)
{
update_nmv
(
bc
,
branch_ct_sign
[
i
],
update_mv
(
bc
,
branch_ct_sign
[
i
],
&
mvc
->
comps
[
i
].
sign
,
&
cpi
->
common
.
fc
.
nmvc
.
comps
[
i
].
sign
,
prob
.
comps
[
i
].
sign
,
VP9_NMV_UPDATE_PROB
);
prob
.
comps
[
i
].
sign
,
for
(
j
=
0
;
j
<
MV_CLASSES
-
1
;
++
j
)
VP9_NMV_UPDATE_PROB
);
update_mv
(
bc
,
branch_ct_classes
[
i
][
j
],
&
mvc
->
comps
[
i
].
classes
[
j
],
for
(
j
=
0
;
j
<
MV_CLASSES
-
1
;
++
j
)
{
prob
.
comps
[
i
].
classes
[
j
],
VP9_NMV_UPDATE_PROB
);
update_nmv
(
bc
,
branch_ct_classes
[
i
][
j
],
&
cpi
->
common
.
fc
.
nmvc
.
comps
[
i
].
classes
[
j
],
for
(
j
=
0
;
j
<
CLASS0_SIZE
-
1
;
++
j
)
prob
.
comps
[
i
].
classes
[
j
],
update_mv
(
bc
,
branch_ct_class0
[
i
][
j
],
&
mvc
->
comps
[
i
].
class0
[
j
],
VP9_NMV_UPDATE_PROB
);
prob
.
comps
[
i
].
class0
[
j
],
VP9_NMV_UPDATE_PROB
);
}
for
(
j
=
0
;
j
<
CLASS0_SIZE
-
1
;
++
j
)
{
for
(
j
=
0
;
j
<
MV_OFFSET_BITS
;
++
j
)
update_nmv
(
bc
,
branch_ct_class0
[
i
][
j
],
update_mv
(
bc
,
branch_ct_bits
[
i
][
j
],
&
mvc
->
comps
[
i
].
bits
[
j
],
&
cpi
->
common
.
fc
.
nmvc
.
comps
[
i
].
class0
[
j
],
prob
.
comps
[
i
].
bits
[
j
],
VP9_NMV_UPDATE_PROB
);
prob
.
comps
[
i
].
class0
[
j
],
VP9_NMV_UPDATE_PROB
);
}
for
(
j
=
0
;
j
<
MV_OFFSET_BITS
;
++
j
)
{
update_nmv
(
bc
,
branch_ct_bits
[
i
][
j
],
&
cpi
->
common
.
fc
.
nmvc
.
comps
[
i
].
bits
[
j
],
prob
.
comps
[
i
].
bits
[
j
],
VP9_NMV_UPDATE_PROB
);
}
}
}
for
(
i
=
0
;
i
<
2
;
++
i
)
{
for
(
i
=
0
;
i
<
2
;
++
i
)
{
for
(
j
=
0
;
j
<
CLASS0_SIZE
;
++
j
)
{
for
(
j
=
0
;
j
<
CLASS0_SIZE
;
++
j
)
{
int
k
;
int
k
;
for
(
k
=
0
;
k
<
3
;
++
k
)
{
for
(
k
=
0
;
k
<
3
;
++
k
)
update_nmv
(
bc
,
branch_ct_class0_fp
[
i
][
j
][
k
],
update_mv
(
bc
,
branch_ct_class0_fp
[
i
][
j
][
k
],
&
cpi
->
common
.
fc
.
nmvc
.
comps
[
i
].
class0_fp
[
j
][
k
],
&
mvc
->
comps
[
i
].
class0_fp
[
j
][
k
],
prob
.
comps
[
i
].
class0_fp
[
j
][
k
],
prob
.
comps
[
i
].
class0_fp
[
j
][
k
],
VP9_NMV_UPDATE_PROB
);
VP9_NMV_UPDATE_PROB
);
}
}
for
(
j
=
0
;
j
<
3
;
++
j
)
{
update_nmv
(
bc
,
branch_ct_fp
[
i
][
j
],
&
cpi
->
common
.
fc
.
nmvc
.
comps
[
i
].
fp
[
j
],
prob
.
comps
[
i
].
fp
[
j
],
VP9_NMV_UPDATE_PROB
);
}
}
for
(
j
=
0
;
j
<
3
;
++
j
)
update_mv
(
bc
,
branch_ct_fp
[
i
][
j
],
&
mvc
->
comps
[
i
].
fp
[
j
],
prob
.
comps
[
i
].
fp
[
j
],
VP9_NMV_UPDATE_PROB
);
}
}
if
(
usehp
)
{
if
(
usehp
)
{
for
(
i
=
0
;
i
<
2
;
++
i
)
{
for
(
i
=
0
;
i
<
2
;
++
i
)
{
update_nmv
(
bc
,
branch_ct_class0_hp
[
i
],
update_mv
(
bc
,
branch_ct_class0_hp
[
i
],
&
mvc
->
comps
[
i
].
class0_hp
,
&
cpi
->
common
.
fc
.
nmvc
.
comps
[
i
].
class0_hp
,
prob
.
comps
[
i
].
class0_hp
,
VP9_NMV_UPDATE_PROB
);
prob
.
comps
[
i
].
class0_hp
,
update_mv
(
bc
,
branch_ct_hp
[
i
],
&
mvc
->
comps
[
i
].
hp
,
VP9_NMV_UPDATE_PROB
);
prob
.
comps
[
i
].
hp
,
VP9_NMV_UPDATE_PROB
);
update_nmv
(
bc
,
branch_ct_hp
[
i
],
&
cpi
->
common
.
fc
.
nmvc
.
comps
[
i
].
hp
,
prob
.
comps
[
i
].
hp
,
VP9_NMV_UPDATE_PROB
);
}
}
}
}
}
}
...
@@ -582,29 +563,29 @@ void vp9_update_nmv_count(VP9_COMP *cpi, MACROBLOCK *x,
...
@@ -582,29 +563,29 @@ void vp9_update_nmv_count(VP9_COMP *cpi, MACROBLOCK *x,
if
(
pi
->
bmi
[
i
].
mode
==
NEWMV
)
{
if
(
pi
->
bmi
[
i
].
mode
==
NEWMV
)
{
mv
.
row
=
(
pi
->
bmi
[
i
].
mv
.
as_mv
.
row
-
best_ref_mv
->
as_mv
.
row
);
mv
.
row
=
(
pi
->
bmi
[
i
].
mv
.
as_mv
.
row
-
best_ref_mv
->
as_mv
.
row
);
mv
.
col
=
(
pi
->
bmi
[
i
].
mv
.
as_mv
.
col
-
best_ref_mv
->
as_mv
.
col
);
mv
.
col
=
(
pi
->
bmi
[
i
].
mv
.
as_mv
.
col
-
best_ref_mv
->
as_mv
.
col
);
vp9_inc
rement_n
mv
(
&
mv
,
&
best_ref_mv
->
as_mv
,
&
cpi
->
NMVcount
,
vp9_inc
_
mv
(
&
mv
,
&
best_ref_mv
->
as_mv
,
&
cpi
->
NMVcount
,
x
->
e_mbd
.
allow_high_precision_mv
);
x
->
e_mbd
.
allow_high_precision_mv
);
if
(
x
->
e_mbd
.
mode_info_context
->
mbmi
.
ref_frame
[
1
]
>
INTRA_FRAME
)
{
if
(
x
->
e_mbd
.
mode_info_context
->
mbmi
.
ref_frame
[
1
]
>
INTRA_FRAME
)
{
mv
.
row
=
pi
->
bmi
[
i
].
second_mv
.
as_mv
.
row
-
mv
.
row
=
pi
->
bmi
[
i
].
second_mv
.
as_mv
.
row
-
second_best_ref_mv
->
as_mv
.
row
;
second_best_ref_mv
->
as_mv
.
row
;
mv
.
col
=
pi
->
bmi
[
i
].
second_mv
.
as_mv
.
col
-
mv
.
col
=
pi
->
bmi
[
i
].
second_mv
.
as_mv
.
col
-
second_best_ref_mv
->
as_mv
.
col
;
second_best_ref_mv
->
as_mv
.
col
;
vp9_inc
rement_n
mv
(
&
mv
,
&
second_best_ref_mv
->
as_mv
,
&
cpi
->
NMVcount
,
vp9_inc
_
mv
(
&
mv
,
&
second_best_ref_mv
->
as_mv
,
&
cpi
->
NMVcount
,
x
->
e_mbd
.
allow_high_precision_mv
);
x
->
e_mbd
.
allow_high_precision_mv
);
}
}
}
}
}
}
}
}
}
else
if
(
mbmi
->
mode
==
NEWMV
)
{
}
else
if
(
mbmi
->
mode
==
NEWMV
)
{
mv
.
row
=
(
mbmi
->
mv
[
0
].
as_mv
.
row
-
best_ref_mv
->
as_mv
.
row
)
;
mv
.
row
=
mbmi
->
mv
[
0
].
as_mv
.
row
-
best_ref_mv
->
as_mv
.
row
;
mv
.
col
=
(
mbmi
->
mv
[
0
].
as_mv
.
col
-
best_ref_mv
->
as_mv
.
col
)
;
mv
.
col
=
mbmi
->
mv
[
0
].
as_mv
.
col
-
best_ref_mv
->
as_mv
.
col
;
vp9_inc
rement_n
mv
(
&
mv
,
&
best_ref_mv
->
as_mv
,
&
cpi
->
NMVcount
,
vp9_inc
_
mv
(
&
mv
,
&
best_ref_mv
->
as_mv
,
&
cpi
->
NMVcount
,
x
->
e_mbd
.
allow_high_precision_mv
);
x
->
e_mbd
.
allow_high_precision_mv
);
if
(
mbmi
->
ref_frame
[
1
]
>
INTRA_FRAME
)
{
if
(
mbmi
->
ref_frame
[
1
]
>
INTRA_FRAME
)
{
mv
.
row
=
(
mbmi
->
mv
[
1
].
as_mv
.
row
-
second_best_ref_mv
->
as_mv
.
row
)
;
mv
.
row
=
mbmi
->
mv
[
1
].
as_mv
.
row
-
second_best_ref_mv
->
as_mv
.
row
;
mv
.
col
=
(
mbmi
->
mv
[
1
].
as_mv
.
col
-
second_best_ref_mv
->
as_mv
.
col
)
;
mv
.
col
=
mbmi
->
mv
[
1
].
as_mv
.
col
-
second_best_ref_mv
->
as_mv
.
col
;
vp9_inc
rement_n
mv
(
&
mv
,
&
second_best_ref_mv
->
as_mv
,
&
cpi
->
NMVcount
,
vp9_inc
_
mv
(
&
mv
,
&
second_best_ref_mv
->
as_mv
,
&
cpi
->
NMVcount
,
x
->
e_mbd
.
allow_high_precision_mv
);
x
->
e_mbd
.
allow_high_precision_mv
);
}
}
}
}
}
}
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