a tiny patch for recpt1/tssplitter_lite.c

| No Comments | No TrackBacks

年明けに northeye さんに代理購入して頂いていたのに、半年も受け取る機会に恵まれず(長らくすんませんでした)、結局7月3日に無事受け取りを済ませた PT2

その後も箱に入れたままになっていましたが、8月12日に1998年製造のブラウン管アナログテレビがついに壊れてしまい、安い REGZA (32R1) を購入したのを機に、うちに転がっていた古いキューブ型PCにやっとこさ取り付けたのが8月20日。

いまなら linux カーネルに入っている DVB 版ドライバ を使うのが素直なんでしょうが、そのキューブ型PCに入れたのがたまたま VineSeed (linux-2.6.35) ではなく Vine 5.1 (linux-2.6.27) だったため、なんとなく 以前からある方の chardev 版 PT1 ドライバ で環境を構築しました。

tssplitter_lite 相当の動作が内包された recpt1 もお手軽でいい感じですし、これまたお手軽操作の epgrec も悪くない。

が、WOWOW の SD 放送の録画でちょっと面倒臭いことになってしまい、時間を見つけてはあれこれ調べていました。以下経緯と経過。





そもそも私が PT2 を購入した最大の動機は、もう20年以上前からしこしこやっている通り、テニスの試合を録画・保存するためです。現在は WOWOW (四大大会全部とその他小さな大会をときどき)、GAORA (マスターズ1000全大会とマスターズファイナル、ウィンブルドンダブルス、その他)、NHK 地上波 (ウィンブルドンなど) などでカバーされている男子プロテニスの試合放送ですが、ディジタル放送に切り替わると、編集したり保存したりするのがあれこれ面倒くさくなると思われるので。


それはさておき、WOWOW での四大大会放送ですが、現時点ではおおよそ以下のような感じで放送されています。

  • 1回戦〜準々決勝:BS 191ch, 192ch, 193ch で適宜 SD 放送
  • 準決勝、決勝:BS 191ch で HD 放送



WOWOW SD 16:9 放送って、なんか変?

この SD 放送のときがくせものです。例えば、


  Program 193 
    Stream #0.0[0x280]: Video: mpeg2video, yuv420p, 720x480
            [PAR 32:27 DAR 16:9], 15000 kb/s, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0.1[0x281]: Audio: aac, 48000 Hz, stereo, s16, 185 kb/s

となっているので、720x480 アスペクト比 16:9 で普通に放送されているのかと思いきや、実は上下額縁なのです。例えばこの映像を vlc などで再生しようとすると、720x480 アスペクト比 4:3 で表示して、上下をクロッピングすると、やっと本来意図された表示になります。WOWOW が、どうしてこのような方式で SD 16:9 放送をしているのかはよくわかりません。


不思議なのは、テレビでこのチャンネルを普通に視聴している分には、アスペクト比やクロッピングを特に微調整しなくとも、上下の額縁はなく 16:9 で表示されています。どうやら、BS 191/192/193ch の SD 放送で 16:9 と指定されているストリームは、テレビのチューナ側でクロッピングし、上下に引き伸ばして表示しているように思えます(確かに 720x480 16:9 にしては荒い)。

事実、PT2 で録画した TS ファイルを DLNA 経由で REGZA で再生した場合、普通 (?) に 720x480 16:9 で表示されています(実際にはクロッピングして引き伸ばしているので、620x480 16:9 といった辺りでしょう)が、例えば TMPGEnc MPEG Editor 3 などでカット編集して出力した TS ファイルを DLNA 経由で REGZA で再生した場合、vlc で再生した時と同様に上下額縁状態で(横にアスペクトが引き伸ばされた様な見栄えで)表示されます。果たして、その TS は、チャンネル番号(正確には PID?)が変更されています。


なので、クロッピングしてアスペクト比をいじって再エンコードしたりしない限り、元の PID を保ったまま不要なチャンネルのストリームを削除した TS が欲しいわけです。もちろん、PC なり PS3 なりを HDMI 経由でテレビに接続して観るのであれば、こういったことを考えずに済むのでしょうし、最終的に保存するフォーマットの自由度も高まるのでしょうが、いまの我が家の環境で、PT2 で録画した映像を REGZA 32R1 で観るには、DLNA サーバ上に置いた TS をネットワーク越しに再生するしかないので、このような(やや不毛な?)ことを考えているのです。




tssplitter_lite が WOWOW SD 放送をうまく分割できない

そこでもうひとつの問題。tssplitter_lite 内包の recpt1 では、WOWOW の SD 放送時に --sid オプションで残したいチャンネルを指定しても、意図した通りの動作をしてくれないのです。従来の、単体バージョンの tssplitter_lite でも同じ。


  # 191 を指定しても、そもそも「Available sid」に現れておらず、
  # 実際に生成された TS も再生不能 
  $ ./recpt1 --b25 --sid 191 191 5 /tmp/191.ts
  using B25...
  pid = 8910
  C/N = 15.383486dB
  Recording...
  Available sid = 192 193 791 792 0 
  Chosen sid    = 192 193 791 792 0
  Recorded 5sec

  $ ffmpeg -i /tmp/191.ts
  (...中略...)
    /tmp/191.ts: could not find codec parameters

  # 192 を指定して、一見うまくいっているように見えるが、
  # 実際に生成された TS の PAT から 191 が削除されておらず、
  # よって REGZA などからは不正な TS と見なされ、再生できない
  $ ./recpt1 --b25 --sid 192 192 5 /tmp/192.ts
  using B25...
  pid = 9097
  C/N = 15.008206dB
  Recording...
  Available sid = 192 193 791 792 0 
  Chosen sid    = 192
  Recorded 5sec

  $ ffmpeg -i /tmp/192.ts
  (...中略...)
    Program 191 
    Program 192 
      Stream #0.0[0x240]: Video: mpeg2video, yuv420p, 720x480
              [PAR 32:27 DAR 16:9], 15000 kb/s, 29.97 tbr, 90k tbn, 59.94 tbc
      Stream #0.1[0x241]: Audio: aac, 48000 Hz, stereo, s16, 185 kb/s

もちろん、--sid オプションなしで録画した TS を、wine 経由で Tssplitter.exe に食わせれば、意図した通りの TS が生成されます。が、それはちょっと。

tsselect from.ts to.ts 0x0000 0x0240 0x0241 0x0201 0x0211」とかで吐き出した TS を REGZA が認識してくれればそれでもよかったのですが、残念ながら PAT が無修正なため、だめでした。


WOWOW 以外、例えば NHK BS1/BS2 などでは、意図した通りに動作しているようにみえます。--sid 指定で、101ch あるいは 102ch のいずれかだけが残り、PAT がそれにあわせて書き換えられた TS が生成されています。もちろん REGZA でも DLNA 経由で再生可能でした。


  $ ./recpt1 --b25 --sid 101 101 5 /tmp/101.ts 
  using B25...
  pid = 10439
  C/N = 14.838169dB
  Recording...
  Available sid = 101 102 910 929 
  Chosen sid    = 101
  Recorded 6sec

  $ ffmpeg -i /tmp/101.ts
  (...中略...)
    Program 101 
    Stream #0.0[0x100]: Video: mpeg2video, yuv420p, 720x480
            [PAR 32:27 DAR 16:9], 10500 kb/s, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0.1[0x101]: Video: mpeg2video, yuv420p, 352x240
            [PAR 40:33 DAR 16:9], 300 kb/s, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0.2[0x110]: Audio: aac, 48000 Hz, stereo, s16, 131 kb/s
    Stream #0.3[0x112]: Audio: aac, 48000 Hz, mono, s16, 63 kb/s
    Stream #0.4[0x111]: Audio: aac, 48000 Hz, stereo, s16, 162 kb/s
    # 降雨対応モードの低画質映像 (0x0101) と音声 (0x0112) が残ったままですが、
    # この際いいことにしておきます

先程上に書いたこととも重なりますが、現在私がやりたいのはこういうことです。

  • WOWOW SD 放送 (BS 191/192/193ch) の望むチャンネルだけが残され、
  • PAT 情報がそれにあわせて適切に書き換えられていて、
  • ストリーム PID は書き換えられていない、
  • TS ファイルを、
  • Linux 上で生成したい。

で、本来これを行ってくれるはずの、tssplitter_lite 内包の recpt1 が、どういうわけか WOWOW SD 放送に関してはうまく --sid 指定で意図した通りに動いてくれない、と。




仕方がないので

web 上に転がっている情報、例えば

や、それらからたどることのできる

などをありがたく拝読しながら、実際に録画した WOWOW SD 3チャンネル同時放送中の TS ストリームの16進ダンプと比較しつつ、現時点での最新版 38a793ac3d9drecpt1/tssplitter_lite.c のコードを眺めることに。


0x47 で始まる188バイトごとの TS パケットのうち、PAT の (先頭を0バイト目として) 13バイト目から4バイトごとに PMT 情報が格納されています。この PMT 情報4バイトの下位13ビットが PID となります。そして一連の PMT 情報の直後に CRC 4バイトが入ります。

以下、いくつかのチャンネルにおける、PAT のペイロード部分における PMT 情報を抜き出したものです。


NHK デジタル総合 (1ch) の PAT パケットに含まれる PMT PID はこんな感じ。

00 00 e0 10        # PMT PID 0x0010 - Network
04 00 e1 f0        # PMT PID 0x01f0 - Program 1024 (NHK デジタル総合1)
04 01 e3 f0        # PMT PID 0x03f0 - Program 1025 (NHK デジタル総合2)
05 80 ff c8        # PMT PID 0x1fc8 - Program 1408 (NHK デジタル総合ワンセグ)
ff f0 fc f0        # PMT PID 0x1cf0 - Program 65520 (?)

NHK BS 放送 (BS 101/102) の PAT パケットに含まれる PMT PID はこんな感じ。

00 00 e0 10        # PMT PID 0x0010 - Network
00 65 e1 f0        # PMT PID 0x01f0 - Program 101 (NHK BS1 SD)
00 66 e2 f0        # PMT PID 0x02f0 - Program 102 (NHK BS2 SD)
03 8e f9 01        # PMT PID 0x1901 - Program 910 (BSウェザーニュース)
03 a1 e7 01        # PMT PID 0x0701 - Program 929 (Dpa エンジアリングストリーム)

BS 日テレ (BS 141) の PAT パケットに含まれる PMT PID はこんな感じ。

00 00 e0 10        # PMT PID 0x0010 - Network
00 8d e1 01        # PMT PID 0x0101 - Program 141 (BS 日テレ)
00 8e e2 01        # PMT PID 0x0201 - Program 142 (BS 日テレ)
00 8f e2 03        # PMT PID 0x0203 - Program 143 (BS 日テレ)
02 e8 e4 05        # PMT PID 0x0405 - Program 744 (データ放送)
02 e9 e4 06        # PMT PID 0x0406 - Program 745 (データ放送)
02 ea e4 07        # PMT PID 0x0407 - Program 746 (データ放送)

WOWOW HD 放送 (BS 191) の PAT パケットに含まれる PMT PID はこんな感じ。

00 bf e1 01        # PMT PID 0x0101 - Program 191 (WOWOW HD)
00 c0 e2 01        # PMT PID 0x0201 - Program 192 (WOWOW HD)
00 c1 e2 03        # PMT PID 0x0203 - Program 193 (WOWOW HD)
03 17 e4 02        # PMT PID 0x0402 - Program 791 (データ放送)
03 18 e4 03        # PMT PID 0x0403 - Program 792 (データ放送)
00 00 e0 10        # PMT PID 0x0010 - Network

で、WOWOW SD 放送 (BS 191/192/193) の場合も上と同じ。

00 bf e1 01        # PMT PID 0x0101 - Program 191 (WOWOW1 SD)
00 c0 e2 01        # PMT PID 0x0201 - Program 192 (WOWOW2 SD)
00 c1 e2 03        # PMT PID 0x0203 - Program 193 (WOWOW3 SD)
03 17 e4 02        # PMT PID 0x0402 - Program 791 (データ放送)
03 18 e4 03        # PMT PID 0x0403 - Program 792 (データ放送)
00 00 e0 10        # PMT PID 0x0010 - Network

で、recpt1/tssplitter_lite.c を眺めてみると、以下のようなコードがありました。PAT 解析を行う関数 AnalyzePat() 内で、SID/PMT をプリスキャンする箇所です。

                /* prescan SID/PMT */
                for(i = 17, j = 0; i < (size + 8) - 4; i = i + 4, j++) {
                        avail_sids[j] = (buf[i] << 8) + buf[i+1];
                        sp->avail_pmts[j] = GetPid(&buf[i+2]);
                }

ん、なんで 17 から始まってるんだ? 13 ちゃうの?


恐らくこういうことでしょう。tssplitter_lite の作者さん(あるいはその元となった tss.py の作者さん)が、13バイト目〜16バイト目は「00 00 e0 10」、すなわちここに現れる PMT PID は必ず 0x0010 (NIT: Network Information Table) なので、それは無視して 17バイト目からみるようにした、と。

ところが先程上に載せた通り、WOWOW の TS では、最初に現れる PMT 情報内の PID は 0x0010 ではないのです。逆に CRC 4バイトの直前、最後に現れる PMT 情報がそれにあたります。一連の PMT 情報のうち、必ずしも先頭4バイトが「00 00 e0 10」とは限らない、ということのようです。

なので、recpt1 実行中に「Available sid = 192 193 791 792 0」と出てしまっていたわけですね。先頭の 191 が欠けて、無視していたはずの(先頭にあると期待されていた)0 が出てきてしまった、と。




というわけで修正してみました

これで recpt1 を使った WOWOW SD 放送録画時に --sid 191 といった指定をすることで、正しく 191チャンネル分のみ切り出され、かつ PAT もそれにあわせて適切に修正された TS が生成されるようになりました(もちろん 192, 193 も同様に切り出せます)。

ただし、かなりアドホックです


具体的には、以下のような修正になります。

  • SID/PMT プリスキャン時に 17バイト目からではなく13バイト目から読み出す
    • その際、NIT が現れたら SID としては無視
  • PAT再構成の時、13バイト目〜16バイト目の4バイトを強制的に「00 00 e0 10」に書き換える



いちおう

どちらも当方の環境・当方の利用目的でのみ動作確認したものです。
くれぐれもご注意ください。



間違い、勘違いなどあればご指摘ください。






No TrackBacks

TrackBack URL: http://microgroove.jp/mt42/mt-tb.cgi/1001

Leave a comment

Pages

OpenID accepted here Learn more about OpenID
Powered by Movable Type 4.23-en

About this Entry

This page contains a single entry by Shaolin published on September 3, 2010 3:41 PM.

iScrob - a perfect replacement for iPod app was the previous entry in this blog.

懐かしの8ビットマイコンゲーム? is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.