scottlamb / retina

High-level RTSP multimedia streaming library, in Rust
https://crates.io/crates/retina
Apache License 2.0
244 stars 48 forks source link

Allow interleaved data on RTP as well #46

Closed valpackett closed 2 years ago

valpackett commented 2 years ago

This is necessary for at least some versions of the open source v4l2rtspserver. Namely whatever version is on the earlier dafang-hacks build that works better than the latest main one on my 64mb RAM camera :D

T20211228 22:43:57.782 tokio-runtime-worker tokio_util::codec::framed_impl] frame decoded from buffer
D20211228 22:43:57.782 tokio-runtime-worker retina::client] ignoring interleaved data message on Rtcp channel 1 while waiting for response to PLAY CSeq 4
T20211228 22:43:57.782 tokio-runtime-worker tokio_util::codec::framed_impl] attempting to decode a frame
T20211228 22:43:57.782 tokio-runtime-worker tokio_util::codec::framed_impl] frame decoded from buffer
D20211228 22:43:57.782 tokio-runtime-worker retina::client] ignoring interleaved data message on Rtp channel 0 while waiting for response to PLAY CSeq 4
T20211228 22:43:57.782 tokio-runtime-worker tokio_util::codec::framed_impl] attempting to decode a frame
T20211228 22:43:57.782 tokio-runtime-worker tokio_util::codec::framed_impl] frame decoded from buffer
D20211228 22:43:57.782 tokio-runtime-worker retina::client::parse] PLAY response described stream rtsp://192.168.xx.yy:8554/unicast/track2 in Uninit state
valpackett commented 2 years ago

I'm not sure what it is, can you tell me what logging to add to find that out?

scottlamb commented 2 years ago

I'm not sure what it is, can you tell me what logging to add to find that out?

It might actually be harder to manually feed the packet in question through the right layers of decoding to log this than to try implementing one of those alternatives.

But I would cheat: rather than writing any code to answer this question, I'd look at the conversation in Wireshark. If you've never used Wireshark before, it's worth learning for any kind of protocol work. It has a nice UI that usually can (among other things) pick out a RTSP interleaved data channel, identify it as RTP or RTCP, and even decode some of the higher-level protocol going over it. eg:

image

In the above screenshot, I've put in a "display filter" of "h264", which shows me all the Ethernet frames containing H.264. I've selected one (frame 29), and I've expanded the decoded parts to show me the NAL unit types: SPS, PPS, and SEI. The camera I'm talking to sends these at the beginning of every key frame. The SPS and PPS are critical for decoding the pictures, although at least on my cameras they're also sent as part of the DESCRIBE response (the part that says sprop-parameter-sets=...).

After those, this camera sends a fragmented RTP packet:

image

the "coded slice of an IDR picture" says this is the actual picture data of a key frame.

I'm also happy to look over a packet capture (in .pcap or .pcapng formats) if you email one to me. Just be warned though that by sharing a packet capture you're sharing your camera's IP, MAC, password (digest's protection is breakable), and whatever video/audio it was streaming at the time.

valpackett commented 2 years ago

Oh I know wireshark, I just thought it would be easier to println!() here. I haven't studied all this RTSP/RTP stuff so I didn't think this info would be as deep as the video codec itself.

Screen_2021-12-29-13:32:58

It's a "coded slice of a non-IDR picture" right before the 200 OK.

// I should try the other custom firmware build again but either way it all works with this patch (and e.g. mpv plays the stream fine).

scottlamb commented 2 years ago

It's a "coded slice of a non-IDR picture" right before the 200 OK.

Interesting. That's likely to get discarded downstream anyway (as in the mp4 example). Thanks for checking.

Can you lose the if as in my comment? I'll merge your patch then.

valpackett commented 2 years ago

Done