Je cherche une fonction qui convertit une valeur entière en trames en NTSC Drop Frame Timecode (hh: mm: ss.ff). J'utilise Delphi, mais pourrait être dans n'importe quelle langue.Conversion de trames en NTSC Drop Frame Code temporel
Merci
Je cherche une fonction qui convertit une valeur entière en trames en NTSC Drop Frame Timecode (hh: mm: ss.ff). J'utilise Delphi, mais pourrait être dans n'importe quelle langue.Conversion de trames en NTSC Drop Frame Code temporel
Merci
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;
Vous devez copier la routine DIVMOD de l'unité SysUtils, et également l'unité SysUtils quelle que soit implémente cette fonction.
Il est bien connu solution classique pour ce problème ...
(bien sûr vous pouvez utiliser un plus petit type int si vous connaissez votre plage de valeurs est limitée)
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"
De la résultante « drop » frameNumber, vous pouvez calculer les composants comme d'habitude, en utilisant le framerate de 30fps nominal. ..
frames = frameNumber % 30
seconds = (frameNumber/30) % 60
et ainsi de suite ...
Je devrais ajouter ... ce code est C/C++ '%' est modulo (reste) '/' est une division intégrale (tronquée) 'Lldiv' calcule à la fois le quotient et le reste. – Ichthyo
Ce n'est toujours pas correct. Deux problèmes ne sont pas résolus: 1) Dans les drop frames à 30fps, vous n'avez PAS 30 frames dans chaque seconde. Certaines secondes n'ont que 28 images, et celles qui sont ignorées sont les images 0 et 1. 2) Pour cette raison, il est possible que les images perdues augmentent le nombre de secondes, minutes ou même heures (si le nombre est assez grand) . Il semble que tout le monde fait cette erreur subtile. –
Voici un peu plus: Je travaille actuellement exactement sur le même problème (en convertissant le nombre de frames en smpte time avec drop frames). Va poster mon algorithme une fois que je suis sûr que c'est correct. –
+1, mais l'OMI la chaîne de format devrait être '% .2d:% 2d:% 2d% 2d....' - enlever les trois premiers les chiffres parce qu'ils ne sont pas nécessaires, et en ajoutant le dernier parce que sinon les images à un chiffre dans une seconde ne sont pas formatées correctement. – mghie
Corrigé, À l'origine, j'avais laissé le dernier chiffre ouvert pour le formatage afin de pouvoir traiter des images de plus grande taille, ce qui, rétrospectivement, est peu probable. – skamradt
NTSC Drop Frame Le timecode est de 29,97 ips, mais votre code n'accepte que fps comme entier, donc je ne pense pas que ce soit correct. –