⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pe_consumer_dvd.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

/**
 * If active start consuming and presenting AV data.  Wakes up dataProc.
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::Run(void)
{
    VDVD_ERROR  error   = VDVD_SUCCESS;
    PE_STATUS   status  = PE_SUCCESS;

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Run (%d)\n", m_ConsumerInput));

    if (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == FALSE)
    {
        m_fFirstPlay = TRUE;

        /* start the PSDemux */
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Run - start the PSDemux (%d)\n", m_ConsumerInput));
        pcDemux->Start();

        /* start the subpic decoder */
        if (m_spu_decoder != NULL)
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Run - start the subpic decoder (%d)\n", m_ConsumerInput));
            SPUStart(m_spu_decoder);
        }

        /* start the decoder */
        if (m_videoDecode[0] != NULL)
        {
            /* TODO-SDK - Configure and start the primary decoder */

            DECODER_SETTINGS_TYPE settings;
            settings.streamType = DECODER_STREAM_TYPE_MPEG2;

            error = m_videoDecode[0]->Setup(&settings);
            if (VDVD_IS_ERROR(error))
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer_DVD::Run() - decode setup FAILED! (%d)\n", m_ConsumerInput));
                status = PE_FAILURE;
            }

            /* if we are in I-Frame trick mode this causes a problem so skip it */
            if (m_playrate.discontiguous == FALSE)
            {
                // setup a/v sync
            }
            else
            {
                /* SKD TODO: Mute CC during any trickplay*/
            }

        }
        if (m_videoDecode[1] != NULL)
        {
            /* TODO-SDK - Configure and start the secondary decoder */
            DECODER_SETTINGS_TYPE settings;
            settings.streamType = DECODER_STREAM_TYPE_MPEG2;
            error = m_videoDecode[1]->Setup(&settings);
            if (VDVD_IS_ERROR(error))
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer_DVD::Run() - decode setup FAILED! (%d)\n", m_ConsumerInput));
                status = PE_FAILURE;
            }

            /* if we are in I-Frame trick mode this causes a problem so skip it */
            if (m_playrate.discontiguous == FALSE)
            {
                // setup a/v sync
            }
            else
            {
                /* SDK: TODO: Mute CC during any trickplay*/
            }
        }
    }

    if (status == PE_SUCCESS)
    {
        /* update state info */
        m_fPrefill         = FALSE;
        m_fSuspend         = FALSE;
        m_fStillOn         = FALSE;
        m_fPauseAfterVOBU  = FALSE;
        m_ConsumerState    = PE_CONSUMER_STATE_RUN;
        m_fWasPaused       = FALSE;
        m_SPULastNavPackTime = 0;
    }

    return (status);

} /* end cPEConsumer_DVD::Run() */

/**
 * If active start consuming and presenting AV data.
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::Stop(BOOLEAN fHoldPicture)
{
    VDVD_ERROR  error    = VDVD_SUCCESS;
    PE_STATUS   peStatus = PE_SUCCESS;

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop()\n"));

    /* clear prefill since we are going to stop state */
    m_fPrefill      = FALSE;
    m_fSuspend      = FALSE;
    m_fWasPaused    = FALSE;
    m_SPULastNavPackTime = 0;

    if ( (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == TRUE) && (m_fStop == FALSE) )
    {
        PEINPUTMESSAGE *pMessage   = NULL;
        ULONG          ulSPDStatus = 0;

        /* tell the consumer data task it should stop */
        m_fStop  = TRUE;
        m_fAbort = TRUE;

        /* flush nav packs */
        m_fFlushNavPacks = TRUE;
        m_fFlushPlayback = TRUE;

        /* kick the dataProc so it won't wait */
        pMessage = (PEINPUTMESSAGE*)m_InputStream->GetMsg(OS_NO_WAIT);
        if (pMessage != NULL)
        {
            m_InputStream->Write(pMessage);
        }


        /* stop the PSDemux */
        pcDemux->Stop();

        /* Stop the spu decoder
         * NOTE: disable forced subpics so the the current spu doesn't get displayed during the flush */
        if (m_spu_decoder != NULL)
        {
            ULONG ulSPDStatus;
            SPUGetStatus(m_spu_decoder, &ulSPDStatus);
            if ((ulSPDStatus & SPU_STATE_MASK) != SPU_STATE_STOPPED)
            {
                DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() stop spu decoder, pids %d %d\n", m_spu_pesID, m_spu_subID));
                SPUDisableForced(m_spu_decoder);
                SPUStop(m_spu_decoder);
            }
        }

        /* wait for transition to stopped state */
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - wait for transition to stopped state\n"));
        while (m_fStop == TRUE)
        {
            OS_TaskYield();
        }

        /* Make sure the playback task has stopped */
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - Make sure the playback task has stopped\n"));
        while (m_fFlushPlayback == TRUE)
        {
            OS_TaskYield();
        }
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - Make sure the navpack task has stopped\n"));
        while (m_fFlushNavPacks == TRUE)
        {
            OS_TaskYield();
        }

        /* stop the decoder */
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - stop the decoder\n"));
        if (m_videoDecode[0] != NULL)
        {
             /* TODO-SDK - Flush out the data channel and stop the primary decoder. */
            error = m_videoDecode[0]->Flush(DECODER_TYPE_AUDIO, DECODE_FLUSH_MODE_DISCARD);
            error = m_videoDecode[0]->Stop(fHoldPicture);
        }
        if (m_videoDecode[1] != NULL)
        {
            /* TODO-SDK - Flush out the data channel and stop the primary decoder. */
            error = m_videoDecode[1]->Flush(DECODER_TYPE_AUDIO, DECODE_FLUSH_MODE_DISCARD);
            error = m_videoDecode[1]->Stop(fHoldPicture);
        }

        /* TODO-SDK - wait until outstanding payloads are released */
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - wait until outstanding payloads are released\n"));

        /* make sure the SPU has stopped */
        if (m_spu_decoder != NULL)
        {
            /* if the subpic stop is still in progress wait for it to complete */
            SPUGetStatus(m_spu_decoder, &ulSPDStatus);
            while ((ulSPDStatus & SPU_STATE_MASK) == SPU_STATE_STOPPING)
            {
                OS_TaskDelayMsec(100);
                SPUGetStatus(m_spu_decoder, &ulSPDStatus);
                if (m_fKillDataProc == TRUE)
                {
                    break;
                }
            }

            /* restore Forced SPU display */
            SPUEnableForced(m_spu_decoder);
        }

        m_fAbort     = FALSE;
        m_fFirstPlay = TRUE;
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::Stop() - Exit\n"));

    return (PE_SUCCESS);

} /* end cPEConsumer_DVD::Stop() */

/**
 * Flush the decoder and all related streams.
 * Returns to the RUN state once completed.
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::Flush(void)
{
    VDVD_ERROR  error = VDVD_SUCCESS;

    DBGPRINT(DBG_ON(DBG_TRACE), (("cPEConsumer_DVD::Flush\n" )));

    if ( (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == TRUE) && (m_fStop == FALSE) )
    {
        PEINPUTMESSAGE *pMessage   = NULL;
        ULONG          ulSPDStatus = 0;

        /* tell the consumer data task it should stop */
        m_fStop  = TRUE;
        m_fAbort = TRUE;

        /* flush nav packs */
        m_fFlushNavPacks = TRUE;
        m_fFlushPlayback = TRUE;

        /* kick the dataProc so it won't wait */
        pMessage = (PEINPUTMESSAGE*)m_InputStream->GetMsg(OS_NO_WAIT);
        if (pMessage != NULL)
        {
            m_InputStream->Write(pMessage);
        }

        /* stop the PSDemux */
        pcDemux->Stop();

        /* Flush the spu decoder
         * NOTE: disable forced subpics so the the current spu doesn't get displayed during the flush */
        if (m_spu_decoder != NULL)
        {
            SPUDisableForced(m_spu_decoder);
            SPUFlush(m_spu_decoder);
        }

        /* wait for transition to stopped state */
        DBGPRINT(DBG_ON(DBG_TRACE), (("cPEConsumer_DVD::Flush() - wait for transition to stopped state\n" )));
        while (m_fStop == TRUE)
        {
            OS_TaskYield();
        }

        /* restart the PSDemux
         * We do this here because the call to Start will wait for the stop
         * to complete before restarting. This will make sure the demux has
         * consumed all data before we flush the decoder */
        pcDemux->Start();

        /* if the subpic flush is still in progress wait for it to complete */
        if (m_spu_decoder != NULL)
        {
            SPUGetStatus(m_spu_decoder, &ulSPDStatus);
            while ((ulSPDStatus & SPU_STATE_MASK) == SPU_STATE_FLUSHING)
            {
                OS_TaskDelayMsec(100);
                SPUGetStatus(m_spu_decoder, &ulSPDStatus);
                if (m_fKillDataProc == TRUE)
                {
                    break;
                }
            }

            /* restore SPU */
            SPUEnableForced(m_spu_decoder);
        }

        /* Make sure the playback/navpack task has stopped */
        while (m_fFlushPlayback == TRUE)
        {
            OS_TaskYield();
        }
        while (m_fFlushNavPacks == TRUE)
        {
            OS_TaskYield();
        }

        /* flush the decoder */
        if (m_videoDecode[0] != NULL)
        {
            /* TODO-SDK - Flush the decoder. */
            error = m_videoDecode[0]->Flush(DECODER_TYPE_VIDEO, DECODE_FLUSH_MODE_DISCARD);
            error = m_videoDecode[0]->Flush(DECODER_TYPE_AUDIO, DECODE_FLUSH_MODE_DISCARD);
        }
        if (m_videoDecode[1] != NULL)
        {
            /* TODO-SDK - Flush the decoder. */
            error = m_videoDecode[1]->Flush(DECODER_TYPE_VIDEO, DECODE_FLUSH_MODE_DISCARD);
            error = m_videoDecode[1]->Flush(DECODER_TYPE_AUDIO, DECODE_FLUSH_MODE_DISCARD);
        }

        /* TODO-SDK - wait until outstanding payloads are released */
    
        m_fAbort = FALSE;

        /* restore the run state */
        m_ConsumerState   = PE_CONSUMER_STATE_RUN;
        m_fPauseAfterVOBU = FALSE;
        m_fFirstPlay      = TRUE;
    }

    return (PE_SUCCESS);

} /* end cPEConsumer_DVD::Flush() */

/**
 * cPEConsumer_DVD::SetRate
 *
 * @param PE_ISTREAMCTRL_PLAYRATE *pPlayRate
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::SetRate(PE_ISTREAMCTRL_PLAYRATE *pPlayRate)
{
    PE_STATUS status;

    status = cPEConsumer::SetRate(pPlayRate);

    if (status == PE_SUCCESS)
    {
        if (pPlayRate->rate > PLAY_RATE_PAUSE)
        {
            m_fPauseAfterVOBU = FALSE;
        }
    }

    return (status);
}



/**
 * Handles trick mode changes for DVD
 *
 * @param rate - The new rate requested.
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::SetVideoDecodeRate(PE_ISTREAMCTRL_PLAYRATE *pPlayRate)
{
    PE_STATUS status = PE_SUCCESS;

    if (pPlayRate == NULL)
    {
        status = PE_FAILURE;
    }
    else
    {
        /* step is handled slightly differently than the rest of the trick modes - and especially for DVD */
        if ( (pPlayRate->rate == PLAY_RATE_STEP) && (pPlayRate->direction == PE_ISTREAMCTRL_DIRECTION_BACKWARD) &&
            ( (m_playrate.rate == PLAY_RATE_STEP) ) )
        {
            m_fPauseAfterVOBU = FALSE;
        }
        else
        {
            status = cPEConsumer::SetVideoDecodeRate(pPlayRate);
        }
    }

    return (status);
}


/**
 * Perform dvd specific processing of end of stream, then call
 * the base class consumer for additional processing.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -