summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sna/sna_video.h19
-rw-r--r--src/sna/sna_video_overlay.c53
-rw-r--r--src/sna/sna_video_sprite.c46
-rw-r--r--src/sna/sna_video_textured.c37
4 files changed, 96 insertions, 59 deletions
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index c0c023cf..2e7144ec 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -35,6 +35,20 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SNA_XVMC 1
#endif
+/*
+ * Below, a dummy picture type that is used in XvPutImage
+ * only to do an overlay update.
+ * Introduced for the XvMC client lib.
+ * Defined to have a zero data size.
+ */
+#define XVMC_YUV { \
+ FOURCC_XVMC, XvYUV, LSBFirst, \
+ {'X', 'V', 'M', 'C', 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}, \
+ 12, XvPlanar, 3, 0, 0, 0, 0, 8, 8, 8, 1, 2, 2, 1, 2, 2, \
+ {'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}, \
+ XvTopToBottom \
+}
+
struct sna_video {
int brightness;
int contrast;
@@ -88,6 +102,11 @@ XF86VideoAdaptorPtr sna_video_textured_setup(struct sna *sna, ScreenPtr screen);
#define FOURCC_XVMC (('C' << 24) + ('M' << 16) + ('V' << 8) + 'X')
+static inline int xvmc_passthrough(int id)
+{
+ return id == FOURCC_XVMC;
+}
+
static inline int is_planar_fourcc(int id)
{
switch (id) {
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index 3655b876..459541c8 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -91,12 +91,12 @@ static const XF86AttributeRec GammaAttributes[GAMMA_ATTRIBUTES] = {
{XvSettable | XvGettable, 0, 0xffffff, "XV_GAMMA5"}
};
-#define NUM_IMAGES 4
-static const XF86ImageRec Images[NUM_IMAGES] = {
+static const XF86ImageRec Images[] = {
XVIMAGE_YUY2,
XVIMAGE_YV12,
XVIMAGE_I420,
XVIMAGE_UYVY,
+ XVMC_YUV
};
/* kernel modesetting overlay functions */
@@ -515,15 +515,32 @@ sna_video_overlay_put_image(ScrnInfoPtr scrn,
/* overlay can't handle rotation natively, store it for the copy func */
video->rotation = crtc->rotation;
- frame.bo = sna_video_buffer(sna, video, &frame);
- if (frame.bo == NULL) {
- DBG(("%s: failed to allocate video bo\n", __FUNCTION__));
- return BadAlloc;
- }
-
- if (!sna_video_copy_data(sna, video, &frame, buf)) {
- DBG(("%s: failed to copy video data\n", __FUNCTION__));
- return BadAlloc;
+ if (xvmc_passthrough(id)) {
+ DBG(("%s: using passthough, name=%d\n",
+ __FUNCTION__, *(uint32_t *)buf));
+
+ frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf);
+ if (frame.bo == NULL) {
+ DBG(("%s: failed to open bo\n", __FUNCTION__));
+ return BadAlloc;
+ }
+
+ assert(kgem_bo_size(frame.bo) >= frame.size);
+ frame.image.x1 = 0;
+ frame.image.y1 = 0;
+ frame.image.x2 = frame.width;
+ frame.image.y2 = frame.height;
+ } else {
+ frame.bo = sna_video_buffer(sna, video, &frame);
+ if (frame.bo == NULL) {
+ DBG(("%s: failed to allocate video bo\n", __FUNCTION__));
+ return BadAlloc;
+ }
+
+ if (!sna_video_copy_data(sna, video, &frame, buf)) {
+ DBG(("%s: failed to copy video data\n", __FUNCTION__));
+ return BadAlloc;
+ }
}
if (!sna_video_overlay_show
@@ -533,7 +550,10 @@ sna_video_overlay_put_image(ScrnInfoPtr scrn,
}
frame.bo->domain = DOMAIN_NONE;
- sna_video_buffer_fini(sna, video);
+ if (xvmc_passthrough(id))
+ kgem_bo_destroy(&sna->kgem, frame.bo);
+ else
+ sna_video_buffer_fini(sna, video);
/* update cliplist */
if (!REGION_EQUAL(scrn->pScreen, &video->clip, clip)) {
@@ -572,6 +592,13 @@ sna_video_overlay_query_video_attributes(ScrnInfoPtr scrn,
offsets[0] = 0;
switch (id) {
+ case FOURCC_XVMC:
+ *h = (*h + 1) & ~1;
+ size = sizeof(uint32_t);
+ if (pitches)
+ pitches[0] = size;
+ break;
+
/* IA44 is for XvMC only */
case FOURCC_IA44:
case FOURCC_AI44:
@@ -689,7 +716,7 @@ XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna,
memcpy(adaptor->pAttributes + NUM_ATTRIBUTES, GammaAttributes,
sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES);
- adaptor->nImages = NUM_IMAGES;
+ adaptor->nImages = ARRAY_SIZE(Images);
adaptor->pImages = (XF86ImagePtr)Images;
adaptor->PutVideo = NULL;
adaptor->PutStill = NULL;
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index 7737460b..a749d1ef 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -53,7 +53,7 @@ static Atom xvColorKey;
static XF86VideoFormatRec xv_formats[] = {
{15, TrueColor}, {16, TrueColor}, {24, TrueColor}
};
-static XF86ImageRec xv_images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, };
+static XF86ImageRec xv_images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_YUV};
static const XF86VideoEncodingRec xv_dummy_encoding[] = {
{ 0, "XV_IMAGE", IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, {1, 1} }
};
@@ -314,15 +314,30 @@ static int sna_video_sprite_put_image(ScrnInfoPtr scrn,
/* sprites can't handle rotation natively, store it for the copy func */
video->rotation = crtc->rotation;
- frame.bo = sna_video_buffer(sna, video, &frame);
- if (frame.bo == NULL) {
- DBG(("%s: failed to allocate video bo\n", __FUNCTION__));
- return BadAlloc;
- }
+ if (xvmc_passthrough(id)) {
+ DBG(("%s: using passthough, name=%d\n",
+ __FUNCTION__, *(uint32_t *)buf));
- if (!sna_video_copy_data(sna, video, &frame, buf)) {
- DBG(("%s: failed to copy video data\n", __FUNCTION__));
- return BadAlloc;
+ frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf);
+ if (frame.bo == NULL)
+ return BadAlloc;
+
+ assert(kgem_bo_size(frame.bo) >= frame.size);
+ frame.image.x1 = 0;
+ frame.image.y1 = 0;
+ frame.image.x2 = frame.width;
+ frame.image.y2 = frame.height;
+ } else {
+ frame.bo = sna_video_buffer(sna, video, &frame);
+ if (frame.bo == NULL) {
+ DBG(("%s: failed to allocate video bo\n", __FUNCTION__));
+ return BadAlloc;
+ }
+
+ if (!sna_video_copy_data(sna, video, &frame, buf)) {
+ DBG(("%s: failed to copy video data\n", __FUNCTION__));
+ return BadAlloc;
+ }
}
if (!sna_video_sprite_show(sna, video, &frame, crtc, &dst_box)) {
@@ -330,7 +345,11 @@ static int sna_video_sprite_put_image(ScrnInfoPtr scrn,
return BadAlloc;
}
- sna_video_buffer_fini(sna, video);
+ frame.bo->domain = DOMAIN_NONE;
+ if (xvmc_passthrough(id))
+ kgem_bo_destroy(&sna->kgem, frame.bo);
+ else
+ sna_video_buffer_fini(sna, video);
if (!REGION_EQUAL(scrn->pScreen, &video->clip, clip)) {
REGION_COPY(scrn->pScreen, &video->clip, clip);
@@ -356,6 +375,13 @@ static int sna_video_sprite_query_attrs(ScrnInfoPtr scrn, int id,
offsets[0] = 0;
switch (id) {
+ case FOURCC_XVMC:
+ *h = (*h + 1) & ~1;
+ size = sizeof(uint32_t);
+ if (pitches)
+ pitches[0] = size;
+ break;
+
case FOURCC_YUY2:
default:
size = *w << 1;
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index d94dbd8f..ddde2494 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -69,44 +69,9 @@ static const XF86ImageRec Images[NUM_IMAGES] = {
XVIMAGE_YV12,
XVIMAGE_I420,
XVIMAGE_UYVY,
-#ifdef SNA_XVMC
- {
- /*
- * Below, a dummy picture type that is used in XvPutImage
- * only to do an overlay update.
- * Introduced for the XvMC client lib.
- * Defined to have a zero data size.
- */
- FOURCC_XVMC,
- XvYUV,
- LSBFirst,
- {'X', 'V', 'M', 'C',
- 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0xAA, 0x00,
- 0x38, 0x9B, 0x71},
- 12,
- XvPlanar,
- 3,
- 0, 0, 0, 0,
- 8, 8, 8,
- 1, 2, 2,
- 1, 2, 2,
- {'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},
- XvTopToBottom},
-#endif
+ XVMC_YUV,
};
-static int xvmc_passthrough(int id)
-{
-#ifdef SNA_XVMC
- return id == FOURCC_XVMC;
-#else
- return 0;
- (void)id;
-#endif
-}
-
static void sna_video_textured_stop(ScrnInfoPtr scrn,
pointer data,
Bool shutdown)