2026-05-10

週次オープンソース:goro の VM 着地、OxideAV のコーデック網が広がる

W18 で「来週 goro に VM が入る」と書いたやつが、実際に入った。 libwallet は、地味に Bitcoin の送金を全件壊していた 1 行のバグを 修正してリリース。OxideAV は「ドキュメントスタックといくつかの コーデック」だった先週から、pure-Rust の ffmpeg 相当のマトリクスに 近い形へと一気に広がった。

goro:バイトコード VM

goro(Go で書く PHP)は これまで、AST を辿るインタプリタと、PHP → Go のトランスパイラの 2 本立てで動いていた。間にあるはずのバイトコード VM がずっと 未着手だったのが、今週着地した。

形は以下:

  • コンパイラ+ランタイムの骨格 — AST をバイトコードに落とし、 小さな VM でディスパッチする。GORO_VM ゲートで、当面は既存 インタプリタをデフォルトに残してある。
  • ネイティブ実装 — リテラル、変数、二項演算(PHP セマンティクスを そのまま扱うため compiler.EvalBinop 経由)、配列・インデックス 読み書き・append、foreach??(null 合体)、オブジェクト 生成・プロパティ参照・メソッド呼び出し、throw / try / catch / finally、クロージャ本体を VM 経由でディスパッチ ($this バインディング込み)、文字列補間、class const / static / ::class
  • 効果 — ローカル変数をスロット配列にキャッシュ(読み出し時に ハッシュテーブルを引かない)で Arithmetic ベンチ −50%。 クロージャの inline + 間接呼び出しで FunctionCalls −21%。

phpt スイートに対してリグレッションなし。インタプリタと VM を 並べた diff テストも組んである。VM は当面オプトイン、デフォルト 切り替えはカバレッジが落ち着いてから。

libwallet:txid の二重反転

libwallet v0.4.13 → v0.4.17。目玉は wlttx/bitcoin: fix double txid byte-reversal that broke every send。txid のエンディアンを 2 回ひっくり返して いたせいで、署名済みの Bitcoin 送金がすべてオンチェーンに存在 しない入力を指していた。実際にブロードキャストするまで気づき にくい種類のバグ。

その他の今週分:

  • Bitcoin 送金に priority フィールド:cheap / fast の手数料予算 を選べる。
  • wlttx/maxSendable は入力と fee rate をピン留めし、見積もり からブロードキャストまで「最大送金額」が崩れないように。m/0m/1 の両派生鎖を見て、入力ごとの vsize も加味する。
  • UTXO の取得元を modchain_assets 一本に集約。コイン選択側と ブロードキャスト側が「使える UTXO」で食い違わないように。
  • Bitcoin のブロードキャストエラーに inputs と生 hex を同梱。
  • Dart の FFI が、プラットフォームごとに正しいネイティブ ライブラリをロードするように。

OxideAV:マトリクスが埋まり始めた

W18 はドキュメントスタック(TTF / OTF / SVG / PDF)と、ロスレス・ 旧来コーデックの最初の一掃の週だった。W19 はそこから横方向に 一気に広がる。動画・音声・画像・ハードウェアアクセラレーション・ 3D まで。

エンコーダの深掘り

  • H.266 / VVC (oxideav-h266) — エンコーダの round 49 → 56。chroma SAO の RDO + apply、chroma 残差 emit、alf_luma_clip_idx の係数 / clip 同時 RDO + chroma SAO merge、明示的な tu_*_coded_flag CABAC、MTT BT/TT 分割 シンタックス、CU 単位の cu_qp_delta、128×128 CTB の強制 QT 分割、複数行にまたがる CU 隣接トラッキング。
  • JPEG XL (oxideav-jpegxl) — ISO/IEC 18181-1:2024 に対する再実装。小サイズのロスレス fixture 5 本がすべて pixel-correct。round 20 → 28 で DC_GROUP 境界の数え直し、ANS の終端 state オラクル、parent-dispatch IDCT、 Annex L のカラー変換(XYB / YCbCr 逆変換)など。
  • WebP VP8L (oxideav-webp) — ロスレス側に Viterbi 風の最適 LZ77。VP8 intra-frame は 100% bit-exact を維持。
  • MagicYUV (oxideav-magicyuv) — クリーンルーム再構築 round 1〜3、17 FOURCC 全部 + エンコーダ。 Auditor サインオフ込みで 100% 宣言。
  • TTA (oxideav-tta) — クリーンルーム再構築 round 1+2、Auditor PASS。

今週新しく入ったコーデック

動画H.261, H.263, H.264, H.265, AV1, VP6 / VP8 / VP9, MPEG-1/2 / MPEG-4 / MS-MPEG4, MJPEG, Dirac, Theora, ProRes, AVIF

音声AAC, AC-3, AC-4, Opus + CELT, Vorbis, FLAC, MP1 / MP2 / MP3, Speex, GSM, iLBC, G.711 / G.722 / G.723.1 / G.728 / G.729, Ogg コンテナ。

画像PNG, JPEG 2000, OpenEXR, Radiance HDR, BMP, ICO, TGA, PCX, QOI, DDS, Farbfeld, WBMP, Apple PICT, Amiga IFF/ILBM, ICER(NASA 火星探査機の 圧縮)。

トラッカー/チップチューンAmiga MOD, ScreamTracker S3M, Nintendo NSF

ハードウェアアクセラレーション

OS が提供するハードウェアコーデックエンジンを、oxideav-core の API の裏に隠す sibling crate 群を新設:

これらはプロジェクト内で唯一 OS FFI を使う crate 群で、それは ラップ対象が OS 側のエンジンだから仕方ない。workspace の README も、その点を踏まえて書き直した。「pure Rust」はプロジェクト全体 を指す主張ではなく、pure-rust プリセット(hwaccel を除いた すべて)の意味だ、と明示。

PDF:暗号化

oxideav-pdf に ISO 32000-1 §7.6 の暗号化デコードが入った。AES-256 リビジョン 5・ リビジョン 6 まで含む。パスワード付き PDF が往復できるように なった。

3D アセット

シーンモデルに 3D メッシュのスタックが接続された。中身は mesh3d を共通の メモリ表現として、 STLOBJglTFUSDZ の sibling crate。 USDZ のテストは Apple の usdzconvert をオラクルとして経由させて いる(CI 互換のために Python 3.9 + usd-core 21.11 をピン)。

ワークスペースの形

  • oxideav-format-alloxideav-meta に リネーム。linkme をやめて、明示的な register_all(ctx) + Cargo features で登録セットを形にする方式へ。 oxideav アンブレラも 痩せた:sibling 側が enable!() マクロで register(ctx) を 公開し、アンブレラがすべてに依存するのをやめた。
  • Pure-Rust プリセット(pure-rust = hwaccel を除いた全部)が 正式な一級市民になった。
  • CLI も整備:oxideav info <codec> でバックエンド可用性、 bench でハードウェアバックエンドに対する codec ごとの スループット、transcode がマルチストリーム入力対応、 list は codec ごとのバックエンドテーブルをメディア種別で グルーピング。
  • oxideav-metaoxideav-cli-convert が、それぞれ最初の 0.0.x / 0.1 を刻んだ。

今週その他

  • oxideav-vfw — Video for Windows / DirectShow のシム。IBaseFilter / IFilterGraph / IPin::ReceiveConnection の配線を順に通し、 自動ディスカバリまで。
  • oxideav-image-filter — 画像フィルターグラフ、round 7 → 10。

来週

JPEG XL は引き続き 2024 仕様を進める。H.266 のエンコーダループ 継続。HW アクセラ系の crate がそれぞれ最初の動くバックエンドを 持ち始める。goro の VM はもう少し PHP のセマンティクスを順に ネイティブに移していく。