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.
```
thread 'main' panicked at 'range start index 1 out of range for slice of length 0', examples/client/mp4.rs:171:44
stack backtrace:
0: rust_begin_unwind
at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:515:5
1: core::panicking::panic_fmt
at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/panicking.rs:92:14
2: core::slice::index::slice_start_index_len_fail
at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/core/src/slice/index.rs:34:5
3: client::mp4::TrakTracker::write_common_stbl_parts
4: client::mp4::Mp4Writer<W>::write_audio_trak
5: client::mp4::run::{{closure}}
6: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
7: tokio::park:🧵:CachedParkThread::block_on
8: tokio::runtime::thread_pool::ThreadPool::block_on
9: tokio::runtime::Runtime::block_on
10: client::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```
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.
* add a couple tests
* fix#4: put the whole video frame (including multiple NALs) into
a single Bytes. This is simpler to use and speeds up the
depacketize/h264_aac_writevideo benchmark. It's also a behavior
change; now I include non-VUI data such as SPS/PPS/SEI into the
data. I think this is a better default but it might be worth
making customizable.
* add variant which writes video to /dev/null
* (try?) to compile with debug symbols. (it seems to work but
cargo flamegraph still seems to complain?)
* faster parsing of inline data. I'd like to figure out why this is
slow with rtsp_types and fix it, but anyway in this benchmark I want
to just focus on the depacketization
These are huge, not present for every stream, and only allocated once at
describe time, so boxing makes sense. I probably should listen to that
clippy lint!