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

📄 cdda_app.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* vim:set ts=4 sw=4 et: */
/*****************************************************************************
******************************************************************************
**                                                                          **
**  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 cdda_app.cpp
 *
 * Application for playing CDDAs
 *
 * $Id: cdda_app.cpp,v 1.55 2007/01/26 21:14:54 rbehe Exp $
 */

#include <stdlib.h>
#include <string.h>
#include "vdvd_types.h"
#include "osapi.h"
#include "loader_app.h"
#include "dr_app.h"
#include "pe_app.h"
#include "usrapi.h"
#include "dbgprint.h"
#include "cdda_app.h"
#include "utility.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif

/* Macros */
/* Debug Print Control */
#define CDDAAPP_DEBUG               (DBG_ERROR)
#define CDDAAPP_TRACE_TOC           (DBG_ERROR)
#define CDDAAPP_TRACE_DR_EVENT_MSF  (DBG_ERROR)
#define DBG_ON(x)                   (CDDAAPP_DEBUG >= x)

/* General */
#define CDDA_MSG_QUEUE_DEPTH        (2)                     /* Max number of command messages allowed in queue */
#define CDDA_TASK_STACKSIZE         (8 * 1024)              /* CDDA task stack size */

/* Version information for the CDDA player */
#define CDDA_VERSION_STRING      "cdda_app_00_00_06"
#define CDDA_VERSION_DATE_STRING "April 6, 2006"
#define CDDA_VERSION_YEAR        0x2006
#define CDDA_VERSION_MONTH       0x04
#define CDDA_VERSION_DAY         0x06

#define CDDA_SECTOR_SIZE 2352
#define CD_FRAMES        75
#define MAX_SYNC_LOOP    64

/* Globals */
static CDDA_AppInfo CddaAppControl;                     /* CDDA application control           */
static BYTE         bCddaLocalBuf[CDDA_SECTOR_SIZE];
static USHORT       g_RandomList[99];
static USHORT       g_RandomCur;

/* Function Prototypes */
static OS_STATUS cddaAppStartNav(void);
static void cddaAppStopNav(void);
static ULONG cddaRetrieveCddaTOC(void);
static void cddaParseCddaTOC(void);
static void cddaGetTrackLBAs(BYTE bRequestedTrack, CDDA_TrackInfo *pRequestedTrackInfo);
static PE_STATUS cddaPEEventCallback(PVOID pContext, PE_EVENT_CODE event, PVOID pEventInfo);
static DR_ERROR  cddaDrEventCallback(PVOID pContext, DR_EVENT_CODE event, PVOID pEventInfo);
static ULONG cddaAppTask(PVOID argv);
static BOOLEAN cddaAppCheckForDts(LOADER_HANDLE loader, ULONG lba, BYTE *buffPtr);

ULONG CddaAppGetChapterTotalTime(ULONG ulChapterNumber)
{
    ULONG ulCurrenrTrackTime, ulNextTrackTime;
    BYTE bFirstTrack, bLastTrack, bEntry;
    CDDA_TrackDescriptorInfo *pTrackDescriptorInfo;
    CDDA_TrackDescriptorInfo *pTDIEntry;

    bFirstTrack = CddaAppControl.TOC.bFirstTrackNumber;
    bLastTrack = CddaAppControl.TOC.bLastTrackNumber;

    pTrackDescriptorInfo = (CDDA_TrackDescriptorInfo *) (CddaAppControl.TOC.bData +CDDA_TOC_HEADER_SIZE_BYTES );

    if ( (ulChapterNumber < (ULONG)bFirstTrack) || (ulChapterNumber > (ULONG)bLastTrack) )
        return 0;


    bEntry =CddaAppControl.TOC.bTrackToEntry[(BYTE)ulChapterNumber ];
    pTDIEntry =&(pTrackDescriptorInfo[bEntry]);

    ulCurrenrTrackTime =(60 * pTDIEntry->bPMinute);
    ulCurrenrTrackTime +=pTDIEntry->bPSecond;
    ulCurrenrTrackTime+=(pTDIEntry->bPFrame /CD_FRAMES );


    if (ulChapterNumber== CddaAppControl.TOC.bLastTrackNumber)
    {
        /* Use lead-out */
        ulNextTrackTime  = (60 * CddaAppControl.TOC.LeadOut.bPMinute);
        ulNextTrackTime += CddaAppControl.TOC.LeadOut.bPSecond;
        ulNextTrackTime += (CddaAppControl.TOC.LeadOut.bPFrame / CD_FRAMES);
    }
    else
    {
        /* Use next track */
        /* Translate track to TOC entry number, then set pointer */
        bEntry    = CddaAppControl.TOC.bTrackToEntry[((BYTE)ulChapterNumber + 1)];
        pTDIEntry = &(pTrackDescriptorInfo[bEntry]);

        /* Determine time (in seconds) */
        ulNextTrackTime  = (60 * pTDIEntry->bPMinute);
        ulNextTrackTime += pTDIEntry->bPSecond;
        ulNextTrackTime += (pTDIEntry->bPFrame / CD_FRAMES);
    }

    return ( ulNextTrackTime - ulCurrenrTrackTime );
}

void PrintfAllTrackTimes()
{
    int i=0;
    ULONG ulCurrenrTrackTime, ulNextTrackTime;
    BYTE bFirstTrack, bLastTrack, bEntry;
    CDDA_TrackDescriptorInfo *pTrackDescriptorInfo;
    CDDA_TrackDescriptorInfo *pTDIEntry;
    ULONG TrackTime[CDDA_TOC_TRACK_MAXIMUM];

    bFirstTrack = CddaAppControl.TOC.bFirstTrackNumber;
    bLastTrack = CddaAppControl.TOC.bLastTrackNumber;
    DbgPrint(("\nbFirstTrack %d \n", (int)bFirstTrack));
    DbgPrint(("\bLastTrack %d \n", (int)bLastTrack));

    pTrackDescriptorInfo = (CDDA_TrackDescriptorInfo *) (CddaAppControl.TOC.bData +CDDA_TOC_HEADER_SIZE_BYTES );

    for(i=(int)bFirstTrack; i<=(int)bLastTrack ; i++)
    {
        bEntry =CddaAppControl.TOC.bTrackToEntry[(BYTE)i ];
        pTDIEntry =&(pTrackDescriptorInfo[bEntry]);

        ulCurrenrTrackTime =(60 * pTDIEntry->bPMinute);
        ulCurrenrTrackTime +=pTDIEntry->bPSecond;
        ulCurrenrTrackTime+=(pTDIEntry->bPFrame /CD_FRAMES );


        if (i == CddaAppControl.TOC.bLastTrackNumber)
        {
            /* Use lead-out */
            ulNextTrackTime  = (60 * CddaAppControl.TOC.LeadOut.bPMinute);
            ulNextTrackTime += CddaAppControl.TOC.LeadOut.bPSecond;
            ulNextTrackTime += (CddaAppControl.TOC.LeadOut.bPFrame / CD_FRAMES);
        }
        else
        {
            /* Use next track */
            /* Translate track to TOC entry number, then set pointer */
            bEntry    = CddaAppControl.TOC.bTrackToEntry[((BYTE)i + 1)];
            pTDIEntry = &(pTrackDescriptorInfo[bEntry]);

            /* Determine time (in seconds) */
            ulNextTrackTime  = (60 * pTDIEntry->bPMinute);
            ulNextTrackTime += pTDIEntry->bPSecond;
            ulNextTrackTime += (pTDIEntry->bPFrame / CD_FRAMES);
        }

        TrackTime[i] = ulNextTrackTime - ulCurrenrTrackTime;

        DbgPrint(("Track %d: Time (in seconds): %d~%d (%d ) \n", i, ulCurrenrTrackTime, ulNextTrackTime, TrackTime[i] ));
    }

}


/**
 * Initialize the CDDA application.
 *
 * @param loader - Handle to loader module.
 * @param dr     - Handle to DR module.
 * @param pe     - Handle to PE module.
 *
 * @return OS_STATUS - Status / error code.
 */
OS_STATUS CddaAppInitialize(LOADER_HANDLE loader, DR_HANDLE dr, PE_HANDLE pe)
{
    ULONG ulEvents;

    /* Announce version information */
    DbgPrint(("%s(): %s, %s\n", __FUNCTION__, CDDA_VERSION_STRING, CDDA_VERSION_DATE_STRING));

    if ((loader == NULL) || (dr == NULL) || (pe == NULL))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: NULL HANDLE.\n", __FUNCTION__));
        return (OS_NULL_POINTER);
    }

    /* Initialize variables */
    CddaAppControl.tLoader         = loader;
    CddaAppControl.tDR             = dr;
    CddaAppControl.tPE             = pe;

    CddaAppControl.State           = CDDA_STATE_UNITIALIZED;
    CddaAppControl.RepeatMode      = CDDA_REPEAT_NONE;
    CddaAppControl.bABRepeatCount  = 0;
    CddaAppControl.sSpeed          = 1;
    CddaAppControl.ulCurrentPETime = 0; /* Held in LBA units */
    CddaAppControl.ulRepeatATime   = 0; /* Held in LBA units */
    CddaAppControl.ulRepeatBTime   = 0; /* Held in LBA units */

    /* Retrieve the Table of Contents */
    if (CDDA_SUCCESS != cddaRetrieveCddaTOC())
    {
        DbgPrint(("CddaAppInitialize() - cddaRetrieveCddaTOC FAILED\n"));
        return (OS_FAILURE);
    }

    /* Parse the Table of Contents */
    cddaParseCddaTOC();

    /* Retrieve LBAs, which also sets current track info */
    cddaGetTrackLBAs(CddaAppControl.TOC.bFirstTrackNumber, &CddaAppControl.CurrentTrack);

    /* attach DR event handler */
    if (DRAttachEvent(CddaAppControl.tDR, cddaDrEventCallback, CddaAppControl.tDR) != DR_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: DRAttachEvent Failed.\n", __FUNCTION__));
        goto error_out;
    }

    ulEvents = (PE_EVENT_BEG_OF_STREAM | PE_EVENT_END_OF_STREAM | PE_EVENT_DISCONTINUITY | PE_EVENT_ASYNC_PREFILL | PE_EVENT_POSITION);

    /* attach PE event handler */
    if (PERegisterForEvents(CddaAppControl.tPE, cddaPEEventCallback, ulEvents, CddaAppControl.tPE) != PE_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: PEiStreamCtrlRegisterForEvents Failed.\n", __FUNCTION__));
        goto error_out;
    }

    /* Check for DTS audio on a CDDA disc */
    if (cddaAppCheckForDts(loader, CddaAppControl.CurrentTrack.ulStartLBA, bCddaLocalBuf) == TRUE)
    {
        /* TODO: configure for dts */
//        if (PEiStreamCtrlDemuxAddAudioPS(CddaAppControl.tPE, 0, 0, INPUT_MAIN, AUDIO_TYPE_DTS) == PE_NOT_SUPPORTED)
//        {
//            ULONG out_msg[4];
//            out_msg[0] = VDVD_STATUS_AUDIO_NOT_SUPPORTED;
//            out_msg[1] = VDVD_INFO_AUDIOTYPE_DTS;
//            UsrEventHandler(out_msg);
//            goto error_out;
//        }
    }
    else
    {
        PE_ISTREAMCTRL_AUDIO_ATTRIBUTES audio_attributes;

        /* Set audio type: 16-bit, stereo PCM, 44.1 kHz */
        audio_attributes.sampling_frequency = AUDIO_SAMPLING_FREQUENCY_44_1_KHz;
        audio_attributes.n_channels         = AUDIO_STEREO;
        if (PEiStreamCtrlDemuxAddAudioPS(CddaAppControl.tPE, 0, 0, INPUT_MAIN, AUDIO_TYPE_PCM, &audio_attributes) == PE_NOT_SUPPORTED)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: PEiStreamCtrlSetAudioType Failed.\n", __FUNCTION__));
            goto error_out;
        }
    }

    /* create RTOS tasks */
    if (cddaAppStartNav() != OS_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: cddaAppStartNav Failed.\n", __FUNCTION__));
        goto error_out;
    }

    /* prefill the PE */
    if (PEiStreamCtrlPrefill(CddaAppControl.tPE, INPUT_MAIN, PE_ASYNC) != PE_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: PEiStreamCtrlPrefill Failed.\n", __FUNCTION__));
    }

    CddaAppControl.State = CDDA_STATE_STOPPED;

    return (OS_OK);

error_out:
    CddaAppUnInitialize();
    return (OS_FAILURE);
}


/**
 * Uninitialize / tear-down the CDDA application.
 *
 * @param none.
 *
 * @return OS_STATUS - Status / error code.
 */
OS_STATUS CddaAppUnInitialize(void)
{

⌨️ 快捷键说明

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