def output_picture(picture, video_parameters, picture_coding_mode): file_format.write( picture, video_parameters, picture_coding_mode, os.path.join( model_answer_directory, "picture_{}.raw".format(index[0]), ), ) index[0] += 1
def _output_picture(self, picture, video_parameters, picture_coding_mode): filename = self._output_filename % (self._next_picture_index, ) self._next_picture_index += 1 write( picture, video_parameters, picture_coding_mode, filename, ) if self._show_status: self._update_status_line( "Decoded picture written to {}".format(filename))
def test_read_and_write_convenience_functions(picture, video_parameters, picture_coding_mode, tmp_path): filename = os.path.join(str(tmp_path), "test_file.xxx") write(picture, video_parameters, picture_coding_mode, filename) # Correct files created assert set(os.listdir(str(tmp_path))) == set( ["test_file.raw", "test_file.json"]) # Round-trip works assert read(filename) == ( picture, video_parameters, picture_coding_mode, )
def test_video_range(self, video_parameters, tmpdir): video_parameters[ "color_diff_format_index" ] = ColorDifferenceSamplingFormats.color_4_4_4 video_parameters["luma_offset"] = 16 video_parameters["luma_excursion"] = 219 video_parameters["color_diff_offset"] = 128 video_parameters["color_diff_excursion"] = 224 deltas = { "Y": np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0]]), "C1": np.array([[1, 1, 1, 0], [1, 1, 0, 1], [0, 0, 0, 0], [0, 0, 0, 0]]), "C2": np.array([[1, 1, 0, 0], [1, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]), } mask = generate_difference_mask_picture(deltas, video_parameters, 100) write( mask, video_parameters, PictureCodingModes.pictures_are_frames, str(tmpdir.join("out.raw")), ) assert mask["Y"].tolist() == [ [235, 235, 235, 16], [235, 235, 16, 235], [16, 235, 16, 235], [235, 16, 235, 16], ] assert mask["C1"].tolist() == [ [128, 128, 128, 128], [128, 128, 128, 128], [128, 128, 128, 128], [128, 128, 128, 128], ] assert mask["C2"].tolist() == [ [128, 128, 128, 128], [128, 128, 128, 128], [128, 128, 128, 128], [128, 128, 128, 128], ] assert mask["pic_num"] == 100
def output_encoder_test_case(output_dir, codec_features, test_case): """ Write an encoder test case to disk. Parameters ========== output_dir : str Output directory to write test cases to. codec_features : :py:class:`~vc2_conformance.codec_features.CodecFeatures` test_case : :py:class:`~vc2_conformance.test_cases.TestCase` """ # Write raw pictures for i, picture in enumerate(test_case.value.pictures): picture_directory = os.path.join( output_dir, test_case.name, ) makedirs(picture_directory, exist_ok=True) file_format.write( picture, test_case.value.video_parameters, test_case.value.picture_coding_mode, os.path.join( picture_directory, "picture_{}.raw".format(i), ), ) # Write metadata if test_case.metadata is not None: with open( os.path.join( output_dir, "{}_metadata.json".format(test_case.name), ), "w", ) as f: json.dump(test_case.metadata, f) logging.info( "Generated encoder test case %s for %s", test_case.name, codec_features["name"], )
def test_rgb(self, video_parameters, tmpdir): video_parameters[ "color_diff_format_index" ] = ColorDifferenceSamplingFormats.color_4_4_4 video_parameters["color_matrix_index"] = PresetColorMatrices.rgb video_parameters["luma_offset"] = 0 video_parameters["color_diff_offset"] = 0 deltas = { "Y": np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0]]), "C1": np.array([[1, 1, 1, 0], [1, 1, 0, 1], [0, 0, 0, 0], [0, 0, 0, 0]]), "C2": np.array([[1, 1, 0, 0], [1, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]), } mask = generate_difference_mask_picture(deltas, video_parameters, 100) write( mask, video_parameters, PictureCodingModes.pictures_are_frames, str(tmpdir.join("out.raw")), ) assert mask["Y"].tolist() == [ [1023, 1023, 1023, 0], [1023, 1023, 0, 1023], [0, 1023, 0, 1023], [1023, 0, 1023, 0], ] assert mask["C1"].tolist() == [ [1023, 1023, 1023, 0], [1023, 1023, 0, 1023], [0, 1023, 0, 1023], [1023, 0, 1023, 0], ] assert mask["C2"].tolist() == [ [1023, 1023, 1023, 0], [1023, 1023, 0, 1023], [0, 1023, 0, 1023], [1023, 0, 1023, 0], ] assert mask["pic_num"] == 100
def write_pictures_to_dir( picture_generator, video_parameters, picture_coding_mode, dirname, ): """ Take a set of pictures generated by ``picture_generator`` and write them as raw images to the specified directory. """ for i, picture in enumerate(picture_generator): write( picture, video_parameters, picture_coding_mode, os.path.join( dirname, "picture_{}.raw".format(i), ), )
def generate_picture( filename, pixel_values=0, picture_number=0, bit_width=10, luma_bit_width=None, color_diff_bit_width=None, picture_coding_mode=PictureCodingModes.pictures_are_fields, width=8, height=4, ): """ Generate a 4:2:0 color subsampled raw picture with the specified file name. Parameters ========== filename : str Filename to write the raw picture to. pixel_values : int or (2D-array, 2D-array, 2D-array) If an integer, a ``width`` x ``height`` picture with all pixel values set to that value will be generated. If a set of three 2D arrays, uses these for the picture. The second and third arrays must be exactly half the width and height of the first. picture_number: int The VC-2 picture number. bit_width : int Bit depth for pixel values. luma_bit_width : int Bit depth for luma pixel values (overrides bit_width). color_diff_bit_width : int Bit depth for color difference pixel values (overrides bit_width). picture_coding_mode : :py:class:`~vc2_data_tables.PictureCodingModes` The picture coding mode to use. width, height : int The dimensions of the picture to generate (not the frame dimensions). Ignored if pixel_values is given. """ if isinstance(pixel_values, int): pixel_values = ( np.full((height, width), pixel_values, dtype=np.int64), np.full((height // 2, width // 2), pixel_values, dtype=np.int64), np.full((height // 2, width // 2), pixel_values, dtype=np.int64), ) else: pixel_values = ( np.array(pixel_values[0]), np.array(pixel_values[1]), np.array(pixel_values[2]), ) height, width = pixel_values[0].shape assert pixel_values[1].shape == (height // 2, width // 2) assert pixel_values[2].shape == (height // 2, width // 2) if luma_bit_width is None: luma_bit_width = bit_width if color_diff_bit_width is None: color_diff_bit_width = bit_width if picture_coding_mode == PictureCodingModes.pictures_are_fields: height *= 2 video_parameters = VideoParameters( frame_width=width, frame_height=height, color_diff_format_index=ColorDifferenceSamplingFormats.color_4_2_0, 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=width, clean_height=height, left_offset=0, top_offset=0, luma_offset=0, luma_excursion=(1 << luma_bit_width) - 1, color_diff_offset=1 << (color_diff_bit_width - 1), color_diff_excursion=(1 << color_diff_bit_width) - 1, color_primaries_index=PresetColorPrimaries.hdtv, color_matrix_index=PresetColorMatrices.hdtv, transfer_function_index=PresetTransferFunctions.tv_gamma, ) picture = { "Y": pixel_values[0], "C1": pixel_values[1], "C2": pixel_values[2], "pic_num": picture_number, } write(picture, video_parameters, picture_coding_mode, filename)
def compare_pictures(filename_a, filename_b, difference_mask_filename=None): """ Compare a pair of pictures. Returns a string describing the differences between the pictures (if any) and integer return code which is non-zero iff the pictures differ. If a difference_mask filename is given, writes a difference mask to that file. """ out = "" ( (picture_a, video_parameters_a, picture_coding_mode_a), (picture_b, video_parameters_b, picture_coding_mode_b), byte_for_byte_identical, ) = read_pictures_with_only_one_metadata_file_required( filename_a, filename_b) if video_parameters_a != video_parameters_b: out += "Video parameters are different:\n" out += indent( video_parameter_diff(video_parameters_a, video_parameters_b)) out += "\n" return (out.rstrip(), 1) if picture_coding_mode_a != picture_coding_mode_b: out += "Picture coding modes are different:\n" out += indent( picture_coding_mode_diff(picture_coding_mode_a, picture_coding_mode_b)) out += "\n" return (out.rstrip(), 2) if picture_a["pic_num"] != picture_b["pic_num"]: out += "Picture numbers are different:\n" out += indent( picture_number_diff(picture_a["pic_num"], picture_b["pic_num"])) out += "\n" return (out.rstrip(), 3) deltas = OrderedDict(( c, # NB: Convert pictures into Numpy arrays (for easier comparison) # using object mode (to ensure unlimited integer precision) np.array(picture_b[c], dtype=object) - np.array(picture_a[c], dtype=object), ) for c in ["Y", "C1", "C2"]) identical, differences = measure_differences(deltas, video_parameters_a, picture_coding_mode_a) if identical: if not byte_for_byte_identical: out += ("Warning: Padding bits in raw picture data are different " "(is file endianness correct?)\n") out += "Pictures are identical\n" else: out += "Pictures are different:\n" out += indent(differences) out += "\n" # Write difference mask, as required if difference_mask_filename is not None: mask = generate_difference_mask_picture( deltas, video_parameters_a, picture_number=picture_a["pic_num"], ) write(mask, video_parameters_a, picture_coding_mode_a, difference_mask_filename) return (out.rstrip(), 0 if identical else 4)
frame_height=height, color_diff_format_index=ColorDifferenceSamplingFormats.color_4_4_4, 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=width, clean_height=height, left_offset=0, top_offset=0, luma_offset=0, luma_excursion=(1 << picture_bit_width) - 1, color_diff_offset=0, color_diff_excursion=(1 << picture_bit_width) - 1, # XXX: This may/may not match the supplied image's actual colour model... color_primaries_index=PresetColorPrimaries.hdtv, color_matrix_index=PresetColorMatrices.rgb, transfer_function_index=PresetTransferFunctions.tv_gamma, ) picture_coding_mode = PictureCodingModes.pictures_are_frames file_format.write( picture, video_parameters, picture_coding_mode, args.output_filename, )