summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2009-08-10 17:27:15 +0200
committerLuc Verhaegen <libv@skynet.be>2009-11-04 15:13:02 +0100
commit1318f248783935e3370340e0ab3e3fb5547fbb0d (patch)
tree8e35ec05fcfb0aacf9f5bec279a3c4e33f9e88d4
parent589e5fe6988ce12b63a33deca26b0659d6944622 (diff)
XvMC: Fill out Xv side further so that we display (empty) mpeg buffers.
-rw-r--r--src/via_mpeg.c64
-rw-r--r--src/via_mpeg.h3
-rw-r--r--src/via_video.c87
3 files changed, 120 insertions, 34 deletions
diff --git a/src/via_mpeg.c b/src/via_mpeg.c
index 0c435ed..3eebbdd 100644
--- a/src/via_mpeg.c
+++ b/src/via_mpeg.c
@@ -631,6 +631,70 @@ ViaMpegSlicePut(struct ViaMpeg *Mpeg, XID BufferID, CARD8 SliceCode,
/*
*
*/
+Bool
+ViaMpegBufferIDVerify(struct ViaMpeg *Mpeg, XID BufferID, int Width, int Height)
+{
+ int i;
+
+ ViaDebug(Mpeg->scrnIndex, "%s: 0x%08X (%dx%d)\n",
+ __func__, BufferID, Width, Height);
+
+ if ((Width != Mpeg->Width) || (Height != Mpeg->Height)) {
+ xf86DrvMsg(Mpeg->scrnIndex, X_WARNING, "%s: Wrong dimensions for Buffer"
+ " 0x%08X: %dx%d versus %dx%d.\n", __func__,
+ (unsigned int) BufferID, Width, Height,
+ Mpeg->Width, Mpeg->Height);
+ return FALSE;
+ }
+
+ /* Check ID */
+ for (i = 0; i < VIAMPEG_BUFFERS_MAX; i++)
+ if (Mpeg->Buffers[i].ID == BufferID)
+ break;
+
+ if (i == VIAMPEG_BUFFERS_MAX) {
+ xf86DrvMsg(Mpeg->scrnIndex, X_WARNING,
+ "%s: Wrong Buffer ID (0x%08X).\n",
+ __func__, (unsigned int) BufferID);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ *
+ */
+unsigned long
+ViaMpegBufferFlip(struct ViaMpeg *Mpeg, XID BufferID)
+{
+ int i;
+
+ ViaDebug(Mpeg->scrnIndex, "%s: 0x%08X\n",
+ __func__, BufferID);
+
+ /* Check ID */
+ for (i = 0; i < VIAMPEG_BUFFERS_MAX; i++)
+ if (Mpeg->Buffers[i].ID == BufferID)
+ break;
+
+ /* should never happen, as ID should've been checked before. */
+ if (i == VIAMPEG_BUFFERS_MAX) {
+ xf86DrvMsg(Mpeg->scrnIndex, X_WARNING,
+ "%s: Wrong Buffer ID (0x%08X).\n",
+ __func__, (unsigned int) BufferID);
+ return 0;
+ }
+
+ if (BufferID == Mpeg->CurrentID)
+ ViaMpegEngineIdle(Mpeg);
+
+ return Mpeg->Buffers[i].Mem->Base;
+}
+
+/*
+ *
+ */
void
ViaMpegInit(ScrnInfoPtr pScrn)
{
diff --git a/src/via_mpeg.h b/src/via_mpeg.h
index f5e5996..c56d8b3 100644
--- a/src/via_mpeg.h
+++ b/src/via_mpeg.h
@@ -88,6 +88,9 @@ void ViaSubPictureDestroy(ScrnInfoPtr pScrn);
void ViaMpegInit(ScrnInfoPtr pScrn);
void ViaMpegStop(ScrnInfoPtr pScrn);
void ViaMpegDestroy(ScrnInfoPtr pScrn);
+Bool ViaMpegBufferIDVerify(struct ViaMpeg *Mpeg, XID BufferID,
+ int Width, int Height);
+unsigned long ViaMpegBufferFlip(struct ViaMpeg *Mpeg, XID BufferID);
/* prototypes for the X extension. */
Bool ViaMpegEngineInit(struct ViaMpeg *Mpeg, CARD16 Width, CARD16 Height);
diff --git a/src/via_video.c b/src/via_video.c
index 2cafa10..768f01c 100644
--- a/src/via_video.c
+++ b/src/via_video.c
@@ -1051,6 +1051,7 @@ ViaHQVFetch(VIAPtr pVia)
switch (Port->FourCC) {
case FOURCC_YV12:
case FOURCC_I420:
+ case FOURCC_MPEG:
/* Fetch is ok */
break;
case FOURCC_YUY2:
@@ -1076,7 +1077,7 @@ ViaHQVFetch(VIAPtr pVia)
}
/*
- *
+ * Abuse this when using MPEG, we use it to set up offsets and stuff.
*/
static Bool
ViaAllocateFrontBuffer(ScrnInfoPtr pScrn, int FourCC, CARD16 Width, CARD16 Height)
@@ -1098,6 +1099,7 @@ ViaAllocateFrontBuffer(ScrnInfoPtr pScrn, int FourCC, CARD16 Width, CARD16 Heigh
switch (FourCC) {
case FOURCC_YV12:
case FOURCC_I420:
+ case FOURCC_MPEG:
if (FourCC == FOURCC_I420) { /* YUV */
Port->CbOffset = Width * Height;
Port->CrOffset = Port->CbOffset + (Width >> 1) * (Height >> 1);
@@ -1136,25 +1138,28 @@ ViaAllocateFrontBuffer(ScrnInfoPtr pScrn, int FourCC, CARD16 Width, CARD16 Heigh
Port->Width = Width;
Port->Height = Height;
- /* Front buffer, where the HQV sources its video. */
- Port->Front[0] = ViaMemAlloc(pScrn, Size, 16);
- if (!Port->Front[0])
- return FALSE;
-
- /* This one may fail. */
- Port->Front[1] = ViaMemAlloc(pScrn, Size, 16);
- if (!Port->Front[1]) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Not enough memory available.\n",
- __func__);
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Using only a single front buffer.\n",
- __func__);
-
- /* single buffering -- address always remains the same so set it now */
- Swov->HQV->SrcAddressY = Port->Front[0]->Base;
- if (Port->CrOffset) {
- Swov->HQV->SrcAddressU = Port->Front[0]->Base + Port->CbOffset;
- Swov->HQV->SrcAddressV = Port->Front[0]->Base + Port->CrOffset;
- }
+ /* MPEG code does its own front buffer management. */
+ if (FourCC != FOURCC_MPEG) {
+ /* Front buffer, where the HQV sources its video. */
+ Port->Front[0] = ViaMemAlloc(pScrn, Size, 16);
+ if (!Port->Front[0])
+ return FALSE;
+
+ /* This one may fail. */
+ Port->Front[1] = ViaMemAlloc(pScrn, Size, 16);
+ if (!Port->Front[1]) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Not enough memory available.\n",
+ __func__);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Using only a single front buffer.\n",
+ __func__);
+
+ /* single buffering -- address always remains the same so set it now */
+ Swov->HQV->SrcAddressY = Port->Front[0]->Base;
+ if (Port->CrOffset) {
+ Swov->HQV->SrcAddressU = Port->Front[0]->Base + Port->CbOffset;
+ Swov->HQV->SrcAddressV = Port->Front[0]->Base + Port->CrOffset;
+ }
+ }
}
ViaHQVFetch(pVia);
@@ -1171,6 +1176,7 @@ ViaSwovStride(struct ViaSwov *Swov, struct ViaXvPort *Port)
switch (Port->FourCC) {
case FOURCC_YV12:
case FOURCC_I420:
+ case FOURCC_MPEG:
/* planar YUV */
Swov->HQV->SrcStride = ((Port->Width >> 1) << 16) | Port->Width;
Swov->HQV->DstStride = Port->Width << 1;
@@ -1222,6 +1228,7 @@ ViaAllocateBackBuffers(ScrnInfoPtr pScrn)
case FOURCC_YUY2:
case FOURCC_RV15:
case FOURCC_RV16:
+ case FOURCC_MPEG:
Size = Port->Width * Port->Height * 2;
break;
case FOURCC_RV32:
@@ -1366,6 +1373,7 @@ ViaHQVFormat(struct ViaSwov *Swov)
switch (Port->FourCC) {
case FOURCC_YV12:
case FOURCC_I420:
+ case FOURCC_MPEG:
Swov->HQV->Control |= HQV_YUV420;
break;
case FOURCC_YUY2:
@@ -1421,6 +1429,7 @@ ViaVideo3Format(struct ViaSwov *Swov)
case FOURCC_YV12:
case FOURCC_I420:
case FOURCC_YUY2:
+ case FOURCC_MPEG:
Swov->V3Shadow->Control |= V3_YUV422;
break;
case FOURCC_RV15:
@@ -1889,15 +1898,23 @@ ViaHQVFlip(VIAPtr pVia, unsigned char* buf)
}
if (buf) { /* if NULL, then we need to flip the previous buffer again */
- if (!Port->Front[1]) /* single buffering */
- ViaSwovCopy(xf86Screens[pVia->scrnIndex], Port->Front[0], buf);
- else { /* We only need to set the address */
- Swov->HQV->SrcAddressY = Port->Front[0]->Base;
- if (Port->CrOffset) {
- Swov->HQV->SrcAddressU = Port->Front[0]->Base + Port->CbOffset;
- Swov->HQV->SrcAddressV = Port->Front[0]->Base + Port->CrOffset;
- }
- }
+ if (Port->FourCC != FOURCC_MPEG) {
+ if (!Port->Front[1]) /* single buffering */
+ ViaSwovCopy(xf86Screens[pVia->scrnIndex], Port->Front[0], buf);
+ else { /* We only need to set the address */
+ Swov->HQV->SrcAddressY = Port->Front[0]->Base;
+ if (Port->CrOffset) {
+ Swov->HQV->SrcAddressU = Port->Front[0]->Base + Port->CbOffset;
+ Swov->HQV->SrcAddressV = Port->Front[0]->Base + Port->CrOffset;
+ }
+ }
+ } else {
+ unsigned long Base = ViaMpegBufferFlip(Swov->Mpeg, *((XID *) buf));
+
+ Swov->HQV->SrcAddressY = Base;
+ Swov->HQV->SrcAddressU = Base + Port->CbOffset;
+ Swov->HQV->SrcAddressV = Base + Port->CrOffset;
+ }
}
Swov->HQV->Control |= HQV_SW_FLIP | HQV_FLIP_STATUS;
@@ -1975,11 +1992,13 @@ viaPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x,
struct ViaXvPort *Port = (struct ViaXvPort *) data;
Bool ReAlloc = FALSE, Video3Touched = FALSE, ClippingTouched = FALSE;
- if (id == FOURCC_MPEG) {
- ViaDebug(pScrn->scrnIndex, "%s: MPEG: 0x%08X\n", __func__,
- *((XID *) buf));
- return Success;
- }
+ if (id == FOURCC_MPEG)
+ if (!ViaMpegBufferIDVerify(Swov->Mpeg, *((XID *) buf), width, height)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Unable to display "
+ "Mpeg Buffer 0x%08X.\n", __func__,
+ (unsigned int) *((XID *) buf));
+ return BadAccess;
+ }
if (!Swov->Active) { /* initial pass */
ReAlloc = TRUE;