mirror of
https://github.com/jojo61/vdr-plugin-softhdcuvid.git
synced 2023-10-10 13:37:41 +02:00
Fix jump in recordings
Fix in CUVID Bufferhandling
This commit is contained in:
parent
6eb0a7f35a
commit
a2b52bb804
26
audio.c
26
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
|
||||
|
||||
|
71
po/de_DE.po
71
po/de_DE.po
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: VDR \n"
|
||||
"Report-Msgid-Bugs-To: <see README>\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)"
|
||||
|
||||
|
@ -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
|
||||
|
277
video.c
277
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"));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user