internal void ReleaseOutputBuffer(MMALBufferImpl bufferImpl) { bufferImpl.Release(); bufferImpl.Dispose(); try { if (!this.Enabled) { MMALLog.Logger.Warn("Port not enabled."); } if (this.BufferPool == null) { MMALLog.Logger.Warn("Buffer pool null."); } if (this.Enabled && this.BufferPool != null) { var newBuffer = MMALQueueImpl.GetBuffer(this.BufferPool.Queue.Ptr); if (newBuffer != null) { this.SendBuffer(newBuffer); } else { MMALLog.Logger.Warn("Buffer null. Continuing."); } } } catch (Exception e) { MMALLog.Logger.Warn($"Unable to send buffer header. {e.Message}"); } }
/// <summary> /// The native callback MMAL passes buffer headers to /// </summary> /// <param name="port">The port the buffer is sent to</param> /// <param name="buffer">The buffer header</param> internal override void NativeOutputPortCallback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { lock (MMALPortBase.OutputLock) { var bufferImpl = new MMALBufferImpl(buffer); if (MMALCameraConfig.Debug) { bufferImpl.PrintProperties(); } if (bufferImpl.Length > 0) { this.ManagedOutputCallback(bufferImpl, this); } //Ensure we release the buffer before any signalling or we will cause a memory leak due to there still being a reference count on the buffer. this.ReleaseOutputBuffer(bufferImpl); //If this buffer signals the end of data stream, allow waiting thread to continue. if (bufferImpl.Properties.Any(c => c == MMALBufferProperties.MMAL_BUFFER_HEADER_FLAG_FRAME_END || c == MMALBufferProperties.MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED)) { MMALLog.Logger.Debug("End of stream. Signaling completion..."); if (this.Trigger != null && this.Trigger.CurrentCount > 0) { this.Trigger.Signal(); } } } }
internal override void NativeInputPortCallback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { lock (MMALPortBase.InputLock) { var bufferImpl = new MMALBufferImpl(buffer); if (MMALCameraConfig.Debug) { bufferImpl.PrintProperties(); } this.ReleaseInputBuffer(bufferImpl); } }
/// <summary> /// Provides functionality to enable processing on an input port. /// </summary> /// <param name="managedCallback"></param> internal virtual void EnablePort(Func <MMALBufferImpl, MMALPortBase, ProcessResult> managedCallback) { //We populate the input buffers with user provided data. this.BufferPool = new MMALPoolImpl(this); var length = this.BufferPool.Queue.QueueLength(); for (int i = 0; i < length; i++) { MMALBufferImpl buffer = this.BufferPool.Queue.GetBuffer(); ProcessResult result = managedCallback(buffer, this); buffer.ReadIntoBuffer(result.BufferFeed, result.EOF); this.SendBuffer(buffer); } }
/// <summary> /// The native callback MMAL passes buffer headers to. /// </summary> /// <param name="port">The port the buffer is sent to.</param> /// <param name="buffer">The buffer header.</param> internal override void NativeOutputPortCallback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { lock (MMALPortBase.OutputLock) { if (MMALCameraConfig.Debug) { MMALLog.Logger.Debug("In native output callback"); } var bufferImpl = new MMALBufferImpl(buffer); if (MMALCameraConfig.Debug) { bufferImpl.PrintProperties(); } var triggered = this.Trigger != null && this.Trigger.CurrentCount == 0; var failed = bufferImpl.Properties.Any(c => c == MMALBufferProperties.MMAL_BUFFER_HEADER_FLAG_TRANSMISSION_FAILED); var eos = bufferImpl.Properties.Any(c => c == MMALBufferProperties.MMAL_BUFFER_HEADER_FLAG_FRAME_END || c == MMALBufferProperties.MMAL_BUFFER_HEADER_FLAG_EOS) || this.ComponentReference.ForceStopProcessing; if ((bufferImpl.CheckState() && bufferImpl.Length > 0 && !eos && !failed && !triggered) || (eos && !triggered)) { this.ManagedOutputCallback.Callback(bufferImpl); } // Ensure we release the buffer before any signalling or we will cause a memory leak due to there still being a reference count on the buffer. this.ReleaseOutputBuffer(bufferImpl); // If this buffer signals the end of data stream, allow waiting thread to continue. if (eos || failed) { if (this.Trigger != null && this.Trigger.CurrentCount > 0) { MMALLog.Logger.Debug("End of stream. Signaling completion..."); this.Trigger.Signal(); } } } }
internal void ReleaseInputBuffer(MMALBufferImpl bufferImpl) { bufferImpl.Release(); if (this.Enabled && this.BufferPool != null) { var newBuffer = MMALQueueImpl.GetBuffer(this.BufferPool.Queue.Ptr); //Populate the new input buffer with user provided image data. var result = this.ManagedInputCallback(newBuffer, this); bufferImpl.ReadIntoBuffer(result.BufferFeed, result.EOF); try { if (this.Trigger != null && this.Trigger.CurrentCount > 0 && result.EOF) { MMALLog.Logger.Debug("Received EOF. Releasing."); this.Trigger.Signal(); newBuffer.Release(); } if (newBuffer != null) { this.SendBuffer(newBuffer); } else { MMALLog.Logger.Warn("Buffer null. Continuing."); } } catch (Exception ex) { MMALLog.Logger.Warn($"Buffer handling failed. {ex.Message}"); } } }
/// <summary> /// Delegate to process the buffer header containing image data /// </summary> /// <param name="buffer">The current buffer header being processed</param> /// <param name="port">The port we're currently processing on</param> public virtual void ManagedOutputCallback(MMALBufferImpl buffer, MMALPortBase port) { var data = buffer.GetBufferData(); this.Handler?.Process(data); }
/// <summary> /// Delegate to process the buffer header containing image data /// </summary> /// <param name="buffer">The current buffer header being processed</param> /// <param name="port">The port we're currently processing on</param> public virtual ProcessResult ManagedInputCallback(MMALBufferImpl buffer, MMALPortBase port) { return(this.Handler?.Process()); }
internal void Put(MMALBufferImpl buffer) { MMALQueue.mmal_queue_put(this.Ptr, buffer.Ptr); }
public virtual void ManagedConnectionCallback(MMALBufferImpl buffer) { MMALLog.Logger.Debug("Inside Managed connection callback"); }
/// <summary> /// Send a buffer header to a port. /// </summary> /// <param name="buffer"></param> internal void SendBuffer(MMALBufferImpl buffer) { MMALCheck(MMALPort.mmal_port_send_buffer(this.Ptr, buffer.Ptr), "Unable to send buffer header."); }
internal static MMALEventFormat GetEventFormat(MMALBufferImpl buffer) { var ev = MMALEvents.mmal_event_format_changed_get(buffer.Ptr); return(new MMALEventFormat(Marshal.PtrToStructure <MMAL_ES_FORMAT_T>((IntPtr)ev->Format), ev->Format)); }