fix framedrop in vaapi

This commit is contained in:
jojo61 2019-08-26 15:00:40 +02:00
parent 18759e8dab
commit cdac2bcc3d
1 changed files with 26 additions and 19 deletions

35
video.c
View File

@ -555,7 +555,6 @@ static void VideoSetPts(int64_t * pts_p, int interlaced,
} }
// Debug(4, "video: %d/%d %" PRIx64 " -> %d\n", video_ctx->framerate.den, video_ctx->framerate.num, av_frame_get_pkt_duration(frame), duration); // Debug(4, "video: %d/%d %" PRIx64 " -> %d\n", video_ctx->framerate.den, video_ctx->framerate.num, av_frame_get_pkt_duration(frame), duration);
// update video clock // update video clock
if (*pts_p != (int64_t) AV_NOPTS_VALUE) { if (*pts_p != (int64_t) AV_NOPTS_VALUE) {
*pts_p += duration * 90; *pts_p += duration * 90;
@ -4281,16 +4280,16 @@ static void CuvidDisplayFrame(void)
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
#else #else
// if (CuvidDecoderN) { if (CuvidDecoderN) {
// CuvidDecoders[0]->Frameproc = (float)(GetusTicks()-last_time)/1000000.0; CuvidDecoders[0]->Frameproc = (float)(GetusTicks()-last_time)/1000000.0;
// } }
#if 1 #if 1
diff = (GetusTicks()-last_time)/1000; //000; diff = (GetusTicks()-last_time)/1000; //000;
// last_time = GetusTicks(); // last_time = GetusTicks();
//printf("Roundtrip %d\n",diff); //printf("Roundtrip Displayframe %d\n",diff);
if (diff < 15000 && skipwait != 1) { if (diff < 15000 && skipwait != 1) {
// printf("Sleep %d\n",15000-diff); //printf("Sleep %d\n",15000-diff);
usleep((15000 - diff));// * 1000); usleep((15000 - diff));// * 1000);
} else if (skipwait != 1) { } else if (skipwait != 1) {
// usleep(15000); // usleep(15000);
@ -4302,7 +4301,7 @@ static void CuvidDisplayFrame(void)
//last_time = GetusTicks(); //last_time = GetusTicks();
VideoThreadLock(); VideoThreadLock();
#if 1
if (!first) { if (!first) {
// last_time = GetusTicks(); // last_time = GetusTicks();
if (!pl_swapchain_submit_frame(p->swapchain)) if (!pl_swapchain_submit_frame(p->swapchain))
@ -4310,7 +4309,7 @@ static void CuvidDisplayFrame(void)
pl_swapchain_swap_buffers(p->swapchain); // swap buffers pl_swapchain_swap_buffers(p->swapchain); // swap buffers
// printf("submit and swap %d\n",(GetusTicks()-last_time)/1000000); // printf("submit and swap %d\n",(GetusTicks()-last_time)/1000000);
} }
#endif
first = 0; first = 0;
#if 0 #if 0
fdiff = (float)(GetusTicks()-first_time)/1000.0; fdiff = (float)(GetusTicks()-first_time)/1000.0;
@ -4324,7 +4323,7 @@ static void CuvidDisplayFrame(void)
while (!pl_swapchain_start_frame(p->swapchain, &frame)) { // get new frame wait for previous to swap while (!pl_swapchain_start_frame(p->swapchain, &frame)) { // get new frame wait for previous to swap
usleep(5); usleep(5);
} }
last_time = GetusTicks();
//printf("wait for frame %d\n",(GetusTicks()-last_time)/1000000); //printf("wait for frame %d\n",(GetusTicks()-last_time)/1000000);
@ -4466,7 +4465,6 @@ static void CuvidDisplayFrame(void)
#endif #endif
#ifdef PLACEBO #ifdef PLACEBO
VideoThreadUnlock(); VideoThreadUnlock();
#else #else
glXGetVideoSyncSGI (&Count); // get current frame glXGetVideoSyncSGI (&Count); // get current frame
@ -4595,6 +4593,7 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder)
int64_t audio_clock; int64_t audio_clock;
int64_t video_clock; int64_t video_clock;
int err = 0; int err = 0;
static uint64_t last_time;
video_clock = CuvidGetClock(decoder); video_clock = CuvidGetClock(decoder);
filled = atomic_read(&decoder->SurfacesFilled); filled = atomic_read(&decoder->SurfacesFilled);
@ -4652,7 +4651,9 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder)
diff = video_clock - audio_clock - VideoAudioDelay; diff = video_clock - audio_clock - VideoAudioDelay;
diff = (decoder->LastAVDiff + diff) / 2; diff = (decoder->LastAVDiff + diff) / 2;
decoder->LastAVDiff = diff; decoder->LastAVDiff = diff;
decoder->Frameproc = diff/90; // decoder->Frameproc = diff/90;
// printf("Roundtrip sync %d\n",(GetusTicks()-last_time)/1000);
// last_time = GetusTicks();
#if 1 #if 1
if (skipwait <= 1) { if (skipwait <= 1) {
if ((diff/90) > 55) { if ((diff/90) > 55) {
@ -4665,7 +4666,7 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder)
} }
#endif #endif
skipwait =0; skipwait =0;
// printf("Diff %d filled %d skipwait %d\n",diff/90,filled,skipwait); // printf(" Diff %d filled %d skipwait %d \n",diff/90,filled,skipwait);
if (abs(diff) > 5000 * 90) { // more than 5s if (abs(diff) > 5000 * 90) { // more than 5s
err = CuvidMessage(2, "video: audio/video difference too big\n"); err = CuvidMessage(2, "video: audio/video difference too big\n");
@ -4686,7 +4687,7 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder)
err = CuvidMessage(3, "video: speed up video, droping frame\n"); err = CuvidMessage(3, "video: speed up video, droping frame\n");
++decoder->FramesDropped; ++decoder->FramesDropped;
CuvidAdvanceDecoderFrame(decoder); CuvidAdvanceDecoderFrame(decoder);
if (filled > 2 && (diff < -50 * 90)) if (filled >2)
CuvidAdvanceDecoderFrame(decoder); CuvidAdvanceDecoderFrame(decoder);
// filled = atomic_read(&decoder->SurfacesFilled); // filled = atomic_read(&decoder->SurfacesFilled);
// Debug(3,"hinter drop frame filled %d\n",atomic_read(&decoder->SurfacesFilled)); // Debug(3,"hinter drop frame filled %d\n",atomic_read(&decoder->SurfacesFilled));
@ -4775,6 +4776,7 @@ static void CuvidSyncDisplayFrame(void)
CuvidDisplayFrame(); CuvidDisplayFrame();
CuvidSyncFrame(); CuvidSyncFrame();
} }
/// ///
@ -5649,7 +5651,12 @@ void InitPlacebo(){
p->swapchain = pl_vulkan_create_swapchain(p->vk, &(struct pl_vulkan_swapchain_params) { p->swapchain = pl_vulkan_create_swapchain(p->vk, &(struct pl_vulkan_swapchain_params) {
.surface = p->pSurface, .surface = p->pSurface,
.present_mode = VK_PRESENT_MODE_FIFO_KHR, .present_mode = VK_PRESENT_MODE_FIFO_KHR,
#ifdef VAAPI
.swapchain_depth = 2,
#endif
#ifdef CUVID
.swapchain_depth = 1, .swapchain_depth = 1,
#endif
}); });
if (!p->swapchain) { if (!p->swapchain) {
@ -5741,7 +5748,7 @@ static void *VideoHandlerThread(void *dummy) {
// first_time = GetusTicks(); // first_time = GetusTicks();
CuvidSyncDisplayFrame(); CuvidSyncDisplayFrame();
// printf("syncdisplayframe exec %d\n",(GetusTicks()-first_time)/1000000); // printf("syncdisplayframe exec %d\n",(GetusTicks()-first_time)/1000);
} }
return dummy; return dummy;