[x264-devel] [PATCH] set: fix transpose custom scaling lists
Nicolas Gaullier
nicolas.gaullier at arkena.com
Mon Sep 17 17:08:59 CEST 2018
x264_sps_init() may be called twice, resulting in a second call to transpose() which cancels the first one. This patch isolates input parameters from current scaling lists stored in x264_sps_t.
Fix AVC-Intra cqm_8iy scaling list in 1080i
---
common/set.h | 1 +
encoder/encoder.c | 14 ++++++++++++--
encoder/set.c | 47 +++++++++++++++++++++++++++++------------------
encoder/set.h | 2 +-
4 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/common/set.h b/common/set.h
index 32ea96ce..7f1e539a 100644
--- a/common/set.h
+++ b/common/set.h
@@ -143,6 +143,7 @@ typedef struct
int b_avcintra;
int i_cqm_preset;
const uint8_t *scaling_list[8]; /* could be 12, but we don't allow separate Cb/Cr lists */
+ int b_scaling_list_allocated;
} x264_sps_t;
diff --git a/encoder/encoder.c b/encoder/encoder.c
index 7316a586..e2e3a4c8 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -1194,7 +1194,8 @@ static int validate_parameters( x264_t *h, int b_open )
int maxrate_bak = h->param.rc.i_vbv_max_bitrate;
if( h->param.rc.i_rc_method == X264_RC_ABR && h->param.rc.i_vbv_buffer_size <= 0 )
h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate * 2;
- x264_sps_init( h->sps, h->param.i_sps_id, &h->param );
+ if (x264_sps_init( h->sps, h->param.i_sps_id, &h->param ))
+ return -1;
do h->param.i_level_idc = l->level_idc;
while( l[1].level_idc && x264_validate_levels( h, 0 ) && l++ );
h->param.rc.i_vbv_max_bitrate = maxrate_bak;
@@ -1507,7 +1508,8 @@ x264_t *x264_encoder_open( x264_param_t *param )
set_aspect_ratio( h, &h->param, 1 );
- x264_sps_init( h->sps, h->param.i_sps_id, &h->param );
+ if (x264_sps_init( h->sps, h->param.i_sps_id, &h->param ))
+ goto fail;
x264_pps_init( h->pps, h->param.i_sps_id, &h->param, h->sps );
x264_validate_levels( h, 1 );
@@ -4468,6 +4470,14 @@ void x264_encoder_close ( x264_t *h )
#if HAVE_OPENCL
x264_opencl_close_library( ocl );
#endif
+
+ /* set */
+ if (h->sps->b_scaling_list_allocated)
+ {
+ for( int i = 0; i < 8; i++ )
+ x264_free((void *)h->sps->scaling_list[i]);
+ h->sps->b_scaling_list_allocated = 0;
+ }
}
int x264_encoder_delayed_frames( x264_t *h )
diff --git a/encoder/set.c b/encoder/set.c
index da4a8a10..8ed426a6 100644
--- a/encoder/set.c
+++ b/encoder/set.c
@@ -98,9 +98,20 @@ void x264_sei_write( bs_t *s, uint8_t *payload, int payload_size, int payload_ty
bs_flush( s );
}
-void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
+int x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
{
int csp = param->i_csp & X264_CSP_MASK;
+ uint8_t *param_cqms[8] = {
+ param->cqm_4iy,
+ param->cqm_4py,
+ param->cqm_4ic,
+ param->cqm_4pc,
+ param->cqm_8iy,
+ param->cqm_8py,
+ param->cqm_8ic,
+ param->cqm_8pc
+ };
+
sps->i_id = i_id;
sps->i_mb_width = ( param->i_width + 15 ) / 16;
@@ -255,29 +266,29 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
sps->scaling_list[i] = x264_cqm_jvt[i];
break;
case X264_CQM_CUSTOM:
- /* match the transposed DCT & zigzag */
- transpose( param->cqm_4iy, 4 );
- transpose( param->cqm_4py, 4 );
- transpose( param->cqm_4ic, 4 );
- transpose( param->cqm_4pc, 4 );
- transpose( param->cqm_8iy, 8 );
- transpose( param->cqm_8py, 8 );
- transpose( param->cqm_8ic, 8 );
- transpose( param->cqm_8pc, 8 );
- sps->scaling_list[CQM_4IY] = param->cqm_4iy;
- sps->scaling_list[CQM_4PY] = param->cqm_4py;
- sps->scaling_list[CQM_4IC] = param->cqm_4ic;
- sps->scaling_list[CQM_4PC] = param->cqm_4pc;
- sps->scaling_list[CQM_8IY+4] = param->cqm_8iy;
- sps->scaling_list[CQM_8PY+4] = param->cqm_8py;
- sps->scaling_list[CQM_8IC+4] = param->cqm_8ic;
- sps->scaling_list[CQM_8PC+4] = param->cqm_8pc;
+ if (sps->b_scaling_list_allocated)
+ for( int i = 0; i < 8; i++ )
+ x264_free((void*)sps->scaling_list[i]);
+ else
+ sps->b_scaling_list_allocated = 1;
+ for( int i = 0; i < 8; i++ )
+ {
+ uint8_t *new_scaling_list;
+ CHECKED_MALLOC( new_scaling_list, i < 4 ? 16 : 64 );
+ memcpy(new_scaling_list, param_cqms[i], i < 4 ? 16 : 64);
+ /* match the transposed DCT & zigzag */
+ transpose( new_scaling_list, i < 4 ? 4 : 8);
+ sps->scaling_list[i] = new_scaling_list;
+ }
for( int i = 0; i < 8; i++ )
for( int j = 0; j < (i < 4 ? 16 : 64); j++ )
if( sps->scaling_list[i][j] == 0 )
sps->scaling_list[i] = x264_cqm_jvt[i];
break;
}
+ return 0;
+fail:
+ return -1;
}
void x264_sps_init_reconfigurable( x264_sps_t *sps, x264_param_t *param )
diff --git a/encoder/set.h b/encoder/set.h
index bd0c4d7b..1217475b 100644
--- a/encoder/set.h
+++ b/encoder/set.h
@@ -28,7 +28,7 @@
#define X264_ENCODER_SET_H
#define x264_sps_init x264_template(sps_init)
-void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param );
+int x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param );
#define x264_sps_init_reconfigurable x264_template(sps_init_reconfigurable)
void x264_sps_init_reconfigurable( x264_sps_t *sps, x264_param_t *param );
#define x264_sps_write x264_template(sps_write)
--
2.14.1.windows.1
More information about the x264-devel
mailing list