📄 vid_atom.c
字号:
while((iTempSize > 0) && (segnum < 7)) { segnum++; segaddr += 0x00100000<<segsize; addr = ulTempAddr; PDEBUG("segnum = %d, segaddr = 0x%8.8x, addr = 0x%8.8x\n",segnum,segaddr,addr); if(iTempSize > 0x01000000) iIncrementSize = 0x01000000; else iIncrementSize = iTempSize; PDEBUG("iTempSize = 0x%8.8x\n",iTempSize); PDEBUG("iIncrementSize = 0x%8.8x\n",iIncrementSize); PDEBUG("addr & 0x000FFFFF = 0x%8.8x\n",(addr & 0x000FFFFF)); i = ((addr & 0x000FFFFF)+iIncrementSize-1)>>20; PDEBUG("i = 0x%8.8x\n",i); for(segsize = 0; i != 0; segsize++) { i = i>>1; } if(segsize>4){ //max segment siz is 4 (16MB) segsize=4; } videoMemSize+=1<<segsize; PDEBUG("segsize = %d, increment size = 0x%8.8x\n",segsize,iIncrementSize); segreg=(segsize<<12)|((addr&0xFFF00000)>>20); PDEBUG("\nsegnum %d is being set to 0x%8.8x for graphics plane. segment size = %d\n",segnum, segreg, segsize); __vid_init_segment_reg(segnum, segsize,addr); iTempSize-=iIncrementSize; ulTempAddr+=iIncrementSize; } if(iTempSize > 0) printk("vid_atom_init: unable to allocate all the memory in the video segments\n"); } /*-------------------------------------------------------------------------+ | Set display control for errta +--------------------------------------------------------------------------*/ //reg = MF_DCR(VID_DISP_CNTL); //MT_DCR(VID_DISP_CNTL, reg | 0x000000C0); /*-------------------------------------------------------------------------+ | Define top and left borders, and display delay. Set top border in the | letterbox mode (number of lines from the top of the display). +-------------------------------------------------------------------------*/ MT_DCR(VID_DISP_BOR, 0); MT_DCR(VID_LBOX, 0); /*-------------------------------------------------------------------------+ | Set display mode. Right now the external and internal DENC both use the | leading sync mode. +-------------------------------------------------------------------------*/ MT_DCR(VID_DISP_MODE, DECOD_DISP_MODE_BK_BLACK | DECOD_DISP_MODE_TRANS_POL_LOW | DECOD_DISP_MODE_SYNC_LEADING); /*-------------------------------------------------------------------------+ | Set PTS control. PTS filter set to 728ms (90Khz clock), or 621ms (27Mhz | clock (32* 22.76ms, or 32* 19.42ms). +-------------------------------------------------------------------------*/ MT_DCR(VID_PTS_CTRL, 32); /*-------------------------------------------------------------------------+ | Set display delay for denc +-------------------------------------------------------------------------*/ MT_DCR(VID_DISP_DLY, uDispDelay); return 0;}/*----------------------------------------------------------------------------+| Config_video_modes.+----------------------------------------------------------------------------*/INT vid_atom_config_vdec(VDEC_CON *pVdec){ unsigned long reg; VIDEOCMD vc; /*-------------------------------------------------------------------------+ | Load video microcode. This is required for the rest of the | initialization. +-------------------------------------------------------------------------*/ if( vid_atom_load_microcode((USHORT*)vid_ucode, vid_ucode_len/2) != 0) { PDEBUG("load microcode failed\n"); return (-1); } PDEBUG("load microcode OK\n"); /*-------------------------------------------------------------------------+ | Start video processor | +-------------------------------------------------------------------------*/ reg = DECOD_CHIP_CONTROL_SVP | DECOD_CHIP_CONTROL_DIS_SYNC;#ifdef VID_BLANK_ENABLE reg |= DECOD_CHIP_CONTROL_BLANK_VID;#endif MT_DCR(VID_CHIP_CTRL, reg); /*------------------------------------------------------------------------- | Set user data base +--------------------------------------------------------------------------*/ pVdec->user.ulVideoLogicalAddr=guUserVideoOffset;// MT_DCR(VID_USERDATA_BASE, pVdec->user.uAddr / DECOD_MEM_ALIGN); MT_DCR(VID_USERDATA_BASE,pVdec->user.ulVideoLogicalAddr / DECOD_MEM_ALIGN); PDEBUG("user data video logical addr = 0x%08x setting user base = 0x%08x\n", pVdec->user.ulVideoLogicalAddr, pVdec->user.ulVideoLogicalAddr / DECOD_MEM_ALIGN); /*------------------------------------------------------------------------- | Set VBI0 and VBI1 data base +--------------------------------------------------------------------------*/ if (VID_VBI_LINES > 0) { reg = (((guVBI0VideoOffset / DECOD_MEM_ALIGN)<<16) & 0x7FFF0000); reg |= ((guVBI1VideoOffset / DECOD_MEM_ALIGN) & 0x00007FFF); MT_DCR(VID_VBI_BASE, reg); PDEBUG("Setting VBI0 base = 0x%08x\n", guVBI0VideoOffset / DECOD_MEM_ALIGN); PDEBUG("Setting VBI1 base = 0x%08x\n", guVBI1VideoOffset / DECOD_MEM_ALIGN); PDEBUG("Setting number VBI lines = 0x%08x\n", VID_VBI_LINES); } /*------------------------------------------------------------------------- | Set rate buffer base and size +--------------------------------------------------------------------------*/ pVdec->ratebuf.ulVideoLogicalAddr=guRBVideoOffset;// MT_DCR(VID_RB_BASE, pVdec->ratebuf.uAddr / DECOD_MEM_ALIGN); MT_DCR(VID_RB_BASE, pVdec->ratebuf.ulVideoLogicalAddr / DECOD_MEM_ALIGN); MT_DCR(VID_RB_SIZE, pVdec->ratebuf.uLen / DECOD_RB_ALIGN); PDEBUG("ratebuf video logical base addr = 0x%08x setting rate base reg to 0x%08x\n", pVdec->ratebuf.ulVideoLogicalAddr, pVdec->ratebuf.ulVideoLogicalAddr / DECOD_MEM_ALIGN); PDEBUG("ratebuf size =0x%08x setting rate size reg to 0x%08x\n", pVdec->ratebuf.uLen, pVdec->ratebuf.uLen / DECOD_RB_ALIGN); /*------------------------------------------------------------------------- | Set frame buffer base +--------------------------------------------------------------------------*/ if(_fmt == DENC_MODE_NTSC) { pVdec->framebuf.ulVideoLogicalAddr=guFBVideoOffset+0x21d00; // use 0x21d00 for NTSC on Vulcan } else { pVdec->framebuf.ulVideoLogicalAddr=guFBVideoOffset+0x16900; // use 0x16900 for PAL on Vulcan } reg = MF_DCR(VID_FRAME_BUF) & (~0x00007FFF);// reg |= ((pVdec->framebuf.uAddr / DECOD_MEM_ALIGN) & 0x00007FFF); reg |= ((pVdec->framebuf.ulVideoLogicalAddr / DECOD_MEM_ALIGN) & 0x00007FFF); MT_DCR(VID_FRAME_BUF, reg); PDEBUG("framebuf.uAddr = 0x%08x\n", pVdec->framebuf.uAddr); PDEBUG("framebuf.uLen = 0x%08x\n", pVdec->framebuf.uLen); PDEBUG("framebuf.ulLogicalAddr = 0x%08x\n", pVdec->framebuf.ulLogicalAddr); PDEBUG("framebuf.ulVideoLogicalAddr = 0x%08x\n", pVdec->framebuf.ulVideoLogicalAddr); PDEBUG("framebuf video logical base addr = 0x%08x setting framebuf base reg to 0x%08x\n", pVdec->framebuf.ulVideoLogicalAddr,pVdec->framebuf.ulVideoLogicalAddr / DECOD_MEM_ALIGN); /*-------------------------------------------------------------------------+ | Load configuration parameters and execute configuration command. +-------------------------------------------------------------------------*/ vc.uCmd = DECOD_COM_CONF; vc.uNum = 1; vc.uPara[0] = 0; vc.uChained = 0; vc.uRetry = DECOD_TIMEOUT; if (vid_atom_exec_cmd(&vc) != 0) { PDEBUG("execute config command failed\n"); return -1; }#ifdef __DRV_FOR_PALLAS__ /*-------------------------------------------------------------------------+ | Execute 'set display regs' command +-------------------------------------------------------------------------*/ vc.uCmd =0x20; vc.uNum = 0; vc.uPara[0] = 0; vc.uChained = 0; vc.uRetry = DECOD_TIMEOUT; if (vid_atom_exec_cmd(&vc) != 0) { PDEBUG("set display regs command failed\n"); return -1; }#endif _initial_cc = 1; PDEBUG("config video mode OK\n"); return (0);}/*-------------------------------------------------------------------| MPEG video play+-------------------------------------------------------------------*/INT vid_atom_play(){ unsigned long reg; VIDEOCMD vc; // normal play reg = MF_DCR(VID_CHIP_CTRL);#ifdef VID_BLANK_ENABLE reg |= DECOD_CHIP_CONTROL_BLANK_VID;#endif vc.uCmd = DECOD_COM_PLAY; vc.uNum = 0; vc.uChained = 0; vc.uRetry = DECOD_TIMEOUT; if (vid_atom_exec_cmd(&vc) != 0) { PDEBUG("exec video play error\n"); return -1; } reg |= DECOD_CHIP_CONTROL_SVP | DECOD_CHIP_CONTROL_SVD; MT_DCR(VID_CHIP_CTRL, reg);//sync problem/* if (get_vid_sync() != 0) DEMUX_PCR_CALLBACK(XP_CALLBACK_RUN);*/ //vid_atom_enable_sync(); _initial_cc = 0; return (0);}void vid_atom_stop(){ unsigned long reg; vid_atom_disable_sync(); reg = MF_DCR(VID_CHIP_CTRL) & (~(DECOD_CHIP_CONTROL_SVD)) ; MT_DCR(VID_CHIP_CTRL, reg);}/*WARNING: This function may result in re-schedule*/INT vid_atom_ps_wait(){ int i = 0; while (1) { if (++i >= 20) { PDEBUG("PAUSE wait overtime\n"); return (-1); } if (__PS_SF_COMPLETE != 0) return 0; os_sleep(1); } return (0);}INT vid_atom_pause(){ VIDEOCMD vc; PDEBUG("video paused\n"); vid_atom_disable_sync(); // set display to first field only vid_atom_set_sfm(VID_SFM_FIRST_ONLY); __PS_SF_COMPLETE = 0; vc.uCmd = DECOD_COM_PAUSE; vc.uNum = 0; vc.uChained = 0; vc.uRetry = DECOD_TIMEOUT; if (vid_atom_exec_cmd(&vc) != 0) { PDEBUG("exec video freeze frame error\n"); return -1; } if(vid_atom_ps_wait() != 0) return -1; return 0;}/*WARNING: This function may result in re-schedule*/INT vid_atom_ff_wait(){ int i = 0; int rc = 0; __FF_COMPLETE = 0; __FF_PENDING = 1; vid_atom_set_irq_mask(vid_atom_get_irq_mask() | DECOD_HOST_MASK_PSTART); while (1) { if (++i >= 20) { PDEBUG("FFRAME wait overtime\n"); rc = -1; break; } if (__FF_COMPLETE != 0) break; os_sleep(1); } __FF_PENDING = 0; __FF_COMPLETE = 0; return (rc);}//video freeze only freeze screen but decoder keep on runningINT vid_atom_freeze(){ VIDEOCMD vc; vid_atom_disable_sync(); // set display to first field only vid_atom_set_sfm(VID_SFM_FIRST_ONLY); vc.uCmd = DECOD_COM_FFRAME; vc.uNum = 1; vc.uPara[0] = 0; vc.uChained = 0; vc.uRetry = DECOD_TIMEOUT; if (vid_atom_exec_cmd(&vc) != 0) { PDEBUG("exec video freeze frame error\n"); return -1; } if( vid_atom_ff_wait() != 0 ) { return -1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -