/// <summary> /// Release an output port buffer, get a new one from the queue and send it for processing. /// </summary> /// <param name="bufferImpl">A managed buffer object.</param> /// <param name="eos">Flag that this buffer is the end of stream.</param> public virtual void ReleaseBuffer(IBuffer bufferImpl, bool eos) { bufferImpl.Release(); if (eos) { // If we have reached the end of stream, we don't want to send a buffer to the output port again. return; } IBuffer newBuffer = null; try { if (MMALCameraConfig.Debug) { if (!this.Enabled) { MMALLog.Logger.LogDebug($"{this.Name}: Port not enabled."); } if (this.BufferPool == null) { MMALLog.Logger.LogDebug($"{this.Name}: Buffer pool null."); } } if (this.Enabled && this.BufferPool != null) { newBuffer = this.BufferPool.Queue.GetBuffer(); if (newBuffer.CheckState()) { this.SendBuffer(newBuffer); } else { MMALLog.Logger.LogWarning($"{this.Name}: Buffer null. Continuing."); } } } catch (Exception e) { if (newBuffer != null && newBuffer.CheckState()) { newBuffer.Release(); } MMALLog.Logger.LogWarning($"{this.Name}: Unable to send buffer header. {e.Message}"); } }
private void ProcessBuffer(IBuffer bufferImpl) { var eos = bufferImpl.AssertProperty(MMALBufferProperties.MMAL_BUFFER_HEADER_FLAG_EOS) || this.ComponentReference.ForceStopProcessing; if (bufferImpl.CheckState()) { if (bufferImpl.Cmd > 0) { if (bufferImpl.Cmd == MMALEvents.MMAL_EVENT_FORMAT_CHANGED) { Task.Run(() => { this.ProcessFormatChangedEvent(bufferImpl); }); } else { this.ReleaseBuffer(bufferImpl); } } else { if ((bufferImpl.Length > 0 && !eos && !this.Trigger.Task.IsCompleted) || (eos && !this.Trigger.Task.IsCompleted)) { this.CallbackHandler.Callback(bufferImpl); } else { MMALLog.Logger.LogDebug("Buffer length empty."); } // 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.ReleaseBuffer(bufferImpl); } } else { MMALLog.Logger.LogDebug($"Invalid output buffer received"); } // If this buffer signals the end of data stream, allow waiting thread to continue. if (eos) { MMALLog.Logger.LogDebug($"{this.ComponentReference.Name} {this.Name} End of stream. Signaling completion..."); Task.Run(() => { this.Trigger.SetResult(true); }); } }