@@ -84,6 +84,9 @@ public DecoderContext(Config config = null, Control control = null, int uniqueId
84
84
VideoDecoder = new VideoDecoder ( Config , control , UniqueId ) ;
85
85
AudioDecoder = new AudioDecoder ( Config , UniqueId , VideoDecoder ) ;
86
86
SubtitlesDecoder = new SubtitlesDecoder ( Config , UniqueId ) ;
87
+
88
+ VideoDecoder . recCompleted = RecordCompleted ;
89
+ AudioDecoder . recCompleted = RecordCompleted ;
87
90
}
88
91
public void Initialize ( )
89
92
{
@@ -626,6 +629,7 @@ public int Seek(long ms = -1, bool foreward = false)
626
629
627
630
if ( ms == - 1 ) ms = GetCurTimeMs ( ) ;
628
631
632
+ // Review decoder locks (lockAction should be added to avoid dead locks with flush mainly before lockCodecCtx)
629
633
lock ( VideoDecoder . lockCodecCtx )
630
634
lock ( AudioDecoder . lockCodecCtx )
631
635
lock ( SubtitlesDecoder . lockCodecCtx )
@@ -657,7 +661,7 @@ public int Seek(long ms = -1, bool foreward = false)
657
661
{
658
662
AudioDecoder . Pause ( ) ;
659
663
AudioDecoder . Flush ( ) ;
660
- AudioDemuxer . PauseOnQueueFull = true ; // Pause() will cause corrupted packets which causes av_read_frame to EOF
664
+ AudioDemuxer . PauseOnQueueFull = true ;
661
665
RequiresResync = true ;
662
666
}
663
667
@@ -673,44 +677,55 @@ public int Seek(long ms = -1, bool foreward = false)
673
677
}
674
678
public int SeekAudio ( long ms = - 1 , bool foreward = false )
675
679
{
676
- int ret = - 1 ;
680
+ int ret = 0 ;
677
681
678
- if ( AudioDemuxer . Disposed || AudioDecoder . OnVideoDemuxer || ! Config . Audio . Enabled ) return ret ;
682
+ if ( AudioDemuxer . Disposed || AudioDecoder . OnVideoDemuxer || ! Config . Audio . Enabled ) return - 1 ;
679
683
680
684
if ( ms == - 1 ) ms = GetCurTimeMs ( ) ;
681
685
686
+ long seekTimestamp = CalcSeekTimestamp ( AudioDemuxer , ms , ref foreward ) ;
687
+
688
+ lock ( AudioDecoder . lockActions )
682
689
lock ( AudioDecoder . lockCodecCtx )
683
690
{
684
- ret = AudioDemuxer . Seek ( CalcSeekTimestamp ( AudioDemuxer , ms , ref foreward ) , foreward ) ;
685
- AudioDecoder . Flush ( ) ;
686
- }
691
+ lock ( AudioDemuxer . lockActions )
692
+ if ( AudioDemuxer . SeekInQueue ( seekTimestamp , foreward ) != 0 )
693
+ ret = AudioDemuxer . Seek ( seekTimestamp , foreward ) ;
687
694
688
- if ( VideoDecoder . IsRunning )
689
- {
690
- AudioDemuxer . Start ( ) ;
691
- AudioDecoder . Start ( ) ;
695
+ AudioDecoder . Flush ( ) ;
696
+ if ( VideoDecoder . IsRunning )
697
+ {
698
+ AudioDemuxer . Start ( ) ;
699
+ AudioDecoder . Start ( ) ;
700
+ }
692
701
}
693
702
694
703
return ret ;
695
704
}
696
705
public int SeekSubtitles ( long ms = - 1 , bool foreward = false )
697
706
{
698
- int ret = - 1 ;
707
+ int ret = 0 ;
699
708
700
- if ( SubtitlesDemuxer . Disposed || SubtitlesDecoder . OnVideoDemuxer || ! Config . Subtitles . Enabled ) return ret ;
709
+ if ( SubtitlesDemuxer . Disposed || SubtitlesDecoder . OnVideoDemuxer || ! Config . Subtitles . Enabled ) return - 1 ;
701
710
702
711
if ( ms == - 1 ) ms = GetCurTimeMs ( ) ;
703
712
713
+ long seekTimestamp = CalcSeekTimestamp ( SubtitlesDemuxer , ms , ref foreward ) ;
714
+
715
+ lock ( SubtitlesDecoder . lockActions )
704
716
lock ( SubtitlesDecoder . lockCodecCtx )
705
717
{
706
- ret = SubtitlesDemuxer . Seek ( CalcSeekTimestamp ( SubtitlesDemuxer , ms , ref foreward ) , foreward ) ;
707
- SubtitlesDecoder . Flush ( ) ;
708
- }
718
+ // Currently disabled as it will fail to seek within the queue the most of the times
719
+ //lock (SubtitlesDemuxer.lockActions)
720
+ //if (SubtitlesDemuxer.SeekInQueue(seekTimestamp, foreward) != 0)
721
+ ret = SubtitlesDemuxer . Seek ( seekTimestamp , foreward ) ;
709
722
710
- if ( VideoDecoder . IsRunning )
711
- {
712
- SubtitlesDemuxer . Start ( ) ;
713
- SubtitlesDecoder . Start ( ) ;
723
+ SubtitlesDecoder . Flush ( ) ;
724
+ if ( VideoDecoder . IsRunning )
725
+ {
726
+ SubtitlesDemuxer . Start ( ) ;
727
+ SubtitlesDecoder . Start ( ) ;
728
+ }
714
729
}
715
730
716
731
return ret ;
@@ -994,58 +1009,64 @@ public void PrintStats()
994
1009
995
1010
#region Recorder
996
1011
Remuxer Recorder = new Remuxer ( ) ;
1012
+ public event EventHandler RecordingCompleted ;
997
1013
public bool IsRecording
998
1014
{
999
- get => VideoDemuxer . IsRecording || AudioDemuxer . IsRecording ;
1015
+ get => VideoDecoder . isRecording || AudioDecoder . isRecording ;
1000
1016
}
1001
1017
int oldMaxAudioFrames ;
1018
+ bool recHasVideo ;
1002
1019
public void StartRecording ( ref string filename , bool useRecommendedExtension = true )
1003
1020
{
1004
- oldMaxAudioFrames = - 1 ;
1005
-
1006
- if ( AudioStream == null || AudioStream . Demuxer . Type == MediaType . Video )
1007
- {
1008
- VideoDemuxer . StartRecording ( ref filename , useRecommendedExtension ) ;
1009
- return ;
1010
- }
1011
1021
1012
1022
if ( IsRecording ) StopRecording ( ) ;
1013
1023
1024
+ oldMaxAudioFrames = - 1 ;
1025
+ recHasVideo = false ;
1026
+
1014
1027
Log ( "Record Start" ) ;
1015
- VideoDemuxer . RecordingCompleted += RecordingCompleted ;
1028
+
1029
+ recHasVideo = ! VideoDecoder . Disposed && VideoDecoder . Stream != null ;
1016
1030
1017
1031
if ( useRecommendedExtension )
1018
- filename = $ "{ filename } .{ VideoDemuxer . Extension } ";
1032
+ filename = $ "{ filename } .{ ( recHasVideo ? VideoDecoder . Stream . Demuxer . Extension : AudioDecoder . Stream . Demuxer . Extension ) } ";
1019
1033
1020
1034
Recorder . Open ( filename ) ;
1021
- for ( int i = 0 ; i < VideoDemuxer . EnabledStreams . Count ; i ++ )
1022
- Log ( Recorder . AddStream ( VideoDemuxer . AVStreamToStream [ VideoDemuxer . EnabledStreams [ i ] ] . AVStream ) . ToString ( ) ) ;
1023
-
1024
- for ( int i = 0 ; i < AudioDemuxer . EnabledStreams . Count ; i ++ )
1025
- Log ( Recorder . AddStream ( AudioDemuxer . AVStreamToStream [ AudioDemuxer . EnabledStreams [ i ] ] . AVStream , true ) . ToString ( ) ) ;
1035
+ if ( recHasVideo )
1036
+ Log ( Recorder . AddStream ( VideoDecoder . Stream . AVStream ) . ToString ( ) ) ;
1037
+
1038
+ if ( ! AudioDecoder . Disposed && AudioDecoder . Stream != null )
1039
+ Log ( Recorder . AddStream ( AudioDecoder . Stream . AVStream , ! AudioDecoder . OnVideoDemuxer ) . ToString ( ) ) ;
1026
1040
1027
1041
if ( ! Recorder . HasStreams || Recorder . WriteHeader ( ) != 0 ) return ; //throw new Exception("Invalid remuxer configuration");
1028
1042
1029
1043
// Check also buffering and possible Diff of first audio/video timestamp to remuxer to ensure sync between each other (shouldn't be more than 30-50ms)
1030
1044
oldMaxAudioFrames = Config . Decoder . MaxAudioFrames ;
1031
- long timestamp = Math . Max ( VideoDemuxer . CurTime + VideoDemuxer . BufferedDuration , AudioDemuxer . CurTime + AudioDemuxer . BufferedDuration ) + 1500 * 10000 ;
1045
+ // long timestamp = Math.Max(VideoDemuxer.CurTime + VideoDemuxer.BufferedDuration, AudioDemuxer.CurTime + AudioDemuxer.BufferedDuration) + 1500 * 10000;
1032
1046
Config . Decoder . MaxAudioFrames = Config . Decoder . MaxVideoFrames ;
1033
1047
1034
- VideoDemuxer . StartRecording ( Recorder , timestamp ) ;
1035
- AudioDemuxer . StartRecording ( Recorder , timestamp ) ;
1048
+ VideoDecoder . StartRecording ( Recorder ) ;
1049
+ AudioDecoder . StartRecording ( Recorder ) ;
1036
1050
}
1037
1051
public void StopRecording ( )
1038
1052
{
1039
1053
if ( oldMaxAudioFrames != - 1 ) Config . Decoder . MaxAudioFrames = oldMaxAudioFrames ;
1040
1054
1041
- VideoDemuxer . RecordingCompleted -= RecordingCompleted ;
1042
- VideoDemuxer . StopRecording ( ) ;
1043
- AudioDemuxer . StopRecording ( ) ;
1055
+ VideoDecoder . StopRecording ( ) ;
1056
+ AudioDecoder . StopRecording ( ) ;
1044
1057
Recorder . Dispose ( ) ;
1045
1058
oldMaxAudioFrames = - 1 ;
1046
1059
Log ( "Record Completed" ) ;
1047
1060
}
1048
- private void RecordingCompleted ( object sender , EventArgs e ) { StopRecording ( ) ; }
1061
+
1062
+ internal void RecordCompleted ( MediaType type )
1063
+ {
1064
+ if ( ! recHasVideo || ( recHasVideo && type == MediaType . Video ) )
1065
+ {
1066
+ StopRecording ( ) ;
1067
+ RecordingCompleted ? . Invoke ( this , new EventArgs ( ) ) ;
1068
+ }
1069
+ }
1049
1070
#endregion
1050
1071
1051
1072
private void Log ( string msg ) { Debug . WriteLine ( $ "[{ DateTime . Now . ToString ( "hh.mm.ss.fff" ) } ] [#{ UniqueId } ] [DecoderContext] { msg } ") ; }
0 commit comments