Skip to content

Commit ce5a9e6

Browse files
committed
Updating to v3.3.8 / v1.1.12
-= FlyleafLib =- Improves interrupts implementation Adds draining support to VideoDecoder.GetNextFrame Initializes AudioPlayer early to allow changing volume/mute (before opening any input) Ensures rendering is disabled on initialization Fixes critical issues with interrupts (could stop the demuxers/decoders) Fixes critical race condition issues with RunThreadBase (could prevent demuxers/decoders from starting) -= FlyleafLib.Controls.WPF =- Prepares Color Themes (based on MaterialDesigninXaml) Prepares Load/Save Config for both Player & UI
1 parent b925b6d commit ce5a9e6

13 files changed

Lines changed: 176 additions & 90 deletions

File tree

FlyleafLib.Controls.WPF/Flyleaf.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ private void IdleThread()
770770
// Temp fix
771771
if (Player != null && !Player.IsPlaying && Player.CanPlay)
772772
{
773-
long bufferedDuration = Player.Video.IsOpened ? VideoDemuxer.BufferedDuration : AudioDemuxer.BufferedDuration;
773+
long bufferedDuration = Player.Video.IsOpened || AudioDecoder.OnVideoDemuxer ? VideoDemuxer.BufferedDuration : AudioDemuxer.BufferedDuration;
774774
if (bufferedDuration != Player.BufferedDuration)
775775
Dispatcher.BeginInvoke(new Action(() => Player.BufferedDuration = bufferedDuration));
776776
}

FlyleafLib.Controls.WPF/FlyleafLib.Controls.WPF.csproj

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFrameworks>net5.0-windows;net472</TargetFrameworks>
55
<UseWindowsForms>true</UseWindowsForms>
66
<UseWPF>true</UseWPF>
7-
<Version>1.1.11</Version>
7+
<Version>1.1.12</Version>
88
<Authors>SuRGeoNix</Authors>
99
<Copyright>SuRGeoNix © 2021</Copyright>
1010
<PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
@@ -13,11 +13,7 @@
1313
<PackageIconUrl />
1414
<PackageTags>flyleaf flyleaflib video audio media player element control</PackageTags>
1515
<Description>WPF Media Player Control/Element (based on FlyleafLib)</Description>
16-
<PackageReleaseNotes>
17-
Adds Plugins Options in Settings
18-
Ensures seek within the current buffered queue
19-
Ensures UI refresh of buffered duration selection range
20-
</PackageReleaseNotes>
16+
<PackageReleaseNotes>Adds Color Themes (based on MaterialDesigninXaml)</PackageReleaseNotes>
2117
</PropertyGroup>
2218

2319
<ItemGroup>

FlyleafLib/FlyleafLib.csproj

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<PackageIconUrl />
99
<RepositoryUrl></RepositoryUrl>
1010
<Description>Media Player .NET Library for WPF/WinForms (based on FFmpeg/DirectX)</Description>
11-
<Version>3.3.7</Version>
11+
<Version>3.3.8</Version>
1212
<Authors>SuRGeoNix</Authors>
1313
<Copyright>SuRGeoNix © 2021</Copyright>
1414
<PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
@@ -17,11 +17,12 @@
1717
<IncludeSymbols>true</IncludeSymbols>
1818
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
1919
<PackageReleaseNotes>
20-
Implements buffering even while the Player is paused
21-
Improves and fixes issues with Player.Speed
22-
Improves and fixes issues with seek within the current buffered queue
23-
Fixes an issue with exlusion of image streams
24-
Fixes a calculation of X frame issue with VideoDecoder's GetFrame / Extractor
20+
Improves interrupts implementation
21+
Adds draining support to VideoDecoder.GetNextFrame
22+
Initializes AudioPlayer early to allow changing volume/mute (before opening any input)
23+
Ensures rendering is disabled on initialization
24+
Fixes critical issues with interrupts (could stop the demuxers/decoders)
25+
Fixes critical race condition issues with RunThreadBase (could prevent demuxers/decoders from starting)
2526
</PackageReleaseNotes>
2627
</PropertyGroup>
2728

FlyleafLib/MediaFramework/MediaContext/DecoderContext.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,21 @@ public int Seek(long ms = -1, bool foreward = false)
630630
lock (AudioDecoder.lockCodecCtx)
631631
lock (SubtitlesDecoder.lockCodecCtx)
632632
{
633-
ret = VideoDemuxer.Seek(CalcSeekTimestamp(VideoDemuxer, ms, ref foreward), foreward);
633+
long seekTimestamp = CalcSeekTimestamp(VideoDemuxer, ms, ref foreward);
634+
635+
// Should exclude seek in queue for all "local/fast" files
636+
lock (VideoDemuxer.lockActions)
637+
if (OpenedPlugin.Name == "BitSwarm" || VideoDemuxer.SeekInQueue(seekTimestamp, foreward) != 0)
638+
{
639+
VideoDemuxer.Interrupter.ForceInterrupt = 1;
640+
OpenedPlugin.OnBuffering();
641+
lock (VideoDemuxer.lockFmtCtx)
642+
{
643+
if (VideoDemuxer.Disposed) { VideoDemuxer.Interrupter.ForceInterrupt = 0; return -1; }
644+
ret = VideoDemuxer.Seek(seekTimestamp, foreward);
645+
}
646+
}
647+
634648
VideoDecoder.Flush();
635649
if (AudioStream != null && AudioDecoder.OnVideoDemuxer)
636650
AudioDecoder.Flush();
@@ -643,15 +657,15 @@ public int Seek(long ms = -1, bool foreward = false)
643657
{
644658
AudioDecoder.Pause();
645659
AudioDecoder.Flush();
646-
AudioDemuxer.Pause();
660+
AudioDemuxer.PauseOnQueueFull = true; // Pause() will cause corrupted packets which causes av_read_frame to EOF
647661
RequiresResync = true;
648662
}
649663

650664
if (SubtitlesStream != null && !SubtitlesDecoder.OnVideoDemuxer)
651665
{
652666
SubtitlesDecoder.Pause();
653667
SubtitlesDecoder.Flush();
654-
SubtitlesDemuxer.Pause();
668+
SubtitlesDemuxer.PauseOnQueueFull = true;
655669
RequiresResync = true;
656670
}
657671

@@ -746,10 +760,6 @@ public void PauseOnQueueFull()
746760
VideoDemuxer.PauseOnQueueFull = true;
747761
AudioDemuxer.PauseOnQueueFull = true;
748762
SubtitlesDemuxer.PauseOnQueueFull = true;
749-
750-
VideoDecoder.PauseOnQueueFull = true;
751-
AudioDecoder.PauseOnQueueFull = true;
752-
SubtitlesDecoder.PauseOnQueueFull = true;
753763
}
754764
public void Start()
755765
{
@@ -800,7 +810,6 @@ public void Resync(long timestamp = -1)
800810
SeekAudio(timestamp / 10000);
801811
if (isRunning)
802812
{
803-
System.Threading.Thread.Sleep(10); // TBR: Probably race condition on Ending/Pausing
804813
AudioDemuxer.Start();
805814
AudioDecoder.Start();
806815
}

FlyleafLib/MediaFramework/MediaDecoder/AudioDecoder.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,11 @@ public void Flush()
7676
{
7777
if (Disposed) return;
7878

79+
if (Status == Status.Ended) Status = Status.Stopped;
80+
//else if (Status == Status.Draining) Status = Status.Stopping;
81+
7982
Frames = new ConcurrentQueue<AudioFrame>();
8083
avcodec_flush_buffers(codecCtx);
81-
if (Status == Status.Ended) Status = Status.Stopped;
8284

8385
keyFrameRequired = !VideoDecoder.Disposed;
8486
curSpeedFrame = Speed;
@@ -98,11 +100,10 @@ protected override void RunInternal()
98100
lock (lockStatus)
99101
if (Status == Status.Running) Status = Status.QueueFull;
100102

101-
while (!PauseOnQueueFull && Frames.Count >= Config.Decoder.MaxAudioFrames && Status == Status.QueueFull) Thread.Sleep(20);
103+
while (Frames.Count >= Config.Decoder.MaxAudioFrames && Status == Status.QueueFull) Thread.Sleep(20);
102104

103105
lock (lockStatus)
104106
{
105-
if (PauseOnQueueFull) Status = Status.Pausing;
106107
if (Status != Status.QueueFull) break;
107108
Status = Status.Running;
108109
}
@@ -111,6 +112,8 @@ protected override void RunInternal()
111112
// While Packets Queue Empty (Ended | Quit if Demuxer stopped | Wait until we get packets)
112113
if (demuxer.AudioPackets.Count == 0)
113114
{
115+
CriticalArea = true;
116+
114117
lock (lockStatus)
115118
if (Status == Status.Running) Status = Status.QueueEmpty;
116119

@@ -125,6 +128,15 @@ protected override void RunInternal()
125128
{
126129
Log($"Demuxer is not running [Demuxer Status: {demuxer.Status}]");
127130

131+
int retries = 5;
132+
133+
while (retries > 0)
134+
{
135+
retries--;
136+
Thread.Sleep(10);
137+
if (demuxer.IsRunning) break;
138+
}
139+
128140
lock (demuxer.lockStatus)
129141
lock (lockStatus)
130142
{
@@ -144,6 +156,7 @@ protected override void RunInternal()
144156

145157
lock (lockStatus)
146158
{
159+
CriticalArea = false;
147160
if (Status != Status.QueueEmpty) break;
148161
Status = Status.Running;
149162
}

FlyleafLib/MediaFramework/MediaDecoder/SubtitlesDecoder.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@ public void Flush()
3737
{
3838
if (Disposed) return;
3939

40+
if (Status == Status.Ended) Status = Status.Stopped;
41+
//else if (Status == Status.Draining) Status = Status.Stopping;
42+
4043
DisposeFrames();
4144
avcodec_flush_buffers(codecCtx);
42-
if (Status == Status.Ended) Status = Status.Stopped;
4345
curSpeedFrame = Speed;
4446
}
4547
}
@@ -58,11 +60,10 @@ protected override void RunInternal()
5860
lock (lockStatus)
5961
if (Status == Status.Running) Status = Status.QueueFull;
6062

61-
while (!PauseOnQueueFull && Frames.Count >= Config.Decoder.MaxSubsFrames && Status == Status.QueueFull) Thread.Sleep(20);
63+
while (Frames.Count >= Config.Decoder.MaxSubsFrames && Status == Status.QueueFull) Thread.Sleep(20);
6264

6365
lock (lockStatus)
6466
{
65-
if (PauseOnQueueFull) Status = Status.Pausing;
6667
if (Status != Status.QueueFull) break;
6768
Status = Status.Running;
6869
}
@@ -71,6 +72,8 @@ protected override void RunInternal()
7172
// While Packets Queue Empty (Ended | Quit if Demuxer stopped | Wait until we get packets)
7273
if (demuxer.SubtitlesPackets.Count == 0)
7374
{
75+
CriticalArea = true;
76+
7477
lock (lockStatus)
7578
if (Status == Status.Running) Status = Status.QueueEmpty;
7679

@@ -85,6 +88,15 @@ protected override void RunInternal()
8588
{
8689
Log($"Demuxer is not running [Demuxer Status: {demuxer.Status}]");
8790

91+
int retries = 5;
92+
93+
while (retries > 0)
94+
{
95+
retries--;
96+
Thread.Sleep(10);
97+
if (demuxer.IsRunning) break;
98+
}
99+
88100
lock (demuxer.lockStatus)
89101
lock (lockStatus)
90102
{
@@ -104,6 +116,7 @@ protected override void RunInternal()
104116

105117
lock (lockStatus)
106118
{
119+
CriticalArea = false;
107120
if (Status != Status.QueueEmpty) break;
108121
Status = Status.Running;
109122
}

FlyleafLib/MediaFramework/MediaDecoder/VideoDecoder.cs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,12 @@ internal void Flush()
179179
{
180180
if (Disposed) return;
181181

182+
if (Status == Status.Ended) Status = Status.Stopped;
183+
else if (Status == Status.Draining) Status = Status.Stopping;
184+
182185
DisposeFrames();
183186
avcodec_flush_buffers(codecCtx);
184-
if (Status == Status.Ended) Status = Status.Stopped;
187+
185188
keyFrameRequired = true;
186189
StartTime = AV_NOPTS_VALUE;
187190
curSpeedFrame = Speed;
@@ -202,11 +205,10 @@ protected override void RunInternal()
202205
lock (lockStatus)
203206
if (Status == Status.Running) Status = Status.QueueFull;
204207

205-
while (!PauseOnQueueFull && Frames.Count >= Config.Decoder.MaxVideoFrames && Status == Status.QueueFull) Thread.Sleep(20);
208+
while (Frames.Count >= Config.Decoder.MaxVideoFrames && Status == Status.QueueFull) Thread.Sleep(20);
206209

207210
lock (lockStatus)
208211
{
209-
if (PauseOnQueueFull) Status = Status.Pausing;
210212
if (Status != Status.QueueFull) break;
211213
Status = Status.Running;
212214
}
@@ -215,25 +217,40 @@ protected override void RunInternal()
215217
// While Packets Queue Empty (Drain | Quit if Demuxer stopped | Wait until we get packets)
216218
if (demuxer.VideoPackets.Count == 0)
217219
{
220+
CriticalArea = true;
221+
218222
lock (lockStatus)
219223
if (Status == Status.Running) Status = Status.QueueEmpty;
220224

221225
while (demuxer.VideoPackets.Count == 0 && Status == Status.QueueEmpty)
222226
{
223227
if (demuxer.Status == Status.Ended)
224228
{
225-
Log("Draining...");
226-
Status = Status.Draining;
227-
AVPacket* drainPacket = av_packet_alloc();
228-
drainPacket->data = null;
229-
drainPacket->size = 0;
230-
demuxer.VideoPackets.Enqueue((IntPtr)drainPacket);
229+
lock (lockStatus)
230+
{
231+
Log("Draining...");
232+
Status = Status.Draining;
233+
AVPacket* drainPacket = av_packet_alloc();
234+
drainPacket->data = null;
235+
drainPacket->size = 0;
236+
demuxer.VideoPackets.Enqueue((IntPtr)drainPacket);
237+
}
238+
231239
break;
232240
}
233241
else if (!demuxer.IsRunning)
234242
{
235243
Log($"Demuxer is not running [Demuxer Status: {demuxer.Status}]");
236244

245+
int retries = 5;
246+
247+
while (retries > 0)
248+
{
249+
retries--;
250+
Thread.Sleep(10);
251+
if (demuxer.IsRunning) break;
252+
}
253+
237254
lock (demuxer.lockStatus)
238255
lock (lockStatus)
239256
{
@@ -253,6 +270,7 @@ protected override void RunInternal()
253270

254271
lock (lockStatus)
255272
{
273+
CriticalArea = false;
256274
if (Status != Status.QueueEmpty && Status != Status.Draining) break;
257275
if (Status != Status.Draining) Status = Status.Running;
258276
}

0 commit comments

Comments
 (0)