Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
VideoLAN
x264
Commits
df732ec7
Commit
df732ec7
authored
Nov 09, 2009
by
Loren Merritt
Browse files
cosmetics
parent
09411091
Changes
9
Hide whitespace changes
Inline
Side-by-side
common/frame.c
View file @
df732ec7
...
...
@@ -53,8 +53,8 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
frame
->
i_lines
[
i
]
=
i_lines
>>
!!
i
;
}
luma_plane_size
=
(
frame
->
i_stride
[
0
]
*
(
frame
->
i_lines
[
0
]
+
2
*
i_padv
));
chroma_plane_size
=
(
frame
->
i_stride
[
1
]
*
(
frame
->
i_lines
[
1
]
+
2
*
i_padv
));
luma_plane_size
=
(
frame
->
i_stride
[
0
]
*
(
frame
->
i_lines
[
0
]
+
2
*
i_padv
));
chroma_plane_size
=
(
frame
->
i_stride
[
1
]
*
(
frame
->
i_lines
[
1
]
+
2
*
i_padv
));
for
(
i
=
1
;
i
<
3
;
i
++
)
{
CHECKED_MALLOC
(
frame
->
buffer
[
i
],
chroma_plane_size
);
...
...
@@ -79,14 +79,14 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
* requires them to be in-phase wrt cacheline alignment. */
if
(
h
->
param
.
analyse
.
i_subpel_refine
&&
b_fdec
)
{
CHECKED_MALLOC
(
frame
->
buffer
[
0
],
4
*
luma_plane_size
);
CHECKED_MALLOC
(
frame
->
buffer
[
0
],
4
*
luma_plane_size
);
for
(
i
=
0
;
i
<
4
;
i
++
)
frame
->
filtered
[
i
]
=
frame
->
buffer
[
0
]
+
i
*
luma_plane_size
+
frame
->
i_stride
[
0
]
*
i_padv
+
PADH
;
frame
->
plane
[
0
]
=
frame
->
filtered
[
0
];
}
else
{
CHECKED_MALLOC
(
frame
->
buffer
[
0
],
luma_plane_size
);
CHECKED_MALLOC
(
frame
->
buffer
[
0
],
luma_plane_size
);
frame
->
filtered
[
0
]
=
frame
->
plane
[
0
]
=
frame
->
buffer
[
0
]
+
frame
->
i_stride
[
0
]
*
i_padv
+
PADH
;
}
...
...
@@ -124,7 +124,7 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
frame
->
i_stride_lowres
=
ALIGN
(
frame
->
i_width_lowres
+
2
*
PADH
,
align
);
frame
->
i_lines_lowres
=
frame
->
i_lines
[
0
]
/
2
;
luma_plane_size
=
frame
->
i_stride_lowres
*
(
frame
->
i_lines
[
0
]
/
2
+
2
*
i_padv
);
luma_plane_size
=
frame
->
i_stride_lowres
*
(
frame
->
i_lines
[
0
]
/
2
+
2
*
i_padv
);
CHECKED_MALLOC
(
frame
->
buffer_lowres
[
0
],
4
*
luma_plane_size
);
for
(
i
=
0
;
i
<
4
;
i
++
)
...
...
@@ -339,8 +339,8 @@ void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame )
int
i_subsample
=
i
?
1
:
0
;
int
i_width
=
h
->
param
.
i_width
>>
i_subsample
;
int
i_height
=
h
->
param
.
i_height
>>
i_subsample
;
int
i_padx
=
(
h
->
sps
->
i_mb_width
*
16
-
h
->
param
.
i_width
)
>>
i_subsample
;
int
i_pady
=
(
h
->
sps
->
i_mb_height
*
16
-
h
->
param
.
i_height
)
>>
i_subsample
;
int
i_padx
=
(
h
->
sps
->
i_mb_width
*
16
-
h
->
param
.
i_width
)
>>
i_subsample
;
int
i_pady
=
(
h
->
sps
->
i_mb_height
*
16
-
h
->
param
.
i_height
)
>>
i_subsample
;
if
(
i_padx
)
{
...
...
@@ -761,8 +761,8 @@ void x264_frame_deblock_row( x264_t *h, int mb_y )
else if( !h->mb.b_interlaced )\
refs_equal = h->fref0[h->mb.ref[0][i8p]]->i_poc == h->fref0[h->mb.ref[0][i8q]]->i_poc;\
else\
refs_equal =
(
h->fref0[h->mb.ref[0][i8p]>>1]->i_poc == h->fref0[h->mb.ref[0][i8q]>>1]->i_poc
) &&
\
(
(h->mb.ref[0][i8p]&1) == (h->mb.ref[0][i8q]&1)
)
;\
refs_equal = h->fref0[h->mb.ref[0][i8p]>>1]->i_poc == h->fref0[h->mb.ref[0][i8q]>>1]->i_poc\
&&
(h->mb.ref[0][i8p]&1) == (h->mb.ref[0][i8q]&1);\
if((!refs_equal ||\
abs( h->mb.mv[0][i4p][0] - h->mb.mv[0][i4q][0] ) >= 4 ||\
abs( h->mb.mv[0][i4p][1] - h->mb.mv[0][i4q][1] ) >= mvy_limit ) ||\
...
...
@@ -1065,7 +1065,7 @@ void x264_weight_scale_plane( x264_t *h, uint8_t *dst, int i_dst_stride, uint8_t
* in terms of the cache loads. */
while
(
i_height
>
0
)
{
for
(
x
=
0
;
x
<
i_width
;
x
+=
16
)
for
(
x
=
0
;
x
<
i_width
;
x
+=
16
)
w
->
weightfn
[
16
>>
2
](
dst
+
x
,
i_dst_stride
,
src
+
x
,
i_src_stride
,
w
,
X264_MIN
(
i_height
,
16
)
);
i_height
-=
16
;
dst
+=
16
*
i_dst_stride
;
...
...
common/frame.h
View file @
df732ec7
...
...
@@ -65,7 +65,7 @@ typedef struct x264_frame
uint8_t
*
buffer
[
4
];
uint8_t
*
buffer_lowres
[
4
];
x264_weight_t
weight
[
16
][
3
];
/*
the weights for the P frames used to encode this frame
*/
x264_weight_t
weight
[
16
][
3
];
/*
[ref_index][plane]
*/
uint8_t
*
weighted
[
16
];
/* plane[0] weighted of the reference frames */
int
b_duplicate
;
struct
x264_frame
*
orig
;
...
...
common/mc.c
View file @
df732ec7
...
...
@@ -124,8 +124,8 @@ static void x264_weight_cache( x264_t *h, x264_weight_t *w )
{
w
->
weightfn
=
h
->
mc
.
weight
;
}
#define opscale(x) dst[x] = x264_clip_uint8( (
( (
src[x] * weight->i_scale
)
+ (1<<(weight->i_denom - 1)
)
)
>> weight->i_denom
) + weight->i_offset )
#define opscale_noden(x) dst[x] = x264_clip_uint8(
(
src[x] * weight->i_scale
)
+ weight->i_offset )
#define opscale(x) dst[x] = x264_clip_uint8( (
(
src[x] * weight->i_scale + (1<<(weight->i_denom - 1)
)
) >> weight->i_denom) + weight->i_offset )
#define opscale_noden(x) dst[x] = x264_clip_uint8( src[x] * weight->i_scale + weight->i_offset )
static
inline
void
mc_weight
(
uint8_t
*
dst
,
int
i_dst_stride
,
uint8_t
*
src
,
int
i_src_stride
,
const
x264_weight_t
*
weight
,
int
i_width
,
int
i_height
)
{
...
...
common/x86/mc-a.asm
View file @
df732ec7
...
...
@@ -198,7 +198,7 @@ AVG_WEIGHT ssse3, 16, 7
mova
m3
,
[
r4
]
mova
m4
,
[
r4
+
16
]
pxor
m2
,
m2
%if
(
%1 == 20 || %1 == 12
)
%if %1 == 20 || %1 == 12
movdq2q
mm3
,
xmm3
movdq2q
mm4
,
xmm4
pxor
mm2
,
mm2
...
...
common/x86/mc-c.c
View file @
df732ec7
...
...
@@ -197,7 +197,7 @@ static void x264_weight_cache_mmxext( x264_t *h, x264_weight_t *w )
return
;
}
w
->
weightfn
=
h
->
mc
.
weight
;
den1
=
1
<<
(
w
->
i_denom
-
1
)
|
w
->
i_offset
<<
w
->
i_denom
;
den1
=
1
<<
(
w
->
i_denom
-
1
)
|
w
->
i_offset
<<
w
->
i_denom
;
for
(
i
=
0
;
i
<
8
;
i
++
)
{
w
->
cachea
[
i
]
=
w
->
i_scale
;
...
...
@@ -219,10 +219,10 @@ static void x264_weight_cache_ssse3( x264_t *h, x264_weight_t *w )
return
;
}
w
->
weightfn
=
h
->
mc
.
weight
;
den1
=
(
w
->
i_scale
)
<<
(
8
-
w
->
i_denom
);
den1
=
w
->
i_scale
<<
(
8
-
w
->
i_denom
);
for
(
i
=
0
;
i
<
8
;
i
++
)
{
w
->
cachea
[
i
]
=
den1
;
w
->
cachea
[
i
]
=
den1
;
w
->
cacheb
[
i
]
=
w
->
i_offset
;
}
}
...
...
@@ -278,11 +278,11 @@ static uint8_t *get_ref_##name( uint8_t *dst, int *i_dst_stride,\
x264_pixel_avg_wtab_##name[i_width>>2](\
dst, *i_dst_stride, src1, i_src_stride,\
src2, i_height );\
if( weight->weightfn )
\
weight->weightfn[i_width>>2]( dst, *i_dst_stride, dst, *i_dst_stride, weight, i_height );
\
if( weight->weightfn )\
weight->weightfn[i_width>>2]( dst, *i_dst_stride, dst, *i_dst_stride, weight, i_height );\
return dst;\
}\
else if( weight->weightfn )
\
else if( weight->weightfn )\
{\
weight->weightfn[i_width>>2]( dst, *i_dst_stride, src1, i_src_stride, weight, i_height );\
return dst;\
...
...
common/x86/x86inc.asm
View file @
df732ec7
...
...
@@ -277,15 +277,11 @@ DECLARE_REG 6, rax, eax, ax, al, [rsp + stack_offset + 56]
%endif
%endmacro
%macro PROLOGUE 2-4+
; #args, #regs, #xmm_regs, arg_names...
%macro PROLOGUE 2-4+
0
; #args, #regs, #xmm_regs, arg_names...
ASSERT
%
2
>
=
%
1
%assign regs_used %2
ASSERT
regs_used
<
=
7
%if %0 > 2
%assign xmm_regs_used %3
%else
%assign xmm_regs_used 0
%endif
%assign xmm_regs_used %3
ASSERT
xmm_regs_used
<
=
16
%if regs_used > 4
push
r4
...
...
encoder/slicetype.c
View file @
df732ec7
...
...
@@ -43,7 +43,7 @@ static void x264_lowres_context_init( x264_t *h, x264_mb_analysis_t *a )
h
->
mb
.
b_chroma_me
=
0
;
}
/* makes a non-h264 weight (ie.
a multipler with a denominator of 128
), into an h264 weight */
/* makes a non-h264 weight (i
.
e.
fix7
), into an h264 weight */
static
void
get_h264_weight
(
unsigned
int
weight_nonh264
,
int
offset
,
x264_weight_t
*
w
)
{
w
->
i_offset
=
offset
;
...
...
@@ -73,7 +73,7 @@ static void weights_plane_analyse( x264_t *h, uint8_t *plane, int width, int hei
}
*
sum
=
sad
;
*
var
=
ssd
-
(
uint64_t
)
sad
*
sad
/
(
width
*
height
);
*
var
=
ssd
-
(
uint64_t
)
sad
*
sad
/
(
width
*
height
);
x264_emms
();
}
...
...
@@ -100,7 +100,7 @@ static uint8_t *x264_weight_cost_init_luma( x264_t *h, x264_frame_t *fenc, x264_
int
i_width
=
b_lowres
?
fenc
->
i_width_lowres
:
fenc
->
i_width
[
0
];
int
i_mb_xy
=
0
;
int
mbsizeshift
=
b_lowres
?
3
:
4
;
int
mbsize
=
1
<<
mbsizeshift
;
int
mbsize
=
1
<<
mbsizeshift
;
int
x
,
y
;
int
i_pel_offset
=
0
;
...
...
@@ -135,14 +135,14 @@ static unsigned int x264_weight_cost( x264_t *h, x264_frame_t *fenc, uint8_t *sr
int
i_mb
=
0
;
if
(
w
)
for
(
y
=
0
;
y
<
i_lines
;
y
+=
mbsize
,
pixoff
=
(
y
*
i_stride
)
)
for
(
y
=
0
;
y
<
i_lines
;
y
+=
mbsize
,
pixoff
=
y
*
i_stride
)
for
(
x
=
0
;
x
<
i_width
;
x
+=
mbsize
,
i_mb
++
,
pixoff
+=
mbsize
)
{
w
->
weightfn
[
mbsize
>>
2
](
buf
,
16
,
&
src
[
pixoff
],
i_stride
,
w
,
mbsize
);
cost
+=
X264_MIN
(
h
->
pixf
.
mbcmp
[
pixelsize
](
buf
,
16
,
&
fenc_plane
[
pixoff
],
i_stride
),
fenc
->
i_intra_cost
[
i_mb
]
);
}
else
for
(
y
=
0
;
y
<
i_lines
;
y
+=
mbsize
,
pixoff
=
(
y
*
i_stride
)
)
for
(
y
=
0
;
y
<
i_lines
;
y
+=
mbsize
,
pixoff
=
y
*
i_stride
)
for
(
x
=
0
;
x
<
i_width
;
x
+=
mbsize
,
i_mb
++
,
pixoff
+=
mbsize
)
cost
+=
X264_MIN
(
h
->
pixf
.
mbcmp
[
pixelsize
](
&
src
[
pixoff
],
i_stride
,
&
fenc_plane
[
pixoff
],
i_stride
),
fenc
->
i_intra_cost
[
i_mb
]
);
...
...
@@ -152,8 +152,8 @@ static unsigned int x264_weight_cost( x264_t *h, x264_frame_t *fenc, uint8_t *sr
int
numslices
;
if
(
h
->
param
.
i_slice_count
)
numslices
=
h
->
param
.
i_slice_count
;
else
if
(
h
->
param
.
i_slice_max_mbs
)
numslices
=
(
h
->
sps
->
i_mb_width
*
h
->
sps
->
i_mb_height
+
h
->
param
.
i_slice_max_mbs
-
1
)
/
h
->
param
.
i_slice_max_mbs
;
else
if
(
h
->
param
.
i_slice_max_mbs
)
numslices
=
(
h
->
sps
->
i_mb_width
*
h
->
sps
->
i_mb_height
+
h
->
param
.
i_slice_max_mbs
-
1
)
/
h
->
param
.
i_slice_max_mbs
;
else
numslices
=
1
;
// FIXME still need to calculate for --slice-max-size
...
...
@@ -183,12 +183,12 @@ void x264_weights_analyse( x264_t *h, x264_frame_t *fenc, x264_frame_t *ref, int
weights_plane_analyse
(
h
,
ref
->
plane
[
0
],
ref
->
i_width
[
0
],
ref
->
i_lines
[
0
],
ref
->
i_stride
[
0
],
&
ref_sum
,
&
ref_var
);
fenc_var
=
round
(
sqrt
(
fenc_var
)
);
ref_var
=
round
(
sqrt
(
ref_var
)
);
fenc_mean
=
(
float
)
fenc_sum
/
(
fenc
->
i_lines
[
0
]
*
fenc
->
i_width
[
0
]
);
ref_mean
=
(
float
)
ref_sum
/
(
fenc
->
i_lines
[
0
]
*
fenc
->
i_width
[
0
]
);
fenc_mean
=
(
float
)
fenc_sum
/
(
fenc
->
i_lines
[
0
]
*
fenc
->
i_width
[
0
]);
ref_mean
=
(
float
)
ref_sum
/
(
fenc
->
i_lines
[
0
]
*
fenc
->
i_width
[
0
]);
//early termination
if
(
fabs
(
ref_mean
-
fenc_mean
)
<
0
.
5
&&
fabsf
(
1
-
(
(
float
)
fenc_var
/
ref_var
)
)
<
epsilon
)
if
(
fabs
(
ref_mean
-
fenc_mean
)
<
0
.
5
&&
fabsf
(
1
-
(
float
)
fenc_var
/
ref_var
)
<
epsilon
)
return
;
guess_scale
=
ref_var
?
(
float
)
fenc_var
/
ref_var
:
0
;
...
...
@@ -214,7 +214,7 @@ void x264_weights_analyse( x264_t *h, x264_frame_t *fenc, x264_frame_t *ref, int
// This gives a slight improvement due to rounding errors but only tests
// one offset on lookahead.
// TODO: currently searches only offset +1.
try other offsets/multipliers/combinations thereof?
// TODO: currently searches only offset +1. try other offsets/multipliers/combinations thereof?
for
(
i_off
=
offset_search
;
i_off
<=
offset_search
+!
b_lookahead
;
i_off
++
)
{
SET_WEIGHT
(
weights
[
0
],
1
,
minscale
,
mindenom
,
i_off
);
...
...
@@ -224,7 +224,7 @@ void x264_weights_analyse( x264_t *h, x264_frame_t *fenc, x264_frame_t *ref, int
x264_emms
();
/* FIXME: More analysis can be done here on SAD vs. SATD termination. */
if
(
!
found
||
(
minscale
==
1
<<
mindenom
&&
minoff
==
0
)
||
minscore
>=
fenc
->
i_width
[
0
]
*
fenc
->
i_lines
[
0
]
*
(
b_lowres
?
2
:
8
)
)
if
(
!
found
||
(
minscale
==
1
<<
mindenom
&&
minoff
==
0
)
||
minscore
>=
fenc
->
i_width
[
0
]
*
fenc
->
i_lines
[
0
]
*
(
b_lowres
?
2
:
8
)
)
{
SET_WEIGHT
(
weights
[
0
],
0
,
1
,
0
,
0
);
return
;
...
...
@@ -245,7 +245,7 @@ void x264_weights_analyse( x264_t *h, x264_frame_t *fenc, x264_frame_t *ref, int
int
height
=
ref
->
i_lines_lowres
+
i_padv
*
2
;
x264_weight_scale_plane
(
h
,
dst
,
ref
->
i_stride_lowres
,
src
,
ref
->
i_stride_lowres
,
width
,
height
,
&
weights
[
0
]
);
fenc
->
weighted
[
0
]
=
h
->
mb
.
p_weight_buf
[
0
]
+
PADH
+
(
ref
->
i_stride_lowres
*
i_padv
)
;
fenc
->
weighted
[
0
]
=
h
->
mb
.
p_weight_buf
[
0
]
+
PADH
+
ref
->
i_stride_lowres
*
i_padv
;
}
}
...
...
@@ -262,7 +262,7 @@ static int x264_slicetype_mb_cost( x264_t *h, x264_mb_analysis_t *a,
const
int
i_mb_stride
=
h
->
sps
->
i_mb_width
;
const
int
i_mb_xy
=
i_mb_x
+
i_mb_y
*
i_mb_stride
;
const
int
i_stride
=
fenc
->
i_stride_lowres
;
const
int
i_pel_offset
=
8
*
(
i_mb_x
+
i_mb_y
*
i_stride
);
const
int
i_pel_offset
=
8
*
(
i_mb_x
+
i_mb_y
*
i_stride
);
const
int
i_bipred_weight
=
h
->
param
.
analyse
.
b_weighted_bipred
?
64
-
(
dist_scale_factor
>>
2
)
:
32
;
int16_t
(
*
fenc_mvs
[
2
])[
2
]
=
{
&
frames
[
b
]
->
lowres_mvs
[
0
][
b
-
p0
-
1
][
i_mb_xy
],
&
frames
[
b
]
->
lowres_mvs
[
1
][
p1
-
b
-
1
][
i_mb_xy
]
};
int
(
*
fenc_costs
[
2
])
=
{
&
frames
[
b
]
->
lowres_mv_costs
[
0
][
b
-
p0
-
1
][
i_mb_xy
],
&
frames
[
b
]
->
lowres_mv_costs
[
1
][
p1
-
b
-
1
][
i_mb_xy
]
};
...
...
@@ -642,8 +642,8 @@ static void x264_macroblock_tree_finish( x264_t *h, x264_frame_t *frame, int ref
if
(
intra_cost
)
{
int
propagate_cost
=
frame
->
i_propagate_cost
[
mb_index
];
float
log2_ratio
=
x264_log2
(
intra_cost
+
propagate_cost
)
-
x264_log2
(
intra_cost
);
frame
->
f_qp_offset
[
mb_index
]
=
frame
->
f_qp_offset_aq
[
mb_index
]
-
strength
*
(
log2_ratio
+
weightdelta
)
;
float
log2_ratio
=
x264_log2
(
intra_cost
+
propagate_cost
)
-
x264_log2
(
intra_cost
)
+
weightdelta
;
frame
->
f_qp_offset
[
mb_index
]
=
frame
->
f_qp_offset_aq
[
mb_index
]
-
strength
*
log2_ratio
;
}
}
}
...
...
tools/checkasm.c
View file @
df732ec7
...
...
@@ -927,7 +927,7 @@ static int check_mc( int cpu_ref, int cpu_new )
for
(
o
=
-
128
;
o
<=
127
&&
ok
;
o
++
)
{
if
(
rand
()
&
2047
)
continue
;
for
(
d
=
0
;
d
<=
7
&&
ok
;
d
++
)
for
(
d
=
0
;
d
<=
7
&&
ok
;
d
++
)
{
if
(
s
==
1
<<
d
)
continue
;
...
...
x264.c
View file @
df732ec7
...
...
@@ -560,11 +560,11 @@ static int select_output( char *filename, const char *pipe_format )
static
int
select_input
(
char
*
filename
,
char
*
resolution
,
const
char
*
pipe_format
,
x264_param_t
*
param
)
{
char
*
psz
=
filename
+
strlen
(
filename
)
-
1
;
while
(
psz
>
filename
&&
*
psz
!=
'.'
)
psz
--
;
char
*
ext
=
filename
+
strlen
(
filename
)
-
1
;
while
(
ext
>
filename
&&
*
ext
!=
'.'
)
ext
--
;
if
(
!
strcasecmp
(
psz
,
".avi"
)
||
!
strcasecmp
(
psz
,
".avs"
)
)
if
(
!
strcasecmp
(
ext
,
".avi"
)
||
!
strcasecmp
(
ext
,
".avs"
)
)
{
#ifdef AVIS_INPUT
input
=
avis_input
;
...
...
@@ -573,16 +573,17 @@ static int select_input( char *filename, char *resolution, const char *pipe_form
return
-
1
;
#endif
}
else
if
(
!
strcasecmp
(
psz
,
".y4m"
)
||
(
!
strcmp
(
filename
,
"-"
)
&&
!
strcasecmp
(
pipe_format
,
"y4m"
))
)
else
if
(
!
strcasecmp
(
ext
,
".y4m"
)
||
(
!
strcmp
(
filename
,
"-"
)
&&
!
strcasecmp
(
pipe_format
,
"y4m"
))
)
input
=
y4m_input
;
else
// yuv
{
if
(
!
resolution
)
{
/* try to parse the file name */
for
(
psz
=
filename
;
*
psz
;
psz
++
)
if
(
*
psz
>=
'0'
&&
*
psz
<=
'9'
&&
sscanf
(
psz
,
"%ux%u"
,
&
param
->
i_width
,
&
param
->
i_height
)
==
2
)
char
*
p
;
for
(
p
=
filename
;
*
p
;
p
++
)
if
(
*
p
>=
'0'
&&
*
p
<=
'9'
&&
sscanf
(
p
,
"%ux%u"
,
&
param
->
i_width
,
&
param
->
i_height
)
==
2
)
{
if
(
param
->
i_log_level
>=
X264_LOG_INFO
)
fprintf
(
stderr
,
"x264 [info]: %dx%d (given by file name) @ %.2f fps
\n
"
,
param
->
i_width
,
...
...
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