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

📄 dvdnvpck.c

📁 这是DVD中伺服部分的核心代码
💻 C
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  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 dvdnvpck.c
 *
 * DVD Navigation-Pack Parser.
 *
 * $Id: dvdnvpck.c,v 1.25 2006/10/26 18:35:27 eric Exp $
 */

#include <stdio.h>
#include "vdvd_types.h"
#include "dvd_vmgi.h"   /* Video Manager Information file structure defs */
#include "dvd_pgci.h"   /* includes dvd_cmd.h */
#include "dvdnvpck.h"   /* Navi-pack structure definitions */
#include "timer.h"
#include "dbgprint.h"
#include "utility.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif

nvpck_struct nvpck[NAV_BUFFER_SIZE];

UBYTE ssbuf[2048];

/* Lookup table for logical button number given the group number and
   absolute position within the button table (relative to zero). */
const UBYTE lbtn[MAX_BTNGR_NS][MAX_BTN_NS] =
{
    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36},
    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18},
    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
};

BOOLEAN parse_pci(UBYTE * buf);
BOOLEAN parse_dsi(UBYTE * buf);

/**
 * parse_nvpck()
 * Read in the navigation packet & decode it
 *
 * @param pbPCIPacket - pointer to PCI packet buffer
 * @param pbDSIPacket - pointer to DSI packet buffer
 *
 * @return SUCCESS or FAILURE
 *
 * @date 03/24/2003  rbehe  prototype modified, and parse seems to be succeeding.
 */
BOOLEAN parse_nvpck(BYTE *pbPCIPacket, BYTE *pbDSIPacket)
{
    /*
     * We should have 979+7+1017+7 bytes in DSI/PCI buffer = 2010, but the
     * granularity of the read is 8 bytes, so it would indicate 2008 bytes.
     * We should be OK as long as we have more than this but not overflow
     */
    /* read the navi-pack into the sector buffer */

    /*
     * PCI is 979 bytes + 1 byte for sub-stream ID = 0x03D4 first seven bytes
     * should be 00 00 01 BF 03 D4 00 private_stream_2 start
     * code___//_//_//_// || || || packet_length___//_// || sub_stream_id
     * __//
     */
    if (parse_pci(pbPCIPacket) == FAILURE)
    {
        DbgPrint(("parse_nvpck: parse_pci FAILURE\n"));
        return (FAILURE);
    }

    /*
     * DSI is 1017 bytes + 1 byte for sub-stream ID = 0x03FA next bytes
     * agfter PCI should be 00 00 01 BF 03 FA 01 private_stream_2 start
     * code___//_//_//_// || || || packet_length___//_// || sub_stream_id
     * __//
     */
    if (parse_dsi(pbDSIPacket) == FAILURE)
    {
        DbgPrint(("parse_dsi() - FAILURE\n"));
        return (FAILURE);
    }

    if (nvpck[LATEST_LOCAL].pci_gi.nv_pck_lbn != nvpck[LATEST_LOCAL].dsi_gi.nv_pck_lbn)
    {
        DbgPrint(("PCI, DSI Packet mismatch! pci=%lx, dsi=%lx\n",
            (unsigned long)nvpck[LATEST_LOCAL].pci_gi.nv_pck_lbn, (unsigned long)nvpck[LATEST_LOCAL].dsi_gi.nv_pck_lbn));
        return (FAILURE);
    }

    return (SUCCESS);
}


/**
 **  Name:           parse_pci
 **
 **  Description:    parse the PCI information from the NV_PCK
 **
 **  Arguments:      buf - pointer to array of bytes where PCI resides
 **
 **  Returns:        SUCCESS or FAILURE
 **
 *   Functionality:
 *    Presentation Control Information (PCI) is the Navigation Data to control
 *    the presentation of a VOB Unit (VOBU).
 *
 **/
BOOLEAN parse_pci(UBYTE * buf)
{
    USHORT n, i, j;

    /* parse the PCI_GI for a total of 60 bytes */
    n = 7;

    /* parse NV_PCK_LBN in PCI */
    nvpck[LATEST_LOCAL].pci_gi.nv_pck_lbn = MAKE_DWORD(&buf[n]);

    n += 4;
    nvpck[LATEST_LOCAL].pci_gi.apstb = buf[n] >> 6;

    /* skip over reserved bytes in VOBU_CAT & beyond */
    n += 4;

    /* get VOBU_UOP_CTL */
    for (i = 0; i < 4; i++)
    {
        nvpck[LATEST_LOCAL].pci_gi.vobu_uop_ctl[i] = buf[n++];
    }

    /* get VOBU_S_PTM */
    nvpck[LATEST_LOCAL].pci_gi.vobu_s_ptm = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get VOBU_E_PTM */
    nvpck[LATEST_LOCAL].pci_gi.vobu_e_ptm = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get VOBU_SE_E_PTM */
    nvpck[LATEST_LOCAL].pci_gi.vobu_se_e_ptm = MAKE_DWORD(&buf[n]);
    n += 4;

    nvpck[LATEST_LOCAL].pci_gi.c_eltm = MAKE_DWORD(&buf[n]);

    /* skip over Cell Elapse Time and reserved bytes */
    n += 4 + 32;        /* 32 bytes reserved */

    /* parse the NSML_AGLI for a total of 36 bytes */
    for (i = 0; i < MAX_ANGLES; i++, n += 4)
    {
        nvpck[LATEST_LOCAL].nsml_agli[i] = MAKE_DWORD(&buf[n]);
    }

    /* initialize highlight */
    nvpck[LATEST_LOCAL].hl_gi.hli_s_ptm = 0;
    nvpck[LATEST_LOCAL].hl_gi.hli_e_ptm = 0;
    nvpck[LATEST_LOCAL].hl_gi.btn_sl_e_ptm = 0;
    nvpck[LATEST_LOCAL].hl_gi.btngr_ns = 0;
    nvpck[LATEST_LOCAL].hl_gi.btngr1_dsp_ty = 0;
    nvpck[LATEST_LOCAL].hl_gi.btngr2_dsp_ty = 0;
    nvpck[LATEST_LOCAL].hl_gi.btngr3_dsp_ty = 0;
    nvpck[LATEST_LOCAL].hl_gi.btn_ofn = 0;
    nvpck[LATEST_LOCAL].hl_gi.btn_ns = 0;
    nvpck[LATEST_LOCAL].hl_gi.nsl_btn_ns = 0;
    nvpck[LATEST_LOCAL].hl_gi.fosl_btnn = 0;
    nvpck[LATEST_LOCAL].hl_gi.foac_btnn = 0;

    /* parse the HLI for a total of 694 bytes */
    /* starting with 22 bytes of HL_GI */
    n++;
    nvpck[LATEST_LOCAL].hl_gi.hli_ss = buf[n] & 0x03;
    if (nvpck[LATEST_LOCAL].hl_gi.hli_ss == 0)
    {
        /* the rest of the HLI is to be invalid, not a failure - we're just done */
        return (SUCCESS);
    }

    n += 1;

    /* get HLI_S_PTM */
    nvpck[LATEST_LOCAL].hl_gi.hli_s_ptm = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get HLI_E_PTM */
    nvpck[LATEST_LOCAL].hl_gi.hli_e_ptm = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get BTN_SL_E_PTM */
    nvpck[LATEST_LOCAL].hl_gi.btn_sl_e_ptm = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get BTN_MD stuff */
    nvpck[LATEST_LOCAL].hl_gi.btngr_ns = (buf[n] >> 4) & 0x03;
    nvpck[LATEST_LOCAL].hl_gi.btngr1_dsp_ty = buf[n] & 0x07;
    n += 1;
    nvpck[LATEST_LOCAL].hl_gi.btngr2_dsp_ty = (buf[n] >> 4) & 0x07;
    nvpck[LATEST_LOCAL].hl_gi.btngr3_dsp_ty = buf[n] & 0x07;
    n += 1;

    /* get BTN_OFN */
    nvpck[LATEST_LOCAL].hl_gi.btn_ofn = buf[n];
    n += 1;

    /* get BTN_Ns */
    nvpck[LATEST_LOCAL].hl_gi.btn_ns = buf[n] & 0x3F;
    n += 1;

    /* check for invalid button information */
    if ( ( (nvpck[LATEST_LOCAL].hl_gi.btngr_ns == 0)                                                        ) ||
         ( (nvpck[LATEST_LOCAL].hl_gi.btngr_ns == 1) && (nvpck[LATEST_LOCAL].hl_gi.btn_ns > MAX_BTN_NS    ) ) ||
         ( (nvpck[LATEST_LOCAL].hl_gi.btngr_ns == 2) && (nvpck[LATEST_LOCAL].hl_gi.btn_ns > MAX_BTN_NS / 2) ) ||
         ( (nvpck[LATEST_LOCAL].hl_gi.btngr_ns == 3) && (nvpck[LATEST_LOCAL].hl_gi.btn_ns > MAX_BTN_NS / 3) )  )
    {
        nvpck[LATEST_LOCAL].hl_gi.hli_ss = 0;
        return (SUCCESS);
    }

    /* get NSL_BTN_Ns */
    nvpck[LATEST_LOCAL].hl_gi.nsl_btn_ns = buf[n] & 0x3F;
    n += 2;     /* reserved byte here */

    /* check for invalid button information */
    if ( ( (nvpck[LATEST_LOCAL].hl_gi.btngr_ns == 1) && (nvpck[LATEST_LOCAL].hl_gi.nsl_btn_ns > MAX_BTN_NS    ) ) ||
         ( (nvpck[LATEST_LOCAL].hl_gi.btngr_ns == 2) && (nvpck[LATEST_LOCAL].hl_gi.nsl_btn_ns > MAX_BTN_NS / 2) ) ||
         ( (nvpck[LATEST_LOCAL].hl_gi.btngr_ns == 3) && (nvpck[LATEST_LOCAL].hl_gi.nsl_btn_ns > MAX_BTN_NS / 3) )  )
    {
        nvpck[LATEST_LOCAL].hl_gi.hli_ss = 0;
        return (SUCCESS);
    }

    /* get FOSL_BTNN */
    /* set SPRM(8) to the value of FOSL_BTNN at the time of HLI_S_PTM */
    nvpck[LATEST_LOCAL].hl_gi.fosl_btnn = buf[n] & 0x3F;
    n += 1;

    /* get FOAC_BTNN */
    nvpck[LATEST_LOCAL].hl_gi.foac_btnn = buf[n] & 0x3F;
    n += 1;

    /* next is 8 bytes x 3 groups of Button Color Information Table */
    for (i = 0; i < 3; i++)
    {
        /* get SL_COLI for each group */
        for (j = 0; j < 4; j++)
        {
            nvpck[LATEST_LOCAL].btn_colit[i].sl_coli[j] = buf[n++];
        }

        /* get AC_COLI for each group */
        for (j = 0; j < 4; j++)
        {
            nvpck[LATEST_LOCAL].btn_colit[i].ac_coli[j] = buf[n++];
        }
    }

    /*
     * Next we have 18 bytes x 36 of Button Information Tables. This could be
     * arranged as one 36 BTNIs group mode, two 18 BTNIs group mode or three
     * 12 BTNIs group mode.
     */
    for (i = 0; i < MAX_BTN_NS; i++)        /* for each button */
    {
        /* first parse the Button Position Information (6 bytes) */
        for (j = 0; j < SIZEOF_BTN_POSI; j++)
        {
            nvpck[LATEST_LOCAL].btn_posi[i][j] = buf[n + j];
        }

        n += SIZEOF_BTN_POSI;

        /* then parse the Adjacent Button Position Information (4 bytes) */
        nvpck[LATEST_LOCAL].ajbtn_posi[i].upper_btn = buf[n++] & 0x3F;
        nvpck[LATEST_LOCAL].ajbtn_posi[i].lower_btn = buf[n++] & 0x3F;
        nvpck[LATEST_LOCAL].ajbtn_posi[i].left_btn = buf[n++] & 0x3F;
        nvpck[LATEST_LOCAL].ajbtn_posi[i].right_btn = buf[n++] & 0x3F;

        /* finally parse the Button Command (8 bytes) */
        for (j = 0; j < SIZEOF_CMD; j++)
        {
            nvpck[LATEST_LOCAL].btn_cmd[i][j] = buf[n++];
        }
    }

    /* skip ahead by how many fewer than 36 buttons we parsed above */
    n += 18 * (36 - nvpck[LATEST_LOCAL].hl_gi.btn_ns);

    /* parse the RECI for a total of 189 bytes */
    return (SUCCESS);   /* don't really care about Recording Information
                         * right now */
}

/**
 **  Name:           parse_dsi
 **
 **  Description:    parse the DSI information from the NV_PCK
 **
 **  Arguments:      buf - pointer to array of bytes where DSI resides
 **
 **  Returns:        SUCCESS or FAILURE
 **
 *   Structures:
 *
 *   Pseudocode:
 *
 *   Functionality:
 *    Data Search Information (DSI) is the Navigation Data to search and carry
 *    out Seamless playback of the VOB Unit (VOBU).
 *
 **/
BOOLEAN parse_dsi(UBYTE * buf)
{
    USHORT n, i;

    /* parse the DSI_GI for a total of 32 bytes */
    n = 7;

    /* get NV_PCK_SCR */
    nvpck[LATEST_LOCAL].dsi_gi.nv_pck_scr = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get NV_PCK_LBN */
    nvpck[LATEST_LOCAL].dsi_gi.nv_pck_lbn = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get VOBU_EA */
    nvpck[LATEST_LOCAL].dsi_gi.vobu_ea = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get VOBU_1STREF_EA */
    nvpck[LATEST_LOCAL].dsi_gi.vobu_1stref_ea = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get VOBU_2NDREF_EA */
    nvpck[LATEST_LOCAL].dsi_gi.vobu_2ndref_ea = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get VOBU_3RDREF_EA */
    nvpck[LATEST_LOCAL].dsi_gi.vobu_3rdref_ea = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get VOBU_VOB_IDN */
    nvpck[LATEST_LOCAL].dsi_gi.vobu_vob_idn = MAKE_WORD(&buf[n]);
    n += 3;     /* reserved byte follows VOBU_VOB_IDN */

    /* get VOBU_C_IDN */
    nvpck[LATEST_LOCAL].dsi_gi.vobu_c_idn = buf[n];
    n += 1;

    /* dump Cell Elapse Time on the floor */
    n += 4;

    /* next parse the SML_PBI for a total of 148 bytes */

    /* starting with VOBU_SML_CAT */
    nvpck[LATEST_LOCAL].sml_pbi.vobu_sml_cat = MAKE_WORD(&buf[n]);
    n += 2;     /* skip reserved byte */

    /* get ILVU_EA */
    nvpck[LATEST_LOCAL].sml_pbi.ilvu_ea = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get NXT_ILVU_SA */
    nvpck[LATEST_LOCAL].sml_pbi.nxt_ilvu_sa = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get NXT_ILVU_SZ */
    nvpck[LATEST_LOCAL].sml_pbi.nxt_ilvu_sz = MAKE_WORD(&buf[n]);
    n += 2;

    /* get VOB_V_S_PTM */
    nvpck[LATEST_LOCAL].sml_pbi.vob_v_s_ptm = MAKE_DWORD(&buf[n]);
    n += 4;

    /* get VOB_V_E_PTM */
    nvpck[LATEST_LOCAL].sml_pbi.vob_v_e_ptm = MAKE_DWORD(&buf[n]);
    n += 4;

    for (i = 0; i < 8; i++)
    {
        /* get VOB_A_STP_PTM1 for each audio stream number */
        nvpck[LATEST_LOCAL].sml_pbi.vob_a_stp_ptm1[i] = MAKE_DWORD(&buf[n]);
        n += 4;
        /* get VOB_A_STP_PTM2 for each audio stream number */
        nvpck[LATEST_LOCAL].sml_pbi.vob_a_stp_ptm2[i] = MAKE_DWORD(&buf[n]);
        n += 4;
    }

    for (i = 0; i < 8; i++)
    {
        /* get VOB_A_GAP_LEN1 for each audio stream number */
        nvpck[LATEST_LOCAL].sml_pbi.vob_a_gap_len1[i] = MAKE_DWORD(&buf[n]);
        n += 4;
        /* get VOB_A_GAP_LEN2 for each audio stream number */
        nvpck[LATEST_LOCAL].sml_pbi.vob_a_gap_len2[i] = MAKE_DWORD(&buf[n]);
        n += 4;
    }

    /* next parse the SML_AGLI for a total of 54 bytes */
    for (i = 0; i < MAX_ANGLES; i++)
    {
        nvpck[LATEST_LOCAL].sml_agli[i].agl_c_dsta = MAKE_DWORD(&buf[n]);
        n += 4;
        nvpck[LATEST_LOCAL].sml_agli[i].agl_c_sz = MAKE_WORD(&buf[n]);
        n += 2;
    }

    /* next parse the VOBU_SRI for a total of 168 bytes */
    for (i = 0; i < 42; i++)
    {
        nvpck[LATEST_LOCAL].vobu_sri[i] = MAKE_DWORD(&buf[n]);
        n += 4;
    }

    /* finally parse the SYNCI for a total of 144 bytes */
    for (i = 0; i < 8; i++)
    {
        nvpck[LATEST_LOCAL].synci.a_synca[i] = MAKE_WORD(&buf[n]);
        n += 2;
    }

    for (i = 0; i < 32; i++)
    {
        nvpck[LATEST_LOCAL].synci.sp_synca[i] = MAKE_DWORD(&buf[n]);
        n += 4;
    }

    return (SUCCESS);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -