📄 av_play.c
字号:
vcx_stepmode = 1;
vcx_playvideo_only = 1;
if (XPORT_active)
vcx_step_advance = 1;
else
vcx_step_advance = 0;
video_state = VIDEO_STEP;
} else {
if (vcx_step_advance == 0) {
int space_left;
vcx_step_advance = 1;
#if (!CUST3 || CUST71)
/* To avoid VBV buffer overflow, we won't start copying data *
* if there is enough data in buffer */
VBV_update_occupancy(space_left);
space_left = VBV_size - space_left;
if (space_left > 2000)
#endif
playSectors(previous_sector, 0xe0, 2324);
}
}
return (1);
}
/*------------------------------------------------------------------------
Function:
Parameters:
Description:
------------------------------------------------------------------------*/
static int play_fast_init(int mmssff, int end_mmssff)
{
int cd_time;
reset_video_normal_mode(1); /* clear other video/audio variables.*/
vcx_playvideo_only = 1; /* mute mode */
if (data_type == AUDIO_DATA_TYPE) {
cd_time = ((servo_info & 0xffff) << 8);
#ifdef FAST_MODE_CONTROL
/* when FR across track boundary, previous time has to be set differently */
if (video_state == AUDIO_FR && !servo_info)
previous_sector = adjCDtime(endCDtime, 0x0200, -1);
else
previous_sector = adjCDtime(cd_time, play_start_time, 1);
#else
previous_sector = adjCDtime(cd_time, play_start_time, 1);
#endif
} else {
if (XPORT_active) {
/* Stop TDM/DMA and save the last location */
turn_off_data();
}
clear_dec();
previous_sector = stopCDtime;
#ifdef CUST3
vcx_playaudio_only = 0; /* reset FREEZE */
#endif
vcx_fast_forward = 1;
}
#ifdef CUST71
ff_time_limit = end_mmssff;
#endif
#ifndef CUST3
fast_speed_time_limit = end_mmssff;
#else
switch(video_state)
{
case VIDEO_FF:
case AUDIO_FF: fast_speed_time_limit=0x999900;
break;
case VIDEO_FR:
case AUDIO_FR:
#ifdef CUST71
fast_speed_time_limit = end_mmssff;
#else
fast_speed_time_limit=0;
#endif
break;
}
#endif
vcx_fast_speed_done = 0;
skip_mmssff = mmssff;
play_speed_start();
}
/*------------------------------------------------------------------------
Function: av_play_fast_forward
Parameters:
mmssff: The jump time after an I frame is displayed. The format
of mmssff is BCD's 0xmmssff format.
end_mmssff: When the end_mmssff is played, the vcx_fast_speed_done
variable will be set to 1. The called should check
this variable and decide what to do.
Description:
This function will cause the decoder to a fast forward mode.
------------------------------------------------------------------------*/
int av_play_fast_forward(int mmssff, int end_mmssff)
{
video_state = (data_type == VIDEO_DATA_TYPE) ? VIDEO_FF : AUDIO_FF;
play_fast_init(mmssff, end_mmssff);
}
/*------------------------------------------------------------------------
Function:
Parameters:
mmssff: The jump time after an I frame is displayed. The format
of mmssff is BCD's 0xmmssff format.
end_mmssff: When the end_mmssff is played, the vcx_fast_speed_done
variable will be set to 1. The called should check
this variable and decide what to do.
Description:
This function will cause the decoder to a fast rewind mode.
------------------------------------------------------------------------*/
int av_play_fast_rewind(int mmssff, int end_mmssff)
{
video_state = (data_type == VIDEO_DATA_TYPE) ? VIDEO_FR : AUDIO_FR;
#ifdef FAST_MODE_CONTROL
/* FR across track boundary, play_start is the begin time of the current track */
play_start_time = end_mmssff;
#endif
play_fast_init(mmssff, end_mmssff);
}
/*------------------------------------------------------------------------
Function:
Parameters:
Description:
------------------------------------------------------------------------*/
void video_state_machine()
{
int space_left;
int video_buffer_available;
#if (CUST3 && !CUST71)
unsigned int min, sec, frame;
unsigned int stop_time;
IMPORT int CD_status;
IMPORT unsigned char step_pause;
#endif
switch (video_state) {
case VIDEO_SLOW_MOTION:
VBV_update_occupancy(space_left);
space_left = VBV_size - space_left;
#if (!CUST3 || CUST71)
if (XPORT_active) { /* TDM is running */
if (space_left < 4000) {
turn_off_data();
previous_sector = stopCDtime;
#ifndef DVD_VCD
play_sector_state = 0;
/* Re-start immediately after we stopped. */
playSectors_step_by_step(previous_sector, 0xe0, 2324, 1);
#endif
}
} else {
VBV_update_occupancy(video_buffer_available);
#ifdef DVD_VCD
if(video_buffer_available <= 2*vcx_big){
playSectors(previous_sector, 0xe0, 2324);
}
#else
if ((space_left >= VBV_write) || (play_sector_state < 2)||
(video_buffer_available <= 2*vcx_big)) {
playSectors_step_by_step(previous_sector, 0xe0, 2324, 1);
}
#endif
}
#else /* For custrom */
#define NEXT_KEY 0xff0d
if (XPORT_active) { /* TDM is running */
if (previous_sector &&
begCDtime < adjCDtime(currCDtime, 0x0100, -1)) {
/* In this case, currCDtime passes begCDtime so we can't *
* start decoding unless we make some adjustment. Also *
* don't hang on here, it maybe a scratch on disc */
previous_sector = begCDtime =
adjCDtime(previous_sector, 0x10, 1);
/* commented this line for smooth transition to slow, but may cause hang!
goto play_it;
*/
}
if (space_left < 2500) {
turn_off_data();
dsa_cmd(DSA_PAUSE_AHEAD, 0, 0, 0);
stop_time = glbTimer;
previous_sector = stopCDtime;
}
} else {
if (space_left >= 4000) {
/* Go To where we stopped */
if (previous_sector) /* previous sector may be */
/* incidentally set to 0 */
begCDtime = previous_sector;
play_it:
min = (begCDtime & 0xff0000) >> 16;
sec = (begCDtime & 0xff00) >> 8;
frame = begCDtime & 0xff;
dsa_cmd(DSA_GO_MSF, min, sec, frame);
vcx_pause = 0;
XPORT_play20video(XPORT_OFFSET_PLAY_SECTOR, 0xe0);
TDM_turn_on();
XPORT_active = 1;
}
#if 0 /* Temporarily disable it because CD_status can not be updated *
* in time */
else if ((stop_time + FOUR_SECOND < glbTimer) &&
(CD_status == SERVO_ACCESS) ) {
/* Conclusion : reach end of track, go to next */
current_key = NEXT_KEY;
#ifdef CUST3_63
dsa_cmd(DSA_COMMAND,DSA_MUTEOFF,0,0);
#endif
}
#endif
}
#endif
if (slow_resume && XPORT_active) {
DISP_limit = 1;
reset_video_normal_mode(0);
slow_resume = 0;
video_state = VIDEO_INIT_STATE;
}
break;
case AUDIO_FF:
case AUDIO_FR:
if ((glbTimer - timeout_begin_time) >= ONE_SECOND) {
play_speed_start();
}
break;
case VIDEO_FF:
case VIDEO_FR:
/* Don't hang on here waiting for vcx_pause_ack. (for bad disc) */
if (vcx_pause_ack || (glbTimer - timeout_begin_time) >= THREE_SECOND) {
vcx_pause_ack = 0;
play_speed_start();
}
break;
case VIDEO_STILL:
video_state = VIDEO_DO_STILL;
break;
case VIDEO_DO_STILL:
start_play_still();
video_state = VIDEO_NORMAL;
break;
case VIDEO_STEP:
if (vcx_step_advance == 0) {
#ifdef CUST71
dsa_pause();
cd_pause = 1;
#endif
if (XPORT_active) {
/* Stop TDM/DMA and save the last location */
turn_off_data();
#if (CUST3 && !CUST71)
dsa_cmd(DSA_COMMAND, DSA_PAUSE, 0,0);
step_pause = 1;
#endif
}
/* Record the CD location when DMA is turned off */
previous_sector = stopCDtime;
}
break;
case VIDEO_WAIT_TIMEOUT:
/* we wait for 0.5 second, so the vbv/avb will be in good
state. */
if ((glbTimer - timeout_begin_time) >= HALF_SECOND)
video_state = VIDEO_INIT_STATE;
break;
default:
#ifdef CUST3
/* keep on updating previous_sector */
previous_sector = currCDtime;
#endif
if (set_pause) {
av_play_pause();
set_pause = 0;
}
break;
}
}
static int play_speed_start()
{
int cd_time;
vcx_interupt_FrameCount_pause = 0;
cd_time = previous_sector;
if ((video_state == VIDEO_FF) || (video_state == AUDIO_FF)) {
#ifdef CUST71
if ((video_state == AUDIO_FF) &&
((adjCDtime(cd_time,0x1000,1)) > ff_time_limit)) {
vcx_fast_speed_done = 1;
}
#endif
cd_time = adjCDtime(cd_time, skip_mmssff, 1);
/* need to check the end time */
if (cd_time >= fast_speed_time_limit) {
cd_time = fast_speed_time_limit;
vcx_fast_speed_done = 1;
#ifdef CUST71
OSD_clear_region(FUNCTION_REGION);
#endif
}
}
if ((video_state == VIDEO_FR) || (video_state == AUDIO_FR)) {
cd_time = adjCDtime(cd_time, skip_mmssff, -1);
/* need to check start time */
if (cd_time <= fast_speed_time_limit) {
vcx_fast_speed_done = 1;
#ifdef CUST71
OSD_clear_region(FUNCTION_REGION);
#endif
return (1);
}
}
previous_sector = cd_time; /* store current time point */
timeout_begin_time = glbTimer;
if (data_type == AUDIO_DATA_TYPE) {
playCDDA(cdda_track_start_time, cd_time, endCDtime);
return (1);
}
/* set the interrupt framecount */
/* stop decoder when "fast_frame" frame is displayed */
vcx_interupt_FrameCount = VID_frame_count + 1;
vcx_interupt_FrameCount_pause = VC_PAUSE;
clear_dec();
fuzzyPlaySector(cd_time, 2324);
return (1);
}
/*------------------------------------------------------------------------
Function:
Parameters:
Description:
------------------------------------------------------------------------*/
void av_reset()
{
reset_video_normal_mode(1);
video_state= VIDEO_INIT_STATE;
}
/*------------------------------------------------------------------------
Function:reset_video_normal_mode
Parameters:
Description:
This function resets vcx_variables back to the state that normal
play will be in a good start state.
------------------------------------------------------------------------*/
int reset_video_normal_mode(int reset)
{
/* set the audio to clean state. */
if (reset) AUD_init();
/* variables set in FF/FR state */
vcx_playvideo_only = 0;
vcx_playaudio_only = 0;
vcx_interupt_FrameCount_pause = 0;
vcx_fast_forward = 0;
vcx_pause = vcx_pause_ack = 0;
vcx_fast_speed_done = 0;
/* variable set in slow state */
vcx_slow_motion = 0;
/* variable set in step state */
vcx_stepmode = 0;
vcx_step_advance = 0;
#ifdef CUST71
SET_MUTEOFF;
#endif
/* start decode for the first I frame */
if (reset)
VID_first_time_seek = 1;
if (cd_pause) {
dsa_pauserelease();
cd_pause = 0;
}
}
/* clear decoder buffer */
void clear_dec(void)
{
system_reset();
system_start();
}
#if (CUST3 && !CUST71)
/*
* Force to play as video
*/
av_play_video()
{
extern char play_item_info_type;
TDM_isCDDA = 0;
clear_dec();
XPORT_play20video(XPORT_OFFSET_FUZZY_PLAY, 0xe0);
TDM_turn_on();
play_item_info_type = DATA_TRACK;
data_type = VIDEO_DATA_TYPE;
video_state = VIDEO_NORMAL;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -