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

📄 av_play.c

📁 一个两碟控制的VCD的代码,两碟之间的转动及连续播放,已大量生产的CODE.
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -