#include "s3v.h"
#if 0
#define OFF_DELAY 250
#define FREE_DELAY 15000
#define OFF_TIMER 0x01
#define FREE_TIMER 0x02
#endif
#define CLIENT_VIDEO_ON 0x04
#define S3V_MAX_PORTS 1
#if 0
static void S3VInitOffscreenImages(ScreenPtr);
#endif
static XF86VideoAdaptorPtr S3VAllocAdaptor(ScrnInfoPtr pScrn);
static XF86VideoAdaptorPtr S3VSetupImageVideoOverlay(ScreenPtr);
static int S3VSetPortAttributeOverlay(ScrnInfoPtr, Atom, INT32, pointer);
static int S3VGetPortAttributeOverlay(ScrnInfoPtr, Atom ,INT32 *, pointer);
#if 0
static XF86VideoAdaptorPtr MGASetupImageVideoTexture(ScreenPtr);
static int MGASetPortAttributeTexture(ScrnInfoPtr, Atom, INT32, pointer);
static int MGAGetPortAttributeTexture(ScrnInfoPtr, Atom ,INT32 *, pointer);
#endif
static void S3VStopVideo(ScrnInfoPtr, pointer, Bool);
static void S3VQueryBestSize(ScrnInfoPtr, Bool, short, short, short, short,
unsigned int *, unsigned int *, pointer);
static int S3VPutImage(ScrnInfoPtr, short, short, short, short, short,
short, short, short, int, unsigned char*, short,
short, Bool, RegionPtr, pointer);
static int S3VQueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
unsigned short *, int *, int *);
#if 0
static void MGABlockHandler(int, pointer, pointer, pointer);
#endif
static void S3VResetVideoOverlay(ScrnInfoPtr);
#if 0
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
static Atom xvBrightness, xvContrast, xvColorKey;
#endif
int S3VQueryXvCapable(ScrnInfoPtr pScrn)
{
S3VPtr ps3v = S3VPTR(pScrn);
if(
((pScrn->bitsPerPixel == 24) ||
(pScrn->bitsPerPixel == 16)
)
&&
((ps3v->Chipset == S3_ViRGE_DXGX) ||
S3_ViRGE_MX_SERIES(ps3v->Chipset) ||
S3_ViRGE_GX2_SERIES(ps3v->Chipset)
))
return TRUE;
else
return FALSE;
}
void S3VInitVideo(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
XF86VideoAdaptorPtr newAdaptor = NULL;
S3VPtr ps3v = S3VPTR(pScrn);
int num_adaptors;
if(
((pScrn->bitsPerPixel == 24) ||
(pScrn->bitsPerPixel == 16)
)
&&
((ps3v->Chipset == S3_ViRGE_DXGX) ||
S3_ViRGE_MX_SERIES(ps3v->Chipset) ||
S3_ViRGE_GX2_SERIES(ps3v->Chipset)
)
&& !ps3v->NoAccel
&& ps3v->XVideo
)
{
#if 0
if((pMga->Overlay8Plus24 || pMga->TexturedVideo) &&
(pScrn->bitsPerPixel != 24))
{
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using texture video\n");
newAdaptor = MGASetupImageVideoTexture(pScreen);
pMga->TexturedVideo = TRUE;
} else {
#endif
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using overlay video\n");
newAdaptor = S3VSetupImageVideoOverlay(pScreen);
#if 0
pMga->TexturedVideo = FALSE;
}*/
if(!pMga->Overlay8Plus24 )
S3VInitOffscreenImages(pScreen);
pMga->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = MGABlockHandler;
#endif
}
num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
if(newAdaptor) {
if(!num_adaptors) {
num_adaptors = 1;
adaptors = &newAdaptor;
} else {
newAdaptors =
xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*));
if(newAdaptors) {
memcpy(newAdaptors, adaptors, num_adaptors *
sizeof(XF86VideoAdaptorPtr));
newAdaptors[num_adaptors] = newAdaptor;
adaptors = newAdaptors;
num_adaptors++;
}
}
}
if(num_adaptors)
xf86XVScreenInit(pScreen, adaptors, num_adaptors);
if(newAdaptors)
xfree(newAdaptors);
}
static XF86VideoEncodingRec DummyEncoding[2] =
{
{
0,
"XV_IMAGE",
1024, 1024,
{1, 1}
},
{
0,
"XV_IMAGE",
2046, 2046,
{1, 1}
}
};
#define NUM_FORMATS_OVERLAY 4
#define NUM_FORMATS_TEXTURE 4
static XF86VideoFormatRec Formats[NUM_FORMATS_TEXTURE] =
{
{16, TrueColor}, {24, TrueColor} , {16, DirectColor}, {24, DirectColor}
};
#if 0
#define NUM_ATTRIBUTES_OVERLAY 3
static XF86AttributeRec Attributes[NUM_ATTRIBUTES_OVERLAY] =
{
{XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
{XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
{XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
};
#endif
#define NUM_IMAGES 3
static XF86ImageRec Images[NUM_IMAGES] =
{
XVIMAGE_YUY2,
XVIMAGE_YV12,
XVIMAGE_I420
};
static int
S3VSetPortAttributeOverlay(
ScrnInfoPtr pScrn,
Atom attribute,
INT32 value,
pointer data
){
#if 0
MGAPtr pMga = MGAPTR(pScrn);
MGAPortPrivPtr pPriv = pMga->portPrivate;
CHECK_DMA_QUIESCENT(pMga, pScrn);
if(attribute == xvBrightness) {
if((value < -128) || (value > 127))
return BadValue;
pPriv->brightness = value;
OUTREG(MGAREG_BESLUMACTL, ((pPriv->brightness & 0xff) << 16) |
(pPriv->contrast & 0xff));
} else
if(attribute == xvContrast) {
if((value < 0) || (value > 255))
return BadValue;
pPriv->contrast = value;
OUTREG(MGAREG_BESLUMACTL, ((pPriv->brightness & 0xff) << 16) |
(pPriv->contrast & 0xff));
} else
if(attribute == xvColorKey) {
pPriv->colorKey = value;
outMGAdac(0x55, (pPriv->colorKey & pScrn->mask.red) >>
pScrn->offset.red);
outMGAdac(0x56, (pPriv->colorKey & pScrn->mask.green) >>
pScrn->offset.green);
outMGAdac(0x57, (pPriv->colorKey & pScrn->mask.blue) >>
pScrn->offset.blue);
REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
} else
#endif
return BadMatch;
#if 0
return Success;
#endif
}
static int
S3VGetPortAttributeOverlay(
ScrnInfoPtr pScrn,
Atom attribute,
INT32 *value,
pointer data
){
#if 0
MGAPtr pMga = MGAPTR(pScrn);
MGAPortPrivPtr pPriv = pMga->portPrivate;
if(attribute == xvBrightness) {
*value = pPriv->brightness;
} else
if(attribute == xvContrast) {
*value = pPriv->contrast;
} else
if(attribute == xvColorKey) {
*value = pPriv->colorKey;
} else
#endif
return BadMatch;
#if 0
return Success;
#endif
}
static void
S3VQueryBestSize(
ScrnInfoPtr pScrn,
Bool motion,
short vid_w, short vid_h,
short drw_w, short drw_h,
unsigned int *p_w, unsigned int *p_h,
pointer data
){
*p_w = drw_w;
*p_h = drw_h;
#if 0
if( drw_w < vid_w ) *p_w = vid_w;
if( drw_h < vid_h ) *p_h = vid_h;
#endif
}
static void
S3VResetVideoOverlay(ScrnInfoPtr pScrn)
{
#if 0
S3VPtr ps3v = S3VPTR(pScrn);
S3VPortPrivPtr pPriv = ps3v->portPrivate;
MGAPtr pMga = MGAPTR(pScrn);
MGAPortPrivPtr pPriv = pMga->portPrivate;
CHECK_DMA_QUIESCENT(pMga, pScrn);
outMGAdac(0x51, 0x01);
outMGAdac(0x52, 0xff);
outMGAdac(0x53, 0xff);
outMGAdac(0x54, 0xff);
outMGAdac(0x55, (pPriv->colorKey & pScrn->mask.red) >>
pScrn->offset.red);
outMGAdac(0x56, (pPriv->colorKey & pScrn->mask.green) >>
pScrn->offset.green);
outMGAdac(0x57, (pPriv->colorKey & pScrn->mask.blue) >>
pScrn->offset.blue);
#endif
#if 0
OUTREG(MGAREG_BESLUMACTL, ((pPriv->brightness & 0xff) << 16) |
(pPriv->contrast & 0xff));
#endif
}
static XF86VideoAdaptorPtr
S3VAllocAdaptor(ScrnInfoPtr pScrn)
{
XF86VideoAdaptorPtr adapt;
S3VPtr ps3v = S3VPTR(pScrn);
S3VPortPrivPtr pPriv;
int i;
if(!(adapt = xf86XVAllocateVideoAdaptorRec(pScrn)))
return NULL;
if(!(pPriv = xcalloc(1, sizeof(S3VPortPrivRec) +
(sizeof(DevUnion) * S3V_MAX_PORTS))))
{
xfree(adapt);
return NULL;
}
adapt->pPortPrivates = (DevUnion*)(&pPriv[1]);
for(i = 0; i < S3V_MAX_PORTS; i++)
adapt->pPortPrivates[i].val = i;
#if 0
xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
xvContrast = MAKE_ATOM("XV_CONTRAST");
xvColorKey = MAKE_ATOM("XV_COLORKEY");
#endif
pPriv->colorKey =
(1 << pScrn->offset.red) |
(1 << pScrn->offset.green) |
(((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue);
#if 0
pPriv->brightness = 0;
pPriv->contrast = 128;
#endif
pPriv->videoStatus = 0;
pPriv->lastPort = -1;
ps3v->adaptor = adapt;
ps3v->portPrivate = pPriv;
return adapt;
}
static XF86VideoAdaptorPtr
S3VSetupImageVideoOverlay(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
S3VPtr ps3v = S3VPTR(pScrn);
XF86VideoAdaptorPtr adapt;
adapt = S3VAllocAdaptor(pScrn);
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
adapt->name = "S3 ViRGE Backend Scaler";
adapt->nEncodings = 1;
adapt->pEncodings = &DummyEncoding[0];
adapt->nFormats = NUM_FORMATS_OVERLAY;
adapt->pFormats = Formats;
adapt->nPorts = 1;
adapt->pAttributes = NULL ;
#if 0
if (pMga->Chipset == PCI_CHIP_MGAG400) {
adapt->nImages = 4;
adapt->nAttributes = 3;
} else {
#endif
adapt->nImages = 3;
adapt->nAttributes = 0;
adapt->pImages = Images;
adapt->PutVideo = NULL;
adapt->PutStill = NULL;
adapt->GetVideo = NULL;
adapt->GetStill = NULL;
adapt->StopVideo = S3VStopVideo;
adapt->SetPortAttribute = S3VSetPortAttributeOverlay;
adapt->GetPortAttribute = S3VGetPortAttributeOverlay;
adapt->QueryBestSize = S3VQueryBestSize;
adapt->PutImage = S3VPutImage;
adapt->QueryImageAttributes = S3VQueryImageAttributes;
REGION_NULL(pScreen, &(ps3v->portPrivate->clip));
S3VResetVideoOverlay(pScrn);
return adapt;
}
static void
S3VStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
{
S3VPtr ps3v = S3VPTR(pScrn);
S3VPortPrivPtr pPriv = ps3v->portPrivate;
#if 0
MGAPtr pMga = MGAPTR(pScrn);
MGAPortPrivPtr pPriv = pMga->portPrivate;
if(pMga->TexturedVideo) return;
#endif
REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
if(shutdown) {
if(pPriv->videoStatus & CLIENT_VIDEO_ON)
{
if ( S3_ViRGE_GX2_SERIES(ps3v->Chipset) ||
S3_ViRGE_MX_SERIES(ps3v->Chipset)
)
{
OUTREG(SSTREAM_WINDOW_SIZE_REG, 1);
OUTREG(SSTREAM_START_REG, 0 );
}
else
{
OUTREG(BLEND_CONTROL_REG, 0x01000000);
}
}
if(pPriv->area) {
xf86FreeOffscreenArea(pPriv->area);
pPriv->area = NULL;
}
pPriv->videoStatus = 0;
#if 0
} else {
if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
pPriv->videoStatus |= OFF_TIMER;
pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
}
#endif
}
}
static FBAreaPtr
S3VAllocateMemory(
ScrnInfoPtr pScrn,
FBAreaPtr area,
int numlines
){
ScreenPtr pScreen;
FBAreaPtr new_area;
if(area) {
if((area->box.y2 - area->box.y1) >= numlines)
return area;
if(xf86ResizeOffscreenArea(area, pScrn->displayWidth, numlines))
return area;
xf86FreeOffscreenArea(area);
}
pScreen = screenInfo.screens[pScrn->scrnIndex];
new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
numlines, 0, NULL, NULL, NULL);
if(!new_area) {
int max_w, max_h;
xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0,
FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME);
if((max_w < pScrn->displayWidth) || (max_h < numlines))
return NULL;
xf86PurgeUnlockedOffscreenAreas(pScreen);
new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
numlines, 0, NULL, NULL, NULL);
}
return new_area;
}
static void
S3VDisplayVideoOverlay(
ScrnInfoPtr pScrn,
int id,
int offset,
short width, short height,
int pitch,
int x1, int y1, int x2, int y2,
BoxPtr dstBox,
short src_w, short src_h,
short drw_w, short drw_h
){
int tmp;
#if 0
CHECK_DMA_QUIESCENT(pMga, pScrn);
#endif
S3VPtr ps3v = S3VPTR(pScrn);
S3VPortPrivPtr pPriv = ps3v->portPrivate;
vgaHWPtr hwp = VGAHWPTR(pScrn);
int vgaCRIndex, vgaCRReg, vgaIOBase;
vgaIOBase = hwp->IOBase;
vgaCRIndex = vgaIOBase + 4;
vgaCRReg = vgaIOBase + 5;
if(!ps3v->NeedSTREAMS)
return;
#if 0
tmp = INREG(MGAREG_VCOUNT) + 64;
if(tmp > pScrn->currentMode->VDisplay)
tmp -= pScrn->currentMode->VDisplay;
#endif
#if 0
switch(id) {
case FOURCC_UYVY:
break;
case FOURCC_YUY2:
default:
tmp = drw_w / src_w;
if (drw_w == src_w) tmp = 0;
else if (tmp>=4) tmp =3;
else if (tmp>=2) tmp =2;
else tmp =1;
OUTREG(SSTREAM_CONTROL_REG,
tmp << 28 | 0x01000000 |
((((src_w-1)<<1)-(drw_w-1)) & 0xfff)
);
break;
}
#endif
if (drw_w == src_w)
tmp = 0;
else
tmp =2;
OUTREG(SSTREAM_CONTROL_REG,
tmp << 28 | 0x01000000 |
((((src_w-1)<<1)-(drw_w-1)) & 0xfff)
);
OUTREG(SSTREAM_STRETCH_REG,
((src_w - 1) & 0x7ff) | (((src_w-drw_w-1) & 0x7ff) << 16)
);
if ( S3_ViRGE_GX2_SERIES(ps3v->Chipset) ||
S3_ViRGE_MX_SERIES(ps3v->Chipset)
)
{
OUTREG(BLEND_CONTROL_REG, 0x20 );
}
else
{
OUTREG(BLEND_CONTROL_REG, 0x05000000);
}
OUTREG(SSTREAM_FBADDR0_REG, offset & 0x3fffff );
OUTREG(SSTREAM_STRIDE_REG, pitch & 0xfff );
OUTREG(K1_VSCALE_REG, src_h-1 );
OUTREG(K2_VSCALE_REG, (src_h - drw_h) & 0x7ff );
if ( S3_ViRGE_GX2_SERIES(ps3v->Chipset) ||
S3_ViRGE_MX_SERIES(ps3v->Chipset) )
{
OUTREG(DDA_VERT_REG, (((~drw_h)-1) & 0xfff ) |
0xc000
);
}
else
{
OUTREG(DDA_VERT_REG, (((~drw_h)-1)) & 0xfff );
}
OUTREG(SSTREAM_START_REG, ((dstBox->x1 +1) << 16) | (dstBox->y1 +1));
OUTREG(SSTREAM_WINDOW_SIZE_REG,
( ((drw_w-1) << 16) | (drw_h ) ) & 0x7ff07ff
);
if ( S3_ViRGE_GX2_SERIES(ps3v->Chipset) ||
S3_ViRGE_MX_SERIES(ps3v->Chipset)
)
{
OUTREG(COL_CHROMA_KEY_CONTROL_REG,
0x40000000 |
((pScrn->weight.red-1) << 24) |
((pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red) <<
(16 + 8-pScrn->weight.red) |
((pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green) <<
(8 + 8-pScrn->weight.green) |
((pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue) <<
(8-pScrn->weight.blue)
);
}
else
{
OUTREG(COL_CHROMA_KEY_CONTROL_REG,
0x10000000 |
((pScrn->weight.red-1) << 24) |
((pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red) <<
(16 + 8-pScrn->weight.red) |
((pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green) <<
(8 + 8-pScrn->weight.green) |
((pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue) <<
(8-pScrn->weight.blue)
);
}
if ( S3_ViRGE_GX2_SERIES(ps3v->Chipset) ||
S3_ViRGE_MX_SERIES(ps3v->Chipset) )
{
VGAOUT8(vgaCRIndex, 0x92);
VGAOUT8(vgaCRReg, (((pitch + 7) / 8) >> 8) | 0x80);
VGAOUT8(vgaCRIndex, 0x93);
VGAOUT8(vgaCRReg, (pitch + 7) / 8);
}
}
static int
S3VPutImage(
ScrnInfoPtr pScrn,
short src_x, short src_y,
short drw_x, short drw_y,
short src_w, short src_h,
short drw_w, short drw_h,
int id, unsigned char* buf,
short width, short height,
Bool sync,
RegionPtr clipBoxes, pointer data
){
S3VPtr ps3v = S3VPTR(pScrn);
S3VPortPrivPtr pPriv = ps3v->portPrivate;
INT32 x1, x2, y1, y2;
unsigned char *dst_start;
int pitch, new_h, offset, offset2=0, offset3=0;
int srcPitch, srcPitch2=0, dstPitch;
int top, left, npixels, nlines;
BoxRec dstBox;
CARD32 tmp;
if(!ps3v->NeedSTREAMS)
return Success;
x1 = src_x;
x2 = src_x + src_w;
y1 = src_y;
y2 = src_y + src_h;
dstBox.x1 = drw_x;
dstBox.x2 = drw_x + drw_w;
dstBox.y1 = drw_y;
dstBox.y2 = drw_y + drw_h;
if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2,
clipBoxes, width, height))
return Success;
dstBox.x1 -= pScrn->frameX0;
dstBox.x2 -= pScrn->frameX0;
dstBox.y1 -= pScrn->frameY0;
dstBox.y2 -= pScrn->frameY0;
pitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3;
dstPitch = ((width << 1) + 15) & ~15;
new_h = ((dstPitch * height) + pitch - 1) / pitch;
switch(id) {
case FOURCC_YV12:
case FOURCC_I420:
srcPitch = (width + 3) & ~3;
offset2 = srcPitch * height;
srcPitch2 = ((width >> 1) + 3) & ~3;
offset3 = (srcPitch2 * (height >> 1)) + offset2;
break;
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
srcPitch = (width << 1);
break;
}
if(!(pPriv->area = S3VAllocateMemory(pScrn, pPriv->area, new_h)))
return BadAlloc;
top = y1 >> 16;
left = (x1 >> 16) & ~1;
npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
left <<= 1;
offset = pPriv->area->box.y1 * pitch;
dst_start = ps3v->FBStart + offset + left + (top * dstPitch);
#if 0
if(pMga->TexturedVideo && pMga->AccelInfoRec->NeedToSync &&
((long)data != pPriv->lastPort))
{
MGAStormSync(pScrn);
pMga->AccelInfoRec->NeedToSync = FALSE;
}
#endif
switch(id) {
case FOURCC_YV12:
case FOURCC_I420:
top &= ~1;
tmp = ((top >> 1) * srcPitch2) + (left >> 2);
offset2 += tmp;
offset3 += tmp;
if(id == FOURCC_I420) {
tmp = offset2;
offset2 = offset3;
offset3 = tmp;
}
nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1),
buf + offset2, buf + offset3, dst_start,
srcPitch, srcPitch2, dstPitch, nlines, npixels);
break;
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
buf += (top * srcPitch) + left;
nlines = ((y2 + 0xffff) >> 16) - top;
xf86XVCopyPacked(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
break;
}
#if 0
if(pMga->TexturedVideo) {
pPriv->lastPort = (long)data;
MGADisplayVideoTexture(pScrn, id, offset,
REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes),
width, height, dstPitch, src_x, src_y, src_w, src_h,
drw_x, drw_y, drw_w, drw_h);
pPriv->videoStatus = FREE_TIMER;
pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
} else {
#endif
if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
}
offset += left + (top * dstPitch);
S3VDisplayVideoOverlay(pScrn, id, offset, width, height, dstPitch,
x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
pPriv->videoStatus = CLIENT_VIDEO_ON;
#if 0
}
pMga->VideoTimerCallback = MGAVideoTimerCallback;
#endif
return Success;
}
static int
S3VQueryImageAttributes(
ScrnInfoPtr pScrn,
int id,
unsigned short *w, unsigned short *h,
int *pitches, int *offsets
){
#if 0
MGAPtr pMga = MGAPTR(pScrn);
#endif
int size, tmp;
#if 0
if(pMga->TexturedVideo) {
if(*w > 2046) *w = 2046;
if(*h > 2046) *h = 2046;
} else {
#endif
if(*w > 1024) *w = 1024;
if(*h > 1024) *h = 1024;
#if 0
}
#endif
*w = (*w + 1) & ~1;
if(offsets) offsets[0] = 0;
switch(id) {
case FOURCC_YV12:
case FOURCC_I420:
*h = (*h + 1) & ~1;
size = (*w + 3) & ~3;
if(pitches) pitches[0] = size;
size *= *h;
if(offsets) offsets[1] = size;
tmp = ((*w >> 1) + 3) & ~3;
if(pitches) pitches[1] = pitches[2] = tmp;
tmp *= (*h >> 1);
size += tmp;
if(offsets) offsets[2] = size;
size += tmp;
break;
case FOURCC_UYVY:
case FOURCC_YUY2:
default:
size = *w << 1;
if(pitches) pitches[0] = size;
size *= *h;
break;
}
return size;
}