Commit b6e75925 authored by Jérémy VIGNELLES's avatar Jérémy VIGNELLES Committed by Martin Finkel

Avoid a copy in StreamMediaInput on modern platforms.

This requires unsafe code to use the newer Span APIs
netstandard1.1 is also removed
parent 1d3856b0
......@@ -166,5 +166,31 @@ namespace LibVLCSharp.Helpers
MarshalUtils.LibVLCFree(ref nativeString);
return Encoding.UTF8.GetString(buffer, 0, buffer.Length);
}
#if !APPLE && !ANDROID && !NETSTANDARD2_1
/// <summary>
/// The Span-based APIs on Stream are not available on older targets. Span can be backported on older TFMs through the System.Memory package,
/// but System.IO does not provide the same benefit. This code is extracted from dotnet/runtime to allow efficient media callbacks implementation.
/// </summary>
/// <remarks>https://github.com/dotnet/runtime/blob/c4b9dabec8186a0d61f0cc3ea0b7efea579bf24e/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs#L720-L734</remarks>
/// <param name="stream">the .NET stream</param>
/// <param name="buffer">the buffer to read</param>
/// <returns>number of bytes read</returns>
internal static int Read(this System.IO.Stream stream, Span<byte> buffer)
{
var sharedBuffer = System.Buffers.ArrayPool<byte>.Shared.Rent(buffer.Length);
try
{
var numRead = stream.Read(sharedBuffer, 0, buffer.Length);
if ((uint)numRead > (uint)buffer.Length)
{
throw new System.IO.IOException("StreamTooLong");
}
new Span<byte>(sharedBuffer, 0, numRead).CopyTo(buffer);
return numRead;
}
finally { System.Buffers.ArrayPool<byte>.Shared.Return(sharedBuffer); }
}
#endif
}
}
......@@ -28,7 +28,7 @@ This package also contains the views for the following platforms:
If you need Xamarin.Forms support, see LibVLCSharp.Forms.
LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.</Description>
<TargetFrameworks>netstandard2.1;netstandard2.0;netstandard1.1</TargetFrameworks>
<TargetFrameworks>netstandard2.1;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition="!$([MSBuild]::IsOsPlatform('Linux'))">$(TargetFrameworks);MonoAndroid81;Xamarin.iOS10;Xamarin.Mac20;Xamarin.TVOS10</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOsPlatform('Windows'))">$(TargetFrameworks);uap10.0;uap10.0.16299;net45;net471</TargetFrameworks>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);IncludeAWindow</TargetsForTfmSpecificBuildOutput>
......@@ -49,6 +49,7 @@ LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.</Descri
<PackageIcon>icon.png</PackageIcon>
<PackageReleaseNotes>https://code.videolan.org/videolan/LibVLCSharp/blob/master/NEWS</PackageReleaseNotes>
<PackageTags>libvlc;vlc;videolan;native;c/c++;video;audio;player;media;mediaplayer;codec;ffmpeg;xamarin;graphics;ios;android;linux;windows;macos;cross-platform</PackageTags>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('uap'))">
<GenerateLibraryLayout>true</GenerateLibraryLayout>
......@@ -60,6 +61,7 @@ LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.</Descri
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('MonoAndroid'))">
<Compile Include="Platforms\Android\**\*.cs" />
......@@ -86,7 +88,13 @@ LibVLC needs to be installed separately, see VideoLAN.LibVLC.* packages.</Descri
</Page>
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="SharpDX.Direct3D11" Version="4.2.0" />
<PackageReference Include="System.Memory" Version="4.5.4" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('net4')) Or '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Memory" Version="4.5.4" />
</ItemGroup>
<Target Name="IncludeAWindow" Condition="$(TargetFramework.StartsWith('MonoAndroid'))">
<ItemGroup>
<BuildOutputInPackage Include="$(OutputPath)LibVLCSharp.Android.AWindow.dll" />
......
using System;
using System.IO;
using System.Runtime.InteropServices;
#if !APPLE && !ANDROID && !NETSTANDARD2_1
using LibVLCSharp.Helpers;
#endif
namespace LibVLCSharp
{
/// <summary>
......@@ -10,7 +12,6 @@ namespace LibVLCSharp
public class StreamMediaInput : MediaInput
{
private readonly Stream _stream;
private readonly byte[] _readBuffer = new byte[0x4000];
/// <summary>
/// Initializes a new instance of <see cref="StreamMediaInput"/>, which reads from the given .NET stream.
......@@ -61,14 +62,11 @@ namespace LibVLCSharp
/// <param name="buf">The buffer where read data must be written</param>
/// <param name="len">The buffer length</param>
/// <returns>The number of bytes actually read, -1 on error</returns>
public override int Read(IntPtr buf, uint len)
public unsafe override int Read(IntPtr buf, uint len)
{
try
{
var read = _stream.Read(_readBuffer, 0, Math.Min((int)len, _readBuffer.Length));
Marshal.Copy(_readBuffer, 0, buf, read);
return read;
return _stream.Read(new Span<byte>(buf.ToPointer(), (int)Math.Min(len, int.MaxValue)));
}
catch (Exception)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment