Article 03 · Video Systems
Inside an IP Camera: Understanding RTSP, Codecs, FPS, I-Frames and Video Streaming
How an IP camera turns photons into an RTSP stream, what H.264/H.265, GOP and bitrate settings actually change, and how those choices propagate to VMS capacity, latency and ANPR or object-detection accuracy.
Contents
Why camera settings are an architecture problem
Everything downstream of an IP camera, from recorder disks to GPU decoders to the accuracy of a licence plate reader, is a consequence of a handful of settings on that device: resolution, frame rate, codec, bitrate mode, keyframe interval and which stream profile you pull.
Those settings are usually chosen by whoever mounts the camera, using the vendor web UI, with a view to how the live picture looks. The people who pay for the choice are different: the platform team sizing storage and network, and the analytics team wondering why plate recognition fails at night. I follow the stream from sensor to inference so that you can reason about those trade-offs, not guess them.
I have worked with this class of system, including backend architecture for a video management system (VMS) targeting 100k+ IP cameras. I do not report measurements from that work. Every number here is either a standard protocol fact, qualified by version or configuration where it varies, or clearly labelled illustrative arithmetic. I benchmarked nothing for this piece.
Five interactive labs are embedded at the points where a slider is more convincing than a paragraph. The text stands on its own without them.
The camera pipeline from sensor to network
A camera is a fixed pipeline. Each stage has a configuration surface and a failure mode.
Lens + sensor
CMOS, Bayer mosaic
ISP
demosaic, denoise, WDR, WB
Scaler + OSD
main / sub resolutions
Encoder
H.264 / H.265 / MJPEG
Packetizer
RTP, or file segments
RTSP / ONVIF server
port 554 + HTTP
Sensor. A CMOS sensor records one intensity per photosite through a colour filter array (commonly a Bayer pattern). Exposure time (shutter) and analogue/digital gain determine how bright the frame is. These two are the most consequential settings for analytics, because a long exposure blurs moving objects and a high gain amplifies noise. A camera in a dark car park will trade one for the other, and the encoder then inherits the result.
ISP. The image signal processor demosaics the raw mosaic into RGB, then applies white balance, noise reduction, wide dynamic range (WDR/HDR) merging, gamma and sharpening. Aggressive temporal noise reduction makes footage look clean and compresses well, but it can smear small moving details. For ANPR, vendor tuning for plate capture usually means a short fixed shutter, infrared illumination and constrained gain, at the cost of a darker, noisier general-purpose picture.
Scaler and overlay. The ISP output is scaled to one or more output resolutions. This is where the main stream and substream come from: the same sensor image, scaled and encoded independently. Date/time overlays and privacy masks are typically burned in before encoding.
Encoder. A dedicated hardware block in the SoC compresses frames. The encoder is where resolution, frame rate, bitrate mode and GOP structure take effect. Most cameras expose at least H.264; many also offer H.265 and MJPEG. Cameras generally have a fixed encoder budget, so enabling a third stream or a higher resolution can silently force another stream's limits down.
Packetizer and server. Encoded access units are packetized into RTP packets (or written into segments for onboard recording) and served by the camera's embedded RTSP server. A separate HTTP/SOAP stack implements ONVIF and the vendor's web UI. These are small CPUs: they tolerate a limited number of concurrent sessions, which matters when several consumers want the same camera, as discussed in the VMS section.
Resolution, frame rate and the pixel budget
Resolution and frame rate set the raw pixel rate the encoder must handle. A 1920x1080 stream at 30 frames per second is 62,208,000 pixels per second; a 3840x2160 stream at 30 is 248,832,000, exactly four times as many. Uncompressed 8-bit 4:2:0 video costs 1.5 bytes per pixel, so the 1080p30 example is roughly 93 MB/s (about 746 Mbit/s) before any compression. Compression ratios of two orders of magnitude are what make IP video practical.
A more useful derived number is bits per pixel: bitrate divided by pixel rate. Illustrative arithmetic: 4 Mbit/s at 1080p30 is 4,000,000 / 62,208,000, about 0.064 bits per pixel. The same 4 Mbit/s spent on a 4K stream at 30 fps gives about 0.016. Same bitrate, a quarter of the bit budget per pixel, so the encoder must quantize harder and the picture degrades in complex scenes. Bits per pixel is not a quality metric, since scene content dominates, but it is a good early warning that a configuration is starved.
Two consequences follow:
- Raising resolution without raising bitrate usually does not add detail. It adds pixels to be compressed more heavily. For analytics, more compression artefacts can be worse than fewer pixels.
- Frame rate is not free but is cheaper than it looks. Between consecutive frames at 25 to 30 fps most of the scene is unchanged, so predicted frames compress very well. Dropping from 30 to 15 fps typically cuts bitrate by less than half. How much depends on motion and on the encoder; do not assume proportionality.
Frame rate has its own analytics implications. A vehicle at 60 km/h covers about 16.7 m per second, so at 5 fps it moves about 3.3 m between sampled frames. Trackers that associate detections by overlap need to cope with that displacement; ANPR on a moving vehicle wants the shortest feasible exposure far more than a higher frame rate.
H.264 and H.265 fundamentals
Both codecs are block-based hybrid codecs. A frame is split into blocks (macroblocks of 16x16 in H.264, coding tree units up to 64x64 in H.265). Each block is predicted either from already-decoded pixels in the same frame (intra prediction) or from a region in a reference frame (inter prediction, using a motion vector). The residual between prediction and reality is transformed, quantized and entropy coded. Quantization is the lossy step and is controlled by the quantization parameter (QP): a higher QP discards more detail and produces smaller frames.
This explains most of what matters operationally:
- Static scenes compress well because inter prediction finds near-perfect matches.
- Noise does not compress, because it is unpredictable; a night-time image with high gain consumes far more bitrate than the same scene by day.
- Large uniform motion (swaying trees, rain, headlight sweeps) defeats prediction and inflates bitrate.
H.265 (HEVC) versus H.264 (AVC). H.265 uses larger, more flexible partitioning and better prediction tools. Savings at equivalent visual quality are commonly quoted in the range of 30 to 50 percent, but this is content-, encoder- and quality-target-dependent, and embedded camera encoders typically realise less than reference software encoders. Treat any single number as a planning assumption to be verified on your cameras. H.265 costs more decode effort, has less universal browser support for direct playback, and some "H.265+" or "smart codec" modes are vendor extensions that change GOP behavior dynamically; those modes can break assumptions about keyframe interval, as covered below.
Profiles and levels. A profile defines the toolset a decoder must support; a level bounds resolution, frame rate and bitrate. In H.264, Baseline excludes B-frames and CABAC; Main adds them; High adds more tools such as 8x8 transform and is the common default on modern cameras. Levels such as 4.0 and 4.1 comfortably cover 1080p at 30 fps; 3840x2160 at 30 fps generally needs level 5.1 or higher. These appear in the stream as profile-level-id in SDP, and they matter in practice because a hardware decoder with a capped profile or level will reject or misdecode a stream that exceeds it. H.265 mostly appears as Main profile (8-bit), with levels that scale similarly. Exact support depends on the decoder silicon and driver.
NAL units. Both codecs wrap data in Network Abstraction Layer units. For H.264 the types that matter operationally are 1 (non-IDR slice), 5 (IDR slice, a decodable random-access point), 7 (SPS) and 8 (PPS). For H.265 the equivalents are 19 and 20 (IDR variants), 21 (CRA), 32 (VPS), 33 (SPS) and 34 (PPS). The parameter sets (SPS/PPS, plus VPS in H.265) describe resolution, profile and entropy mode. Without them, nothing decodes. This is why a client that joins mid-stream must obtain them, either out of band in SDP or in band before an IDR.
GOP structure, frame types and random access
Encoders group frames into a group of pictures (GOP) that starts with a frame decodable on its own.
- I-frame (intra): coded without reference to other pictures. Largest, but self-contained. An IDR frame is an I-frame that also resets the reference buffer, so no later frame references anything before it; this is the true random-access point in H.264/H.265.
- P-frame (predicted): references earlier frames. Much smaller than an I-frame; the ratio depends on content and quantization.
- B-frame (bi-directional): references earlier and later frames. Smallest, but the encoder must hold back frames to reorder them, adding latency, and decode order differs from display order, so presentation and decoding timestamps diverge. Many cameras disable B-frames for live-view latency or limit themselves to Baseline-like tool use; some enable them for efficiency. It is a per-model setting, not a codec guarantee.
The keyframe interval (also called I-frame interval, GOP length or key frame distance, depending on vendor) is how often the encoder inserts an IDR. Vendors express it in frames, seconds or as a multiple of frame rate, so check units: "30" means one second at 30 fps but two seconds at 15 fps if the setting is in frames.
The interval creates three trade-offs.
- Compression efficiency. I-frames are the most expensive frames. A short interval raises average bitrate for a given quality.
- Random access and join latency. A decoder can only start cleanly at an IDR. When a consumer connects, it typically has to wait for the next one, so time to first picture can be as long as the interval. Some servers cache and resend the last IDR; many camera firmwares do not. Seeking in recordings has the same granularity.
- Error recovery. If a frame is lost or corrupted, every frame that references it, directly or transitively, is damaged until the next IDR. A long GOP means errors persist longer.
Bitrate is also not constant within a GOP: each I-frame is a burst several times larger than the following P-frames, and on constrained uplinks it can cause packet queues and jitter at every interval boundary.
The GOP visualizer below renders a synthetic frame sequence with adjustable length. It shows an idealized pattern; real encoders may place extra IDRs on scene cuts, use adaptive GOP, or use different reference structures.
Try changing the GOP length, toggling B-frames if offered, and marking a lost frame to watch which frames become undecodable and when the stream recovers.
GOP visualizer
Goal. Understand why one lost packet or frame damages every frame that depends on it until the next I-frame, and why seeking costs more deeper into a GOP.
Click (or press Enter/Space on) a frame to drop it. Arrows point from a frame to the frame it needs.
Key: filled = decodable; hatched with ✕ = undecodable; "lost" = dropped; dashed arrows = B-frame references; triangle = seek target; box height = illustrative relative size.
- Frames unusable
- 0 / 12
- click a frame
- Seek cost to frame 6
- 3 frames decoded
- Worst / average seek
- 5 / 3.7 frames
- I-frame share of GOP bytes
- 32 % (illustrative)
Reading the result
GOP of 12 frames with 2 B-frame(s) between anchors. No frames dropped: click a frame to simulate its loss. Displaying frame 6 requires decoding 3 frame(s); worst case in this GOP is 5.
Assumptions and limits
- Simplified closed-GOP model: I at the start, P every (B+1) frames, B frames reference the previous and next anchor and are not used as references. Trailing frames with no next anchor become P.
- Real encoders vary: open vs closed GOPs, adaptive GOP length, scene-cut I-frames, B-pyramids/reference B-frames, multiple reference frames, and slice-level concealment.
- Frame heights show relative size I > P > B using illustrative weights 10 : 3 : 1; real ratios depend on content and encoder.
- A dropped frame stands for any lost packet that makes the frame undecodable. Concealment is ignored, and the next GOP is not shown (it would recover at its I-frame).
- Seek cost = frames that must be decoded to display the chosen frame, starting from this GOP's I-frame. Display order is shown, not decode order.
What you should see: damage propagates forward along reference arrows until the next I-frame, B-frames add dependencies in both directions, and longer GOPs reduce the number of I-frames per second while extending the worst-case recovery and join time. The pattern drawn is illustrative; it is not a statement about any specific camera.
For analytics, GOP matters in a way that is easy to overlook. If your pipeline decodes only keyframes to save compute, you receive exactly one frame per interval, so the interval is your sampling rate. A one-second interval at 25 fps yields 1 fps of inference input for 1/25th of the decode cost of a full decode, though the exact saving depends on frame sizes and decoder. Conversely, a camera set to a ten-second interval to save bandwidth makes this strategy unusable and slows recovery from any loss.
CBR, VBR and what bitrate really controls
Bitrate is the average number of bits per second the encoder emits. It is the one number that determines network load and storage consumption. Resolution and frame rate influence it only indirectly, which is why capacity calculations should start from measured bitrate, not from the resolution printed on the datasheet.
- CBR (constant bitrate) keeps the output near a target by adjusting QP continuously, constrained by a decoder buffer model (the VBV/HRD buffer). Predictable for network and storage planning. In complex scenes it sacrifices quality instead of bitrate, so fast motion becomes blocky exactly when something interesting happens. In quiet scenes it may waste bits filling the budget, depending on the encoder.
- VBR (variable bitrate) targets a quality level and lets bitrate float, typically up to a configured maximum. It is more efficient, since quiet scenes cost little, but peaks and the day/night difference need to be planned for. VBR with a maximum cap is very common as a default in surveillance firmware, and the cap is the number that protects the network.
- Vendor-specific smart modes modify GOP length and quantization based on motion. They can save significant storage, but they change the behavior your pipeline sees (variable keyframe interval, variable frame rate), so treat them as separate from "H.264" or "H.265" in capacity and troubleshooting.
A practical rule: pick VBR with a sensible cap for general surveillance, CBR when a link is genuinely constrained (cellular, shared wireless), and confirm what the camera does at night with the gain turned up. Whichever mode you use, measure the real average and peak per camera after a representative day-night cycle; spec-sheet bitrates are targets, not observations.
Use the playground below to explore how the settings interact. Move resolution, frame rate, codec, bitrate, GOP length and CBR/VBR, and watch the estimated bandwidth, storage per day, compression pressure, join latency and analytics suitability respond. The model is a deliberately simple approximation with codec-dependent assumptions, not a measurement.
Camera configuration playground
Goal. See how resolution, FPS, codec, bitrate and keyframe interval trade off bandwidth, storage, quality and what an analytics model can read.
- Bandwidth (this stream)
- 4.00 Mbit/s
- constant
- Storage per hour
- 1.80 GB (decimal)
- Storage per day
- 43.2 GB (decimal)
- Bits per pixel
- 0.077
- H.264-equiv. 0.077
- Keyframe interval
- 2.00 s
- 50 frames
- Worst-case join latency
- ~2.0 s
- about one GOP; excludes network/decode
Quality indicator (bits per pixel): adequate
- starved
- low
- ▶ adequate
- good
- generous
Codec rule of thumb (approximate, content dependent): H.264 needs about 0% less bitrate than H.264 for similar quality.
Analytics implications and warnings
- [NOTE] CBR keeps bandwidth predictable but lets quality drop on busy scenes; VBR varies bandwidth with scene activity.
ANPR geometry (illustrative): 0.56 m of travel per frame at 50 km/h; ~9.0 frames in a 5 m zone.
Reading the result
1080p at 25 fps, H.264 CBR 4000 kbit/s: about 4.00 Mbit/s and 43.2 GB/day. Quality indicator: adequate (0.077 bits/pixel, H.264-equivalent). Keyframe every 2.00 s, so a new viewer may wait up to that long for a picture. 0 warning(s) for analytics.
Assumptions and limits
- Estimate only; no camera is connected. Defaults are illustrative, not vendor recommendations.
- Bitrate is the video elementary stream target in kbit/s (decimal). Audio, RTP/network overhead and container overhead are ignored. VBR is treated as an average.
- Storage uses decimal GB (1 GB = 10^9 bytes); 1 hour = 3600 s of continuous recording.
- Bits per pixel = bitrate / (width x height x fps). Bands are rough illustrative thresholds on an H.264-equivalent figure.
- Codec factor is a rough rule of thumb: H.265 needs roughly 30-50% less bitrate than H.264 for similar quality (modelled as 35% less); MJPEG roughly 4x more. Approximate and content dependent.
- Worst-case join latency is about one keyframe interval (wait for the next I-frame); decoder and network delay are extra.
- Sub stream is modelled as 640x360 (illustrative). The ANPR note assumes a 50 km/h vehicle and a 5 m plate-legible zone.
What you should see: raising resolution at a fixed bitrate pushes bits per pixel down and flags quality risk; switching H.264 to H.265 relaxes it by an assumed efficiency factor; lengthening the GOP lowers average bitrate and increases join and recovery time; CBR changes predictability rather than the average. Real devices will differ, so use the lab for direction of effect and use measurements for numbers.
Streaming with RTSP, RTP and RTCP
The camera is a source; a client (VMS, analytics worker, player) needs the stream. The dominant family of protocols for this is RTSP for session control, RTP for media and RTCP for feedback.
RTSP (Real Time Streaming Protocol; RFC 2326 for version 1.0, RFC 7826 for 2.0, with 1.0 overwhelmingly what cameras implement) is a text, HTTP-like control protocol, by default on TCP port 554. It does not carry video. It negotiates and controls a media session using methods: OPTIONS (capabilities), DESCRIBE (retrieve SDP), SETUP (negotiate transport per track), PLAY, PAUSE, TEARDOWN, plus GET_PARAMETER/SET_PARAMETER, which are commonly used as keepalives.
RTP (RFC 3550) carries the media. Each packet has a payload type, a sequence number (to detect loss and reorder), a timestamp (the media clock, 90 kHz for video) and a synchronization source identifier (SSRC). Codec-specific packetization rules define how NAL units map to packets: RFC 6184 for H.264, RFC 7798 for H.265. A NAL larger than the path MTU, such as a big I-frame, is fragmented across many packets (FU-A in H.264), and the loss of any fragment loses the whole NAL unit.
RTCP runs alongside RTP, conventionally on the next port number. Receivers send Receiver Reports (fraction lost, cumulative loss, interarrival jitter); senders send Sender Reports that map the RTP timestamp to wall-clock (NTP) time. That mapping is what lets you align streams from several cameras or relate a frame to real time, provided the camera clock is sound. RTCP is also, in many servers, evidence that a client is alive.
- Client to Camera: OPTIONS (CSeq 1)
- Camera to Client: 200 OK (Public: DESCRIBE, SETUP, PLAY, TEARDOWN)
- Client to Camera: DESCRIBE (Accept: application/sdp)
- Camera to Client: 401 Unauthorized (WWW-Authenticate: Digest)
- Client to Camera: DESCRIBE + Authorization
- Camera to Client: 200 OK + SDP (tracks, codec, sprop params)
- Client to Camera: SETUP track1 (Transport: RTP/AVP/TCP;interleaved=0-1)
- Camera to Client: 200 OK (Session: id;timeout=60)
- Client to Camera: PLAY
- Camera to Client: RTP + RTCP (interleaved on the same TCP connection)
SDP: what DESCRIBE returns
The DESCRIBE response contains a Session Description Protocol body that tells the client what tracks exist and how to decode them. This is an illustrative example, not captured from a device; the base64 parameter sets are placeholders.
v=0
o=- 1731283200 1 IN IP4 192.0.2.10
s=Main stream
t=0 0
a=control:*
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=420029;sprop-parameter-sets=Z0IAKeKQFAe2AtwEBAaQeJEV,aM48gA==
a=framerate:25
a=control:trackID=1The points worth reading in it:
m=video ... RTP/AVP 96anda=rtpmap:96 H264/90000declare a dynamic payload type (96 to 127 range) carrying H.264 on a 90 kHz clock.packetization-mode=1permits fragmentation units and aggregation, which is what practically all cameras use.profile-level-idencodes profile, constraint flags and level in hex. Here,42is Baseline profile and29is level 4.1. A decoder can reject the stream here before touching any media.sprop-parameter-setscarries the base64-encoded SPS and PPS. For H.265 the analogue issprop-vps,sprop-spsandsprop-pps. Cameras are not always faithful about these values, so robust clients also accept parameter sets in band.a=controlgives the per-track URL forSETUP.
A real device may also advertise an audio track, an ONVIF metadata track (for analytics or events) and vendor attributes.
UDP versus interleaved TCP
At SETUP, the client chooses how media travels.
- RTP over UDP. The client and camera agree on a UDP port pair (RTP on an even port, RTCP on the next). Delivery is unreliable: packets can be lost, duplicated or reordered. The upside is low latency, since a late packet is simply discarded, and no head-of-line blocking. The downside is that firewalls and NAT often drop the return path, and loss causes visible corruption until the next IDR.
- Interleaved RTP over TCP. Media is multiplexed on the RTSP TCP connection. Each RTP or RTCP packet is framed as a
$byte, a one-byte channel number and a two-byte length (the Transport headerinterleaved=0-1names the channels). It traverses firewalls and NAT because there is one outbound connection, and loss is repaired by TCP, so no corruption. The downside is that retransmission produces stalls: a lost segment blocks everything behind it, delay accumulates and then the stream appears to "catch up". On a persistently lossy link, TCP converts loss into latency. - UDP multicast is also defined and is occasionally used inside controlled networks to feed many consumers, but is rarely what a typical VMS deploys.
For analytics and recording, where an intact picture matters more than a few hundred milliseconds, interleaved TCP is usually the safer default over anything other than a clean, controlled LAN. For live view with minimal delay on a good network, UDP is attractive. A third approach is to avoid the choice by terminating the camera connection once at a gateway on the same LAN, then distributing from there. Whichever you choose, record the transport per camera, because it is the first thing to flip when diagnosing artefacts.
Authentication and keepalive. Cameras normally require Digest (sometimes Basic) authentication for RTSP. The session identifier from SETUP carries a timeout, commonly 60 seconds by default, and clients must refresh it (with GET_PARAMETER or OPTIONS, or in some servers by sending RTCP) or the camera tears the session down. Some firmware bugs make cameras ignore the timeout or drop sessions early; a reconnect policy with backoff is mandatory.
ONVIF: discovery, profiles and getting the URL
RTSP URLs are vendor-specific. Paths such as /stream1, /Streaming/Channels/101 or /cam/realmonitor?channel=1 differ across manufacturers and firmware, and hard-coding them per brand does not scale. ONVIF is the interoperability layer that standardizes how to find and query devices. It is an SOAP/XML-over-HTTP API family that sits next to, not in place of, RTSP.
Discovery. ONVIF devices respond to WS-Discovery probes sent to the multicast group 239.255.255.250 on UDP port 3702. This works only inside a layer-2/multicast-capable segment. Across routed networks you typically discover with a unicast probe, a scan or a registry. Discovery returns the device service address, not credentials or streams.
Services. After discovery, the client calls the Device service (capabilities, system date and time, network information) and the Media service. GetProfiles lists the media profiles (named combinations of video source, encoder settings and optionally audio, PTZ and analytics configuration), and GetStreamUri returns the RTSP URL for a chosen profile and transport. Newer devices also implement Media2, which adds H.265 support and a different method set. A scan for URLs is replaced by two calls.
Profiles (conformance, not media profiles). ONVIF Profile names indicate which features a device claims to support:
| ONVIF Profile | Focus |
|---|---|
| S | Basic live streaming; video, audio, PTZ and relay outputs (legacy baseline) |
| T | Advanced streaming: H.265, Media2, improved events and imaging |
| G | Edge storage and recording search/retrieval |
| M | Metadata and analytics events and configuration |
| C / A | Access control (door, credentials) |
Claiming a profile does not guarantee identical behavior; conformance testing covers a defined subset, and optional features are optional. A device that lists Profile S may still ignore requested bitrates, and a device that lists Profile T may expose H.265 only for some stream profiles.
Practical caveats.
- ONVIF clock skew: WS-Security
UsernameTokendigest authentication includes a timestamp and nonce, so a camera whose clock is wrong causes authentication failures that look like a bad password. ReadingGetSystemDateAndTimefirst and adjusting is a common client workaround. - Credentials created for ONVIF may be separate from web UI or RTSP users on some firmware.
- ONVIF
SetVideoEncoderConfigurationcan change camera settings remotely, which is useful for fleet management and dangerous if unreviewed; treat it as a write path. - Do not assume every ONVIF field is implemented. Read capabilities, test, and keep a per-model quirks table.
The onvif-camera workflow I use for probing devices (discover, list profiles, resolve URLs, check Profile G recording) relies on exactly these calls.
Main stream, substream and which one to feed to inference
Most cameras expose at least two simultaneous encodes. The main stream is the full-resolution, higher-bitrate one used for recording and detail. The substream is a lower-resolution, lower-bitrate encode (for instance a few hundred kilobits per second at a small fraction of the main resolution) intended for live-view grids, mobile clients and, increasingly, analytics. Each corresponds to a different ONVIF media profile and a different RTSP URL, and the substream codec need not match the main stream's. Some cameras allow a third stream or restrict the substream to H.264 while the main uses H.265.
The question that matters for architecture is which stream a given consumer should read.
| Consumer | Typical choice | Rationale |
|---|---|---|
| Recording | Main | Evidential detail; storage cost is the bitrate you accept |
| Multi-camera wall / grid | Sub | Decode cost scales with pixels; a wall of full-resolution streams is wasteful |
| Single full-screen live view | Main | Detail is wanted, only one decode |
| General object detection | Sub, sized to model input | Detection models resize to a fixed input (for example a few hundred pixels wide); decoding 4K to scale it down wastes compute |
| ANPR / fine-grained recognition | Main, or main-derived crop or snapshot | The plate may span only tens of pixels in the substream |
The inference pattern that balances cost and accuracy is a two-tier pipeline. A substream feeds a continuous detector (cheap, runs on every camera). When it finds a vehicle or event, it triggers a higher-quality read: an ONVIF snapshot, or a short decode of the main stream around the trigger, for plate recognition or attribute classification. Pixel budget is spent only on frames that have something in them.
The failure mode of this design is mismatch: the substream may have a different field of view crop, a lower frame rate (so the plate-frame is a keyframe-spaced sample), different compression artefacts or a different timestamp base. Coordinates detected on the substream must be mapped to the main-stream resolution, and the time-correlation between the two streams must use RTCP/NTP timestamps and not arrival time.
How encoding choices affect ANPR and object detection
Analytics fails for reasons that are rarely the model's fault. The following effects are the usual ones; thresholds are rules of thumb that vary with the model and should be validated on your own footage.
Motion blur and shutter. ANPR depends on a short exposure. A plate on a vehicle at speed blurs if the shutter is long, and no codec setting recovers it. Frame rate and bitrate cannot fix a blurred capture, which is the single most common misattribution.
Pixel density on target. Recognition needs enough pixels across the plate characters. Vendor and integrator guidance is commonly on the order of a hundred or more pixels across the plate width, but the right value depends on the OCR model, plate format and angle. Lens focal length, mounting distance and resolution determine this; the substream may fall below it by design.
Compression artefacts. At low bits per pixel, quantization destroys exactly the fine, high-contrast structures that plate and small-object detectors depend on: thin strokes, character edges, small textures. Blocking and mosquito noise at low bitrate raise both false negatives and false positives. CBR at a bitrate that is too low is the common cause, because motion-heavy frames get the worst quantization when the vehicle is in view.
I-frame cadence in detection logic. Quality fluctuates inside a GOP: right after an IDR the picture is typically sharpest, and quality may degrade across subsequent P-frames in some rate-control regimes. A detector that sees variable per-frame quality will have confidence scores correlated with GOP position. Logging confidence against frame type is a cheap way to see whether this affects your data.
Frame rate and sampling. For tracking, enough frames must see the object before it leaves the field of view, and the association step must tolerate the displacement between samples. For ANPR, a few good frames per vehicle matter more than many poor ones, and the best frame is often not the first one the detector sees.
Loss artefacts. Over UDP, packet loss produces smeared, grey or green frames until the next IDR. A detector will happily fire on them. Gate analytics on stream health (RTCP loss, decoder error counters, discontinuities in RTP sequence numbers) instead of trusting the pixels.
Smart codecs. Variable frame rate and dynamic GOP, when the scene is quiet, may starve a pipeline that expects steady timing. Test with the mode enabled if it is on in production.
Night. Infrared and high gain add noise, bitrate climbs, CBR streams lose quality, and VBR streams hit their cap. Evaluate analytics at the worst hour, not the demo hour.
These effects interact, so tune from the analytics requirement backwards: determine the pixel density and shutter needed for the target, derive the resolution and encode quality that preserve it, then compute bandwidth and storage from the resulting bitrate. Starting from "4K, because it is available" tends to end in a disappointing system.
Decode, frame extraction and the inference pipeline
Consuming a stream for analytics is a pipeline with clearly separable stages, each of which can be the bottleneck or the source of latency.
RTSP session
SETUP / PLAY
RTP receive + jitter buffer
reorder, loss detect
Depayload + demux
NAL units, access units
Decode
CPU or hardware (NVDEC etc.)
Frame selection
drop, sample, resize
Inference
batch + model
Results
events to bus
- Receive and jitter buffer. RTP packets arrive with variable delay. The receiver holds them briefly to reorder and smooth jitter. A larger buffer tolerates more network variability and adds a corresponding amount of latency.
- Depayload and demux. RTP payloads are reassembled into NAL units and grouped into access units (one per picture) using the RTP timestamp and marker bit. Parameter sets are collected here.
- Decode. Inter-frame dependencies mean you cannot skip arbitrary frames. To get frame N you must decode its references. Decoding all frames and discarding most is often cheaper than it sounds relative to inference, but it is rarely free at scale. Options include decoding everything and sampling afterwards, decoding only keyframes (cheapest, sampling rate equals keyframe rate) or using the substream. Hardware decoders (for example NVIDIA NVDEC) offload this, at the price of a limit on concurrent streams per device that depends on the hardware generation, resolution and codec; measure it on your target hardware instead of trusting nominal figures.
- Frame selection. Decide which decoded frames reach the model. Always take the freshest frame, not the next frame in a queue, or a slow model creates ever-growing delay.
- Inference. Batching across cameras increases GPU efficiency but adds queueing delay; there is a throughput/latency trade-off to tune.
The classic bug is the stale-frame queue. If a consumer reads frames slower than the camera produces them, buffers fill, latency climbs steadily and the system analyses events that happened tens of seconds earlier. Reading in a dedicated thread and keeping only the latest frame fixes it.
import threading
import cv2
class LatestFrame:
"""Continuously drains the stream; consumers always get the newest frame."""
def __init__(self, url: str):
# Transport options are passed to FFmpeg via an environment variable;
# exact option names vary by FFmpeg version.
self.cap = cv2.VideoCapture(url, cv2.CAP_FFMPEG)
self.frame = None
self.lock = threading.Lock()
self.alive = True
threading.Thread(target=self._run, daemon=True).start()
def _run(self):
while self.alive:
ok, frame = self.cap.read()
if not ok:
break # caller reconnects with backoff
with self.lock:
self.frame = frame
def get(self):
with self.lock:
return self.frameA command-line equivalent for a quick check with FFmpeg selects interleaved TCP and minimizes buffering. Flag names have changed across versions (the socket timeout option in particular), so confirm against your build.
ffprobe -rtsp_transport tcp -show_streams -select_streams v:0 \
"rtsp://USER:PASS@192.0.2.10:554/stream1"
ffmpeg -rtsp_transport tcp -fflags nobuffer -flags low_delay \
-i "rtsp://USER:PASS@192.0.2.10:554/stream1" -an -f null -The credentials above are placeholders. In a real system they belong in a secrets store, never in URLs that get logged; many clients print the full URL on error.
Walk through the pipeline interactively below. Select each stage to see what it does, where it buffers, what its latency contribution depends on and how it fails.
Video pipeline explorer
Goal. Follow a frame from sensor to AI result, see where delay accumulates, and know what breaks at each stage.
Per-stage delay (illustrative, ms)
1. Sensor / ISP / encoder
What it does. Sensor exposes frames, the image signal processor handles exposure, white balance and noise reduction, then the encoder compresses to H.264/H.265 with the configured GOP and bitrate.
Where latency builds up. Exposure time and encoder look-ahead / rate-control buffer (a long GOP with B-frames adds reorder delay).
Failure modes
- Over-exposed or blurred frames from a slow shutter
- Bitrate too low, so blocking
- Encoder overloaded and frames dropped at the source
Latency budget (illustrative)
| Stage | ms | Cumulative ms |
|---|---|---|
| 1. Sensor / ISP / encoder | 60 | 60 |
| 2. RTSP session | 40 | 100 |
| 3. RTP packets | 30 | 130 |
| 4. Jitter buffer (largest) | 100 | 230 |
| 5. Demux | 10 | 240 |
| 6. Decode | 40 | 280 |
| 7. Frame extraction | 20 | 300 |
| 8. AI inference | 50 | 350 |
- Total (illustrative)
- 350 ms
- Largest stage
- Jitter buffer
- 29% of total
Reading the result
Illustrative end-to-end latency is 350 ms. Largest contributor: Jitter buffer (100 ms, 29%). Selected stage: Sensor / ISP / encoder. Reducing latency usually means shrinking the jitter buffer first, at the cost of more glitches on a lossy network.
Assumptions and limits
- Conceptual pipeline, not a live stream; no camera or network is involved.
- Millisecond values are editable illustrative placeholders, not measurements. Real values depend on camera, network, buffer settings, hardware and model.
- Stages are shown in a typical order; real systems may merge or skip stages (e.g. hardware decode straight into inference).
- RTSP status codes listed (401, 404, 454, 461) are standard RTSP response codes; cameras may reply differently or close the connection.
What you should see: latency is the sum of contributions from capture, encode (including any B-frame reordering), network, jitter buffer, decode and queue, with the biggest controllable terms usually being the jitter buffer, GOP-driven startup delay and stale queues. Stages are inspectable so you can see which setting influences which one; the figures in the lab are illustrative, not measured.
Latency, buffering and packet loss
End-to-end latency is the delay from a scene event to the moment an action is taken. It has many contributors and most are under someone's control.
| Source | Typical driver | Lever |
|---|---|---|
| Capture and exposure | Shutter time, frame period | Frame rate, exposure |
| Encode | Lookahead, B-frame reordering, rate-control buffer | Disable B-frames, lower VBV buffer if exposed |
| Network | Path delay, TCP retransmission | Transport choice, QoS, link quality |
| Jitter buffer | Configured depth | Client buffer size (for example GStreamer rtspsrc latency) |
| Decode | Decoder pipeline depth, queue | Hardware decode, low-delay flags |
| Inference queue | Batching, slow model | Drop stale frames, bound queues |
| Join (cold start) | Wait for the next IDR | Shorter keyframe interval, gateway keeping stream warm |
Notice that none of these is a property of "RTSP". RTSP is a control protocol; latency is made by buffers.
Packet loss behaves differently by transport. Over UDP, a lost packet drops part of a NAL unit. The decoder either discards the frame or conceals it, and every dependent frame inherits the damage until the next IDR. Over interleaved TCP, loss triggers retransmission and head-of-line blocking: the picture stays correct but arrives late, and delay builds until the sender catches up. TCP lets you trade corruption for latency; it does not remove loss.
Burst loss is worse than random loss. A large I-frame is dozens of packets sent back to back; a queue overflow in a switch or Wi-Fi link tends to drop a burst out of that train. That is why artefacts often cluster at the keyframe interval. Staggering keyframes across cameras can smooth aggregate load where cameras share an uplink, though few systems control that.
Reading RTCP. The Receiver Report's fraction lost and jitter fields are direct, cheap measurements of path health, and RTP sequence-number gaps tell you the same thing from the data plane. Alert on sustained loss above a small threshold you choose for your network and on jitter growth; both usually appear before the picture is visibly bad.
Bandwidth and storage sizing
Storage and bandwidth derive from one quantity: the bitrate actually emitted, multiplied by time.
Illustrative arithmetic (decimal units, no overhead):
- 1 Mbit/s equals 0.125 MB/s, which is 10.8 GB per 24 hours.
- A 4 Mbit/s camera recording continuously: 4 x 10.8 = 43.2 GB per day, or about 1.30 TB over 30 days.
- 100 such cameras: 400 Mbit/s aggregate ingest, about 4.3 TB per day and about 130 TB over 30 days.
- If only a fraction of the day is recorded (for example event-triggered at a 25 percent duty cycle), storage scales by that fraction, but the network still carries the stream whenever the consumer is connected, and you still need pre-event buffering.
Adjustments to apply to the raw figure:
- Headers and framing. RTP, UDP/TCP, IP and Ethernet headers add several percent on top of the codec payload; plan network capacity with margin, not at 100 percent of link speed.
- Container and index overhead. Small relative to video, but nonzero.
- Audio and metadata tracks add a small amount.
- Redundancy. RAID, replication or erasure coding multiplies raw disk requirements.
- Peak versus average. For VBR, size storage on the average over a representative period and network on the peak (or the configured cap) across cameras that peak together, such as at dusk, when many cameras raise gain and bitrate in the same hour.
- Day/night variance. Noise at night frequently inflates bitrate; measure over a full cycle.
Resolution and frame rate are poor inputs here because the same 1080p30 stream can be 1 Mbit/s or 8 Mbit/s depending on scene, codec, rate control and noise. Bitrate is the reliable input, and measured bitrate is better than configured bitrate.
Enter your own camera count, bitrate, recording schedule and retention below to see aggregate throughput, storage and unit conversions. Try halving the duty cycle, then try doubling the bitrate to see which input dominates.
Bandwidth and storage calculator
Goal. Size network links and disks from camera count, bitrate, schedule and retention, with every bit-to-byte step visible.
- Aggregate bandwidth
- 64.0 Mbit/s
- all cameras, live
- Storage per day
- 795 GB
- 0.795 TB
- Total 30-day retention
- 23.85 TB
- 21.69 TiB
Link utilisation, 100 Mbit/s: 64%
Link utilisation, 1 Gbit/s: 6.4%
Step by step (bits vs bytes)
- Per camera: 4000 kbit/s x 1000 = 4,000,000 bit/s; / 8 = 500,000 B/s (bits to bytes).
- Aggregate: 16 cameras x 4000 kbit/s = 64,000 kbit/s = 64.00 Mbit/s (decimal, 1 Mbit = 10^6 bit).
- Recorded time/day: 86 400 s x duty 100.0% = 86,400 s.
- Bytes/day: 8,000,000 B/s x 86,400 s x (1 + 15%) = 794.88 GB (decimal, 1 GB = 10^9 B).
- Retention: 794.88 GB/day x 30 days = 23.846 TB (10^12 B) = 21.688 TiB (2^40 B).
Reading the result
16 cameras at 4,000 kbit/s (continuous, 100% duty) produce 64.0 Mbit/s live, using 64% of a 100M link or 6.4% of 1G. Storage is 795 GB/day; over 30 days that is 23.85 TB (21.69 TiB).
Assumptions and limits
- Estimate only. Every camera has the same average bitrate; real VBR streams fluctuate with the scene.
- Bitrate is the main storage input; resolution x fps only matters through the bitrate the encoder actually produces.
- Decimal units: 1 kbit = 1000 bit, 1 GB = 10^9 B, 1 TB = 10^12 B. TiB (2^40 B) shown for comparison with how disks and OSes often report.
- Link utilisation uses live aggregate bitrate (cameras stream whatever the recording schedule) against nominal 100 Mbit/s and 1 Gbit/s; protocol overhead and other traffic not included.
- Overhead % covers container/index metadata and redundancy you choose (e.g. mirroring ~100%); it multiplies storage only, not bandwidth.
- Motion duty cycle is a user-supplied fraction of the day with activity; no pre/post-event buffer modelled.
What you should see: bitrate and retention scale storage linearly and multiply together, camera count scales both aggregate bandwidth and storage, and a recording-schedule fraction reduces storage but not stream bandwidth. The result is an estimate that excludes redundancy and overhead unless the calculator says otherwise; verify the units (decimal gigabytes versus binary gibibytes) when comparing with disk vendors.
NVR and VMS architecture
An NVR (network video recorder) is typically an appliance: it connects to a set of cameras, records, and provides playback and a UI. A VMS (video management system) generalizes this into software that manages cameras, recording, live view, events and analytics, often across many servers and sites. The responsibilities are similar at any scale; what changes is how they are partitioned.
Cameras
RTSP + ONVIF
Device manager
discovery, profiles, credentials
Stream gateway
one pull per camera, fan out
Recorder
segments + index
Analytics workers
decode + inference
Event bus + metadata DB
detections, health
Playback / live API
HLS, WebRTC, clients
Device manager. Owns the camera inventory: addresses, credentials (from a secrets store), ONVIF capabilities, chosen profiles and per-model quirks. It handles discovery and onboarding, and records which stream is used for what.
Stream gateway / relay. Cameras tolerate a limited number of concurrent RTSP sessions, and a camera pulled separately by a recorder, an analytics worker and several viewers will suffer. A gateway pulls each stream once and fans out internally, so the camera sees one consumer. It is also the natural place to keep the stream warm (reducing cold-start delay), terminate transport quirks, normalize timestamps and expose health.
Recorder. Writes the stream to disk. The efficient design remuxes the camera's encoded packets into segments (MP4/fMP4/MKV or a proprietary container) without re-encoding, so storage is exactly bitrate times time and CPU use is mostly I/O. An index maps camera and time range to segments, with keyframe positions to support seeking. Writes are sequential and append-heavy; disk throughput, not CPU, is the usual recorder limit, together with NIC capacity.
Analytics workers. Consume streams (usually substreams) from the gateway, decode, sample and run inference, as in the previous pipeline. These are the only components that must decode every frame they use, so decode capacity, GPU memory and model throughput govern how many cameras a node can analyse. Emit detections as events, not pixels.
Event bus and metadata store. Detections, motion events, health and audit records flow to a message bus and a queryable store. Events reference camera ID and time range so a playback request can resolve straight to recorded segments.
Playback and live APIs. Browsers cannot play RTSP directly. The usual approaches are to repackage into HLS or low-latency HLS (seconds of latency), or WebRTC (sub-second, more moving parts), or to run a native client. Live view for a grid should use substreams.
Scaling to very large camera counts. I have worked on VMS architecture for fleets on the order of 100k+ cameras; the principles, not any measured figures, are what carry over:
- Partition by camera: assign each camera to a recorder and gateway shard through a registry, so no component needs to know about all cameras.
- Make assignment dynamic with leases so a failed node's cameras are re-homed automatically; a camera reconnect storm needs jitter and backoff, or recovery itself causes an outage.
- Separate the planes: media flows between camera and recorder, control and metadata through the bus and database. Do not push video through the event bus.
- Scale decode by AI-enabled camera count, not total camera count; most cameras record without ever being decoded.
- Treat each camera as an unreliable remote dependency with its own health state, connection history and quirks.
- Plan for heterogeneity: mixed vendors, firmware, codecs and clock accuracy are the normal state of a large fleet.
Failure modes, troubleshooting and recovery
The common failures fall into a small number of categories, and most are diagnosable from client-side evidence in a fixed order: can I reach it, can I authenticate, can I negotiate, is media arriving, does it decode, is it timely.
| Symptom | Likely causes | First checks |
|---|---|---|
| Gray, smeared or green frames that clear at intervals | UDP packet loss; corruption until next IDR | RTCP fraction lost, RTP sequence gaps; switch to interleaved TCP |
| Growing delay, then catch-up jumps | TCP retransmission stalls; slow consumer; oversized buffer | Network loss, consumer read rate, stale-frame queue |
| Blocky, soft picture in motion | Bitrate too low for CBR; high bits-per-pixel pressure | Configured vs measured bitrate, VBR cap, scene complexity |
| Connects but no video, or immediate error | Unsupported codec, profile or level; missing parameter sets; decoder limit | SDP rtpmap/profile-level-id, decoder capabilities, stream resolution |
| Works for 60 seconds, then drops | Keepalive not sent; session timeout | Session timeout value, keepalive method |
| 401 on ONVIF, RTSP fine | Clock skew; separate ONVIF user | Device date/time, user configuration |
| Works with player, fails in pipeline | Transport, auth scheme or URL (substream path); too many sessions | Same URL and transport in both; session count on camera |
| CPU or GPU pegged, frames dropped | Decoder overload: too many streams, resolution too high | Decode FPS vs nominal, switch to substream, hardware decode |
| Long wait before first picture | Waiting for next IDR | Keyframe interval, gateway warm streams |
The troubleshooting simulator below lets you pick a synthetic scenario (packet loss, high latency, insufficient bitrate, unsupported codec or profile, decoder overload) and walk through symptoms, probable causes, diagnostic checks and remedies. The scenarios are constructed, not recordings from real incidents.
Stream troubleshooting simulator
Goal. Match what you see on screen and in logs to likely causes, then work through diagnostic checks in a sensible order.
Symptoms
- Intermittent corruption or freezes
- Artifacts persist until the next I-frame
- Worse on Wi-Fi or congested links
Likely causes
- Lossy or congested network path
- UDP transport with no retransmission
- Switch/Wi-Fi buffer overflow
- Long GOP making each loss last longer
Diagnostic checks (0/4)
Remedies
- Use RTSP over TCP (interleaved) where latency allows
- Shorten the keyframe interval
- Fix the congested/lossy link or add QoS
- Use a wired connection
What you would see
Grey smears, green blocks or frozen frames that clear at the next keyframe.
[synthetic] rtp: seq gap expected=1042 got=1044 [synthetic] rtp: 0.8% packets lost in last 10 s [synthetic] decoder: corrupt access unit, waiting for keyframe
Reading the result
Scenario: Packet loss (UDP) (mild). You would see: Grey smears, green blocks or frozen frames that clear at the next keyframe. 0 of 4 diagnostic checks ticked. Work from the cheapest check (usually transport/credentials) to the most invasive.
Assumptions and limits
- Scenarios and log lines are synthetic and hand-written; nothing connects to a real camera, RTSP server or network.
- Real symptoms overlap; several causes often combine. Treat the lists as a starting checklist, not a diagnosis.
- RTSP codes used are standard: 401 Unauthorized and 454 Session Not Found. Behaviour varies by camera: some close the connection or return other codes.
- Severity changes the illustrative numbers in the synthetic logs only.
What you should see: different root causes can produce similar visible symptoms, which is why the diagnostic checks matter more than the symptom, and why remedies differ (a transport switch fixes corruption but can worsen latency; a bitrate increase fixes blockiness but raises storage).
Recovery design. Whatever the cause, the client side needs: bounded reconnect with exponential backoff and jitter; a health state machine per camera (connecting, streaming, degraded, failed); automatic fallback between transports; and no unbounded queues. On the recording side, segment boundaries should be self-contained (starting at an IDR) so that a failure loses seconds, not an entire file, and so the index stays consistent after a crash.
Metrics and alerts
Instrument per camera and per stream, not just per node. Useful signals:
- Stream health: connection state, reconnect count and rate, time to first frame, RTSP errors by code.
- Transport quality: RTCP fraction lost and jitter, RTP sequence gaps, TCP retransmission or buffer occupancy for interleaved streams.
- Media characteristics: measured bitrate (against configured), observed frame rate, observed keyframe interval, resolution and codec as advertised versus received. A mismatch between configured and observed values is the earliest indicator of a firmware or smart-mode change.
- Decode: decode FPS versus nominal, decoder error counts, frames dropped, queue depth, hardware decoder session utilization.
- Freshness: age of the newest frame when it reaches inference; end-to-end latency distribution if a timestamp source exists. Alert on growth, because stale-frame accumulation is silent otherwise.
- Time: camera clock offset (from ONVIF
GetSystemDateAndTimeor RTCP mapping) against server time; drift breaks cross-camera correlation and ONVIF authentication. - Recording: segment write latency, gaps in the index, free disk and projected retention, write throughput versus capacity.
- Analytics: detections per camera per hour (sudden zero or spike usually means a pipeline or scene problem), confidence distribution, and the proportion of frames gated out for unhealthy streams.
Alert on rates and durations (loss above a threshold for N minutes, freshness above a limit) instead of single events, because cameras on real networks produce brief blips constantly. Page on fleet-level signals such as a rising reconnect rate across many cameras, which suggests a shared cause (switch, firmware, certificate, DNS); route single-camera faults to a ticket queue.
Security considerations
Cameras are network-attached embedded devices that often run old firmware and have a poor history of default credentials, so they are a standing risk.
- Network isolation. Place cameras on a dedicated VLAN with no direct internet route; allow only the VMS and gateway to reach RTSP and ONVIF ports. Do not expose port 554 or ONVIF services to the internet.
- Credentials. Change defaults at onboarding; use unique per-device credentials where firmware allows; store them in a secrets manager; never put them in logs. RTSP URLs with embedded
user:passleak through process lists, logs and error messages. - Authentication scheme. Prefer Digest over Basic; Basic on RTSP sends credentials in a trivially decodable form.
- Transport security. Standard RTSP and RTP are unencrypted. RTSP over TLS (RTSPS, commonly port 322) and SRTP exist, but support in cameras is uneven. Where unavailable, rely on network isolation and an encrypted tunnel for any traversal of untrusted networks.
- Least privilege. Create read-only streaming users for consumers; keep configuration-capable accounts for the device manager alone, because ONVIF and vendor APIs can change encoder settings and reboot devices.
- Firmware and services. Patch, disable unused services (UPnP, telnet, cloud relays), and track model/firmware versions in the inventory.
- Time. Point cameras at an internal NTP server. Time integrity affects evidentiary value of recordings as well as authentication.
- Privacy and retention. Video of people and plates is personal data in many jurisdictions. Retention periods, access control and audit logging are design inputs, not afterthoughts.
Assumptions and limitations
- Camera behavior is firmware-dependent. Statements about B-frames, smart codecs, keyframe signalling, session limits and ONVIF coverage describe common cases, not every device.
- The labs use simplified models with assumed efficiency factors and illustrative frame-size ratios. They show direction of effect, not measured outcomes, and should not be used as procurement numbers.
- Efficiency figures for H.265 and thresholds such as pixels across a plate are commonly cited ranges and rules of thumb; validate on your own cameras, scenes and models.
- Code and configuration snippets are illustrative, and I did not validate them against a specific FFmpeg, OpenCV, GStreamer or camera firmware version. Option names in particular change between releases.
- I cover RTSP-based pull ingestion. Push-based paths such as RTMP or SRT, WebRTC ingestion, cloud-managed cameras and onboard-recording retrieval via ONVIF Profile G are outside my scope here.
- I report no performance or capacity measurements from my own systems here.
Conclusion
An IP camera stream is the product of a pipeline in which each setting has a downstream cost: pixels and noise set the bitrate, bitrate sets storage and network, GOP length sets join time and error persistence, transport choice trades corruption for delay, and the stream you pick for inference sets decode cost and the ceiling on recognition accuracy. Size systems from measured bitrate, use substreams for continuous detection with main-stream reads on demand, gate analytics on stream health, and instrument freshness as carefully as throughput. Most video-analytics problems that look like model problems turn out to be exposure, bit budget or latency problems earlier in the chain.