feat(m1): browser-process PCF + encoder injection (CV2-25/26/27) #18

Open
triform-admin wants to merge 0 commits from cv2/m1-native-pcf into integration/native-peer

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_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 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; injects CloudBrowserVideoEncoderFactory under default Config{} + builtin video decoder + builtin audio enc/dec + ADM (default substituted when adm is 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 dedicated rtc::Thread members (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) — codec log line

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 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") in build-integration/BUILD.gn:

  • CloudBrowserPcfTest.DepsCarryInjectedEncoderFactory
  • CloudBrowserPcfTest.DepsAudioDeviceModuleSlotHonoursInjection
  • CloudBrowserPcfTest.PcfVideoSenderCapsMatchFactoryFormats
  • CloudBrowserPcfLogTest.FormatsDeterministicCodecLine (4 cases — VP9+H264+AV1; single VP8; empty; reversed-order stability)

RED-by-construction pre-T17. build-job.yaml CHROMELESS_BUILD_TARGETS appended so the K8s chromeless-build Job on triform-2 picks the new target up on first dispatch.

Test plan

  • Operator-led T17 first-green: kubectl -n chromeless-build apply -f infra/k8s/chromeless-build/build-job.yaml on triform-2
  • Confirm cloud_browser_pcf_unittests builds + runs green inside the Job
  • M0 R5 assertion #3 picks up the CloudBrowser: PCF video sender codecs = [...] log line via its scrape regex
  • After first green: capture one real boot-log line and replace the synthetic provenance comment in cloud_browser_pcf_test.cc

Notes on choices

  • cloud_browser_pcf.{h,cc} live in capture/build-integration/ next to the embedder and worker neighbors (brief named this dir, and BUILD.gn is per-dir gn island).
  • FakeAudioDeviceModule = webrtc::TestAudioDeviceModule from modules/audio_device/include/test_audio_device.h (header named in brief). Uses CreatePulsedNoiseCapturer(max_amplitude=0, ...) for an effectively-silent capturer.
  • PcfVideoSenderCapsMatchFactoryFormats uses IsSupersetOf instead of strict UnorderedElementsAre — 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.
  • Default ADM uses webrtc::AudioDeviceModule::kDummyAudio with a process-static leaked TaskQueueFactory — 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. ## Scope ### CV2-25 (R1) — widen patches/0003 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 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; injects `CloudBrowserVideoEncoderFactory` under default `Config{}` + builtin video decoder + builtin audio enc/dec + ADM (default substituted when `adm` is 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 dedicated `rtc::Thread` members (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) — codec log line 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 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")` in `build-integration/BUILD.gn`: - `CloudBrowserPcfTest.DepsCarryInjectedEncoderFactory` - `CloudBrowserPcfTest.DepsAudioDeviceModuleSlotHonoursInjection` - `CloudBrowserPcfTest.PcfVideoSenderCapsMatchFactoryFormats` - `CloudBrowserPcfLogTest.FormatsDeterministicCodecLine` (4 cases — VP9+H264+AV1; single VP8; empty; reversed-order stability) RED-by-construction pre-T17. `build-job.yaml` `CHROMELESS_BUILD_TARGETS` appended so the K8s chromeless-build Job on triform-2 picks the new target up on first dispatch. ## Test plan - [ ] Operator-led T17 first-green: `kubectl -n chromeless-build apply -f infra/k8s/chromeless-build/build-job.yaml` on triform-2 - [ ] Confirm `cloud_browser_pcf_unittests` builds + runs green inside the Job - [ ] M0 R5 assertion #3 picks up the `CloudBrowser: PCF video sender codecs = [...]` log line via its scrape regex - [ ] After first green: capture one real boot-log line and replace the synthetic provenance comment in `cloud_browser_pcf_test.cc` ## Notes on choices - `cloud_browser_pcf.{h,cc}` live in `capture/build-integration/` next to the embedder and worker neighbors (brief named this dir, and BUILD.gn is per-dir gn island). - `FakeAudioDeviceModule` = `webrtc::TestAudioDeviceModule` from `modules/audio_device/include/test_audio_device.h` (header named in brief). Uses `CreatePulsedNoiseCapturer(max_amplitude=0, ...)` for an effectively-silent capturer. - `PcfVideoSenderCapsMatchFactoryFormats` uses `IsSupersetOf` instead of strict `UnorderedElementsAre` — 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. - Default ADM uses `webrtc::AudioDeviceModule::kDummyAudio` with a process-static leaked `TaskQueueFactory` — satisfies brief's "non-null ADM compiles + emits no audio"; M5.5 swaps the body. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(m1): browser-process PCF + encoder injection (CV2-25/26/27)
Some checks failed
CI / Lint (pull_request) Failing after 2s
CI / Build container image (pull_request) Failing after 8s
CI / Container smoke test (pull_request) Has been skipped
CodeQL / Analyze go (pull_request) Failing after 1s
CodeQL / Analyze javascript-typescript (pull_request) Failing after 1s
E2E / docker-compose + Playwright (pull_request) Failing after 14s
CI / Docs link check (pull_request) Failing after 44s
4ed67d65b9
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.
Some checks failed
CI / Lint (pull_request) Failing after 2s
CI / Build container image (pull_request) Failing after 8s
CI / Container smoke test (pull_request) Has been skipped
CodeQL / Analyze go (pull_request) Failing after 1s
CodeQL / Analyze javascript-typescript (pull_request) Failing after 1s
E2E / docker-compose + Playwright (pull_request) Failing after 14s
CI / Docs link check (pull_request) Failing after 44s
This branch is already included in the target branch. There is nothing to merge.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin cv2/m1-native-pcf:cv2/m1-native-pcf
git switch cv2/m1-native-pcf

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch integration/native-peer
git merge --no-ff cv2/m1-native-pcf
git switch cv2/m1-native-pcf
git rebase integration/native-peer
git switch integration/native-peer
git merge --ff-only cv2/m1-native-pcf
git switch cv2/m1-native-pcf
git rebase integration/native-peer
git switch integration/native-peer
git merge --no-ff cv2/m1-native-pcf
git switch integration/native-peer
git merge --squash cv2/m1-native-pcf
git switch integration/native-peer
git merge --ff-only cv2/m1-native-pcf
git switch integration/native-peer
git merge cv2/m1-native-pcf
git push origin integration/native-peer
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
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
No description provided.