# Project export: Media transcode

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: MediaTranscode is a C++20 and FFmpeg-backed media transcode framework centered on the graph DAG architecture. The entire project is implemented using Codex.
- Devpost: https://devpost.com/software/media-transcode
- GitHub: https://github.com/tangmingcheng/MediaTranscode.git
- Video: https://www.youtube.com/embed/wgKpa7MGsrs?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — tangmingcheng (89 commits)

## Devpost submission (written by the team)

### Inspiration

During OpenAI Build Week, I wanted to explore the boundaries of AI-assisted software engineering in a highly technical and performance-critical domain. I have long been interested in media processing pipelines that power modern video platforms. At the same time, I was fascinated by Codex harness engineering — the systematic use of structured prompting, iteration, and validation to let AI models build complex systems. This led to the question: Can Codex, guided by a well-designed harness, create a media transcoding engine that meets or even exceeds industrial standards? The combination of deep media systems engineering and autonomous AI coding made this an exciting and ambitious experiment.

### What it does

The project is an AI-native media transcoding engine that converts and optimizes video and audio files. It supports: Format conversion (H.264, H.265, AV1, VP9, etc.) Resolution scaling and bitrate control Audio encoding and stream multiplexing Basic filtering and post-processing The engine aims to deliver high perceptual quality while maintaining strong performance characteristics, with the long-term goal of reaching or surpassing traditional industrial-grade transcoding solutions.

### How we built it

I built the entire project using Codex harness engineering, with zero manual code writing. The development followed a structured iterative loop: Defining project functionality, coding constraints, validation requirements, quality scoring criteria, and entropy/cleanup protocols via AGENTS.md. Establishing the project's overall framework via ARCHITECTURE.md. Tracking scores via QUALITY_SCORE.md, a critical component of the project's autonomous iteration loop. Assigning distinct sub-agents to handle planning, coding, and code reviews. Codex generated individual modules (parsers, encoders, pipelines, optimizers) in small, testable units. Automated tests and quality benchmarks were run, with failures fed back to Codex for refactoring. I performed only subjective human evaluation (visual and audio A/B testing) and provided feedback through the harness. This created a closed-loop system where the AI handled implementation and iteration, while I focused on direction and quality validation.

### Challenges we ran into

Zero manual coding constraint: Every line of code had to come from Codex, making debugging and optimization significantly harder. Context and codebase management: Maintaining coherence as the project grew required advanced prompt engineering and summarization. Performance optimization: Achieving low-level efficiency (memory layout, SIMD, GPU acceleration) through natural language guidance demanded many refinement cycles. Perceptual quality consistency: Ensuring output matched industry standards across edge cases relied heavily on repeated subjective testing. Long-term complexity: Building a truly competitive engine is a multi-month effort, not a one-week sprint.

### Accomplishments we're proud of

Successfully built a functional media transcoding engine without writing a single line of code manually. Established a reusable Codex harness framework for complex systems engineering. Through AI-driven iterative optimization, impressive results have been achieved in both local and real-time video transcoding. Demonstrated that AI can tackle deep technical domains when properly scaffolded.

### What we learned

The real skill in AI-assisted development shifts from writing code to designing excellent requirements, feedback loops, and evaluation systems. Media transcoding is an outstanding benchmark for AI coding capabilities due to its mix of algorithmic complexity and human-perceptible results. Disciplined, iterative prompting with strong validation is essential to prevent drift and maintain quality. Autonomous AI engineering shows tremendous potential but still requires thoughtful human oversight and patience.

### What's next

This is a long-term project. Future plans include: Expanding codec support and advanced features ( Multiple forms of hardware acceleration, adaptive streaming, AI-enhanced upscaling) Improving automation and self-optimization capabilities within the harness Rigorous benchmarking against industry leaders (FFmpeg, commercial encoders) Exploring distributed transcoding and cloud-native architectures Continuing to push the boundaries of what fully AI-generated systems can achieve in performance-critical software I’m excited to keep iterating and evolving this engine well beyond Build Week.

## README (from the GitHub repository)

# MediaTranscode

MediaTranscode is a C++20 and FFmpeg-backed media transcode framework centered on the graph DAG architecture.

The active code path is the graph runtime:

```text
src/internal/graph/        # graph model, planner, builder, runtime, and runtime nodes
tools/local_video_cli/     # local-file video transcode CLI
tools/realtime_video_cli/  # realtime video transcode CLI
include/media_transcode/
    Result.h               # shared Result<T> and ErrorInfo type
```

Only the graph architecture and `Result.h` are documented as active project surfaces.

## Build

Use the existing CMake flow:

```bash
cmake -S . -B out/build/x64-debug
cmake --build out/build/x64-debug --target media_transcode_core
cmake --build out/build/x64-debug --target media_transcode_local_video_cli
cmake --build out/build/x64-debug --target media_transcode_realtime_video_cli
```

Useful CMake options:

```text
MEDIA_TRANSCODE_BUILD_GRAPH_TOOLS=ON
```

## Realtime DAG Path

The realtime CLI accepts URL/RTSP, separate H.264/AAC RTP, or MPEG-TS/UDP input. Input clock selection and output protocol selection are independent; every A/V input reaches the same canonical scheduler before exactly one output adapter is assembled.

```text
URL/RTSP, separate RTP, or MPEG-TS/UDP input
    -> planner-owned input clock
    -> shared A/V startup, drift, recovery, and scheduler
    -> separate RTP | MPEG-TS/UDP | MPEG-TS/RTP
```

`--output-layout` and the mandatory `--output-transport` select one of three exact modes:

```text
--output-layout separate --output-transport rtp  per-media RTP/RTCP plus SDP
--output-layout mpegts  --output-transport udp  Project MPEG-TS in UDP datagrams
--output-layout mpegts  --output-transport rtp  Project MPEG-TS over RTP/AVP plus SDP
```

`separate + udp` is rejected. MPEG-TS/RTP uses the static MP2T payload type 33, a 90 kHz RTP clock, adjacent RTP/RTCP ports, and one generated SDP media description. Open separate dynamic-payload RTP through its generated SDP; open MPEG-TS/RTP through its production `rtp://@host:port` URL.

For visible MPEG-TS acceptance, VLC opens the production URL directly:

```powershell
& 'D:\VideoLAN\VLC\vlc.exe' 'rtp://@192.168.96.122:60000'
& 'D:\VideoLAN\VLC\vlc.exe' 'udp://@192.168.96.122:60000'
```

Do not insert FFmpeg, an observer remux, or SDP playback between the production
MPEG-TS output and VLC. Separate dynamic-payload RTP still writes SDP as the
signaling artifact selected by the caller, but it is not the MPEG-TS/RTP receiver
URL.

`--max-duration SECONDS` is optional realtime CLI monitoring policy. When it is
present, it must be positive and stops a still-running CLI after that duration.
When it is absent, startup output, progress, and lifecycle failures retain their
existing checks, but the CLI has no duration deadline and reports
`max_duration=source_driven`. This value is not planned or passed into the
media graph runtime.

Raw RTP input requires explicit video and audio endpoint metadata. For H.264 or HEVC video only, omitting `--video-rtp-fmtp` enables preflight in-band parameter-set detection. Codec, payload type, 90 kHz clock rate, URL, and all timeout/capacity limits remain mandatory. The planner derives canonical fmtp only after complete, unambiguous evidence; the runtime receives the same bound UDP transport and the original pre-read RTP/RTCP queue. Supplying video fmtp keeps strict manual mode and performs no probe I/O. AAC always requires explicit fmtp; Opus keeps its existing no-fmtp contract.

The following VideoOnly example demonstrates automatic H.264 fmtp detection.
Add `--video-rtp-fmtp` only when authoritative signaling is available and manual
mode is required:

```powershell
$inputRtp = @(
    '--input-type','rtp',
    '--video-rtp-url','rtp://127.0.0.1:5004',
    '--video-rtp-codec','h264','--video-rtp-payload-type','96',
    '--video-rtp-clock-rate','90000',
    '--open-timeout-ms','30000','--read-timeout-ms','2000',
    '--analyze-duration-us','5000000','--probe-size','5000000'
)
$common = @(
    '--egress-capacity-bps','50000000','--maximum-wire-residence-ms','100',
    '--video-codec','hevc','--rc','cbr',
    '--width','1920','--height','1080','--fps','25',
    '--bitrate','6000','--gop','50','--no-audio'
)
$cli = 'out/build/x64-release/media_transcode_realtime_video_cli.exe'

& $cli @inputRtp @common --media-id rtp-to-tsudp `
    --output-layout mpegts --output-transport udp `
    --output 'udp://127.0.0.1:5010'

& $cli @inputRtp @common --media-id rtp-to-tsrtp `
    --output-layout mpegts --output-transport rtp `
    --rtp-host 127.0.0.1 --rtp-port 5020 `
    --sdp out/build/x64-debug/rtp-to-tsrtp.sdp
```

Probe limits have exact meanings: `--open-timeout-ms` is the target deadline for controllable startup work, `--analyze-duration-us` is the maximum interval for obtaining complete unambiguous facts after the first matching RTP packet, `--probe-size` caps all bytes received during preflight, and `--read-timeout-ms` bounds each socket wait. Detection ends when the required parameter sets are complete; conflicts observed before completion fail. FFmpeg/driver capability calls are checked for deadline overrun immediately after return because those APIs are not cancellable. Timeout, wrong PT, incomplete/conflicting parameter sets, unsupported packetization, or capacity exhaustion fails preflight before the DAG starts.

Add `--max-duration SECONDS` only when the caller wants the explicit CLI stop
gate; do not use `0`, a sentinel, or a large replacement duration.

Hardware backend and realtime low-latency behavior are planner-owned and have no
caller override; the highest-scoring capability-admitted chain is selected or the
request fails before runtime. `--quiet-graph` only controls diagnostics.
`udp://host:port` remains valid for UDP-carried RTP input in RTP-port mode;
MPEG-TS input uses `--input-type mpegts-udp` and requires an explicit
`--mpegts-max-pcr-gap-ms`. URL input uses `--input-type url`; `rtsp://` URLs
require `--rtsp-transport`, while non-RTSP URLs reject it.

## Production acceptance

Project acceptance is based on the real local and realtime CLIs, real media streams,
FFmpeg/VLC observation, runtime memory metrics, and continuous A/V drift telemetry.
The current absolute-path PowerShell commands and evidence are recorded under
`docs/completed/`.

Input termination is strict: only a true FFmpeg EOF completes successfully.
HTTP, UDP, and RTP source disappearance returns one preserved source-loss
failure; coordinated cancellation of the remaining workers does not replace
that primary error. EOF drains codec state and all sinks before the realtime
CLI performs its normal stop path.


## Detected evidence (automated analysis)

Indexed codebase: 1443 recognized source files, 7320 KB.
- C (language) — detected in the code
- C++ (language) — detected in the code
- AI coding agent: Codex — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (120 of 1515)

```
.gitattributes
.gitignore
3rds/ffmpeg/BUILD_INFO
3rds/ffmpeg/CONTROL
3rds/ffmpeg/debug/lib/avcodec.lib
3rds/ffmpeg/debug/lib/avdevice.lib
3rds/ffmpeg/debug/lib/avfilter.lib
3rds/ffmpeg/debug/lib/avformat.lib
3rds/ffmpeg/debug/lib/avutil.lib
3rds/ffmpeg/debug/lib/pkgconfig/libavcodec.pc
3rds/ffmpeg/debug/lib/pkgconfig/libavdevice.pc
3rds/ffmpeg/debug/lib/pkgconfig/libavfilter.pc
3rds/ffmpeg/debug/lib/pkgconfig/libavformat.pc
3rds/ffmpeg/debug/lib/pkgconfig/libavutil.pc
3rds/ffmpeg/debug/lib/pkgconfig/libswresample.pc
3rds/ffmpeg/debug/lib/pkgconfig/libswscale.pc
3rds/ffmpeg/debug/lib/swresample.lib
3rds/ffmpeg/debug/lib/swscale.lib
3rds/ffmpeg/include/libavcodec/ac3_parser.h
3rds/ffmpeg/include/libavcodec/adts_parser.h
3rds/ffmpeg/include/libavcodec/avcodec.h
3rds/ffmpeg/include/libavcodec/avdct.h
3rds/ffmpeg/include/libavcodec/bsf.h
3rds/ffmpeg/include/libavcodec/codec_desc.h
3rds/ffmpeg/include/libavcodec/codec_id.h
3rds/ffmpeg/include/libavcodec/codec_par.h
3rds/ffmpeg/include/libavcodec/codec.h
3rds/ffmpeg/include/libavcodec/d3d11va.h
3rds/ffmpeg/include/libavcodec/defs.h
3rds/ffmpeg/include/libavcodec/dirac.h
3rds/ffmpeg/include/libavcodec/dv_profile.h
3rds/ffmpeg/include/libavcodec/dxva2.h
3rds/ffmpeg/include/libavcodec/jni.h
3rds/ffmpeg/include/libavcodec/mediacodec.h
3rds/ffmpeg/include/libavcodec/packet.h
3rds/ffmpeg/include/libavcodec/qsv.h
3rds/ffmpeg/include/libavcodec/vdpau.h
3rds/ffmpeg/include/libavcodec/version_major.h
3rds/ffmpeg/include/libavcodec/version.h
3rds/ffmpeg/include/libavcodec/videotoolbox.h
3rds/ffmpeg/include/libavcodec/vorbis_parser.h
3rds/ffmpeg/include/libavdevice/avdevice.h
3rds/ffmpeg/include/libavdevice/version_major.h
3rds/ffmpeg/include/libavdevice/version.h
3rds/ffmpeg/include/libavfilter/avfilter.h
3rds/ffmpeg/include/libavfilter/buffersink.h
3rds/ffmpeg/include/libavfilter/buffersrc.h
3rds/ffmpeg/include/libavfilter/version_major.h
3rds/ffmpeg/include/libavfilter/version.h
3rds/ffmpeg/include/libavformat/avformat.h
3rds/ffmpeg/include/libavformat/avio.h
3rds/ffmpeg/include/libavformat/version_major.h
3rds/ffmpeg/include/libavformat/version.h
3rds/ffmpeg/include/libavutil/adler32.h
3rds/ffmpeg/include/libavutil/aes_ctr.h
3rds/ffmpeg/include/libavutil/aes.h
3rds/ffmpeg/include/libavutil/ambient_viewing_environment.h
3rds/ffmpeg/include/libavutil/attributes.h
3rds/ffmpeg/include/libavutil/audio_fifo.h
3rds/ffmpeg/include/libavutil/avassert.h
3rds/ffmpeg/include/libavutil/avconfig.h
3rds/ffmpeg/include/libavutil/avstring.h
3rds/ffmpeg/include/libavutil/avutil.h
3rds/ffmpeg/include/libavutil/base64.h
3rds/ffmpeg/include/libavutil/blowfish.h
3rds/ffmpeg/include/libavutil/bprint.h
3rds/ffmpeg/include/libavutil/bswap.h
3rds/ffmpeg/include/libavutil/buffer.h
3rds/ffmpeg/include/libavutil/camellia.h
3rds/ffmpeg/include/libavutil/cast5.h
3rds/ffmpeg/include/libavutil/channel_layout.h
3rds/ffmpeg/include/libavutil/common.h
3rds/ffmpeg/include/libavutil/cpu.h
3rds/ffmpeg/include/libavutil/crc.h
3rds/ffmpeg/include/libavutil/csp.h
3rds/ffmpeg/include/libavutil/des.h
3rds/ffmpeg/include/libavutil/detection_bbox.h
3rds/ffmpeg/include/libavutil/dict.h
3rds/ffmpeg/include/libavutil/display.h
3rds/ffmpeg/include/libavutil/dovi_meta.h
3rds/ffmpeg/include/libavutil/downmix_info.h
3rds/ffmpeg/include/libavutil/encryption_info.h
3rds/ffmpeg/include/libavutil/error.h
3rds/ffmpeg/include/libavutil/eval.h
3rds/ffmpeg/include/libavutil/executor.h
3rds/ffmpeg/include/libavutil/ffversion.h
3rds/ffmpeg/include/libavutil/fifo.h
3rds/ffmpeg/include/libavutil/file.h
3rds/ffmpeg/include/libavutil/film_grain_params.h
3rds/ffmpeg/include/libavutil/frame.h
3rds/ffmpeg/include/libavutil/hash.h
3rds/ffmpeg/include/libavutil/hdr_dynamic_metadata.h
3rds/ffmpeg/include/libavutil/hdr_dynamic_vivid_metadata.h
3rds/ffmpeg/include/libavutil/hmac.h
3rds/ffmpeg/include/libavutil/hwcontext_cuda.h
3rds/ffmpeg/include/libavutil/hwcontext_d3d11va.h
3rds/ffmpeg/include/libavutil/hwcontext_d3d12va.h
3rds/ffmpeg/include/libavutil/hwcontext_drm.h
3rds/ffmpeg/include/libavutil/hwcontext_dxva2.h
3rds/ffmpeg/include/libavutil/hwcontext_mediacodec.h
3rds/ffmpeg/include/libavutil/hwcontext_opencl.h
3rds/ffmpeg/include/libavutil/hwcontext_qsv.h
3rds/ffmpeg/include/libavutil/hwcontext_vaapi.h
3rds/ffmpeg/include/libavutil/hwcontext_vdpau.h
3rds/ffmpeg/include/libavutil/hwcontext_videotoolbox.h
3rds/ffmpeg/include/libavutil/hwcontext_vulkan.h
3rds/ffmpeg/include/libavutil/hwcontext.h
3rds/ffmpeg/include/libavutil/iamf.h
3rds/ffmpeg/include/libavutil/imgutils.h
3rds/ffmpeg/include/libavutil/intfloat.h
3rds/ffmpeg/include/libavutil/intreadwrite.h
3rds/ffmpeg/include/libavutil/lfg.h
3rds/ffmpeg/include/libavutil/log.h
3rds/ffmpeg/include/libavutil/lzo.h
3rds/ffmpeg/include/libavutil/macros.h
3rds/ffmpeg/include/libavutil/mastering_display_metadata.h
3rds/ffmpeg/include/libavutil/mathematics.h
3rds/ffmpeg/include/libavutil/md5.h
3rds/ffmpeg/include/libavutil/mem.h
3rds/ffmpeg/include/libavutil/motion_vector.h
[1395 more files omitted for size]
```

### Dependencies

No dependency index available.

### Recent commits (newest first)

- Merge pull request #30 from tangmingcheng/codex/realtime-video-only-stream-set
- docs: refresh final quality score scope
- fix(realtime): close final review boundaries
- fix(realtime): enforce prepared input boundaries
- docs(realtime): record video-only acceptance
- Merge remote-tracking branch 'origin/codex/realtime-video-only-stream-set' into codex/realtime-video-only-stream-set
- fix(realtime): preserve prepared rtsp timestamp lineage
- fix(realtime): preserve prepared rtsp timestamp lineage
- fix(realtime): preserve video-only startup lineage
- fix(avsync): require explicit media identity
- fix(realtime): keep video runtime facts planner-owned
- fix(realtime): honor planned demux startup skew
- fix(graph): classify transient backpressure diagnostics
- fix(rtp): separate receive interruption from lifecycle stop
- fix(rtp): cancel raw input reads on peer failure
- fix(realtime): honor explicit queue capacities
- fix(realtime): enforce raw RTP clock liveness
- fix(realtime): decouple av activation from rtp ntp
- fix(realtime): seal av output authority identity
- fix(realtime): preserve video-only mpegts queue contracts

## Key source files (fetched from GitHub, selected and truncated for size)

### AGENTS.md

```markdown
## 项目介绍

本项目是一个基于 C++20 和 FFmpeg 的媒体转码框架。

项目目标是通过模块化的媒体处理能力，支持文件转码、音视频处理、硬件能力适配以及 DAG 化的媒体处理管线。架构说明放在 `ARCHITECTURE.md`。
具体任务计划应在需要时单独写入 `plan.md`。完成计划中对应计划点时更新计划完成文档，路径放在docs/中

当前核心代码主要位于：

```text
src/internal/graph
```

该目录承载媒体处理图相关能力，包括图模型、策略规划、图构建、运行时调度和具体运行时节点。


## 编码原则

修改本仓库代码时应遵守以下原则：

1. 优先基于当前仓库代码证据进行判断，不要依赖记忆或未经确认的假设。
2. 保持模块职责清晰，避免把策略选择、拓扑构建、运行时执行和节点行为混在一起。
3. 公共逻辑应抽取到公共 helper、可复用组件或明确职责的类中。
4. 不要做补丁式，兼容性修改
5. 只有planner才有决策权，下游节点不可以fallback，或者代码中存在硬编码,默认参数，所有参数都应由上游节点传入，如缺少参数应报错，planner应当在构建阶段就发现问题。
6. 不要复制已有逻辑；能复用已有 builder、segment、helper 或 runtime 组件时优先复用。
7. 需要RAII管理的部分纳入管理
8. 不要存在语义相近，功能相似的方法
9. 不要为了让代码“看起来通过”而隐藏错误、绕过校验或降低约束。
10. 新增枚举值时应保持已有枚举值稳定，除非明确确认可以破坏兼容性。
11. 代码修改应尽量小而聚焦，不要顺手重写无关模块。
12. 文档应简短、准确、可维护，不要写成冗长手册。
13. 不要声称构建、测试或验证通过，除非对应命令确实运行成功。
14. tools中要按能力新增，不要混用，例如本地视频转码工具，实时视频转码工具要独立分开

## 验证要求

完成修改前，应运行当前环境下最强可用验证。

生产核心修改必须由真实 CLI、真实媒体流和生产 DAG 的失败证据驱动。仓库不保留 CI、CTest、unit、integration、acceptance、hardware 或 performance 测试体系，不得新增、恢复或为了自动化测试适配生产核心。必要时允许新增仅供本地验证的临时测试，但不得纳入版本库；核心代码修改完成后必须删除，并确认工作树中没有临时测试残留。

唯一验收标准是 local CLI、realtime CLI 的真实媒体链路、FFmpeg/VLC 进程与画面观察、运行时内部数据、内存趋势和持续 A/V 漂移 telemetry。自动化测试不能替代真实 CLI 验收。

Visual Studio2026 位于D:\VisualStudio2026

ffmpeg相关工具位于D:\mabs\local64\bin-video
VLC播放器位于D:\VideoLAN\VLC\vlc.exe
本地连续120秒验收视频源：D:\Code\MyCode\MediaTranscode\out\acceptance\test-continuous-120s.mp4
后续真实流测试必须统一使用该120秒连续源，禁止使用短视频配合`-stream_loop`进行实时循环，避免循环读取停顿被误判为生产链路时钟错误。
验收完成报告需要包含真实 CLI/FFmpeg/VLC 执行命令和结果，无需包含构建编译命令

优先使用已有 CMake 构建目录：

```bash
out/build/x64-debug
out/build/x64-release
```

如果这些构建目录不存在，应使用仓库现有 CMake 流程进行配置，编译构建时必须选择全部重新生成。
不要为了验证临时发明新的构建系统。

测试时不要写任何测试脚本，要使用单一的绝对路径命令，ffmpeg产生源流，CLI转码，vlc播放，不要添加任何ffmpeg监控破坏该链路，无特殊要求不要使用disable hw,不要使用max duration，要源流驱动，停止时，停止源流，不要停止cli，每次开启测试时需要贴出测试命令，并且需要在后台监控cli的cpu占用率，内存增长，A/V漂移，以及退出原因

## 质量评分
以工业级DAG架构媒体转码引擎为标准，设定完整评分体系，由子Agent对当前代码review后，按照标准，准条发起评分，并保留评分体系与对应分数，生成/更新 QUALITY_SCORE.md，位置与ARCHITECTURE.md同级，这将是以后演进的重要依据，需要更新  注意：评分文档需要简洁，清晰，不要冗长

## 熵与垃圾清理
当用户明确要求熵与垃圾清理时，需要agent开始对代码进行review，重点审查以下几点：
1.graph内部中不要有补丁式代码
2.只有planner有决策权，所有下游节点需要的参数都要从上游节点获得，如果获得不到，直接报错，不允许存在任何默认值以及fallback
3.节点要职责单一，充分解耦
4。需要RAII管理的部分是否都已纳入管理
5.graph内部单个cpp不要过度膨胀
7.不要存在语义相近，功能相似的方法
8.是否存在不必要的拷贝，导致cpu升高
6.修改需要符合工业级DAG架构标准
如有发现，则需由子agent修改，修改结束后由负责review的agent进行review，直至判定通过，清理干净

```

### QUALITY_SCORE.md

```markdown
# MediaTranscode Quality Score

> Scope: `codex/realtime-video-only-stream-set`, `master...5c7f362c`. Updated 2026-08-12.

## Scoring Rubric

| Dimension | Max | Score | Current evidence |
|---|---:|---:|---|
| Architecture responsibilities | 9 | 8 | Model, planner, builder, protocol, node and runtime-validation layers remain distinct; the branch is nevertheless broad at exactly 250 changed files. |
| Typed plans and contracts | 8 | 8 | Explicit stream-set and runtime variants model VideoOnly/A-V input, startup, scheduling, MPEG-TS program and output paths; prepared RTSP evidence and provenance are typed. |
| Planner authority | 8 | 8 | Stream selection, timing, capacities, protocol identity, prepared ownership and handoff limits are planned and fail closed; runtime consumers require exact materialized facts. |
| DAG shape and compilation | 8 | 8 | VideoOnly validation enforces exact nodes, ports, edges, PID/PES/SDP cardinality and legacy-node absence; A/V and video runtime variants compile separately. |
| Runtime scheduling | 8 | 8 | VideoOnly has one paced scheduler and shared protocol-output authority; A/V keeps the canonical scheduler, with exact queue budgets and source-clock liveness. |
| A/V synchronization | 8 | 8 | Prepared RTSP selects a bounded common timestamp window and preserves packet provenance; all counted A/V routes completed without recovery, discontinuity, duplicate or production drop. |
| Protocol outputs | 8 | 7 | Separate RTP, MPEG-TS/UDP and PT 33 MP2T RTP produce exact VideoOnly/A-V stream sets. Nine real RTSP/TCP routes prove publisher and reader signaling; VLC still reports route-dependent receiver warnings. |
| Concurrency, lifecycle and RAII | 8 | 7 | Prepared transports and generic RTSP capture use move-only ownership, bounded replay, interrupt restoration and joined workers; final PID and port residue is zero. Reconnect/replacement concurrency is not exercised. |
| Error semantics | 7 | 6 | Planning rejects missing, conflicting and undersized facts; runtime distinguishes clean drain, clock loss, cancellation and transient pressure. Fatal cancellation may intentionally purge bounded in-flight items. |
| Performance and memory | 7 | 6 | Explicit packet/byte bounds prevent silent growth; typical CLI working set is about 185-221 MiB with bounded CUDA startup transients, but no multi-hour soak or throughput envelope is established. |
| Observability | 5 | 4 | Runtime reports expose queues, workers, errors, drops, CPU, memory and drift. Evidence is detailed but remains distributed across local route directories rather than one machine-readable aggregate. |
| Real-media verification | 7 | 7 | The canonical 120-second source passed all 56 formal chains: local 2, MPEG-TS/UDP input 9, raw RTP 36 and real RTSP/TCP wire 9, with VLC frames, exact drains and zero residue. |
| Maintainability and documentation | 9 | 7 | Architecture, execution plan and concise completion evidence now describe the final topology and 56/56 matrix. T
[truncated — 2539 more characters]
```

### tools/common/VideoCliTranscodeOptions.h

```c
#pragma once

#include "GraphCliSupport.h"

#include "internal/graph/model/MediaTranscodeParameters.h"

namespace media::ffmpeg::graph::cli {

inline void parseCommonVideoTranscodeOptions(int argc, char** argv, MediaTranscodeParameterSet& parameters)
{
    parameters.execution.streamSet = hasArg(argc, argv, "--no-audio")
        ? MediaTranscodeStreamSet::VideoOnly
        : MediaTranscodeStreamSet::AudioVideo;
    parameters.execution.disableHardware = disabledByExplicitArg(argc, argv, "--disable-hw", "hardware planning");
    parameters.execution.diagnosticLogEnabled = !hasArg(argc, argv, "--quiet-graph");
    parameters.queues.metadata = requiredSizeArg(argc, argv, "--metadata-queue");
    parameters.queues.packet = requiredSizeArg(argc, argv, "--packet-queue");
    parameters.queues.frame = requiredSizeArg(argc, argv, "--frame-queue");
    parameters.queues.mux = requiredSizeArg(argc, argv, "--mux-queue");

    parameters.video.codecName = argValue(argc, argv, "--video-codec");
    parameters.video.rateControl = rateControlArg(argc, argv, "--rc");
    parameters.video.preset = argValue(argc, argv, "--preset");
    parameters.video.profile = argValue(argc, argv, "--profile");
    parameters.video.tune = argValue(argc, argv, "--tune");
    parameters.video.level = argValue(argc, argv, "--level");
    parameters.video.width = optionalIntArg(argc, argv, "--width");
    parameters.video.height = optionalIntArg(argc, argv, "--height");
    if (auto fps = optionalIntArg(argc, argv, "--fps")) {
        parameters.video.frameRate.numerator = fps;
        parameters.video.frameRate.denominator = 1;
    }
    parameters.video.bitrateKbps = optionalIntArg(argc, argv, "--bitrate");
    parameters.video.minBitrateKbps = optionalIntArg(argc, argv, "--min-bitrate");
    parameters.video.maxBitrateKbps = optionalIntArg(argc, argv, "--max-bitrate");
    parameters.video.bufferSizeKbits = optionalIntArg(argc, argv, "--buffer-size");
    parameters.video.quality = optionalIntArg(argc, argv, "--quality");
    parameters.video.gop = optionalIntArg(argc, argv, "--gop");

    parameters.audio.codecName = argValue(argc, argv, "--audio-codec");
    parameters.audio.rateControl = rateControlArg(argc, argv, "--audio-rc");
    parameters.audio.bitrateKbps = optionalIntArg(argc, argv, "--audio-bitrate");
    parameters.audio.minBitrateKbps = optionalIntArg(argc, argv, "--audio-min-bitrate");
    parameters.audio.maxBitrateKbps = optionalIntArg(argc, argv, "--audio-max-bitrate");
    parameters.audio.bufferSizeKbits = optionalIntArg(argc, argv, "--audio-buffer-size");
    parameters.audio.sampleRate = optionalIntArg(argc, argv, "--sample-rate");
    parameters.audio.channels = optionalIntArg(argc, argv, "--channels");
    parameters.audio.quality = optionalIntArg(argc, argv, "--audio-quality");
    parameters.audio.preset = argValue(argc, argv, "--audio-preset");
    parameters.audio.profile = argValue(argc, argv, "--audio-profile");
}

inline std::vector<std::string> commonVideoTranscodeValueArgs()
{
    return {
        "--metadata-queue",
        "--packet-queue",
        "--frame-queue",
        "--mux-queue",
        "--video-codec",
        "--rc",
        "--preset",
        "--profile",
        "--tune",
        "--level",
        "--width",
        "--height",
        "--fps",
        "--bitrate",
        "--min-bitrate",
        "--max-bitrate",
        "--buffer-size",
        "--quality",
        "--gop",
        "--audio-codec",
        "--audio-rc",
        "--audio-bitrate",
        "--audio-min-bitrate",
        "--audio-max-bitrate",
        "--audio-buffer-size",
        "--sample-rate",
        "--channels",
        "--audio-quality",
        "--audio-preset",
        "--audio-profile",
    };
}

inline std::vector<std::string> commonVideoTranscodeFlagArgs()
{
    return {
        "--help",
        "-h",
        "--no-audio",
        "--disable-hw",
        "--quiet-graph",
    };
}

} // namespace media::ffmpeg::graph::cli

```

### tools/local_video_cli/main.cpp

```c++
#include "internal/graph/builder/local/LocalFileTranscodeGraphBuilder.h"
#include "internal/graph/runtime/MediaGraphRuntime.h"
#include "internal/graph/runtime/diagnostics/MediaGraphRuntimeReport.h"
#include "internal/graph/utils/MediaUrlUtils.h"
#include "../common/GraphCliSupport.h"
#include "../common/VideoCliTranscodeOptions.h"

#include <exception>
#include <iostream>
#include <optional>
#include <string>
#include <utility>

using namespace media::ffmpeg::graph;
using namespace media::ffmpeg::graph::cli;

namespace {

std::string optionalIntText(const std::optional<int>& value)
{
    return value ? std::to_string(*value) : std::string("source");
}

std::string frameRateText(const MediaFrameRateParameters& frameRate)
{
    if (!frameRate.numerator) {
        return "source";
    }
    return std::to_string(*frameRate.numerator) + "/" + std::to_string(frameRate.denominator.value_or(1));
}

void rejectUnknownLocalArgs(int argc, char** argv)
{
    std::vector<std::string> valueArgs = commonVideoTranscodeValueArgs();
    valueArgs.push_back("--input");
    valueArgs.push_back("--output");

    rejectUnknownArgs(argc,
                      argv,
                      valueArgs,
                      commonVideoTranscodeFlagArgs());
}

LocalFileTranscodeOptions parseOptions(int argc, char** argv)
{
    rejectUnknownLocalArgs(argc, argv);

    LocalFileTranscodeOptions options;
    options.inputUrl = requiredArg(argc, argv, "--input");
    options.outputUrl = requiredArg(argc, argv, "--output");
    parseCommonVideoTranscodeOptions(argc, argv, options.parameters);
    return options;
}

int runLocalVideoCli(int argc, char** argv)
{
    const bool helpRequested = hasArg(argc, argv, "--help") || hasArg(argc, argv, "-h");
    if (argc < 5 || helpRequested) {
        std::cout << "Usage: media_transcode_local_video_cli --input in.mp4 --output out.mp4 --metadata-queue 1 --packet-queue 256 --frame-queue 128 --mux-queue 256 [options]\n";
        return helpRequested ? 0 : 2;
    }

    LocalFileTranscodeOptions options = parseOptions(argc, argv);
    const MediaTranscodeParameterSet& parameters = options.parameters;
    std::cout << "[CLI] input=" << redactUrlUserInfo(options.inputUrl)
              << " output=" << options.outputUrl
              << " audio="
              << (parameters.execution.streamSet == MediaTranscodeStreamSet::AudioVideo
                      ? "on"
                      : "off")
              << " width=" << optionalIntText(parameters.video.width)
              << " height=" << optionalIntText(parameters.video.height)
              << " fps=" << frameRateText(parameters.video.frameRate)
              << " bitrate_kbps=" << optionalIntText(parameters.video.bitrateKbps)
              << " rc=" << mediaRateControlModeName(parameters.video.rateControl)
              << " hw=" << (parameters.execution.disableHardware ? "disabled" : "auto")
              << " diagnostics=" << (parameters.execution.diagnosticLogEnabled ? "on" : "off")
              << '\n';

    auto graphResult = LocalFileTranscodeGraphBuilder::build(options);
    if (!graphResult) {
        return failResult("local video graph build", graphResult);
    }

    MediaGraphRuntime runtime;
    runtime.setDiagnosticsEnabled(parameters.execution.diagnosticLogEnabled);
    auto compileStatus = runtime.compile(std::move(graphResult).value());
    if (!compileStatus) {
        return failStatus("compile local video graph", compileStatus);
    }
    auto registerStatus = runtime.registerDefaultRuntimeNodes();
    if (!registerStatus) {
        return failStatus("register local video runtime nodes", registerStatus);
    }
    auto runResult = runtime.run();
    if (!runResult) {
        return failResult("run local video graph", runResult);
    }

    const auto& result = runResult.value();
    const MediaGraphRuntimeReport report = MediaGraphRuntimeReporter::capture(runtime);
    std::cout << "[CLI] final " << report.summary() << '\n';
    std::cout << "[CLI] done: iterations=" << result.iterations
              << " total_pushed=" << result.totalPushed
              << " total_popped=" << result.totalPopped
              << " completed=" << (result.completed ? "true" : "false")
              << '\n';
    return result.completed ? 0 : 1;
}

} // namespace

int main(int argc, char** argv)
{
    try {
        return runLocalVideoCli(argc, argv);
    } catch (const std::exception& e) {
        std::cerr << "[CLI] fatal exception: " << e.what() << '\n';
        return 2;
    } catch (...) {
        std::cerr << "[CLI] fatal unknown exception\n";
        return 2;
    }
}

```

### include/media_transcode/Result.h

```c
#pragma once

#include <optional>
#include <string>
#include <type_traits>
#include <utility>

namespace media {

/**
 * @brief Stable error category returned by the public MediaTranscode API.
 *
 * The value is intentionally independent from FFmpeg's negative error codes.
 * When the failure comes from FFmpeg, nativeCode may still contain the original
 * FFmpeg return value so callers can log or map it if needed.
 */
enum class ErrorCode {
    None = 0,
    InvalidArgument,
    NotInitialized,
    AllocationFailed,
    Unsupported,
    FFmpegFailure,
    IoFailure,
    HardwareUnavailable,
    InternalError,
    Cancelled,
    WouldBlock
};

/**
 * @brief Convert an ErrorCode to a stable, non-localized string.
 */
inline const char* errorCodeName(ErrorCode code) noexcept
{
    switch (code) {
    case ErrorCode::None: return "None";
    case ErrorCode::InvalidArgument: return "InvalidArgument";
    case ErrorCode::NotInitialized: return "NotInitialized";
    case ErrorCode::AllocationFailed: return "AllocationFailed";
    case ErrorCode::Unsupported: return "Unsupported";
    case ErrorCode::FFmpegFailure: return "FFmpegFailure";
    case ErrorCode::IoFailure: return "IoFailure";
    case ErrorCode::HardwareUnavailable: return "HardwareUnavailable";
    case ErrorCode::WouldBlock: return "WouldBlock";
    case ErrorCode::InternalError: return "InternalError";
    case ErrorCode::Cancelled: return "Cancelled";
    default: return "Unknown";
    }
}

/**
 * @brief Error payload used by Status and Result<T>.
 *
 * message is intended for logs and diagnostics. It is not localized and should
 * not be parsed by business code. Business code should branch on code.
 */
struct ErrorInfo {
    ErrorCode code = ErrorCode::None;
    int nativeCode = 0;
    std::string message;

    bool ok() const noexcept
    {
        return code == ErrorCode::None;
    }

    explicit operator bool() const noexcept
    {
        return !ok();
    }

    std::string describe() const
    {
        if (ok()) {
            return "ok";
        }

        std::string text = std::string(errorCodeName(code)) + ": " + message;
        if (nativeCode != 0) {
            text += " (native=" + std::to_string(nativeCode) + ")";
        }
        return text;
    }

    static ErrorInfo success()
    {
        return {};
    }

    static ErrorInfo make(ErrorCode code,
                          std::string message,
                          int nativeCode = 0)
    {
        return ErrorInfo{ code, nativeCode, std::move(message) };
    }

    static ErrorInfo invalidArgument(std::string message)
    {
        return make(ErrorCode::InvalidArgument, std::move(message));
    }

    static ErrorInfo notInitialized(std::string message)
    {
        return make(ErrorCode::NotInitialized, std::move(message));
    }

    static ErrorInfo allocationFailed(std::string message)
    {
        return make(ErrorCode::AllocationFailed, std::move(message));
    }

    static ErrorInfo unsupported(std::string message)
    {
        return make(ErrorCode::Unsupported, std::move(message));
    }

    static ErrorInfo ffmpegFailure(std::string message, int nativeCode = 0)
    {
        return make(ErrorCode::FFmpegFailure, std::move(message), nativeCode);
    }

    static ErrorInfo ioFailure(std::string message, int nativeCode = 0)
    {
        return make(ErrorCode::IoFailure, std::move(message), nativeCode);
    }

    static ErrorInfo hardwareUnavailable(std::string message)
    {
        return make(ErrorCode::HardwareUnavailable, std::move(message));
    }

    static ErrorInfo wouldBlock(std::string message)
    {
        return make(ErrorCode::WouldBlock, std::move(message));
    }

    static ErrorInfo internalError(std::string message)
    {
        return make(ErrorCode::InternalError, std::move(message));
    }

    static ErrorInfo cancelled(std::string message)
    {
        return make(ErrorCode::Cancelled, std::move(message));
    }
};

/**
 * @brief Lightweight expected-like return type.
 *
 * Result<T, E> owns either a T value or an E error. ErrorInfo remains the
 * default error type. It does not throw exceptions. Always check ok() or use
 * the explicit bool operator before calling value() or error().
 */
template <typename T, typename E = ErrorInfo>
class Result {
public:
    static Result success(T value)
    {
        return Result(ValueTag{}, std::move(value));
    }

    static Result failure(E error)
    {
        if constexpr (std::is_same_v<E, ErrorInfo>) {
            if (error.ok()) {
                error = ErrorInfo::internalError("unknown error");
            }
        }
        return Result(ErrorTag{}, std::move(error));
    }

    bool ok() const noexcept
    {
        return m_value.has_value();
    }

    explicit operator bool() const noexcept
    {
        return ok();
    }

    T& value() &
    {
        return *m_value;
    }

    const T& value() const&
    {
        return *m_value;
    }

    T&& value() &&
    {
        return std::move(*m_value);
    }

    const E& error() const noexcept
    {
        return *m_error;
    }

    T valueOr(T fallback) const
    {
        return m_value ? *m_value : std::move(fallback);
    }

private:
    struct ValueTag {};
    struct ErrorTag {};

    Result(ValueTag, T value)
        : m_value(std::move(value))
    {
        if constexpr (std::is_same_v<E, ErrorInfo>) {
            m_error.emplace();
        }
    }

    Result(ErrorTag, E error)
        : m_error(std::move(error))
    {
    }

private:
    std::optional<T> m_value;
    std::optional<E> m_error;
};

/**
 * @brief Result specialization for operations that only need success/failure.
 */
template <typename E>
class Result<void, E> {
public:
    static Result success()
    {
        return Result();
    }

    static Result failure(E error)
    {
        if constexpr (std::is_same_v<E, ErrorInfo>) {
            if (error.ok()) {
                error = ErrorInfo::internalError("unknown error");
 
[truncated — 631 more characters]
```

### tools/common/GraphCliSupport.h

```c
#pragma once

#include "internal/graph/core/MediaGraph.h"
#include "internal/graph/model/MediaNodeKind.h"
#include "internal/graph/model/MediaTranscodeParameters.h"
#include "internal/graph/nodes/MediaRequiredNodeOptions.h"
#include "media_transcode/Result.h"

#include <iostream>
#include <optional>
#include <stdexcept>
#include <string>
#include <vector>

namespace media::ffmpeg::graph::cli {

inline std::string argValue(int argc, char** argv, const std::string& key)
{
    for (int i = 1; i + 1 < argc; ++i) {
        if (std::string(argv[i]) == key) {
            return argv[i + 1];
        }
    }
    return {};
}

inline std::string argValue(int argc, char** argv, const std::string& key, const std::string& missingValue)
{
    const std::string value = argValue(argc, argv, key);
    return value.empty() ? missingValue : value;
}

inline bool hasArg(int argc, char** argv, const std::string& key)
{
    for (int i = 1; i < argc; ++i) {
        if (std::string(argv[i]) == key) {
            return true;
        }
    }
    return false;
}

inline bool containsKey(const std::vector<std::string>& keys, const std::string& key)
{
    for (const std::string& candidate : keys) {
        if (candidate == key) {
            return true;
        }
    }
    return false;
}

inline void rejectUnknownArgs(int argc,
                              char** argv,
                              const std::vector<std::string>& valueArgs,
                              const std::vector<std::string>& flagArgs)
{
    for (int i = 1; i < argc; ++i) {
        const std::string key = argv[i];
        if (key.rfind("--", 0) != 0) {
            continue;
        }
        if (containsKey(valueArgs, key)) {
            if (i + 1 >= argc || std::string(argv[i + 1]).rfind("--", 0) == 0) {
                throw std::invalid_argument("missing value for argument: " + key);
            }
            ++i;
            continue;
        }
        if (containsKey(flagArgs, key)) {
            continue;
        }
        throw std::invalid_argument("unsupported argument: " + key);
    }
}

inline std::optional<int> optionalIntArg(int argc, char** argv, const std::string& key)
{
    const std::string value = argValue(argc, argv, key);
    if (value.empty()) {
        return std::nullopt;
    }

    std::size_t parsed = 0;
    const int result = std::stoi(value, &parsed, 10);
    if (parsed != value.size()) {
        throw std::invalid_argument("invalid integer value for " + key + ": " + value);
    }
    return result;
}

inline int requiredIntArg(int argc, char** argv, const std::string& key)
{
    auto value = optionalIntArg(argc, argv, key);
    if (!value) {
        throw std::invalid_argument("missing required integer argument: " + key);
    }
    return *value;
}

inline std::size_t requiredSizeArg(int argc, char** argv, const std::string& key)
{
    const int value = requiredIntArg(argc, argv, key);
    if (value <= 0) {
        throw std::invalid_argument(key + " must be positive");
    }
    return static_cast<std::size_t>(value);
}

inline std::string requiredArg(int argc, char** argv, const std::string& key)
{
    const std::string value = argValue(argc, argv, key);
    if (value.empty()) {
        throw std::invalid_argument("missing required argument: " + key);
    }
    return value;
}

inline bool requiredExclusiveBoolArg(int argc,
                                     char** argv,
                                     const std::string& trueKey,
                                     const std::string& falseKey)
{
    const bool trueArg = hasArg(argc, argv, trueKey);
    const bool falseArg = hasArg(argc, argv, falseKey);
    if (trueArg == falseArg) {
        throw std::invalid_argument("specify exactly one of " + trueKey + " or " + falseKey);
    }
    return trueArg;
}

inline bool disabledByExplicitArg(int argc,
                                  char** argv,
                                  const std::string& disableKey,
                                  const std::string& settingName)
{
    if (hasArg(argc, argv, disableKey)) {
        return true;
    }
    (void)settingName;
    return false;
}

inline MediaRateControlMode requiredRateControlArg(int argc, char** argv, const std::string& key)
{
    const std::string value = requiredArg(argc, argv, key);
    MediaRateControlMode mode = MediaRateControlMode::Auto;
    if (!parseMediaRateControlMode(value, mode)) {
        throw std::invalid_argument("unsupported rate control mode for " + key + ": " + value);
    }
    return mode;
}

inline MediaRateControlMode rateControlArg(int argc, char** argv, const std::string& key)
{
    MediaRateControlMode mode = MediaRateControlMode::Auto;
    const std::string value = argValue(argc, argv, key);
    if (!parseMediaRateControlMode(value, mode)) {
        throw std::invalid_argument("unsupported rate control mode for " + key + ": " + value);
    }
    return mode;
}

inline int failStatus(const char* action, const ::media::Status& status)
{
    std::cerr << "[CLI] " << action << " failed: " << status.error().describe() << '\n';
    return 1;
}

template <typename T>
int failResult(const char* action, const ::media::Result<T>& result)
{
    std::cerr << "[CLI] " << action << " failed: " << result.error().describe() << '\n';
    return 1;
}

inline const MediaNode* findNodeByKind(const MediaGraph& graph, MediaNodeKind kind)
{
    for (const MediaNode& node : graph.nodes()) {
        if (node.kind == kind) {
            return &node;
        }
    }
    return nullptr;
}

inline ::media::Status printRealtimePlanSummary(const MediaGraph& graph)
{
    const MediaNode* encoder = findNodeByKind(graph, MediaNodeKind::VideoEncode);
    if (!encoder) {
        return ::media::Status::failure(
            ::media::ErrorInfo::invalidArgument("realtime graph plan summary requires VideoEncode node"));
    }

    auto chain = requiredNodeOption(&encoder->options, "graph CLI realtime plan summary", "pipeline.chain");
    if (!chain) {
  
[truncated — 1665 more characters]
```

### tools/realtime_video_cli/main.cpp

```c++
#include "internal/graph/builder/realtime/MediaRealtimeRtpTranscodeGraphBuilder.h"
#include "internal/graph/planner/realtime/MediaRealtimeRtpTranscodePlanner.h"
#include "internal/graph/runtime/MediaGraphRuntime.h"
#include "internal/graph/runtime/diagnostics/MediaGraphRuntimeReport.h"
#include "internal/graph/runtime/lifecycle/MediaRealtimeProgressTracker.h"
#include "internal/graph/runtime/lifecycle/MediaRealtimeRuntimeCompletion.h"
#include "internal/graph/utils/MediaUrlUtils.h"
#include "../common/GraphCliSupport.h"
#include "../common/VideoCliTranscodeOptions.h"

#include <algorithm>
#include <chrono>
#include <exception>
#include <iostream>
#include <optional>
#include <stdexcept>
#include <string>
#include <thread>
#include <utility>
#include <variant>
#include <vector>

#if defined(_MSC_VER) && defined(_DEBUG)
#include <crtdbg.h>
#endif

using namespace media::ffmpeg::graph;
using namespace media::ffmpeg::graph::cli;

namespace {

struct RealtimeVideoRuntimeOptions {
    std::optional<int> maxDurationSeconds;
    int progressTimeoutMs = 5000;
    int firstOutputTimeoutMs = 30000;
    int pollIntervalMs = 250;
};

RealtimeInputType requiredRealtimeInputType(int argc, char** argv)
{
    const std::string value = requiredArg(argc, argv, "--input-type");
    if (value == "rtsp") {
        return RealtimeInputType::Url;
    }
    if (value == "rtp") {
        return RealtimeInputType::RtpPort;
    }
    if (value == "mpegts-udp") {
        return RealtimeInputType::MpegTsUdp;
    }
    throw std::invalid_argument("unsupported --input-type: " + value);
}

RealtimeInputStreamLayout requiredRealtimeInputLayout(int argc, char** argv)
{
    const std::string value = requiredArg(argc, argv, "--input-layout");
    if (value == "session") {
        return RealtimeInputStreamLayout::SessionDescribed;
    }
    if (value == "separate") {
        return RealtimeInputStreamLayout::SeparateStreams;
    }
    if (value == "mpegts") {
        return RealtimeInputStreamLayout::MuxedTransportStream;
    }
    throw std::invalid_argument("unsupported --input-layout: " + value);
}

RealtimeOutputStreamLayout requiredRealtimeOutputLayout(int argc, char** argv)
{
    const std::string value = requiredArg(argc, argv, "--output-layout");
    if (value == "separate") {
        return RealtimeOutputStreamLayout::SeparateStreams;
    }
    if (value == "mpegts") {
        return RealtimeOutputStreamLayout::MuxedTransportStream;
    }
    throw std::invalid_argument("unsupported --output-layout: " + value);
}

MediaOutputTransportKind requiredRealtimeOutputTransport(int argc, char** argv)
{
    const std::string value = requiredArg(argc, argv, "--output-transport");
    if (value == "udp") {
        return MediaOutputTransportKind::UdpDatagrams;
    }
    if (value == "rtp") {
        return MediaOutputTransportKind::RtpAvp;
    }
    throw std::invalid_argument("unsupported --output-transport: " + value);
}

void rejectUnknownRealtimeArgs(int argc, char** argv)
{
    std::vector<std::string> valueArgs = commonVideoTranscodeValueArgs();
    const std::vector<std::string> realtimeValueArgs {
        "--media-id",
        "--input-type",
        "--input-layout",
        "--output-layout",
        "--output-transport",
        "--input",
        "--rtsp-transport",
        "--open-timeout-ms",
        "--read-timeout-ms",
        "--analyze-duration-us",
        "--probe-size",
        "--mpegts-max-pcr-gap-ms",
        "--video-rtp-url",
        "--video-rtp-codec",
        "--video-rtp-payload-type",
        "--video-rtp-clock-rate",
        "--video-rtp-fmtp",
        "--audio-rtp-url",
        "--audio-rtp-codec",
        "--audio-rtp-payload-type",
        "--audio-rtp-clock-rate",
        "--audio-rtp-channels",
        "--audio-rtp-fmtp",
        "--rtp-host",
        "--rtp-port",
        "--sdp",
        "--packet-size",
        "--output",
        "--max-duration",
        "--progress-timeout-ms",
        "--first-output-timeout-ms",
        "--poll-interval-ms",
        "--startup-max-video-unit-bytes",
        "--startup-max-audio-unit-bytes",
        "--startup-max-gap-ms",
        "--prepared-handoff-video-packets",
        "--prepared-handoff-audio-packets",
        "--prepared-handoff-video-bytes",
        "--prepared-handoff-audio-bytes",
    };
    valueArgs.insert(valueArgs.end(), realtimeValueArgs.begin(), realtimeValueArgs.end());

    std::vector<std::string> flagArgs = commonVideoTranscodeFlagArgs();
    flagArgs.push_back("--no-low-latency");
    rejectUnknownArgs(argc, argv, valueArgs, flagArgs);
}

void parseRealtimeInputOptions(int argc, char** argv, MediaRealtimeInputConfig& input)
{
    input.type = requiredRealtimeInputType(argc, argv);
    input.streamLayout = requiredRealtimeInputLayout(argc, argv);
    input.openTimeoutMs = requiredIntArg(argc, argv, "--open-timeout-ms");
    input.readTimeoutMs = requiredIntArg(argc, argv, "--read-timeout-ms");
    input.analyzeDurationUs = requiredIntArg(argc, argv, "--analyze-duration-us");
    input.probeSizeBytes = requiredIntArg(argc, argv, "--probe-size");
    input.lowLatency = !hasArg(argc, argv, "--no-low-latency");

    if (*input.type != RealtimeInputType::MpegTsUdp &&
        hasArg(argc, argv, "--mpegts-max-pcr-gap-ms")) {
        throw std::invalid_argument("--mpegts-max-pcr-gap-ms is valid only for mpegts-udp input");
    }

    if (*input.type == RealtimeInputType::RtpPort) {
        input.videoRtp.url = requiredArg(argc, argv, "--video-rtp-url");
        input.videoRtp.codecName = requiredArg(argc, argv, "--video-rtp-codec");
        input.videoRtp.payloadType = requiredIntArg(argc, argv, "--video-rtp-payload-type");
        input.videoRtp.clockRate = requiredIntArg(argc, argv, "--video-rtp-clock-rate");
        if (hasArg(argc, argv, "--video-rtp-fmtp")) {
            input.videoRtp.fmtp = requiredArg(argc, argv, "--video-rtp-fmtp");
        }
        return;
    }

    input.url = requiredArg(argc, argv, "--input");
    if (*in
[truncated — 14557 more characters]
```

### 3rds/include/spdlog/fwd.h

```c
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)

#pragma once

namespace spdlog {
class logger;
class formatter;

namespace sinks {
class sink;
}

namespace level {
enum level_enum : int;
}

}  // namespace spdlog

```

### 3rds/include/spdlog/version.h

```c
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)

#pragma once

#define SPDLOG_VER_MAJOR 1
#define SPDLOG_VER_MINOR 15
#define SPDLOG_VER_PATCH 3

#define SPDLOG_TO_VERSION(major, minor, patch) (major * 10000 + minor * 100 + patch)
#define SPDLOG_VERSION SPDLOG_TO_VERSION(SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH)

```

### 3rds/include/spdlog/formatter.h

```c
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)

#pragma once

#include <spdlog/details/log_msg.h>
#include <spdlog/fmt/fmt.h>

namespace spdlog {

class formatter {
public:
    virtual ~formatter() = default;
    virtual void format(const details::log_msg &msg, memory_buf_t &dest) = 0;
    virtual std::unique_ptr<formatter> clone() const = 0;
};
}  // namespace spdlog

```

[1424 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]