Commit eed8fa6b authored by sagnowski's avatar sagnowski
Browse files

Another round of manual sync from main

parent d08164cb
Loading
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ scripts/c-code_instrument/
scripts/ifdef_instrument.list
scripts/ref/
scripts/test/
scripts/out/
scripts/self_test_summary.txt
scripts/tests/cut/
scripts/tests/ref/
@@ -53,6 +54,3 @@ tests/ref
__pycache__/
*.py[cod]
*$py.class

# clangd
.cache/
+7 −2
Original line number Diff line number Diff line
# pytest.ini
# note: per convention, this file is placed in the root directory of the repository
[pytest]
addopts = -ra --tb=short --basetemp=./tmp -v
addopts = -ra --tb=short --basetemp=./tmp -n auto -v
# Write captured system-out log messages to JUnit report.
junit_logging = system-out
# Do not capture log information for passing tests to JUnit report.
junit_log_passing_tests = False
junit_duration_report = call
junit_family = xunit1
log_file_level = DEBUG
log_format = %(asctime)s %(levelname)s %(message)s
+16 −9
Original line number Diff line number Diff line
@@ -36,7 +36,9 @@ import sys
from pyivastest.IvasSvnBuilder import *
from pyivastest import IvasScriptsCommon
import pyivastest.constants as constants
from pyivastest import ivas_svn


RET_CODE_FAILURE = 101


class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript):
@@ -169,14 +171,10 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript):
        for check in checks:
            br.run(check)
            if self.args["create_html_output"]:
                revision = ivas_svn.get_local_svn_info(self.args["srcdir"], self.logger)
                if revision is None:
                    print("Could not get revision from local copy")
                    revision = -1
                else:
                    revision = revision["commit_revision"]
                cmd = ["git", "rev-parse", "HEAD"]
                commit_hash = subprocess.run(cmd, capture_output=True).stdout.decode("utf8")
                br.build_and_run_dict[check]["analyzer"].write_html_file(
                    check, self.args["create_html_output"], revision
                    check, self.args["create_html_output"], commit_hash
                )
            for r in br.build_and_run_dict[check]["runner"].results:
                self.logger.console(r[0])
@@ -195,7 +193,16 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript):
                self.args["create_complexity_tables"]
            )

        for check in checks:
            runner = br.build_and_run_dict[check]["runner"]
            failed_encs = runner.failed_modes["enc"]
            failed_decs = runner.failed_modes["dec"]
            if len(failed_encs) > 0 or len(failed_decs) > 0:
                return RET_CODE_FAILURE
            else:
                return 0


if __name__ == "__main__":
    script = IvasBuildAndRunChecks()
    script.run()
    sys.exit(script.run())
+0 −273
Original line number Diff line number Diff line
#!/usr/bin/env python3

"""
   (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
   Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
   Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
   Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
   contributors to this repository. All Rights Reserved.

   This software is protected by copyright law and by international treaties.
   The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
   Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
   Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
   Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
   contributors to this repository retain full ownership rights in their respective contributions in
   the software. This notice grants no license of any kind, including but not limited to patent
   license, nor is any license granted by implication, estoppel or otherwise.

   Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
   contributions.

   This software is provided "AS IS", without any express or implied warranties. The software is in the
   development stage. It is intended exclusively for experts who have experience with such software and
   solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
   and fitness for a particular purpose are hereby disclaimed and excluded.

   Any dispute, controversy or claim arising under or in relation to providing this software shall be
   submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
   accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
   the United Nations Convention on Contracts on the International Sales of Goods.
"""

"""
Script to run the pytest tests.

Step 1: Set the stage for the pytest run.

Step 2: Run pytest.
"""

import os
import sys
import argparse
import subprocess
import platform
from pathlib import Path

sys.path.append('scripts/ivas_pytests/tests/')
from cut_pcm import cut_samples

BIN_EXT = ".exe" if platform.system() == "Windows" else ""
HERE = Path(__file__).parent.resolve()
DEFAULT_ENCODER_DUT = str(HERE.joinpath(f"../../IVAS_cod{BIN_EXT}").resolve())
DEFAULT_DECODER_DUT = str(HERE.joinpath(f"../../IVAS_dec{BIN_EXT}").resolve())
DEFAULT_ENCODER_REF = str(HERE.joinpath(f"../../IVAS_cod_ref{BIN_EXT}").resolve())
DEFAULT_DECODER_REF = str(HERE.joinpath(f"../../IVAS_dec_ref{BIN_EXT}").resolve())
CREND_UNITTEST_REF = str(HERE.joinpath(f"tests/unit_tests/crend/IVAS_crend_unit_test_ref{BIN_EXT}").resolve())
TEST_VECTOR_DIR = str(HERE.joinpath("../testv").resolve())
REFERENCE_DIR = str(HERE.joinpath("ref").resolve())
DUT_BASE_DIR = str(HERE.joinpath("dut").resolve())


def build_enc_and_dec(src_dir):
    """
    Build the encoder and decoder binaries.
    """
    if platform.system() == "Windows":
        olddir = os.getcwd()
        os.chdir(src_dir)
        os.chdir("Workspace_msvc")
        command = ["MSBuild.exe", "Workspace_msvc.sln", "/t:Clean", "/p:configuration=Release", "/p:Platform=Win32"]
        subprocess.run(command, check=True)
        command = ["MSBuild.exe", "Workspace_msvc.sln", "/property:configuration=Release", "/p:Platform=Win32"]
        subprocess.run(command, check=True)
        os.chdir(olddir)
    else:
        command = ["make", "-C", src_dir, "clean"]
        subprocess.run(command, check=True)
        command = ["make", "-C", src_dir]
        subprocess.run(command, check=True)


def build_crend_unittest(src_dir):
    """
    Build the crend unit test binary.
    """
    crend_dir = f"{src_dir}/scripts/ivas_pytests/tests/unit_tests/crend"
    if platform.system() == "Windows":
        olddir = os.getcwd()
        os.chdir(crend_dir)
        # command = ["MSBuild.exe", "ivas_crend_unit_test.sln", "/t:Clean", "/p:configuration=Release", "/p:Platform=Win32"]
        # subprocess.run(command, check=True)
        command = ["MSBuild.exe", "ivas_crend_unit_test.sln", "/property:configuration=Release", "/p:Platform=Win32"]
        subprocess.run(command, check=True)
        os.chdir(olddir)
    else:
        # command = ["make", "-C", src_dir, "clean"]
        # subprocess.run(command, check=True)
        command = ["make", "-C", src_dir, "IVAS_crend_unit_test"]
        subprocess.run(command, check=True)


def build_dut_binaries():
    """
    Build the DUT binaries.
    """
    print("Building the DUT binaries")
    dut_src_dir = str(HERE.joinpath("../..").resolve())
    build_enc_and_dec(dut_src_dir)
    build_crend_unittest(dut_src_dir)


def create_short_testvectors():
    """
    Create short (5sec) testvectors.
    """
    print("Creating short (5sec) testvectors")
    num_channels = "4" # currently only FOA
    cut_from = "0.0"
    cut_len = "5.0"
    for fs in ['48', '32', '16']:
        in_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c.pcm"
        cut_gain = "1.0"
        cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut.pcm"
        cut_samples(in_file, cut_file, num_channels, fs + "000", cut_from, cut_len, cut_gain)
        cut_gain = "16.0"
        cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut_{cut_gain}.pcm"
        cut_samples(in_file, cut_file, num_channels, fs + "000", cut_from, cut_len, cut_gain)


def main(argv):
    # check for python >= 3.7
    if sys.version_info[0] < 3 or sys.version_info[1] < 7:
        sys.exit("This script is written for Python >= 3.7. Found: " + platform.python_version())

    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument(
        "--create_only",
        action="store_true",
        default=False,
        help="Create references when needed, but don't run the tests"
    )
    parser.add_argument(
        "--numprocesses",
        action="store",
        default="auto",
        help="Number of processes to use in pytest (default: auto)",
    )
    parser.add_argument("--encref", help=f"REF encoder binary (default:{DEFAULT_ENCODER_REF})")
    parser.add_argument("--decref", help=f"REF decoder binary (default:{DEFAULT_DECODER_REF})")
    parser.add_argument("--encdut", help=f"DUT encoder binary (default:{DEFAULT_ENCODER_DUT})")
    parser.add_argument("--decdut", help=f"DUT decoder binary (default:{DEFAULT_DECODER_DUT})")

    args = parser.parse_args(argv[1:])

    # check for DUT binaries
    if args.encdut:
        encdut_path = os.path.realpath(args.encdut)
        if not os.path.exists(encdut_path):
            sys.exit(f"DUT encoder binary {encdut_path} does not exist.")
    else:
        encdut_path = DEFAULT_ENCODER_DUT
    if args.decdut:
        decdut_path = os.path.realpath(args.decdut)
        if not os.path.exists(decdut_path):
            sys.exit(f"DUT encoder binary {decdut_path} does not exist.")
    else:
        decdut_path = DEFAULT_DECODER_DUT
    if not os.path.exists(encdut_path) or not os.path.exists(decdut_path):
        build_dut_binaries()

    if not os.path.exists(REFERENCE_DIR):
        # check for REF binaries
        if args.encref:
            encref_path = os.path.realpath(args.encref)
            if not os.path.exists(encref_path):
                sys.exit(f"REF encoder binary {encref_path} does not exist.")
        else:
            encref_path = DEFAULT_ENCODER_REF
        if args.decref:
            decref_path = os.path.realpath(args.decref)
            if not os.path.exists(decref_path):
                sys.exit(f"REF encoder binary {decref_path} does not exist.")
        else:
            decref_path = DEFAULT_DECODER_REF
        if not os.path.exists(encref_path) or not os.path.exists(decref_path):
            sys.exit("Reference binaries do not exist.")

    # check for test vectors
    if not os.path.exists(TEST_VECTOR_DIR):
        sys.exit(f"Test vector directory {TEST_VECTOR_DIR} does not exist.")

    # check for references
    if os.path.exists(REFERENCE_DIR):
        print(f"Using existing references directory {REFERENCE_DIR}")
    else:
        # create references
        print(f"Creating references within the references directory {REFERENCE_DIR}")
        create_short_testvectors()
        if platform.system() == "Windows":
            base_cmd = ["pytest"]
        else:
            base_cmd = ["python3", "-m", "pytest"]
        base_cmd += [
            "scripts/ivas_pytests/tests",
            "-n",
            args.numprocesses,
            "--update_ref",
            "1",
            "-v",
            "--data_system_tests_path",
            TEST_VECTOR_DIR,
            "--reference_path",
            REFERENCE_DIR,
            "--dut_base_path",
            DUT_BASE_DIR,
            "--ref_encoder_path",
            encref_path,
            "--ref_decoder_path",
            decref_path,
            "--dut_encoder_path",
            encdut_path,
            "--dut_decoder_path",
            decdut_path,
        ]
        # work-around in unit tests via environment variable
        # TESTVECTOR_PATH_REL_GROUPB: to specify the test vector directory relative to ivas_pytests folder
        # TESTVECTOR_PATH_REL_TRUNK:  to specify the test vector directory relative to trunk
        my_env = os.environ.copy()
        my_env["TESTVECTOR_PATH_REL_GROUPB"] = "testv/"
        my_env["TESTVECTOR_PATH_REL_TRUNK"] = "/scripts/ivas_pytests/testv/"  # leading "/" is important
        my_env["CREND_UNIT_TEST_BIN"] = CREND_UNITTEST_REF
        print("pytest command line to be executed from project root folder:")
        print(" ".join(base_cmd + ["-m", "create_ref"]))
        subprocess.run(base_cmd + ["-m", "create_ref"], check=False, env=my_env)
        print("pytest command line to be executed from project root folder:")
        print(" ".join(base_cmd + ["-m", "create_ref_part2"]))
        subprocess.run(base_cmd + ["-m", "create_ref_part2"], check=False, env=my_env)

    if args.create_only:
        return

    # run pytest
    if platform.system() == "Windows":
        cmd = ["pytest"]
    else:
        cmd = ["python3", "-m", "pytest"]
    cmd += [
        "scripts/ivas_pytests/tests",
        "-n",
        args.numprocesses,
        "-v",
        "--data_system_tests_path",
        TEST_VECTOR_DIR,
        "--reference_path",
        REFERENCE_DIR,
        "--dut_base_path",
        DUT_BASE_DIR,
        "--dut_encoder_path",
        encdut_path,
        "--dut_decoder_path",
        decdut_path,
        "--junit-xml=report-junit.xml",
    ]
    # print pytest commandline
    print("pytest command line to be executed from project root folder:")
    print(" ".join(cmd))
    result = subprocess.run(cmd, check=False)
    return result.returncode


if __name__ == "__main__":
    sys.exit(main(sys.argv))
+0 −61
Original line number Diff line number Diff line
"""
   (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
   Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
   Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
   Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
   contributors to this repository. All Rights Reserved.

   This software is protected by copyright law and by international treaties.
   The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
   Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
   Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
   Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
   contributors to this repository retain full ownership rights in their respective contributions in
   the software. This notice grants no license of any kind, including but not limited to patent
   license, nor is any license granted by implication, estoppel or otherwise.

   Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
   contributions.

   This software is provided "AS IS", without any express or implied warranties. The software is in the
   development stage. It is intended exclusively for experts who have experience with such software and
   solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
   and fitness for a particular purpose are hereby disclaimed and excluded.

   Any dispute, controversy or claim arising under or in relation to providing this software shall be
   submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
   accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
   the United Nations Convention on Contracts on the International Sales of Goods.
"""

import os


def il2mm(file_in, num_ch, b_delete=True):
    """
    Convert interleaved input file to multiple mono output files.
    """
    num_bytes_per_sample = 2
    num_bytes_per_frame = num_bytes_per_sample * num_ch
    num_bytes_per_channel = os.path.getsize(file_in) / num_ch

    with open(file_in, "rb") as fid_in:
        out_path = os.path.splitext(file_in)[0]
        for chan in range(num_ch):
            file_out = out_path + str(chan + 1) + "ch.raw"
            with open(file_out, "wb") as fid_out:
                bytes_written = 0
                offset = chan * num_bytes_per_sample
                fid_in.seek(offset, 0)
                while bytes_written < num_bytes_per_channel:
                    data = fid_in.read(num_bytes_per_sample)
                    fid_in.seek(num_bytes_per_frame - num_bytes_per_sample, 1)
                    written = fid_out.write(bytes(data))
                    assert (
                        written == num_bytes_per_sample
                    ), f"Error writing data: {written} != {num_bytes_per_sample}"
                    bytes_written += num_bytes_per_sample

    # delete interleaved input file
    if b_delete:
        os.remove(file_in)
Loading