Skip to content

Latest commit

 

History

History
74 lines (64 loc) · 4.14 KB

quality-tiers.md

File metadata and controls

74 lines (64 loc) · 4.14 KB

Named software recording quality

Version 0.75 accepts quality: 'very-low' | 'low' | 'medium' | 'high' | 'very-high' in recorder/session options. Numeric quality 1..100 and the default numeric 90 retain their previous JPEG/CRF/ABR behavior. A named tier is an explicit opt-in.

import { Recorder, QualityTier, planRecordingQuality } from '@zig-utils/camera'
const settings = {
  width: 3840, height: 2160, fps: 30, codec: 'h264' as const,
  quality: QualityTier['very-high'],
}
console.log(planRecordingQuality(settings))
const recorder = await Recorder.open('trail.mp4', settings)
console.log(recorder.qualityPolicy())
Tier Software JPEG quality AVC reference target at 1080p30
very-low 25 3 Mbps
low 35 4 Mbps
medium 50 7 Mbps
high 65 10 Mbps
very-high 80 14 Mbps

These are the inspected Picamera2 software JpegEncoder/LibavH264Encoder tier policies, implemented through Home without Python or Libav/FFmpeg. HEVC deliberately shares the same Home bitrate heuristic; upstream supplies no matching HEVC table. Hardware H.264/MJPEG use different linear policies and remain separate work. No optical-quality, actual bitrate, encoder speed or physical Pi FPS claim is made.

AVC/HEVC use reference * sqrt(width * height * fps / (1920 * 1080 * 30)). Home computes an exact integer/rational estimate with u128 math and integer square root, floors it to vendor 1000 bit/sec units and imposes a minimum 1000 bit/sec. Overflow or an unsupported session shape rejects without mutation. The C helper also accepts rational fps_num/fps_den. JPEG tier values do not scale with size/fps.

A named video tier selects ABR and overrides a supplied target bitrate. Numeric quality keeps the existing rule: a nonzero bitrate selects ABR, fixed QP selects CQP, otherwise quality selects CRF. Named video tiers conflict with nonzero encoder.qp; choose a numeric quality policy to use fixed QP. JPEG has no target bitrate control, so nonzero MJPEG bitrate/GOP remain invalid. Combined level/VBV limits are validated against the derived target before files or output hooks. ABR is not a hard per-frame, packet, file-size or network rate cap.

planRecordingQuality uses the pure Home/C policy without opening an encoder, camera, file or sink. Its returned numeric recipe has quality: 90 under video ABR, where that scalar is inactive. qualityPolicy() reports a frozen copy of the requested tier, native scalar quality, target bitrate and control mode; it is not measured vendor statistics. Queries reject active producer ownership. Preserve the named request if future geometry/fps changes should derive a new target.

Requested options are copied before native admission and output hooks. Session reconfiguration and coordinated mode/recovery jobs resolve the actual recording stream geometry first, then apply the tier and validate limits. A tier is retained across codec changes; changing to MJPEG uses its JPEG value and changing back derives a new video rate. Cancelled/failed preparation preserves the old policy. Omit quality to inherit, or use quality: null to restore legacy numeric default 90. For example, { quality: null, bitrate: 10000000 } leaves tier mode for explicit ABR. Fully resolved coordinated resets are passed explicitly at publication.

C adds the five ZC_QUALITY_* IDs and transactional zc_video_apply_quality_tier(zc_video_config *, tier). Existing 32-byte video configuration and open defaults remain unchanged. Resolve geometry first when it can adjust, apply the tier, then validate codec options/limits before opening. Zig exposes the shared helper as camera.capture_quality. CLI recording accepts --quality-tier NAME; it overrides numeric --quality/video target bitrate. The tier flag rejects non-record commands before creating an output.

Tests check reference values, rational rates, exact scaling, bounds/overflow and immutable failure. JPEG packets and CLI recordings match the corresponding numeric quality bytes. Video fixtures independently decode MP4 on Linux and cover limits/QP conflicts, copied options, rollback, codec changes, reset semantics, negotiated geometry before VBV checks, and fresh-camera recovery.