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
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
** 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.
|
||||
*/
|
||||
@ -561,7 +603,33 @@ int VideoDecode(void)
|
||||
avpkt->size = avpkt->stream_index;
|
||||
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;
|
||||
|
||||
|
18
video.c
18
video.c
@ -2167,6 +2167,7 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
|
||||
usleep(1 * 1000);
|
||||
}
|
||||
}
|
||||
usleep(1 * 1000);
|
||||
}
|
||||
|
||||
#ifdef USE_GLX
|
||||
@ -2785,6 +2786,10 @@ static void VaapiBlackSurface(VaapiDecoder * decoder)
|
||||
decoder->Image->buf) != VA_STATUS_SUCCESS) {
|
||||
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.
|
||||
if (0
|
||||
@ -2835,6 +2840,7 @@ static void VaapiBlackSurface(VaapiDecoder * decoder)
|
||||
!= VA_STATUS_SUCCESS) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (!decoder->PutImage
|
||||
&& vaDestroyImage(VaDisplay,
|
||||
decoder->Image->image_id) != VA_STATUS_SUCCESS) {
|
||||
Error(_("video/vaapi: can't destroy image!\n"));
|
||||
}
|
||||
|
||||
VaapiQueueSurface(decoder, surface, 1);
|
||||
}
|
||||
|
||||
@ -3533,6 +3545,12 @@ static void VaapiAdvanceFrame(void)
|
||||
if (!(decoder->FramesDisplayed % 300)) {
|
||||
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