2014-01-24 10:37:15 +00:00
/*****************************************************************************
* This file is part of Kvazaar HEVC encoder .
2014-02-21 13:00:20 +00:00
*
2015-02-23 11:18:48 +00:00
* Copyright ( C ) 2013 - 2015 Tampere University of Technology and others ( see
2014-01-24 10:37:15 +00:00
* COPYING file ) .
*
2015-02-23 11:18:48 +00:00
* Kvazaar is free software : you can redistribute it and / or modify it under
* the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation ; either version 2.1 of the License , or ( at your
* option ) any later version .
2014-01-24 10:37:15 +00:00
*
2015-02-23 11:18:48 +00:00
* Kvazaar is distributed in the hope that it will be useful , but WITHOUT ANY
* WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE . See the GNU Lesser General Public License for
* more details .
2014-01-24 10:37:15 +00:00
*
2015-02-23 11:18:48 +00:00
* You should have received a copy of the GNU General Public License along
* with Kvazaar . If not , see < http : //www.gnu.org/licenses/>.
2014-01-24 10:37:15 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-01-25 10:08:27 +00:00
# include "cfg.h"
2013-09-18 09:16:03 +00:00
2012-05-30 12:10:23 +00:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
2016-04-01 14:14:23 +00:00
2015-08-26 08:50:27 +00:00
kvz_config * kvz_config_alloc ( void )
2012-05-30 12:10:23 +00:00
{
2015-06-30 08:03:26 +00:00
kvz_config * cfg = ( kvz_config * ) malloc ( sizeof ( kvz_config ) ) ;
2014-01-31 15:30:27 +00:00
if ( ! cfg ) {
fprintf ( stderr , " Failed to allocate a config object! \n " ) ;
return cfg ;
}
2015-02-13 09:56:55 +00:00
FILL ( * cfg , 0 ) ;
2012-05-30 12:10:23 +00:00
return cfg ;
}
2015-08-26 08:50:27 +00:00
int kvz_config_init ( kvz_config * cfg )
2014-02-21 13:00:20 +00:00
{
2014-03-10 13:53:23 +00:00
cfg - > width = 0 ;
cfg - > height = 0 ;
2016-01-14 20:08:35 +00:00
cfg - > framerate = 25 ; // deprecated and will be removed.
cfg - > framerate_num = 0 ;
cfg - > framerate_denom = 1 ;
2016-09-27 21:15:46 +00:00
cfg - > qp = 22 ;
cfg - > intra_period = 64 ;
2015-02-18 11:41:03 +00:00
cfg - > vps_period = 0 ;
2014-02-06 19:45:37 +00:00
cfg - > deblock_enable = 1 ;
cfg - > deblock_beta = 0 ;
cfg - > deblock_tc = 0 ;
cfg - > sao_enable = 1 ;
2014-03-05 14:56:00 +00:00
cfg - > rdoq_enable = 1 ;
2016-09-27 21:19:30 +00:00
cfg - > rdoq_skip = 1 ;
2015-01-24 18:10:21 +00:00
cfg - > signhide_enable = true ;
2015-12-15 05:57:38 +00:00
cfg - > smp_enable = false ;
2015-12-01 12:37:58 +00:00
cfg - > amp_enable = false ;
2014-04-07 11:36:01 +00:00
cfg - > rdo = 1 ;
2015-11-05 11:59:30 +00:00
cfg - > mv_rdo = 0 ;
2014-06-17 12:32:05 +00:00
cfg - > full_intra_search = 0 ;
2016-09-27 21:19:30 +00:00
cfg - > trskip_enable = 0 ;
2014-05-30 14:19:41 +00:00
cfg - > tr_depth_intra = 0 ;
2015-03-19 16:48:10 +00:00
cfg - > ime_algorithm = 0 ; /* hexbs */
2016-07-12 12:39:01 +00:00
cfg - > fme_level = 4 ;
2015-08-13 09:53:14 +00:00
cfg - > source_scan_type = 0 ; /* progressive */
2014-02-06 19:45:37 +00:00
cfg - > vui . sar_width = 0 ;
cfg - > vui . sar_height = 0 ;
cfg - > vui . overscan = 0 ; /* undef */
cfg - > vui . videoformat = 5 ; /* undef */
cfg - > vui . fullrange = 0 ; /* limited range */
cfg - > vui . colorprim = 2 ; /* undef */
cfg - > vui . transfer = 2 ; /* undef */
cfg - > vui . colormatrix = 2 ; /* undef */
cfg - > vui . chroma_loc = 0 ; /* left center */
2014-02-06 22:35:15 +00:00
cfg - > aud_enable = 0 ;
config: Add --cqmfile to use custom quantization matrices from a file.
The coefficients in a matrix are stored in up-right diagonal order.
The following indicates the default matrices specified in the spec.
INTRA4X4_LUMA
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16
INTRA4X4_CHROMAU
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16
INTRA4X4_CHROMAV
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16
INTER4X4_LUMA
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16
INTER4X4_CHROMAU
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16
INTER4X4_CHROMAV
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16,
16, 16, 16, 16
INTRA8X8_LUMA
16, 16, 16, 16, 17, 18, 21, 24,
16, 16, 16, 16, 17, 19, 22, 25,
16, 16, 17, 18, 20, 22, 25, 29,
16, 16, 18, 21, 24, 27, 31, 36,
17, 17, 20, 24, 30, 35, 41, 47,
18, 19, 22, 27, 35, 44, 54, 65,
21, 22, 25, 31, 41, 54, 70, 88,
24, 25, 29, 36, 47, 65, 88, 115
INTRA8X8_CHROMAU
16, 16, 16, 16, 17, 18, 21, 24,
16, 16, 16, 16, 17, 19, 22, 25,
16, 16, 17, 18, 20, 22, 25, 29,
16, 16, 18, 21, 24, 27, 31, 36,
17, 17, 20, 24, 30, 35, 41, 47,
18, 19, 22, 27, 35, 44, 54, 65,
21, 22, 25, 31, 41, 54, 70, 88,
24, 25, 29, 36, 47, 65, 88, 115
INTRA8X8_CHROMAV
16, 16, 16, 16, 17, 18, 21, 24,
16, 16, 16, 16, 17, 19, 22, 25,
16, 16, 17, 18, 20, 22, 25, 29,
16, 16, 18, 21, 24, 27, 31, 36,
17, 17, 20, 24, 30, 35, 41, 47,
18, 19, 22, 27, 35, 44, 54, 65,
21, 22, 25, 31, 41, 54, 70, 88,
24, 25, 29, 36, 47, 65, 88, 115
INTER8X8_LUMA
16, 16, 16, 16, 17, 18, 20, 24,
16, 16, 16, 17, 18, 20, 24, 25,
16, 16, 17, 18, 20, 24, 25, 28,
16, 17, 18, 20, 24, 25, 28, 33,
17, 18, 20, 24, 25, 28, 33, 41,
18, 20, 24, 25, 28, 33, 41, 54,
20, 24, 25, 28, 33, 41, 54, 71,
24, 25, 28, 33, 41, 54, 71, 91
INTER8X8_CHROMAU
16, 16, 16, 16, 17, 18, 20, 24,
16, 16, 16, 17, 18, 20, 24, 25,
16, 16, 17, 18, 20, 24, 25, 28,
16, 17, 18, 20, 24, 25, 28, 33,
17, 18, 20, 24, 25, 28, 33, 41,
18, 20, 24, 25, 28, 33, 41, 54,
20, 24, 25, 28, 33, 41, 54, 71,
24, 25, 28, 33, 41, 54, 71, 91
INTER8X8_CHROMAV
16, 16, 16, 16, 17, 18, 20, 24,
16, 16, 16, 17, 18, 20, 24, 25,
16, 16, 17, 18, 20, 24, 25, 28,
16, 17, 18, 20, 24, 25, 28, 33,
17, 18, 20, 24, 25, 28, 33, 41,
18, 20, 24, 25, 28, 33, 41, 54,
20, 24, 25, 28, 33, 41, 54, 71,
24, 25, 28, 33, 41, 54, 71, 91
INTRA16X16_LUMA
16, 16, 16, 16, 17, 18, 21, 24,
16, 16, 16, 16, 17, 19, 22, 25,
16, 16, 17, 18, 20, 22, 25, 29,
16, 16, 18, 21, 24, 27, 31, 36,
17, 17, 20, 24, 30, 35, 41, 47,
18, 19, 22, 27, 35, 44, 54, 65,
21, 22, 25, 31, 41, 54, 70, 88,
24, 25, 29, 36, 47, 65, 88, 115
INTRA16X16_CHROMAU
16, 16, 16, 16, 17, 18, 21, 24,
16, 16, 16, 16, 17, 19, 22, 25,
16, 16, 17, 18, 20, 22, 25, 29,
16, 16, 18, 21, 24, 27, 31, 36,
17, 17, 20, 24, 30, 35, 41, 47,
18, 19, 22, 27, 35, 44, 54, 65,
21, 22, 25, 31, 41, 54, 70, 88,
24, 25, 29, 36, 47, 65, 88, 115
INTRA16X16_CHROMAV
16, 16, 16, 16, 17, 18, 21, 24,
16, 16, 16, 16, 17, 19, 22, 25,
16, 16, 17, 18, 20, 22, 25, 29,
16, 16, 18, 21, 24, 27, 31, 36,
17, 17, 20, 24, 30, 35, 41, 47,
18, 19, 22, 27, 35, 44, 54, 65,
21, 22, 25, 31, 41, 54, 70, 88,
24, 25, 29, 36, 47, 65, 88, 115
INTER16X16_LUMA
16, 16, 16, 16, 17, 18, 20, 24,
16, 16, 16, 17, 18, 20, 24, 25,
16, 16, 17, 18, 20, 24, 25, 28,
16, 17, 18, 20, 24, 25, 28, 33,
17, 18, 20, 24, 25, 28, 33, 41,
18, 20, 24, 25, 28, 33, 41, 54,
20, 24, 25, 28, 33, 41, 54, 71,
24, 25, 28, 33, 41, 54, 71, 91
INTER16X16_CHROMAU
16, 16, 16, 16, 17, 18, 20, 24,
16, 16, 16, 17, 18, 20, 24, 25,
16, 16, 17, 18, 20, 24, 25, 28,
16, 17, 18, 20, 24, 25, 28, 33,
17, 18, 20, 24, 25, 28, 33, 41,
18, 20, 24, 25, 28, 33, 41, 54,
20, 24, 25, 28, 33, 41, 54, 71,
24, 25, 28, 33, 41, 54, 71, 91
INTER16X16_CHROMAV
16, 16, 16, 16, 17, 18, 20, 24,
16, 16, 16, 17, 18, 20, 24, 25,
16, 16, 17, 18, 20, 24, 25, 28,
16, 17, 18, 20, 24, 25, 28, 33,
17, 18, 20, 24, 25, 28, 33, 41,
18, 20, 24, 25, 28, 33, 41, 54,
20, 24, 25, 28, 33, 41, 54, 71,
24, 25, 28, 33, 41, 54, 71, 91
INTRA32X32_LUMA
16, 16, 16, 16, 17, 18, 21, 24,
16, 16, 16, 16, 17, 19, 22, 25,
16, 16, 17, 18, 20, 22, 25, 29,
16, 16, 18, 21, 24, 27, 31, 36,
17, 17, 20, 24, 30, 35, 41, 47,
18, 19, 22, 27, 35, 44, 54, 65,
21, 22, 25, 31, 41, 54, 70, 88,
24, 25, 29, 36, 47, 65, 88, 115
INTER32X32_LUMA
16, 16, 16, 16, 17, 18, 20, 24,
16, 16, 16, 17, 18, 20, 24, 25,
16, 16, 17, 18, 20, 24, 25, 28,
16, 17, 18, 20, 24, 25, 28, 33,
17, 18, 20, 24, 25, 28, 33, 41,
18, 20, 24, 25, 28, 33, 41, 54,
20, 24, 25, 28, 33, 41, 54, 71,
24, 25, 28, 33, 41, 54, 71, 91
INTRA16X16_LUMA_DC
16
INTRA16X16_CHROMAU_DC
16
INTRA16X16_CHROMAV_DC
16
INTER16X16_LUMA_DC
16
INTER16X16_CHROMAU_DC
16
INTER16X16_CHROMAV_DC
16
INTRA32X32_LUMA_DC
16
INTER32X32_LUMA_DC
16
2014-02-11 10:55:21 +00:00
cfg - > cqmfile = NULL ;
2014-02-19 13:09:17 +00:00
cfg - > ref_frames = DEFAULT_REF_PIC_COUNT ;
2016-09-27 21:15:46 +00:00
cfg - > gop_len = 4 ;
cfg - > gop_lowdelay = true ;
2015-04-21 11:18:34 +00:00
cfg - > bipred = 0 ;
2015-03-13 14:31:00 +00:00
cfg - > target_bitrate = 0 ;
2016-03-17 15:00:43 +00:00
cfg - > hash = KVZ_HASH_CHECKSUM ;
2016-05-26 07:38:45 +00:00
cfg - > lossless = false ;
2016-08-10 08:58:15 +00:00
cfg - > tmvp_enable = true ;
2016-08-03 05:18:56 +00:00
cfg - > implicit_rdpcm = false ;
2012-05-30 12:10:23 +00:00
2016-05-10 11:15:41 +00:00
cfg - > cu_split_termination = KVZ_CU_SPLIT_TERMINATION_ZERO ;
2016-03-07 15:21:40 +00:00
cfg - > tiles_width_count = 1 ;
cfg - > tiles_height_count = 1 ;
cfg - > tiles_width_split = NULL ;
cfg - > tiles_height_split = NULL ;
2014-05-05 13:17:22 +00:00
2016-09-27 19:55:12 +00:00
cfg - > wpp = 1 ;
2014-12-05 13:21:46 +00:00
cfg - > owf = - 1 ;
2014-05-05 13:17:22 +00:00
cfg - > slice_count = 1 ;
cfg - > slice_addresses_in_ts = MALLOC ( int32_t , 1 ) ;
cfg - > slice_addresses_in_ts [ 0 ] = 0 ;
2016-09-28 20:05:21 +00:00
cfg - > threads = - 1 ;
2014-10-14 09:01:56 +00:00
cfg - > cpuid = 1 ;
2014-04-02 08:38:03 +00:00
2015-01-09 10:04:23 +00:00
// Defaults for what sizes of PUs are tried.
2016-09-27 21:19:30 +00:00
cfg - > pu_depth_inter . min = 2 ; // 0-3
2015-01-09 10:04:23 +00:00
cfg - > pu_depth_inter . max = 3 ; // 0-3
2016-09-27 21:19:30 +00:00
cfg - > pu_depth_intra . min = 2 ; // 0-4
2016-09-27 21:15:46 +00:00
cfg - > pu_depth_intra . max = 3 ; // 0-4
2015-01-09 10:04:23 +00:00
2015-04-16 14:17:17 +00:00
cfg - > add_encoder_info = true ;
2016-01-21 13:08:34 +00:00
cfg - > calc_psnr = true ;
2015-04-16 14:17:17 +00:00
2016-02-24 10:39:03 +00:00
cfg - > mv_constraint = KVZ_MV_CONSTRAIN_NONE ;
2016-06-07 07:55:26 +00:00
cfg - > crypto_features = KVZ_CRYPTO_OFF ;
2016-02-24 10:39:03 +00:00
2016-09-27 21:19:30 +00:00
cfg - > me_early_termination = 1 ;
2016-08-17 07:07:40 +00:00
2016-08-16 16:03:21 +00:00
cfg - > input_format = KVZ_FORMAT_P420 ;
cfg - > input_bitdepth = 8 ;
2016-09-27 21:15:46 +00:00
cfg - > gop_lp_definition . d = 3 ;
cfg - > gop_lp_definition . t = 1 ;
2016-09-27 19:12:02 +00:00
2012-05-30 12:10:23 +00:00
return 1 ;
}
2015-08-26 08:50:27 +00:00
int kvz_config_destroy ( kvz_config * cfg )
2012-05-30 12:10:23 +00:00
{
2015-08-25 09:46:19 +00:00
if ( cfg ) {
FREE_POINTER ( cfg - > cqmfile ) ;
FREE_POINTER ( cfg - > tiles_width_split ) ;
FREE_POINTER ( cfg - > tiles_height_split ) ;
FREE_POINTER ( cfg - > slice_addresses_in_ts ) ;
}
2012-05-30 12:10:23 +00:00
free ( cfg ) ;
return 1 ;
}
2014-02-03 22:16:42 +00:00
static int atobool ( const char * str )
{
if ( ! strcmp ( str , " 1 " ) | |
! strcmp ( str , " true " ) | |
! strcmp ( str , " yes " ) )
return 1 ;
if ( ! strcmp ( str , " 0 " ) | |
! strcmp ( str , " false " ) | |
! strcmp ( str , " no " ) )
return 0 ;
return 0 ;
}
2016-06-07 07:55:26 +00:00
static int parse_enum_n ( const char * arg , unsigned num_chars , const char * const * names , int8_t * dst )
2014-02-06 19:45:37 +00:00
{
2014-02-21 13:15:59 +00:00
int8_t i ;
for ( i = 0 ; names [ i ] ; i + + ) {
2016-06-07 07:55:26 +00:00
if ( ! strncmp ( arg , names [ i ] , num_chars ) ) {
2014-02-06 19:45:37 +00:00
* dst = i ;
return 1 ;
}
2014-02-21 13:15:59 +00:00
}
2014-02-06 19:45:37 +00:00
return 0 ;
}
2016-06-07 07:55:26 +00:00
static int parse_enum ( const char * arg , const char * const * names , int8_t * dst )
{
return parse_enum_n ( arg , 255 , names , dst ) ;
}
2014-04-02 08:38:03 +00:00
static int parse_tiles_specification ( const char * const arg , int32_t * const ntiles , int32_t * * const array ) {
const char * current_arg = NULL ;
int32_t current_value ;
2014-05-05 13:17:52 +00:00
int32_t values [ MAX_TILES_PER_DIM ] ;
2014-04-02 08:38:03 +00:00
int i ;
//Free pointer in any case
if ( * array ) {
FREE_POINTER ( * array ) ;
}
//If the arg starts with u, we want an uniform split
if ( arg [ 0 ] = = ' u ' ) {
2016-03-07 15:21:40 +00:00
* ntiles = atoi ( arg + 1 ) ;
if ( MAX_TILES_PER_DIM < = * ntiles | | 1 > = * ntiles ) {
fprintf ( stderr , " Invalid number of tiles (1 <= %d <= %d = MAX_TILES_PER_DIM)! \n " , * ntiles , MAX_TILES_PER_DIM ) ;
2014-04-02 08:38:03 +00:00
return 0 ;
}
//Done with parsing
return 1 ;
}
//We have a comma-separated list of int for the split...
current_arg = arg ;
2016-03-07 15:21:40 +00:00
* ntiles = 1 ;
2014-04-02 08:38:03 +00:00
do {
int ret = sscanf ( current_arg , " %d " , & current_value ) ;
if ( ret ! = 1 ) {
fprintf ( stderr , " Could not parse integer \" %s \" ! \n " , current_arg ) ;
return 0 ;
}
current_arg = strchr ( current_arg , ' , ' ) ;
//Skip the , if we found one
if ( current_arg ) + + current_arg ;
2016-03-07 15:21:40 +00:00
values [ * ntiles - 1 ] = current_value ;
2014-04-02 08:38:03 +00:00
+ + ( * ntiles ) ;
2014-05-05 13:17:52 +00:00
if ( MAX_TILES_PER_DIM < = * ntiles ) break ;
2014-04-02 08:38:03 +00:00
} while ( current_arg ) ;
2016-03-07 15:21:40 +00:00
if ( MAX_TILES_PER_DIM < = * ntiles | | 1 > = * ntiles ) {
fprintf ( stderr , " Invalid number of tiles (1 <= %d <= %d = MAX_TILES_PER_DIM)! \n " , * ntiles , MAX_TILES_PER_DIM ) ;
2014-04-02 08:38:03 +00:00
return 0 ;
}
2016-03-07 15:21:40 +00:00
* array = MALLOC ( int32_t , * ntiles - 1 ) ;
2014-04-02 08:38:03 +00:00
if ( ! * array ) {
fprintf ( stderr , " Could not allocate array for tiles \n " ) ;
return 0 ;
}
//TODO: memcpy?
2016-03-07 15:21:40 +00:00
for ( i = 0 ; i < * ntiles - 1 ; + + i ) {
2014-04-02 08:38:03 +00:00
( * array ) [ i ] = values [ i ] ;
}
return 1 ;
}
2014-05-05 13:17:22 +00:00
static int parse_slice_specification ( const char * const arg , int32_t * const nslices , int32_t * * const array ) {
const char * current_arg = NULL ;
int32_t current_value ;
int32_t values [ MAX_SLICES ] ;
int i ;
//Free pointer in any case
if ( * array ) {
FREE_POINTER ( * array ) ;
}
//If the arg starts with u, we want an uniform split
if ( arg [ 0 ] = = ' u ' ) {
* nslices = atoi ( arg + 1 ) ;
if ( MAX_SLICES < = * nslices | | 0 > = * nslices ) {
fprintf ( stderr , " Invalid number of tiles (0 < %d <= %d = MAX_SLICES)! \n " , * nslices + 1 , MAX_SLICES ) ;
return 0 ;
}
//Done with parsing
return 1 ;
}
//We have a comma-separated list of int for the split...
current_arg = arg ;
//We always have a slice starting at 0
values [ 0 ] = 0 ;
* nslices = 1 ;
do {
int ret = sscanf ( current_arg , " %d " , & current_value ) ;
if ( ret ! = 1 ) {
fprintf ( stderr , " Could not parse integer \" %s \" ! \n " , current_arg ) ;
return 0 ;
}
current_arg = strchr ( current_arg , ' , ' ) ;
//Skip the , if we found one
if ( current_arg ) + + current_arg ;
values [ * nslices ] = current_value ;
+ + ( * nslices ) ;
if ( MAX_SLICES < = * nslices ) break ;
} while ( current_arg ) ;
if ( MAX_SLICES < = * nslices | | 0 > = * nslices ) {
fprintf ( stderr , " Invalid number of slices (0 < %d <= %d = MAX_SLICES)! \n " , * nslices , MAX_SLICES ) ;
return 0 ;
}
* array = MALLOC ( int32_t , * nslices ) ;
if ( ! * array ) {
fprintf ( stderr , " Could not allocate array for slices \n " ) ;
return 0 ;
}
//TODO: memcpy?
for ( i = 0 ; i < * nslices ; + + i ) {
( * array ) [ i ] = values [ i ] ;
}
return 1 ;
}
2015-08-26 08:50:27 +00:00
int kvz_config_parse ( kvz_config * cfg , const char * name , const char * value )
2014-02-03 20:58:23 +00:00
{
2016-04-21 12:11:35 +00:00
static const char * const me_names [ ] = { " hexbs " , " tz " , " full " , " full8 " , " full16 " , " full32 " , " full64 " , NULL } ;
2015-08-13 09:53:14 +00:00
static const char * const source_scan_type_names [ ] = { " progressive " , " tff " , " bff " , NULL } ;
2015-03-19 16:48:10 +00:00
2014-02-06 19:45:37 +00:00
static const char * const overscan_names [ ] = { " undef " , " show " , " crop " , NULL } ;
static const char * const videoformat_names [ ] = { " component " , " pal " , " ntsc " , " secam " , " mac " , " undef " , NULL } ;
2014-02-08 02:29:50 +00:00
static const char * const range_names [ ] = { " tv " , " pc " , NULL } ;
2014-02-06 19:45:37 +00:00
static const char * const colorprim_names [ ] = { " " , " bt709 " , " undef " , " " , " bt470m " , " bt470bg " , " smpte170m " ,
" smpte240m " , " film " , " bt2020 " , NULL } ;
static const char * const transfer_names [ ] = { " " , " bt709 " , " undef " , " " , " bt470m " , " bt470bg " , " smpte170m " ,
" smpte240m " , " linear " , " log100 " , " log316 " , " iec61966-2-4 " ,
" bt1361e " , " iec61966-2-1 " , " bt2020-10 " , " bt2020-12 " , NULL } ;
static const char * const colormatrix_names [ ] = { " GBR " , " bt709 " , " undef " , " " , " fcc " , " bt470bg " , " smpte170m " ,
" smpte240m " , " YCgCo " , " bt2020nc " , " bt2020c " , NULL } ;
2016-02-29 16:39:21 +00:00
static const char * const mv_constraint_names [ ] = { " none " , " frame " , " tile " , " frametile " , " frametilemargin " , NULL } ;
2016-03-17 15:00:43 +00:00
static const char * const hash_names [ ] = { " none " , " checksum " , " md5 " , NULL } ;
2014-02-06 19:45:37 +00:00
2016-05-10 11:15:41 +00:00
static const char * const cu_split_termination_names [ ] = { " zero " , " off " , NULL } ;
2016-06-07 07:55:26 +00:00
static const char * const crypto_toggle_names [ ] = { " off " , " on " , NULL } ;
2016-06-07 08:54:26 +00:00
static const char * const crypto_feature_names [ ] = { " mvs " , " mv_signs " , " trans_coeffs " , " trans_coeff_signs " , NULL } ;
2016-05-10 11:15:41 +00:00
2016-06-06 12:47:31 +00:00
static const char * const me_early_termination_names [ ] = { " off " , " on " , " sensitive " , NULL } ;
2016-09-29 12:44:12 +00:00
static const char * const preset_values [ 11 ] [ 20 * 2 ] = {
2015-11-03 13:26:34 +00:00
{
" ultrafast " ,
" pu-depth-intra " , " 2-3 " ,
2016-09-27 21:02:27 +00:00
" pu-depth-inter " , " 2-3 " ,
2015-11-03 13:26:34 +00:00
" rd " , " 0 " ,
" me " , " hexbs " ,
" ref " , " 1 " ,
2016-09-27 21:02:27 +00:00
" deblock " , " 0:0 " ,
2015-11-03 13:26:34 +00:00
" signhide " , " 0 " ,
" subme " , " 0 " ,
" sao " , " 0 " ,
" rdoq " , " 0 " ,
2016-09-27 21:02:27 +00:00
" rdoq-skip " , " 1 " ,
2015-11-03 13:26:34 +00:00
" transform-skip " , " 0 " ,
" full-intra-search " , " 0 " ,
2015-11-05 11:59:30 +00:00
" mv-rdo " , " 0 " ,
2016-05-17 11:26:58 +00:00
" smp " , " 0 " ,
" amp " , " 0 " ,
2016-09-27 21:02:27 +00:00
" cu-split-termination " , " zero " ,
" me-early-termination " , " sensitive " ,
2016-09-29 12:44:12 +00:00
" gop " , " lp-g4d3t1 " ,
2015-11-03 13:26:34 +00:00
NULL
} ,
{
" superfast " ,
2016-09-27 21:02:27 +00:00
" pu-depth-intra " , " 2-3 " ,
" pu-depth-inter " , " 2-3 " ,
" rd " , " 0 " ,
2015-11-03 13:26:34 +00:00
" me " , " hexbs " ,
" ref " , " 1 " ,
2016-09-27 21:02:27 +00:00
" deblock " , " 0:0 " ,
2015-11-03 13:26:34 +00:00
" signhide " , " 0 " ,
" subme " , " 0 " ,
2016-09-27 21:02:27 +00:00
" sao " , " 1 " ,
2015-11-03 13:26:34 +00:00
" rdoq " , " 0 " ,
2016-09-27 21:02:27 +00:00
" rdoq-skip " , " 1 " ,
2015-11-03 13:26:34 +00:00
" transform-skip " , " 0 " ,
" full-intra-search " , " 0 " ,
2015-11-05 11:59:30 +00:00
" mv-rdo " , " 0 " ,
2016-05-17 11:26:58 +00:00
" smp " , " 0 " ,
" amp " , " 0 " ,
2016-09-27 21:02:27 +00:00
" cu-split-termination " , " zero " ,
" me-early-termination " , " sensitive " ,
2016-09-29 12:44:12 +00:00
" gop " , " lp-g4d3t1 " ,
2015-11-03 13:26:34 +00:00
NULL
} ,
{
" veryfast " ,
2016-09-27 21:02:27 +00:00
" pu-depth-intra " , " 2-3 " ,
" pu-depth-inter " , " 2-3 " ,
" rd " , " 0 " ,
2015-11-03 13:26:34 +00:00
" me " , " hexbs " ,
2016-09-27 21:02:27 +00:00
" ref " , " 1 " ,
" deblock " , " 0:0 " ,
2015-11-03 13:26:34 +00:00
" signhide " , " 0 " ,
2016-09-27 21:02:27 +00:00
" subme " , " 2 " ,
" sao " , " 1 " ,
2015-11-03 13:26:34 +00:00
" rdoq " , " 0 " ,
2016-09-27 21:02:27 +00:00
" rdoq-skip " , " 1 " ,
2015-11-03 13:26:34 +00:00
" transform-skip " , " 0 " ,
" full-intra-search " , " 0 " ,
2015-11-05 11:59:30 +00:00
" mv-rdo " , " 0 " ,
2016-05-17 11:26:58 +00:00
" smp " , " 0 " ,
" amp " , " 0 " ,
2016-09-27 21:02:27 +00:00
" cu-split-termination " , " zero " ,
" me-early-termination " , " sensitive " ,
2016-09-29 12:44:12 +00:00
" gop " , " lp-g4d3t1 " ,
2015-11-03 13:26:34 +00:00
NULL
} ,
{
" faster " ,
2016-09-27 21:02:27 +00:00
" pu-depth-intra " , " 2-3 " ,
" pu-depth-inter " , " 1-3 " ,
2015-11-03 13:26:34 +00:00
" rd " , " 1 " ,
" me " , " hexbs " ,
2016-09-27 21:02:27 +00:00
" ref " , " 1 " ,
" deblock " , " 0:0 " ,
" signhide " , " 0 " ,
" subme " , " 2 " ,
" sao " , " 1 " ,
2015-11-03 13:26:34 +00:00
" rdoq " , " 0 " ,
2016-09-27 21:02:27 +00:00
" rdoq-skip " , " 1 " ,
2015-11-03 13:26:34 +00:00
" transform-skip " , " 0 " ,
" full-intra-search " , " 0 " ,
2015-11-05 11:59:30 +00:00
" mv-rdo " , " 0 " ,
2016-05-17 11:26:58 +00:00
" smp " , " 0 " ,
" amp " , " 0 " ,
2016-09-27 21:02:27 +00:00
" cu-split-termination " , " zero " ,
" me-early-termination " , " sensitive " ,
2016-09-29 12:44:12 +00:00
" gop " , " lp-g4d3t1 " ,
2015-11-03 13:26:34 +00:00
NULL
} ,
{
" fast " ,
2016-09-27 21:02:27 +00:00
" pu-depth-intra " , " 2-3 " ,
" pu-depth-inter " , " 1-3 " ,
2015-11-03 13:26:34 +00:00
" rd " , " 1 " ,
" me " , " hexbs " ,
2016-09-27 21:02:27 +00:00
" ref " , " 1 " ,
" deblock " , " 0:0 " ,
" signhide " , " 0 " ,
2016-07-12 12:39:01 +00:00
" subme " , " 4 " ,
2016-09-27 21:02:27 +00:00
" sao " , " 1 " ,
2016-09-29 12:44:12 +00:00
" rdoq " , " 0 " ,
2016-09-27 21:02:27 +00:00
" rdoq-skip " , " 1 " ,
2015-11-03 13:26:34 +00:00
" transform-skip " , " 0 " ,
" full-intra-search " , " 0 " ,
2015-11-05 11:59:30 +00:00
" mv-rdo " , " 0 " ,
2016-05-17 11:26:58 +00:00
" smp " , " 0 " ,
" amp " , " 0 " ,
2016-09-27 21:02:27 +00:00
" cu-split-termination " , " zero " ,
" me-early-termination " , " on " ,
2016-09-29 12:44:12 +00:00
" gop " , " lp-g4d3t1 " ,
2015-11-03 13:26:34 +00:00
NULL
} ,
{
" medium " ,
2016-09-27 21:02:27 +00:00
" pu-depth-intra " , " 1-3 " ,
" pu-depth-inter " , " 1-3 " ,
2015-11-03 13:26:34 +00:00
" rd " , " 1 " ,
" me " , " hexbs " ,
2016-09-27 21:02:27 +00:00
" ref " , " 1 " ,
" deblock " , " 0:0 " ,
2016-09-29 12:44:12 +00:00
" signhide " , " 0 " ,
2016-07-12 12:39:01 +00:00
" subme " , " 4 " ,
2016-09-27 21:02:27 +00:00
" sao " , " 1 " ,
" rdoq " , " 1 " ,
" rdoq-skip " , " 1 " ,
2015-11-03 13:26:34 +00:00
" transform-skip " , " 0 " ,
" full-intra-search " , " 0 " ,
2015-11-05 11:59:30 +00:00
" mv-rdo " , " 0 " ,
2016-05-17 11:26:58 +00:00
" smp " , " 0 " ,
" amp " , " 0 " ,
2016-09-27 21:02:27 +00:00
" cu-split-termination " , " zero " ,
" me-early-termination " , " on " ,
2016-09-29 12:44:12 +00:00
" gop " , " lp-g4d3t1 " ,
2015-11-03 13:26:34 +00:00
NULL
} ,
{
" slow " ,
2016-09-27 21:02:27 +00:00
" pu-depth-intra " , " 1-3 " ,
2016-09-29 12:44:12 +00:00
" pu-depth-inter " , " 1-3 " ,
2016-09-27 21:02:27 +00:00
" rd " , " 1 " ,
2015-11-03 13:26:34 +00:00
" me " , " hexbs " ,
2016-09-29 12:44:12 +00:00
" ref " , " 2 " ,
2016-09-27 21:02:27 +00:00
" deblock " , " 0:0 " ,
2015-11-03 13:26:34 +00:00
" signhide " , " 1 " ,
2016-07-12 12:39:01 +00:00
" subme " , " 4 " ,
2015-11-03 13:26:34 +00:00
" sao " , " 1 " ,
2016-09-27 21:02:27 +00:00
" rdoq " , " 1 " ,
" rdoq-skip " , " 1 " ,
2015-11-03 13:26:34 +00:00
" transform-skip " , " 0 " ,
" full-intra-search " , " 0 " ,
2015-11-05 11:59:30 +00:00
" mv-rdo " , " 0 " ,
2016-05-17 11:26:58 +00:00
" smp " , " 0 " ,
" amp " , " 0 " ,
2016-09-27 21:02:27 +00:00
" cu-split-termination " , " zero " ,
" me-early-termination " , " on " ,
2016-09-29 12:44:12 +00:00
" gop " , " lp-g4d2t1 " ,
2015-11-03 13:26:34 +00:00
NULL
} ,
{
" slower " ,
2016-09-29 12:44:12 +00:00
" pu-depth-intra " , " 1-3 " ,
2015-11-03 13:26:34 +00:00
" pu-depth-inter " , " 0-3 " ,
2016-09-27 21:02:27 +00:00
" rd " , " 1 " ,
" me " , " hexbs " ,
2016-09-29 12:44:12 +00:00
" ref " , " 2 " ,
2016-09-27 21:02:27 +00:00
" deblock " , " 0:0 " ,
2015-11-03 13:26:34 +00:00
" signhide " , " 1 " ,
2016-07-12 12:39:01 +00:00
" subme " , " 4 " ,
2015-11-03 13:26:34 +00:00
" sao " , " 1 " ,
" rdoq " , " 1 " ,
2016-09-27 21:02:27 +00:00
" rdoq-skip " , " 1 " ,
2015-11-03 13:26:34 +00:00
" transform-skip " , " 0 " ,
" full-intra-search " , " 0 " ,
2015-11-05 11:59:30 +00:00
" mv-rdo " , " 0 " ,
2016-05-17 11:26:58 +00:00
" smp " , " 0 " ,
" amp " , " 0 " ,
2016-09-27 21:02:27 +00:00
" cu-split-termination " , " zero " ,
" me-early-termination " , " on " ,
2016-09-29 12:44:12 +00:00
" gop " , " lp-g4d2t1 " ,
2015-11-03 13:26:34 +00:00
NULL
} ,
{
" veryslow " ,
" pu-depth-intra " , " 1-4 " ,
" pu-depth-inter " , " 0-3 " ,
2016-09-27 21:02:27 +00:00
" rd " , " 1 " ,
2016-09-29 12:44:12 +00:00
" me " , " hexbs " ,
2016-09-27 21:02:27 +00:00
" ref " , " 3 " ,
" deblock " , " 0:0 " ,
2015-11-03 13:26:34 +00:00
" signhide " , " 1 " ,
2016-07-12 12:39:01 +00:00
" subme " , " 4 " ,
2015-11-03 13:26:34 +00:00
" sao " , " 1 " ,
" rdoq " , " 1 " ,
2016-09-29 12:44:12 +00:00
" rdoq-skip " , " 1 " ,
2016-09-27 21:02:27 +00:00
" transform-skip " , " 0 " ,
2015-11-03 13:26:34 +00:00
" full-intra-search " , " 0 " ,
2016-09-27 21:02:27 +00:00
" mv-rdo " , " 0 " ,
2016-05-17 11:26:58 +00:00
" smp " , " 0 " ,
" amp " , " 0 " ,
2016-09-29 12:44:12 +00:00
" cu-split-termination " , " zero " ,
" me-early-termination " , " on " ,
" gop " , " lp-g4d2t1 " ,
2015-11-03 13:26:34 +00:00
NULL
} ,
{
" placebo " ,
2016-09-29 12:44:12 +00:00
" pu-depth-intra " , " 1-4 " ,
2015-11-03 13:26:34 +00:00
" pu-depth-inter " , " 0-3 " ,
2016-09-29 12:44:12 +00:00
" rd " , " 1 " ,
2015-11-03 13:26:34 +00:00
" me " , " tz " ,
2016-09-27 21:02:27 +00:00
" ref " , " 4 " ,
" deblock " , " 0:0 " ,
2015-11-03 13:26:34 +00:00
" signhide " , " 1 " ,
2016-07-12 12:39:01 +00:00
" subme " , " 4 " ,
2015-11-03 13:26:34 +00:00
" sao " , " 1 " ,
" rdoq " , " 1 " ,
2016-09-27 21:02:27 +00:00
" rdoq-skip " , " 0 " ,
2015-11-03 13:26:34 +00:00
" transform-skip " , " 1 " ,
2016-09-29 12:44:12 +00:00
" full-intra-search " , " 0 " ,
2015-11-05 11:59:30 +00:00
" mv-rdo " , " 1 " ,
2016-05-17 11:26:58 +00:00
" smp " , " 1 " ,
" amp " , " 1 " ,
2016-09-27 21:02:27 +00:00
" cu-split-termination " , " off " ,
" me-early-termination " , " off " ,
2016-09-29 12:44:12 +00:00
" gop " , " lp-g4d2t1 " ,
2015-11-03 13:26:34 +00:00
NULL
} ,
2015-11-03 10:04:22 +00:00
{ NULL }
} ;
2014-02-03 20:58:23 +00:00
if ( ! name )
return 0 ;
2015-06-29 12:50:15 +00:00
2014-02-03 22:16:42 +00:00
if ( ! value )
value = " true " ;
2014-04-04 08:39:25 +00:00
// Treat "--no-param" as --param 0
if ( ( ! strncmp ( name , " no- " , 3 ) ) ) {
name + = 3 ;
2014-02-03 22:16:42 +00:00
value = atobool ( value ) ? " false " : " true " ;
}
2014-02-03 20:58:23 +00:00
2014-04-04 09:20:17 +00:00
# define OPT(STR) (!strcmp(name, STR))
2015-07-03 12:04:36 +00:00
if OPT ( " width " )
2014-02-03 20:58:23 +00:00
cfg - > width = atoi ( value ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " height " )
2014-02-03 20:58:23 +00:00
cfg - > height = atoi ( value ) ;
2015-06-29 12:50:15 +00:00
else if OPT ( " input-res " )
2015-07-29 16:07:27 +00:00
if ( ! strcmp ( value , " auto " ) ) {
return 1 ;
} else {
return ( sscanf ( value , " %dx%d " , & cfg - > width , & cfg - > height ) = = 2 ) ;
}
2016-01-14 20:08:35 +00:00
else if OPT ( " input-fps " ) {
int32_t fps_num , fps_denom ;
if ( sscanf ( value , " %d/%d " , & fps_num , & fps_denom ) = = 2 ) {
cfg - > framerate_num = fps_num ;
cfg - > framerate_denom = fps_denom ;
} else {
// Accept decimal notation, making sure not to round 0 to 1.
cfg - > framerate_num = ( int ) ( atof ( value ) * 1000 + 0.49 ) ;
cfg - > framerate_denom = 1000 ;
}
}
2014-04-04 09:20:17 +00:00
else if OPT ( " qp " )
2014-02-03 20:58:23 +00:00
cfg - > qp = atoi ( value ) ;
2015-06-29 12:50:15 +00:00
else if OPT ( " period " )
2014-02-03 20:58:23 +00:00
cfg - > intra_period = atoi ( value ) ;
2015-02-18 11:41:03 +00:00
else if OPT ( " vps-period " )
cfg - > vps_period = atoi ( value ) ;
2015-06-29 12:50:15 +00:00
else if OPT ( " ref " )
2014-02-18 15:45:54 +00:00
cfg - > ref_frames = atoi ( value ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " deblock " ) {
2014-02-03 22:31:24 +00:00
int beta , tc ;
if ( 2 = = sscanf ( value , " %d:%d " , & beta , & tc ) ) {
cfg - > deblock_enable = 1 ;
cfg - > deblock_beta = beta ;
cfg - > deblock_tc = tc ;
2015-06-29 12:50:15 +00:00
} else {
2014-02-03 22:31:24 +00:00
cfg - > deblock_enable = atobool ( value ) ;
2014-02-06 12:32:30 +00:00
}
2014-02-03 22:31:24 +00:00
}
2014-04-04 09:20:17 +00:00
else if OPT ( " sao " )
2014-02-03 22:55:51 +00:00
cfg - > sao_enable = atobool ( value ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " rdoq " )
2014-03-05 14:56:00 +00:00
cfg - > rdoq_enable = atobool ( value ) ;
2015-01-24 18:10:21 +00:00
else if OPT ( " signhide " )
cfg - > signhide_enable = ( bool ) atobool ( value ) ;
2015-12-15 05:57:38 +00:00
else if OPT ( " smp " )
cfg - > smp_enable = ( bool ) atobool ( value ) ;
2015-12-01 12:37:58 +00:00
else if OPT ( " amp " )
cfg - > amp_enable = ( bool ) atobool ( value ) ;
2014-06-17 12:32:05 +00:00
else if OPT ( " rd " )
2015-06-29 12:50:15 +00:00
cfg - > rdo = atoi ( value ) ;
2014-06-17 12:32:05 +00:00
else if OPT ( " full-intra-search " )
cfg - > full_intra_search = atobool ( value ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " transform-skip " )
2014-04-02 11:41:40 +00:00
cfg - > trskip_enable = atobool ( value ) ;
2015-06-29 12:50:15 +00:00
else if OPT ( " tr-depth-intra " )
2014-05-30 14:19:41 +00:00
cfg - > tr_depth_intra = atoi ( value ) ;
2015-07-06 06:47:18 +00:00
else if OPT ( " me " ) {
int8_t ime_algorithm = 0 ;
if ( ! parse_enum ( value , me_names , & ime_algorithm ) ) return 0 ;
cfg - > ime_algorithm = ime_algorithm ;
}
2015-06-29 12:50:15 +00:00
else if OPT ( " subme " )
2014-11-20 12:59:04 +00:00
cfg - > fme_level = atoi ( value ) ;
2015-08-13 09:53:14 +00:00
else if OPT ( " source-scan-type " )
return parse_enum ( value , source_scan_type_names , & cfg - > source_scan_type ) ;
2016-02-24 10:39:03 +00:00
else if OPT ( " mv-constraint " )
{
int8_t constraint = KVZ_MV_CONSTRAIN_NONE ;
int result = parse_enum ( value , mv_constraint_names , & constraint ) ;
cfg - > mv_constraint = constraint ;
return result ;
}
2015-06-29 12:50:15 +00:00
else if OPT ( " sar " )
return sscanf ( value , " %d:%d " , & cfg - > vui . sar_width , & cfg - > vui . sar_height ) = = 2 ;
2014-04-04 09:20:17 +00:00
else if OPT ( " overscan " )
2015-06-29 12:50:15 +00:00
return parse_enum ( value , overscan_names , & cfg - > vui . overscan ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " videoformat " )
2015-06-29 12:50:15 +00:00
return parse_enum ( value , videoformat_names , & cfg - > vui . videoformat ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " range " )
2015-06-29 12:50:15 +00:00
return parse_enum ( value , range_names , & cfg - > vui . fullrange ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " colorprim " )
2015-06-29 12:50:15 +00:00
return parse_enum ( value , colorprim_names , & cfg - > vui . colorprim ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " transfer " )
2015-06-29 12:50:15 +00:00
return parse_enum ( value , transfer_names , & cfg - > vui . transfer ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " colormatrix " )
2015-06-29 12:50:15 +00:00
return parse_enum ( value , colormatrix_names , & cfg - > vui . colormatrix ) ;
else if OPT ( " chromaloc " )
cfg - > vui . chroma_loc = atoi ( value ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " aud " )
2014-02-06 22:35:15 +00:00
cfg - > aud_enable = atobool ( value ) ;
2014-04-04 09:20:17 +00:00
else if OPT ( " cqmfile " )
2015-07-03 12:04:36 +00:00
cfg - > cqmfile = strdup ( value ) ;
2016-08-10 11:51:41 +00:00
else if OPT ( " tiles-width-split " ) {
int retval = parse_tiles_specification ( value , & cfg - > tiles_width_count , & cfg - > tiles_width_split ) ;
2016-10-26 23:07:10 +00:00
2016-08-10 11:51:41 +00:00
if ( cfg - > tiles_width_count > 1 & & cfg - > tmvp_enable ) {
cfg - > tmvp_enable = false ;
fprintf ( stderr , " Disabling TMVP because tiles are used. \n " ) ;
}
2016-10-26 23:07:10 +00:00
if ( cfg - > wpp ) {
cfg - > wpp = false ;
fprintf ( stderr , " Disabling WPP because tiles were enabled. \n " ) ;
}
2016-08-10 11:51:41 +00:00
return retval ;
}
else if OPT ( " tiles-height-split " ) {
int retval = parse_tiles_specification ( value , & cfg - > tiles_height_count , & cfg - > tiles_height_split ) ;
2016-10-26 23:07:10 +00:00
2016-08-10 11:51:41 +00:00
if ( cfg - > tiles_height_count > 1 & & cfg - > tmvp_enable ) {
cfg - > tmvp_enable = false ;
fprintf ( stderr , " Disabling TMVP because tiles are used. \n " ) ;
}
2016-10-26 23:07:10 +00:00
if ( cfg - > wpp ) {
cfg - > wpp = false ;
fprintf ( stderr , " Disabling WPP because tiles were enabled. \n " ) ;
}
2016-08-10 11:51:41 +00:00
return retval ;
}
2016-03-07 13:54:35 +00:00
else if OPT ( " tiles " )
{
// A simpler interface for setting tiles, accepting only uniform split.
2016-03-07 15:21:40 +00:00
unsigned width ;
unsigned height ;
2016-03-07 13:54:35 +00:00
if ( 2 ! = sscanf ( value , " %ux%u " , & width , & height ) ) {
fprintf ( stderr , " Wrong format for tiles. Expected \" %%ux%%u \" , but got \" %s \" \n " , value ) ;
return 0 ;
}
2016-03-07 15:21:40 +00:00
if ( MAX_TILES_PER_DIM < = width | | 1 > width ) {
2016-03-07 13:54:35 +00:00
fprintf ( stderr , " Invalid number of tiles (0 < %d <= %d = MAX_TILES_PER_DIM)! \n " , width , MAX_TILES_PER_DIM ) ;
return 0 ;
}
2016-03-07 15:21:40 +00:00
if ( MAX_TILES_PER_DIM < = height | | 1 > height ) {
2016-03-07 13:54:35 +00:00
fprintf ( stderr , " Invalid number of tiles (0 < %d <= %d = MAX_TILES_PER_DIM)! \n " , height , MAX_TILES_PER_DIM ) ;
return 0 ;
}
// Free split arrays incase they have already been set by another parameter.
FREE_POINTER ( cfg - > tiles_width_split ) ;
FREE_POINTER ( cfg - > tiles_height_split ) ;
2016-03-07 15:21:40 +00:00
cfg - > tiles_width_count = width ;
cfg - > tiles_height_count = height ;
2016-08-10 11:51:41 +00:00
if ( cfg - > tmvp_enable ) {
cfg - > tmvp_enable = false ;
fprintf ( stderr , " Disabling TMVP because tiles are used. \n " ) ;
}
2016-10-26 23:07:10 +00:00
if ( cfg - > wpp ) {
cfg - > wpp = false ;
fprintf ( stderr , " Disabling WPP because tiles were enabled. \n " ) ;
}
2016-03-07 13:54:35 +00:00
return 1 ;
}
2014-05-05 13:17:22 +00:00
else if OPT ( " wpp " )
cfg - > wpp = atobool ( value ) ;
2014-06-16 06:26:24 +00:00
else if OPT ( " owf " ) {
cfg - > owf = atoi ( value ) ;
2015-06-29 12:50:15 +00:00
if ( cfg - > owf = = 0 & & ! strcmp ( value , " auto " ) ) {
// -1 means automatic selection
2014-11-17 00:19:25 +00:00
cfg - > owf = - 1 ;
2014-06-16 06:26:24 +00:00
}
2016-09-10 17:57:44 +00:00
} else if OPT ( " slice-addresses " ) {
fprintf ( stderr , " --slice-addresses doesn't do anything, because slices are not implemented. \n " ) ;
2015-06-29 12:50:15 +00:00
return parse_slice_specification ( value , & cfg - > slice_count , & cfg - > slice_addresses_in_ts ) ;
2017-01-08 08:56:02 +00:00
} else if OPT ( " threads " ) {
2014-05-13 09:52:10 +00:00
cfg - > threads = atoi ( value ) ;
2017-01-08 08:56:02 +00:00
if ( cfg - > threads = = 0 & & ! strcmp ( value , " auto " ) ) {
// -1 means automatic selection
cfg - > threads = - 1 ;
}
}
2014-10-14 09:01:56 +00:00
else if OPT ( " cpuid " )
cfg - > cpuid = atoi ( value ) ;
2015-01-09 10:04:23 +00:00
else if OPT ( " pu-depth-inter " )
2015-06-29 12:50:15 +00:00
return sscanf ( value , " %d-%d " , & cfg - > pu_depth_inter . min , & cfg - > pu_depth_inter . max ) = = 2 ;
2015-01-09 10:04:23 +00:00
else if OPT ( " pu-depth-intra " )
2015-06-29 12:50:15 +00:00
return sscanf ( value , " %d-%d " , & cfg - > pu_depth_intra . min , & cfg - > pu_depth_intra . max ) = = 2 ;
2015-04-16 14:17:17 +00:00
else if OPT ( " info " )
cfg - > add_encoder_info = atobool ( value ) ;
2015-03-30 06:54:22 +00:00
else if OPT ( " gop " ) {
2015-11-13 16:19:13 +00:00
if ( ! strncmp ( value , " lp- " , 3 ) ) { // Handle GOPs starting with "lp-".
struct {
unsigned g ; // length
unsigned d ; // depth
unsigned t ; // temporal
2016-09-27 19:12:02 +00:00
} gop = { 0 , 0 , 0 } ;
2015-11-13 16:19:13 +00:00
2016-09-27 19:12:02 +00:00
// Parse --gop=lp-g#d#t#
if ( sscanf ( value , " lp-g%ud%ut%u " , & gop . g , & gop . d , & gop . t ) ! = 3 ) {
fprintf ( stderr , " Error in GOP syntax. Example: lp-g8d4t2 \n " ) ;
2015-11-13 16:19:13 +00:00
return 0 ;
}
if ( gop . g < 1 | | gop . g > 32 ) {
fprintf ( stderr , " gop.g must be between 1 and 32. \n " ) ;
2016-09-27 19:12:02 +00:00
return 0 ;
2015-11-13 16:19:13 +00:00
}
if ( gop . d < 1 | | gop . d > 8 ) {
fprintf ( stderr , " gop.d must be between 1 and 8. \n " ) ;
2016-09-27 19:12:02 +00:00
return 0 ;
2015-11-13 16:19:13 +00:00
}
if ( gop . t < 1 | | gop . t > 15 ) {
2016-09-27 19:12:02 +00:00
fprintf ( stderr , " gop.t must be between 1 and 15. \n " ) ;
return 0 ;
2015-11-13 16:19:13 +00:00
}
2016-09-27 19:12:02 +00:00
cfg - > gop_lowdelay = true ;
2015-11-13 16:19:13 +00:00
cfg - > gop_len = gop . g ;
2016-09-27 19:12:02 +00:00
cfg - > gop_lp_definition . d = gop . d ;
cfg - > gop_lp_definition . t = gop . t ;
2015-11-13 16:19:13 +00:00
} else if ( atoi ( value ) = = 8 ) {
2015-11-02 10:22:25 +00:00
cfg - > gop_lowdelay = 0 ;
2015-03-30 06:54:22 +00:00
// GOP
cfg - > gop_len = 8 ;
2015-05-29 11:00:51 +00:00
cfg - > gop [ 0 ] . poc_offset = 8 ; cfg - > gop [ 0 ] . qp_offset = 1 ; cfg - > gop [ 0 ] . layer = 1 ; cfg - > gop [ 0 ] . qp_factor = 0.442 ; cfg - > gop [ 0 ] . is_ref = 1 ;
2015-03-30 06:54:22 +00:00
cfg - > gop [ 0 ] . ref_pos_count = 0 ;
cfg - > gop [ 0 ] . ref_neg_count = 3 ; cfg - > gop [ 0 ] . ref_neg [ 0 ] = 8 ; cfg - > gop [ 0 ] . ref_neg [ 1 ] = 12 ; cfg - > gop [ 0 ] . ref_neg [ 2 ] = 16 ;
2015-05-29 11:00:51 +00:00
cfg - > gop [ 1 ] . poc_offset = 4 ; cfg - > gop [ 1 ] . qp_offset = 2 ; cfg - > gop [ 1 ] . layer = 2 ; cfg - > gop [ 1 ] . qp_factor = 0.3536 ; cfg - > gop [ 1 ] . is_ref = 1 ;
2015-03-30 06:54:22 +00:00
cfg - > gop [ 1 ] . ref_neg_count = 2 ; cfg - > gop [ 1 ] . ref_neg [ 0 ] = 4 ; cfg - > gop [ 1 ] . ref_neg [ 1 ] = 8 ;
cfg - > gop [ 1 ] . ref_pos_count = 1 ; cfg - > gop [ 1 ] . ref_pos [ 0 ] = 4 ;
2015-05-29 11:00:51 +00:00
cfg - > gop [ 2 ] . poc_offset = 2 ; cfg - > gop [ 2 ] . qp_offset = 3 ; cfg - > gop [ 2 ] . layer = 3 ; cfg - > gop [ 2 ] . qp_factor = 0.3536 ; cfg - > gop [ 2 ] . is_ref = 1 ;
2015-03-30 06:54:22 +00:00
cfg - > gop [ 2 ] . ref_neg_count = 2 ; cfg - > gop [ 2 ] . ref_neg [ 0 ] = 2 ; cfg - > gop [ 2 ] . ref_neg [ 1 ] = 6 ;
cfg - > gop [ 2 ] . ref_pos_count = 2 ; cfg - > gop [ 2 ] . ref_pos [ 0 ] = 2 ; cfg - > gop [ 2 ] . ref_pos [ 1 ] = 6 ;
2015-05-29 11:00:51 +00:00
cfg - > gop [ 3 ] . poc_offset = 1 ; cfg - > gop [ 3 ] . qp_offset = 4 ; cfg - > gop [ 3 ] . layer = 4 ; cfg - > gop [ 3 ] . qp_factor = 0.68 ; cfg - > gop [ 3 ] . is_ref = 0 ;
2015-03-30 06:54:22 +00:00
cfg - > gop [ 3 ] . ref_neg_count = 1 ; cfg - > gop [ 3 ] . ref_neg [ 0 ] = 1 ;
cfg - > gop [ 3 ] . ref_pos_count = 3 ; cfg - > gop [ 3 ] . ref_pos [ 0 ] = 1 ; cfg - > gop [ 3 ] . ref_pos [ 1 ] = 3 ; cfg - > gop [ 3 ] . ref_pos [ 2 ] = 7 ;
2015-05-29 11:00:51 +00:00
cfg - > gop [ 4 ] . poc_offset = 3 ; cfg - > gop [ 4 ] . qp_offset = 4 ; cfg - > gop [ 4 ] . layer = 4 ; cfg - > gop [ 4 ] . qp_factor = 0.68 ; cfg - > gop [ 4 ] . is_ref = 0 ;
2015-03-30 06:54:22 +00:00
cfg - > gop [ 4 ] . ref_neg_count = 2 ; cfg - > gop [ 4 ] . ref_neg [ 0 ] = 1 ; cfg - > gop [ 4 ] . ref_neg [ 1 ] = 3 ;
cfg - > gop [ 4 ] . ref_pos_count = 2 ; cfg - > gop [ 4 ] . ref_pos [ 0 ] = 1 ; cfg - > gop [ 4 ] . ref_pos [ 1 ] = 5 ;
2015-05-29 11:00:51 +00:00
cfg - > gop [ 5 ] . poc_offset = 6 ; cfg - > gop [ 5 ] . qp_offset = 3 ; cfg - > gop [ 5 ] . layer = 3 ; cfg - > gop [ 5 ] . qp_factor = 0.3536 ; cfg - > gop [ 5 ] . is_ref = 1 ;
2015-03-30 06:54:22 +00:00
cfg - > gop [ 5 ] . ref_neg_count = 2 ; cfg - > gop [ 5 ] . ref_neg [ 0 ] = 2 ; cfg - > gop [ 5 ] . ref_neg [ 1 ] = 6 ;
cfg - > gop [ 5 ] . ref_pos_count = 1 ; cfg - > gop [ 5 ] . ref_pos [ 0 ] = 2 ;
2015-05-29 11:00:51 +00:00
cfg - > gop [ 6 ] . poc_offset = 5 ; cfg - > gop [ 6 ] . qp_offset = 4 ; cfg - > gop [ 6 ] . layer = 4 ; cfg - > gop [ 6 ] . qp_factor = 0.68 ; cfg - > gop [ 6 ] . is_ref = 0 ;
2015-03-30 06:54:22 +00:00
cfg - > gop [ 6 ] . ref_neg_count = 2 ; cfg - > gop [ 6 ] . ref_neg [ 0 ] = 1 ; cfg - > gop [ 6 ] . ref_neg [ 1 ] = 5 ;
cfg - > gop [ 6 ] . ref_pos_count = 2 ; cfg - > gop [ 6 ] . ref_pos [ 0 ] = 1 ; cfg - > gop [ 6 ] . ref_pos [ 1 ] = 3 ;
2015-05-29 11:00:51 +00:00
cfg - > gop [ 7 ] . poc_offset = 7 ; cfg - > gop [ 7 ] . qp_offset = 4 ; cfg - > gop [ 7 ] . layer = 4 ; cfg - > gop [ 7 ] . qp_factor = 0.68 ; cfg - > gop [ 7 ] . is_ref = 0 ;
2015-03-30 06:54:22 +00:00
cfg - > gop [ 7 ] . ref_neg_count = 3 ; cfg - > gop [ 7 ] . ref_neg [ 0 ] = 1 ; cfg - > gop [ 7 ] . ref_neg [ 1 ] = 3 ; cfg - > gop [ 7 ] . ref_neg [ 2 ] = 7 ;
cfg - > gop [ 7 ] . ref_pos_count = 1 ; cfg - > gop [ 7 ] . ref_pos [ 0 ] = 1 ;
2016-12-20 12:25:13 +00:00
} else if ( atoi ( value ) = = 0 ) {
//Disable gop
cfg - > gop_len = 0 ;
cfg - > gop_lowdelay = 0 ;
cfg - > gop_lp_definition . d = 0 ;
cfg - > gop_lp_definition . t = 0 ;
2015-06-29 12:50:15 +00:00
} else if ( atoi ( value ) ) {
fprintf ( stderr , " Input error: unsupported gop length, must be 0 or 8 \n " ) ;
2015-03-30 06:54:22 +00:00
return 0 ;
}
}
2015-04-21 11:18:34 +00:00
else if OPT ( " bipred " )
cfg - > bipred = atobool ( value ) ;
2015-06-29 12:50:15 +00:00
else if OPT ( " bitrate " )
2015-03-13 14:31:00 +00:00
cfg - > target_bitrate = atoi ( value ) ;
2015-11-03 10:04:22 +00:00
else if OPT ( " preset " ) {
int preset_line = 0 ;
2015-11-03 13:46:23 +00:00
// Accept numbers from 0 to 9.
if ( ( atoi ( value ) = = 0 & & ! strcmp ( value , " 0 " ) ) | | ( atoi ( value ) > = 1 & & atoi ( value ) < = 9 ) ) {
preset_line = atoi ( value ) ;
} else {
// Find the selected preset from the list
while ( preset_values [ preset_line ] [ 0 ] ! = NULL ) {
if ( ! strcmp ( value , preset_values [ preset_line ] [ 0 ] ) ) {
break ;
2015-11-03 10:04:22 +00:00
}
2015-11-03 13:46:23 +00:00
preset_line + + ;
2015-11-03 10:04:22 +00:00
}
}
2015-11-03 13:46:23 +00:00
if ( preset_values [ preset_line ] [ 0 ] ! = NULL ) {
fprintf ( stderr , " Using preset %s: " , value ) ;
// Loop all the name and value pairs and push to the config parser
for ( int preset_value = 1 ; preset_values [ preset_line ] [ preset_value ] ! = NULL ; preset_value + = 2 ) {
fprintf ( stderr , " --%s=%s " , preset_values [ preset_line ] [ preset_value ] , preset_values [ preset_line ] [ preset_value + 1 ] ) ;
kvz_config_parse ( cfg , preset_values [ preset_line ] [ preset_value ] , preset_values [ preset_line ] [ preset_value + 1 ] ) ;
}
fprintf ( stderr , " \n " ) ;
} else {
2015-11-03 10:04:22 +00:00
fprintf ( stderr , " Input error: unknown preset \" %s \" \n " , value ) ;
return 0 ;
}
}
2015-11-05 11:59:30 +00:00
else if OPT ( " mv-rdo " )
cfg - > mv_rdo = atobool ( value ) ;
2016-01-21 13:08:34 +00:00
else if OPT ( " psnr " )
cfg - > calc_psnr = ( bool ) atobool ( value ) ;
2016-03-17 15:00:43 +00:00
else if OPT ( " hash " )
{
int8_t hash ;
int result ;
if ( ( result = parse_enum ( value , hash_names , & hash ) ) ) {
cfg - > hash = hash ;
}
return result ;
}
2016-05-10 11:15:41 +00:00
else if OPT ( " cu-split-termination " )
2016-05-10 11:34:46 +00:00
{
int8_t mode = KVZ_CU_SPLIT_TERMINATION_ZERO ;
int result = parse_enum ( value , cu_split_termination_names , & mode ) ;
cfg - > cu_split_termination = mode ;
return result ;
}
2016-06-07 07:55:26 +00:00
else if OPT ( " crypto " )
{
// on, off, feature1+feature2
const char * token_begin = value ;
const char * cur = token_begin ;
cfg - > crypto_features = KVZ_CRYPTO_OFF ;
// If value is on or off, set all features to on or off.
int8_t toggle = 0 ;
if ( parse_enum ( token_begin , crypto_toggle_names , & toggle ) ) {
if ( toggle = = 1 ) {
cfg - > crypto_features = KVZ_CRYPTO_ON ;
}
2016-06-07 10:13:33 +00:00
} else {
// Try and parse "feature1+feature2" type list.
for ( ; ; ) {
if ( * cur = = ' + ' | | * cur = = ' \0 ' ) {
int8_t feature = 0 ;
int num_chars = cur - token_begin ;
if ( parse_enum_n ( token_begin , num_chars , crypto_feature_names , & feature ) ) {
cfg - > crypto_features | = ( 1 < < feature ) ;
} else {
cfg - > crypto_features = KVZ_CRYPTO_OFF ;
return 0 ;
}
token_begin = cur + 1 ;
}
2016-06-07 07:55:26 +00:00
2016-06-07 10:13:33 +00:00
if ( * cur = = ' \0 ' ) {
break ;
2016-06-07 07:55:26 +00:00
} else {
2016-06-07 10:13:33 +00:00
+ + cur ;
2016-06-07 07:55:26 +00:00
}
}
2016-06-07 10:13:33 +00:00
}
2016-06-07 07:55:26 +00:00
2016-06-07 10:13:33 +00:00
// Disallow turning on the encryption when it's not compiled in.
bool encryption_compiled_in = false ;
# ifdef KVZ_SEL_ENCRYPTION
encryption_compiled_in = true ;
# endif
if ( ! encryption_compiled_in & & cfg - > crypto_features ) {
fprintf ( stderr , " --crypto cannot be enabled because it's not compiled in. \n " ) ;
cfg - > crypto_features = KVZ_CRYPTO_OFF ;
return 0 ;
2016-06-07 07:55:26 +00:00
}
return 1 ;
}
2016-06-06 12:47:31 +00:00
else if OPT ( " me-early-termination " ) {
int8_t mode = 0 ;
int result = parse_enum ( value , me_early_termination_names , & mode ) ;
cfg - > me_early_termination = mode ;
return result ;
}
2016-05-26 07:38:45 +00:00
else if OPT ( " lossless " )
cfg - > lossless = ( bool ) atobool ( value ) ;
2016-08-10 08:58:15 +00:00
else if OPT ( " tmvp " ) {
cfg - > tmvp_enable = atobool ( value ) ;
if ( cfg - > gop_len & & cfg - > tmvp_enable ) {
fprintf ( stderr , " Cannot enable TMVP because GOP is used. \n " ) ;
cfg - > tmvp_enable = false ;
}
2016-08-10 11:51:41 +00:00
if ( cfg - > tiles_width_count > 1 | | cfg - > tiles_height_count > 1 ) {
fprintf ( stderr , " Cannot enable TMVP because tiles are used. \n " ) ;
cfg - > tmvp_enable = false ;
}
2016-08-10 08:58:15 +00:00
}
2016-08-17 07:07:40 +00:00
else if OPT ( " rdoq-skip " ) {
cfg - > rdoq_skip = atobool ( value ) ;
}
2016-08-16 16:03:21 +00:00
else if OPT ( " input-format " ) {
static enum kvz_input_format const formats [ ] = { KVZ_FORMAT_P400 , KVZ_FORMAT_P420 } ;
static const char * const format_names [ ] = { " P400 " , " P420 " , NULL } ;
int8_t format = 0 ;
if ( ! parse_enum ( value , format_names , & format ) ) {
fprintf ( stderr , " input-format not recognized. \n " ) ;
return 0 ;
}
cfg - > input_format = formats [ format ] ;
}
else if OPT ( " input-bitdepth " ) {
cfg - > input_bitdepth = atoi ( value ) ;
if ( cfg - > input_bitdepth < 8 | | cfg - > input_bitdepth > 16 ) {
fprintf ( stderr , " input-bitdepth not between 8 and 16. \n " ) ;
return 0 ;
}
if ( cfg - > input_bitdepth > 8 & & KVZ_BIT_DEPTH = = 8 ) {
// Because the image is read straight into the reference buffers,
// reading >8 bit samples doesn't work when sizeof(kvz_pixel)==1.
fprintf ( stderr , " input-bitdepth can't be set to larger than 8 because "
" Kvazaar is compiled with KVZ_BIT_DEPTH=8. \n " ) ;
return 0 ;
}
}
2016-08-03 05:18:56 +00:00
else if OPT ( " implicit-rdpcm " )
cfg - > implicit_rdpcm = ( bool ) atobool ( value ) ;
2014-02-03 20:58:23 +00:00
else
return 0 ;
# undef OPT
2015-06-29 12:50:15 +00:00
return 1 ;
2014-02-03 20:58:23 +00:00
}
2016-09-27 19:12:02 +00:00
void kvz_config_process_lp_gop ( kvz_config * cfg )
{
struct {
unsigned g ;
unsigned d ;
unsigned t ;
} gop ;
gop . g = cfg - > gop_len ;
gop . d = cfg - > gop_lp_definition . d ;
gop . t = cfg - > gop_lp_definition . t ;
// Initialize modulos for testing depth.
// The picture belong to the lowest depth in which (poc % modulo) == 0.
unsigned depth_modulos [ 8 ] = { 0 } ;
for ( int d = 0 ; d < gop . d ; + + d ) {
depth_modulos [ gop . d - 1 - d ] = 1 < < d ;
}
depth_modulos [ 0 ] = gop . g ;
cfg - > gop_lowdelay = 1 ;
cfg - > gop_len = gop . g ;
for ( int g = 1 ; g < = gop . g ; + + g ) {
kvz_gop_config * gop_pic = & cfg - > gop [ g - 1 ] ;
// Find gop depth for picture.
2016-09-28 19:47:57 +00:00
int gop_layer = 1 ;
while ( gop_layer < gop . d & & ( g % depth_modulos [ gop_layer - 1 ] ) ) {
2016-09-27 19:12:02 +00:00
+ + gop_layer ;
}
gop_pic - > poc_offset = g ;
2016-09-28 19:47:57 +00:00
gop_pic - > layer = gop_layer ;
gop_pic - > qp_offset = gop_layer ;
2016-09-27 19:12:02 +00:00
gop_pic - > ref_pos_count = 0 ;
gop_pic - > ref_neg_count = cfg - > ref_frames ;
gop_pic - > is_ref = 0 ;
// Set first ref to point to previous frame, and the rest to previous
// key-frames.
// If gop.t > 1, have (poc % gop.t) == 0 point gop.t frames away,
// instead of the previous frame. Set the frames in between to
// point to the nearest frame with a lower gop-depth.
if ( gop . t > 1 ) {
if ( gop_pic - > poc_offset % gop . t = = 0 ) {
gop_pic - > ref_neg [ 0 ] = gop . t ;
} else {
int r = gop_pic - > poc_offset - 1 ;
while ( r > 0 ) {
if ( cfg - > gop [ r ] . layer < gop_pic - > layer ) break ;
- - r ;
}
// Var r is now 0 or index of the pic with layer < depth.
if ( cfg - > gop [ r ] . layer < gop_pic - > layer ) {
gop_pic - > ref_neg [ 0 ] = gop_pic - > poc_offset - cfg - > gop [ r ] . poc_offset ;
cfg - > gop [ r ] . is_ref = 1 ;
} else {
// No ref was found, just refer to the previous key-frame.
gop_pic - > ref_neg [ 0 ] = gop_pic - > poc_offset % gop . g ;
}
}
} else {
gop_pic - > ref_neg [ 0 ] = 1 ;
if ( gop_pic - > poc_offset > = 2 ) {
cfg - > gop [ gop_pic - > poc_offset - 2 ] . is_ref = 1 ;
}
}
int keyframe = gop_pic - > poc_offset ;
for ( int i = 1 ; i < gop_pic - > ref_neg_count ; + + i ) {
while ( keyframe = = gop_pic - > ref_neg [ i - 1 ] ) {
keyframe + = gop . g ;
}
gop_pic - > ref_neg [ i ] = keyframe ;
}
gop_pic - > qp_factor = 0.4624 ; // from HM
}
for ( int g = 0 ; g < gop . g ; + + g ) {
kvz_gop_config * gop_pic = & cfg - > gop [ g ] ;
if ( ! gop_pic - > is_ref ) {
gop_pic - > qp_factor = 0.68 * 1.31 ; // derived from HM
}
}
// Key-frame is always a reference.
cfg - > gop [ gop . g - 1 ] . is_ref = 1 ;
cfg - > gop [ gop . g - 1 ] . qp_factor = 0.578 ; // from HM
}
2014-03-10 13:53:23 +00:00
/**
2015-06-29 12:50:15 +00:00
* \ brief Check that configuration is sensible .
2014-03-10 13:53:23 +00:00
*
2015-06-29 12:50:15 +00:00
* \ param cfg config to check
* \ return 1 if the config is ok , otherwise 1
2014-03-10 13:53:23 +00:00
*/
2015-08-26 08:50:27 +00:00
int kvz_config_validate ( const kvz_config * const cfg )
2014-03-10 13:53:23 +00:00
{
2015-06-29 12:50:15 +00:00
int error = 0 ;
if ( cfg - > width < = 0 ) {
2015-07-15 08:37:37 +00:00
fprintf ( stderr , " Input error: width must be positive \n " ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
}
2015-07-15 08:37:37 +00:00
if ( cfg - > height < = 0 ) {
fprintf ( stderr , " Input error: height must be positive \n " ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
}
2015-07-15 08:37:37 +00:00
if ( cfg - > width % 2 ! = 0 ) {
fprintf ( stderr , " Input error: width must be a multiple of two \n " ) ;
error = 1 ;
}
if ( cfg - > height % 2 ! = 0 ) {
fprintf ( stderr , " Input error: height must be a multiple of two \n " ) ;
error = 1 ;
}
2016-01-14 20:08:35 +00:00
if ( cfg - > framerate < 0.0 ) {
2015-07-15 08:37:37 +00:00
fprintf ( stderr , " Input error: --input-fps must be positive \n " ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
}
2016-01-14 20:08:35 +00:00
if ( cfg - > framerate_num < 0 ) {
fprintf ( stderr , " Input error: --input-fps must >=0 \n " ) ;
error = 1 ;
}
if ( cfg - > framerate_denom < = 0 ) {
fprintf ( stderr , " Input error: --input-fps denominator must be >0 \n " ) ;
error = 1 ;
}
2015-06-29 12:50:15 +00:00
2016-09-27 19:25:11 +00:00
if ( cfg - > gop_len & & cfg - > intra_period & & ! cfg - > gop_lowdelay & &
cfg - > intra_period % cfg - > gop_len ! = 0 )
{
2015-06-29 12:50:15 +00:00
fprintf ( stderr ,
2016-09-27 19:25:11 +00:00
" Input error: intra period (%d) not a multiple of B-gop length (%d) \n " ,
2015-06-29 12:50:15 +00:00
cfg - > intra_period ,
cfg - > gop_len ) ;
error = 1 ;
}
if ( cfg - > ref_frames < 1 | | cfg - > ref_frames > = MAX_REF_PIC_COUNT ) {
fprintf ( stderr , " Input error: --ref out of range [1..%d] \n " , MAX_REF_PIC_COUNT - 1 ) ;
error = 1 ;
}
if ( cfg - > deblock_beta < - 6 | | cfg - > deblock_beta > 6 ) {
fprintf ( stderr , " Input error: deblock beta parameter out of range [-6..6] \n " ) ;
error = 1 ;
}
if ( cfg - > deblock_tc < - 6 | | cfg - > deblock_tc > 6 ) {
fprintf ( stderr , " Input error: deblock tc parameter out of range [-6..6] \n " ) ;
error = 1 ;
}
2015-10-04 23:28:10 +00:00
if ( cfg - > rdo < 0 | | cfg - > rdo > 3 ) {
fprintf ( stderr , " Input error: --rd parameter out of range [0..3] \n " ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
}
if ( cfg - > tr_depth_intra < 0 | | cfg - > tr_depth_intra > 4 ) {
// range is 0 .. CtbLog2SizeY - Log2MinTrafoSize
fprintf ( stderr , " Input error: --tr-depth-intra is out of range [0..4] \n " ) ;
error = 1 ;
}
2016-07-12 12:39:01 +00:00
if ( cfg - > fme_level ! = 0 & & cfg - > fme_level > 4 ) {
fprintf ( stderr , " Input error: invalid --subme parameter (must be in range 0-4) \n " ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
}
if ( cfg - > vui . chroma_loc < 0 | | cfg - > vui . chroma_loc > 5 ) {
fprintf ( stderr , " Input error: --chromaloc parameter out of range [0..5] \n " ) ;
error = 1 ;
}
if ( cfg - > owf < - 1 ) {
fprintf ( stderr , " Input error: --owf must be nonnegative or -1 \n " ) ;
error = 1 ;
}
if ( cfg - > target_bitrate < 0 ) {
fprintf ( stderr , " Input error: --bitrate must be nonnegative \n " ) ;
error = 1 ;
}
if ( ! WITHIN ( cfg - > pu_depth_inter . min , PU_DEPTH_INTER_MIN , PU_DEPTH_INTER_MAX ) | |
! WITHIN ( cfg - > pu_depth_inter . max , PU_DEPTH_INTER_MIN , PU_DEPTH_INTER_MAX ) )
{
fprintf ( stderr , " Input error: illegal value for --pu-depth-inter (%d-%d) \n " ,
cfg - > pu_depth_inter . min , cfg - > pu_depth_inter . max ) ;
error = 1 ;
} else if ( cfg - > pu_depth_inter . min > cfg - > pu_depth_inter . max ) {
fprintf ( stderr , " Input error: Inter PU depth min (%d) > max (%d) \n " ,
cfg - > pu_depth_inter . min , cfg - > pu_depth_inter . max ) ;
error = 1 ;
}
if ( ! WITHIN ( cfg - > pu_depth_intra . min , PU_DEPTH_INTRA_MIN , PU_DEPTH_INTRA_MAX ) | |
! WITHIN ( cfg - > pu_depth_intra . max , PU_DEPTH_INTRA_MIN , PU_DEPTH_INTRA_MAX ) )
{
fprintf ( stderr , " Input error: illegal value for --pu-depth-intra (%d-%d) \n " ,
cfg - > pu_depth_intra . min , cfg - > pu_depth_intra . max ) ;
error = 1 ;
} else if ( cfg - > pu_depth_intra . min > cfg - > pu_depth_intra . max ) {
fprintf ( stderr , " Input error: Intra PU depth min (%d) > max (%d) \n " ,
cfg - > pu_depth_intra . min , cfg - > pu_depth_intra . max ) ;
error = 1 ;
2014-03-10 13:53:23 +00:00
}
2015-06-29 12:50:15 +00:00
// Tile separation should be at round position in terms of LCU, should be monotonic, and should not start by 0
2014-04-02 08:38:03 +00:00
if ( cfg - > tiles_width_split ) {
int i ;
int32_t prev_tile_split = 0 ;
2016-03-07 15:21:40 +00:00
for ( i = 0 ; i < cfg - > tiles_width_count - 1 ; + + i ) {
2014-04-02 08:38:03 +00:00
if ( cfg - > tiles_width_split [ i ] < = prev_tile_split ) {
fprintf ( stderr , " Input error: tile separations in width should be strictly monotonic (%d <= %d) \n " , cfg - > tiles_width_split [ i ] , prev_tile_split ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
break ;
2014-04-02 08:38:03 +00:00
}
if ( ( cfg - > tiles_width_split [ i ] % LCU_WIDTH ) ! = 0 ) {
fprintf ( stderr , " Input error: tile separation in width %d (at %d) is not at a multiple of LCU_WIDTH (%d) \n " , i , cfg - > tiles_width_split [ i ] , LCU_WIDTH ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
break ;
2014-04-02 08:38:03 +00:00
}
prev_tile_split = cfg - > tiles_width_split [ i ] ;
}
2016-03-07 15:21:40 +00:00
if ( cfg - > tiles_width_split [ cfg - > tiles_width_count - 2 ] > = cfg - > width ) {
fprintf ( stderr , " Input error: last x tile separation in width (%d) should smaller than image width (%d) \n " , cfg - > tiles_width_split [ cfg - > tiles_width_count - 2 ] , cfg - > width ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
2014-04-02 08:38:03 +00:00
}
}
2015-06-29 12:50:15 +00:00
2014-04-02 08:38:03 +00:00
if ( cfg - > tiles_height_split ) {
int i ;
int32_t prev_tile_split = 0 ;
2016-03-07 15:21:40 +00:00
for ( i = 0 ; i < cfg - > tiles_height_count - 1 ; + + i ) {
2014-04-02 08:38:03 +00:00
if ( cfg - > tiles_height_split [ i ] < = prev_tile_split ) {
fprintf ( stderr , " Input error: tile separations in height should be strictly monotonic (%d <= %d) \n " , cfg - > tiles_height_split [ i ] , prev_tile_split ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
break ;
2014-04-02 08:38:03 +00:00
}
if ( ( cfg - > tiles_height_split [ i ] % LCU_WIDTH ) ! = 0 ) {
fprintf ( stderr , " Input error: tile separation in height %d (at %d) is not at a multiple of LCU_WIDTH (%d) \n " , i , cfg - > tiles_height_split [ i ] , LCU_WIDTH ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
break ;
2014-04-02 08:38:03 +00:00
}
prev_tile_split = cfg - > tiles_height_split [ i ] ;
}
2015-06-29 12:50:15 +00:00
2016-03-07 15:21:40 +00:00
if ( cfg - > tiles_height_split [ cfg - > tiles_height_count - 2 ] > = cfg - > height ) {
fprintf ( stderr , " Input error: last tile separation in height (%d) should smaller than image height (%d) \n " , cfg - > tiles_height_split [ cfg - > tiles_height_count - 2 ] , cfg - > height ) ;
2015-06-29 12:50:15 +00:00
error = 1 ;
2014-04-02 08:38:03 +00:00
}
}
2015-06-29 12:50:15 +00:00
2016-08-03 05:18:56 +00:00
if ( cfg - > implicit_rdpcm & & ! cfg - > lossless ) {
fprintf ( stderr , " Input error: --implicit-rdpcm is not suppoted without --lossless \n " ) ;
error = 1 ;
}
2015-06-29 12:50:15 +00:00
return ! error ;
2014-03-10 13:53:23 +00:00
}