/// <inheritdoc /> internal override void ReleaseOutputBuffer(MMALBufferImpl bufferImpl) { bufferImpl.Release(); 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> /// Encodes/decodes user provided image data. /// </summary> /// <param name="outputPort">The output port to begin processing on. Usually will be 0.</param> /// <returns>An awaitable task.</returns> public virtual async Task Convert(int outputPort = 0) { MMALLog.Logger.Info("Beginning Image encode from filestream. Please note, this process may take some time depending on the size of the input image."); this.Inputs[0].Trigger = new Nito.AsyncEx.AsyncCountdownEvent(1); this.Outputs[0].Trigger = new Nito.AsyncEx.AsyncCountdownEvent(1); // Enable control, input and output ports. Input & Output ports should have been pre-configured by user prior to this point. this.Start(this.Control); this.Start(this.Inputs[0]); this.Start(this.Outputs[outputPort]); this.EnableComponent(); WorkingQueue = MMALQueueImpl.Create(); var eosReceived = false; while (!eosReceived) { await this.WaitForTriggers(); this.GetAndSendInputBuffer(); MMALLog.Logger.Debug("Getting processed output pool buffer"); while (true) { MMALBufferImpl buffer; lock (MMALPortBase.OutputLock) { buffer = WorkingQueue.GetBuffer(); } if (buffer != null) { eosReceived = ((int)buffer.Flags & (int)MMALBufferProperties.MMAL_BUFFER_HEADER_FLAG_EOS) == (int)MMALBufferProperties.MMAL_BUFFER_HEADER_FLAG_EOS; if (buffer.Cmd > 0) { if (buffer.Cmd == MMALEvents.MMAL_EVENT_FORMAT_CHANGED) { this.ProcessFormatChangedEvent(buffer); } else { lock (MMALPortBase.OutputLock) { buffer.Release(); } } continue; } else { if (buffer.Length > 0) { this.Outputs[0].ManagedOutputCallback.Callback(buffer); } else { MMALLog.Logger.Debug("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. lock (MMALPortBase.OutputLock) { buffer.Release(); } } } else { MMALLog.Logger.Debug("Buffer null."); break; } } this.GetAndSendOutputBuffer(); } MMALLog.Logger.Info("Received EOS. Exiting."); this.DisableComponent(); this.CleanPortPools(); WorkingQueue.Dispose(); }