Repository navigation
Use smaller packets or the PC's other address when no video arrives - #219
Merged
Merged
Conversation
When the PC says it sent video and the iPad still has no picture, the iPad asks for smaller media datagrams (1,200, then 576 bytes, each with a fresh keyframe). If that doesn't help, it asks the PC to sign its other home network addresses with the pairing, confirms the same PC at one of them, and reconnects there. The address that worked is tried first next time. The size request is a field appended to KEYFRAME_REQUEST, and the frame count is appended to HEARTBEAT. Both are gated on FEATURE_MEDIA_SIZE and HOSTCAP_MEDIA_SIZE, so older PCs and iPads see the same bytes as before. A PC session that sent video and ended with the iPad's error goodbye without a counted frame now summarizes as no_video or no_frame instead of other.
- A remembered address gets HELLO2 and the token only after the PC there proves it holds the pairing, as a move with the same-PC checks. Without the proof, the entry is forgotten and the attempt goes to the address tapped. Entries are bound to a digest of the pairing token. - The other-address step only tries addresses on the iPad's own subnet, as a PC that Bonjour moved does. - Only the first two smaller sizes in a session skip the keyframe rate limit; later ones are ordinary keyframe requests. - The iPad's summary for a move after no picture says no_frame when some video arrived, as the PC's does.
…x/no-video-path-fallback # Conflicts: # ios/EternalMonitor/Network/WireProtocol.swift
- Before the identity check, a remembered address must be on this iPad's own subnet, as the other-address step requires; otherwise the entry is forgotten and the attempt goes to the address tapped. - When the attempt at a remembered address fails after its proof (no HELLO2 answer, no picture before the timeout, or another PC by name or pairing), the entry is forgotten and a new attempt goes to the address tapped. - Try again and a resume go to the address tapped while the remembered one is checked. - A golden vector covers a heartbeat that carries both the no-display notice and the frame count.
…in the remembered-address test
…x/no-video-path-fallback # Conflicts: # ios/EternalMonitor/App/ConnectionManager.swift # ios/EternalMonitor/Network/WireProtocol.swift # ios/EternalMonitorTests/WireProtocolGoldenTests.swift # proto/src/v2/control.rs # proto/tests/golden.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
On some networks a session is accepted and the PC streams, but the iPad gets no picture. The small handshake and heartbeat packets get through, and the large video packets don't: the path's MTU, fragmentation or a filter drops them. The iPad then retried the same address until it gave up. Field data had this on one PC with two networks. Video showed up at once when the iPad reached the PC's other address.
With this change, when the PC says it has sent video and the iPad still has no picture, the iPad:
PCs and iPads without this change behave exactly as before.
Protocol
No existing field can carry a packet-size request. HELLO2 is too early, and the receiver report has no spare field. Both new fields are appended and gated by capability bits:
FEATURE_MEDIA_SIZE(HELLO2 bit 6): the iPad may ask for smaller packets.HOSTCAP_MEDIA_SIZE(HELLO_ACK bit 7): the PC takes the request. It is set only in replies to an iPad that setFEATURE_MEDIA_SIZE, so older iPads get the same bytes as before.KeyframeRequest.max_media_dgram(u16, appended, 0 = no request): media packets no larger than this for the rest of the session, clamped to 576–1400. The first two smaller sizes in a session (the iPad asks for 1,200 and then 576) force an IDR at once, outside the keyframe rate limit; any later one is an ordinary, rate-limited keyframe request. Older hosts ignore the trailing bytes.Heartbeat.frames_sent(u32, appended afternotice, which is then always written): the video frames sent to this session so far. Only iPads that set the feature bit get it. It tells "the PC hasn't sent anything yet" (a slow second screen, a locked PC) apart from "the PC sent video and none of it made a picture", so the iPad never acts on the first case.Bits 5 and 6 are left free because #192 uses them.
The PC's own packet-size setting still applies. The session uses whichever of the two sizes is smaller, and the next session starts at the PC's setting.
Diagnostics
no_video_fallback step=smaller_packets size=<n> result=video|no_video,no_video_fallback step=other_address result=moved|none|no_answer|unpaired|moved_before, andno_video_fallback step=remembered result=tried|not_local|not_confirmed|no_reply|no_picture|other_pc.Media packet size lowered for this session max_dgram=<n> frames_sent=<n>.stage=accepted outcome=no_picture end=superseded, withfailure=no_videowhen nothing arrived orfailure=no_framewhen some video did, as on the PC.failure=other. It now saysfailure=no_videowhen no fragment arrived, orfailure=no_framewhen some did.Tests
hello_ack_media_size,keyframe_request_media_size,heartbeat_frames_sent, andheartbeat_no_display_frames_sent, which has Recover capture after sleep, lost displays and repeated access loss #205's no-display notice together with the count), checked by both the Rust and Swift suites. The existing vectors are byte-identical. A unit test checks that the old bodies are prefixes of the new ones.an_ipad_gets_the_smaller_media_datagrams_it_asks_for) runs the real transport: datagrams go from over 1,000 bytes to at most 576 after the request, starting with a keyframe; an older iPad's request changes nothing; the next session starts at full size.NoVideoFallbackTests):