feat(server): walk the replayed sample instead of freezing it
A still replayed as frames gave every frame the same boxes, so the live path
never saw a track move. /v1/samples/{id}?pan=N now returns a portrait 720x1280
window slid N*PAN_STEP pixels along the sample, reversing at each edge, at the
frame size and JPEG quality the phone sends.
The decoded image is cached by (mtime, size): re-reading a 1500x2000 JPEG per
frame cost more than the encode and made the walk slower than PAN_STEP says.
Measured after the cache: 3.3 ms mean per panned frame, 301 frames/s ceiling.
Two tests, both verified to fail before the change.
This commit is contained in:
parent
4b00323ae2
commit
4ce41ecb17
3 changed files with 106 additions and 2 deletions
|
|
@ -69,6 +69,30 @@ class RestContractTests(unittest.TestCase):
|
|||
self.assertIn("version", body["model"])
|
||||
self.assertEqual(body["catalog"]["sku_count"], 2)
|
||||
|
||||
def test_a_panned_sample_walks_and_stays_portrait(self):
|
||||
# The debug replay source walks a shelf by asking for a frame index. A
|
||||
# pan that returned the same window every time would freeze the stage
|
||||
# while the boxes moved, which is the bug this pins.
|
||||
first = self.client.get("/v1/samples/image6?pan=0")
|
||||
self.assertEqual(first.status_code, 200)
|
||||
self.assertEqual(first.headers["content-type"], "image/jpeg")
|
||||
|
||||
later = self.client.get("/v1/samples/image6?pan=40")
|
||||
self.assertEqual(later.status_code, 200)
|
||||
self.assertNotEqual(first.content, later.content, "a later pan must show a different window")
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
decoded = cv2.imdecode(np.frombuffer(later.content, dtype="uint8"), cv2.IMREAD_COLOR)
|
||||
height, width = decoded.shape[:2]
|
||||
self.assertEqual((width, height), (720, 1280), "the window must match the phone's portrait frame")
|
||||
|
||||
def test_a_sample_without_pan_is_the_whole_image(self):
|
||||
response = self.client.get("/v1/samples/image6")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertGreater(len(response.content), 1024)
|
||||
|
||||
def test_catalog_shape_has_no_local_paths(self):
|
||||
body = self.client.get("/v1/catalog").json()
|
||||
product = body["products"][0]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue