Skip to content

EmptyPoseBody: zero-allocation reads + fix v0.1 frame count via BytesIOReader#234

Merged
AmitMY merged 2 commits into
masterfrom
empty-pose-body-no-alloc
Jul 7, 2026
Merged

EmptyPoseBody: zero-allocation reads + fix v0.1 frame count via BytesIOReader#234
AmitMY merged 2 commits into
masterfrom
empty-pose-body-no-alloc

Conversation

@AmitMY

@AmitMY AmitMY commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Changes

1. unpack_empty_tensor no longer allocates

Returns np.broadcast_to(np.array(0, dtype=...), shape) — a zero-stride, read-only view backed by 4 bytes — instead of np.empty(shape). EmptyPoseBody keeps the full shape and dtype without shape-sized memory, and values are now deterministically 0 instead of uninitialized garbage.

2. Fix: v0.1 files read 0 frames through BytesIOReader

Adding a shape test for EmptyPoseBody exposed a pre-existing bug: read_v0_1 infers the frame count from reader.bytes_left(), but BytesIOReader.bytes_left() only counted already-buffered bytes — nearly zero right after the header. This broke every v0.1 read through the BytesIOReader path, not just EmptyPoseBody:

with open('tests/data/mediapipe.pose', 'rb') as f:
    Pose.read(f, start_frame=5)
# ValueError: Start frame 5 is greater than the number of frames 0

bytes_left() now reports the stream's remaining bytes (matching BufferReader semantics), while expect_to_read uses a new buffered_bytes_left() to decide when to fetch more from the file — the two callers need different quantities.

3. Tests

  • test_unpack_empty_tensor: shape, dtype, and buffer advancement.
  • test_read_empty_pose_body_shape_matches_numpy_pose_body: reads every sample .pose file with both NumPyPoseBody and EmptyPoseBody and asserts identical data shape, dtype, confidence shape, and fps. Skips the legacy v0.0 openpose.pose (EmptyPoseBody has never supported v0.0, which stores variable people per frame).

Verification

  • EmptyPoseBody on mediapipe.pose: shape (170, 1, 178, 3), strides (0, 0, 0, 0), 4-byte backing buffer (previously read as 0 frames).
  • Pose.read(f, start_frame=5) on a v0.1 file now matches a bytes-based read exactly (shape and values).
  • Full suite: 197 passed; only pre-existing failures (TensorFlow not installed) remain.

🤖 Generated with Claude Code

Amit Moryossef and others added 2 commits July 7, 2026 16:49
…OReader

unpack_empty_tensor now returns a zero-stride broadcast view instead of
np.empty, keeping shape and dtype without allocating shape-sized memory.

Adding a shape test exposed a pre-existing bug: BytesIOReader.bytes_left()
only counted already-buffered bytes, so v0.1 files (which infer frame count
from bytes_left) read 0 frames through any BytesIOReader path (EmptyPoseBody,
start_frame/start_time on file objects). bytes_left() now reports the
stream's remaining bytes, matching BufferReader semantics, while
expect_to_read uses the new buffered_bytes_left() for chunk fetching.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@AmitMY AmitMY merged commit 77adf0b into master Jul 7, 2026
8 checks passed
@AmitMY AmitMY deleted the empty-pose-body-no-alloc branch July 7, 2026 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant