Example #1
0
 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
Example #2
0
    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))
Example #3
0
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
Example #5
0
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)
Example #9
0
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)
Example #10
0
    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,
)