flickering issue

This commit is contained in:
sumona-banerjeee
2026-02-25 11:03:43 +05:30
parent 2c20a59083
commit c2615c8d33

View File

@@ -422,6 +422,7 @@ export default function VideoPlayerSection({ data, videoId, videoFile, detection
const loggedFrames = useRef<Set<number>>(new Set()) const loggedFrames = useRef<Set<number>>(new Set())
const cumulativeCountsMap = useRef<Map<number, Record<string, number>>>(new Map()) const cumulativeCountsMap = useRef<Map<number, Record<string, number>>>(new Map())
const sortedFrameIndices = useRef<number[]>([]) const sortedFrameIndices = useRef<number[]>([])
const detectedFrameSkip = useRef<number>(3) // Computed from data, fallback to 3
const MAX_LOGS = 50 const MAX_LOGS = 50
const isCombined = detectionType === "pot-sign-detection" const isCombined = detectionType === "pot-sign-detection"
@@ -586,6 +587,18 @@ export default function VideoPlayerSection({ data, videoId, videoFile, detection
map.set(frameId, { ...lastCounts }) map.set(frameId, { ...lastCounts })
}) })
sortedFrameIndices.current = indices sortedFrameIndices.current = indices
// Compute the frame skip gap from the data (minimum gap between consecutive detection frames)
// This tells us how far apart processed frames are, so we only carry forward within that gap
if (indices.length >= 2) {
let minGap = Infinity
for (let i = 1; i < indices.length; i++) {
const gap = indices[i] - indices[i - 1]
if (gap > 0 && gap < minGap) minGap = gap
}
detectedFrameSkip.current = minGap === Infinity ? 3 : minGap
console.log(`[VideoPlayer] Detected frame skip gap: ${detectedFrameSkip.current}`)
}
} }
cumulativeCountsMap.current = map cumulativeCountsMap.current = map
@@ -629,6 +642,43 @@ export default function VideoPlayerSection({ data, videoId, videoFile, detection
} }
}, []) }, [])
// Helper to get nearest detections for any frame (handles frame skipping)
// Uses binary search to find the closest processed frame <= current frame,
// but only carries forward within the frame-skip gap to avoid stale bounding boxes
const getNearestDetections = useCallback((frame: number): any[] | undefined => {
// First try exact match (fastest path)
const exact = frameDetectionMap.current.get(frame)
if (exact) return exact
// Binary search for the nearest processed frame <= current frame
const indices = sortedFrameIndices.current
if (indices.length === 0) return undefined
let low = 0, high = indices.length - 1
let targetIndex = -1
while (low <= high) {
const mid = Math.floor((low + high) / 2)
if (indices[mid] <= frame) {
targetIndex = indices[mid]
low = mid + 1
} else {
high = mid - 1
}
}
if (targetIndex !== -1) {
// Only carry forward if we're within the frame-skip gap
// This prevents bounding boxes from persisting after the detection has ended
const gap = frame - targetIndex
if (gap <= detectedFrameSkip.current) {
return frameDetectionMap.current.get(targetIndex)
}
}
return undefined
}, [])
// Function to draw bounding boxes on canvas // Function to draw bounding boxes on canvas
const drawBoundingBoxes = useCallback((detections: any[]) => { const drawBoundingBoxes = useCallback((detections: any[]) => {
const canvas = canvasRef.current const canvas = canvasRef.current
@@ -719,13 +769,13 @@ export default function VideoPlayerSection({ data, videoId, videoFile, detection
canvas.width = rect.width canvas.width = rect.width
canvas.height = rect.height canvas.height = rect.height
// Redraw current frame's detections // Redraw current frame's detections (using nearest frame for skipped frames)
const frame = Math.round(video.currentTime * data.video_info.fps) const frame = Math.round(video.currentTime * data.video_info.fps)
const detections = frameDetectionMap.current.get(frame) const detections = getNearestDetections(frame)
if (detections) { if (detections) {
drawBoundingBoxes(detections) drawBoundingBoxes(detections)
} }
}, [data.video_info.fps, drawBoundingBoxes]) }, [data.video_info.fps, drawBoundingBoxes, getNearestDetections])
// Handle window resize // Handle window resize
useEffect(() => { useEffect(() => {
@@ -847,10 +897,11 @@ export default function VideoPlayerSection({ data, videoId, videoFile, detection
lastProcessedFrame.current = frame lastProcessedFrame.current = frame
setCurrentFrame(frame) setCurrentFrame(frame)
const detections = frameDetectionMap.current.get(frame) // Use nearest processed frame's detections to avoid flickering from frame skipping
const detections = getNearestDetections(frame)
setDetectionsCount(detections?.length || 0) setDetectionsCount(detections?.length || 0)
// Draw bounding boxes for current frame // Draw bounding boxes for current frame (carried forward from nearest processed frame)
drawBoundingBoxes(detections || []) drawBoundingBoxes(detections || [])
// Update counts using sticky logic // Update counts using sticky logic
@@ -860,7 +911,7 @@ export default function VideoPlayerSection({ data, videoId, videoFile, detection
addDetectionLog(frame, detections) addDetectionLog(frame, detections)
} }
} }
}, [data.video_info.fps, addDetectionLog, drawBoundingBoxes]) }, [data.video_info.fps, addDetectionLog, drawBoundingBoxes, getNearestDetections])
// Video playback monitoring // Video playback monitoring
useEffect(() => { useEffect(() => {