Commit 8c5d78cc authored by kinuthia's avatar kinuthia
Browse files

temporarily skip EXT for OMASA

parents 6c80a97d 500156c8
Loading
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ the United Nations Convention on Contracts on the International Sales of Goods.

import filecmp
import subprocess
from typing import Union
from pathlib import Path
from itertools import product
from ..testconfig import MD5_REF_DICT
from .constants import (
@@ -61,13 +63,18 @@ def get_bitstream_path(
    base_path,
    testv_name,
    encoder_format,
    bitrate,
    bitrate: Union[int, Path],
    sampling_rate,
    max_band,
    dtx,
    suffix="",
):
    bs_name = f"{testv_name}-{encoder_format}-{bitrate}kbps-{sampling_rate}kHz-max_band_{max_band}-{dtx}{suffix}.192"
    bitrate_str = f"{bitrate}kbps"
    if isinstance(bitrate, Path):
        # br switching file path given
        bitrate_str = f"BRswfile_{bitrate.name}"

    bs_name = f"{testv_name}-{encoder_format}-{bitrate_str}-{sampling_rate}kHz-max_band_{max_band}-{dtx}{suffix}.192"
    return base_path.joinpath(bs_name)


+137 −13
Original line number Diff line number Diff line
@@ -28,8 +28,11 @@ accordance with the laws of the Federal Republic of Germany excluding its confli
the United Nations Convention on Contracts on the International Sales of Goods.
"""

from itertools import product
from itertools import product, permutations
from typing import Optional
import random
from pathlib import Path
import numpy as np
import os

HERE = Path(__file__).parent
@@ -49,12 +52,112 @@ def bitrates_between(lowest, highest):
    return [b for b in BITRATES_ALL if b >= lowest and b <= highest]


def get_file_from_repo(path):
def get_file_from_repo(path, to_str=True):
    """
    Helper for getting a file from the repo, e.g. from scripts/testv. The path needs to be given relative to the repository root!
    """
    repo_root = HERE.joinpath("../..").resolve().absolute()
    return str(repo_root.joinpath(path))
    filepath = repo_root.joinpath(path)
    return str(filepath) if to_str else filepath


def random_choice(
    values: list, n, allow_repetitions: bool = False, last_init=None, seed=None
):
    """
    Generator for randomly picking from a list of values.
    """
    assert len(values) > 1

    # create copy to be safe against external modifications
    values = list(values)
    last = last_init
    if seed is not None:
        random.seed(seed)

    for i in range(n):
        while ((curr := random.choice(values)) == last) and not allow_repetitions:
            pass
        yield curr
        last = curr


def create_br_switching_file(
    bitrates: np.ndarray,
    strategy: str,
    switch_time: int = 1,
    length_frames: int = 0,
    seed: Optional[int] = None,
    starting_br: Optional[int] = None,
):
    """
    Create bitrate switching pattern files on the fly and return path to it

    bitrates - array of bitrate values to include
    strategy - how to create pattern:
        "from_array" - use given array as is
        "exhaustive" - generate array where every bitrate is preceeded and followed at least once by every other bitrate
        "random" - randomly pick from bitrates
    switch_time - number of frames before next switch
    length_frames - for "random" strategy: length of pattern in frames
    seed - for "exhaustive" and "random" strategies: inject seed for shuffling/choosing from array
    starting_br - for "exhaustive" and "random" strategies: start pattern with given bitrate, has to be contained in bitrates
    """
    STRATEGIES = ["from_array", "exhaustive", "random"]
    assert strategy in STRATEGIES
    assert starting_br is None or starting_br in bitrates

    brs = np.asarray(bitrates)

    # if no seed given, compute it from other parameters, so that same params => same seed
    if seed is None:
        seed = brs.sum() + STRATEGIES.index(strategy) + switch_time + length_frames
    random.seed(seed)

    seed_str = f"_{seed}" if strategy == "random" or strategy == "exhaustive" else ""
    length_str = f"-l{length_frames}" if length_frames > 0 else ""
    start_str = f"-start_{starting_br}" if starting_br is not None else ""
    fname = f"br_sw_pattern-{strategy}{seed_str}-{switch_time}{length_str}{start_str}"

    if strategy == "exhaustive":
        n = len(brs) - 1
        permuts = list(permutations(bitrates, 2))
        split_permuts = [permuts[i * n : (i + 1) * n] for i in range(len(brs))]
        for i in range(len(split_permuts)):
            random.shuffle(split_permuts[i])
        split_permuts = np.asarray(split_permuts)
        brs = np.concatenate([split_permuts[:, i] for i in range(n)])

        if starting_br is not None:
            # brs is still a 2-D array here
            # find first row with starting br in first column, then roll array by that amount
            i_row, i_col = np.where(brs == starting_br)
            idx_col = np.where(i_col == 0)[0][0]
            shift = i_row[idx_col]
            brs = np.roll(brs, -shift, axis=0)

    elif strategy == "random":
        brs = list()

        # if starting bitrate is given, put it at first place and sample one br less
        if starting_br is not None:
            brs = [starting_br]
            length_frames -= 1

        rand_gen = random_choice(
            bitrates,
            length_frames,
            allow_repetitions=False,
            last_init=starting_br,
            seed=seed,
        )
        brs += [x for x in rand_gen]

    brs = np.repeat(brs, switch_time).astype(np.int32)
    out_path = DUT_PATH.joinpath(fname)
    brs.tofile(out_path)

    return out_path


DTX_ON = "DTXon"
@@ -199,12 +302,24 @@ BITRATES_ISM1 = bitrates_between(13200, 128000)
BITRATES_ISM2 = bitrates_between(16400, 256000)
BITRATES_ISM3 = bitrates_between(24400, 384000)
BITRATES_ISM4 = bitrates_between(24400, 512000)
BITRATES_ISM1_EXTENDED = [b for b in BITRATES_ISM1 if b > 64000]
BITRATES_ISM2_EXTENDED = [b for b in BITRATES_ISM2 if b > 64000]
BITRATES_ISM3_EXTENDED = [b for b in BITRATES_ISM3 if b > 64000]
BITRATES_ISM4_EXTENDED = [b for b in BITRATES_ISM4 if b > 64000]
BITRATES_ISM1_EXTENDED = [b for b in BITRATES_ISM1 if b >= 64000]
BITRATES_ISM2_EXTENDED = [b for b in BITRATES_ISM2 if b >= 64000]
BITRATES_ISM3_EXTENDED = [b for b in BITRATES_ISM3 if b >= 64000]
BITRATES_ISM4_EXTENDED = [b for b in BITRATES_ISM4 if b >= 64000]
BITRATES_EVS = [5900, 7200, 8000, 9600] + BITRATES_ALL[:6] + BITRATES_ALL[7:9]

### Bitrate switching files
BR_SW_START_STEREO = [13200, 32000, 48000, 80000, 256000]
BR_SW_FILES_STEREO = dict(
    (
        start_br,
        create_br_switching_file(
            BITRATES_STEREO, "exhaustive", switch_time=5, starting_br=start_br
        ),
    )
    for start_br in BR_SW_START_STEREO
)

SAMPLING_RATES_ALL = [16, 32, 48]
MAX_BAND_ALL = ["WB", "SWB", "FB"]

@@ -424,14 +539,23 @@ DECODER_CONST_BR_NO_BINAURAL_SCENEBASED = collapse_into_list_of_pairs(
    )
)
DECODER_CONST_BR_NO_BINAURAL_COMBINED_PARAMS = collapse_into_list_of_pairs(
    list(
        product(
        COMBINED_FORMATS_PARAMS,
        OUTPUT_FORMATS_NON_BINAURAL[:10],  # one less to exclude EXT
            OSBA_PARAMS,
            OUTPUT_FORMATS_NON_BINAURAL[:-1],  # no EXT here
            SAMPLING_RATES_ALL,
        BITSTREAM_PROCESSING[:2],  # TODO: re-add JBM once fully functional
            BITSTREAM_PROCESSING,
        )
    )
    + list(
        product(
            OMASA_PARAMS,
            OUTPUT_FORMATS_NON_BINAURAL[:-1],
            SAMPLING_RATES_ALL,
            BITSTREAM_PROCESSING,
        )
    )
)


# parameters for const bitrate testcases with binaural output

+5 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ the United Nations Convention on Contracts on the International Sales of Goods.
import numpy as np
import pytest
from contextlib import contextmanager
from typing import Union
from pathlib import Path
from tempfile import TemporaryDirectory
import subprocess
@@ -101,7 +102,7 @@ def get_output_path(
def get_bitstream_and_options(
    testv_name,
    encoder_format,
    bitrate,
    bitrate: Union[int, str],
    input_sampling_rate,
    dtx,
    processing,
@@ -172,7 +173,9 @@ def get_bitstream_and_options(

        if hrtf != BINAURAL_HRTF_NONE:
            assert output_sampling_rate is not None
            options.extend(["-hrtf", str(HRTF_PATHS[hrtf]).format(fs=output_sampling_rate)])
            options.extend(
                ["-hrtf", str(HRTF_PATHS[hrtf]).format(fs=output_sampling_rate)]
            )

        if non_diegetic_pan_value is not None:
            options.extend(["-non_diegetic_pan", f"{non_diegetic_pan_value}"])
+75 −0
Original line number Diff line number Diff line
__copyright__ = """
(C) 2022-2023 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 pytest
from ..constants import *
from . import run_check, get_bitstream_and_options
from .. import get_testv_path, get_bitstream_path


@pytest.mark.parametrize("input_sampling_rate", SAMPLING_RATES_ALL)
@pytest.mark.parametrize("max_band", MAX_BAND_ALL)
@pytest.mark.parametrize("dtx", [DTX_OFF, DTX_ON])
@pytest.mark.parametrize("output_format", OUTPUT_FORMATS_ALL[:7])
@pytest.mark.parametrize("output_sampling_rate", SAMPLING_RATES_ALL)
@pytest.mark.parametrize("bitstream_processing", BITSTREAM_PROCESSING)
@pytest.mark.parametrize("start_bitrate", [13200, 32000, 48000, 80000, 256000])
def test_decoder_br_switching_stereo(
    start_bitrate,
    input_sampling_rate,
    max_band,
    dtx,
    output_format,
    output_sampling_rate,
    bitstream_processing,
    dut_decoder_frontend,
    update_ref,
):
    input_format = "STEREO"
    br_sw_file = BR_SW_FILES_STEREO[start_bitrate]
    testv_name = get_testv_path(input_format, input_sampling_rate).stem
    with get_bitstream_and_options(
        testv_name,
        input_format,
        br_sw_file,
        input_sampling_rate,
        dtx,
        processing=bitstream_processing,
        max_band=max_band,
    ) as (ref_bitstream, options):
        run_check(
            ref_bitstream,
            output_format,
            output_sampling_rate,
            options,
            dut_decoder_frontend,
            update_ref == 1,
            bitstream_processing=bitstream_processing,
        )
+5 −57
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import numpy as np
import random
import pytest
from itertools import permutations
from typing import Optional
from .. import is_be_to_ref, get_bitstream_path
from ..constants import (
    METADATA_FOR_INPUT_FORMAT,
@@ -48,57 +49,6 @@ from ..constants import (
)


def create_br_switching_file(
    bitrates: np.ndarray,
    strategy: str,
    switch_time: int = 1,
    length_frames: int = 0,
    seed: int = None,
):
    """
    Create bitrate switching pattern files on the fly and return path to it

    bitrates - array of bitrate values to include
    strategy - how to create pattern:
        "from_array" - use given array as is
        "exhaustive" - generate array where every bitrate is preceeded and followed at least once by every other bitrate
        "random" - randomly pick from bitrates
    switch_time - number of frames before next switch
    length_frames - for "random" strategy: length of pattern in frames
    seed - for "exhaustive" and "random" strategies: inject seed for shuffling/choosing from array
    """
    assert strategy in ["from_array", "exhaustive", "random"]

    seed_str = f"_{seed}" if strategy == "random" or strategy == "exhaustive" else ""
    length_str = f"-l{length_frames}" if length_frames > 0 else ""
    fname = f"br_sw_pattern-{strategy}{seed_str}-{switch_time}{length_str}"

    # TODO: maybe calculate seed based on given parameter to automatically have reproducibility
    if seed is not None:
        random.seed(seed)

    if strategy == "from_array":
        brs = bitrates
    elif strategy == "exhaustive":
        # TODO: review, probably needs more work to be really exhaustive...
        n = len(brs) - 1
        permuts = list(permutations(bitrates, 2))
        split_permuts = [permuts[i * n : (i + 1) * n] for i in range(len(brs))]
        for i in range(len(split_permuts)):
            random.shuffle(split_permuts[i])
        split_permuts = np.asarray(split_permuts)
        brs = np.concatenate([split_permuts[:, i] for i in range(n)])
    elif strategy == "random":
        brs = np.asarray(random.choices(bitrates, k=length_frames))

    brs = np.repeat(brs, switch_time).astype(np.int32)

    out_path = DUT_PATH.joinpath(fname)
    brs.tofile(out_path)

    return out_path


def get_md(input_format, md_type=None):
    md_files = METADATA_FOR_INPUT_FORMAT.get(input_format, list())
    if md_type == ISM_MD_NULL:
@@ -109,10 +59,7 @@ def get_md(input_format, md_type=None):


def get_options(input_format_1, input_format_2=None, max_band=None, md_type=None):

    print(input_format_1)
    options = list(CMDL_OPTIONS_FOR_INPUT_FORMAT[input_format_1])
    print(options)

    if md_type == ISM_MD_EXTENDED:
        assert input_format_1 in INPUT_FORMATS_OBJECT_BASED
@@ -130,7 +77,9 @@ def get_options(input_format_1, input_format_2=None, max_band=None, md_type=None
        elif input_format_2 in INPUT_FORMATS_MASA:
            input_format_combined = "OMASA"

        options_combined = list(CMDL_OPTIONS_FOR_INPUT_FORMAT.get(input_format_combined, list()))
        options_combined = list(
            CMDL_OPTIONS_FOR_INPUT_FORMAT.get(input_format_combined, list())
        )

        # add MASA MD files for OMASA modes
        md_options += get_md(input_format_2)
@@ -176,7 +125,6 @@ def run_check(
        dtx,
        suffix=bitstream_suffix,
    )
    print(options)
    encoder_frontend.run(
        bitrate,
        sampling_rate,
Loading