/// <summary> /// Meldet, dass nun eine Verbindung zu einem anderen Endpunkt festgelegt wurde. /// </summary> /// <param name="connector">Ein anderer Endpunkt.</param> /// <param name="mediaType">Die Art der Daten, die zwischen den Endpunkten ausgetauscht werden.</param> public void ReceiveConnection(IntPtr connector, IntPtr mediaType) { // Free Disconnect(); // Remember if (connector != null) { Marshal.AddRef(connector); } m_Connected = connector; // Clone the media type m_ConnectType.Dispose(); m_ConnectType = new MediaType(mediaType); // Attach to raw COM interface m_MemPin = ComIdentity.QueryInterface(m_Connected, typeof(IMemInputPin)); // Get the delegate for the calls - dirty but we have to avoid automatic marshalling inside the graph IntPtr comFunctionTable = Marshal.ReadIntPtr(m_MemPin); IntPtr receiveSingle = Marshal.ReadIntPtr(comFunctionTable, 24); IntPtr notifyAllocator = Marshal.ReadIntPtr(comFunctionTable, 16); m_MemSink = (MediaSampleSink)Marshal.GetDelegateForFunctionPointer(receiveSingle, typeof(MediaSampleSink)); m_NotifySink = (NotifyAllocatorSink)Marshal.GetDelegateForFunctionPointer(notifyAllocator, typeof(NotifyAllocatorSink)); }
/// <summary> /// Verbindet diesen Endpunkt mit einem anderen. /// </summary> /// <param name="connector">Ein Erzeuger.</param> /// <param name="mediaType">Der gewünschte Datentyp.</param> public void ReceiveConnection(IntPtr connector, IntPtr mediaType) { // Free BDAEnvironment.Release(ref m_Connected); // Remember if (connector != null) { Marshal.AddRef(connector); } m_Connected = connector; // Clone the media type m_ConnectType.Dispose(); m_ConnectType = new MediaType(mediaType); }
public bool EncodeSample(Sample inputSample, out Sample outputSample) { bool Result = false; outputSample = null; if (inputSample == null) { return(false); } encoder.ProcessInput(0, inputSample, 0); //if (processor.OutputStatus == (int)MftOutputStatusFlags.MftOutputStatusSampleReady) { encoder.GetOutputStreamInfo(0, out TOutputStreamInformation streamInfo); MftOutputStreamInformationFlags flags = (MftOutputStreamInformationFlags)streamInfo.DwFlags; bool createSample = !flags.HasFlag(MftOutputStreamInformationFlags.MftOutputStreamProvidesSamples); if (createSample) { outputSample = MediaFactory.CreateSample(); outputSample.SampleTime = inputSample.SampleTime; outputSample.SampleDuration = inputSample.SampleDuration; outputSample.SampleFlags = inputSample.SampleFlags; using (var mediaBuffer = MediaFactory.CreateMemoryBuffer(streamInfo.CbSize)) { outputSample.AddBuffer(mediaBuffer); } } TOutputDataBuffer[] outputDataBuffer = new TOutputDataBuffer[1]; var data = new TOutputDataBuffer { DwStatus = 0, DwStreamID = 0, PSample = outputSample, PEvents = null, }; outputDataBuffer[0] = data; var res = encoder.TryProcessOutput(TransformProcessOutputFlags.None, outputDataBuffer, out TransformProcessOutputStatus status); if (res == SharpDX.Result.Ok) { if (outputSample == null) { outputSample = outputDataBuffer[0].PSample; } Debug.Assert(outputSample != null, "res.Success && outputSample != null"); Result = true; } else if (res == SharpDX.MediaFoundation.ResultCode.TransformNeedMoreInput) { logger.Warn(res.ToString() + " TransformNeedMoreInput"); Result = true; } else if (res == SharpDX.MediaFoundation.ResultCode.TransformStreamChange) { logger.Warn(res.ToString() + " TransformStreamChange"); MediaType newOutputType = null; try { encoder.TryGetOutputAvailableType(outputStreamId, 0, out newOutputType); encoder.SetOutputType(outputStreamId, newOutputType, 0); if (OutputMediaType != null) { OutputMediaType.Dispose(); OutputMediaType = null; } OutputMediaType = newOutputType; logger.Info("============== NEW OUTPUT TYPE=================="); logger.Info(MfTool.LogMediaType(OutputMediaType)); } finally { newOutputType?.Dispose(); newOutputType = null; } } else { res.CheckError(); } } return(Result); }
private void ProcessOutput() { if (stopping) { logger.Warn("ProcessOutput() stopping..."); } if (closing) { logger.Warn("ProcessOutput() closing..."); return; } encoder.GetOutputStreamInfo(0, out TOutputStreamInformation streamInfo); MftOutputStreamInformationFlags flags = (MftOutputStreamInformationFlags)streamInfo.DwFlags; bool createSample = !flags.HasFlag(MftOutputStreamInformationFlags.MftOutputStreamProvidesSamples); // Create output sample Sample outputSample = null; try { if (createSample) { Debug.Assert(streamInfo.CbSize > 0, "streamInfo.CbSize > 0"); outputSample = MediaFactory.CreateSample(); using (var mediaBuffer = MediaFactory.CreateMemoryBuffer(streamInfo.CbSize)) { outputSample.AddBuffer(mediaBuffer); } } TOutputDataBuffer[] outputDataBuffer = new TOutputDataBuffer[1]; var data = new TOutputDataBuffer { DwStatus = 0, DwStreamID = 0, PSample = outputSample, PEvents = null, }; outputDataBuffer[0] = data; var res = encoder.TryProcessOutput(TransformProcessOutputFlags.None, outputDataBuffer, out TransformProcessOutputStatus status); if (res == SharpDX.Result.Ok) { if (outputSample == null) { outputSample = outputDataBuffer[0].PSample; } Debug.Assert(outputSample != null, "res.Success && outputSample != null"); FinalizeSample(outputSample); // SampleReady?.Invoke(outputSample); } else if (res == SharpDX.MediaFoundation.ResultCode.TransformNeedMoreInput) { //logger.Debug(res.ToString() + " TransformNeedMoreInput"); //Result = true; } else if (res == SharpDX.MediaFoundation.ResultCode.TransformStreamChange) {// не должны приходить для энкодера... // но приходят для Intel MFT !!! logger.Warn(res.ToString() + " TransformStreamChange"); MediaType newOutputType = null; try { encoder.TryGetOutputAvailableType(outputStreamId, 0, out newOutputType); encoder.SetOutputType(outputStreamId, newOutputType, 0); if (OutputMediaType != null) { OutputMediaType.Dispose(); OutputMediaType = null; } OutputMediaType = newOutputType; logger.Info("============== NEW OUTPUT TYPE=================="); logger.Info(MfTool.LogMediaType(OutputMediaType)); } finally { newOutputType?.Dispose(); newOutputType = null; } } else { res.CheckError(); } } finally { if (outputSample != null) { outputSample.Dispose(); outputSample = null; } } }
public bool ProcessSample(Sample inputSample, Action <Sample> OnSampleDecoded) { bool Result = false; if (inputSample == null) { return(false); } //FIXME: frameNumber++; inputSample.SampleTime = frameNumber * frameDuration; //!!!!!!!!!1 inputSample.SampleDuration = frameDuration; decoder.ProcessInput(0, inputSample, 0); //if (decoder.OutputStatus == (int)MftOutputStatusFlags.MftOutputStatusSampleReady) { decoder.GetOutputStreamInfo(0, out TOutputStreamInformation streamInfo); MftOutputStreamInformationFlags flags = (MftOutputStreamInformationFlags)streamInfo.DwFlags; bool createSample = !flags.HasFlag(MftOutputStreamInformationFlags.MftOutputStreamProvidesSamples); do { Sample pSample = null; // Create output sample if (createSample) { pSample = MediaFactory.CreateSample(); pSample.SampleTime = inputSample.SampleTime; pSample.SampleDuration = inputSample.SampleDuration; pSample.SampleFlags = inputSample.SampleFlags; logger.Debug("CreateSample: " + inputSample.SampleTime); using (var mediaBuffer = MediaFactory.CreateMemoryBuffer(streamInfo.CbSize)) { pSample.AddBuffer(mediaBuffer); } } TOutputDataBuffer[] outputBuffers = new TOutputDataBuffer[1]; var outputBuffer = new TOutputDataBuffer { DwStatus = 0, DwStreamID = 0, PSample = pSample, PEvents = null, }; outputBuffers[0] = outputBuffer; var res = decoder.TryProcessOutput(TransformProcessOutputFlags.None, outputBuffers, out TransformProcessOutputStatus status); //logger.Info("TryProcessOutput(...) " + res + " " + outputDataBuffer[0].DwStatus); if (res == SharpDX.Result.Ok) { var buf = outputBuffers[0]; var outputSample = buf.PSample; var pEvents = buf.PEvents; if (pEvents != null) { var eventsCount = pEvents.ElementCount; Debug.Assert(eventsCount == 0, "eventsCount == 0"); if (eventsCount > 0) { for (int i = 0; i < eventsCount; i++) { var e = pEvents.GetElement(i); if (e != null) { e.Dispose(); e = null; } } } } Debug.Assert(outputSample != null, "res.Success && outputSample != null"); OnSampleDecoded?.Invoke(outputSample); Result = true; //continue; } else if (res == SharpDX.MediaFoundation.ResultCode.TransformNeedMoreInput) { //logger.Info("-------------------------"); Result = true; break; } else if (res == SharpDX.MediaFoundation.ResultCode.TransformStreamChange) { logger.Warn(res.ToString() + " TransformStreamChange"); MediaType newOutputType = null; try { decoder.TryGetOutputAvailableType(outputStreamId, 0, out newOutputType); decoder.SetOutputType(outputStreamId, newOutputType, 0); if (OutputMediaType != null) { OutputMediaType.Dispose(); OutputMediaType = null; } OutputMediaType = newOutputType; logger.Info("============== NEW OUTPUT TYPE=================="); logger.Info(MfTool.LogMediaType(OutputMediaType)); } finally { newOutputType?.Dispose(); newOutputType = null; } } else { res.CheckError(); Result = false; break; } //if (outputSample != null) //{ // // logger.Debug("DisposeSample: " + outputSample?.SampleTime); // outputSample?.Dispose(); // outputSample = null; //} }while (true); } return(Result); }