📄 dvd_pgci.c
字号:
#endif
if (0 == nv_pck_ready)
{
nv_pck_ready = 1;
}
#if 0
nav_state = POWER_ON_FP;
#else
nav_state = FULL_STOPPED;
#endif
pgc_domain = FP_PGC;
player_state = STOP;
/* clear the program mode */
user_program_enable = 0;
/* stop disc drive */
DRStop(tDR);
logo_display();
out_msg[0] = VDVD_STATUS_PARENTAL_PROHIBIT;
if (UsrEventHandler(out_msg) != USR_SUCCESS)
{
DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
}
out_msg[0] = VDVD_STATUS_STOP;
out_msg[1] = 1; /* full-stop */
if (UsrEventHandler(out_msg) != USR_SUCCESS)
{
DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
}
return (ret);
}
}
/* Setup Address and load sbuf based on what domain we are in */
switch (pgc_domain)
{
case VMGM_PGC:
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci() - case VMGM_PGC\n"));
#endif
/* Start address NOTE: LU hard coded to 0, for time being */
times = (USHORT)( (vmgm_lu_srp[lang_index].vmgm_lu_sa + vmgm_pgci_srp[lang_index][*pgci_num-1].vmgm_pgci_sa) / 0x800 );
sector_address = video_ts.ifo_address + vmgi_mat.vmgm_pgci_ut_sa + times;
start_address = vmgm_lu_srp[lang_index].vmgm_lu_sa + vmgm_pgci_srp[lang_index][*pgci_num-1].vmgm_pgci_sa - times * 0x800;
/* Message Q wait for Disk task to load the next sector */
if (last_sector_address == sector_address)
{
same_pgci = TRUE; /* PGCI is in the same sector */
}
else
{
last_sector_address = sector_address;
ret = (UBYTE)(LoaderSectorRead(tLoader, sector_address, sbuf, (UBYTE)10));
if (ret != LOADER_SUCCESS)
{
#if LOADER_ERROR_RECOVER == TRUE
if (0xff != ret)
{
sector_address = video_ts.bup_address + vmgi_mat.vmgm_pgci_ut_sa + times;
last_sector_address = sector_address;
ret = (UBYTE)(LoaderSectorRead(tLoader, sector_address, sbuf, (UBYTE)10));
if (ret == LOADER_SUCCESS)
{
break;
}
}
#endif
return (ret);
}
}
break;
case VTSM_PGC:
/* Start address for pgci data */
times = (USHORT)((vtsm_lu_srp[lang_index].vtsm_lu_sa + vtsm_pgci_srp[lang_index][*pgci_num-1].vts_pgci_sa) / 0x800);
sector_address = next_vts_sa + vtsi_mat.vtsm_pgci_ut_sa + times;
start_address = vtsm_lu_srp[lang_index].vtsm_lu_sa + vtsm_pgci_srp[lang_index][*pgci_num-1].vts_pgci_sa - (times * 0x800);
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci() - VTSM_PGC: lang_index=%x, pgci_num=%x\n",
(int)lang_index, (int)*pgci_num));
DbgPrint(("parse_pgci() - VTSM_PGC: vtsm_lu_srp[lang_index].vtsm_lu_sa=%x, vtsm_pgci_srp[lang_index][*pgci_num-1].vts_pgci_sa=%x, times=%x\n",
(int)vtsm_lu_srp[lang_index].vtsm_lu_sa, (int)vtsm_pgci_srp[lang_index][*pgci_num-1].vts_pgci_sa, (int)times));
#endif
/* Message Q wait for Disk task to load the next sector */
if (last_sector_address == sector_address)
{
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci() - (last_sector_address == sector_address)\n"));
#endif
same_pgci = TRUE; /* PGCI is in the same sector */
}
else
{
last_sector_address = sector_address;
ret = (UBYTE)LoaderSectorRead(tLoader, sector_address, sbuf, (UBYTE)10);
if (ret != LOADER_SUCCESS)
{
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci() - LoaderSectorRead FAILED, sector=%x\n", sector_address));
#endif
#if LOADER_ERROR_RECOVER == TRUE
if (0xff != ret)
{
sector_address = vts_file[tt_srp[sprm[SPRM_TTN_TT_DOM] - 1].vtsn - 1].bup_address + vtsi_mat.vtsm_pgci_ut_sa + times;
last_sector_address = sector_address;
ret = (UBYTE)(LoaderSectorRead(tLoader, sector_address, sbuf, (UBYTE)10));
if (ret == LOADER_SUCCESS)
{
break;
}
}
#endif
return (ret);
}
}
break;
case FP_PGC:
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci() - case FP_PGC\n"));
#endif
/* Start address for pgci data */
start_address = vmgi_mat.fp_pgci_sa;
sector_address = video_ts.ifo_address;
/* Message Q wait for Disk task to load the next sector */
/* Message Q wait for Disk task to load the next sector */
if (last_sector_address == sector_address)
{
same_pgci = TRUE; /* PGCI is in the same sector */
}
else
{
last_sector_address = sector_address;
ret = (UBYTE)(LoaderSectorRead(tLoader, sector_address, sbuf, (UBYTE)10));
if (ret != LOADER_SUCCESS)
{
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci() - LoaderSectorRead FAILED, sector=%x\n", sector_address));
#endif
#if LOADER_ERROR_RECOVER == TRUE
if (0xff != ret)
{
sector_address = video_ts.bup_address;
last_sector_address = sector_address;
ret = (UBYTE)(LoaderSectorRead(tLoader, sector_address, sbuf, (UBYTE)10));
if (ret == LOADER_SUCCESS)
{
break;
}
}
#endif
return (ret);
}
}
break;
case TT_PGC:
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci() - case TT_PGC\n"));
#endif
/* Start address for pgci data */
times = (USHORT)(vts_pgci_srp[*pgci_num-1].vts_pgci_sa / 0x800);
sector_address = next_vts_sa + vtsi_mat.vts_pgcit_sa + times;
start_address = vts_pgci_srp[*pgci_num-1].vts_pgci_sa - (times * 0x800);
/* Message Q wait for Disk task to load the next sector */
if (last_sector_address == sector_address)
{
same_pgci = TRUE; /* PGCI is in the same sector */
}
else
{
last_sector_address = sector_address;
ret = (UBYTE)(LoaderSectorRead(tLoader, sector_address, sbuf, (UBYTE)10));
if (ret != LOADER_SUCCESS)
{
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci() - LoaderSectorRead FAILED, sector=%x\n", sector_address));
#endif
#if LOADER_ERROR_RECOVER == TRUE
if (0xff != ret)
{
sector_address = vts_file[tt_srp[sprm[SPRM_TTN_TT_DOM] - 1].vtsn - 1].bup_address +
vtsi_mat.vts_pgcit_sa + times;
last_sector_address = sector_address;
ret = (UBYTE)(LoaderSectorRead(tLoader, sector_address, sbuf, (UBYTE)10));
if (ret == LOADER_SUCCESS)
{
break;
}
}
#endif
return (ret);
}
}
break;
}
if ( (last_start_address == start_address) && (same_pgci == TRUE) )
{
/* PGCI_GI has already been parsed */
#ifdef DEBUG_DVD_PGCI
DbgPrint(("PGCI_GI has already been parsed\n"));
#endif
}
else
{
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci: start_address = 0x%x\n", (int)start_address));
#endif
last_start_address = start_address;
/* Parse the PGCI GI */
#ifdef DEBUG_DVD_PGCI
DbgPrint(("Parse the PGCI GI\n"));
#endif
parse_pgci_gi(start_address);
/* Parse Program Chain Command Table */
#ifdef DEBUG_DVD_PGCI
DbgPrint(("Parse Program Chain Command Table\n"));
#endif
parse_pgc_cmdti(pgc_gi.pgc_cmdt_sa, start_address);
/* Parse Program Chain Program Map */
#ifdef DEBUG_DVD_PGCI
DbgPrint(("Parse Program Chain Program Map\n"));
#endif
parse_pgc_pgmap(pgc_gi.pgc_pgmap_sa, start_address);
/* Parse the Cell Playback Information Table */
#ifdef DEBUG_DVD_PGCI
DbgPrint(("Parse the Cell Playback Information Table\n"));
#endif
parse_c_pbi(pgc_gi.c_pbit_sa, start_address);
/* Parse the Cell Position Information Table */
#ifdef DEBUG_DVD_PGCI
DbgPrint(("Parse the Cell Position Information Table\n"));
#endif
parse_c_posit(pgc_gi.c_posit_sa, start_address);
}
/*
* Set unique identifier to playback time of first program chain
*/
/* if (get_disc_id == -1)
{
get_disc_id = *(ULONG *) pgc_gi.pgc_pb_tm;
}
*/
update_playback_mode();
return (ret);
}
/**
* Determine if a cell is the last cell from a PGC to be played and/or if it is the last Cell
* from a VOB to be played.
*
* @params
* ubCellNumber -- cell number
* fLastPGCCell -- boolean that gets set to true if the cell is the last cell to be played in a PGC
* fLastVobCell -- boolean that gets set to true if the cell is the last cell of a VOB.
*
* @return
* none
*/
void is_last_cell(UBYTE ubCellNumber, BOOLEAN *fLastPGCCell, BOOLEAN *fLastVobCell)
{
PE_ISTREAMCTRL_PLAYRATE PlayRate;
UBYTE ubNextPlayCell = 0;
USHORT usAngleNum;
UBYTE i;
/* validate parameters */
if ( (fLastPGCCell == NULL) || (fLastVobCell == NULL) )
{
DbgPrint(("is_last_cell(): NULL pointer!\n"));
return;
}
/* Cell numbers start from 1, so disallow cell 0 */
if (ubCellNumber == 0)
{
DbgPrint(("is_last_cell(): invalid cell number\n"));
return;
}
/* get angle number from system parameter */
usAngleNum = get_sprm(SPRM_AGLN_TT_DOM);
/* get rate from PE so we know if we are going forward or backward */
PEiStreamCtrlGetRate(tPE, &PlayRate);
/*
* Start from this cell and search ahead (backwards if going in reverse) in the pgc for
* the next cell to be played. We need to account for angle-blocks here. There are
* three possible cases for the next cell to be played.
* 1. The next cell will be in a non-angle block.
* 2. The next cell will be in an angle block, so we need to calculate
* which cell it is by finding the first cell of the angle block then
* adding the angle offset to that cell.
* 3. We are on the last cell to be played in a PGC and there is no next cell.
* Based on these 3 possibilities, we will search through the cells following (preceding if
* going in reverse) the current cell until we find a cell in a non-angle block, or we find a
* cell that is the first cell in an angle block, or we search to the end of the pgc.
*/
if (PlayRate.direction == PE_ISTREAMCTRL_DIRECTION_FORWARD)
{
/*
* Playback is forward. Search forward to the end of the pgc.
*/
/*
* Initialize last pgc cell to true, because if we search to the end of the
* pgc without finding a cell that will be played next, then we know that the
* cell we are currently on is the last cell to be played in the pgc.
*/
*fLastPGCCell = TRUE;
for (i = ubCellNumber + 1; i <= pgc_gi.pgc_cnt[3]; i++)
{
/*
* If this cell is not in an angle block, then this will be the
* next played cell.
*/
if ( (c_pbi[i - 1].c_cat[0] & 0x10) == 0)
{
ubNextPlayCell = i;
*fLastPGCCell = FALSE;
break;
}
/*
* If this cell is the first cell in an angle block, then the next played
* cell is in this angle block. Need to calculate offset for angle.
*/
if ( (c_pbi[i - 1].c_cat[0] & 0xc0) == 0x40)
{
ubNextPlayCell = i + usAngleNum - 1;
*fLastPGCCell = FALSE;
break;
}
}
}
else
{
/*
* Playback is in reverse. Do a similar thing here as in the forward case, except
* search backwards to the beginning of the pgc instead of forward to the end, and
* check for last cell in angle block, rather than first.
*/
/*
* Initialize last pgc cell to true, because if we search to the end of the
* pgc without finding a cell that will be played next, then we know that the
* cell we are currently on is the last cell to be played in the pgc.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -