diff options
author | Luc Verhaegen <libv@skynet.be> | 2009-08-10 17:27:15 +0200 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2009-11-04 15:13:02 +0100 |
commit | 1318f248783935e3370340e0ab3e3fb5547fbb0d (patch) | |
tree | 8e35ec05fcfb0aacf9f5bec279a3c4e33f9e88d4 | |
parent | 589e5fe6988ce12b63a33deca26b0659d6944622 (diff) |
XvMC: Fill out Xv side further so that we display (empty) mpeg buffers.
-rw-r--r-- | src/via_mpeg.c | 64 | ||||
-rw-r--r-- | src/via_mpeg.h | 3 | ||||
-rw-r--r-- | src/via_video.c | 87 |
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; |