📄 radeon_video.c
字号:
CARD8 a; int i; pPriv->theatre = NULL; if(!info->MM_TABLE_valid && !((info->RageTheatreCrystal>=0) && (info->RageTheatreTunerPort>=0) && (info->RageTheatreCompositePort>=0) && (info->RageTheatreSVideoPort>=0))) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no multimedia table present, disabling Rage Theatre.\n"); return; } /* Go and find Rage Theatre, if it exists */ switch(info->Chipset){ case PCI_CHIP_RADEON_LY: case PCI_CHIP_RADEON_LZ: xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M6, not scanning for Rage Theatre\n"); break; case PCI_CHIP_RADEON_LW: xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M7, not scanning for Rage Theatre\n"); break; default: pPriv->theatre=xf86_DetectTheatre(pPriv->VIP); } if(pPriv->theatre==NULL)return; /* just a matter of convenience */ t=pPriv->theatre; t->video_decoder_type=info->video_decoder_type; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type is 0x%04x (BIOS value) versus 0x%04x (current PLL setting)\n", t->video_decoder_type, pll->xclk); if(info->MM_TABLE_valid){ for(i=0;i<5;i++){ a=info->MM_TABLE.input[i]; switch(a & 0x3){ case 1: t->wTunerConnector=i; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Tuner is on port %d\n",i); break; case 2: if(a & 0x4){ t->wComp0Connector=RT_COMP2; } else { t->wComp0Connector=RT_COMP1; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %ld\n", t->wComp0Connector); break; case 3: if(a & 0x4){ t->wSVideo0Connector=RT_YCR_COMP4; } else { t->wSVideo0Connector=RT_YCF_COMP4; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %ld\n", t->wSVideo0Connector); break; default: break; } } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%ld, composite=%ld, svideo=%ld\n", t->wTunerConnector, t->wComp0Connector, t->wSVideo0Connector); } if(info->RageTheatreTunerPort>=0)t->wTunerConnector=info->RageTheatreTunerPort; if(info->RageTheatreCompositePort>=0)t->wComp0Connector=info->RageTheatreCompositePort; if(info->RageTheatreSVideoPort>=0)t->wSVideo0Connector=info->RageTheatreSVideoPort; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%ld, composite=%ld, svideo=%ld\n", t->wTunerConnector, t->wComp0Connector, t->wSVideo0Connector); switch((info->RageTheatreCrystal>=0)?info->RageTheatreCrystal:pll->reference_freq){ case 2700: t->video_decoder_type=RT_FREF_2700; break; case 2950: t->video_decoder_type=RT_FREF_2950; break; default: xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Unsupported reference clock frequency, Rage Theatre disabled\n"); t->theatre_num=-1; xfree(pPriv->theatre); pPriv->theatre = NULL; return; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "video decoder type used: 0x%04x\n", t->video_decoder_type);}static XF86VideoAdaptorPtrRADEONAllocAdaptor(ScrnInfoPtr pScrn){ XF86VideoAdaptorPtr adapt; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONPortPrivPtr pPriv; CARD32 dot_clock; if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn))) return NULL; if(!(pPriv = xcalloc(1, sizeof(RADEONPortPrivRec) + sizeof(DevUnion)))) { xfree(adapt); return NULL; } adapt->pPortPrivates = (DevUnion*)(&pPriv[1]); adapt->pPortPrivates[0].ptr = (pointer)pPriv; pPriv->colorKey = info->videoKey; pPriv->doubleBuffer = TRUE; pPriv->videoStatus = 0; pPriv->brightness = 0; pPriv->transform_index = 0; pPriv->saturation = 0; pPriv->contrast = 0; pPriv->red_intensity = 0; pPriv->green_intensity = 0; pPriv->blue_intensity = 0; pPriv->hue = 0; pPriv->currentBuffer = 0; pPriv->autopaint_colorkey = TRUE; pPriv->gamma = 1000; if (info->OverlayOnCRTC2) pPriv->crt2 = TRUE; else pPriv->crt2 = FALSE; pPriv->ov_alpha = 255; pPriv->gr_alpha = 255; pPriv->alpha_mode = 0; /* TV-in stuff */ pPriv->video_stream_active = FALSE; pPriv->encoding = 4; pPriv->frequency = 1000; pPriv->volume = -1000; pPriv->mute = TRUE; pPriv->v = 0; pPriv->overlay_deinterlacing_method = METHOD_BOB; pPriv->capture_vbi_data = 0; pPriv->dec_brightness = 0; pPriv->dec_saturation = 0; pPriv->dec_contrast = 0; pPriv->dec_hue = 0; /* * Unlike older Mach64 chips, RADEON has only two ECP settings: * 0 for PIXCLK < 175Mhz, and 1 (divide by 2) * for higher clocks, sure makes life nicer */ /* Figure out which head we are on */ if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary) dot_clock = info->ModeReg.dot_clock_freq_2; else dot_clock = info->ModeReg.dot_clock_freq; if(dot_clock < 17500) pPriv->ecp_div = 0; else pPriv->ecp_div = 1;#if 0 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dotclock is %g Mhz, setting ecp_div to %d\n", info->ModeReg.dot_clock_freq/100.0, pPriv->ecp_div);#endif OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (pPriv->ecp_div << 8)); /* I suspect we may need a usleep after writing to the PLL. if you play a video too soon after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey on the right edge video output. */ if ((info->ChipFamily == CHIP_FAMILY_RS100) || (info->ChipFamily == CHIP_FAMILY_RS200) || (info->ChipFamily == CHIP_FAMILY_RS300)) { /* Force the overlay clock on for integrated chips */ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) | (1<<18))); } /* overlay scaler line length differs for different revisions this needs to be maintained by hand */ switch(info->ChipFamily){ case CHIP_FAMILY_R200: case CHIP_FAMILY_R300: pPriv->overlay_scaler_buffer_width=1920; break; default: pPriv->overlay_scaler_buffer_width=1536; } /* Decide on tuner type */ if((info->tunerType<0) && (info->MM_TABLE_valid)) { pPriv->tuner_type = info->MM_TABLE.tuner_type; } else pPriv->tuner_type = info->tunerType; /* Initialize I2C bus */ RADEONInitI2C(pScrn, pPriv); if(pPriv->i2c != NULL)RADEON_board_setmisc(pPriv); #if 0 /* this is just here for easy debugging - normally off */ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Scanning I2C Bus\n"); for(i=0;i<255;i+=2) if(RADEONProbeAddress(pPriv->i2c, i)) xf86DrvMsg(pScrn->scrnIndex, X_INFO, " found device at address 0x%02x\n", i); #endif /* Initialize VIP bus */ RADEONVIP_init(pScrn, pPriv); info->adaptor = adapt; if(!xf86LoadSubModule(pScrn,"theatre_detect")) { xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre detect module\n"); goto skip_theatre; } xf86LoaderReqSymbols(TheatreDetectSymbolsList, NULL); RADEONSetupTheatre(pScrn, pPriv); /* * Now load the correspondind theatre chip based on what has been detected. */ if (pPriv->theatre) { xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Going to load the corresponding theatre module\n"); switch (pPriv->theatre->theatre_id) { case RT100_ATI_ID: { if(!xf86LoadSubModule(pScrn,"theatre")) { xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n"); xfree(pPriv->theatre); goto skip_theatre; } break; } case RT200_ATI_ID: { if(!xf86LoadSubModule(pScrn,"theatre200")) { xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unable to load Rage Theatre module\n"); xfree(pPriv->theatre); goto skip_theatre; } pPriv->theatre->microc_path = info->RageTheatreMicrocPath; pPriv->theatre->microc_type = info->RageTheatreMicrocType; break; } default: { xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Unknown Theatre chip\n"); xfree(pPriv->theatre); goto skip_theatre; } } xf86LoaderReqSymbols(TheatreSymbolsList, NULL); } if(pPriv->theatre!=NULL) { xf86_InitTheatre(pPriv->theatre); if(pPriv->theatre->mode == MODE_UNINITIALIZED) { Xfree(pPriv->theatre); pPriv->theatre = NULL; xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Rage Theatre disabled\n"); /* Here the modules must be unloaded */ goto skip_theatre; } } if(pPriv->theatre!=NULL){ xf86_ResetTheatreRegsForNoTVout(pPriv->theatre); xf86_RT_SetTint(pPriv->theatre, pPriv->dec_hue); xf86_RT_SetSaturation(pPriv->theatre, pPriv->dec_saturation); xf86_RT_SetSharpness(pPriv->theatre, RT_NORM_SHARPNESS); xf86_RT_SetContrast(pPriv->theatre, pPriv->dec_contrast); xf86_RT_SetBrightness(pPriv->theatre, pPriv->dec_brightness); RADEON_RT_SetEncoding(pScrn, pPriv); } skip_theatre: return adapt;}static XF86VideoAdaptorPtrRADEONSetupImageVideo(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; RADEONPortPrivPtr pPriv; XF86VideoAdaptorPtr adapt; if(!(adapt = RADEONAllocAdaptor(pScrn))) return NULL; adapt->type = XvWindowMask | XvInputMask | XvImageMask; adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; adapt->name = "ATI Radeon Video Overlay"; adapt->nEncodings = 1; adapt->pEncodings = &DummyEncoding; adapt->nFormats = NUM_FORMATS; adapt->pFormats = Formats; adapt->nPorts = 1; adapt->nAttributes = NUM_ATTRIBUTES; adapt->pAttributes = Attributes; adapt->nImages = NUM_IMAGES; adapt->pImages = Images; adapt->PutVideo = NULL; adapt->PutStill = NULL; adapt->GetVideo = NULL; adapt->GetStill = NULL; adapt->StopVideo = RADEONStopVideo; adapt->SetPortAttribute = RADEONSetPortAttribute; adapt->GetPortAttribute = RADEONGetPortAttribute; adapt->QueryBestSize = RADEONQueryBestSize; adapt->PutImage = RADEONPutImage; adapt->QueryImageAttributes = RADEONQueryImageAttributes; pPriv = (RADEONPortPrivPtr)(adapt->pPortPrivates[0].ptr); REGION_NULL(pScreen, &(pPriv->clip)); if(pPriv->theatre != NULL) { /* video decoder is present, extend capabilities */ adapt->nEncodings = 13; adapt->pEncodings = InputVideoEncodings; adapt->type |= XvVideoMask; adapt->nAttributes = NUM_DEC_ATTRIBUTES; adapt->PutVideo = RADEONPutVideo; } RADEONResetVideo(pScrn); return adapt;}static voidRADEONStopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup){ RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data; REGION_EMPTY(pScrn->pScreen, &pPriv->clip); if(cleanup) { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { RADEONWaitForFifo(pScrn, 2); OUTREG(RADEON_OV0_SCALE_CNTL, 0); } if(pPriv->video_stream_active){ RADEONWaitForFifo(pScrn, 2); OUTREG(RADEON_FCP_CNTL, RADEON_FCP0_SRC_GND); OUTREG(RADEON_CAP0_TRIG_CNTL, 0); RADEONResetVideo(pScrn); pPriv->video_stream_active = FALSE; if(pPriv->msp3430 != NULL) xf86_MSP3430SetVolume(pPriv->msp3430, MSP3430_FAST_MUTE); if(pPriv->uda1380 != NULL) xf86_uda1380_mute(pPriv->uda1380, TRUE); if(pPriv->i2c != NULL) RADEON_board_setmisc(pPriv); } if (pPriv->video_memory != NULL) { RADEONFreeMemory(pScrn, pPriv->video_memory); pPriv->video_memory = NULL; } pPriv->videoStatus = 0; } else { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { pPriv->videoStatus |= OFF_TIMER; pPriv->offTime = currentTime.milliseconds + OFF_DELAY; } }}static int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -