Skip to content

Commit

Permalink
Updating to 3.1.10
Browse files Browse the repository at this point in the history
- Fixes Pause/Play async issue (lock added)
- Fixes a duration issue
- Fixes Recording/Dowloading/Remuxing issue with subtitles
- Fixes a non-proper stopping issue for decoders
- Allowing demuxers to properly close format context even during interrupts

- FlyleafLib.Controls.WPF: Adding Show Debug for video/bitrate/record/gpu info
  • Loading branch information
SuRGeoNix committed Jul 20, 2021
1 parent 5897819 commit 2e00236
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 37 deletions.
33 changes: 30 additions & 3 deletions FlyleafLib.Controls.WPF/Flyleaf.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,39 @@
<!--Pop Up Dialog (Settings/Set Values)-->
<materialDesign:DialogHost x:Name="PART_DialogSettings"/>

<!--GPU Usage-->
<TextBlock Margin="0 0 0 50" VerticalAlignment="top" HorizontalAlignment="Right" TextAlignment="Center" TextWrapping="Wrap" FontSize="33" Foreground="White" FontWeight="Bold" Text="{Binding GPUUsage}"/>
<!--Media Info-->
<TextBlock Margin="0 20 20 0" VerticalAlignment="top" HorizontalAlignment="Right" TextAlignment="Right" TextWrapping="Wrap" FontSize="16" Background="Black" Foreground="DarkOrange" FontWeight="Bold">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ShowDebug}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
<TextBlock.Text>
<MultiBinding StringFormat=" {0}p @{1} {2}/{3} [hw: {4}|{5}] &#x0d;&#x0a; [tbr: {6:#,#.00}] [vbr: {7:#,#.00}] [abr: {8:#,#.00}] &#x0d;&#x0a; [rec: {9}] [drops: {10}] [gpu: {11}]">
<Binding Path="VideoDecoder.VideoStream.Height"/>
<Binding Path="Player.FPS"/>
<Binding Path="VideoDecoder.VideoStream.CodecName"/>
<Binding Path="VideoDecoder.VideoStream.PixelFormatStr"/>
<Binding Path="Decoder.HWAcceleration"/>
<Binding Path="VideoDecoder.VideoAccelerated"/>
<Binding Path="Player.TBR"/>
<Binding Path="Player.VBR"/>
<Binding Path="Player.ABR"/>
<Binding Path="VideoDemuxer.IsRecording"/>
<Binding Path="Player.DroppedFrames"/>
<Binding Path="GPUUsage"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>

<!--Subtitles-->
<TextBlock x:Name="PART_Subtitles" Margin="0 0 0 50" VerticalAlignment="Bottom" HorizontalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap" FontSize="33" Foreground="White" FontWeight="Bold" Text="{Binding Session.SubsText}"/>

<!--Flyleaf Bar-->
<materialDesign:Card TextElement.FontSize="14" TextElement.FontWeight="Medium" TextElement.Foreground="{DynamicResource MaterialDesignBody}" FontFamily="{materialDesign:MaterialDesignFont}" VerticalAlignment="Bottom" Focusable="False" Background="{StaticResource RadialBrush}">
<materialDesign:Card.Style>
Expand Down
14 changes: 14 additions & 0 deletions FlyleafLib.Controls.WPF/Flyleaf.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

using FlyleafLib.MediaPlayer;
using FlyleafLib.MediaStream;
using FlyleafLib.MediaFramework.MediaDecoder;
using FlyleafLib.MediaFramework.MediaDemuxer;

namespace FlyleafLib.Controls.WPF
{
Expand All @@ -27,6 +29,11 @@ public partial class Flyleaf : UserControl, INotifyPropertyChanged, IVideoView

public Player Player { get => _Player; set { _Player = value; InitializePlayer(); } }
Player _Player;

public VideoDemuxer VideoDemuxer => Player?.decoder?.VideoDemuxer;
public VideoDecoder VideoDecoder => Player?.decoder?.VideoDecoder;
public AudioDecoder AudioDecoder => Player?.decoder?.AudioDecoder;

public AudioPlayer AudioPlayer => Player?.audioPlayer;
public AudioMaster AudioMaster => Master.AudioMaster;
public FlyleafWindow WindowFront => VideoView?.WindowFront;
Expand All @@ -41,6 +48,13 @@ public partial class Flyleaf : UserControl, INotifyPropertyChanged, IVideoView
public Config.Decoder Decoder => Config?.decoder;
public Config.Demuxer Demuxer => Config?.demuxer;

bool _ShowDebug;
public bool ShowDebug
{
get => _ShowDebug;
set => Set(ref _ShowDebug, value);
}

bool _IsRecording;
public bool IsRecording
{
Expand Down
8 changes: 4 additions & 4 deletions FlyleafLib.Controls.WPF/PopUpMenu.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -436,12 +436,12 @@
<MenuItem Header="Zoom In" Command="{Binding Zoom}" CommandParameter="50" Icon="{materialDesign:PackIcon Kind=ZoomIn}"/>
<MenuItem Header="Zoom out" Command="{Binding Zoom}" CommandParameter="-50" Icon="{materialDesign:PackIcon Kind=ZoomOut}"/>
</MenuItem>

</MenuItem>

<!--<Separator />
<MenuItem Header="Media Info" Icon="{materialDesign:PackIcon InfoOutline}"/>-->
</MenuItem>

<Separator />
<MenuItem Header="Show Debug" IsCheckable="True" IsChecked="{Binding ShowDebug}"/>

<Separator />
<MenuItem Header="Exit" Icon="{materialDesign:PackIcon ExitToApp}" Command="{Binding ExitApplication}"/>
</ContextMenu>
Expand Down
9 changes: 6 additions & 3 deletions FlyleafLib/MediaFramework/MediaDecoder/AudioDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public unsafe class AudioDecoder : DecoderBase

protected override unsafe int Setup(AVCodec* codec)
{
lock (lockCodecCtx)
{
int ret;

if (swrCtx == null) swrCtx = swr_alloc();
Expand All @@ -58,6 +60,7 @@ protected override unsafe int Setup(AVCodec* codec)
decCtx.player.audioPlayer.Initialize(codecCtx->sample_rate);

return ret;
}
}

public override void Stop()
Expand Down Expand Up @@ -113,13 +116,13 @@ protected override void DecodeInternal()
if (demuxer.Status == MediaDemuxer.Status.Ended)
{
Status = Status.Ended;
return;
break;
}
else if (demuxer.Status != MediaDemuxer.Status.Demuxing && demuxer.Status != MediaDemuxer.Status.QueueFull)
{
Log($"Demuxer is not running [Demuxer Status: {demuxer.Status}]");
Status = demuxer.Status == MediaDemuxer.Status.Stopping || demuxer.Status == MediaDemuxer.Status.Stopped ? Status.Stopped : Status.Pausing;
return;
Status = demuxer.Status == MediaDemuxer.Status.Stopping || demuxer.Status == MediaDemuxer.Status.Stopped ? Status.Stopping2 : Status.Paused;
break;
}

Thread.Sleep(20);
Expand Down
13 changes: 7 additions & 6 deletions FlyleafLib/MediaFramework/MediaDecoder/DecoderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,19 @@ public int Open(StreamBase stream)

public virtual void Stop()
{
if (Status == Status.Stopped) return;
StopThread();

lock (lockCodecCtx)
{
if (Status == Status.Stopped) return;

StopThread();

if (Stream != null)
{
if (Stream.Demuxer.Type == MediaType.Video)
Stream.Demuxer.DisableStream(Stream);
else
Stream.Demuxer.Stop();
}

avcodec_flush_buffers(codecCtx); // ??
avcodec_close(codecCtx);
if (frame != null) fixed (AVFrame** ptr = &frame) av_frame_free(ptr);
Expand Down Expand Up @@ -178,7 +177,8 @@ protected void Decode()

} // While !stopThread

if (Status != Status.Ended) Status = Status.Stopped;
//if (Status == Status.Stopping2) Stop();
if (Status != Status.Ended && Status != Status.Stopping2) Status = Status.Stopped;
Log($"[Thread] Stopped ({Status})");
}
protected abstract void DecodeInternal();
Expand All @@ -194,6 +194,7 @@ protected void Log(string msg)
public enum Status
{
Stopping,
Stopping2,
Stopped,

Opening,
Expand Down
6 changes: 3 additions & 3 deletions FlyleafLib/MediaFramework/MediaDecoder/SubtitlesDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ protected override void DecodeInternal()
if (demuxer.Status == MediaDemuxer.Status.Ended)
{
Status = Status.Ended;
return;
break;
}
else if (demuxer.Status != MediaDemuxer.Status.Demuxing && demuxer.Status != MediaDemuxer.Status.QueueFull)
{
Log($"Demuxer is not running [Demuxer Status: {demuxer.Status}]");
Status = demuxer.Status == MediaDemuxer.Status.Stopping || demuxer.Status == MediaDemuxer.Status.Stopped ? Status.Stopped : Status.Pausing;
return;
Status = demuxer.Status == MediaDemuxer.Status.Stopping || demuxer.Status == MediaDemuxer.Status.Stopped ? Status.Stopping2 : Status.Paused;
break;
}

Thread.Sleep(20);
Expand Down
7 changes: 5 additions & 2 deletions FlyleafLib/MediaFramework/MediaDecoder/VideoDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public VideoDecoder(MediaContext.DecoderContext decCtx) : base(decCtx)

protected override unsafe int Setup(AVCodec* codec)
{
lock (lockCodecCtx)
{
VideoAccelerated = false;

if (cfg.decoder.HWAcceleration)
Expand Down Expand Up @@ -103,6 +105,7 @@ protected override unsafe int Setup(AVCodec* codec)
decCtx.player.renderer.FrameResized();

return 0;
}
}

public override void Stop()
Expand Down Expand Up @@ -168,8 +171,8 @@ protected override void DecodeInternal()
else if (demuxer.Status != MediaDemuxer.Status.Demuxing && demuxer.Status != MediaDemuxer.Status.QueueFull)
{
Log($"Demuxer is not running [Demuxer Status: {demuxer.Status}]");
Status = demuxer.Status == MediaDemuxer.Status.Stopping || demuxer.Status == MediaDemuxer.Status.Stopped ? Status.Stopped : Status.Pausing;
return;
Status = demuxer.Status == MediaDemuxer.Status.Stopping || demuxer.Status == MediaDemuxer.Status.Stopped ? Status.Stopping2 : Status.Paused;
break;
}

Thread.Sleep(20);
Expand Down
32 changes: 24 additions & 8 deletions FlyleafLib/MediaFramework/MediaDemuxer/DemuxerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public ConcurrentQueue<IntPtr> GetPacketsPtr(MediaType type)
public long VideoBytes { get; private set; } = 0;
public long AudioBytes { get; private set; } = 0;

internal bool allowProperClose;

internal GCHandle handle;

Thread thread;
Expand All @@ -59,7 +61,7 @@ public ConcurrentQueue<IntPtr> GetPacketsPtr(MediaType type)

AVFormatContext*fmtCtx;
AVPacket* packet;
internal object lockFmtCtx = new object();
internal object lockFmtCtx = new object();

Config cfg;

Expand All @@ -69,6 +71,8 @@ public ConcurrentQueue<IntPtr> GetPacketsPtr(MediaType type)
GCHandle demuxerHandle = (GCHandle)((IntPtr)opaque);
DemuxerBase demuxer = (DemuxerBase)demuxerHandle.Target;
if (demuxer.allowProperClose) return 0;
int interrupt = demuxer.DemuxInterrupt != 0 || demuxer.Status == Status.Stopping || demuxer.Status == Status.Stopped ? 1 : 0;
//if (demuxer.DemuxInterrupt == 1) demuxer.Log($"Interrupt 1 | {demuxer.Status}");
Expand Down Expand Up @@ -267,12 +271,11 @@ public void Pause()
//[System.Security.SecurityCritical]
public void Stop()
{
if (Status == Status.Stopped) return;
StopThread();

lock (lockFmtCtx)
{
if (Status == Status.Stopped) return;

StopThread();

// Free Streams
AudioStreams.Clear();
VideoStreams.Clear();
Expand All @@ -286,7 +289,11 @@ public void Stop()

// Close Format / Custom Contexts
if (fmtCtx != null)
{
allowProperClose = true;
fixed (AVFormatContext** ptr = &fmtCtx) { avformat_close_input(ptr); fmtCtx = null; }
allowProperClose = false;
}

if (packet != null) fixed (AVPacket** ptr = &packet) av_packet_free(ptr);
CustomIOContext.Dispose();
Expand Down Expand Up @@ -422,7 +429,7 @@ private void Demux()
if (!recGotKeyframe && fmtCtx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
if ((packet->flags & AV_PKT_FLAG_KEY) != 0) recGotKeyframe = true;

if (recGotKeyframe)
if (recGotKeyframe && (fmtCtx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || fmtCtx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO))
{
in_stream = fmtCtx->streams[packet->stream_index];
out_stream = oFmtCtx->streams[mapInOutStreams[packet->stream_index]];
Expand Down Expand Up @@ -482,8 +489,14 @@ private void Demux()
}

#region Preparing Recording
public bool IsRecording { get; private set; }

bool recGotKeyframe;
bool _IsRecording;
public bool IsRecording
{
get => _IsRecording;
set => Set(ref _IsRecording, value);
}

public void StartRecording(string filename)
{
Expand All @@ -493,8 +506,8 @@ public void StartRecording(string filename)

Log("Record Start");
OpenOutputFormat(filename);
IsRecording = true;
recGotKeyframe = false;
IsRecording = true;
}
}

Expand Down Expand Up @@ -572,6 +585,9 @@ private int OpenOutputFormat(string filename)
{
AVStream *out_stream;
AVStream *in_stream = fmtCtx->streams[EnabledStreams[i]];
#pragma warning disable CS0618 // Type or member is obsolete
if (in_stream->codec->codec_type != AVMEDIA_TYPE_VIDEO && in_stream->codec->codec_type != AVMEDIA_TYPE_AUDIO) continue;
#pragma warning restore CS0618 // Type or member is obsolete
AVCodecParameters *in_codecpar = in_stream->codecpar;
out_stream = avformat_new_stream(oFmtCtx, null);
ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
Expand Down
13 changes: 10 additions & 3 deletions FlyleafLib/MediaPlayer/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,13 @@ private void InitializeEnv()

Status = Status.Paused;
Session.CanPlay = true;
Session.Movie.Duration = decoder.VideoDemuxer.Duration;

// Should review this for the right duration
long duration2 = 0;
foreach (var vstream in decoder.VideoDemuxer.VideoStreams)
if (vstream.InUse) duration2 = vstream.Duration;

Session.Movie.Duration = duration2 > 0 ? duration2 : decoder.VideoDemuxer.Duration;

OnOpenCompleted(MediaType.Video, true);
Log($"[Initialized Env]");
Expand Down Expand Up @@ -611,7 +617,7 @@ public void Play()
{
lock (lockPlayPause)
{
if (Session == null || !Session.CanPlay || Status == Status.Playing || Status == Status.Ended) return;
if (Session == null || !Session.CanPlay || Status == Status.Playing) return;

Status = Status.Playing;
EnsureThreadDone(tSeek);
Expand Down Expand Up @@ -711,7 +717,8 @@ public void Stop()
{
lock (this)
{
Pause();
Status = Status.Stopped;
EnsureThreadDone(tPlay);
if (disposed || decoder == null) return;
decoder.Stop();
lock (lockSeek)
Expand Down
4 changes: 2 additions & 2 deletions FlyleafLib/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("3.1.9.0")]
[assembly: AssemblyFileVersion("3.1.9.0")]
[assembly: AssemblyVersion("3.1.10.0")]
[assembly: AssemblyFileVersion("3.1.10.0")]

[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
Expand Down
4 changes: 2 additions & 2 deletions Wpf Samples/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("3.1.9.0")]
[assembly: AssemblyFileVersion("3.1.9.0")]
[assembly: AssemblyVersion("3.1.10.0")]
[assembly: AssemblyFileVersion("3.1.10.0")]
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.9" Height="450" Width="800" Background="Black" Icon="Flyleaf.png" Loaded="Window_Loaded">
Title="Flyleaf v3.1.10" Height="450" Width="800" Background="Black" Icon="Flyleaf.png" Loaded="Window_Loaded">
<Grid>
<fl:VideoView Player="{Binding Player}">
<flwpf:Flyleaf x:Name="flyleafControl"/>
Expand Down

0 comments on commit 2e00236

Please sign in to comment.