예제 #1
0
        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;
            }
        }
예제 #2
0
        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);
        }