Skip to content

Commit

Permalink
Testing Changes
Browse files Browse the repository at this point in the history
Extend CRF range up to 70
Consistency improvements
CLI fixes
  • Loading branch information
gianni-rosato authored Mar 25, 2024
2 parents 9eaa28a + 78801d9 commit 13a4887
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Docs/Parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ For more information on valid values for specific keys, refer to the [EbEncSetti
|----------------------------------|----------------------------------|------------|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| **RateControlMode** | --rc | [0-2] | 0 | Rate control mode [0: CRF or CQP (if `--aq-mode` is 0) [Default], 1: VBR, 2: CBR] |
| **QP** | --qp | [1-63] | 35 | Initial QP level value |
| **CRF** | --crf | [1-63] | 35 | Constant Rate Factor value, setting this value is equal to `--rc 0 --aq-mode 2 --qp x` |
| **CRF** | --crf | [1-70] | 35 | Constant Rate Factor value, setting this value is equal to `--rc 0 --aq-mode 2 --qp x`, and can be set up in quarter-step increments |
| **TargetBitRate** | --tbr | [1-100000] | 2000 | Target Bitrate (kbps), only applicable for VBR and CBR encoding, also accepts `b`, `k`, and `m` suffixes |
| **MaxBitRate** | --mbr | [1-100000] | 0 | Maximum Bitrate (kbps) only applicable for CRF encoding, also accepts `b`, `k`, and `m` suffixes |
| **UseQpFile** | --use-q-file | [0-1] | 0 | Overwrite the encoder default picture based QP assignments and use QP values from `--qp-file` |
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ A new progress mode that provides more detailed information about the encoding p

Argument for providing a film grain table for synthetic film grain (similar to aomenc's '--film-grain-table=' argument).

- `Extended CRF`

Provides a more versatile and granular way to set CRF. Range has been expanded to 70 (from 63) to help with ultra-low bitrate encodes, and can now be set in quarter-step (0.25) increments.

### Modified Defaults

SVT-AV1-PSY has different defaults than mainline SVT-AV1 in order to provide better visual fidelity out of the box. They include:
Expand Down
8 changes: 7 additions & 1 deletion Source/API/EbSvtAv1Enc.h
Original file line number Diff line number Diff line change
Expand Up @@ -969,8 +969,14 @@ typedef struct EbSvtAv1EncConfiguration {
*/
int8_t sharpness;

/* @brief Q index for extended CRF support
* Value is internally determined by CRF parameter value
* Default is 0 if CRF is an integer
*/
uint8_t extended_crf_qindex_offset;

/*Add 128 Byte Padding to Struct to avoid changing the size of the public configuration struct*/
uint8_t padding[128 - 3 * sizeof(uint8_t) - sizeof(int8_t)];
uint8_t padding[128 - 4 * sizeof(uint8_t) - sizeof(int8_t)];

} EbSvtAv1EncConfiguration;

Expand Down
2 changes: 1 addition & 1 deletion Source/App/EncApp/EbAppConfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -1950,7 +1950,7 @@ uint32_t get_help(int32_t argc, char *const argv[]) {
printf(
"\x1b[1;4mUsage\x1b[0m: SvtAv1EncApp <options> <-b dst_filename> -i src_filename\n"
"\n"
"\x1b[1;4mExamples:\n"
"\x1b[1;4mExamples\x1b[0m:\n"
"Multi-pass encode (VBR):\n"
" SvtAv1EncApp <--stats svtav1_2pass.log> --passes 2 --rc 1 --tbr 1000 -b dst_filename "
"-i src_filename\n"
Expand Down
1 change: 1 addition & 0 deletions Source/App/EncApp/EbAppProcessCmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,7 @@ void process_output_stream_buffer(EncChannel *channel, EncApp *enc_app, int32_t
(app_cfg->frames_encoded * 1000)),
fps >= 1.0 ? fps : fps * 60,
fps >= 1.0 ? 's' : 'm');
break;
case 3:
if ((int)app_cfg->frames_to_be_encoded == -1) {
fprintf(stderr,
Expand Down
32 changes: 25 additions & 7 deletions Source/Lib/Encoder/Codec/EbRateControlProcess.c
Original file line number Diff line number Diff line change
Expand Up @@ -3239,11 +3239,16 @@ void *svt_aom_rate_control_kernel(void *input_ptr) {
}

if (scs->static_config.rate_control_mode == SVT_AV1_RC_MODE_CQP_OR_CRF) {
const int32_t scs_qindex = CLIP3(MIN_Q_INDEX,
MAX_Q_INDEX,
quantizer_to_qindex[(uint8_t)scs->static_config.qp] + scs->static_config.extended_crf_qindex_offset);

// if RC mode is 0, fixed QP is used
// QP scaling based on POC number for Flat IPPP structure
// make sure no run to run is cause
if (pcs->ppcs->seq_param_changed)
rc->active_worst_quality = quantizer_to_qindex[(uint8_t)scs->static_config.qp];
if (pcs->ppcs->seq_param_changed) {
rc->active_worst_quality = scs_qindex;
}
frm_hdr->quantization_params.base_q_idx = quantizer_to_qindex[pcs->picture_qp];
if (pcs->ppcs->qp_on_the_fly == TRUE) {
pcs->picture_qp = (uint8_t)CLIP3((int32_t)scs->static_config.min_qp_allowed,
Expand All @@ -3253,36 +3258,44 @@ void *svt_aom_rate_control_kernel(void *input_ptr) {

} else {
if (scs->enable_qp_scaling_flag) {
const int32_t qindex = quantizer_to_qindex[(uint8_t)scs->static_config.qp];
// if there are need enough pictures in the LAD/SlidingWindow, the adaptive QP scaling is not used
int32_t new_qindex;
// if CRF
if (pcs->ppcs->tpl_ctrls.enable) {
if (pcs->picture_number == 0) {
rc->active_worst_quality = quantizer_to_qindex[(uint8_t)scs->static_config.qp];
rc->active_worst_quality = scs_qindex;
av1_rc_init(scs);
}
new_qindex = crf_qindex_calc(pcs, rc, rc->active_worst_quality);
} else // if CQP
new_qindex = cqp_qindex_calc(pcs, qindex);
new_qindex = cqp_qindex_calc(pcs, scs_qindex);
frm_hdr->quantization_params.base_q_idx = (uint8_t)CLIP3(
(int32_t)quantizer_to_qindex[scs->static_config.min_qp_allowed],
(int32_t)quantizer_to_qindex[scs->static_config.max_qp_allowed],
(int32_t)(new_qindex));
}

if (scs->static_config.use_fixed_qindex_offsets) {
if (scs->static_config.use_fixed_qindex_offsets || scs->static_config.tune == 3 || scs->static_config.extended_crf_qindex_offset) {
int32_t qindex = scs->static_config.use_fixed_qindex_offsets == 1
? quantizer_to_qindex[(uint8_t)scs->static_config.qp]
? scs_qindex
: frm_hdr->quantization_params
.base_q_idx; // do not shut the auto QPS if use_fixed_qindex_offsets 2

if (scs->static_config.tune == 3) {
qindex += (int32_t)rint(-pow(qindex / 48.0, 0.5) * pcs->temporal_layer_index); // Adaptive qindex offset based on temporal layer index (later is more boosted)
}

if (!frame_is_intra_only(pcs->ppcs)) {
qindex += scs->static_config.qindex_offsets[pcs->temporal_layer_index];
} else {
qindex += scs->static_config.key_frame_qindex_offset;
}

// Extended CRF range (63.25 - 70), add offset to all temporal layers to truncate QP scaling
if (scs->static_config.qp == MAX_QP_VALUE && scs->static_config.extended_crf_qindex_offset) {
qindex += scs->static_config.extended_crf_qindex_offset;
}

qindex = CLIP3(quantizer_to_qindex[scs->static_config.min_qp_allowed],
quantizer_to_qindex[scs->static_config.max_qp_allowed],
qindex);
Expand All @@ -3301,6 +3314,11 @@ void *svt_aom_rate_control_kernel(void *input_ptr) {
chroma_qindex += scs->static_config.chroma_qindex_offsets[pcs->temporal_layer_index];
}

if (scs->static_config.tune == 3) {
chroma_qindex += -rint(chroma_qindex / 8.0); // Chroma boost to fix saturation issues
}

chroma_qindex += scs->static_config.extended_crf_qindex_offset;
chroma_qindex = CLIP3(quantizer_to_qindex[scs->static_config.min_qp_allowed],
quantizer_to_qindex[scs->static_config.max_qp_allowed],
chroma_qindex);
Expand Down
3 changes: 3 additions & 0 deletions Source/Lib/Encoder/Globals/EbEncHandle.c
Original file line number Diff line number Diff line change
Expand Up @@ -4599,6 +4599,9 @@ static void copy_api_from_app(

// Sharpness
scs->static_config.sharpness = config_struct->sharpness;

// Extended CRF
scs->static_config.extended_crf_qindex_offset = config_struct->extended_crf_qindex_offset;
return;
}

Expand Down
50 changes: 43 additions & 7 deletions Source/Lib/Encoder/Globals/EbEncSettings.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,21 @@ EbErrorType svt_av1_verify_settings(SequenceControlSet *scs) {
return_error = EB_ErrorBadParameter;
}

if ((config->enable_adaptive_quantization || config->variance_boost_strength) && config->extended_crf_qindex_offset > (7 * 4)) {
SVT_ERROR("Instance %u: %s must be [0 - %d]\n",
channel_number + 1,
"CRF",
70);
return_error = EB_ErrorBadParameter;
}
if (config->qp > MAX_QP_VALUE) {
SVT_ERROR("Instance %u: %s must be [0 - %d]\n",
channel_number + 1,
config->enable_adaptive_quantization ? "CRF" : "QP",
MAX_QP_VALUE);
return_error = EB_ErrorBadParameter;
}

if (config->hierarchical_levels > 5) {
SVT_ERROR("Instance %u: Hierarchical Levels supported [0-5]\n", channel_number + 1);
return_error = EB_ErrorBadParameter;
Expand Down Expand Up @@ -1054,6 +1062,7 @@ EbErrorType svt_av1_set_default_params(EbSvtAv1EncConfiguration *config_ptr) {
config_ptr->variance_octile = 6;
config_ptr->enable_alt_curve = 0;
config_ptr->sharpness = 0;
config_ptr->extended_crf_qindex_offset = 0;
return return_error;
}

Expand All @@ -1072,6 +1081,10 @@ static const char *level_to_str(unsigned in) {
return ret;
}

static double get_extended_crf(EbSvtAv1EncConfiguration *config_ptr) {
return (double)config_ptr->qp + (double)config_ptr->extended_crf_qindex_offset / 4;
}

//#define DEBUG_BUFFERS
void svt_av1_print_lib_params(SequenceControlSet *scs) {
EbSvtAv1EncConfiguration *config = &scs->static_config;
Expand Down Expand Up @@ -1130,16 +1143,16 @@ void svt_av1_print_lib_params(SequenceControlSet *scs) {
if (config->max_bit_rate)
SVT_INFO(
"SVT [config]: BRC mode / %s / max bitrate (kbps)\t\t\t: %s / %d / "
"%d\n",
"%.2f\n",
scs->tpl || scs->static_config.variance_boost_strength ? "rate factor" : "CQP Assignment",
scs->tpl || scs->static_config.variance_boost_strength ? "capped CRF" : "CQP",
scs->static_config.qp,
get_extended_crf(config),
(int)config->max_bit_rate / 1000);
else
SVT_INFO("SVT [config]: BRC mode / %s \t\t\t\t\t: %s / %d \n",
SVT_INFO("SVT [config]: BRC mode / %s \t\t\t\t\t: %s / %.2f \n",
scs->tpl || scs->static_config.variance_boost_strength ? "rate factor" : "CQP Assignment",
scs->tpl || scs->static_config.variance_boost_strength ? "CRF" : "CQP",
scs->static_config.qp);
get_extended_crf(config));
break;
case SVT_AV1_RC_MODE_VBR:
SVT_INFO("SVT [config]: BRC mode / target bitrate (kbps)\t\t\t\t: VBR / %d \n",
Expand Down Expand Up @@ -1298,6 +1311,21 @@ static EbErrorType str_to_uint(const char *nptr, uint32_t *out, char **nextptr)
return EB_ErrorNone;
}

static EbErrorType str_to_double(const char *nptr, double *out, char **nextptr) {
char *endptr;
double val;

val = strtod(nptr, &endptr);

if (endptr == nptr || (!nextptr && *endptr))
return EB_ErrorBadParameter;

*out = val;
if (nextptr)
*nextptr = endptr;
return EB_ErrorNone;
}

//assume the input list of values are in the format of "[v1,v2,v3,...]"
static EbErrorType parse_list_s32(const char *nptr, int32_t *list, size_t n) {
const char *ptr = nptr;
Expand Down Expand Up @@ -1424,16 +1452,24 @@ static EbErrorType str_to_bool(const char *nptr, Bool *out) {
}

static EbErrorType str_to_crf(const char *nptr, EbSvtAv1EncConfiguration *config_struct) {
uint32_t crf;
double crf;
EbErrorType return_error;

return_error = str_to_uint(nptr, &crf, NULL);
return_error = str_to_double(nptr, &crf, NULL);

if (return_error == EB_ErrorBadParameter)
return return_error;
if (crf < 0)
return EB_ErrorBadParameter;

uint32_t extended_q_index = (uint32_t)(crf * 4);
uint32_t qp = AOMMIN(MAX_QP_VALUE, (uint32_t)crf);
uint32_t extended_crf_qindex_offset = extended_q_index - qp * 4;

config_struct->qp = crf;
config_struct->qp = qp;
config_struct->rate_control_mode = SVT_AV1_RC_MODE_CQP_OR_CRF;
config_struct->enable_adaptive_quantization = 2;
config_struct->extended_crf_qindex_offset = extended_crf_qindex_offset;

return EB_ErrorNone;
}
Expand Down

0 comments on commit 13a4887

Please sign in to comment.