private-octopus / picoquic

Minimal implementation of the QUIC protocol
MIT License
540 stars 159 forks source link

Can we modify the sample progs such that the server sends the files without the client having to request? #1744

Open ArubaGit opened 1 week ago

ArubaGit commented 1 week ago

I want to develop a video streaming application using picoquic. I want that the as soon as the client initiates the connection to the server and the server accepts it, the server starts sending the files. could this be achieved by modifying the sample codes. I tried but no luck. Would be great if I could get any hint

hfstco commented 1 week ago

I don't know if you mean picoquicdemo or the sample_(server, client).c code. Also, that's a bit little information about how you want to stream the video. (h3, plain, which client, live streaming, ...)

There is already a document that describes sending and receiving in picoquic well. (https://github.com/private-octopus/picoquic/blob/deaf1624bd20bb01406c8ce746e3988ff378793b/doc/send_receive_data.md)

But I try to explain it in general.

If there is a new event (new connection, data received, ready to send, ...), picoquic notifies your application via callback. https://github.com/private-octopus/picoquic/blob/deaf1624bd20bb01406c8ce746e3988ff378793b/sample/sample_server.c#L204-L206

First, you have to have to recognise that a new connection is ready: https://github.com/private-octopus/picoquic/blob/deaf1624bd20bb01406c8ce746e3988ff378793b/sample/sample_server.c#L357-L357

After that you can start sending your stream data. There are two ways to achieve that in picoquic:

1) Use picoquic_callback_prepare_to_send to send data. If you want to use callbacks, you are responsible to pick the next junk of data when picoquic is ready to send. But you can react more easily to feedback/response from the client, in case there is kind of. picoquic is ready to send data of length bytes: https://github.com/private-octopus/picoquic/blob/deaf1624bd20bb01406c8ce746e3988ff378793b/sample/sample_server.c#L297 Request buffer of length/available bytes and copy data into it: https://github.com/private-octopus/picoquic/blob/deaf1624bd20bb01406c8ce746e3988ff378793b/sample/sample_server.c#L316

2) Otherwise, you can also send data via picoquic_add_to_stream or picoquic_add_to_stream_with_ctx. In this case, after a new connection is ready, you just add the entire data into the internal queue of picoquic and picoquic will handle to send the data itself: https://github.com/private-octopus/picoquic/blob/deaf1624bd20bb01406c8ce746e3988ff378793b/picoquic/picoquic.h#L1277-L1278 https://github.com/private-octopus/picoquic/blob/deaf1624bd20bb01406c8ce746e3988ff378793b/picoquic/picoquic.h#L1285-L1285

Nevertheless, you must of course react to things like resets or FIN flags from the client's side.

huitema commented 1 week ago

As @hfstco says, you can certainly write your own application that reacts to callbacks and sends data. That does not fit well in the "picoquic sample" logic, so that means a different application.

The closest thing in the spirit of the sample would be something like the client "asking for a wildcard", and then the server sending all the files in the server folder back to back. But that does not capture classic video issues like sending 30 frames per second, managing I and P frames, etc.

huitema commented 1 week ago

Thinking of this some more. I think we need a "video" sample, with a client and a server option. Mixing the video and files scenarios in the same client or server would make the samples hard to follow. In the video server, we want to demonstrate:

We need to write the samples with minimum system dependencies, so the sample is easily portable. The simplest way is to NOT actually send a video, but use some kind of simulation instead. Maybe have the sender "video" being read from a file, and have the client "display video" either written to a file or piped into a video reader.

@ArubaGit, would you be willing to define the "video" file format and provide an example? Plus maybe a simple program demonstrating reading frames and writing them to either a client file or a pipe for display?

ArubaGit commented 1 week ago

Hi I have a framework ready to capture frames and send process them for live streaming. I just need need to utilize quic library for sending the segmented video files. I am trying to modify the sample.c code for this. I was stuck therefore posted here. Got some hint for the server side from above reply. But the client side is not working. The video file format is .mp4. Would this code work fine if I am using two threads for this quic API to transfer video files, because I was reading it is not thread safe.

huitema commented 1 week ago

The idea is to use application logic in the system calls to only call the picoquic API from the picoquic thread, on either the client or the server. See the "background" example for examples on how to do that.