日々

 TS読み込みプログラムは昨日PCRを元に録画時間を求める処理が上手く動作していないことを確認したので原因を調査。すると、関西テレビPSYCHO-PASS サイコパス 3の最終回を保存したTSファイルの番組先頭から4分35秒あたりで、PCRのラップアラウンドが発生しているのが確認できた。
 PCRのPIDは0x0100で、PCR baseは33537800、33543005、33553415と5205ずつ増えていたのに、次は33558620にならず4188になっている。33558620は2進数で10000000000001000001011100‬、4188は2進数で1000001011100なので、末尾25bitは一致している。
 PCR baseは33bitあるけれど、放送局側の機材などの都合で25bit(6分13秒弱ごと)でラップアラウンドする場合もあるってことなのかも知れない。
 ただ、こういう事例を見ると何bitでラップアラウンドが発生するか判らないので、前回の値から(今回の例だと33553415=1111111111111110000000111)次の値(今回の例だと4188=1000001011100)に加える値(10000000000000000000000000)を求める方法を考えなければならない。
 要は最も上位にある1であるビット以下が全て1ならば簡単に求められる。1bit長の場合は1なら1だと判るのでいいが、2bit長の場合は10や11なら11だと判るようにしたいので、1ビット右シフトして(10なら01)元の値と論理和(OR)を取れば(10なら10と01で11)良いことになる。
 4bit長の場合は次に2ビット右シフトして元の値と論理和を取れば(1000なら0100で1100、1100なら0011で1111)良いことになる。8bit長なら次に4ビット右シフトのように続けていけば答えは出る。C言語で33bit以上(64bit)までに対応する処理を書くと以下のようなカンジ。

n=n|(n>>1);
n=n|(n>>2);
n=n|(n>>4);
n=n|(n>>8);
n=n|(n>>16);
n=n|(n>>32);
n=(n^(n>>1))<<1;

 最後に1ビット右シフトして元の値と排他的論理和を取れば(1111なら0111で1000)最も上位にある1であるビットのみを残した値になるので、これを1ビット左シフトすれば(1000なら10000)求めていた値が得られる。ビット演算まとめに書いてあった方法を使わせてもらった。
 PCRで録画時間を正しく求めることが出来るようになったところで、PCRが現れるまでと、PCRが最後に現れた後のバイト数あたりの時間を求める処理を追加、これでかなり正確な録画時間を求めることが出来るようになった。
 ここでTOTから求めた現在日時をPCRで補正することで録画開始日時と録画終了日時もかなり正確に求めることが出来るようになったところで本日は終了。
 定時後、第二神明で帰宅。晩御飯はとんかつとポタージュスープ。未読軽くした後に眠くて、こたつソファで横になって寝る。夜9時半頃に起きる。何やらソファからZenFone Max Pro(M1)のものと思わしき、SIMトレイ取り出しピンが出てきたので母親に渡す。
 お茶入れてもらって一服しつつ、今月出かける予定とか3月に出かける予定とかのハナシとか。