Skip to content
This repository has been archived by the owner on Feb 22, 2024. It is now read-only.

Commit

Permalink
#47. Port configuration to accept IMMALPortConfig.
Browse files Browse the repository at this point in the history
  • Loading branch information
techyian committed Feb 20, 2020
1 parent 976ee0d commit 9f5011a
Show file tree
Hide file tree
Showing 18 changed files with 160 additions and 52 deletions.
2 changes: 2 additions & 0 deletions src/MMALSharp/Callbacks/PortCallbackHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ public virtual void Callback(IBuffer buffer)
var eos = buffer.AssertProperty(MMALBufferProperties.MMAL_BUFFER_HEADER_FLAG_FRAME_END) ||
buffer.AssertProperty(MMALBufferProperties.MMAL_BUFFER_HEADER_FLAG_EOS);

MMALLog.Logger.LogDebug("Attempting to process data.");

this.CaptureHandler?.Process(data, eos);

if (eos)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public MMALImageEncoder(bool rawBayer = false, bool useExif = true, bool continu
}

/// <inheritdoc />
public override IDownstreamComponent ConfigureOutputPort(int outputPort, MMALPortConfig config, IOutputCaptureHandler handler)
public override IDownstreamComponent ConfigureOutputPort(int outputPort, IMMALPortConfig config, IOutputCaptureHandler handler)
{
base.ConfigureOutputPort(outputPort, config, handler);

Expand Down
25 changes: 17 additions & 8 deletions src/MMALSharp/Components/EncoderComponents/MMALVideoEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,29 @@ public MMALVideoEncoder()
}

/// <inheritdoc />
public override IDownstreamComponent ConfigureOutputPort(int outputPort, MMALPortConfig config, IOutputCaptureHandler handler)
public override IDownstreamComponent ConfigureOutputPort(int outputPort, IMMALPortConfig config, IOutputCaptureHandler handler)
{
this.Quality = config.Quality;

var bufferSize = 0;
var framerate = 0;

if (config.EncodingType == MMALEncoding.H264)
{
config.BufferSize = Math.Max(this.Outputs[outputPort].Ptr->BufferSizeRecommended, this.Outputs[outputPort].Ptr->BufferSizeMin);
bufferSize = Math.Max(this.Outputs[outputPort].Ptr->BufferSizeRecommended, this.Outputs[outputPort].Ptr->BufferSizeMin);
}
else
{
// Follow raspivid logic.
config.BufferSize = Math.Max(this.Outputs[outputPort].Ptr->BufferSizeRecommended, 256 << 10);
bufferSize = Math.Max(this.Outputs[outputPort].Ptr->BufferSizeRecommended, 256 << 10);
}

var bitrate = this.GetValidBitrate(outputPort, config);

// Force framerate to be 0 in case it was provided by user.
config.Framerate = 0;

this.ConfigureBitrate(outputPort, config);
config = new MMALPortConfig(config.EncodingType, config.PixelFormat, config.Width, config.Height, framerate,
config.Quality, bitrate, config.ZeroCopy, config.Timeout, config.BufferNum, bufferSize, config.Crop,
config.StoreMotionVectors);

base.ConfigureOutputPort(outputPort, config, handler);

Expand All @@ -103,8 +108,10 @@ public override IDownstreamComponent ConfigureOutputPort(int outputPort, MMALPor
return this;
}

private void ConfigureBitrate(int outputPort, MMALPortConfig config)
private int GetValidBitrate(int outputPort, IMMALPortConfig config)
{
var bitrate = config.Bitrate;

if (this.Outputs[outputPort].EncodingType == MMALEncoding.H264)
{
List<VideoLevel> levelList = null;
Expand Down Expand Up @@ -134,9 +141,11 @@ private void ConfigureBitrate(int outputPort, MMALPortConfig config)
if (this.Outputs[outputPort].Bitrate > MaxBitrateMJPEG)
{
MMALLog.Logger.LogWarning("Bitrate too high: Reducing to 25MBit/s");
config.Bitrate = MaxBitrateMJPEG;
bitrate = MaxBitrateMJPEG;
}
}

return bitrate;
}

private void ConfigureRateControl(int outputPort)
Expand Down
12 changes: 6 additions & 6 deletions src/MMALSharp/Components/IDownstreamComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public interface IDownstreamComponent : IComponent
/// <param name="copyPort">The port to copy from.</param>
/// <param name="handler">The capture handler to use with this port.</param>
/// <returns>This component.</returns>
IDownstreamComponent ConfigureInputPort(MMALPortConfig config, IPort copyPort, IInputCaptureHandler handler);
IDownstreamComponent ConfigureInputPort(IMMALPortConfig config, IPort copyPort, IInputCaptureHandler handler);

/// <summary>
/// Call to configure changes on a downstream component input port.
Expand All @@ -38,7 +38,7 @@ public interface IDownstreamComponent : IComponent
/// pipeline and you are feeding data to it directly from a <see cref="IInputCaptureHandler"/>. If this port is connected to by another component then leave this parameter null.
/// </param>
/// <returns>This <see cref="MMALDownstreamComponent"/>.</returns>
IDownstreamComponent ConfigureInputPort(MMALPortConfig config, IInputCaptureHandler handler);
IDownstreamComponent ConfigureInputPort(IMMALPortConfig config, IInputCaptureHandler handler);

/// <summary>
/// Configures the input port. In addition, it will create a new instance of the port
Expand All @@ -50,7 +50,7 @@ public interface IDownstreamComponent : IComponent
/// pipeline and you are feeding data to it directly from a <see cref="IInputCaptureHandler"/>. If this port is connected to by another component then leave this parameter null.
/// </param>
/// <returns>This component.</returns>
IDownstreamComponent ConfigureInputPort<TPort>(MMALPortConfig config, IInputCaptureHandler handler)
IDownstreamComponent ConfigureInputPort<TPort>(IMMALPortConfig config, IInputCaptureHandler handler)
where TPort : IInputPort;

/// <summary>
Expand All @@ -59,7 +59,7 @@ IDownstreamComponent ConfigureInputPort<TPort>(MMALPortConfig config, IInputCapt
/// <param name="config">The port configuration object.</param>
/// <param name="handler">The output port capture handler.</param>
/// <returns>This component.</returns>
IDownstreamComponent ConfigureOutputPort(MMALPortConfig config, IOutputCaptureHandler handler);
IDownstreamComponent ConfigureOutputPort(IMMALPortConfig config, IOutputCaptureHandler handler);

/// <summary>
/// Configures the output port.
Expand All @@ -68,7 +68,7 @@ IDownstreamComponent ConfigureInputPort<TPort>(MMALPortConfig config, IInputCapt
/// <param name="config">The port configuration object.</param>
/// <param name="handler">The capture handler to use with this port.</param>
/// <returns>This component.</returns>
IDownstreamComponent ConfigureOutputPort(int outputPort, MMALPortConfig config, IOutputCaptureHandler handler);
IDownstreamComponent ConfigureOutputPort(int outputPort, IMMALPortConfig config, IOutputCaptureHandler handler);

/// <summary>
/// Configures the output port. In addition, it will create a new instance of the port
Expand All @@ -79,7 +79,7 @@ IDownstreamComponent ConfigureInputPort<TPort>(MMALPortConfig config, IInputCapt
/// <param name="config">The port configuration object.</param>
/// <param name="handler">The capture handler to use with this port.</param>
/// <returns>This component.</returns>
IDownstreamComponent ConfigureOutputPort<TPort>(int outputPort, MMALPortConfig config, IOutputCaptureHandler handler)
IDownstreamComponent ConfigureOutputPort<TPort>(int outputPort, IMMALPortConfig config, IOutputCaptureHandler handler)
where TPort : IOutputPort;
}
}
12 changes: 6 additions & 6 deletions src/MMALSharp/Components/MMALDownstreamComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ protected MMALDownstreamComponent(string name)
/// pipeline and you are feeding data to it directly from a <see cref="IInputCaptureHandler"/>. If this port is connected to by another component then leave this parameter null.
/// </param>
/// <returns>This <see cref="MMALDownstreamComponent"/>.</returns>
public virtual IDownstreamComponent ConfigureInputPort(MMALPortConfig config, IInputCaptureHandler handler)
public virtual IDownstreamComponent ConfigureInputPort(IMMALPortConfig config, IInputCaptureHandler handler)
{
return this.ConfigureInputPort(config, null, handler);
}
Expand All @@ -60,7 +60,7 @@ public virtual IDownstreamComponent ConfigureInputPort(MMALPortConfig config, II
/// pipeline and you are feeding data to it directly from a <see cref="IInputCaptureHandler"/>. If this port is connected to by another component then leave this parameter null.
/// </param>
/// <returns>This <see cref="MMALDownstreamComponent"/>.</returns>
public virtual unsafe IDownstreamComponent ConfigureInputPort(MMALPortConfig config, IPort copyPort, IInputCaptureHandler handler)
public virtual unsafe IDownstreamComponent ConfigureInputPort(IMMALPortConfig config, IPort copyPort, IInputCaptureHandler handler)
{
this.Inputs[0].Configure(config, copyPort, handler);

Expand All @@ -79,7 +79,7 @@ public virtual unsafe IDownstreamComponent ConfigureInputPort(MMALPortConfig con
/// <param name="config">User provided port configuration object.</param>
/// <param name="handler">The input port capture handler.</param>
/// <returns>This <see cref="MMALDownstreamComponent"/>.</returns>
public virtual unsafe IDownstreamComponent ConfigureInputPort<TPort>(MMALPortConfig config, IInputCaptureHandler handler)
public virtual unsafe IDownstreamComponent ConfigureInputPort<TPort>(IMMALPortConfig config, IInputCaptureHandler handler)
where TPort : IInputPort
{
this.Inputs[0] = (IInputPort)Activator.CreateInstance(typeof(TPort), (IntPtr)(&(*this.Ptr->Input[0])), this, Guid.NewGuid());
Expand All @@ -93,7 +93,7 @@ public virtual unsafe IDownstreamComponent ConfigureInputPort<TPort>(MMALPortCon
/// <param name="config">User provided port configuration object.</param>
/// <param name="handler">The output port capture handler.</param>
/// <returns>This <see cref="MMALDownstreamComponent"/>.</returns>
public virtual IDownstreamComponent ConfigureOutputPort(MMALPortConfig config, IOutputCaptureHandler handler)
public virtual IDownstreamComponent ConfigureOutputPort(IMMALPortConfig config, IOutputCaptureHandler handler)
{
return this.ConfigureOutputPort(0, config, handler);
}
Expand All @@ -105,7 +105,7 @@ public virtual IDownstreamComponent ConfigureOutputPort(MMALPortConfig config, I
/// <param name="config">User provided port configuration object.</param>
/// <param name="handler">The output port capture handler.</param>
/// <returns>This <see cref="MMALDownstreamComponent"/>.</returns>
public virtual IDownstreamComponent ConfigureOutputPort(int outputPort, MMALPortConfig config, IOutputCaptureHandler handler)
public virtual IDownstreamComponent ConfigureOutputPort(int outputPort, IMMALPortConfig config, IOutputCaptureHandler handler)
{
if (this.ProcessingPorts.ContainsKey(outputPort))
{
Expand All @@ -127,7 +127,7 @@ public virtual IDownstreamComponent ConfigureOutputPort(int outputPort, MMALPort
/// <param name="config">User provided port configuration object.</param>
/// <param name="handler">The output port capture handler.</param>
/// <returns>This <see cref="MMALDownstreamComponent"/>.</returns>
public virtual unsafe IDownstreamComponent ConfigureOutputPort<TPort>(int outputPort, MMALPortConfig config, IOutputCaptureHandler handler)
public virtual unsafe IDownstreamComponent ConfigureOutputPort<TPort>(int outputPort, IMMALPortConfig config, IOutputCaptureHandler handler)
where TPort : IOutputPort
{
this.Outputs[outputPort] = (IOutputPort)Activator.CreateInstance(typeof(TPort), (IntPtr)(&(*this.Ptr->Output[outputPort])), this, Guid.NewGuid());
Expand Down
16 changes: 12 additions & 4 deletions src/MMALSharp/Components/MMALSplitterComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,27 @@ public unsafe MMALSplitterComponent()
}

/// <inheritdoc />
public override IDownstreamComponent ConfigureInputPort(MMALPortConfig config, IPort copyPort, IInputCaptureHandler handler)
public override IDownstreamComponent ConfigureInputPort(IMMALPortConfig config, IPort copyPort, IInputCaptureHandler handler)
{
config.BufferNum = Math.Max(this.Inputs[0].BufferNumRecommended, 3);
var bufferNum = Math.Max(this.Inputs[0].BufferNumRecommended, 3);

config = new MMALPortConfig(config.EncodingType, config.PixelFormat, config.Width, config.Height, config.Framerate,
config.Quality, config.Bitrate, config.ZeroCopy, config.Timeout, bufferNum, config.BufferSize, config.Crop,
config.StoreMotionVectors);

base.ConfigureInputPort(config, copyPort, handler);

return this;
}

/// <inheritdoc />
public override IDownstreamComponent ConfigureInputPort(MMALPortConfig config, IInputCaptureHandler handler)
public override IDownstreamComponent ConfigureInputPort(IMMALPortConfig config, IInputCaptureHandler handler)
{
config.BufferNum = Math.Max(this.Inputs[0].BufferNumRecommended, 3);
var bufferNum = Math.Max(this.Inputs[0].BufferNumRecommended, 3);

config = new MMALPortConfig(config.EncodingType, config.PixelFormat, config.Width, config.Height, config.Framerate,
config.Quality, config.Bitrate, config.ZeroCopy, config.Timeout, bufferNum, config.BufferSize, config.Crop,
config.StoreMotionVectors);

base.ConfigureInputPort(config, handler);

Expand Down
80 changes: 80 additions & 0 deletions src/MMALSharp/Ports/IMMALPortConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using MMALSharp.Config;
using MMALSharp.Native;
using System;
using System.Drawing;

namespace MMALSharp.Ports
{
public interface IMMALPortConfig
{
/// <summary>
/// The encoding type this output port will send data in.
/// </summary>
MMALEncoding EncodingType { get; }

/// <summary>
/// The pixel format this output port will send data in.
/// </summary>
MMALEncoding PixelFormat { get; }

/// <summary>
/// User provided width of output frame.
/// </summary>
int Width { get; }

/// <summary>
/// User provided height of output frame.
/// </summary>
int Height { get; }

/// <summary>
/// The framerate of the outputted data.
/// </summary>
int Framerate { get; }

/// <summary>
/// The quality of our outputted data.
/// </summary>
int Quality { get; }

/// <summary>
/// The bitrate we are sending data at.
/// </summary>
int Bitrate { get; }

/// <summary>
/// Instruct MMAL to not copy buffers to ARM memory (useful for large buffers and handling raw data).
/// </summary>
bool ZeroCopy { get; }

/// <summary>
/// Time that processing shall stop. Relevant for video recording.
/// </summary>
DateTime? Timeout { get; }

/// <summary>
/// Requested number of buffer headers.
/// </summary>
int BufferNum { get; }

/// <summary>
/// Requested size of buffer headers.
/// </summary>
int BufferSize { get; }

/// <summary>
/// The Region of Interest requested.
/// </summary>
Rectangle? Crop { get; }

/// <summary>
/// Video split configuration object.
/// </summary>
Split Split { get; }

/// <summary>
/// Indicates whether motion vector data should be stored to a separate output stream. Only applies to Video recording.
/// </summary>
bool StoreMotionVectors { get; }
}
}
2 changes: 1 addition & 1 deletion src/MMALSharp/Ports/IPort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public interface IPort : IMMALObject
/// <summary>
/// The config for this port.
/// </summary>
MMALPortConfig PortConfig { get; }
IMMALPortConfig PortConfig { get; }

/// <summary>
/// Native name of port.
Expand Down
2 changes: 1 addition & 1 deletion src/MMALSharp/Ports/Inputs/IInputPort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public interface IInputPort : IPort
/// <param name="config">The port configuration object.</param>
/// <param name="copyPort">The port to copy from.</param>
/// <param name="handler">The capture handler to assign to this port.</param>
void Configure(MMALPortConfig config, IPort copyPort, IInputCaptureHandler handler);
void Configure(IMMALPortConfig config, IPort copyPort, IInputCaptureHandler handler);

/// <summary>
/// Enables processing on an input port.
Expand Down
8 changes: 6 additions & 2 deletions src/MMALSharp/Ports/Inputs/InputPort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void ConnectTo(IOutputPort outputPort, IConnection connection)
/// <param name="config">The port configuration object.</param>
/// <param name="copyPort">The port to copy from.</param>
/// <param name="handler">The capture handler to assign to this port.</param>
public virtual void Configure(MMALPortConfig config, IPort copyPort, IInputCaptureHandler handler)
public virtual void Configure(IMMALPortConfig config, IPort copyPort, IInputCaptureHandler handler)
{
copyPort?.ShallowCopy(this);

Expand Down Expand Up @@ -184,7 +184,11 @@ public virtual void ReleaseBuffer(IBuffer bufferImpl)

// Populate the new input buffer with user provided image data.
var result = this.CallbackHandler.CallbackWithResult(newBuffer);
newBuffer.ReadIntoBuffer(result.BufferFeed, result.DataLength, result.EOF);

if (result.Success)
{
newBuffer.ReadIntoBuffer(result.BufferFeed, result.DataLength, result.EOF);
}

this.SendBuffer(newBuffer);

Expand Down
Loading

0 comments on commit 9f5011a

Please sign in to comment.