summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohns <johns98@gmx.net>2012-01-29 11:28:10 +0100
committerJohns <johns98@gmx.net>2012-01-29 11:28:10 +0100
commit422c378a5e221392715e3a824f0759fea58a0f2d (patch)
tree320b4b555e433c73ad6b834be3a2116c5fb1b81c
parenteed708b9ea6fa3f8647590a58867f4f798ab728c (diff)
downloadvdr-plugin-softhddevice-422c378a5e221392715e3a824f0759fea58a0f2d.tar.gz
vdr-plugin-softhddevice-422c378a5e221392715e3a824f0759fea58a0f2d.tar.bz2
Add workaround for Intel VA-API MPEG GPU hung.
-rw-r--r--ChangeLog5
-rw-r--r--README.txt2
-rw-r--r--Todo10
-rw-r--r--video.c76
4 files changed, 72 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 34b470c..2eb324c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,11 @@
User johns
Date:
+ Add workaround for Intel VA-API MPEG GPU hung.
+
+User johns
+Date: Sat Jan 28 13:32:12 CET 2012
+
Release Version 0.4.5
Add configurable skip lines at video top and bottom.
Add auto-crop tolerance configuration.
diff --git a/README.txt b/README.txt
index 09ca6de..aaec1c9 100644
--- a/README.txt
+++ b/README.txt
@@ -146,6 +146,8 @@ Setup: /etc/vdr/setup.conf
if detected crop area is too small, cut max 'n' pixels at top and
bottom.
+ softhddevice.SkipLines = 0
+ skip 'n' lines at top and bottom of the video picture.
softhddevice.Suspend.Close = 0
1 suspend closes x11 window, connection and audio device.
diff --git a/Todo b/Todo
index 03ea597..9ace52b 100644
--- a/Todo
+++ b/Todo
@@ -38,7 +38,9 @@ video:
suspendoutput didn't show logo or black pictures
(must detect video format to show image)
hard channel switch
- skip line not configurable from setup menu.
+ skip lines not configurable from setup menu.
+ software decoder path didn't support auto-crop
+ software decoder path didn't support correct 4:3 16:9
vdpau:
@@ -46,7 +48,7 @@ libva:
yaepghd (VaapiSetOutputPosition) support
can associate only displayed part of osd
grab image for va-api
- still many:
+ still many: (workaround export NO_MPEG_HW=1)
[drm:i915_hangcheck_elapsed] *ERROR* Hangcheck timer elapsed... GPU hung
[drm:i915_wait_request] *ERROR* i915_wait_request returns -11 ...
@@ -56,7 +58,8 @@ libva: branch vaapi-ext
libva-intel-driver:
1080i does no v-sync (sometimes correct working with vaapi-ext)
OSD has sometimes wrong size (workaround written)
- software decoder needs UV swab
+ sometimes software decoder deinterlace isn't working and 1080i channels
+ show artefacts
libva-vdpau-driver:
G210/GT520 OSD update too slow (needs hardware problem workaround)
@@ -85,6 +88,7 @@ audio/alsa:
audio/oss:
alsa oss emulation mixer "pcm" not working
+ oss4 mixer channel not working
ring buffer overflow with alsa oss emulation
HDMI/SPDIF Passthrough:
diff --git a/video.c b/video.c
index 7bc5234..04dbbeb 100644
--- a/video.c
+++ b/video.c
@@ -1561,6 +1561,7 @@ static void VaapiCleanup(VaapiDecoder * decoder)
VaapiDestroyDeinterlaceImages(decoder);
}
+ decoder->FrameCounter = 0;
decoder->PTS = AV_NOPTS_VALUE;
VideoDeltaPTS = 0;
}
@@ -1865,7 +1866,10 @@ static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder,
// cleanup last context
VaapiCleanup(decoder);
- if (!VideoHardwareDecoder) { // hardware disabled by config
+ if (!VideoHardwareDecoder
+ || (video_ctx->codec_id == CODEC_ID_MPEG2VIDEO
+ && VideoHardwareDecoder == 1)
+ ) { // hardware disabled by config
Debug(3, "codec: hardware acceleration disabled\n");
goto slow_path;
}
@@ -2064,6 +2068,8 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
{
unsigned type;
VAStatus status;
+ uint32_t s;
+ uint32_t e;
// deinterlace
if (interlaced
@@ -2086,6 +2092,7 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
type = VA_FRAME_PICTURE;
}
+ s = GetMsTicks();
xcb_flush(Connection);
if ((status = vaPutSurface(decoder->VaDisplay, surface, decoder->Window,
// decoder src
@@ -2100,6 +2107,15 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
Error(_("video/vaapi: vaPutSurface failed %d\n"), status);
}
+ if (0 && vaSyncSurface(decoder->VaDisplay, surface) != VA_STATUS_SUCCESS) {
+ Error(_("video/vaapi: vaSyncSurface failed\n"));
+ }
+ e = GetMsTicks();
+ if (e - s > 2000) {
+ Error(_("video/vaapi: gpu hung %d ms %d\n"), e - s, decoder->FrameCounter);
+ fprintf(stderr, _("video/vaapi: gpu hung %d ms %d\n"), e - s, decoder->FrameCounter);
+ }
+
if (0) {
// check if surface is really ready
// VDPAU backend, says always ready
@@ -2133,7 +2149,6 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
usleep(1 * 1000);
}
}
-
}
#ifdef USE_GLX
@@ -2792,14 +2807,16 @@ static void VaapiBlackSurface(VaapiDecoder * decoder)
clock_gettime(CLOCK_REALTIME, &decoder->FrameTime);
put1 = GetMsTicks();
+ if (put1 - sync > 2000 ) {
+ Error(_("video/vaapi: gpu hung %d ms %d\n"), put1 - sync, decoder->FrameCounter);
+ fprintf(stderr, _("video/vaapi: gpu hung %d ms %d\n"), put1 - sync, decoder->FrameCounter);
+ }
Debug(4, "video/vaapi: sync %2u put1 %2u\n", sync - start, put1 - sync);
if (0 && vaSyncSurface(decoder->VaDisplay, decoder->BlackSurface)
!= VA_STATUS_SUCCESS) {
Error(_("video/vaapi: vaSyncSurface failed\n"));
}
-
- usleep(500);
}
///
@@ -3385,20 +3402,40 @@ static void VaapiRenderFrame(VaapiDecoder * decoder,
!= VA_STATUS_SUCCESS) {
Error(_("video/vaapi: can't map the image!\n"));
}
+ // crazy: intel mixes YV12 and NV12 with mpeg
if (decoder->Image->format.fourcc == VA_FOURCC_NV12) {
- static int warned;
+ int x;
+
+ // intel NV12 convert YV12 to NV12
- // FIXME: intel NV12 convert YV12 to NV12
- if (!warned) {
- warned = 1;
- Error(_("video/vaapi: FIXME: yv12->nv12 not written\n"));
+ // copy Y
+ for ( i=0; i<height; ++i ) {
+ memcpy(va_image_data + decoder->Image->offsets[0] +
+ decoder->Image->pitches[0] * i,
+ frame->data[0] + frame->linesize[0] * i,
+ frame->linesize[0]);
+ }
+ // copy UV
+ for ( i=0; i< height / 2; ++i ) {
+ for ( x=0; x < frame->linesize[1]; ++x ) {
+ ((uint8_t*)va_image_data)[decoder->Image->offsets[1]
+ + decoder->Image->pitches[1] * i + x * 2 + 0]
+ = frame->data[1][i * frame->linesize[1] + x];
+ ((uint8_t*)va_image_data)[decoder->Image->offsets[1]
+ + decoder->Image->pitches[1] * i + x * 2 + 1]
+ = frame->data[2][i * frame->linesize[2] + x];
+ }
}
} else {
// FIXME: I420 vs YV12
- for (i = 0; (unsigned)i < decoder->Image->num_planes; ++i) {
- picture->data[i] = va_image_data + decoder->Image->offsets[i];
- picture->linesize[i] = decoder->Image->pitches[i];
+ if ( decoder->Image->num_planes == 3 ) {
+ picture->data[0] = va_image_data + decoder->Image->offsets[0];
+ picture->linesize[0] = decoder->Image->pitches[0];
+ picture->data[1] = va_image_data + decoder->Image->offsets[2];
+ picture->linesize[1] = decoder->Image->pitches[2];
+ picture->data[2] = va_image_data + decoder->Image->offsets[1];
+ picture->linesize[2] = decoder->Image->pitches[1];
}
av_picture_copy(picture, (AVPicture *) frame, video_ctx->pix_fmt,
@@ -3576,10 +3613,6 @@ static void VaapiDisplayFrame(void)
#endif
decoder->FrameTime = nowtime;
-
- // fixes: [drm:i915_hangcheck_elapsed] *ERROR* Hangcheck
- // timer elapsed... GPU hung
- usleep(1 * 1000);
}
}
@@ -5426,7 +5459,10 @@ static enum PixelFormat Vdpau_get_format(VdpauDecoder * decoder,
Debug(3, "video: new stream format %d\n", GetMsTicks() - VideoSwitch);
VdpauCleanup(decoder);
- if (!VideoHardwareDecoder) { // hardware disabled by config
+ if (!VideoHardwareDecoder
+ || (video_ctx->codec_id == CODEC_ID_MPEG2VIDEO
+ && VideoHardwareDecoder == 1)
+ ) { // hardware disabled by config
Debug(3, "codec: hardware acceleration disabled\n");
goto slow_path;
}
@@ -8518,9 +8554,13 @@ void VideoInit(const char *display_name)
#endif
// FIXME: make it configurable from gui
- if (!getenv("NO_HW")) {
+ VideoHardwareDecoder = -1;
+ if (getenv("NO_MPEG_HW")) {
VideoHardwareDecoder = 1;
}
+ if (getenv("NO_HW")) {
+ VideoHardwareDecoder = 0;
+ }
//xcb_prefetch_maximum_request_length(Connection);
xcb_flush(Connection);
}