ラベル 24時間ワンセグ野郎 の投稿を表示しています。 すべての投稿を表示
ラベル 24時間ワンセグ野郎 の投稿を表示しています。 すべての投稿を表示

2008年2月17日日曜日

(メモ)DUS01まとめ

忘れる前にワンセグチューナーDUS-01の挙動についてメモしておく。半分は自分のため、あとの半分は「24時間ワンセグコミュニティ(?)」のため。Linuxやwindowsで使うときにどうぞ。

ハードウェア

  • CPU: Silicon Laboratories C8051F342
  • チューナー: sharp VA1A5JZ9902A (参考リンク:ascii24)
  • アンテナ:ロッドアンテナ
  • インターフェイス: USB1.1
シャープの9902Aは1-2世代前のワンセグモジュール。最新版には及ばないが感度が-107dbmは優秀なんじゃないかと思う。googleで探したけど仕様書等は見つからなかった。残念。

USBデバイス情報
USBデバイスとしては、こんな感じ。ほかに何をかけばいいのかな。
  • Vendor ID:0x1bc8 , Product ID:0x0001
  • endpointは0,1,2,3の4本。
  • EP1は制御用のバルク転送エンドポイント(読み書き可能)。
  • EP3はMPEG2TS転送用のアイソクロナス転送エンドポイント(読み込み専用)
  • EP2は使っているのを見たことないけど、ファームウェアアップデートなどに使うのじゃないかと推測
  • 起動時にファームウェアロードなどは発生しない。電源を入れれば動く。

さらに詳しく知りたい人のためにNetBSDのusbgenの出力を載せておく。
CONFIGURATION descriptor index 0:
bLength=9 bDescriptorType=2 wTotalLength=46 bNumInterface=1
bConfigurationValue=1 iConfiguration=0 bmAttributes=80 bMaxPower=150 mA

INTERFACE descriptor index 0, alt index 0:
bLength=9 bDescriptorType=4 bInterfaceNumber=0 bAlternateSetting=0
bNumEndpoints=4 bInterfaceClass=0 bInterfaceSubClass=0
bInterfaceProtocol=0 iInterface=0

ENDPOINT descriptor index 0:
bLength=7 bDescriptorType=5 bEndpointAddress=1-out
bmAttributes=2 wMaxPacketSize=64 bInterval=5

ENDPOINT descriptor index 1:
bLength=7 bDescriptorType=5 bEndpointAddress=1-in
bmAttributes=2 wMaxPacketSize=64 bInterval=5

ENDPOINT descriptor index 2:
bLength=7 bDescriptorType=5 bEndpointAddress=2-out
bmAttributes=2 wMaxPacketSize=64 bInterval=5

ENDPOINT descriptor index 3:
bLength=7 bDescriptorType=5 bEndpointAddress=3-in
bmAttributes=1 wMaxPacketSize=188 bInterval=1


制御コマンド
制御コマンドはEP1をつかってやりとりする。今のところ分かっているコマンドはこれだけ。全部推測なので正しいかはわからないけど。
  • ファームウェアバージョンチェック (0x9f) - 現在のファームウェアのバージョン(1.0.0)が返ってくる。
  • チャネル設定 (0x10) - これに加えてKHz単位の周波数をくべるとチューナーが設定される。
  • 入力検出(0x11) - 電波が受信できていたら0x1、受信できなければ0x0が返ってくる。
  • ストリームモードチェック(0x12) - たぶんMPEG2TSストリームを出しているかしないかをチェック。
  • ストリームスタート (0x20) - EP3へのMPEG2TS出力を開始する。
  • ストリームストップ(0x21) - EP3へのMPEG2TS出力を停止する。
  • シリアル番号チェック(0x43) - デバイス固有のシリアル番号を返す。
(2008/2/18 1:30修正:miroさんありがとうございました。)

それぞれのコマンドは10byte長で、先頭にコマンドを、引数がないものは0x0で埋めて送る。
チャネルを変えるときのシーケンスは
  • ストリームが出ていたら止める
  • 止まったかモードをチェックする
  • チャネル変更リクエストを出す
  • ちょっと待つ
  • 入力検出リクエストを出す
  • 返り値をチェックして0x0だったら「ちょっと待つまで戻る」。0x1が出るまでがんばる。(もしくはタイムアウトする)
  • ストリームを出力する
って感じ。チャネル設定コマンドは、{0x10, 0x04, 0x00, A, B, C, 0x00, 0x00, 0x00, 0x00} というフォーマットで、A,B,CにKHz単位の周波数を指定する。たとえば、521.43MHz(チャンネル21)なら{0x07, 0xf3, 0xb7}を埋め込めば良い。
(2008/2/19修正:チャネル設定コマンドの例の先頭バイトをtypoしていたので修正)

出力ストリーム
EP3からはMPEG2TSもどきが出力される。先頭はMPEG2TSで規定された同期ビット列(0x47)でかつ、パケット長が188Byteというのは良いのだが、MPEG2TSとして解釈すると全部エラーになる、という変な状態。きっと、プログラムミスでこうなってしまっているのだろうとおもう。あまりにも不憫なので正しいストリームに治してあげよう。
「先頭の0x47を除いて、他のバイト列に対して0xb5を排他的論理和を取る。」
すると、普通のMPEG2TSになる。

まとめ
USB的には、「USBデバイスとしてのJ200への不満」、はほぼ解決されているようなデバイスだった。最初はストリームが見えるか少しどきどきしたが、まあすぐにわかってよかった。
まだ入手性もよいみたいだし、ここにある情報を使えば他にも対応ソフトを作れそうな人がいると思うので、いけているデバイスじゃないかと思う。明日もう少し補充を(自分用に)買っておこう。。

NetBSDで「24時間ワンセグ野郎」(新デバイス)(3)

新デバイスさらに続き。

バイトストリームを眺め続ける人生にもちょっとだけ疲れたので、ここらで絵(と音)でも見てみたい、という願望が大きくなってきた。というわけで、ちょっと真面目に絵と音声を見る部分を書いてみることにした。もし絵とか音声が見えたら、それがちゃんとしたMPEG2TSストリームとして扱えているか?っていう検証になるし。(バイトストリームを検証するためにはちゃんとパーサーと表示系をいちいち書かないといけないから、すぐには対応できないし)
というわけで、新デバイスでも生TSをキャプチャして録画までできることを確認できた。(絵は今とったらこれだった、てだけ、意味はないです)。ワンセグチューナさわっていて初めてまともに絵を見たよ。

下手に書いちゃって動かないのに買っちゃう人がいたら災難だから「新デバイス」とだけ書いていたけど、これで今まで伏せていた製品名をかける。写真のRockridgesoundのDitune(DUS-01)が最近触っていたデバイス。秋葉原だと3000円弱で買える&結構店頭に並んでいるので見たことがある人も多いかもしれない。
外部アンテナはつながらないけど、選択肢の一つとしてはいいかな、と思っている。

NetBSDで「24時間ワンセグ野郎」(新デバイス)(2)

新デバイスの話再び。

前回のエントリー(NetBSDで「24時間ワンセグ野郎」(新デバイス))に、生TSっぽいのが出ているとかいてしまったが、ちょっと寝てから冷静に見直してみると、なんか変だということに気がついた。

簡単にいえば、「先頭の0x47以降は本来受信したはずのデータ列と異なっている」ようだ。キャプチャされたTSの解析結果も載せてあったので、鋭い人なら一目で気がつくような気もするけど、異様にフラグが多かったり、アダプテーションフィールド長が255だったり、(あそこには含まれていないけど、PIDが0x1fffを超えていたり)、していた。

また、

  • だいぶ感度が悪そう。ちょっと、置き場所を変えるだけで、MPEG2TSのパケットでTS_ERRORフラグが立ってしまう。あんまり頻度が高いと、TS_ERROR付きでも眺めてみる、みたいな処理に変えないといけないかもしれない。
とも書いていたが、これもTS_ERRORビットの値がずれているのが問題だったようだ。値を読み替えてからみてみると、感度はそんなに問題ないみたい。

幸いにもMPEG2TSヘッダは固定長で単純かつ、特定の部分に決まった情報が出やすいという特徴があるので、しばらく眺めていると変換のパターンは見えてくる。もう少し解析しないとだめだけど、今のところ、「各バイト単位で特定の値で排他的論理和をとる」っていう単純なルールでもとに戻るようだ。(コンティニュティカウンタの値が1->0->3->2->5と進むところで、XORじゃないか、って推測できたのが決め手だった)。

というわけで、今度こそ生TSだと思われる出力。それっぽくなった。
これで、MPEG2TSパーサーに戻れる。

2008年2月16日土曜日

NetBSDで「24時間ワンセグ野郎」(新デバイス)

このエントリーの一行まとめ: 使えるUSBワンセグチューナーは、実はたくさんある、かも?

本家の昨晩のエントリーでふれられていた「一部で非常に不評なLOG-J200のUSB(笑)」をおもに専門に扱っている:)わけですが、そこに非常に気になる記述があった。

  • ちゃんとエンドポイントは分かれてるしTSのデータはアイソクロナスで送ってきているし ^^; なんといってもコントロールコマンドがシンプル簡単で使いやすい!(笑) それこそ他OSでいじるベースとしては便利そうな感触ですよ。USBXPressではなく今度はEZ-USBベース、そして実売価格は3000円。探せばいろいろあるものです。

しかも入手性がいいようなので注目に値する情報だ。これで、24時間ワンセグ野郎コミュニティ(?)もさらに盛り上がるに違いない。
と、そのエントリーを読んだのが午前2時半すぎ。それまでは、ARIBの資料を眺めながらワンセグのMPEG2TSストリームの制御情報を処理する部分をつらつらと書いていたのだが、デバイスを触りたい気分がいきなり盛り上がってしまった。私も実は、その辺でみかけるたびにUSBデバイスを買ってあって、そろそろ家があふれそうだったりしているので、そのなかでまだ開けていなかった箱をいくつか取り出してUSBストリームを眺める、という作業に従事してみた。

2-3種類眺めてみると、やっぱりいろいろと特徴が見えてくる、その辺の話はまた今度まとめる機会を探すとして、また新しく「188byte単位の情報転送 & 先頭バイトが0x47」のストリームを吐くチューナーを見つけてしまった。俄然盛り上がったので、NetBSD用のデバイスドライバも書いてみた。(おかげで眠い)

このデバイスは、
  • CPUは8051ベース(シリコンラボラトリC8051F342)
  • チューナーはシャープ製
  • アンテナはロッドアンテナのみ
  • 眩しく光る青色LED付き
  • 3000円台のお得な値段で入手可能かも
というハードウェアで、基板を眺める限り、J200よりは出来がよさそう。挙動としては、
  • コマンド用のEndpoingとデータ用のEndpointがわかれている
  • データ用Endpointはアイソクロナス転送で188Byte単位で送ってくる
  • 初期化コマンド等はほとんどいらない。お行儀よくチャネル切り替えをすれば動く
  • 電波が安定するまではストリームを出力しない。チューナーがセットアップされたかどうかを問い合わせてみて0x1がかえってきたら、転送開始、みたいな処理をする。
というかんじで、この前のエントリに書いた不満はおおむね解消されているようだ。

ただ、気になるのが、まだソフトウェアが悪い可能性もあるので何ともいえないけど、だいぶ感度が悪そう。ちょっと、置き場所を変えるだけで、MPEG2TSのパケットでTS_ERRORフラグが立ってしまう。あんまり頻度が高いと、TS_ERROR付きでも眺めてみる、みたいな処理に変えないといけないかもしれない。付属のソフトではそんなに画像が乱れるみたいなことが頻発するわけではないので、もう少し調査が必要。
MPEG2TSのストリームはとれているみたいなので、もう少し調査して詳細をお知らせしたいとおもいます。というわけで、MPEG2TSストリームが出ている証拠も載せておきます。先頭バイトが0x47だけ、ってわけではないので安心。

2008年2月15日金曜日

(ワンセグ)電波時計(の特性)


一発芸のつもりだった「ワンセグ電波時計」だったが、もう少し詳しく特性を調べてみることにした。
ARIBの仕様書では時刻情報(TOT)のデフォルト送出間隔は5秒と決まっているらしいが、その5秒刻みというのがどのくらい正確なのか?というあたりを知りたくなったからだ。

前回のエントリーではNTPで同期しているNetBSDの時刻情報と並べて表示していたが、今回はgettimeofday()を使ってマイクロ秒単位でTOTとTOTの間隔を計測してみた。108個(つまり540秒ほど)連続して受信したTOTの間隔の統計的な値を表に示しておく。

思っていたよりも精度が高いようで、うまくつかえば結構便利かもしれないな、と別の野望も妄想中。簡単な機材で大域時刻同期ができるって結構すごいことなんだよね。

2008年2月14日木曜日

NetBSDで「24時間ワンセグ野郎」(2)

さすがに平日はあまり時間が取れないので、あっと驚くような進捗があるわけではないけど、進んでいないというわけでもないので、メモがてらに書いてみることにした。Log-J200のUSBデバイスとしての感想など。

USBデバイスとしてのLog-J200
ざっくりいうとLog-J100もUOT-100も同じなんだが、どれもこれもUSBデバイスとしてみたときにはあまりいけているデバイスだとは言い難い。一言でいうなら、

  • USBデバイスのファーム設計のセオリーを見直してこい!
と、受け側のソフトを書きながら思わずデバイスに突っ込みをいれてしまうような、そんな仕様がいくつもある。たとえば、
  • 機能とエンドポイントの分離がうまくできてない、とか
  • コマンドを受理しても返答しない、という動作をするコマンドがある
  • なぜかbulk転送になっているMPEG2TSストリームの転送モード、とか
  • なぜか64Byte長で細切れな転送
とか。最初の「エンドポイントの使い方」は、endpoint0でやればよいようなデバイスの制御が、なぜかMPEG2TSストリームをやりとりしているendpoint2にのっている、とか、そのあたりが顕著な例。2つめも問題で、USBのホストコントローラ的には受理したならackを返してほしいと思っているのに、黙ってしまうのでコマンドがストールしたように見えてしまう。必ず受理される、と信じて送らないといけないのはどうかとおもう。
で、性能上問題になるのは3つめと4つめ。MPEG2TSのパケット長は188Byteで、空から約380KBps程度の速度でどんどんと情報が降ってきている。これを受け取るそばからUSBバスの上に流してあげる、というのがUSBワンセグチューナデバイスのお仕事。(たぶん)普通はこんな特性の情報を扱うためには、USBではアイソクロナス転送モードというのを使うことになっている。アイソクロナス転送にするとハンドシェイクやリトライをしないので時間制約に即した転送ができる、ので、次々に発生する事象(音とか映像とか電波とか)を扱うのに向いている。Log-J200(とその仲間たち)はなぜかMPEG2TSストリームの転送にBulkエンドポイントを採用している。Bulkエンドポイントでは転送サイズは64byteまでなので、188Byteの転送をするために少なくとも3回(J200の場合は4回)の転送要求発行しないといけない。

ちょっと計算してみるとわかるのだが、ワンセグのパケットは約1.2msくらいに一回の周期で受信される。つまり、1.2ms以内に4回のトランザクションを必ず発行するような動作をしていないと取りこぼしてしまう。
いまどきの速いコンピュータにとっては1msなんて無限な時間にみえるかもしれないが、実時間動作が苦手なUNIX系のOSではちゃんとやらないと実際に取りこぼしてしまう場合があった。

特に今回はugenをつかったユーザーランドアプリケーションとして書いてみているので、そのあたりは結構シビアだなあ、というのが感想。eggmanさんのlinuxデバイスドライバの話をみて、「やっぱりカーネルデバイスドライバのほうがかっこいいし、オーバーヘッド少なくなるからよいだろうなあ。」と思ったのは内緒だ。いつか気が向いたらkernelのデバイスドライバも書いてみよう。
でも、アイソクロナス転送のしてくれていれば、ユーザランドからさわってもこんなことは起こらないので、やっぱり設計に難がある、っていう気がしている。

ちなみに、内部バッファとかも持っていない設計になっているようで、USBデバイスへのポーリングが遅れるとデータの一部が化ける(nバイトシフトしているように見える&nバイト足りない)。最初は何で先頭にMPEG2TSの先頭バイト(0x47)が現れない場合があるんだろうか?と悩んでしまったが、USBアナライザの時間計測モードをつかってみたら、アクセス間隔がWindowsでみた場合とくらべて長いかった。
複数のkerenlへのリクエストをまとめるとか、小技を使って解決している。

Log-J200の受信感度
外付けアンテナがつくのであんまり問題にならないんだけど、受信したMPEG2TSストリームを数字で眺めていると、数パーセントの割合でエラーが出ているみたい。エラーとしては以下の3パターン。
  • そもそも受信できていない。MPEG2TSのカウンターを計測していると取れなかったことがわかる
  • MPEG2TSのトランスポートエラーインジケーターの値が1になっている。つまり、受信時に「このデータ使わないほうがいいじゃない?」と言ってきている
  • 先頭バイトが0x47じゃない。タイミング制約は満たしているはずだとは思うけど、たまに発生する
特にトランスポートエラーインジケーターは受信を開始してから200パケットくらいに全部ついているので、受信機が設定されてから正しいデータ出すまでに300msくらいはかかるってことかな?

NetBSDの24時間ワンセグ野郎の現状
とまあ、USBレベルでは取りこぼしもなく普通に受信情報を取り出せている。とりあえず受信データMPEG2TSの状態でファイルに書き出すこともできる。とまあ、そのくらい。いまは画像を眺めるというよりは、受信したストリームを数字で見ながら、ヘッダとかペイロードとかのいろいろな部分のパーサーとダンプ関数を書いてみて、「ほほー」とか言いながらにやけている状態。今日の参考資料はARIB-TR-B14(英語版)とかARIB-STD-B10(英語版)。なぜ英語かというと無料で公開されているから。(ARIBの英語版配布サイト

というわけで、外堀はほとんど埋まっているような感じですが、本家みたいな作りこみをできるまでには、まだしばらくかかりそうです。

最後に色気はないけど、動作中のテキスト出力など。ワンセグっていうことでPID=0x1fc8のパケット情報。本当になんかプログラムを書いている、ってい証拠に(なるかな?)。

== MPEG2TS header (PID:0x1fc8) -:P == Cont count:08, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:09, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:10, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:11, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:12, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:13, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:14, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:15, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:00, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:01, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:02, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:03, Flags PUSTART TRANSPRIO
== MPEG2TS header (PID:0x1fc8) -:P == Cont count:04, Flags PUSTART TRANSPRIO

2008年2月12日火曜日

NetBSDで「24時間ワンセグ野郎」(1)

MobileHackerz再起動日記で開発が進められている「24時間ワンセグ野郎」だが、ひと月ほど前のエントリーを見たときから「すげえ」素直に感嘆していた。「これはいけてる!」とおもって、その場でUOT-100を6本ほど買ってあった、ということからも(今はすでに入手困難だということを考えて)本当にぐっときたことは推測してもらえると思う。
ちょっと忙しくしていたので出遅れてしまったのだが、これができるということは、別のOS、たとえばNetBSDでも同じようなアプリケーションを構築できるんじゃないかとおもってやってみた、というのがこのエントリーの内容。
この3連休の時間で始めたことなので、本家の完成度には到底およばないけれど、最近一部でブームも盛り上がってきているようなのでちょっと参戦してみようと思う。

UOT-100を持っているから、といってもそれをそのまま使うのは二番煎じすぎる。本家にもなにか貢献できないかなーとおもって最近どこかで安いワンセグチューナを見かけるたびいくつかを購入してみていた。分解したり、USBのデータストリームを眺めていたりもしたのだが、まだ「これは!」という機種には出会えていない。
今回は、Log-J200をつかってワンセグ野郎をしてみることにする。
Log-J200はUOT-100と似たデバイスで、UOT-100と同様に「生TSをバス上に流している」ので、扱いが簡単だから、というのと、「まだ入手できるから」というのが理由。

いきなりkernelドライバを書いてもいいのだが、「ugenでラピッドプロトタイピング」という話も書いていたし、今回は

  • NetBSD ugenをつかったユーザランドアプリケーションで実装
  • ハードウェア改修なしに複数デバイスに対応
  • (できればネットワークサーバ化)
という感じでいってみている。

先に、現状を書いておくと、昨晩から24時間(当然途中では寝ているしごはんもたべてる)くらい経過したところで、
  • NetBSDで複数デバイス同時に認識
  • Windowsデバイスドライバには非依存
  • とりあえずチャネルは2チャンネルくらいは変更可能
  • 生TSだと思われるファイルを書きだしている(けど、まだみえない)
  • MPEG2TSの簡単なヘッダパーサを書いて、それなりにエラーハンドリングをできるようになりつつある
くらい。パケットダンプを見ている限り、それなりに正しくMPEG2TSのキャプチャはできているようにみえるので、あともう少しで画像がみえるか?という期待でここまで来ている、というところ。Log-J200は分解が大変(というか分解するとたぶん復元できない)ので、ハードウェアを触らなくてもいいというのは大きな利点じゃなかなと(個人的には)おもっている。

というわけで、現状報告を先にしておく。ソースをまとめたら公開予定(BSDライセンス)。
次のエントリーで解析した内容を書く予定。

週末の娯楽としては大変楽しめたし、これからもちょっと楽しめそう。がんばろう。