# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging
import os
import tempfile
from PIL import Image

from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import file_utils
from autotest_lib.client.cros.chameleon import chameleon_port_finder
from autotest_lib.client.cros.chameleon import chameleon_stream_server
from autotest_lib.client.cros.chameleon import edid
from autotest_lib.server import test
from autotest_lib.server.cros.multimedia import remote_facade_factory


class video_PlaybackQuality(test.test):
    """Server side video playback quality measurement.

    This test measures the video playback quality by chameleon.
    It will output 2 performance data. Number of Corrupted Frames and Number of
    Dropped Frames.

    """
    version = 1

    # treat 0~0x30 as 0
    COLOR_MARGIN_0 = 0x30
    # treat (0xFF-0x60)~0xFF as 0xFF.
    COLOR_MARGIN_255 = 0xFF - 0x60

    # If we can't find the expected frame after TIMEOUT_FRAMES, raise exception.
    TIMEOUT_FRAMES = 120

    # RGB for black. Used for preamble and postamble.
    RGB_BLACK = [0, 0, 0]

    # Expected color bar rgb. The color order in the array is the same order in
    # the video frames.
    EXPECTED_RGB = [('Blue', [0, 0, 255]), ('Green', [0, 255, 0]),
                    ('Cyan', [0, 255, 255]), ('Red', [255, 0, 0]),
                    ('Magenta', [255, 0, 255]), ('Yellow', [255, 255, 0]),
                    ('White', [255, 255, 255])]

    def _save_frame_to_file(self, resolution, frame, filename):
        """Save video frame to file under results directory.

        This function will append .png filename extension.

        @param resolution: A tuple (width, height) of resolution.
        @param frame: The video frame data.
        @param filename: File name.

        """
        image = Image.fromstring('RGB', resolution, frame)
        image.save('%s/%s.png' % (self.resultsdir, filename))

    def _check_rgb_value(self, value, expected_value):
        """Check value of the RGB.

        This function will check if the value is in the range of expected value
        and its margin.

        @param value: The value for checking.
        @param expected_value: Expected value. It's ether 0 or 0xFF.
        @returns: True if the value is in range. False otherwise.

        """
        if expected_value <= value <= self.COLOR_MARGIN_0:
            return True

        if expected_value >= value >= self.COLOR_MARGIN_255:
            return True

        return False

    def _check_rgb(self, frame, expected_rgb):
        """Check the RGB raw data of all pixels in a video frame.

        Because checking all pixels may take more than one video frame time. If
        we want to analyze the video frame on the fly, we need to skip pixels
        for saving the checking time.
        The parameter of how many pixels to skip is self._skip_check_pixels.

        @param frame: Array of all pixels of video frame.
        @param expected_rgb: Expected values for RGB.
        @returns: number of error pixels.

        """
        error_number = 0

        for i in xrange(0, len(frame), 3 * (self._skip_check_pixels + 1)):
            if not self._check_rgb_value(ord(frame[i]), expected_rgb[0]):
                error_number += 1
                continue

            if not self._check_rgb_value(ord(frame[i + 1]), expected_rgb[1]):
                error_number += 1
                continue

            if not self._check_rgb_value(ord(frame[i + 2]), expected_rgb[2]):
                error_number += 1

        return error_number

    def _find_and_skip_preamble(self, description):
        """Find and skip the preamble video frames.

        @param description: Description of the log and file name.

        """
        # find preamble which is the first black frame.
        number_of_frames = 0
        while True:
            video_frame = self._stream_server.receive_realtime_video_frame()
            (frame_number, width, height, _, frame) = video_frame
            if self._check_rgb(frame, self.RGB_BLACK) == 0:
                logging.info('Find preamble at frame %d', frame_number)
                break
            if number_of_frames > self.TIMEOUT_FRAMES:
                raise error.TestFail('%s found no preamble' % description)
            number_of_frames += 1
            self._save_frame_to_file((width, height), frame,
                                     '%s_pre_%d' % (description, frame_number))
        # skip preamble.
        # After finding preamble, find the first frame that is not black.
        number_of_frames = 0
        while True:
            video_frame = self._stream_server.receive_realtime_video_frame()
            (frame_number, _, _, _, frame) = video_frame
            if self._check_rgb(frame, self.RGB_BLACK) != 0:
                logging.info('End preamble at frame %d', frame_number)
                self._save_frame_to_file((width, height), frame,
                                         '%s_end_preamble' % description)
                break
            if number_of_frames > self.TIMEOUT_FRAMES:
                raise error.TestFail('%s found no color bar' % description)
            number_of_frames += 1

    def _store_wrong_frames(self, frame_number, resolution, frames):
        """Store wrong frames for debugging.

        @param frame_number: latest frame number.
        @param resolution: A tuple (width, height) of resolution.
        @param frames: Array of video frames. The latest video frame is in the
                front.

        """
        for index, frame in enumerate(frames):
            if not frame:
                continue
            element = ((frame_number - index), resolution, frame)
            self._wrong_frames.append(element)

    def _check_color_bars(self, description):
        """Check color bars for video playback quality.

        This function will read video frame from stream server and check if the
        color is right by self._check_rgb until read postamble.
        If only some pixels are wrong, the frame will be counted to corrupted
        frame. If all pixels are wrong, the frame will be counted to wrong
        frame.

        @param description: Description of log and file name.
        @return A tuple (corrupted_frame_count, wrong_frame_count) for quality
                data.

        """
        # store the recent 2 video frames for debugging.
        # Put the latest frame in the front.
        frame_history = [None, None]
        # Check index for color bars.
        check_index = 0
        corrupted_frame_count = 0
        wrong_frame_count = 0
        while True:
            # Because the first color bar is skipped in _find_and_skip_preamble,
            # we start from the 2nd color.
            check_index = (check_index + 1) % len(self.EXPECTED_RGB)
            video_frame = self._stream_server.receive_realtime_video_frame()
            (frame_number, width, height, _, frame) = video_frame
            # drop old video frame and store new one
            frame_history.pop(-1)
            frame_history.insert(0, frame)
            color_name = self.EXPECTED_RGB[check_index][0]
            expected_rgb = self.EXPECTED_RGB[check_index][1]
            error_number = self._check_rgb(frame, expected_rgb)

            # The video frame is correct, go to next video frame.
            if not error_number:
                continue

            # Total pixels need to be adjusted by the _skip_check_pixels.
            total_pixels = width * height / (self._skip_check_pixels + 1)
            log_string = ('[%s] Number of error pixels %d on frame %d, '
                          'expected color %s, RGB %r' %
                          (description, error_number, frame_number, color_name,
                           expected_rgb))

            self._store_wrong_frames(frame_number, (width, height),
                                     frame_history)
            # clean history after they are stored.
            frame_history = [None, None]

            # Some pixels are wrong.
            if error_number != total_pixels:
                corrupted_frame_count += 1
                logging.warn('[Corrupted]%s', log_string)
                continue

            # All pixels are wrong.
            # Check if we get postamble where all pixels are black.
            if self._check_rgb(frame, self.RGB_BLACK) == 0:
                logging.info('Find postamble at frame %d', frame_number)
                break

            wrong_frame_count += 1
            logging.info('[Wrong]%s', log_string)
            # Adjust the check index due to frame drop.
            # The screen should keep the old frame or go to next video frame
            # due to frame drop.
            # Check if color is the same as the previous frame.
            # If it is not the same as previous frame, we assign the color of
            # next frame without checking.
            previous_index = ((check_index + len(self.EXPECTED_RGB) - 1)
                              % len(self.EXPECTED_RGB))
            if not self._check_rgb(frame, self.EXPECTED_RGB[previous_index][1]):
                check_index = previous_index
            else:
                check_index = (check_index + 1) % len(self.EXPECTED_RGB)

        return (corrupted_frame_count, wrong_frame_count)

    def _dump_wrong_frames(self, description):
        """Dump wrong frames to files.

        @param description: Description of the file name.

        """
        for frame_number, resolution, frame in self._wrong_frames:
            self._save_frame_to_file(resolution, frame,
                                     '%s_%d' % (description, frame_number))
        self._wrong_frames = []

    def _prepare_playback(self):
        """Prepare playback video."""
        # Workaround for white bar on rightmost and bottommost on samus when we
        # set fullscreen from fullscreen.
        self._display_facade.set_fullscreen(False)
        self._video_facade.prepare_playback(self._video_tempfile.name)

    def _get_playback_quality(self, description, capture_dimension):
        """Get the playback quality.

        This function will playback the video and analysis each video frames.
        It will output performance data too.

        @param description: Description of the log, file name and performance
                data.
        @param capture_dimension: A tuple (width, height) of the captured video
                frame.
        """
        logging.info('Start to get %s playback quality', description)
        self._prepare_playback()
        self._chameleon_port.start_capturing_video(capture_dimension)
        self._stream_server.reset_video_session()
        self._stream_server.dump_realtime_video_frame(
            False, chameleon_stream_server.RealtimeMode.BestEffort)

        self._video_facade.start_playback()
        self._find_and_skip_preamble(description)

        (corrupted_frame_count, wrong_frame_count) = (
            self._check_color_bars(description))

        self._stream_server.stop_dump_realtime_video_frame()
        self._chameleon_port.stop_capturing_video()
        self._video_facade.pause_playback()
        self._dump_wrong_frames(description)

        dropped_frame_count = self._video_facade.dropped_frame_count()

        graph_name = '%s_%s' % (self._video_description, description)
        self.output_perf_value(description='Corrupted frames',
                               value=corrupted_frame_count, units='frame',
                               higher_is_better=False, graph=graph_name)
        self.output_perf_value(description='Wrong frames',
                               value=wrong_frame_count, units='frame',
                               higher_is_better=False, graph=graph_name)
        self.output_perf_value(description='Dropped frames',
                               value=dropped_frame_count, units='frame',
                               higher_is_better=False, graph=graph_name)

    def run_once(self, host, video_url, video_description, test_regions,
                 skip_check_pixels=5):
        """Runs video playback quality measurement.

        @param host: A host object representing the DUT.
        @param video_url: The ULR of the test video.
        @param video_description: a string describes the video to play which
                will be part of entry name in dashboard.
        @param test_regions: An array of tuples (description, capture_dimension)
                for the testing region of video. capture_dimension is a tuple
                (width, height).
        @param skip_check_pixels: We will check one pixel and skip number of
                pixels. 0 means no skip. 1 means check 1 pixel and skip 1 pixel.
                Because we may take more than 1 video frame time for checking
                all pixels. Skip some pixles for saving time.

        """
        # Store wrong video frames for dumping and debugging.
        self._video_url = video_url
        self._video_description = video_description
        self._wrong_frames = []
        self._skip_check_pixels = skip_check_pixels

        factory = remote_facade_factory.RemoteFacadeFactory(
                host, results_dir=self.resultsdir, no_chrome=True)
        chameleon_board = host.chameleon
        browser_facade = factory.create_browser_facade()
        display_facade = factory.create_display_facade()
        self._display_facade = display_facade
        self._video_facade = factory.create_video_facade()
        self._stream_server = chameleon_stream_server.ChameleonStreamServer(
            chameleon_board.host.hostname)

        chameleon_board.setup_and_reset(self.outputdir)
        self._stream_server.connect()

        # Download the video to self._video_tempfile.name
        _, ext = os.path.splitext(video_url)
        self._video_tempfile = tempfile.NamedTemporaryFile(suffix=ext)
        # The default permission is 0o600.
        os.chmod(self._video_tempfile.name, 0o644)
        file_utils.download_file(video_url, self._video_tempfile.name)

        browser_facade.start_default_chrome()
        display_facade.set_mirrored(False)

        edid_path = os.path.join(self.bindir, 'test_data', 'edids',
                                 'EDIDv2_1920x1080')
        finder = chameleon_port_finder.ChameleonVideoInputFinder(
                chameleon_board, display_facade)
        for chameleon_port in finder.iterate_all_ports():
            self._chameleon_port = chameleon_port

            connector_type = chameleon_port.get_connector_type()
            logging.info('See the display on Chameleon: port %d (%s)',
                         chameleon_port.get_connector_id(),
                         connector_type)

            with chameleon_port.use_edid(
                    edid.Edid.from_file(edid_path, skip_verify=True)):
                resolution = utils.wait_for_value_changed(
                    display_facade.get_external_resolution,
                    old_value=None)
                if resolution is None:
                    raise error.TestFail('No external display detected on DUT')

            display_facade.move_to_display(
                display_facade.get_first_external_display_index())

            for description, capture_dimension in test_regions:
                self._get_playback_quality('%s_%s' % (connector_type,
                                                      description),
                                           capture_dimension)
