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

📄 pe_consumer_dvd.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        pcDemux->DetachOutputStream(m_pBypassStream);

        /* detach the input stream from the demux */
        DBGPRINT(DBG_ON(DBG_TRACE), ("DeletePSDemux: detach the input stream from the demux\n"));
        pcDemux->DetachInputStream();

        /* now it is safe to delete the demux */
        DBGPRINT(DBG_ON(DBG_TRACE), ("DeletePSDemux: Tell demux to delete\n"));
        if (pcDemux->Delete() != DEMUX_PASS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("%s: cDemux::Delete FAILED!\n", __FUNCTION__));
        }

        if (m_semPSDemxMsgSync != 0)
        {
            OS_SemDelete(m_semPSDemxMsgSync);
            m_semPSDemxMsgSync = 0;
        }

        if (m_semNavPackState != 0)
        {
            OS_SemDelete(m_semNavPackState);
            m_semNavPackState = 0;
        }

        DBGPRINT(DBG_ON(DBG_TRACE), ("DeletePSDemux: delete the demux class\n"));
        delete pcDemux;
        pcDemux = NULL;
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("DeletePSDemux: Finished\n"));

    return (PE_SUCCESS);
}

/**
 * Private function that creates any required cStreams.
 *
 * @param None
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::CreateStreams(void)
{
    /* Create the subpic decoder input stream */
    m_pSPUStream       = new cStream;
    m_pSPUStreamBuffer = OS_MemAlloc(sizeof(cSPUStreamMessage) * SUBPIC_NUM_MESSAGES);
    if ((NULL == m_pSPUStream) || (NULL == m_pSPUStreamBuffer))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("CreateStreams: Could not create subpic cStream\n"));
        goto error_out;
    }

    /* Create a stream for receiving nav packs from the PSDemux */
    m_pNvPckStream       = new cStream;
    m_pNvPckStreamBuffer = OS_MemAlloc(sizeof(DEMUXOUTPUTMESSAGE) * NVPACK_NUM_MESSAGES);
    if ( (m_pNvPckStream == NULL) || (m_pNvPckStreamBuffer == NULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("CreateStreams: Could not create navpack cStream\n"));
        goto error_out;
    }

    /* Create the stream for feeding decode playback */
    m_pBypassStream       = (cStream*) new cStream;
    m_pBypassStreamBuffer = OS_MemAlloc(sizeof(DEMUXOUTPUTMESSAGE) * BYPASS_NUM_MESSAGES);
    if ( (m_pBypassStream == NULL) || (m_pBypassStreamBuffer == NULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("CreateStreams: Could not create bypass cStream\n"));
        goto error_out;
    }

    /* create the input stream for the PSDemux */
    m_pDemuxInStream     = new DEMUXIOSTREAM;
    m_pDemuxStreamBuffer = OS_MemAlloc(sizeof(DEMUXINPUTMESSAGE) * INPUT_STREAM_DEPTH);
    if ((m_pDemuxInStream == NULL) || (m_pDemuxStreamBuffer == NULL))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("CreateStreams: Could not create PSDemux cStream\n"));
        goto error_out;
    }

    /* Initialize the new streams */
    m_pSPUStream->Initialize(m_pSPUStreamBuffer, SUBPIC_NUM_MESSAGES, sizeof(cSPUStreamMessage), "SPUStream");
    m_pNvPckStream->Initialize(m_pNvPckStreamBuffer, NVPACK_NUM_MESSAGES, sizeof(DEMUXOUTPUTMESSAGE), "NvPckStream");
    m_pBypassStream->Initialize(m_pBypassStreamBuffer, BYPASS_NUM_MESSAGES, sizeof(DEMUXOUTPUTMESSAGE), "BypassStream");
    m_pDemuxInStream->Initialize(m_pDemuxStreamBuffer, INPUT_STREAM_DEPTH, sizeof(DEMUXINPUTMESSAGE), "DemuxStream");

    return (PE_SUCCESS);

error_out:

    DeleteStreams();
    return (PE_FAILURE);
}

/**
 * Private function that deletes cStreams created by CreateStreams().
 *
 * @param None
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::DeleteStreams(void)
{
    /* Delete the PSDemux stream */
    if (NULL != m_pDemuxInStream)
    {
        DEMUXINPUTMESSAGE *message;
        while (1)
        {
            message = (DEMUXINPUTMESSAGE*)m_pDemuxInStream->Read(OS_NO_WAIT);
            if (message == NULL)
            {
                break;
            }
            if (NULL != message->payload)
            {
                delete(message->payload);
                message->payload = NULL;
            }
        }
        m_pDemuxInStream->Destroy();
        delete (m_pDemuxInStream);
        m_pDemuxInStream = NULL;
    }
    if (NULL != m_pDemuxStreamBuffer)
    {
        OS_MemFree(m_pDemuxStreamBuffer);
        m_pDemuxStreamBuffer = NULL;
    }

    /* Delete the bypass stream */
    if (NULL != m_pBypassStream)
    {
        DEMUXOUTPUTMESSAGE *message;
        while (1)
        {
            message = (DEMUXOUTPUTMESSAGE*)m_pBypassStream->Read(OS_NO_WAIT);
            if (message == NULL)
            {
                break;
            }
            if (NULL != message->payload)
            {
                delete(message->payload);
                message->payload = NULL;
            }
        }
        m_pBypassStream->Destroy();
        delete (m_pBypassStream);
        m_pBypassStream = NULL;
    }
    if (NULL != m_pBypassStreamBuffer)
    {
        OS_MemFree(m_pBypassStreamBuffer);
        m_pBypassStreamBuffer = NULL;
    }

    /* delete navpack stream */
    if (NULL != m_pNvPckStream)
    {
        DEMUXOUTPUTMESSAGE *message;
        while (1)
        {
            message = (DEMUXOUTPUTMESSAGE*)m_pNvPckStream->Read(OS_NO_WAIT);
            if (message == NULL)
            {
                break;
            }
            if (NULL != message->payload)
            {
                delete(message->payload);
                message->payload = NULL;
            }
        }
        m_pNvPckStream->Destroy();
        delete m_pNvPckStream;
        m_pNvPckStream = NULL;
    }
    if (NULL != m_pNvPckStreamBuffer)
    {
        OS_MemFree(m_pNvPckStreamBuffer);
        m_pNvPckStreamBuffer = NULL;
    }

    /* delete SPU stream */
    if (NULL != m_pSPUStream)
    {
        DEMUXOUTPUTMESSAGE *message;
        while (1)
        {
            message = (DEMUXOUTPUTMESSAGE*)m_pSPUStream->Read(OS_NO_WAIT);
            if (message == NULL)
            {
                break;
            }
            if (NULL != message->payload)
            {
                delete(message->payload);
                message->payload = NULL;
            }
        }
        m_pSPUStream->Destroy();
        delete m_pSPUStream;
        m_pSPUStream = NULL;
    }
    if (NULL != m_pSPUStreamBuffer)
    {
        OS_MemFree(m_pSPUStreamBuffer);
        m_pSPUStreamBuffer = NULL;
    }

    return (PE_SUCCESS);
}

/**
 * DemuxAddSubpicPS
 *
 * @param LONG lPID
 * @param LONG lSubID
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::DemuxAddSubpicPS(LONG lPesID, LONG lSubID, PVOID pDecoder)
{
    PE_STATUS status = PE_SUCCESS;
    ULONG ulSPDStatus;

    if (pDecoder == NULL)
    {
        return (PE_NULL_POINTER);
    }

    /* If we are already demuxing a subpic first cancel the old one */
    if (m_spu_decoder != NULL)
    {
        /* the decoder should not change */
        DbgAssert(m_spu_decoder == pDecoder);

        if (m_spu_pesID != -1)
        {
            /* Remove the current subpic demux */
            pcDemux->DetachOutputStream(m_pSPUStream);
        }
    }
    else
    {
        /* store pointer to the spu decoder */
        m_spu_decoder = pDecoder;
    }

    /* if the decoder hasn't been configured do it now */
    SPUGetStatus(m_spu_decoder, &ulSPDStatus);
    if ((ulSPDStatus & SPU_STATE_MASK) < SPU_STATE_REALIZED)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_DVD::DemuxAddSubpicPS - Configure SPU Decoder\n"));

        /* attach the input stream */
        if (SPUAttachInputStream(m_spu_decoder, m_pSPUStream) != SPU_SUCCESS)
        {
            DbgPrint(("SPDecoderAttachInputStream FAILED!\n"));
        }

        /* attach the spu sync callback */
        if (SPUAttachSyncCallback(m_spu_decoder, peConsumerDVDSubpicSyncCallback, this) != SPU_SUCCESS)
        {
            DbgPrint(("SPDecoderAttachSyncCallback FAILED!\n"));
        }
    }

    /* if a SPU flush is in progress wait for it to complete */
    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;
        }
    }

    /* if consumer state is running, but the SPU is stopped then start it now */
    if (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == TRUE)
    {
        SPUGetStatus(m_spu_decoder, &ulSPDStatus);
        if ((ulSPDStatus & SPU_STATE_MASK) != SPU_STATE_RUN)
        {
            /* start the subpic decoder */
            SPUStart(m_spu_decoder);
        }
    }

    /* configure ps demux */
    if (pcDemux->AttachOutputStream( (BYTE)(lPesID), (BYTE)(lSubID), DEMUX_ANY, UNDEFINED, m_pSPUStream) != DEMUX_PASS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer_DVD::DemuxAddSubpicPS - Could not add SUBPIC Demux\n"));
        status = PE_FAILURE;
    }

    /* reset spu pointer */
    m_spu_pesID = lPesID;
    m_spu_subID = lSubID;

    return (status);
}

/**
 * DemuxRemoveSubpicPS
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::DemuxRemoveSubpicPS(void)
{
    if (m_spu_decoder != NULL)
    {
        ULONG ulSPDStatus = 0;

        SPUGetStatus(m_spu_decoder, &ulSPDStatus);
        if ((ulSPDStatus & SPU_STATE_MASK) == SPU_STATE_STOPPED)
        {
            /* Remove the subpic demux */
            m_spu_pesID   = -1;
            m_spu_subID   = -1;

            /* remove the subpic stream from the decoder */
            pcDemux->DetachOutputStream(m_pSPUStream);

            /* flush sub pic decoder, this is necessary to prevent highlights
               from reappearing when the next highlight enable goes to the SPU */
            SPUFlush(m_spu_decoder);

            return PE_SUCCESS;
        }

        SPUStop(m_spu_decoder);

        /* Remove the subpic demux */
        pcDemux->DetachOutputStream(m_pSPUStream);

        /* flush sub pic decoder */
        SPUFlush(m_spu_decoder);

        /* wait for the subpic decoder to finish stopping */
        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;
            }
        }
    }

    /* reset spu pointer
     * TODO: can't do this because it prevents the spu from being cleaned up properly
     * when we delete the dvd consumer. I need to study this and figure out a better
     * solution. This patch is a temp solution, but will not work for hd-dvd since it
     * has multiple consumers. */
//    m_spu_decoder = NULL;
    m_spu_pesID   = -1;
    m_spu_subID   = -1;

    return (PE_SUCCESS);
}

/**
 * Return status of SPU demux for this consumer
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_DVD::DemuxGetSubpicPS(LONG *plPesID, LONG *plSubID, BOOLEAN *pfIsActive)
{
    /* the decoder handle is null if we are not actively demuxing */
    if ( (m_spu_decoder != NULL) && (m_spu_pesID != -1) )
    {
        *pfIsActive = TRUE;
        *plPesID    = m_spu_pesID;
        *plSubID    = m_spu_subID;
    }
    else
    {
        *pfIsActive = FALSE;
        *plPesID    = m_spu_pesID;
        *plSubID    = m_spu_subID;
    }

    return (PE_SUCCESS);
}

⌨️ 快捷键说明

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