feat(m1): browser-process PCF + encoder injection (CV2-25/26/27) #18
Closed
triform-admin
wants to merge 0 commits from
cv2/m1-native-pcf into integration/native-peer
pull from: cv2/m1-native-pcf
merge into: triform:integration/native-peer
triform:main
triform:adm/move-out-of-compile-lane
triform:c8/three-unbuilt-tests
triform:c3/config-surface
triform:c7/transport-seam
triform:c5/reject-unknown-params
triform:verify/c4-with-tests
triform:c4b/wire-envelope-tests
triform:verify/tests-run-for-real
triform:fix/base-public-deps
triform:c4/wire-envelope-dialects
triform:fix/conformance-readme-media
triform:track6/docs-map
triform:track7/conformance-kit
triform:chore/guest-release-0a0d28c
triform:fix/ci-registry-login
triform:fix/step7-ldpath
triform:fix/t7-lane-restore-unittests
triform:feat/client-session-split
triform:fix/profile-var-rename-severed-x264
triform:agent/cb-fidelity-wave1
triform:agent/cb-api-pins-7727
triform:agent/a4-guest-provenance
triform:capstats-plus-rearm
triform:repin-buildjob-main
triform:cv2-capture-rearm-land
triform:cv2/ideal-guest-45b6899-capstats
triform:agent/cv2-capture-stats-health-gate
triform:cv2/gpu-death-recycle
triform:cv2/gpu-crash-watchdog
triform:cv2/idle-refresh-capturer
triform:cv2/walls-on-deployed
triform:fix/cv2-walls-guest
triform:exp/answer-buffer
triform:cv2/warm-snapshot-native-session
triform:build/cv2-ice-beginframe-v5
triform:cv2/wave-3-integration
triform:build/cv2-ice-beginframe-v4
triform:build/cv2-ice-beginframe-v3
triform:build/cv2-ice-beginframe-v2
triform:build/cv2-ice-beginframe-2e5d147
triform:cv2/framesink-retarget-resolution
triform:codex/cv2-framesink-retarget-20260609
triform:codex/controller-response-signaling-cache
triform:codex/native-ice-env-220646
triform:codex/native-env-controller-212857
triform:codex/session-reconcile-conflict-retry
triform:codex/revive-ended-browser-sessions
triform:codex/browserless-emptydir-budget
triform:cv2-96-dcsctp-verbose-capture
triform:cv2-95-dispatch-tail-trace
triform:cv2-95-input-dc-receive-trace
triform:cv2-95-setactivecapture-on-capture-start
triform:cv2-95-dc-before-transceiver
triform:fix/cv2-offerer-getstats-threading
triform:cv2/wave-2-integration
triform:cv2-guest-rtp-stats-obs
triform:cv2-ws-large-frame-reassembly
triform:cv2-compositor-redraw
triform:cv2-ice-observability
triform:cv2-89-svg-contentclient
triform:cv2-89-svg-pak-scale-fix
triform:codex/cv2-wave2-verification-20260522
triform:codex/cv2-91-native-frames
triform:build/cv2-83-65d65f0
triform:build/cv2-83-286f520
triform:build/cv2-83-6cb777d
triform:codex/cv2-wave2-recovery-20260522
triform:cv2/m5.5-pulse-env-runtime-wire
triform:cv2/m4-typed-dispatcher-runtime-wire
triform:cv2/wave-1-integration
triform:cv2/m3-r5-dc-host-adoption
triform:cv2/m3-r5-dc-host-adoption-rename
triform:cv2/m5-r1-screen-impl
triform:cv2/m4-m5-m6-runtime-wire
triform:cv2/m7-integration-staged
triform:cv2/m2-r5-rearch-rebased
triform:cv2/m2-track-source-deps
triform:cv2/m7-integration
triform:cv2/m2-r5-rearch
triform:integration/native-peer
triform:cv2/m0-ci-gate
triform:team-lead/native-webrtc-review-2026-05-13
triform:codex/chromeless-context-profile-isolation
triform:codex/chromeless-input-target-session
triform:codex/triform-sw-pool-pod-watchdog
triform:codex/phase2-idle-watchdog-env
triform:codex/chromeless-pattern-c-warm-pool
triform:codex/triform-disable-streamer-autostart
triform:codex/streamer-ice-servers
triform:codex/streamer-cdp-page-session
triform:codex/skip-disabled-signaling-smoke
triform:codex/chromeless-runtime-pool-wiring
triform:codex/chromeless-gateway-signaling-url
triform:codex/streamer-signaling-url
triform:codex/idle-watchdog-env
triform:feat/otlp-logs
triform:feat/wave-1-emitters
triform:wip/pre-rename-20260504-1622
No reviewers
Labels
Clear labels
No items
No labels
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set.
Reference
triform/chromeless!18
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "cv2/m1-native-pcf"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
ChromelessV2 M1 — replaces the renderer-side libwebrtc PCF that the M0 streamer.js path constructed with a browser-process PCF that owns the entire WebRTC peer. M2+ hang the VideoTrackSource / PeerConnection / DataChannel off pcf_; M5.5 substitutes its real ADM at the audio seam without touching this call site.
Scope
CV2-25 (R1) — widen patches/0003
Re-export PCF + audio + env + threading webrtc public-API targets through the
webrtc_api_passthroughsource_set. New labels:api:create_peerconnection_factoryapi:libjingle_peerconnection_apiapi:scoped_refptrapi:enable_mediaapi/environment:environment+:environment_factoryapi/audio_codecs:builtin_audio_encoder_factory+:builtin_audio_decoder_factoryapi/audio:audio_devicertc_base:rtc_base+:threadingPatch commit-message
Targets re-exportedblock updated to match.CV2-26 (R2) — PCF seam
New
capture/build-integration/cloud_browser_pcf.{h,cc}with three free fns:BuildCloudBrowserPcfDependencies(net, worker, signaling, env, adm)— pure assembly; injectsCloudBrowserVideoEncoderFactoryunder defaultConfig{}+ builtin video decoder + builtin audio enc/dec + ADM (default substituted whenadmis null).CreateCloudBrowserPcf(...)— thin wrapper = BuildDeps +EnableMedia+CreateModularPeerConnectionFactory.CreateCloudBrowserDefaultAudioDeviceModule()— M1 dummy/no-audio ADM; the M5.5 cross-module injection slot.cloud_browser_browser_main_parts.{h,cc}now owns 3 dedicatedrtc::Threadmembers (network/worker/signaling — CV2-26 R-thread DECISION) +pcf_, constructs them inPreMainMessageLoopRunstep 5 after the DevTools listener, and tears them down (pcf_ first, then threads in reverse-construction order, then web_contents/browser_context) inPostMainMessageLoopRunper the cc:303-328 aura precedent.CV2-27 (R3) — codec log line
Pure
FormatPcfVideoCodecLogLine(video_send_codecs)incloud_browser_pcf.{h,cc}.cloud_browser_browser_main_parts.ccemits:immediately after PCF construction. Format is LOAD-BEARING — M0 R5's assertion #3 swappable probe scrapes this line by regex. The synthetic test fixtures carry a provenance comment marking them for replacement with a real cb-chromium boot-log capture once T17 goes first-green.
Tests
New
test("cloud_browser_pcf_unittests")inbuild-integration/BUILD.gn:CloudBrowserPcfTest.DepsCarryInjectedEncoderFactoryCloudBrowserPcfTest.DepsAudioDeviceModuleSlotHonoursInjectionCloudBrowserPcfTest.PcfVideoSenderCapsMatchFactoryFormatsCloudBrowserPcfLogTest.FormatsDeterministicCodecLine(4 cases — VP9+H264+AV1; single VP8; empty; reversed-order stability)RED-by-construction pre-T17.
build-job.yamlCHROMELESS_BUILD_TARGETSappended so the K8s chromeless-build Job on triform-2 picks the new target up on first dispatch.Test plan
kubectl -n chromeless-build apply -f infra/k8s/chromeless-build/build-job.yamlon triform-2cloud_browser_pcf_unittestsbuilds + runs green inside the JobCloudBrowser: PCF video sender codecs = [...]log line via its scrape regexcloud_browser_pcf_test.ccNotes on choices
cloud_browser_pcf.{h,cc}live incapture/build-integration/next to the embedder and worker neighbors (brief named this dir, and BUILD.gn is per-dir gn island).FakeAudioDeviceModule=webrtc::TestAudioDeviceModulefrommodules/audio_device/include/test_audio_device.h(header named in brief). UsesCreatePulsedNoiseCapturer(max_amplitude=0, ...)for an effectively-silent capturer.PcfVideoSenderCapsMatchFactoryFormatsusesIsSupersetOfinstead of strictUnorderedElementsAre— libwebrtc adds RTX/red/ulpfec companions to capability lists alongside primary codecs; strict equality would be brittle against benign libwebrtc additions. VP8 absence asserted separately as a "must not contain" check.webrtc::AudioDeviceModule::kDummyAudiowith a process-static leakedTaskQueueFactory— satisfies brief's "non-null ADM compiles + emits no audio"; M5.5 swaps the body.🤖 Generated with Claude Code
ChromelessV2 M1 — replaces the renderer-side libwebrtc PCF that the M0 streamer.js path constructed with a browser-process PCF that owns the entire WebRTC peer. M2+ hang the VideoTrackSource / PeerConnection / DataChannel off pcf_; M5.5 substitutes its real ADM at the audio seam without touching this call site. CV2-25 (R1) — widen patches/0003-add-cloud-browser-webrtc-overrides to re-export PCF + audio + env + threading webrtc public-API targets through the webrtc_api_passthrough source_set. New labels: api:create_peerconnection_factory, api:libjingle_peerconnection_api, api:scoped_refptr, api:enable_media, api/environment:environment + :environment_factory, api/audio_codecs:builtin_audio_encoder_factory + :builtin_audio_decoder_factory, api/audio:audio_device, rtc_base:rtc_base + :threading. Patch commit-message Targets- re-exported block updated. CV2-26 (R2) — extract PCF construction into a unit-testable seam: new capture/build-integration/cloud_browser_pcf.{h,cc} with three free fns — * BuildCloudBrowserPcfDependencies(net, worker, signaling, env, adm) — pure assembly; injects CloudBrowserVideoEncoderFactory under default Config{} + builtin video decoder + builtin audio enc/dec factories + the ADM (substituting the default dummy when adm is null); * CreateCloudBrowserPcf(...) — thin wrapper = BuildDeps + EnableMedia + CreateModularPeerConnectionFactory; * CreateCloudBrowserDefaultAudioDeviceModule() — M1 dummy/no-audio ADM; this is the M5.5 cross-module injection slot. cloud_browser_browser_main_parts.{h,cc} now owns 3 dedicated rtc::Threads (network/worker/signaling — CV2-26 R-thread DECISION) + pcf_, constructs them in PreMainMessageLoopRun step 5 after the DevTools listener, and tears them down (pcf_ first, then threads in reverse-construction order, then web_contents/browser_context) in PostMainMessageLoopRun per the cc:303-328 aura precedent. CV2-27 (R3) — pure FormatPcfVideoCodecLogLine(video_send_codecs) in cloud_browser_pcf.{h,cc}. cloud_browser_browser_main_parts.cc emits LOG(INFO) << FormatPcfVideoCodecLogLine( pcf_->GetRtpSenderCapabilities(VIDEO).codecs) immediately after PCF construction. Format is LOAD-BEARING — M0 R5's assertion #3 swappable probe scrapes this line from the container log by regex. The synthetic test fixtures carry a provenance comment marking them for replacement with a real cb-chromium boot-log capture once T17 goes first-green. Test target: new test("cloud_browser_pcf_unittests") in build-integration/BUILD.gn covering all three TDD tests from the CV2-26 plan + the four CV2-27 codec-line cases. RED-by-construction pre-T17 (build env runs inside the chromeless-build K8s Job on triform-2). build-job.yaml CHROMELESS_BUILD_TARGETS appended so the job picks the new target up on first dispatch. Notes on choices: * cloud_browser_pcf.{h,cc} live in capture/build-integration/ next to the embedder and worker neighbors (the brief named that as the target dir and the BUILD.gn was already a per-dir gn island). * FakeAudioDeviceModule = webrtc::TestAudioDeviceModule from modules/audio_device/include/test_audio_device.h — the brief pointed at this header explicitly. Uses CreatePulsedNoiseCapturer with max_amplitude=0 for an effectively-silent capturer. * PcfVideoSenderCapsMatchFactoryFormats uses IsSupersetOf instead of strict UnorderedElementsAre because libwebrtc adds RTX/red/ ulpfec companions to the capability list alongside primary codecs; the strict equality would be brittle against benign libwebrtc additions. VP8 absence asserted separately as a "must not contain" check. * Audio default uses webrtc::AudioDeviceModule::kDummyAudio with a process-static leaked TaskQueueFactory — satisfies the "non-null ADM compiles + emits no audio" brief; M5.5 swaps the body.Closing as fully landed — this PR would add nothing.
Evidence on the current tree:
The three-dot diff is what a merge would actually introduce, and it is empty:
every commit on
cv2/m1-native-pcfis reachable frommain.Worth stating because I got it wrong first: the two-dot
git diff origin/main origin/cv2/m1-native-pcfis NOT empty (~353 commits of difference), but that measures howfar main has moved since this branch was cut, not what this PR carries. Only
the three-dot form answers the question.
It also targets
integration/native-peer, which is no longer the integrationpath.
Nothing is lost by closing; reopen if the three-dot diff ever shows content.
Pull request closed