📄 pbc.cpp
字号:
/******************************************************************************
*******************************************************************************
** **
** 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
* pbc.c
*
* VCD Control Task
*
* $Id: pbc.cpp,v 1.37 2006/10/09 21:19:38 rbehe Exp $
*/
#include <string.h>
#include "vdvd_types.h"
#include "osapi.h"
#include "usrapi.h"
#include "vcd.h"
#include "loader_app.h"
#include "pe_app.h"
#include "dr_app.h"
#include "utility.h"
#include "mpeg_ids.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
namespace vcd {
/* MACROS */
#define PBC_DEBUG DBG_ERROR
#define DBG_ON(x) (PBC_DEBUG >= x)
#define QUEUE_CLR 0x02
/* GLOBALS */
LOADER_HANDLE tLoader;
DR_HANDLE tDR;
PE_HANDLE tPE;
OS_TIMER_ID apause_timer = 0;
OS_MSG_Q_ID queue_vcd;
ULONG ulPlaySpeed;
UBYTE pbc_mode; /* PBC play back mode */
UBYTE pbc_play_time[4]; /* current disc MSF */
ULONG pbc_apause_tim; /* auto pause time */
UBYTE g_pbc_on; /* PBC on/off */
UBYTE g_random_mode; /* current play mode */
UBYTE g_play_kind; /* current play kind */
UBYTE g_track; /* current track number */
UBYTE g_time[2]; /* current local play time */
USHORT g_scene; /* current scene (PBC list ID)*/
ULONG g_max_time; /* last MSF address on disc */
UBYTE s_msf[3], e_msf[3]; /* start/end MSF */
UBYTE a_msf[3], b_msf[3]; /* start/end MSF */
UBYTE cdda_track; /* CDDA playing on VCD disc flag */
UBYTE logo_on = 0; /* logo onscreen flag */
UBYTE g_track_prev; /* previous MSF for time display filtering */
UBYTE next_prev_key; /* whether next or prev was pushed */
UBYTE pbc_end_flag; /* flag to say a MSG_PLAY_END is in the queue */
UBYTE audio_channel_mode;
UBYTE VERSION_FLG;
UBYTE g_repeat_mode, A_B_count;
BOOLEAN fIsStillPic;
/* VCD Navigation Structures */
TOC_INFO g_toc_info; /* TOC infomation */
INFO_VCD g_info_vcd; /* INFO.VCD information */
ENTRY_VCD g_entry_vcd; /* ENTRY.VCD information */
TRACKS_SVD g_tracks_svd; /* svcd: TRACK.SVD info about svcd tracks */
USHORT *g_lot_addr = NULL; /* start of LOT array */
UBYTE *g_psd_addr = NULL; /* start of PSD array */
UBYTE *g_current_psd = NULL; /* Current PSD Addr. */
UBYTE *g_previous_psd = NULL; /* Previous PSD Addr. */
/* LOCALS */
static UBYTE pbc_seg_item; /* segment play item */
static UBYTE pbc_loop_count; /* loop count */
static UBYTE pbc_jump_key; /* jump timing key */
static ULONG pbc_jump_num; /* jump timing num */
static UBYTE pbc_play_item_num; /* number of items(NOI) */
/* local pbc key functions */
void pbc_key_proc(ULONG *);
void pbc_key_proc_stop(NAV_COMMAND, ULONG, ULONG);
void pbc_key_proc_play(NAV_COMMAND, ULONG, ULONG);
void pbc_key_proc_play_play(void);
void pbc_key_proc_end(NAV_COMMAND, ULONG, ULONG);
/* local helper functions */
USR_STATUS uop_prohibited_msg(void);
void pbc_start_vcd(void);
USHORT pbc_get_selection_no(void);
USHORT pbc_default_check(void);
ULONG pbc_get_waite_time(UBYTE);
void pbc_fe_playcd_req(UBYTE, UBYTE, UBYTE, UBYTE *, UBYTE *);
UBYTE pbc_loop_jump_chk(void);
UBYTE get_map_value(UBYTE tno);
void cd_020_set_req(UBYTE, UBYTE);
void pbc_timesearch(BOOLEAN, ULONG);
void pbc_shuffle(void);
/* BEGIN STUBS */
#define STUBMSG DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %s, %d, STUBBED\n", __FUNCTION__, __FILE__, __LINE__));
/* END STUBS */
/*************************************************
Function Name: pbc_main
Purpose: Main VCD task loop.
Theory: Primary VCD control loop. All VCD
navigation is handled through here.
Arguments: none
Returns: nothing
*************************************************/
ULONG pbc_main( PVOID pvarg )
{
ULONG msg_com[4];
BOOLEAN fKillVCDTask;
/* init variables */
fKillVCDTask = FALSE;
/* Initialize the task */
pbc_init();
/* Loop forever */
while (fKillVCDTask == FALSE)
{
if (OS_MsgQReceive(queue_vcd, (char *)&msg_com[0], VCD_MSG_SIZE, OS_WAIT_FOREVER) == OS_OK)
{
DBGPRINT(DBG_ON(DBG_VERBOSE), ("%s: Received Message ", __FUNCTION__));
DBGPRINT(DBG_ON(DBG_VERBOSE), ("0x%X, 0x%X, 0x%X, 0x%X\n", msg_com[0], msg_com[1], msg_com[2], msg_com[3]));
switch (msg_com[0])
{
/* Player kill message */
case MSG_PBC_TASK_EXIT:
fKillVCDTask = TRUE;
DBGPRINT(DBG_ON(DBG_ERROR), ("pbc_main() -- MSG_PBC_TASK_EXIT\n"));
continue;
break;
/* Timer has expired */
case MSG_TIM_OUT:
DBGPRINT(DBG_ON(DBG_TRACE), ("pbc_main: MSG_TIM_OUT\n"));
pbc_timeout_proc();
break;
/* keypress from user */
case MSG_KEY:
DBGPRINT(DBG_ON(DBG_TRACE), ("pbc_main: MSG_KEY\n"));
pbc_key_proc(msg_com);
break;
/* End of play item detected */
case MSG_PLAY_END:
DBGPRINT(DBG_ON(DBG_TRACE), ("pbc_main: MSG_PLAY_END\n"));
pbc_play_end();
break;
/* VCD startup */
case MSG_START_VCD:
DBGPRINT(DBG_ON(DBG_TRACE), ("pbc_main: MSG_START_VCD\n"));
pbc_start_vcd();
DBGPRINT(DBG_ON(DBG_TRACE), ("pbc_main: MSG_START_VCD exit\n"));
break;
/* MSF position information mailed back from drive task */
case MSG_FE_LBA:
pbc_fe_msf_rcv((ULONG*)&msg_com[0]);
break;
default:
DbgPrint(("Message not recognized!\n"));
break;
}
update_timedisp_vcd();
}
}
/* clean up the timers */
if (apause_timer != 0)
{
OS_TimerStop(apause_timer);
OS_TimerDelete(apause_timer);
apause_timer = 0;
}
DBGPRINT(DBG_ON(DBG_TRACE), ("pbc_main() exiting\n"));
OS_TaskExit();
return (OS_OK);
}
/*************************************************
Function Name: pbc_init
Purpose: VCD global initialization.
Theory: Global initialization on VCD task
entry.
Arguments: none
Returns: nothing
*************************************************/
void pbc_init(void)
{
ULONG i;
pbc_mode = PBC_MODE_LOAD;
g_scene = 1; /* Default is List ID 1 */
pbc_apause_tim = 0;
g_lot_addr = (USHORT *)OS_MemAlloc(LOT_BUF_SIZE);
if (g_lot_addr == NULL)
{
DBGPRINT(DBG_ON(DBG_TRACE),("Could not allocate memory for g_lot_addr\n"));
}
else
{
memset(g_lot_addr, 0xFF, LOT_BUF_SIZE);
}
g_psd_addr = (UBYTE *)OS_MemAlloc(PSD_BUF_SIZE);
if (g_psd_addr == NULL)
{
DBGPRINT(DBG_ON(DBG_TRACE),("Could not allocate memory for g_psd_addr - FAILURE\n"));
g_current_psd = NULL;
g_previous_psd = NULL;
}
else
{
g_current_psd = g_psd_addr;
g_previous_psd = g_psd_addr;
memset(g_psd_addr, 0xFF, PSD_BUF_SIZE);
}
/* clear out the VCD structures */
memset(&g_toc_info, 0, sizeof(g_toc_info));
memset(&g_info_vcd, 0, sizeof(g_info_vcd));
memset(&g_entry_vcd, 0, sizeof(g_entry_vcd));
memset(&g_tracks_svd, 0, sizeof(g_tracks_svd));
if (g_lot_addr != NULL)
{
/* lot values should be initialized to all 0xF's */
memset(g_lot_addr, 0xFF, LOT_BUF_SIZE);
}
/* SYSTEM */
cdda_track = 0;
g_pbc_on = PBC_OFF;
g_random_mode = PMODE_NORMAL;
g_play_kind = PKIND_STOP;
g_track = 0xFF;
g_time[0] = 0;
g_time[1] = 0;
s_msf[0] = 0xFF;
s_msf[1] = 0xFF;
s_msf[2] = 0xFF;
e_msf[0] = 0xFF;
e_msf[1] = 0xFF;
e_msf[2] = 0xFF;
a_msf[0] = 0xFF;
a_msf[1] = 0xFF;
a_msf[2] = 0xFF;
b_msf[0] = 0xFF;
b_msf[1] = 0xFF;
b_msf[2] = 0xFF;
apause_timer = 0;
logo_on = 0; /* logo onscreen flag */
g_track_prev = 0; /* previous MSF for time display filtering */
VERSION_FLG = 1;
fIsStillPic = 0;
g_pg_play_point = 0;
g_scene = 1;
g_repeat_mode = REPEAT_OFF;
pbc_play_time[0] = 0;
pbc_play_time[1] = 0;
pbc_play_time[2] = 0;
pbc_play_time[3] = 0;
pbc_seg_item = 0;
pbc_loop_count = 1;
pbc_jump_key = 0;
pbc_jump_num = 0;
pbc_play_item_num = 0;
pbc_end_flag = 0;
audio_channel_mode = AUDIO_STEREO;
ulPlaySpeed = 1000;
A_B_count = 0;
g_max_time = 0;
next_prev_key = 0;
cd_max_tno = 0; /* total number of tracks */
cd_max_tno_cdda = 0;
for (i = 0; i <= PROGRAM_MAX; i++)
{
g_pg_entry[i] = 0;
}
g_pg_entry_max = 0;
/* create the autopause timer */
if (OS_TimerCreate(&apause_timer, (OS_FUNCPTR)pbc_apause) != OS_OK)
{
DbgPrint(("OS_TimerCreate: apause_timer FAILED\n"));
}
}
/*************************************************
Function Name: pbc_start_vcd
Purpose: Parse tables and prepare for startup.
Arguments: none
Returns: nothing
*************************************************/
void pbc_start_vcd(void)
{
ULONG msg[4];
CHAR status;
if (load_cd_toc())
{
DbgPrint(("pbc_start_vcd() -- load_cd_toc FAILED\n"));
goto errout;
}
status = get_vcd_info();
if (status < 0)
{
DbgPrint(("pbc_start_vcd() -- get_vcd_info FAILED\n"));
goto errout;
}
msg[0] = VDVD_STATUS_PLAY;
if (UsrEventHandler(msg) != USR_SUCCESS)
{
DbgPrint(("\nUsrEventHandler FAILURE, %s, %d\n\n", __FILE__, __LINE__));
}
/* get first track */
g_track = com_bcdtobin(g_toc_info.tno[1].tno);
if (status == 1)
{
/* PBC play */
g_pbc_on = PBC_ON;
pbc_mode = PBC_MODE_PLAY;
if (pbc_scene_play())
{
goto errout;
}
}
else
{
/* No PBC - just track play */
g_time[0] = 0;
g_time[1] = 0;
g_play_kind = PKIND_PLAY;
ulPlaySpeed = 1000;
pbc_track_play(g_track, PLY_TIM_EOF);
}
fIsStillPic = 0;
return;
errout:
DBGPRINT(DBG_ON(DBG_TRACE), ("pbc_start_vcd: FAILED\n"));
pbc_mode = PBC_MODE_LOAD;
stop_on_error();
return;
}
/*************************************************
Function Name: pbc_play_end
Purpose: VCD end of track handler.
Theory: When the end of a track is detected
via the MSF timer this is called to
decide what to do next.
Arguments: none
Returns: nothing
*************************************************/
void pbc_play_end(void)
{
SELECT_LIST slist; /* Selection List */
PLAY_LIST plist; /* Play List */
ULONG time; /* Play Time */
USHORT pin; /* Play Item Number */
USHORT base;
UBYTE tno;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -