예제 #1
0
    def test_index_must_be_valid(self):
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.SignalRange(
                    custom_signal_range_flag=True,
                    index=tables.PresetSignalRanges.video_8bit,
                ),
                {},
                {},
            ))
        state["major_version"] = 3
        decoder.signal_range(state, {})

        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.SignalRange(
                    custom_signal_range_flag=True,
                    index=9999,
                ),
                {},
                {},
            ))
        state["major_version"] = 3
        with pytest.raises(decoder.BadPresetSignalRange) as exc_info:
            decoder.signal_range(state, {})
        assert exc_info.value.index == 9999
예제 #2
0
    def test_index_must_be_valid(self):
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.FrameRate(
                    custom_frame_rate_flag=True,
                    index=tables.PresetFrameRates.fps_25,
                ),
                {},
                {},
            ))
        state["major_version"] = 3
        decoder.frame_rate(state, {})

        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.FrameRate(
                    custom_frame_rate_flag=True,
                    index=9999,
                ),
                {},
                {},
            ))
        state["major_version"] = 3
        with pytest.raises(decoder.BadPresetFrameRateIndex) as exc_info:
            decoder.frame_rate(state, {})
        assert exc_info.value.index == 9999
예제 #3
0
    def test_disallows_unsupported_combinations(self):
        state = {
            "wavelet_index": tables.WaveletFilters.haar_no_shift,
            "wavelet_index_ho": tables.WaveletFilters.haar_no_shift,
            "dwt_depth": 1,
            "dwt_depth_ho": 1,
        }
        state.update(
            bytes_to_state(
                serialise_to_bytes(
                    bitstream.QuantMatrix(custom_quant_matrix=False, ),
                    state.copy(),
                )))
        decoder.quant_matrix(state)

        state = {
            "wavelet_index": tables.WaveletFilters.haar_no_shift,
            "wavelet_index_ho": tables.WaveletFilters.haar_with_shift,
            "dwt_depth": 999,
            "dwt_depth_ho": 9999,
        }
        state.update(
            bytes_to_state(
                serialise_to_bytes(
                    bitstream.QuantMatrix(custom_quant_matrix=False, ),
                    state.copy(),
                )))
        with pytest.raises(decoder.NoQuantisationMatrixAvailable) as exc_info:
            decoder.quant_matrix(state)
        assert exc_info.value.wavelet_index == tables.WaveletFilters.haar_no_shift
        assert exc_info.value.wavelet_index_ho == tables.WaveletFilters.haar_with_shift
        assert exc_info.value.dwt_depth == 999
        assert exc_info.value.dwt_depth_ho == 9999
예제 #4
0
    def test_picture_not_allowed_to_change_between_fragments(self):
        fh1 = serialise_to_bytes(
            bitstream.FragmentHeader(
                fragment_slice_count=1,
                picture_number=1000,
            ))
        fh2 = serialise_to_bytes(
            bitstream.FragmentHeader(
                fragment_slice_count=1,
                picture_number=1001,
            ))

        state = bytes_to_state(fh1 + fh2)
        state["_last_picture_number"] = 1000
        state["_last_picture_number_offset"] = (-1, 4)
        state["_picture_initial_fragment_offset"] = (-1, 0)
        state[
            "picture_coding_mode"] = tables.PictureCodingModes.pictures_are_frames
        state["_num_pictures_in_sequence"] = 0
        state["_fragment_slices_remaining"] = 1
        state["fragment_slices_received"] = 0
        state["slices_x"] = 1
        state["slices_y"] = 1

        decoder.fragment_header(state)
        with pytest.raises(
                decoder.PictureNumberChangedMidFragmentedPicture) as exc_info:
            decoder.fragment_header(state)
        assert exc_info.value.last_picture_number_offset == (-1, 4)
        assert exc_info.value.picture_number_offset == (len(fh1) + 4, 7)
        assert exc_info.value.last_picture_number == 1000
        assert exc_info.value.picture_number == 1001
예제 #5
0
    def test_byte_for_byte_identical(self):
        sh1 = serialise_to_bytes(
            bitstream.SequenceHeader(
                parse_parameters=bitstream.ParseParameters(
                    major_version=1,
                    profile=tables.Profiles.low_delay,
                ), ))
        sh2 = serialise_to_bytes(
            bitstream.SequenceHeader(
                parse_parameters=bitstream.ParseParameters(major_version=2), ))

        state = bytes_to_state(sh1 + sh1 + sh2)

        decoder.sequence_header(state)
        decoder.byte_align(state)
        decoder.sequence_header(state)
        decoder.byte_align(state)
        with pytest.raises(
                decoder.SequenceHeaderChangedMidSequence) as exc_info:
            decoder.sequence_header(state)

        assert exc_info.value.last_sequence_header_offset == len(sh1)
        assert exc_info.value.last_sequence_header_bytes == sh1
        assert exc_info.value.this_sequence_header_offset == len(sh1) * 2
        assert exc_info.value.this_sequence_header_bytes == sh2
예제 #6
0
def test_whole_picture(parse_code):
    # A sanity check which runs picture decoding for whole pictures and makes
    # sure nothing crashes

    # Serialise a sample stream
    sh = bitstream.SequenceHeader(
        video_parameters=bitstream.SourceParameters(
            frame_size=bitstream.FrameSize(
                # Don't waste time on full-sized frames
                custom_dimensions_flag=True,
                frame_width=4,
                frame_height=4,
            ),
            clean_area=bitstream.CleanArea(
                custom_clean_area_flag=True,
                clean_width=4,
                clean_height=4,
            ),
        ), )
    serialisation_state = State()
    sh_bytes = serialise_to_bytes(sh, serialisation_state)
    serialisation_state["parse_code"] = parse_code
    pic_bytes = serialise_to_bytes(bitstream.PictureParse(),
                                   serialisation_state)

    # Check it is parsed without failiures
    state = bytes_to_state(sh_bytes + pic_bytes)
    state["_num_pictures_in_sequence"] = 0
    decoder.sequence_header(state)
    state["parse_code"] = parse_code
    decoder.picture_parse(state)
예제 #7
0
    def test_wavelet_index_ho_must_be_valid(self):
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.ExtendedTransformParameters(
                    asym_transform_index_flag=True,
                    wavelet_index_ho=tables.WaveletFilters.haar_no_shift,
                ), ))
        state["wavelet_index"] = tables.WaveletFilters.haar_no_shift
        state["wavelet_index_ho"] = tables.WaveletFilters.haar_no_shift
        state["dwt_depth"] = 0
        state["dwt_depth_ho"] = 0
        decoder.extended_transform_parameters(state)

        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.ExtendedTransformParameters(
                    asym_transform_index_flag=True,
                    wavelet_index_ho=9999,
                ), ))
        state["wavelet_index"] = tables.WaveletFilters.haar_no_shift
        state["wavelet_index_ho"] = tables.WaveletFilters.haar_no_shift
        state["dwt_depth"] = 0
        state["dwt_depth_ho"] = 0
        with pytest.raises(decoder.BadHOWaveletIndex) as exc_info:
            decoder.extended_transform_parameters(state)
        assert exc_info.value.wavelet_index_ho == 9999
예제 #8
0
    def test_index_must_be_valid(self):
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.ColorMatrix(
                    custom_color_matrix_flag=True,
                    index=tables.PresetColorMatrices.hdtv,
                ),
                {},
                {},
            ))
        state["major_version"] = 3
        decoder.color_matrix(state, {})

        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.ColorMatrix(
                    custom_color_matrix_flag=True,
                    index=9999,
                ),
                {},
                {},
            ))
        state["major_version"] = 3
        with pytest.raises(decoder.BadPresetColorMatrix) as exc_info:
            decoder.color_matrix(state, {})
        assert exc_info.value.index == 9999
예제 #9
0
    def test_index_must_be_valid(self):
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.TransferFunction(
                    custom_transfer_function_flag=True,
                    index=tables.PresetTransferFunctions.hybrid_log_gamma,
                ),
                {},
                {},
            ))
        state["major_version"] = 3
        decoder.transfer_function(state, {})

        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.TransferFunction(
                    custom_transfer_function_flag=True,
                    index=9999,
                ),
                {},
                {},
            ))
        state["major_version"] = 3
        with pytest.raises(decoder.BadPresetTransferFunction) as exc_info:
            decoder.transfer_function(state, {})
        assert exc_info.value.index == 9999
예제 #10
0
    def test_index_must_be_valid(self):
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.PixelAspectRatio(
                    custom_pixel_aspect_ratio_flag=True,
                    index=tables.PresetPixelAspectRatios.ratio_1_1,
                ),
                {},
                {},
            ))
        state["major_version"] = 3
        decoder.pixel_aspect_ratio(state, {})

        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.PixelAspectRatio(
                    custom_pixel_aspect_ratio_flag=True,
                    index=9999,
                ),
                {},
                {},
            ))
        state["major_version"] = 3
        with pytest.raises(decoder.BadPresetPixelAspectRatio) as exc_info:
            decoder.pixel_aspect_ratio(state, {})
        assert exc_info.value.index == 9999
예제 #11
0
def test_color_diff_sampling_format_index_must_be_valid():
    state = bytes_to_state(
        serialise_to_bytes(
            bitstream.ColorDiffSamplingFormat(
                custom_color_diff_format_flag=True,
                color_diff_format_index=tables.ColorDifferenceSamplingFormats.
                color_4_4_4,
            ),
            {},
            {},
        ))
    decoder.color_diff_sampling_format(state, {})

    state = bytes_to_state(
        serialise_to_bytes(
            bitstream.ColorDiffSamplingFormat(
                custom_color_diff_format_flag=True,
                color_diff_format_index=9999,
            ),
            {},
            {},
        ))
    with pytest.raises(decoder.BadColorDifferenceSamplingFormat) as exc_info:
        decoder.color_diff_sampling_format(state, {})
    assert exc_info.value.color_diff_format_index == 9999
예제 #12
0
    def test_level_must_be_valid(self):
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.ParseParameters(level=tables.Levels.unconstrained)))
        decoder.parse_parameters(state)

        state = bytes_to_state(
            serialise_to_bytes(bitstream.ParseParameters(level=9999)))
        with pytest.raises(decoder.BadLevel) as exc_info:
            decoder.parse_parameters(state)
        assert exc_info.value.level == 9999
예제 #13
0
    def test_profile_must_be_valid(self):
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.ParseParameters(
                    profile=tables.Profiles.high_quality)))
        decoder.parse_parameters(state)

        state = bytes_to_state(
            serialise_to_bytes(bitstream.ParseParameters(profile=9999)))
        with pytest.raises(decoder.BadProfile) as exc_info:
            decoder.parse_parameters(state)
        assert exc_info.value.profile == 9999
예제 #14
0
def test_custom_clean_area(via_custom_clean_width, clean_width, clean_height,
                           left_offset, top_offset, exp_fail):
    frame_width = 1920
    frame_height = 1080

    if via_custom_clean_width:
        video_parameters = {
            "frame_width": frame_width,
            "frame_height": frame_height,
        }
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.CleanArea(
                    custom_clean_area_flag=True,
                    clean_width=clean_width,
                    clean_height=clean_height,
                    left_offset=left_offset,
                    top_offset=top_offset,
                ),
                {},
                video_parameters,
            ))
        state["major_version"] = 3
    else:
        video_parameters = {
            "frame_width": frame_width,
            "frame_height": frame_height,
            "clean_width": clean_width,
            "clean_height": clean_height,
            "left_offset": left_offset,
            "top_offset": top_offset,
        }
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.CleanArea(custom_clean_area_flag=False, ),
                {},
                video_parameters,
            ))
        state["major_version"] = 3

    if exp_fail:
        with pytest.raises(decoder.CleanAreaOutOfRange) as exc_info:
            decoder.clean_area(state, video_parameters)
        assert exc_info.value.clean_width == clean_width
        assert exc_info.value.clean_height == clean_height
        assert exc_info.value.left_offset == left_offset
        assert exc_info.value.top_offset == top_offset
        assert exc_info.value.frame_width == frame_width
        assert exc_info.value.frame_height == frame_height
    else:
        decoder.clean_area(state, video_parameters)
예제 #15
0
    def test_profile_version_restriction(self):
        # A sequence with no pictures but (incorrectly) major_version 1 and
        # profile high quality.
        seq = bitstream.Sequence(data_units=[
            bitstream.DataUnit(
                parse_info=bitstream.ParseInfo(
                    parse_code=tables.ParseCodes.sequence_header, ),
                sequence_header=bitstream.SequenceHeader(
                    parse_parameters=bitstream.ParseParameters(
                        major_version=1,
                        profile=tables.Profiles.high_quality,
                    ),
                    video_parameters=bitstream.SourceParameters(
                        frame_size=bitstream.FrameSize(
                            # Don't waste time on full-sized frames
                            custom_dimensions_flag=True,
                            frame_width=4,
                            frame_height=4,
                        ),
                        clean_area=bitstream.CleanArea(
                            custom_clean_area_flag=True,
                            clean_width=4,
                            clean_height=4,
                        ),
                    ),
                ),
            ),
            bitstream.DataUnit(parse_info=bitstream.ParseInfo(
                parse_code=tables.ParseCodes.end_of_sequence, ), ),
        ])
        populate_parse_offsets(seq)

        state = bytes_to_state(serialise_to_bytes(seq))
        with pytest.raises(decoder.ProfileNotSupportedByVersion):
            decoder.parse_stream(state)
예제 #16
0
    def test_must_not_have_too_many_slices(
        self,
        fragment_slice_count,
        fragment_slices_remaining,
        exp_fail,
    ):
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.FragmentHeader(
                    fragment_slice_count=fragment_slice_count,
                    picture_number=0,
                )))
        state["_picture_initial_fragment_offset"] = (-1, 7)
        state["_fragment_slices_remaining"] = fragment_slices_remaining
        state["fragment_slices_received"] = 0
        state["_last_picture_number"] = 0

        # Only required in non-failing cases
        state["slices_x"] = 1
        state["slices_y"] = 1

        if exp_fail:
            with pytest.raises(
                    decoder.TooManySlicesInFragmentedPicture) as exc_info:
                decoder.fragment_header(state)
            assert exc_info.value.initial_fragment_offset == (-1, 7)
            assert exc_info.value.this_fragment_offset == (0, 7)
            assert exc_info.value.fragment_slices_received == 0
            assert exc_info.value.fragment_slices_remaining == fragment_slices_remaining
            assert exc_info.value.fragment_slice_count == fragment_slice_count
        else:
            decoder.fragment_header(state)
예제 #17
0
def test_signal_range_excursion_must_be_valid(luma_excursion,
                                              color_diff_excursion,
                                              exp_component):
    state = bytes_to_state(
        serialise_to_bytes(
            bitstream.SignalRange(
                custom_signal_range_flag=True,
                index=0,
                luma_offset=0,
                luma_excursion=luma_excursion,
                color_diff_offset=0,
                color_diff_excursion=color_diff_excursion,
            ),
            {},
            {},
        ))
    state["major_version"] = 3

    if exp_component is None:
        # Should not fail
        decoder.signal_range(state, {})
    else:
        with pytest.raises(decoder.BadCustomSignalExcursion) as exc_info:
            decoder.signal_range(state, {})
        assert exc_info.value.component_type_name == exp_component
예제 #18
0
 def test_bad_parse_code(self):
     state = bytes_to_state(
         serialise_to_bytes(bitstream.ParseInfo(parse_code=0x11)))
     state["_generic_sequence_matcher"] = Matcher(".*")
     with pytest.raises(decoder.BadParseCode) as exc_info:
         decoder.parse_info(state)
     assert exc_info.value.parse_code == 0x11
예제 #19
0
 def test_unsupported_picture_coding_mode(self):
     state = bytes_to_state(
         serialise_to_bytes(
             bitstream.SequenceHeader(picture_coding_mode=2)))
     with pytest.raises(decoder.BadPictureCodingMode) as exc_info:
         decoder.sequence_header(state)
     assert exc_info.value.picture_coding_mode == 2
예제 #20
0
    def test_first_fragment_must_have_slice_count_zero(
        self,
        fragment_slice_count,
        fragment_slices_remaining,
        exp_fail,
    ):
        state = bytes_to_state(
            serialise_to_bytes(
                bitstream.FragmentHeader(
                    fragment_slice_count=fragment_slice_count, )))
        state["_picture_initial_fragment_offset"] = (-1, 7)
        state["fragment_slices_received"] = 0
        state["_fragment_slices_remaining"] = fragment_slices_remaining

        # Required only when not failing
        state["_num_pictures_in_sequence"] = 0
        state[
            "picture_coding_mode"] = tables.PictureCodingModes.pictures_are_frames

        if exp_fail:
            with pytest.raises(decoder.FragmentedPictureRestarted) as exc_info:
                decoder.fragment_header(state)
            assert exc_info.value.initial_fragment_offset == (-1, 7)
            assert exc_info.value.this_fragment_offset == (0, 7)
            assert exc_info.value.fragment_slices_received == 0
            assert exc_info.value.fragment_slices_remaining == fragment_slices_remaining
        else:
            decoder.fragment_header(state)
예제 #21
0
 def test_supported_picture_coding_mode(self):
     state = bytes_to_state(
         serialise_to_bytes(
             bitstream.SequenceHeader(
                 picture_coding_mode=tables.PictureCodingModes.
                 pictures_are_frames)))
     decoder.sequence_header(state)
예제 #22
0
 def sh_data_unit_bytes(self, sh_bytes, sh_parse_offset):
     # parse_info + sequence header
     return (serialise_to_bytes(
         bitstream.ParseInfo(
             parse_code=tables.ParseCodes.sequence_header,
             next_parse_offset=sh_parse_offset,
         )) + sh_bytes)
예제 #23
0
 def test_unsupported_base_video_format(self):
     state = bytes_to_state(
         serialise_to_bytes(
             bitstream.SequenceHeader(base_video_format=9999)))
     with pytest.raises(decoder.BadBaseVideoFormat) as exc_info:
         decoder.sequence_header(state)
     assert exc_info.value.base_video_format == 9999
예제 #24
0
    def test_non_empty_sequence(self):
        sh = bitstream.SequenceHeader()

        seq = bitstream.Sequence(data_units=[
            bitstream.DataUnit(
                parse_info=bitstream.ParseInfo(
                    parse_code=tables.ParseCodes.sequence_header, ),
                sequence_header=sh,
            ),
            bitstream.DataUnit(
                parse_info=bitstream.ParseInfo(
                    parse_code=tables.ParseCodes.sequence_header, ),
                sequence_header=sh,
            ),
            bitstream.DataUnit(parse_info=bitstream.ParseInfo(
                parse_code=tables.ParseCodes.end_of_sequence, ), ),
        ])

        sh_length = len(serialise_to_bytes(sh))
        populate_parse_offsets(seq)

        assert seq["data_units"][0]["parse_info"]["next_parse_offset"] == (
            tables.PARSE_INFO_HEADER_BYTES + sh_length)
        assert seq["data_units"][0]["parse_info"]["previous_parse_offset"] == 0

        assert seq["data_units"][1]["parse_info"]["next_parse_offset"] == (
            tables.PARSE_INFO_HEADER_BYTES + sh_length)
        assert seq["data_units"][1]["parse_info"]["previous_parse_offset"] == (
            tables.PARSE_INFO_HEADER_BYTES + sh_length)

        assert seq["data_units"][2]["parse_info"]["next_parse_offset"] == 0
        assert seq["data_units"][2]["parse_info"]["previous_parse_offset"] == (
            tables.PARSE_INFO_HEADER_BYTES + sh_length)
예제 #25
0
 def test_value_ranges_restricted(self, dwt_depth, dwt_depth_ho, matrix,
                                  exp_fail_value):
     state = {
         "wavelet_index": tables.WaveletFilters.haar_no_shift,
         "wavelet_index_ho": tables.WaveletFilters.haar_no_shift,
         "dwt_depth": dwt_depth,
         "dwt_depth_ho": dwt_depth_ho,
         "_level_constrained_values": {
             "level": tables.Levels.sub_sd
         },
     }
     state.update(
         bytes_to_state(
             serialise_to_bytes(
                 bitstream.QuantMatrix(
                     custom_quant_matrix=True,
                     quant_matrix=matrix,
                 ),
                 state.copy(),
             )))
     if exp_fail_value is not None:
         with pytest.raises(decoder.QuantisationMatrixValueNotAllowedInLevel
                            ) as exc_info:
             decoder.quant_matrix(state)
         assert exc_info.value.value == exp_fail_value
         assert exc_info.value.allowed_values == ValueSet((0, 127))
         assert exc_info.value.level_constrained_values == {
             "level": tables.Levels.sub_sd,
             "custom_quant_matrix": True,
         }
     else:
         decoder.quant_matrix(state)
예제 #26
0
def test_initialize_wavelet_data(dwt_depth, dwt_depth_ho):
    # This test attempts to ensure that initialize_wavelet_data produces arrays
    # of the correct size etc. This is done using an all-zeros hq_slice to zero out these
    # arrays (which are initialised to 'None'). If all values are zero after
    # this step (and nothing crashes with an out-of-bounds error) this function
    # should be correct.

    state = {
        "parse_code":
        tables.ParseCodes.high_quality_picture,
        "slices_x":
        1,
        "slices_y":
        1,
        "luma_width":
        20,
        "luma_height":
        10,
        "color_diff_width":
        10,
        "color_diff_height":
        5,
        "wavelet_index":
        tables.WaveletFilters.haar_no_shift,
        "wavelet_index_ho":
        tables.WaveletFilters.haar_no_shift,
        "dwt_depth":
        dwt_depth,
        "dwt_depth_ho":
        dwt_depth_ho,
        "slice_prefix_bytes":
        0,
        "slice_size_scaler":
        1,
        "quant_matrix":
        tables.QUANTISATION_MATRICES[(
            tables.WaveletFilters.haar_no_shift,
            tables.WaveletFilters.haar_no_shift,
            dwt_depth,
            dwt_depth_ho,
        )],
    }
    state.update(
        bytes_to_state(
            serialise_to_bytes(
                bitstream.TransformData(),
                state.copy(),
            )))

    decoder.transform_data(state)

    for transform in ["y_transform", "c1_transform", "c2_transform"]:
        for level_data in state[transform].values():
            for orientation_data in level_data.values():
                for row in orientation_data:
                    for value in row:
                        assert value == 0
예제 #27
0
 def test_allowed_zero_next_parse_offset_for_pictures(self, parse_code):
     state = bytes_to_state(
         serialise_to_bytes(
             bitstream.ParseInfo(
                 parse_code=parse_code,
                 next_parse_offset=0,
             )))
     state["major_version"] = 3
     state["_generic_sequence_matcher"] = Matcher(".*")
     decoder.parse_info(state)
예제 #28
0
 def test_major_version_must_be_at_least_one(self):
     state = bytes_to_state(
         serialise_to_bytes(
             bitstream.ParseParameters(
                 level=0,
                 profile=0,
                 major_version=0,
                 minor_version=0,
             )))
     with pytest.raises(decoder.MajorVersionTooLow):
         decoder.parse_parameters(state)
예제 #29
0
 def test_minor_version_must_be_zero(self):
     state = bytes_to_state(
         serialise_to_bytes(
             bitstream.ParseParameters(
                 level=0,
                 profile=0,
                 major_version=3,
                 minor_version=1,
             )))
     with pytest.raises(decoder.MinorVersionNotZero):
         decoder.parse_parameters(state)
예제 #30
0
 def test_high_quality_profile_requires_version_two(self):
     state = bytes_to_state(
         serialise_to_bytes(
             bitstream.ParseParameters(
                 level=0,
                 profile=tables.Profiles.high_quality,
                 major_version=1,
                 minor_version=0,
             )))
     with pytest.raises(decoder.ProfileNotSupportedByVersion):
         decoder.parse_parameters(state)