Rewrite stream management for RUSH and WARP #113
Description
In the current architecture, bidirectional QUIC streams are always used as "control streams". Arrival of data on a stream is signalled by the events picoquic_callback_stream_data
or picoquic_callback_stream_fin
, which make the implict assumption that these are client-initiated bidirectional streams. RUSH and WARP introduce two different kinds of streams. With RUSH, the media sender can send single frames in unidirectional streams. With WARP, the media sender can send an entire group of block on an unidirectional stream. The structure of the stream will be:
- For RUSH, a Rush header followed by the encoding of a single object content
- For WARP, a Warp header followed by the encoding of a series of objects, each of which will include an Object separator followed by an object content.
The Rush header shall contain enough data to differentiate from a Warp header, and to identify the object. This could be:
- Rush header code (TBD)
- media ID (same as the datagram stream ID used for datagrams?)
- GOB ID (same as GOB ID used in other contexts)
- Object ID (Same as Object ID for datagrams)
- Flags (same as datagrams)
- If object ID is zero (first object), number of objects in previous block (same as first fragment in case of datagrams)
- Maybe length of object data (debatable, since we can also deduce the information from the FIN of stream)
- Maybe some indication of how many objects before this one were "skipped", so relays can indicate losses?
The Warp Header shall contain enough data to differentiate it from a Rush header and to identify the media stream and the GOB:
- Warp header code (TBD)
- media ID (same as the datagram stream ID used for datagrams?)
- GOB ID (same as GOB ID used in other contexts)
- Maybe number of objects in previous GOB (debatable)
The Warp header will be followed by object encodings, each composed of object header and object data. The object header should include:
- Flags (same as datagrams)
- length of object data
There is no need to include the object ID, since it can be deduced from order of transmission in the Warp stream. If we want to skip an object, simplest solution is to just send two bytes: flags set to a conventional value (0xFF) and length set to 0. FIN happens after the last object in the stream. There is a potential error condition if the stream stops before the last object is fully sent (e.g., reset stream)
We will need to create a new type of stream context, maybe "unidirectional stream context", to handle the encoding or decoding state for the stream. The objects or fragment can be handled in the same reordering list used for datagram fragments.