32 Commits
V3.6 ... V3.12

Author SHA1 Message Date
jojo61
4b9cd22405 More changes for placebo API 292 2023-07-14 14:14:19 +02:00
jojo61
38bda0c834 Support libplacebo up to API 292 2023-07-14 10:46:25 +02:00
jojo61
45c86f12dd Use first Connector with EDID Data for drm output. 2023-07-14 10:41:41 +02:00
jojo61
e2e9ae94d7 Disable use of HBR for DD+ 2023-07-14 09:15:34 +02:00
jojo61
4837f7fa35 Fix Thread locking for softhddrm Version with placebo 2023-07-14 09:13:09 +02:00
jojo61
7f054f8320 OPENGLOSD: early break on no text draw 2023-05-25 13:57:15 +02:00
jojo61
ad7acde1f4 OPENGLOSD: don't draw if nothin to draw 2023-05-25 12:56:35 +02:00
jojo61
e5c48a4bb7 Update Version 2023-04-23 11:09:08 +02:00
jojo61
fb67617d63 Make Switch for AES Paramters
Change VAAPI Lock
2023-04-23 11:07:09 +02:00
jojo61
8aa807eec6 Disable vaapi Lock only with placebo 2023-04-22 13:07:57 +02:00
jojo61
0621ed064d Set AES Parameter for SPDIF 2023-04-22 09:57:00 +02:00
jojo61
9219f06c5a Remove vaapi Lock for DRM 2023-04-21 12:22:44 +02:00
jojo61
7b41b9b45a Support libplacebo API 229 2023-02-18 08:45:32 +01:00
jojo61
58c39d51f4 Fix Make with LIBPLACBEO_GL
No LUT with HLG Video
2023-02-16 12:50:57 +01:00
jojo61
d78e905411 Update libplacebo link in README 2023-02-15 16:03:10 +01:00
jojo61
7b10c2d0a3 Update for libplacebo API 246 2023-02-15 15:58:51 +01:00
jojo61
9714824a5a Fix non placebo Version for newer INTEL GPUs (A380) 2023-02-15 13:06:44 +01:00
jojo61
3e9b909685 More FFMPEG fixes and Version update 2023-02-13 12:01:15 +01:00
jojo61
464f7de014 Update README with link to libplacebo 2023-02-13 10:48:30 +01:00
jojo61
da33b90f94 Update for latest FFMPEG 2023-02-13 10:11:12 +01:00
jojo61
90194d4b6c Fix for pts (fixed hang at the end when playing records). Version 3.7.5 2022-12-19 09:17:34 +01:00
jojo61
45a83eaa3f Fix Connector Search for DRM
More debug prints in syslog
2022-12-09 11:27:57 +01:00
jojo61
37f87e2511 Reenable Alsa Set Audio 2022-10-19 16:54:45 +02:00
jojo61
bd9184db01 Reenable Alsa Set Volume 2022-10-19 16:53:08 +02:00
jojo61
101bffd01f Merge branch 'master' of github.com:jojo61/vdr-plugin-softhdcuvid 2022-10-19 16:48:11 +02:00
jojo61
43085a3608 Reenable Alsa Set Volume 2022-10-19 16:47:32 +02:00
jojo61
3de7a17105 Merge pull request #65 from dnehring7/master
Remove RASPI support
2022-10-04 13:04:47 +02:00
dnehring7
c229e77151 Merge branch 'jojo61:master' into master 2022-10-03 12:27:16 +02:00
jojo61
af370721d4 Fix Audio for NUC11 2022-09-24 14:59:46 +02:00
jojo61
79fa8efc6a Fix E-AC3 Parser 2022-09-20 15:05:18 +02:00
jojo61
d5dec38d62 remove glxMakeCurrent 2022-07-09 12:52:28 +02:00
Dirk Nehring
74847c9bed Remove RASPI support 2022-05-24 00:09:55 +02:00
9 changed files with 382 additions and 252 deletions

View File

@@ -37,7 +37,6 @@ A software and GPU emulated UHD output device plugin for VDR.
o PIP (Picture-in-Picture) (only for CUVID) o PIP (Picture-in-Picture) (only for CUVID)
To compile you must have the 'requires' installed.
This is a fork of johns original softhddevice work and I reworked it to support HEVC with CUDA and opengl output. This is a fork of johns original softhddevice work and I reworked it to support HEVC with CUDA and opengl output.
@@ -83,7 +82,9 @@ You have to adapt the Makefile. There are 3 possible Version that you can build:
runs without X Server. There are several commandline options to select the resolution and refresh rate. runs without X Server. There are several commandline options to select the resolution and refresh rate.
I recommend to use libplacebo and set LIBPLACEBO_GL=1 in the Makefile. I recommend to use libplacebo and set LIBPLACEBO_GL=1 in the Makefile.
Libplacebo API Version >= 113 is needed. You should use the following libplacebo Version:
https://github.com/haasn/libplacebo/archive/f2c4da9d6121bb330c9fff640aad40e98c081190.zip
Newer Versions may not work.
Install: Install:

70
audio.c
View File

@@ -927,6 +927,7 @@ static snd_pcm_t *AlsaOpenPCM(int passthrough) {
const char *device; const char *device;
snd_pcm_t *handle; snd_pcm_t *handle;
int err; int err;
char tmp[80];
// &&|| hell // &&|| hell
if (!(passthrough && ((device = AudioPassthroughDevice) || (device = getenv("ALSA_PASSTHROUGH_DEVICE")))) && if (!(passthrough && ((device = AudioPassthroughDevice) || (device = getenv("ALSA_PASSTHROUGH_DEVICE")))) &&
@@ -936,30 +937,42 @@ static snd_pcm_t *AlsaOpenPCM(int passthrough) {
if (!AudioDoingInit) { // reduce blabla during init if (!AudioDoingInit) { // reduce blabla during init
Info(_("audio/alsa: using %sdevice '%s'\n"), passthrough ? "pass-through " : "", device); Info(_("audio/alsa: using %sdevice '%s'\n"), passthrough ? "pass-through " : "", device);
} }
//printf("audio/alsa: using %sdevice '%s'\n", passthrough ? "pass-through " : "", device);
// //
// for AC3 pass-through try to set the non-audio bit, use AES0=6 // for AC3 pass-through try to set the non-audio bit, use AES0=6
// //
if (passthrough && AudioAppendAES) { if (passthrough && AudioAppendAES) {
#if 0 if (!(strchr(device, ':'))) {
// FIXME: not yet finished sprintf(tmp,
char *buf; //"AES0=%d,AES1=%d,AES2=0,AES3=%d",
const char *s; "%s:AES0=%d,AES1=%d,AES2=0",
int n; device,
IEC958_AES0_NONAUDIO | IEC958_AES0_PRO_EMPHASIS_NONE,
n = strlen(device); IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER);
buf = alloca(n + sizeof(":AES0=6") + 1); //map_iec958_srate(ao->samplerate));
strcpy(buf, device); }
if (!(s = strchr(buf, ':'))) { else {
// no alsa parameters sprintf(tmp,
strcpy(buf + n, ":AES=6"); //"AES0=%d,AES1=%d,AES2=0,AES3=%d",
} "%s,AES0=%d,AES1=%d,AES2=0",
Debug(3, "audio/alsa: try '%s'\n", buf); device,
#endif IEC958_AES0_NONAUDIO | IEC958_AES0_PRO_EMPHASIS_NONE,
} IEC958_AES1_CON_ORIGINAL | IEC958_AES1_CON_PCM_CODER);
// open none blocking; if device is already used, we don't want wait //map_iec958_srate(ao->samplerate));
if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { }
Error(_("audio/alsa: playback open '%s' error: %s\n"), device, snd_strerror(err));
return NULL; printf( "opening device '%s' => '%s'\n", device, tmp);
if ((err = snd_pcm_open(&handle, tmp, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0 ) {
Error(_("audio/alsa: playback open '%s' error: %s\n"), device, snd_strerror(err));
return NULL;
}
} else {
// open none blocking; if device is already used, we don't want wait
if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) {
Error(_("audio/alsa: playback open '%s' error: %s\n"), device, snd_strerror(err));
return NULL;
}
} }
if ((err = snd_pcm_nonblock(handle, 0)) < 0) { if ((err = snd_pcm_nonblock(handle, 0)) < 0) {
@@ -2173,6 +2186,22 @@ found:
AudioDoingInit = 1; AudioDoingInit = 1;
AudioRingInit(); AudioRingInit();
AudioUsedModule->Init(); AudioUsedModule->Init();
#if 1
for (u = 0; u < AudioRatesMax; ++u) {
AudioChannelMatrix[u][1]=AudioChannelMatrix[u][2]=AudioChannelMatrix[u][3]=AudioChannelMatrix[u][4]=\
AudioChannelMatrix[u][5]=AudioChannelMatrix[u][6]=AudioChannelMatrix[u][7]=AudioChannelMatrix[u][8]=2;
//printf("audio: %6dHz supports %d %d %d %d %d %d %d %d channels\n", AudioRatesTable[u],
// AudioChannelMatrix[u][1], AudioChannelMatrix[u][2], AudioChannelMatrix[u][3], AudioChannelMatrix[u][4],
// AudioChannelMatrix[u][5], AudioChannelMatrix[u][6], AudioChannelMatrix[u][7], AudioChannelMatrix[u][8]);
}
AudioChannelsInHw[1]=AudioChannelsInHw[3]=AudioChannelsInHw[4]=AudioChannelsInHw[5]=AudioChannelsInHw[6]=AudioChannelsInHw[7]=AudioChannelsInHw[8]=0;
AudioChannelsInHw[2]=2;
#else
// //
// Check which channels/rates/formats are supported // Check which channels/rates/formats are supported
// FIXME: we force 44.1Khz and 48Khz must be supported equal // FIXME: we force 44.1Khz and 48Khz must be supported equal
@@ -2294,6 +2323,7 @@ found:
AudioChannelMatrix[u][1], AudioChannelMatrix[u][2], AudioChannelMatrix[u][3], AudioChannelMatrix[u][4], AudioChannelMatrix[u][1], AudioChannelMatrix[u][2], AudioChannelMatrix[u][3], AudioChannelMatrix[u][4],
AudioChannelMatrix[u][5], AudioChannelMatrix[u][6], AudioChannelMatrix[u][7], AudioChannelMatrix[u][8]); AudioChannelMatrix[u][5], AudioChannelMatrix[u][6], AudioChannelMatrix[u][7], AudioChannelMatrix[u][8]);
} }
#endif
#ifdef USE_AUDIO_THREAD #ifdef USE_AUDIO_THREAD
if (AudioUsedModule->Thread) { // supports threads if (AudioUsedModule->Thread) { // supports threads
AudioInitThread(); AudioInitThread();

43
codec.c
View File

@@ -234,20 +234,6 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) {
break; break;
} }
} }
#endif
#ifdef RASPI
switch (codec_id) {
case AV_CODEC_ID_MPEG2VIDEO:
name = "mpeg2_v4l2m2m";
break;
case AV_CODEC_ID_H264:
name = "h264_v4l2m2m";
// name = "h264_mmal";
break;
case AV_CODEC_ID_HEVC:
name = "hevc_v4l2m2m";
break;
}
#endif #endif
if (name && (video_codec = avcodec_find_decoder_by_name(name))) { if (name && (video_codec = avcodec_find_decoder_by_name(name))) {
Debug(3, "codec: decoder found\n"); Debug(3, "codec: decoder found\n");
@@ -264,16 +250,10 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) {
Fatal(_("codec: can't allocate video codec context\n")); Fatal(_("codec: can't allocate video codec context\n"));
} }
#ifndef RASPI
if (!HwDeviceContext) { if (!HwDeviceContext) {
Fatal("codec: no hw device context to be used"); Fatal("codec: no hw device context to be used");
} }
decoder->VideoCtx->hw_device_ctx = av_buffer_ref(HwDeviceContext); decoder->VideoCtx->hw_device_ctx = av_buffer_ref(HwDeviceContext);
#else
decoder->VideoCtx->pix_fmt = AV_PIX_FMT_DRM_PRIME; /* request a DRM frame */
// decoder->VideoCtx->pix_fmt = AV_PIX_FMT_MMAL; /* request a DRM frame
//*/
#endif
// FIXME: for software decoder use all cpus, otherwise 1 // FIXME: for software decoder use all cpus, otherwise 1
decoder->VideoCtx->thread_count = 1; decoder->VideoCtx->thread_count = 1;
@@ -288,7 +268,9 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) {
#ifdef YADIF #ifdef YADIF
deint = 2; deint = 2;
#endif #endif
#if defined VAAPI && !defined RASPI
#if defined VAAPI
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,8,100)
// decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1 // decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1
if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) { if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) {
Debug(3, "codec: auto threads enabled"); Debug(3, "codec: auto threads enabled");
@@ -299,6 +281,7 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) {
Debug(3, "codec: supports truncated packets"); Debug(3, "codec: supports truncated packets");
// decoder->VideoCtx->flags |= CODEC_FLAG_TRUNCATED; // decoder->VideoCtx->flags |= CODEC_FLAG_TRUNCATED;
} }
#endif
// FIXME: own memory management for video frames. // FIXME: own memory management for video frames.
if (video_codec->capabilities & AV_CODEC_CAP_DR1) { if (video_codec->capabilities & AV_CODEC_CAP_DR1) {
Debug(3, "codec: can use own buffer management"); Debug(3, "codec: can use own buffer management");
@@ -315,22 +298,10 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) {
} }
// if (av_opt_set_int(decoder->VideoCtx, "refcounted_frames", 1, 0) < 0) // if (av_opt_set_int(decoder->VideoCtx, "refcounted_frames", 1, 0) < 0)
// Fatal(_("VAAPI Refcounts invalid\n")); // Fatal(_("VAAPI Refcounts invalid\n"));
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,8,100)
decoder->VideoCtx->thread_safe_callbacks = 0; decoder->VideoCtx->thread_safe_callbacks = 0;
#endif #endif
#ifdef RASPI
decoder->VideoCtx->codec_id = codec_id;
decoder->VideoCtx->flags |= AV_CODEC_FLAG_BITEXACT;
if (video_codec->capabilities & AV_CODEC_CAP_FRAME_THREADS || AV_CODEC_CAP_SLICE_THREADS) {
Debug(3, "codec: supports frame threads");
decoder->VideoCtx->thread_count = 4;
// decoder->VideoCtx->thread_type |= FF_THREAD_FRAME;
}
if (video_codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
Debug(3, "codec: supports slice threads");
decoder->VideoCtx->thread_type |= FF_THREAD_SLICE;
}
#endif #endif
#ifdef CUVID #ifdef CUVID
@@ -401,7 +372,7 @@ void CodecVideoOpen(VideoDecoder *decoder, int codec_id) {
// reset buggy ffmpeg/libav flag // reset buggy ffmpeg/libav flag
decoder->GetFormatDone = 0; decoder->GetFormatDone = 0;
#if defined(YADIF) || defined(RASPI) #if defined(YADIF)
decoder->filter = 0; decoder->filter = 0;
#endif #endif
} }
@@ -923,7 +894,7 @@ static int CodecAudioUpdateHelper(AudioDecoder *audio_decoder, int *passthrough)
(CodecPassthrough & CodecEAC3 && audio_ctx->codec_id == AV_CODEC_ID_EAC3)) { (CodecPassthrough & CodecEAC3 && audio_ctx->codec_id == AV_CODEC_ID_EAC3)) {
if (audio_ctx->codec_id == AV_CODEC_ID_EAC3) { if (audio_ctx->codec_id == AV_CODEC_ID_EAC3) {
// E-AC-3 over HDMI some receivers need HBR // E-AC-3 over HDMI some receivers need HBR
audio_decoder->HwSampleRate *= 4; //audio_decoder->HwSampleRate *= 4;
} }
audio_decoder->HwChannels = 2; audio_decoder->HwChannels = 2;
audio_decoder->SpdifIndex = 0; // reset buffer audio_decoder->SpdifIndex = 0; // reset buffer

29
drm.c
View File

@@ -168,6 +168,7 @@ void set_video_mode(int width, int height) {
drmModeConnector *connector; drmModeConnector *connector;
drmModeModeInfo *mode; drmModeModeInfo *mode;
int ii; int ii;
printf("Set video mode %d &%d\n",width,height);
if (height != 1080 && height != 2160) if (height != 1080 && height != 2160)
return; return;
connector = drmModeGetConnector(render->fd_drm, render->connector_id); connector = drmModeGetConnector(render->fd_drm, render->connector_id);
@@ -206,11 +207,7 @@ static int FindDevice(VideoRender *render) {
int i, ii = 0; int i, ii = 0;
char connectorstr[10]; char connectorstr[10];
int found = 0; int found = 0;
#ifdef RASPI
render->fd_drm = open("/dev/dri/card1", O_RDWR);
#else
render->fd_drm = open("/dev/dri/card0", O_RDWR); render->fd_drm = open("/dev/dri/card0", O_RDWR);
#endif
if (render->fd_drm < 0) { if (render->fd_drm < 0) {
fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n"); fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n");
return -errno; return -errno;
@@ -278,10 +275,12 @@ static int FindDevice(VideoRender *render) {
connector->connector_type_id); connector->connector_type_id);
printf("Connector >%s< is %sconnected\n", connectorstr, printf("Connector >%s< is %sconnected\n", connectorstr,
connector->connection == DRM_MODE_CONNECTED ? "" : "not "); connector->connection == DRM_MODE_CONNECTED ? "" : "not ");
Debug(3,"Connector >%s< is %sconnected\n", connectorstr,
connector->connection == DRM_MODE_CONNECTED ? "" : "not ");
if (DRMConnector && strcmp(DRMConnector, connectorstr)) if (DRMConnector && strcmp(DRMConnector, connectorstr))
continue; continue;
if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) { if (/*connector->connection == DRM_MODE_CONNECTED && */ connector->count_modes > 0) {
float aspect = (float)connector->mmWidth / (float)connector->mmHeight; float aspect = (float)connector->mmWidth / (float)connector->mmHeight;
if ((aspect > 1.70) && (aspect < 1.85)) { if ((aspect > 1.70) && (aspect < 1.85)) {
render->mmHeight = 90; render->mmHeight = 90;
@@ -309,7 +308,7 @@ static int FindDevice(VideoRender *render) {
mode = &connector->modes[ii]; mode = &connector->modes[ii];
printf("Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh); printf("Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh);
Debug(3,"Mode %d %dx%d Rate %d\n", ii, mode->hdisplay, mode->vdisplay, mode->vrefresh);
if (VideoWindowWidth && VideoWindowHeight) { // preset by command line if (VideoWindowWidth && VideoWindowHeight) { // preset by command line
if (VideoWindowWidth == mode->hdisplay && VideoWindowHeight == mode->vdisplay && if (VideoWindowWidth == mode->hdisplay && VideoWindowHeight == mode->vdisplay &&
mode->vrefresh == DRMRefresh && !(mode->flags & DRM_MODE_FLAG_INTERLACE)) { mode->vrefresh == DRMRefresh && !(mode->flags & DRM_MODE_FLAG_INTERLACE)) {
@@ -328,11 +327,16 @@ static int FindDevice(VideoRender *render) {
found = 1; found = 1;
i = resources->count_connectors; // uuuuhh i = resources->count_connectors; // uuuuhh
} }
VideoWindowWidth = render->mode.hdisplay;
VideoWindowHeight = render->mode.vdisplay; if (found) {
if (found) VideoWindowWidth = render->mode.hdisplay;
VideoWindowHeight = render->mode.vdisplay;
printf("Use Mode %d %dx%d Rate %d\n", ii, render->mode.hdisplay, render->mode.vdisplay, printf("Use Mode %d %dx%d Rate %d\n", ii, render->mode.hdisplay, render->mode.vdisplay,
render->mode.vrefresh); render->mode.vrefresh);
Debug(3,"Use Mode %d %dx%d Rate %d\n", ii, render->mode.hdisplay, render->mode.vdisplay,
render->mode.vrefresh);
}
drmModeFreeConnector(connector); drmModeFreeConnector(connector);
} }
if (!found) { if (!found) {
@@ -372,11 +376,7 @@ static int FindDevice(VideoRender *render) {
for (k = 0; k < plane->count_formats; k++) { for (k = 0; k < plane->count_formats; k++) {
if (encoder->possible_crtcs & plane->possible_crtcs) { if (encoder->possible_crtcs & plane->possible_crtcs) {
switch (plane->formats[k]) { switch (plane->formats[k]) {
#ifdef RASPI
case DRM_FORMAT_ARGB8888:
#else
case DRM_FORMAT_XRGB2101010: case DRM_FORMAT_XRGB2101010:
#endif
if (!render->video_plane) { if (!render->video_plane) {
render->video_plane = plane->plane_id; render->video_plane = plane->plane_id;
} }
@@ -492,6 +492,7 @@ static void drm_swap_buffers() {
uint32_t fb; uint32_t fb;
eglSwapBuffers(eglDisplay, eglSurface); eglSwapBuffers(eglDisplay, eglSurface);
usleep(1000);
struct gbm_bo *bo = gbm_surface_lock_front_buffer(gbm.surface); struct gbm_bo *bo = gbm_surface_lock_front_buffer(gbm.surface);
#if 1 #if 1
if (bo == NULL) if (bo == NULL)
@@ -630,4 +631,4 @@ static void drm_clean_up() {
close(render->fd_drm); close(render->fd_drm);
eglDisplay = NULL; eglDisplay = NULL;
free(render); free(render);
} }

View File

@@ -20,12 +20,8 @@ void ConvertColor(const GLint &colARGB, glm::vec4 &col) {
#ifdef CUVID #ifdef CUVID
const char *glversion = "#version 330 core "; const char *glversion = "#version 330 core ";
#else #else
#ifdef RASPI
const char *glversion = "#version 300 es";
#else
const char *glversion = "#version 300 es "; const char *glversion = "#version 300 es ";
#endif #endif
#endif
const char *rectVertexShader = "%s\n \ const char *rectVertexShader = "%s\n \
\ \
@@ -837,6 +833,8 @@ cOglCmdDrawRectangle::cOglCmdDrawRectangle(cOglFb *fb, GLint x, GLint y, GLint w
} }
bool cOglCmdDrawRectangle::Execute(void) { bool cOglCmdDrawRectangle::Execute(void) {
if (width <= 0 || height <= 0)
return false;
GLfloat x1 = x; GLfloat x1 = x;
GLfloat y1 = y; GLfloat y1 = y;
GLfloat x2 = x + width; GLfloat x2 = x + width;
@@ -883,6 +881,8 @@ cOglCmdDrawEllipse::cOglCmdDrawEllipse(cOglFb *fb, GLint x, GLint y, GLint width
} }
bool cOglCmdDrawEllipse::Execute(void) { bool cOglCmdDrawEllipse::Execute(void) {
if (width <= 0 || height <= 0)
return false;
int numVertices = 0; int numVertices = 0;
GLfloat *vertices = NULL; GLfloat *vertices = NULL;
@@ -1090,6 +1090,8 @@ cOglCmdDrawSlope::cOglCmdDrawSlope(cOglFb *fb, GLint x, GLint y, GLint width, GL
} }
bool cOglCmdDrawSlope::Execute(void) { bool cOglCmdDrawSlope::Execute(void) {
if (width <= 0 || height <= 0)
return false;
bool falling = type & 0x02; bool falling = type & 0x02;
bool vertical = type & 0x04; bool vertical = type & 0x04;
@@ -1177,7 +1179,7 @@ cOglCmdDrawText::~cOglCmdDrawText(void) { free(symbols); }
bool cOglCmdDrawText::Execute(void) { bool cOglCmdDrawText::Execute(void) {
cOglFont *f = cOglFont::Get(*fontName, fontSize); cOglFont *f = cOglFont::Get(*fontName, fontSize);
if (!f) if (!f || !symbols[0])
return false; return false;
VertexBuffers[vbText]->ActivateShader(); VertexBuffers[vbText]->ActivateShader();
@@ -1256,10 +1258,13 @@ cOglCmdDrawImage::cOglCmdDrawImage(cOglFb *fb, tColor *argb, GLint width, GLint
cOglCmdDrawImage::~cOglCmdDrawImage(void) { free(argb); } cOglCmdDrawImage::~cOglCmdDrawImage(void) { free(argb); }
bool cOglCmdDrawImage::Execute(void) { bool cOglCmdDrawImage::Execute(void) {
if (width <= 0 || height <= 0)
return false;
GLuint texture; GLuint texture;
#ifdef USE_DRM #ifdef USE_DRM
// pthread_mutex_lock(&OSDMutex); //esyslog("upload Image\n");
pthread_mutex_lock(&OSDMutex);
GlxDrawopengl(); // here we need the Shared Context for upload GlxDrawopengl(); // here we need the Shared Context for upload
GlxCheck(); GlxCheck();
#endif #endif
@@ -1272,10 +1277,10 @@ bool cOglCmdDrawImage::Execute(void) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glFlush(); glFlush();
#ifdef USE_DRM #ifdef USE_DRM
GlxInitopengl(); // Reset Context GlxInitopengl(); // Reset Context
GlxCheck(); GlxCheck();
// pthread_mutex_unlock(&OSDMutex); pthread_mutex_unlock(&OSDMutex);
#endif #endif
GLfloat x1 = x; // left GLfloat x1 = x; // left
@@ -1322,6 +1327,8 @@ cOglCmdDrawTexture::cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x,
} }
bool cOglCmdDrawTexture::Execute(void) { bool cOglCmdDrawTexture::Execute(void) {
if (imageRef->width <= 0 || imageRef->height <= 0)
return false;
GLfloat x1 = x; // top GLfloat x1 = x; // top
GLfloat y1 = y; // left GLfloat y1 = y; // left
GLfloat x2 = x + imageRef->width; // right GLfloat x2 = x + imageRef->width; // right
@@ -1363,7 +1370,8 @@ cOglCmdStoreImage::~cOglCmdStoreImage(void) { free(data); }
bool cOglCmdStoreImage::Execute(void) { bool cOglCmdStoreImage::Execute(void) {
#ifdef USE_DRM #ifdef USE_DRM
// pthread_mutex_lock(&OSDMutex); return false;
pthread_mutex_lock(&OSDMutex);
GlxDrawopengl(); // here we need the Shared Context for upload GlxDrawopengl(); // here we need the Shared Context for upload
GlxCheck(); GlxCheck();
#endif #endif
@@ -1380,7 +1388,7 @@ bool cOglCmdStoreImage::Execute(void) {
#ifdef USE_DRM #ifdef USE_DRM
GlxInitopengl(); // Reset Context GlxInitopengl(); // Reset Context
GlxCheck(); GlxCheck();
// pthread_mutex_lock(&OSDMutex); pthread_mutex_lock(&OSDMutex);
#endif #endif
return true; return true;
} }
@@ -1460,7 +1468,9 @@ int cOglThread::StoreImage(const cImage &image) {
if (!maxCacheSize) { if (!maxCacheSize) {
return 0; return 0;
} }
#ifdef USE_DRM
return 0;
#endif
if (image.Width() > maxTextureSize || image.Height() > maxTextureSize) { if (image.Width() > maxTextureSize || image.Height() > maxTextureSize) {
esyslog("[softhddev] cannot store image of %dpx x %dpx " esyslog("[softhddev] cannot store image of %dpx x %dpx "
"(maximum size is %dpx x %dpx) - falling back to " "(maximum size is %dpx x %dpx) - falling back to "
@@ -1640,6 +1650,7 @@ void cOglThread::Action(void) {
bool cOglThread::InitOpenGL(void) { bool cOglThread::InitOpenGL(void) {
#ifdef USE_DRM #ifdef USE_DRM
esyslog("InitOpenGL\n");
GlxInitopengl(); GlxInitopengl();
#else #else
const char *displayName = X11DisplayName; const char *displayName = X11DisplayName;
@@ -1651,7 +1662,7 @@ bool cOglThread::InitOpenGL(void) {
} }
} }
dsyslog("[softhddev]OpenGL using display %s", displayName); esyslog("[softhddev]OpenGL using display %s", displayName);
int argc = 3; int argc = 3;
char *buffer[3]; char *buffer[3];

View File

@@ -4,12 +4,8 @@
#ifdef CUVID #ifdef CUVID
const char *gl_version = "#version 330"; const char *gl_version = "#version 330";
#else #else
#ifdef RASPI
const char *gl_version = "#version 300 es";
#else
const char *gl_version = "#version 300 es "; const char *gl_version = "#version 300 es ";
#endif #endif
#endif
/* Color conversion matrix: RGB = m * YUV + c /* Color conversion matrix: RGB = m * YUV + c
* m is in row-major matrix, with m[row][col], e.g.: * m is in row-major matrix, with m[row][col], e.g.:

View File

@@ -61,7 +61,7 @@ extern void ToggleLUT();
/// vdr-plugin version number. /// vdr-plugin version number.
/// Makefile extracts the version number for generating the file name /// Makefile extracts the version number for generating the file name
/// for the distribution archive. /// for the distribution archive.
static const char *const VERSION = "3.6" static const char *const VERSION = "3.12"
#ifdef GIT_REV #ifdef GIT_REV
"-GIT" GIT_REV "-GIT" GIT_REV
#endif #endif
@@ -642,33 +642,84 @@ void cSoftOsd::Flush(void) {
#ifdef USE_OPENGLOSD #ifdef USE_OPENGLOSD
//Dummy Pixmap for skins // Dummy Pixmap for skins
class cDummyPixmap : public cPixmap { class cDummyPixmap : public cPixmap {
public: public:
cDummyPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null) : cPixmap(Layer, ViewPort, DrawPort) {} cDummyPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null)
: cPixmap(Layer, ViewPort, DrawPort) {}
virtual ~cDummyPixmap(void) {} virtual ~cDummyPixmap(void) {}
virtual void Clear(void) {} virtual void Clear(void) {}
virtual void Fill(tColor Color) { (void)Color; } virtual void Fill(tColor Color) { (void)Color; }
virtual void DrawImage(const cPoint &Point, const cImage &Image) { (void)Point; (void)Image; } virtual void DrawImage(const cPoint &Point, const cImage &Image) {
virtual void DrawImage(const cPoint &Point, int ImageHandle) { (void)Point; (void)ImageHandle; } (void)Point;
virtual void DrawPixel(const cPoint &Point, tColor Color) { (void)Point; (void)Color; } (void)Image;
virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false) { }
(void) Point; (void)Bitmap; (void)ColorFg; (void)ColorBg; (void)Overlay; } virtual void DrawImage(const cPoint &Point, int ImageHandle) {
virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault) { (void)Point;
(void)Point; (void)s; (void)ColorFg; (void) ColorBg; (void) Font; (void)Width; (void)Height; (void)Alignment; } (void)ImageHandle;
virtual void DrawRectangle(const cRect &Rect, tColor Color) { (void)Rect; (void)Color; } }
virtual void DrawEllipse(const cRect &Rect, tColor Color, int Quadrants = 0) { (void)Rect; (void)Color; (void)Quadrants; } virtual void DrawPixel(const cPoint &Point, tColor Color) {
virtual void DrawSlope(const cRect &Rect, tColor Color, int Type) { (void)Rect; (void)Color; (void)Type; } (void)Point;
virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) { (void)Pixmap; (void)Source; (void)Dest; } (void)Color;
virtual void Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) { (void)Pixmap; (void)Source; (void)Dest; } }
virtual void Scroll(const cPoint &Dest, const cRect &Source = cRect::Null) { (void)Dest; (void)Source; } virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0,
virtual void Pan(const cPoint &Dest, const cRect &Source = cRect::Null) { (void)Dest; (void)Source; } bool Overlay = false) {
(void)Point;
(void)Bitmap;
(void)ColorFg;
(void)ColorBg;
(void)Overlay;
}
virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font,
int Width = 0, int Height = 0, int Alignment = taDefault) {
(void)Point;
(void)s;
(void)ColorFg;
(void)ColorBg;
(void)Font;
(void)Width;
(void)Height;
(void)Alignment;
}
virtual void DrawRectangle(const cRect &Rect, tColor Color) {
(void)Rect;
(void)Color;
}
virtual void DrawEllipse(const cRect &Rect, tColor Color, int Quadrants = 0) {
(void)Rect;
(void)Color;
(void)Quadrants;
}
virtual void DrawSlope(const cRect &Rect, tColor Color, int Type) {
(void)Rect;
(void)Color;
(void)Type;
}
virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) {
(void)Pixmap;
(void)Source;
(void)Dest;
}
virtual void Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) {
(void)Pixmap;
(void)Source;
(void)Dest;
}
virtual void Scroll(const cPoint &Dest, const cRect &Source = cRect::Null) {
(void)Dest;
(void)Source;
}
virtual void Pan(const cPoint &Dest, const cRect &Source = cRect::Null) {
(void)Dest;
(void)Source;
}
}; };
// Dummy OSD for OpenGL OSD if no X Server is available // Dummy OSD for OpenGL OSD if no X Server is available
class cDummyOsd : public cOsd { class cDummyOsd : public cOsd {
private: private:
cDummyPixmap *p; cDummyPixmap *p;
public: public:
cDummyOsd(int Left, int Top, uint Level) : cOsd(Left, Top, Level) {} cDummyOsd(int Left, int Top, uint Level) : cOsd(Left, Top, Level) {}
virtual ~cDummyOsd() {} virtual ~cDummyOsd() {}

View File

@@ -364,7 +364,7 @@ static int Ac3Check(const uint8_t *data, int size) {
if ((data[4] & 0xF0) == 0xF0) { // invalid fscod fscod2 if ((data[4] & 0xF0) == 0xF0) { // invalid fscod fscod2
return 0; return 0;
} }
frame_size = ((data[2] & 0x03) << 8) + data[3] + 1; frame_size = ((data[2] & 0x07) << 8) + data[3] + 1;
frame_size *= 2; frame_size *= 2;
} else { // AC-3 } else { // AC-3
int fscod; int fscod;
@@ -2142,7 +2142,7 @@ int PlayVideo3(VideoStream *stream, const uint8_t *data, int size) {
} }
// hard limit buffer full: needed for replay // hard limit buffer full: needed for replay
if (atomic_read(&stream->PacketsFilled) >= VIDEO_PACKET_MAX - 10) { if (atomic_read(&stream->PacketsFilled) >= VIDEO_PACKET_MAX - 10) {
// Debug(3, "video: video buffer full\n"); //Debug(3, "video: video buffer full\n");
return 0; return 0;
} }
#ifdef USE_SOFTLIMIT #ifdef USE_SOFTLIMIT

357
video.c
View File

@@ -155,15 +155,12 @@ typedef enum {
#endif #endif
#ifdef VAAPI #ifdef VAAPI
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57,74,100) #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 74, 100)
#include <libavcodec/vaapi.h> #include <libavcodec/vaapi.h>
#endif #endif
#include <libavutil/hwcontext_vaapi.h>
#include <libdrm/drm_fourcc.h> #include <libdrm/drm_fourcc.h>
#include <va/va_drmcommon.h> #include <va/va_drmcommon.h>
#ifdef RASPI
#include <libavutil/hwcontext_drm.h>
#endif
#include <libavutil/hwcontext_vaapi.h>
#define TO_AVHW_DEVICE_CTX(x) ((AVHWDeviceContext *)x->data) #define TO_AVHW_DEVICE_CTX(x) ((AVHWDeviceContext *)x->data)
#define TO_AVHW_FRAMES_CTX(x) ((AVHWFramesContext *)x->data) #define TO_AVHW_FRAMES_CTX(x) ((AVHWFramesContext *)x->data)
#define TO_VAAPI_DEVICE_CTX(x) ((AVVAAPIDeviceContext *)TO_AVHW_DEVICE_CTX(x)->hwctx) #define TO_VAAPI_DEVICE_CTX(x) ((AVVAAPIDeviceContext *)TO_AVHW_DEVICE_CTX(x)->hwctx)
@@ -341,7 +338,7 @@ typedef struct {
#define NUM_SHADERS 5 // Number of supported user shaders with placebo #define NUM_SHADERS 5 // Number of supported user shaders with placebo
#if defined VAAPI && !defined RASPI #if defined VAAPI
#define PIXEL_FORMAT AV_PIX_FMT_VAAPI #define PIXEL_FORMAT AV_PIX_FMT_VAAPI
#define SWAP_BUFFER_SIZE 3 #define SWAP_BUFFER_SIZE 3
#endif #endif
@@ -349,21 +346,13 @@ typedef struct {
#define PIXEL_FORMAT AV_PIX_FMT_CUDA #define PIXEL_FORMAT AV_PIX_FMT_CUDA
#define SWAP_BUFFER_SIZE 3 #define SWAP_BUFFER_SIZE 3
#endif #endif
#if defined RASPI
#define PIXEL_FORMAT AV_PIX_FMT_MMAL
#define SWAP_BUFFER_SIZE 3
#endif
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Variables // Variables
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
AVBufferRef *HwDeviceContext; ///< ffmpeg HW device context AVBufferRef *HwDeviceContext; ///< ffmpeg HW device context
char VideoIgnoreRepeatPict; ///< disable repeat pict warning char VideoIgnoreRepeatPict; ///< disable repeat pict warning
#ifdef RASPI
int Planes = 3;
#else
int Planes = 2; int Planes = 2;
#endif
unsigned char *posd; unsigned char *posd;
@@ -475,7 +464,7 @@ extern void AudioVideoReady(int64_t); ///< tell audio video is ready
static pthread_t VideoThread; ///< video decode thread static pthread_t VideoThread; ///< video decode thread
static pthread_cond_t VideoWakeupCond; ///< wakeup condition variable static pthread_cond_t VideoWakeupCond; ///< wakeup condition variable
static pthread_mutex_t VideoMutex; ///< video condition mutex static pthread_mutex_t VideoMutex; ///< video condition mutex
static pthread_mutex_t VideoLockMutex; ///< video lock mutex pthread_mutex_t VideoLockMutex; ///< video lock mutex
pthread_mutex_t OSDMutex; ///< OSD update mutex pthread_mutex_t OSDMutex; ///< OSD update mutex
#endif #endif
@@ -628,6 +617,8 @@ char *eglErrorString(EGLint error) {
static void VideoSetPts(int64_t *pts_p, int interlaced, const AVCodecContext *video_ctx, const AVFrame *frame) { static void VideoSetPts(int64_t *pts_p, int interlaced, const AVCodecContext *video_ctx, const AVFrame *frame) {
int64_t pts; int64_t pts;
int duration; int duration;
static int64_t lastpts;
// //
// Get duration for this frame. // Get duration for this frame.
@@ -675,11 +666,12 @@ static void VideoSetPts(int64_t *pts_p, int interlaced, const AVCodecContext *vi
Debug(3, "++++++++++++++++++++++++++++++++++++starte audio\n"); Debug(3, "++++++++++++++++++++++++++++++++++++starte audio\n");
AudioVideoReady(pts); AudioVideoReady(pts);
} }
if (*pts_p != pts) { if (*pts_p != pts && lastpts != pts) {
Debug(4, "video: %#012" PRIx64 "->%#012" PRIx64 " delta=%4" PRId64 " pts\n", *pts_p, pts, pts - *pts_p); Debug(4, "video: %#012" PRIx64 "->%#012" PRIx64 " delta=%4" PRId64 " pts\n", *pts_p, pts, pts - *pts_p);
*pts_p = pts; *pts_p = pts;
} }
} }
lastpts = pts;
} }
int CuvidMessage(int level, const char *format, ...); int CuvidMessage(int level, const char *format, ...);
@@ -833,6 +825,8 @@ static uint64_t test_time = 0;
#define Lock_and_SharedContext \ #define Lock_and_SharedContext \
{ \ { \
VideoThreadLock(); \ VideoThreadLock(); \
Debug(4,"Lock OSDMutex %s %d\n",__FILE__, __LINE__); \
pthread_mutex_lock(&OSDMutex); \
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext); \ eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext); \
EglCheck(); \ EglCheck(); \
} }
@@ -840,10 +834,14 @@ static uint64_t test_time = 0;
{ \ { \
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); \ eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); \
EglCheck(); \ EglCheck(); \
Debug(4,"UnLock OSDMutex %s %d\n",__FILE__, __LINE__); \
pthread_mutex_unlock(&OSDMutex); \
VideoThreadUnlock(); \ VideoThreadUnlock(); \
} }
#define SharedContext \ #define SharedContext \
{ \ { \
Debug(4,"Lock OSDMutex %s %d\n",__FILE__, __LINE__); \
pthread_mutex_lock(&OSDMutex); \
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext); \ eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext); \
EglCheck(); \ EglCheck(); \
} }
@@ -851,6 +849,8 @@ static uint64_t test_time = 0;
{ \ { \
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); \ eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); \
EglCheck(); \ EglCheck(); \
Debug(4,"UnLock OSDMutex %s %d\n",__FILE__, __LINE__); \
pthread_mutex_unlock(&OSDMutex); \
} }
#else #else
#ifdef PLACEBO #ifdef PLACEBO
@@ -1227,7 +1227,7 @@ static void EglExit(void) {
// must destroy glx // must destroy glx
// if (glXGetCurrentContext() == glxContext) { // if (glXGetCurrentContext() == glxContext) {
// if currently used, set to none // if currently used, set to none
glXMakeCurrent(XlibDisplay, None, NULL); // glXMakeCurrent(XlibDisplay, None, NULL);
// } // }
if (OSDcontext) { if (OSDcontext) {
glXDestroyContext(XlibDisplay, OSDcontext); glXDestroyContext(XlibDisplay, OSDcontext);
@@ -1444,27 +1444,31 @@ struct file {
}; };
typedef struct priv { typedef struct priv {
#if PL_API_VER >= 229
const struct pl_gpu_t *gpu;
const struct pl_vulkan_t *vk;
const struct pl_vk_inst_t *vk_inst;
#else
const struct pl_gpu *gpu; const struct pl_gpu *gpu;
const struct pl_vulkan *vk; const struct pl_vulkan *vk;
const struct pl_vk_inst *vk_inst; const struct pl_vk_inst *vk_inst;
struct pl_context *ctx;
#if PL_API_VER >= 113
struct pl_custom_lut *lut;
#endif #endif
struct pl_context *ctx;
struct pl_custom_lut *lut;
struct pl_renderer *renderer; struct pl_renderer *renderer;
struct pl_renderer *renderertest; struct pl_renderer *renderertest;
const struct pl_swapchain *swapchain; const struct pl_swapchain *swapchain;
struct pl_context_params context; struct pl_log_params context;
// struct pl_frame r_target;
// struct pl_render_params r_params;
// struct pl_tex final_fbo;
#ifndef PLACEBO_GL #ifndef PLACEBO_GL
VkSurfaceKHR pSurface; VkSurfaceKHR pSurface;
#endif #endif
// VkSemaphore sig_in;
int has_dma_buf; int has_dma_buf;
#ifdef PLACEBO_GL #ifdef PLACEBO_GL
#if PL_API_VER >= 229
struct pl_opengl_t *gl;
#else
struct pl_opengl *gl; struct pl_opengl *gl;
#endif
#endif #endif
const struct pl_hook *hook[NUM_SHADERS]; const struct pl_hook *hook[NUM_SHADERS];
int num_shaders; int num_shaders;
@@ -1473,6 +1477,9 @@ typedef struct priv {
static priv *p; static priv *p;
static struct pl_overlay osdoverlay; static struct pl_overlay osdoverlay;
#if PL_API_VER >= 229
static struct pl_overlay_part part;
#endif
static int semid; static int semid;
struct itimerval itimer; struct itimerval itimer;
@@ -1866,7 +1873,6 @@ static bool create_context_cb(EGLDisplay display, int es_version, EGLContext *ou
EGL_NONE}; EGL_NONE};
EGLint num_configs = 0; EGLint num_configs = 0;
#ifndef RASPI
attribs = attributes10; attribs = attributes10;
*bpp = 10; *bpp = 10;
if (!eglChooseConfig(display, attributes10, NULL, 0, if (!eglChooseConfig(display, attributes10, NULL, 0,
@@ -1879,9 +1885,7 @@ static bool create_context_cb(EGLDisplay display, int es_version, EGLContext *ou
&num_configs)) { // try 8 Bit &num_configs)) { // try 8 Bit
num_configs = 0; num_configs = 0;
} }
} else } else if (num_configs == 0) {
#endif
if (num_configs == 0) {
EglCheck(); EglCheck();
Debug(3, " 10 Bit egl Failed\n"); Debug(3, " 10 Bit egl Failed\n");
attribs = attributes8; attribs = attributes8;
@@ -2014,22 +2018,20 @@ static CuvidDecoder *CuvidNewHwDecoder(VideoStream *stream) {
Fatal("codec: can't allocate HW video codec context err %04x", i); Fatal("codec: can't allocate HW video codec context err %04x", i);
} }
#endif #endif
#if defined(VAAPI) && !defined(RASPI) #if defined(VAAPI)
// if ((i = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, // if ((i = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI,
// ":0.0" , NULL, 0)) != 0 ) { // ":0.0" , NULL, 0)) != 0 ) {
if ((i = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, "/dev/dri/renderD128", NULL, 0)) != 0) { if ((i = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, "/dev/dri/renderD128", NULL, 0)) != 0) {
Fatal("codec: can't allocate HW video codec context err %04x", i); Fatal("codec: can't allocate HW video codec context err %04x", i);
} }
#endif #endif
#ifndef RASPI
HwDeviceContext = av_buffer_ref(hw_device_ctx); HwDeviceContext = av_buffer_ref(hw_device_ctx);
#endif
if (!(decoder = calloc(1, sizeof(*decoder)))) { if (!(decoder = calloc(1, sizeof(*decoder)))) {
Error(_("video/cuvid: out of memory\n")); Error(_("video/cuvid: out of memory\n"));
return NULL; return NULL;
} }
#if defined(VAAPI) && !defined(RASPI) #if defined(VAAPI)
VaDisplay = TO_VAAPI_DEVICE_CTX(HwDeviceContext)->display; VaDisplay = TO_VAAPI_DEVICE_CTX(HwDeviceContext)->display;
decoder->VaDisplay = VaDisplay; decoder->VaDisplay = VaDisplay;
#endif #endif
@@ -2353,9 +2355,6 @@ void createTextureDst(CuvidDecoder *decoder, int anz, unsigned int size_x, unsig
img->repr.alpha = PL_ALPHA_UNKNOWN; img->repr.alpha = PL_ALPHA_UNKNOWN;
img->color.primaries = pl_color_primaries_guess(size_x, size_y); // Gammut overwritten later img->color.primaries = pl_color_primaries_guess(size_x, size_y); // Gammut overwritten later
img->color.transfer = PL_COLOR_TRC_BT_1886; // overwritten later img->color.transfer = PL_COLOR_TRC_BT_1886; // overwritten later
img->color.light = PL_COLOR_LIGHT_SCENE_709_1886; // needs config ???
img->color.sig_peak = 0.0f; // needs config ????
img->color.sig_avg = 0.0f;
img->num_overlays = 0; img->num_overlays = 0;
} }
NoContext; NoContext;
@@ -2381,13 +2380,19 @@ void generateVAAPIImage(CuvidDecoder *decoder, int index, const AVFrame *frame,
return; return;
} }
// vaSyncSurface(decoder->VaDisplay, (unsigned int)frame->data[3]); // vaSyncSurface(decoder->VaDisplay, (unsigned int)frame->data[3]);
Lock_and_SharedContext; Lock_and_SharedContext;
for (n = 0; n < 2; n++) { // Set DMA_BUF from VAAPI decoder to Textures for (n = 0; n < 2; n++) { // Set DMA_BUF from VAAPI decoder to Textures
int id = desc.layers[n].object_index[0]; int id = desc.layers[n].object_index[0];
int fd = desc.objects[id].fd; int fd = desc.objects[id].fd;
uint32_t size = desc.objects[id].size; uint32_t size = desc.objects[id].size;
uint32_t offset = desc.layers[n].offset[0]; uint32_t offset = desc.layers[n].offset[0];
#if PL_API_VER < 229
struct pl_fmt *fmt; struct pl_fmt *fmt;
#else
struct pl_fmt_t *fmt;
#endif
if (fd == -1) { if (fd == -1) {
printf("Fehler beim Import von Surface %d\n", index); printf("Fehler beim Import von Surface %d\n", index);
@@ -2450,7 +2455,9 @@ void generateVAAPIImage(CuvidDecoder *decoder, int index, const AVFrame *frame,
decoder->pl_frames[index].planes[n].texture = pl_tex_create(p->gpu, &tex_params); decoder->pl_frames[index].planes[n].texture = pl_tex_create(p->gpu, &tex_params);
} }
Unlock_and_NoContext; Unlock_and_NoContext;
} }
#endif #endif
@@ -2495,21 +2502,12 @@ void createTextureDst(CuvidDecoder *decoder, int anz, unsigned int size_x, unsig
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#ifdef RASPI
if (PixFmt == AV_PIX_FMT_NV12)
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, n == 0 ? size_x : size_x / 2, n == 0 ? size_y : size_y / 2, 0,
GL_RED, GL_UNSIGNED_BYTE, NULL);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, n == 0 ? size_x : size_x / 2, n == 0 ? size_y : size_y / 2, 0,
GL_RED, GL_UNSIGNED_SHORT, NULL);
#else
if (PixFmt == AV_PIX_FMT_NV12) if (PixFmt == AV_PIX_FMT_NV12)
glTexImage2D(GL_TEXTURE_2D, 0, n == 0 ? GL_R8 : GL_RG8, n == 0 ? size_x : size_x / 2, glTexImage2D(GL_TEXTURE_2D, 0, n == 0 ? GL_R8 : GL_RG8, n == 0 ? size_x : size_x / 2,
n == 0 ? size_y : size_y / 2, 0, n == 0 ? GL_RED : GL_RG, GL_UNSIGNED_BYTE, NULL); n == 0 ? size_y : size_y / 2, 0, n == 0 ? GL_RED : GL_RG, GL_UNSIGNED_BYTE, NULL);
else else
glTexImage2D(GL_TEXTURE_2D, 0, n == 0 ? GL_R16 : GL_RG16, n == 0 ? size_x : size_x / 2, glTexImage2D(GL_TEXTURE_2D, 0, n == 0 ? GL_R16 : GL_RG16, n == 0 ? size_x : size_x / 2,
n == 0 ? size_y : size_y / 2, 0, n == 0 ? GL_RED : GL_RG, GL_UNSIGNED_SHORT, NULL); n == 0 ? size_y : size_y / 2, 0, n == 0 ? GL_RED : GL_RG, GL_UNSIGNED_SHORT, NULL);
#endif
SDK_CHECK_ERROR_GL(); SDK_CHECK_ERROR_GL();
// register this texture with CUDA // register this texture with CUDA
#ifdef CUVID #ifdef CUVID
@@ -2522,6 +2520,7 @@ void createTextureDst(CuvidDecoder *decoder, int anz, unsigned int size_x, unsig
#endif #endif
} }
} }
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
GlxCheck(); GlxCheck();
#ifdef VAAPI #ifdef VAAPI
@@ -2542,11 +2541,23 @@ void createTextureDst(CuvidDecoder *decoder, int anz, unsigned int size_x, unsig
attribs[num_attribs] = EGL_NONE; \ attribs[num_attribs] = EGL_NONE; \
} while (0) } while (0)
#define ADD_PLANE_ATTRIBS(plane) \
do { \ #define ADD_DMABUF_PLANE_ATTRIBS(plane, fd, offset, stride) \
ADD_ATTRIB(EGL_DMA_BUF_PLANE##plane##_FD_EXT, desc.objects[desc.layers[n].object_index[plane]].fd); \ do { \
ADD_ATTRIB(EGL_DMA_BUF_PLANE##plane##_OFFSET_EXT, desc.layers[n].offset[plane]); \ ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _FD_EXT, \
ADD_ATTRIB(EGL_DMA_BUF_PLANE##plane##_PITCH_EXT, desc.layers[n].pitch[plane]); \ fd); \
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _OFFSET_EXT, \
offset); \
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _PITCH_EXT, \
stride); \
} while (0)
#define ADD_DMABUF_PLANE_MODIFIERS(plane, mod) \
do { \
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _MODIFIER_LO_EXT, \
(uint32_t) ((mod) & 0xFFFFFFFFlu)); \
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _MODIFIER_HI_EXT, \
(uint32_t) (((mod) >> 32u) & 0xFFFFFFFFlu)); \
} while (0) } while (0)
void generateVAAPIImage(CuvidDecoder *decoder, VASurfaceID index, const AVFrame *frame, int image_width, void generateVAAPIImage(CuvidDecoder *decoder, VASurfaceID index, const AVFrame *frame, int image_width,
@@ -2555,7 +2566,7 @@ void generateVAAPIImage(CuvidDecoder *decoder, VASurfaceID index, const AVFrame
uint64_t first_time; uint64_t first_time;
#if defined(VAAPI) && !defined(RASPI) #if defined(VAAPI)
VADRMPRIMESurfaceDescriptor desc; VADRMPRIMESurfaceDescriptor desc;
vaSyncSurface(decoder->VaDisplay, (VASurfaceID)(uintptr_t)frame->data[3]); vaSyncSurface(decoder->VaDisplay, (VASurfaceID)(uintptr_t)frame->data[3]);
@@ -2570,26 +2581,26 @@ void generateVAAPIImage(CuvidDecoder *decoder, VASurfaceID index, const AVFrame
// vaSyncSurface(decoder->VaDisplay, (VASurfaceID) (uintptr_t) // vaSyncSurface(decoder->VaDisplay, (VASurfaceID) (uintptr_t)
// frame->data[3]); // frame->data[3]);
#endif #endif
#ifdef RASPI pthread_mutex_lock(&OSDMutex);
AVDRMFrameDescriptor desc;
memcpy(&desc, frame->data[0], sizeof(desc));
#endif
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext); eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext);
EglCheck(); EglCheck();
for (int n = 0; n < Planes; n++) { for (int n = 0; n < Planes; n++) {
int attribs[20] = {EGL_NONE}; int attribs[20] = {EGL_NONE};
uint num_attribs = 0; uint num_attribs = 0;
int fd; int id = desc.layers[n].object_index[0];
int fd = desc.objects[id].fd;
#if defined(VAAPI) && !defined(RASPI) #if defined(VAAPI)
ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, desc.layers[n].drm_format); //Debug(3,"Plane %d w %d h %d layers %d planes %d pitch %d format %04x\n",n,image_width,image_height,desc.num_layers,desc.layers[n].num_planes,desc.layers[n].pitch[0],desc.layers[n].drm_format);
ADD_ATTRIB(EGL_WIDTH, n == 0 ? image_width : image_width / 2); ADD_ATTRIB(EGL_WIDTH, n == 0 ? image_width : image_width / 2);
ADD_ATTRIB(EGL_HEIGHT, n == 0 ? image_height : image_height / 2); ADD_ATTRIB(EGL_HEIGHT, n == 0 ? image_height : image_height / 2);
ADD_PLANE_ATTRIBS(0); ADD_DMABUF_PLANE_MODIFIERS(0, desc.objects[id].drm_format_modifier);
ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, desc.layers[n].drm_format);
ADD_DMABUF_PLANE_ATTRIBS(0, fd, desc.layers[n].offset[0],desc.layers[n].pitch[0]);
#endif #endif
decoder->images[index * Planes + n] = decoder->images[index * Planes + n] =
@@ -2606,6 +2617,7 @@ void generateVAAPIImage(CuvidDecoder *decoder, VASurfaceID index, const AVFrame
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
EglCheck(); EglCheck();
pthread_mutex_unlock(&OSDMutex);
return; return;
esh_failed: esh_failed:
@@ -2614,6 +2626,7 @@ esh_failed:
close(desc.objects[n].fd); close(desc.objects[n].fd);
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
EglCheck(); EglCheck();
pthread_mutex_unlock(&OSDMutex);
} }
#endif #endif
#endif #endif
@@ -3060,18 +3073,10 @@ int get_RGB(CuvidDecoder *decoder) {
glUniform1i(texLoc, 0); glUniform1i(texLoc, 0);
texLoc = glGetUniformLocation(gl_prog, "texture1"); texLoc = glGetUniformLocation(gl_prog, "texture1");
glUniform1i(texLoc, 1); glUniform1i(texLoc, 1);
#ifdef RASPI
texLoc = glGetUniformLocation(gl_prog, "texture2");
glUniform1i(texLoc, 2);
#endif
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 0]); glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 0]);
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 1]); glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 1]);
#ifdef RASPI
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 2]);
#endif
glBindFramebuffer(GL_FRAMEBUFFER, fb); glBindFramebuffer(GL_FRAMEBUFFER, fb);
render_pass_quad(1, 0.0, 0.0); render_pass_quad(1, 0.0, 0.0);
@@ -3124,7 +3129,7 @@ int get_RGB(CuvidDecoder *decoder) {
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
} }
glFlush(); glFlush();
//Debug(3, "Read pixels %d %d\n", width, height); // Debug(3, "Read pixels %d %d\n", width, height);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
@@ -3183,13 +3188,11 @@ int get_RGB(CuvidDecoder *decoder) {
target.repr.bits.bit_shift = 0; target.repr.bits.bit_shift = 0;
target.color.primaries = PL_COLOR_PRIM_BT_709; target.color.primaries = PL_COLOR_PRIM_BT_709;
target.color.transfer = PL_COLOR_TRC_BT_1886; target.color.transfer = PL_COLOR_TRC_BT_1886;
target.color.light = PL_COLOR_LIGHT_DISPLAY;
target.color.sig_peak = 0;
target.color.sig_avg = 0;
if (ovl) { if (ovl) {
target.overlays = ovl; target.overlays = ovl;
target.num_overlays = 1; target.num_overlays = 1;
#if PL_API_VER < 229
#ifdef PLACEBO_GL #ifdef PLACEBO_GL
x0 = ovl->rect.x0; x0 = ovl->rect.x0;
y1 = ovl->rect.y0; y1 = ovl->rect.y0;
@@ -3209,6 +3212,28 @@ int get_RGB(CuvidDecoder *decoder) {
ovl->rect.x1 = (float)x1 * faktorx; ovl->rect.x1 = (float)x1 * faktorx;
ovl->rect.y1 = (float)y1 * faktory; ovl->rect.y1 = (float)y1 * faktory;
#endif #endif
#else
#ifdef PLACEBO_GL
x0 = part.dst.x0;
y1 = part.dst.y0;
x1 = part.dst.x1;
y0 = part.dst.y1;
part.dst.x0 = (float)x0 * faktorx;
part.dst.y0 = (float)y0 * faktory;
part.dst.x1 = (float)x1 * faktorx;
part.dst.y1 = (float)y1 * faktory;
#else
x0 = part.dst.x0;
y0 = part.dst.y0;
x1 = part.dst.x1;
y1 = part.dst.y1;
part.dst.x0 = (float)x0 * faktorx;
part.dst.y0 = (float)y0 * faktory;
part.dst.x1 = (float)x1 * faktorx;
part.dst.y1 = (float)y1 * faktory;
#endif
#endif
} else { } else {
target.overlays = 0; target.overlays = 0;
@@ -3222,6 +3247,7 @@ int get_RGB(CuvidDecoder *decoder) {
pl_gpu_finish(p->gpu); pl_gpu_finish(p->gpu);
if (ovl) { if (ovl) {
#if PL_API_VER < 229
#ifdef PLACEBO_GL #ifdef PLACEBO_GL
ovl->rect.x0 = x0; ovl->rect.x0 = x0;
ovl->rect.y0 = y1; ovl->rect.y0 = y1;
@@ -3232,6 +3258,19 @@ int get_RGB(CuvidDecoder *decoder) {
ovl->rect.y0 = y0; ovl->rect.y0 = y0;
ovl->rect.x1 = x1; ovl->rect.x1 = x1;
ovl->rect.y1 = y1; ovl->rect.y1 = y1;
#endif
#else
#ifdef PLACEBO_GL
part.dst.x0 = x0;
part.dst.y0 = y1;
part.dst.x1 = x1;
part.dst.y1 = y0;
#else
part.dst.x0 = x0;
part.dst.y0 = y0;
part.dst.x1 = x1;
part.dst.y1 = y1;
#endif
#endif #endif
} }
@@ -3499,37 +3538,14 @@ static void CuvidRenderFrame(CuvidDecoder *decoder, const AVCodecContext *video_
if (frame->color_trc == AVCOL_TRC_RESERVED0) // cuvid decoder failure with SD channels if (frame->color_trc == AVCOL_TRC_RESERVED0) // cuvid decoder failure with SD channels
frame->color_trc = AVCOL_TRC_SMPTE170M; frame->color_trc = AVCOL_TRC_SMPTE170M;
// printf("Patched colorspace %d Primaries %d TRC // printf("Patched colorspace %d Primaries %d TRC
// %d\n",frame->colorspace,frame->color_primaries,frame->color_trc); // %d\n",frame->colorspace,frame->color_primaries,frame->color_trc);
#ifdef RASPI
//
// Check image, format, size
//
if ( // decoder->PixFmt != video_ctx->pix_fmt
video_ctx->width != decoder->InputWidth
// || decoder->ColorSpace != color
|| video_ctx->height != decoder->InputHeight) {
Debug(3, "fmt %02d:%02d width %d:%d hight %d:%d\n", decoder->ColorSpace, frame->colorspace, video_ctx->width,
decoder->InputWidth, video_ctx->height, decoder->InputHeight);
decoder->PixFmt = AV_PIX_FMT_NV12;
decoder->InputWidth = video_ctx->width;
decoder->InputHeight = video_ctx->height;
CuvidCleanup(decoder);
decoder->SurfacesNeeded = VIDEO_SURFACES_MAX + 1;
CuvidSetupOutput(decoder);
}
#endif
// //
// Copy data from frame to image // Copy data from frame to image
// //
#ifdef RASPI
if (video_ctx->pix_fmt == 0) {
#else
if (video_ctx->pix_fmt == PIXEL_FORMAT) { if (video_ctx->pix_fmt == PIXEL_FORMAT) {
#endif
int w = decoder->InputWidth; int w = decoder->InputWidth;
int h = decoder->InputHeight; int h = decoder->InputHeight;
decoder->ColorSpace = color; // save colorspace decoder->ColorSpace = color; // save colorspace
decoder->trc = frame->color_trc; decoder->trc = frame->color_trc;
decoder->color_primaries = frame->color_primaries; decoder->color_primaries = frame->color_primaries;
@@ -3557,8 +3573,13 @@ static void CuvidRenderFrame(CuvidDecoder *decoder, const AVCodecContext *video_
// %p\n",surface,decoder->pl_frames[surface].planes[0].texture,decoder->pl_frames[surface].planes[1].texture); // %p\n",surface,decoder->pl_frames[surface].planes[0].texture,decoder->pl_frames[surface].planes[1].texture);
bool ok = pl_tex_upload(p->gpu, &(struct pl_tex_transfer_params){ bool ok = pl_tex_upload(p->gpu, &(struct pl_tex_transfer_params){
.tex = decoder->pl_frames[surface].planes[0].texture, .tex = decoder->pl_frames[surface].planes[0].texture,
#if PL_API_VER < 292
.stride_w = output->linesize[0], .stride_w = output->linesize[0],
.stride_h = h, .stride_h = h,
#else
.row_pitch = output->linesize[0],
.depth_pitch = h,
#endif
.ptr = output->data[0], .ptr = output->data[0],
.rc.x1 = w, .rc.x1 = w,
.rc.y1 = h, .rc.y1 = h,
@@ -3566,8 +3587,13 @@ static void CuvidRenderFrame(CuvidDecoder *decoder, const AVCodecContext *video_
}); });
ok &= pl_tex_upload(p->gpu, &(struct pl_tex_transfer_params){ ok &= pl_tex_upload(p->gpu, &(struct pl_tex_transfer_params){
.tex = decoder->pl_frames[surface].planes[1].texture, .tex = decoder->pl_frames[surface].planes[1].texture,
#if PL_API_VER < 292
.stride_w = output->linesize[0] / 2, .stride_w = output->linesize[0] / 2,
.stride_h = h / 2, .stride_h = h / 2,
#else
.row_pitch = output->linesize[0] / 2,
.depth_pitch = h,
#endif
.ptr = output->data[1], .ptr = output->data[1],
.rc.x1 = w / 2, .rc.x1 = w / 2,
.rc.y1 = h / 2, .rc.y1 = h / 2,
@@ -3750,7 +3776,6 @@ static void CuvidMixVideo(CuvidDecoder *decoder, __attribute__((unused)) int lev
struct pl_cone_params cone; struct pl_cone_params cone;
struct pl_tex_vk *vkp; struct pl_tex_vk *vkp;
struct pl_plane *pl; struct pl_plane *pl;
const struct pl_fmt *fmt;
struct pl_tex *tex0, *tex1; struct pl_tex *tex0, *tex1;
struct pl_frame *img; struct pl_frame *img;
@@ -3821,19 +3846,11 @@ static void CuvidMixVideo(CuvidDecoder *decoder, __attribute__((unused)) int lev
glUniform1i(texLoc, 0); glUniform1i(texLoc, 0);
texLoc = glGetUniformLocation(gl_prog, "texture1"); texLoc = glGetUniformLocation(gl_prog, "texture1");
glUniform1i(texLoc, 1); glUniform1i(texLoc, 1);
#ifdef RASPI
texLoc = glGetUniformLocation(gl_prog, "texture2");
glUniform1i(texLoc, 2);
#endif
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 0]); glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 0]);
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 1]); glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 1]);
#ifdef RASPI
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 2]);
#endif
render_pass_quad(0, xcropf, ycropf); render_pass_quad(0, xcropf, ycropf);
@@ -3848,6 +3865,12 @@ static void CuvidMixVideo(CuvidDecoder *decoder, __attribute__((unused)) int lev
memcpy(&render_params, &pl_render_default_params, sizeof(render_params)); memcpy(&render_params, &pl_render_default_params, sizeof(render_params));
render_params.deband_params = &deband; render_params.deband_params = &deband;
// provide LUT Table
if (LUTon)
render_params.lut = p->lut;
else
render_params.lut = NULL;
frame = decoder->frames[current]; frame = decoder->frames[current];
// Fix Color Parameters // Fix Color Parameters
@@ -3858,7 +3881,6 @@ static void CuvidMixVideo(CuvidDecoder *decoder, __attribute__((unused)) int lev
memcpy(&img->repr, &pl_color_repr_sdtv, sizeof(struct pl_color_repr)); memcpy(&img->repr, &pl_color_repr_sdtv, sizeof(struct pl_color_repr));
img->color.primaries = PL_COLOR_PRIM_BT_601_625; img->color.primaries = PL_COLOR_PRIM_BT_601_625;
img->color.transfer = PL_COLOR_TRC_BT_1886; img->color.transfer = PL_COLOR_TRC_BT_1886;
img->color.light = PL_COLOR_LIGHT_DISPLAY;
pl->shift_x = 0.0f; pl->shift_x = 0.0f;
break; break;
case AVCOL_SPC_BT709: case AVCOL_SPC_BT709:
@@ -3872,9 +3894,10 @@ static void CuvidMixVideo(CuvidDecoder *decoder, __attribute__((unused)) int lev
memcpy(&img->repr, &pl_color_repr_uhdtv, sizeof(struct pl_color_repr)); 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)); memcpy(&img->color, &pl_color_space_bt2020_hlg, sizeof(struct pl_color_space));
deband.grain = 0.0f; // no grain in HDR deband.grain = 0.0f; // no grain in HDR
img->color.sig_scale = 1.0f;
pl->shift_x = -0.5f; pl->shift_x = -0.5f;
// Kein LUT bei HDR
render_params.lut = NULL;
#if 0
if ((sd = av_frame_get_side_data(frame, AV_FRAME_DATA_ICC_PROFILE))) { if ((sd = av_frame_get_side_data(frame, AV_FRAME_DATA_ICC_PROFILE))) {
img->profile = (struct pl_icc_profile){ img->profile = (struct pl_icc_profile){
.data = sd->data, .data = sd->data,
@@ -3903,13 +3926,14 @@ static void CuvidMixVideo(CuvidDecoder *decoder, __attribute__((unused)) int lev
// Make sure this value is more or less legal // Make sure this value is more or less legal
if (img->color.sig_peak < 1.0 || img->color.sig_peak > 50.0) if (img->color.sig_peak < 1.0 || img->color.sig_peak > 50.0)
img->color.sig_peak = 0.0; img->color.sig_peak = 0.0;
#endif
#if defined VAAPI || defined USE_DRM #if defined VAAPI || defined USE_DRM
render_params.peak_detect_params = NULL; render_params.peak_detect_params = NULL;
render_params.deband_params = NULL; render_params.deband_params = NULL;
render_params.dither_params = NULL; render_params.dither_params = NULL;
render_params.skip_anti_aliasing = true; render_params.skip_anti_aliasing = true;
#endif #endif
break; break;
default: // fallback default: // fallback
@@ -3943,7 +3967,6 @@ static void CuvidMixVideo(CuvidDecoder *decoder, __attribute__((unused)) int lev
if (decoder->ColorSpace == AVCOL_SPC_BT470BG) { if (decoder->ColorSpace == AVCOL_SPC_BT470BG) {
target->color.primaries = PL_COLOR_PRIM_BT_601_625; target->color.primaries = PL_COLOR_PRIM_BT_601_625;
target->color.transfer = PL_COLOR_TRC_BT_1886; target->color.transfer = PL_COLOR_TRC_BT_1886;
target->color.light = PL_COLOR_LIGHT_DISPLAY;
} else { } else {
memcpy(&target->color, &pl_color_space_bt709, sizeof(struct pl_color_space)); memcpy(&target->color, &pl_color_space_bt709, sizeof(struct pl_color_space));
} }
@@ -3955,7 +3978,6 @@ static void CuvidMixVideo(CuvidDecoder *decoder, __attribute__((unused)) int lev
} else if (decoder->ColorSpace == AVCOL_SPC_BT470BG) { } else if (decoder->ColorSpace == AVCOL_SPC_BT470BG) {
target->color.primaries = PL_COLOR_PRIM_BT_601_625; target->color.primaries = PL_COLOR_PRIM_BT_601_625;
target->color.transfer = PL_COLOR_TRC_BT_1886; target->color.transfer = PL_COLOR_TRC_BT_1886;
target->color.light = PL_COLOR_LIGHT_DISPLAY;
; ;
} else { } else {
memcpy(&target->color, &pl_color_space_bt709, sizeof(struct pl_color_space)); memcpy(&target->color, &pl_color_space_bt709, sizeof(struct pl_color_space));
@@ -3983,8 +4005,6 @@ static void CuvidMixVideo(CuvidDecoder *decoder, __attribute__((unused)) int lev
} }
#endif #endif
// printf("sys %d prim %d trc %d light
// %d\n",img->repr.sys,img->color.primaries,img->color.transfer,img->color.light);
// Source crop // Source crop
if (VideoScalerTest) { // right side defined scaler if (VideoScalerTest) { // right side defined scaler
@@ -4108,13 +4128,9 @@ static void CuvidMixVideo(CuvidDecoder *decoder, __attribute__((unused)) int lev
render_params.num_hooks = p->num_shaders; render_params.num_hooks = p->num_shaders;
} }
#endif #endif
#if PL_API_VER >= 113
// provide LUT Table
if (LUTon)
render_params.lut = p->lut;
else
render_params.lut = NULL;
#endif
if (decoder->newchannel && current == 0) { if (decoder->newchannel && current == 0) {
colors.brightness = -1.0f; colors.brightness = -1.0f;
@@ -4185,11 +4201,16 @@ void make_osd_overlay(int x, int y, int width, int height) {
pl = &osdoverlay; pl = &osdoverlay;
#if PL_API_VER < 229
if (pl->plane.texture && (pl->plane.texture->params.w != width || pl->plane.texture->params.h != height)) { if (pl->plane.texture && (pl->plane.texture->params.w != width || pl->plane.texture->params.h != height)) {
// pl_tex_clear(p->gpu, pl->plane.texture, (float[4]) { 0 });
pl_tex_destroy(p->gpu, &pl->plane.texture); pl_tex_destroy(p->gpu, &pl->plane.texture);
#else
if (pl->tex && (pl->tex->params.w != width || pl->tex->params.h != height)) {
pl_tex_destroy(p->gpu, &pl->tex);
#endif
} }
#if PL_API_VER < 229
// make texture for OSD // make texture for OSD
if (pl->plane.texture == NULL) { if (pl->plane.texture == NULL) {
pl->plane.texture = pl_tex_create( pl->plane.texture = pl_tex_create(
@@ -4210,12 +4231,29 @@ void make_osd_overlay(int x, int y, int width, int height) {
pl->plane.component_mapping[1] = PL_CHANNEL_G; pl->plane.component_mapping[1] = PL_CHANNEL_G;
pl->plane.component_mapping[2] = PL_CHANNEL_B; pl->plane.component_mapping[2] = PL_CHANNEL_B;
pl->plane.component_mapping[3] = PL_CHANNEL_A; pl->plane.component_mapping[3] = PL_CHANNEL_A;
#else
// make texture for OSD
if (pl->tex == NULL) {
pl->tex = pl_tex_create(
p->gpu, &(struct pl_tex_params) {
.w = width, .h = height, .d = 0, .format = fmt, .sampleable = true, .host_writable = true,
.blit_dst = true,
});
}
// make overlay
pl_tex_clear(p->gpu, pl->tex, (float[4]){0});
part.src.x0 = 0.0f;
part.src.y0 = 0.0f;
part.src.x1 = width;
part.src.y1 = height;
#endif
pl->mode = PL_OVERLAY_NORMAL; pl->mode = PL_OVERLAY_NORMAL;
pl->repr.sys = PL_COLOR_SYSTEM_RGB; pl->repr.sys = PL_COLOR_SYSTEM_RGB;
pl->repr.levels = PL_COLOR_LEVELS_PC; pl->repr.levels = PL_COLOR_LEVELS_PC;
pl->repr.alpha = PL_ALPHA_INDEPENDENT; pl->repr.alpha = PL_ALPHA_INDEPENDENT;
memcpy(&osdoverlay.color, &pl_color_space_srgb, sizeof(struct pl_color_space)); memcpy(&osdoverlay.color, &pl_color_space_srgb, sizeof(struct pl_color_space));
#if PL_API_VER < 229
#ifdef PLACEBO_GL #ifdef PLACEBO_GL
pl->rect.x0 = x; pl->rect.x0 = x;
pl->rect.y1 = VideoWindowHeight - y; // Boden von oben pl->rect.y1 = VideoWindowHeight - y; // Boden von oben
@@ -4228,6 +4266,21 @@ void make_osd_overlay(int x, int y, int width, int height) {
pl->rect.x1 = x + width; pl->rect.x1 = x + width;
pl->rect.y1 = VideoWindowHeight - height - y + offset; pl->rect.y1 = VideoWindowHeight - height - y + offset;
#endif #endif
#else
osdoverlay.parts = &part;
osdoverlay.num_parts = 1;
#ifdef PLACEBO_GL
part.dst.x0 = x;
part.dst.y1 = VideoWindowHeight - y; // Boden von oben
part.dst.x1 = x + width;
part.dst.y0 = VideoWindowHeight - height - y;
#else
part.dst.x0 = x;
part.dst.y0 = VideoWindowHeight - y + offset; // Boden von oben
part.dst.x1 = x + width;
part.dst.y1 = VideoWindowHeight - height - y + offset;
#endif
#endif
} }
#endif #endif
/// ///
@@ -4271,12 +4324,12 @@ static void CuvidDisplayFrame(void) {
#else #else
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglThreadContext); eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglThreadContext);
EglCheck(); EglCheck();
#ifndef USE_DRM #ifndef USE_DRM
usleep(5000); usleep(5000);
#endif #endif
#endif #endif
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
#else // PLACEBO #else // PLACEBO
@@ -4366,18 +4419,23 @@ static void CuvidDisplayFrame(void) {
} }
valid_frame = 1; valid_frame = 1;
#ifdef PLACEBO #ifdef PLACEBO
//pthread_mutex_lock(&OSDMutex);
if (OsdShown == 1) { // New OSD opened if (OsdShown == 1) { // New OSD opened
pthread_mutex_lock(&OSDMutex);
make_osd_overlay(OSDx, OSDy, OSDxsize, OSDysize); make_osd_overlay(OSDx, OSDy, OSDxsize, OSDysize);
if (posd) { if (posd) {
pl_tex_upload(p->gpu, &(struct pl_tex_transfer_params){ pl_tex_upload(p->gpu, &(struct pl_tex_transfer_params){
// upload OSD // upload OSD
#if PL_API_VER >= 229
.tex = osdoverlay.tex,
#else
.tex = osdoverlay.plane.texture, .tex = osdoverlay.plane.texture,
#endif
.ptr = posd, .ptr = posd,
}); });
} }
OsdShown = 2; OsdShown = 2;
pthread_mutex_unlock(&OSDMutex);
} }
if (OsdShown == 2) { if (OsdShown == 2) {
@@ -4385,7 +4443,7 @@ static void CuvidDisplayFrame(void) {
} else { } else {
CuvidMixVideo(decoder, i, &target, NULL); CuvidMixVideo(decoder, i, &target, NULL);
} }
//pthread_mutex_unlock(&OSDMutex);
#else #else
CuvidMixVideo(decoder, i); CuvidMixVideo(decoder, i);
#endif #endif
@@ -4467,10 +4525,15 @@ static void CuvidDisplayFrame(void) {
#if defined PLACEBO // && !defined PLACEBO_GL #if defined PLACEBO // && !defined PLACEBO_GL
// first_time = GetusTicks(); // first_time = GetusTicks();
if (!pl_swapchain_submit_frame(p->swapchain)) if (!pl_swapchain_submit_frame(p->swapchain))
Fatal(_("Failed to submit swapchain buffer\n")); Fatal(_("Failed to submit swapchain buffer\n"));
pl_swapchain_swap_buffers(p->swapchain); // swap buffers
NoContext;
VideoThreadUnlock(); VideoThreadUnlock();
pl_swapchain_swap_buffers(p->swapchain); // swap buffers
#ifdef PLACEBO_GL
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
EglCheck();
#endif
#else // not PLACEBO #else // not PLACEBO
#ifdef CUVID #ifdef CUVID
glXGetVideoSyncSGI(&Count); // get current frame glXGetVideoSyncSGI(&Count); // get current frame
@@ -5517,7 +5580,7 @@ void InitPlacebo() {
p->context.log_cb = &pl_log_intern; p->context.log_cb = &pl_log_intern;
p->context.log_level = PL_LOG_WARN; // WARN p->context.log_level = PL_LOG_WARN; // WARN
p->ctx = pl_context_create(PL_API_VER, &p->context); p->ctx = pl_log_create(PL_API_VER, &p->context);
if (!p->ctx) { if (!p->ctx) {
Fatal(_("Failed initializing libplacebo\n")); Fatal(_("Failed initializing libplacebo\n"));
} }
@@ -5595,7 +5658,9 @@ void InitPlacebo() {
.surface = p->pSurface, .surface = p->pSurface,
.present_mode = VK_PRESENT_MODE_FIFO_KHR, .present_mode = VK_PRESENT_MODE_FIFO_KHR,
.swapchain_depth = SWAP_BUFFER_SIZE, .swapchain_depth = SWAP_BUFFER_SIZE,
#if PL_API_VER < 229
.prefer_hdr = true, .prefer_hdr = true,
#endif
}); });
#endif #endif
@@ -5677,8 +5742,13 @@ void exit_display() {
return; return;
} }
pl_gpu_finish(p->gpu); pl_gpu_finish(p->gpu);
#if PL_API_VER >= 229
if (osdoverlay.tex)
pl_tex_destroy(p->gpu, &osdoverlay.tex);
#else
if (osdoverlay.plane.texture) if (osdoverlay.plane.texture)
pl_tex_destroy(p->gpu, &osdoverlay.plane.texture); pl_tex_destroy(p->gpu, &osdoverlay.plane.texture);
#endif
// pl_renderer_destroy(&p->renderer); // pl_renderer_destroy(&p->renderer);
if (p->renderertest) { if (p->renderertest) {
@@ -5696,7 +5766,7 @@ void exit_display() {
pl_vk_inst_destroy(&p->vk_inst); pl_vk_inst_destroy(&p->vk_inst);
#endif #endif
pl_context_destroy(&p->ctx); pl_log_destroy(&p->ctx);
#if PL_API_VER >= 113 #if PL_API_VER >= 113
pl_lut_free(&p->lut); pl_lut_free(&p->lut);
#endif #endif
@@ -7022,14 +7092,13 @@ void VideoInit(const char *display_name) {
if (!display_name && !(display_name = getenv("DISPLAY"))) { if (!display_name && !(display_name = getenv("DISPLAY"))) {
// if no environment variable, use :0.0 as default display name // if no environment variable, use :0.0 as default display name
display_name = ":0.0"; display_name = ":0.0";
} }
if (!getenv("DISPLAY")) { if (!getenv("DISPLAY")) {
//force set DISPLAY environment variable, otherwise nvidia driver // force set DISPLAY environment variable, otherwise nvidia driver
//has problems at libplace-swapchain-init // has problems at libplace-swapchain-init
Debug(3, "video: setting ENV DISPLAY=%s\n",display_name); Debug(3, "video: setting ENV DISPLAY=%s\n", display_name);
setenv("DISPLAY",display_name,0); setenv("DISPLAY", display_name, 0);
//Debug(3, "video: ENV:(%s)\n",getenv("DISPLAY")); // Debug(3, "video: ENV:(%s)\n",getenv("DISPLAY"));
} }
if (!(XlibDisplay = XOpenDisplay(display_name))) { if (!(XlibDisplay = XOpenDisplay(display_name))) {
@@ -7212,16 +7281,16 @@ int GlxInitopengl() {
if (!eglOSDContext) { if (!eglOSDContext) {
EglCheck(); EglCheck();
Fatal(_("video/egl: can't create thread egl context\n")); Fatal(_("video/egl: can't create thread egl context\n"));
return NULL; return 1;
} }
} }
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglOSDContext); eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglOSDContext);
return; return 0;
} }
int GlxDrawopengl() { int GlxDrawopengl() {
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext); eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext);
return; return 0;
} }
void GlxDestroy() { void GlxDestroy() {