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

📄 pe_consumer.cpp

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

/*****************************************************************************
******************************************************************************
**                                                                          **
**  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.cpp
 *
 * $Revision: 1.29 $ 
 *
 * PE Consumer Base 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"

#define DEBUG_PE_CONSUMER   DBG_ERROR
#define DBG_PROCTRACE       DBG_VERBOSE  /* set lower than DEBUG_PE_CONSUMER to trace the PE dataProc threads */
#define DBG_ON(x)           (DEBUG_PE_CONSUMER >= x)

#define PE_CONSUMER_PROC_PRIORITY       OS_TASK_NORMAL_PRIORITY
#define PE_CONSUMER_PROC_STACK_SIZE    (16 * 1024)

char *stream_name[] = { "main", "pg", "ig", "ts", (char *)0};


/**
 * cPEConsumer::Configure
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer::Configure(PE_CONSUMER_CONFIG_INFO *pConfigInfo)
{
    PE_STATUS status;

    if (m_ConsumerState != PE_CONSUMER_STATE_UNREALIZED)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer::Configure() - STATE ERROR"));
        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;

    /* Store the input that this consumer is responsible for */
    m_ConsumerInput = pConfigInfo->input;

    if (FALSE == pConfigInfo->fPlaybackStarted)
    {
        /* TODO-SDK - Setup data channel. */
    }

    /* update state */
    m_ConsumerState = PE_CONSUMER_STATE_REALIZING;

    return (PE_SUCCESS);

error_out:

    return (status);
}

/**
 * cPEConsumer::Reset
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer::Reset(void)
{
    VDVD_ERROR                  error       = VDVD_SUCCESS;
    PE_STATUS                   status      = PE_SUCCESS;
    PEINPUTMESSAGE              *pMessage   = NULL;

    if (m_ConsumerState == PE_CONSUMER_STATE_UNREALIZED)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer::Reset() - PE_INVALID_STATE (%d)\n", m_ConsumerState));
        return (PE_INVALID_STATE);
    }

    m_fKillDataProc = TRUE;
    m_fStop         = TRUE;
    m_fAbort        = TRUE;
    m_fSuspend      = FALSE;

    if (m_ConsumerState > PE_CONSUMER_STATE_REALIZING)
    { 
        /* 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);
        }

        /* kill the data task */
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer::Reset() - Killing the data task\n"));
        OS_TaskJoin(m_dataProcID);
        OS_TaskDelete(m_dataProcID);
        m_dataProcID = 0;
    }


    /* stop the decoder */
    if ( m_videoDecode[0] != NULL )
    {
        error = m_videoDecode[0]->Stop(FALSE);
        if ( VDVD_IS_ERROR(error) )
        {
            status = PE_FAILURE;
        }
    }

    if (m_videoDecode[1] != NULL)
    {
        error = m_videoDecode[1]->Stop(FALSE);
        if ( VDVD_IS_ERROR(error) )
        {
            status = PE_FAILURE;
        }
    }

    /* update the state */
    m_ConsumerState = PE_CONSUMER_STATE_UNREALIZED;

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer::Reset() - DONE\n"));

    return (status);

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

/**
 * AttachInputStream
 *
 * @param[in] cStream *pStream
 * @param[in] PE_ISTREAMCTRL_INPUT input
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer::AttachInputStream(cStream *pStream, PE_ISTREAMCTRL_INPUT input)
{
    char task_name[32];
    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer::AttachInputStream()\n"));

    DbgAssert(NULL != pStream);

    if (m_ConsumerState != PE_CONSUMER_STATE_REALIZING)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer::AttachInputStream - STATE ERROR, state=%d\n", m_ConsumerState));
        return (PE_INVALID_STATE);
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer::AttachInputStream - pStream = %lx, input = %lx\n", (long)pStream, (long)input));

    /* Intialize parameters */
    m_InputStream   = pStream;


    /* create the data task */
    snprintf(task_name, sizeof(task_name), "%s_%s", "dataProc", stream_name[m_ConsumerInput]);
    m_dataProcID = OS_TaskSpawnParam(task_name, PE_CONSUMER_PROC_PRIORITY, PE_CONSUMER_PROC_STACK_SIZE,
        peConsumerDataProcCaller, this, NULL);

    if (OS_FAILURE == m_dataProcID)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer::AttachInputStream - dataProc spawn failure\n"));
        m_dataProcID = 0;
        goto AttachInputStream_err_out;
    }

    /* update the state */
    m_ConsumerState = PE_CONSUMER_STATE_STOP;

    return (PE_SUCCESS);

AttachInputStream_err_out:

    m_fKillDataProc = TRUE;

    /* kill the data task */
    if (m_dataProcID != 0)
    {
        OS_TaskJoin(m_dataProcID);
        OS_TaskDelete(m_dataProcID);
        m_dataProcID = 0;
    }


    /* invalidate stream pointer */
    m_InputStream = NULL;

    return (PE_FAILURE);
}

/**
 * AttachEvent
 *
 * @param PE_CONSUMER_CALLBACK function
 * @param PVOID pContext
 *
 * @return PE_STATUS
 *
 * @remarks Only one event is ever attached and used.  It may be overwritten without notification.
 */
PE_STATUS cPEConsumer::AttachEvent(PE_CONSUMER_CALLBACK function, PVOID pContext)
{
    PE_STATUS status;

    if (function != NULL)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer::AttachEvent - function = %08x, pContext = %08x\n", (ULONG)function, (ULONG)pContext));
        peConsumerCallback        = function;
        peConsumerCallbackContext = pContext;
        status                    = PE_SUCCESS;
    }
    else
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("cPEConsumer::AttachEvent - tried to attach NULL callback\n"));
        status = PE_FAILURE;
    }

    return (status);

} /* end cPEConsumer::AttachEvent() */

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

    if (INPUT_MAIN == m_ConsumerInput)
    {
        status = SetVideoDecodeRate(pPlayRate);
        if (status == PE_SUCCESS)
        {
            /* update playrate */
            m_playrate = *pPlayRate;
        }
    }
    else
    {
        status = PE_NOT_IMPLEMENTED;
    }

    return (status);

} /* end cPEConsumer::SetRate() */


/**
 * Base class consumer Run implementation.
 * Does nothing more than initialize some variables.
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer::Run(void)
{
    /* the base class just updates the state info
     * a media specific consumer should override this version to add
     * real functionality. This base class version can still be used
     * by the derived class to update the state info */

    /* update state info */
    m_fPrefill               = FALSE;
    m_fSuspend               = FALSE;
    m_fStillOn               = FALSE;
    m_ConsumerState          = PE_CONSUMER_STATE_RUN;

    return (PE_SUCCESS);

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

/**
 * DemuxAddVideoPS
 *
 * @param lPID
 * @param VideoType
 * @param lExtID
 * @param ExtVideoType
 * @param pDecoder
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer::DemuxAddVideoPS(LONG lPID, PE_ISTREAMCTRL_VIDEO_TYPE VideoType, LONG lExtID,
    PE_ISTREAMCTRL_VIDEO_EXT_TYPE ExtVideoType, Decoder* pDecoder)
{
    VDVD_ERROR  error = VDVD_SUCCESS;
    PE_STATUS   status = PE_SUCCESS;

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer::DemuxAddVideoPS() - PID=%x, VideoType=%d\n", lPID, VideoType));

    /* validate state
     * NOTE: We don't support dynamic video configuration. You should stop the consumer if you
     * want to change video streams */
    if ( (m_ConsumerState == PE_CONSUMER_STATE_UNREALIZED) || (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == TRUE) )
    {
        status = PE_INVALID_STATE;
    }

    /* validate input */
    if (pDecoder == NULL)
    {
        status = PE_NULL_POINTER;
    }

    if (status == PE_SUCCESS)
    {
        DECODE_VIDEO_PARAMETERS video_params;

        /* Store main video decode handle */
        m_videoDecode[0] = pDecoder;

        /* TODO-SDK - Configure the demux and decoder for the attributes given in the params. */
        video_params.pid          = 0;
        video_params.stream_id    = lPID;
        video_params.substream_id = 0;
        video_params.extstream_id = 0;
        video_params.stc_offset   = 0;

       /* add demux to decoder */
        error = m_videoDecode[0]->SelectVideoStream(&video_params);
        if ( VDVD_IS_ERROR( error ))
        {
            m_videoDecode[0] = NULL;
            status           = PE_FAILURE;
        }
    }

    return (status);

} /* end cPEConsumer::DemuxAddVideoPS() */


/**
 * DemuxAddAudioPS
 *
 * @param lPID
 * @param lSubID
 * @param AudioType
 * @param pDecoder
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer::DemuxAddAudioPS(LONG lPID, LONG lSubID, PE_ISTREAMCTRL_AUDIO_TYPE AudioType, PE_ISTREAMCTRL_AUDIO_ATTRIBUTES *pAttributes, Decoder* pDecoder)
{
    VDVD_ERROR  error  = VDVD_SUCCESS;
    PE_STATUS   status = PE_SUCCESS;

    DBGPRINT(DBG_ON(DBG_TRACE), ("cPEConsumer::DemuxAddAudioPS() - id=%x, subid=%x, AudioType=%d\n",
        lPID, lSubID, AudioType));

    /* validate state */
    if (m_ConsumerState == PE_CONSUMER_STATE_UNREALIZED)
    {
        status = PE_INVALID_STATE;
    }

    /* validate input */
    if (pDecoder == NULL)
    {
        status = PE_NULL_POINTER;
    }

    if (status == PE_SUCCESS)
    {
        DECODE_AUDIO_PARAMETERS audio_params;

        /* Store main audio decode handle */
        m_audioDecode[0] = pDecoder;

        /* TODO-SDK - Setup the audio decoder and configure according to the attributes. */
        audio_params.pid            = 0;
        audio_params.stream_id      = lPID;
        audio_params.substream_id   = (lSubID == 0xff) ? 0 : lSubID;
        audio_params.extstream_id   = 0;
        audio_params.stc_offset     = 0;
        audio_params.downmix_enable = false;
        if (pAttributes != NULL)
        {
            /* config sampling freq and num channels */
            switch (pAttributes->sampling_frequency)
            {
                case AUDIO_SAMPLING_FREQUENCY_44_1_KHz:
                    audio_params.sample_rate = 44100;
                    break;

                default:
                case AUDIO_SAMPLING_FREQUENCY_INVALID:
                case AUDIO_SAMPLING_FREQUENCY_48_KHz:
                    audio_params.sample_rate = 48000;
                    break;

                case AUDIO_SAMPLING_FREQUENCY_96_KHz:
                    audio_params.sample_rate = 96000;
                    break;

                case AUDIO_SAMPLING_FREQUENCY_192_KHz:
                    audio_params.sample_rate = 192000;
                    break;
            }

            switch(pAttributes->n_channels)
            {
                case AUDIO_MONO:
                    audio_params.num_channels = 1;
                    break;

                case AUDIO_DUAL_MONO:
                case AUDIO_STEREO:
                    audio_params.num_channels = 2;
                    break;

                case AUDIO_3_CHANNELS:
                    audio_params.num_channels = 3;
                    break;

                case AUDIO_4_CHANNELS:
                    audio_params.num_channels = 4;
                    break;

                case AUDIO_5_CHANNELS:
                    audio_params.num_channels = 5;
                    break;

                case AUDIO_6_CHANNELS:
                    audio_params.num_channels = 6;
                    break;

                case AUDIO_7_CHANNELS:
                    audio_params.num_channels = 7;
                    break;

                case AUDIO_8_CHANNELS:
                    audio_params.num_channels = 8;
                    break;

                case AUDIO_MULTI_CHANNEL:            /* Blu-Ray audio_presentation_type 6  */
                case AUDIO_STEREO_PLUS_MULTI_EXT:    /* Blu-Ray audio_presentation_type 12 */
                case AUDIO_CHANNELS_INVALID:
                    audio_params.num_channels = 0;
                    break;
            }
        }
        else
        {
            /* the audio attributes were NULL */
            audio_params.sample_rate = 48000;
            audio_params.num_channels = 0;
        }

 
        audio_params.format       = AudioType;

        // if need to check if already running before changing streams use
        // if (IS_PECONSUMER_STATE_RUNNING(m_ConsumerState) == TRUE)

        error = m_audioDecode[0]->SelectAudioStream(&audio_params);
        if ( VDVD_IS_ERROR(error) )
        {
            m_audioDecode[0] = NULL;
            status           = PE_FAILURE;
        }
    }

    return (status);

} /* end cPEConsumer::DemuxAddAudioPS() */

/**
 * DemuxRemoveVideoPS
 *
 * @return PE_STATUS
 */
PE_STATUS cPEConsumer::DemuxRemoveVideoPS(void)
{
    if (m_ConsumerState == PE_CONSUMER_STATE_UNREALIZED)
    {
        return (PE_INVALID_STATE);
    }

    /* Invalidate video decoder */
    m_videoDecode[0] = NULL;

    return (PE_SUCCESS);

⌨️ 快捷键说明

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