diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 06afcab3fe6479a3427ad07520f6d7dd07db1bc2..9755bf3057e07d05947fb40329706fd6c10414b9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -995,8 +995,9 @@ check-first-frame-is-sid: - exit_code_foa=0 # run all modes and cut bitstream to start with an SID. Use stereo output to limit runtime, test is only about decoding + - ism_md_cmd="--ism_metadata_files /usr/local/ltv/ltvISM1.csv /usr/local/ltv/ltvISM2.csv /usr/local/ltv/ltvISM3.csv /usr/local/ltv/ltvISM4.csv" - modes=$(scripts/runIvasCodec.py -l | grep dtx | grep -vE "FOA|HOA" ) - - scripts/runIvasCodec.py -z console -p scripts/config/ci_linux_sidstart_test.json -m $modes -s --bs_length 200 -U 0:20 --oc stereo || exit_code_no_sba=$? + - scripts/runIvasCodec.py -z console -p scripts/config/ci_linux_sidstart_test.json -m $modes -s --bs_length 200 -U 0:20 --oc stereo $ism_md_cmd || exit_code_no_sba=$? - modes=$(scripts/runIvasCodec.py -l | grep dtx | grep -E "HOA") - scripts/runIvasCodec.py -z console -p scripts/config/ci_linux_sidstart_test.json -m $modes -s --bs_length 100 -U 70:80 --oc stereo || exit_code_hoa=$? - modes=$(scripts/runIvasCodec.py -l | grep dtx | grep "FOA") diff --git a/ci/run_scheduled_sanitizer_test.py b/ci/run_scheduled_sanitizer_test.py index 661df093d1e03ecfbc2034cf2756761a964cce04..c30c7bc2c49eabacc0e9802f6138ba80f3e2a4b7 100755 --- a/ci/run_scheduled_sanitizer_test.py +++ b/ci/run_scheduled_sanitizer_test.py @@ -110,8 +110,8 @@ def get_modes(in_format: str) -> list: def get_md_file_command(in_format: str) -> list: cmd = list() - if in_format.startswith("ISM"): - cmd.append("--metadata_files") + if "ISM" in in_format: + cmd.append("--ism_metadata_files") md_filename = "/usr/local/ltv/ltvISM{}.csv" n = int(in_format[-1]) cmd.extend([md_filename.format(i) for i in range(1, n + 1)]) diff --git a/ci/smoke_test.sh b/ci/smoke_test.sh index 4e3be38db3f6b2ad95f8ef455fa0df1551e41f7d..ce93d26046cdbf20a3613e5f41aa82625012a802 100755 --- a/ci/smoke_test.sh +++ b/ci/smoke_test.sh @@ -53,7 +53,7 @@ fi cfg=./scripts/config/ci_linux.json dly_profile=./scripts/dly_error_profiles/dly_error_profile_10.dat -ism_md_cmd="--metadata_files /usr/local/ltv/ltvISM1.csv /usr/local/ltv/ltvISM2.csv /usr/local/ltv/ltvISM3.csv /usr/local/ltv/ltvISM4.csv" +ism_md_cmd="--ism_metadata_files /usr/local/ltv/ltvISM1.csv /usr/local/ltv/ltvISM2.csv /usr/local/ltv/ltvISM3.csv /usr/local/ltv/ltvISM4.csv" duration_arg="-U 1:2" verbosity_cmd="-z console" diff --git a/scripts/README.md b/scripts/README.md index f547c7e80f7eba4495cdd5aaab55653cf7b7a74d..bc7ae8f32e89b4d451703522a85c3d1494218f82 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -110,57 +110,58 @@ Given output directories have a certain structure to avoid to much cluttering The different scripts share a common set of command line options: ``` -h, --help show this help message and exit - -C [FORMAT [FORMAT ...]], --formats [FORMAT [FORMAT ...]] - List of IVAS formats to run, default all (for possible - choices get a list with -L - -m [MODE [MODE ...]], --modes [MODE [MODE ...]] - List of IVAS modes to run, default all (for possible - choices get a list with -l - --oc [OC_DICT [OC_DICT ...]] - List of output formats, either a space separated list - or a json string in single quotes + -z [{silent,console,progress,debug,info,warning,error,critical}], --loglevel [{silent,console,progress,debug,info,warning,error,critical}] + Either show with minimal output (default, 'silent'), or reroute log messages with levels higher than LEVEL to the console + -g LOGFILE, --logfile LOGFILE + log file + -t MAX_WORKERS, --max_workers MAX_WORKERS + use multithreading with MAX_WORKERS threads (default: number of CPUs available at the machine) + -C [FORMAT ...], --formats [FORMAT ...] + List of IVAS formats to run, default all (for possible choices get a list with -L + -m [MODE ...], --modes [MODE ...] + List of IVAS modes to run, default all (for possible choices get a list with -l + --oc [OC_DICT ...] List of output formats, either a space separated list or a json string in single quotes -E "-opt1 opt2", --enc_options "-opt1 opt2" - Additional command line options for the encoder - (always use it in the form -E="-o -opt ...") + Additional command line options for the encoder (always use it in the form -E="-o -opt ...") -D "-opt1 opt2", --dec_options "-opt1 opt2" - Additional command line options for the decoder - (always use it in the form -D="-o -opt ...") + Additional command line options for the decoder (always use it in the form -D="-o -opt ...") --format_file FORMAT_FILE - File name for the IVAS ivas_format dictionary to use - (default: ivas_modes.json) - -I [ITEM [ITEM ...]], --items [ITEM [ITEM ...]] - List of items to be coded, allows for explicit - definition of metadata files by grouping an item - together with its metadata files in square brackets - [ITEM,METADATAFILE,...] - --metadata_files [MDFILE [MDFILE ...]] - List of common metadata files - -z [{silent,debug,info,warning,error,critical}], --silent [{silent,debug,info,warning,error,critical}] - Either show with minimal output (default, 'silent'), - or reroute log messages with levels higher than LEVEL - to the console - -S SRIN, --srin SRIN Input sample rate for the encoder + File name for the IVAS ivas_format dictionary to use (default: ivas_modes_v2.json) + -I [ITEM ...], --items [ITEM ...] + List of items to be coded, allows for explicit definition of metadata files by grouping an item together with its metadata files in square brackets [ITEM,METADATAFILE,...] + --ism_metadata_files [ISM_MDFILE ...] + List of ISM metadata files + --masa_metadata_file MASA_MDFILE + MASA metadata file + -S SRIN, --srin SRIN Input sample rate for the encoder (either in Hz or kHz) -R SROUT, --srout SROUT - Output sample rate for the decoder + Output sample rate for the decoder (either in Hz or kHz) -p CONFIG, --config CONFIG select site-related config as CONFIG.json - -t [MAX_WORKERS], --max_workers [MAX_WORKERS] - use multithreading with MAX_WORKERS threads (default: - number of CPUs available at the machine) -l, --list_modes list all supported IVAS ivas_formats -L, --list_formats list all supported IVAS formats -U LIMIT_DURATION, --limit_duration LIMIT_DURATION - limit dUration of input file to X seconds + limit dUration by specifying start and end of input signal in seconds. Can be either a single float value (will be interpreted as length), or by giving as start: (will be interpreted as start), or by giving as start:end -f FER_FILE, --fer_file FER_FILE frame error pattern file + -y BER_FILE, --ber_file BER_FILE + bit error pattern file + -J JBM_FILE, --jbm_file JBM_FILE + jbm file -i INDIR, --indir INDIR - Directory for items to be coded, either a single - directory or a json string for different directories - with the input formats as keys + Directory for items to be coded, either a single directory or a json string for different directories with the input formats as keys --decoder_only only run the decoder -x FILTER_REGEX, --filter FILTER_REGEX Regex for filtering modes - -s, --sidstart Cut bitstreams until the first SID frame before decoding + -s, --sidstart Cut frames from the beginning of the encoded bit stream until the first SID frame + --bs_length BS_LENGTH + Cut bitstream to this (maximum) length. Is applied AFTER --sidstart processing, if this is given + --info Ouput debug info in subfolders of /res (use with caution, this can generate a huge amount of data) + --sofa SOFA Directory for the group B binaural renderer to look for SOFA files + -e ENC, --enc ENC Encoder binary name (default ./IVAS_cod) + -d DEC, --dec DEC Decoder binary name (default ./IVAS_dec) + --fail_log_dir FAIL_LOG_DIR + Move logs of failed modes to dir (default none) ``` Some notable difference exits to similar command line options of `runEvsCodec.pl` and a few new ones are added: diff --git a/scripts/config/ivas_modes.json b/scripts/config/ivas_modes.json index 0f6596b9f6d0ca85e59d72fb38653204c8dd7221..89c9d46b15eb5cfb915400b31c54a305068744ba 100644 --- a/scripts/config/ivas_modes.json +++ b/scripts/config/ivas_modes.json @@ -4967,7 +4967,7 @@ "table_name": "OMASA ISM1 2TC @{table_bitrate} kbps {bandwidth}", "nummetadata": 2, "metadatafilenames": [ - "{item}_ISM1.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": false, @@ -5042,7 +5042,7 @@ "table_name": "OMASA ISM1 2TC @{table_bitrate} RS {bandwidth}", "nummetadata": 2, "metadatafilenames": [ - "{item}_ISM1.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": true, @@ -5081,7 +5081,7 @@ "table_name": "OMASA ISM1 1TC @{table_bitrate} kbps {bandwidth}", "nummetadata": 2, "metadatafilenames": [ - "{item}_ISM1.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": false, @@ -5129,8 +5129,7 @@ "table_name": "OMASA ISM2 2TC @{table_bitrate} kbps {bandwidth}", "nummetadata": 3, "metadatafilenames": [ - "{item}_ISM1.csv", - "{item}_ISM2.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": false, @@ -5204,8 +5203,7 @@ "table_name": "OMASA ISM2 2TC @{table_bitrate} RS {bandwidth}", "nummetadata": 3, "metadatafilenames": [ - "{item}_ISM1.csv", - "{item}_ISM2.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": true, @@ -5243,8 +5241,7 @@ "table_name": "OMASA ISM2 1TC @{table_bitrate} kbps {bandwidth}", "nummetadata": 3, "metadatafilenames": [ - "{item}_ISM1.csv", - "{item}_ISM2.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": false, @@ -5293,9 +5290,7 @@ "table_name": "OMASA ISM3 2TC @{table_bitrate} kbps {bandwidth}", "nummetadata": 4, "metadatafilenames": [ - "{item}_ISM1.csv", - "{item}_ISM2.csv", - "{item}_ISM3.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": false, @@ -5369,9 +5364,7 @@ "table_name": "OMASA ISM3 2TC @{table_bitrate} RS {bandwidth}", "nummetadata": 4, "metadatafilenames": [ - "{item}_ISM1.csv", - "{item}_ISM2.csv", - "{item}_ISM3.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": true, @@ -5409,9 +5402,7 @@ "table_name": "OMASA ISM3 1TC @{table_bitrate} kbps {bandwidth}", "nummetadata": 4, "metadatafilenames": [ - "{item}_ISM1.csv", - "{item}_ISM2.csv", - "{item}_ISM3.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": false, @@ -5460,10 +5451,7 @@ "table_name": "OMASA ISM4 2TC @{table_bitrate} kbps {bandwidth}", "nummetadata": 5, "metadatafilenames": [ - "{item}_ISM1.csv", - "{item}_ISM2.csv", - "{item}_ISM3.csv", - "{item}_ISM4.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": false, @@ -5537,10 +5525,7 @@ "table_name": "OMASA ISM4 2TC @{table_bitrate} RS {bandwidth}", "nummetadata": 5, "metadatafilenames": [ - "{item}_ISM1.csv", - "{item}_ISM2.csv", - "{item}_ISM3.csv", - "{item}_ISM4.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": true, @@ -5578,10 +5563,7 @@ "table_name": "OMASA ISM4 1TC @{table_bitrate} kbps {bandwidth}", "nummetadata": 5, "metadatafilenames": [ - "{item}_ISM1.csv", - "{item}_ISM2.csv", - "{item}_ISM3.csv", - "{item}_ISM4.csv", + "{item}_ISM{mdi}.csv", "{item}.met" ], "rs": false, diff --git a/scripts/pyivastest/IvasModeCollector.py b/scripts/pyivastest/IvasModeCollector.py index b5e386f794c4b737d7f3ae1b2716342d240a1864..50efe78e137a798a37181cda40ee95f7e794a365 100644 --- a/scripts/pyivastest/IvasModeCollector.py +++ b/scripts/pyivastest/IvasModeCollector.py @@ -157,7 +157,8 @@ class IvasModeCollector(IvasBaseClass.IvasBaseClass): self.format_select_list = [] self.bw_select_list = [] self.global_item_list = [] - self.global_metadata_file_list = [] + self.global_ism_metadata = list() + self.global_masa_metadata = None self.global_bitstream_processing = None self.flat_mode_list = None self.filter = None @@ -482,9 +483,6 @@ class IvasModeCollector(IvasBaseClass.IvasBaseClass): def set_global_item_list(self, global_item_list): self.global_item_list = [os.path.abspath(f) for f in global_item_list] - def set_global_metadata_file_list(self, metadata_file_list): - self.global_metadata_file_list = metadata_file_list - def add_format_output_config(self, ivas_format, oc_dict): """ diff --git a/scripts/pyivastest/IvasModeRunner.py b/scripts/pyivastest/IvasModeRunner.py index c39ef36485d5a1b51bcc33e461572bcc794ef4cf..97f8808c1d2af80b619931df06c967dcfbab90e1 100644 --- a/scripts/pyivastest/IvasModeRunner.py +++ b/scripts/pyivastest/IvasModeRunner.py @@ -430,12 +430,12 @@ class IvasModeRunner(IvasModeCollector.IvasModeCollector): return self.lock.release() - metadata_file_names = [] + metadata_file_names = list() + + # TODO: is this still needed - what case does this cover? if isinstance(in_file_name, list): metadata_file_names = in_file_name[1:] in_file_name = in_file_name[0] - elif self.global_metadata_file_list: - metadata_file_names = deepcopy(self.global_metadata_file_list) self.logger.info("Encoding Mode {} input file {}".format(mode, in_file_name)) config["lock"].release() self.lock.acquire() @@ -625,89 +625,44 @@ class IvasModeRunner(IvasModeCollector.IvasModeCollector): # build the encoder commandline enc_options = enc_dec_cmd["encmodeoption"] - # metadata handling - if enc_dec_cmd["nummetadata"] > 0: - - for cur_metadata_idx in range(enc_dec_cmd["nummetadata"]): - fallback = False - if len(metadata_file_names) == 1: - # try for a filename with format patterns - metadata_file_name = metadata_file_names[0] - if metadata_file_name != "NULL": - metadata_file_name = str.format( - metadata_file_name, - item=item_base_name, - mdi=cur_metadata_idx, - ) - elif len(metadata_file_names) >= (cur_metadata_idx + 1): - metadata_file_name = str.format( - metadata_file_names[cur_metadata_idx], - item=item_base_name, - mdi=cur_metadata_idx, - ) - else: - fallback = True - - if not fallback and not os.path.exists(metadata_file_name): - # maybe we need to attach the indir - mdf_for_log = metadata_file_name - metadata_file_name = os.path.join(in_dir, metadata_file_name) - if not os.path.exists(metadata_file_name): - self.logger.warning( - "Given metadata file {} for item {} does not exists, trying default pattern!".format( - mdf_for_log, enc_file_name - ) - ) - fallback = True - - if fallback: - - if len(enc_dec_cmd["metadatafilenames"]) == 1: - # try for a filename with format patterns - metadata_file_name = enc_dec_cmd["metadatafilenames"][0] - if metadata_file_name != "NULL": - metadata_file_name = str.format( - metadata_file_name, - item=item_base_name, - mdi=cur_metadata_idx + 1, - ) - elif len(enc_dec_cmd["metadatafilenames"]) >= ( - cur_metadata_idx + 1 - ): - metadata_file_name = enc_dec_cmd["metadatafilenames"][ - cur_metadata_idx - ] - if metadata_file_name != "NULL": - metadata_file_name = str.format( - metadata_file_name, - item=item_base_name, - mdi=cur_metadata_idx, - ) - else: - self.logger.warning( - "Falling back to NULL for metadata file {} of item {}!".format( - cur_metadata_idx, enc_file_name - ) - ) + # metadata is either explicitly taken from the respective command line args or, + # if not given, the default pattern form the config is used to get filenames in + # the same dir as the input file. NULL for ISM MD has to be explicitly given, + # otherwise this may hapen without the user being aware and lead to unexpected results. + # If the default filenames from the configs do not point to existing files, the + # codec will complain later + nummetadata = enc_dec_cmd["nummetadata"] + if nummetadata > 0: + md_files = list() - metadata_file_name = "NULL" + if "OMASA" in in_format: + nummetadata -= 1 - if metadata_file_name != "NULL" and not os.path.exists( - metadata_file_name - ): - # maybe we need to attach the indir - metadata_file_name = os.path.join( - in_dir, metadata_file_name - ) - if not os.path.exists(metadata_file_name): - self.logger.warning( - "Falling back to NULL for metadata file {} of item {}!".format( - cur_metadata_idx, enc_file_name - ) - ) - metadata_file_name = "NULL" + if "ISM" in in_format: + md_files.extend(self.global_ism_metadata[:nummetadata]) + + # if not enough md files explicitly given, try default pattern from config + if len(md_files) != nummetadata: + default = os.path.join(in_dir, enc_dec_cmd["metadatafilenames"][0]) + for i in range(len(md_files), nummetadata): + md_f = default.format(item=item_base_name, mdi=i + 1) + if not os.path.exists(md_f): + self.logger.warning(f"Can't find default md file {md_file} for item {item}. Default to NULL") + md_f = "NULL" + md_files.append(md_f) - enc_options.append(metadata_file_name) + + if "MASA" in in_format: + masa_md = self.global_masa_metadata + + # if not explicitly given, try default pattern from config + if masa_md is None: + default = os.path.join(in_dir, enc_dec_cmd["metadatafilenames"][-1]) + masa_md = default.format(item=item_base_name) + + md_files.append(masa_md) + + enc_options.extend(md_files) enc_options.extend(enc_dec_cmd["encoptions"]) enc_options.extend(self.encoder_cmdline_options) @@ -1604,4 +1559,4 @@ class IvasModeRunner(IvasModeCollector.IvasModeCollector): class NoInputForAnyModesFound(Exception): - pass \ No newline at end of file + pass diff --git a/scripts/pyivastest/IvasScriptsCommon.py b/scripts/pyivastest/IvasScriptsCommon.py index 987ce9727acf32120a713882bad3b0b9e1aacb33..0d1558c8ecd6b1227f12776a665592c2777b75bd 100644 --- a/scripts/pyivastest/IvasScriptsCommon.py +++ b/scripts/pyivastest/IvasScriptsCommon.py @@ -200,12 +200,18 @@ class IvasScriptArgParser(argparse.ArgumentParser): action=ParseItems, ) self.add_argument( - "--metadata_files", - metavar="MDFILE", - help="List of common metadata files", + "--ism_metadata_files", + metavar="ISM_MDFILE", + help="List of ISM metadata files", nargs="*", default=[], ) + self.add_argument( + "--masa_metadata_file", + metavar="MASA_MDFILE", + help="MASA metadata file", + default=None, + ) self.add_argument( "-S", "--srin", @@ -664,9 +670,18 @@ def runner_setup(runner, args): runner.set_format_select_list(args["formats"]) if args["item_list"]: runner.set_global_item_list(args["item_list"]) - if args["metadata_files"]: - metadata_files = [os.path.abspath(f) for f in args["metadata_files"]] - runner.set_global_metadata_file_list(metadata_files) + + metadata_files = list() + if args["ism_metadata_files"] != []: + for f in args["ism_metadata_files"]: + md_f = f + if os.path.isfile(f): + md_f = os.path.abspath(f) + metadata_files.append(md_f) + runner.global_ism_metadata = metadata_files + if args["masa_metadata_file"] is not None: + runner.global_masa_metadata = os.path.abspath(args["masa_metadata_file"]) + if args["decoder_only"]: runner.run_encoder = False if args["info"]: