{"id":48518237,"url":"https://github.com/micilini/nessmuxer","last_synced_at":"2026-04-07T20:02:49.789Z","repository":{"id":349665965,"uuid":"1202510264","full_name":"micilini/NessMuxer","owner":"micilini","description":"Standalone C library that encodes raw NV12 frames to H.264 and muxes them into a playable MKV container.","archived":false,"fork":false,"pushed_at":"2026-04-07T01:52:18.000Z","size":252,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-07T03:17:55.044Z","etag":null,"topics":["c","ebml","h264","matroska","media-foundation","mkv","nv12","nvenc","screen-recording","video-encoding","videotoolbox","x264"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/micilini.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-06T05:12:16.000Z","updated_at":"2026-04-07T01:52:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/micilini/NessMuxer","commit_stats":null,"previous_names":["micilini/nessmuxer"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/micilini/NessMuxer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micilini%2FNessMuxer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micilini%2FNessMuxer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micilini%2FNessMuxer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micilini%2FNessMuxer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/micilini","download_url":"https://codeload.github.com/micilini/NessMuxer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micilini%2FNessMuxer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31526666,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","ebml","h264","matroska","media-foundation","mkv","nv12","nvenc","screen-recording","video-encoding","videotoolbox","x264"],"created_at":"2026-04-07T20:02:37.052Z","updated_at":"2026-04-07T20:02:49.771Z","avatar_url":"https://github.com/micilini.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NessMuxer\n\n![License](https://img.shields.io/badge/license-MIT-green)\n![Platform](https://img.shields.io/badge/platform-Windows%20|%20Linux%20|%20macOS-blue)\n![Language](https://img.shields.io/badge/language-C11-orange)\n\n**Standalone C library: raw NV12 frames in → playable `.mkv` file out.**\n\nNessMuxer is a cross-platform C library that receives raw NV12 video frames, encodes them to H.264, and muxes the result into a valid Matroska (`.mkv`) container.\n\nIt has no mandatory external dependencies at runtime. Some optional encoder backends may require platform SDKs, system frameworks, or third-party libraries during build and/or distribution.\n\nThe caller only needs three functions: **Open → WriteFrame → Close**.\n\n---\n\n## What does it do?\n\nNessMuxer takes the raw pixel data that comes out of screen capture APIs (like Windows Graphics Capture, PipeWire, or AVFoundation) or camera devices and turns it into a compressed, playable video file:\n\n```\nNV12 raw frame → H.264 encoding → MKV container (custom EBML muxer) → .mkv file\n```\n\nYour application sends uncompressed frames. NessMuxer gives you back a video file that plays in VLC, MPC-HC, ffplay, or any modern player.\n\n---\n\n## Features\n\n- **Cross-platform** — runs on Windows, Linux, and macOS\n- **Multiple encoder backends** — Media Foundation, NVENC, libx264, VideoToolbox\n- **Smart AUTO mode** — runtime probe detects the best available encoder automatically\n- **3-function API** — `Open`, `WriteFrame`, `Close`. That's it\n- **Real-time encoding** — designed for screen recording and live capture scenarios\n- **Valid MKV output** — includes SeekHead, Cues (seek index), and proper Duration\n- **CLI tools** — converter (`nessmux`), validator (`nessmux_validate`), and benchmark (`nessmux_bench`)\n- **P/Invoke ready** — clean C API, works directly from C#, Rust, Python, etc.\n- **~3000 lines of C** — small, auditable, no bloat\n\n---\n\n## Platform \u0026 Encoder Matrix\n\n| Platform | Default Encoder | Optional Encoders | HW Accel |\n|---|---|---|---|\n| Windows 10/11 | Media Foundation | NVENC, libx264 | Yes (Intel QSV, AMD AMF via MF) |\n| Linux | libx264 | NVENC | CPU (or GPU via NVENC) |\n| macOS | VideoToolbox | libx264 | Yes (Apple Silicon / Intel) |\n\nWhen `encoder_type = AUTO`, NessMuxer probes each backend at runtime and picks the best one available: NVENC → VideoToolbox → Media Foundation → libx264.\n\n---\n\n## Optional Dependencies\n\nNessMuxer itself is MIT-licensed, but some encoder backends depend on third-party components with their own licenses and distribution terms.\n\n### Backends that do not require third-party redistribution\n\n- **Media Foundation** — available on supported Windows versions\n- **VideoToolbox** — available on macOS\n\n### Backends that require extra care\n\n- **NVENC** — requires NVIDIA Video Codec SDK headers at build time and a supported NVIDIA GPU/driver at runtime\n- **libx264** — requires x264 headers/libraries and is subject to GPL/commercial licensing terms from its authors\n\n### Where to get them\n\n- **NVIDIA Video Codec SDK / NVENC headers**\n  Download from the official NVIDIA Video Codec SDK page.\n\n- **x264 source / headers**\n  Download from the official x264 project page maintained by VideoLAN.\n\n### Suggested local layout\n\nThese dependencies are **not** shipped in this repository. A common local layout is:\n\n```text\nthird_party/\n  nvenc/\n    include/\n  x264/\n    include/\n    lib/\n```\n\nYou should obtain these files yourself and point CMake to your local paths.\n\n---\n\n## Quick Start\n\n### Windows\n\n**Requirements:** Visual Studio Build Tools with C++ workload, CMake 3.15+\n\n```bash\n# Default (Media Foundation only):\ncmake -B build -A x64\ncmake --build build --config Release\n\n# With NVENC (requires NVIDIA Video Codec SDK headers downloaded separately):\ncmake -B build -A x64 ^\n  -DNESS_USE_NVENC=ON ^\n  -DNESS_NVENC_INCLUDE_DIR=\"C:/SDKs/NVIDIA/VideoCodecSDK/Interface\"\ncmake --build build --config Release\n\n# With libx264 (requires x264 headers/libraries obtained separately):\ncmake -B build -A x64 ^\n  -DNESS_USE_X264=ON ^\n  -DNESS_X264_INCLUDE_DIR=\"C:/SDKs/x264/include\"\ncmake --build build --config Release\n\n# Everything:\ncmake -B build -A x64 ^\n  -DNESS_USE_NVENC=ON ^\n  -DNESS_NVENC_INCLUDE_DIR=\"C:/SDKs/NVIDIA/VideoCodecSDK/Interface\" ^\n  -DNESS_USE_X264=ON ^\n  -DNESS_X264_INCLUDE_DIR=\"C:/SDKs/x264/include\"\ncmake --build build --config Release\n```\n\nOr use the automated script:\n```bash\nbuild_and_test.bat          # Media Foundation only\nbuild_and_test.bat nvenc    # + NVENC\nbuild_and_test.bat x264     # + libx264\nbuild_and_test.bat all      # Everything\n```\n\n### Linux\n\n**Requirements:** GCC/Clang, CMake 3.15+\n\n```bash\n# Ubuntu / Debian example for libx264:\nsudo apt install build-essential cmake pkg-config libx264-dev\n\ncmake -B build -DNESS_USE_X264=ON\ncmake --build build -j$(nproc)\n```\n\nFor NVENC on Linux, install the NVIDIA driver/runtime required by your GPU and obtain the NVIDIA Video Codec SDK headers separately.\n\nOr use the automated script:\n```bash\nchmod +x build_and_test.sh\n./build_and_test.sh\n./build_and_test.sh --raw /path/to/screen.raw    # with CLI tests\n```\n\n### macOS\n\n**Requirements:** Xcode Command Line Tools, CMake 3.15+\n\n```bash\n# VideoToolbox (ships with macOS):\ncmake -B build\ncmake --build build\n\n# With libx264:\nbrew install x264\ncmake -B build -DNESS_USE_X264=ON\ncmake --build build\n```\n\n---\n\n## Third-party setup\n\nThis repository does **not** redistribute proprietary SDK materials or GPL third-party code inside `third_party/`.\n\n### NVIDIA Video Codec SDK (NVENC)\n\n1. Go to the official NVIDIA Video Codec SDK page\n2. Accept the SDK terms if required\n3. Download the SDK package\n4. Use the header directory from the SDK in your CMake configuration\n\nExample local path on Windows:\n\n```text\nC:/SDKs/NVIDIA/VideoCodecSDK/Interface\n```\n\n### x264\n\nYou have two common options:\n\n1. **Linux/macOS package manager route**\n\n   * Install x264 from your system package manager (`apt`, `brew`, etc.)\n2. **Manual source route**\n\n   * Download the official x264 source from VideoLAN\n   * Build it locally\n   * Point NessMuxer to your local `include` directory\n\nExample local path:\n\n```text\nC:/SDKs/x264/include\n```\n\n---\n\n## CLI Tools\n\n### nessmux — Raw-to-MKV Converter\n\n```bash\nnessmux input.raw output.mkv --width 1920 --height 1080 --fps 30 --bitrate 6000\nnessmux input.raw output.mkv --width 1920 --height 1080 --fps 30 --bitrate 6000 --encoder nvenc\n```\n\nSupported `--encoder` values: `auto`, `mf`, `x264`, `nvenc`, `vt` (VideoToolbox)\n\n### nessmux_validate — MKV Validator\n\n```bash\nnessmux_validate output.mkv\n```\n\n```\n[OK] EBML Header: version=1, doctype=matroska, doctypeversion=4\n[OK] Segment found at offset 59\n[OK] SeekHead: 3 entries\n[OK] Info: TimestampScale=1000000, Duration=19699.33ms\n[OK] Tracks: 1 track(s)\n     Track 1: video, V_MPEG4/ISO/AVC, 1920x1080\n     CodecPrivate: 39 bytes (AVCC v1, profile=66, level=40)\n[OK] Clusters: 20 clusters, 591 SimpleBlocks\n[OK] Cues: 10 entries\n[OK] VALID — 591 frames, 19.70s, 10 keyframes\n```\n\n### nessmux_bench — Encoder Benchmark\n\n```bash\nnessmux_bench                          # all presets, auto encoder\nnessmux_bench --encoder nvenc          # benchmark specific encoder\nnessmux_bench --width 1920 --height 1080 --frames 300 --encoder x264\n```\n\n---\n\n## Usage (C)\n\n```c\n#include \"ness_muxer.h\"\n\nNessMuxer* muxer = NULL;\nNessMuxerConfig config = {0};\nconfig.output_path  = \"output.mkv\";\nconfig.width        = 1920;\nconfig.height       = 1080;\nconfig.fps          = 30;\nconfig.bitrate_kbps = 6000;\nconfig.encoder_type = NESS_ENCODER_AUTO;  /* picks best available */\n\nness_muxer_open(\u0026muxer, \u0026config);\n\nwhile (capturing) {\n    uint8_t* nv12_frame = get_frame_from_capture();\n    int frame_size = 1920 * 1080 * 3 / 2;\n    ness_muxer_write_frame(muxer, nv12_frame, frame_size);\n}\n\nness_muxer_close(muxer);\n```\n\n## Usage (C# / P/Invoke)\n\n```csharp\n[DllImport(\"NessMuxer\", CallingConvention = CallingConvention.Cdecl)]\nstatic extern int ness_muxer_open(out IntPtr muxer, ref NessMuxerConfig config);\n\n[DllImport(\"NessMuxer\", CallingConvention = CallingConvention.Cdecl)]\nstatic extern int ness_muxer_write_frame(IntPtr muxer, IntPtr nv12_data, int nv12_size);\n\n[DllImport(\"NessMuxer\", CallingConvention = CallingConvention.Cdecl)]\nstatic extern int ness_muxer_close(IntPtr muxer);\n```\n\n---\n\n## API Reference\n\n| Function | Description |\n|---|---|\n| `ness_muxer_open(muxer, config)` | Initialize encoder + muxer. MKV header is written after the first keyframe |\n| `ness_muxer_write_frame(muxer, nv12, size)` | Send one NV12 frame. Encoding + muxing happens internally |\n| `ness_muxer_close(muxer)` | Drain encoder, write Cues/SeekHead, patch Duration, close file |\n| `ness_muxer_error(muxer)` | Get last error message |\n| `ness_muxer_frame_count(muxer)` | Number of frames submitted |\n| `ness_muxer_encoded_count(muxer)` | Number of H.264 packets written to MKV |\n\n### Config\n\n| Field | Type | Description |\n|---|---|---|\n| `output_path` | `const char*` | Path to the output `.mkv` file |\n| `width` | `int` | Frame width in pixels (must be even) |\n| `height` | `int` | Frame height in pixels (must be even) |\n| `fps` | `int` | Framerate (e.g., 30) |\n| `bitrate_kbps` | `int` | H.264 bitrate in kbps (e.g., 6000 for 1080p) |\n| `encoder_type` | `int` | 0=AUTO, 1=MediaFoundation, 2=x264, 3=NVENC, 4=VideoToolbox |\n\n### Return Codes\n\n| Code | Value | Meaning |\n|---|---|---|\n| `NESS_OK` | 0 | Success |\n| `NESS_ERROR` | -1 | Generic error |\n| `NESS_ERROR_IO` | -2 | File I/O error |\n| `NESS_ERROR_PARAM` | -3 | Invalid parameter |\n| `NESS_ERROR_STATE` | -4 | Invalid state |\n| `NESS_ERROR_ENCODER` | -5 | Encoder backend error |\n| `NESS_ERROR_ALLOC` | -6 | Memory allocation error |\n\n---\n\n## Architecture\n\n```\nNessMuxer/\n├── include/\n│   └── ness_muxer.h                  ← Public API (the only header consumers need)\n├── src/\n│   ├── ness_muxer.c                  ← Orchestrator: open/write_frame/close\n│   ├── encoder/\n│   │   ├── encoder.h                 ← Encoder interface (vtable)\n│   │   ├── encoder.c                 ← Backend dispatcher + runtime probe\n│   │   ├── mf_encoder_backend.c      ← Windows Media Foundation wrapper\n│   │   ├── x264_encoder.c            ← libx264 software encoder\n│   │   ├── nvenc_encoder.c           ← NVIDIA NVENC hardware encoder\n│   │   └── vtbox_encoder.c           ← macOS VideoToolbox hardware encoder\n│   ├── mf_encoder.h/.c               ← Media Foundation IMFTransform (Windows)\n│   ├── mkv_muxer.h/.c                ← MKV container writer (EBML/Matroska)\n│   ├── ebml_writer.h/.c              ← EBML primitive writers\n│   ├── avc_utils.h/.c                ← H.264 NALU parsing, Annex-B ↔ AVCC\n│   ├── buffered_io.h/.c              ← Buffered file I/O layer (cross-platform)\n│   └── mkv_defs.h                    ← Matroska element IDs\n├── tools/\n│   ├── nessmux.c                     ← Raw-to-MKV CLI converter\n│   ├── nessmux_validate.c            ← MKV structure validator\n│   └── nessmux_bench.c               ← Encoder benchmark\n├── test/\n│   ├── test_ebml.c                   ← Unit tests: EBML primitives (10 tests)\n│   ├── test_avc.c                    ← Unit tests: H.264 utils (8 tests)\n│   ├── test_encoder.c                ← Integration: MF encoder (Windows only)\n│   ├── test_muxer_only.c             ← Integration: MKV muxer (6 tests)\n│   └── test_full_pipeline.c          ← End-to-end: NV12 → MKV (3 checks)\n├── build_and_test.bat                ← Automated build/test (Windows)\n├── build_and_test.sh                 ← Automated build/test (Linux/macOS)\n├── CMakeLists.txt\n└── README.md\n```\n\n\u003e Optional third-party SDKs/libraries are expected to live outside the repository or in an ignored local `third_party/` folder.\n\n### Encoder Selection Flow\n\n```\nness_muxer_open(config)\n    │\n    ├─ encoder_type == AUTO?\n    │   └─→ ness_encoder_get_best()\n    │       ├─ try NVENC    → create(160x120) → success? use it\n    │       ├─ try VTBox    → create(160x120) → success? use it\n    │       ├─ try MF       → create(160x120) → success? use it\n    │       └─ try x264     → create(160x120) → success? use it\n    │\n    └─ encoder_type == specific?\n        └─→ ness_encoder_get(type) → return vtable directly\n```\n\n### Internal Pipeline\n\n```\nness_muxer_write_frame(nv12_data)\n    │\n    ├─→ vtable-\u003esubmit_frame(nv12_data)      ← NV12 → encoder backend\n    │\n    ├─→ vtable-\u003ereceive_packets()             ← Collect H.264 packets\n    │       └─→ for each H.264 packet:\n    │\n    └─→ mkv_muxer_write_packet(h264_data)    ← Write to MKV\n            ├─→ avc_annexb_to_mp4()           ← Convert start codes\n            ├─→ Cluster management\n            └─→ EBML SimpleBlock write\n```\n\n---\n\n## Tested Configurations\n\n| OS | Encoder | Status |\n|---|---|---|\n| Windows 11 (x64) | Media Foundation | ✅ 591 frames, 1080p, valid MKV |\n| Windows 11 (x64) | NVENC (RTX GPU) | ✅ 591 frames, 1080p, valid MKV |\n| Windows 11 (x64) | libx264 (DLL) | ✅ 591 frames, 1080p, valid MKV |\n| Windows 11 (x64) | AUTO (→ NVENC) | ✅ Runtime probe selected NVENC |\n| Ubuntu 24.04 (x64) | libx264 | ✅ 591 frames, 1080p, valid MKV |\n| Ubuntu 24.04 (x64) | AUTO (→ x264) | ✅ Runtime probe selected x264 |\n| macOS | VideoToolbox | 🔧 Implemented, awaiting test hardware |\n\n---\n\n## Validation\n\nThe output MKV files are spec-compliant and can be validated with standard tools:\n\n```bash\n# Built-in validator:\nnessmux_validate output.mkv\n\n# External tools:\nffprobe -v error -show_format -show_streams output.mkv\nmkvinfo output.mkv\nffplay output.mkv\n```\n\n---\n\n## License\n\nNessMuxer itself is licensed under the [MIT License](LICENSE).\n\nOptional encoder backends may be subject to separate licenses and distribution terms:\n\n- **Media Foundation** ships with supported versions of Windows\n- **VideoToolbox** ships with macOS\n- **NVIDIA Video Codec SDK / NVENC headers** are provided by NVIDIA under NVIDIA's own license terms\n- **x264** is provided by its authors under GPL/commercial licensing terms\n\nThis repository does **not** redistribute NVIDIA Video Codec SDK materials or x264 source code/headers.\n\nIf you plan to distribute binaries that use optional third-party encoders, review the applicable license terms carefully and obtain legal advice when needed.\n\n---\n\n## Author\n\nBuilt as part of [NessStudio](https://github.com/micilini/NessStudio) — a Windows 10/11+ screen recording application.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicilini%2Fnessmuxer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicilini%2Fnessmuxer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicilini%2Fnessmuxer/lists"}