예제 #1
0
파일: kernel.cpp 프로젝트: andemi02/orkid
CSystem::CSystem()
	: NoRttiSingleton< CSystem >()
{
#if defined( NITRO )
	OS_InitTick();
#endif

	miCalibCounter = 0;
	miBaseCycle = GetClockCycle();
	mfWallClockBaseTime = GetHiResTime();

}
예제 #2
0
bool FFmpegDecoder::handleVideoPacket(
    const AVPacket& packet,
    double& videoClock,
    VideoParseContext& context)
{
    enum { MAX_SKIPPED = 4 };
    const double MAX_DELAY = 0.2;

    const int ret = avcodec_send_packet(m_videoCodecContext, &packet);
    if (ret < 0)
        return false;

    AVFramePtr videoFrame(av_frame_alloc());
    while (avcodec_receive_frame(m_videoCodecContext, videoFrame.get()) == 0)
    {
		const int64_t duration_stamp =
			videoFrame->best_effort_timestamp; //av_frame_get_best_effort_timestamp(m_videoFrame);

        // compute the exact PTS for the picture if it is omitted in the stream
        // pts1 is the dts of the pkt / pts of the frame
        if (duration_stamp != AV_NOPTS_VALUE)
        {
            videoClock = duration_stamp * av_q2d(m_videoStream->time_base);
        }
        const double pts = videoClock;

        // update video clock for next frame
        // for MPEG2, the frame can be repeated, so we update the clock accordingly
        const double frameDelay = av_q2d(m_videoCodecContext->time_base) *
            (1. + videoFrame->repeat_pict * 0.5);
        videoClock += frameDelay;

        boost::posix_time::time_duration td(boost::posix_time::pos_infin);
        bool inNextFrame = false;
        const bool haveVideoPackets = !m_videoPacketsQueue.empty();

        {
            boost::lock_guard<boost::mutex> locker(m_isPausedMutex);

            inNextFrame = m_isPaused && m_isVideoSeekingWhilePaused;
            if (!context.initialized || inNextFrame)
            {
                m_videoStartClock = (m_isPaused ? m_pauseTimer : GetHiResTime()) - pts;
            }

            // Skipping frames
            if (context.initialized && !inNextFrame && haveVideoPackets)
            {
                const double curTime = GetHiResTime();
                if (m_videoStartClock + pts <= curTime)
                {
                    if (m_videoStartClock + pts < curTime - MAX_DELAY)
                    {
                        InterlockedAdd(m_videoStartClock, MAX_DELAY);
                    }

                    if (++context.numSkipped > MAX_SKIPPED)
                    {
                        context.numSkipped = 0;
                    }
                    else
                    {
                        CHANNEL_LOG(ffmpeg_sync) << "Hard skip frame";

                        // pause
                        if (m_isPaused && !m_isVideoSeekingWhilePaused)
                        {
                            break;
                        }

                        continue;
                    }
                }
                else
                {
                    int speedNumerator, speedDenominator;
                    std::tie(speedNumerator, speedDenominator) = static_cast<const std::pair<int, int>&>(m_speedRational);
                    context.numSkipped = 0;
                    td = boost::posix_time::milliseconds(
                        int((m_videoStartClock + pts - curTime) * 1000.  * speedDenominator / speedNumerator) + 1);
                }
            }
        }

        context.initialized = true;

        {
            boost::unique_lock<boost::mutex> locker(m_videoFramesMutex);

            if (!m_videoFramesCV.timed_wait(locker, td, [this]
                {
                    return m_isPaused && !m_isVideoSeekingWhilePaused ||
                        m_videoFramesQueue.canPush();
                }))
            {
                continue;
            }
        }

        {
            boost::lock_guard<boost::mutex> locker(m_isPausedMutex);
            if (m_isPaused && !m_isVideoSeekingWhilePaused)
            {
                break;
            }

            m_isVideoSeekingWhilePaused = false;
        }

        if (inNextFrame)
        {
            m_isPausedCV.notify_all();
        }

        VideoFrame& current_frame = m_videoFramesQueue.back();
        handleDirect3dData(videoFrame.get());
        if (!frameToImage(current_frame, videoFrame, m_imageCovertContext, m_pixelFormat))
        {
            continue;
        }

        current_frame.m_pts = pts;
        current_frame.m_duration = duration_stamp;

        {
            boost::lock_guard<boost::mutex> locker(m_videoFramesMutex);
            m_videoFramesQueue.pushBack();
        }
        m_videoFramesCV.notify_all();
    }

    return true;
}