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

📄 pe_consumer_vcd.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2006 Videon Central, Inc.                                 **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/
/**
 * @file pe_consumer_vcd.cpp
 *
 * $Revision: 1.20 $ 
 *
 * PE Consumer VCD/SVCD Derived Class Definition
 * The PE Consumer moves data from an input stream to a decoder or demux.
 *
 */

#include <stdlib.h>
#include "decoder.h"
#include "vdvd_types.h"
#include "osapi.h"
#include "dbgprint.h"
#include "pe_app.h"
#include "pe_consumer.h"
#include "pe_consumer_vcd.h"


#define DEBUG_PE_CONSUMER_VCD DBG_ERROR
#define DBG_ON(x)             (DEBUG_PE_CONSUMER_VCD >= x)



/**
 * cPEConsumer_VCD::Configure
 *
 * @return PE_STATUS
 *
 */
PE_STATUS cPEConsumer_VCD::Configure(PE_CONSUMER_CONFIG_INFO *pConfigInfo)
{
    PE_STATUS status = PE_SUCCESS;

    if ( (m_streamType == STREAM_TYPE_MPEG1_SS) || (m_streamType == STREAM_TYPE_AUDIO) )
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer::Configure() - Ring buffer model\n"));

        /*
         * Config Ring buffer model
         */
        /*
         * Cleanup of all the created resources happen in the pe_consumer base class
         */
        if (m_ConsumerState != PE_CONSUMER_STATE_UNREALIZED)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer::Configure() - STATE ERROR\n"));
            return (PE_INVALID_STATE);
        }

        /* verify input */
        if (pConfigInfo == NULL)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer::Configure() - pConfigInfo NULL\n"));
            status = PE_NULL_POINTER;
            goto error_out;
        }

        /* These need intialized */
        m_fKillDataProc             = FALSE;
        m_fStillOn                  = FALSE;
        m_fPCM                      = FALSE;


        /* TODO-SDK - Configure the data channel. */

        /* update state */
        m_ConsumerState = PE_CONSUMER_STATE_REALIZING;
    }
    else
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer::Configure() - SG buffer model\n"));

        /*
         * Config for SG buffer model
         */
        status = cPEConsumer::Configure(pConfigInfo);
    }

    return (status);

  error_out :

    return (status);
}

/**
 * cPEConsumer_VCD::Reset
 *
 * @return PE_STATUS
 *
 */
PE_STATUS cPEConsumer_VCD::Reset(void)
{
    PE_STATUS status;

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Reset()\n"));

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

    /* @todo Examine what decode/channel stops need to be called and if teardown
     * of dataProc for this VCD consumer and its information should be done. */
    if ( (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == TRUE) && (m_fStop == FALSE) )
    {
        /* tell the consumer data task it should stop */
        m_fStop = TRUE;
        m_fAbort = TRUE;

        /* wait for transition to stopped state */
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Reset() - wait for transition to stopped (%d)\n", m_ConsumerInput));
        while (m_fStop == TRUE)
        {
            OS_TaskYield();
        }

        m_fAbort = FALSE;
    }

    /* use the base clase to terminate the consumer task */
    status = cPEConsumer::Reset();

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Reset() done\n"));

    return (status);

} /* end cPEConsumer_VCD::Reset() */


/**
 * DemuxAddVideoPS
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_VCD::DemuxAddVideoPS(LONG lPID, PE_ISTREAMCTRL_VIDEO_TYPE VideoType, LONG lExtID,
    PE_ISTREAMCTRL_VIDEO_EXT_TYPE ExtVideoType, Decoder* pDecoder)
{
    m_lPid = lPID;
    return ( cPEConsumer::DemuxAddVideoPS(lPID, VideoType, lExtID, ExtVideoType, pDecoder) );
}


/**
 * DemuxAddAudioPS
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer_VCD::DemuxAddAudioPS(LONG lPID, LONG lSubID, PE_ISTREAMCTRL_AUDIO_TYPE AudioType,
    PE_ISTREAMCTRL_AUDIO_ATTRIBUTES *pAttributes, Decoder* pDecoder)
{
    if (AudioType == AUDIO_TYPE_PCM)
    {
        m_fPCM = TRUE;
        return (PE_SUCCESS);
    }
    else
    {
        m_fPCM = FALSE;
        return ( cPEConsumer::DemuxAddAudioPS(lPID, lSubID, AudioType, pAttributes, pDecoder) );
    }
}


/**
 * DemuxRemoveAudioPS
 *
 * @return PE_STATUS
 *
 */
PE_STATUS cPEConsumer_VCD::DemuxRemoveAudioPS(void)
{
    if (m_fPCM == TRUE)
    {
        m_fPCM = FALSE;
        return (PE_SUCCESS);
    }
    else
    {
        return ( cPEConsumer::DemuxRemoveAudioPS() );
    }
}


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

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Run()\n"));

    if (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == FALSE)
    {
        if (INPUT_MAIN == m_ConsumerInput)
        {
            if (m_fPCM)
            {
                if (m_audioDecode[0] != NULL)
                {
                    DECODER_SETTINGS_TYPE settings;

                    settings.streamType = DECODER_STREAM_TYPE_PCM;
                    settings.pcm.bits_per_sample = 16;
                    settings.pcm.sample_rate = 44100;
                    settings.pcm.channels = 2;


                    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Run - pcm decoder setup\n"));

                    error = m_audioDecode[0]->Setup(&settings);
                    if (VDVD_IS_ERROR(error))
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer_VCD::Run - pcm decoder setup FAILED!\n"));
                    }
                }
            }
            else if (m_videoDecode[0] != NULL)
            {
                DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Run() - decode setup\n"));

                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_VCD::Run() - decode setup FAILED!\n"));
                    status = PE_FAILURE;
                }
            }
        }
    }

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

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Run() - DONE\n"));
    return (status);

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

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

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Stop() - input = %d\n", m_ConsumerInput));

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

    /* @todo Examine what decode/channel stops need to be called and if teardown
     * of dataProc for this VCD consumer and its information should be done. */

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

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

        /* TODO-SDK - Wait for payloads to be consumed by the decoder. */

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

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

        /* stop the decoder */
        if (m_fPCM == TRUE)
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Stop() - pcm decoder stop\n"));
            if (m_audioDecode[0] != NULL)
            {   
                error = m_audioDecode[0]->Stop(FALSE);
            }
        }
        else
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Stop() - decoder stop\n"));
            if (INPUT_MAIN == m_ConsumerInput)
            {
                if (m_videoDecode[0] != NULL)
                {
                    error = m_videoDecode[0]->Stop(fHoldPicture);
                }
            }
        }

        m_fAbort = FALSE;
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer_VCD::Stop() - DONE (%d)\n", m_ConsumerInput));
    return (PE_SUCCESS);

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

/**
 * If active start consuming and presenting AV data.
 *
 * @return PE_STATUS
 *
 */
PE_STATUS cPEConsumer_VCD::Flush(void)
{
    DBGPRINT(DBG_ON(DBG_VERBOSE), ("cPEConsumer_VCD::Flush\n" ));
    return (PE_NOT_IMPLEMENTED);

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



PE_STATUS cPEConsumer_VCD::ProcessEndOfStream(PVOID StreamContext)
{
    PE_END_OF_STREAM_EVENT_INFO info;
    PE_STATUS event_status;

    /* fill in the event info */
    info.pContext = StreamContext;
    info.input    = m_ConsumerInput;

     /* TODO-SDK - Wait until outstanding payloads are released */

    /* send the event */
    DBGPRINT(DBG_ON(DBG_TRACE), ("ProcessEndOfStream: PE_EVENT_END_OF_STREAM\n"));
    event_status = SendEvent(PE_EVENT_END_OF_STREAM, &info);

    /* check status returned from event handler */
    if (m_fPCM == FALSE)
    {
        if ( (event_status & PE_EVNT_VCD_PUSH) == PE_EVNT_VCD_PUSH)
        {
            /* Push out the last frame (vcd never has a seamless connection) */
            DBGPRINT(DBG_ON(DBG_TRACE), ("ProcessEndOfStream: ForceLastPictureDecode\n"));
            ForceLastPictureDecode();
        }
    }

    return (event_status);
}

/**
 * If active start consuming and presenting AV data.
 *
 * @return PE_STATUS
 *
 */
PE_STATUS cPEConsumer_VCD::processData(PEINPUTMESSAGE *pInMessage)
{
    VDVD_ERROR          error         = VDVD_SUCCESS;
    PE_STATUS           pe_status     = PE_SUCCESS;
    ULONG               currentPosition;
    DECODE_STATUS_TYPE  d_status;

    /* get the current position, adjust for buffering, and send */
    currentPosition = pInMessage->payload->get_user_data();
    if (!m_fPCM)
    {
        if (m_videoDecode[0] != NULL)
        {
            /* TODO-SDK - Get the current amount of data in the channel so that the display time can be adjusted. */
            error = m_videoDecode[0]->GetStatus(&d_status);
            if ( VDVD_IS_ERROR(error))
            {
                currentPosition -= (d_status.video_fifo_depth / CD_MODE2_FORM2_USER_DATA);
            }
        }
    }
    SendEvent(PE_EVENT_POSITION, &currentPosition);

    /* send autopause message */
    if (pInMessage->AutoPause)
    {
        SendEvent(PE_EVENT_AUTO_PAUSE, NULL);
    }

    /* send the payload to the appropriate place */
    if (m_fPCM == TRUE)
    {
        /* CDDA Track */
        pe_status = SendPayloadToDecoder(m_audioDecode[0], pInMessage->payload);
    }
    else
    {
        pe_status = SendPayloadToDecoder(m_videoDecode[0], pInMessage->payload);
    }

    if (m_fPCM == FALSE)
    {
        if ((0xE0 + pInMessage->SequenceEnd - 1) == m_lPid)
        {
            /* Push out the frames whenever a sequenceEnd is received */
            DBGPRINT(DBG_ON(DBG_TRACE),("processData: ForceLastPictureDecode\n "));
            ForceLastPictureDecode();
        }
    }

    return (pe_status);

} /* end cPEConsumer_VCD::processData() */

⌨️ 快捷键说明

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