Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From 9f8b2eb163ea7a7b9810cb1e3c189eac9abbdcf9 Mon Sep 17 00:00:00 2001
- From: Alexander Strange <astrange@ithinksw.com>
- Date: Mon, 10 Nov 2008 00:55:20 -0500
- Subject: [PATCH 1/8] Allow | as a separator between psy-rd and psy-trellis values.
- [,:/] are all taken when setting psy-trellis in a zone in an mencoder option.
- ---
- common/common.c | 3 ++-
- 1 files changed, 2 insertions(+), 1 deletions(-)
- diff --git a/common/common.c b/common/common.c
- index 6d1d7f0..bf47223 100644
- --- a/common/common.c
- +++ b/common/common.c
- -515,7 +515,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )
- OPT("psy-rd")
- {
- if( 2 == sscanf( value, "%f:%f", &p->analyse.f_psy_rd, &p->analyse.f_psy_trellis ) ||
- - 2 == sscanf( value, "%f,%f", &p->analyse.f_psy_rd, &p->analyse.f_psy_trellis ) )
- + 2 == sscanf( value, "%f,%f", &p->analyse.f_psy_rd, &p->analyse.f_psy_trellis ) ||
- + 2 == sscanf( value, "%f|%f", &p->analyse.f_psy_rd, &p->analyse.f_psy_trellis ))
- { }
- else if( sscanf( value, "%f", &p->analyse.f_psy_rd ) )
- {
- --
- 1.6.6
- From f044100562365fec2fe443dfa44ec44199108f58 Mon Sep 17 00:00:00 2001
- From: Alexander Strange <astrange@ithinksw.com>
- Date: Thu, 29 Oct 2009 01:55:46 -0400
- Subject: [PATCH 2/8] B-direct SSD tie-breaker
- by Gabriel
- ---
- common/common.h | 1 +
- encoder/analyse.c | 4 ++++
- encoder/ratecontrol.c | 13 ++++++++++++-
- 3 files changed, 17 insertions(+), 1 deletions(-)
- diff --git a/common/common.h b/common/common.h
- index 950f48f..a5a0726 100644
- --- a/common/common.h
- +++ b/common/common.h
- -689,6 +689,7 @@ struct x264_t
- int i_mb_pred_mode[3][13];
- /* Adaptive direct mv pred */
- int i_direct_score[2];
- + int64_t i_direct_score_SSD[2];
- /* Metrics */
- int64_t i_ssd[3];
- double f_ssim;
- diff --git a/encoder/analyse.c b/encoder/analyse.c
- index 666596b..cdae26d 100644
- --- a/encoder/analyse.c
- +++ b/encoder/analyse.c
- -2698,12 +2698,16 @@ intra_analysis:
- analysis.b_direct_available = x264_mb_predict_mv_direct16x16( h, i && analysis.b_direct_available ? &b_changed : NULL );
- if( analysis.b_direct_available )
- {
- + int i_bskip_local_cost = 0;
- if( b_changed )
- {
- x264_mb_mc( h );
- b_skip = x264_macroblock_probe_bskip( h );
- + if (b_skip)
- + i_bskip_local_cost = ssd_mb( h );
- }
- h->stat.frame.i_direct_score[ h->sh.b_direct_spatial_mv_pred ] += b_skip;
- + h->stat.frame.i_direct_score_SSD[ h->sh.b_direct_spatial_mv_pred ] += i_bskip_local_cost;
- }
- else
- b_skip = 0;
- diff --git a/encoder/ratecontrol.c b/encoder/ratecontrol.c
- index 63b3be6..beba2c3 100644
- --- a/encoder/ratecontrol.c
- +++ b/encoder/ratecontrol.c
- -1336,7 +1336,18 @@ int x264_ratecontrol_end( x264_t *h, int bits )
- char c_type = h->sh.i_type==SLICE_TYPE_I ? (h->fenc->i_poc==0 ? 'I' : 'i')
- : h->sh.i_type==SLICE_TYPE_P ? 'P'
- : h->fenc->b_kept_as_ref ? 'B' : 'b';
- - int dir_frame = h->stat.frame.i_direct_score[1] - h->stat.frame.i_direct_score[0];
- + /* if number of skip blocs in spatial and temporal modes are close, use SSD as a selecting criterion*/
- + int i_direct_score_0 = h->stat.frame.i_direct_score[0];
- + int i_direct_score_1 = h->stat.frame.i_direct_score[1];
- + int b_tied_skip_nums = X264_MIN(i_direct_score_1, i_direct_score_0) > (X264_MAX(i_direct_score_1, i_direct_score_0)*95/100)
- + && i_direct_score_0 && i_direct_score_1;
- + int b_skip_SSD_dif = X264_MIN(h->stat.frame.i_direct_score_SSD[1], h->stat.frame.i_direct_score_SSD[0]) <
- + (X264_MAX(h->stat.frame.i_direct_score_SSD[1], h->stat.frame.i_direct_score_SSD[0])*80/100);
- +
- + int dir_frame = (b_tied_skip_nums && b_skip_SSD_dif) ?
- + h->stat.frame.i_direct_score_SSD[0] - h->stat.frame.i_direct_score_SSD[1] :
- + i_direct_score_1 - i_direct_score_0;
- +
- int dir_avg = h->stat.i_direct_score[1] - h->stat.i_direct_score[0];
- char c_direct = h->mb.b_direct_auto_write ?
- ( dir_frame>0 ? 's' : dir_frame<0 ? 't' :
- --
- 1.6.6
- From 081a40f1c777d023607c8f4a8e6cc0ac1417aa73 Mon Sep 17 00:00:00 2001
- From: Alexander Strange <astrange@ithinksw.com>
- Date: Mon, 9 Nov 2009 00:11:57 -0500
- Subject: [PATCH 3/8] todo comment about qp deltas
- ---
- encoder/analyse.c | 1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
- diff --git a/encoder/analyse.c b/encoder/analyse.c
- index cdae26d..037e00a 100644
- --- a/encoder/analyse.c
- +++ b/encoder/analyse.c
- -2357,6 +2357,7 @@ void x264_macroblock_analyse( x264_t *h )
- x264_adaptive_quant( h );
- /* If the QP of this MB is within 1 of the previous MB, code the same QP as the previous MB,
- * to lower the bit cost of the qp_delta. Don't do this if QPRD is enabled. */
- + //FIXME try also allowing +/- 1 qp_delta if it was +/- 2 two MBs ago
- if( h->param.analyse.i_subpel_refine < 10 && abs(h->mb.i_qp - h->mb.i_last_qp) == 1 )
- h->mb.i_qp = h->mb.i_last_qp;
- }
- --
- 1.6.6
- From 6225fc42c74f5a8fcf5af2c5b99d1734a39ca91a Mon Sep 17 00:00:00 2001
- From: Alexander Strange <astrange@ithinksw.com>
- Date: Sun, 7 Feb 2010 04:09:25 -0500
- Subject: [PATCH 4/8] Fix a comment typo.
- ---
- encoder/encoder.c | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
- diff --git a/encoder/encoder.c b/encoder/encoder.c
- index d873cd0..7bd55d2 100644
- --- a/encoder/encoder.c
- +++ b/encoder/encoder.c
- -84,7 +84,7 @@ static void x264_slice_header_init( x264_t *h, x264_slice_header_t *sh,
- x264_param_t *param = &h->param;
- int i;
- - /* First we fill all field */
- + /* First we fill all fields */
- sh->sps = sps;
- sh->pps = pps;
- --
- 1.6.6
- From 9e6831ffb32c336d42d547514c40c110a2362a12 Mon Sep 17 00:00:00 2001
- From: Alexander Strange <astrange@ithinksw.com>
- Date: Sat, 13 Feb 2010 01:40:44 -0500
- Subject: [PATCH 5/8] Remove useless variable assignment.
- ---
- encoder/encoder.c | 2 --
- 1 files changed, 0 insertions(+), 2 deletions(-)
- diff --git a/encoder/encoder.c b/encoder/encoder.c
- index 7bd55d2..5161e66 100644
- --- a/encoder/encoder.c
- +++ b/encoder/encoder.c
- -659,8 +659,6 @@ static int x264_validate_parameters( x264_t *h )
- /* Psy trellis has a similar effect. */
- if( h->mb.i_psy_trellis )
- h->param.analyse.i_chroma_qp_offset -= h->param.analyse.f_psy_trellis < 0.25 ? 1 : 2;
- - else
- - h->mb.i_psy_trellis = 0;
- h->param.analyse.i_chroma_qp_offset = x264_clip3(h->param.analyse.i_chroma_qp_offset, -12, 12);
- h->param.rc.i_aq_mode = x264_clip3( h->param.rc.i_aq_mode, 0, 2 );
- h->param.rc.f_aq_strength = x264_clip3f( h->param.rc.f_aq_strength, 0, 3 );
- --
- 1.6.6
- From 5e8946747d2d906abb01e768b759e3f6b814e4a0 Mon Sep 17 00:00:00 2001
- From: Alexander Strange <astrange@ithinksw.com>
- Date: Sat, 13 Feb 2010 01:41:41 -0500
- Subject: [PATCH 6/8] mkv: Write SimpleBlock instead of Block for frame headers.
- mkvtoolnix writes these by default since 2009/04/13.
- Slightly simplifies muxer and allows 'mkvinfo -s' to show B-frames
- as 'B' (but not B-ref frames).
- ---
- output/matroska.c | 2 +-
- output/matroska_ebml.c | 72 ++++++------------------------------------------
- output/matroska_ebml.h | 2 +-
- 3 files changed, 11 insertions(+), 65 deletions(-)
- diff --git a/output/matroska.c b/output/matroska.c
- index 8e84f52..db7639c 100644
- --- a/output/matroska.c
- +++ b/output/matroska.c
- @@ -185,7 +185,7 @@ static int write_frame( hnd_t handle, uint8_t *p_nalu, int i_size, x264_picture_
- p_mkv->b_writing_frame = 0;
- - if( mk_set_frame_flags( p_mkv->w, i_stamp, p_picture->b_keyframe ) < 0 )
- + if( mk_set_frame_flags( p_mkv->w, i_stamp, p_picture->b_keyframe, p_picture->i_type == X264_TYPE_B ) < 0 )
- return -1;
- return i_size;
- diff --git a/output/matroska_ebml.c b/output/matroska_ebml.c
- index d1c6e13..6aa42bd 100644
- --- a/output/matroska_ebml.c
- +++ b/output/matroska_ebml.c
- @@ -53,9 +53,9 @@ struct mk_writer
- int64_t def_duration;
- int64_t timescale;
- int64_t cluster_tc_scaled;
- - int64_t frame_tc, prev_frame_tc_scaled, max_frame_tc;
- + int64_t frame_tc, max_frame_tc;
- - char wrote_header, in_frame, keyframe;
- + char wrote_header, in_frame, keyframe, skippable;
- };
- static mk_context *mk_create_context( mk_writer *w, mk_context *parent, unsigned id )
- @@ -258,23 +258,6 @@ static int mk_write_uint( mk_context *c, unsigned id, int64_t ui )
- return 0;
- }
- -static int mk_write_sint( mk_context *c, unsigned id, int64_t si )
- -{
- - unsigned char c_si[8] = { si >> 56, si >> 48, si >> 40, si >> 32, si >> 24, si >> 16, si >> 8, si };
- - unsigned i = 0;
- -
- - CHECK( mk_write_id( c, id ) );
- - if( si < 0 )
- - while( i < 7 && c_si[i] == 0xff && c_si[i+1] & 0x80 )
- - ++i;
- - else
- - while( i < 7 && c_si[i] == 0 && !(c_si[i+1] & 0x80 ) )
- - ++i;
- - CHECK( mk_write_size( c, 8 - i ) );
- - CHECK( mk_append_context_data( c, c_si+i, 8 - i ) );
- - return 0;
- -}
- -
- static int mk_write_float_raw( mk_context *c, float f )
- {
- union
- @@ -301,34 +284,6 @@ static int mk_write_float( mk_context *c, unsigned id, float f )
- return 0;
- }
- -static unsigned mk_ebml_size_size( unsigned s )
- -{
- - if( s < 0x7f )
- - return 1;
- - if( s < 0x3fff )
- - return 2;
- - if( s < 0x1fffff )
- - return 3;
- - if( s < 0x0fffffff )
- - return 4;
- - return 5;
- -}
- -
- -static unsigned mk_ebml_sint_size( int64_t si )
- -{
- - unsigned char c_si[8] = { si >> 56, si >> 48, si >> 40, si >> 32, si >> 24, si >> 16, si >> 8, si };
- - unsigned i = 0;
- -
- - if( si < 0 )
- - while( i < 7 && c_si[i] == 0xff && c_si[i+1] & 0x80 )
- - ++i;
- - else
- - while( i < 7 && c_si[i] == 0 && !(c_si[i+1] & 0x80) )
- - ++i;
- -
- - return 8 - i;
- -}
- -
- mk_writer *mk_create_writer( const char *filename )
- {
- mk_writer *w = malloc( sizeof(*w) );
- @@ -446,8 +401,8 @@ static int mk_close_cluster( mk_writer *w )
- static int mk_flush_frame( mk_writer *w )
- {
- - int64_t delta, ref = 0;
- - unsigned fsize, bgsize;
- + int64_t delta;
- + unsigned fsize;
- unsigned char c_delta_flags[3];
- if( !w->in_frame )
- @@ -470,33 +425,22 @@ static int mk_flush_frame( mk_writer *w )
- }
- fsize = w->frame ? w->frame->d_cur : 0;
- - bgsize = fsize + 4 + mk_ebml_size_size( fsize + 4 ) + 1;
- - if( !w->keyframe )
- - {
- - ref = w->prev_frame_tc_scaled - w->cluster_tc_scaled - delta;
- - bgsize += 1 + 1 + mk_ebml_sint_size( ref );
- - }
- - CHECK( mk_write_id( w->cluster, 0xa0 ) ); // BlockGroup
- - CHECK( mk_write_size( w->cluster, bgsize ) );
- - CHECK( mk_write_id( w->cluster, 0xa1 ) ); // Block
- + CHECK( mk_write_id( w->cluster, 0xa3 ) ); // SimpleBlock
- CHECK( mk_write_size( w->cluster, fsize + 4 ) );
- CHECK( mk_write_size( w->cluster, 1 ) ); // track number
- c_delta_flags[0] = delta >> 8;
- c_delta_flags[1] = delta;
- - c_delta_flags[2] = 0;
- + c_delta_flags[2] = (w->keyframe << 7) | w->skippable;
- CHECK( mk_append_context_data( w->cluster, c_delta_flags, 3 ) );
- if( w->frame )
- {
- CHECK( mk_append_context_data( w->cluster, w->frame->data, w->frame->d_cur ) );
- w->frame->d_cur = 0;
- }
- - if( !w->keyframe )
- - CHECK( mk_write_sint( w->cluster, 0xfb, ref ) ); // ReferenceBlock
- w->in_frame = 0;
- - w->prev_frame_tc_scaled = w->cluster_tc_scaled + delta;
- if( w->cluster->d_cur > CLSIZE )
- CHECK( mk_close_cluster( w ) );
- @@ -511,17 +455,19 @@ int mk_start_frame( mk_writer *w )
- w->in_frame = 1;
- w->keyframe = 0;
- + w->skippable= 0;
- return 0;
- }
- -int mk_set_frame_flags( mk_writer *w, int64_t timestamp, int keyframe )
- +int mk_set_frame_flags( mk_writer *w, int64_t timestamp, int keyframe, int skippable )
- {
- if( !w->in_frame )
- return -1;
- w->frame_tc = timestamp;
- w->keyframe = keyframe != 0;
- + w->skippable= skippable!= 0;
- if( w->max_frame_tc < timestamp )
- w->max_frame_tc = timestamp;
- diff --git a/output/matroska_ebml.h b/output/matroska_ebml.h
- index 252e781..56eb8cc 100644
- --- a/output/matroska_ebml.h
- +++ b/output/matroska_ebml.h
- @@ -35,7 +35,7 @@ int mk_writeHeader( mk_writer *w, const char *writing_app,
- int mk_start_frame( mk_writer *w );
- int mk_add_frame_data( mk_writer *w, const void *data, unsigned size );
- -int mk_set_frame_flags( mk_writer *w, int64_t timestamp, int keyframe );
- +int mk_set_frame_flags( mk_writer *w, int64_t timestamp, int keyframe, int skippable );
- int mk_close( mk_writer *w, int64_t last_delta );
- #endif
- --
- 1.6.6
- From cde64a308c2766b59fa34945eb0985b52bf774f5 Mon Sep 17 00:00:00 2001
- From: Alexander Strange <astrange@ithinksw.com>
- Date: Sat, 13 Feb 2010 02:00:57 -0500
- Subject: [PATCH 7/8] mkv: Write the x264 version into the file header.
- This only updates the "writing application"; matroska_ebml.c is the
- "muxing application", but the version string for that is still hardcoded.
- ---
- output/matroska.c | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
- diff --git a/output/matroska.c b/output/matroska.c
- index db7639c..b1805e4 100644
- --- a/output/matroska.c
- +++ b/output/matroska.c
- -146,7 +146,7 @@ static int write_headers( hnd_t handle, x264_nal_t *p_nal )
- memcpy( avcC+11+sps_size, pps, pps_size );
- - ret = mk_writeHeader( p_mkv->w, "x264", "V_MPEG4/ISO/AVC",
- + ret = mk_writeHeader( p_mkv->w, "x264" X264_VERSION, "V_MPEG4/ISO/AVC",
- avcC, avcC_len, p_mkv->frame_duration, 50000,
- p_mkv->width, p_mkv->height,
- p_mkv->d_width, p_mkv->d_height );
- --
- 1.6.6
- From efc3c57a0eb4c74bd31fd616078aa0077033af92 Mon Sep 17 00:00:00 2001
- From: Alexander Strange <astrange@ithinksw.com>
- Date: Sat, 13 Feb 2010 02:22:04 -0500
- Subject: [PATCH 8/8] Mark cli_input/output_t variables as const when possible.
- ---
- input/avs.c | 2 +-
- input/ffms.c | 2 +-
- input/input.h | 10 +++++-----
- input/lavf.c | 2 +-
- input/y4m.c | 2 +-
- input/yuv.c | 2 +-
- output/flv.c | 2 +-
- output/matroska.c | 2 +-
- output/mp4.c | 2 +-
- output/output.h | 8 ++++----
- output/raw.c | 2 +-
- 11 files changed, 18 insertions(+), 18 deletions(-)
- diff --git a/input/avs.c b/input/avs.c
- index 522f8fe..79b5c80 100644
- --- a/input/avs.c
- +++ b/input/avs.c
- -313,4 +313,4 @@ static int close_file( hnd_t handle )
- return 0;
- }
- -cli_input_t avs_input = { open_file, get_frame_total, picture_alloc, read_frame, release_frame, picture_clean, close_file };
- +const cli_input_t avs_input = { open_file, get_frame_total, picture_alloc, read_frame, release_frame, picture_clean, close_file };
- diff --git a/input/ffms.c b/input/ffms.c
- index b680967..14962c7 100644
- --- a/input/ffms.c
- +++ b/input/ffms.c
- -244,4 +244,4 @@ static int close_file( hnd_t handle )
- return 0;
- }
- -cli_input_t ffms_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };
- +const cli_input_t ffms_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };
- diff --git a/input/input.h b/input/input.h
- index 9fb425c..6e386f4 100644
- --- a/input/input.h
- +++ b/input/input.h
- -60,11 +60,11 @@ typedef struct
- int (*close_file)( hnd_t handle );
- } cli_input_t;
- -extern cli_input_t yuv_input;
- -extern cli_input_t y4m_input;
- -extern cli_input_t avs_input;
- +extern const cli_input_t yuv_input;
- +extern const cli_input_t y4m_input;
- +extern const cli_input_t avs_input;
- extern cli_input_t thread_input;
- -extern cli_input_t lavf_input;
- -extern cli_input_t ffms_input;
- +extern const cli_input_t lavf_input;
- +extern const cli_input_t ffms_input;
- #endif
- diff --git a/input/lavf.c b/input/lavf.c
- index 180e509..6ecc6b0 100644
- --- a/input/lavf.c
- +++ b/input/lavf.c
- -269,4 +269,4 @@ static int close_file( hnd_t handle )
- return 0;
- }
- -cli_input_t lavf_input = { open_file, get_frame_total, picture_alloc, read_frame, NULL, picture_clean, close_file };
- +const cli_input_t lavf_input = { open_file, get_frame_total, picture_alloc, read_frame, NULL, picture_clean, close_file };
- diff --git a/input/y4m.c b/input/y4m.c
- index 1619f74..8645ff7 100644
- --- a/input/y4m.c
- +++ b/input/y4m.c
- -242,4 +242,4 @@ static int close_file( hnd_t handle )
- return 0;
- }
- -cli_input_t y4m_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };
- +const cli_input_t y4m_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };
- diff --git a/input/yuv.c b/input/yuv.c
- index dbd0317..3e39e07 100644
- --- a/input/yuv.c
- +++ b/input/yuv.c
- -125,4 +125,4 @@ static int close_file( hnd_t handle )
- return 0;
- }
- -cli_input_t yuv_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };
- +const cli_input_t yuv_input = { open_file, get_frame_total, x264_picture_alloc, read_frame, NULL, x264_picture_clean, close_file };
- diff --git a/output/flv.c b/output/flv.c
- index b3e5d16..2e0a0e4 100644
- --- a/output/flv.c
- +++ b/output/flv.c
- -305,4 +305,4 @@ static int close_file( hnd_t handle, int64_t largest_pts, int64_t second_largest
- return 0;
- }
- -cli_output_t flv_output = { open_file, set_param, write_headers, write_frame, close_file };
- +const cli_output_t flv_output = { open_file, set_param, write_headers, write_frame, close_file };
- diff --git a/output/matroska.c b/output/matroska.c
- index b1805e4..fb39ced 100644
- --- a/output/matroska.c
- +++ b/output/matroska.c
- -206,4 +206,4 @@ static int close_file( hnd_t handle, int64_t largest_pts, int64_t second_largest
- return ret;
- }
- -cli_output_t mkv_output = { open_file, set_param, write_headers, write_frame, close_file };
- +const cli_output_t mkv_output = { open_file, set_param, write_headers, write_frame, close_file };
- diff --git a/output/mp4.c b/output/mp4.c
- index e3ad9c6..02c0b7d 100644
- --- a/output/mp4.c
- +++ b/output/mp4.c
- -297,4 +297,4 @@ static int write_frame( hnd_t handle, uint8_t *p_nalu, int i_size, x264_picture_
- return i_size;
- }
- -cli_output_t mp4_output = { open_file, set_param, write_headers, write_frame, close_file };
- +const cli_output_t mp4_output = { open_file, set_param, write_headers, write_frame, close_file };
- diff --git a/output/output.h b/output/output.h
- index 851b819..c79b48e 100644
- --- a/output/output.h
- +++ b/output/output.h
- -33,9 +33,9 @@ typedef struct
- int (*close_file)( hnd_t handle, int64_t largest_pts, int64_t second_largest_pts );
- } cli_output_t;
- -extern cli_output_t raw_output;
- -extern cli_output_t mkv_output;
- -extern cli_output_t mp4_output;
- -extern cli_output_t flv_output;
- +extern const cli_output_t raw_output;
- +extern const cli_output_t mkv_output;
- +extern const cli_output_t mp4_output;
- +extern const cli_output_t flv_output;
- #endif
- diff --git a/output/raw.c b/output/raw.c
- index a4d1175..02e4c56 100644
- --- a/output/raw.c
- +++ b/output/raw.c
- -62,5 +62,5 @@ static int close_file( hnd_t handle, int64_t largest_pts, int64_t second_largest
- return fclose( (FILE*)handle );
- }
- -cli_output_t raw_output = { open_file, set_param, write_headers, write_frame, close_file };
- +const cli_output_t raw_output = { open_file, set_param, write_headers, write_frame, close_file };
- --
- 1.6.6
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement