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

📄 pgc_play.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************
*******************************************************************************
**                                                                           **
**  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 pgc_play.cpp
 *
 * DVD Program Chain Playback Sequencer.
 *
 * $Id: pgc_play.cpp,v 1.133 2007/01/26 23:35:48 jared Exp $
 */

#include <stdlib.h>
#include "vdvd_types.h"
#include "osapi.h"
#include "loader_app.h"
#include "dr_app.h"
#include "pe_app.h"
#include "nav_task.h"
#include "dvd_pgci.h"
#include "dvd_vtsi.h"
#include "dvd_prm.h"
#include "dvdnvpck.h"
#include "pgc_play.h"
#include "readdir.h"
#include "init.h"
#include "timer.h"
#include "trickmode.h"
#include "spu_con.h"
#include "hw_init.h"
#include "mpeg_ids.h"
#include "dbgprint.h"
#include "usrapi.h"
#include "utility.h"
#include "disctask.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif

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

#define DBG_TIMESEARCH DBG_TRACE

static void pgc_init(void);
static void pb_mode_init(void);
static void update_osd_audio(UBYTE, UBYTE *);
static USHORT timetovobuoffset (LONG time);

#ifdef __cplusplus
   extern "C" {
#endif

USHORT  pgc_domain;
UBYTE   which_sp;
USHORT  playback_mode;
UBYTE   pg_repeat_count; /* number of times programs are repeated */
USHORT  pgc_mode;        /* current state */
USHORT  next_pgcn;       /* playback information for next pgc */
USHORT  next_cell;
USHORT  old_cell;
UBYTE   next_pgn;
UBYTE   next_vtsn;
ULONG   next_vts_sa;
UBYTE   menu_rsm, trick_rsm;
UBYTE   trick_rsm_cell;
UBYTE   button_cmd_buff[MAX_CEL_CMD_NS][SIZEOF_CMD];
USHORT  button_cmd_n;
USHORT  num_of_sh_stored;
UBYTE   shuffle_list[128];
USHORT  timer_count, timer_count1, hli_count;
USHORT  lang_index, country_index, subtitle_index, audio_index;
UBYTE   nav_suspend_flag = FALSE;
USHORT  suspending_nav_cmd;
USHORT  suspending_cmd_index;
USHORT  resume_cmd_index;
UBYTE   a_drc_fs;
UBYTE   prev_domain = 0xff;
UBYTE   title_play_enter;
UBYTE   change_hl_forbidden;
UBYTE   clear_search;
USHORT  repeat_ttn;
USHORT  nv_tmr_tt_pgcn;

extern DVD_SYSTEM_PARAMS dvd_system_params;
extern DR_HANDLE        tDR;
extern PE_HANDLE        tPE;
extern LOADER_HANDLE    tLoader;
extern BOOLEAN          fStartNavTimerCounter;
extern ULONG            cell_still_expire;
extern rsm_info_struct  rsm_info;
extern ULONG            pgc_still_expire, skip_expire, nav_timer_counter, nv_tmr_100;
extern USHORT           angle_cell_start;
extern ULONG            trick_resume_offset;
extern ULONG            vts_vobu_ad_size;
extern ULONG            rsm_nv_pck_lbn;
extern UBYTE            modify_video_mode;
extern UBYTE            skip_flag, continuous_skip_tt, block_continuous_skip, prev_pg_prohibited;
extern USHORT           prev_ptt_count;
extern UBYTE            WAIT_NEXT_CMD;
extern int              timeout_wait_next_cmd;
extern UBYTE            wait_first_nvpck;
extern UBYTE            audio_mode[2];
extern UBYTE            DISK_TYPE;
extern UBYTE            TV_TYPE;
extern UBYTE            TV_Type_Changed;
extern UBYTE            reset_scr_flag;
extern UBYTE            forcedly_reset_scr;
extern BOOLEAN          fKillNavTasks;
extern BOOLEAN          fAngleReady;
extern UBYTE            disc_type;

/* CELL_V1 */
extern ULONG ptt_v1, vts_tt_v1, tt_v1;
extern USHORT next_cell_v1, last_vobu_mode;
extern UBYTE next_pgn_v1, last_vobu_flag;
/******************/

extern UBYTE angle_change, goto_angle;
extern UBYTE ChangeOverride;

/* Li, condition and last memo */
extern CONDITION_STRUCT condition[5];
extern UBYTE condition_index;

extern LAST_MEMO_STRUCT last_memo[5];
extern UBYTE last_memo_index;
extern UBYTE prev_apstb;
extern UBYTE nv_pck_ready;
extern USHORT astn_in_pre_stop;

#if LOADER_ERROR_RECOVER == TRUE
extern UBYTE disc_error_flag;
#endif

extern USHORT angle_num_tt;
extern VMG_FILE_STRUCT video_ts;
extern UBYTE repeat_mode, A_B_count, repeat_count;
extern ULONG A_addr, B_addr;
extern UBYTE power_on_flag;
extern UBYTE zoom_on;
extern ULONG program_on, search_on, search_mode;
extern USHORT cell_play_counter;
extern TITLE_SET_FILE_STRUCT vts_file[99];

#ifdef __cplusplus
   }
#endif

void first_play(void)
{
    DBGPRINT(DBG_ON(DBG_TRACE), ("first_play:\n"));

    /* Initialize system parameters */
    sprm_init();

    /* Initialize general purpose parameters */
    gprm_init();

    pgc_init();
    pgc_play();
}

void repeat_A_B(void)
{
    UBYTE    vts_ttn, ret_val;
    USHORT   pttn;
    ULONG    startLBN;
    ULONG    endLBN;
    ULONG    beginLBN;
    DR_ERROR dr_status;
    DR_PARAMS_DVD params;
    BOOLEAN  fIsLast;

    DBGPRINT(DBG_ON(DBG_TRACE), ("repeat_A_B()\n"));

    /*** CELL_V1 ****/
    if (last_vobu_flag == 1)
        last_vobu_flag = 4;
    /************************/

    abort_drive_reset_channel();

    forcedly_reset_scr = 1;
    reset_scr_flag     = 0x05; /* CELL_V1 */

    /*
     * if the expected angle change isn't done yet, discard angle change commands
     * and force angle change ready
     */
    if (angle_change & 0x0f)
    {
        angle_num_tt = 0;

        fAngleReady = TRUE;

        angle_change = 0;  /* force angle has been changed */
    }

    /* restore some parameters at A point to handle cross chapter/title
     * boundary situation */
    next_cell = rsm_info.cell_num;

    /* if angle has been changed during A-B repeat, we will return to the old angle
     * when we return to A point.  Change angle number in sprm back to the old angle.
     * (In the new architecture with pm, will let it keep the new angle by mapping
     * A_addr and B_addr into the new angle cell. -- Li) */
    if ((0x10 == (c_pbi[next_cell - 1].c_cat[0] & 0x30)) &&    /* angle block     */
        (TT_PGC == pgc_domain)                           &&    /* title domain    */
        (tt_srp[sprm[SPRM_TTN_TT_DOM]-1].agl_n > 1 ))          /* total angle > 1 */
    {
        if ((next_cell < angle_cell_start + tt_srp[sprm[SPRM_TTN_TT_DOM]-1].agl_n) &&
            (next_cell >= angle_cell_start)) /* double check A point is in angle block */
        {
            set_sprm(SPRM_AGLN_TT_DOM, next_cell - angle_cell_start + 1);
        }
    }

    if (next_vtsn != rsm_info.vtsn)
    {
        next_vtsn = rsm_info.vtsn;

        ret_val = get_vtsi_ifo(next_vts_sa);
        if (ret_val != SUCCESS)
        {
            /* if there was a parse error retry */
            if (ret_val == FAILURE)
            {
                int index;

                /* find the index */
                for (index = 0; index < tt_srpti.tt_srp_n && index < MAX_NUM_TT; index++)
                {
                    if (tt_srp[index].vts_sa == next_vts_sa)
                    {
                        /* try new address found by readdir */
                        next_vts_sa = vts_file[tt_srp[index].vtsn - 1].ifo_address;
                        ret_val = get_vtsi_ifo(next_vts_sa);
                        break;
                    }
                }
            }
            if (ret_val != SUCCESS)
            {
                return;
            }
        }

        next_vts_sa = rsm_info.next_vts_sa;
    }

    set_sprm(SPRM_TTN_TT_DOM, rsm_info.sprm4);
    set_sprm(SPRM_VTS_TTN_TT_DOM, rsm_info.sprm5);
    set_sprm(SPRM_TT_PGCN_TT_DOM, rsm_info.sprm6);
    set_sprm(SPRM_PTTN_ONE_SEQ_PGC, rsm_info.sprm7);

    vts_ttn = (UBYTE)(get_sprm(SPRM_VTS_TTN_TT_DOM));
    pttn = get_sprm(SPRM_PTTN_ONE_SEQ_PGC);
    next_pgn = ptt_srp[vts_ttn - 1][pttn - 1].pgn;
    next_pgcn = ptt_srp[vts_ttn - 1][pttn - 1].pgcn;

    vob_init();

    /* CELL_V1 */
    clear_loader_queue();
    ptt_v1 = vts_tt_v1 = tt_v1 = 0xffffffff;
    next_cell_v1 = next_cell;
    next_pgn_v1 = next_pgn;
    /***************************/

    /* sectors of current cell to be presented */
    startLBN = A_addr;
    endLBN   = next_vts_sa + vtsi_mat.vtstt_vobs_sa + c_pbi[next_cell - 1].c_lvobu_ea;
    beginLBN = next_vts_sa + vtsi_mat.vtstt_vobs_sa + c_pbi[next_cell - 1].c_lvobu_sa;

    params.playtype     = DR_TYPE_VOB;
    params.queue        = DR_QUEUE_SEAMLESS;
    params.startLBN     = startLBN;
    params.endLBN       = endLBN;
    params.beginLBN     = beginLBN;
    params.fIsVobuStill = (c_pbi[next_cell - 1].c_cat[1] & 0x40) ? TRUE : FALSE;

    /*
     * Determine if this cell we're sending to play is the last cell to be played
     * in the PGC and/or if it is the last cell to be played in the VOB.
     */
    is_last_cell((UBYTE)(next_cell), &fIsLast, &params.fIsLastCell);

    /* Send message to disc task to request the sectors of cell */
    dr_status = DRPlayDVD(tDR, &params, (PVOID)fIsLast);

    if (dr_status != DR_SUCCESS)
    {
        DbgPrint(("DRPlayDVD returned error = %d\n", (int)dr_status));
    }

    EnableNavCmdTimer();

    /* CELL_V1 */
    if (last_vobu_flag == 4)
    {
        last_vobu_flag = 2;
    }
    /******************/

    DBGPRINT(DBG_ON(DBG_TRACE), ("repeat_A_B() -- EXIT\n"));
}

void pgc_end_repeat(void)
{
    ULONG tt, ptt;
    USHORT pgcn;
    UBYTE vts_ttn, retval;

    pgcn = pgc_gi.pgc_nv_ctl.next_pgcn;

    if ((pgcn == 0)             ||
        (pgcn == next_pgcn)     ||
        (pgcn == vts_pgciti.vts_pgci_srp_n))   /* next pgc doesn't exist or this is the last pgc */
    {
        if (repeat_mode == REPEAT_TT)
        {
            retval = title_play((UBYTE) sprm[SPRM_TTN_TT_DOM]);
            if (retval)
            {
#if LOADER_ERROR_RECOVER == TRUE
                if ((0xff != retval) && !parental_prohibit)
                    disc_error_flag = 1;
#endif
                pgc_mode = PGC_STOP;
            }

            pgc_play();
            return;
        }
        else if (repeat_mode == REPEAT_PTT)
        {
            ptt_search((USHORT) sprm[SPRM_PTTN_ONE_SEQ_PGC]);
            return;
        }
        else if (repeat_mode == REPEAT_ALL)
        {
            if (sprm[SPRM_TTN_TT_DOM] == tt_srpti.tt_srp_n)
                set_sprm(SPRM_TTN_TT_DOM, 1);
            else
                ++sprm[SPRM_TTN_TT_DOM];

            title_play_enter = 1;

            retval = title_play( (UBYTE)(sprm[SPRM_TTN_TT_DOM]) );
            if (retval)
            {
#if LOADER_ERROR_RECOVER == TRUE
                if ((0xff != retval) && !parental_prohibit)
                    disc_error_flag = 1;
#endif
                pgc_mode = PGC_STOP;
            }

            pgc_play();
            title_play_enter = 0;
            return;
        }

    }

    /* next pgc exists */
    vts_ttn = (vts_pgci_srp[pgcn - 1].vts_pgc_cat[0] & 0x7f);

    /* Get ttn for NEXT_PGCN */
    for (tt = 0; tt < tt_srpti.tt_srp_n; tt++)
    {
        if (tt_srp[tt].vts_ttn == vts_ttn)
        {
            break;
        }
    }

    if (repeat_mode == REPEAT_TT)
    {
        if (get_sprm(SPRM_TTN_TT_DOM) != (tt + 1))
        {
            retval = title_play((UBYTE) get_sprm(SPRM_TTN_TT_DOM));

            if (retval)
            {
#if LOADER_ERROR_RECOVER == TRUE
                if ((0xff != retval) && !parental_prohibit)
                    disc_error_flag = 1;
#endif
                pgc_mode = PGC_STOP;
            }

            pgc_play();
        }
        else
        {
            pgc_mode = PGC_POST_CMD;
            pgc_play();
        }
    }
    else if (repeat_mode == REPEAT_PTT)
    {

        /* find next pttn. If it's different from the current pttn, repeat the current ptt */
        for (ptt = 0; ptt < ttu_srp_num[vts_ttn - 1]; ptt++)
        {
            if ((ptt_srp[vts_ttn - 1][ptt].pgcn == pgcn) && (ptt_srp[vts_ttn - 1][ptt].pgn == 1 /* next_pgn */ ))
            {
                if (sprm[SPRM_PTTN_ONE_SEQ_PGC] != (ptt + 1))
                {
                    ptt_search((USHORT) sprm[SPRM_PTTN_ONE_SEQ_PGC]);
                }
            }
        }
    }
    else if (repeat_mode == REPEAT_ALL)
    {
        if ((playback_mode != 0x00) && pg_repeat_count)   /* random */
        {
            pgc_mode = PGC_LOOP_COUNT;
        }

⌨️ 快捷键说明

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