mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Workaround for mpeg2 FFMpeg+VA-API+Intel GPU hung.
This commit is contained in:
parent
364cc04736
commit
bd84e3f3b9
@ -1,7 +1,9 @@
|
|||||||
User johns
|
User johns
|
||||||
Date:
|
Date:
|
||||||
|
|
||||||
Fix bug: Nur schwarzes Bild bei VA-API hw decoder.
|
Workaround for mpeg2 FFMpeg + VA-API + Intel GPU hung.
|
||||||
|
Fix bug: Missing vaSyncSurface and vaDestroyImage.
|
||||||
|
Fix bug: Only black picture with VA-API hw decoder.
|
||||||
|
|
||||||
User HelAu
|
User HelAu
|
||||||
Date: Mon Jan 30 16:54:47 CET 2012
|
Date: Mon Jan 30 16:54:47 CET 2012
|
||||||
|
70
softhddev.c
70
softhddev.c
@ -487,6 +487,48 @@ static void VideoNextPacket(int codec_id)
|
|||||||
avpkt->dts = AV_NOPTS_VALUE;
|
avpkt->dts = AV_NOPTS_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
** Fix packet for FFMpeg.
|
||||||
|
**
|
||||||
|
** Some tv-stations sends mulitple pictures in a singe PES packet.
|
||||||
|
** Current ffmpeg 0.10 and libav-0.8 has problems with this.
|
||||||
|
** Split the packet into single picture packets.
|
||||||
|
*/
|
||||||
|
void FixPacketForFFMpeg(VideoDecoder * MyVideoDecoder, AVPacket * avpkt)
|
||||||
|
{
|
||||||
|
uint8_t *p;
|
||||||
|
int n;
|
||||||
|
AVPacket tmp[1];
|
||||||
|
int first;
|
||||||
|
|
||||||
|
p = avpkt->data;
|
||||||
|
n = avpkt->size;
|
||||||
|
*tmp = *avpkt;
|
||||||
|
|
||||||
|
first = 1;
|
||||||
|
while (n > 4) {
|
||||||
|
// scan for picture header
|
||||||
|
if (!p[0] && !p[1] && p[2] == 0x01 && !p[3]) {
|
||||||
|
if (first) {
|
||||||
|
first = 0;
|
||||||
|
n -= 4;
|
||||||
|
p += 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// packet has already an picture header
|
||||||
|
printf("split\n");
|
||||||
|
tmp->size = p - tmp->data;
|
||||||
|
CodecVideoDecode(MyVideoDecoder, tmp);
|
||||||
|
tmp->data = p;
|
||||||
|
tmp->size = n;
|
||||||
|
}
|
||||||
|
--n;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
CodecVideoDecode(MyVideoDecoder, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Decode from PES packet ringbuffer.
|
** Decode from PES packet ringbuffer.
|
||||||
*/
|
*/
|
||||||
@ -561,7 +603,33 @@ int VideoDecode(void)
|
|||||||
avpkt->size = avpkt->stream_index;
|
avpkt->size = avpkt->stream_index;
|
||||||
avpkt->stream_index = 0;
|
avpkt->stream_index = 0;
|
||||||
|
|
||||||
CodecVideoDecode(MyVideoDecoder, avpkt);
|
if (0) {
|
||||||
|
static int done;
|
||||||
|
|
||||||
|
if (done < 2) {
|
||||||
|
int fildes;
|
||||||
|
int who_designed_this_is____;
|
||||||
|
|
||||||
|
if (done == 0)
|
||||||
|
fildes =
|
||||||
|
open("frame0.pes", O_WRONLY | O_TRUNC | O_CREAT, 0666);
|
||||||
|
else if (done == 1)
|
||||||
|
fildes =
|
||||||
|
open("frame1.pes", O_WRONLY | O_TRUNC | O_CREAT, 0666);
|
||||||
|
else
|
||||||
|
fildes =
|
||||||
|
open("frame2.pes", O_WRONLY | O_TRUNC | O_CREAT, 0666);
|
||||||
|
done++;
|
||||||
|
who_designed_this_is____ = write(fildes, avpkt->data, avpkt->size);
|
||||||
|
close(fildes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_codec_id == CODEC_ID_MPEG2VIDEO) {
|
||||||
|
FixPacketForFFMpeg(MyVideoDecoder, avpkt);
|
||||||
|
} else {
|
||||||
|
CodecVideoDecode(MyVideoDecoder, avpkt);
|
||||||
|
}
|
||||||
|
|
||||||
avpkt->size = saved_size;
|
avpkt->size = saved_size;
|
||||||
|
|
||||||
|
18
video.c
18
video.c
@ -2167,6 +2167,7 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
|
|||||||
usleep(1 * 1000);
|
usleep(1 * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
usleep(1 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
@ -2785,6 +2786,10 @@ static void VaapiBlackSurface(VaapiDecoder * decoder)
|
|||||||
decoder->Image->buf) != VA_STATUS_SUCCESS) {
|
decoder->Image->buf) != VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't unmap the image!\n"));
|
Error(_("video/vaapi: can't unmap the image!\n"));
|
||||||
}
|
}
|
||||||
|
if (vaDestroyImage(VaDisplay,
|
||||||
|
decoder->Image->image_id) != VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't destroy image!\n"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// FIXME: intel didn't support put image.
|
// FIXME: intel didn't support put image.
|
||||||
if (0
|
if (0
|
||||||
@ -2835,6 +2840,7 @@ static void VaapiBlackSurface(VaapiDecoder * decoder)
|
|||||||
!= VA_STATUS_SUCCESS) {
|
!= VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: vaSyncSurface failed\n"));
|
Error(_("video/vaapi: vaSyncSurface failed\n"));
|
||||||
}
|
}
|
||||||
|
usleep(1 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -3470,6 +3476,12 @@ static void VaapiRenderFrame(VaapiDecoder * decoder,
|
|||||||
Error(_("video/vaapi: can't put image err:%d!\n"), i);
|
Error(_("video/vaapi: can't put image err:%d!\n"), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!decoder->PutImage
|
||||||
|
&& vaDestroyImage(VaDisplay,
|
||||||
|
decoder->Image->image_id) != VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: can't destroy image!\n"));
|
||||||
|
}
|
||||||
|
|
||||||
VaapiQueueSurface(decoder, surface, 1);
|
VaapiQueueSurface(decoder, surface, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3533,6 +3545,12 @@ static void VaapiAdvanceFrame(void)
|
|||||||
if (!(decoder->FramesDisplayed % 300)) {
|
if (!(decoder->FramesDisplayed % 300)) {
|
||||||
VaapiPrintFrames(decoder);
|
VaapiPrintFrames(decoder);
|
||||||
}
|
}
|
||||||
|
// wait for rendering finished
|
||||||
|
surface = decoder->SurfacesRb[decoder->SurfaceRead];
|
||||||
|
if (vaSyncSurface(decoder->VaDisplay, surface)
|
||||||
|
!= VA_STATUS_SUCCESS) {
|
||||||
|
Error(_("video/vaapi: vaSyncSurface failed\n"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user