예제 #1
0
        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();
                }
            }
        }
예제 #2
0
        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();
                }
            }
        }