/// <summary> /// Is Invoked by playTimer to render the next frame for the video /// It will trigger the playThread to render the next frame. /// This solution is more complex than a simple Thread.Sleep, but /// has the advantage that the playback will be smoother if the frames /// take long to render. /// </summary> private void playNextFrame(object state) { try { //playback speed is correct, but frames may be dropped if computer is too slow if (EnsureCorrectPlaybackSpeed) { if (!OffsetPosition(1, false)) { Stop(); } else { InvokeOnPositionChanged(); } UpdateVideo(); } //no frames will be dropped, but the playback speed might be slower than realtime else { nextFrameEvent.Set(); } //Console.WriteLine("Frame {0} requested", Position); } catch (Exception e) { MeGUI.core.util.LogItem _oLog = MainForm.Instance.Log.Info("Error"); _oLog.LogValue("playNextFrame", e, MeGUI.core.util.ImageType.Error); } }
/// <summary> /// saves the currently configured matrix to a file /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void saveMatrixButton_Click(object sender, System.EventArgs e) { if (this.saveFileDialog.ShowDialog() == DialogResult.OK) { StreamWriter sw = null; try { sb = new StringBuilder(); sb.Append("#" + Path.GetFileNameWithoutExtension(saveFileDialog.FileName) + "\r\n\r\nINTRA4X4_LUMA =\r\n"); sb.Append(convertMatrixToString(this.I4x4L)); sb.Append("\r\n\r\nINTRA4X4_CHROMAU =\r\n"); sb.Append(convertMatrixToString(this.I4x4CU)); sb.Append("\r\n\r\nINTRA4X4_CHROMAV =\r\n"); sb.Append(convertMatrixToString(this.I4x4CY)); sb.Append("\r\n\r\nINTER4X4_LUMA =\r\n"); sb.Append(convertMatrixToString(this.P4x4L)); sb.Append("\r\n\r\nINTER4X4_CHROMAU =\r\n"); sb.Append(convertMatrixToString(this.P4x4CU)); sb.Append("\r\n\r\nINTER4X4_CHROMAV =\r\n"); sb.Append(convertMatrixToString(this.P4x4CY)); sb.Append("\r\n\r\nINTRA8X8_LUMA =\r\n"); sb.Append(convertMatrixToString(this.I8x8)); sb.Append("\r\n\r\nINTER8X8_LUMA =\r\n"); sb.Append(convertMatrixToString(this.P8x8)); sw = new StreamWriter(saveFileDialog.FileName, false); sw.Write(sb.ToString()); } catch (Exception f) { MeGUI.core.util.LogItem _oLog = MainForm.Instance.Log.Info("Error"); _oLog.LogValue("Error", f, MeGUI.core.util.ImageType.Error); } finally { if (sw != null) { try { sw.Close(); } catch (Exception f) { MeGUI.core.util.LogItem _oLog = MainForm.Instance.Log.Info("Error"); _oLog.LogValue("Error", f, MeGUI.core.util.ImageType.Error); } } } } }
/// <summary> /// converts a comma separated /// </summary> /// <param name="matrix"></param> /// <param name="size"></param> /// <returns></returns> private int[,] convertStringToMatrix(string matrix, int size) { int[,] retval = new int[size, size]; char[] splitChars = { ',' }; matrix = matrix.Replace("\r", ""); // removes newlines matrix = matrix.Replace("\n", ""); matrix = matrix.Replace("\t", ""); // remove tabs string[] quantizers = matrix.Split(splitChars); int column = 0; int line = 0; foreach (string quantizer in quantizers) { int val = 16; try { val = Int32.Parse(quantizer); } catch (Exception e) { MeGUI.core.util.LogItem _oLog = MainForm.Instance.Log.Info("Error"); _oLog.LogValue("convertStringToMatrix: " + matrix, e, MeGUI.core.util.ImageType.Error); MessageBox.Show("Invalid quantizer detected: " + quantizer + "\nUsing 16 instead", "Invalid quantizer", MessageBoxButtons.OK, MessageBoxIcon.Warning); } retval[line, column] = val; if (column == size - 1) { line++; column = 0; } else { column++; } } return(retval); }
/// <summary> /// loads a matrix from file /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void loadMatrixButton_Click(object sender, System.EventArgs e) { if (openFileDialog.ShowDialog() == DialogResult.OK) { StreamReader sr = null; string matrix = "", line = null; try { sr = new StreamReader(openFileDialog.FileName); while ((line = sr.ReadLine()) != null) { if (line.IndexOf("4X4") != -1) // 4x3 matrix { matrix = sr.ReadLine(); matrix += sr.ReadLine(); matrix += sr.ReadLine(); matrix += sr.ReadLine(); int[,] matrixRead = convertStringToMatrix(matrix, 4); if (line.IndexOf("INTRA4X4_LUMA") != -1) // I4x4L matrix { this.I4x4L = matrixRead; } else if (line.IndexOf("INTRA4X4_CHROMAU") != -1) { this.I4x4CU = matrixRead; } else if (line.IndexOf("INTRA4X4_CHROMAV") != -1) { this.I4x4CY = matrixRead; } else if (line.IndexOf("INTER4X4_LUMA") != -1) { this.P4x4L = matrixRead; } else if (line.IndexOf("INTER4X4_CHROMAU") != -1) { this.P4x4CU = matrixRead; } else if (line.IndexOf("INTER4X4_CHROMAV") != -1) { this.P4x4CY = matrixRead; } } if (line.IndexOf("8X8") != -1) // 8x8 matrix { matrix = sr.ReadLine(); matrix += sr.ReadLine(); matrix += sr.ReadLine(); matrix += sr.ReadLine(); matrix += sr.ReadLine(); matrix += sr.ReadLine(); matrix += sr.ReadLine(); matrix += sr.ReadLine(); int[,] matrixRead = convertStringToMatrix(matrix, 8); if (line.IndexOf("INTRA8X8_LUMA") != -1) { this.I8x8 = matrixRead; } else if (line.IndexOf("INTER8X8_LUMA") != -1) { this.P8x8 = matrixRead; } } } this.loadMatrix(getCurrentConfig()); this.predefinedMatrix.SelectedIndex = 3; } catch (Exception f) { MeGUI.core.util.LogItem _oLog = MainForm.Instance.Log.Info("Error"); _oLog.LogValue("Error", f, MeGUI.core.util.ImageType.Error); } finally { if (sr != null) { try { sr.Close(); } catch (Exception f) { MeGUI.core.util.LogItem _oLog = MainForm.Instance.Log.Info("Error"); _oLog.LogValue("Error", f, MeGUI.core.util.ImageType.Error); } } } } }
private void renderThreadLoop() { int framesPlayed = 0; DateTime start = DateTime.Now; do { DateTime end = DateTime.Now; TimeSpan renderTime = end - start; //do not update current framerate more often than 200ms if (renderTime.Milliseconds > 200 && framesPlayed > 0) { //average results actualFramerate = 0.9d * actualFramerate + 0.1d * (TimeSpan.TicksPerSecond / (double)renderTime.Ticks) * framesPlayed; start = end; framesPlayed = 0; } if (WaitHandle.WaitAny(new WaitHandle[] { nextFrameEvent, renderEvent }) == 0) { if (!OffsetPosition(1, false)) { Stop(); } else { InvokeOnPositionChanged(); } } Bitmap finalBitmap; int pos = position; try { using (Bitmap b = getFrame(pos)) { if (b == null) { continue; } //if (cropMargin != Padding.Empty) // only crop when necessary // cropImage(b); finalBitmap = resizeBitmap(b, videoPreview.Width, videoPreview.Height); } } catch (Exception ex) { MessageBox.Show("Could not read AVS frame.", "Video Player Error", MessageBoxButtons.OK, MessageBoxIcon.Error); MeGUI.core.util.LogItem _oLog = MainForm.Instance.AVSScriptCreatorLog; if (_oLog == null) { _oLog = MainForm.Instance.Log.Info("AVS Script Creator"); MainForm.Instance.AVSScriptCreatorLog = _oLog; } _oLog.LogValue("Could not read frame", ex.Message, MeGUI.core.util.ImageType.Warning, true); break; } using (videoPreview.Image) // get rid of previous bitmap { //do the actual rendering on GUI thread Invoke((SimpleDelegate)(delegate { videoPreview.Image = finalBitmap; })); } //Console.WriteLine("Frame {0} updated", pos); //needed for fps display framesPlayed++; } while (!IsDisposed); }