diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 625a3cc8bcd812e91926c2e909a1188ae8016e3e..e8099bb83dfdbed426684ef93cbdb706a4191efd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,11 +24,14 @@ variables: - 'ivas-conformance' - 'ivas-conformance-linux' - 'check-float-reference' + - 'check-clipping' - 'test-branch-vs-input-passthrough' + GIT_CLEAN_FLAGS: -ffdxq TESTCASE_TIMEOUT_STV_SANITIZERS: 180 TESTCASE_TIMEOUT_LTV_SANITIZERS: 1200 BASOP_REFERENCE_BRANCH: "ivas-float-update" + SCALE_FACTOR: "3.162" default: @@ -70,6 +73,9 @@ workflow: - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'check-float-reference' variables: IVAS_PIPELINE_NAME: 'check-float-reference: $CI_COMMIT_BRANCH' + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'check-clipping' + variables: + IVAS_PIPELINE_NAME: 'Check core input clipping: $CI_COMMIT_BRANCH' - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'test-branch-vs-input-passthrough' variables: IVAS_PIPELINE_NAME: 'Pass-through comparison vs input: $CI_COMMIT_BRANCH' @@ -125,6 +131,11 @@ stages: # automatically disable #DEBUGGING macro in options.h using /**/-comment - sed -i.bak -e "s/^[[:space:]]*\(#define[[:space:]]*DEBUGGING\)/\/\*\1\*\//g" lib_com/options.h +.enable-debugging-macro: &enable-debugging-macro +# automatically enable #DEBUGGING macro in options.h using either /**/-comment or //-comment + - sed -i.bak -e "s/\/\*\ *\(#define\ *DEBUGGING\ *\)\*\//\1/g" lib_com/options.h + - sed -i.bak -e "s/\/\/\ *\(#define\ *DEBUGGING\ *\)/\1/g" lib_com/options.h + .merge-request-comparison-setup-codec: &merge-request-comparison-setup-codec ### build test binaries, initial clean for paranoia reasons - *disable-debugging-macro @@ -268,6 +279,7 @@ stages: when: never - if: $MANUAL_PIPELINE_TYPE == 'check-float-reference' when: never + - if: $MANUAL_PIPELINE_TYPE == 'check-clipping' - if: $MANUAL_PIPELINE_TYPE == 'test-branch-vs-input-passthrough' when: never - when: on_success @@ -1644,6 +1656,36 @@ test-long-self-test: junit: - report-junit-ltv.xml +check-clipping: + tags: + - ivas-linux + stage: test + timeout: "30 minutes" + rules: + - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == 'check-clipping' + allow_failure: + exit_codes: + - 123 + script: + - *print-common-info + - *enable-debugging-macro + - make -j + - tests/scale_pcm.py ./scripts/testv/ $SCALE_FACTOR # Default: 3.162 (+10 dB). Can be set in manual trigger. + - python3 -m pytest $TESTS_DIR_CODEC_BE_ON_MR -v --update_ref 1 --html=report.html --self-contained-html --junit-xml=report-junit.xml --ref_encoder_path ./IVAS_cod --ref_decoder_path ./IVAS_dec + - python3 scripts/parse_xml_report.py report-junit.xml report.csv --clipping + artifacts: + name: "check-clipping--sha-$CI_COMMIT_SHORT_SHA--results" + when: always + expire_in: 2 weeks + paths: + - report-junit.xml + - report.html + - report.csv + expose_as: "check-clipping results" + reports: + junit: + - report-junit.xml + test-branch-vs-input-passthrough: tags: - ivas-linux @@ -1679,6 +1721,7 @@ test-branch-vs-input-passthrough: junit: - report-junit.xml + # --------------------------------------------------------------- # Scheduled jobs on main # --------------------------------------------------------------- diff --git a/apps/encoder.c b/apps/encoder.c index f64986ec84806593f683db4f9412aa275b7ede47..4caa60803d8cad63471931608cc2cb2e719d65b9 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -195,6 +195,8 @@ int main( #ifdef DEBUG_SBA int16_t numTransportChannels = 1; #endif + int32_t noClipping; + float maxOverload, minOverload; #endif #ifdef DEBUGGING @@ -792,6 +794,12 @@ int main( } #ifdef DEBUGGING + if ( ( noClipping = IVAS_ENC_GetNoCLipping( hIvasEnc, &maxOverload, &minOverload ) ) > 0 ) + { + fprintf( stdout, "Core input overload detected: %d samples!!!\n", noClipping ); + fprintf( stdout, "Max overload value: %f \n", maxOverload ); + fprintf( stdout, "Min overload value: %f \n\n", minOverload ); + } print_snr(); #endif /*------------------------------------------------------------------------------------------* diff --git a/lib_com/prot.h b/lib_com/prot.h index c8f70bb4fc22ff2de71e2429edccfeb865f51127..1df0eb7838c43f12e504e570a71dbc1474407f8c 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -222,6 +222,17 @@ void mvs2s( const int16_t n /* i : vector size */ ); +#ifdef DEBUGGING +/*! r: number of overload samples */ +uint32_t check_clipping( + const float x[], /* i : input vector */ + const int16_t n, /* i : vector size */ + float *maxOverload, /* i/o: max overload value */ + float *minOverload /* i/o: max overload value */ +); + +#endif +/*! r: number of clipped samples */ uint32_t mvr2s( const float x[], /* i : input vector */ int16_t y[], /* o : output vector */ diff --git a/lib_com/tools.c b/lib_com/tools.c index 9dfa8b9f81bc999cb6770fafc2cba16d6303fd53..b235d5d499d17299577b47a33f41da52aaa7e671 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -373,6 +373,46 @@ void mvs2s( return; } +#ifdef DEBUGGING +/*! r: number of overload samples */ +uint32_t check_clipping( + const float x[], /* i : input vector */ + const int16_t n, /* i : vector size */ + float *maxOverload, /* i/o: max overload value */ + float *minOverload /* i/o: max overload value */ +) +{ + int16_t i; + float temp; + uint32_t noClipping = 0; + + for ( i = 0; i < n; i++ ) + { + temp = x[i]; + + if ( temp >= ( MAX16B_FLT + 0.5f ) ) + { + noClipping++; + if ( temp > *maxOverload ) + { + *maxOverload = temp; + } + } + else if ( temp <= ( MIN16B_FLT - 0.5f ) ) + { + noClipping++; + if ( temp < *minOverload ) + { + *minOverload = temp; + } + } + } + + return noClipping; +} + +#endif +/*! r: number of clipped samples */ uint32_t mvr2s( const float x[], /* i : input vector */ int16_t y[], /* o : output vector */ diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index a3a2bec2573d72bcaa9d7b193ecede972e1c3900..292cbd6a5fc4d2738e8d0b94c3c76600dffb7fd9 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -471,6 +471,10 @@ ivas_error ivas_cpe_enc( for ( n = 0; n < n_CoreChannels; n++ ) { +#ifdef DEBUGGING + st_ivas->noClipping += check_clipping( hCPE->hCoreCoder[n]->input, input_frame, &st_ivas->maxOverload, &st_ivas->minOverload ); + +#endif error = pre_proc_front_ivas( NULL, hCPE, hCPE->element_brate, nb_bits_metadata, input_frame, n, old_inp_12k8[n], old_inp_16k[n], &ener[n], &relE[n], A[n], Aw[n], epsP[n], lsp_new[n], lsp_mid[n], &vad_hover_flag[n], &attack_flag[n], realBuffer[n], imagBuffer[n], old_wsp[n], pitch_fr[n], voicing_fr[n], &loc_harm[n], &cor_map_sum[n], &vad_flag_dtx[n], enerBuffer[n], diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 05621dfaaaf765870ec498d27afefef931b71ce9..48a3286a4ed55b74249f954b260f6663d7e8b706 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -410,6 +410,11 @@ ivas_error ivas_init_encoder( st_ivas->nchan_transport = -1; +#ifdef DEBUGGING + st_ivas->noClipping = 0; + st_ivas->maxOverload = 0; + st_ivas->minOverload = 0; +#endif /*-----------------------------------------------------------------* * Allocate floating-point input audio buffers *-----------------------------------------------------------------*/ diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 6e2732f44a4e3e5c34d70b033f1023522519658b..c72431bd0bbba983877532e2df681f8215524060 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -172,6 +172,10 @@ ivas_error ivas_ism_enc( * Front Pre-processing *----------------------------------------------------------------*/ +#ifdef DEBUGGING + st_ivas->noClipping += check_clipping( hSCE->hCoreCoder[0]->input, input_frame, &st_ivas->maxOverload, &st_ivas->minOverload ); + +#endif error = pre_proc_front_ivas( hSCE, NULL, hSCE->element_brate, nb_bits_metadata[sce_id], input_frame, 0, old_inp_12k8[sce_id][0], old_inp_16k[sce_id][0], &ener[sce_id][0], &relE[sce_id][0], A[sce_id][0], Aw[sce_id][0], epsP[sce_id][0], lsp_new[sce_id][0], lsp_mid[sce_id][0], &vad_hover_flag[sce_id][0], &attack_flag[sce_id][0], realBuffer[sce_id][0], imagBuffer[sce_id][0], old_wsp[sce_id][0], pitch_fr[sce_id][0], voicing_fr[sce_id][0], &loc_harm[sce_id][0], &cor_map_sum[sce_id][0], &vad_flag_dtx[sce_id][0], enerBuffer[sce_id][0], diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index 8f5d472ea95f605c7159b8a4001d6260bbc2c12d..257e8061953cd4b5d4e58d9cca2c7f6aac579660 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -180,6 +180,10 @@ ivas_error ivas_sce_enc( * Front Pre-processing *----------------------------------------------------------------*/ +#ifdef DEBUGGING + st_ivas->noClipping += check_clipping( hSCE->hCoreCoder[0]->input, input_frame, &st_ivas->maxOverload, &st_ivas->minOverload ); + +#endif error = pre_proc_front_ivas( hSCE, NULL, hSCE->element_brate, nb_bits_metadata, input_frame, 0, old_inp_12k8[0], old_inp_16k[0], &ener[0], &relE[0], A[0], Aw[0], epsP[0], lsp_new[0], lsp_mid[0], &vad_hover_flag[0], &attack_flag[0], realBuffer[0], imagBuffer[0], old_wsp[0], pitch_fr[0], voicing_fr[0], &loc_harm[0], &cor_map_sum[0], &vad_flag_dtx[0], enerBuffer[0], diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 4bb9a5f417688a732afcf8b227b81c76c1ba9035..ad844b95d5252e8250c6ab645d2dc5e6dfba8c5d 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1246,6 +1246,11 @@ typedef struct int16_t nCPE; /* number of total CPEs */ SCE_ENC_HANDLE hSCE[MAX_SCE]; /* SCE handles */ CPE_ENC_HANDLE hCPE[MCT_MAX_BLOCKS]; /* CPE handles */ +#ifdef DEBUGGING + int32_t noClipping; /* number of clipped samples */ + float maxOverload; /* Maximum overload value */ + float minOverload; /* Maximum overload value */ +#endif /* multichannel modules */ ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS]; /* ISM metadata handles (storage for one frame of read ISM metadata) */ diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 23e666a7f096a69cbc154b9d6515f4c7efea8923..acc1358db65f612d9e40e5df7a5be79cbbb4d949 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -2417,3 +2417,23 @@ static void init_encoder_config( return; } + +#ifdef DEBUGGING + +/*---------------------------------------------------------------------* + * IVAS_ENC_GetNoCLipping() + * + * return number of clipped samples + *---------------------------------------------------------------------*/ + +int32_t IVAS_ENC_GetNoCLipping( + IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ + float *maxOverload, /* o : Max overload value */ + float *minOverload /* o : Min overload value */ +) +{ + *maxOverload = hIvasEnc->st_ivas->maxOverload; + *minOverload = hIvasEnc->st_ivas->minOverload; + return hIvasEnc->st_ivas->noClipping; +} +#endif diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 2f40c1ab1beda5b883618dbd755b2a68076989f0..7ece6666523f1320245369cd700ef2e732054fd4 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -383,6 +383,13 @@ void IVAS_ENC_PrintDisclaimer( void ); +#ifdef DEBUGGING +int32_t IVAS_ENC_GetNoCLipping( + IVAS_ENC_HANDLE hIvasEnc, /* i : IVAS encoder handle */ + float *maxOverload, /* o : Max overload value */ + float *minOverload /* o : Min overload value */ +); +#endif /* clang-format on */ #endif /* LIB_ENC_H */ diff --git a/scripts/parse_xml_report.py b/scripts/parse_xml_report.py index e0f02238e4fddd970567023b2637975e4ead4213..902b31f0acfd1ad27a1413e7fc06cc4f6717f7be 100644 --- a/scripts/parse_xml_report.py +++ b/scripts/parse_xml_report.py @@ -67,11 +67,16 @@ if __name__ == "__main__": action="store_true", help="Parse using EVS 26.444 formats", ) + parser.add_argument( + "--clipping", + action="store_true", + help="Extract clipping information. Available if encoder has been run with DEBUGGING active.", + ) parser.add_argument( "--skip_formats", action="store_true", help="Parse without formats and categories. Suitable for general tests which do not match the IVAS categories.", - ) + ) args = parser.parse_args() xml_report = args.xml_report csv_file = args.csv_file @@ -80,6 +85,11 @@ if __name__ == "__main__": if args.evs: FORMATS = EVS_FORMATS CATEGORIES = EVS_CATEGORIES + else: + FORMATS = IVAS_FORMATS + CATEGORIES = IVAS_CATEGORIES + if args.clipping: + PROPERTIES += ["ENC_CORE_OVL","MAX_OVL","MIN_OVL"] if args.skip_formats: FORMATS = NO_FORMATS CATEGORIES = NO_CATEGORIES diff --git a/tests/codec_be_on_mr_nonselection/test_param_file.py b/tests/codec_be_on_mr_nonselection/test_param_file.py index 5d6b5cbaa1fa7b3bb126d6da34f7c7e643d401bb..13a49c3f329c706fdc00f7cd7759889da1a9c564 100644 --- a/tests/codec_be_on_mr_nonselection/test_param_file.py +++ b/tests/codec_be_on_mr_nonselection/test_param_file.py @@ -151,7 +151,6 @@ def convert_test_string_to_tag(test_string): # hack to have stv/ltv/evs in the test name @pytest.mark.parametrize("param_file_id", [PARAM_FILE_ID]) def test_param_file_tests( - record_property, props_to_record, encoder_only, decoder_only, @@ -259,7 +258,7 @@ def test_param_file_tests( cmp_result_msg += enc_test_result_msg props = parse_properties(cmp_result_msg, False, props_to_record) for k, v in props.items(): - record_property(k, v) + dut_encoder_frontend.record_property(k, v) if enc_test_result: pytest.fail("Too high difference in encoder statistics found.") @@ -452,7 +451,7 @@ def test_param_file_tests( props = parse_properties(cmp_result_msg, output_differs, props_to_record) for k, v in props.items(): - record_property(k, v) + dut_decoder_frontend.record_property(k, v) metadata_differs = False diff --git a/tests/codec_be_on_mr_nonselection/test_sba.py b/tests/codec_be_on_mr_nonselection/test_sba.py index 885ac488ad36b2ec2cad0b1ae762c4536fa0cecb..e8ae17f55b6da65a09d6a00e624792640f728cd5 100644 --- a/tests/codec_be_on_mr_nonselection/test_sba.py +++ b/tests/codec_be_on_mr_nonselection/test_sba.py @@ -92,7 +92,6 @@ def check_and_makedir(dir_path): @pytest.mark.parametrize("tag", tag_list) @pytest.mark.parametrize("sampling_rate", sample_rate_list) def test_pca_enc( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -164,7 +163,6 @@ def test_pca_enc( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -200,7 +198,6 @@ def test_pca_enc( @pytest.mark.parametrize("gain_flag", gain_list) @pytest.mark.parametrize("sid", SID_list) def test_sba_enc_system( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -327,7 +324,7 @@ def test_sba_enc_system( enc_test_result_msg, enc_test_result != 0, props_to_record ) for k, v in props.items(): - record_property(k, v) + dut_encoder_frontend.record_property(k, v) # report compare result if enc_test_result != 0: @@ -335,7 +332,6 @@ def test_sba_enc_system( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -367,7 +363,6 @@ def test_sba_enc_system( @pytest.mark.parametrize("bitrate", ivas_br_HOA2) @pytest.mark.parametrize("tag", tag_list_HOA2) def test_spar_hoa2_enc_system( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -464,7 +459,7 @@ def test_spar_hoa2_enc_system( enc_test_result_msg, enc_test_result != 0, props_to_record ) for k, v in props.items(): - record_property(k, v) + dut_encoder_frontend.record_property(k, v) # report compare result if enc_test_result != 0: @@ -472,7 +467,6 @@ def test_spar_hoa2_enc_system( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -504,7 +498,6 @@ def test_spar_hoa2_enc_system( @pytest.mark.parametrize("bitrate", ivas_br_HOA3) @pytest.mark.parametrize("tag", tag_list_HOA3) def test_spar_hoa3_enc_system( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -595,7 +588,7 @@ def test_spar_hoa3_enc_system( enc_test_result_msg, enc_test_result != 0, props_to_record ) for k, v in props.items(): - record_property(k, v) + dut_encoder_frontend.record_property(k, v) # report compare result if enc_test_result != 0: @@ -603,7 +596,6 @@ def test_spar_hoa3_enc_system( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -637,7 +629,6 @@ def test_spar_hoa3_enc_system( @pytest.mark.parametrize("tag", tag_list_bw_force) @pytest.mark.parametrize("sample_rate_bw_idx", sample_rate_bw_idx_list) def test_sba_enc_BWforce_system( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -746,7 +737,7 @@ def test_sba_enc_BWforce_system( enc_test_result_msg, enc_test_result != 0, props_to_record ) for k, v in props.items(): - record_property(k, v) + dut_encoder_frontend.record_property(k, v) # report compare result if enc_test_result != 0: @@ -754,7 +745,6 @@ def test_sba_enc_BWforce_system( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -790,7 +780,6 @@ def test_sba_enc_BWforce_system( @pytest.mark.parametrize("sampling_rate", sample_rate_list) @pytest.mark.parametrize("gain_flag", gain_list) def test_sba_plc_system( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -886,7 +875,6 @@ def test_sba_plc_system( if not encoder_only: sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -1042,7 +1030,6 @@ def sba_enc( def sba_dec( - record_property, props_to_record, test_vector_path, dut_decoder_frontend, @@ -1158,7 +1145,7 @@ def sba_dec( text_to_parse = reason props = parse_properties(text_to_parse, cmp_result != 0, props_to_record) for k, v in props.items(): - record_property(k, v) + dut_decoder_frontend.record_property(k, v) # report compare result if cmp_result != 0: diff --git a/tests/conftest.py b/tests/conftest.py index 8f3e4e961bc7e87499d0c9af4642fe96d84f22ad..989f080c906d28e954d252c8aeec4d133242151c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -57,6 +57,12 @@ from .constants import ( ODG, MAX_ENC_DIFF, MAX_ENC_DIFF_PATTERN, + ENC_CORE_OVL, + ENC_CORE_OVL_PATTERN, + MAX_OVL, + MAX_OVL_PATTERN, + MIN_OVL, + MIN_OVL_PATTERN, SCRIPTS_DIR, ) @@ -322,11 +328,10 @@ def get_enc_stats(request) -> bool: @pytest.fixture(scope="session", autouse=True) def get_odg(request): """ - Return indication to compute ssnr during ref/dut comparison. + Return indication to compute PEAQ ODG during ref/dut comparison. """ return request.config.option.odg - @pytest.fixture(scope="session") def abs_tol(request) -> int: """ @@ -358,6 +363,8 @@ def dut_encoder_path(request) -> str: """ if request.config.option.dut_encoder_path: return request.config.option.dut_encoder_path + if request.config.option.update_ref == "1": + return None here = Path(__file__).parent.resolve() system = platform.system() @@ -378,13 +385,14 @@ def dut_encoder_path(request) -> str: class EncoderFrontend: - def __init__(self, path, enc_type, timeout=None) -> None: + def __init__(self, path, enc_type, record_property, timeout=None) -> None: self._path = Path(path).absolute() self._type = enc_type self.returncode = None self.stdout = None self.stderr = None self.timeout = timeout + self.record_property = record_property def extract_enc_stats( self, @@ -533,6 +541,15 @@ class EncoderFrontend: self.returncode = result.returncode self.stderr = result.stderr.decode("ascii") self.stdout = result.stdout.decode("ascii") + + # Record core encoder clipping + for (prop, pattern) in [(ENC_CORE_OVL,ENC_CORE_OVL_PATTERN),(MAX_OVL,MAX_OVL_PATTERN),(MIN_OVL,MIN_OVL_PATTERN)]: + val = 0 + search_result = re.search(pattern, self.stdout) + if search_result: + val = search_result.group(1) + self.record_property( prop, val ) + if self.stdout: stdout_str = textwrap.indent(self.stdout, prefix="\t") log_dbg_msg(f"{self._type} encoder stdout:\n{stdout_str}") @@ -559,16 +576,20 @@ class EncoderFrontend: @pytest.fixture(scope="function") -def dut_encoder_frontend(dut_encoder_path, request) -> EncoderFrontend: +def dut_encoder_frontend(dut_encoder_path, request, record_property) -> Union[None, EncoderFrontend]: """ Return a :class:`conftest.EncoderFrontend` instance as DUT for the test session. """ - timeout = request.config.getoption("--testcase_timeout") - encoder = EncoderFrontend(dut_encoder_path, "DUT", timeout=timeout) + encoder = None + + if dut_encoder_path: + timeout = request.config.getoption("--testcase_timeout") + encoder = EncoderFrontend(dut_encoder_path, "DUT", record_property, timeout=timeout) yield encoder - # Fixture teardown - encoder._check_run() + if encoder is not None: + # Fixture teardown + encoder._check_run() @pytest.fixture(scope="session") @@ -602,7 +623,7 @@ def ref_encoder_path(request) -> str: @pytest.fixture(scope="function") -def ref_encoder_frontend(ref_encoder_path, request) -> Union[None, EncoderFrontend]: +def ref_encoder_frontend(ref_encoder_path, request, record_property) -> Union[None, EncoderFrontend]: """ Return a :class:`conftest.EncoderFrontend` instance as REF for the test session. """ @@ -610,7 +631,7 @@ def ref_encoder_frontend(ref_encoder_path, request) -> Union[None, EncoderFronte if ref_encoder_path: timeout = request.config.getoption("--testcase_timeout") - encoder = EncoderFrontend(ref_encoder_path, "REF", timeout=timeout) + encoder = EncoderFrontend(ref_encoder_path, "REF", record_property, timeout=timeout) yield encoder @@ -627,6 +648,9 @@ def dut_decoder_path(request) -> str: if request.config.option.dut_decoder_path: return request.config.option.dut_decoder_path + if request.config.option.update_ref == "1": + return None + here = Path(__file__).parent.resolve() system = platform.system() @@ -646,7 +670,7 @@ def dut_decoder_path(request) -> str: class DecoderFrontend: - def __init__(self, path, dec_type, timeout=None, fr=20) -> None: + def __init__(self, path, dec_type, record_property, timeout=None, fr=20) -> None: self._path = str(Path(path).absolute()) self._type = dec_type self.returncode = None @@ -654,6 +678,7 @@ class DecoderFrontend: self.stderr = None self.timeout = timeout self.fr = fr + self.record_property = record_property def run( self, @@ -821,20 +846,21 @@ class DecoderFrontend: @pytest.fixture(scope="function") -def dut_decoder_frontend(dut_decoder_path, request) -> DecoderFrontend: +def dut_decoder_frontend(dut_decoder_path, request, record_property) -> Union[None, DecoderFrontend]: """ Return a :class:`conftest.DecoderFrontend` instance as DUT for the test session. """ - decoder = DecoderFrontend( - dut_decoder_path, - "DUT", - timeout=request.config.getoption("--testcase_timeout"), - fr=request.config.option.dut_fr, - ) + decoder = None + + if dut_decoder_path: + timeout = request.config.getoption("--testcase_timeout") + decoder = DecoderFrontend(dut_decoder_path, "DUT", record_property, timeout=timeout, fr=request.config.option.dut_fr) + yield decoder - # Fixture teardown - decoder._check_run() + if decoder is not None: + # Fixture teardown + decoder._check_run() @pytest.fixture(scope="session") @@ -868,7 +894,7 @@ def ref_decoder_path(request) -> str: @pytest.fixture(scope="function") -def ref_decoder_frontend(ref_decoder_path, request) -> Union[None, DecoderFrontend]: +def ref_decoder_frontend(ref_decoder_path, request, record_property) -> Union[None, DecoderFrontend]: """ Return a :class:`conftest.DecoderFrontend` instance as DUT for the test session. """ @@ -876,7 +902,7 @@ def ref_decoder_frontend(ref_decoder_path, request) -> Union[None, DecoderFronte if ref_decoder_path: timeout = request.config.getoption("--testcase_timeout") - decoder = DecoderFrontend(ref_decoder_path, "REF", timeout=timeout) + decoder = DecoderFrontend(ref_decoder_path, "REF", record_property, timeout=timeout) yield decoder @@ -1059,7 +1085,6 @@ def parse_properties(text_to_parse: str, output_differs: bool, props_to_record: if max_enc_diff: max_enc_diff = float(max_enc_diff) props[MAX_ENC_DIFF] = max_enc_diff - return props diff --git a/tests/constants.py b/tests/constants.py index c2e84e50b71834715df52eaebdfac22c1b15d838..36dabd0584c78e8f02e39ba90242654654fe38c6 100644 --- a/tests/constants.py +++ b/tests/constants.py @@ -12,7 +12,9 @@ MAX_ABS_DIFF = "MAXIMUM ABS DIFF" SSNR = "SSNR" ODG = "ODG" MAX_ENC_DIFF = "MAXIMUM ENC DIFF" - +ENC_CORE_OVL = "ENC_CORE_OVL" +MAX_OVL = "MAX_OVL" +MIN_OVL = "MIN_OVL" # regex patterns for parsing the output from comparisons -> mainly for BASOP ci MLD_PATTERN = r"MLD: ([\d\.]*)" @@ -21,6 +23,9 @@ ODG_PATTERN_PQEVALAUDIO = r"Objective Difference Grade: (-*\d*\.\d*)" ODG_PATTERN = r"ODG: (-*\d*\.\d*)" SSNR_PATTERN = r"Channel \d* SSNR: (nan|[+-]*inf|[-*\d\.]*)" MAX_ENC_DIFF_PATTERN = r"MAXIMUM ENC DIFF: (\d+) \((\d+\.\d+)%\)" +ENC_CORE_OVL_PATTERN = r"Core input overload detected: (\d+)" +MAX_OVL_PATTERN = r"Max overload value: (\d+\.\d+)" +MIN_OVL_PATTERN = r"Min overload value: (-*\d+\.\d+)" # minimum difference between ref and dut encoder file lengths diff --git a/tests/test_26444.py b/tests/test_26444.py index fa6214c66a8c5164ba636346839c8041aa7ae197..08d0ff77c5baed9e51243046d39040e97627d073 100644 --- a/tests/test_26444.py +++ b/tests/test_26444.py @@ -78,7 +78,6 @@ for s in scripts: @pytest.mark.parametrize("test_tag", list(test_dict.keys())) def test_evs_26444( - record_property, props_to_record, dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, @@ -180,7 +179,7 @@ def test_evs_26444( props = parse_properties(reason, output_differs, props_to_record) for k, v in props.items(): - record_property(k, v) + ref_decoder_frontend.record_property(k, v) equal &= not output_differs else: