Testing and release evidence

Verify Camera Timestamp Sources Before Cross-Clock Alignment

Separate frame exposure anchors, capture identity and callback arrival under documented UNKNOWN or REALTIME source contracts.

Review status: Fact and editorial QA complete; owner review pending · 2026-10-08 · Fact IDs: ANDROID-CAMERAX-ANALYSIS-2026-01, ANDROID-TIMEBASE-2026-10, ANDROID-CAMERA-TIMESTAMP-SOURCE-2026-10

Direct answer

ImageInfo.getTimestamp is a timestamp attached to image metadata, but CameraX documents that timestamp details depend on the source providing the image. The ImageAnalysis.Analyzer documentation says image timestamps are nanoseconds and monotonic and can be compared across use cases bound to the same camera instance. That statement is a bounded comparison rule, not a promise that a frame timestamp equals the time an application callback ran, when inference completed, or when a UI displayed a result. For Camera2, CaptureResult.SENSOR_TIMESTAMP is the time at the start of exposure of the first row of the sensor active array. The CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE key describes the clock source. Both are available from API 21. With REALTIME, Camera2 documents that sensor timestamps share the timebase of SystemClock.elapsedRealtimeNanos. With UNKNOWN, timestamps are monotonic but start from an unspecified origin and are not generally comparable to another camera or system time source. Use the source value as part of the timestamp, not as incidental metadata. A valid same-clock comparison requires more than two numbers that increase. Record the CameraX library version, camera instance or camera ID, selected use case, sensor timestamp source where available, timestamp value, and the exact image/capture identity. For one Camera2 capture, the sensor timestamp is included in all image buffers produced for that capture and is identical on those outputs. A CameraX ImageInfo timestamp and a Camera2 CaptureResult may refer to the same capture only when the selected CameraX implementation exposes a documented or empirically verified association. Do not match them merely because callback order looks similar; outputs can be delayed, dropped, transformed, or surfaced through a wrapper. Keep capture time separate from delivery time. Record ImageInfo.getTimestamp as the image timestamp and, if needed, record callback entry with a separately named SystemClock value. Their difference is not automatically camera processing latency because the clocks may have different origins, the callback can be queued, and the sensor clock may be UNKNOWN. Do not calibrate UNKNOWN against elapsedRealtimeNanos, boot time, audio timestamps, or a second camera from a nearby poll and then report a reusable offset. If there is no supported common source or capture-identity relation, store cross-domain mapping as unknown. The timestamp does not make a rolling-shutter image simultaneous. Camera2 defines SENSOR_TIMESTAMP relative to the first row exposure start; different rows can be exposed at different times. A single image timestamp can label the documented frame anchor, but it is not a per-pixel capture time, guaranteed midpoint, or precision bound for every visual event. If the task needs row-level timing, rolling-shutter correction, or sensor fusion, define that as a separate model and cite the relevant capture metadata rather than silently treating the frame as an instantaneous scene. REALTIME is useful because Android documents a shared clock with elapsedRealtimeNanos, but the shared timebase does not guarantee camera exposure accuracy, callback latency, A/V synchronization quality, or precision on an arbitrary device. Test the exact path and report only the permitted comparison: same camera-instance frame ordering for CameraX, or a REALTIME sensor timestamp compared within its documented clock domain. For UNKNOWN, retain the source and camera identity and compare only within the scope documented for that stream; do not generalize a relationship to another camera, process boot, audio path, or wall clock. A safe test record includes camera ID/session, CameraX version and use case, sensor timestamp source, ImageInfo timestamp, available Camera2 CaptureResult identity and SENSOR_TIMESTAMP, callback-arrival clock recorded separately, orientation/crop state if the consumer uses it, and the observed association method. Exercise two use cases from the same camera, camera rebind, camera switch, delayed analyzer callback, missing/partial capture result, and both timestamp-source categories when available. Synthetic values can test comparison code but cannot prove a device's sensor clock or CameraX-to-Camera2 identity mapping. This is not an AudioRecord frame-to-chunk guide. Camera timestamps have different APIs and origins: keep source, capture identity, and callback time separate. Do not borrow audio formulas, infer precision from REALTIME, or claim Cove uses these timestamps; unsupported links stay unknown.

An analyzer callback arrives after a capture result

A camera feature logs ImageProxy frames and separately receives Camera2 capture results. The team wants to associate a delayed vision result with a capture event and compare it to an app event timestamp. It has not checked SENSOR_INFO_TIMESTAMP_SOURCE or established that both callbacks refer to the same capture.

Decision

Record CameraX image time, Camera2 sensor source/time, capture identity, and callback arrival as separate fields. Compare across clocks only through a documented source contract and a verified same-capture association.

Expected outcome

The report can preserve same-camera ordering or a documented REALTIME comparison while leaving unsupported cross-source mapping unknown; it does not claim per-pixel timing or device precision.

Evidence to collect

The claim becomes reviewable only when the following evidence is attached to the same artifact and test run:

  • Camera/session and timestamp-source identity
  • Same-capture association evidence
  • Unknown-source and delayed-callback fixtures

A release claim is valid only for the recorded configuration and acceptance set. Generalization requires additional records.

Implementation workflow

  1. Pin the camera path and timestamp API. Record CameraX version, provider implementation if known, camera ID/session, bound use cases, API level, and whether timestamps come from ImageInfo, Camera2 CaptureResult, or both. Do not substitute callback time for image time.
  2. Read and preserve the sensor clock source. For Camera2, query SENSOR_INFO_TIMESTAMP_SOURCE when available and store UNKNOWN or REALTIME with every comparison. REALTIME maps to elapsedRealtimeNanos by documentation; UNKNOWN has an unspecified origin and must not be calibrated to another subsystem by guesswork.
  3. Establish capture identity before joining records. Use only a documented association or a controlled, version-pinned observation linking the CameraX ImageInfo timestamp to the CaptureResult for the same frame. Record missing/partial results and dropped frames; callback order alone is not identity.
  4. Keep callback arrival in its own clock field. If measuring delivery delay, record callback entry in a named system clock and compare only if it shares a documented domain with the capture timestamp. Otherwise preserve both raw values and mark subtraction unavailable; queue delay and clock origin are different unknowns.
  5. Respect exposure and rolling-shutter meaning. Treat SENSOR_TIMESTAMP as first-row exposure start for that capture. Do not label it whole-frame midpoint or per-pixel time; use row-timing metadata only in a separately documented rolling-shutter method.
  6. Test supported and unknown-source behavior. Test same-camera use cases, camera rebind/switch, delayed callback, missing capture result, and each reported source. Assert no cross-device or audio join for UNKNOWN and no precision claim for REALTIME; synthetic clock values test code only.

Keep each transition observable. A failure should identify the stage, artifact, runtime, and recovery action without logging private user content.

Acceptance criteria

  • ImageInfo timestamp, Camera2 SENSOR_TIMESTAMP, and callback arrival are stored as distinct events with camera/session identity and source where available.
  • UNKNOWN timestamps are not compared across cameras, elapsedRealtime/boot clocks, audio, or app callback clocks without a documented shared-source contract; unsupported mapping stays unknown.
  • REALTIME comparison uses elapsedRealtimeNanos only within the documented shared timebase and does not imply capture precision, callback latency, or synchronization quality.
  • A CameraX-to-Camera2 join requires documented or version/device-tested capture identity; SENSOR_TIMESTAMP is described as first-row exposure start, not a simultaneous whole-frame time.

Decision table

DimensionChoice or evidenceHow to interpret it
ImageInfo timestampTimestamp of the image metadata from its sourceCameraX documents source-dependent details and same-camera-instance comparisons; callback delivery remains a separate event.
Camera2 SENSOR_TIMESTAMPStart of exposure for the first active-array rowIdentifies a sensor capture anchor; rolling shutter means it is not the exposure time of every row.
Timestamp source UNKNOWNMonotonic values with unspecified originKeep comparisons to the documented same camera source; do not infer equality with elapsedRealtime, audio, or another camera.
Timestamp source REALTIMECamera2 documented shared timebase with elapsedRealtimeNanosAllows a clock-domain comparison, not a measurement-accuracy or A/V-sync guarantee.

Failure patterns to prevent

  • Matching captures by callback order alone
  • Calibrating UNKNOWN with a nearby poll
  • Inferring precision from REALTIME

Also prevent silent fallback, unpinned artifacts, missing cancellation, and conclusions that combine unlike configurations. Store unsuccessful runs alongside successful ones.

Minimum reproducibility record

LayerRecord
DeviceManufacturer, model, chipset, RAM class, operating-system build
SoftwareApplication version and git commit
ModelFamily, variant, revision, format, file length, hash, quantization
RuntimeName, revision, requested backend, observed backend evidence
WorkloadFixture revision, input hash, prompt hash, output policy
OutcomeCompleted, failed, cancelled, fallback, and privacy-safe diagnostics

Release checklist

  • ☐ The primary query is answered without an unsupported number.
  • ☐ Every artifact and runtime is pinned.
  • ☐ The representative task and failure policy are explicit.
  • ☐ Lifecycle, cancellation, cleanup, and fallback are tested.
  • ☐ User-content and network boundaries are documented.
  • ☐ Result wording applies only to the recorded configuration.
  • ☐ The page links to raw method or evidence when results are added.

Sources and related evidence

Chinese deployment and troubleshooting content is organized in the .奇连 AI 端侧专题.

Frequently asked questions

Can I subtract callback arrival time from ImageInfo.getTimestamp?

Only if the exact timestamp source and callback clock are documented to share an origin and your capture identity is established. Otherwise the subtraction mixes event and clock domains; preserve both raw timestamps and mark the delay unknown.

Can Camera2 UNKNOWN timestamps be compared to audio or elapsedRealtimeNanos?

Do not assume so. UNKNOWN has an unspecified origin and Camera2 limits useful comparison to its documented camera scope. Keep audio, other cameras, boot clocks, and app arrival outside that mapping unless the exact integration supplies a supported relation.

Does REALTIME prove precise camera-to-audio synchronization?

No. It means the documented clock base matches elapsedRealtimeNanos. It does not establish exposure accuracy, callback delay, timestamp association, rolling-shutter correction, or synchronization error bounds.

Is SENSOR_TIMESTAMP the time of every pixel in a frame?

No. Camera2 defines it at the first row's exposure start. Rolling shutter can give different rows different exposure times; treat the value as its documented capture anchor, not a simultaneous whole-frame timestamp.