Skip to content

Commit

Permalink
Updating to v2.6 (pre-release)
Browse files Browse the repository at this point in the history
-= Re-coding MediaRender =-

Notes: Backwards compatibility with Win7/8 might broke (not tested yet)

Additions / Enhancements
 - 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 & ?): Still using fallback to "heavy" SwsScale
 - Partial Color Range & Space support (BT601/BT709 Full/Limited) (TODO: HDR BT2020 requires also implementation from FFmpeg.Autogen to retrieve HDR metadata)
 - Better SwapChain implementation and more BackBuffers in use

Issues: Minor

Former-commit-id: 724004f
  • Loading branch information
SuRGeoNix committed Mar 19, 2021
1 parent aef3cb5 commit 5d81ded
Show file tree
Hide file tree
Showing 41 changed files with 1,253 additions and 552 deletions.
8 changes: 8 additions & 0 deletions Flyleaf Multi-Player (WinForms Demo 2)/FrmMain.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 11 additions & 4 deletions Flyleaf/Controls/FlyleafPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -678,11 +678,14 @@ private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
if (!seeking && !player.isLive)
{
if (tblBar.seekBar.Maximum == 1) return; // TEMP... thorws exception just after open
int barValue = (int)(player.CurTime / 10000000) + 1;
int barValue = (int)(player.CurTime / 10000000);
if (barValue > (int)tblBar.seekBar.Maximum) barValue = (int)tblBar.seekBar.Maximum;
else if (barValue < (int)tblBar.seekBar.Minimum) barValue = (int)tblBar.seekBar.Minimum;

tblBar.seekBar.SetValue(barValue);
if (barValue == tblBar.seekBar.Maximum -1)
tblBar.seekBar.SetValue(tblBar.seekBar.Maximum);
else
tblBar.seekBar.SetValue(barValue);

// Saves the current second in history (should be only if the duration of movie is large enough and playing time was at least X secs) - see also on OpenFinished for Seek
timerLoop++;
Expand Down Expand Up @@ -824,6 +827,7 @@ public void OpenFinished(bool success, string selectedFile)
{
tblBar.seekBar.SetValue(0);
tblBar.seekBar.Maximum = (int)(player.Duration / 10000000);
if (tblBar.seekBar.Maximum == 1) tblBar.seekBar.SetValue(1);
}
else
{
Expand Down Expand Up @@ -1038,7 +1042,7 @@ public void FixAspectRatio (bool fromOpen = false)
if (!config.hookForm._Enabled || !config.hookForm.AutoResize) return;
if (form.InvokeRequired) { form.BeginInvoke(new Action(() => FixAspectRatio())); return; }

float AspectRatio = config.video.AspectRatio == ViewPorts.KEEP ? player.DecoderRatio : player.CustomRatio;
float AspectRatio = config.video.AspectRatio == ViewPorts.KEEP ? player.decoder.vStreamInfo.AspectRatio : player.CustomRatio;

if (fromOpen)
if (config.hookForm._Enabled && config.hookForm.HookHandle) form.Size = formInitSize; else form.Size = thisInitSize;
Expand Down Expand Up @@ -1361,10 +1365,13 @@ private void FlyLeaf_KeyPress (object sender, KeyPressEventArgs e)
{
if (player.ViewPort == MediaRouter.ViewPorts.KEEP) player.ViewPort = MediaRouter.ViewPorts.FILL;
else if (player.ViewPort != MediaRouter.ViewPorts.KEEP) player.ViewPort = MediaRouter.ViewPorts.KEEP;

if (isFullScreen) player.renderer.HookResized(null, null);
}
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))
Expand Down Expand Up @@ -1714,7 +1721,7 @@ private void WM_MOUSEMOVE_MK_LBUTTON(MouseEventArgs e)

if (config.video.AspectRatio != ViewPorts.FILL)
{
float AspectRatio = config.video.AspectRatio == ViewPorts.KEEP ? player.DecoderRatio : player.CustomRatio;
float AspectRatio = config.video.AspectRatio == ViewPorts.KEEP ? player.decoder.vStreamInfo.AspectRatio : player.CustomRatio;

// RESIZE FORM [KEEP ASPECT RATIO]
if (displayMoveSideCur == 1)
Expand Down
25 changes: 19 additions & 6 deletions Flyleaf/Flyleaf.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,6 @@
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<None Include="Shaders\PixelShader_YUV.hlsl" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Controls\FlyleafBar.resx">
<DependentUpon>FlyleafBar.cs</DependentUpon>
Expand All @@ -226,13 +223,29 @@
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="Shaders\PixelShader.hlsl" />
</ItemGroup>
<ItemGroup>
<None Include="Shaders\VertexShader.hlsl" />
</ItemGroup>
<ItemGroup>
<None Include="Shaders\PixelShader.hlsl" />
<None Include="Shaders\BT601.Y_U_V.FULL.hlsl" />
<None Include="Shaders\BT601.Y_U_V.LIMITED.hlsl" />
<None Include="Shaders\BT601.Y_UV.FULL.hlsl" />
<None Include="Shaders\BT601.Y_UV.LIMITED.hlsl" />
<None Include="Shaders\BT601.Y_VU.FULL.hlsl" />
<None Include="Shaders\BT601.Y_VU.LIMITED.hlsl" />
<None Include="Shaders\BT709.Y_U_V.FULL.hlsl" />
<None Include="Shaders\BT709.Y_U_V.LIMITED.hlsl" />
<None Include="Shaders\BT709.Y_UV.FULL.hlsl" />
<None Include="Shaders\BT709.Y_UV.LIMITED.hlsl" />
<None Include="Shaders\BT709.Y_VU.FULL.hlsl" />
<None Include="Shaders\BT709.Y_VU.LIMITED.hlsl" />
<None Include="Shaders\BT2020.Y_U_V.FULL.hlsl" />
<None Include="Shaders\BT2020.Y_U_V.LIMITED.hlsl" />
<None Include="Shaders\BT2020.Y_UV.FULL.hlsl" />
<None Include="Shaders\BT2020.Y_UV.LIMITED.hlsl" />
<None Include="Shaders\BT2020.Y_VU.FULL.hlsl" />
<None Include="Shaders\BT2020.Y_VU.LIMITED.hlsl" />
<None Include="Images\VideoFile.png" />
<None Include="Images\Web.png" />
<Content Include="Images\Mute.png" />
Expand Down
101 changes: 41 additions & 60 deletions Flyleaf/MediaFramework/Decoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ public unsafe class Decoder
public bool hwAccelSuccess;

public SwsContext* swsCtx;
internal Texture2DDescription textDescHW;
internal Texture2DDescription textDescYUV;
internal Texture2DDescription textDescRGB;
internal Texture2DDescription textDesc, textDescUV;
internal Texture2D textureFFmpeg;

public SwrContext* swrCtx;
Expand Down Expand Up @@ -156,76 +154,64 @@ public int SetupVideo(AVCodec* codec)
{
hwAccelSuccess = false;

if (opt.video.HWAcceleration && VideoAcceleration.CheckCodecSupport(codec))
if (opt.video.HWAcceleration)
{
if (demuxer.decCtx.va.hw_device_ctx == null) demuxer.decCtx.va.Init(demuxer.decCtx.device);

if (demuxer.decCtx.va.hw_device_ctx != null)
if (VideoAcceleration.CheckCodecSupport(codec))
{
codecCtx->hw_device_ctx = av_buffer_ref(demuxer.decCtx.va.hw_device_ctx);
hwAccelSuccess = true;
if (demuxer.decCtx.va.hw_device_ctx == null) demuxer.decCtx.va.Init(demuxer.decCtx.device);

if (demuxer.decCtx.va.hw_device_ctx != null)
{
codecCtx->hw_device_ctx = av_buffer_ref(demuxer.decCtx.va.hw_device_ctx);
hwAccelSuccess = true;
Log("HW Acceleration Success");
}
}
else
Log("HW Acceleration Failed");
}
else
Log("HW Acceleration Disabled");

codecCtx->thread_count = Math.Min(opt.video.DecoderThreads, codecCtx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16);
codecCtx->thread_type = 0;
//vCodecCtx->active_thread_type = FF_THREAD_FRAME;
//vCodecCtx->active_thread_type = FF_THREAD_SLICE;
codecCtx->thread_safe_callbacks = 1;

// Hardware Texture (NV12 | P010) | Format will be set from source
textDescHW = new Texture2DDescription()
{
Usage = ResourceUsage.Default,

Width = codecCtx->width,
Height = codecCtx->height,
AVPixFmtDescriptor* pixFmtDesc = av_pix_fmt_desc_get((AVPixelFormat) Enum.ToObject(typeof(AVPixelFormat), info.PixelFormat));
int bits = pixFmtDesc->comp.ToArray()[0].depth;

BindFlags = BindFlags.Decoder,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None,

SampleDescription = new SampleDescription(1, 0),
ArraySize = 1,
MipLevels = 1
};

// YUV Pixel Shader (textureY | textureU | textureV)
textDescYUV = new Texture2DDescription()
textDesc = new Texture2DDescription()
{
Usage = ResourceUsage.Immutable,
Format = Format.R8_UNorm,
Usage = ResourceUsage.Default,
BindFlags = BindFlags.ShaderResource,

Format = bits > 8 ? Format.R16_UNorm : Format.R8_UNorm, // FOR HW/SW will be set later
Width = codecCtx->width,
Height = codecCtx->height,

BindFlags = BindFlags.ShaderResource,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None,

SampleDescription = new SampleDescription(1, 0),
ArraySize = 1,
MipLevels = 1
};

// RGBA Sws Scale
textDescRGB = new Texture2DDescription()
textDescUV = new Texture2DDescription()
{
Usage = ResourceUsage.Immutable,
Format = Format.R8G8B8A8_UNorm,

Width = codecCtx->width,
Height = codecCtx->height,

Usage = ResourceUsage.Default,
BindFlags = BindFlags.ShaderResource,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None,

//Format = bits > 8 ? Format.R16G16_UNorm : Format.R8G8_UNorm, // FOR HW/SW will be set later
Format = bits > 8 ? Format.R16_UNorm : Format.R8_UNorm, // FOR HW/SW will be set later
Width = codecCtx->width >> info.PixelFormatDesc->log2_chroma_w,
Height = codecCtx->height >> info.PixelFormatDesc->log2_chroma_h,

SampleDescription = new SampleDescription(1, 0),
ArraySize = 1,
MipLevels = 1
};

decCtx.VideoCodecChanged_();
return 0;
}

Expand All @@ -241,16 +227,8 @@ public void Flush()
}

if (type == Type.Video)
{
foreach (MediaFrame m in frames)
{
SharpDX.Utilities.Dispose(ref m.textureHW);
SharpDX.Utilities.Dispose(ref m.textureY);
SharpDX.Utilities.Dispose(ref m.textureU);
SharpDX.Utilities.Dispose(ref m.textureV);
SharpDX.Utilities.Dispose(ref m.textureRGB);
}
}
foreach (MediaFrame frame in frames)
if (frame.textures != null) for (int i=0; i<frame.textures.Length; i++) SharpDX.Utilities.Dispose(ref frame.textures[i]);

packets = new ConcurrentQueue<IntPtr>();
frames = new ConcurrentQueue<MediaFrame>();
Expand Down Expand Up @@ -316,7 +294,7 @@ public void Decode()
if (demuxer.status == Status.READY)
{
demuxer.demuxARE.Set();
while (!demuxer.isPlaying && demuxer.status != Status.END) Thread.Sleep(1);
while (!demuxer.isPlaying && demuxer.status != Status.END && !forcePause && decCtx.isPlaying) Thread.Sleep(1);
}

while (true)
Expand Down Expand Up @@ -417,8 +395,7 @@ public void Decode()
}
}

lock (demuxer.decCtx.device)
ret = avcodec_send_packet(codecCtx, pkt);
ret = avcodec_send_packet(codecCtx, pkt);

if (ret != 0 && ret != AVERROR(EAGAIN))
{
Expand Down Expand Up @@ -448,8 +425,7 @@ public void Decode()

while (true)
{
lock (demuxer.decCtx.device)
ret = avcodec_receive_frame(codecCtx, frame);
ret = avcodec_receive_frame(codecCtx, frame);

if (ret == 0)
{
Expand All @@ -463,10 +439,15 @@ public void Decode()
}

//Log(Utils.TicksToTime((long)(mFrame.pts * demuxer.streams[st->index].Timebase)) + " | pts -> " + mFrame.pts);

if (type == Type.Video)
{
if (hwAccelSuccess && frame->hw_frames_ctx == null) hwAccelSuccess = false;
if (hwAccelSuccess && frame->hw_frames_ctx == null)
{
Log("HW Acceleration Failed 2");
hwAccelSuccess = false;
decCtx.VideoCodecChanged_();
}
mFrame.timestamp = ((long)(mFrame.pts * info.Timebase) - demuxer.streams[st->index].StartTime) + opt.audio.LatencyTicks;
if (MediaFrame.ProcessVideoFrame(this, mFrame, frame) != 0) mFrame = null;

Expand Down
10 changes: 10 additions & 0 deletions Flyleaf/MediaFramework/DecoderContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,12 @@ public long GetVideoFrame()

if (firstTs == -1)
{
if (vDecoder.hwAccelSuccess && frame->hw_frames_ctx == null)
{
Log("HW Acceleration Failed 2");
vDecoder.hwAccelSuccess = false;
VideoCodecChanged_();
}
if (vDecoder.hwAccelSuccess && frame->hw_frames_ctx == null) vDecoder.hwAccelSuccess = false;
firstTs = mFrame.timestamp;
}
Expand Down Expand Up @@ -427,6 +433,10 @@ public long GetVideoFrame()
return firstTs;
}

public event VideoCodecChangedHandler VideoCodecChanged;
public delegate void VideoCodecChangedHandler(object source, EventArgs e);
internal void VideoCodecChanged_() { VideoCodecChanged?.Invoke(this, new EventArgs()); }

private void Log(string msg) { Console.WriteLine($"[{DateTime.Now.ToString("hh.mm.ss.fff")}] [DecoderContext] {msg}"); }
}
}
4 changes: 3 additions & 1 deletion Flyleaf/MediaFramework/Demuxer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ public int Open(string url, bool doAudio = true, bool doSubs = true, Stream stre
status = Status.READY;

pkt = av_packet_alloc();

//Console.WriteLine($"CP: {decoder.codecCtx->colorspace} | PR: {decoder.codecCtx->color_primaries} | TRC: {decoder.codecCtx->color_trc} | CR: {decoder.codecCtx->color_range}");
return 0;
}
public void Close(bool closeExternals = true)
Expand Down Expand Up @@ -437,6 +437,7 @@ public void Demux()
forcePause = false;
Log("Started");
int ret = 0;
int allowedErrors = 30;

while (true)
{
Expand All @@ -451,6 +452,7 @@ public void Demux()
if (ret == AVERROR_EXIT)
{
Log("AVERROR_EXIT!!! " + decCtx.interrupt);
allowedErrors--; if (allowedErrors == 0) break;
continue;
}

Expand Down
Loading

0 comments on commit 5d81ded

Please sign in to comment.