Конвертировать кадры в NTSC Drop Frame Timecode - PullRequest
3 голосов
/ 15 мая 2009

Я ищу функцию, которая преобразует целочисленное значение в кадрах в временной код пропуска кадров NTSC (чч: мм: сс.фф).

Я использую Delphi, но может быть на любом языке.

Спасибо

Ответы [ 2 ]

4 голосов
/ 21 мая 2011

Существует известное классическое решение для этой проблемы ...

  • входное число кадров nr относительно реальной частоты кадров, которая всегда 30000/1001 ~ = 29,97 кадров в секунду для NTSC
  • рассчитанный результат frame-nr равен номинальной частоте кадров 30 кадров в секунду (и будет демонстрировать скачок + 2 кадра в каждую полную минуту, если минута не делится на 10

(конечно, вы можете использовать меньший тип int, если знаете, что диапазон значений ограничен)

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"

Из полученного "drop" frameNumber вы можете рассчитать компоненты как обычно, используя номинальную частоту кадров 30fps ...

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

и так далее ...

1 голос
/ 15 мая 2009
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;

Вам нужно будет скопировать процедуру DivMod из модуля SysUtils, а также включить модуль sysUtils во все, что реализует эту функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...