private void PlayScript(string script) { try { reader = new AviSynthReader(); reader.ParseScript(script); int total = reader.FrameCount; for (int i = 0; i < total && !IsAborted; i++) { reader.ReadFrameDummy(i); worker.ReportProgress(((i + 1) * 100) / total); } } catch (Exception ex) { if (!IsAborted && num_closes == 0) { IsErrors = true; ErrorText = "SourceDetector (PlayScript): " + ex.Message; StackTrace = ex.StackTrace; Script = script; } } finally { CloseReader(true); } }
private void worker_DoWork(object sender, DoWorkEventArgs e) { try { reader = new AviSynthReader(); reader.ParseScript(script); total = reader.FrameCount; start = DateTime.Now; for (int i = 0; i < total && !IsAborted; i++) { reader.ReadFrameDummy(i); worker.ReportProgress(i + 1, DateTime.Now); } } catch (Exception ex) { if (!IsAborted && num_closes == 0) { e.Result = ex; } } finally { CloseReader(true); } }
private void CloseReader(bool _null) { lock (locker) { if (reader != null) { reader.Close(); if (_null) reader = null; } } }
private void CloseReader(bool _null) { lock (locker) { if (reader != null) { reader.Close(); if (_null) { reader = null; } } } }
private void CloseReader() { lock (locker) { if (buffer != IntPtr.Zero) { Marshal.FreeHGlobal(buffer); buffer = IntPtr.Zero; } if (reader != null) { reader.Close(); reader = null; } } }
private void LoadAviSynth() { try { if (reader == null) { reader = new AviSynthReader(AviSynthColorspace.RGB32, AudioSampleType.Undefined); reader.OpenScript(script); if (!reader.Clip.HasVideo || reader.FrameCount == 0) { HasVideo = false; } else { HasVideo = true; Width = reader.Width; Height = reader.Height; TotalFrames = reader.FrameCount; Framerate = reader.Framerate; } if (!EnableAudio || reader.SamplesCount == 0 || reader.Samplerate == 0 || reader.Channels == 0) { HasAudio = false; } else { HasAudio = true; Samplerate = reader.Samplerate; TotalSamples = reader.SamplesCount; } if (AvsStateChanged != null) { OwnerDispatcher.Invoke(Priority, (ThreadStart) delegate() { AvsStateChanged(this, true); }); } } } catch (Exception ex) { SetError(ex); } }
public static string CheckScriptErrors(Massive m) { string er = null; AviSynthReader reader = new AviSynthReader(); try { reader.ParseScript(m.script); } catch (Exception ex) { er = ex.Message; } reader.Close(); reader = null; return er; }
public void UnloadAviSynth() { lock (locker) { if (reader != null) { try { reader.Close(); } //catch (Exception) { } //Всё-равно вылезет в ~AviSynthClip() finally { reader = null; if (!IsError && !IsAborted && AvsStateChanged != null) { OwnerDispatcher.Invoke(Priority, (ThreadStart) delegate() { AvsStateChanged(this, false); }); } } } } }
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { //Выходим при отмене if (m == null || worker.CancellationPending) { return; } string script = ""; try { string ext = Path.GetExtension(m.infilepath).ToLower(); //получаем инфу из простого avs script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.Info); reader = new AviSynthReader(AviSynthColorspace.RGB24, AudioSampleType.INT16); reader.ParseScript(script); //Выходим при отмене if (m == null || worker.CancellationPending) { return; } //Видео if (!only_audio) { if (reader.Framerate != Double.PositiveInfinity && reader.Framerate != 0.0) { m.induration = TimeSpan.FromSeconds((double)reader.FrameCount / reader.Framerate); m.outduration = m.induration; m.inframes = reader.FrameCount; if (string.IsNullOrEmpty(m.inframerate)) { m.inframerate = Calculate.ConvertDoubleToPointString(reader.Framerate); } } if (m.isvideo && ext != ".avs" && (reader.Width == 0 || reader.Height == 0)) { throw new Exception(m.vdecoder.ToString() + " can't decode video (zero-size image was returned)!"); } else if ((m.vdecoder == AviSynthScripting.Decoders.LSMASHVideoSource || m.vdecoder == AviSynthScripting.Decoders.LWLibavVideoSource) && //16 - допуск на паддинг и т.д. string.IsNullOrEmpty(m.disable_hacked_vout) && ((Math.Abs(reader.Width / 2 - m.inresw) < 16) || (Math.Abs(reader.Height / 2 - m.inresh)) < 16)) { //LSMASH декодирует многобитное видео с удвоением ширины\высоты, пока-что это не поддерживается m.disable_hacked_vout = Calculate.GetLSMASHFormat8(reader.Clip.OriginalColorspace); throw new Exception("Hacked output"); } else { m.inresw = reader.Width; m.inresh = reader.Height; if (m.inaspect == 0 || double.IsNaN(m.inaspect)) { m.inaspect = (double)m.inresw / (double)m.inresh; } if (ext == ".avs") { //Такое можно получить видимо только вписав в скрипт KillVideo()\KillAudio() if ((reader.Width == 0 || reader.Height == 0) && reader.Samplerate == 0) { throw new Exception("An empty script (no video and no audio)!"); } //Считываем SAR из скрипта m.pixelaspect = reader.GetVarFloat("OUT_SAR_X", 1) / reader.GetVarFloat("OUT_SAR_Y", 1); } } } //Звук if (reader.Samplerate == 0) { if (m.inaudiostreams.Count > 0 && Settings.EnableAudio || only_audio) { //похоже что звук не декодируется этим декодером throw new Exception("Script doesn't contain audio!"); } } else { //Определение продолжительности и числа кадров для audio-only файлов (т.е. без видео) if (!m.isvideo && m.inframes == 0 && m.induration == TimeSpan.Zero) { m.induration = m.outduration = TimeSpan.FromSeconds(reader.SamplesCount / (double)reader.Samplerate); m.inframes = (int)(m.induration.TotalSeconds * ((!string.IsNullOrEmpty(m.inframerate)) ? Calculate.ConvertStringToDouble(m.inframerate) : 25)); } AudioStream instream = (m.inaudiostreams.Count > 0) ? (AudioStream)m.inaudiostreams[m.inaudiostream] : new AudioStream(); if (instream.channels > 0) { //вероятно аудио декодер меняет количество каналов if (instream.channels != reader.Channels) { instream.badmixing = true; } } else { instream.channels = reader.Channels; } instream.samplerate = reader.Samplerate.ToString(); instream.bits = reader.BitsPerSample; if (m.inaudiostreams.Count > 0) { //Битрейт для PCM if (instream.bitrate == 0 && (instream.codecshort == "PCM" || instream.codecshort == "LPCM")) { instream.bitrate = (reader.BitsPerSample * reader.Samplerate * reader.Channels) / 1000; //kbps } } else if (ext == ".avs" && !only_audio) { //Звук из скрипта instream.bitrate = (reader.BitsPerSample * reader.Samplerate * reader.Channels) / 1000; //kbps instream.codec = instream.codecshort = "PCM"; instream.language = "Unknown"; m.inaudiostreams.Add(instream.Clone()); } } } catch (Exception ex) { if (worker != null && !worker.CancellationPending && m != null && num_closes == 0) { //Ошибка ex.HelpLink = script; e.Result = ex; try { //записываем скрипт с ошибкой в файл AviSynthScripting.WriteScriptToFile(script + "\r\n\r\n__END__\r\n\r\n Error: " + ex.Message + "\r\n" + ex.StackTrace, "error"); } catch (Exception) { } } } finally { CloseReader(true); } }
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { try { //забиваем необходимые параметры MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(m.infilepath); m.invcodec = media.VCodecString; m.invcodecshort = media.VCodecShort; //Добавляем инфу, по которой потом можно будет определить, применять ли ForceFilm m.inframerate = media.FrameRate; bool pulldown = media.ScanOrder.Contains("Pulldown"); media.Close(); //Выходим при отмене if (worker.CancellationPending) { return; } //проверка на невалидную индексацию if (!NV && m.invcodecshort != "MPEG2" && m.invcodecshort != "MPEG1") { //Выходим отсюда, декодер будет выбран позже m.indexfile = null; m.vdecoder = 0; return; } //получаем индекс файл m.indexfile = Calculate.GetBestIndexFile(m.infilepath, NV); //определяем видео декодер if (NV) { m.vdecoder = AviSynthScripting.Decoders.DGSource; m.dgdecnv_path = Calculate.StartupPath + "\\apps\\DGDecNV\\"; } else { m.vdecoder = AviSynthScripting.Decoders.MPEG2Source; } if (File.Exists(m.indexfile) && !worker.CancellationPending) { //Определяем, использовался ли Force Film (#1) //Для DGSource ForceFilm задается через скрипт, а не через правку индекс-файла, //его в любой момент можно вкл\выкл, поэтому тут нужно определиться, использовать ли ForceFilm. if (m.vdecoder == AviSynthScripting.Decoders.DGSource) { if (Indexing_DGIndexNV.CheckIndexAndForceFilm(m.indexfile, m.inframerate)) { m.IsForcedFilm = true; m.interlace = SourceType.UNKNOWN; } } //проверяем папки script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.Info); reader = new AviSynthReader(); reader.ParseScript(script); m.induration = TimeSpan.FromSeconds((double)reader.FrameCount / reader.Framerate); //Определяем, использовался ли Force Film (#2) //Для MPEG2Source ForceFilm задается через правку индекс-файла, //поэтому изменив его однажды (при индексации) ForceFilm всегда будет вкл. if (m.vdecoder == AviSynthScripting.Decoders.MPEG2Source) { if ((pulldown && m.inframerate == "23.976" || m.inframerate == "29.970") && Math.Abs(reader.Framerate - 23.976) < 0.001) { m.IsForcedFilm = true; m.interlace = SourceType.UNKNOWN; } } //Закрываем ридер CloseReader(true); //проверка на устаревшую индекс папку string ifopath = Calculate.GetIFO(m.infilepath); if (File.Exists(ifopath) && !worker.CancellationPending) { VStripWrapper vs = new VStripWrapper(); vs.Open(ifopath); TimeSpan duration = vs.Duration(); vs.Close(); //папка устарела (если разница между продолжительностью в скрипте и в IFO больше 10-ти секунд) if (Math.Abs(m.induration.Duration().TotalSeconds - duration.TotalSeconds) > 10) { //Будем папку удалять.. throw new Exception("MPEG2Source"); } } } } catch (Exception ex) { if (worker != null && !worker.CancellationPending && m != null && num_closes == 0) { //Ошибка ex.HelpLink = script; e.Result = ex; } } finally { CloseReader(true); } }
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { try { //Готовим скрипт script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.Autocrop); script = AviSynthScripting.TuneAutoCropScript(script, frame); //Открываем скрипт reader = new AviSynthReader(); reader.ParseScript(script); int width = m.inresw; int height = m.inresh; int frames = reader.FrameCount; ArrayList ll = new ArrayList(); ArrayList tt = new ArrayList(); ArrayList rr = new ArrayList(); ArrayList bb = new ArrayList(); //Проигрываем все кадры и считываем значения кропа for (int i = 0; i < frames && !worker.CancellationPending; i++) { reader.ReadFrameDummy(i); worker.ReportProgress(((i + 1) * 100) / frames); //Фильтрация возможных(?) недопустимых значений ll.Add(Math.Min(Math.Max(reader.GetVarInteger("crop_left", 0), 0), width)); tt.Add(Math.Min(Math.Max(reader.GetVarInteger("crop_top", 0), 0), height)); rr.Add(Math.Min(Math.Max(reader.GetVarInteger("crop_right", 0), 0), width)); bb.Add(Math.Min(Math.Max(reader.GetVarInteger("crop_bottom", 0), 0), height)); } //Анализ полученного if (!worker.CancellationPending) { if (ll.Count > 0) { bool new_mode = Settings.AutocropMostCommon; //Ищем наиболее часто встречающиеся значения ("усредняем") или берём минимальные значения m.cropl = m.cropl_copy = (ll.Count > 4 && new_mode) ? FindMostCommon(ll) : FindMinimum(ll); //Слева m.cropt = m.cropt_copy = (tt.Count > 4 && new_mode) ? FindMostCommon(tt) : FindMinimum(tt); //Сверху m.cropr = m.cropr_copy = (rr.Count > 4 && new_mode) ? FindMostCommon(rr) : FindMinimum(rr); //Справа m.cropb = m.cropb_copy = (bb.Count > 4 && new_mode) ? FindMostCommon(bb) : FindMinimum(bb); //Снизу } else { m.cropl = m.cropl_copy = 0; //Слева m.cropt = m.cropt_copy = 0; //Сверху m.cropr = m.cropr_copy = 0; //Справа m.cropb = m.cropb_copy = 0; //Снизу } } } catch (Exception ex) { if (worker != null && !worker.CancellationPending && m != null && num_closes == 0) { //Ошибка ex.HelpLink = script; e.Result = ex; } } finally { CloseReader(true); } }
public VisualCrop(Massive mass, Window owner) { m = mass.Clone(); oldm = mass.Clone(); this.InitializeComponent(); this.Owner = owner; //Создаем скрипт (т.к. текущий с кропом и ресайзом не годится) script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.VCrop); numl.Value = left = m.cropl; numr.Value = right = m.cropr; numt.Value = top = m.cropt; numb.Value = bottom = m.cropb; Color color = Settings.VCropBrush; slider_R.Value = R = color.R; slider_G.Value = G = color.G; slider_B.Value = B = color.B; slider_A.Value = A = color.A; FinalColor.Color = Color.FromArgb(255, R, G, B); numl.ToolTip = Languages.Translate("Left"); numt.ToolTip = Languages.Translate("Top"); numr.ToolTip = Languages.Translate("Right"); numb.ToolTip = Languages.Translate("Bottom"); button_autocrop.Content = Languages.Translate("Analyse"); button_autocrop.ToolTip = Languages.Translate("Autocrop black borders"); button_autocrop_current.ToolTip = Languages.Translate("Autocrop on current frame"); button_uncrop.ToolTip = Languages.Translate("Remove crop"); button_settings.ToolTip = Languages.Translate("Settings"); slider_A.ToolTip = Languages.Translate("Transparency of the mask"); slider_R.ToolTip = slider_G.ToolTip = slider_B.ToolTip = Languages.Translate("Brightness of the mask"); button_fullscreen.ToolTip = Languages.Translate("Fullscreen mode"); button_cancel.Content = Languages.Translate("Cancel"); frame_of = Languages.Translate("Frame XX of YY").ToLower(); cropped_s = Languages.Translate("cropped size"); try { reader = new AviSynthReader(AviSynthColorspace.RGB24, AudioSampleType.Undefined); reader.ParseScript(script); if (reader.Clip.HasVideo && reader.FrameCount > 0) { slider_pos.Maximum = reader.FrameCount; slider_pos.Value = (Settings.VCropFrame == "THM-frame") ? m.thmframe : 0; numl.Maximum = numr.Maximum = width = reader.Width; numt.Maximum = numb.Maximum = height = reader.Height; fps = reader.Framerate; stride = width * bpp; buffer = Marshal.AllocHGlobal(stride * height); HasVideo = true; SetFrame((int)slider_pos.Value); ShowCroppedFrame(); } else { PreviewError("NO VIDEO", Brushes.Gainsboro); } } catch (Exception ex) { SetPreviewError(ex); } if (IsError) { CloseReader(); Close(); } else { WindowLoaded = true; ShowDialog(); } }
public Task(string thm, TaskStatus status, Massive mass) { _info = ""; _thm = thm; _status = status; _name = Path.GetFileName(mass.outfilepath); if (mass.outvcodec != "Copy" && mass.outvcodec != "Disabled") { //Переопределение некоторых параметров видео на основе текущего скрипта (т.к. он мог быть изменен вручную) if (Settings.ReadScript) //если в настройках это разрешено { bool recalc_sar = false; AviSynthReader reader = null; try { reader = new AviSynthReader(); reader.ParseScript(mass.script); if (mass.outresw != reader.Width) { if (mass.outvcodec == "x264" && Calculate.GetScriptBitDepth(mass.script) != 8) { if (mass.outresw != reader.Width / 2) { mass.outresw = reader.Width / 2; recalc_sar = true; } } else { mass.outresw = reader.Width; recalc_sar = true; } } if (mass.outresh != reader.Height) { mass.outresh = reader.Height; recalc_sar = true; } mass.outframes = reader.FrameCount; mass.outframerate = Calculate.ConvertDoubleToPointString(reader.Framerate); mass.outduration = TimeSpan.FromSeconds((double)mass.outframes / reader.Framerate); mass.outfilesize = Calculate.GetEncodingSize(mass); } catch { } finally { reader.Close(); reader = null; } //Переопределяем SAR в случае анаморфного кодирования (если разрешение поменялось) if (recalc_sar && mass.sar != null && mass.sar != "1:1") { mass = Calculate.CalculateSAR(mass); } } _info += mass.outresw + "x" + mass.outresh; _info += " " + mass.outframerate; if (mass.encodingmode == Settings.EncodingModes.Quality || mass.encodingmode == Settings.EncodingModes.Quantizer || mass.encodingmode == Settings.EncodingModes.TwoPassQuality || mass.encodingmode == Settings.EncodingModes.ThreePassQuality) { _info += " Q" + Calculate.ConvertDoubleToPointString((double)mass.outvbitrate, 1); } else if (mass.encodingmode == Settings.EncodingModes.TwoPassSize || mass.encodingmode == Settings.EncodingModes.ThreePassSize || mass.encodingmode == Settings.EncodingModes.OnePassSize) { _info += " " + mass.outvbitrate + "mb"; } else { _info += " " + mass.outvbitrate + "kbps"; } } else if (mass.outvcodec == "Copy") { _info += mass.inresw + "x" + mass.inresh; _info += " " + mass.inframerate; _info += " " + mass.invbitrate + "kbps"; } if (mass.outaudiostreams.Count > 0) { AudioStream outstream = (AudioStream)mass.outaudiostreams[mass.outaudiostream]; if (outstream.codec != "Copy") { _info += " " + outstream.samplerate + "Hz"; _info += " " + Calculate.ExplainChannels(outstream.channels); _info += " " + ((outstream.bitrate > 0) ? outstream.bitrate + "kbps" : "VBR"); if (mass.volume != "Disabled") { _info += " " + mass.volume; } } else { if (mass.inaudiostreams.Count > 0) { AudioStream instream = (AudioStream)mass.inaudiostreams[mass.inaudiostream]; _info += " " + instream.samplerate + "Hz"; _info += " " + Calculate.ExplainChannels(instream.channels); _info += " " + instream.bitrate + "kbps"; } } } _info += " " + ((mass.outfilesize != Languages.Translate("Unknown")) ? mass.outfilesize.Replace(" ", "") : "?mb"); _mass = mass.Clone(); _id = mass.key; }
private void LoadAviSynth() { try { if (reader == null) { reader = new AviSynthReader(AviSynthColorspace.RGB32, AudioSampleType.Undefined); reader.OpenScript(script); if (!reader.Clip.HasVideo || reader.FrameCount == 0) { HasVideo = false; } else { HasVideo = true; Width = reader.Width; Height = reader.Height; TotalFrames = reader.FrameCount; Framerate = reader.Framerate; } if (!EnableAudio || reader.SamplesCount == 0 || reader.Samplerate == 0 || reader.Channels == 0) { HasAudio = false; } else { HasAudio = true; Samplerate = reader.Samplerate; TotalSamples = reader.SamplesCount; } if (AvsStateChanged != null) { OwnerDispatcher.Invoke(Priority, (ThreadStart)delegate() { AvsStateChanged(this, true); }); } } } catch (Exception ex) { SetError(ex); } }
private void RunAnalyzer(Detecting detecting, int frameCount, string trimLine) { if (IsAborted || IsErrors) { return; } string script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.Interlace); int numFrames = 0; if (frameCount > 0) { numFrames = frameCount; } else { try { reader = new AviSynthReader(); reader.ParseScript(script); numFrames = reader.FrameCount; } catch (Exception ex) { if (!IsAborted && num_closes == 0) { IsErrors = true; ErrorText = "SourceDetector (RunAnalyzer): " + ex.Message; StackTrace = ex.StackTrace; Script = script; } } finally { CloseReader(true); } } if (IsAborted || IsErrors) { return; } //Еще настройки int SelectLength = 5; //Длина выборки (5 кадров) int MinAnalyseSections = Settings.SD_Min_Sections; //Мин. кол-во секций для анализа, 150 if (detecting == Detecting.Fields) { //Тут в описании неточность, в оригинале выход скрипта имеет в два раза больше кадров из-за //loop(2), а не из-за SeparateFields. Вместо loop(2) лучше использовать один из уже готовых //клипов с удвоенным кол-вом кадров: atff или abff (без разницы) - декодеру не придется //дважды проходить по одному и тому-же месту (loop(2) - дошли до конца, идем в начало и //начинаем новый проход через весь клип). А если еще вместо DifferenceFromPrevious //использовать DifferenceToNext, то скорость вырастет еще больше! //SelectLength надо тоже установить равным 10-ти, иначе в одной выборке для FieldOrder //будут группы кадров (полей) из двух разных участков видео. //----- // Field order script. For this, we separatefields, so we have twice as many frames anyway // It saves time, and costs nothing to halve the minimum sections to analyse for this example //minAnalyseSections = minAnalyseSections / 2 + 1; // We add one to prevent getting 0; int NewLength = 10; //Длина выборки будет 10 кадров, а мин. кол-во секций пропорционально уменьшаем MinAnalyseSections = (int)Math.Max(MinAnalyseSections / (NewLength / (double)SelectLength), 1); SelectLength = NewLength; } // Check if we need to modify the SelectRangeEvery parameters: int SelectEvery = (int)((100.0 * (double)SelectLength) / AnalysePercent); if (((double)SelectLength * (double)numFrames / (double)SelectEvery) < (int)MinAnalyseSections * SelectLength) { if (numFrames >= MinAnalyseSections * SelectLength) // If there are actually enough frames { SelectEvery = (int)(((double)numFrames / ((double)MinAnalyseSections * (double)SelectLength)) * (double)SelectLength); } else { // if there aren't enough frames, analyse everything -- that's got to be good enough SelectEvery = SelectLength; } } //Имя лог-файла string logFileName = Settings.TempPath + "\\detecting_" + detecting.ToString().ToLower() + ".log"; File.Delete(logFileName); //Прогон скрипта if (detecting == Detecting.Fields) { SetFieldPhase(); } PlayScript(AviSynthScripting.GetSourceDetectionScript(detecting, script, trimLine, logFileName, SelectEvery, SelectLength)); if (IsAborted || IsErrors) { return; } //Определение интерлейса\полей (чтение и анализ лог-файлов) if (detecting == Detecting.Interlace) { AnalyseInterlace(logFileName, SelectEvery, SelectLength, numFrames); } else if (detecting == Detecting.Fields) { AnalyseFields(logFileName, SelectLength); } }
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { //Выходим при отмене if (m == null || worker.CancellationPending) return; string script = ""; try { string ext = Path.GetExtension(m.infilepath).ToLower(); //получаем инфу из простого avs script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.Info); reader = new AviSynthReader(AviSynthColorspace.RGB24, AudioSampleType.INT16); reader.ParseScript(script); //Выходим при отмене if (m == null || worker.CancellationPending) return; AudioStream instream = (m.inaudiostreams.Count > 0) ? (AudioStream)m.inaudiostreams[m.inaudiostream] : new AudioStream(); if (reader.Framerate != Double.PositiveInfinity && reader.Framerate != 0.0) { m.induration = TimeSpan.FromSeconds((double)reader.FrameCount / reader.Framerate); m.outduration = m.induration; m.inframes = reader.FrameCount; if (string.IsNullOrEmpty(m.inframerate)) m.inframerate = Calculate.ConvertDoubleToPointString(reader.Framerate); } if (m.isvideo && ext != ".avs" && (reader.Width == 0 || reader.Height == 0)) throw new Exception(m.vdecoder.ToString() + " can't decode video (zero-size image was returned)!"); else { m.inresw = reader.Width; m.inresh = reader.Height; if (m.inaspect == 0 || double.IsNaN(m.inaspect)) m.inaspect = (double)m.inresw / (double)m.inresh; if (ext == ".avs") { //Считываем SAR из скрипта m.pixelaspect = reader.GetVarFloat("OUT_SAR_X", 1) / reader.GetVarFloat("OUT_SAR_Y", 1); } } int samplerate = reader.Samplerate; if (samplerate == 0 && m.inaudiostreams.Count > 0 && Settings.EnableAudio) { //похоже что звук не декодируется этим декодером throw new Exception("Script doesn't contain audio"); } if (samplerate != 0 && (m.inaudiostreams.Count > 0 || instream.samplerate == null)) { if (instream.channels > 0) { //вероятно аудио декодер меняет количество каналов if (instream.channels != reader.Channels) instream.badmixing = true; } else instream.channels = reader.Channels; instream.samplerate = samplerate.ToString(); instream.bits = reader.BitsPerSample; //Определение продолжительности и числа кадров только для звука (например, если исходник - RAW ААС) if (!m.isvideo && m.inframes == 0 && m.induration == TimeSpan.Zero) { m.induration = m.outduration = TimeSpan.FromSeconds(reader.SamplesCount / (double)reader.Samplerate); m.inframes = (int)(m.induration.TotalSeconds * 25); } if (m.inaudiostreams.Count > 0 && instream.bitrate == 0 && (instream.codecshort == "PCM" || instream.codecshort == "LPCM")) instream.bitrate = (reader.BitsPerSample * reader.Samplerate * reader.Channels) / 1000; //kbps //если звук всё ещё не забит if (m.inaudiostreams.Count == 0 && ext == ".avs" && samplerate != 0) { instream.bitrate = (reader.BitsPerSample * reader.Samplerate * reader.Channels) / 1000; //kbps instream.codec = instream.codecshort = "PCM"; instream.language = "Unknown"; m.inaudiostreams.Add(instream.Clone()); } } } catch (Exception ex) { if (worker != null && !worker.CancellationPending && m != null && num_closes == 0) { //Ошибка ex.HelpLink = script; e.Result = ex; try { //записываем скрипт с ошибкой в файл AviSynthScripting.WriteScriptToFile(script, "error"); } catch (Exception) { } } } finally { CloseReader(true); } }
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { //Выходим при отмене if (m == null || worker.CancellationPending) return; string script = ""; try { string ext = Path.GetExtension(m.infilepath).ToLower(); //получаем инфу из простого avs script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.Info); reader = new AviSynthReader(AviSynthColorspace.RGB24, AudioSampleType.INT16); reader.ParseScript(script); //Выходим при отмене if (m == null || worker.CancellationPending) return; //Видео if (!only_audio) { if (reader.Framerate != Double.PositiveInfinity && reader.Framerate != 0.0) { m.induration = TimeSpan.FromSeconds((double)reader.FrameCount / reader.Framerate); m.outduration = m.induration; m.inframes = reader.FrameCount; if (string.IsNullOrEmpty(m.inframerate)) m.inframerate = Calculate.ConvertDoubleToPointString(reader.Framerate); } if (m.isvideo && ext != ".avs" && (reader.Width == 0 || reader.Height == 0)) { throw new Exception(m.vdecoder.ToString() + " can't decode video (zero-size image was returned)!"); } else if ((m.vdecoder == AviSynthScripting.Decoders.LSMASHVideoSource || m.vdecoder == AviSynthScripting.Decoders.LWLibavVideoSource) && //16 - допуск на паддинг и т.д. string.IsNullOrEmpty(m.disable_hacked_vout) && ((Math.Abs(reader.Width / 2 - m.inresw) < 16) || (Math.Abs(reader.Height / 2 - m.inresh)) < 16)) { //LSMASH декодирует многобитное видео с удвоением ширины\высоты, пока-что это не поддерживается m.disable_hacked_vout = Calculate.GetLSMASHFormat8(reader.Clip.OriginalColorspace); throw new Exception("Hacked output"); } else { m.inresw = reader.Width; m.inresh = reader.Height; if (m.inaspect == 0 || double.IsNaN(m.inaspect)) m.inaspect = (double)m.inresw / (double)m.inresh; if (ext == ".avs") { //Такое можно получить видимо только вписав в скрипт KillVideo()\KillAudio() if ((reader.Width == 0 || reader.Height == 0) && reader.Samplerate == 0) throw new Exception("An empty script (no video and no audio)!"); //Считываем SAR из скрипта m.pixelaspect = reader.GetVarFloat("OUT_SAR_X", 1) / reader.GetVarFloat("OUT_SAR_Y", 1); } } } //Звук if (reader.Samplerate == 0) { if (m.inaudiostreams.Count > 0 && Settings.EnableAudio || only_audio) { //похоже что звук не декодируется этим декодером throw new Exception("Script doesn't contain audio!"); } } else { //Определение продолжительности и числа кадров для audio-only файлов (т.е. без видео) if (!m.isvideo && m.inframes == 0 && m.induration == TimeSpan.Zero) { m.induration = m.outduration = TimeSpan.FromSeconds(reader.SamplesCount / (double)reader.Samplerate); m.inframes = (int)(m.induration.TotalSeconds * ((!string.IsNullOrEmpty(m.inframerate)) ? Calculate.ConvertStringToDouble(m.inframerate) : 25)); } AudioStream instream = (m.inaudiostreams.Count > 0) ? (AudioStream)m.inaudiostreams[m.inaudiostream] : new AudioStream(); if (instream.channels > 0) { //вероятно аудио декодер меняет количество каналов if (instream.channels != reader.Channels) instream.badmixing = true; } else instream.channels = reader.Channels; instream.samplerate = reader.Samplerate.ToString(); instream.bits = reader.BitsPerSample; if (m.inaudiostreams.Count > 0) { //Битрейт для PCM if (instream.bitrate == 0 && (instream.codecshort == "PCM" || instream.codecshort == "LPCM")) instream.bitrate = (reader.BitsPerSample * reader.Samplerate * reader.Channels) / 1000; //kbps } else if (ext == ".avs" && !only_audio) { //Звук из скрипта instream.bitrate = (reader.BitsPerSample * reader.Samplerate * reader.Channels) / 1000; //kbps instream.codec = instream.codecshort = "PCM"; instream.language = "Unknown"; m.inaudiostreams.Add(instream.Clone()); } } } catch (Exception ex) { if (worker != null && !worker.CancellationPending && m != null && num_closes == 0) { //Ошибка ex.HelpLink = script; e.Result = ex; try { //записываем скрипт с ошибкой в файл AviSynthScripting.WriteScriptToFile(script + "\r\n\r\n__END__\r\n\r\n Error: " + ex.Message + "\r\n" + ex.StackTrace, "error"); } catch (Exception) { } } } finally { CloseReader(true); } }
private void UpdateScriptAndDuration() { //Обновляем скрипт m = AviSynthScripting.CreateAutoAviSynthScript(m); LoadVideo(MediaLoad.update); //Пересчет кол-ва кадров в видео, его продолжительности и размера получаемого файла int outframes = 0; TimeSpan outduration = TimeSpan.Zero; AviSynthReader reader = null; bool is_errors = false; try { reader = new AviSynthReader(); reader.ParseScript(m.script); outframes = reader.FrameCount; outduration = TimeSpan.FromSeconds((double)outframes / reader.Framerate); // / fps) } catch { is_errors = true; } finally { reader.Close(); reader = null; } if (!is_errors) { m.outframes = outframes; m.outduration = outduration; //TimeSpan.FromSeconds((double)m.outframes / fps); m.thmframe = m.outframes / 2; } else m = Calculate.UpdateOutFrames(m); m.outfilesize = Calculate.GetEncodingSize(m); UpdateTaskMassive(m); }
private void SavePicture(string path, int width, int height, bool fix_ar, int frame) { System.Drawing.Bitmap bmp = null; System.Drawing.Graphics g = null; AviSynthReader reader = null; string new_script = m.script; try { if (fix_ar && width != 0 && height != 0) { int crop_w = 0, crop_h = 0; double old_asp = m.outaspect; double new_asp = (double)width / (double)height; if (old_asp < new_asp) { crop_h = Math.Max(Convert.ToInt32((m.outresh - ((m.outresh * old_asp) / new_asp)) / 2), 0); } else if (old_asp > new_asp) { crop_w = Math.Max(Convert.ToInt32((m.outresw - (m.outresw / old_asp) * new_asp) / 2), 0); } new_script += ("Lanczos4Resize(" + width + ", " + height + ", " + crop_w + ", " + crop_h + ", -" + crop_w + ", -" + crop_h + ")\r\n"); } reader = new AviSynthReader(AviSynthColorspace.RGB24, AudioSampleType.Undefined); reader.ParseScript(new_script); if (width == 0 || height == 0 || (width == reader.Width && height == reader.Height)) { bmp = new System.Drawing.Bitmap(reader.ReadFrameBitmap(frame)); } else { bmp = new System.Drawing.Bitmap(width, height); g = System.Drawing.Graphics.FromImage(bmp); //метод интерполяции при ресайзе g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage(reader.ReadFrameBitmap(frame), 0, 0, width, height); } string ext = Path.GetExtension(path).ToLower(); if (ext == ".jpg") { //процент cжатия jpg System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders(); System.Drawing.Imaging.EncoderParameters encoderParameters = new System.Drawing.Imaging.EncoderParameters(1); encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 95L); //jpg bmp.Save(path, info[1], encoderParameters); } else if (ext == ".png") { //png bmp.Save(path, System.Drawing.Imaging.ImageFormat.Png); } else { //bmp bmp.Save(path, System.Drawing.Imaging.ImageFormat.Bmp); } } catch (Exception ex) { ErrorException("SavePicture: " + ex.Message, ex.StackTrace); } finally { //завершение if (g != null) { g.Dispose(); g = null; } if (bmp != null) { bmp.Dispose(); bmp = null; } if (reader != null) { reader.Close(); reader = null; } } }
private void RunAnalyzer(Detecting detecting, int frameCount, string trimLine) { if (IsAborted || IsErrors) return; string script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.Interlace); int numFrames = 0; if (frameCount > 0) numFrames = frameCount; else { try { reader = new AviSynthReader(); reader.ParseScript(script); numFrames = reader.FrameCount; } catch (Exception ex) { if (!IsAborted && num_closes == 0) { IsErrors = true; ErrorText = "SourceDetector (RunAnalyzer): " + ex.Message; StackTrace = ex.StackTrace; Script = script; } } finally { CloseReader(true); } } if (IsAborted || IsErrors) return; //Еще настройки int SelectLength = 5; //Длина выборки (5 кадров) int MinAnalyseSections = Settings.SD_Min_Sections; //Мин. кол-во секций для анализа, 150 if (detecting == Detecting.Fields) { //Тут в описании неточность, в оригинале выход скрипта имеет в два раза больше кадров из-за //loop(2), а не из-за SeparateFields. Вместо loop(2) лучше использовать один из уже готовых //клипов с удвоенным кол-вом кадров: atff или abff (без разницы) - декодеру не придется //дважды проходить по одному и тому-же месту (loop(2) - дошли до конца, идем в начало и //начинаем новый проход через весь клип). А если еще вместо DifferenceFromPrevious //использовать DifferenceToNext, то скорость вырастет еще больше! //SelectLength надо тоже установить равным 10-ти, иначе в одной выборке для FieldOrder //будут группы кадров (полей) из двух разных участков видео. //----- // Field order script. For this, we separatefields, so we have twice as many frames anyway // It saves time, and costs nothing to halve the minimum sections to analyse for this example //minAnalyseSections = minAnalyseSections / 2 + 1; // We add one to prevent getting 0; int NewLength = 10; //Длина выборки будет 10 кадров, а мин. кол-во секций пропорционально уменьшаем MinAnalyseSections = (int)Math.Max(MinAnalyseSections / (NewLength / (double)SelectLength), 1); SelectLength = NewLength; } // Check if we need to modify the SelectRangeEvery parameters: int SelectEvery = (int)((100.0 * (double)SelectLength) / AnalysePercent); if (((double)SelectLength * (double)numFrames / (double)SelectEvery) < (int)MinAnalyseSections * SelectLength) { if (numFrames >= MinAnalyseSections * SelectLength) // If there are actually enough frames { SelectEvery = (int)(((double)numFrames / ((double)MinAnalyseSections * (double)SelectLength)) * (double)SelectLength); } else // if there aren't enough frames, analyse everything -- that's got to be good enough SelectEvery = SelectLength; } //Имя лог-файла string logFileName = Settings.TempPath + "\\detecting_" + detecting.ToString().ToLower() + ".log"; File.Delete(logFileName); //Прогон скрипта if (detecting == Detecting.Fields) SetFieldPhase(); PlayScript(AviSynthScripting.GetSourceDetectionScript(detecting, script, trimLine, logFileName, SelectEvery, SelectLength)); if (IsAborted || IsErrors) return; //Определение интерлейса\полей (чтение и анализ лог-файлов) if (detecting == Detecting.Interlace) AnalyseInterlace(logFileName, SelectEvery, SelectLength, numFrames); else if (detecting == Detecting.Fields) AnalyseFields(logFileName, SelectLength); }
public Task(string thm, TaskStatus status, Massive mass) { _info = ""; _thm = thm; _status = status; _name = Path.GetFileName(mass.outfilepath); if (mass.outvcodec != "Copy" && mass.outvcodec != "Disabled") { //Переопределение некоторых параметров видео на основе текущего скрипта (т.к. он мог быть изменен вручную) if (Settings.ReadScript) //если в настройках это разрешено { bool recalc_sar = false; AviSynthReader reader = null; try { reader = new AviSynthReader(); reader.ParseScript(mass.script); if (mass.outresw != reader.Width) { if (mass.outvcodec == "x264" && Calculate.GetScriptBitDepth(mass.script) != 8) { if (mass.outresw != reader.Width / 2) { mass.outresw = reader.Width / 2; recalc_sar = true; } } else { mass.outresw = reader.Width; recalc_sar = true; } } if (mass.outresh != reader.Height) { mass.outresh = reader.Height; recalc_sar = true; } mass.outframes = reader.FrameCount; mass.outframerate = Calculate.ConvertDoubleToPointString(reader.Framerate); mass.outduration = TimeSpan.FromSeconds((double)mass.outframes / reader.Framerate); mass.outfilesize = Calculate.GetEncodingSize(mass); } catch { } finally { reader.Close(); reader = null; } //Переопределяем SAR в случае анаморфного кодирования (если разрешение поменялось) if (recalc_sar && mass.sar != null && mass.sar != "1:1") { mass = Calculate.CalculateSAR(mass); } } _info += mass.outresw + "x" + mass.outresh; _info += " " + mass.outframerate; if (mass.encodingmode == Settings.EncodingModes.Quality || mass.encodingmode == Settings.EncodingModes.Quantizer || mass.encodingmode == Settings.EncodingModes.TwoPassQuality || mass.encodingmode == Settings.EncodingModes.ThreePassQuality) _info += " Q" + Calculate.ConvertDoubleToPointString((double)mass.outvbitrate, 1); else if (mass.encodingmode == Settings.EncodingModes.TwoPassSize || mass.encodingmode == Settings.EncodingModes.ThreePassSize || mass.encodingmode == Settings.EncodingModes.OnePassSize) _info += " " + mass.outvbitrate + "mb"; else _info += " " + mass.outvbitrate + "kbps"; } else if (mass.outvcodec == "Copy") { _info += mass.inresw + "x" + mass.inresh; _info += " " + mass.inframerate; _info += " " + mass.invbitrate + "kbps"; } if (mass.outaudiostreams.Count > 0) { AudioStream outstream = (AudioStream)mass.outaudiostreams[mass.outaudiostream]; if (outstream.codec != "Copy") { _info += " " + outstream.samplerate + "Hz"; _info += " " + Calculate.ExplainChannels(outstream.channels); _info += " " + ((outstream.bitrate > 0) ? outstream.bitrate + "kbps" : "VBR"); if (mass.volume != "Disabled") _info += " " + mass.volume; } else { if (mass.inaudiostreams.Count > 0) { AudioStream instream = (AudioStream)mass.inaudiostreams[mass.inaudiostream]; _info += " " + instream.samplerate + "Hz"; _info += " " + Calculate.ExplainChannels(instream.channels); _info += " " + instream.bitrate + "kbps"; } } } _info += " " + ((mass.outfilesize != Languages.Translate("Unknown")) ? mass.outfilesize.Replace(" ", "") : "?mb"); _mass = mass.Clone(); _id = mass.key; }
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { try { //забиваем необходимые параметры MediaInfoWrapper media = new MediaInfoWrapper(); media.Open(m.infilepath); m.invcodec = media.VCodecString; m.invcodecshort = media.VCodecShort; //Добавляем инфу, по которой потом можно будет определить, применять ли ForceFilm m.inframerate = media.FrameRate; bool pulldown = media.ScanOrder.Contains("Pulldown"); media.Close(); //Выходим при отмене if (worker.CancellationPending) return; //проверка на невалидную индексацию if (m.invcodecshort != "MPEG2" && m.invcodecshort != "MPEG1") { //Выходим отсюда, декодер будет выбран позже m.indexfile = null; m.vdecoder = 0; return; } //получаем индекс файл m.indexfile = Calculate.GetBestIndexFile(m.infilepath); //определяем видео декодер m.vdecoder = AviSynthScripting.Decoders.MPEG2Source; if (File.Exists(m.indexfile) && !worker.CancellationPending) { //проверяем папки script = AviSynthScripting.GetInfoScript(m, AviSynthScripting.ScriptMode.Info); reader = new AviSynthReader(); reader.ParseScript(script); m.induration = TimeSpan.FromSeconds((double)reader.FrameCount / reader.Framerate); //Определяем, использовался ли Force Film if ((pulldown && m.inframerate == "23.976" || m.inframerate == "29.970") && Math.Abs(reader.Framerate - 23.976) < 0.001) { m.IsForcedFilm = true; m.interlace = SourceType.UNKNOWN; } //Закрываем ридер CloseReader(true); //проверка на устаревшую индекс папку string ifopath = Calculate.GetIFO(m.infilepath); if (File.Exists(ifopath) && !worker.CancellationPending) { VStripWrapper vs = new VStripWrapper(); vs.Open(ifopath); TimeSpan duration = vs.Duration(); vs.Close(); //папка устарела (если разница между продолжительностью в скрипте и в IFO больше 10-ти секунд) if (Math.Abs(m.induration.Duration().TotalSeconds - duration.TotalSeconds) > 10) { //Будем папку удалять.. throw new Exception("MPEG2Source"); } } } } catch (Exception ex) { if (worker != null && !worker.CancellationPending && m != null && num_closes == 0) { //Ошибка ex.HelpLink = script; e.Result = ex; } } finally { CloseReader(true); } }
private void make_thm(int width, int height, bool fix_ar, string format) { Bitmap bmp = null; Graphics g = null; AviSynthReader reader = null; string new_script = m.script; string thmpath = Calculate.RemoveExtention(m.outfilepath) + format; SetLog("CREATING THM"); SetLog("------------------------------"); SetLog("Saving picture to: " + thmpath); SetLog(format.ToUpper() + " " + width + "x" + height + " \r\n"); try { if (fix_ar) { int crop_w = 0, crop_h = 0; double old_asp = m.outaspect; double new_asp = (double)width / (double)height; if (old_asp < new_asp) { crop_h = Math.Max(Convert.ToInt32((m.outresh - ((m.outresh * old_asp) / new_asp)) / 2), 0); } else if (old_asp > new_asp) { crop_w = Math.Max(Convert.ToInt32((m.outresw - (m.outresw / old_asp) * new_asp) / 2), 0); } new_script += ("Lanczos4Resize(" + width + ", " + height + ", " + crop_w + ", " + crop_h + ", -" + crop_w + ", -" + crop_h + ")\r\n"); } reader = new AviSynthReader(AviSynthColorspace.RGB24, AudioSampleType.Undefined); reader.ParseScript(new_script); //проверка на выходы за пределы общего количества кадров int frame = (m.thmframe > reader.FrameCount) ? reader.FrameCount / 2 : m.thmframe; if (width == reader.Width && height == reader.Height) { bmp = new System.Drawing.Bitmap(reader.ReadFrameBitmap(frame)); } else { bmp = new Bitmap(width, height); g = Graphics.FromImage(bmp); //метод интерполяции при ресайзе g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage(reader.ReadFrameBitmap(frame), 0, 0, width, height); } if (format == "jpg") { //процент cжатия jpg System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders(); System.Drawing.Imaging.EncoderParameters encoderParameters = new System.Drawing.Imaging.EncoderParameters(1); encoderParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 95L); //jpg bmp.Save(thmpath, info[1], encoderParameters); } else if (format == "png") { //png bmp.Save(thmpath, System.Drawing.Imaging.ImageFormat.Png); } else { //bmp bmp.Save(thmpath, System.Drawing.Imaging.ImageFormat.Bmp); } } catch (Exception ex) { SetLog("\r\nError creating THM: " + ex.Message.ToString() + Environment.NewLine); } finally { //завершение if (g != null) { g.Dispose(); g = null; } if (bmp != null) { bmp.Dispose(); bmp = null; } if (reader != null) { reader.Close(); reader = null; } SetLog(""); } }
public void UnloadAviSynth() { lock (locker) { if (reader != null) { try { reader.Close(); } //catch (Exception) { } //Всё-равно вылезет в ~AviSynthClip() finally { reader = null; if (!IsError && !IsAborted && AvsStateChanged != null) { OwnerDispatcher.Invoke(Priority, (ThreadStart)delegate() { AvsStateChanged(this, false); }); } } } } }