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
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)
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)
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
def test_picture_dimensions_must_be_multiple_of_frame_dimensions( self, frame_width, frame_height, exp_luma_width, exp_luma_height, exp_color_diff_width, exp_color_diff_height, exp_error, ): state = bytes_to_state( serialise_to_bytes( bitstream.SequenceHeader( picture_coding_mode=tables.PictureCodingModes. pictures_are_fields, video_parameters=bitstream.SourceParameters( frame_size=bitstream.FrameSize( custom_dimensions_flag=True, frame_width=frame_width, frame_height=frame_height, ), clean_area=bitstream.CleanArea( custom_clean_area_flag=True, clean_width=frame_width, clean_height=frame_height, ), color_diff_sampling_format=bitstream. ColorDiffSamplingFormat( custom_color_diff_format_flag=True, color_diff_format_index=tables. ColorDifferenceSamplingFormats. color_4_2_0, # noqa: E501 ), ), ))) if exp_error: with pytest.raises( decoder.PictureDimensionsNotMultipleOfFrameDimensions ) as exc_info: decoder.sequence_header(state) assert exc_info.value.luma_width == exp_luma_width assert exc_info.value.luma_height == exp_luma_height assert exc_info.value.color_diff_width == exp_color_diff_width assert exc_info.value.color_diff_height == exp_color_diff_height assert exc_info.value.frame_width == frame_width assert exc_info.value.frame_height == frame_height else: decoder.sequence_header(state) assert state["luma_width"] == exp_luma_width assert state["luma_height"] == exp_luma_height assert state["color_diff_width"] == exp_color_diff_width assert state["color_diff_height"] == exp_color_diff_height
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
def test_whole_picture(parse_code, fragment_slice_counts): # A sanity check which runs fragmented 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=8, frame_height=8, ), clean_area=bitstream.CleanArea( custom_clean_area_flag=True, clean_width=8, clean_height=8, ), ), ) serialisation_state = State() sh_bytes = serialise_to_bytes(sh, serialisation_state) serialisation_state["parse_code"] = parse_code frag_bytes = b"" # Add the first (header) fragment in the picture frag_bytes += serialise_to_bytes( bitstream.FragmentParse( fragment_header=bitstream.FragmentHeader(fragment_slice_count=0, ), transform_parameters=bitstream.TransformParameters( slice_parameters=bitstream.SliceParameters( slices_x=3, slices_y=2, )), ), serialisation_state, ) # Add the slice-containing fragments num_slices = 0 for fragment_slice_count in fragment_slice_counts: x = num_slices % 3 y = num_slices // 3 num_slices += fragment_slice_count frag_bytes += serialise_to_bytes( bitstream.FragmentParse(fragment_header=bitstream.FragmentHeader( fragment_slice_count=fragment_slice_count, fragment_x_offset=x, fragment_y_offset=y, ), ), serialisation_state, ) # Check it is parsed without failiures state = bytes_to_state(sh_bytes + frag_bytes) state["_num_pictures_in_sequence"] = 0 state["_fragment_slices_remaining"] = 0 decoder.sequence_header(state) # Parse header fragment decoder.byte_align(state) state["parse_code"] = parse_code decoder.fragment_parse(state) # Parse slice-containing fragments num_slices = 0 for fragment_slice_count in fragment_slice_counts: assert state["fragmented_picture_done"] is False decoder.byte_align(state) state["parse_code"] = parse_code decoder.fragment_parse(state) num_slices += fragment_slice_count assert state["fragment_slices_received"] == num_slices assert state["_fragment_slices_remaining"] == 6 - num_slices assert state["fragmented_picture_done"] is True
def test_level_constraints(): # Simply check that all constrainted level values get asserted. We check # this by making sure assert_level_constraint has added the relevant values # to # state["_level_constrained_values"]. state = bytes_to_state( serialise_to_bytes( bitstream.SequenceHeader( base_video_format=tables.BaseVideoFormats.custom_format, picture_coding_mode=tables.PictureCodingModes. pictures_are_frames, parse_parameters=bitstream.ParseParameters( level=tables.Levels.unconstrained, profile=tables.Profiles.high_quality, major_version=3, minor_version=0, ), video_parameters=bitstream.SourceParameters( frame_size=bitstream.FrameSize( custom_dimensions_flag=True, frame_width=1280, frame_height=1080, ), color_diff_sampling_format=bitstream. ColorDiffSamplingFormat( custom_color_diff_format_flag=True, color_diff_format_index=tables. ColorDifferenceSamplingFormats.color_4_4_4, ), scan_format=bitstream.ScanFormat( custom_scan_format_flag=True, source_sampling=tables.SourceSamplingModes.progressive, ), frame_rate=bitstream.FrameRate( custom_frame_rate_flag=True, index=0, frame_rate_numer=25, frame_rate_denom=1, ), pixel_aspect_ratio=bitstream.PixelAspectRatio( custom_pixel_aspect_ratio_flag=True, index=0, pixel_aspect_ratio_numer=1, pixel_aspect_ratio_denom=1, ), clean_area=bitstream.CleanArea( custom_clean_area_flag=True, clean_width=1, clean_height=2, left_offset=3, top_offset=4, ), signal_range=bitstream.SignalRange( custom_signal_range_flag=True, index=0, luma_offset=1, luma_excursion=2, color_diff_offset=3, color_diff_excursion=4, ), color_spec=bitstream.ColorSpec( custom_color_spec_flag=True, index=0, color_primaries=bitstream.ColorPrimaries( custom_color_primaries_flag=True, index=tables.PresetColorPrimaries.uhdtv, ), color_matrix=bitstream.ColorMatrix( custom_color_matrix_flag=True, index=tables.PresetColorMatrices.uhdtv, ), transfer_function=bitstream.TransferFunction( custom_transfer_function_flag=True, index=tables.PresetTransferFunctions. hybrid_log_gamma, ), ), ), ))) decoder.sequence_header(state) assert state["_level_constrained_values"] == { # sequence_header "base_video_format": tables.BaseVideoFormats.custom_format, "picture_coding_mode": tables.PictureCodingModes.pictures_are_frames, # parse_parameters "level": tables.Levels.unconstrained, "profile": tables.Profiles.high_quality, "major_version": 3, "minor_version": 0, # frame_size "custom_dimensions_flag": True, "frame_width": 1280, "frame_height": 1080, # color_diff_sampling_format "custom_color_diff_format_flag": True, "color_diff_format_index": tables.ColorDifferenceSamplingFormats.color_4_4_4, # scan_format "custom_scan_format_flag": True, "source_sampling": tables.SourceSamplingModes.progressive, # frame_rate "custom_frame_rate_flag": True, "frame_rate_index": 0, "frame_rate_numer": 25, "frame_rate_denom": 1, # pixel_aspect_ratio "custom_pixel_aspect_ratio_flag": True, "pixel_aspect_ratio_index": 0, "pixel_aspect_ratio_numer": 1, "pixel_aspect_ratio_denom": 1, # clean_area "custom_clean_area_flag": True, "clean_width": 1, "clean_height": 2, "left_offset": 3, "top_offset": 4, # signal_range "custom_signal_range_flag": True, "custom_signal_range_index": 0, "luma_offset": 1, "luma_excursion": 2, "color_diff_offset": 3, "color_diff_excursion": 4, # color_spec "custom_color_spec_flag": True, "color_spec_index": 0, # color_primaries "custom_color_primaries_flag": True, "color_primaries_index": tables.PresetColorPrimaries.uhdtv, # color_matrix "custom_color_matrix_flag": True, "color_matrix_index": tables.PresetColorMatrices.uhdtv, # transfer_function "custom_transfer_function_flag": True, "transfer_function_index": tables.PresetTransferFunctions.hybrid_log_gamma, }
def test_supported_base_video_format(self): state = bytes_to_state( serialise_to_bytes( bitstream.SequenceHeader( base_video_format=tables.BaseVideoFormats.custom_format))) decoder.sequence_header(state)