Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

enable auto crop black bars on dxva decoded #395

Closed
wants to merge 1 commit into from

3 participants

@Voyager1
Collaborator

Added this code to enable 4:3 widescreen (black bars) dxva-decoded content to be auto-cropped.

@CrystalP
Collaborator

Yes for the idea, but no for the implementation. Performance is going to be bad with the gpu->sys mem copies. That's the reason it hasn't been done yet with dxva decoding or vdpau.
The work needs to be done in gpu memory and only the result should be sent back, to save on upload bandwidth. This may be the first reason we have to look into OpenCL as I'm not sure a shader can do it in a reasonable manner.

@Voyager1
Collaborator

i'm experimenting with hardware decoding of dvds and on the ION it seems to be doing just fine. Now what we could do to mitigate performance risk, is to only auto crop every 25 frames (or so) and assume that in between the same crop rectangle has to be applied. This would reduce the load significantly (that could even be used on software decoded).

@CrystalP
Collaborator

What matters here is the time available between two vsyncs and the amount of work to get done. Whether the copy is done every frame or once in 25 frames, that doesn't change your worst case.
To reduce the load, the work would have to be broken down in 1/25 (or whatever) slices of images at each frame.
Meaning an extra buffer (1/25 the height for example) receiving only a slice of the frame. Uploading that to sys mem would take less resources.
At each frame, a different slice gets copied so that in 25 frames, the whole frame has been transferred. As you said, black bars shouldn't move much so it's not important that the 25 slices are from the same frame.

Or just do the work with the GPU.

@elupus elupus closed this
@Voyager1 Voyager1 deleted the Voyager1:fix-crop-black-bars-dxva branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 2, 2011
  1. enable auto crop black bars on dxva decoded

    Voyager-xbmc authored
This page is out of date. Refresh to see the latest.
Showing with 59 additions and 22 deletions.
  1. +59 −22 xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
View
81 xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
@@ -1255,6 +1255,7 @@ void CDVDPlayerVideo::AutoCrop(DVDVideoPicture *pPicture)
{
if ((pPicture->format == DVDVideoPicture::FMT_YUV420P) ||
(pPicture->format == DVDVideoPicture::FMT_NV12) ||
+ (pPicture->format == DVDVideoPicture::FMT_DXVA) ||
(pPicture->format == DVDVideoPicture::FMT_YUY2) ||
(pPicture->format == DVDVideoPicture::FMT_UYVY))
{
@@ -1326,15 +1327,43 @@ void CDVDPlayerVideo::AutoCrop(DVDVideoPicture *pPicture, RECT &crop)
xstart = 1;
}
+ // define base parameters for non-dxva
+ unsigned int lineSize = pPicture->iLineSize[0];
+ unsigned int pictureWidth = pPicture->iWidth;
+ unsigned int pictureHeight = pPicture->iHeight;
+ BYTE *pictureBase = pPicture->data[0];
+
+#ifdef HAS_DX
+ IDirect3DSurface9* surface = NULL;
+ if (pPicture->format == DVDVideoPicture::FMT_DXVA)
+ {
+ switch (pPicture->extended_format) {
+ case MAKEFOURCC('N','V','1','2'):
+ {
+ surface = (IDirect3DSurface9*)pPicture->data[3];
+ D3DLOCKED_RECT rectangle;
+ if (FAILED(surface->LockRect(&rectangle, NULL, 0)))
+ return;
+ pictureBase = (BYTE *)rectangle.pBits;
+ lineSize = rectangle.Pitch;
+ break;
+ }
+ default:
+ // other FOURCC not implemented
+ return;
+ }
+ }
+#endif
+
// Crop top
- s = pPicture->data[0];
+ s = pictureBase;
last = black2;
- for (unsigned int y = 0; y < pPicture->iHeight/2; y++)
+ for (unsigned int y = 0; y < pictureHeight/2; y++)
{
int total = 0;
- for (unsigned int x = xstart; x < pPicture->iWidth * xspacing; x += xspacing)
+ for (unsigned int x = xstart; x < pictureWidth * xspacing; x += xspacing)
total += s[x];
- s += pPicture->iLineSize[0];
+ s += lineSize;
if (total > detect)
{
@@ -1346,37 +1375,37 @@ void CDVDPlayerVideo::AutoCrop(DVDVideoPicture *pPicture, RECT &crop)
}
// Crop bottom
- s = pPicture->data[0] + (pPicture->iHeight-1) * pPicture->iLineSize[0];
+ s = pictureBase + (pictureHeight-1) * lineSize;
last = black2;
- for (unsigned int y = (int)pPicture->iHeight; y > pPicture->iHeight/2; y--)
+ for (unsigned int y = (int)pictureHeight; y > pictureHeight/2; y--)
{
int total = 0;
- for (unsigned int x = xstart; x < pPicture->iWidth * xspacing; x += xspacing)
+ for (unsigned int x = xstart; x < pictureWidth * xspacing; x += xspacing)
total += s[x];
- s -= pPicture->iLineSize[0];
+ s -= lineSize;
if (total > detect)
{
if (total - black2 > (last - black2) * multi)
- crop.bottom = pPicture->iHeight - y;
+ crop.bottom = pictureHeight - y;
break;
}
last = total;
}
// left and right levels
- black2 = black * pPicture->iHeight;
- detect = level * pPicture->iHeight + black2;
+ black2 = black * pictureHeight;
+ detect = level * pictureHeight + black2;
// Crop left
- s = pPicture->data[0];
+ s = pictureBase;
last = black2;
- for (unsigned int x = xstart; x < pPicture->iWidth/2*xspacing; x += xspacing)
+ for (unsigned int x = xstart; x < pictureWidth/2*xspacing; x += xspacing)
{
int total = 0;
- for (unsigned int y = 0; y < pPicture->iHeight; y++)
- total += s[y * pPicture->iLineSize[0]];
+ for (unsigned int y = 0; y < pictureHeight; y++)
+ total += s[y * lineSize];
s++;
if (total > detect)
{
@@ -1388,19 +1417,19 @@ void CDVDPlayerVideo::AutoCrop(DVDVideoPicture *pPicture, RECT &crop)
}
// Crop right
- s = pPicture->data[0] + (pPicture->iWidth-1);
+ s = pictureBase + (pictureWidth-1);
last = black2;
- for (unsigned int x = (int)pPicture->iWidth*xspacing-1; x > pPicture->iWidth/2*xspacing; x -= xspacing)
+ for (unsigned int x = (int)pictureWidth*xspacing-1; x > pictureWidth/2*xspacing; x -= xspacing)
{
int total = 0;
- for (unsigned int y = 0; y < pPicture->iHeight; y++)
- total += s[y * pPicture->iLineSize[0]];
+ for (unsigned int y = 0; y < pictureHeight; y++)
+ total += s[y * lineSize];
s--;
if (total > detect)
{
if (total - black2 > (last - black2) * multi)
- crop.right = pPicture->iWidth - (x / xspacing);
+ crop.right = pictureWidth - (x / xspacing);
break;
}
last = total;
@@ -1414,17 +1443,25 @@ void CDVDPlayerVideo::AutoCrop(DVDVideoPicture *pPicture, RECT &crop)
min = std::min(crop.left, crop.right);
max = std::max(crop.left, crop.right);
- if(10 * (max - min) / pPicture->iWidth < 1)
+ if(10 * (max - min) / pictureWidth < 1)
crop.left = crop.right = max;
else
crop.left = crop.right = min;
min = std::min(crop.top, crop.bottom);
max = std::max(crop.top, crop.bottom);
- if(10 * (max - min) / pPicture->iHeight < 1)
+ if(10 * (max - min) / pictureHeight < 1)
crop.top = crop.bottom = max;
else
crop.top = crop.bottom = min;
+
+#ifdef HAS_DX
+ if (surface)
+ {
+ if (FAILED(surface->UnlockRect()))
+ return;
+ }
+#endif
}
std::string CDVDPlayerVideo::GetPlayerInfo()
Something went wrong with that request. Please try again.