Skip to content

Commit

Permalink
Updating to 3.1.14
Browse files Browse the repository at this point in the history
- Finalizes new interrupts implementation and fixes downloader/remuxer issues


Former-commit-id: 6230207
  • Loading branch information
SuRGeoNix committed Jul 28, 2021
1 parent c3112c0 commit 6d9a718
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 16 deletions.
16 changes: 12 additions & 4 deletions FlyleafLib/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,23 +94,28 @@ public Demuxer Clone()


/// <summary>
/// av_read_frame timeout (ticks) for protocols that support interrupts
/// avformat_close_input timeout (ticks) for protocols that support interrupts
/// </summary>
public long CloseTimeout { get; set; } = 1 * 1000 * 10000;

/// <summary>
/// av_read_frame timeout (ticks) for protocols that support interrupts
/// avformat_open_input + avformat_find_stream_info timeout (ticks) for protocols that support interrupts (should be related to probesize/analyzeduration)
/// </summary>
public long OpenTimeout { get; set; } = 30 * 1000 * 10000;
public long OpenTimeout { get; set; } = 5 * 60 * (long)1000 * 10000;

/// <summary>
/// av_read_frame timeout (ticks) for protocols that support interrupts
/// </summary>
public long ReadTimeout { get; set; } = 2 * 1000 * 10000;
public long ReadTimeout { get; set; } = 5 * 1000 * 10000;

/// <summary>
/// av_read_frame timeout (ticks) for protocols that support interrupts
/// </summary>
public long ReadLiveTimeout { get; set; } = 6 * 1000 * 10000;

/// <summary>
/// av_seek_frame timeout (ticks) for protocols that support interrupts
/// </summary>
public long SeekTimeout { get; set; } = 8 * 1000 * 10000;

/// <summary>
Expand Down Expand Up @@ -143,6 +148,9 @@ public static SerializableDictionary<string, string> DefaultVideoFormatOpt()
defaults.Add("reconnect_streamed", "1"); // auto reconnect streamed / non seekable streams
defaults.Add("reconnect_delay_max", "5"); // max reconnect delay in seconds after which to give up
defaults.Add("rtsp_transport", "tcp"); // Seems UDP causing issues (use this by default?)

//defaults.Add("timeout", (2 * (long)1000 * 1000).ToString()); // (Bytes) Default 5MB | Higher for weird formats (such as .ts?)
//defaults.Add("rw_timeout", (2 * (long)1000 * 1000).ToString()); // (Microseconds) Default 5 seconds | Higher for network streams
return defaults;
}

Expand Down
8 changes: 4 additions & 4 deletions FlyleafLib/FlyleafLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@
<PackageIconUrl />
<RepositoryUrl></RepositoryUrl>
<Description>Video Player .NET Library for WPF/WinForms (based on FFmpeg/SharpDX)</Description>
<Version>3.1.13</Version>
<Version>3.1.14</Version>
<Authors>SuRGeoNix</Authors>
<Copyright>SuRGeoNix © 2021</Copyright>
<PackageLicenseExpression>LGPL-3.0-or-later</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/SuRGeoNix/Flyleaf</PackageProjectUrl>
<PackageTags>flyleaf flyleaflib video media player engine framework ffmpeg sharpdx directx</PackageTags>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageReleaseNotes>Adds demuxer timeouts (open/read/seek/close) to the configuration
<PackageReleaseNotes>Adds demuxer timeouts (open/read/readlive/seek/close) to the configuration
Resets MaxQueueSize to 100
Fixes network stream issues
Fixes hanging issues on av_read_frame/av_seek_frame by changing the interrupt implementation</PackageReleaseNotes>
<AssemblyVersion>3.1.13.0</AssemblyVersion>
<FileVersion>3.1.13.0</FileVersion>
<AssemblyVersion>3.1.14.0</AssemblyVersion>
<FileVersion>3.1.14.0</FileVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
Expand Down
42 changes: 36 additions & 6 deletions FlyleafLib/MediaFramework/MediaDemuxer/DemuxerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ enum InterruptRequester
break;

case InterruptRequester.Read:
curTimeout = demuxer.cfg.demuxer.ReadTimeout;
curTimeout = demuxer.Duration == 0 ? demuxer.cfg.demuxer.ReadLiveTimeout : demuxer.cfg.demuxer.ReadTimeout;
break;

case InterruptRequester.Seek:
Expand All @@ -108,7 +108,13 @@ enum InterruptRequester
return 1;
}

return demuxer.interruptRequester != InterruptRequester.Close && (demuxer.DemuxInterrupt != 0 || demuxer.Status == Status.Stopping || demuxer.Status == Status.Stopped) ? 1 : 0;
if (demuxer.interruptRequester != InterruptRequester.Close && (demuxer.DemuxInterrupt != 0 || demuxer.Status == Status.Stopping || demuxer.Status == Status.Stopped))
{
//demuxer.Log($"{demuxer.interruptRequester} Interrupt !!! {demuxer.DemuxInterrupt} | {demuxer.Status}");
return 1;
}

return 0;
};

public DemuxerBase(Config config, int uniqueId)
Expand Down Expand Up @@ -214,7 +220,7 @@ public bool FillInfo()
LongName = Utils.BytePtrToStringUTF8(fmtCtx->iformat->long_name);
Extensions = Utils.BytePtrToStringUTF8(fmtCtx->iformat->extensions);
StartTime = fmtCtx->start_time * 10;
Duration = fmtCtx->duration * 10;
Duration = fmtCtx->duration > 0 ? fmtCtx->duration * 10 : 0;

bool hasVideo = false;
mapInAVStreamsToStreams = new Dictionary<int, StreamBase>();
Expand Down Expand Up @@ -243,6 +249,10 @@ public bool FillInfo()
SubtitlesStreams.Add(new SubtitlesStream(fmtCtx->streams[i]) { Demuxer = this, Converted = true, Downloaded = true });
mapInAVStreamsToStreams.Add(i, SubtitlesStreams[SubtitlesStreams.Count-1]);
break;

default:
Log($"#[Unknown #{i}] {fmtCtx->streams[i]->codecpar->codec_type}");
break;
}
}

Expand All @@ -252,6 +262,8 @@ public bool FillInfo()
Programs = new int[fmtCtx->nb_programs][];
for (int i=0; i<fmtCtx->nb_programs; i++)
{
//fmtCtx->programs[i]->discard = AVDiscard.AVDISCARD_ALL;

if (fmtCtx->programs[i]->nb_stream_indexes > 0)
{
Programs[i] = new int[fmtCtx->programs[i]->nb_stream_indexes];
Expand Down Expand Up @@ -380,6 +392,7 @@ public void Stop()

TotalBytes = 0; VideoBytes = 0; AudioBytes = 0;
Status = Status.Stopped;
Log("Disposed");
}
}
public void StopThread()
Expand Down Expand Up @@ -484,6 +497,9 @@ private void Demux()
interruptRequestedAt = DateTime.UtcNow.Ticks;
interruptRequester = InterruptRequester.Read;
ret = av_read_frame(fmtCtx, packet);
//long t1 = (DateTime.UtcNow.Ticks - interruptRequestedAt)/10000;
//if (t1 > 100) Log($"Took {t1}ms");

// Check for Errors / End
if (ret != 0)
{
Expand Down Expand Up @@ -622,7 +638,16 @@ public void StopRecording()
/// Fires on partial or full download completed
/// </summary>
public event EventHandler<bool> DownloadCompleted;
protected virtual void OnDownloadCompleted(bool success) { System.Threading.Tasks.Task.Run(() => { Stop(); DownloadCompleted?.Invoke(this, success); }); }
protected virtual void OnDownloadCompleted(bool success)
{
System.Threading.Tasks.Task.Run(() =>
{
while (thread != null && thread.IsAlive) Thread.Sleep(5);

Stop();
DownloadCompleted?.Invoke(this, success);
});
}

/// <summary>
/// Downloads the currently configured AVS streams (Experimental)
Expand Down Expand Up @@ -701,7 +726,7 @@ private void Remux()
{
Log2($"[Thread] Started");

while (Status != Status.Stopped && Status != Status.Stopping && Status != Status.Ended)
while (Status != Status.Stopped && Status != Status.Stopping && Status != Status.Stopping2 && Status != Status.Ended)
{
threadARE.Reset();
Status = Status.Paused;
Expand Down Expand Up @@ -739,6 +764,9 @@ private void Remux()

if (ret == AVERROR_EOF)
{
// We get proper eof even when we interrupt (no AVERROR_EXIT) should be marked as downloadSuccess = false
// We could force for live streams if (Duration == 0) continue; but possible we get the same eof in case of disconnect or another actual error
// Consider also having a different interrupt callback for the remuxer with different config.remuxer?
if (Status == Status.Demuxing)
{
Status = Status.Ended;
Expand Down Expand Up @@ -790,12 +818,13 @@ private void Remux()

} // While Demuxing

if (Status == Status.Demuxing) Status = Status.Stopping2;
IsRunning = false;
Log2($"{Status}");

} // While !stopThread

if (Status != Status.Ended) Status = Status.Stopped;
if (Status != Status.Ended) Status = Status.Stopping2;
Log2($"[Thread] Stopped ({Status})");
CloseOutputFormat();
}
Expand All @@ -819,6 +848,7 @@ public void DisposePackets(ConcurrentQueue<IntPtr> packets)
public enum Status
{
Stopping,
Stopping2, // Only for remux
Stopped,

Opening,
Expand Down
2 changes: 1 addition & 1 deletion FlyleafLib/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static List<Language> GetSystemLanguages()
return Languages;
}

public static void EnsureThreadDone(Thread t, long maxMS = 10000, int minMS = 4)
public static void EnsureThreadDone(Thread t, long maxMS = 15000, int minMS = 4) // Until Pause on live streams can be aborted must be > ReadLiveTimeout
{
if (t == null || !t.IsAlive) return;

Expand Down
2 changes: 1 addition & 1 deletion Wpf Samples/Sample1_Basic.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

xmlns:fl="clr-namespace:FlyleafLib.Controls.WPF;assembly=FlyleafLib"
xmlns:flwpf="clr-namespace:FlyleafLib.Controls.WPF;assembly=FlyleafLib.Controls.WPF"
Title="Flyleaf v3.1.13" Height="450" Width="800" Background="Black" Icon="/Flyleaf.ico" Loaded="Window_Loaded">
Title="Flyleaf v3.1.14" Height="450" Width="800" Background="Black" Icon="/Flyleaf.ico" Loaded="Window_Loaded">
<Grid>
<fl:VideoView Player="{Binding Player}">
<flwpf:Flyleaf x:Name="flyleafControl"/>
Expand Down
7 changes: 7 additions & 0 deletions Wpf Samples/Sample4_Downloader.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ public Sample4_Downloader()
Master.RegisterFFmpeg(":2");

Config config = new Config();

// For live stream might required
//config.demuxer.VideoFormatOpt.Add("reconnect_at_eof", "1");

// Especially for live streams but generally large read timeouts
config.demuxer.ReadTimeout = 40 * 1000 * 10000;
config.demuxer.ReadLiveTimeout = 40 * 1000 * 10000;

config.demuxer.VideoFormatOpt.Add("probesize",(50 * (long)1024 * 1024).ToString());
config.demuxer.VideoFormatOpt.Add("analyzeduration",(10 * (long)1000 * 1000).ToString());
Downloader = new VideoDemuxer(config, 777);
Expand Down

0 comments on commit 6d9a718

Please sign in to comment.