def test_function_in_main_codebase(self):
     try:
         # Should crash due to invalid base video format index
         video_parameters.set_source_defaults(-1)
     except:  # noqa: 722
         exc_type, exc_value, exc_tb = sys.exc_info()
     assert most_recent_pseudocode_function(exc_tb) == "set_source_defaults (11.4.2)"
 def test_complete(self):
     assert (
         count_video_parameter_differences(
             VideoParameters(set_source_defaults(BaseVideoFormats.hd1080p_50)),
             VideoParameters(set_source_defaults(BaseVideoFormats.hd1080p_60)),
         )
         == 2
     )  # frame_rate_{numer,denom}
    def test_mismatched_top_field_first(self):
        base_video_parameters = set_source_defaults(BaseVideoFormats.custom_format)
        video_parameters = set_source_defaults(BaseVideoFormats.hd1080p_50)
        level_constraints_dict = defaultdict(AnyValue)

        assert (
            list(
                iter_source_parameter_options(
                    base_video_parameters, video_parameters, level_constraints_dict
                )
            )
            == []
        )
Пример #4
0
def source_parameters(serdes, state, base_video_format):
    """
    (11.4.1) Parse the video source parameters. Returns a VideoParameters
    object.
    """
    video_parameters = set_source_defaults(base_video_format)

    with serdes.subcontext("frame_size"):
        frame_size(serdes, state, video_parameters)
    with serdes.subcontext("color_diff_sampling_format"):
        color_diff_sampling_format(serdes, state, video_parameters)
    with serdes.subcontext("scan_format"):
        scan_format(serdes, state, video_parameters)
    with serdes.subcontext("frame_rate"):
        frame_rate(serdes, state, video_parameters)
    with serdes.subcontext("pixel_aspect_ratio"):
        pixel_aspect_ratio(serdes, state, video_parameters)
    with serdes.subcontext("clean_area"):
        clean_area(serdes, state, video_parameters)
    with serdes.subcontext("signal_range"):
        signal_range(serdes, state, video_parameters)
    with serdes.subcontext("color_spec"):
        color_spec(serdes, state, video_parameters)

    return video_parameters
    def test_unsatisfiable_level_constraints(self):
        base_video_parameters = set_source_defaults(BaseVideoFormats.hd720p_50)
        video_parameters = set_source_defaults(BaseVideoFormats.hd1080p_50)
        level_constraints_dict = defaultdict(
            AnyValue,
            custom_dimensions_flag=ValueSet(False),
        )

        assert (
            list(
                iter_source_parameter_options(
                    base_video_parameters, video_parameters, level_constraints_dict
                )
            )
            == []
        )
Пример #6
0
def rank_base_video_format_similarity(
        video_parameters,
        base_video_formats=list(BaseVideoFormats),
):
    """
    Given a set of
    :py:class:`~vc2_conformance.pseudocode.video_parameters.VideoParameters`, return an
    ordered list of :py:class:`~vc2_data_tables.BaseVideoFormats` with the most
    similar format first and least similar last.

    .. note::
        The returned :py:class:`~vc2_data_tables.BaseVideoFormats` will always
        have the same ``top_field_first`` setting.

    Parameters
    ==========
    video_parameters : :py:class:`~vc2_conformance.pseudocode.video_parameters.VideoParameters`
        The video parameters against which to rank base video formats'
        similarity.
    base_video_formats : [:py:class:`~vc2_data_tables.BaseVideoFormats`, ...]
        Optional. The base video format indices to consider. Defaults to all
        base video formats.
    """
    return sorted(
        (index for index in base_video_formats
         if (BASE_VIDEO_FORMAT_PARAMETERS[index].top_field_first ==
             video_parameters["top_field_first"])),
        key=lambda index: count_video_parameter_differences(
            set_source_defaults(index),
            video_parameters,
        ),
    )
    def test_valid_bitstream(self):
        # This test runs all of the option sets produced through the bitstream
        # generator to verify that 1: the dictionaries all contain the expected
        # fields and 2: that they encode the options they're supposed to. This
        # test also indirectly tests all of the contributing option generating
        # functions.
        base_video_format = BaseVideoFormats.hd1080p_50
        video_parameters = set_source_defaults(base_video_format)
        level_constraints_dict = defaultdict(AnyValue)

        source_parameters_sets = list(
            iter_source_parameter_options(
                video_parameters, video_parameters, level_constraints_dict
            )
        )

        for context in source_parameters_sets:
            state = State()

            f = BytesIO()
            with Serialiser(BitstreamWriter(f), context) as ser:
                resulting_video_parameters = source_parameters(
                    ser,
                    state,
                    base_video_format,
                )

            assert resulting_video_parameters == video_parameters
Пример #8
0
def iter_sequence_headers(codec_features):
    """
    Generate a series of :py:class:`~vc2_conformance.bitstream.SequenceHeader`
    objects which encode the video format specified in
    :py:class:`~vc2_conformance.codec_features.CodecFeatures` dictionary
    provided.

    This generator will start with an efficient encoding of the required
    features, built on the most closely matched base video format. This will be
    followed by successively less efficient encodings (i.e. using more custom
    fields) but the same (best-matched) base video format. After this,
    encodings based on other base video formats will be produced (again
    starting with the most efficient encoding for each format first).

    This generator may output no items if the VC-2 level specified does not
    permit the format given.

    Parameters
    ==========
    codec_features : :py:class:`~vc2_conformance.codec_features.CodecFeatures`

    Yields
    ======
    sequence_header : :py:class:`~vc2_conformance.bitstream.SequenceHeader`
    """
    picture_coding_mode = codec_features["picture_coding_mode"]
    video_parameters = codec_features["video_parameters"]

    constrained_values = codec_features_to_trivial_level_constraints(
        codec_features)

    # Level constraints may force us to use a particular base video format for
    # this encoding so we try all possible encodings (starting with the most
    # compact) and stop when we find one compliant with the level restrictions.
    base_video_formats = rank_allowed_base_video_format_similarity(
        codec_features)
    for base_video_format in base_video_formats:
        base_video_parameters = set_source_defaults(base_video_format)

        filtered_constraint_table = filter_constraint_table(
            LEVEL_CONSTRAINTS,
            dict(constrained_values, base_video_format=base_video_format),
        )
        for level_constraints_dict in filtered_constraint_table:
            for source_parameters in iter_source_parameter_options(
                    base_video_parameters, video_parameters,
                    level_constraints_dict):
                yield SequenceHeader(
                    parse_parameters=make_parse_parameters(codec_features),
                    base_video_format=base_video_format,
                    video_parameters=source_parameters,
                    picture_coding_mode=picture_coding_mode,
                )
Пример #9
0
def source_parameters(state, base_video_format):
    """(11.4.1)"""
    video_parameters = set_source_defaults(base_video_format)
    frame_size(state, video_parameters)
    color_diff_sampling_format(state, video_parameters)
    scan_format(state, video_parameters)
    frame_rate(state, video_parameters)
    pixel_aspect_ratio(state, video_parameters)
    clean_area(state, video_parameters)
    signal_range(state, video_parameters)
    color_spec(state, video_parameters)
    return video_parameters
Пример #10
0
 def codec_features(self):
     return CodecFeatures(
         name="example",
         level=Levels.unconstrained,
         profile=Profiles.high_quality,
         picture_coding_mode=PictureCodingModes.pictures_are_frames,
         video_parameters=set_source_defaults(BaseVideoFormats.hd1080p_50),
         wavelet_index=WaveletFilters.haar_with_shift,
         wavelet_index_ho=WaveletFilters.haar_with_shift,
         dwt_depth=2,
         dwt_depth_ho=0,
         slices_x=120,
         slices_y=108,
         fragment_slice_count=0,
         lossless=False,
         picture_bytes=1036800,
         quantization_matrix=None,
     )
    def test_matching(self):
        video_parameters = set_source_defaults(BaseVideoFormats.hd1080p_50)

        ranking = rank_base_video_format_similarity(video_parameters)

        # Exact match
        assert ranking[0] == BaseVideoFormats.hd1080p_50

        # Close match (source sampling differs)
        assert ranking[1] == BaseVideoFormats.hd1080i_50

        # Next closest (frame rate numer/denom differs)
        assert set(ranking[2:5]) == set(
            [
                BaseVideoFormats.hd1080i_60,
                BaseVideoFormats.hd1080p_60,
                BaseVideoFormats.hd1080p_24,
            ]
        )
Пример #12
0
def video_parameters():
    video_parameters = set_source_defaults(
        tables.BaseVideoFormats.custom_format)

    # Low-resolution 4:2:0 format (matching the picture fixture above)
    video_parameters["frame_width"] = 4
    video_parameters["frame_height"] = 4
    video_parameters[
        "color_diff_format_index"] = tables.ColorDifferenceSamplingFormats.color_4_2_0
    video_parameters["clean_width"] = 4
    video_parameters["clean_height"] = 4

    # 100-bit luma samples: Not a whole number of bytes and not nearest to a
    # power-of-two bytes, and not a format Numpy natively supports
    video_parameters["luma_excursion"] = (1 << 100) - 1
    # 8-bit color-diff samples: An exact number of bytes
    video_parameters["color_diff_excursion"] = 255

    return video_parameters
def test_compute_dimensions_and_depths():
    # Just to set all unimportant fields to something sensible
    vp = set_source_defaults(BaseVideoFormats.cif)

    vp["frame_width"] = 1000
    vp["frame_height"] = 600

    # Make luma and chroma different sizes
    vp["color_diff_format_index"] = ColorDifferenceSamplingFormats.color_4_2_0

    # Make luma and chroma different depths
    vp["luma_excursion"] = 200  # 8 bits
    vp["color_diff_excursion"] = (1 << 18) - 100  # 18 bits

    # Make frame size differ from picture size
    pcm = PictureCodingModes.pictures_are_fields

    dd = compute_dimensions_and_depths(vp, pcm)

    assert list(dd.items()) == [
        (
            "Y",
            DimensionsAndDepths(width=1000,
                                height=300,
                                depth_bits=8,
                                bytes_per_sample=1),
        ),
        (
            "C1",
            DimensionsAndDepths(width=500,
                                height=150,
                                depth_bits=18,
                                bytes_per_sample=4),
        ),
        (
            "C2",
            DimensionsAndDepths(width=500,
                                height=150,
                                depth_bits=18,
                                bytes_per_sample=4),
        ),
    ]
    def test_covers_all_flag_states(self):
        # Checks that the examples produced show every flag in every possible
        # state (when the options we choose correspond with a base video
        # format).

        base_video_format = BaseVideoFormats.hd1080p_50
        video_parameters = set_source_defaults(base_video_format)
        level_constraints_dict = defaultdict(AnyValue)

        source_parameters_sets = list(
            iter_source_parameter_options(
                video_parameters, video_parameters, level_constraints_dict
            )
        )

        # {flag_name: set([bool, ...]), ...}
        observed_flag_settings = defaultdict(set)

        for src_parameters in source_parameters_sets:
            flag_settings = {}

            def find_flags(d):
                if isinstance(d, dict):
                    for key, value in d.items():
                        if key.endswith("_flag"):
                            assert key not in flag_settings
                            flag_settings[key] = value
                        else:
                            find_flags(value)

            find_flags(src_parameters)
            for flag, setting in flag_settings.items():
                observed_flag_settings[flag].add(setting)

        assert all(
            settings == set([True, False])
            for settings in observed_flag_settings.values()
        )
    def test_top_field_first_always_matches(self, top_field_first):
        video_parameters = VideoParameters(top_field_first=top_field_first)

        for index in rank_base_video_format_similarity(video_parameters):
            assert set_source_defaults(index)["top_field_first"] == top_field_first
Пример #16
0
 def test_basic_valid(self):
     assert read_codec_features_csv(
         [
             "name,                      hd",
             "level,                     unconstrained,        0",
             "profile,                   high_quality,         3",
             "base_video_format,         hd1080p_50,           custom_format",
             "picture_coding_mode,       pictures_are_frames,  pictures_are_frames",
             "frame_width,               default,              8",
             "frame_height,              default,              4",
             "color_diff_format_index,   default,              color_4_4_4",
             "source_sampling,           default,              progressive",
             "top_field_first,           default,              TRUE",
             "frame_rate_numer,          default,              1",
             "frame_rate_denom,          default,              1",
             "pixel_aspect_ratio_numer,  default,              1",
             "pixel_aspect_ratio_denom,  default,              1",
             "clean_width,               default,              8",
             "clean_height,              default,              4",
             "left_offset,               default,              0",
             "top_offset,                default,              0",
             "luma_offset,               default,              0",
             "luma_excursion,            default,              255",
             "color_diff_offset,         default,              128",
             "color_diff_excursion,      default,              255",
             "color_primaries_index,     default,              hdtv",
             "color_matrix_index,        default,              hdtv",
             "transfer_function_index,   default,              tv_gamma",
             "wavelet_index,             haar_with_shift,      haar_with_shift",
             "wavelet_index_ho,          haar_with_shift,      haar_no_shift",
             "dwt_depth,                 2,                    2",
             "dwt_depth_ho,              0,                    1",
             "slices_x,                  120,                  2",
             "slices_y,                  108,                  1",
             "fragment_slice_count,      0,                    1",
             "lossless,                  FALSE,                FALSE",
             "picture_bytes,             1036800,              24",
             "quantization_matrix,       default,              0 0 0 0 0 0 0 0",
         ]
     ) == OrderedDict(
         [
             (
                 "hd",
                 CodecFeatures(
                     name="hd",
                     level=Levels.unconstrained,
                     profile=Profiles.high_quality,
                     picture_coding_mode=PictureCodingModes.pictures_are_frames,
                     video_parameters=set_source_defaults(
                         BaseVideoFormats.hd1080p_50
                     ),
                     wavelet_index=WaveletFilters.haar_with_shift,
                     wavelet_index_ho=WaveletFilters.haar_with_shift,
                     dwt_depth=2,
                     dwt_depth_ho=0,
                     slices_x=120,
                     slices_y=108,
                     fragment_slice_count=0,
                     lossless=False,
                     picture_bytes=1036800,
                     quantization_matrix=None,
                 ),
             ),
             (
                 "column_C",
                 CodecFeatures(
                     name="column_C",
                     level=Levels.unconstrained,
                     profile=Profiles.high_quality,
                     picture_coding_mode=PictureCodingModes.pictures_are_frames,
                     video_parameters=VideoParameters(
                         frame_width=8,
                         frame_height=4,
                         color_diff_format_index=ColorDifferenceSamplingFormats.color_4_4_4,  # noqa: E501
                         source_sampling=SourceSamplingModes.progressive,
                         top_field_first=True,
                         frame_rate_numer=1,
                         frame_rate_denom=1,
                         pixel_aspect_ratio_numer=1,
                         pixel_aspect_ratio_denom=1,
                         clean_width=8,
                         clean_height=4,
                         left_offset=0,
                         top_offset=0,
                         luma_offset=0,
                         luma_excursion=255,
                         color_diff_offset=128,
                         color_diff_excursion=255,
                         color_primaries_index=PresetColorPrimaries.hdtv,
                         color_matrix_index=PresetColorMatrices.hdtv,
                         transfer_function_index=PresetTransferFunctions.tv_gamma,
                     ),
                     wavelet_index=WaveletFilters.haar_with_shift,
                     wavelet_index_ho=WaveletFilters.haar_no_shift,
                     dwt_depth=2,
                     dwt_depth_ho=1,
                     slices_x=2,
                     slices_y=1,
                     fragment_slice_count=1,
                     lossless=False,
                     picture_bytes=24,
                     quantization_matrix={
                         0: {"L": 0},
                         1: {"H": 0},
                         2: {"HL": 0, "LH": 0, "HH": 0},
                         3: {"HL": 0, "LH": 0, "HH": 0},
                     },
                 ),
             ),
         ]
     )
Пример #17
0
def read_codec_features_csv(csvfile):
    """
    Read a set of :py:class:`CodecFeatures` from a CSV file in the format
    described by :ref:`codec-features`.

    ..
        If you're reading this, you probably can't click on the reference
        above... It points to the 'Defining codec features' section of
        ``docs/user_guide/generating_test_cases.rst``

    Parameters
    ==========
    csvfile : iterable
        An iterable of lines from a CSV file, e.g. an open :py:class:`file`
        object.

    Returns
    =======
    codec_feature_sets : OrderedDict([(name, :py:class:`CodecFeatures`), ...])

    Raises
    ======
    :py:exc:`InvalidCodecFeaturesError`
        Raised if the provided CSV contains invalid or incomplete data.

        .. note::

            Validation largely extends only to syntactic issues (e.g. invalid
            integer values, 'picture_bytes' being specified for lossless
            formats etc). It does not include validation of 'deeper' issues
            such as too-small picture_bytes values or parameters not being
            permitted by the specified level.
    """
    csv_columns = read_dict_list_csv(csvfile)

    out = OrderedDict()

    for i, column in zip(islice(spreadsheet_column_names(), 1, None), csv_columns):
        if not column:
            continue

        def pop(field_name, parser, *default_):
            """
            Check for the existance of a value in the current column and return
            the native-type version of it. If a third argument, 'default', is
            given, the default value will be returned if the field contains the
            string "default".
            """
            assert len(default_) in (0, 1)
            try:
                value = column.pop(field_name)
                if default_ and value.lower() == "default":
                    return default_[0]
                else:
                    return parser(value)
            except KeyError:
                raise InvalidCodecFeaturesError(
                    "Missing entry for '{}' in '{}' column".format(
                        field_name,
                        name,
                    )
                )
            except ValueError as e:
                raise InvalidCodecFeaturesError(
                    "Invalid entry for '{}' in '{}' column: {} ({})".format(
                        field_name,
                        name,
                        value,
                        e,
                    )
                )

        features = CodecFeatures()

        # Create default names for columns where not provided
        if "name" not in column:
            name = "column_{}".format(i)
        else:
            name = column.pop("name")
        name = name.strip()

        features["name"] = name

        # Check for name uniqueness
        if name in out:
            raise InvalidCodecFeaturesError(
                "Name '{}' used more than once".format(name)
            )

        out[name] = features

        # Parse basic fields
        for field_name, field_type in [
            ("level", partial(parse_int_enum, Levels)),
            ("profile", partial(parse_int_enum, Profiles)),
            ("picture_coding_mode", partial(parse_int_enum, PictureCodingModes)),
            ("wavelet_index", partial(parse_int_enum, WaveletFilters)),
            ("wavelet_index_ho", partial(parse_int_enum, WaveletFilters)),
            ("dwt_depth", partial(parse_int_at_least, 0)),
            ("dwt_depth_ho", partial(parse_int_at_least, 0)),
            ("slices_x", partial(parse_int_at_least, 1)),
            ("slices_y", partial(parse_int_at_least, 1)),
            ("fragment_slice_count", partial(parse_int_at_least, 0)),
            ("lossless", parse_bool),
        ]:
            features[field_name] = pop(field_name, field_type)

        features["video_parameters"] = set_source_defaults(
            pop(
                "base_video_format",
                partial(parse_int_enum, BaseVideoFormats),
            )
        )

        # Parse integer video_parameters fields
        for field_name, field_type in [
            ("frame_width", partial(parse_int_at_least, 1)),
            ("frame_height", partial(parse_int_at_least, 1)),
            (
                "color_diff_format_index",
                partial(parse_int_enum, ColorDifferenceSamplingFormats),
            ),
            ("source_sampling", partial(parse_int_enum, SourceSamplingModes)),
            ("top_field_first", parse_bool),
            ("frame_rate_numer", partial(parse_int_at_least, 1)),
            ("frame_rate_denom", partial(parse_int_at_least, 1)),
            ("pixel_aspect_ratio_numer", partial(parse_int_at_least, 1)),
            ("pixel_aspect_ratio_denom", partial(parse_int_at_least, 1)),
            ("clean_width", partial(parse_int_at_least, 0)),
            ("clean_height", partial(parse_int_at_least, 0)),
            ("left_offset", partial(parse_int_at_least, 0)),
            ("top_offset", partial(parse_int_at_least, 0)),
            ("luma_offset", partial(parse_int_at_least, 0)),
            ("luma_excursion", partial(parse_int_at_least, 1)),
            ("color_diff_offset", partial(parse_int_at_least, 0)),
            ("color_diff_excursion", partial(parse_int_at_least, 1)),
            ("color_primaries_index", partial(parse_int_enum, PresetColorPrimaries)),
            ("color_matrix_index", partial(parse_int_enum, PresetColorMatrices)),
            (
                "transfer_function_index",
                partial(parse_int_enum, PresetTransferFunctions),
            ),
        ]:
            features["video_parameters"][field_name] = pop(
                field_name,
                field_type,
                features["video_parameters"][field_name],
            )

        # Parse picture_bytes option
        if features["lossless"]:
            if "picture_bytes" in column:
                raise InvalidCodecFeaturesError(
                    "Entry provided for 'picture_bytes' when lossless mode "
                    "specified for '{}' column".format(
                        name,
                    )
                )
            features["picture_bytes"] = None
        else:
            features["picture_bytes"] = pop(
                "picture_bytes",
                partial(parse_int_at_least, 1),
            )

        # Parse quantisation matrix
        features["quantization_matrix"] = pop(
            "quantization_matrix",
            partial(
                parse_quantization_matrix,
                features["dwt_depth"],
                features["dwt_depth_ho"],
            ),
            None,
        )

        # Check for extraneous rows
        if column:
            raise InvalidCodecFeaturesError(
                "Unrecognised row(s): {}".format(
                    ", ".join(set(column)),
                )
            )

    return out
Пример #18
0
 def test_all_base_video_formats_sensible(self, base_video_format):
     # Sanity check that all base video formats are considered to make sense
     video_parameters = set_source_defaults(base_video_format)
     assert sanity_check_video_parameters(video_parameters)