0

I want to try a code sample for libvlcsharp, found here: https://code.videolan.org/mfkl/libvlcsharp-samples/-/blob/master/PreviewThumbnailExtractor/Program.cs#L113

I want to try it in a Framework 4.6.1 project, but the sample is targeted at .NET 6. I am having trouble getting one line to compile. The section in question is here:

    private static async Task ProcessThumbnailsAsync(string destination, CancellationToken token)
            {
                var frameNumber = 0;
                while (!token.IsCancellationRequested)
                {
                    if (FilesToProcess.TryDequeue(out var file))
                    {
                        using (var image = new Image<SixLabors.ImageSharp.PixelFormats.Bgra32>((int)(Pitch / BytePerPixel), (int)Lines))
                        using (var sourceStream = file.file.CreateViewStream())
                        {
                            var mg = image.GetPixelMemoryGroup();
                            for(int i = 0; i < mg.Count; i++)
                            {
                                sourceStream.Read(MemoryMarshal.AsBytes(mg[i].Span));
                            }
    
                            Console.WriteLine($"Writing {frameNumber:0000}.jpg");
                            var fileName = Path.Combine(destination, $"{frameNumber:0000}.jpg");
                            using (var outputFile = File.Open(fileName, FileMode.Create))
                            {
                                image.Mutate(ctx => ctx.Crop((int)Width, (int)Height));
                                image.SaveAsJpeg(outputFile);
                            }
                        }
                        file.accessor.Dispose();
                        file.file.Dispose();
                        frameNumber++;
                    }
                    else
                    {
                        await Task.Delay(TimeSpan.FromSeconds(1), token);
                    }
                }
            }

The troublesome line is :

sourceStream.Read(MemoryMarshal.AsBytes(mg[i].Span));

In .NET 6 there are two overloads,

Read(Span) Reads all the bytes of this unmanaged memory stream into the specified span of bytes.

Read(Byte[], Int32, Int32) Reads the specified number of bytes into the specified array.

but in .NET Framework 4.x there is just one

Read(Byte[], Int32, Int32)

I am having trouble understanding what is going on here, can someone please suggest a way to convert the line from the Read(Span) style to the Read(Byte[], Int32, Int32) style so that it works the same? I don't have experience with C#.

Thanks for any advice.

3
  • 2
    .NET 4.6.1 reached end of life in April 2022. It would be wise to consider upgrading your target framework instead. Commented Jun 21, 2022 at 14:12
  • 1
    Note that the old .NET Framework will never get support for Spans in Streams, so switching to .NET (Core) is required here. Commented Jun 21, 2022 at 16:56
  • 1
    Does this answer your question? Span<T> and streams in .NET framework Commented Jun 21, 2022 at 16:56

1 Answer 1

2

To understand what's happening, consider the following .NET 4.6.1 code which would achieve the same:

var mg = image.GetPixelMemoryGroup();
for(int i = 0; i < mg.Count; i++)
{
    Span<byte> span = MemoryMarshal.AsBytes(mg[i].Span);
    byte[] buffer = new byte[span.Length];
    sourceStream.Read(buffer, 0, buffer.Length);
    buffer.CopyTo(span);
}

This is just for demonstration though as it would allocate lots of byte arrays. You're better off "backporting" what new .NET does by default, s. this answer. Especially since you'll run into this again as the SixLabors libraries were written with .NET Core in mind, AFAIK. It may also not be as performant as what new .NET can do in case memory mapped file streams remove the need for the one copy done by default.

Also note that .NET 4.6.1 is no longer supported, and if you consider upgrading, you may find switching to .NET (Core) easier than pursuing backporting a whole library.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Ray that answered all my questions. Much appreciated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.