private void buttonStart_Click(object sender, EventArgs e) { //walidacja if (!File.Exists(textBoxFFmegPath.Text)) { //jak pliku z ffmpegiem ni ma statusLabel.Text = "Path to ffmpeg.exe is not valid"; //dodać jakieś wygaszanie tego napisu czy coś resetTimer(); return; } if (!File.Exists(textBoxInputFile.Text)) { statusLabel.Text = "Path to input file is not valid"; resetTimer(); return; } if (!Directory.Exists(Path.GetDirectoryName(textBoxOutputFile.Text))) { statusLabel.Text = "Output directory does not exist"; resetTimer(); return; } int videoWidth; int videoHeight; try { videoWidth = int.Parse(maskedTextBoxWidth.Text); if (videoWidth <= 0) { statusLabel.Text = "Input video width set incorrectly"; resetTimer(); return; } videoHeight = int.Parse(maskedTextBoxHeight.Text); if (videoHeight <= 0) { statusLabel.Text = "Input video height set incorrectly"; resetTimer(); return; } if (float.Parse(maskedTextBoxFPS.Text) <= 0) { statusLabel.Text = "Input video FPS set incorrectly"; resetTimer(); return; } } catch (Exception ex) { MessageBox.Show("Incorrect video dimensions\n" + ex.Message, "Error", MessageBoxButtons.OK); return; } if (File.Exists(textBoxOutputFile.Text)) { var result = MessageBox.Show(String.Format("File {0} already exist in output directory. Override it?", Path.GetFileName(textBoxOutputFile.Text)), "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (result == DialogResult.No) { return; } } String tempFilePath = Path.GetDirectoryName(textBoxOutputFile.Text) + "\\temp.yuv"; //argumenty do ffmpega String args = String.Format("-i {0} -c:v rawvideo -pix_fmt yuv420p {1}", textBoxInputFile.Text, tempFilePath); //odpalenie ffmpega żeby wypluł plik yuv do obróbki Process ffmpeg = new Process(); ffmpeg.StartInfo.FileName = textBoxFFmegPath.Text; ffmpeg.StartInfo.Arguments = args; statusLabel.Text = "Calling FFmpeg..."; resetTimer(); ffmpeg.Start(); ffmpeg.WaitForExit(); statusLabel.Text = String.Empty; var workerArgs = new BackgroundWorkerArguments(tempFilePath, videoWidth, videoHeight); backgroundWorker.RunWorkerAsync(workerArgs); statusLabel.Text = "Processing..."; buttonStart.Enabled = false; buttonFFmpegSearch.Enabled = false; buttonInputFileSearch.Enabled = false; buttonOutputFileSearch.Enabled = false; maskedTextBoxWidth.Enabled = false; maskedTextBoxHeight.Enabled = false; maskedTextBoxFPS.Enabled = false; textBoxFFmegPath.Enabled = false; textBoxInputFile.Enabled = false; textBoxOutputFile.Enabled = false; }
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; BackgroundWorkerArguments workerArguments = (BackgroundWorkerArguments)e.Argument; String workingDir = Path.GetDirectoryName(workerArguments.InputFilePath); int videoWidth = workerArguments.VideoWidth; int videoHeight = workerArguments.VideoHeight; FrameReader frameReader = new FrameReader(workerArguments.InputFilePath, videoWidth, videoHeight); //rozmiary w bajtach long inputFileSize = (new FileInfo(workerArguments.InputFilePath)).Length; long singleInputFrameSize = videoWidth * videoHeight + videoWidth * videoHeight / 2; long inputFrameCount = inputFileSize / singleInputFrameSize; //tutaj cała pracka powinna iść byte[] combinedYFrame = new byte[videoWidth * videoHeight * 4]; byte[] combinedUFrame = new byte[videoWidth * videoHeight]; byte[] combinedVFrame = new byte[videoWidth * videoHeight]; //miejsce na wejściowe byte[] input1Y; frameReader.getNextFrameY(out input1Y); byte[] input1U; frameReader.getNextFrameU(out input1U); byte[] input1V; frameReader.getNextFrameV(out input1V); byte[] input2Y; byte[] input2U; byte[] input2V; String outTempFilePath = workingDir + "\\out_temp.yuv"; using (BinaryWriter outputFile = new BinaryWriter(File.Open(outTempFilePath, FileMode.Create))) { //o jedna mniej niż klatka wejściowa //każda klatka for (long i = 0; i < inputFrameCount - 1; ++i) { frameReader.getNextFrameY(out input2Y); frameReader.getNextFrameU(out input2U); frameReader.getNextFrameV(out input2V); long idx; //dla każdej próbki w Y for (long px = 0; px < videoWidth * videoHeight; ++px) { idx = (px / videoWidth) * (4 * videoWidth) + 2 * (px % videoWidth); combinedYFrame[idx] = input1Y[px]; //"pierwsza" klatka combinedYFrame[idx + 1] = input2Y[px]; //"druga" klatka idx += (videoWidth * 2) + 1; combinedYFrame[idx] = input1Y[px]; //"pierwsza" klatka combinedYFrame[idx - 1] = input2Y[px]; //"druga" klatka } //dla każdej próbki w U for (long px = 0; px < (videoWidth * videoHeight) / 4; ++px) { idx = (px / (videoWidth / 2)) * (4 * (videoWidth / 2)) + 2 * (px % (videoWidth / 2)); combinedUFrame[idx] = input1U[px]; //"pierwsza" klatka combinedUFrame[idx + 1] = input2U[px]; //"druga" klatka idx += videoWidth + 1; combinedUFrame[idx] = input1U[px]; //"pierwsza" klatka combinedUFrame[idx - 1] = input2U[px]; //"druga" klatka } //dla każdej próbki w V for (long px = 0; px < (videoWidth * videoHeight) / 4; ++px) { idx = (px / (videoWidth / 2)) * (4 * (videoWidth / 2)) + 2 * (px % (videoWidth / 2)); combinedVFrame[idx] = input1V[px]; //"pierwsza" klatka combinedVFrame[idx + 1] = input2V[px]; //"druga" klatka idx += videoWidth + 1; combinedVFrame[idx] = input1V[px]; //"pierwsza" klatka combinedVFrame[idx - 1] = input2V[px]; //"druga" klatka } input1Y = input2Y; input1U = input2U; input1V = input2V; outputFile.Write(combinedYFrame); outputFile.Write(combinedUFrame); outputFile.Write(combinedVFrame); worker.ReportProgress((int)((i * 100) / inputFrameCount)); } } e.Result = new BackgroindWorkerResult(outTempFilePath, workerArguments.InputFilePath, 2 * videoWidth, 2 * videoHeight); }