diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 24a5e46d9fa202a3f4cf1a7f9ac429b646550624..d824b11f3ed7ff1f1dc72b18f8b0947ec5b892b0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -69,7 +69,9 @@ stages: # compare to last target branch commit before pipeline was created - target_commit=$(git log $CI_MERGE_REQUEST_TARGET_BRANCH_NAME -1 --oneline --before=${CI_PIPELINE_CREATED_AT} --format=%H) - +.check-for-testvectors: &check-for-testvectors + # check if the testvector files specified in scripts/config/ci_linux*.json are present + - python3 -m pytest tests/ci/test_vectors_available.py .merge-request-comparison-setup-codec: &merge-request-comparison-setup-codec ### build test binaries, initial clean for paranoia reasons @@ -660,30 +662,35 @@ clang-format-check: expose_as: 'formatting patch' # check for crashes if first received frame on decoder side is an SID -.check-first-frame-is-sid: +check-first-frame-is-sid: extends: - .test-job-linux-needs-testv-dir - .rules-merge-request tags: - ivas-linux stage: test - needs: ["build-codec-linux-cmake"] + # needs: ["build-codec-linux-cmake"] script: - *print-common-info - *update-ltv-repo + - *check-for-testvectors - cmake . - make -j # TODO: for some MASA modes, we currently do not have testvectors that actually trigger DTX - - modes=$(scripts/runIvasCodec.py -l | grep dtx | grep -v MASA) - - echo $modes - - scripts/runIvasCodec.py -p scripts/config/ci_linux_sidstart_test.json -m $modes -s --bs_length 500 + # SBA is run separately to use shorter part of file + - modes=$(scripts/runIvasCodec.py -l | grep dtx | grep -v MASA | grep -v SBA) + - scripts/runIvasCodec.py -p scripts/config/ci_linux_sidstart_test.json -m $modes -s --bs_length 500 -U 0:20 || exit_code_no_sba=$? + - modes=$(scripts/runIvasCodec.py -l | grep dtx | grep SBA) + - scripts/runIvasCodec.py -p scripts/config/ci_linux_sidstart_test.json -m $modes -s --bs_length 500 -U 70:80 || exit_code_sba=$? + - if [ $exit_code_no_sba != 0 || $exit_code_sba != 0]; then exit 1; fi artifacts: paths: - out/logs when: on_failure name: "$CI_JOB_NAME--$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--sidstart" expose_as: "logs-sidstart" + expire_in: "5 days" # --------------------------------------------------------------- # Test jobs for main branch diff --git a/lib_com/options.h b/lib_com/options.h index 7350f8ec6ef6c2e642783a70a944d2b7fd24c729..e51736a79f1ce27b32fa6e781a6eba17427770b1 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -159,6 +159,9 @@ #define IGF_TUNING_96 /* FhG: Issue 546: slight tuning of IGF config used in 96 kbps stereo, 128 kbps SBA and others */ +#define FIX_522_ISM_FIRST_SID /* VA: fix ISM decoder crash if first received frame is an SID */ + + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index b746baf47b7e448f196aba3a96d081f709928e96..00b8d49d0c1403978025df68ab9543e944679fc3 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -282,6 +282,37 @@ ivas_error ivas_dec_setup( st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate; } } + +#ifdef FIX_522_ISM_FIRST_SID + if ( st_ivas->ini_frame == 0 && st_ivas->ivas_format == ISM_FORMAT ) + { + /* read the number of objects */ + st_ivas->nchan_transport = 1; + nchan_ism = 1; + k = (int16_t) ( ( ivas_total_brate / FRAMES_PER_SEC ) - 1 ) - SID_FORMAT_NBITS; + while ( st_ivas->bit_stream[k] && nchan_ism < MAX_NUM_OBJECTS ) + { + nchan_ism++; + k--; + } + k--; + + st_ivas->nchan_ism = nchan_ism; + + /* read ism_mode */ + if ( nchan_ism > 2 ) + { + k -= nchan_ism; /* SID metadata flags */ + idx = st_ivas->bit_stream[k]; + st_ivas->ism_mode = (ISM_MODE) ( idx + 1 ); + } + + if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif } /*-------------------------------------------------------------------* diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 66b69c6a2c3601b1aa950f566201f57cf0e31d15..6da3c05e75051ff3856ac07b1aaff494d1df321e 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -67,7 +67,6 @@ static ivas_error ivas_ism_bitrate_switching( RENDERER_TYPE renderer_type_old; error = IVAS_ERR_OK; - nCPE_old = st_ivas->nCPE; nSCE_old = st_ivas->nSCE; @@ -205,12 +204,7 @@ static ivas_error ivas_ism_bitrate_switching( ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); /* Open Crend Binaural renderer */ - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), - st_ivas->intern_config, - st_ivas->hOutSetup.output_config, - st_ivas->hRenderConfig, - st_ivas->hSetOfHRTF, - st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; } @@ -364,10 +358,8 @@ ivas_error ivas_ism_dec_config( int16_t nchan_transport_old; error = IVAS_ERR_OK; - ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - /* Assumes that num of input objects are constant */ nchan_transport_old = st_ivas->nchan_ism; diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index 30f6c7442c2569d2682ec7a756be234ae9078571..eb14177b0b81d8190fbd69e09d3e9019afb056d6 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -138,18 +138,18 @@ static void ism_metadata_smooth( *-------------------------------------------------------------------------*/ ivas_error ivas_ism_metadata_dec( - const int32_t ism_total_brate, /* i : ISM total bitrate */ - const int16_t nchan_ism, /* i : number of ISM channels */ - int16_t *nchan_transport, /* o : number of transport channels */ - ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ - SCE_DEC_HANDLE hSCE[], /* i/o: SCE decoder handles */ - const int16_t bfi, /* i : bfi flag */ - int16_t nb_bits_metadata[], /* o : number of metadata bits */ - ISM_MODE ism_mode, /* i : ISM mode */ - ISM_DTX_DATA_DEC hISMDTX, /* i/o: ISM DTX structure */ - const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Config Handle */ - int16_t *ism_extmeta_active, /* i/o: Extended metadata active in renderer*/ - int16_t *ism_extmeta_cnt /* i/o: Number of change frames observed*/ + const int32_t ism_total_brate, /* i : ISM total bitrate */ + const int16_t nchan_ism, /* i : number of ISM channels */ + int16_t *nchan_transport, /* o : number of transport channels */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + SCE_DEC_HANDLE hSCE[], /* i/o: SCE decoder handles */ + const int16_t bfi, /* i : bfi flag */ + int16_t nb_bits_metadata[], /* o : number of metadata bits */ + ISM_MODE ism_mode, /* i : ISM mode */ + ISM_DTX_DATA_DEC hISMDTX, /* i/o: ISM DTX structure */ + const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Config Handle */ + int16_t *ism_extmeta_active, /* i/o: Extended metadata active in renderer */ + int16_t *ism_extmeta_cnt /* i/o: Number of change frames observed */ ) { int16_t ch, nb_bits_start = 0, last_bit_pos; @@ -634,6 +634,10 @@ ivas_error ivas_ism_metadata_dec_create( st_ivas->hIsmMetaData[ch]->last_true_azimuth = 0; st_ivas->hIsmMetaData[ch]->last_true_elevation = 0; +#ifdef FIX_522_ISM_FIRST_SID + st_ivas->hIsmMetaData[ch]->last_azimuth = 0; + st_ivas->hIsmMetaData[ch]->last_elevation = 0; +#endif ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] ); } @@ -659,7 +663,7 @@ static void decode_angle_indices( DEC_CORE_HANDLE st0, /* i/o: bitstream handle */ ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */ const int16_t non_diegetic_flag, /* i : Non diegetic flag */ - int16_t *flag_abs_angle1 /* o : Azimuth/yaw encoding mode */ + int16_t *flag_abs_angle1 /* o : Azimuth/yaw encoding mode */ ) { int16_t idx_angle1, nbits_diff_angle1, diff, sgn; diff --git a/scripts/config/ci_linux_sidstart_test.json b/scripts/config/ci_linux_sidstart_test.json index 3436d9eaea7fe55a06f705250065e3e1c4930e07..f3a564ab31c738778e34cb9e859b32289a9e9ae3 100644 --- a/scripts/config/ci_linux_sidstart_test.json +++ b/scripts/config/ci_linux_sidstart_test.json @@ -2,24 +2,24 @@ "afspPath": "not_needed", "utilPath": "/tools", "inpaths": { - "MONO": "/usr/local/testv/test_mono.wav", - "STEREO": "/usr/local/testv/test_stereo.wav", + "MONO": "/usr/local/testv/stv48n.wav", + "STEREO": "/usr/local/ltv/ltv48_STEREO.wav", "FOA": "/usr/local/ltv/ltv48_FOA.wav", "HOA2": "/usr/local/ltv/ltv48_HOA2.wav", "HOA3": "/usr/local/ltv/ltv48_HOA3.wav", "SBA": "/usr/local/ltv/ltv48_HOA3.wav", - "MASA1TC1DIR": "/usr/local/testv/test_MASA_1dir1TC.wav", - "MASA1TC2DIR": "/usr/local/testv/test_MASA_2dir1TC.wav", - "MASA2TC1DIR": "/usr/local/testv/test_MASA_1dir2TC.wav", - "MASA2TC2DIR": "/usr/local/testv/test_MASA_2dir2TC.wav", - "5_1": "/usr/local/testv/test_MC51.wav", - "5_1_2": "/usr/local/testv/test_MC51p2.wav", - "5_1_4": "/usr/local/testv/test_MC51p4.wav", - "7_1": "/usr/local/testv/test_MC71.wav", - "7_1_4": "/usr/local/testv/test_MC71p4.wav", - "ISM1": "/usr/local/testv/test_mono.wav", - "ISM2": "/usr/local/testv/test_ISM_2obj.wav", - "ISM3": "/usr/local/testv/test_ISM_3obj.wav", - "ISM4": "/usr/local/testv/test_ISM_4obj.wav" + "MASA1TC1DIR": "/usr/local/testv/stv1MASA1TC48n.wav", + "MASA1TC2DIR": "/usr/local/testv/stv2MASA1TC48c.wav", + "MASA2TC1DIR": "/usr/local/testv/stv1MASA2TC48n.wav", + "MASA2TC2DIR": "/usr/local/testv/stv2MASA2TC48c.wav", + "5_1": "/usr/local/testv/stv51MC48c.wav", + "5_1_2": "/usr/local/testv/stv512MC48c.wav", + "5_1_4": "/usr/local/testv/stv514MC48c.wav", + "7_1": "/usr/local/testv/stv71MC48c.wav", + "7_1_4": "/usr/local/testv/stv714MC48c.wav", + "ISM1": "/usr/local/ltv/ltv48_1ISM.wav", + "ISM2": "/usr/local/ltv/ltv48_2ISM.wav", + "ISM3": "/usr/local/ltv/ltv48_3ISM.wav", + "ISM4": "/usr/local/ltv/ltv48_4ISM.wav" } } diff --git a/scripts/pyivastest/IvasModeRunner.py b/scripts/pyivastest/IvasModeRunner.py index cabf7d424bb45dd19eeb61782e831bf5fc4aa4b7..85515e824d25aec5ddd840002e6fa448b98ee8fb 100644 --- a/scripts/pyivastest/IvasModeRunner.py +++ b/scripts/pyivastest/IvasModeRunner.py @@ -182,7 +182,7 @@ class IvasModeRunner(IvasModeCollector.IvasModeCollector): self.max_workers = max_workers self.flat_output_structure = flat_output_structure self.limit_duration = False - self.max_duration = 0.0 + self.end_time = 0.0 self.start_time = 0.0 self.encoder_cmdline_options = [] self.decoder_cmdline_options = [] @@ -542,7 +542,7 @@ class IvasModeRunner(IvasModeCollector.IvasModeCollector): str(sample_rate_in), "_", config["cmd"]["in_config"].upper(), - "_L{}-{}s".format("_".join(str(self.start_time).split(".")), "_".join(str(self.max_duration).split("."))), + "_L{}-{}s".format("_".join(str(self.start_time).split(".")), "_".join(str(self.end_time).split("."))), ".pcm", ] ) @@ -613,13 +613,14 @@ class IvasModeRunner(IvasModeCollector.IvasModeCollector): if start_time_samples >= in_len: raise RuntimeError("Signal is shorter than given start time") - cut_len_samples = int(float(self.max_duration) * fs) + end_time_samples = int(float(self.end_time) * fs) + cut_len_samples = end_time_samples - start_time_samples if cut_len_samples + start_time_samples < in_len or start_time_samples > 0: - out_len = min(cut_len_samples, in_len - start_time_samples) - sig = ar.cut(sig, (start_time_samples, out_len)) + end_time_samples = min(end_time_samples, in_len) + sig = ar.cut(sig, (start_time_samples, end_time_samples)) - pcm_log.write("Limit signal length to {}:{} samples".format(start_time_samples, out_len)) + pcm_log.write("Limit signal length to {}:{} samples".format(start_time_samples, end_time_samples)) af.writefile(pcm_name_cpy_transformed, sig, fs) resamp_in_path = pcm_name_cpy_transformed diff --git a/scripts/pyivastest/IvasScriptsCommon.py b/scripts/pyivastest/IvasScriptsCommon.py index ec501d0154219e3556f656024e1aa8de4eb38130..987ce9727acf32120a713882bad3b0b9e1aacb33 100644 --- a/scripts/pyivastest/IvasScriptsCommon.py +++ b/scripts/pyivastest/IvasScriptsCommon.py @@ -563,7 +563,7 @@ def runner_setup(runner, args): except ValueError: raise ValueError(f"Given duration string {arg} is invalid") - runner.max_duration = end + runner.end_time = end runner.start_time = start if "fer_file" in args.keys() or "ber_file" in args.keys(): diff --git a/tests/ci/test_vectors_available.py b/tests/ci/test_vectors_available.py new file mode 100644 index 0000000000000000000000000000000000000000..42a9945d82500d7c47f0ad602f699231d5385ad6 --- /dev/null +++ b/tests/ci/test_vectors_available.py @@ -0,0 +1,19 @@ +import pytest +import pathlib +import json +import itertools + +TEST_CONFIG_DIR = pathlib.Path(__file__).parent.parent.parent.joinpath("scripts/config") +TEST_CONFIGS = [f for f in TEST_CONFIG_DIR.iterdir() if f.name.startswith("ci_linux")] + +def get_testvectors_from_config(config) -> list: + with open(config) as f: + cfg = json.load(f) + return list(cfg["inpaths"].values()) + +TESTVECTORS = sorted(set(itertools.chain(*[get_testvectors_from_config(cfg) for cfg in TEST_CONFIGS]))) + +@pytest.mark.parametrize("testvector", TESTVECTORS) +def test_vectors_available(testvector): + if not pathlib.Path(testvector).exists(): + raise FileNotFoundError(f"Testvector {testvector} can not be found")