private void SetupTranscoder() { transcoder = new PrimoSoftware.AVBlocks.Transcoder(); transcoder.AllowDemoMode = true; captureFramerate = Convert.ToInt32(cCaptureFramerate.Text); /* * Important! * Make sure the calculated viewport size is in pixels because it's used as video frame size. * The rendered viewport size includes the margins. */ var margin = viewport.Margin; var frameWidth = (int)(viewport.ActualWidth * dpiScaleX + margin.Left + margin.Right); var frameHeight = (int)(viewport.ActualHeight * dpiScaleY + margin.Top + margin.Bottom); /* * Round down to even frame size. * This is required by the AVBlocks Transcoder */ captureFrameWidth = frameWidth / 2 * 2; captureFrameHeight = frameHeight / 2 * 2; var preset = cOutputPreset.SelectedItem as PresetDescriptor; var output = MediaSocket.FromPreset(preset.Name); output.File = cOutputFile.Text; AdjustVideoOutput(output, captureFramerate); transcoder.Outputs.Add(output); var input = new MediaSocket() { StreamType = StreamType.UncompressedVideo }; input.Pins.Add(new MediaPin() { StreamInfo = new VideoStreamInfo() { StreamType = StreamType.UncompressedVideo, FrameWidth = captureFrameWidth, FrameHeight = captureFrameHeight, ColorFormat = ColorFormat.BGR32, ScanType = ScanType.Progressive, } }); transcoder.Inputs.Add(input); File.Delete(output.File); }
public int SampleCB(double SampleTime, IMediaSample pSample) { if (!bProcess) { lastSampleTime = SampleTime; return(WinAPI.E_FAIL); } // internal stats ++sampleIndex; long tStart, tEnd; pSample.GetMediaTime(out tStart, out tEnd); Debug.Assert(tStart < tEnd); Debug.Assert(tStart > lastMediaTime); sampleProcessed += tEnd - tStart; sampleDropped += tStart - lastMediaTime - 1; lastMediaTime = tEnd - 1; int dataLen = pSample.GetActualDataLength(); IntPtr bufPtr; int hr = pSample.GetPointer(out bufPtr); Debug.Assert(0 == hr); // BEGIN TRACE int bufSize = pSample.GetSize(); long timeStart, timeEnd; pSample.GetTime(out timeStart, out timeEnd); string msg = string.Format( "SampleCB ({0}) {1}, sampleTime:{2} datalen:{3} bufsize:{4} mediaTime:{5}-{6} time:{7}-{8}", name, sampleIndex, SampleTime, dataLen, bufSize, tStart, tEnd, timeStart, timeEnd); Trace.WriteLine(msg); if (tStart - lastMediaTime - 1 > 0) { msg = string.Format("!!! Frame drop: {0}", tStart - lastMediaTime - 1 > 0); Trace.WriteLine(msg); } //END TRACE byte[] buf = new byte[dataLen]; Marshal.Copy(bufPtr, buf, 0, dataLen); if (file != null) { file.Write(buf, 0, dataLen); } //DBG - simulate encoding error //if (sampleIndex > 100) // goto STOP_CAPTURE; if (mediaState != null && mediaState.mpeg2Enc != null) { PrimoSoftware.AVBlocks.Transcoder enc = mediaState.mpeg2Enc; MediaSample inputSample = new MediaSample(); inputSample.Buffer = new MediaBuffer(buf); inputSample.StartTime = Math.Max(SampleTime, 0); //TODO: end time try { bool pushed = false; // transcoder.Push() is not threads safe. // lock (enc){ } ensure that only one thread is calling transcoder.Push() lock (enc) { pushed = enc.Push(StreamNumber, inputSample); } if (pushed) { return(0); } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.ToString()); } Trace.WriteLine("PushSample FAILED"); } //STOP_CAPTURE: Trace.WriteLine("SampleCB: Before Post STOP_CAPTURE"); WinAPI.PostMessage(MainWindow, Util.WM_STOP_CAPTURE, new IntPtr(streamNumber), IntPtr.Zero); Trace.WriteLine("SampleCB: After Post STOP_CAPTURE"); bProcess = false; return(WinAPI.E_FAIL); } // end of SampleCB