Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get dynamic groups target frame rate from app config instead of harcoded value #5368

Merged
merged 4 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion app/packages/core/src/components/Modal/ImaVidLooker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ export const ImaVidLookerReact = React.memo(
({ sample: sampleDataWithExtraParams }: ImaVidLookerReactProps) => {
const [id] = useState(() => uuid());
const colorScheme = useRecoilValue(fos.colorScheme);
const dynamicGroupsTargetFrameRate = useRecoilValue(
fos.dynamicGroupsTargetFrameRate
);

const { sample } = sampleDataWithExtraParams;

Expand Down Expand Up @@ -219,8 +222,9 @@ export const ImaVidLookerReact = React.memo(
}

return {
totalFrames: totalFrameCount,
loop: (looker as ImaVidLooker).options.loop,
targetFrameRate: dynamicGroupsTargetFrameRate,
totalFrames: totalFrameCount,
} as FoTimelineConfig;
}, [totalFrameCount, (looker as ImaVidLooker).options.loop]);

Expand Down
19 changes: 12 additions & 7 deletions app/packages/looker/src/elements/imavid/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import {
BUFFERING_PAUSE_TIMEOUT,
DEFAULT_FRAME_RATE,
DEFAULT_PLAYBACK_RATE,
LOOK_AHEAD_MULTIPLIER,
} from "../../lookers/imavid/constants";
Expand Down Expand Up @@ -80,9 +79,9 @@ export class ImaVidElement extends BaseElement<ImaVidState, HTMLImageElement> {
private canvas: HTMLCanvasElement;
private ctx: CanvasRenderingContext2D;
private playBackRate = DEFAULT_PLAYBACK_RATE;
// adding a new state to track it because we want to compute it conditionally in renderSelf and not drawFrame
private setTimeoutDelay = getMillisecondsFromPlaybackRate(this.playBackRate);
private frameNumber = 1;
private setTimeoutDelay: number;
private targetFrameRate: number;
private isThumbnail: boolean;
private thumbnailSrc: string;
/**
Expand Down Expand Up @@ -349,7 +348,9 @@ export class ImaVidElement extends BaseElement<ImaVidState, HTMLImageElement> {

const offset = this.isSeeking
? 2
: DEFAULT_FRAME_RATE * LOOK_AHEAD_MULTIPLIER * frameCountMultiplierWeight;
: this.targetFrameRate *
LOOK_AHEAD_MULTIPLIER *
frameCountMultiplierWeight;

const frameRangeMax = Math.min(
Math.trunc(currentFrameNumber + offset),
Expand Down Expand Up @@ -425,7 +426,7 @@ export class ImaVidElement extends BaseElement<ImaVidState, HTMLImageElement> {
renderSelf(state: Readonly<ImaVidState>) {
const {
options: { playbackRate, loop },
config: { thumbnail, src: thumbnailSrc },
config: { thumbnail, src: thumbnailSrc, frameRate },
currentFrameNumber,
seeking,
hovering,
Expand All @@ -447,10 +448,14 @@ export class ImaVidElement extends BaseElement<ImaVidState, HTMLImageElement> {
this.isSeeking = seeking;
this.isThumbnail = thumbnail;
this.frameNumber = currentFrameNumber;
this.targetFrameRate = frameRate;

if (this.playBackRate !== playbackRate) {
if (this.playBackRate !== playbackRate || !this.setTimeoutDelay) {
this.playBackRate = playbackRate;
this.setTimeoutDelay = getMillisecondsFromPlaybackRate(playbackRate);
this.setTimeoutDelay = getMillisecondsFromPlaybackRate(
frameRate,
playbackRate
);
}

// `destroyed` is called when looker is reset
Expand Down
1 change: 0 additions & 1 deletion app/packages/looker/src/lookers/imavid/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export const DEFAULT_FRAME_RATE = 30;
export const DEFAULT_PLAYBACK_RATE = 1.5;
export const BUFFERING_PAUSE_TIMEOUT = 250;
export const BUFFERS_REFRESH_TIMEOUT_YIELD = 500;
Expand Down
14 changes: 8 additions & 6 deletions app/packages/looker/src/lookers/imavid/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as foq from "@fiftyone/relay";
import { BufferManager } from "@fiftyone/utilities";
import { Environment, Subscription, fetchQuery } from "relay-runtime";
import { BufferRange, ImaVidState, StateUpdate } from "../../state";
import { BUFFERS_REFRESH_TIMEOUT_YIELD, DEFAULT_FRAME_RATE } from "./constants";
import { BUFFERS_REFRESH_TIMEOUT_YIELD } from "./constants";
import {
ImaVidFrameSamples,
ModalSampleExtendedWithImage,
Expand All @@ -12,9 +12,9 @@ import { ImaVidStore } from "./store";
const BUFFER_METADATA_FETCHING = "fetching";

export class ImaVidFramesController {
private frameRate = DEFAULT_FRAME_RATE;
private mediaField = "filepath";
private subscription: Subscription;
private targetFrameRate: number;
private timeoutId: number;

public fetchBufferManager = new BufferManager();
Expand All @@ -32,6 +32,7 @@ export class ImaVidFramesController {
page: any;
key: string;
totalFrameCountPromise: Promise<number>;
targetFrameRate: number;
}
) {
this.storeBufferManager = new BufferManager([
Expand All @@ -40,6 +41,7 @@ export class ImaVidFramesController {
config.totalFrameCountPromise.then((frameCount) => {
this.totalFrameCount = frameCount;
});
this.targetFrameRate = config.targetFrameRate;
}

public setImaVidStateUpdater(updater: StateUpdate<ImaVidState>) {
Expand Down Expand Up @@ -150,7 +152,7 @@ export class ImaVidFramesController {
}

public get currentFrameRate() {
return this.frameRate;
return this.targetFrameRate;
}

public get isStoreBufferManagerEmpty() {
Expand Down Expand Up @@ -181,15 +183,15 @@ export class ImaVidFramesController {
}

public setFrameRate(newFrameRate: number) {
if (newFrameRate > 24) {
throw new Error("max frame rate is 24");
if (newFrameRate > 60) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just curious, is there a technical reason to cap at 60?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no... it's arbitrary based on local testing. but i'm hoping to set the right expectation by enforcing this cap. in ImaVid, we're on-the-fly fetching and streaming images and achieving higher fps than even 30 is kind of hard

throw new Error("max frame rate is 60");
}

if (newFrameRate < 1) {
throw new Error("min frame rate is 1");
}

this.frameRate = newFrameRate;
this.targetFrameRate = newFrameRate;
}

public setMediaField(mediaField: string) {
Expand Down
4 changes: 2 additions & 2 deletions app/packages/looker/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
ServerError,
getFetchParameters,
} from "@fiftyone/utilities";
import { DEFAULT_FRAME_RATE } from "./lookers/imavid/constants";
import LookerWorker from "./worker/index.ts?worker&inline";

/**
Expand Down Expand Up @@ -254,11 +253,12 @@ export const ensureCanvasSize = (
};

export const getMillisecondsFromPlaybackRate = (
frameRate: number,
playbackRate: number
): number => {
const normalizedPlaybackRate =
playbackRate > 1 ? playbackRate * 1.5 : playbackRate;
return 1000 / (DEFAULT_FRAME_RATE * normalizedPlaybackRate);
return 1000 / (frameRate * normalizedPlaybackRate);
};

/**
Expand Down
Loading
Loading