Quicr / old-quicrq

BSD 2-Clause "Simplified" License
4 stars 2 forks source link

Rewrite stream management for RUSH and WARP #113

Open huitema opened 1 year ago

huitema commented 1 year ago

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:

The Rush header shall contain enough data to differentiate from a Warp header, and to identify the object. This could be:

The Warp Header shall contain enough data to differentiate it from a Rush header and to identify the media stream and the GOB:

The Warp header will be followed by object encodings, each composed of object header and object data. The object header should include:

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.

suhasHere commented 1 year ago

I wonder if we need a rush/warp header code or should we make it more generic

Common Envelope/Header includes:

TrackId - audio/video codec bitstream identifier SegmentId/GroupId - It will be increment for eacb IDR change ObjectId - Monotonically increases but resets on each IDR

Individual objects will have Flags ObjectLen

For Datagram, It will need to further include fragment info.

With that, RUSH will have per streams/per frame [TrackID|SegmentID|flags|ObjectID||Len| object-data]

Warp will have, per stream (per GOP) [TrackID|SegmentID|Flags|ObjectId1|len1|object-data|Flags|ObjectID2|len|obejct-data....]

This can be further optimized .. @huitema what are your thoughts

huitema commented 1 year ago

We could do that. For GOP, the objectid1 will mostly be 0, but we never know, and that's only one byte anyhow.

huitema commented 1 year ago

I am looking at steps for implementing this. The first step may be a to change the "quicrq_request_message" as follow:

Old:
 quicrq_request_message {
      message_type(i),
      url_length(i),
      url(...),
      intent_mode(i),
      [ start_group_id(i),
        start_object_id(i),]
      datagram_stream_id(i)
 }

New:
quicrq_request_message {
      message_type(i), // Only one message type, "request"
      url_length(i),
      url(...),
      media_id(i), // Replace the old "datagram_stream_id", available in all formats
      intent_mode(i),
      transport_mode(i), // Allow for unspecified(0), single_stream(1), stream_per_gop(2), stream_per_object(3), datagram(4)
      [ start_group_id(i),
        start_object_id(i),]
 }

Do similar changes for the Post and Accept messages. We should do that before actually supporting steam_per_gop or stream_per_object. Just define the types, change the names of the variables in the code, and also replace "is_datagram" or "use_datagram" in the stream context by some "transport_mode" variable. After that, we can concentrate on the next steps.