Skip to content

Fix Android 9 H.264 streaming and server resilience#48

Merged
DigitallyRefined merged 2 commits into
DigitallyRefined:mainfrom
sabag:android9-h264-sps-pps
Jul 10, 2026
Merged

Fix Android 9 H.264 streaming and server resilience#48
DigitallyRefined merged 2 commits into
DigitallyRefined:mainfrom
sabag:android9-h264-sps-pps

Conversation

@sabag

@sabag sabag commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

1. Android 9 H.264 compatibility

projects/mi6-ip-camera/android-ip-camera-src/app/src/main/kotlin/com/github/digitallyrefined/androidipcamera/helpers/H264HardwareEncoder.kt

  • Removes the Android 10-only SPS/PPS prepend option.
  • Reads SPS/PPS from csd-0 and csd-1.
  • Handles partial MediaCodec buffers.
  • Detects actual IDR frames.
  • Releases codec buffers before downstream processing.
  • Avoids a shutdown locking problem.

projects/mi6-ip-camera/android-ip-camera-src/app/src/main/kotlin/com/github/digitallyrefined/androidipcamera/helpers/H264Bitstream.kt — new

  • Normalizes Annex-B, avcC, length-prefixed AVC and raw NAL data.
  • Caches SPS/PPS.
  • Prepends SPS/PPS to every IDR.
  • Drops configuration-only buffers.
  • Reassembles partial access units.
  • Validates malformed H.264 input.

2. Stalled NVR protection

projects/mi6-ip-camera/android-ip-camera-src/app/src/main/kotlin/com/github/digitallyrefined/androidipcamera/helpers/H264StreamingEncoder.kt

  • Moves network writing away from MediaCodec.
  • Uses one ordered writer thread.
  • Adds a bounded 30-access-unit queue.
  • Disconnects stalled clients when the queue fills.
  • Invalidates queued frames after encoder restart.
  • Prevents old frames from reaching new clients.
  • Waits for a successfully transmitted keyframe before activating clients.

3. True configured frame rate

projects/mi6-ip-camera/android-ip-camera-src/app/src/main/kotlin/com/github/digitallyrefined/androidipcamera/StreamingService.kt

  • Passes the configured FPS into the GL camera pipeline.

projects/mi6-ip-camera/android-ip-camera-src/app/src/main/kotlin/com/github/digitallyrefined/androidipcamera/helpers/CameraGlPipe.kt

  • Consumes all camera frames but sends only correctly paced frames to the encoder.
  • Uses camera timestamps with a system-clock fallback.
  • Resets pacing state when stopped.

projects/mi6-ip-camera/android-ip-camera-src/app/src/main/kotlin/com/github/digitallyrefined/androidipcamera/helpers/FrameRateLimiter.kt — new

  • Provides timestamp-based 1–60 fps limiting.
  • Drops excess frames without accumulating timing drift.
  • Handles timestamps moving backwards.

4. Platform TLS and server lifecycle

projects/mi6-ip-camera/android-ip-camera-src/app/src/main/kotlin/com/github/digitallyrefined/androidipcamera/helpers/StreamingServerHelper.kt

  • Uses Android’s built-in TLS provider.

  • Automatic mode selects:

    • Android 7–9: TLS 1.2.
    • Android 10+: TLS 1.3.
  • Explicit TLS 1.2 remains supported.

  • Does not permanently rewrite the automatic preference.

  • Generates and securely stores a random certificate password.

  • Generates a device-local certificate when needed.

  • Adds server-generation tracking for safe restarts.

  • Prevents old server jobs and clients from surviving restarts.

  • Tracks and closes H.264, MJPEG and audio clients.

  • Makes client removal idempotent.

projects/mi6-ip-camera/android-ip-camera-src/app/src/main/res/values/strings.xml

  • Renames the first TLS option to automatic platform selection.

projects/mi6-ip-camera/android-ip-camera-src/app/src/main/res/xml/preferences.xml

  • Clarifies automatic TLS, forced TLS 1.2 and disabled HTTPS behavior.

5. Build configuration

projects/mi6-ip-camera/android-ip-camera-src/app/build.gradle

  • Adds JUnit 4.13.2.

6. Tests

projects/mi6-ip-camera/android-ip-camera-src/app/src/test/kotlin/com/github/digitallyrefined/androidipcamera/helpers/H264BitstreamTest.kt — new

  • Ten H.264 normalization, SPS/PPS, IDR and partial-buffer tests.

projects/mi6-ip-camera/android-ip-camera-src/app/src/test/kotlin/com/github/digitallyrefined/androidipcamera/helpers/FrameRateLimiterTest.kt — new

  • Four frame-pacing and timestamp-handling tests.

@sabag sabag force-pushed the android9-h264-sps-pps branch from 362aa73 to 0fd0adb Compare July 9, 2026 17:49
@DigitallyRefined DigitallyRefined merged commit 90f9f80 into DigitallyRefined:main Jul 10, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants