0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

地デジUSBチューナーのブロックノイズが嫌で、ドライバを作り直した(macOS※ / Windows / Android / Linux)

0
Last updated at Posted at 2026-08-29

TL;DR

録画のブロックノイズと音飛びが嫌で、PLEX PX-S1UD のドライバをカーネルの外に作り直しました。成果物は CLI 一本 siano-ts で、MPEG-TS を stdout に出します。Linux・Windows・Android(Termux)は実機で TS が出るところまで確認済みです。※ macOS はビルドが通っているだけで、実機のチューナーはまだ繋いでいません。

何を作ったか

siano-ts はユーザ空間のドライバで、やっていることは次のとおりです。

  1. libusb で PX-S1UD を開く
  2. isdbt_rio.inp を載せる
  3. 日本の地デジの物理チャンネルに合わせる
  4. MPEG-TS を stdout に書く

プロトコルは Linux の smsusb / smscoreapi / smsdvb(GPL)をユーザ空間へ移植したもので、本体は GPL-2.0-or-later です。

複数 OS 対応

カーネルを捨てた理由はブロックノイズでしたが、ユーザ空間で書き直したことで、カーネルモジュールが無い場所でも同じチューナーが開くようになりました。

カーネル smsusb siano-ts
普通の Linux 動く。debugfs の WARN と DKMS が残る 動く
Home Assistant OS CONFIG_SMS_USB_DRV が無い 動く。筆者も現在利用中
Windows PLEX のカーネルドライバは HVCI(コア分離)と相性が悪い WinUSB(Zadig)で、HVCI を切らずに録画できた
macOS 地デジ USB を開く手段が見当たらない CI でビルドが通る。実機は未
Android (Termux) 不可 Termux の termux-usb -e で、Google TV Streamer に挿して TS が出た
Android (APK) 不可 dtv-android が動作確認済み

macOS は実機を持っていないため未検証です。動作報告も不具合報告も歓迎します。

使い方

siano-ts を入れて、mirakc / Mirakurun の tuner command を差し替えてください。

./siano-ts --list
./siano-ts --channel 27 -t 30 -o /tmp/nhk.ts

Windows なら siano-ts.exe を同じ引数で叩きます。

mirakc に渡すときは、チャンネル定義の channel を物理番号にしてください。

# mirakc(channels[].channel は物理番号。例: '27')
tuners:
  - name: PX-S1UD
    types: [GR]
    command: siano-ts --channel {{{channel}}} --firmware /lib/firmware/isdbt_rio.inp
filters:
  decode-filter:
    command: recisdb decode --input - -
# Mirakurun
- name: PX-S1UD
  types: [GR]
  command: >-
    siano-ts --channel <channel> --firmware /lib/firmware/isdbt_rio.inp

バイナリと isdbt_rio.inpReleases に並んでいます。B-CAS は recisdb と PC/SCリーダに任せます。decode-filter に置いておけば、番組表スキャンは生 TS の PAT / SDT を読みます。なお USB の URB 長は 188 の倍数ではないため、siano-ts の側で TSパケット境界に揃えてから出しています。ここを揃えずに渡すと、mirakc の scan-services が空で終わります。

Windows(Zadig で WinUSB に載せる)

PLEX のドライバが当たったままでは libusb から開けないので、WinUSB に載せ替えます。

  1. Zadig を落として管理者権限で起動する
  2. Options → List All Devices にチェックを入れる(既にドライバが当たっている機器は、これを入れないと一覧に出ない)
  3. 一覧から PX-S1UD を選ぶ。USB ID が 3275:0080 であることを確認する
  4. 右側のドライバを WinUSB にする
  5. Replace Driver を押す

以後 siano-ts.exe から開けます。コア分離(HVCI)も Secure Boot も有効のままで構いません。

戻すときは、デバイスマネージャーで当該デバイスを右クリック → デバイスのアンインストール → 「このデバイスのドライバーを削除します」にチェック → 抜き差しして PLEX のドライバを入れ直します。

WinUSB に載せ替えたデバイスは、BonDriver からは見えなくなります。同じ機器を BonDriver と siano-ts で同時には使えません。

Android(Termux)

アプリからは /dev/bus/usb を開けないので、Termux に fd を取ってもらいます。

pkg install termux-api libusb
termux-usb -l
termux-usb -r -e "./siano-ts --channel 27 -t 30 -o /sdcard/nhk.ts" /dev/bus/usb/001/002

-r で権限ダイアログを出し、-e に渡したコマンドへ fd を引き渡します。siano-ts は末尾に付く整数を fd として解釈するので、--fd を明示しなくても通ります。Termux:API アプリの導入も必要です。

Android(APK)

Google TV Streamer や Android TV に ADB 経由でインストールすることで、mirakc / EPGStation がPC無しで利用できます。接続にはUSBハブなどをご利用ください。録画の保存先はリムーバブルストレージを推奨します。

Home Assistant OS

同じ構成のアドオンも置いてあります。

https://github.com/Khronos31/hassio-addons/tree/main/mirakc
https://github.com/Khronos31/hassio-addons/tree/main/epgstation

あとがき

長年バグが放置されていた既存のドライバを放棄した結果、より安定したものが作れて満足しています。macOS での地デジ視聴については情報が見つからなかったので、これで視聴ができるようになると嬉しいです。実際の動作報告を心待ちにしています。

蛇足

ライセンスについて

ファームウェア isdbt_rio.inpLICENCE.siano は、無改変のバイナリ形式での再配布を許可する一方、著作権表示の再現を求め、リバースエンジニアリングを禁じています。実行ファイルへ埋め込むと「無改変のバイナリ」ではなくなるため、Releases ではバイナリの隣にファイルとして置いています。linux-firmware と同じ mere aggregation です。

出発点

PX-S1UD は Siano RIO の地デジUSBドングルで、Linux ならカーネルの smsusb / smsdvb/dev/dvb を生やしてくれます。うちではそれを mirakc に渡して録画していました。

その録画に、映像のブロックノイズと音声の飛びが乗ります。電波を疑って C/NUCB も見ましたが、どちらも問題ありません。USBハブが犯人だと思い込んで配線を組み替え、それでも直りませんでした。

本丸は smsdvb-debugfs.c にありました。debugfs のバッファに sysfs_emit_at() を使っています。この関数は sysfs の show() 向けで、渡されたバッファがページ境界に乗っていないと WARN を出し、何も書かずに帰ります。debugfs 側のバッファは構造体の中にあるので、境界には決して乗りません。

つまり統計を受け取るたびに WARN が出ます。しかもそれが走る場所は URB完了の bottom half で、ここは同じコントローラ配下の USB が共有しています。TS の取りこぼしと lsusb のスタックと /var/log の数十 GB は、まとめて同じ原因から出ていました。

debugfs を外して smsdvb だけ差し替えたところ、同じ 15 分で ffmpeg の corrupt は 545 件から 5 件に落ちました。この残った 5 件が何だったのかは、後で測り直したときに分かります。いずれにせよカーネルを上げるたびにモジュールを焼き直すことになりますし、Home Assistant OS のようにカーネルを差し替えられない環境では、その焼き直しすら選べません。

そこまで来て、作り直すことにしました。

測って比べた

「カーネルを捨てたが、代わりに品質を落としていないか」を確かめないと意味がありません。同じマシン・同じチャンネル・同じデコーダで、カーネル経路とユーザ空間経路を 5 分ずつ 交互に 3 本ずつ取りました。交互にしたのは、時間帯による電波と負荷の変動を相殺するためです。

マシンは手持ちで最も非力な Atom のスティック PC です。mirakc は止めて、ドライバから recisdb へ直接つないでいます。サービスフィルタもバッファリングも挟まないので、差が出るならドライバの差です。

秒数 ffmpeg の Packet corrupt 件/分 CC 誤り sync 外れ TEI
kernel-1 297 1 0.20 0 0 0
kernel-2 297 1 0.20 0 0 0
kernel-3 298 3 0.60 0 0 0
userland-1 300 3 0.60 0 0 0
userland-2 298 3 0.60 0 0 0
userland-3 298 2 0.40 0 0 0

カーネル経路が 0.34 件/分、ユーザ空間経路が 0.54 件/分。数字だけ見るとユーザ空間のほうが 1.6 倍悪い、と読めます。

ところが 6 本すべてで連続性カウンタの飛びが 0、sync 外れが 0、TEI が 0 でした。1 本あたり約 320 万パケットあって、トランスポート層では 1 つも落ちていません。それなら ffmpeg は何を corrupt と呼んでいるのか。

位置を出しました。12 件すべてが 297〜298 秒目、つまりキャプチャの最終フレームに集中しています。先頭には 1 件もありません。正体は timeout がプロセスを切った瞬間の書きかけのパケットで、受信品質とは関係ありませんでした。ユーザ空間側が多いのは、siano-tsrecisdb とパイプ段が 1 つ多いぶん、切断時にバッファへ残る量が大きいからだと思われます。

つまり 5 分の窓では、両者とも欠落ゼロです。「カーネル版と同等」ではなく「どちらも定常状態では落としていない」というのが実測でした。冒頭で debugfs を外したあとに残った 5 件も、同じ切断アーティファクトだったと考えるのが自然です。

ひとつ、計測の落とし穴を書いておきます。先頭を捨てて数えようとして ffmpeg -ss 10 を使うと、corrupt が増えます。この 6 本を grep -c corrupt で数えると、通常が合計 15 件なのに対し -ss 10 では 35 件でした。生の TS の途中へシークすること自体が不連続を作るためです。先頭を捨てたいならバイト単位で切ってください。そちらで切って数え直すと、連続性カウンタの飛びは 0 のままでした。

まだ残っていること

上の比較は 5 分の窓の話です。長時間になると別の顔が出ます。 別のマシン(Core i5 のノート)で siano-ts に 2 局を同時に 3 時間流したときは、ハングも sync 外れも TEI も無かった一方、連続性カウンタの飛びが 423 件と 527 件ありました。こちらはユーザ空間側だけの計測で、カーネル経路の 3 時間は取っていません。10 分の窓で見ると 0〜85 件とばらつき、時間とともに単調に増えるわけではありません。両局とも最初の飛びが同じ時刻に出たので、ホスト側の一時的な停滞だと見ています。末尾 10 分を目視すると僅かなブロックノイズがありました。

つまり「5 分なら完全、3 時間だと数百件」です。ここをゼロにする作業には手を付けていません。普通のテレビとの比較も合否にはしていません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?