{"id":50290388,"url":"https://github.com/shiguredo/nvcodec-rs","last_synced_at":"2026-05-28T05:34:24.588Z","repository":{"id":340742961,"uuid":"1167256862","full_name":"shiguredo/nvcodec-rs","owner":"shiguredo","description":"Rust bindings for NVIDIA Video Codec SDK","archived":false,"fork":false,"pushed_at":"2026-05-20T00:44:46.000Z","size":278,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2026-05-28T05:34:14.950Z","etag":null,"topics":["nvidia-video-codec","rust","zero-dependency"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shiguredo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-26T05:15:45.000Z","updated_at":"2026-05-20T00:44:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/shiguredo/nvcodec-rs","commit_stats":null,"previous_names":["shiguredo/nvcodec-rs"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/shiguredo/nvcodec-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shiguredo%2Fnvcodec-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shiguredo%2Fnvcodec-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shiguredo%2Fnvcodec-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shiguredo%2Fnvcodec-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shiguredo","download_url":"https://codeload.github.com/shiguredo/nvcodec-rs/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shiguredo%2Fnvcodec-rs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33596316,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["nvidia-video-codec","rust","zero-dependency"],"created_at":"2026-05-28T05:34:21.963Z","updated_at":"2026-05-28T05:34:24.583Z","avatar_url":"https://github.com/shiguredo.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nvcodec-rs\n\n[![crates.io](https://img.shields.io/crates/v/shiguredo_nvcodec.svg)](https://crates.io/crates/shiguredo_nvcodec)\n[![docs.rs](https://docs.rs/shiguredo_nvcodec/badge.svg)](https://docs.rs/shiguredo_nvcodec)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![GitHub Actions](https://github.com/shiguredo/nvcodec-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/shiguredo/nvcodec-rs/actions/workflows/ci.yml)\n[![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?logo=discord\u0026logoColor=white)](https://discord.gg/shiguredo)\n\n## About Shiguredo's open source software\n\nWe will not respond to PRs or issues that have not been discussed on Discord. Also, Discord is only available in Japanese.\n\nPlease read \u003chttps://github.com/shiguredo/oss\u003e before use.\n\n## 時雨堂のオープンソースソフトウェアについて\n\n利用前に \u003chttps://github.com/shiguredo/oss\u003e をお読みください。\n\n## 概要\n\n[NVIDIA Video Codec SDK](https://developer.nvidia.com/video-codec-sdk) を利用したハードウェアビデオエンコーダーおよびデコーダーの Rust バインディングです。\n\nCUDA ドライバー API を実行時に動的ロード (`dlopen`) するため、ビルド時に CUDA Toolkit のリンクは不要です。\n\n## 特徴\n\n- NVENC によるハードウェアエンコード (H.264 / H.265 / AV1)\n- NVCUVID によるハードウェアデコード (H.264 / H.265 / AV1 / VP8 / VP9 / JPEG)\n- CUDA ライブラリの実行時動的ロード (ビルド時の CUDA Toolkit リンク不要)\n- エンコーダー / デコーダーのケーパビリティクエリ\n- エンコード入力バッファフォーマット選択 (NV12 / YV12 / I420 / YUV444 / 10bit / ARGB / ABGR)\n- デコード出力サーフェスフォーマット選択 (NV12 / P016 / YUV444 / NV16 / P216)\n- フレーム単位のエンコードオプション (IDR フレーム強制、SPS/PPS 出力)\n- エンコーダーのランタイム再構成 (解像度、ビットレート、フレームレート変更)\n- デコーダーの動的解像度変更の自動対応\n- CUDA デバイス列挙\n- CUDA ストリーム管理\n- 2D メモリコピー、ピッチ付きメモリ割り当て\n\n## 動作要件\n\n- Linux (x86_64)\n- NVIDIA GPU (Kepler 世代以降)\n- NVIDIA ドライバー (CUDA ドライバー API を含む)\n- NVIDIA Video Codec SDK 13.0 以降のヘッダーファイル (ビルド時)\n\n## ビルド\n\nCUDA Toolkit がインストールされている Linux 環境でビルドしてください。\n\n```bash\ncargo build\n```\n\n### docs.rs 向けビルド\n\nCUDA Toolkit がない環境では、同梱のスタブヘッダーを使って docs.rs 向けのドキュメント生成のみ可能です。\n\n```bash\nDOCS_RS=1 cargo doc --no-deps\n```\n\n## 使い方\n\n### エンコード\n\n```rust\nuse std::sync::mpsc;\nuse shiguredo_nvcodec::{\n    BufferFormat, CodecConfig, EncodeOptions, EncodedFrame, Encoder, EncoderConfig, Error,\n    FnEncodeHandler, H264EncoderConfig, Preset, TuningInfo, RateControlMode,\n};\n\nlet config = EncoderConfig {\n    codec: CodecConfig::H264(H264EncoderConfig {\n        profile: None,\n        idr_period: None,\n    }),\n    width: 1920,\n    height: 1080,\n    max_encode_width: None,\n    max_encode_height: None,\n    framerate_num: 30,\n    framerate_den: 1,\n    average_bitrate: Some(5_000_000),\n    preset: Preset::P4,\n    tuning_info: TuningInfo::LOW_LATENCY,\n    rate_control_mode: RateControlMode::Cbr,\n    gop_length: None,\n    frame_interval_p: 1,\n    buffer_format: BufferFormat::Nv12,\n    device_id: 0,\n};\n\nlet (tx, rx) = mpsc::sync_channel(4);\nlet encoder = Encoder::new(config, FnEncodeHandler::new(move |frame: Result\u003cEncodedFrame\u003c()\u003e, Error\u003e| {\n    let _ = tx.send(frame);\n}))?;\n\n// NV12 フレームデータをエンコード\nlet options = EncodeOptions {\n    force_intra: false,\n    force_idr: false,\n    output_spspps: false,\n};\nencoder.encode(\u0026nv12_data, \u0026options, ())?;\n\n// IDR フレームを強制してエンコード\nlet force_idr_options = EncodeOptions {\n    force_intra: false,\n    force_idr: true,\n    output_spspps: false,\n};\nencoder.encode(\u0026nv12_data, \u0026force_idr_options, ())?;\n\n// 全エンコード完了を待機\nencoder.flush()?;\n\n// エンコード済みフレームを取得\nfor frame in rx.try_iter() {\n    let frame = frame?;\n    println!(\"encoded bytes: {}\", frame.data().len());\n}\n```\n\n### デコード\n\n```rust\nuse std::sync::mpsc;\nuse shiguredo_nvcodec::{DecodedFrame, Decoder, DecoderCodec, DecoderConfig, Error, FnDecodeHandler, SurfaceFormat};\n\nlet config = DecoderConfig {\n    codec: DecoderCodec::H264,\n    device_id: 0,\n    max_num_decode_surfaces: 20,\n    max_display_delay: 0,\n    surface_format: SurfaceFormat::Nv12,\n};\n\nlet (tx, rx) = mpsc::sync_channel(4);\nlet decoder = Decoder::new(config, FnDecodeHandler::new(move |frame: Result\u003cDecodedFrame\u003c()\u003e, Error\u003e| {\n    let _ = tx.send(frame);\n}))?;\n\n// エンコード済みデータをデコード\ndecoder.decode(\u0026encoded_data, ())?;\n\n// 全デコード完了を待機\ndecoder.flush()?;\n\n// デコード済みフレームを取得\nfor frame in rx.try_iter() {\n    let frame = frame?;\n    // NV12 フォーマットのデコード結果を取得\n    let y_plane = frame.y_plane();\n    let uv_plane = frame.uv_plane();\n    println!(\"Y: {}, UV: {}\", y_plane.len(), uv_plane.len());\n}\n```\n\n### エンコーダーケーパビリティクエリ\n\n```rust\nuse shiguredo_nvcodec::{EncoderCodec, query_encoder_caps};\n\nlet caps = query_encoder_caps(EncoderCodec::H264, 0)?;\nprintln!(\"max width: {}\", caps.width_max);\nprintln!(\"max height: {}\", caps.height_max);\nprintln!(\"10-bit encode: {}\", caps.support_10bit_encode);\n```\n\n### デコーダーケーパビリティクエリ\n\n```rust\nuse shiguredo_nvcodec::{DecoderCodec, query_decoder_caps};\n\nlet caps = query_decoder_caps(DecoderCodec::H264, 0)?;\nprintln!(\"supported: {}\", caps.is_supported);\nprintln!(\"max: {}x{}\", caps.max_width, caps.max_height);\n```\n\n### CUDA デバイス列挙\n\n```rust\nuse shiguredo_nvcodec;\n\nlet count = shiguredo_nvcodec::device_count()?;\nfor i in 0..count {\n    let name = shiguredo_nvcodec::device_name(i)?;\n    println!(\"GPU {}: {}\", i, name);\n}\n```\n\n## サポートコーデック\n\n### エンコード\n\n| コーデック | `CodecConfig` |\n|-----------|--------------|\n| H.264     | `CodecConfig::H264(H264EncoderConfig)` |\n| H.265     | `CodecConfig::Hevc(HevcEncoderConfig)` |\n| AV1       | `CodecConfig::Av1(Av1EncoderConfig)` |\n\n### デコード\n\n| コーデック | `DecoderCodec` |\n|-----------|--------------|\n| H.264     | `DecoderCodec::H264` |\n| H.265     | `DecoderCodec::Hevc` |\n| AV1       | `DecoderCodec::Av1` |\n| VP8       | `DecoderCodec::Vp8` |\n| VP9       | `DecoderCodec::Vp9` |\n| JPEG      | `DecoderCodec::Jpeg` |\n\n## サポートフォーマット\n\n### エンコード入力バッファフォーマット (`BufferFormat`)\n\n| フォーマット | `BufferFormat` | 説明 |\n|---|---|---|\n| NV12 | `BufferFormat::Nv12` | Semi-Planar YUV 4:2:0 8bit |\n| YV12 | `BufferFormat::Yv12` | Planar YUV 4:2:0 8bit (Y+V+U) |\n| IYUV (I420) | `BufferFormat::Iyuv` | Planar YUV 4:2:0 8bit (Y+U+V) |\n| YUV444 | `BufferFormat::Yuv444` | Planar YUV 4:4:4 8bit |\n| YUV420 10bit | `BufferFormat::Yuv420_10bit` | Semi-Planar YUV 4:2:0 10bit |\n| YUV444 10bit | `BufferFormat::Yuv444_10bit` | Planar YUV 4:4:4 10bit |\n| ARGB | `BufferFormat::Argb` | Packed A8R8G8B8 |\n| ABGR | `BufferFormat::Abgr` | Packed A8B8G8R8 |\n| ARGB 10bit | `BufferFormat::Argb10` | Packed A2R10G10B10 |\n| ABGR 10bit | `BufferFormat::Abgr10` | Packed A2B10G10R10 |\n\n### デコード出力サーフェスフォーマット (`SurfaceFormat`)\n\n| フォーマット | `SurfaceFormat` | 説明 |\n|---|---|---|\n| NV12 | `SurfaceFormat::Nv12` | Semi-Planar YUV 4:2:0 8bit |\n\n## 動的解像度変更\n\nWebRTC やアダプティブビットレートストリーミングなど、ストリーム中に解像度が変わるユースケースに対応しています。\n\n### エンコーダー\n\n`reconfigure()` で解像度を変更できます。エンコーダーの作り直しは不要です。\n\nただし、初期化時に `max_encode_width` / `max_encode_height` を設定しておく必要があります。新しい解像度がこの範囲内であれば変更可能です。\n\n```rust\nuse shiguredo_nvcodec::ReconfigureParams;\n\n// 作成時に最大解像度を指定\nlet config = EncoderConfig {\n    width: 1920,\n    height: 1080,\n    max_encode_width: Some(3840),   // 4K まで変更可能\n    max_encode_height: Some(2160),\n    // ...\n};\nlet mut encoder = Encoder::new(config, FnEncodeHandler::new(move |_frame| {\n    // エンコード結果の処理\n}))?;\n\n// 動的に解像度を変更\nencoder.reconfigure(ReconfigureParams {\n    width: Some(1280),\n    height: Some(720),\n    ..Default::default()\n})?;\n```\n\n### デコーダー\n\n利用者側の操作は不要です。ストリーム中に解像度が変わった場合、内部で自動的にデコーダーが再作成されます。\n\n`DecodedFrame` はフレームごとに `width()` / `height()` を持っているので、フレームごとにサイズを確認してください。\n\n```rust\n// 解像度が変わっても同じデコーダーで継続可能\nlet (tx, rx) = mpsc::sync_channel(4);\nlet decoder = Decoder::new(config, FnDecodeHandler::new(move |frame: Result\u003cDecodedFrame\u003cu32\u003e, Error\u003e| {\n    let _ = tx.send(frame);\n}))?;\n\ndecoder.decode(\u0026data_1080p, 0)?;\nlet frame = rx.recv()??;\nassert_eq!(frame.width(), 1920);\n\ndecoder.decode(\u0026data_720p, 1)?;\nlet frame = rx.recv()??;\nassert_eq!(frame.width(), 1280);  // 自動的に変更される\n```\n\n### まとめ\n\n| | エンコーダー | デコーダー |\n|---|---|---|\n| 仕組み | `reconfigure()` で明示的に変更 | パーサーが自動検出して再作成 |\n| 利用者の操作 | `ReconfigureParams` で新解像度を指定 | 不要 |\n| 制約 | `max_encode_width` / `max_encode_height` 以内 | なし |\n| 超えた場合 | エンコーダーを作り直す | 自動対応 |\n\n## ライセンス\n\nApache License 2.0\n\n```text\nCopyright 2026-2026, Shiguredo Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\n## NVIDIA Video Codec SDK\n\n\u003chttps://docs.nvidia.com/video-technologies/video-codec-sdk/13.0/index.html\u003e\n\n\u003chttps://docs.nvidia.com/video-technologies/video-codec-sdk/13.0/license/index.html\u003e\n\n```text\n“This software contains source code provided by NVIDIA Corporation.”\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshiguredo%2Fnvcodec-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshiguredo%2Fnvcodec-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshiguredo%2Fnvcodec-rs/lists"}