sna_video.h revision fe8aea9e
1/***************************************************************************
2
3Copyright 2000 Intel Corporation.  All Rights Reserved.
4
5Permission is hereby granted, free of charge, to any person obtaining a
6copy of this software and associated documentation files (the
7"Software"), to deal in the Software without restriction, including
8without limitation the rights to use, copy, modify, merge, publish,
9distribute, sub license, and/or sell copies of the Software, and to
10permit persons to whom the Software is furnished to do so, subject to
11the following conditions:
12
13The above copyright notice and this permission notice (including the
14next paragraph) shall be included in all copies or substantial portions
15of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20IN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
21DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
23THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25**************************************************************************/
26
27#ifndef SNA_VIDEO_H
28#define SNA_VIDEO_H
29
30#include <xf86_OSproc.h>
31#include <xf86xv.h>
32#include <fourcc.h>
33
34#if defined(XvMCExtension) && defined(ENABLE_XVMC)
35#define SNA_XVMC 1
36#endif
37
38#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
39#define FOURCC_RGB565 ((16 << 24) + ('B' << 16) + ('G' << 8) + 'R')
40#define FOURCC_RGB888 ((24 << 24) + ('B' << 16) + ('G' << 8) + 'R')
41#define FOURCC_NV12 (('2' << 24) + ('1' << 16) + ('V' << 8) + 'N')
42#define FOURCC_AYUV (('V' << 24) + ('U' << 16) + ('Y' << 8) + 'A')
43
44/*
45 * Below, a dummy picture type that is used in XvPutImage
46 * only to do an overlay update.
47 * Introduced for the XvMC client lib.
48 * Defined to have a zero data size.
49 */
50#define XVMC_YUV { \
51	FOURCC_XVMC, XvYUV, LSBFirst, \
52	{'X', 'V', 'M', 'C', 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}, \
53	12, XvPlanar, 3, 0, 0, 0, 0, 8, 8, 8, 1, 2, 2, 1, 2, 2, \
54	{'Y', 'V', 'U', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
55	XvTopToBottom \
56}
57
58#define XVMC_RGB565 { \
59	FOURCC_RGB565, XvRGB, LSBFirst, \
60	{'P', 'A', 'S', 'S', 'T', 'H', 'R', 'O', 'U', 'G', 'H', 'R', 'G', 'B', '1', '6'}, \
61	16, XvPacked, 1, 16, 0x1f<<11, 0x3f<<5, 0x1f<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
62	{'B', 'G', 'R', 'X', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
63	XvTopToBottom \
64}
65
66#define XVMC_RGB888 { \
67	FOURCC_RGB888, XvRGB, LSBFirst, \
68	{'P', 'A', 'S', 'S', 'T', 'H', 'R', 'O', 'U', 'G', 'H', 'R', 'G', 'B', '2', '4'}, \
69	32, XvPacked, 1, 24, 0xff<<16, 0xff<<8, 0xff<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
70	{'B', 'G', 'R', 'X', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
71	XvTopToBottom \
72}
73
74/* no standard define for this */
75#define XVIMAGE_NV12 { \
76	FOURCC_NV12, XvYUV, LSBFirst,				\
77	{'N','V','1','2', 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \
78	12, XvPlanar, 2, 0, 0, 0, 0, 8, 8, 8, 1, 2, 2, 1, 2, 2, \
79	{'Y','U','V', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
80	XvTopToBottom \
81}
82
83#define XVIMAGE_AYUV { \
84	FOURCC_AYUV, XvYUV, LSBFirst, \
85	{'A', 'Y', 'U', 'V', 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}, \
86	32, XvPacked, 1, 0, 0, 0, 0, 8, 8, 8, 1, 1, 1, 1, 1, 1, \
87	{'A', 'Y', 'U', 'V', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
88	XvTopToBottom \
89}
90
91struct sna_video {
92	struct sna *sna;
93
94	int idx; /* XXX expose struct plane instead? */
95
96	int brightness;
97	int contrast;
98	int saturation;
99	xf86CrtcPtr desired_crtc;
100
101	uint32_t gamma0;
102	uint32_t gamma1;
103	uint32_t gamma2;
104	uint32_t gamma3;
105	uint32_t gamma4;
106	uint32_t gamma5;
107
108	unsigned color_key;
109	unsigned color_key_changed;
110	bool has_color_key;
111
112	unsigned colorspace;
113	unsigned colorspace_changed;
114
115	/** YUV data buffers */
116	struct kgem_bo *old_buf[2];
117	struct kgem_bo *buf;
118	int width, height, format;
119
120	int alignment;
121	bool tiled;
122	bool textured;
123
124	struct kgem_bo *bo[4];
125	RegionRec clip;
126
127	int SyncToVblank;	/* -1: auto, 0: off, 1: on */
128	int AlwaysOnTop;
129};
130
131struct sna_video_frame {
132	struct kgem_bo *bo;
133	uint32_t id;
134	uint32_t size;
135	uint32_t UBufOffset;
136	uint32_t VBufOffset;
137	Rotation rotation;
138
139	uint16_t width, height;
140	uint16_t pitch[2];
141
142	/* extents */
143	BoxRec image;
144	BoxRec src;
145};
146
147static inline XvScreenPtr to_xv(ScreenPtr screen)
148{
149	return dixLookupPrivate(&screen->devPrivates, XvGetScreenKey());
150}
151
152void sna_video_init(struct sna *sna, ScreenPtr screen);
153void sna_video_overlay_setup(struct sna *sna, ScreenPtr screen);
154void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen);
155void sna_video_textured_setup(struct sna *sna, ScreenPtr screen);
156void sna_video_destroy_window(WindowPtr win);
157void sna_video_close(struct sna *sna);
158
159XvAdaptorPtr sna_xv_adaptor_alloc(struct sna *sna);
160int sna_xv_fixup_formats(ScreenPtr screen,
161			 XvFormatPtr formats,
162			 int num_formats);
163int sna_xv_alloc_port(unsigned long port, XvPortPtr in, XvPortPtr *out);
164int sna_xv_free_port(XvPortPtr port);
165
166static inline int xvmc_passthrough(int id)
167{
168	switch (id) {
169	case FOURCC_XVMC:
170	case FOURCC_RGB565:
171	case FOURCC_RGB888:
172		return true;
173	default:
174		return false;
175	}
176}
177
178static inline int is_planar_fourcc(int id)
179{
180	switch (id) {
181	case FOURCC_YV12:
182	case FOURCC_I420:
183	case FOURCC_XVMC:
184	case FOURCC_NV12:
185		return 1;
186	default:
187		return 0;
188	}
189}
190
191static inline int is_nv12_fourcc(int id)
192{
193	switch (id) {
194	case FOURCC_NV12:
195		return 1;
196	default:
197		return 0;
198	}
199}
200
201static inline int is_ayuv_fourcc(int id)
202{
203	switch (id) {
204	case FOURCC_AYUV:
205		return 1;
206	default:
207		return 0;
208	}
209}
210
211bool
212sna_video_clip_helper(struct sna_video *video,
213		      struct sna_video_frame *frame,
214		      xf86CrtcPtr *crtc_ret,
215		      BoxPtr dst,
216		      short src_x, short src_y,
217		      short drw_x, short drw_y,
218		      short src_w, short src_h,
219		      short drw_w, short drw_h,
220		      RegionPtr reg);
221
222void
223sna_video_frame_init(struct sna_video *video,
224		     int id, short width, short height,
225		     struct sna_video_frame *frame);
226
227void
228sna_video_frame_set_rotation(struct sna_video *video,
229			     struct sna_video_frame *frame,
230			     Rotation rotation);
231
232struct kgem_bo *
233sna_video_buffer(struct sna_video *video,
234		 struct sna_video_frame *frame);
235
236bool
237sna_video_copy_data(struct sna_video *video,
238		    struct sna_video_frame *frame,
239		    const uint8_t *buf);
240void
241sna_video_fill_colorkey(struct sna_video *video,
242			const RegionRec *clip);
243
244void sna_video_buffer_fini(struct sna_video *video);
245
246void sna_video_free_buffers(struct sna_video *video);
247
248static inline XvPortPtr
249sna_window_get_port(WindowPtr window)
250{
251	return ((void **)__get_private(window, sna_window_key))[2];
252}
253
254static inline void
255sna_window_set_port(WindowPtr window, XvPortPtr port)
256{
257	((void **)__get_private(window, sna_window_key))[2] = port;
258}
259
260static inline int offset_and_clip(int x, int dx)
261{
262	x += dx;
263	if (x <= 0)
264		return 0;
265	if (x >= MAXSHORT)
266		return MAXSHORT;
267	return x;
268}
269
270static inline void init_video_region(RegionRec *region,
271				     DrawablePtr draw,
272				     int drw_x, int drw_y,
273				     int drw_w, int drw_h)
274{
275	region->extents.x1 = offset_and_clip(draw->x, drw_x);
276	region->extents.y1 = offset_and_clip(draw->y, drw_y);
277	region->extents.x2 = offset_and_clip(draw->x, drw_x + drw_w);
278	region->extents.y2 = offset_and_clip(draw->y, drw_y + drw_h);
279	region->data = NULL;
280}
281
282#endif /* SNA_VIDEO_H */
283