-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
PipeMediaInput.cs
106 lines (93 loc) · 3.62 KB
/
PipeMediaInput.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Sample created by Jérémy VIGNELLES
// You can copy, paste, modify, use this file in any of your projects as long as you have supported my work through github sponsors (monthly or one-time payment) : https://github.com/sponsors/jeremyVignelles
// After payment, the file is considered yours and no copyright notice is required (though it would be appreciated).
// The file is provided as-is without any guarantee or support, and you still need to comply to the licenses of the dependencies of this file.
using System.IO.Pipelines;
namespace LibVLCSharp.Shared
{
/// <summary>
/// A media input that allows you to push data to the video player as they are available, thanks to System.IO.Pipelines
/// </summary>
public class PipeMediaInput : MediaInput
{
private readonly PipeReader _reader;
private bool _completed = true;// True until the media input has been opened by libvlc.
/// <summary>
/// The constructor
/// </summary>
/// <param name="reader">The reader end of the pipe</param>
public PipeMediaInput(PipeReader reader)
{
this._reader = reader;
this.CanSeek = false;
}
/// <summary>
/// Called by libvlc when the stream is closed
/// </summary>
public override void Close()
{
this._reader.Complete();
this._reader.CancelPendingRead();
}
/// <summary>
/// Called by libvlc when the stream opens
/// </summary>
/// <param name="size">Filled with ulong.MaxValue to indicate that the stream has an unknown length</param>
/// <returns>true</returns>
public override bool Open(out ulong size)
{
size = ulong.MaxValue;
this._completed = false;
return true;
}
/// <summary>
/// Called by libvlc when it wants to read more data
/// </summary>
/// <param name="buf">The buffer pointer</param>
/// <param name="len">The buffer length</param>
/// <returns>The number of bytes written to the stream, 0 for EOF, -1 for error</returns>
public unsafe override int Read(IntPtr buf, uint len)
{
if (this._completed)
{
return 0;
}
var readResult = this._reader.ReadAsync().AsTask().GetAwaiter().GetResult();
if(readResult.IsCanceled)
{
return -1;
}
var buffer = (readResult.Buffer.Length > len) ? readResult.Buffer.Slice(0, len) : readResult.Buffer;
var outputBuffer = new Span<byte>(buf.ToPointer(), (int)len);
if(buffer.IsSingleSegment)
{
buffer.FirstSpan.CopyTo(outputBuffer);
}
else
{
var outputPosition = 0;
foreach(var memory in buffer)
{
memory.Span.CopyTo(outputBuffer.Slice(outputPosition));
outputPosition += memory.Length;
}
}
var consumed = (int)buffer.Length;
this._reader.AdvanceTo(buffer.End);
if (readResult.IsCompleted)
{
this._completed = true;
}
return consumed;
}
/// <summary>
/// Seek override that should not be called by libvlc
/// </summary>
/// <param name="offset">The offset at which libvlc wants to seek</param>
/// <returns>false</returns>
public override bool Seek(ulong offset)
{
return false;
}
}
}