Skip to content

Commit

Permalink
Updating to v2.6
Browse files Browse the repository at this point in the history
-= Re-coding MediaRenderer =-

- Hardware Frames (NV12/P010 Semi-Planar): Direct Convert to RGB with PixelShaders (No more VideoProcessorBlt)
- Software Frames (8-bit YUV Planar/Packed): PixelShaders support for most of them (Planar/Packed)
- Rest Frames (RGB & YUV > 8-bit): Still using fallback to "heavy" SwsScale (however improvements also here with direct copy)
- ColorSpace / ColorRange support (BT601/BT709 Full/Limited)
- Better multi-threading SwapChain implementation and more BackBuffers in use
- Audio auto re-sync in case of de-sync
- Fixing an issue while ffmpeg fails to seek on keyframe we skip until it finds one (was showing broken frames)
- Fixing an issue with Audio noise during pause/play
- Updating Libraries


Former-commit-id: 08b568f
  • Loading branch information
SuRGeoNix committed Mar 21, 2021
1 parent 5d81ded commit 4c38dd6
Show file tree
Hide file tree
Showing 13 changed files with 221 additions and 158 deletions.
54 changes: 10 additions & 44 deletions Flyleaf Player (WinForms Demo 1)/README.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
============
Flyleaf v2.5
Flyleaf v2.6
============
A video player with HD & Streaming (Torrent/Web +) support
by John Stamatakis (aka SuRGeoNix)
Expand All @@ -11,52 +11,18 @@ NOTES
- Firewall : It is recommended to add an exception for Flyleaf to ensure proper streaming (especially for torrent streaming)

Additions / Enhancements
- Re-design of Flyleaf's core to achieve better performance and lower resources
- Seperating Demux with Decode (useful for buffering especially on network streams)
- Using the same direct3D 11 device both for rendering & decoding (better performance as no extra shared copy is required)
- Generalize AVIO context to support any Stream type (currently used for Torrent streaming)
- Better thread handling without abort/start by using reset events (better performance)
- Making Seek process even more efficient and faster for better user experience
- Better audio handling by spoting NAudio's issue with threading & better volume / mute control (by handling also app session's device)
- Adding Subtitles outline and performing more efficient syncing
- Adding Exit & Media Info on right click pop-up menu
- Updating dependency libraries (FFmpeg/BitSwarm/APF/Youtube-dl)
- Re-coding MediaRenderer
- Hardware Frames (NV12/P010 Semi-Planar): Direct Convert to RGB with PixelShaders (No more VideoProcessorBlt)
- Software Frames (8-bit YUV Planar/Packed): PixelShaders support for most of them (Planar/Packed)
- Rest Frames (RGB & YUV > 8-bit): Still using fallback to "heavy" SwsScale (however improvement also here with direct copy)
- ColorSpace / ColorRange support (BT601/BT709 Full/Limited)
- Better Multi-threading SwapChain implementation and more BackBuffers in use
- Audio auto re-sync in case of de-sync

Issues
- FFmpeg's seek abort would cause scanning the whole file (on matroska)
- No more green screens and thread sleeps to avoid them by using the same direct3D 11 device for decoding & rendering
- Screamer would not scream last video frame
- Rendering on non-fullscreen was not accurate (aspect ratio issue)
- Temporarly disabling rendering to boot faster (during settings loading)

Changes 2.5.3
- Finalizing Youtube-dl properly including all the required headers/cookies/user-agent/referrer etc. (TODO: black/white lists for codecs)
- Audio/Video stream selection on pop-up menu. Change resolution, will try to add best audio match automatically (+Youtube-dl)
- Video stream best match based on screen resolution (Youtube-dl)
- Audio stream best match based on Language priorities (in case of multi audio streams with different languages)
- Audio volume affects directly Master (to achieve constant changes, will be reviewed)
- Adding video title instead of url for web in recent history and OSD
- MediaBuffer: Ensures that it has enough video & audio frames before playing (no audio silence on start / minqueuesize currently not required by default and set to 1)
- Fixing issues with seeking, timestamps & invalid packets
- Fixing a crashing issue when the GPU does not support codec decoding
- Fixing a crashing issue on opening
- Overall more smooth playback (support for higher fps) and better audio sync
- Fixing an issue while ffmpeg fails to seek on keyframe we skip until it finds one (was showing broken frames)
- Fixing an issue with Audio noise during pause/play

Changes 2.5.2
- Saving Subs delay in History seperately for each subtitle
- Fixing subs to open properly from history and after seek abort (reopening), including the proper delay
- Fixing an issue with youtube urls (for channels/lists, not supported currently will play single video) which was crashing the app

Changes 2.5.1
- Finalizing new Seek also for network (slow) streams
- Fixing a critical issue for all other non-common protocols (rtsp/ftp etc.)
- Fixing an issue with streams that have start_time != 0
- Fixing a freeze issue and other crashing issues during open (re-enabling interrupt/abort instead of thread abort)
- Fixing an issue with OSD clock, was not displaying seek time on non-SeekOnSlide
- Fixing an issue with BitSwarm with PieceRetries (was dropping peers that shouldn't)
- Adding http-refer for youtube-dl urls to support more sites
- Adjusting default torrent streaming timing settings & default timeout for rtsp (10 seconds)

Project : https://github.com/SuRGeoNix/Flyleaf
License : LGPL-3.0
<3<3<3<3: FFmpeg, FFmpeg.Autogen, Opensubtitles & SharpDX
45 changes: 22 additions & 23 deletions Flyleaf/AudioPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class AudioPlayer : IMMNotificationClient, IAudioSessionEventsHandler

public Control uiThread; // Requires to run on same thread (using UI thread) | Warning! Any access to audio device should be invoke ui thread (otherwise will hang on player.Dispose() | player.Init())

public const int NAUDIO_DELAY_MS = 300; // Latency (buffer before play), consider same audio delay for video player in order to be sync
public const int NAUDIO_DELAY_MS = 200; // Latency (buffer before play), consider same audio delay for video player in order to be sync
int CHANNELS = 2; // Currently fixed
public int Rate = 48000; // Will be set from Input Format
//int _BITS = 16; // Currently not used (CreateIeeeFloatWaveFormat 32bit, if we need to set it use WaveFormatExtensible)
Expand Down Expand Up @@ -107,6 +107,27 @@ public void Initialize(int rate = -1) // !!! Must be called from the same thread
public void Stop() { lock (locker) { player.Stop(); Initialize(); } }
public void Close() { lock (locker) { if (player != null) player.Dispose(); } }

public void FrameClbk(byte[] buffer, int offset, int count)
{
try
{
if (player.PlaybackState != PlaybackState.Playing) return;

if (this.buffer.BufferedDuration.Milliseconds > NAUDIO_DELAY_MS)
{
// We will see this happen on HLS streams that change source (eg. ads - like two streams playing audio in parallel)
Log("Resynch !!! | " + this.buffer.BufferedBytes);
this.buffer.ClearBuffer();
}

this.buffer.AddSamples(buffer, offset, count);
}
catch (Exception e)
{
Log(e.Message + " " + e.StackTrace);
}
}

public int GetVolume()
{
lock (locker)
Expand Down Expand Up @@ -136,28 +157,6 @@ private bool GetSetMute(bool Get = true, bool mute = false)
return false;
}

// Callbacks
public void FrameClbk(byte[] buffer, int offset, int count)
{
try
{
if (player.PlaybackState != PlaybackState.Playing) return;

if (this.buffer.BufferedDuration.Milliseconds > NAUDIO_DELAY_MS)
{
Log("Resynch !!! | " + this.buffer.BufferedBytes);
this.buffer.ClearBuffer();
}

this.buffer.AddSamples(buffer, offset, count);
}
catch (Exception e)
{
Log(e.Message + " " + e.StackTrace);
}
}
public void ResetClbk() { lock (locker) buffer.ClearBuffer(); }

// Master Audio Events | MMDeviceEnumerator
public void OnMasterVolumeChanged(AudioVolumeNotificationData data)
{
Expand Down
6 changes: 5 additions & 1 deletion Flyleaf/Controls/FlyleafPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1371,12 +1371,16 @@ private void FlyLeaf_KeyPress (object sender, KeyPressEventArgs e)
else if (c == KeyCodeToUnicode(Keys.M) || Char.ToUpper(c) == KeyCodeToUnicode(Keys.M)) { MuteUnmute(); }
else if (c == KeyCodeToUnicode(Keys.S) || Char.ToUpper(c) == KeyCodeToUnicode(Keys.S))
{
//player.renderer.tryNext(); // Testing SwapChains ColorSpaces
player.doSubs = !player.doSubs;
}
else if (c == KeyCodeToUnicode(Keys.A) || Char.ToUpper(c) == KeyCodeToUnicode(Keys.A))
{
player.doAudio = !player.doAudio;

if (!player.hasAudio || !player.doAudio)
{ tblBar.btnMute.Enabled = false; tblBar.volBar.Enabled = false; }
else
{ tblBar.btnMute.Enabled = true; tblBar.volBar.Enabled = true; }
}
else if (c == KeyCodeToUnicode(Keys.O) || Char.ToUpper(c) == KeyCodeToUnicode(Keys.O))
{
Expand Down
12 changes: 6 additions & 6 deletions Flyleaf/Flyleaf.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,17 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="BencodeNET, Version=3.1.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\BencodeNET.3.1.4\lib\netstandard2.0\BencodeNET.dll</HintPath>
<Reference Include="BencodeNET, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\BencodeNET.4.0.0\lib\netstandard2.0\BencodeNET.dll</HintPath>
</Reference>
<Reference Include="BitSwarmLib, Version=2.3.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\BitSwarm.2.3.4\lib\netstandard2.0\BitSwarmLib.dll</HintPath>
<Reference Include="BitSwarmLib, Version=2.3.5.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\BitSwarm.2.3.5\lib\netstandard2.0\BitSwarmLib.dll</HintPath>
</Reference>
<Reference Include="ColorSlider">
<HintPath>Libs\ColorSlider.dll</HintPath>
</Reference>
<Reference Include="FFmpeg.AutoGen, Version=4.3.1.0, Culture=neutral, PublicKeyToken=9b7632533a381715, processorArchitecture=MSIL">
<HintPath>..\packages\FFmpeg.AutoGen.4.3.1\lib\net472\FFmpeg.AutoGen.dll</HintPath>
<Reference Include="FFmpeg.AutoGen, Version=4.3.2.0, Culture=neutral, PublicKeyToken=9b7632533a381715, processorArchitecture=MSIL">
<HintPath>..\packages\FFmpeg.AutoGen.4.3.2\lib\net472\FFmpeg.AutoGen.dll</HintPath>
</Reference>
<Reference Include="NAudio, Version=1.10.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NAudio.1.10.0\lib\net35\NAudio.dll</HintPath>
Expand Down
5 changes: 3 additions & 2 deletions Flyleaf/MediaFramework/DecoderContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -377,15 +377,16 @@ public long GetVideoFrame()
AVFrame* frame = av_frame_alloc();
lock (device)
ret = avcodec_receive_frame(vDecoder.codecCtx, frame);

if (ret == 0)
{
MediaFrame mFrame = new MediaFrame();
mFrame.pts = frame->best_effort_timestamp == AV_NOPTS_VALUE ? frame->pts : frame->best_effort_timestamp;
mFrame.timestamp = ((long)(mFrame.pts * vDecoder.info.Timebase) - demuxer.streams[vDecoder.st->index].StartTime) + opt.audio.LatencyTicks;

if (mFrame.pts == AV_NOPTS_VALUE)
if (mFrame.pts == AV_NOPTS_VALUE || frame->pict_type != AVPictureType.AV_PICTURE_TYPE_I)
{
if (frame->pict_type != AVPictureType.AV_PICTURE_TYPE_I) Log($"Invalid Seek to Keyframe, skip... {frame->pict_type} | {frame->key_frame.ToString()}");
av_frame_free(&frame);
continue;
}
Expand Down
Loading

0 comments on commit 4c38dd6

Please sign in to comment.