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

📄 timer.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 timer.c
 *
 * Timer Functions and Display Timer Control.
 *
 * $Id: timer.c,v 1.45 2007/01/26 22:52:38 rbehe Exp $
 */

#include <stdio.h>
#include "vdvd_types.h"
#include "osapi.h"
#include "nav_task.h"
#include "dvd_prm.h"
#include "dvd_pgci.h"
#include "dvdnvpck.h"
#include "timer.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif


/* MACROS */
#define DBG_TIMER DBG_ERROR
#define DBG_ON(x) (DBG_TIMER >= x)


/* GLOBALS */
ULONG    bin_bound_time   = 0;          /* time to the beginning of the current chapter */
ULONG    bin_chap_time    = 0;          /* length of current chapter */
ULONG    bin_title_time   = 0;          /* length of current title */

OS_TIMER_ID timer_nav            = 0;
OS_TIMER_ID timer_nav_cmd        = 0;

TIME_STRUCT time_info_struct;
TIME_STRUCT *time_info = &time_info_struct;

USHORT   prev_cur_cell = 0;  /* Backup of the cur_cell used before a skip or search was started */

/* EXTERNS */
extern USHORT angle_cell_start;
extern UBYTE  nav_pack_abort;
extern UBYTE  nav_pack_suspend;
extern UBYTE  nv_pck_ready;
extern UBYTE  wait_first_nvpck;
extern UBYTE  during_search;
extern UBYTE  adjust_nv_tmr;

void CreateNavTimer(void)
{
    OS_STATUS status;
    status = OS_TimerCreate(&timer_nav, (OS_FUNCPTR)nav_timer_expire);
    DBGPRINT((status != OS_OK), ("CreateNavTimer: FAILED with status = %d\n", status));

    EnableNavTimer();
}

void DeleteNavTimer(void)
{
    if (timer_nav == 0)
    {
        return;
    }

    DisableNavTimer();

    if (OS_TimerDelete(timer_nav) != OS_OK)
    {
        DbgPrint(("DeleteNavTimer: FAILED\n"));
    }
    timer_nav = 0;
}

void EnableNavTimer(void)
{
    if (timer_nav == 0)
    {
        return;
    }

    /* Enable a repeating one second timer */
    if (OS_TimerSetRepeatMsec(timer_nav, 1000) != OS_OK)
    {
        DbgPrint(("EnableNopTimer: FAILED\n"));
    }
}

void DisableNavTimer(void)
{
    if (timer_nav == 0)
    {
        return;
    }

    if (OS_TimerStop(timer_nav) != OS_OK)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("DisableNavTimer: FAILED\n"));
    }
}

/* Create navigation command time-out timer */
void CreateNavCmdTimer(void)
{
    OS_STATUS status;
    status = OS_TimerCreate(&timer_nav_cmd, (OS_FUNCPTR)nav_cmd_timer);
    DBGPRINT((status != OS_OK), ("CreateNavCmdTimer: FAILED with status = %d\n", status));
}

void DeleteNavCmdTimer(void)
{
    if (timer_nav_cmd == 0)
    {
        return;
    }

    DisableNavCmdTimer();

    if (OS_TimerDelete(timer_nav_cmd) != OS_OK)
    {
        DbgPrint(("DeleteNavCmdTimer: FAILED\n"));
    }
    timer_nav_cmd = 0;
}

void EnableNavCmdTimer(void)
{
    if (timer_nav_cmd == 0)
    {
        return;
    }

    /* Make nav_cmd a repeating 25 millisecond timer */
    if (OS_TimerSetRepeatMsec(timer_nav_cmd, 25) != OS_OK)
    {
        DbgPrint(("EnableNavCmdTimer: FAILED\n"));
    }
}

void DisableNavCmdTimer(void)
{
    if (timer_nav_cmd == 0)
    {
        return;
    }

    if (OS_TimerStop(timer_nav_cmd) != OS_OK)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("DisableNavCmdTimer: FAILED\n"));
    }
}


/********************************************************
 * DVD display timer support
 *******************************************************/

/*
 * init_disptimer
 */
void init_dvddisptimer(void)
{
    DBGPRINT(DBG_ON(DBG_TRACE), ("init_dvddisptimer: ENTER\n"));
    bin_bound_time           = 0; /* time to the beginning of the current chapter */
    bin_chap_time            = 0;  /* length of current chapter */
    bin_title_time           = 0; /* length of current title */
    time_info->chapter_valid = TRUE;
    time_info->title_valid   = TRUE;
}


/*
 * bin_to_time
 *      Converts a binary time to dvd time structure
 *      Input:   Time in 150*seconds
 *      Output:  Hr, Min, Second in a TIME_STRUCT
 *               typedef struct  {
 *                   ULONG title_tot;   hrBCD, minBCD, secBCD, framesBCD
 *                   ULONG chap_tot;    hrBCD, minBCD, secBCD, framesBCD
 *                   UBYTE title_n;
 *                   UBYTE chap_n;
 *                   UBYTE hour;        binary
 *                   UBYTE min;         binary
 *                   UBYTE sec;         binary
 *                   TIME_MODE display_mode;
 *               } TIME_STRUCT;
 */
void bin_to_time(TIME_STRUCT * timeinfo, ULONG time)
{
    time = time / 150; /* seconds */
    timeinfo->sec = (UBYTE)(time % 60);
    time /= 60; /* minutes */
    timeinfo->min = (UBYTE)(time % 60);
    time /= 60; /* hours */
    timeinfo->hour = (UBYTE)(time % 60);
}

/*
 * time_to_bin
 *      Converts a dvd time structure to binary
 *      There are 25 fps in PAL and 30 fps in NTSC.
 *      The least common multiple is 150 so we define 150 to be 1 second.
 */
ULONG time_to_bin(ULONG intime)
{
    ULONG vf;
    ULONG time;
    TIME_FORMAT in;

    in.ltime = intime;

    vf = (in.eltm->vft * 10) + in.eltm->vfu;

    time = (       (in.eltm->ht * 10) + in.eltm->hu) * 60;      /* hours to minutes */
    time = (time + (in.eltm->mt * 10) + in.eltm->mu) * 60;      /* minutes to seconds */
    time = (time + (in.eltm->st * 10) + in.eltm->su) * 150;     /* seconds to frame
                                                                 * units */
    time = time + (vf * ((in.eltm->tc == 1) ? 6 : 5));  /* frame contribution */
    return (time);
}

/*
 * update_timedisp
 *      Update info for VFD/OSD Display operation
 */
void update_timedisp(ULONG cur_time)
{
    ULONG  bin_cur_time        = 0;    /* current time in 150x seconds */
    ULONG  bin_total_time      = 0;    /* result time to display */
    USHORT i, j, k;
    ULONG  cell_time;
    USHORT chap_next_cell      = 0;
    USHORT cur_cell            = prev_cur_cell; /* current cell # from next cell # */
    ULONG  bin_chap_bound_time = 0;
    USHORT angle_offset;

    /* obtain current time in binary */
    bin_cur_time = time_to_bin(cur_time);

    /* If a skip is still being processed, the SPRM may reflect the desired title or chapter,
     * not the currently displayed and expected chapter and title */
    if ((nv_pck_ready != 0) && (nav_pack_abort != 1) && (wait_first_nvpck != 1) && (during_search != 1) && (adjust_nv_tmr != 1) && (nav_pack_suspend != 1))
    {
        /* Update title chapter information */
        time_info->title_n = (UBYTE)sprm[SPRM_TTN_TT_DOM];         /* current title # */
        time_info->chap_n  = (UBYTE)sprm[SPRM_PTTN_ONE_SEQ_PGC];   /* current chapter # */

        /* Offset current cell number to array index 0 */
        cur_cell = next_cell - 1;

        /* Backup the cur_cell for future use when skip or search is enacted */ 
        prev_cur_cell = cur_cell;
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("update_timedisp: %d %d %d\n", time_info->title_n, time_info->chap_n, bin_cur_time));

    /* Total title time */
    bin_title_time = time_to_bin(*(ULONG *) pgc_gi.pgc_pb_tm);

    /* Total time to beginning of chapter */
    bin_bound_time = 0;

    /* Compute the boundary chapter of the current cell  */
    for (i = 0; (next_cell >= pgc_pgmap[i]) && (i < (pgc_gi.pgc_cnt[2] & 0x7f) ); i++)
    {
        chap_next_cell = i;
    }

    /* adjust cell number for cells in angle block */
    if (c_pbi[next_cell - 1].c_cat[0] & 0x10)
    {
        angle_offset = next_cell - angle_cell_start;

        if (0 != angle_offset)
        {
            cur_cell -= angle_offset;
        }
    }

    /*
     * Compute the boundary time of a chapter and the current chapter total
     * time. We sum the times of all previous chapters to get the boundary
     * time. We sum multiple cells in a single chapter or one cell in a block
     *
     * pgc_gi.pgc_cnt[2] - number of programs in PGC, i.e. chapters in title
     * pgc_gi.pgc_cnt[3] - number of cells in PGC or title
     *
     * A Program Chain, a Title, has multiple Programs, Chapters. A Program may
     * have multiple Cells or Cell blocks
     */
    /* Sum all Program times in the Title */
    for (i = 0; i < (pgc_gi.pgc_cnt[2] & 0x7f) && (pgc_pgmap[i] <= next_cell); i++)
    {
        bin_chap_time = 0;
        bin_chap_bound_time = 0;

        /* get last cell in chapter */
        if (i == (pgc_gi.pgc_cnt[2] & 0x7f) - 1) /* last chapter of the PGC */
        {
            k = pgc_gi.pgc_cnt[3];      /* set upper count to last cell */
        }
        else
        {
            k = pgc_pgmap[i + 1] - 1;   /* set upper cell count to cell before next program */
        }

        /* Sum all cell times or first cell time of a block in the Program */
        for (j = pgc_pgmap[i] - 1; j < k; j++)
        {
            cell_time = time_to_bin(*(ULONG *) c_pbi[j].c_pbtm);

            /*
             * Sum every cell time if the cell in the program is not part of a cell block.
             * Sum time for only one cell of the block if this is the First Cell of a block,
             * i.e. Multi-angle Block Not a cell block or the first cell in a block
             * (Check this if chapter down times are too big)
             */
            if ((c_pbi[j].c_cat[0] & 0x30) == 0)        /* Not a cell block */
            {
                /* Sum every sequential cell time */
                bin_chap_time += cell_time;
                if ( (chap_next_cell == i) && (cur_cell > j) )
                {
                    bin_chap_bound_time += cell_time;
                }
                if (cur_cell > j)
                {
                    bin_bound_time += cell_time;
                }

            }
            else if ((c_pbi[j].c_cat[0] & 0xc0) == 0x40)        /* First cell in block */
            {
                /* Make sure only one value is added */
                bin_chap_time += cell_time;
                if ( (chap_next_cell >= i) && (cur_cell > j) )
                {
                    bin_bound_time += cell_time;
                }

                /*
                 * There may be more than one cell in a chapter in an angle block
                 * Hence, the bin_chap_bound_time need to be calculated Li 3/31/99
                 */
                if ( (chap_next_cell == i) && (cur_cell > j) )
                {
                    bin_chap_bound_time += cell_time;
                }
            }
        }
    }

    switch (time_info->display_mode)
    {
    case TITLE_DOWN:  /* title_time - boundary_cell_time - cur_time */
        bin_total_time = bin_title_time - bin_bound_time - bin_cur_time;
        break;

    case TITLE_UP:    /* chap_start_time + cur_time */
        bin_total_time = bin_cur_time + bin_bound_time;
        break;

    case CHAP_DOWN:   /* chap_tot - cur_time */
        bin_total_time = bin_chap_time - bin_cur_time - bin_chap_bound_time;
        break;

    case CHAP_UP:     /* cur_time */
    default:
        bin_total_time = bin_cur_time + bin_chap_bound_time;
        break;
    }

    bin_to_time(time_info, bin_total_time);     /* Fill the UI structure */
}

⌨️ 快捷键说明

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