日々適当

hibitekitou

タイムコードのドロップフレームの計算

cg |2013-07-09
放送規格に歴史的な事情により日本の放送におけるフレームレートは29.97フレーム毎秒(59.94フィールド毎秒)でございます。そのため、タイムコードが微妙にややこしく、以下の決まりがあります。
ドロップフレームの場合、10分の倍数の時間以外の「分」ちょうどのフレームで2フレーム飛ばした数字を表示する。つまり、「分」ごとの表示を羅列すると

00:00:00:00
00:00:01:02
00:00:02:02



00:00:09:02
00:00:10:00
00:00:11:02




ってことです。これがTCを計算する方法を考えるときにややこしい事になる原因となっております。ノンドロップフレームの場合、時間はどんどんずれていきますけど、30フレームで1秒というルールで固定です。

以下、こちらにかかれている内容を、自分なりにかみ砕いてみたものです。

Time Codes

タイムコードからそれが何フレーム目(fN)か調べるには

tM = 60 * hours + mins
fN = 60 * 60 * 30 * hours + 60 * 30 * mins + 30 * secs + frames -2 * (tM - tM div 10)

と書けます。div は整数を整数で割った商、ついでに mod は整数を整数で割った余りです。
ノンドロップフレームで考えたときのフレーム数が

60 * 60 * 30 * hours + 60 * 30 * mins + 30 * secs + frames

で、ここから2フレーム引かねばならいタイミングが何回あったかを調べ(tM - tM div 10)、その回数と2フレームの乗算分だけ引いた値、というわけです。

フレーム数にしてしまえば、足したり引いたりは普通の四則演算ですね。

こうして必要なフレーム数を出したら、それをまたタイムコードの値に戻すわけですが、それがちょっとややこしい。

基本、タイムコードは毎秒30フレームのフレームレートの数値を表示したものなので、フレーム数 fN を毎秒30フレームのフレーム数に換算してやります。
しかし、単純に fN * 30 / 29.97ではよろしくなさそうです。

29.97フレーム毎秒のフレームレートなので、10分経つと、フレーム数は29.97 * 60 * 10フレームとなります。計算すると17982フレームです。ですから、10分置きの値は

D = fN div 17982
(10分なら 1 、20分なら 2 って感じ)

10分に満たない部分のフレーム数は

M = fN mod 17982

です。

10分に満たない時、そのフレーム数は、毎分2フレ飛ばした数字を表示するドロップフレームの特性上、毎分2フレーム少ない値になります。そう考えるとき、1分あたりのフレーム数は1798です(0.2足りないですが、10分置きに2フレーム減らす処理を省略することで足りない分を補完します)。ですから、10分に満たないフレーム数について、それが何分ぶんかを調べるとき、

(M - 2) div 1798

となります。
ただし、M - 2 < 0 の時、つまり、M = 0 か 1 の時、(M - 2)div 1798 は -2 か -1 になりますが、その場合、0が帰ってくるように設定します。
んで、30フレーム毎秒に換算するとき、フレーム数はその数と2の乗数だけフレーム数が増えるので fN に 2 * ((M - 2) div 1798) 足します。
さらに、10分置きの値 D を求めていますが、30フレーム毎秒に換算するとき10分置きに18フレーム増えるので※、さらに D * 18 を加えます。
※:毎分2フレーム増えるけど、10分置きに2フレーム増やす処理をしないから、2 * 10 - 2で18

結果、30フレーム毎秒に換算したフレーム数は

fN = fN + D * 18 + 2 * ((M - 2 ) div 1798)

となります。
後はこれを時、分、秒、フレームの各値に変換するだけです。

frames = fN mod 30
secs = ( fN div 30 ) mod 60
mins = (( fN div 30) div 60 ) mod 60
hours = (((fN div 30) div 60) div 60 ) mod 24

説明が相当面倒で分かりにくい…
でも、この通り書いてやれば、たぶん出来るはず…

でまぁとりいそぎICEのフレーム数をTCにしたもんがこれ(FPSは29.97限定ってことかな)。



なお、商を求める計算がうまくいかないので、こんなコンパウンド↓で対処しています。

コメント ( 0 )|Trackback ( )
  ・