UnityPlugin-AVProVideo icon indicating copy to clipboard operation
UnityPlugin-AVProVideo copied to clipboard

[macOS] Frame duration and seeking not accurate

Open acgourley opened this issue 8 months ago • 0 comments

Unity version

2022.3

Unity editor platform

macOS

AVPro Video edition

Ultra

AVPro Video version

3.2.4

Device hardware

Mac Studio M2 Ultra

Which macOS version are you using?

15.2

Texture format

BGRA

Audio output

System Direct

Any other Media Player component configuration required to reproduce the issue.

No response

Which output component(s) are you using?

No response

Any other component configuration required to reproduce the issue.

No response

The issue

I've found what I think are bugs in BaseMediaPlayer.cs

First we have reading frames from media:

public int GetDurationFrames(float overrideFrameRate = 0f)
{
  int result = 0;
  float frameRate = (overrideFrameRate > 0f) ? overrideFrameRate : GetVideoFrameRate();
  if (frameRate > 0f)
  {
    result = Helper.ConvertTimeSecondsToFrame(GetDuration(), frameRate);
  }
}

which when calls

public static int ConvertTimeSecondsToFrame(double seconds, float frameRate)
{
	// NOTE: Generally you should use RountToInt when converting from time to frame number
	// but because we're adding a half frame offset (which seems to be the safer thing to do) we need to FloorToInt
	seconds = System.Math.Max(0.0, seconds);
	frameRate = Mathf.Max(0f, frameRate);
	return (int)System.Math.Floor(frameRate * seconds);
}

Now when I pass this a media file (link) which has 100 frames over 1.65 seconds (according to ffmpeg) it does this: GetDuration() returns 1.65166666666667 frame rate is passed in as 59.93821 ConvertTimeSecondsToFrame(1.65166666666667, 59.93821) then calculate 98.999 and floors it to returns 98!

Based on the the comment in your code you say half a frames time should be added before the floor function, but no where in this chain of calls does that happen, leading to being off by 1.

I believe GetDurationFrames() should also just be adding 1, because a video of duration 0 should still have 1 frame. Your code in GetMaxFrameNumber() subtracts 1, which I believe only makes sense if GetDurationFrames() was adding 1.

I hope both of these together makes the library more robust. For now I'm working around them by getting frame count through another method and using time based seek not frame based seek helpers.

Media information

No response

Log output


acgourley avatar Mar 28 '25 20:03 acgourley