void runThread() { Span <pollfd> pollHandles = stackalloc pollfd[4]; DecoderPoll.initHandles(pollHandles, device.file, audioQueue.emptyQueueHandle, seekEventHandle, shutdownEvent); eDecoderBits decoderBits; eAudioBits audio; bool seek, shutdown; while (true) { DecoderPoll.poll(pollHandles, out decoderBits, out audio, out seek, out shutdown); if (shutdown) { return; } if (seek) { if (!handleSeek()) { return; } continue; } if (audio.HasFlag(eAudioBits.FreeBuffer)) { dispatchAudio(); } if (decoderBits == eDecoderBits.None) { continue; } // Logger.logVerbose( "Video decoder poll result: {0}", decoderBits ); if (decoderBits.HasFlag(eDecoderBits.Event)) { dispatchEvents(); // Logger.logVerbose( "Dispatched an event" ); } if (decoderBits.hasDecodedBits()) { dispatchOutput(); } if (decoderBits.hasEncodedBits()) { dispatchInput(); } } }
bool waitForVideoFrame(TimeSpan timestamp) { timestamp = timestamp.floorToMicro(); Span <pollfd> pollHandles = stackalloc pollfd[4]; DecoderPoll.initHandles(pollHandles, device.file, audioQueue.emptyQueueHandle, seekEventHandle, shutdownEvent); eDecoderBits decoderBits; eAudioBits audio; bool seek, shutdown; while (true) { DecoderPoll.poll(pollHandles, out decoderBits, out audio, out seek, out shutdown); if (shutdown) { return(false); } if (seek) { throw new ApplicationException("Invalid state transition, seek request while still processing previous one."); } if (audio.HasFlag(eAudioBits.FreeBuffer)) { dispatchAudio(); } if (decoderBits == eDecoderBits.None) { continue; } // Logger.logVerbose( "Video decoder poll result: {0}", decoderBits ); if (decoderBits.HasFlag(eDecoderBits.Event)) { dispatchEvents(); } if (decoderBits.hasDecodedBits()) { Debug.Assert(decoded.anyKernelBuffer); DecodedBuffer buffer = decoded.dequeue(); if (buffer.timestamp != timestamp) { if (buffer.timestamp > timestamp) { throw new ApplicationException(@"There’s a bug somewhere in this library; time is kept in 64-bit integers and shouldn’t suffer from precision-related issues."); } // Logger.logVerbose( "DecoderThread.waitForVideoFrame got {0}, need {1}", buffer.timestamp, timestamp ); // Video starts from a keyframe, very likely need to decode + discard a few frames before getting the one we need. decoded.enqueue(buffer); } else { Logger.logVerbose("DecoderThread.waitForVideoFrame got the target {0}", buffer.timestamp); eventsSink.onFrameDecoded(buffer); return(true); } } if (decoderBits.hasEncodedBits()) { dispatchInput(); } } }