Esempio n. 1
0
        /// <summary>
        /// opens a dgindex script
        /// if the file can be properly opened, auto-cropping is performed, then depending on the AR settings
        /// the proper resolution for automatic resizing, taking into account the derived cropping values
        /// is calculated, and finally the avisynth script is written and its name returned
        /// </summary>
        /// <param name="path">dgindex script</param>
        /// <param name="aspectRatio">aspect ratio selection to be used</param>
        /// <param name="customDAR">custom display aspect ratio for this source</param>
        /// <param name="horizontalResolution">desired horizontal resolution of the output</param>
        /// <param name="settings">the codec settings (used only for x264)</param>
        /// <param name="sarX">pixel aspect ratio X</param>
        /// <param name="sarY">pixel aspect ratio Y</param>
        /// <param name="height">the final height of the video</param>
        /// <param name="signalAR">whether or not ar signalling is to be used for the output
        /// (depending on this parameter, resizing changes to match the source AR)</param>
        /// <returns>the name of the AviSynth script created, empty of there was an error</returns>
        private string openVideo(string path, Dar?AR, int horizontalResolution,
                                 bool signalAR, LogItem log, AviSynthSettings avsSettings, bool autoDeint,
                                 VideoCodecSettings settings, out Dar?dar)
        {
            dar = null;
            IMediaFile   d2v    = new d2vFile(path);
            IVideoReader reader = d2v.GetVideoReader();

            if (reader.FrameCount < 1)
            {
                log.Error("DGDecode reported 0 frames in this file. This is a fatal error. Please recreate the DGIndex project");
                return("");
            }

            //Autocrop
            CropValues final = Autocrop.autocrop(reader);

            if (signalAR)
            {
                if (avsSettings.Mod16Method == mod16Method.overcrop)
                {
                    ScriptServer.overcrop(ref final);
                }
                else if (avsSettings.Mod16Method == mod16Method.mod4Horizontal)
                {
                    ScriptServer.cropMod4Horizontal(ref final);
                }
                else if (avsSettings.Mod16Method == mod16Method.undercrop)
                {
                    ScriptServer.undercrop(ref final);
                }
            }

            bool error = (final.left == -1);

            if (!error)
            {
                log.LogValue("Autocrop values", final);
            }
            else
            {
                log.Error("Autocrop failed, aborting now");
                return("");
            }

            decimal customDAR;

            log.LogValue("Auto-detect aspect ratio now", AR == null);
            //Check if AR needs to be autodetected now
            if (AR == null) // it does
            {
                customDAR = d2v.Info.DAR.ar;
                if (customDAR > 0)
                {
                    log.LogValue("Aspect ratio", customDAR);
                }
                else
                {
                    customDAR = Dar.ITU16x9PAL.ar;
                    log.Warn(string.Format("No aspect ratio found, defaulting to {0}.", customDAR));
                }
            }
            else
            {
                customDAR = AR.Value.ar;
            }

            // Minimise upsizing
            int sourceHorizontalResolution = (int)d2v.Info.Width - final.right - final.left;

            if (horizontalResolution > sourceHorizontalResolution)
            {
                if (avsSettings.Mod16Method == mod16Method.resize)
                {
                    while (horizontalResolution > sourceHorizontalResolution + 16)
                    {
                        horizontalResolution -= 16;
                    }
                }
                else
                {
                    horizontalResolution = sourceHorizontalResolution;
                }
            }

            //Suggest a resolution (taken from AvisynthWindow.suggestResolution_CheckedChanged)
            int scriptVerticalResolution = Resolution.suggestResolution(d2v.Info.Height, d2v.Info.Width, (double)customDAR,
                                                                        final, horizontalResolution, signalAR, mainForm.Settings.AcceptableAspectErrorPercent, out dar);

            log.LogValue("Output resolution", horizontalResolution + "x" + scriptVerticalResolution);

            if (settings != null && settings is x264Settings) // verify that the video corresponds to the chosen avc level, if not, change the resolution until it does fit
            {
                x264Settings xs = (x264Settings)settings;
                if (xs.Level != 15)
                {
                    AVCLevels al = new AVCLevels();
                    log.LogValue("AVC level", al.getLevels()[xs.Level]);

                    int compliantLevel = 15;
                    while (!this.al.validateAVCLevel(horizontalResolution, scriptVerticalResolution, d2v.Info.FPS, xs, out compliantLevel))
                    { // resolution not profile compliant, reduce horizontal resolution by 16, get the new vertical resolution and try again
                        string levelName = al.getLevels()[xs.Level];
                        horizontalResolution    -= 16;
                        scriptVerticalResolution = Resolution.suggestResolution(d2v.Info.Height, d2v.Info.Width, (double)customDAR,
                                                                                final, horizontalResolution, signalAR, mainForm.Settings.AcceptableAspectErrorPercent, out dar);
                    }
                    log.LogValue("Resolution adjusted for AVC Level", horizontalResolution + "x" + scriptVerticalResolution);
                }
            }

            //Generate the avs script based on the template
            string inputLine        = "#input";
            string deinterlaceLines = "#deinterlace";
            string denoiseLines     = "#denoise";
            string cropLine         = "#crop";
            string resizeLine       = "#resize";

            inputLine = ScriptServer.GetInputLine(path, false, PossibleSources.d2v,
                                                  false, false, false, 0);

            log.LogValue("Automatic deinterlacing", autoDeint);
            if (autoDeint)
            {
                string         d2vPath = path;
                SourceDetector sd      = new SourceDetector(inputLine, d2vPath, false,
                                                            mainForm.Settings.SourceDetectorSettings,
                                                            new UpdateSourceDetectionStatus(analyseUpdate),
                                                            new FinishedAnalysis(finishedAnalysis));
                finished = false;
                sd.analyse();
                waitTillAnalyseFinished();
                deinterlaceLines = filters[0].Script;
                log.LogValue("Deinterlacing used", deinterlaceLines);
            }

            inputLine = ScriptServer.GetInputLine(path, interlaced, PossibleSources.d2v, avsSettings.ColourCorrect, avsSettings.MPEG2Deblock, false, 0);

            cropLine     = ScriptServer.GetCropLine(true, final);
            denoiseLines = ScriptServer.GetDenoiseLines(avsSettings.Denoise, (DenoiseFilterType)avsSettings.DenoiseMethod);
            resizeLine   = ScriptServer.GetResizeLine(!signalAR || avsSettings.Mod16Method == mod16Method.resize, horizontalResolution, scriptVerticalResolution, (ResizeFilterType)avsSettings.ResizeMethod);

            string newScript = ScriptServer.CreateScriptFromTemplate(avsSettings.Template, inputLine, cropLine, resizeLine, denoiseLines, deinterlaceLines);

            if (dar.HasValue)
            {
                newScript = string.Format("global MeGUI_darx = {0}\r\nglobal MeGUI_dary = {1}\r\n{2}", dar.Value.X, dar.Value.Y, newScript);
            }

            log.LogValue("Generated Avisynth script", newScript);
            try
            {
                StreamWriter sw = new StreamWriter(Path.ChangeExtension(path, ".avs"));
                sw.Write(newScript);
                sw.Close();
            }
            catch (IOException i)
            {
                log.LogValue("Error saving AviSynth script", i, ImageType.Error);
                return("");
            }
            return(Path.ChangeExtension(path, ".avs"));
        }
Esempio n. 2
0
/*        private void getAudioStreams(Dictionary<int, string> audioFiles, OneClickWindow.PartialAudioStream[] partialAudioStream, out List<AudioJob> encodableAudioStreams, out List<MuxStream> muxOnlyAudioStreams)
 *      {
 *          muxOnlyAudioStreams = new List<MuxStream>();
 *          encodableAudioStreams = new List<AudioJob>();
 *          int counter = 0;
 *          foreach (OneClickWindow.PartialAudioStream propertiesStream in job.PostprocessingProperties.AudioStreams)
 *          {
 *              counter++; // The track number starts at 1, so we increment right here. This also ensures it will always be incremented
 *
 *              bool error = false;
 *              string input = null, output = null, language = null;
 *              AudioCodecSettings settings = null;
 *              // Input
 *              if (string.IsNullOrEmpty(propertiesStream.input))
 *                  continue; // Here we have an unconfigured stream. Let's just go on to the next one
 *
 *              if (propertiesStream.useExternalInput)
 *                  input = propertiesStream.input;
 *              else if (audioFiles.ContainsKey(propertiesStream.trackNumber))
 *                  input = audioFiles[propertiesStream.trackNumber];
 *              else
 *                  error = true;
 *
 *              // Settings
 *              if (propertiesStream.dontEncode)
 *                  settings = null;
 *              else if (propertiesStream.settings != null)
 *                  settings = propertiesStream.settings;
 *              else
 *                  error = true;
 *
 *              // Output
 *              if (propertiesStream.dontEncode)
 *                  output = input;
 *              else if (!error)
 *                  output = Path.Combine(
 *                      Path.GetDirectoryName(input),
 *                      Path.GetFileNameWithoutExtension(input) + "_" +
 *                      propertiesStream.trackNumber + ".file");
 *
 *              // Language
 *              if (!string.IsNullOrEmpty(propertiesStream.language))
 *                  language = propertiesStream.language;
 *              else
 *                  language = "";
 *
 *              if (error)
 *              {
 *                  logBuilder.AppendFormat("Trouble with audio track {0}. Skipping track...{1}", counter, Environment.NewLine);
 *                  output = null;
 *                  input = null;
 *                  input = null;
 *              }
 *              else
 *              {
 *                  if (propertiesStream.dontEncode)
 *                  {
 *                      MuxStream newStream = new MuxStream();
 *                      newStream.path = input;
 *                      newStream.name = "";
 *                      newStream.language = language;
 *                      muxOnlyAudioStreams.Add(newStream);
 *                  }
 *                  else
 *                  {
 *                      AudioJob encodeStream = new AudioJob();
 *                      encodeStream.Input = input;
 *                      encodeStream.Output = output;
 *                      encodeStream.Settings = settings;
 *                      encodableAudioStreams.Add(encodeStream);
 *                  }
 *              }
 *          }
 *      }*/

        /// <summary>
        /// opens a dgindex script
        /// if the file can be properly opened, auto-cropping is performed, then depending on the AR settings
        /// the proper resolution for automatic resizing, taking into account the derived cropping values
        /// is calculated, and finally the avisynth script is written and its name returned
        /// </summary>
        /// <param name="path">dgindex script</param>
        /// <param name="aspectRatio">aspect ratio selection to be used</param>
        /// <param name="customDAR">custom display aspect ratio for this source</param>
        /// <param name="horizontalResolution">desired horizontal resolution of the output</param>
        /// <param name="logBuilder">stringbuilder where to append log messages</param>
        /// <param name="settings">the codec settings (used only for x264)</param>
        /// <param name="sarX">pixel aspect ratio X</param>
        /// <param name="sarY">pixel aspect ratio Y</param>
        /// <param name="height">the final height of the video</param>
        /// <param name="signalAR">whether or not ar signalling is to be used for the output
        /// (depending on this parameter, resizing changes to match the source AR)</param>
        /// <returns>the name of the AviSynth script created, empty of there was an error</returns>
        private string openVideo(string path, Dar?AR, int horizontalResolution,
                                 bool signalAR, StringBuilder logBuilder, AviSynthSettings avsSettings, bool autoDeint,
                                 VideoCodecSettings settings, out Dar?dar)
        {
            dar = null;
            IMediaFile   d2v    = new d2vFile(path);
            IVideoReader reader = d2v.GetVideoReader();

            if (reader.FrameCount < 1)
            {
                logBuilder.Append("DGDecode reported 0 frames in this file.\r\nThis is a fatal error.\r\n\r\nPlease recreate the DGIndex project");
                return("");
            }

            //Autocrop
            CropValues final = Autocrop.autocrop(reader);

            if (signalAR)
            {
                if (avsSettings.Mod16Method == mod16Method.overcrop)
                {
                    ScriptServer.overcrop(ref final);
                }
                else if (avsSettings.Mod16Method == mod16Method.mod4Horizontal)
                {
                    ScriptServer.cropMod4Horizontal(ref final);
                }
            }

            bool error = (final.left == -1);

            if (!error)
            {
                logBuilder.Append("Autocropping successful. Using the following crop values: left: " + final.left +
                                  ", top: " + final.top + ", right: " + final.right + ", bottom: " + final.bottom + ".\r\n");
            }
            else
            {
                logBuilder.Append("Autocropping did not find 3 frames that have matching crop values\r\n"
                                  + "Autocrop failed, aborting now");
                return("");
            }

            decimal customDAR;

            //Check if AR needs to be autodetected now
            if (AR == null) // it does
            {
                logBuilder.Append("Aspect Ratio set to auto-detect later, detecting now. ");
                customDAR = d2v.Info.DAR.ar;
                if (customDAR > 0)
                {
                    logBuilder.AppendFormat("Found aspect ratio of {0}.{1}", customDAR, Environment.NewLine);
                }
                else
                {
                    customDAR = Dar.ITU16x9PAL.ar;
                    logBuilder.AppendFormat("No aspect ratio found, defaulting to {0}.{1}", customDAR, Environment.NewLine);
                }
            }
            else
            {
                customDAR = AR.Value.ar;
            }

            //Suggest a resolution (taken from AvisynthWindow.suggestResolution_CheckedChanged)
            int scriptVerticalResolution = Resolution.suggestResolution(d2v.Info.Height, d2v.Info.Width, (double)customDAR,
                                                                        final, horizontalResolution, signalAR, mainForm.Settings.AcceptableAspectErrorPercent, out dar);

            if (settings != null && settings is x264Settings) // verify that the video corresponds to the chosen avc level, if not, change the resolution until it does fit
            {
                x264Settings xs = (x264Settings)settings;
                if (xs.Level != 15)
                {
                    int compliantLevel = 15;
                    while (!this.al.validateAVCLevel(horizontalResolution, scriptVerticalResolution, d2v.Info.FPS, xs, out compliantLevel))
                    { // resolution not profile compliant, reduce horizontal resolution by 16, get the new vertical resolution and try again
                        AVCLevels al        = new AVCLevels();
                        string    levelName = al.getLevels()[xs.Level];
                        logBuilder.Append("Your chosen AVC level " + levelName + " is too strict to allow your chosen resolution of " +
                                          horizontalResolution + "*" + scriptVerticalResolution + ". Reducing horizontal resolution by 16.\r\n");
                        horizontalResolution    -= 16;
                        scriptVerticalResolution = Resolution.suggestResolution(d2v.Info.Height, d2v.Info.Width, (double)customDAR,
                                                                                final, horizontalResolution, signalAR, mainForm.Settings.AcceptableAspectErrorPercent, out dar);
                    }
                    logBuilder.Append("Final resolution that is compatible with the chosen AVC Level: " + horizontalResolution + "*"
                                      + scriptVerticalResolution + "\r\n");
                }
            }

            //Generate the avs script based on the template
            string inputLine        = "#input";
            string deinterlaceLines = "#deinterlace";
            string denoiseLines     = "#denoise";
            string cropLine         = "#crop";
            string resizeLine       = "#resize";

            inputLine = ScriptServer.GetInputLine(path, false, PossibleSources.d2v,
                                                  false, false, false, 0);

            if (autoDeint)
            {
                logBuilder.AppendLine("Automatic deinterlacing was checked. Running now...");
                string         d2vPath = path;
                SourceDetector sd      = new SourceDetector(inputLine, d2vPath, false,
                                                            mainForm.Settings.SourceDetectorSettings,
                                                            new UpdateSourceDetectionStatus(analyseUpdate),
                                                            new FinishedAnalysis(finishedAnalysis));
                finished = false;
                sd.analyse();
                waitTillAnalyseFinished();
                deinterlaceLines = filters[0].Script;
                logBuilder.AppendLine("Deinterlacing used: " + deinterlaceLines);
            }

            inputLine = ScriptServer.GetInputLine(path, interlaced, PossibleSources.d2v,
                                                  avsSettings.ColourCorrect, avsSettings.MPEG2Deblock, false, 0);

            cropLine     = ScriptServer.GetCropLine(true, final);
            denoiseLines = ScriptServer.GetDenoiseLines(avsSettings.Denoise, (DenoiseFilterType)avsSettings.DenoiseMethod);
            resizeLine   = ScriptServer.GetResizeLine(!signalAR || avsSettings.Mod16Method == mod16Method.resize, horizontalResolution, scriptVerticalResolution, (ResizeFilterType)avsSettings.ResizeMethod);

            string newScript = ScriptServer.CreateScriptFromTemplate(avsSettings.Template, inputLine, cropLine, resizeLine, denoiseLines, deinterlaceLines);

            if (dar.HasValue)
            {
                newScript = string.Format("global MeGUI_darx = {0}\r\nglobal MeGUI_dary = {1}\r\n{2}", dar.Value.X, dar.Value.Y, newScript);
            }
            logBuilder.Append("Avisynth script created:\r\n");
            logBuilder.Append(newScript);
            try
            {
                StreamWriter sw = new StreamWriter(Path.ChangeExtension(path, ".avs"));
                sw.Write(newScript);
                sw.Close();
            }
            catch (IOException i)
            {
                logBuilder.Append("An error ocurred when trying to save the AviSynth script:\r\n" + i.Message);
                return("");
            }
            return(Path.ChangeExtension(path, ".avs"));
        }