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

📄 dvd_pgci.c

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