Skip to content

Commit

Permalink
Use PTS differences for _Duration props
Browse files Browse the repository at this point in the history
frame->duration is often just computed from the track-wide frame rate
and hence unreliable.

For the last frame, where no following PTS is available, the logic just
matches the previous frames's duration. In theory the track's duration
could be referenced instead, but the current logic matches FFMS2.
  • Loading branch information
arch1t3cht committed Feb 9, 2025
1 parent eef4d1d commit 546ea79
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 8 deletions.
3 changes: 1 addition & 2 deletions src/avisynth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,9 @@ class AvisynthVideoSource : public IClip {
Env->ThrowError("BestVideoSource: %s", e.what());
}

const BSVideoProperties &VP = V->GetVideoProperties();
AVSMap *Props = Env->getFramePropsRW(Dst);

SetSynthFrameProperties(Src, VP, RFF, V->GetFrameIsTFF(n, RFF),
SetSynthFrameProperties(n, Src, *V, RFF, V->GetFrameIsTFF(n, RFF),
[Props, Env](const char *Name, int64_t V) { Env->propSetInt(Props, Name, V, 1); },
[Props, Env](const char *Name, double V) { Env->propSetFloat(Props, Name, V, 1); },
[Props, Env](const char *Name, const char *V, int Size, bool Utf8) { Env->propSetData(Props, Name, V, Size, 1); });
Expand Down
16 changes: 13 additions & 3 deletions src/synthshared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
#include "synthshared.h"
#include "VSHelper4.h"

void SetSynthFrameProperties(const std::unique_ptr<BestVideoFrame> &Src, const BSVideoProperties &VP, bool RFF, bool TFF, const std::function<void(const char *, int64_t)> &mapSetInt, const std::function<void(const char *, double)> &mapSetFloat, const std::function<void(const char *, const char *, int, bool)> &mapSetData) {
void SetSynthFrameProperties(int n, const std::unique_ptr<BestVideoFrame> &Src, const BestVideoSource &VS, bool RFF, bool TFF, const std::function<void(const char *, int64_t)> &mapSetInt, const std::function<void(const char *, double)> &mapSetFloat, const std::function<void(const char *, const char *, int, bool)> &mapSetData) {
const BSVideoProperties VP = VS.GetVideoProperties();

// Set AR variables
if (VP.SAR.Num > 0 && VP.SAR.Den > 0) {
mapSetInt("_SARNum", VP.SAR.Num);
Expand Down Expand Up @@ -49,11 +51,19 @@ void SetSynthFrameProperties(const std::unique_ptr<BestVideoFrame> &Src, const B
mapSetInt("_FieldBased", FieldBased);
mapSetInt("RepeatField", Src->RepeatPict);

// FIXME, use PTS difference between frames instead?
if (Src->Duration > 0) {
int64_t DurNum = VP.TimeBase.Num;
int64_t DurDen = VP.TimeBase.Den;
vsh::muldivRational(&DurNum, &DurDen, Src->Duration, 1);

int64_t Dur = Src->Duration;
if (n < VP.NumFrames - 1) {
Dur = VS.GetFrameInfo(n + 1).PTS - Src->PTS;
} else if (VP.NumFrames >= 2) {
// Assume the last frame has the same duration as the previous one, if the latter exists
Dur = Src->PTS - VS.GetFrameInfo(n - 1).PTS;
}

vsh::muldivRational(&DurNum, &DurDen, Dur, 1);
mapSetInt("_DurationNum", DurNum);
mapSetInt("_DurationDen", DurDen);
}
Expand Down
2 changes: 1 addition & 1 deletion src/synthshared.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
#include <functional>
#include <cstdint>

void SetSynthFrameProperties(const std::unique_ptr<BestVideoFrame> &Src, const BSVideoProperties &VP, bool RFF, bool TFF, const std::function<void(const char *, int64_t)> &mapSetInt, const std::function<void(const char *, double)> &mapSetFloat, const std::function<void(const char *, const char *, int, bool)> &mapSetData);
void SetSynthFrameProperties(int n, const std::unique_ptr<BestVideoFrame> &Src, const BestVideoSource &VS, bool RFF, bool TFF, const std::function<void(const char *, int64_t)> &mapSetInt, const std::function<void(const char *, double)> &mapSetFloat, const std::function<void(const char *, const char *, int, bool)> &mapSetData);

#endif
3 changes: 1 addition & 2 deletions src/vapoursynth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,11 @@ static const VSFrame *VS_CC BestVideoSourceGetFrame(int n, int ActivationReason,
return nullptr;
}

const BSVideoProperties &VP = D->V->GetVideoProperties();
VSMap *Props = vsapi->getFramePropertiesRW(Dst);
if (AlphaDst)
vsapi->mapConsumeFrame(Props, "_Alpha", AlphaDst, maAppend);

SetSynthFrameProperties(Src, VP, D->RFF, D->V->GetFrameIsTFF(n, D->RFF),
SetSynthFrameProperties(n, Src, *D->V, D->RFF, D->V->GetFrameIsTFF(n, D->RFF),
[Props, vsapi](const char *Name, int64_t V) { vsapi->mapSetInt(Props, Name, V, maAppend); },
[Props, vsapi](const char *Name, double V) { vsapi->mapSetFloat(Props, Name, V, maAppend); },
[Props, vsapi](const char *Name, const char *V, int Size, bool Utf8) { vsapi->mapSetData(Props, Name, V, Size, Utf8 ? dtUtf8 : dtBinary, maAppend); });
Expand Down

0 comments on commit 546ea79

Please sign in to comment.