2009-05-15 16 views

答えて

2
function FramesToNTSCDropFrameCode(Frames:Integer;FramesPerSecond:Double):string; 
var 
    iTH, iTM, iTS, iTF : word; 
    MinCount, MFrameCount : word; 
begin 
    DivMod(Frames, Trunc(SecsPerMin * FramesPerSecond), MinCount, MFrameCount); 
    DivMod(MinCount, MinsPerHour, iTH, iTM); 
    DivMod(MFrameCount, Trunc(FramesPerSecond), ITS, ITF); 
    Result := Format('%.2d:%.2d:%.2d.%.2d',[iTH,iTM,iTS,iTF]); 
end; 

あなたはSysUtilsユニットからDivModルーチンをコピーする必要があり、また、この機能を実装して何にSysUtilsユニットが含まれます。その問題のためのよく知られた古典的な溶液があり

+1

1が、IMOフォーマット文字列は '%の.2d:%2D:。。。。%2D%2D' でなければなりません - 最初の3を取り外しますそれ以外の場合は1桁の1桁のフレームが正しくフォーマットされないため、最後の1桁を追加する必要があります。 – mghie

+0

修正済み、もともと私は、より大きなフレームペース秒を処理するためにフォーマットのために最後の桁を開いたままにしていました...振り返ってみるとほとんどありません。 – skamradt

+0

NTSCドロップフレームのタイムコードは29.97fpsですが、コードでは整数としてfpsしか受け付けないので、正しくはないと思います。 –

2

...

  • 入力フレームカウントNRがオールウェイズ 1001分の30000〜= 29.97で実際のフレームレート、に相対的ですNTSC
  • 算出結果フレーム-Nrが30fpsの公称フレームレートである(分10
によって分割可能でない限り、各フル分で+ 2framesジャンプを示すことになるため、毎秒フレーム0

結果のフレーム番号を「ドロップ」から

const uint FRAMES_PER_10min = 10*60 * 30000/1001; 
const uint FRAMES_PER_1min = 1*60 * 30000/1001; 
const uint DISCREPANCY  = (1*60 * 30) - FRAMES_PER_1min; 


/** reverse the drop-frame calculation 
* @param frameNr raw frame number in 30000/1001 = 29.97fps 
* @return frame number using NTSC drop-frame encoding, nominally 30fps 
*/ 
int64_t 
calculate_drop_frame_number (int64_t frameNr) 
{ 
    // partition into 10 minute segments 
    lldiv_t tenMinFrames = lldiv (frameNr, FRAMES_PER_10min); 

    // ensure the drop-frame incidents happen at full minutes; 
    // at start of each 10-minute segment *no* drop incident happens, 
    // thus we need to correct discrepancy between nominal/real framerate once: 
    int64_t remainingMinutes = (tenMinFrames.rem - DISCREPANCY)/FRAMES_PER_1min; 

    int64_t dropIncidents = (10-1) * tenMinFrames.quot + remainingMinutes; 
    return frameNr + 2*dropIncidents; 
}     // perform "drop" 

を(あなたがあなたの値の範囲が限定されている知っていればもちろん、あなたが小さいint型を使用する場合があります)、あなたは公称30fpsのフレームレートを使用して、いつものようにコンポーネントを計算することができます。 ..

frames = frameNumber % 30 
seconds = (frameNumber/30) % 60 

のように...

+0

このコードはC/C++ '%'はモジュロ(剰余) '/'は整数除算(切り捨て)です。 'lldiv'は商と剰余の両方を計算します – Ichthyo

+0

これはまだ正しくありません。対処されていない2つの問題があります。1)30fpsのドロップフレームでは、1秒に30フレームがありません。いくつかの秒はわずか28フレームしかなく、スキップされたものはフレーム0と1です。2)これにより、ドロップされたフレームが数秒、数分、さらには数時間を増加させる可能性があります。誰もがこの微妙な間違いをしているようです。 –

+0

ここでもう少しです:私は現在、まったく同じ問題(フレーム数をドロップフレームで時間を消すために変換する)に取り組んでいます。私はそれが正しいと確信したら私のアルゴリズムを投稿します。 –

関連する問題