Ejemplo n.º 1
0
    def get_frame(self):
        """Take a screenshot using ADB.

        If you are capturing video from the Android device via another method
        (HDMI or `Stb-tester CAMERA`_) sometimes it can be useful to capture a
        frame via ADB for debugging. This function will manipulate the ADB
        screenshot (scale and/or rotate it) to match the screenshots from your
        main video-capture method as closely as possible, as specified by the
        `CoordinateSystem`.

        :returns: A `stbt.Frame`, that is, an image in OpenCV format. Note that
            the ``time`` attribute won't be very accurate (probably to <0.5s or
            so).
        """

        for attempt in range(1, 4):
            timestamp = time.time()
            data = (self.adb(["shell", "screencap", "-p"],
                             timeout_secs=60, capture_output=True)
                    .replace("\r\n", "\n"))
            img = cv2.imdecode(
                numpy.asarray(bytearray(data), dtype=numpy.uint8),
                cv2.CV_LOAD_IMAGE_COLOR)
            if img is None:
                logging.warning(
                    "AdbDevice.get_frame: Failed to get screenshot "
                    "via ADB (attempt %d/10)\n"
                    "Length of data: %d", attempt, len(data))
            else:
                break
        else:
            raise RuntimeError(
                "Failed to capture screenshot from android device")

        w, h = img.shape[1], img.shape[0]

        if self.coordinate_system == CoordinateSystem.ADB_NATIVE:
            pass
        elif self.coordinate_system == CoordinateSystem.ADB_720P:
            # Resize to 720p preserving orientation
            if w > h:
                img = cv2.resize(img, (1280, 720))
            else:
                img = cv2.resize(img, (720, 1280))
        elif self.coordinate_system == CoordinateSystem.CAMERA_720P:
            # Resize to 720p landscape for compatibility with screenshots from
            # `stbt.get_frame` with the Stb-tester CAMERA.
            if w > h:
                img = cv2.resize(img, (1280, 720))
            else:
                img = numpy.rot90(cv2.resize(img, (720, 1280)))
        else:
            raise NotImplementedError(
                "AdbDevice.get_frame not implemented for %s. "
                "Use a separate AdbDevice instance with "
                "coordinate_system=CoordinateSystem.ADB_NATIVE"
                % self.coordinate_system)

        return stbt.Frame(img, time=timestamp)
Ejemplo n.º 2
0
    def frames(self):
        if self._frames is not None:
            # Ignore self.state, send the specified frames instead.
            t = time.time()
            for state in self._frames:
                array = F(state, t)
                yield stbt.Frame(array, time=t)
                t += 0.04  # 25fps

        else:
            while True:
                t = time.time()
                array = F(self.state, t)
                if self.state == "fade-to-black":
                    self.state = "black"
                elif self.state == "fade-to-white":
                    self.state = "white"
                yield stbt.Frame(array, time=t)
Ejemplo n.º 3
0
def test_motionresult_repr():
    assert repr(stbt.MotionResult(
        time=1466002032.335607, motion=True,
        region=stbt.Region(x=321, y=32, right=334, bottom=42),
        frame=stbt.Frame(numpy.zeros((720, 1280, 3)),
                         time=1466002032.335607))) \
        == ("MotionResult("
            "time=1466002032.336, motion=True, "
            "region=Region(x=321, y=32, right=334, bottom=42), "
            "frame=<stbt.Frame(time=1466002032.336, dimensions=1280x720x3)>)")
Ejemplo n.º 4
0
def fake_frames():
    a = numpy.zeros((2, 2, 3), dtype=numpy.uint8)
    a.flags.writeable = False
    b = numpy.ones((2, 2, 3), dtype=numpy.uint8) * 255
    b.flags.writeable = False

    # Motion:                 v     v     v     v     v     v     v     v     v
    data = [a, a, a, a, a, a, b, b, a, a, b, b, a, a, b, b, a, a, b, b, a, a, b]
    #       ^                 ^
    #       |                 L Motion starts here at timestamp 1466084606.
    #       L Video starts here at timestamp 1466084600

    start_time = time.time()
    for n, x in enumerate(data):
        t = start_time + n
        time.sleep(t - time.time())
        yield stbt.Frame(x, time=t)
Ejemplo n.º 5
0
    def get_frame(self):
        """Take a screenshot using ADB.

        If you are capturing video from the Android device via another method
        (HDMI or `Stb-tester CAMERA`_) sometimes it can be useful to capture a
        frame via ADB for debugging. This function will manipulate the ADB
        screenshot (scale and/or rotate it) to match the screenshots from your
        main video-capture method as closely as possible, as specified by the
        `CoordinateSystem`.

        :returns: A `stbt.Frame`, that is, an image in OpenCV format. Note that
            the ``time`` attribute won't be very accurate (probably to <0.5s or
            so).
        """

        import cv2
        import numpy
        import stbt

        for attempt in range(1, 4):
            timestamp = time.time()
            data = (self.adb(["shell", "screencap", "-p"],
                             timeout_secs=60,
                             capture_output=True).replace("\r\n", "\n"))
            img = cv2.imdecode(
                numpy.asarray(bytearray(data), dtype=numpy.uint8),
                cv2.IMREAD_COLOR)
            if img is None:
                logging.warning(
                    "AdbDevice.get_frame: Failed to get screenshot "
                    "via ADB (attempt %d/3)\n"
                    "Length of data: %d", attempt, len(data))
            else:
                break
        else:
            raise RuntimeError(
                "Failed to capture screenshot from android device")

        img = _resize(img, self.coordinate_system)
        return stbt.Frame(img, time=timestamp)
Ejemplo n.º 6
0
def gradient_wipe(min_=100, max_=200, swipe_height=40):
    """Use write_video(gradient_wipe()) to see what this looks like."""
    frame = min_ * numpy.ones(
        (720 + swipe_height * 4, 1280, 3), dtype=numpy.uint8)
    diff = max_ - min_

    # detect_motion ignores differences of under 40, so what's the fastest we
    # can wipe while making sure the inter-frame differences are always under
    # 40?:
    speed = 40 * swipe_height / diff

    print("pixel difference: %f" % (diff / swipe_height))
    print("max_speed: %f" % speed)

    edge = numpy.ones((swipe_height * 3, 1280, 3), dtype=numpy.uint8) * min_
    for n in range(swipe_height * 3):
        edge[n, :, :] = clamp(max_ - (n - swipe_height) * diff / swipe_height,
                              min_, max_)

    for x in range(0, frame.shape[0] - swipe_height * 3, int(speed)):
        frame[x:x + swipe_height * 3, :, :] = edge
        yield stbt.Frame(frame[swipe_height * 2:swipe_height * 2 + 720],
                         time=x / 30.)
Ejemplo n.º 7
0
 def fake_frames():
     for i, f in enumerate(
         ["box-00001.png", "box-00002.png", "box-00003.png"]):
         yield stbt.Frame(stbt.load_image(f), time=i)
Ejemplo n.º 8
0
def wipe():
    frame = numpy.zeros((720, 1280, 3), dtype=numpy.uint8)
    for x in range(0, 720, 2):
        frame[x:x + 2, :, :] = 255
        yield stbt.Frame(frame, time=x / 30.)