add async Media Foundation H264 and texture backend abstraction

This commit is contained in:
KingKDot
2026-07-11 03:40:18 -05:00
parent 9adcbb24a5
commit 62cd920936
6 changed files with 694 additions and 60 deletions
@@ -8,12 +8,36 @@ import (
"fmt"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"time"
"overlord-client/cmd/agent/capture"
"overlord-client/cmd/agent/sysinfo"
)
type machineInfo struct {
Hostname string `json:"hostname"`
OS string `json:"os"`
Arch string `json:"arch"`
CPU string `json:"cpu"`
GPU string `json:"gpu"`
RAM string `json:"ram"`
GeneratedAt string `json:"generated_at"`
}
type smokeReport struct {
Machine machineInfo `json:"machine"`
Findings []capture.H264MFTFinding `json:"media_foundation_findings"`
FindingError string `json:"media_foundation_finding_error,omitempty"`
H264 []capture.H264SmokeResult `json:"h264"`
Capture []capture.CaptureSmokeResult `json:"capture,omitempty"`
NVENC *capture.NVENCSmokeResult `json:"nvenc,omitempty"`
NVENCD3D11 []capture.NVENCD3D11SmokeResult `json:"nvenc_d3d11,omitempty"`
Nvidia []string `json:"nvidia_smi,omitempty"`
}
func main() {
var frames int
var captureFrames int
@@ -27,6 +51,7 @@ func main() {
var resArg string
var fpsArg string
var providersArg string
var reportPath string
flag.IntVar(&frames, "frames", 30, "frames to feed each encoder case")
flag.IntVar(&captureFrames, "capture-frames", 30, "frames to capture for each capture backend")
flag.IntVar(&captureDisplay, "display", 0, "display index for capture smoke")
@@ -39,7 +64,12 @@ func main() {
flag.StringVar(&resArg, "res", "1280x720,1920x1080,2560x1440,3840x2160", "comma-separated resolutions")
flag.StringVar(&fpsArg, "fps", "30,60,120", "comma-separated requested FPS values")
flag.StringVar(&providersArg, "providers", "hardware,software", "comma-separated providers: hardware,software")
flag.StringVar(&reportPath, "report", "", "also write the complete JSON report to this file")
flag.Parse()
hostname, _ := os.Hostname()
system := sysinfo.Collect()
machine := machineInfo{Hostname: hostname, OS: sysinfo.OSName(), Arch: runtime.GOARCH, CPU: system.CPU, GPU: system.GPU, RAM: system.RAM, GeneratedAt: time.Now().Format(time.RFC3339)}
findings, findingErr := capture.FindH264HardwareMFTs()
opts := capture.DefaultH264SmokeOptions()
opts.Frames = frames
@@ -66,22 +96,28 @@ func main() {
nvidiaSMI = queryNvidiaSMI()
}
}
report := smokeReport{Machine: machine, Findings: findings, H264: results, Capture: captureResults, NVENC: nvencResult, NVENCD3D11: nvencD3D11Results, Nvidia: nvidiaSMI}
if findingErr != nil {
report.FindingError = findingErr.Error()
}
if reportPath != "" {
if err := writeJSONReport(reportPath, report); err != nil {
fmt.Fprintf(os.Stderr, "write report failed: %v\n", err)
os.Exit(1)
}
}
if jsonOut {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
payload := struct {
H264 []capture.H264SmokeResult `json:"h264"`
Capture []capture.CaptureSmokeResult `json:"capture,omitempty"`
NVENC *capture.NVENCSmokeResult `json:"nvenc,omitempty"`
NVENCD3D11 []capture.NVENCD3D11SmokeResult `json:"nvenc_d3d11,omitempty"`
Nvidia []string `json:"nvidia_smi,omitempty"`
}{H264: results, Capture: captureResults, NVENC: nvencResult, NVENCD3D11: nvencD3D11Results, Nvidia: nvidiaSMI}
if err := enc.Encode(payload); err != nil {
if err := enc.Encode(report); err != nil {
fmt.Fprintf(os.Stderr, "json encode failed: %v\n", err)
os.Exit(1)
}
return
}
printMachine(machine)
printMFTFindings(findings, findingErr)
fmt.Println()
printTable(results)
if includeCapture {
fmt.Println()
@@ -102,6 +138,51 @@ func main() {
}
}
func writeJSONReport(path string, report smokeReport) error {
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
enc := json.NewEncoder(f)
enc.SetIndent("", " ")
return enc.Encode(report)
}
func printMachine(info machineInfo) {
fmt.Println("Machine:")
fmt.Printf(" Host: %s\n OS: %s (%s)\n CPU: %s\n GPU: %s\n RAM: %s\n Time: %s\n", info.Hostname, info.OS, info.Arch, info.CPU, info.GPU, info.RAM, info.GeneratedAt)
}
func printMFTFindings(findings []capture.H264MFTFinding, err error) {
fmt.Println("Media Foundation hardware H.264 findings:")
if err != nil {
fmt.Printf(" ERROR: %v\n", err)
return
}
if len(findings) == 0 {
fmt.Println(" No hardware H.264 MFTs found.")
return
}
for _, finding := range findings {
status := "ok"
if !finding.ActivationOK {
status = "failed"
}
mode := "sync"
if finding.Asynchronous {
mode = "async"
}
fmt.Printf(" [%d] %s | activation=%s | mode=%s | d3d11=%t\n", finding.Index, finding.Name, status, mode, finding.D3D11Aware)
if finding.HardwareURL != "" {
fmt.Printf(" device: %s\n", finding.HardwareURL)
}
if finding.Error != "" {
fmt.Printf(" error: %s\n", finding.Error)
}
}
}
func parseResolutions(raw string) []capture.H264SmokeResolution {
parts := parseStrings(raw)
out := make([]capture.H264SmokeResolution, 0, len(parts))
@@ -143,8 +224,8 @@ func parseStrings(raw string) []string {
}
func printTable(results []capture.H264SmokeResult) {
fmt.Printf("%-18s %-5s %9s %7s %7s %8s %9s %8s %7s %9s %9s %s\n",
"provider", "input", "size", "reqfps", "cfgfps", "config", "first_ms", "avg_ms", "frames", "avg_bytes", "total", "error")
fmt.Printf("%-28s %-5s %-5s %9s %7s %7s %8s %9s %8s %7s %9s %9s %s\n",
"provider", "mode", "input", "size", "reqfps", "cfgfps", "config", "first_ms", "avg_ms", "frames", "avg_bytes", "total", "error")
for _, r := range results {
status := "fail"
if r.ConfigureOK && r.EncodeOK {
@@ -152,8 +233,12 @@ func printTable(results []capture.H264SmokeResult) {
} else if r.ConfigureOK {
status = "no-data"
}
fmt.Printf("%-18s %-5s %4dx%-4d %7d %7d %8s %9.2f %8.2f %7d %9.0f %9d %s\n",
r.Provider, r.Input, r.Width, r.Height, r.RequestedFPS, r.ConfiguredFPS, status,
mode := "sync"
if r.Asynchronous {
mode = "async"
}
fmt.Printf("%-28s %-5s %-5s %4dx%-4d %7d %7d %8s %9.2f %8.2f %7d %9.0f %9d %s\n",
r.Provider, mode, r.Input, r.Width, r.Height, r.RequestedFPS, r.ConfiguredFPS, status,
r.FirstOutputMS, r.AvgEncodeMS, r.FramesTried, r.AvgBytes, r.TotalBytes, r.Error)
}
}