xpark.dataset.VideoQualityCheck#
- class xpark.dataset.VideoQualityCheck(*, detectors: list[BlackFrameSpec | StaticSceneSpec | OverexposedSpec | LowLightSpec | BlurSpec | MissingFrameSpec], segment_policy: SegmentPolicy | None = None, output_per_frame: bool = False, stream_format: str | None = None, pts_fallback_fps: float = 30.0, segment_hard_cap: int = 100000, raises_on_error: bool = True, factories: Mapping[type, Callable[[Any, SegmentPolicy, int], Detector]] | None = None)#
Exact (full-decode) video quality measurement operator.
Detects capture-level defects (black frames, freezes, over/under exposure, blur, frame-count completeness) and emits segment-level intervals + episode-level statistics. The operator is a pure measurement stage; accept / reject verdicts are left to downstream filters.
Prefer this operator when holding a video source at modest scale, or when segment-level
[start, end)localization, missing-frame reconciliation, MCAP embedded byte-streams or transient single-frame defects are needed. Already holding a pre-extractedframescolumn (e.g. from a frame-train pipeline)?VideoQualityCheckFromFramesreuses it and skips the decode entirely.Corruption coverage: hard decoder errors (
av.error.InvalidDataError/av.error.EOFErrorfrom corrupt data or truncated streams) are always caught and counted intoreport.decode_error_count;report.decoded_frame_countcounts successfully decoded frames only, so familyframe_ratiodenominators are never diluted by failed slots. PyAV’s per-frameis_corruptcodec flag is not consumed; pixel-domain corruption (macroblocking) is not covered.Detector families are declared via the
detectorslist, a tagged union of frozen dataclasses (BlackFrameSpec,StaticSceneSpec,OverexposedSpec,LowLightSpec,BlurSpec,MissingFrameSpec). Each Spec type may appear at most once. Segment-aggregation behaviour (per-familymin_duration_frames, blursample_rate_fps) is configured viaSegmentPolicy.- Parameters:
detectors – List of Spec instances declaring which detectors to run. Custom detectors registered via
register_detector()may be mixed in – they ride the same decode pass and extend the output struct with their family fields.factories – Explicit
{SpecCls: factory}map for custom Specs, taking precedence overregister_detector(); travels with the constructor through cloudpickle (seeregister_detector()for the three factory resolution paths).segment_policy – Per-family aggregation policy. Defaults to
SegmentPolicyfield defaults.output_per_frame – When true, the
per_framefield of the result struct is populated with a row per decoded frame (heavy; intended for calibration / debugging). Default false.stream_format – PyAV demuxer name (e.g.
"hevc"/"h264") for byte-stream inputs. Required when thevideoscolumn carries raw MCAP-embedded bytes; ignored for URI / local-path inputs.pts_fallback_fps – Frame rate assumed when the container carries no per-frame PTS (typically raw MCAP bytes). Only affects segment
*_nstimestamps; frame numbers are unaffected. A warning is logged whenever this fallback is used.segment_hard_cap – Maximum segments retained per family before truncation kicks in and
report.is_truncatedflips to true.raises_on_error – When true (default), a data-level failure (corrupt container, no video stream, fatal decode error) raises and fails the batch. When false, such rows degrade to an all-null result –
report is nullmarks “not checked”; healthy rows always carry a report. Infrastructure errors (download / IO) always raise.
- Raises:
ValueError – At construction time – empty
detectors, duplicate Spec types, out-of-range Spec/Policy thresholds, invalid operator params (pts_fallback_fps/segment_hard_cap),factoriescovering a built-in Spec, unknown Spec types, or custom family names colliding with built-ins. At run time (raises_on_error=Trueonly) – containers without a video stream or fatal decode failures.
Examples
from xpark.dataset import from_items from xpark.dataset.expressions import col from xpark.dataset.processors.video_quality_check import ( VideoQualityCheck, SegmentPolicy, StaticPolicy, BlackFrameSpec, StaticSceneSpec, OverexposedSpec, LowLightSpec, BlurSpec, MissingFrameSpec, ) ds = from_items([{"video": "cos://bucket/videos/001.mp4"}]) ds = ds.with_column( "qc_result", VideoQualityCheck( detectors=[ BlackFrameSpec(), StaticSceneSpec(), OverexposedSpec(), LowLightSpec(), BlurSpec(), MissingFrameSpec(), ], segment_policy=SegmentPolicy( static=StaticPolicy(min_duration_frames=60), ), ) .options(num_workers={"CPU": (2, 8)}) .with_column(col("video")), )
Methods
__call__(videos)Process a batch of videos and emit
qc_resultstructs.options(**kwargs)with_column(videos)Process a batch of videos and emit
qc_resultstructs.- __call__(videos: pa.ChunkedArray) pa.Array#
Process a batch of videos and emit
qc_resultstructs.
- options(**kwargs: Unpack[ExprUDFOptions]) Self#
- with_column(videos: pa.ChunkedArray) pa.Array#
Process a batch of videos and emit
qc_resultstructs.