From a2b52bb80429e6e71a523f93ec3baefcfbaf8629 Mon Sep 17 00:00:00 2001 From: jojo61 Date: Fri, 11 Oct 2019 11:47:11 +0200 Subject: [PATCH] Fix jump in recordings Fix in CUVID Bufferhandling --- audio.c | 26 ++++- po/de_DE.po | 71 +++++++------ softhdcuvid.cpp | 2 +- video.c | 277 +++++++++++++++++++++++++++--------------------- 4 files changed, 218 insertions(+), 158 deletions(-) diff --git a/audio.c b/audio.c index a4cdb55..e4f6fd3 100644 --- a/audio.c +++ b/audio.c @@ -2044,7 +2044,7 @@ static int AudioNextRing(void) // stop, if not enough in next buffer used = RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer); - if (AudioStartThreshold * 4 < used || (AudioVideoIsReady + if (AudioStartThreshold * 10 < used || (AudioVideoIsReady && AudioStartThreshold < used)) { return 0; } @@ -2228,6 +2228,24 @@ static const AudioModule *AudioModules[] = { &NoopModule, }; +void AudioDelayms(int delayms) { + int count; + unsigned char *p; + +#ifdef DEBUG + printf("Try Delay Audio for %d ms Samplerate %d Channels %d bps %d\n", + delayms,AudioRing[AudioRingWrite].HwSampleRate,AudioRing[AudioRingWrite].HwChannels,AudioBytesProSample); +#endif + + count = delayms * AudioRing[AudioRingWrite].HwSampleRate * AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample / 1000; + + if (delayms < 5000 && delayms > 0) { // not more than 5seconds + p = calloc(1,count); + RingBufferWrite(AudioRing[AudioRingWrite].RingBuffer, p, count); + free(p); + } +} + /** ** Place samples in audio output queue. ** @@ -2334,7 +2352,7 @@ void AudioEnqueue(const void *samples, int count) } // forced start or enough video + audio buffered // for some exotic channels * 4 too small - if (AudioStartThreshold * 4 < n || (AudioVideoIsReady + if (AudioStartThreshold * 10 < n || (AudioVideoIsReady // if ((AudioVideoIsReady && AudioStartThreshold < n)) { // restart play-back @@ -2390,7 +2408,7 @@ void AudioVideoReady(int64_t pts) Timestamp2String(pts), Timestamp2String(audio_pts), (int)(pts - audio_pts) / 90, AudioRunning ? "running" : "ready"); - if (!AudioRunning || 1) { + if (!AudioRunning) { int skip; // buffer ~15 video frames @@ -2420,8 +2438,6 @@ void AudioVideoReady(int64_t pts) } else { Debug(3,"No audio skip -> should skip %d\n",skip/90); - AudioRunning = 0; - usleep(abs(skip/90)*1000); } // FIXME: skip<0 we need bigger audio buffer diff --git a/po/de_DE.po b/po/de_DE.po index 87c1282..7ee637b 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-04 09:19+0100\n" +"POT-Creation-Date: 2019-10-04 14:23+0200\n" "PO-Revision-Date: blabla\n" "Last-Translator: blabla\n" "Language-Team: blabla\n" @@ -251,9 +251,6 @@ msgstr "" msgid "audio: %6dHz supports %d %d %d %d %d %d %d %d channels\n" msgstr "" -msgid "codec: buggy libav, use ffmpeg\n" -msgstr "" - msgid "codec: can't allocate vodeo decoder\n" msgstr "" @@ -266,6 +263,9 @@ msgstr "" msgid "codec: can't allocate video codec context\n" msgstr "" +msgid "VAAPI Refcounts invalid\n" +msgstr "" + msgid "codec: can't set option deint to video codec!\n" msgstr "" @@ -284,6 +284,9 @@ msgstr "" msgid "codec: can't allocate video decoder frame buffer\n" msgstr "" +msgid "video: Init of YADIF Filter failed\n" +msgstr "" + msgid "codec: can't allocate audio decoder\n" msgstr "" @@ -327,21 +330,9 @@ msgstr "" msgid "codec/audio: can't open resample\n" msgstr "" -msgid "codec/audio: latm\n" +msgid "A software and GPU emulated UHD device" msgstr "" -msgid "codec/audio: bad audio frame\n" -msgstr "" - -msgid "codec/audio: error more than one frame data\n" -msgstr "" - -msgid "codec/audio: no frame\n" -msgstr "" - -msgid "A software and GPU emulated HD device" -msgstr "Ein Software und GPU emulieres HD-Gerät" - msgid "SoftUHD" msgstr "" @@ -801,15 +792,12 @@ msgstr "" msgid "[softhddev] ready%s\n" msgstr "" -msgid "video/glx: can't make glx context current\n" +msgid "video/egl: GlxSetupWindow can't make egl context current\n" msgstr "" msgid "video/glx: no v-sync\n" msgstr "" -msgid "glewinit failed\n" -msgstr "" - msgid "video/glx: no GLX support\n" msgstr "" @@ -820,15 +808,6 @@ msgstr "" msgid "did not get FBconfig" msgstr "" -msgid "video/glx: can't get a RGB visual\n" -msgstr "" - -msgid "video/glx: no valid visual found\n" -msgstr "" - -msgid "video/glx: need atleast 8-bits per RGB\n" -msgstr "" - msgid "video/glx: can't create glx context\n" msgstr "" @@ -850,6 +829,9 @@ msgstr "" msgid "video/glx: SGI v-sync enabled\n" msgstr "" +msgid "video/egl: can't create egl context\n" +msgstr "" + msgid "video/cuvid: surface needed not set\n" msgstr "" @@ -857,6 +839,27 @@ msgstr "" msgid "video/cuvid: release surface %#08x, which is not in use\n" msgstr "" +msgid "Wrong ES version \n" +msgstr "" + +msgid " Could not bind API!\n" +msgstr "" + +msgid "Can't get EGL Extentions\n" +msgstr "" + +msgid "Could not initialize EGL.\n" +msgstr "" + +msgid "Could not create EGL Context\n" +msgstr "" + +msgid "Could not create EGL surface!\n" +msgstr "" + +msgid "Could not make context current!\n" +msgstr "" + msgid "video/cuvid: out of decoders\n" msgstr "" @@ -866,7 +869,7 @@ msgstr "" msgid "video/cuvid: decoder not in decoder list.\n" msgstr "" -msgid "video/glx: glx error\n" +msgid "video/egl: egl init error\n" msgstr "" #, c-format @@ -952,6 +955,9 @@ msgstr "" msgid "Failed initializing libplacebo renderer\n" msgstr "" +msgid "video/egl: can't create thread egl context\n" +msgstr "" + msgid "video: can't queue cancel video display thread\n" msgstr "" @@ -986,6 +992,9 @@ msgstr "" msgid "video: error closing display\n" msgstr "" +#~ msgid "A software and GPU emulated HD device" +#~ msgstr "Ein Software und GPU emulieres HD-Gerät" + #~ msgid "Use studio levels (vdpau only)" #~ msgstr "Benutze Studio Levels (nur vdpau)" diff --git a/softhdcuvid.cpp b/softhdcuvid.cpp index 339fc23..2b13833 100644 --- a/softhdcuvid.cpp +++ b/softhdcuvid.cpp @@ -67,7 +67,7 @@ extern "C" /// vdr-plugin version number. /// Makefile extracts the version number for generating the file name /// for the distribution archive. -static const char *const VERSION = "2.0.0" +static const char *const VERSION = "2.1.0" #ifdef GIT_REV "-GIT" GIT_REV #endif diff --git a/video.c b/video.c index 080baac..c354301 100644 --- a/video.c +++ b/video.c @@ -445,7 +445,7 @@ static xcb_atom_t NetWmStateAbove; extern uint32_t VideoSwitch; ///< ticks for channel switch #endif extern void AudioVideoReady(int64_t); ///< tell audio video is ready -extern int AudioDelay; + #ifdef USE_VIDEO_THREAD @@ -456,7 +456,7 @@ static pthread_mutex_t VideoLockMutex; ///< video lock mutex pthread_mutex_t OSDMutex; ///< OSD update mutex #endif -int skipwait; + static pthread_t VideoDisplayThread; ///< video display thread //static pthread_cond_t VideoDisplayWakeupCond; ///< wakeup condition variable @@ -489,6 +489,7 @@ static char EnableDPMSatBlackScreen; ///< flag we should enable dpms at black sc static int EglEnabled; ///< use EGL static int GlxVSyncEnabled = 1; ///< enable/disable v-sync + #ifdef CUVID static GLXContext eglSharedContext; ///< shared gl context static GLXContext eglContext; ///< our gl context @@ -758,6 +759,33 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width, *crop_x, *crop_y); return; } + +static uint64_t test_time=0; +/// +/// Lock video thread. +/// +#define VideoThreadLock(void)\ +{\ + if (VideoThread) {\ + if (pthread_mutex_lock(&VideoLockMutex)) {\ + Error(_("video: can't lock thread\n"));\ + }\ + }\ +} +// test_time = GetusTicks(); +// printf("Lock start...."); +/// +/// Unlock video thread. +/// +#define VideoThreadUnlock(void)\ +{\ + if (VideoThread) {\ + if (pthread_mutex_unlock(&VideoLockMutex)) {\ + Error(_("video: can't unlock thread\n"));\ + }\ + }\ +} +// printf("Video Locked for %d\n",(GetusTicks()-test_time)/1000); //---------------------------------------------------------------------------- // GLX @@ -1435,7 +1463,11 @@ struct ext_buf { int fd; #ifdef CUVID CUexternalMemory mem; - CUdeviceptr buf; + CUmipmappedArray mma; +// CUdeviceptr buf; + CUexternalSemaphore ss; + CUexternalSemaphore ws; + const struct pl_sysnc *sysnc; #endif }; #endif @@ -1523,8 +1555,8 @@ typedef struct _cuvid_decoder_ #ifdef PLACEBO struct pl_image pl_images[CODEC_SURFACES_MAX+1]; // images for Placebo chain // const struct pl_tex *pl_tex_in[CODEC_SURFACES_MAX+1][2]; // Textures in image - const struct pl_buf *pl_buf_Y[2],*pl_buf_UV[2]; // buffer for Texture upload - struct ext_buf ebuf[4]; // for managing vk buffer +// const struct pl_buf *pl_buf_Y[2],*pl_buf_UV[2]; // buffer for Texture upload + struct ext_buf ebuf[CODEC_SURFACES_MAX+1]; // for managing vk buffer #endif @@ -1765,7 +1797,7 @@ static void CuvidDestroySurfaces(CuvidDecoder * decoder) } } #ifdef PLACEBO -#ifdef CUVID +#ifdef CUVID1 pl_buf_destroy(p->gpu,&decoder->pl_buf_Y[0]); pl_buf_destroy(p->gpu,&decoder->pl_buf_UV[0]); pl_buf_destroy(p->gpu,&decoder->pl_buf_Y[1]); @@ -1986,7 +2018,7 @@ static bool create_context_cb(EGLDisplay display, EGL_RED_SIZE, 10, EGL_GREEN_SIZE, 10, EGL_BLUE_SIZE, 10, - EGL_ALPHA_SIZE, 8, + EGL_ALPHA_SIZE, 2, EGL_RENDERABLE_TYPE, rend, EGL_NONE }; @@ -1994,13 +2026,20 @@ static bool create_context_cb(EGLDisplay display, attribs = attributes10; -// if (!eglChooseConfig(display, attributes10, NULL, 0, &num_configs)) { // try 10 Bit + if (!eglChooseConfig(display, attributes10, NULL, 0, &num_configs)) { // try 10 Bit + Debug(3," 10 Bit egl Failed\n"); attribs = attributes8; if (!eglChooseConfig(display, attributes8, NULL, 0, &num_configs)) { // try 8 Bit num_configs = 0; } -// } - + } else if (num_configs == 0) { + EglCheck(); + Debug(3," 10 Bit egl Failed\n"); + attribs = attributes8; + if (!eglChooseConfig(display, attributes8, NULL, 0, &num_configs)) { // try 8 Bit + num_configs = 0; + } + } EGLConfig *configs = malloc(sizeof(EGLConfig) * num_configs); if (!eglChooseConfig(display, attribs, configs, num_configs, &num_configs)) num_configs = 0; @@ -2240,7 +2279,7 @@ static void CuvidDelHwDecoder(CuvidDecoder * decoder) int i; Debug(3,"cuvid del hw decoder \n"); if (decoder == CuvidDecoders[0]) - pthread_mutex_lock(&VideoLockMutex); + VideoThreadLock(); #ifndef PLACEBO #ifdef CUVID glXMakeCurrent(XlibDisplay, VideoWindow, eglContext); @@ -2254,7 +2293,7 @@ Debug(3,"cuvid del hw decoder \n"); CuvidDestroySurfaces(decoder); } if (decoder == CuvidDecoders[0]) - pthread_mutex_unlock(&VideoLockMutex); + VideoThreadUnlock(); // glXMakeCurrent(XlibDisplay, None, NULL); for (i = 0; i < CuvidDecoderN; ++i) { @@ -2344,7 +2383,7 @@ void SDK_CHECK_ERROR_GL() { void createTextureDst(CuvidDecoder * decoder,int anz, unsigned int size_x, unsigned int size_y, enum AVPixelFormat PixFmt) { - int n,i,size=1; + int n,i,size=1,fd; const struct pl_fmt *fmt; struct pl_tex *tex; struct pl_image *img; @@ -2368,14 +2407,14 @@ createTextureDst(CuvidDecoder * decoder,int anz, unsigned int size_x, unsigned i size = 2; } if (decoder->pl_images[i].planes[n].texture) { -#ifdef VAAPI - if (p->has_dma_buf && decoder->pl_images[i].planes[n].texture->params.shared_mem.handle.fd) { +//#ifdef VAAPI + if (decoder->pl_images[i].planes[n].texture->params.shared_mem.handle.fd) { close(decoder->pl_images[i].planes[n].texture->params.shared_mem.handle.fd); } -#endif +//#endif pl_tex_destroy(p->gpu,&decoder->pl_images[i].planes[n].texture); // delete old texture } -// decoder->pl_tex_in[i][n] = pl_tex_create(p->gpu, &(struct pl_tex_params) { + if (p->has_dma_buf == 0) { decoder->pl_images[i].planes[n].texture = pl_tex_create(p->gpu, &(struct pl_tex_params) { .w = n==0?size_x:size_x/2, @@ -2386,11 +2425,11 @@ createTextureDst(CuvidDecoder * decoder,int anz, unsigned int size_x, unsigned i .host_writable = true, .sample_mode = PL_TEX_SAMPLE_LINEAR, .address_mode = PL_TEX_ADDRESS_CLAMP, + .export_handle = PL_HANDLE_FD, }); } // make planes for image pl = &decoder->pl_images[i].planes[n]; -// pl->texture = decoder->pl_tex_in[i][n]; pl->components = n==0?1:2; pl->shift_x = 0.0f; pl->shift_y = 0.0f; @@ -2408,6 +2447,30 @@ createTextureDst(CuvidDecoder * decoder,int anz, unsigned int size_x, unsigned i if (!ok) { Fatal(_("Unable to create placebo textures")); } +#ifdef CUVID + fd = dup(decoder->pl_images[i].planes[n].texture->shared_mem.handle.fd); + CUDA_EXTERNAL_MEMORY_HANDLE_DESC ext_desc = { + .type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD, + .handle.fd = fd, + .size = decoder->pl_images[i].planes[n].texture->shared_mem.size, // image_width * image_height * bytes, + .flags = 0, + }; + checkCudaErrors(cuImportExternalMemory(&decoder->ebuf[i*2+n].mem, &ext_desc)); // Import Memory segment + CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC tex_desc = { + .offset = decoder->pl_images[i].planes[n].texture->shared_mem.offset, + .arrayDesc = { + .Width = n==0?size_x:size_x/2, + .Height = n==0?size_y:size_y/2, + .Depth = 0, + .Format = PixFmt == AV_PIX_FMT_NV12 ? CU_AD_FORMAT_UNSIGNED_INT8:CU_AD_FORMAT_UNSIGNED_INT16, + .NumChannels = n==0?1:2, + .Flags = 0, + }, + .numLevels = 1, + }; + checkCudaErrors(cuExternalMemoryGetMappedMipmappedArray(&decoder->ebuf[i*2+n].mma,decoder->ebuf[i*2+n].mem,&tex_desc)); + checkCudaErrors(cuMipmappedArrayGetLevel(&decoder->cu_array[i][n],decoder->ebuf[i*2+n].mma,0)); +#endif } // make image img = &decoder->pl_images[i]; @@ -2425,7 +2488,7 @@ createTextureDst(CuvidDecoder * decoder,int anz, unsigned int size_x, unsigned i img->height = size_y; img->num_overlays = 0; } -#ifdef CUVID +#ifdef CUVID1 decoder->pl_buf_Y[0] = pl_buf_create(p->gpu, &(struct pl_buf_params) { // buffer for Y texture upload .type = PL_BUF_TEX_TRANSFER, .size = size_x * size_y * size, @@ -2534,7 +2597,7 @@ void generateVAAPIImage(CuvidDecoder * decoder,int index, const AVFrame *frame,i { int n; VAStatus status; - static int toggle = 0; + int toggle = 0; uint64_t first_time; VADRMPRIMESurfaceDescriptor desc; @@ -2608,31 +2671,55 @@ void generateVAAPIImage(CuvidDecoder * decoder,int index, const AVFrame *frame,i #ifdef CUVID // copy image and process using CUDA void generateCUDAImage(CuvidDecoder * decoder,int index, const AVFrame *frame,int image_width , int image_height, int bytes) +{ + int n; + for (n = 0; n < 2; n++) { // + // widthInBytes must account for the chroma plane + // elements being two samples wide. + CUDA_MEMCPY2D cpy = { + .srcMemoryType = CU_MEMORYTYPE_DEVICE, + .dstMemoryType = CU_MEMORYTYPE_ARRAY, + .srcDevice = (CUdeviceptr)frame->data[n], + .srcPitch = frame->linesize[n], + .srcY = 0, + .dstArray = decoder->cu_array[index][n], + .WidthInBytes = image_width * bytes, + .Height = n==0?image_height:image_height/2 , + }; + checkCudaErrors(cuMemcpy2D(&cpy)); + } +} +#if 0 +void generateCUDAImage(CuvidDecoder * decoder,int index, const AVFrame *frame,int image_width , int image_height, int bytes) { int n; static int toggle = 0; uint64_t first_time; // struct ext_buf ebuf[2]; -//first_time = GetusTicks(); +first_time = GetusTicks(); VideoThreadLock(); //printf("Upload buf to texture for frame %d in size %d-%d\n",index,image_width,image_height); if (decoder->pl_buf_Y[toggle]) while (pl_buf_poll(p->gpu,decoder->pl_buf_Y[toggle], 000000)) { // 5 ms VideoThreadUnlock(); - usleep(1); + usleep(100); VideoThreadLock(); } - else + else { + VideoThreadUnlock(); return; + } if (decoder->pl_buf_UV[toggle]) while (pl_buf_poll(p->gpu,decoder->pl_buf_UV[toggle], 000000)) { VideoThreadUnlock(); - usleep(1); + usleep(100); VideoThreadLock(); } - else + else { + VideoThreadUnlock(); return; + } // printf("1 got Image buffers %2.2f\n",(float)(GetusTicks()-first_time)/1000000.0); for (n = 0; n < 2; n++) { // Copy 2 Planes from Cuda decoder to upload Buffer @@ -2666,9 +2753,12 @@ void generateCUDAImage(CuvidDecoder * decoder,int index, const AVFrame *frame,in // toggle = toggle==0?1:0; // pl_gpu_flush(p->gpu); VideoThreadUnlock(); - + if (((float)(GetusTicks()-first_time)/1000000.0) > 15.0) { + // printf("made Image buffers %2.2f ms\n",(float)(GetusTicks()-first_time)/1000000.0); + } } #endif +#endif #else void @@ -2727,7 +2817,6 @@ createTextureDst(CuvidDecoder * decoder,int anz, unsigned int size_x, unsigned i void generateCUDAImage(CuvidDecoder * decoder,int index, const AVFrame *frame,int image_width , int image_height, int bytes) { int n; - for (n = 0; n < 2; n++) { // // widthInBytes must account for the chroma plane // elements being two samples wide. @@ -2768,7 +2857,7 @@ void generateVAAPIImage(CuvidDecoder * decoder,int index, const AVFrame *frame,i { int n,i; VAStatus status; - static int toggle = 0; + uint64_t first_time; VADRMPRIMESurfaceDescriptor desc; @@ -3220,6 +3309,7 @@ static enum AVPixelFormat Cuvid_get_format(CuvidDecoder * decoder, if (*fmt_idx != AV_PIX_FMT_CUDA) { Fatal(_("video: no valid profile found\n")); } + decoder->newchannel = 1; if (ist->GetFormatDone) return AV_PIX_FMT_CUDA; #endif @@ -3885,14 +3975,6 @@ static void CuvidRenderFrame(CuvidDecoder * decoder, int surface; enum AVColorSpace color; -#ifdef CUVID - if (skipwait > 1) { - skipwait--; - av_frame_free(&frame); - return; - } -#endif - // update aspect ratio changes #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,60,100) if (decoder->InputWidth && decoder->InputHeight @@ -3978,7 +4060,6 @@ static void CuvidRenderFrame(CuvidDecoder * decoder, VideoThreadLock(); vaSyncSurface(decoder->VaDisplay,(unsigned int)frame->data[3]); output = av_frame_alloc(); - // av_frame_ref(output,frame); av_hwframe_transfer_data(output,frame,0); av_frame_copy_props(output,frame); // printf("Save Surface ID %d %p %p\n",surface,decoder->pl_images[surface].planes[0].texture,decoder->pl_images[surface].planes[1].texture); @@ -4231,17 +4312,21 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))int lev // img->color.light = PL_COLOR_LIGHT_SCENE_709_1886; // img->color.light = PL_COLOR_LIGHT_DISPLAY; break; -#ifdef CUVID + case AVCOL_SPC_BT2020_NCL: img->repr.sys = PL_COLOR_SYSTEM_BT_2020_NC; memcpy(&img->repr,&pl_color_repr_uhdtv,sizeof(struct pl_color_repr)); memcpy(&img->color,&pl_color_space_bt2020_hlg,sizeof(struct pl_color_space)); deband.grain = 0.0f; // no grain in HDR + img->color.sig_scale = 2.0f; +#ifdef VAAPI + render_params.peak_detect_params = NULL; +#endif // img->color.primaries = PL_COLOR_PRIM_BT_2020; // img->color.transfer = PL_COLOR_TRC_HLG; // img->color.light = PL_COLOR_LIGHT_SCENE_HLG; break; -#endif + default: // fallback img->repr.sys = PL_COLOR_SYSTEM_BT_709; memcpy(&img->color,&pl_color_space_bt709,sizeof(struct pl_color_space)); @@ -4320,7 +4405,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))int lev target->num_overlays = 0; } - if (decoder->newchannel && current == 0 ) { + if (decoder->newchannel && current == 0 ) { colors.brightness = -1.0f; colors.contrast = 0.0f; if (!pl_render_image(p->renderer, &decoder->pl_images[current], target, &render_params)) { @@ -4470,14 +4555,10 @@ static void CuvidDisplayFrame(void) // last_time = GetusTicks(); //printf("Roundtrip Displayframe %d\n",diff); - if (diff < 15000 && skipwait != 1) { + if (diff < 15000) { //printf("Sleep %d\n",15000-diff); usleep((15000 - diff));// * 1000); - } else if (skipwait != 1) { -#ifdef CUVID - usleep(15000); -#endif - } + } #endif if (!p->swapchain) @@ -4486,6 +4567,7 @@ static void CuvidDisplayFrame(void) //last_time = GetusTicks(); #ifdef CUVID + first_time = GetusTicks(); VideoThreadLock(); if (!first) { // last_time = GetusTicks(); @@ -4494,17 +4576,15 @@ static void CuvidDisplayFrame(void) pl_swapchain_swap_buffers(p->swapchain); // swap buffers // printf("submit and swap %d\n",(GetusTicks()-last_time)/1000000); } + #endif first = 0; last_time = GetusTicks(); 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); - if (!frame.fbo) { #ifdef CUVID @@ -4571,7 +4651,7 @@ static void CuvidDisplayFrame(void) decoder->StartCounter++; filled = atomic_read(&decoder->SurfacesFilled); -//printf("Filled %d\n",filled); + // need 1 frame for progressive, 3 frames for interlaced if (filled < 1 + 2 * decoder->Interlaced) { // FIXME: rewrite MixVideo to support less surfaces @@ -4664,6 +4744,7 @@ static void CuvidDisplayFrame(void) // printf("submit and swap %d us\n",(GetusTicks()-first_time)/1000); #endif VideoThreadUnlock(); +// printf("Display time %d\n",(GetusTicks()-first_time)/1000000); #else #ifdef CUVID glXGetVideoSyncSGI (&Count); // get current frame @@ -4720,7 +4801,7 @@ static int64_t CuvidGetClock(const CuvidDecoder * decoder) return decoder->PTS - 20 * 90 * (2 * atomic_read(&decoder->SurfacesFilled) - decoder->SurfaceField - 2 + 2); } // + 2 in driver queue - return decoder->PTS - 20 * 90 * (atomic_read(&decoder->SurfacesFilled)+SWAP_BUFFER_SIZE-1); // +2 + return decoder->PTS - 20 * 90 * (atomic_read(&decoder->SurfacesFilled)+SWAP_BUFFER_SIZE-1 +2); // +2 } /// @@ -4790,7 +4871,7 @@ void CuvidGetStats(CuvidDecoder * decoder, int *missed, int *duped, /// /// @param decoder CUVID hw decoder /// - +void AudioDelayms(int); static void CuvidSyncDecoder(CuvidDecoder * decoder) { int filled; @@ -4858,27 +4939,11 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder) // decoder->Frameproc = diff/90; // printf("Roundtrip sync %d\n",(GetusTicks()-last_time)/1000); // last_time = GetusTicks(); -#ifdef CUVID1 - if (skipwait <= 1) { - if ((diff/90) > 55) { - skipwait = 1; - } else if ((diff/90) < -200 && filled > 1) { - skipwait = 3; - decoder->SyncCounter = 1; - } else if ((diff/90) < -100 && filled > 1) { - skipwait = 2; - decoder->SyncCounter = 1; - } else { - decoder->SyncCounter = 1; - skipwait = 0; - } - } -#else - skipwait =0; -#endif + + #if 0 - if (abs(diff/90)> 55 ) { - printf(" Diff %d filled %d skipwait %d \n",diff/90,filled,skipwait); + if (abs(diff/90)> 0 ) { + printf(" Diff %d filled %d \n",diff/90,filled); } #endif if (abs(diff) > 5000 * 90) { // more than 5s @@ -4888,27 +4953,25 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder) // goto out; } else if (diff > 100 * 90) { // FIXME: this quicker sync step, did not work with new code! - err = CuvidMessage(4, "video: slow down video, duping frame\n"); + err = CuvidMessage(4, "video: slow down video, duping frame %d\n",diff/90); ++decoder->FramesDuped; decoder->SyncCounter = 1; goto out; } else if (diff > 55 * 90) { - err = CuvidMessage(3, "video: slow down video, duping frame\n"); + err = CuvidMessage(3, "video: slow down video, duping frame %d \n",diff/90); ++decoder->FramesDuped; decoder->SyncCounter = 1; goto out; - } else if (diff < -25 * 90) { - err = CuvidMessage(3, "video: speed up video, droping frame\n"); - ++decoder->FramesDropped; - CuvidAdvanceDecoderFrame(decoder); - -// if ((AudioDelay == 0) && (filled < 3)) -// AudioDelay = abs(diff/90); -// if (filled >2 && diff < -55) -// CuvidAdvanceDecoderFrame(decoder); - // filled = atomic_read(&decoder->SurfacesFilled); -// Debug(3,"hinter drop frame filled %d\n",atomic_read(&decoder->SurfacesFilled)); - decoder->SyncCounter = 1; + } else if ((diff < -35 * 90)) { + if (filled > 2) { + err = CuvidMessage(3, "video: speed up video, droping frame %d\n",diff/90); + ++decoder->FramesDropped; + CuvidAdvanceDecoderFrame(decoder); + } + else if ((diff < -65 * 90)) // give it some time to get frames to drop + AudioDelayms(abs(diff/90)); + + decoder->SyncCounter = 3; } #if defined(DEBUG) || defined(AV_INFO) if (!decoder->SyncCounter && decoder->StartCounter < 1000) { @@ -5104,7 +5167,7 @@ static void CuvidDisplayHandlerThread(void) decoded = 0; #ifndef PLACEBO - pthread_mutex_lock(&VideoLockMutex); + VideoThreadLock(); #endif for (i = 0; i < CuvidDecoderN; ++i) { @@ -5144,7 +5207,7 @@ static void CuvidDisplayHandlerThread(void) } #ifndef PLACEBO - pthread_mutex_unlock(&VideoLockMutex); + VideoThreadUnlock(); #endif if (!decoded) { // nothing decoded, sleep @@ -5153,7 +5216,7 @@ static void CuvidDisplayHandlerThread(void) } #ifdef PLACEBO -// usleep(1000); + usleep(1000); #endif // all decoder buffers are full @@ -5168,9 +5231,9 @@ static void CuvidDisplayHandlerThread(void) } } #ifndef PLACEBO - pthread_mutex_lock(&VideoLockMutex); + VideoThreadLock(); CuvidSyncDisplayFrame(); - pthread_mutex_unlock(&VideoLockMutex); + VideoThreadUnlock(); #endif return; } @@ -5740,35 +5803,7 @@ void VideoSetVideoEventCallback(void (*videoEventCallback)(void)) #ifdef USE_VIDEO_THREAD - -static uint64_t test_time=0; -/// -/// Lock video thread. -/// -void VideoThreadLock(void) -{ - if (VideoThread) { - if (pthread_mutex_lock(&VideoLockMutex)) { - Error(_("video: can't lock thread\n")); - } -// test_time = GetusTicks(); -// printf("Lock start...."); - } -} - -/// -/// Unlock video thread. -/// -void VideoThreadUnlock(void) -{ - if (VideoThread) { - if (pthread_mutex_unlock(&VideoLockMutex)) { - Error(_("video: can't unlock thread\n")); - } -// printf("Video Locked for %d\n",(GetusTicks()-test_time)/1000000); - } -} #ifdef PLACEBO void pl_log_intern(void *stream, enum pl_log_level level, const char *msg) @@ -6010,7 +6045,7 @@ static void VideoThreadExit(void) if (pthread_cancel(VideoDisplayThread)) { Error(_("video: can't queue cancel video display thread\n")); } - + usleep(200000); // 200ms if (pthread_join(VideoDisplayThread, &retval) || retval != PTHREAD_CANCELED) { Error(_("video: can't cancel video display thread\n")); }