Exemple #1
0
    def model_callback(self, output_sample_timestamp, frames):
        """
        Function that receives frames from measurement window, to call the model
        on and produce scores.

        Arguments:
            output_sample_timestamp {int} -- timestamp of the output sample (1, 2, ...)
            frames {list} -- list of all frames from measurement window
        """
        logger.debug("Output score at timestamp " +
                     str(output_sample_timestamp))
        output_sample_index = [
            i for i, f in enumerate(frames)
            if f["dts"] < output_sample_timestamp
        ][-1]

        # only get the relevant frames from the chunk
        frames = utils.get_chunk(frames, output_sample_index, type="video")

        first_frame = frames[0]
        if self.mode == 0:
            # average the bitrate for all of the segments
            bitrate = np.mean([f["bitrate"] for f in frames])
            score = self.video_model_function_mode0(
                utils.resolution_to_number(first_frame["resolution"]),
                utils.resolution_to_number(self.display_res), bitrate,
                first_frame["fps"])
        elif self.mode == 1:
            # average the bitrate based on the frame sizes, as implemented
            # in submitted model code
            compensated_sizes = [
                utils.calculate_compensated_size(f["type"], f["size"],
                                                 f["dts"]) for f in frames
            ]
            duration = np.sum([f["duration"] for f in frames])
            bitrate = np.sum(compensated_sizes) * 8 / duration / 1000
            score = self.video_model_function_mode1(
                utils.resolution_to_number(first_frame["resolution"]),
                utils.resolution_to_number(self.display_res), bitrate,
                first_frame["fps"], frames)
        elif self.mode == 2:
            score = self.video_model_function_mode2(
                utils.resolution_to_number(first_frame["resolution"]),
                utils.resolution_to_number(self.display_res),
                first_frame["fps"], frames)
        elif self.mode == 3:
            score = self.video_model_function_mode3(
                utils.resolution_to_number(first_frame["resolution"]),
                utils.resolution_to_number(self.display_res),
                first_frame["fps"], frames)
        else:
            raise P1203StandaloneError("Unsupported mode: {}".format(
                self.mode))

        # mobile adjustments
        if self.device in ["mobile", "handheld"]:
            score = self.handheld_adjustment(score)

        self.o22.append(score)
Exemple #2
0
    def video_model_function_mode1(self,
                                   coding_res,
                                   display_res,
                                   bitrate_kbps_segment_size,
                                   framerate,
                                   frames,
                                   iframe_ratio=None):
        """
        Mode 1 model

        Arguments:
            coding_res {int} -- number of pixels in coding resolution
            display_res {int} -- number of display resolution pixels
            bitrate_kbps_segment_size {float} -- bitrate in kBit/s
            framerate {float} -- frame rate
            frames {list} -- frames
            iframe_ratio {float} -- iframe ratio, only for debugging

        Returns:
            float -- O22 score
        """
        # compression degradation
        a1 = self.coeffs["mode1"]["a1"]
        a2 = self.coeffs["mode1"]["a2"]
        a3 = self.coeffs["mode1"]["a3"]
        a4 = self.coeffs["mode1"]["a4"]
        q1 = self.coeffs["q1"]
        q2 = self.coeffs["q2"]
        q3 = self.coeffs["q3"]
        quant = a1 + a2 * np.log(
            a3 + np.log(bitrate_kbps_segment_size) +
            np.log(bitrate_kbps_segment_size * bitrate_kbps_segment_size /
                   (coding_res * framerate) + a4))
        mos_cod_v = q1 + q2 * np.exp(q3 * quant)
        mos_cod_v = utils.constrain(mos_cod_v, 1.0, 5.0)

        # if iframe ratio is already set (debug mode)

        # complexity correction
        c0 = self.coeffs["mode1"]["c0"]
        c1 = self.coeffs["mode1"]["c1"]
        c2 = self.coeffs["mode1"]["c2"]
        c3 = self.coeffs["mode1"]["c3"]
        if not iframe_ratio:
            i_sizes = []
            noni_sizes = []
            for frame in frames:
                frame_size = utils.calculate_compensated_size(
                    frame["type"], frame["size"], frame["dts"])
                if frame["type"] == "I":
                    i_sizes.append(int(frame_size))
                else:
                    noni_sizes.append(int(frame_size))

            # only compute ratio when there are frames of both types
            if i_sizes and noni_sizes:
                iframe_ratio = np.mean(i_sizes) / np.mean(noni_sizes)
            else:
                iframe_ratio = 0
        complexity = utils.sigmoid(c0, c1, c2, c3, iframe_ratio)
        mos_cod_v += complexity

        deg_cod_v = 100.0 - utils.r_from_mos(mos_cod_v)
        deg_cod_v = utils.constrain(deg_cod_v, 0.0, 100.0)

        # scaling, framerate degradation
        deg_scal_v = self.degradation_due_to_upscaling(coding_res, display_res)
        deg_frame_rate_v = self.degradation_due_to_frame_rate_reduction(
            deg_cod_v, deg_scal_v, framerate)

        # degradation integration
        score = self.degradation_integration(mos_cod_v, deg_cod_v, deg_scal_v,
                                             deg_frame_rate_v)

        logger.debug(
            json.dumps(
                {
                    'coding_res':
                    round(coding_res, 2),
                    'display_res':
                    round(display_res, 2),
                    'bitrate_kbps_segment_size':
                    round(bitrate_kbps_segment_size, 2),
                    'framerate':
                    round(framerate, 2),
                    'mos_cod_v':
                    round(mos_cod_v, 2),
                    'deg_cod_v':
                    round(deg_cod_v, 2),
                    'iframe_ratio':
                    round(iframe_ratio, 2),
                    'complexity':
                    round(complexity, 2),
                    'deg_scal_v':
                    round(deg_scal_v, 2),
                    'deg_frame_rate_v':
                    round(deg_frame_rate_v, 2),
                    'score':
                    round(score, 2)
                },
                indent=True))

        return score