📄 timer.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 + -