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

📄 cdemux.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2002 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 cDemux.cpp
 *
 * Software Demux source file.
 *
 * $Id: cDemux.cpp,v 1.27 2006/09/28 21:12:54 mspinnenweber Exp $
 */
#include <string.h>
#include "vdvd_types.h"
#include "osapi.h"
#include "cStream.h"
#include "cDemux.h"
#include "mpeg_demux.h"
#include "dbgprint.h"
#ifdef __DEMUX_TS_SUPPORT__
#include "mpeg_tsdemux.h"
#endif
#ifdef __DEMUX_MP3_SUPPORT__
#include "mp3_demux.h"
#endif
#ifdef DMALLOC
#include "dmalloc.h"
#endif

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

/*****************************************************************************
******************************************************************************
**                                                                          **
**  Private variables                                                       **
**                                                                          **
******************************************************************************
*****************************************************************************/

/*****************************************************************************
******************************************************************************
**                                                                          **
**  Public variables                                                        **
**                                                                          **
******************************************************************************
*****************************************************************************/

/*****************************************************************************
******************************************************************************
**                                                                          **
**  Private functions                                                       **
**                                                                          **
******************************************************************************
*****************************************************************************/

/*****************************************************************************
******************************************************************************
**                                                                          **
**  Public functions                                                        **
**                                                                          **
******************************************************************************
*****************************************************************************/

/*****************************************************************************
******************************************************************************
**                                                                          **
**  Demux Class Member Definitions (Public functions)                       **
**                                                                          **
******************************************************************************
*****************************************************************************/

/**
 * Demux constructor.
 *
 * @param
 *    None.
 *
 * @retval
 *    None.
 *
 * @remark
 *    None.
 *
 * @verified
 *    Yes.
 */
cDemux::cDemux(void)
{
    int i;

    /* Initialize the Demux state */
    tDemuxConfigInfo.ulDemuxState  = DEMUX_STOPPED;
    tCurrentType = DEMUX_NONE;

    /* Initialize the Demux thread ID */
    iDemuxThreadID = 0;

    /* Reset the input pin data */
    tDemuxConfigInfo.tInputPin = NULL;

    /* Reset the output pin data */
    tDemuxConfigInfo.fUpdateOutputPins = TRUE;
    tDemuxConfigInfo.iOutputPinCount = 0;
    for( i = 0; i < OUTPUT_STREAM_MAX_COUNT; i++ )
    {
        tDemuxConfigInfo.tOutputPin[i].bPesID      = 0x00;
        tDemuxConfigInfo.tOutputPin[i].bSubID      = NO_SUB_ID;
        tDemuxConfigInfo.tOutputPin[i].tTimeType   = DEMUX_ANY;
        tDemuxConfigInfo.tOutputPin[i].tStreamType = UNDEFINED;
        tDemuxConfigInfo.tOutputPin[i].pDestStream = NULL;

#ifdef __DEMUX_TS_SUPPORT__
        tDemuxConfigInfo.tOutputPin[i].wPID        = (SHORT)(INVALID_PID);
#endif
    }

} /* end cDemux::cDemux() */

/**
 * Demux destructor. Basically does nothing.
 *
 * @param
 *    None.
 *
 * @retval
 *    None.
 *
 * @remark
 *    None.
 *
 * @verified
 *    Yes.
 */
cDemux::~cDemux(void)
{
    /* Stop and remove our worker task */
    tDemuxConfigInfo.ulDemuxState = DEMUX_DELETE;
    if (iDemuxThreadID != 0)
    {
        OS_TaskDelete(iDemuxThreadID);
        iDemuxThreadID = 0;
    }

} /* end cDemux::~cDemux() */

/**
 * Create function. Spawns the appropriate Demux task. A name must be supplied
 * to this function because there can be more than one Demux running at any
 * one time. It is up to the application to make sure it does not give two
 * Demux tasks the same name.
 *
 * @param
 *    char *strDemuxName - Names the Demux task
 *
 * @param
 *    BOOLEAN fStreamType - Selects MPEG1 or MPEG2 as the stream to Demux
 *
 * @retval
 *    DEMUX_PASS - if successful
 *    DEMUX_FAIL - if not successful
 *
 * @remark
 *    Recall that threads in eCos must be explicitly started after creation.
 *
 * @verified
 *    Yes.
 */
BOOLEAN cDemux::Create( char *strDemuxName, DEMUX_STREAM_TYPE tStreamType )
{
    int priority = OS_TASK_NORMAL_PRIORITY;

    /* Make sure a Demux thread has not already been created */
    if (iDemuxThreadID != 0)
    {
        return (DEMUX_FAIL);
    }

    /* create semaphores */
    tDemuxConfigInfo.semPinUpdate = OS_SemBCreateNamed(OS_SEM_Q_FIFO, OS_SEM_FULL, "DmxUpdatePin");
    if (tDemuxConfigInfo.semPinUpdate == 0)
    {
        return (DEMUX_FAIL);
    }
    tDemuxConfigInfo.semPinSync = OS_SemCCreateNamed(OS_SEM_Q_FIFO, 0, "DmxSyncPin");
    if (tDemuxConfigInfo.semPinSync == 0)
    {
        OS_SemDelete(tDemuxConfigInfo.semPinUpdate);
        tDemuxConfigInfo.semPinUpdate = 0;
        return (DEMUX_FAIL);
    }

#if ENABLE_DEMUX_REMAP_FEATURE
    /* Initialize the demux remap parameters */
    tDemuxConfigInfo.semRemapUpdate = OS_SemCCreateNamed(OS_SEM_Q_FIFO, OS_SEM_FULL, "DmxRemapUpdate");
    if (tDemuxConfigInfo.semRemapUpdate == 0)
    {
        OS_SemDelete(tDemuxConfigInfo.semPinUpdate);
        OS_SemDelete(tDemuxConfigInfo.semPinSync);
        tDemuxConfigInfo.semPinUpdate = 0;
        tDemuxConfigInfo.semPinSync = 0;
        return (DEMUX_FAIL);
    }
    else
    {
        tDemuxConfigInfo.fUpdateRemap = FALSE;
        tDemuxConfigInfo.bRemapStreamID = 0xFF;
        tDemuxConfigInfo.bRemapSubStreamID = 0xFF;
        tDemuxConfigInfo.bRemapStreamIDValue = 0xFF;
        tDemuxConfigInfo.bRemapSubStreamIDValue = 0xFF;
    }
#endif

    /* Create the appropriate Demux thread */
    switch (tStreamType)
    {
    case DEMUX_MPEG1:
        tCurrentType = DEMUX_MPEG1;
        iDemuxThreadID = OS_TaskSpawnParam(strDemuxName, priority, DEMUX_STACK_SIZE,
            MPEG1DemuxThreadProc, (PVOID)&tDemuxConfigInfo, NULL );
        break;

#ifdef __DEMUX_TS_SUPPORT__
    case DEMUX_TRANSPORT:
        tCurrentType = DEMUX_TRANSPORT;
        iDemuxThreadID = OS_TaskSpawnParam(strDemuxName, priority, DEMUX_STACK_SIZE,
            MPEG2TSDemuxThreadProc, (PVOID)&tDemuxConfigInfo, NULL);
        break;
#endif

#ifdef __DEMUX_MP3_SUPPORT__
    case DEMUX_MP3:
        tCurrentType = DEMUX_MP3;
        iDemuxThreadID = OS_TaskSpawnParam(strDemuxName, priority, DEMUX_STACK_SIZE,
            MP3DemuxThreadProc, (PVOID)&tDemuxConfigInfo, NULL);
        break;
#endif

    case DEMUX_MPEG2:
    default:
        tCurrentType = DEMUX_MPEG2;
        iDemuxThreadID = OS_TaskSpawnParam(strDemuxName, priority, DEMUX_STACK_SIZE,
            MPEG2DemuxThreadProc, (PVOID)&tDemuxConfigInfo, NULL);
        break;
    }

    /* Make sure the thread was started successfully */
    if (iDemuxThreadID == OS_FAILURE)
    {
        DbgPrint(("ERROR: Could not create Demux thread!\n"));
        OS_SemDelete(tDemuxConfigInfo.semPinUpdate);
        OS_SemDelete(tDemuxConfigInfo.semPinSync);
        tDemuxConfigInfo.semPinUpdate = 0;
        tDemuxConfigInfo.semPinSync   = 0;
        iDemuxThreadID = 0;
        return DEMUX_FAIL;
    }

    /* The Demux thread was created in the stopped state (See above remark) */
    tDemuxConfigInfo.ulDemuxState = DEMUX_STOPPED;

    /* Return successfully */
    return DEMUX_PASS;
}

/**
 * Delete function. Kills the Demux task. Do any necessary cleanup here!
 *
 * @param
 *    None.
 *
 * @retval
 *    DEMUX_PASS - if successful
 *    DEMUX_FAIL - if not successful
 *
 * @remark
 *    This function still needs some clean up work.
 *
 * @verified
 *    No.
 */
BOOLEAN cDemux::Delete(void)
{
    DBGPRINT(DBG_ON(DBG_TRACE), ("cDemux::Delete() - Stop and remove our worker task\n"));

    /* Stop and remove all spawned tasks */
    tDemuxConfigInfo.ulDemuxState = DEMUX_DELETE;
    if (iDemuxThreadID != 0)
    {
        OS_TaskJoin  (iDemuxThreadID);
        OS_TaskDelete(iDemuxThreadID);

        /* Reset the Demux thread ID */
        iDemuxThreadID = 0;
    }

    /* Reset the Demux state */
    tDemuxConfigInfo.ulDemuxState = DEMUX_STOPPED;

    /* delete semaphores */
    OS_SemDelete(tDemuxConfigInfo.semPinUpdate);
    OS_SemDelete(tDemuxConfigInfo.semPinSync);
#if ENABLE_DEMUX_REMAP_FEATURE
    OS_SemDelete(tDemuxConfigInfo.semRemapUpdate);
#endif
    tDemuxConfigInfo.semPinUpdate = 0;
    tDemuxConfigInfo.semPinSync   = 0;
#if ENABLE_DEMUX_REMAP_FEATURE
    tDemuxConfigInfo.semRemapUpdate = 0;
#endif

    /* Return successfully */
    return DEMUX_PASS;
}

/**
 * Start function. Starts the Demux task.
 *
 * @param
 *    None.
 *
 * @retval
 *    DEMUX_PASS - if successful
 *    DEMUX_FAIL - if not successful
 *
 * @remark
 *    None.
 *
 * @verified
 *    Yes.
 */
BOOLEAN cDemux::Start(void)
{
    /* the input stream needs to be attached before starting */
    if (NULL == tDemuxConfigInfo.tInputPin)
    {
        return (DEMUX_FAIL);
    }

    /* if the demux is stopping wait for it to complete */
    while (tDemuxConfigInfo.ulDemuxState == DEMUX_STOPPING)
    {
        OS_TaskDelay(OS_WAIT_1S/10);
    }

    /* Update the Demux state */
    tDemuxConfigInfo.ulDemuxState = DEMUX_STARTED;

    /* Return status */
    return (DEMUX_PASS);
}

/**
 * Stop function. Stops the Demux task by placing it into a
 * suspended state.
 *
 * @param
 *    None.
 *
 * @retval
 *    DEMUX_PASS - if successful
 *    DEMUX_FAIL - if not successful
 *
 * @remark
 *    None.
 *
 * @verified
 *    No.
 */
BOOLEAN cDemux::Stop(void)
{
    /* Make sure the Demux is not already stopped */
    if (tDemuxConfigInfo.ulDemuxState == DEMUX_STARTED)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("DEMUX: Stopping the Demux thread...\n"));

        /* Update the Demux state */
        tDemuxConfigInfo.ulDemuxState = DEMUX_STOPPING;
    }

    /* Return status */
    return (DEMUX_PASS);

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

/**
 * Attach Input Stream function. Provides the demux with a cStream object
 * from which it will read all of its input data.
 *
 * @param
 *    DEMUXIOSTREAM *pInputStream - pointer to the cStream object to be
 *                                  assigned to the demux.
 *
 * @retval
 *    DEMUX_PASS - if successful
 *    DEMUX_FAIL - if not successful
 *
 * @remark
 *    None.

⌨️ 快捷键说明

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