Пример #1
0
        private void bgWorkerDualSave_DoWork(object sender, DoWorkEventArgs e)
        {
            // This is executed in Worker Thread space. (Do not call any UI methods)
            log.Debug("Saving side by side video.");

            int threadResult = 0;

            // Get first frame outside the loop to set up the saving context.
            long   currentTime = 0;
            Bitmap composite   = GetCompositeImage(currentTime);

            log.DebugFormat("Composite size: {0}.", composite.Size);

            VideoInfo info = new VideoInfo
            {
                ReferenceSize = composite.Size
            };

            string formatString = FilenameHelper.GetFormatString(dualSaveFileName);

            SaveResult result = videoFileWriter.OpenSavingContext(dualSaveFileName, info, formatString, fileFrameInterval);

            if (result != SaveResult.Success)
            {
                e.Result = 2;
                return;
            }

            videoFileWriter.SaveFrame(composite);
            composite.Dispose();

            while (currentTime < commonTimeline.LastTime && !dualSaveCancelled)
            {
                currentTime += commonTimeline.FrameTime;

                if (bgWorkerDualSave.CancellationPending)
                {
                    threadResult      = 1;
                    dualSaveCancelled = true;
                    break;
                }

                composite = GetCompositeImage(currentTime);
                videoFileWriter.SaveFrame(composite);
                composite.Dispose();

                int percent = (int)((double)currentTime * 100 / commonTimeline.LastTime);
                bgWorkerDualSave.ReportProgress(percent);
            }

            if (!dualSaveCancelled)
            {
                threadResult = 0;
            }

            e.Result = threadResult;
        }
Пример #2
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;
        }