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

📄 mach64_vid.c

📁 原名叫avifile
💻 C
📖 第 1 页 / 共 3 页
字号:
			  config->dest.pitch.v = best_pitch;			  besr.vid_buf_pitch= pitch>>1;			  break;    }    dest_w = config->dest.w;    dest_h = config->dest.h;    besr.fourcc = config->fourcc;    ecp = (INPLL(PLL_VCLK_CNTL) & PLL_ECP_DIV) >> 4;#if 0{int i;for(i=0; i<32; i++){    printf("%X ", INPLL(i));}}#endif    if(__verbose>0) printf("[mach64] ecp: %d\n", ecp);    v_inc = src_h * mach64_get_vert_stretch();        if(mach64_is_interlace()) v_inc<<=1;    if(mach64_is_dbl_scan() ) v_inc>>=1;    v_inc/= dest_h;    v_inc>>=4; // convert 16.16 -> 4.12    h_inc = (src_w << (12+ecp)) / dest_w;    /* keep everything in 4.12 */    config->offsets[0] = 0;    for(i=1; i<config->num_frames; i++)        config->offsets[i] = config->offsets[i-1] + config->frame_size;    	/*FIXME the left / top stuff is broken (= zoom a src rectangle from a larger one)		1. the framesize isnt known as the outer src rectangle dimensions arent known		2. the mach64 needs aligned addresses so it cant work anyway		   -> so we could shift the outer buffer to compensate that but that would mean		      alignment problems for the code which writes into it	*/        if(is_420)    {	config->offset.y= 0;	config->offset.u= (pitch*src_h + 15)&~15; 	config->offset.v= (config->offset.u + (pitch*src_h>>2) + 15)&~15;		src_offset_y= config->offset.y + top*pitch + left;	src_offset_u= config->offset.u + (top*pitch>>2) + (left>>1);	src_offset_v= config->offset.v + (top*pitch>>2) + (left>>1);	if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV)	{	  uint32_t tmp;	  tmp = config->offset.u;	  config->offset.u = config->offset.v;	  config->offset.v = tmp;	  src_offset_u=config->offset.u;	  src_offset_v=config->offset.v;	}    }    else if(besr.fourcc == IMGFMT_YVU9)    {	config->offset.y= 0;	config->offset.u= (pitch*src_h + 15)&~15; 	config->offset.v= (config->offset.u + (pitch*src_h>>4) + 15)&~15;		src_offset_y= config->offset.y + top*pitch + left;	src_offset_u= config->offset.u + (top*pitch>>4) + (left>>1);	src_offset_v= config->offset.v + (top*pitch>>4) + (left>>1);    }    else if(besr.fourcc == IMGFMT_BGR32)    {      config->offset.y = config->offset.u = config->offset.v = 0;      src_offset_y= src_offset_u= src_offset_v= top*pitch + (left << 2);    }    else    {      config->offset.y = config->offset.u = config->offset.v = 0;      src_offset_y= src_offset_u= src_offset_v= top*pitch + (left << 1);    }    num_mach64_buffers= config->num_frames;    for(i=0; i<config->num_frames; i++)    {	mach64_buffer_base[i][0]= (mach64_overlay_offset + config->offsets[i] + src_offset_y)&~15;	mach64_buffer_base[i][1]= (mach64_overlay_offset + config->offsets[i] + src_offset_u)&~15;	mach64_buffer_base[i][2]= (mach64_overlay_offset + config->offsets[i] + src_offset_v)&~15;    }    leftUV = (left >> 17) & 15;    left = (left >> 16) & 15;    besr.scale_inc = ( h_inc << 16 ) | v_inc;    y_pos = config->dest.y;    if(mach64_is_dbl_scan()) y_pos*=2;    else    if(mach64_is_interlace()) y_pos/=2;    besr.y_x_start = y_pos | (config->dest.x << 16);    y_pos =config->dest.y + dest_h;    if(mach64_is_dbl_scan()) y_pos*=2;    else    if(mach64_is_interlace()) y_pos/=2;    besr.y_x_end = y_pos | ((config->dest.x + dest_w) << 16);    besr.height_width = ((src_w - left)<<16) | (src_h - top);    return 0;}static int is_supported_fourcc(uint32_t fourcc){    switch(fourcc)    {    case IMGFMT_YV12:    case IMGFMT_I420:    case IMGFMT_YVU9:    case IMGFMT_IYUV:	return supports_planar;    case IMGFMT_YUY2:    case IMGFMT_UYVY:    case IMGFMT_BGR15:    case IMGFMT_BGR16:    case IMGFMT_BGR32:	return 1;    default:	return 0;    }}int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to){    if(is_supported_fourcc(to->fourcc))    {	to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP |		    VID_DEPTH_4BPP | VID_DEPTH_8BPP |		    VID_DEPTH_12BPP| VID_DEPTH_15BPP|		    VID_DEPTH_16BPP| VID_DEPTH_24BPP|		    VID_DEPTH_32BPP;	to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY;	return 0;    }    else  to->depth = to->flags = 0;    return ENOSYS;}int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info){  unsigned rgb_size,nfr;  uint32_t mach64_video_size;  if(!is_supported_fourcc(info->fourcc)) return ENOSYS;  if(info->src.h > 720 || info->src.w > 720)  {    printf("[mach64] Can't apply width or height > 720\n");    return EINVAL;  }  if(info->num_frames>VID_PLAY_MAXFRAMES) info->num_frames=VID_PLAY_MAXFRAMES;  mach64_compute_framesize(info);  rgb_size = mach64_get_xres()*mach64_get_yres()*((mach64_vid_get_dbpp()+7)/8);  nfr = info->num_frames;  mach64_video_size = mach64_ram_size;  for(;nfr>0;nfr--)  {      mach64_overlay_offset = mach64_video_size - info->frame_size*nfr;      mach64_overlay_offset &= 0xffff0000;      if(mach64_overlay_offset >= (int)rgb_size ) break;  }  if(nfr <= 3)  {   nfr = info->num_frames;   for(;nfr>0;nfr--)   {      mach64_overlay_offset = mach64_video_size - info->frame_size*nfr;      mach64_overlay_offset &= 0xffff0000;      if(mach64_overlay_offset>=0) break;   }  }  if(nfr <= 0) return EINVAL;  info->num_frames=nfr;  num_mach64_buffers = info->num_frames;  info->dga_addr = (char *)mach64_mem_base + mach64_overlay_offset;  mach64_vid_init_video(info);  return 0;}int VIDIX_NAME(vixPlaybackOn)(void){  int err;  unsigned dw,dh;  dw = (besr.y_x_end >> 16) - (besr.y_x_start >> 16);  dh = (besr.y_x_end & 0xFFFF) - (besr.y_x_start & 0xFFFF);  if(dw == mach64_get_xres() || dh == mach64_get_yres()) mach64_vid_exclusive();  else mach64_vid_non_exclusive();  mach64_vid_display_video();  err = INREG(SCALER_BUF_PITCH) == besr.vid_buf_pitch ? 0 : EINTR;  if(err)  {    printf("[mach64] *** Internal fatal error ***: Detected pitch corruption\n"	   "[mach64] Try decrease number of buffers\n");  }  return err;}int VIDIX_NAME(vixPlaybackOff)(void){  mach64_vid_stop_video();  return 0;}int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame){    uint32_t off[6];    int i;    int last_frame= (frame-1+num_mach64_buffers) % num_mach64_buffers;    /*    buf3-5 always should point onto second buffer for better    deinterlacing and TV-in    */    if(num_mach64_buffers==1) return 0;    for(i=0; i<3; i++)    {    	off[i]  = mach64_buffer_base[frame][i];    	off[i+3]= mach64_buffer_base[last_frame][i];    }    if(__verbose > VERBOSE_LEVEL) printf("mach64_vid: flip_page = %u\n",frame);#if 0 // delay routine so the individual frames can be ssen better{volatile int i=0;for(i=0; i<10000000; i++);}#endif    mach64_wait_for_idle();    mach64_fifo_wait(7);    OUTREG(SCALER_BUF0_OFFSET,		off[0]);    OUTREG(SCALER_BUF0_OFFSET_U,	off[1]);    OUTREG(SCALER_BUF0_OFFSET_V,	off[2]);    OUTREG(SCALER_BUF1_OFFSET,		off[3]);    OUTREG(SCALER_BUF1_OFFSET_U,	off[4]);    OUTREG(SCALER_BUF1_OFFSET_V,	off[5]);    if(num_mach64_buffers==2) mach64_wait_vsync(); //only wait for vsync if we do double buffering           if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs();    return 0;}vidix_video_eq_t equal ={ VEQ_CAP_BRIGHTNESS | VEQ_CAP_SATURATION , 0, 0, 0, 0, 0, 0, 0, 0 };int 	VIDIX_NAME(vixPlaybackGetEq)( vidix_video_eq_t * eq){  memcpy(eq,&equal,sizeof(vidix_video_eq_t));  if(!supports_colour_adj) eq->cap = VEQ_CAP_BRIGHTNESS;  return 0;}int 	VIDIX_NAME(vixPlaybackSetEq)( const vidix_video_eq_t * eq){  int br,sat;    if(eq->cap & VEQ_CAP_BRIGHTNESS) equal.brightness = eq->brightness;    if(eq->cap & VEQ_CAP_CONTRAST)   equal.contrast   = eq->contrast;    if(eq->cap & VEQ_CAP_SATURATION) equal.saturation = eq->saturation;    if(eq->cap & VEQ_CAP_HUE)        equal.hue        = eq->hue;    if(eq->cap & VEQ_CAP_RGB_INTENSITY)    {      equal.red_intensity   = eq->red_intensity;      equal.green_intensity = eq->green_intensity;      equal.blue_intensity  = eq->blue_intensity;    }    if(supports_colour_adj)    {	equal.flags = eq->flags;	br = equal.brightness * 64 / 1000;	if(br < -64) br = -64; if(br > 63) br = 63;	sat = (equal.saturation + 1000) * 16 / 1000;	if(sat < 0) sat = 0; if(sat > 31) sat = 31;	OUTREG(SCALER_COLOUR_CNTL, (br & 0x7f) | (sat << 8) | (sat << 16));    }    else    {	unsigned gamma;	br = equal.brightness * 3 / 1000;	if(br < 0) br = 0;	switch(br)	{	    default:gamma = SCALE_GAMMA_SEL_BRIGHT; break;	    case 1: gamma = SCALE_GAMMA_SEL_G14; break;	    case 2: gamma = SCALE_GAMMA_SEL_G18; break;	    case 3: gamma = SCALE_GAMMA_SEL_G22; break;	}	OUTREG(OVERLAY_SCALE_CNTL,(INREG(OVERLAY_SCALE_CNTL) & ~SCALE_GAMMA_SEL_MSK) | gamma);    }  return 0;}int VIDIX_NAME(vixGetGrKeys)(vidix_grkey_t *grkey){    memcpy(grkey, &mach64_grkey, sizeof(vidix_grkey_t));    return(0);}int VIDIX_NAME(vixSetGrKeys)(const vidix_grkey_t *grkey){    memcpy(&mach64_grkey, grkey, sizeof(vidix_grkey_t));    if(mach64_grkey.ckey.op == CKEY_TRUE)    {	besr.ckey_on=1;	switch(mach64_vid_get_dbpp())	{	case 15:		besr.graphics_key_msk=0x7FFF;		besr.graphics_key_clr=			  ((mach64_grkey.ckey.blue &0xF8)>>3)			| ((mach64_grkey.ckey.green&0xF8)<<2)			| ((mach64_grkey.ckey.red  &0xF8)<<7);		break;	case 16:		besr.graphics_key_msk=0xFFFF;		besr.graphics_key_clr=			  ((mach64_grkey.ckey.blue &0xF8)>>3)			| ((mach64_grkey.ckey.green&0xFC)<<3)			| ((mach64_grkey.ckey.red  &0xF8)<<8);		break;	case 24:		besr.graphics_key_msk=0xFFFFFF;		besr.graphics_key_clr=			  ((mach64_grkey.ckey.blue &0xFF))			| ((mach64_grkey.ckey.green&0xFF)<<8)			| ((mach64_grkey.ckey.red  &0xFF)<<16);		break;	case 32:		besr.graphics_key_msk=0xFFFFFF;		besr.graphics_key_clr=			  ((mach64_grkey.ckey.blue &0xFF))			| ((mach64_grkey.ckey.green&0xFF)<<8)			| ((mach64_grkey.ckey.red  &0xFF)<<16);		break;	default:		besr.ckey_on=0;		besr.graphics_key_msk=0;		besr.graphics_key_clr=0;	}    }    else    {	besr.ckey_on=0;	besr.graphics_key_msk=0;	besr.graphics_key_clr=0;    }    mach64_fifo_wait(4);    OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk);    OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr);//    OUTREG(OVERLAY_VIDEO_KEY_MSK, 0);//    OUTREG(OVERLAY_VIDEO_KEY_CLR, 0);    if(besr.ckey_on)    	OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND);    else    	OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_TRUE|CMP_MIX_AND);    return(0);}#ifdef MACH64_ENABLE_BMstatic int mach64_setup_frame( vidix_dma_t * dmai ){    if(mach64_overlay_offset + dmai->dest_offset + dmai->size > mach64_ram_size) return E2BIG;    if(dmai->idx > VID_PLAY_MAXFRAMES-1) dmai->idx=0;    if(!(dmai->internal[dmai->idx] && (dmai->flags & BM_DMA_FIXED_BUFFS)))    {	bm_list_descriptor * list = (bm_list_descriptor *)mach64_dma_desc_base[dmai->idx];	unsigned long dest_ptr;	unsigned i,n,count;	int retval;	n = dmai->size / 4096;	if(dmai->size % 4096) n++;	if((retval = VIRT_TO_CARD(dmai->src,dmai->size,dma_phys_addrs)) != 0) return retval;	dmai->internal[dmai->idx] = mach64_dma_desc_base[dmai->idx];	dest_ptr = dmai->dest_offset;	count = dmai->size;#if 0printf("MACH64_DMA_REQUEST va=%X size=%X\n",dmai->src,dmai->size);#endif	for(i=0;i<n;i++)	{	    list[i].framebuf_offset = mach64_overlay_offset + dest_ptr; /* offset within of video memory */	    list[i].sys_addr = dma_phys_addrs[i];	    list[i].command = (count > 4096 ? 4096 : (count | DMA_GUI_COMMAND__EOL));	    list[i].reserved = 0;#if 0printf("MACH64_DMA_TABLE[%i] fboff=%X pa=%X cmd=%X rsrvd=%X\n",i,list[i].framebuf_offset,list[i].sys_addr,list[i].command,list[i].reserved);#endif	    dest_ptr += 4096;	    count -= 4096;	}	cpu_flush(list,4096);    }    return 0;}static int mach64_transfer_frame( unsigned long ba_dma_desc,int sync_mode ){    uint32_t crtc_int;    mach64_wait_for_idle();    mach64_fifo_wait(4);    OUTREG(BUS_CNTL,(INREG(BUS_CNTL)|BUS_EXT_REG_EN)&(~BUS_MASTER_DIS));    crtc_int = INREG(CRTC_INT_CNTL);    if(sync_mode && can_use_irq) OUTREG(CRTC_INT_CNTL,crtc_int|CRTC_BUSMASTER_EOL_INT|CRTC_BUSMASTER_EOL_INT_EN);    else			 OUTREG(CRTC_INT_CNTL,crtc_int|CRTC_BUSMASTER_EOL_INT);    OUTREG(BM_SYSTEM_TABLE,ba_dma_desc|SYSTEM_TRIGGER_SYSTEM_TO_VIDEO);    if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs();    #if 0    mach64_fifo_wait(4);    mach64_fifo_wait(16);    printf("MACH64_DMA_DBG: bm_fb_off=%08X bm_sysmem_addr=%08X bm_cmd=%08X bm_status=%08X bm_agp_base=%08X bm_agp_cntl=%08X\n",	    INREG(BM_FRAME_BUF_OFFSET),	    INREG(BM_SYSTEM_MEM_ADDR),	    INREG(BM_COMMAND),	    INREG(BM_STATUS),	    INREG(AGP_BASE),	    INREG(AGP_CNTL));#endif    return 0;}int VIDIX_NAME(vixQueryDMAStatus)( void ){    int bm_off;    unsigned crtc_int_cntl;    mach64_wait_for_idle();    mach64_fifo_wait(2);    crtc_int_cntl = INREG(CRTC_INT_CNTL);    bm_off = crtc_int_cntl & CRTC_BUSMASTER_EOL_INT;//    if(bm_off) OUTREG(CRTC_INT_CNTL,crtc_int_cntl | CRTC_BUSMASTER_EOL_INT);    return bm_off?0:1;}int VIDIX_NAME(vixPlaybackCopyFrame)( vidix_dma_t * dmai ){    int retval,sync_mode;    if(!(dmai->flags & BM_DMA_FIXED_BUFFS)) if(bm_lock_mem(dmai->src,dmai->size) != 0) return errno;    sync_mode = (dmai->flags & BM_DMA_SYNC) == BM_DMA_SYNC;    if(sync_mode)    {	if(!irq_installed) init_irq();	/* burn CPU instead of PCI bus here */	while(vixQueryDMAStatus()!=0){	    if(can_use_irq)	hwirq_wait(pci_info.irq);	    else		usleep(0); /* ugly but may help */	}    }    mach64_engine_reset();    retval = mach64_setup_frame(dmai);    VIRT_TO_CARD(mach64_dma_desc_base[dmai->idx],1,&bus_addr_dma_desc);    if(retval == 0) retval = mach64_transfer_frame(bus_addr_dma_desc,sync_mode);    if(!(dmai->flags & BM_DMA_FIXED_BUFFS)) bm_unlock_mem(dmai->src,dmai->size);    return retval;}#endif

⌨️ 快捷键说明

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