Add workaround for Intel VA-API MPEG GPU hung.

This commit is contained in:
Johns 2012-01-29 11:28:10 +01:00
parent eed708b9ea
commit 422c378a5e
4 changed files with 72 additions and 21 deletions

View File

@ -1,6 +1,11 @@
User johns User johns
Date: 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 Release Version 0.4.5
Add configurable skip lines at video top and bottom. Add configurable skip lines at video top and bottom.
Add auto-crop tolerance configuration. Add auto-crop tolerance configuration.

View File

@ -146,6 +146,8 @@ Setup: /etc/vdr/setup.conf
if detected crop area is too small, cut max 'n' pixels at top and if detected crop area is too small, cut max 'n' pixels at top and
bottom. bottom.
softhddevice.SkipLines = 0
skip 'n' lines at top and bottom of the video picture.
softhddevice.Suspend.Close = 0 softhddevice.Suspend.Close = 0
1 suspend closes x11 window, connection and audio device. 1 suspend closes x11 window, connection and audio device.

10
Todo
View File

@ -38,7 +38,9 @@ video:
suspendoutput didn't show logo or black pictures suspendoutput didn't show logo or black pictures
(must detect video format to show image) (must detect video format to show image)
hard channel switch 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: vdpau:
@ -46,7 +48,7 @@ libva:
yaepghd (VaapiSetOutputPosition) support yaepghd (VaapiSetOutputPosition) support
can associate only displayed part of osd can associate only displayed part of osd
grab image for va-api 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_hangcheck_elapsed] *ERROR* Hangcheck timer elapsed... GPU hung
[drm:i915_wait_request] *ERROR* i915_wait_request returns -11 ... [drm:i915_wait_request] *ERROR* i915_wait_request returns -11 ...
@ -56,7 +58,8 @@ libva: branch vaapi-ext
libva-intel-driver: libva-intel-driver:
1080i does no v-sync (sometimes correct working with vaapi-ext) 1080i does no v-sync (sometimes correct working with vaapi-ext)
OSD has sometimes wrong size (workaround written) 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: libva-vdpau-driver:
G210/GT520 OSD update too slow (needs hardware problem workaround) G210/GT520 OSD update too slow (needs hardware problem workaround)
@ -85,6 +88,7 @@ audio/alsa:
audio/oss: audio/oss:
alsa oss emulation mixer "pcm" not working alsa oss emulation mixer "pcm" not working
oss4 mixer channel not working
ring buffer overflow with alsa oss emulation ring buffer overflow with alsa oss emulation
HDMI/SPDIF Passthrough: HDMI/SPDIF Passthrough:

76
video.c
View File

@ -1561,6 +1561,7 @@ static void VaapiCleanup(VaapiDecoder * decoder)
VaapiDestroyDeinterlaceImages(decoder); VaapiDestroyDeinterlaceImages(decoder);
} }
decoder->FrameCounter = 0;
decoder->PTS = AV_NOPTS_VALUE; decoder->PTS = AV_NOPTS_VALUE;
VideoDeltaPTS = 0; VideoDeltaPTS = 0;
} }
@ -1865,7 +1866,10 @@ static enum PixelFormat Vaapi_get_format(VaapiDecoder * decoder,
// cleanup last context // cleanup last context
VaapiCleanup(decoder); 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"); Debug(3, "codec: hardware acceleration disabled\n");
goto slow_path; goto slow_path;
} }
@ -2064,6 +2068,8 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
{ {
unsigned type; unsigned type;
VAStatus status; VAStatus status;
uint32_t s;
uint32_t e;
// deinterlace // deinterlace
if (interlaced if (interlaced
@ -2086,6 +2092,7 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
type = VA_FRAME_PICTURE; type = VA_FRAME_PICTURE;
} }
s = GetMsTicks();
xcb_flush(Connection); xcb_flush(Connection);
if ((status = vaPutSurface(decoder->VaDisplay, surface, decoder->Window, if ((status = vaPutSurface(decoder->VaDisplay, surface, decoder->Window,
// decoder src // decoder src
@ -2100,6 +2107,15 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
Error(_("video/vaapi: vaPutSurface failed %d\n"), status); 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) { if (0) {
// check if surface is really ready // check if surface is really ready
// VDPAU backend, says always ready // VDPAU backend, says always ready
@ -2133,7 +2149,6 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
usleep(1 * 1000); usleep(1 * 1000);
} }
} }
} }
#ifdef USE_GLX #ifdef USE_GLX
@ -2792,14 +2807,16 @@ static void VaapiBlackSurface(VaapiDecoder * decoder)
clock_gettime(CLOCK_REALTIME, &decoder->FrameTime); clock_gettime(CLOCK_REALTIME, &decoder->FrameTime);
put1 = GetMsTicks(); 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); Debug(4, "video/vaapi: sync %2u put1 %2u\n", sync - start, put1 - sync);
if (0 && vaSyncSurface(decoder->VaDisplay, decoder->BlackSurface) if (0 && vaSyncSurface(decoder->VaDisplay, decoder->BlackSurface)
!= VA_STATUS_SUCCESS) { != VA_STATUS_SUCCESS) {
Error(_("video/vaapi: vaSyncSurface failed\n")); Error(_("video/vaapi: vaSyncSurface failed\n"));
} }
usleep(500);
} }
/// ///
@ -3385,20 +3402,40 @@ static void VaapiRenderFrame(VaapiDecoder * decoder,
!= VA_STATUS_SUCCESS) { != VA_STATUS_SUCCESS) {
Error(_("video/vaapi: can't map the image!\n")); 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) { if (decoder->Image->format.fourcc == VA_FOURCC_NV12) {
static int warned; int x;
// FIXME: intel NV12 convert YV12 to NV12 // intel NV12 convert YV12 to NV12
if (!warned) {
warned = 1; // copy Y
Error(_("video/vaapi: FIXME: yv12->nv12 not written\n")); 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 { } else {
// FIXME: I420 vs YV12 // FIXME: I420 vs YV12
for (i = 0; (unsigned)i < decoder->Image->num_planes; ++i) { if ( decoder->Image->num_planes == 3 ) {
picture->data[i] = va_image_data + decoder->Image->offsets[i]; picture->data[0] = va_image_data + decoder->Image->offsets[0];
picture->linesize[i] = decoder->Image->pitches[i]; 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, av_picture_copy(picture, (AVPicture *) frame, video_ctx->pix_fmt,
@ -3576,10 +3613,6 @@ static void VaapiDisplayFrame(void)
#endif #endif
decoder->FrameTime = nowtime; 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); Debug(3, "video: new stream format %d\n", GetMsTicks() - VideoSwitch);
VdpauCleanup(decoder); 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"); Debug(3, "codec: hardware acceleration disabled\n");
goto slow_path; goto slow_path;
} }
@ -8518,9 +8554,13 @@ void VideoInit(const char *display_name)
#endif #endif
// FIXME: make it configurable from gui // FIXME: make it configurable from gui
if (!getenv("NO_HW")) { VideoHardwareDecoder = -1;
if (getenv("NO_MPEG_HW")) {
VideoHardwareDecoder = 1; VideoHardwareDecoder = 1;
} }
if (getenv("NO_HW")) {
VideoHardwareDecoder = 0;
}
//xcb_prefetch_maximum_request_length(Connection); //xcb_prefetch_maximum_request_length(Connection);
xcb_flush(Connection); xcb_flush(Connection);
} }