@@ -10,11 +10,12 @@ namespace PartyTime
1010{
1111 public class MediaRouter
1212 {
13- Codecs . FFmpeg decoder ;
14- Thread screamer ;
13+ Codecs . FFmpeg decoder ;
14+ Thread screamer ;
1515
1616 // Audio Output Configuration
1717 int _BITS = 16 ; int _CHANNELS = 1 ; int _RATE = 48000 ;
18+
1819 long audioFlowTicks = 0 ;
1920 long audioFlowBytes = 0 ;
2021 long audioLastSyncTicks = 0 ;
@@ -24,13 +25,13 @@ public class MediaRouter
2425 long subsExternalDelay = 0 ;
2526
2627 // Queues
27- Queue < MediaFrame > aFrames ;
28- Queue < MediaFrame > vFrames ;
29- Queue < MediaFrame > sFrames ;
28+ Queue < MediaFrame > aFrames ;
29+ Queue < MediaFrame > vFrames ;
30+ Queue < MediaFrame > sFrames ;
3031
3132 int AUDIO_MIX_QUEUE_SIZE = 40 ; int AUDIO_MAX_QUEUE_SIZE = 140 ;
3233 int VIDEO_MIX_QUEUE_SIZE = 3 ; int VIDEO_MAX_QUEUE_SIZE = 4 ;
33- int SUBS_MIN_QUEUE_SIZE = 3 ; int SUBS_MAX_QUEUE_SIZE = 200 ;
34+ int SUBS_MIN_QUEUE_SIZE = 3 ; int SUBS_MAX_QUEUE_SIZE = 200 ;
3435
3536 // Status
3637 enum Status
@@ -49,21 +50,21 @@ enum Status
4950 public Action < string , int > SubFrameClbk ;
5051
5152 // Properties (Public)
52- public bool isReady { get ; private set ; }
53- public bool isPlaying { get { return ( status == Status . PLAYING ) ; } }
54- public bool isPaused { get { return ( status == Status . PAUSED ) ; } }
55- public bool isSeeking { get { return ( status == Status . SEEKING ) ; } }
56- public bool isStopped { get { return ( status == Status . STOPPED ) ; } }
57- public bool hasAudio { get ; private set ; }
58- public bool hasVideo { get ; private set ; }
59- public bool hasSubs { get ; private set ; }
60- public int Width { get ; private set ; }
61- public int Height { get ; private set ; }
62- public long Duration { get ; private set ; }
63- public long CurTime { get ; private set ; }
64- public int verbosity { get ; set ; }
65- public bool HighQuality { get { return decoder . HighQuality ; } set { decoder . HighQuality = value ; } }
66- public bool HWAcceleration { get ; set ; }
53+ public bool isReady { get ; private set ; }
54+ public bool isPlaying { get { return ( status == Status . PLAYING ) ; } }
55+ public bool isPaused { get { return ( status == Status . PAUSED ) ; } }
56+ public bool isSeeking { get { return ( status == Status . SEEKING ) ; } }
57+ public bool isStopped { get { return ( status == Status . STOPPED ) ; } }
58+ public bool hasAudio { get ; private set ; }
59+ public bool hasVideo { get ; private set ; }
60+ public bool hasSubs { get ; private set ; }
61+ public int Width { get ; private set ; }
62+ public int Height { get ; private set ; }
63+ public long Duration { get ; private set ; }
64+ public long CurTime { get ; private set ; }
65+ public int verbosity { get ; set ; }
66+ public bool HighQuality { get { return decoder . HighQuality ; } set { decoder . HighQuality = value ; } }
67+ public bool HWAcceleration { get ; set ; }
6768 public long AudioExternalDelay
6869 {
6970 get { return audioExternalDelay ; }
@@ -356,7 +357,7 @@ private void SendAudioFrames()
356357 {
357358 double curRate = audioFlowBytes / ( ( DateTime . UtcNow . Ticks - audioFlowTicks ) / 10000000.0 ) ;
358359 if ( curRate > audioBytesPerSecond ) return ;
359-
360+
360361 lock ( aFrames )
361362 {
362363 int count = 0 ;
@@ -366,6 +367,10 @@ private void SendAudioFrames()
366367 AudioFrameClbk ( aFrame . data , 0 , aFrame . data . Length ) ;
367368 audioFlowBytes += aFrame . data . Length ;
368369 count ++ ;
370+
371+ // Check on every frame that we send to ensure the buffer will not be full
372+ curRate = audioFlowBytes / ( ( DateTime . UtcNow . Ticks - audioFlowTicks ) / 10000000.0 ) ;
373+ if ( curRate > audioBytesPerSecond ) return ;
369374 }
370375 }
371376 }
@@ -504,24 +509,25 @@ public int Open(string url)
504509 CurTime = 0 ;
505510 audioExternalDelay = 0 ;
506511
507- hasAudio = decoder . hasAudio ;
508- hasVideo = decoder . hasVideo ;
509- hasSubs = decoder . hasSubs ;
512+ hasAudio = decoder . hasAudio ;
513+ hasVideo = decoder . hasVideo ;
514+ hasSubs = decoder . hasSubs ;
510515
511- Width = ( hasVideo ) ? decoder . vStreamInfo . width : 0 ;
512- Height = ( hasVideo ) ? decoder . vStreamInfo . height : 0 ;
513- Duration = ( hasVideo ) ? decoder . vStreamInfo . durationTicks : decoder . aStreamInfo . durationTicks ;
516+ Width = ( hasVideo ) ? decoder . vStreamInfo . width : 0 ;
517+ Height = ( hasVideo ) ? decoder . vStreamInfo . height : 0 ;
518+ Duration = ( hasVideo ) ? decoder . vStreamInfo . durationTicks : decoder . aStreamInfo . durationTicks ;
514519
515520 return 0 ;
516521 }
517522 public int OpenSubs ( string url )
518523 {
519524 int ret ;
520525
521- if ( ! decoder . hasVideo ) return - 1 ;
526+ if ( ! decoder . hasVideo ) return - 1 ;
522527 if ( ( ret = decoder . OpenSubs ( url ) ) != 0 ) { hasSubs = false ; return ret ; }
523528
524529 hasSubs = decoder . hasSubs ;
530+
525531 if ( ! isStopped && decoder . hasSubs ) ResynchSubs ( CurTime - subsExternalDelay ) ;
526532
527533 return 0 ;
@@ -570,26 +576,28 @@ public int Seek(int ms, bool curPos)
570576
571577 Status old = status ;
572578
573- if ( curPos ) { ms += ( int ) ( CurTime / 10000 ) ; /*CurTime += ms * 10000;*/ }
574- CurTime = ( long ) ms * 10000 ;
579+ if ( curPos ) ms += ( int ) ( CurTime / 10000 ) ;
575580
576- status = Status . SEEKING ;
577- if ( decoder != null ) decoder . Pause ( ) ;
578- if ( screamer != null ) screamer . Abort ( ) ;
581+ CurTime = ( long ) ms * 10000 ;
582+ status = Status . SEEKING ;
583+
584+ if ( decoder != null ) decoder . Pause ( ) ;
585+ if ( screamer != null ) screamer . Abort ( ) ;
579586
580587 lock ( aFrames ) aFrames = new Queue < MediaFrame > ( ) ;
581588 lock ( sFrames ) vFrames = new Queue < MediaFrame > ( ) ;
582589 lock ( sFrames ) sFrames = new Queue < MediaFrame > ( ) ;
583590
584591 if ( hasVideo ) decoder . SeekAccurate ( ms , FFmpeg . AutoGen . AVMediaType . AVMEDIA_TYPE_VIDEO ) ;
585592
586- if ( old == Status . PLAYING ) Play ( ) ;
593+ if ( old == Status . PLAYING ) Play ( ) ;
587594
588595 return 0 ;
589596 }
590597 public int Stop ( )
591598 {
592599 if ( decoder != null ) decoder . Stop ( ) ;
600+
593601 Initialize ( ) ;
594602 CurTime = 0 ;
595603
0 commit comments