1
/* COPYRIGHT AND PERMISSION NOTICE
3
Copyright (c) 2000, 2001 Nokia Home Communications
7
Permission is hereby granted, free of charge, to any person obtaining
8
a copy of this software and associated documentation files (the
9
"Software"), to deal in the Software without restriction, including
10
without limitation the rights to use, copy, modify, merge, publish,
11
distribute, and/or sell copies of the Software, and to permit persons
12
to whom the Software is furnished to do so, provided that the above
13
copyright notice(s) and this permission notice appear in all copies of
14
the Software and that both the above copyright notice(s) and this
15
permission notice appear in supporting documentation.
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
20
OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21
HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY
22
SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
23
RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
24
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
25
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27
Except as contained in this notice, the name of a copyright holder
28
shall not be used in advertising or otherwise to promote the sale, use
29
or other dealings in this Software without prior written authorization
30
of the copyright holder.
32
X Window System is a trademark of The Open Group */
34
/***************************************************************************
36
Copyright 2000 Intel Corporation. All Rights Reserved.
38
Permission is hereby granted, free of charge, to any person obtaining a
39
copy of this software and associated documentation files (the
40
"Software"), to deal in the Software without restriction, including
41
without limitation the rights to use, copy, modify, merge, publish,
42
distribute, sub license, and/or sell copies of the Software, and to
43
permit persons to whom the Software is furnished to do so, subject to
44
the following conditions:
46
The above copyright notice and this permission notice (including the
47
next paragraph) shall be included in all copies or substantial portions
50
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
51
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
52
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
53
IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
54
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
55
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
56
THE USE OR OTHER DEALINGS IN THE SOFTWARE.
58
**************************************************************************/
62
* i810_video.c: i810 KDrive Xv driver.
63
* Based on the XFree86 i810 Xv driver by Jonathan Bian.
66
* Jonathan Bian <jonathan.bian@intel.com>
67
* Pontus Lidman <pontus.lidman@nokia.com>
72
#include <kdrive-config.h>
78
#include <X11/extensions/Xv.h>
85
} FBLinearRec, *FBLinearPtr;
87
#define OFF_DELAY 250 /* milliseconds */
88
#define FREE_DELAY 15000
90
#define OFF_TIMER 0x01
91
#define FREE_TIMER 0x02
92
#define CLIENT_VIDEO_ON 0x04
94
#define TIMER_MASK (OFF_TIMER | FREE_TIMER)
96
static KdVideoAdaptorPtr i810SetupImageVideo(ScreenPtr);
97
static void i810StopVideo(KdScreenInfo *, pointer, Bool);
98
static int i810SetPortAttribute(KdScreenInfo *, Atom, int, pointer);
99
static int i810GetPortAttribute(KdScreenInfo *, Atom, int *, pointer);
100
static void i810QueryBestSize(KdScreenInfo *, Bool,
101
short, short, short, short, unsigned int *, unsigned int *, pointer);
102
static int i810PutImage( KdScreenInfo *, DrawablePtr,
103
short, short, short, short, short, short, short, short,
104
int, unsigned char*, short, short, Bool, RegionPtr, pointer);
105
static int i810QueryImageAttributes(KdScreenInfo *,
106
int, unsigned short *, unsigned short *, int *, int *);
108
static void i810BlockHandler(int, pointer, pointer, pointer);
110
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
112
static Atom xvBrightness, xvContrast, xvColorKey;
114
#define IMAGE_MAX_WIDTH 720
115
#define IMAGE_MAX_HEIGHT 576
116
#define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT)
118
#define OVERLAY_UPDATE(p) OUTREG(0x30000, p | 0x80000000);
121
* OV0CMD - Overlay Command Register
123
#define VERTICAL_CHROMINANCE_FILTER 0x70000000
124
#define VC_SCALING_OFF 0x00000000
125
#define VC_LINE_REPLICATION 0x10000000
126
#define VC_UP_INTERPOLATION 0x20000000
127
#define VC_PIXEL_DROPPING 0x50000000
128
#define VC_DOWN_INTERPOLATION 0x60000000
129
#define VERTICAL_LUMINANCE_FILTER 0x0E000000
130
#define VL_SCALING_OFF 0x00000000
131
#define VL_LINE_REPLICATION 0x02000000
132
#define VL_UP_INTERPOLATION 0x04000000
133
#define VL_PIXEL_DROPPING 0x0A000000
134
#define VL_DOWN_INTERPOLATION 0x0C000000
135
#define HORIZONTAL_CHROMINANCE_FILTER 0x01C00000
136
#define HC_SCALING_OFF 0x00000000
137
#define HC_LINE_REPLICATION 0x00400000
138
#define HC_UP_INTERPOLATION 0x00800000
139
#define HC_PIXEL_DROPPING 0x01400000
140
#define HC_DOWN_INTERPOLATION 0x01800000
141
#define HORIZONTAL_LUMINANCE_FILTER 0x00380000
142
#define HL_SCALING_OFF 0x00000000
143
#define HL_LINE_REPLICATION 0x00080000
144
#define HL_UP_INTERPOLATION 0x00100000
145
#define HL_PIXEL_DROPPING 0x00280000
146
#define HL_DOWN_INTERPOLATION 0x00300000
148
#define Y_ADJUST 0x00010000
149
#define OV_BYTE_ORDER 0x0000C000
150
#define UV_SWAP 0x00004000
151
#define Y_SWAP 0x00008000
152
#define Y_AND_UV_SWAP 0x0000C000
153
#define SOURCE_FORMAT 0x00003C00
154
#define RGB_555 0x00000800
155
#define RGB_565 0x00000C00
156
#define YUV_422 0x00002000
157
#define YUV_411 0x00002400
158
#define YUV_420 0x00003000
159
#define YUV_410 0x00003800
160
#define BUFFER_AND_FIELD 0x00000006
161
#define BUFFER0_FIELD0 0x00000000
162
#define BUFFER1_FIELD0 0x00000004
163
#define OVERLAY_ENABLE 0x00000001
166
* DOV0STA - Display/Overlay 0 Status Register
168
#define DOV0STA 0x30008
170
#define MINUV_SCALE 0x1
172
#define RGB16ToColorKey(c) \
173
(((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3))
175
#define RGB15ToColorKey(c) \
176
(((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3))
178
Bool i810InitVideo(ScreenPtr pScreen)
180
KdScreenPriv(pScreen);
181
KdScreenInfo *screen = pScreenPriv->screen;
182
KdVideoAdaptorPtr *adaptors, *newAdaptors = NULL;
183
KdVideoAdaptorPtr newAdaptor = NULL;
186
/* fprintf(stderr,"i810InitVideo\n"); */
188
if (screen->fb[0].bitsPerPixel != 8)
190
newAdaptor = i810SetupImageVideo(pScreen);
193
num_adaptors = KdXVListGenericAdaptors(screen, &adaptors);
198
adaptors = &newAdaptor;
200
newAdaptors = /* need to free this someplace */
201
xalloc((num_adaptors + 1) * sizeof(KdVideoAdaptorPtr*));
203
memcpy(newAdaptors, adaptors, num_adaptors *
204
sizeof(KdVideoAdaptorPtr));
205
newAdaptors[num_adaptors] = newAdaptor;
206
adaptors = newAdaptors;
213
KdXVScreenInit(pScreen, adaptors, num_adaptors);
220
/* client libraries expect an encoding */
221
static KdVideoEncodingRec DummyEncoding[1] =
226
IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
231
#define NUM_FORMATS 3
233
static KdVideoFormatRec Formats[NUM_FORMATS] =
235
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
238
#define NUM_ATTRIBUTES 3
240
static KdAttributeRec Attributes[NUM_ATTRIBUTES] =
242
{XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
243
{XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
244
{XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
249
static KdImageRec Images[NUM_IMAGES] =
285
} I810OverlayRegRec, *I810OverlayRegPtr;
296
unsigned char currentBuf;
298
unsigned char brightness;
299
unsigned char contrast;
308
} I810PortPrivRec, *I810PortPrivPtr;
310
#define GET_PORT_PRIVATE(screen) \
311
(I810PortPrivPtr)(((I810CardInfo *) (screen->card->driver))->adaptor->pPortPrivates[0].ptr)
313
static void i810ResetVideo(KdScreenInfo *screen)
315
ScreenPtr pScreen = screen->pScreen;
316
KdScreenPriv(pScreen);
317
KdCardInfo *card = pScreenPriv->card;
318
I810CardInfo *i810c = (I810CardInfo *) card->driver;
320
I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr;
321
I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart);
324
* Default to maximum image size in YV12
327
overlay->YRGB_VPH = 0;
329
overlay->HORZ_PH = 0;
330
overlay->INIT_PH = 0;
331
overlay->DWINPOS = 0;
332
overlay->DWINSZ = (IMAGE_MAX_HEIGHT << 16) | IMAGE_MAX_WIDTH;
333
overlay->SWID = IMAGE_MAX_WIDTH | (IMAGE_MAX_WIDTH << 15);
334
overlay->SWIDQW = (IMAGE_MAX_WIDTH >> 3) | (IMAGE_MAX_WIDTH << 12);
335
overlay->SHEIGHT = IMAGE_MAX_HEIGHT | (IMAGE_MAX_HEIGHT << 15);
336
overlay->YRGBSCALE = 0x80004000; /* scale factor 1 */
337
overlay->UVSCALE = 0x80004000; /* scale factor 1 */
338
overlay->OV0CLRC0 = 0x4000; /* brightness: 0 contrast: 1.0 */
339
overlay->OV0CLRC1 = 0x80; /* saturation: bypass */
342
* Enable destination color keying
344
switch(screen->fb[0].depth) {
345
case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);
346
overlay->DCLRKM = 0x80070307;
348
case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);
349
overlay->DCLRKM = 0x80070707;
351
default: overlay->DCLRKV = pPriv->colorKey;
352
overlay->DCLRKM = 0x80000000;
356
overlay->SCLRKVH = 0;
357
overlay->SCLRKVL = 0;
358
overlay->SCLRKM = 0; /* source color key disable */
359
overlay->OV0CONF = 0; /* two 720 pixel line buffers */
361
overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST |
364
OVERLAY_UPDATE(i810c->OverlayPhysical);
368
static KdVideoAdaptorPtr
369
i810SetupImageVideo(ScreenPtr pScreen)
371
KdScreenPriv(pScreen);
372
KdScreenInfo *screen = pScreenPriv->screen;
373
KdCardInfo *card = pScreenPriv->card;
374
I810CardInfo *i810c = (I810CardInfo *) card->driver;
377
KdVideoAdaptorPtr adapt;
378
I810PortPrivPtr pPriv;
380
/* fprintf(stderr,"i810SetupImageVideo\n"); */
382
if(!(adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) +
383
sizeof(I810PortPrivRec) +
387
adapt->type = XvWindowMask | XvInputMask | XvImageMask;
388
adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
389
adapt->name = "I810 Video Overlay";
390
adapt->nEncodings = 1;
391
adapt->pEncodings = DummyEncoding;
392
adapt->nFormats = NUM_FORMATS;
393
adapt->pFormats = Formats;
395
adapt->pPortPrivates = (DevUnion*)(&adapt[1]);
397
pPriv = (I810PortPrivPtr)(&adapt->pPortPrivates[1]);
399
adapt->pPortPrivates[0].ptr = (pointer)(pPriv);
400
adapt->pAttributes = Attributes;
401
adapt->nImages = NUM_IMAGES;
402
adapt->nAttributes = NUM_ATTRIBUTES;
403
adapt->pImages = Images;
404
adapt->PutVideo = NULL;
405
adapt->PutStill = NULL;
406
adapt->GetVideo = NULL;
407
adapt->GetStill = NULL;
408
adapt->StopVideo = i810StopVideo;
409
adapt->SetPortAttribute = i810SetPortAttribute;
410
adapt->GetPortAttribute = i810GetPortAttribute;
411
adapt->QueryBestSize = i810QueryBestSize;
412
adapt->PutImage = i810PutImage;
413
adapt->QueryImageAttributes = i810QueryImageAttributes;
415
pPriv->colorKey = i810c->colorKey & ((1 << screen->fb[0].depth) - 1);
416
pPriv->videoStatus = 0;
417
pPriv->brightness = 0;
418
pPriv->contrast = 128;
419
pPriv->linear = NULL;
420
pPriv->currentBuf = 0;
422
/* gotta uninit this someplace */
423
REGION_INIT(pScreen, &pPriv->clip, NullBox, 0);
425
i810c->adaptor = adapt;
427
i810c->BlockHandler = pScreen->BlockHandler;
428
pScreen->BlockHandler = i810BlockHandler;
430
xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
431
xvContrast = MAKE_ATOM("XV_CONTRAST");
432
xvColorKey = MAKE_ATOM("XV_COLORKEY");
434
i810ResetVideo(screen);
442
Takes the dst box in standard X BoxRec form (top and left
443
edges inclusive, bottom and right exclusive). The new dst
444
box is returned. The source boundaries are given (x1, y1
445
inclusive, x2, y2 exclusive) and returned are the new source
446
boundaries in 16.16 fixed point.
456
BoxPtr extents, /* extents of the clip region */
460
INT32 vscale, hscale, delta;
463
hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1);
464
vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1);
466
*x1 <<= 16; *x2 <<= 16;
467
*y1 <<= 16; *y2 <<= 16;
469
diff = extents->x1 - dst->x1;
471
dst->x1 = extents->x1;
472
*x1 += diff * hscale;
474
diff = dst->x2 - extents->x2;
476
dst->x2 = extents->x2;
477
*x2 -= diff * hscale;
479
diff = extents->y1 - dst->y1;
481
dst->y1 = extents->y1;
482
*y1 += diff * vscale;
484
diff = dst->y2 - extents->y2;
486
dst->y2 = extents->y2;
487
*y2 -= diff * vscale;
491
diff = (- *x1 + hscale - 1)/ hscale;
493
*x1 += diff * hscale;
495
delta = *x2 - (width << 16);
497
diff = (delta + hscale - 1)/ hscale;
499
*x2 -= diff * hscale;
502
diff = (- *y1 + vscale - 1)/ vscale;
504
*y1 += diff * vscale;
506
delta = *y2 - (height << 16);
508
diff = (delta + vscale - 1)/ vscale;
510
*y2 -= diff * vscale;
515
i810StopVideo(KdScreenInfo *screen, pointer data, Bool exit)
517
I810PortPrivPtr pPriv = (I810PortPrivPtr)data;
518
KdCardInfo *card = screen->card;
519
I810CardInfo *i810c = (I810CardInfo *) card->driver;
521
I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart);
523
REGION_EMPTY(screen->pScreen, &pPriv->clip);
526
if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
527
overlay->OV0CMD &= 0xFFFFFFFE;
528
OVERLAY_UPDATE(i810c->OverlayPhysical);
531
xfree(pPriv->linear);
532
pPriv->linear = NULL;
534
pPriv->videoStatus = 0;
536
if(pPriv->videoStatus & CLIENT_VIDEO_ON) {
537
pPriv->videoStatus |= OFF_TIMER;
538
pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
545
i810SetPortAttribute(
546
KdScreenInfo *screen,
551
I810PortPrivPtr pPriv = (I810PortPrivPtr)data;
552
KdCardInfo *card = screen->card;
553
I810CardInfo *i810c = (I810CardInfo *) card->driver;
555
I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart);
557
if(attribute == xvBrightness) {
558
if((value < -128) || (value > 127))
560
pPriv->brightness = value;
561
overlay->OV0CLRC0 &= 0xFFFFFF00;
562
overlay->OV0CLRC0 |= value;
563
OVERLAY_UPDATE(i810c->OverlayPhysical);
565
if(attribute == xvContrast) {
566
if((value < 0) || (value > 255))
568
pPriv->contrast = value;
569
overlay->OV0CLRC0 &= 0xFFFE00FF;
570
overlay->OV0CLRC0 |= value << 9;
571
OVERLAY_UPDATE(i810c->OverlayPhysical);
573
if(attribute == xvColorKey) {
574
pPriv->colorKey = value;
575
switch(screen->fb[0].depth) {
576
case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);
578
case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);
580
default: overlay->DCLRKV = pPriv->colorKey;
583
OVERLAY_UPDATE(i810c->OverlayPhysical);
584
REGION_EMPTY(screen->pScreen, &pPriv->clip);
585
} else return BadMatch;
591
i810GetPortAttribute(
592
KdScreenInfo *screen,
597
I810PortPrivPtr pPriv = (I810PortPrivPtr)data;
599
if(attribute == xvBrightness) {
600
*value = pPriv->brightness;
602
if(attribute == xvContrast) {
603
*value = pPriv->contrast;
605
if(attribute == xvColorKey) {
606
*value = pPriv->colorKey;
607
} else return BadMatch;
614
KdScreenInfo *screen,
616
short vid_w, short vid_h,
617
short drw_w, short drw_h,
618
unsigned int *p_w, unsigned int *p_h,
628
KdScreenInfo *screen,
638
KdCardInfo *card = screen->card;
639
I810CardInfo *i810c = (I810CardInfo *) card->driver;
640
I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr;
641
unsigned char *src, *dst;
643
src = buf + (top*srcPitch) + (left<<1);
645
if (pPriv->currentBuf == 0)
646
dst = i810c->FbBase + pPriv->YBuf0offset;
648
dst = i810c->FbBase + pPriv->YBuf1offset;
660
KdScreenInfo *screen,
663
int dstPitch, /* of chroma */
672
KdCardInfo *card = screen->card;
673
I810CardInfo *i810c = (I810CardInfo *) card->driver;
674
I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr;
676
unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3;
679
src1 = buf + (top*srcPitch) + left;
680
if (pPriv->currentBuf == 0)
681
dst1 = i810c->FbBase + pPriv->YBuf0offset;
683
dst1 = i810c->FbBase + pPriv->YBuf1offset;
685
for (i = 0; i < h; i++) {
686
memcpy(dst1, src1, w);
688
dst1 += dstPitch << 1;
691
/* Copy V data for YV12, or U data for I420 */
692
src2 = buf + (srcH*srcPitch) + ((top*srcPitch)>>2) + (left>>1);
693
if (pPriv->currentBuf == 0) {
694
if (id == FOURCC_I420)
695
dst2 = i810c->FbBase + pPriv->UBuf0offset;
697
dst2 = i810c->FbBase + pPriv->VBuf0offset;
699
if (id == FOURCC_I420)
700
dst2 = i810c->FbBase + pPriv->UBuf1offset;
702
dst2 = i810c->FbBase + pPriv->VBuf1offset;
705
for (i = 0; i < h/2; i++) {
706
memcpy(dst2, src2, w/2);
711
/* Copy U data for YV12, or V data for I420 */
712
src3 = buf + (srcH*srcPitch) + ((srcH*srcPitch)>>2) + ((top*srcPitch)>>2) + (left>>1);
713
if (pPriv->currentBuf == 0) {
714
if (id == FOURCC_I420)
715
dst3 = i810c->FbBase + pPriv->VBuf0offset;
717
dst3 = i810c->FbBase + pPriv->UBuf0offset;
719
if (id == FOURCC_I420)
720
dst3 = i810c->FbBase + pPriv->VBuf1offset;
722
dst3 = i810c->FbBase + pPriv->UBuf1offset;
725
for (i = 0; i < h/2; i++) {
726
memcpy(dst3, src3, w/2);
734
KdScreenInfo *screen,
736
short width, short height,
737
int dstPitch, /* of chroma for 4:2:0 */
738
int x1, int y1, int x2, int y2,
740
short src_w, short src_h,
741
short drw_w, short drw_h
743
KdCardInfo *card = screen->card;
744
I810CardInfo *i810c = (I810CardInfo *) card->driver;
745
I810PortPrivPtr pPriv = i810c->adaptor->pPortPrivates[0].ptr;
746
I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart);
747
int xscaleInt, xscaleFract, yscaleInt, yscaleFract;
748
int xscaleIntUV = 0, xscaleFractUV = 0, yscaleIntUV = 0, yscaleFractUV = 0;
754
swidth = (width + 7) & ~7;
755
overlay->SWID = (swidth << 15) | swidth;
756
overlay->SWIDQW = (swidth << 12) | (swidth >> 3);
761
swidth = ((width + 3) & ~3) << 1;
762
overlay->SWID = swidth;
763
overlay->SWIDQW = swidth >> 3;
767
overlay->SHEIGHT = height | (height << 15);
768
overlay->DWINPOS = (dstBox->y1 << 16) | dstBox->x1;
769
overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) |
770
(dstBox->x2 - dstBox->x1);
772
/* buffer locations */
773
overlay->OBUF_0Y = pPriv->YBuf0offset;
774
overlay->OBUF_1Y = pPriv->YBuf1offset;
775
overlay->OBUF_0U = pPriv->UBuf0offset;
776
overlay->OBUF_0V = pPriv->VBuf0offset;
777
overlay->OBUF_1U = pPriv->UBuf1offset;
778
overlay->OBUF_1V = pPriv->VBuf1offset;
781
* Calculate horizontal and vertical scaling factors, default to 1:1
783
overlay->YRGBSCALE = 0x80004000;
784
overlay->UVSCALE = 0x80004000;
787
* Initially, YCbCr and Overlay Enable and
788
* vertical chrominance up interpolation and horozontal chrominance
791
overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST |
794
if ((drw_w != src_w) || (drw_h != src_h))
796
xscaleInt = (src_w / drw_w) & 0x3;
797
xscaleFract = (src_w << 12) / drw_w;
798
yscaleInt = (src_h / drw_h) & 0x3;
799
yscaleFract = (src_h << 12) / drw_h;
801
overlay->YRGBSCALE = (xscaleInt << 15) |
802
((xscaleFract & 0xFFF) << 3) |
804
((yscaleFract & 0xFFF) << 20);
808
/* horizontal up-scaling */
809
overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER;
810
overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER;
811
overlay->OV0CMD |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION);
816
/* vertical up-scaling */
817
overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER;
818
overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER;
819
overlay->OV0CMD |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION);
824
/* horizontal down-scaling */
825
overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER;
826
overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER;
827
overlay->OV0CMD |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION);
832
/* vertical down-scaling */
833
overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER;
834
overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER;
835
overlay->OV0CMD |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION);
838
/* now calculate the UV scaling factor */
842
xscaleFractUV = xscaleFract >> MINUV_SCALE;
843
overlay->OV0CMD &= ~HC_DOWN_INTERPOLATION;
844
overlay->OV0CMD |= HC_UP_INTERPOLATION;
849
xscaleIntUV = xscaleInt >> MINUV_SCALE;
852
overlay->OV0CMD &= ~HC_UP_INTERPOLATION;
858
yscaleFractUV = yscaleFract >> MINUV_SCALE;
859
overlay->OV0CMD &= ~VC_DOWN_INTERPOLATION;
860
overlay->OV0CMD |= VC_UP_INTERPOLATION;
865
yscaleIntUV = yscaleInt >> MINUV_SCALE;
868
overlay->OV0CMD &= ~VC_UP_INTERPOLATION;
869
overlay->OV0CMD |= VC_DOWN_INTERPOLATION;
873
overlay->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) |
874
((yscaleFractUV & 0xFFF) << 20);
880
overlay->OV0STRIDE = (dstPitch << 1) | (dstPitch << 16);
881
overlay->OV0CMD &= ~SOURCE_FORMAT;
882
overlay->OV0CMD |= YUV_420;
887
overlay->OV0STRIDE = dstPitch;
888
overlay->OV0CMD &= ~SOURCE_FORMAT;
889
overlay->OV0CMD |= YUV_422;
890
overlay->OV0CMD &= ~OV_BYTE_ORDER;
891
if (id == FOURCC_UYVY)
892
overlay->OV0CMD |= Y_SWAP;
896
overlay->OV0CMD &= ~BUFFER_AND_FIELD;
897
if (pPriv->currentBuf == 0)
898
overlay->OV0CMD |= BUFFER0_FIELD0;
900
overlay->OV0CMD |= BUFFER1_FIELD0;
902
OVERLAY_UPDATE(i810c->OverlayPhysical);
908
KdScreenInfo *screen,
912
KdCardInfo *card=screen->card;
913
I810CardInfo *i810c = (I810CardInfo *) card->driver;
914
FBLinearPtr new_linear;
917
if(linear->size >= size)
920
ErrorF("Ran out of memory for overlay buffer, requested size = %d\n",size);
923
new_linear = xalloc(sizeof(FBLinearRec));
924
new_linear->size = i810c->XvMem.Size;
925
new_linear->offset = i810c->XvMem.Start;
927
/* fprintf(stderr,"Overlay mem offset %lx\n",new_linear->offset); */
933
i810PutImage(KdScreenInfo *screen,
951
KdCardInfo *card = screen->card;
952
I810CardInfo *i810c = (I810CardInfo *) card->driver;
953
I810PortPrivPtr pPriv = (I810PortPrivPtr)data;
954
INT32 x1, x2, y1, y2;
955
int srcPitch, dstPitch;
956
int top, left, npixels, nlines, size;
966
dstBox.x2 = drw_x + drw_w;
968
dstBox.y2 = drw_y + drw_h;
970
I810ClipVideo(&dstBox, &x1, &x2, &y1, &y2,
971
REGION_EXTENTS(pScreen, clipBoxes), width, height);
973
if((x1 >= x2) || (y1 >= y2))
979
srcPitch = (width + 3) & ~3;
980
dstPitch = ((width >> 1) + 7) & ~7; /* of chroma */
981
size = dstPitch * height * 3;
986
srcPitch = (width << 1);
987
dstPitch = (srcPitch + 7) & ~7;
988
size = dstPitch * height;
992
if(!(pPriv->linear = i810AllocateMemory(screen, pPriv->linear,
993
(screen->fb[0].bitsPerPixel == 16) ? size : (size >> 1))))
997
pPriv->YBuf0offset = pPriv->linear->offset;
998
pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height);
999
pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height >> 1);
1001
pPriv->YBuf1offset = pPriv->linear->offset + size;
1002
pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height);
1003
pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height >> 1);
1005
/* wait for the last rendered buffer to be flipped in */
1006
while (((INREG(DOV0STA)&0x00100000)>>20) != pPriv->currentBuf);
1009
if (pPriv->currentBuf == 0)
1010
pPriv->currentBuf = 1;
1012
pPriv->currentBuf = 0;
1016
left = (x1 >> 16) & ~1;
1017
npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
1023
nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
1024
i810CopyPlanarData(screen, buf, srcPitch, dstPitch, height, top, left,
1025
nlines, npixels, id);
1030
nlines = ((y2 + 0xffff) >> 16) - top;
1031
I810CopyPackedData(screen, buf, srcPitch, dstPitch, top, left, nlines,
1036
/* update cliplist */
1037
if(!REGION_EQUAL(screen->pScreen, &pPriv->clip, clipBoxes)) {
1038
REGION_COPY(screen->pScreen, &pPriv->clip, clipBoxes);
1039
KXVPaintRegion (pDraw, &pPriv->clip, pPriv->colorKey);
1043
i810DisplayVideo(screen, id, width, height, dstPitch,
1044
x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
1046
pPriv->videoStatus = CLIENT_VIDEO_ON;
1053
i810QueryImageAttributes(
1054
KdScreenInfo *screen,
1056
unsigned short *w, unsigned short *h,
1057
int *pitches, int *offsets
1061
if(*w > 720) *w = 720;
1062
if(*h > 576) *h = 576;
1065
if(offsets) offsets[0] = 0;
1071
size = (*w + 3) & ~3;
1072
if(pitches) pitches[0] = size;
1074
if(offsets) offsets[1] = size;
1075
tmp = ((*w >> 1) + 3) & ~3;
1076
if(pitches) pitches[1] = pitches[2] = tmp;
1079
if(offsets) offsets[2] = size;
1086
if(pitches) pitches[0] = size;
1101
ScreenPtr pScreen = screenInfo.screens[i];
1102
KdScreenPriv(pScreen);
1103
KdScreenInfo *screen = pScreenPriv->screen;
1104
KdCardInfo *card = screen->card;
1105
I810CardInfo *i810c = (I810CardInfo *) card->driver;
1106
I810PortPrivPtr pPriv = GET_PORT_PRIVATE(screen);
1107
I810OverlayRegPtr overlay = (I810OverlayRegPtr) (i810c->FbBase + i810c->OverlayStart);
1109
pScreen->BlockHandler = i810c->BlockHandler;
1111
(*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
1113
pScreen->BlockHandler = i810BlockHandler;
1115
if(pPriv->videoStatus & TIMER_MASK) {
1116
UpdateCurrentTime();
1117
if(pPriv->videoStatus & OFF_TIMER) {
1118
if(pPriv->offTime < currentTime.milliseconds) {
1119
/* Turn off the overlay */
1120
overlay->OV0CMD &= 0xFFFFFFFE;
1121
OVERLAY_UPDATE(i810c->OverlayPhysical);
1123
pPriv->videoStatus = FREE_TIMER;
1124
pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
1126
} else { /* FREE_TIMER */
1127
if(pPriv->freeTime < currentTime.milliseconds) {
1129
xfree(pPriv->linear);
1130
pPriv->linear = NULL;
1132
pPriv->videoStatus = 0;