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

📄 dvd_pgci.c

📁 这是DVD中伺服部分的核心代码
💻 C
📖 第 1 页 / 共 3 页
字号:
         */
        *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 + -