Skip to content

Commit

Permalink
feat: read FFmpeg samples without intermediary buffer
Browse files Browse the repository at this point in the history
Use newer .NET API to read samples from native layer directly into managed memory and avoid the overhead of copying into a transfer buffer.
  • Loading branch information
protyposis committed Jan 26, 2024
1 parent ba619ab commit 7eed50a
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 16 deletions.
1 change: 1 addition & 0 deletions src/Aurio.FFmpeg/Aurio.FFmpeg.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<FFmpegProxyLinuxPath>..\..\nativesrc\out\build\linux-$(FFmpegProxyBuildConfig)\aurioffmpegproxy</FFmpegProxyLinuxPath>
<IsPackable>true</IsPackable>
<Description>Extension library for Aurio, which provides audio decoding through FFmpeg (see https://ffmpeg.org/).</Description>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<None Include="..\Aurio.licenseheader" Link="Aurio.licenseheader" />
Expand Down
19 changes: 3 additions & 16 deletions src/Aurio.FFmpeg/FFmpegReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,31 +75,18 @@ public FFmpegReader(FileInfo fileInfo, Type mode)
/// <param name="stream">the stream to decode</param>
/// <param name="mode">the types of data to read</param>
/// <param name="fileName">optional filename as a hint for FFmpeg to determine the data format</param>
public FFmpegReader(Stream stream, Type mode, string fileName)
public unsafe FFmpegReader(Stream stream, Type mode, string fileName)
{
ValidateNativeLibraryAvailability();

this.filename = fileName ?? "bufferedIO_stream";
this.mode = mode;

var transferBuffer = new byte[0];
readPacketDelegate = delegate(IntPtr opaque, IntPtr buffer, int bufferSize)
{
/* NOTE there's no way to cast the IntPtr to a byte array which is required
* for stream reading, so we need to add an intermediary transfer buffer.
*/
// Increase transfer buffer's size if too small
if (transferBuffer.Length < bufferSize)
{
transferBuffer = new byte[bufferSize];
}
// Read data into transfer buffer
int bytesRead = stream.Read(transferBuffer, 0, bufferSize);

// Transfer data to unmanaged memory
Marshal.Copy(transferBuffer, 0, buffer, bytesRead);
var bufferSpan = new Span<byte>(buffer.ToPointer(), bufferSize);
int bytesRead = stream.Read(bufferSpan);

// Return number of bytes read
return bytesRead;
};
seekDelegate = delegate(IntPtr opaque, long offset, int whence)
Expand Down

0 comments on commit 7eed50a

Please sign in to comment.