Broadcomのmpeg encoder

いつもは行かないハードオフで8%消費税最後の見回りをして[PC-MV5/U2](http://buffalo.jp/products/catalog/item/p/pc-mv5_u2/index.html)を108円で購入。ACアダプタの束ね方から、一度も使われていなかったぽい。

[CX23416](https://qiita.com/yamori813/items/ba488fb0bab96191ff11)より前の製品のようだ。CX23416な製品はバスパワーで動くが、こちらはACアダプタ(6V 2A)が付属で、最大消費電力が500mA以上なのだと思われる。使ってみると結構発熱しました。

Pinnacle PCTV Deluxeとほぼ同じものらしい。

![41STNF60D2L._SX466_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/4580ab00-20d4-9af6-c958-8fe055205447.jpeg)

IO DataのGV-MPEG2/USB2も同じもののような気がします。

とりあえず分解してみたらBCM7040という初めて見るチップが出てきた。Broadcomは2001年にVisionTechというイスラエルの会社を買収していて、ここで開発されたチップのようだ。チップはマーキングから2002年34週の製造と思われる。

![写真（2019-09-14 15.27）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/ac0d0293-bb8d-ea6d-df53-81a93f83c705.jpeg)

デバイスの構成はこんな感じになってる。

![Kfir.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/f3f466bd-a542-c83d-bb97-a3bdff6d959a.png)

Pinnacle PCTV Deluxeには赤外線リモコン受信機能が付いたモデルがあったようだが、PC-MV5/U2ではパターンはあるが未実装だった。

ネットでいろいろ検索してみたらLinuxで試した人がいた。

https://jeltsch.org/pinnacle_linux?language=fi

オリジナルのドイツのRainer Keuchelさんのページはリンク切れで[Internet archiveにはあった](https://web.archive.org/web/20050204014715/http://www.paranoyaxc.de:80/dune/dune.html)。

CX23416に比べ情報が極端に少ない。CX23416にシェアーを取られて生産数が少なかったのかもしれない。

Windows7で製品付属のWinDVRを試してみたら色がおかしい。壊れてるのかな。。。

![oooo.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/83fd93d9-a27a-29c0-046f-e005305964a6.jpeg)

CX23416を使った製品と同じようにEZ-USB FX2用のfirmwareとBCM7040用のfirmwareがあり、EZ用のfirmwareはWindowsのドライバ(SYS)の中にあり、BCM7040のfirmwareは別ファイルとしていくつか用意されている。

上記のページのソースをInternet archiveからダウンロードして確認してみた。

LinuxとWindowsのコードでWindowsのドライバからfirmwareを抜き出してダウンロードして、再度プログラムを起動してBCM7040のfirmware(ucode)をダウンロードするように作られている。 15年くらい前のコードなのでlibusb 0.1系のコードで1.0系ではそのままではビルドできない。WindowsのコードはEZ-USBのドライバを介してUSBアクセスをしているようだ。

コードのNTSCデコーダーはSAA7114になっていたのでPinnacle PCTV Deluxeはこのチップを使っていたようです。

CX23416を使った製品は初期状態ではEZ-USBのVID/PIDが見えてます。この製品はEEPROMが付いていて、初期状態でも製品のVID/PIDになっていてfirmwareをダウンロードしてもVID/PIDは変わりません。ダウンロードされているかされてないかの判断はシリアルがあるかないかを確認しています。

EZ-USBのfirmwareは特殊なフォーマットで入っていて、1レコードが22バイトでヘッダーが5バイトで2バイトのアドレスとサイズがあり、1バイトがレコードが続いているかの属性を持つ。 6バイト目からデータになる。Windowsのドライバをスキャンして先頭の32ビット値を探し出すコードになっている。既存のコードの値と違っていたのでWiresharkでUSBをsnoopしてこの値を拾い出した。

当初新たに書き直そうかと思ったのだが、オリジナルコードにはあまりエラーがなかったのと簡潔に手を入れられそうだったのでlibusb 1.0対応など、いろいろいじってたら突然キャプチャできるようになりました。

![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/da3f2595-af5d-f899-5a88-7cbe2672913e.png)

https://github.com/yamori813/dune2-macos

ざっくりビルド方法は以下の通りです。

libusb 1.0をビルドしてinstall_name_toolでライブラリのパスを書き換え、ライブラリとヘッダーをdunelibにコピーしてmakeする。

```
$ make -f Makefile.mac
```

メーカーのサイトにあるドライバ(1.31)のPcMv5U2.sysをdune.sysとしてdunetools/dunerecにコピーする。k2.vなどのファイルもコピーする。libusbのライブラリをコピーするかリンクをはっておく。これでmakeする。

```
$ make -f Makefile.mac
$ ./dunerec 
DuneRec Version 1.0
Usage: ./dunerec [-d <level> -v]
 -R <outfile|-> | -S <flags> | -I <flags>
 [-a <freq>
 [-c <configfile>]
 [-i <inputsource>]
 [-s <seconds>]
 [-m <maxfilesize>
 [-t <dvd|dvdlong|dvd5mbit|svcd|vcd|svcd2|vcd2>]
 [-x <pal|ntsc>]
 [-z]
```

1度目の起動でEZ-USBのfirmwareがダウンロードされて終了します。インジケータが点滅から点灯に変わります。もう一度起動するとキャプチャーが開始されます。iオプションは入力切替で0がチューナーで1がS端子で2がコンポジットです。

```
$ ./dunerec -i 2 -x ntsc -R test.mpeg
Loading ezusb2 firmware...
You have to restart the program!
$ ./dunerec -i 2 -x ntsc -R test.mpeg
EZUSB2 FW Version: 2 Microcode Version: MPEG2.02.27b
```

一度キャプチャーすると二度目は画面が真っ黒になり失敗します。なんらか初期化に問題があるのだと思われます。アナログ地上波はドイツではPALでNTSCはサポートしたけどあまりチェックされてない可能性があるかもしれない。かろうじて動いているような感じです。

CX23416の[mpegcapt](https://github.com/yamori813/mpeg-usb/blob/master/mpegcapt.c)は非同期(ASYNC)でBULKを読んでいますが、こちらは同期(SYNC)でBULKを処理しています。

いじると変わるのかもしれませんが、後継製品のCX23416の方が画質がシャープな気がします。

FreeBSDでもコンパイルできて動きました。

オリジナルの作者のRainer Keuchelさんはメーカらかの情報提供無しによくこれだけ調べられたと思います。感謝します。

いろいろ調べてみるとハードウエアMPEGエンコードモジュールのチップは C-CUBE(LSI) Dvxplore -> ZORAN ZR36120 -> GlobeSpan iTVC12 -> Broadcom BCM7040, WISchip GO7007 -> Conexant CX23416というように変遷したようだ。PioneerやNECも作っていたようです。USBのソリューションはGlobeSpan以降のチップになる。これはUSB 1.0では帯域が不足していて、2.0が普及してからになったためだと思われる。CX23416の前にモジュール側ではキャプチャだけして、PCの方で[ソフトウエアでエンコードする製品](https://qiita.com/yamori813/items/7e26a57e37b2fb8bdd30)もありました。これはPC側が十分に高速になったからかもしれませんが、NTSCといえども素のデータをUSBで流すのは結構な負荷になるので、ハードウエアエンコードのほうが良い気がします。

謎なのはPC-MV5/PCIと型番が近い製品でなぜかDvxploreが使われているようです。PC-MV5DX/U2という製品もあってひょっとするとこれと同等なのかもしれません。

以前焼いたDVDがメディアの変質やドライブの劣化で読めなくなってるものが複数あります。MacのHDに残したほうが安全な気がします。

録画していると、結構飛ぶことがあります。たかだか6Mbpsくらいのストリームがハードディスクに書けないことはないはずなのですが。setvbufで設定しているサイズを大きくしたら良くなった気がしますが、負荷をかけると飛びます。

dtraceのfs_usageで見てみました。

```
09:50:23  write                                         0.000016   dunerec     
09:50:23  read                                          0.000004   dunerec     
09:50:23  write                                         0.000017   dunerec     
09:50:23  read                                          0.000004   dunerec     
09:50:23    HFS_update                                  0.000022   dunerec     
09:50:23    HFS_update                                  0.000014   dunerec     
09:50:23  write                                         0.002012   dunerec     
09:50:23  write                                         0.000016   dunerec     
09:50:23  read                                          0.000004   dunerec     
09:50:23  write                                         0.000013   dunerec     
09:50:23  read                                          0.000003   dunerec     
09:50:23    HFS_update                                  0.000021   dunerec     
09:50:23  write                                         0.000183   dunerec     
09:50:23  write                                         0.000015   dunerec     
09:50:23  read                                          0.000004   dunerec     
09:50:23  write                                         0.000016   dunerec     
09:50:23  read                                          0.000004   dunerec     
09:50:23    HFS_update                                  0.000022   dunerec     
09:50:23  write                                         0.000168   dunerec     
09:50:23  write                                         0.000016   dunerec     
09:50:23  read                                          0.000004   dunerec     
09:50:23  write                                         0.000017   dunerec     
09:50:23  read                                          0.000004   dunerec     
09:50:23    HFS_update                                  0.000023   dunerec     
09:50:23  write                                         0.000208   dunerec     
09:50:23  write                                         0.000016   dunerec     
09:50:23  read                                          0.000004   dunerec     
09:50:23  write                                         0.000014   dunerec     
09:50:23  read                                          0.000003   dunerec     
09:50:23    HFS_update                                  0.000001   dunerec     
09:50:23  write                                         0.000666   dunerec     
09:50:23  write                                         0.000015   dunerec     
09:50:23  read                                          0.000004   dunerec     
09:50:23  write                                         0.000013   dunerec     
09:50:23  read                                          0.000003   dunerec     
09:50:23    HFS_update                                  0.000001   dunerec     
09:50:23  write                                         0.000576   dunerec     
```

1秒に800KByteとしてsetvbufで設定している128Kのバッファで実質6回くらいのwriteになる。libusbのbulkは64Kで読んでいるので12回。

libusbの同期での処理では限界なのかな。。。

VHSビデオのキャプチャーサンプルアップしました。
https://youtu.be/wKOvgeBJdLA