📄 pgc_play.cpp
字号:
/******************************************************************************
*******************************************************************************
** **
** 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, ¶ms.fIsLastCell);
/* Send message to disc task to request the sectors of cell */
dr_status = DRPlayDVD(tDR, ¶ms, (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 + -