public void Evaluate(int spreadMax) { // SpreadMax is not correct (should be correct in streams branch). spreadMax = FDirectoryIn .CombineWith(FFilemaskIn) .CombineWith(FBufferSizeIn) .CombineWith(FVisibleFramesIn) .CombineWith(FPreloadFramesIn) .CombineWith(FReloadIn); FImagePlayers.Resize(spreadMax, CreateImagePlayer, DestroyImagePlayer); FImagePlayers.SliceCount = spreadMax; FTextureOut.SliceCount = spreadMax; FTextureWidthOut.SliceCount = spreadMax; FTextureHeightOut.SliceCount = spreadMax; FFrameCountOut.SliceCount = spreadMax; FDurationIOOut.SliceCount = spreadMax; FDurationTextureOut.SliceCount = spreadMax; FUnusedFramesOut.SliceCount = spreadMax; FLoadedOut.SliceCount = spreadMax; for (int i = 0; i < spreadMax; i++) { bool reload = FReloadIn[i] || FDirectoryIn.IsChanged || FFilemaskIn.IsChanged; var imagePlayer = FImagePlayers[i]; if (imagePlayer.ThreadsIO != FThreadsIOConfig[i] || imagePlayer.ThreadsTexture != FThreadsTextureConfig[i]) { DestroyImagePlayer(imagePlayer); imagePlayer = CreateImagePlayer(i); reload = true; FImagePlayers[i] = imagePlayer; } imagePlayer.Directories = FDirectoryIn[i]; imagePlayer.Filemasks = FFilemaskIn[i]; if (reload) { imagePlayer.Reload(); FMemoryPool.Clear(); } int frameCount = 0; double durationIO = 0.0; double durationTexture = 0.0; int unusedFrames = 0; var loadedFrames = FLoadedOut[i]; var frame = imagePlayer.Preload( FVisibleFramesIn[i], FPreloadFramesIn[i], FBufferSizeIn[i], out frameCount, out durationIO, out durationTexture, out unusedFrames, ref loadedFrames); FTextureOut[i] = frame; FTextureWidthOut[i] = frame.Select(f => f.Metadata.Width).ToSpread(); FTextureHeightOut[i] = frame.Select(f => f.Metadata.Height).ToSpread(); FFrameCountOut[i] = frameCount; FDurationIOOut[i] = durationIO; FDurationTextureOut[i] = durationTexture; FUnusedFramesOut[i] = unusedFrames; } }
public ISpread <Frame> Preload( ISpread <int> visibleFrameIndices, ISpread <int> preloadFrameNrs, int bufferSize, out int frameCount, out double durationIO, out double durationTexture, out int unusedFrames, ref ISpread <bool> loadedFrames) { frameCount = FFiles.Length; durationIO = 0.0; durationTexture = 0.0; unusedFrames = 0; // Nothing to do if (FFiles.Length == 0) { loadedFrames.SliceCount = 0; return(new Spread <Frame>(0)); } // Map frame numbers to file names var preloadFiles = preloadFrameNrs.Select(frameNr => FFiles[VMath.Zmod(frameNr, FFiles.Length)]).ToArray(); // Dispose previously loaded frames foreach (var file in FPreloadedFrames.Keys.ToArray()) { if (!preloadFiles.Contains(file)) { var frame = FPreloadedFrames[file]; Dispose(frame); } } // Ensure that there are as much dequeues as enqueues (or we'll run out of memory) while (FScheduledFrameInfos.Count > preloadFrameNrs.SliceCount) { var frame = Dequeue(); var frameInfo = frame.Metadata; if (!preloadFiles.Contains(frameInfo.Filename) || frameInfo.IsCanceled) { // Not needed anymore Dispose(frame); unusedFrames++; } else { FPreloadedFrames.Add(frameInfo.Filename, frame); } } // Cancel unused scheduled frames foreach (var frameInfo in FScheduledFrameInfos.Where(fi => !fi.IsCanceled)) { if (!preloadFiles.Contains(frameInfo.Filename)) { frameInfo.Cancel(); } } // Free resources if there're no frames to preload and we didn't free them yet if (preloadFiles.Length == 0 && !FClearedMemoryPool) { FMemoryPool.Clear(); // Remember that we cleared the pool FClearedMemoryPool = true; } // Schedule new frames foreach (var file in preloadFiles) { if (!IsScheduled(file) && !IsPreloaded(file)) { var frameInfo = CreateFrameInfo(file, bufferSize); Enqueue(frameInfo); } // We're back using resources from the pool -> not clean anymore FClearedMemoryPool = false; } // Write the "is loaded" state loadedFrames.SliceCount = preloadFrameNrs.SliceCount; for (int i = 0; i < loadedFrames.SliceCount; i++) { var file = preloadFiles[i]; if (!IsPreloaded(file)) { var frameInfo = FScheduledFrameInfos.First(fi => fi.Filename == file); loadedFrames[i] = frameInfo.IsLoaded; } else { loadedFrames[i] = true; } } // Wait for the visible frames (and dipose unused ones) var visibleFrames = new Spread <Frame>(0); // Map frame numbers to file names var visibleFiles = preloadFiles.Length > 0 ? visibleFrameIndices.Select(i => preloadFiles[VMath.Zmod(i, preloadFiles.Length)]) : Enumerable.Empty <string>(); foreach (var file in visibleFiles) { while (!IsPreloaded(file)) { var frame = Dequeue(); var frameInfo = frame.Metadata; if (!preloadFiles.Contains(frameInfo.Filename) || frameInfo.IsCanceled) { // Not needed anymore Dispose(frame); unusedFrames++; } else { FPreloadedFrames.Add(frameInfo.Filename, frame); } } var visibleFrame = FPreloadedFrames[file]; var visibleFrameInfo = visibleFrame.Metadata; durationIO += visibleFrameInfo.DurationIO; durationTexture += visibleFrameInfo.DurationTexture; visibleFrames.Add(visibleFrame); } // Release textures of non visible frames foreach (var frame in FPreloadedFrames.Values.Where(f => !visibleFrames.Contains(f))) { frame.Dispose(); } return(visibleFrames); }