As listed in #47.
This improves throughput in the client/h264 benchmark by about 20%,
I think because we copy fewer bytes around. CodecItem went from 256
bytes to 176.
Found by inspection. It'd be nice to fuzz the tokio module to more
reliably find problems like this, but it looks like I'd have to make
a bunch more stuff public for that. Maybe later...
It's allowed for a server to send only in-band parameters, although I
haven't encountered this yet. The VStarcam cameras sometimes send
invalid out-of-band parameters; treat that as if it sent nothing.
Fixes#42
* out-of-order packets should be ignored (except for logging).
* after ignored RTP or RTCP packet, don't incorrectly return Pending
without both underlying sockets actually returning Pending. This
could lead to not rechecking the sockets until prompted for another
reason, like an RTSP keepalive.
This was an attempt at #17 that didn't work out. Besides additionally
hitting the framing error, my Reolink test camera never timed out
the old session while the new one was in progress. This behavior is
different than the vanilla 2013.04.06 live555 server, so apparently
Reolink sprinkled in their own brokenness on top. In any case,
the other solutions described in that bug are more likely to work.
There's one narrow case I want to keep working: ignoring RTCP messages
immediately prior to the PLAY response. More recent Reolink cameras
do this. I just have this behavior on all the time now.
* support setting transport to UDP
* breaking change: use new PacketContext rather than RtspMessageContext
in places where an RTP/RTCP packet is expected, as it can now be over
UDP instead of via RTSP interleaved data
* send teardown, which is important with UDP sessions. (It also will
help somewhat with Reolink TCP.) Along the way, make Session Unpin
so that teardown can consume it without tripping over tokio::pin!().
* refactor to shrink the amount of data used by Session and how much
gets memmoved around on the stack, instead of further growing it.
Because of missing RTCP RR and reorder buffer support, this is only
appropriate for using on a LAN. That's enough for me right now.
This isn't RFC-compliant, but it seems to be quite common, and it
works with some cameras where the RFC-compliant way does not.
Fixes#9
Based on lucaszanella's PR #12, including his vstarcam test.
Fixes#17
I'm accumulating unit testing debt, but I think I'd rather get this
quickly out in the field to test against scenarios I haven't anticipated
than get my unit tests in order for scenarios I have anticiapted.
rtcp recently had an accidental semver break, so this fixes#8.
I also don't like that newer versions depend on several unnecessary
crates including tokio. retina also depends on tokio, but in the future
I want it to be IO library-agnostic.
I'm moving to v0.1.0 so I *can* release versions that claim semver
compatibility. There are still plenty of API changes to make but also
likely upcoming camera compatibility changes that won't break anything.
This is the method recommended by the ONVIF Streaming Specification
version 21.06 section 5.2.2.2.
I was using GET_PARAMETERS. This matched ffmpeg's behavior if the
OPTIONS shows that GET_PARAMETERS is supported, although I wasn't doing
the initial OPTIONS request.
Apparently the GW Security GW4089IP will simply ignore GET_PARAMETERS,
not even sending a 405 Method Not Allowed response. It supports and
responds to SET_PARAMETERS.
I've noticed some (buggy) cameras' out-of-band parameters don't quite
match the initial in-band parameters. Out-of-band parameters aren't
required anyway, and this is progress toward handling in-band only.
* Box the remaining Depacketizer variants. I already boxed the largest
ones, which are also the most common. Might as well box the others
and not have so much dead space in the common case...
* Don't keep around a full codec::Parameters on all codecs. This
shrinks several depacketizers. I also avoid some awkward
destructuring.
* Box VideoFrame::new_parameters, which is populated rarely.
```
sizes changes on 64-bit platforms:
type before after
client::Stream 512 312
codec::Depacketizer 224 16
codec::aac::Depacketizer 232 208
codec::g723::Depacketizer 200 104
codec::h264::Depacketizer 560 552
codec::onvif::Depacketizer 216 128
codec::simple_audio::Depacketizer 208 112
codec::CodecItem 240 160
codec::VideoFrame 232 152
codec::AudioFrame 104 104
codec::MessageFrame 104 104
client::rtp::SenderReport 72 72
```
* stop using deprecated failure crate and its deps
* more uniformly detailed error messages
* an enum of the type of error, currently internal-only. I'm not
confident enough I understand what cases a caller might want to
distinguish, so I added a comment inviting input instead of
exposing it now.
* while I'm at it, separate connection context and message contexts.
This shrinks some of the data memmoved around in PacketItem and
CodecItem.
prepare v0.0.4 immediately; v0.0.3 is effectively unusable.
I want to test this properly, but I haven't yet figured out how to set
up good mocks of tokio::Sleep and such. For now just fix the bug.
The new implementation has several benefits:
* it's more correct, in a way that probably doesn't matter now but
will if we ever send ONVIF backchannel audio. See the removed
comment about deadlock possibility. Similarly, I realized that if
packets became readable halfway through flushing a keepalive, the
keepalive future would be improperly dropped as described at
the beginning of this blog post:
https://carllerche.com/2021/06/17/six-ways-to-make-async-rust-easier/
* we'll be able to make other method calls on the Session while using
the stream, eg sending audio with ONVIF backchannel
* it's 8% faster according to the client benchmark.
* it doesn't pull in the async-stream dependency anymore.
* we can name the type of the stream, avoiding a Box in some cases.