From 1584d065f06205aed51a6c7e36c8ca45fa3c18ad Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Tue, 21 Oct 2025 16:43:11 +0200 Subject: [PATCH 01/20] add IVAS ISAR encoder command and ISAR EXT REND command --- scripts/parse_commands.py | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/scripts/parse_commands.py b/scripts/parse_commands.py index 3a5fb6c1af..951433fa37 100644 --- a/scripts/parse_commands.py +++ b/scripts/parse_commands.py @@ -13,7 +13,7 @@ if __name__ == '__main__': parser.add_argument('txt_file',type=str,help='Output txt file, e.g. output.txt') args = parser.parse_args() input = args.input - txt_file = args.txt_file + txt_file = args.txt_file TESTV_PATH='$TESTV_PATH' REF_PATH='$REF_PATH' @@ -24,6 +24,7 @@ if __name__ == '__main__': cmds_enc=[] cmds_dec=[] cmds_rend=[] + cmds_isar_enc=[] cmds_isar_post_rend=[] @@ -38,15 +39,18 @@ if __name__ == '__main__': cmds_enc.extend(re.findall(r"DUT encoder command:\\n\\t(.*?)\\n", line)) cmds_dec.extend(re.findall(r"DUT decoder command:\\n\\t(.*?)\\n", line)) cmds_rend.extend(re.findall(r"Running command\\n(.*?)\\n", line)) + cmds_isar_enc.extend(re.findall(r"Running IVAS ISAR encoder command\\n(.*?)\\n", line)) cmds_isar_post_rend.extend(re.findall(r"Running ISAR post renderer command\\n(.*?)\\n", line)) + cmds_isar_post_rend.extend(re.findall(r"Running ISAR EXT REND command\\n(.*?)\\n", line)) # If pytest-html < v4 is used, the parsing will fail and render empty lists. This is a work-around in case that happens. - if all(not x for x in [cmds_enc, cmds_dec, cmds_rend, cmds_isar_post_rend]): + if all(not x for x in [cmds_enc, cmds_dec, cmds_rend, cmds_isar_enc, cmds_isar_post_rend]): for html_report in input: with open(html_report,'r') as infile: enc_cmd = False dec_cmd = False rend_cmd = False + isar_enc_cmd = False isar_post_rend_cmd = False for line in infile.readlines(): line = line.split("
")[0] # Remove trailing html tags @@ -59,6 +63,9 @@ if __name__ == '__main__': elif rend_cmd: cmds_rend.append(line) rend_cmd = False + elif isar_enc_cmd: + cmds_isar_enc.append(line) + isar_enc_cmd = False elif isar_post_rend_cmd: cmds_isar_post_rend.append(line) isar_post_rend_cmd = False @@ -69,13 +76,18 @@ if __name__ == '__main__': dec_cmd = True elif "Running command" in line: rend_cmd = True + elif "Running IVAS ISAR encoder command" in line: + isar_enc_cmd = True elif "Running ISAR post renderer command" in line: isar_post_rend_cmd = True + elif "Running ISAR EXT REND command" in line: + isar_post_rend_cmd = True # Sort lists to keep deterministic order between runs cmds_enc.sort() cmds_dec.sort() cmds_rend.sort() + cmds_isar_enc.sort() cmds_isar_post_rend.sort() with open(txt_file.replace('.','_enc.'),'w', newline='\n') as outfile: @@ -100,6 +112,28 @@ if __name__ == '__main__': with open('scripts/script_footer.txt','r') as footer: outfile.write(footer.read()) + with open(txt_file.replace('.','_ISAR_enc.'),'w', newline='\n') as outfile: + with open('scripts/enc_isar_header.txt','r') as header: + outfile.write(header.read()) + for cmd in cmds_isar_enc: + args = [] + for arg in cmd.split(): + # Adjust file arguments, pass other arguments as they are + if path.exists(arg): + arg = path.relpath(arg).replace('\\','/') + arg = re.sub('IVAS_cod(.exe)?', '$CUT_ENC_BIN', arg) + arg = re.sub('scripts', TESTV_PATH, arg) + arg = re.sub('tests', CUT_PATH, arg) + args.append(arg) + cmd = ' '.join(args) + outfile.write(cmd+'\n') + bts = re.search(r"\s(([\S]+)(.bts|.192|.pkt|.fer))$", cmd) + if bts: + outfile.write('$DIFF_BIN '+bts.group(1).replace(CUT_PATH + r'/dut',REF_PATH + r'/ref')+' '+bts.group(1)+' >> $LOG_FILE 2>&1\n') + outfile.write('\n') + with open('scripts/script_footer.txt','r') as footer: + outfile.write(footer.read()) + with open(txt_file.replace('.','_dec.'),'w', newline='\n') as outfile_dec, open(txt_file.replace('.','_JBM_dec.'),'w', newline='\n') as outfile_jbm, open(txt_file.replace('.','_ISAR_dec.'),'w', newline='\n') as outfile_isar: with open('scripts/dec_header.txt','r') as header: outfile_dec.write(header.read()) -- GitLab From 255bc37bddce3ec53eb26e5a6cf5f29ce00021d4 Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Tue, 21 Oct 2025 17:03:55 +0200 Subject: [PATCH 02/20] add ISAR enc header file --- scripts/enc_isar_header.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 scripts/enc_isar_header.txt diff --git a/scripts/enc_isar_header.txt b/scripts/enc_isar_header.txt new file mode 100644 index 0000000000..00134190a9 --- /dev/null +++ b/scripts/enc_isar_header.txt @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + exit -1 +fi + +CUT_ENC_BIN=$1 +DIFF_BIN="diff" + +TESTV_PATH="." +REF_PATH="./testv" +CUT_PATH="./TMP_ENC_ISAR" +LOG_FILE=Readme_IVAS_ISAR_enc_log.txt + +rm -rf tmp +rm -rf $CUT_PATH +mkdir -p $CUT_PATH +mkdir -p $CUT_PATH/split_rendering/cut + -- GitLab From d2242a3bd628d0e63e568d5db78ea9d3a944e05e Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Wed, 22 Oct 2025 12:19:15 +0200 Subject: [PATCH 03/20] add Readme_IVAS_ISAR_enc.txt into artifacts --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ef4908c45b..e6978a41ba 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1352,6 +1352,7 @@ ivas-conformance: - Readme_IVAS_enc.txt - Readme_IVAS_rend.txt - Readme_IVAS_JBM_dec.txt + - Readme_IVAS_ISAR_enc.txt - Readme_IVAS_ISAR_dec.txt - Readme_IVAS_ISAR_post_rend.txt expose_as: "Draft IVAS conformance" -- GitLab From f02c0cc400a69576d0517d367b54925a886cfdbd Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Wed, 22 Oct 2025 12:22:12 +0200 Subject: [PATCH 04/20] fix copying of add Readme_IVAS_ISAR_enc.txt file --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e6978a41ba..694845d0fe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1422,6 +1422,7 @@ ivas-conformance-linux: - cp Readme_IVAS_enc.txt testvec - cp Readme_IVAS_rend.txt testvec - cp Readme_IVAS_JBM_dec.txt testvec + - cp Readme_IVAS_ISAR_enc.txt testvec - cp Readme_IVAS_ISAR_dec.txt testvec - cp Readme_IVAS_ISAR_post_rend.txt testvec -- GitLab From 1371f0be5b9466ab94604aef816a228bb981d3ee Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Wed, 22 Oct 2025 12:23:03 +0200 Subject: [PATCH 05/20] remove --update_ref 1 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 694845d0fe..80963ad109 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1386,7 +1386,7 @@ ivas-conformance-linux: # Reference creation - python3 scripts/prepare_combined_format_inputs.py - TEST_SET="tests/codec_be_on_mr_nonselection tests/renderer/test_renderer.py tests/split_rendering/test_split_rendering.py" - - python3 -m pytest -q $TEST_SET -v -n auto --update_ref 1 --create_ref --keep_files + - python3 -m pytest -q $TEST_SET -v -n auto --create_ref --keep_files # Output creation - python3 -m pytest -q $TEST_SET -v -n auto --keep_files --create_cut --html=report_cmd.html --self-contained-html -- GitLab From d7025afa9ae5ab3c91b4be63bbcda4bed00dbad0 Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Wed, 22 Oct 2025 14:18:12 +0200 Subject: [PATCH 06/20] ensure that .splt.bit files are not stored in /tmp/xxx/ folder --- tests/split_rendering/utils.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/tests/split_rendering/utils.py b/tests/split_rendering/utils.py index 89f8aa2370..7a6a7f9ad7 100644 --- a/tests/split_rendering/utils.py +++ b/tests/split_rendering/utils.py @@ -257,7 +257,7 @@ def run_full_chain_split_rendering( enc_cmd[1:1] = FORMAT_TO_IVAS_COD_FORMAT[in_fmt] - run_ivas_isar_enc_cmd(enc_cmd) + run_ivas_isar_enc_cmd(enc_cmd, test_info=test_info) if delay_profile: rtp_bitstream = ivas_bitstream.with_suffix(".rtpg192") @@ -292,8 +292,8 @@ def run_full_chain_split_rendering( if delay_profile: dec_cmd[5:5] = ["-voip"] - run_ivas_isar_dec_cmd(dec_cmd) - + run_ivas_isar_dec_cmd(dec_cmd, test_info=test_info) + # run split renderer post_rend_cmd = SPLIT_POST_REND_CMD[:] @@ -309,7 +309,7 @@ def run_full_chain_split_rendering( if renderer_fmt == "BINAURAL_SPLIT_PCM": post_rend_cmd[7:7] = ["-im", str(split_md_file)] - run_isar_post_rend_cmd(post_rend_cmd) + run_isar_post_rend_cmd(post_rend_cmd, test_info=test_info) if test_info.config.option.create_cut: # CUT creation mode will run a comparison with REF @@ -376,19 +376,25 @@ def run_external_split_rendering( with TemporaryDirectory() as tmp_dir: tmp_dir = Path(tmp_dir) cut_in_file = tmp_dir.joinpath("cut_input.wav") - split_bitstream = tmp_dir.joinpath("split.bit") + + renderer_fmt_for_filename = renderer_fmt.replace("BINAURAL_", "") + filename_base = f"{in_fmt}_{renderer_fmt_for_filename}_ext_cfg_{render_config.stem}_fr_pre_{pre_rend_fr}_post_{post_rend_fr}" + + split_bitstream_stem = f"{filename_base}.splt.bit" if renderer_fmt == "BINAURAL_SPLIT_PCM": - split_md_file = tmp_dir.joinpath("split_md.bin") + split_md_file_stem = f"{filename_base}.spltmd.bit" - renderer_fmt_for_filename = renderer_fmt.replace("BINAURAL_", "") - out_file_stem = f"{in_fmt}_{renderer_fmt_for_filename}_ext_cfg_{render_config.stem}_fr_pre_{pre_rend_fr}_post_{post_rend_fr}.wav" + out_file_stem = f"{filename_base}.wav" if test_info.config.option.create_ref: output_path_base = OUTPUT_PATH_REF else: output_path_base = OUTPUT_PATH_CUT + split_bitstream = output_path_base.joinpath(split_bitstream_stem) out_file = output_path_base.joinpath(out_file_stem) + if renderer_fmt == "BINAURAL_SPLIT_PCM": + split_md_file = output_path_base.joinpath(split_md_file_stem) if plc_error_pattern: out_file = out_file.with_stem( @@ -404,7 +410,7 @@ def run_external_split_rendering( else: in_meta_files = None - # generate split-rendering bitstream + # run ISAR pre-renderer split_pre_cmd = SPLIT_PRE_REND_CMD[:] if test_info.config.option.create_ref: @@ -430,9 +436,9 @@ def run_external_split_rendering( if in_meta_files: split_pre_cmd[9:9] = ["-im", *in_meta_files] - run_isar_ext_rend_cmd(split_pre_cmd) + run_isar_ext_rend_cmd(split_pre_cmd, test_info=test_info) - # run split renderer + # run ISAR post-renderer split_post_cmd = SPLIT_POST_REND_CMD[:] if test_info.config.option.create_ref: @@ -450,7 +456,7 @@ def run_external_split_rendering( if plc_error_pattern: split_post_cmd[1:1] = ["-prbfi", str(plc_error_pattern)] - run_isar_ext_rend_cmd(split_post_cmd) + run_isar_ext_rend_cmd(split_post_cmd, test_info=test_info) if test_info.config.option.create_cut: # CUT creation mode will run a comparison with REF -- GitLab From 840b54f700d6793bc4a7852aefa0b0903d09d434 Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Wed, 22 Oct 2025 14:23:04 +0200 Subject: [PATCH 07/20] revert removal of --update_ref 1 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 80963ad109..694845d0fe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1386,7 +1386,7 @@ ivas-conformance-linux: # Reference creation - python3 scripts/prepare_combined_format_inputs.py - TEST_SET="tests/codec_be_on_mr_nonselection tests/renderer/test_renderer.py tests/split_rendering/test_split_rendering.py" - - python3 -m pytest -q $TEST_SET -v -n auto --create_ref --keep_files + - python3 -m pytest -q $TEST_SET -v -n auto --update_ref 1 --create_ref --keep_files # Output creation - python3 -m pytest -q $TEST_SET -v -n auto --keep_files --create_cut --html=report_cmd.html --self-contained-html -- GitLab From 1d8fc6b9d57ee06f74ce01afb50fc4322a434d1e Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Wed, 22 Oct 2025 14:32:15 +0200 Subject: [PATCH 08/20] add eadme_IVAS_ISAR_enc.txt --- tests/conformance-test/test_26252.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conformance-test/test_26252.py b/tests/conformance-test/test_26252.py index 0179f58bfc..ddcb4b83a2 100644 --- a/tests/conformance-test/test_26252.py +++ b/tests/conformance-test/test_26252.py @@ -59,7 +59,7 @@ def replace_paths(instr, testv_path, ref_path, cut_path): test_dict = {} TEST_DIR = "." -scripts=["Readme_IVAS_enc.txt", "Readme_IVAS_dec.txt", "Readme_IVAS_rend.txt", "Readme_IVAS_JBM_dec.txt", "Readme_IVAS_ISAR_dec.txt", "Readme_IVAS_ISAR_post_rend.txt"] +scripts=["Readme_IVAS_enc.txt", "Readme_IVAS_dec.txt", "Readme_IVAS_rend.txt", "Readme_IVAS_JBM_dec.txt", "Readme_IVAS_ISAR_enc.txt", "Readme_IVAS_ISAR_dec.txt", "Readme_IVAS_ISAR_post_rend.txt"] for s in scripts: with open(os.path.join(TEST_DIR, s), "r", encoding="UTF-8") as fp: -- GitLab From 837c9deed641c82dcd7d7557376ab38de0c024f9 Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Wed, 22 Oct 2025 14:37:56 +0200 Subject: [PATCH 09/20] ensure test_info is correctly propagated to _run_cmd() --- tests/renderer/utils.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index 2a0d50568c..0c37fb2879 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -67,8 +67,7 @@ from pyaudio3dtools.audiofile import readfile from ..cmp_pcm import cmp_pcm from ..conftest import get_split_idx, parse_properties - -def _run_cmd(cmd, env, test_info=None): +def _run_cmd(cmd, test_info=None, env=None ): """ Helper function for running some command. Raises a SystemError if either the return code is non-zero or a USAN printout is detected @@ -93,29 +92,29 @@ def _run_cmd(cmd, env, test_info=None): raise SystemError(error) -def run_cmd(cmd, test_info, env=None): +def run_cmd(cmd, test_info=None, env=None): logging.info(f"\nRunning command\n{' '.join(cmd)}\n") - _run_cmd(cmd, env, test_info) + _run_cmd(cmd, env=env, test_info=test_info) -def run_isar_ext_rend_cmd(cmd, env=None): +def run_isar_ext_rend_cmd(cmd, test_info=None, env=None): logging.info(f"\nRunning ISAR EXT REND command\n{' '.join(cmd)}\n") - _run_cmd(cmd, env) + run_cmd(cmd, test_info=test_info, env=env) -def run_ivas_isar_enc_cmd(cmd, env=None): +def run_ivas_isar_enc_cmd(cmd, test_info=None, env=None): logging.info(f"\nRunning IVAS ISAR encoder command\n{' '.join(cmd)}\n") - _run_cmd(cmd, env) + run_cmd(cmd, test_info=test_info, env=env) -def run_ivas_isar_dec_cmd(cmd, env=None): +def run_ivas_isar_dec_cmd(cmd, test_info=None, env=None): logging.info(f"\nDUT decoder command:\n\t{' '.join(cmd)}\n") - _run_cmd(cmd, env) + run_cmd(cmd, test_info=test_info, env=env) -def run_isar_post_rend_cmd(cmd, env=None): +def run_isar_post_rend_cmd(cmd, test_info=None, env=None): logging.info(f"\nRunning ISAR post renderer command\n{' '.join(cmd)}\n") - _run_cmd(cmd, env) + run_cmd(cmd, test_info=test_info, env=env) def check_BE( -- GitLab From 21e10825ba14ad4a65cd28c7f9f34a48e9fc202b Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Wed, 22 Oct 2025 16:17:55 +0200 Subject: [PATCH 10/20] add error pattern to .bit filenames to avoid race condition --- tests/split_rendering/utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/split_rendering/utils.py b/tests/split_rendering/utils.py index d7717292c8..bd3781e810 100644 --- a/tests/split_rendering/utils.py +++ b/tests/split_rendering/utils.py @@ -396,6 +396,9 @@ def run_external_split_rendering( split_md_file = output_path_base.joinpath(split_md_file_stem) if plc_error_pattern: + split_bitstream = split_bitstream.with_stem( + f"{split_bitstream.stem}_plc_{plc_error_pattern.stem}" + ) out_file = out_file.with_stem( f"{out_file.stem}_plc_{plc_error_pattern.stem}" ) -- GitLab From 10920878e44b06e8d346f44a0f6e979724b8b1a4 Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Thu, 23 Oct 2025 09:12:29 +0200 Subject: [PATCH 11/20] add Readme_IVAS_ISAR_enc.txt --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 694845d0fe..131ba00e91 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1327,6 +1327,7 @@ ivas-conformance: - cp Readme_IVAS_enc.txt testvec - cp Readme_IVAS_rend.txt testvec - cp Readme_IVAS_JBM_dec.txt testvec + - cp Readme_IVAS_ISAR_enc.txt testvec - cp Readme_IVAS_ISAR_dec.txt testvec - cp Readme_IVAS_ISAR_post_rend.txt testvec - cp IVAS_cod.exe testvec/bin @@ -1461,6 +1462,7 @@ ivas-conformance-linux: - Readme_IVAS_enc.txt - Readme_IVAS_rend.txt - Readme_IVAS_JBM_dec.txt + - Readme_IVAS_ISAR_enc.txt - Readme_IVAS_ISAR_dec.txt - Readme_IVAS_ISAR_post_rend.txt - $COVERAGE_OUTPUT_FILE -- GitLab From c6ac426397e98f4affa8e27e8e7469f8ff0a904f Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Thu, 23 Oct 2025 14:18:00 +0200 Subject: [PATCH 12/20] do not use temporary directory for cut_input.wav --- tests/split_rendering/utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/split_rendering/utils.py b/tests/split_rendering/utils.py index bd3781e810..cf14915075 100644 --- a/tests/split_rendering/utils.py +++ b/tests/split_rendering/utils.py @@ -199,7 +199,6 @@ def run_full_chain_split_rendering( with TemporaryDirectory() as tmp_dir: tmp_dir = Path(tmp_dir) - cut_in_file = tmp_dir.joinpath("cut_input.wav") renderer_fmt_for_filename = renderer_fmt.replace("BINAURAL_", "") filename_base = f"{in_fmt}_{bitrate}_{renderer_fmt_for_filename}_full_cfg_{render_config.stem}_fr_pre_{pre_rend_fr}_post_{post_rend_fr}" @@ -223,6 +222,7 @@ def run_full_chain_split_rendering( ivas_bitstream = output_path_base.joinpath(ivas_bitstream_stem) split_bitstream = output_path_base.joinpath(split_bitstream_stem) out_file = output_path_base.joinpath(out_file_stem) + if renderer_fmt == "BINAURAL_SPLIT_PCM": split_md_file = output_path_base.joinpath(split_md_file_stem) @@ -245,6 +245,7 @@ def run_full_chain_split_rendering( # if in REF or CUT creation mode use the comparetestv if test_info.config.option.create_ref or test_info.config.option.create_cut: in_file = FORMAT_TO_FILE_COMPARETEST[in_fmt] + cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) truncate_signal(in_file, cut_in_file) enc_cmd[3] = str(cut_in_file) @@ -374,7 +375,6 @@ def run_external_split_rendering( with TemporaryDirectory() as tmp_dir: tmp_dir = Path(tmp_dir) - cut_in_file = tmp_dir.joinpath("cut_input.wav") renderer_fmt_for_filename = renderer_fmt.replace("BINAURAL_", "") filename_base = f"{in_fmt}_{renderer_fmt_for_filename}_ext_cfg_{render_config.stem}_fr_pre_{pre_rend_fr}_post_{post_rend_fr}" @@ -422,6 +422,7 @@ def run_external_split_rendering( # if in REF or CUT creation mode use the comparetestv if test_info.config.option.create_ref or test_info.config.option.create_cut: in_file = FORMAT_TO_FILE_COMPARETEST[in_fmt] + cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) truncate_signal(in_file, cut_in_file) split_pre_cmd[6] = str(cut_in_file) -- GitLab From 4295f81ad7c11773de7878a18bcb237a8b8381b3 Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Thu, 23 Oct 2025 14:20:46 +0200 Subject: [PATCH 13/20] add Readme_IVAS_ISAR_enc.txt to test_26252.py --- tests/conformance-test/test_26252.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conformance-test/test_26252.py b/tests/conformance-test/test_26252.py index ddcb4b83a2..a60fe01994 100644 --- a/tests/conformance-test/test_26252.py +++ b/tests/conformance-test/test_26252.py @@ -59,7 +59,7 @@ def replace_paths(instr, testv_path, ref_path, cut_path): test_dict = {} TEST_DIR = "." -scripts=["Readme_IVAS_enc.txt", "Readme_IVAS_dec.txt", "Readme_IVAS_rend.txt", "Readme_IVAS_JBM_dec.txt", "Readme_IVAS_ISAR_enc.txt", "Readme_IVAS_ISAR_dec.txt", "Readme_IVAS_ISAR_post_rend.txt"] +scripts=["Readme_IVAS_enc.txt", "Readme_IVAS_ISAR_enc.txt", "Readme_IVAS_dec.txt", "Readme_IVAS_rend.txt", "Readme_IVAS_JBM_dec.txt", "Readme_IVAS_ISAR_dec.txt", "Readme_IVAS_ISAR_post_rend.txt"] for s in scripts: with open(os.path.join(TEST_DIR, s), "r", encoding="UTF-8") as fp: -- GitLab From 2056953cc225dac86a79ffa59bcaa84d27573b4c Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Thu, 23 Oct 2025 15:41:30 +0200 Subject: [PATCH 14/20] debug error --- tests/split_rendering/utils.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/split_rendering/utils.py b/tests/split_rendering/utils.py index cf14915075..a1b6202505 100644 --- a/tests/split_rendering/utils.py +++ b/tests/split_rendering/utils.py @@ -248,6 +248,11 @@ def run_full_chain_split_rendering( cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) truncate_signal(in_file, cut_in_file) + # !!!! debug only + if not path.exists(cut_in_file): + logging.error(f"Unable to cut file {str(in_file)} into {str(cut_in_file)}") + pytest.fail(f"Unable to cut file {str(in_file)} into {str(cut_in_file)") + enc_cmd[3] = str(cut_in_file) else: enc_cmd[3] = str(FORMAT_TO_FILE_SMOKETEST[in_fmt]) @@ -425,6 +430,11 @@ def run_external_split_rendering( cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) truncate_signal(in_file, cut_in_file) + # !!!! debug only + if not path.exists(cut_in_file): + logging.error(f"Unable to cut file {str(in_file)} into {str(cut_in_file)}") + pytest.fail(f"Unable to cut file {str(in_file)} into {str(cut_in_file)") + split_pre_cmd[6] = str(cut_in_file) else: split_pre_cmd[6] = str(FORMAT_TO_FILE_SMOKETEST[in_fmt]) -- GitLab From 4e3fc8c3a773eb0d8d41be5d6bf9d3d80245604a Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Thu, 23 Oct 2025 15:49:40 +0200 Subject: [PATCH 15/20] fix typo --- tests/split_rendering/utils.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/split_rendering/utils.py b/tests/split_rendering/utils.py index a1b6202505..cf3eefcb29 100644 --- a/tests/split_rendering/utils.py +++ b/tests/split_rendering/utils.py @@ -35,6 +35,7 @@ import sys from pathlib import Path from tempfile import TemporaryDirectory from typing import Tuple, Optional +from os import path import numpy as np import pytest @@ -251,7 +252,7 @@ def run_full_chain_split_rendering( # !!!! debug only if not path.exists(cut_in_file): logging.error(f"Unable to cut file {str(in_file)} into {str(cut_in_file)}") - pytest.fail(f"Unable to cut file {str(in_file)} into {str(cut_in_file)") + pytest.fail(f"Unable to cut file {str(in_file)} into {str(cut_in_file)}") enc_cmd[3] = str(cut_in_file) else: @@ -428,12 +429,13 @@ def run_external_split_rendering( if test_info.config.option.create_ref or test_info.config.option.create_cut: in_file = FORMAT_TO_FILE_COMPARETEST[in_fmt] cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) - truncate_signal(in_file, cut_in_file) + if not path.exists(cut_in_file): + truncate_signal(in_file, cut_in_file) # !!!! debug only if not path.exists(cut_in_file): logging.error(f"Unable to cut file {str(in_file)} into {str(cut_in_file)}") - pytest.fail(f"Unable to cut file {str(in_file)} into {str(cut_in_file)") + pytest.fail(f"Unable to cut file {str(in_file)} into {str(cut_in_file)}") split_pre_cmd[6] = str(cut_in_file) else: -- GitLab From 6e6ec8fe4840733c3eea2cbe6118d04276054545 Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Thu, 23 Oct 2025 16:21:08 +0200 Subject: [PATCH 16/20] fix typo --- tests/split_rendering/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/split_rendering/utils.py b/tests/split_rendering/utils.py index cf3eefcb29..d48913752c 100644 --- a/tests/split_rendering/utils.py +++ b/tests/split_rendering/utils.py @@ -247,7 +247,8 @@ def run_full_chain_split_rendering( if test_info.config.option.create_ref or test_info.config.option.create_cut: in_file = FORMAT_TO_FILE_COMPARETEST[in_fmt] cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) - truncate_signal(in_file, cut_in_file) + if not path.exists(cut_in_file): + truncate_signal(in_file, cut_in_file) # !!!! debug only if not path.exists(cut_in_file): -- GitLab From 75b174152e69ac46287dc1f15a087824c5c4e13a Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Fri, 24 Oct 2025 09:02:09 +0200 Subject: [PATCH 17/20] call _run_cmd() instead of run_cmd() in wrappers --- tests/renderer/utils.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index 1386962c4d..1aa7370f08 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -94,30 +94,28 @@ def _run_cmd(cmd, test_info=None, env=None ): def run_cmd(cmd, test_info=None, env=None): logging.info(f"\nRunning command\n{' '.join(cmd)}\n") - _run_cmd(cmd, env=env, test_info=test_info) + _run_cmd(cmd, test_info=test_info, env=env) def run_isar_ext_rend_cmd(cmd, test_info=None, env=None): logging.info(f"\nRunning ISAR EXT REND command\n{' '.join(cmd)}\n") - run_cmd(cmd, test_info=test_info, env=env) + _run_cmd(cmd, test_info=test_info, env=env) def run_ivas_isar_enc_cmd(cmd, test_info=None, env=None): logging.info(f"\nRunning IVAS ISAR encoder command\n{' '.join(cmd)}\n") - run_cmd(cmd, test_info=test_info, env=env) + _run_cmd(cmd, test_info=test_info, env=env) - -def run_ivas_isar_dec_cmd(cmd, env=None): +def run_ivas_isar_dec_cmd(cmd, test_info=None, env=None): if BIN_SUFFIX_MERGETARGET in cmd[0]: logging.info(f"\nREF decoder command:\n\t{' '.join(cmd)}\n") else: logging.info(f"\nDUT decoder command:\n\t{' '.join(cmd)}\n") - _run_cmd(cmd, env) - + _run_cmd(cmd, test_info=test_info, env=env) def run_isar_post_rend_cmd(cmd, test_info=None, env=None): logging.info(f"\nRunning ISAR post renderer command\n{' '.join(cmd)}\n") - run_cmd(cmd, test_info=test_info, env=env) + _run_cmd(cmd, test_info=test_info, env=env) def check_BE( -- GitLab From 92f4c662c8a85bbcfc932ca5691e801d6b8f2f8f Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Fri, 24 Oct 2025 10:24:20 +0200 Subject: [PATCH 18/20] add file_lock to prevent race condition due to truncate_signal() --- tests/split_rendering/utils.py | 38 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/split_rendering/utils.py b/tests/split_rendering/utils.py index d48913752c..e61b27ce92 100644 --- a/tests/split_rendering/utils.py +++ b/tests/split_rendering/utils.py @@ -36,6 +36,7 @@ from pathlib import Path from tempfile import TemporaryDirectory from typing import Tuple, Optional from os import path +import threading import numpy as np import pytest @@ -62,6 +63,7 @@ from ..conftest import parse_properties sys.path.append(SCRIPTS_DIR) from pyaudio3dtools.audiofile import readfile, writefile +file_lock = threading.Lock() def lc3plus_used(test_info, in_fmt, render_config): return ( @@ -157,16 +159,18 @@ def truncate_signal( Truncate the signal in in_file to maximum INPUT_DURATION_SEC seconds, and write the truncated signal to out_file """ - data, fs = readfile(in_file) - - if data.ndim == 1: - data_out = data[: INPUT_DURATION_SEC * fs] - elif data.ndim == 2: - data_out = data[: INPUT_DURATION_SEC * fs, :] - else: - raise ValueError(f"Cannot truncate data with dimension of {data.ndim}") + + with file_lock: + data, fs = readfile(in_file) + + if data.ndim == 1: + data_out = data[: INPUT_DURATION_SEC * fs] + elif data.ndim == 2: + data_out = data[: INPUT_DURATION_SEC * fs, :] + else: + raise ValueError(f"Cannot truncate data with dimension of {data.ndim}") - writefile(out_file, data_out, fs) + writefile(out_file, data_out, fs) def run_full_chain_split_rendering( @@ -249,11 +253,9 @@ def run_full_chain_split_rendering( cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) if not path.exists(cut_in_file): truncate_signal(in_file, cut_in_file) - - # !!!! debug only - if not path.exists(cut_in_file): - logging.error(f"Unable to cut file {str(in_file)} into {str(cut_in_file)}") - pytest.fail(f"Unable to cut file {str(in_file)} into {str(cut_in_file)}") + else: + file_lock.acquire(timeout=10) # wait max 10s until the lock is available + file_lock.release() # release immediately enc_cmd[3] = str(cut_in_file) else: @@ -432,11 +434,9 @@ def run_external_split_rendering( cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) if not path.exists(cut_in_file): truncate_signal(in_file, cut_in_file) - - # !!!! debug only - if not path.exists(cut_in_file): - logging.error(f"Unable to cut file {str(in_file)} into {str(cut_in_file)}") - pytest.fail(f"Unable to cut file {str(in_file)} into {str(cut_in_file)}") + else: + file_lock.acquire(timeout=10) # wait max 10s until the lock is available + file_lock.release() # release immediately split_pre_cmd[6] = str(cut_in_file) else: -- GitLab From 079c0bc5af8b7fb091a30979c098aba0bd3fdf3a Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Fri, 24 Oct 2025 10:50:47 +0200 Subject: [PATCH 19/20] try alternative file_lock solution by @kiene --- tests/split_rendering/utils.py | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/tests/split_rendering/utils.py b/tests/split_rendering/utils.py index e61b27ce92..d1e5b8b182 100644 --- a/tests/split_rendering/utils.py +++ b/tests/split_rendering/utils.py @@ -160,17 +160,16 @@ def truncate_signal( and write the truncated signal to out_file """ - with file_lock: - data, fs = readfile(in_file) + data, fs = readfile(in_file) - if data.ndim == 1: - data_out = data[: INPUT_DURATION_SEC * fs] - elif data.ndim == 2: - data_out = data[: INPUT_DURATION_SEC * fs, :] - else: - raise ValueError(f"Cannot truncate data with dimension of {data.ndim}") + if data.ndim == 1: + data_out = data[: INPUT_DURATION_SEC * fs] + elif data.ndim == 2: + data_out = data[: INPUT_DURATION_SEC * fs, :] + else: + raise ValueError(f"Cannot truncate data with dimension of {data.ndim}") - writefile(out_file, data_out, fs) + writefile(out_file, data_out, fs) def run_full_chain_split_rendering( @@ -251,11 +250,9 @@ def run_full_chain_split_rendering( if test_info.config.option.create_ref or test_info.config.option.create_cut: in_file = FORMAT_TO_FILE_COMPARETEST[in_fmt] cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) - if not path.exists(cut_in_file): - truncate_signal(in_file, cut_in_file) - else: - file_lock.acquire(timeout=10) # wait max 10s until the lock is available - file_lock.release() # release immediately + with file_lock: + if not path.exists(cut_in_file): + truncate_signal(in_file, cut_in_file) enc_cmd[3] = str(cut_in_file) else: @@ -432,11 +429,9 @@ def run_external_split_rendering( if test_info.config.option.create_ref or test_info.config.option.create_cut: in_file = FORMAT_TO_FILE_COMPARETEST[in_fmt] cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) - if not path.exists(cut_in_file): - truncate_signal(in_file, cut_in_file) - else: - file_lock.acquire(timeout=10) # wait max 10s until the lock is available - file_lock.release() # release immediately + with file_lock: + if not path.exists(cut_in_file): + truncate_signal(in_file, cut_in_file) split_pre_cmd[6] = str(cut_in_file) else: -- GitLab From dac33e6332ef6898522b02545cbc6996561fc89d Mon Sep 17 00:00:00 2001 From: Vladimir Malenovsky Date: Fri, 24 Oct 2025 14:24:25 +0200 Subject: [PATCH 20/20] debug: try running truncate_signal as session-scope function --- tests/conftest.py | 12 ++++ tests/split_rendering/test_split_rendering.py | 66 ++++++++++++++++++- tests/split_rendering/utils.py | 52 +++++++-------- 3 files changed, 102 insertions(+), 28 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 6f293b9502..742c42060f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1546,3 +1546,15 @@ def ref_postrend_frontend(ref_postrend_path, request) -> Optional[PostRendFronte # Fixture teardown if postrend is not None: postrend._check_run() + +def pytest_sessionstart(session): + session.test_functions = [] + +def pytest_collection_finish(session): + # Collect all test function names + session.test_functions = [item.nodeid for item in session.items] + +@pytest.fixture(scope="session") +def collected_tests(request): + # Access the collected test function names + return getattr(request.session, "test_functions", []) \ No newline at end of file diff --git a/tests/split_rendering/test_split_rendering.py b/tests/split_rendering/test_split_rendering.py index 0ff32fa290..72da6fcf8e 100644 --- a/tests/split_rendering/test_split_rendering.py +++ b/tests/split_rendering/test_split_rendering.py @@ -33,9 +33,72 @@ the United Nations Convention on Contracts on the International Sales of Goods. import pytest from tests.split_rendering.utils import * +import pdb + + +@pytest.fixture(scope="session", autouse=True) +def truncate_input_files(collected_tests, request): + """ + Truncate the test vectors to maximum INPUT_DURATION_SEC seconds + """ + + INPUT_FORMATS_FULL_CHAIN_SPLIT_PCM = [entry[0] for entry in full_chain_split_pcm_params] + INPUT_FORMATS_EXT_SPLIT_PCM = [entry[0] for entry in external_split_pcm_params] + + TEST_FUNCTIONS_TO_FORMATS = { + "test_ambisonics_full_chain_split": INPUT_FORMATS_AMBI_SPLIT_REND, + "test_ambisonics_external_split": INPUT_FORMATS_AMBI_SPLIT_REND, + "test_multichannel_full_chain_split": INPUT_FORMATS_MC_SPLIT_REND, + "test_multichannel_external_split": INPUT_FORMATS_MC_SPLIT_REND, + "test_ism_full_chain_split": INPUT_FORMATS_ISM_SPLIT_REND, + "test_ism_external_split": INPUT_FORMATS_ISM_SPLIT_REND, + "test_masa_full_chain_split": INPUT_FORMATS_MASA_SPLIT_REND, + "test_masa_external_split": INPUT_FORMATS_MASA_SPLIT_REND, + "test_omasa_full_chain_split": INPUT_FORMATS_OMASA_SPLIT_REND, + "test_omasa_external_split": INPUT_FORMATS_OMASA_SPLIT_REND, + "test_osba_full_chain_split": INPUT_FORMATS_OSBA_SPLIT_REND, + "test_osba_external_split": INPUT_FORMATS_OSBA_SPLIT_REND, + "test_post_rend_plc": [INPUT_FORMATS_AMBI_SPLIT_REND[-1]], + "test_full_chain_split_pcm": INPUT_FORMATS_FULL_CHAIN_SPLIT_PCM, + "test_external_split_pcm": INPUT_FORMATS_EXT_SPLIT_PCM, + "test_framing_combinations_full_chain_split": ["5_1", "FOA"], + "test_framing_combinations_external_split": ["5_1"], + } + + pattern = r'::([^\[]+)\[' + + # get the list of test functions to run + functions_to_run = {re.search(pattern, entry).group(1) for entry in collected_tests if re.search(pattern, entry)} + functions_to_run = list(functions_to_run) + + # get the list of file formats for test functions + formats = [] + for name in functions_to_run: + formats.extend(TEST_FUNCTIONS_TO_FORMATS.get(name, [])) + seen = set() + formats = [fmt for fmt in formats if not (fmt in seen or seen.add(fmt))] # remove duplicates + + logging.info(f"\nCutting input files for the following formats: {', '.join(formats)}\n") + + # pdb.set_trace() + for in_fmt in formats: + in_file = FORMAT_TO_FILE_COMPARETEST[in_fmt] + cut_in_file = in_file.with_stem(in_file.stem + "_cut") + + if not path.exists(cut_in_file): + data, fs = readfile(in_file) + + if data.ndim == 1: + data_out = data[: INPUT_DURATION_SEC * fs] + elif data.ndim == 2: + data_out = data[: INPUT_DURATION_SEC * fs, :] + else: + raise ValueError(f"Cannot truncate data with dimension of {data.ndim}") + + writefile(cut_in_file, data_out, fs) -""" Ambisonics """ +""" Ambisonics """ @pytest.mark.parametrize("delay_profile", DELAY_PROFILES) @pytest.mark.parametrize("trajectory", SPLIT_REND_HR_TRAJECTORIES_TO_TEST) @@ -557,7 +620,6 @@ def test_post_rend_plc( """ BINAURAL_SPLIT_PCM """ - full_chain_split_pcm_params = [ ("HOA3", "96000", "split_renderer_config_1dof_512k_default"), ("7_1_4", "512000", "split_renderer_config_3dofhq_512k_lc3plus"), diff --git a/tests/split_rendering/utils.py b/tests/split_rendering/utils.py index d1e5b8b182..4d32057697 100644 --- a/tests/split_rendering/utils.py +++ b/tests/split_rendering/utils.py @@ -36,7 +36,7 @@ from pathlib import Path from tempfile import TemporaryDirectory from typing import Tuple, Optional from os import path -import threading +# from filelock import FileLock import numpy as np import pytest @@ -63,7 +63,7 @@ from ..conftest import parse_properties sys.path.append(SCRIPTS_DIR) from pyaudio3dtools.audiofile import readfile, writefile -file_lock = threading.Lock() +# file_lock = FileLock("tmp_truncate_signal_token.lock") def lc3plus_used(test_info, in_fmt, render_config): return ( @@ -151,25 +151,25 @@ def check_xfail( ) -def truncate_signal( - in_file: Path, - out_file: Path, -) -> None: - """ - Truncate the signal in in_file to maximum INPUT_DURATION_SEC seconds, - and write the truncated signal to out_file - """ +# def truncate_signal( + # in_file: Path, + # out_file: Path, +# ) -> None: + # """ + # Truncate the signal in in_file to maximum INPUT_DURATION_SEC seconds, + # and write the truncated signal to out_file + # """ - data, fs = readfile(in_file) + # data, fs = readfile(in_file) - if data.ndim == 1: - data_out = data[: INPUT_DURATION_SEC * fs] - elif data.ndim == 2: - data_out = data[: INPUT_DURATION_SEC * fs, :] - else: - raise ValueError(f"Cannot truncate data with dimension of {data.ndim}") + # if data.ndim == 1: + # data_out = data[: INPUT_DURATION_SEC * fs] + # elif data.ndim == 2: + # data_out = data[: INPUT_DURATION_SEC * fs, :] + # else: + # raise ValueError(f"Cannot truncate data with dimension of {data.ndim}") - writefile(out_file, data_out, fs) + # writefile(out_file, data_out, fs) def run_full_chain_split_rendering( @@ -249,10 +249,10 @@ def run_full_chain_split_rendering( # if in REF or CUT creation mode use the comparetestv if test_info.config.option.create_ref or test_info.config.option.create_cut: in_file = FORMAT_TO_FILE_COMPARETEST[in_fmt] - cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) - with file_lock: - if not path.exists(cut_in_file): - truncate_signal(in_file, cut_in_file) + cut_in_file = in_file.with_stem(in_file.stem + "_cut") + # with file_lock: + # if not path.exists(cut_in_file): + # truncate_signal(in_file, cut_in_file) enc_cmd[3] = str(cut_in_file) else: @@ -428,10 +428,10 @@ def run_external_split_rendering( # if in REF or CUT creation mode use the comparetestv if test_info.config.option.create_ref or test_info.config.option.create_cut: in_file = FORMAT_TO_FILE_COMPARETEST[in_fmt] - cut_in_file = output_path_base.joinpath(in_file.stem + "_cut" + in_file.suffix) - with file_lock: - if not path.exists(cut_in_file): - truncate_signal(in_file, cut_in_file) + cut_in_file = in_file.with_stem(in_file.stem + "_cut") + # with file_lock: + # if not path.exists(cut_in_file): + # truncate_signal(in_file, cut_in_file) split_pre_cmd[6] = str(cut_in_file) else: -- GitLab