// Implementation private void GetFrame(MediaFrame frame, FFmpeg.AutoGen.AVMediaType mType) { Queue <MediaFrame> curQueue = null; int curMaxSize = 0; bool mTypeIsRunning = false; // CHOOSE QUEUE switch (mType) { case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_AUDIO: curQueue = aFrames; curMaxSize = AUDIO_MAX_QUEUE_SIZE; mTypeIsRunning = decoder.isAudioRunning; break; case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_VIDEO: curQueue = vFrames; curMaxSize = VIDEO_MAX_QUEUE_SIZE; mTypeIsRunning = decoder.isVideoRunning; break; case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_SUBTITLE: curQueue = sFrames; curMaxSize = SUBS_MAX_QUEUE_SIZE; mTypeIsRunning = decoder.isSubsRunning; break; } if (curQueue == null) { return; } // IF MAX SLEEP UNTIL 3/4 OF QUEUE LEFT if (curQueue.Count == curMaxSize) { int escapeInfinity = 0; int sleepMs = (int)((decoder.vStreamInfo.frameAvgTicks / 10000) * (curMaxSize * (1.0 / 4.0))); if (sleepMs > 5000) { sleepMs = 5000; } if (mType == FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_SUBTITLE) { sleepMs *= 10; } while (mTypeIsRunning && curQueue.Count > (curMaxSize * (3.0 / 4.0))) { Thread.Sleep(sleepMs); escapeInfinity++; if (escapeInfinity > 30 && mType != FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_SUBTITLE || escapeInfinity > 100) { Log($"[ERROR EI1] {mType} Frames Queue is full ... [{curQueue.Count}/{curMaxSize}]"); decoder.Stop(); return; } mTypeIsRunning = false; if (mType == FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_AUDIO) { mTypeIsRunning = decoder.isAudioRunning; } else if (mType == FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_VIDEO) { mTypeIsRunning = decoder.isVideoRunning; } else if (mType == FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_SUBTITLE) { mTypeIsRunning = decoder.isSubsRunning; } } } if (!mTypeIsRunning) { return; } // FILL QUEUE switch (mType) { case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_AUDIO: lock (aFrames) curQueue.Enqueue(frame); break; case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_VIDEO: lock (vFrames) curQueue.Enqueue(frame); break; case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_SUBTITLE: lock (sFrames) curQueue.Enqueue(frame); break; } }
// Implementation private void GetFrame(MediaFrame frame, FFmpeg.AutoGen.AVMediaType mType) { ConcurrentQueue <MediaFrame> curQueue = null; int curMaxSize = 0; bool mTypeIsRunning = false; // CHOOSE QUEUE switch (mType) { case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_AUDIO: curQueue = aFrames; curMaxSize = AUDIO_MAX_QUEUE_SIZE; mTypeIsRunning = decoder.isAudioRunning; break; case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_VIDEO: curQueue = vFrames; curMaxSize = VIDEO_MAX_QUEUE_SIZE; mTypeIsRunning = decoder.isVideoRunning; break; case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_SUBTITLE: curQueue = sFrames; curMaxSize = SUBS_MAX_QUEUE_SIZE; mTypeIsRunning = decoder.isSubsRunning; break; } if (curQueue == null) { return; } // IF MAX SLEEP UNTIL 3/4 OF QUEUE LEFT if (curQueue.Count == curMaxSize) { int escapeInfinity = 0; int sleepMs = (int)((decoder.vStreamInfo.frameAvgTicks / 10000) * (curMaxSize * (1.0 / 4.0))); if (sleepMs > 5000) { sleepMs = 5000; } if (mType == FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_SUBTITLE) { sleepMs *= 10; } while (mTypeIsRunning && curQueue.Count > (curMaxSize * (3.0 / 4.0))) { Thread.Sleep(sleepMs); escapeInfinity++; if (escapeInfinity > 1000) { Log($"[ERROR EI1] {mType} Frames Queue is full ... [{curQueue.Count}/{curMaxSize}]"); decoder.Stop(); return; } mTypeIsRunning = false; if (mType == FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_AUDIO) { mTypeIsRunning = decoder.isAudioRunning; } else if (mType == FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_VIDEO) { mTypeIsRunning = decoder.isVideoRunning; } else if (mType == FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_SUBTITLE) { mTypeIsRunning = decoder.isSubsRunning; } } } if (!mTypeIsRunning && (mType != FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_VIDEO && status != Status.SEEKING)) { return; } // FILL QUEUE | Queue possible not thread-safe try { switch (mType) { case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_AUDIO: lock (aFrames) curQueue.Enqueue(frame); break; case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_VIDEO: lock (vFrames) curQueue.Enqueue(frame); break; case FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_SUBTITLE: lock (sFrames) curQueue.Enqueue(frame); break; } } catch (Exception e) { Log("Error[" + (-1).ToString("D4") + "], Func: GetFrame(), Msg: " + e.StackTrace); } }