feat(clients): codec preference on Windows/Apple/Android clients (Phase 2b)
Rounds out codec negotiation across the last three clients — each advertises what it can decode, builds its decoder from the resolved Welcome.codec, and exposes a "Video codec" preference picker. **Windows** (Rust, mirrors Linux): `decodable_codecs()` + `ffmpeg_codec_id()`; the D3D11VA and software FFmpeg decoders (and the mid-session D3D11VA→software demotion) open the negotiated codec instead of hardcoding HEVC; settings gain a `codec` field + reactor ComboBox; `--codec` CLI flag. **Apple** (Swift/C-ABI): AnnexB is now codec-aware — a `VideoCodec` enum drives H.264 vs HEVC NAL parsing / parameter-set extraction (`CMVideoFormatDescriptionCreateFromH264ParameterSets` for H.264, no VPS) and AVCC repacking; `PunktfunkConnection` advertises H264|HEVC via `punktfunk_connect_ex7`, reads `resolvedCodec` (`punktfunk_connection_codec`), and threads `videoCodec` into the stage-1/2 pipelines + `VideoDecoder`; SettingsView "Video codec" Picker (auto/HEVC/H.264). AV1 is left out (hosts don't emit it on the native path, and it's not an AnnexB codec). Test call sites updated. **Android** (Kotlin + Rust JNI): the JNI `nativeConnect` gains `preferredCodec`; the native decode loop picks the AMediaCodec MIME (`video/hevc`|`video/avc`) from `connector.codec` and advertises H264|HEVC; Settings `codec` field + Compose dropdown. Core/host/probe/Linux clippy + tests green (unchanged from 2a). Windows/Apple/Android compile on their platform CI (this Linux box can't build them — Windows toolchain / Xcode / the Android NDK's opus-cmake toolchain). All follow the Linux client's validated pattern. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -138,7 +138,7 @@ final class RemoteFirstLightTests: XCTestCase {
|
||||
if firstPtsNs == 0 { firstPtsNs = au.ptsNs }
|
||||
lastPtsNs = au.ptsNs
|
||||
|
||||
if let f = AnnexB.formatDescription(fromIDR: au.data) {
|
||||
if let f = AnnexB.formatDescription(fromIDR: au.data, codec: .hevc) {
|
||||
format = f
|
||||
if decoder == nil {
|
||||
let dims = CMVideoFormatDescriptionGetDimensions(f)
|
||||
@@ -155,7 +155,7 @@ final class RemoteFirstLightTests: XCTestCase {
|
||||
}
|
||||
}
|
||||
guard let f = format, let dec = decoder,
|
||||
let sample = AnnexB.sampleBuffer(au: au, format: f)
|
||||
let sample = AnnexB.sampleBuffer(au: au, format: f, codec: .hevc)
|
||||
else { continue }
|
||||
|
||||
var gotPixels = false
|
||||
|
||||
Reference in New Issue
Block a user