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; }