Exemple #1
0
        private void bgWorkerSave_DoWork(object sender, DoWorkEventArgs e)
        {
            Thread.CurrentThread.Name = "Saving";
            BackgroundWorker bgWorker = sender as BackgroundWorker;

            if (!(e.Argument is SavingSettings))
            {
                saveResult = SaveResult.UnknownError;
                e.Result   = 0;
                return;
            }

            SavingSettings settings = (SavingSettings)e.Argument;

            if (settings.ImageRetriever == null || settings.InputFrameInterval < 0 || bgWorker == null)
            {
                saveResult = SaveResult.UnknownError;
                e.Result   = 0;
                return;
            }

            try
            {
                log.DebugFormat("Saving selection [{0}]->[{1}] to: {2}", settings.Section.Start, settings.Section.End, Path.GetFileName(settings.File));

                // TODO it may actually make more sense to split the saving methods for regular
                // save, paused video and diaporama. It will cause inevitable code duplication but better encapsulation and simpler algo.
                // When each save method has its own class and UI panel, it will be a better design.

                if (!settings.PausedVideo)
                {
                    // Take special care for slowmotion, the frame interval can not go down indefinitely.
                    // Use frame duplication when under 8fps.
                    settings.Duplication         = (int)Math.Ceiling(settings.InputFrameInterval / 125.0);
                    settings.KeyframeDuplication = settings.Duplication;
                    settings.OutputFrameInterval = settings.InputFrameInterval / settings.Duplication;
                    if (settings.KeyframesOnly)
                    {
                        settings.EstimatedTotal = metadata.Count * settings.Duplication;
                    }
                    else
                    {
                        settings.EstimatedTotal = videoReader.EstimatedFrames * settings.Duplication;
                    }
                }
                else
                {
                    // For paused video, slow motion is not supported.
                    // InputFrameInterval will have been set to a multiple of the original frame interval.
                    settings.Duplication         = 1;
                    settings.KeyframeDuplication = (int)(settings.InputFrameInterval / metadata.UserInterval);
                    settings.OutputFrameInterval = metadata.UserInterval;

                    long regularFramesTotal = videoReader.EstimatedFrames - metadata.Count;
                    long keyframesTotal     = metadata.Count * settings.KeyframeDuplication;
                    settings.EstimatedTotal = regularFramesTotal + keyframesTotal;
                }

                log.DebugFormat("interval:{0}, duplication:{1}, kf duplication:{2}", settings.OutputFrameInterval, settings.Duplication, settings.KeyframeDuplication);

                videoReader.BeforeFrameEnumeration();
                IEnumerable <Bitmap> images = EnumerateImages(settings);

                VideoFileWriter w            = new VideoFileWriter();
                string          formatString = FilenameHelper.GetFormatString(settings.File);
                saveResult = w.Save(settings, videoReader.Info, formatString, images, bgWorker);
                videoReader.AfterFrameEnumeration();
            }
            catch (Exception exp)
            {
                saveResult = SaveResult.UnknownError;
                log.Error("Unknown error while saving video.");
                log.Error(exp.StackTrace);
            }

            e.Result = 0;
        }