📄 dvd_pgci.c
字号:
*/
*fLastPGCCell = TRUE;
for (i = ubCellNumber - 1; i > 0; 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 last 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) == 0xc0)
{
ubNextPlayCell = i - tt_srp[get_sprm(SPRM_TTN_TT_DOM) - 1].agl_n + usAngleNum;
*fLastPGCCell = FALSE;
break;
}
}
}
if ( (0 == c_pbi[next_cell - 1].c_cat[2]) && /* no cell still */
(0 == (c_pbi[next_cell - 1].c_cat[1] & 0x40)) ) /* no infinite vobu still */
{
/*
* If the current cell is the last cell in the PGC to be played, then set last vob cell to false. Even
* if the current cell is the last cell of a vob to be played, it doesn't matter because there will be
* a non-seamless connection after the current cell. If the current cell is not the last cell of a pgc
* to be played, then compare the vob id of the current cell and the vob id of the next cell in the pgc
* to be played. If the vob id's are different, then this is the last cell of the vob to be played.
*/
*fLastVobCell = *fLastPGCCell ? TRUE : (c_posi[ubCellNumber - 1].c_vob_idn != c_posi[ubNextPlayCell - 1].c_vob_idn);
}
else
{
*fLastVobCell = FALSE;
}
}
/**
* Name: parse_pgci_gi
*
* Description: Parses the Program Chain General Information
* DVD Part 3:Video Spec Version 1.0 section 4.3.2
*
* Arguments: Start_RBP ULONG pgci_sa;
*
* Returns: Fills in structures
*
* Structures: pgc_gi
*
*
* Pseudocode:
*
*/
void parse_pgci_gi(ULONG pgci_sa)
{
ULONG index;
ULONG offset;
UBYTE *temp;
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci_gi: BEGIN\n"));
#endif
/* PGC Contents pgc_cnt */
store((UBYTE *)&pgc_gi.pgc_cnt[0], pgci_sa, 4, STORE_BIG_ENDIAN);
/* Total Presentation Time of programs in this PGC PGC_PB_TM */
store((UBYTE *)&pgc_gi.pgc_pb_tm[0], (pgci_sa + 4), 4, STORE_LITTLE_ENDIAN);
/* User Operation prohibitied for this PGC PGC_UOP_CTL */
store((UBYTE *)&pgc_gi.pgc_uop_ctl[0], (pgci_sa + 8), 4, STORE_BIG_ENDIAN);
/*
* Availabilty and conversion info for the eight audio streams PGC_AST_CTLT
*/
offset = 12; /* start of PGC_AST_CTLT */
for (index = 0; index < 8; index++)
{
store((UBYTE *)&pgc_gi.pgc_ast_ctlt[index][0], (pgci_sa + offset), 2, STORE_BIG_ENDIAN);
offset += 2;
}
/* Availabilty and info for the 32 sub-picture streams PGC_SPST_CTLT */
offset = 28; /* start of PGC_AST_CTL */
for (index = 0; index < 32; index++)
{
store((UBYTE *)&pgc_gi.pgc_spst_ctlt[index][0], (pgci_sa + offset), 4, STORE_BIG_ENDIAN);
offset += 4;
}
/* Describes the PGC navigation control pgc_nv_ctl */
offset = pgci_sa + 156;
/* store the Next_PGCN info */
store((UBYTE *)&pgc_gi.pgc_nv_ctl.next_pgcn, offset, 2, STORE_LITTLE_ENDIAN);
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci_gi: next_pgcn = %x\n", (int)pgc_gi.pgc_nv_ctl.next_pgcn));
#endif
/* store the Previous_PGCN info */
store((UBYTE *)&pgc_gi.pgc_nv_ctl.previous_pgcn, (offset + 2), 2, STORE_LITTLE_ENDIAN);
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci_gi: previous_pgcn = %x\n", (int)pgc_gi.pgc_nv_ctl.previous_pgcn));
#endif
/* store the GoUp_PGCN info */
store((UBYTE *)&pgc_gi.pgc_nv_ctl.goup_pgcn, (offset + 4), 2, STORE_LITTLE_ENDIAN);
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci_gi: goup_pgcn = %x\n", (int)pgc_gi.pgc_nv_ctl.goup_pgcn));
#endif
/* store the PG_Playback_Mode info */
store((UBYTE *)&pgc_gi.pgc_nv_ctl.pg_playback_mode, (offset + 6), 1, STORE_LITTLE_ENDIAN);
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci_gi: pg_playback_mode = %x\n", (int)pgc_gi.pgc_nv_ctl.pg_playback_mode));
#endif
/* store the Still_Time_Value info */
store((UBYTE *)&pgc_gi.pgc_nv_ctl.still_time_value, (offset + 7), 1, STORE_LITTLE_ENDIAN);
#ifdef DEBUG_DVD_PGCI
DbgPrint(("parse_pgci_gi: still_time_value = %x\n", (int)pgc_gi.pgc_nv_ctl.still_time_value));
#endif
/* Parsing of the PGC_SP_PLT There is 16 sets of color palette data */
temp = (UBYTE *)&pgc_gi.pgc_sp_plt[0];
offset = 164; /* set position at Y value for PGC_SP_PLT[0] */
for (index = 0; index < 16; index++)
{
/* store only Y, Cr, and Cb */
store(temp, (pgci_sa + offset + 1), 1, STORE_LITTLE_ENDIAN);
store(temp + 1, (pgci_sa + offset + 2), 1, STORE_LITTLE_ENDIAN);
store(temp + 2, (pgci_sa + offset + 3), 1, STORE_LITTLE_ENDIAN);
offset += 4; /* Move to next palette info in buffer */
temp += 3; /* Move to next palette structure */
}
/* Start Address of PGC_CMDT (pgc_cmdt_sa) */
store((UBYTE *)&pgc_gi.pgc_cmdt_sa, (pgci_sa + 228), 2, STORE_LITTLE_ENDIAN);
/* Start Address of PGC_PGMAP (PGC_PGMAP_SA) */
store((UBYTE *)&pgc_gi.pgc_pgmap_sa, (pgci_sa + 230), 2, STORE_LITTLE_ENDIAN);
/* Start Address of C_PBIT (C_PBIT_SA) */
store((UBYTE *)&pgc_gi.c_pbit_sa, (pgci_sa + 232), 2, STORE_LITTLE_ENDIAN);
/* Start Address of C_POSIT (C_POSIT_SA) */
store((UBYTE *)&pgc_gi.c_posit_sa, (pgci_sa + 234), 2, STORE_LITTLE_ENDIAN);
}
/**
* Name: parse_pgc_cmdti
*
* Description: Parses the Program Chain Command Table
* DVD Part 3:Video Spec Version 1.0 section 4.3.3
*
* Arguments: pgc_cmdt_sa Relative Start Address of Program Chain Command Table
*
* Returns: Fills in structures
*
* Structures: pgc_cmdti
*
* Pseudocode:
*
*/
void parse_pgc_cmdti(USHORT pgc_cmdt_sa, ULONG pgci_sa)
{
ULONG current_rbn;
ULONG cmd_num, index;
/* If no PGC_CMDTI exist, clear structures and exit */
if (pgc_gi.pgc_cmdt_sa == 0)
{
/* Clear stuctures */
pgc_cmdti.pre_cmd_n = 0;
pgc_cmdti.post_cmd_n = 0;
pgc_cmdti.c_cmd_n = 0;
pgc_cmdti.pgc_cmdt_ea = 0;
return;
}
/* Number of PRE_CMDs PRE_CMD_N */
store((UBYTE *) & pgc_cmdti.pre_cmd_n, pgci_sa + pgc_cmdt_sa, 2, STORE_LITTLE_ENDIAN);
/* Number of POST_CMDs POST_CMD_N */
store((UBYTE *) & pgc_cmdti.post_cmd_n, pgci_sa + pgc_cmdt_sa + 2, 2, STORE_LITTLE_ENDIAN);
/* Number of C_CMDs C_CMD_N */
store((UBYTE *) & pgc_cmdti.c_cmd_n, pgci_sa + pgc_cmdt_sa + 4, 2, STORE_LITTLE_ENDIAN);
/* End address of PGC_CMDT PGC_CMDT_EA */
store((UBYTE *) & pgc_cmdti.pgc_cmdt_ea, pgci_sa + pgc_cmdt_sa + 6, 2, STORE_LITTLE_ENDIAN);
/* Initalize the current_rbn to the start of the commands */
/* This is immediately following the pgc_cmdti */
/* Commands start address = Start Address of FP_PGCI */
/* + Start Address of PGC_CMDT */
/* + Length of pgc_cmdti (8 bytes) */
current_rbn = pgci_sa + pgc_cmdt_sa + 8;
/* Dump Pre, Post, and Cell Commands into temp Buffers */
/* Pre command dump */
if (pgc_cmdti.pre_cmd_n > 0) /* If there is some Pre Commands store them */
{
for (cmd_num = 0; (cmd_num < pgc_cmdti.pre_cmd_n) && (cmd_num < MAX_PRE_CMD_NS); cmd_num++)
{
for (index = 0; index < SIZEOF_CMD; index++)
{
store((UBYTE *) & pre_cmd_buff[cmd_num][index], current_rbn++, 1, STORE_BIG_ENDIAN);
}
}
ERROR_CHECK(pgc_cmdti.pre_cmd_n, MAX_PRE_CMD_NS+1, "MAX_PRE_CMD_NS");
}
/* Post Command dump */
if (pgc_cmdti.post_cmd_n > 0) /* If there is some Post Commands store them */
{
for (cmd_num = 0; (cmd_num < pgc_cmdti.post_cmd_n) && (cmd_num < MAX_PST_CMD_NS); cmd_num++)
{
for (index = 0; index < SIZEOF_CMD; index++)
{
store((UBYTE *) & post_cmd_buff[cmd_num][index], current_rbn++, 1, STORE_BIG_ENDIAN);
}
}
ERROR_CHECK(pgc_cmdti.post_cmd_n, MAX_PST_CMD_NS+1, "MAX_PST_CMD_NS");
}
/* Cell command dump */
if (pgc_cmdti.c_cmd_n > 0) /* If there is some Cel Commands... store them */
{
for (cmd_num = 0; cmd_num < pgc_cmdti.c_cmd_n; cmd_num++)
{
for (index = 0; index < SIZEOF_CMD; index++)
{
store((UBYTE *) & c_cmd_buff[cmd_num][index], current_rbn++, 1, STORE_BIG_ENDIAN);
}
}
}
}
/**
* Name: parse_pgc_pgmap
*
* Description: Parses the Program Chain Program Map
* DVD Part 3:Video Spec Version 1.0 section 4.3.4
*
* Arguments: PGC_PGMAP_SA Relative Start Address of Program Chain Map
*
* Returns: Fills in structures
*
* Structures: PGC_PGMAP
*
* Pseudocode:
*
*/
void parse_pgc_pgmap(USHORT pgc_pgmap_sa, ULONG pgci_sa)
{
ULONG index;
ULONG offset = 0;
/* If no pgc_pgmap exists, clear structures and return */
if (pgc_gi.pgc_pgmap_sa == 0)
{
return;
}
for (index = 0; index < MAX_NUM_PG; index++)
pgc_pgmap[index] = 0;
/* Need to loop through for each Program */
for (index = 0; (index < ((UBYTE) (pgc_gi.pgc_cnt[2] & 0x7f))) && (index < MAX_NUM_PG); index++)
{
store((UBYTE *) & pgc_pgmap[index], (pgc_pgmap_sa + pgci_sa + offset), 1, STORE_LITTLE_ENDIAN);
offset++;
}
ERROR_CHECK(index, MAX_NUM_PG, "MAX_NUM_PG");
}
/**
** Name: parse_c_pbi
**
** Description: Parses the Cell Playback Information Table
** DVD Part 3:Video Spec Version 1.0 section 4.3.5
**
** Arguments: C_PBI_SA Relative Start Address of Program Chain Map
**
** Returns: Fills in Structures
**
** Structures: C_PBI
**
* Pseudocode:
*
**/
void parse_c_pbi(USHORT c_pbi_sa, ULONG pgci_sa)
{
ULONG index;
ULONG offset = 0;
ULONG address = (ULONG) (c_pbi_sa + pgci_sa);
/* If no c_pbi exists, clear structures and return */
if (pgc_gi.c_pbit_sa == 0)
{
return;
}
/* Need to loop through for each Program and get C_PBI */
for (index = 0; (index < ((UBYTE) (pgc_gi.pgc_cnt[3]))) && (index < MAX_NUM_CELLS); index++)
{
/* store C_CAT */
store((UBYTE *) & c_pbi[index].c_cat[0], (address + offset), 4, STORE_BIG_ENDIAN);
/* store C_PBTM */
store((UBYTE *) & c_pbi[index].c_pbtm[0], (address + offset + 4), 4, STORE_LITTLE_ENDIAN);
/* store C_FVOBU_SA */
store((UBYTE *) & c_pbi[index].c_fvobu_sa, (address + offset + 8), 4, STORE_LITTLE_ENDIAN);
/* store C_FILVU_EA */
store((UBYTE *) & c_pbi[index].c_filvu_ea, (address + offset + 12), 4, STORE_LITTLE_ENDIAN);
/* store C_LVOBU_SA */
store((UBYTE *) & c_pbi[index].c_lvobu_sa, (address + offset + 16), 4, STORE_LITTLE_ENDIAN);
/* store C_LVOBU_EA */
store((UBYTE *) & c_pbi[index].c_lvobu_ea, (address + offset + 20), 4, STORE_LITTLE_ENDIAN);
offset += 24;
}
ERROR_CHECK(index, MAX_NUM_CELLS, "MAX_NUM_CELLS");
}
/**
** Name: parse_c_posit
**
** Description: Parses the Cell Position Information Table (C_POSIT)
** DVD Part 3:Video Spec Version 1.0 section 4.3.6
**
** Arguments: C_POSIT_SA Relative Start address of the Position Info table
**
** Returns: Fills in structures
**
** Structures: C_POSI
**
**/
void parse_c_posit(USHORT c_posit_sa, ULONG pgci_sa)
{
ULONG index;
ULONG offset = 0;
ULONG address = (ULONG) (c_posit_sa + pgci_sa);
/* If no c_posit exists, clear structures and return */
if (pgc_gi.c_posit_sa == 0)
{
return;
}
/* Need to loop through for each Program and get C_PBI */
for (index = 0; (index < ((UBYTE) (pgc_gi.pgc_cnt[3]))) && (index < MAX_NUM_CELLS); index++)
{
/* store C_VOB_IDN */
store((UBYTE *) & c_posi[index].c_vob_idn, (address + offset), 2, STORE_LITTLE_ENDIAN);
/* store C_IDN */
store((UBYTE *) & c_posi[index].c_idn, (address + offset + 3), 1, STORE_LITTLE_ENDIAN);
offset += 4;
}
ERROR_CHECK(index, MAX_NUM_CELLS, "MAX_NUM_CELLS");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -