diff --git a/Makefile b/Makefile index 8b62f8c..5fffe76 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # # Makefile for a Video Disk Recorder plugin -# +# # $Id: 2a41981a57e5e83036463c6a08c84b86ed9d2be3 $ # The official name of this plugin. @@ -11,7 +11,7 @@ ### Configuration (edit this for your needs) # config as needed -# what kind of decoder do we make - +# what kind of decoder do we make - # if VAAPI is enabled the pluginname is softhdvaapi # if CUVID is enabled the pluginname is softhdcuvid # if DRM is enabled the pluginname is softhddrm @@ -19,12 +19,12 @@ VAAPI ?= 0 CUVID ?= 0 # if you enable DRM then the plugin will only run without X server -# only valid for VAAPI +# only valid for VAAPI # does not work with libplacebo DRM ?= 0 -# use libplacebo - available for both decoders but not for DRM +# use libplacebo - available for both decoders but not for DRM LIBPLACEBO ?= 1 # use YADIF deint - only available with cuvid @@ -124,7 +124,7 @@ TMPDIR ?= /tmp ### The compiler options: -export CFLAGS = $(call PKGCFG,cflags) +export CFLAGS = $(call PKGCFG,cflags) export CXXFLAGS = $(call PKGCFG,cxxflags) ifeq ($(CFLAGS),) @@ -146,10 +146,10 @@ APIVERSION = $(call PKGCFG,apiversion) ### Parse config ifeq ($(VAAPI),1) -CONFIG += -DVAAPI +CONFIG += -DVAAPI #LIBPLACEBO=1 PLUGIN = softhdvaapi -LIBS += -lEGL +LIBS += -lEGL endif @@ -159,13 +159,13 @@ CONFIG += -DUSE_DRM -DVAAPI LIBPLACEBO=0 _CFLAGS += $(shell pkg-config --cflags libdrm) LIBS += -lgbm -ldrm -LIBS += -lEGL +LIBS += -lEGL endif ifeq ($(CUVID),1) CONFIG += -DUSE_PIP # PIP support CONFIG += -DCUVID # enable CUVID decoder -LIBS += -lEGL -lGL +LIBS += -lEGL -lGL ifeq ($(YADIF),1) CONFIG += -DYADIF # Yadif only with CUVID endif @@ -213,7 +213,7 @@ SOFILE = libvdr-$(PLUGIN).so # -# Test that libswresample is available +# Test that libswresample is available # #ifneq (exists, $(shell pkg-config libswresample && echo exists)) # $(warning ******************************************************************) @@ -222,7 +222,7 @@ SOFILE = libvdr-$(PLUGIN).so #endif # -# Test and set config for libavutil +# Test and set config for libavutil # ifneq (exists, $(shell pkg-config libavutil && echo exists)) $(warning ******************************************************************) @@ -233,7 +233,7 @@ _CFLAGS += $(shell pkg-config --cflags libavutil) LIBS += $(shell pkg-config --libs libavutil) # -# Test and set config for libswscale +# Test and set config for libswscale # ifneq (exists, $(shell pkg-config libswscale && echo exists)) $(warning ******************************************************************) @@ -281,14 +281,14 @@ _CFLAGS += -I./opengl -I./ LIBS += -L/usr/lib64 ifeq ($(LIBPLACEBO),1) -LIBS += -lplacebo +LIBS += -lplacebo endif ifeq ($(CUVID),1) -LIBS += -lcuda -lnvcuvid +LIBS += -lcuda -lnvcuvid endif -LIBS += -lGLEW -lGLU -ldl -lglut +LIBS += -lGLEW -lGLU -ldl -lglut ### Includes and Defines (add further entries here): INCLUDES += @@ -299,16 +299,16 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -D_GNU_SOURCE $(CONFIG) \ ### Make it standard override CXXFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \ - -g -W -Wextra -Winit-self -Werror=overloaded-virtual -Wno-unused-parameter + -g -W -Wextra -Winit-self -Werror=overloaded-virtual -Wno-unused-parameter override CFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \ -g -W -Wextra -Winit-self -Wdeclaration-after-statement ### The object files (add further files here): -OBJS = softhdcuvid.o softhddev.o video.o audio.o codec.o ringbuffer.o +OBJS = softhdcuvid.o softhddev.o video.o audio.o codec.o ringbuffer.o ifeq ($(OPENGLOSD),1) -OBJS += openglosd.o +OBJS += openglosd.o endif SRCS = $(wildcard $(OBJS:.o=.c)) *.cpp @@ -385,9 +385,7 @@ HDRS= $(wildcard *.h) indent: for i in $(SRCS) $(HDRS); do \ - indent $$i; \ - unexpand -a $$i | sed -e s/constconst/const/ > $$i.up; \ - mv $$i.up $$i; \ + VERSION_CONTROL=none indent $$i; \ done video_test: video.c Makefile diff --git a/README.md b/README.md index 3c10961..69f2b3e 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Only via DisplayPort you can get 10 Bit output to a compatible screen. This is a Current Status with VAAPI: I tested it with Intel VAAPI. If you have problmes with the shaders then copy the drirc file in your home directory as .drirc -AMD VAAPI is broken by AMD and will not work currently. +AMD VAAPI is broken by AMD and will not work currently. You have to adapt the Makefile to your needs. I use FFMPEG 4.0 The Makefile expects the CUDA SDK in /usr/local/cuda. Currently it is tested with CUDA 10 @@ -73,13 +73,13 @@ Quickstart: You have to adapt the Makefile. There are 3 possible Version that you can build: softhdcuvid - This is for NVIDA cards and uses cuvid as decoder. It uses xcb for output and needs a X Server to run. - + This is for NVIDA cards and uses cuvid as decoder. It uses xcb for output and needs a X Server to run. + softhdvaapi This is for INTEL cards and uses Vaapi as decoder. It uses xcb for output and needs a X Server to run. - + softhddrm - This is for INTEL cards and also uses Vaapi as decoder. It uses the DRM API for output and + This is for INTEL cards and also uses Vaapi as decoder. It uses the DRM API for output and runs without X Server. There are several commandline options to select the resolution and refresh rate. Install: @@ -98,27 +98,27 @@ Install: Beginners Guide for libplacebo: ------------------------------- - When using libplacebo you will find several config options. - + When using libplacebo you will find several config options. + First of all you need to set the right scaler for each resolution: - Best you beginn with setting all to "bilinear". If that works ok for you, you can try to change them - for more advanced scaler. I use ewa_robidouxsharp on my GTX1050, but your mileage may vary. + Best you beginn with setting all to "bilinear". If that works ok for you, you can try to change them + for more advanced scaler. I use ewa_robidouxsharp on my GTX1050, but your mileage may vary. Unfortunatly on INTEL not all scalers may work or crash. - - You can enable a Scaler Test feature. When enabled then the screen is split.On the left half you will - see the scaler defined by Scaler Test and on the right side you will see the scaler defined at the - Resolution setting. There is as small black line between the halfs to remaind you that Scaler Test + + You can enable a Scaler Test feature. When enabled then the screen is split.On the left half you will + see the scaler defined by Scaler Test and on the right side you will see the scaler defined at the + Resolution setting. There is as small black line between the halfs to remaind you that Scaler Test is activ. - + Then you should set the Monitor Colorspace to "sRGB". This guarantees you the best colors on your screen. - At the moment all calculations internaly are done in RGB space and all cards output also RGB. - - If you are colorblind you could try to remedy this with the Colorblind Settings. Realy only needed + At the moment all calculations internaly are done in RGB space and all cards output also RGB. + + If you are colorblind you could try to remedy this with the Colorblind Settings. Realy only needed in rare cases. - + All other settings can be in their default state. - - + + Setup: environment ------ @@ -283,11 +283,13 @@ Setup: /etc/vdr/setup.conf 0 pan and scan 1 letter box 2 center cut-out + 3 original softhddevice.VideoOtherDisplayFormat = 1 0 pan and scan 1 pillar box 2 center cut-out + 3 original softhddevice.pip.X = 79 softhddevice.pip.Y = 78 @@ -378,6 +380,3 @@ Running: Known Bugs: ----------- SD Streams not working very well on vaapi - - - diff --git a/audio.c b/audio.c index 8b42c64..c8fd966 100644 --- a/audio.c +++ b/audio.c @@ -146,7 +146,6 @@ static volatile char AudioRunning; ///< thread running / stopped static volatile char AudioPaused; ///< audio paused static volatile char AudioVideoIsReady; ///< video ready start early static int AudioSkip; ///< skip audio to sync to video -int AudioDelay; /// delay audio to sync to video static const int AudioBytesProSample = 2; ///< number of bytes per sample @@ -2005,7 +2004,7 @@ static void *AudioPlayHandlerThread(void *dummy) { Debug(3, "audio: play thread started\n"); prctl(PR_SET_NAME, "cuvid audio", 0, 0, 0); - + for (;;) { // check if we should stop the thread if (AudioThreadStop) { @@ -2024,7 +2023,8 @@ static void *AudioPlayHandlerThread(void *dummy) Debug(3, "audio: ----> %dms %d start\n", (AudioUsedBytes() * 1000) / (!AudioRing[AudioRingWrite].HwSampleRate + !AudioRing[AudioRingWrite].HwChannels + - AudioRing[AudioRingWrite].HwSampleRate * AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample),AudioUsedBytes()); + AudioRing[AudioRingWrite].HwSampleRate * AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample), + AudioUsedBytes()); do { int filled; @@ -2252,7 +2252,7 @@ void AudioEnqueue(const void *samples, int count) AudioNormalizer(buffer, count); } } - + n = RingBufferWrite(AudioRing[AudioRingWrite].RingBuffer, buffer, count); if (n != (size_t)count) { Error(_("audio: can't place %d samples in ring buffer\n"), count); @@ -2291,7 +2291,7 @@ void AudioEnqueue(const void *samples, int count) // no lock needed, can wakeup next time AudioRunning = 1; pthread_cond_signal(&AudioStartCond); - Debug(3, "Start on AudioEnque Threshold %d n %d\n",AudioStartThreshold,n); + Debug(3, "Start on AudioEnque Threshold %d n %d\n", AudioStartThreshold, n); } } // Update audio clock (stupid gcc developers thinks INT64_C is unsigned) @@ -2325,7 +2325,7 @@ void AudioVideoReady(int64_t pts) // Audio.PTS = next written sample time stamp used = RingBufferUsedBytes(AudioRing[AudioRingWrite].RingBuffer); - audio_pts = + audio_pts = AudioRing[AudioRingWrite].PTS - (used * 90 * 1000) / (AudioRing[AudioRingWrite].HwSampleRate * AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample); @@ -2337,11 +2337,12 @@ void AudioVideoReady(int64_t pts) if (!AudioRunning) { int skip; + // buffer ~15 video frames // FIXME: HDTV can use smaller video buffer skip = pts - 0 * 20 * 90 - AudioBufferTime * 90 - audio_pts + VideoAudioDelay; #ifdef DEBUG - // fprintf(stderr, "a/v-diff %dms a/v-delay %dms skip %dms Audiobuffer %d\n", (int)(pts - audio_pts) / 90, VideoAudioDelay / 90, skip / 90,AudioBufferTime); + // fprintf(stderr, "a/v-diff %dms a/v-delay %dms skip %dms Audiobuffer %d\n", (int)(pts - audio_pts) / 90, VideoAudioDelay / 90, skip / 90,AudioBufferTime); #endif // guard against old PTS if (skip > 0 && skip < 4000 * 90) { @@ -2479,7 +2480,7 @@ int64_t AudioGetDelay(void) pts += ((int64_t) RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer) * 90 * 1000) / (AudioRing[AudioRingRead].HwSampleRate * AudioRing[AudioRingRead].HwChannels * AudioBytesProSample); - Debug(4,"audio: hw+sw delay %zd %" PRId64 "ms\n", RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer), + Debug(4, "audio: hw+sw delay %zd %" PRId64 "ms\n", RingBufferUsedBytes(AudioRing[AudioRingRead].RingBuffer), pts / 90); return pts; @@ -2496,7 +2497,7 @@ void AudioSetClock(int64_t pts) Debug(4, "audio: set clock %s -> %s pts\n", Timestamp2String(AudioRing[AudioRingWrite].PTS), Timestamp2String(pts)); } -// printf("Audiosetclock pts %#012" PRIx64 " %d\n",pts,RingBufferUsedBytes(AudioRing[AudioRingWrite].RingBuffer)); +// printf("Audiosetclock pts %#012" PRIx64 " %d\n",pts,RingBufferUsedBytes(AudioRing[AudioRingWrite].RingBuffer)); AudioRing[AudioRingWrite].PTS = pts; } diff --git a/codec.c b/codec.c index d0249a4..4ad7824 100644 --- a/codec.c +++ b/codec.c @@ -96,6 +96,7 @@ static pthread_mutex_t CodecLockMutex; /// Flag prefer fast channel switch char CodecUsePossibleDefectFrames; AVBufferRef *hw_device_ctx; + //---------------------------------------------------------------------------- // Video //---------------------------------------------------------------------------- @@ -255,18 +256,18 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) #endif #ifdef RASPI switch (codec_id) { - case AV_CODEC_ID_MPEG2VIDEO: - name = "mpeg2_v4l2m2m"; - break; - case AV_CODEC_ID_H264: - name = "h264_v4l2m2m"; + 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; + break; + case AV_CODEC_ID_HEVC: + name = "hevc_v4l2m2m"; + break; } -#endif +#endif if (name && (video_codec = avcodec_find_decoder_by_name(name))) { Debug(3, "codec: decoder found\n"); } else if ((video_codec = avcodec_find_decoder(codec_id)) == NULL) { @@ -281,15 +282,15 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) if (!(decoder->VideoCtx = avcodec_alloc_context3(video_codec))) { Fatal(_("codec: can't allocate video codec context\n")); } - + #ifndef RASPI if (!HwDeviceContext) { Fatal("codec: no hw device context to be used"); } 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 */ + 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 @@ -310,7 +311,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) { Debug(3, "codec: auto threads enabled"); // decoder->VideoCtx->thread_count = 0; - } + } if (video_codec->capabilities & AV_CODEC_CAP_TRUNCATED) { Debug(3, "codec: supports truncated packets"); @@ -333,9 +334,9 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id) // if (av_opt_set_int(decoder->VideoCtx, "refcounted_frames", 1, 0) < 0) // Fatal(_("VAAPI Refcounts invalid\n")); decoder->VideoCtx->thread_safe_callbacks = 0; - + #endif - + #ifdef RASPI decoder->VideoCtx->codec_id = codec_id; decoder->VideoCtx->flags |= AV_CODEC_FLAG_BITEXACT; @@ -508,18 +509,18 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) int ret; AVPacket pkt[1]; AVFrame *frame; - + *pkt = *avpkt; // use copy ret = avcodec_send_packet(video_ctx, pkt); if (ret < 0) { return; - } - + } + if (!CuvidTestSurfaces()) usleep(1000); - + ret = 0; - while (ret >= 0 && CuvidTestSurfaces()) { + while (ret >= 0 && CuvidTestSurfaces()) { frame = av_frame_alloc(); ret = avcodec_receive_frame(video_ctx, frame); @@ -549,7 +550,7 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) av_frame_free(&frame); return; } - } + } } } #endif @@ -596,9 +597,9 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) } else { got_frame = 0; } - // printf("got %s packet from decoder\n",got_frame?"1":"no"); + // printf("got %s packet from decoder\n",got_frame?"1":"no"); if (got_frame) { // frame completed -// printf("video frame pts %#012" PRIx64 " %dms\n",frame->pts,(int)(apts - frame->pts) / 90); +// printf("video frame pts %#012" PRIx64 " %dms\n",frame->pts,(int)(apts - frame->pts) / 90); #ifdef YADIF if (decoder->filter) { if (decoder->filter == 1) { @@ -647,7 +648,7 @@ void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt) void CodecVideoFlushBuffers(VideoDecoder * decoder) { if (decoder->VideoCtx) { - avcodec_flush_buffers(decoder->VideoCtx); + avcodec_flush_buffers(decoder->VideoCtx); } } @@ -819,7 +820,7 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id) void CodecAudioClose(AudioDecoder * audio_decoder) { // FIXME: output any buffered data - + #ifdef USE_SWRESAMPLE if (audio_decoder->Resample) { swr_free(&audio_decoder->Resample); @@ -1111,8 +1112,6 @@ static int CodecAudioPassthroughHelper(AudioDecoder * audio_decoder, const AVPac return 0; } - - #if defined(USE_SWRESAMPLE) || defined(USE_AVRESAMPLE) /** @@ -1346,6 +1345,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt) if (audio_decoder->Resample) { uint8_t outbuf[8192 * 2 * 8]; uint8_t *out[1]; + out[0] = outbuf; ret = swr_convert(audio_decoder->Resample, out, sizeof(outbuf) / (2 * audio_decoder->HwChannels), diff --git a/drm.c b/drm.c index 41f2303..cb5c833 100644 --- a/drm.c +++ b/drm.c @@ -18,13 +18,13 @@ struct _Drm_Render_ int fd_drm; drmModeModeInfo mode; drmModeCrtc *saved_crtc; -// drmEventContext ev; +// drmEventContext ev; int bpp; uint32_t connector_id, crtc_id, video_plane; uint32_t hdr_metadata; uint32_t mmWidth,mmHeight; // Size in mm uint32_t hdr_blob_id; - + }; typedef struct _Drm_Render_ VideoRender; @@ -193,12 +193,12 @@ void set_video_mode(int width, int height) return; connector = drmModeGetConnector(render->fd_drm, render->connector_id); for (ii = 0; ii < connector->count_modes; ii++) { - mode = &connector->modes[ii]; + mode = &connector->modes[ii]; printf("Mode %d %dx%d Rate %d\n",ii,mode->hdisplay,mode->vdisplay,mode->vrefresh); - if (width == mode->hdisplay && - height == mode->vdisplay && + if (width == mode->hdisplay && + height == mode->vdisplay && mode->vrefresh == DRMRefresh && - render->mode.hdisplay != width && + render->mode.hdisplay != width && render->mode.vdisplay != height && !(mode->flags & DRM_MODE_FLAG_INTERLACE)) { memcpy(&render->mode, mode, sizeof(drmModeModeInfo)); @@ -211,7 +211,7 @@ void set_video_mode(int width, int height) CuvidSetVideoMode(); Debug(3,"Set new mode %d:%d\n",mode->hdisplay,mode->vdisplay); break; - } + } } } @@ -241,10 +241,10 @@ static int FindDevice(VideoRender * render) return -errno; } drmSetMaster(render->fd_drm); - + version = drmGetVersion(render->fd_drm); fprintf(stderr, "FindDevice: open /dev/dri/card0: %s\n", version->name); - + // check capability if (drmGetCap(render->fd_drm, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || has_dumb == 0) fprintf(stderr, "FindDevice: drmGetCap DRM_CAP_DUMB_BUFFER failed or doesn't have dumb buffer\n"); @@ -263,7 +263,7 @@ static int FindDevice(VideoRender * render) if (drmGetCap(render->fd_drm, DRM_PRIME_CAP_IMPORT, &has_prime) < 0) fprintf(stderr, "FindDevice: DRM_PRIME_CAP_IMPORT not available.\n"); - + if ((resources = drmModeGetResources(render->fd_drm)) == NULL){ fprintf(stderr, "FindDevice: cannot retrieve DRM resources (%d): %m\n", errno); return -errno; @@ -282,18 +282,18 @@ static int FindDevice(VideoRender * render) fprintf(stderr, "FindDevice: cannot retrieve DRM connector (%d): %m\n", errno); return -errno; } - + sprintf(connectorstr,"%s-%u",util_lookup_connector_type_name(connector->connector_type),connector->connector_type_id); printf("Connector >%s< is %sconnected\n",connectorstr,connector->connection == DRM_MODE_CONNECTED?"":"not "); if (DRMConnector && strcmp(DRMConnector,connectorstr)) continue; - + if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes > 0) { float aspect = (float)connector->mmWidth / (float)connector->mmHeight; if ((aspect > 1.70) && (aspect < 1.85)) { render->mmHeight = 90; render->mmWidth = 160; - } else { + } else { render->mmHeight = connector->mmHeight; render->mmWidth = connector->mmWidth; } @@ -304,27 +304,27 @@ static int FindDevice(VideoRender * render) return -errno; } render->crtc_id = encoder->crtc_id; - + render->hdr_metadata = GetPropertyID(render->fd_drm, connector->connector_id, - DRM_MODE_OBJECT_CONNECTOR, "HDR_OUTPUT_METADATA"); + DRM_MODE_OBJECT_CONNECTOR, "HDR_OUTPUT_METADATA"); printf("ID %d of METADATA in Connector %d connected %d\n",render->hdr_metadata,connector->connector_id,connector->connection); - + memcpy(&render->mode, &connector->modes[0], sizeof(drmModeModeInfo)); // set fallback // search Modes for Connector for (ii = 0; ii < connector->count_modes; ii++) { mode = &connector->modes[ii]; - + printf("Mode %d %dx%d Rate %d\n",ii,mode->hdisplay,mode->vdisplay,mode->vrefresh); - - if (VideoWindowWidth && VideoWindowHeight) { // preset by command line - if (VideoWindowWidth == mode->hdisplay && - VideoWindowHeight == mode->vdisplay && + + if (VideoWindowWidth && VideoWindowHeight) { // preset by command line + if (VideoWindowWidth == mode->hdisplay && + VideoWindowHeight == mode->vdisplay && mode->vrefresh == DRMRefresh && !(mode->flags & DRM_MODE_FLAG_INTERLACE)) { memcpy(&render->mode, mode, sizeof(drmModeModeInfo)); break; } - } + } else { if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) { memcpy(&render->mode, mode, sizeof(drmModeModeInfo)); @@ -335,7 +335,7 @@ static int FindDevice(VideoRender * render) } } found = 1; - i = resources->count_connectors; // uuuuhh + i = resources->count_connectors; // uuuuhh } VideoWindowWidth = render->mode.hdisplay; VideoWindowHeight = render->mode.vdisplay; @@ -348,7 +348,7 @@ static int FindDevice(VideoRender * render) printf("Requested Connector not found or not connected\n"); return -1; } - + // find first plane if ((plane_res = drmModeGetPlaneResources(render->fd_drm)) == NULL) fprintf(stderr, "FindDevice: cannot retrieve PlaneResources (%d): %m\n", errno); @@ -366,7 +366,7 @@ static int FindDevice(VideoRender * render) uint64_t type = GetPropertyValue(render->fd_drm, plane_res->planes[j], DRM_MODE_OBJECT_PLANE, "type"); - uint64_t zpos = 0; + uint64_t zpos = 0; #ifdef DRM_DEBUG // If more then 2 crtcs this must rewriten!!! printf("[FindDevice] Plane id %i crtc_id %i possible_crtcs %i possible CRTC %i type %s\n", @@ -384,7 +384,7 @@ static int FindDevice(VideoRender * render) case DRM_FORMAT_ARGB8888: #else case DRM_FORMAT_XRGB2101010: -#endif +#endif if (!render->video_plane) { render->video_plane = plane->plane_id; } @@ -419,25 +419,25 @@ static int FindDevice(VideoRender * render) void VideoInitDrm() { int i; - - + + if (!(render = calloc(1, sizeof(*render)))) { Fatal(_("video/DRM: out of memory\n")); return; } - + if (FindDevice(render)){ Fatal(_( "VideoInit: FindDevice() failed\n")); } - + gbm.dev = gbm_create_device (render->fd_drm); assert (gbm.dev != NULL); - + PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL; get_platform_display = (void *) eglGetProcAddress("eglGetPlatformDisplay"); assert(get_platform_display != NULL); - + eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, gbm.dev, NULL); assert (eglDisplay != NULL); @@ -462,22 +462,21 @@ void VideoInitDrm() DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", render->crtc_id); SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 1); - + if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0) fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno); - + if (drmModeDestroyPropertyBlob(render->fd_drm, modeID) != 0) fprintf(stderr, "cannot destroy property blob (%d): %m\n", errno); - + drmModeAtomicFree(ModeReq); } void get_drm_aspect(int *num,int *den) { - Debug(3,"mmHeight %d mmWidth %d VideoHeight %d VideoWidth %d\n",render->mmHeight,render->mmWidth,VideoWindowHeight,VideoWindowWidth); - *num = VideoWindowWidth * render->mmHeight; - *den = VideoWindowHeight * render->mmWidth; + *num = VideoWindowWidth; + *den = VideoWindowHeight; } struct gbm_bo *bo = NULL, *next_bo=NULL; @@ -488,8 +487,8 @@ static int old_color=-1,old_trc=-1; void InitBo(int bpp) { // create the GBM and EGL surface render->bpp = bpp; - gbm.surface = gbm_surface_create (gbm.dev, VideoWindowWidth,VideoWindowHeight, - bpp==10?GBM_FORMAT_XRGB2101010:GBM_FORMAT_ARGB8888, + gbm.surface = gbm_surface_create (gbm.dev, VideoWindowWidth,VideoWindowHeight, + bpp==10?GBM_FORMAT_XRGB2101010:GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT|GBM_BO_USE_RENDERING); assert(gbm.surface != NULL); eglSurface = eglCreateWindowSurface (eglDisplay, eglConfig, gbm.surface, NULL); @@ -501,10 +500,10 @@ static struct gbm_bo *previous_bo = NULL; static uint32_t previous_fb; static void drm_swap_buffers () { - + uint32_t fb; - - eglSwapBuffers (eglDisplay, eglSurface); + + eglSwapBuffers (eglDisplay, eglSurface); struct gbm_bo *bo = gbm_surface_lock_front_buffer (gbm.surface); #if 1 if (bo == NULL) @@ -517,7 +516,7 @@ static void drm_swap_buffers () { drmModeAddFB (render->fd_drm, VideoWindowWidth,VideoWindowHeight,render->bpp==10? 30:24, 32, pitch, handle, &fb); // drmModeSetCrtc (render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode); - + if (m_need_modeset) { drmModeAtomicReqPtr ModeReq; const uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; @@ -531,14 +530,14 @@ static void drm_swap_buffers () { fprintf(stderr, "cannot allocate atomic request (%d): %m\n", errno); return; } - - // Need to disable the CRTC in order to submit the HDR data.... + + // Need to disable the CRTC in order to submit the HDR data.... SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, - DRM_MODE_OBJECT_CRTC, "ACTIVE", 0); + DRM_MODE_OBJECT_CRTC, "ACTIVE", 0); if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0) fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno); sleep(2); - + SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, DRM_MODE_OBJECT_CONNECTOR, "Colorspace",old_color==AVCOL_PRI_BT2020?9:2 ); SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, @@ -547,7 +546,7 @@ static void drm_swap_buffers () { DRM_MODE_OBJECT_CONNECTOR, "CRTC_ID", render->crtc_id); SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, DRM_MODE_OBJECT_CRTC, "ACTIVE", 1); - + if (drmModeAtomicCommit(render->fd_drm, ModeReq, flags, NULL) != 0) fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno); @@ -558,7 +557,7 @@ static void drm_swap_buffers () { m_need_modeset = 0; } drmModeSetCrtc (render->fd_drm, render->crtc_id, fb, 0, 0, &render->connector_id, 1, &render->mode); - + if (previous_bo) { drmModeRmFB (render->fd_drm, previous_fb); gbm_surface_release_buffer (gbm.surface, previous_bo); @@ -579,15 +578,15 @@ static void drm_clean_up () { drmModeRmFB (render->fd_drm, previous_fb); gbm_surface_release_buffer (gbm.surface, previous_bo); } - + drmModeSetCrtc (render->fd_drm, render->saved_crtc->crtc_id, render->saved_crtc->buffer_id, render->saved_crtc->x, render->saved_crtc->y, &render->connector_id, 1, &render->saved_crtc->mode); drmModeFreeCrtc (render->saved_crtc); - + if (render->hdr_blob_id) drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id); render->hdr_blob_id = 0; - + eglDestroySurface (eglDisplay, eglSurface); EglCheck(); gbm_surface_destroy (gbm.surface); @@ -597,9 +596,9 @@ static void drm_clean_up () { EglCheck(); eglSharedContext = NULL; - eglTerminate (eglDisplay); + eglTerminate (eglDisplay); EglCheck(); - + gbm_device_destroy (gbm.dev); drmDropMaster(render->fd_drm); close (render->fd_drm); diff --git a/hdr.c b/hdr.c index 5ec1cca..12946a0 100644 --- a/hdr.c +++ b/hdr.c @@ -334,11 +334,11 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid int max_lum=4000,min_lum=0050; struct AVMasteringDisplayMetadata *md = NULL; struct AVContentLightMetadata *ld = NULL; - + if (render->hdr_metadata == -1) { // Metadata not supported return; } - + // clean up FFMEPG stuff if (trc == AVCOL_TRC_BT2020_10) trc = AVCOL_TRC_ARIB_STD_B67; @@ -346,16 +346,16 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid trc = AVCOL_TRC_BT709; if (color == AVCOL_PRI_UNSPECIFIED) color = AVCOL_PRI_BT709; - + if ((old_color == color && old_trc == trc && !sd1 && !sd2) || !render->hdr_metadata) return; // nothing to do - + if (sd1) md = sd1->data; - + if (sd2) ld = sd2->data; - + if (md && !memcmp(md,&md_save,sizeof(md_save))) if (ld && !memcmp(ld,&ld_save,sizeof(ld_save))) { return; @@ -363,23 +363,23 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid else if (ld && !memcmp(ld,&ld_save,sizeof(ld_save))) { return; } - + if (ld) memcpy(&ld_save,ld,sizeof(ld_save)); if (md) memcpy(&md_save,md,sizeof(md_save)); - + Debug(3,"Update HDR to TRC %d color %d\n",trc,color); if (trc == AVCOL_TRC_BT2020_10) trc = AVCOL_TRC_ARIB_STD_B67; - + old_color = color; old_trc = trc; - + if (render->hdr_blob_id) drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id); - + switch(trc) { case AVCOL_TRC_BT709: // 1 case AVCOL_TRC_UNSPECIFIED: // 2 @@ -387,7 +387,7 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid break; case AVCOL_TRC_BT2020_10: // 14 case AVCOL_TRC_BT2020_12: - case AVCOL_TRC_ARIB_STD_B67: // 18 HLG + case AVCOL_TRC_ARIB_STD_B67: // 18 HLG eotf = EOTF_HLG; break; case AVCOL_TRC_SMPTE2084: // 16 @@ -397,7 +397,7 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid eotf = EOTF_TRADITIONAL_GAMMA_SDR; break; } - + switch (color) { case AVCOL_PRI_BT709: // 1 case AVCOL_PRI_UNSPECIFIED: // 2 @@ -413,7 +413,7 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid cs = weston_colorspace_lookup("BT.709"); break; } - + if (md) { // we got Metadata if (md->has_primaries) { Debug(3,"Mastering Display Metadata,\n has_primaries:%d has_luminance:%d \n" @@ -465,9 +465,9 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid MaxCLL, // Maximum Content Light Level (MaxCLL) MaxFALL, // Maximum Frame-Average Light Level (MaxFALL) eotf); - - + + ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &render->hdr_blob_id); if (ret) { printf("DRM: HDR metadata: failed blob create \n"); @@ -479,15 +479,14 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid render->hdr_metadata, render->hdr_blob_id); if (ret) { printf("DRM: HDR metadata: failed property set %d\n",ret); - + if (render->hdr_blob_id) drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id); render->hdr_blob_id = 0; return; } m_need_modeset = 1; - - Debug(3,"DRM: HDR metadata: prop set\n"); - -} + Debug(3,"DRM: HDR metadata: prop set\n"); + +} diff --git a/openglosd.cpp b/openglosd.cpp index f962cbd..e1c912a 100644 --- a/openglosd.cpp +++ b/openglosd.cpp @@ -2,20 +2,18 @@ #include #include "openglosd.h" - /**************************************************************************************** * Helpers ****************************************************************************************/ -void ConvertColor(const GLint &colARGB, glm::vec4 &col) { +void ConvertColor(const GLint & colARGB, glm::vec4 & col) +{ col.a = ((colARGB & 0xFF000000) >> 24) / 255.0; col.r = ((colARGB & 0x00FF0000) >> 16) / 255.0; - col.g = ((colARGB & 0x0000FF00) >> 8 ) / 255.0; - col.b = ((colARGB & 0x000000FF) ) / 255.0; + col.g = ((colARGB & 0x0000FF00) >> 8) / 255.0; + col.b = ((colARGB & 0x000000FF)) / 255.0; } - - /**************************************************************************************** * cShader ****************************************************************************************/ @@ -30,8 +28,7 @@ const char *glversion = "#version 300 es "; #endif #endif -const char *rectVertexShader = -"%s\n \ +const char *rectVertexShader = "%s\n \ \ layout (location = 0) in vec2 position; \ out vec4 rectCol; \ @@ -45,8 +42,7 @@ void main() \ } \ "; -const char *rectFragmentShader = -"%s\n \ +const char *rectFragmentShader = "%s\n \ \ precision mediump float; \ in vec4 rectCol; \ @@ -58,8 +54,7 @@ void main() \ } \ "; -const char *textureVertexShader = -"%s\n \ +const char *textureVertexShader = "%s\n \ \ layout (location = 0) in vec2 position; \ layout (location = 1) in vec2 texCoords; \ @@ -78,8 +73,7 @@ void main() \ } \ "; -const char *textureFragmentShader = -"%s\n \ +const char *textureFragmentShader = "%s\n \ precision mediump float; \ in vec2 TexCoords; \ in vec4 alphaValue; \ @@ -93,8 +87,7 @@ void main() \ } \ "; -const char *textVertexShader = -"%s\n \ +const char *textVertexShader = "%s\n \ \ layout (location = 0) in vec2 position; \ layout (location = 1) in vec2 texCoords; \ @@ -113,8 +106,7 @@ void main() \ } \ "; -const char *textFragmentShader = -"%s\n \ +const char *textFragmentShader = "%s\n \ precision mediump float; \ in vec2 TexCoords; \ in vec4 textColor; \ @@ -144,11 +136,13 @@ void main() \ static cShader *Shaders[stCount]; -void cShader::Use(void) { +void cShader::Use(void) +{ glUseProgram(id); } -bool cShader::Load(eShaderType type) { +bool cShader::Load(eShaderType type) +{ this->type = type; const char *vertexCode = NULL; @@ -184,53 +178,61 @@ bool cShader::Load(eShaderType type) { return true; } -void cShader::SetFloat(const GLchar *name, GLfloat value) { +void cShader::SetFloat(const GLchar * name, GLfloat value) +{ glUniform1f(glGetUniformLocation(id, name), value); } -void cShader::SetInteger(const GLchar *name, GLint value) { +void cShader::SetInteger(const GLchar * name, GLint value) +{ glUniform1i(glGetUniformLocation(id, name), value); } -void cShader::SetVector2f(const GLchar *name, GLfloat x, GLfloat y) { +void cShader::SetVector2f(const GLchar * name, GLfloat x, GLfloat y) +{ glUniform2f(glGetUniformLocation(id, name), x, y); } -void cShader::SetVector3f(const GLchar *name, GLfloat x, GLfloat y, GLfloat z) { +void cShader::SetVector3f(const GLchar * name, GLfloat x, GLfloat y, GLfloat z) +{ glUniform3f(glGetUniformLocation(id, name), x, y, z); } -void cShader::SetVector4f(const GLchar *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { +void cShader::SetVector4f(const GLchar * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ glUniform4f(glGetUniformLocation(id, name), x, y, z, w); } -void cShader::SetMatrix4(const GLchar *name, const glm::mat4 &matrix) { +void cShader::SetMatrix4(const GLchar * name, const glm::mat4 & matrix) +{ glUniformMatrix4fv(glGetUniformLocation(id, name), 1, GL_FALSE, glm::value_ptr(matrix)); } -bool cShader::Compile(const char *vertexCode, const char *fragmentCode) { +bool cShader::Compile(const char *vertexCode, const char *fragmentCode) +{ GLuint sVertex, sFragment; - char *buffer = (char *)malloc(1000); + char *buffer = (char *)malloc(1000); + // Vertex Shader sVertex = glCreateShader(GL_VERTEX_SHADER); - sprintf(buffer,vertexCode,glversion); - glShaderSource(sVertex, 1, (const GLchar**) &buffer, NULL); + sprintf(buffer, vertexCode, glversion); + glShaderSource(sVertex, 1, (const GLchar **)&buffer, NULL); glCompileShader(sVertex); // esyslog("[softhddev]:SHADER:VERTEX %s\n",vertexCode); if (!CheckCompileErrors(sVertex)) { - free(buffer); + free(buffer); return false; - } + } // Fragment Shader sFragment = glCreateShader(GL_FRAGMENT_SHADER); - sprintf(buffer,fragmentCode,glversion); - glShaderSource(sFragment, 1, (const GLchar**)&buffer, NULL); + sprintf(buffer, fragmentCode, glversion); + glShaderSource(sFragment, 1, (const GLchar **)&buffer, NULL); glCompileShader(sFragment); // esyslog("[softhddev]:SHADER:FRAGMENT %s\n",fragmentCode); if (!CheckCompileErrors(sFragment)) { - free(buffer); + free(buffer); return false; - } + } // link Program id = glCreateProgram(); glAttachShader(id, sVertex); @@ -241,13 +243,15 @@ bool cShader::Compile(const char *vertexCode, const char *fragmentCode) { // Delete the shaders as they're linked into our program now and no longer necessery glDeleteShader(sVertex); glDeleteShader(sFragment); - free(buffer); + free(buffer); return true; } -bool cShader::CheckCompileErrors(GLuint object, bool program) { +bool cShader::CheckCompileErrors(GLuint object, bool program) +{ GLint success; GLchar infoLog[1024]; + if (!program) { glGetShaderiv(object, GL_COMPILE_STATUS, &success); if (!success) { @@ -267,10 +271,12 @@ bool cShader::CheckCompileErrors(GLuint object, bool program) { } #define KERNING_UNKNOWN (-10000) + /**************************************************************************************** * cOglGlyph ****************************************************************************************/ -cOglGlyph::cOglGlyph(FT_ULong charCode, FT_BitmapGlyph ftGlyph) { +cOglGlyph::cOglGlyph(FT_ULong charCode, FT_BitmapGlyph ftGlyph) +{ this->charCode = charCode; bearingLeft = ftGlyph->left; bearingTop = ftGlyph->top; @@ -280,43 +286,39 @@ cOglGlyph::cOglGlyph(FT_ULong charCode, FT_BitmapGlyph ftGlyph) { LoadTexture(ftGlyph); } -cOglGlyph::~cOglGlyph(void) { +cOglGlyph::~cOglGlyph(void) +{ } -int cOglGlyph::GetKerningCache(FT_ULong prevSym) { - for (int i = kerningCache.Size(); --i > 0; ) { +int cOglGlyph::GetKerningCache(FT_ULong prevSym) +{ + for (int i = kerningCache.Size(); --i > 0;) { if (kerningCache[i].prevSym == prevSym) return kerningCache[i].kerning; } return KERNING_UNKNOWN; } -void cOglGlyph::SetKerningCache(FT_ULong prevSym, int kerning) { +void cOglGlyph::SetKerningCache(FT_ULong prevSym, int kerning) +{ kerningCache.Append(tKerning(prevSym, kerning)); } -void cOglGlyph::BindTexture(void) { +void cOglGlyph::BindTexture(void) +{ glBindTexture(GL_TEXTURE_2D, texture); } -void cOglGlyph::LoadTexture(FT_BitmapGlyph ftGlyph) { +void cOglGlyph::LoadTexture(FT_BitmapGlyph ftGlyph) +{ // Disable byte-alignment restriction glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RED, - ftGlyph->bitmap.width, - ftGlyph->bitmap.rows, - 0, - GL_RED, - GL_UNSIGNED_BYTE, - ftGlyph->bitmap.buffer - ); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, ftGlyph->bitmap.width, ftGlyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, + ftGlyph->bitmap.buffer); // Set texture options glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -325,26 +327,29 @@ void cOglGlyph::LoadTexture(FT_BitmapGlyph ftGlyph) { glBindTexture(GL_TEXTURE_2D, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - } extern "C" void GlxInitopengl(); extern "C" void GlxDrawopengl(); extern "C" void GlxDestroy(); -extern "C" void makejpg(uint8_t *data, int width, int height); +extern "C" void makejpg(uint8_t * data, int width, int height); + /**************************************************************************************** * cOglFont ****************************************************************************************/ FT_Library cOglFont::ftLib = 0; -cList *cOglFont::fonts = 0; + +cList < cOglFont > *cOglFont::fonts = 0; bool cOglFont::initiated = false; -cOglFont::cOglFont(const char *fontName, int charHeight) : name(fontName) { +cOglFont::cOglFont(const char *fontName, int charHeight):name(fontName) +{ size = charHeight; height = 0; bottom = 0; int error = FT_New_Face(ftLib, fontName, 0, &face); + if (error) esyslog("[softhddev]ERROR: failed to open %s!", *name); @@ -353,15 +358,18 @@ cOglFont::cOglFont(const char *fontName, int charHeight) : name(fontName) { bottom = abs((face->size->metrics.descender - 63) / 64); } -cOglFont::~cOglFont(void) { +cOglFont::~cOglFont(void) +{ FT_Done_Face(face); } -cOglFont *cOglFont::Get(const char *name, int charHeight) { +cOglFont *cOglFont::Get(const char *name, int charHeight) +{ if (!fonts) Init(); cOglFont *font; + for (font = fonts->First(); font; font = fonts->Next(font)) if (!strcmp(font->Name(), name) && charHeight == font->Size()) { return font; @@ -371,32 +379,36 @@ cOglFont *cOglFont::Get(const char *name, int charHeight) { return font; } -void cOglFont::Init(void) { - +void cOglFont::Init(void) +{ + if (FT_Init_FreeType(&ftLib)) { esyslog("[softhddev]failed to initialize FreeType library!"); - return; - } - fonts = new cList; + return; + } + fonts = new cList < cOglFont >; initiated = true; } -void cOglFont::Cleanup(void) { +void cOglFont::Cleanup(void) +{ if (!initiated) return; delete fonts; + fonts = 0; if (FT_Done_FreeType(ftLib)) esyslog("failed to deinitialize FreeType library!"); } -cOglGlyph* cOglFont::Glyph(FT_ULong charCode) const { +cOglGlyph *cOglFont::Glyph(FT_ULong charCode) const +{ // Non-breaking space: if (charCode == 0xA0) charCode = 0x20; // Lookup in cache: - for (cOglGlyph *g = glyphCache.First(); g; g = glyphCache.Next(g)) { + for (cOglGlyph * g = glyphCache.First(); g; g = glyphCache.Next(g)) { if (g->CharCode() == charCode) { return g; } @@ -405,8 +417,10 @@ cOglGlyph* cOglFont::Glyph(FT_ULong charCode) const { FT_UInt glyph_index = FT_Get_Char_Index(face, charCode); FT_Int32 loadFlags = FT_LOAD_NO_BITMAP; + // Load glyph image into the slot (erase previous one): int error = FT_Load_Glyph(face, glyph_index, loadFlags); + if (error) { esyslog("[softhddev]FT_Error (0x%02x) : %s\n", FT_Errors[error].code, FT_Errors[error].message); return NULL; @@ -414,18 +428,15 @@ cOglGlyph* cOglFont::Glyph(FT_ULong charCode) const { FT_Glyph ftGlyph; FT_Stroker stroker; - error = FT_Stroker_New( ftLib, &stroker ); + + error = FT_Stroker_New(ftLib, &stroker); if (error) { esyslog("[softhddev]FT_Stroker_New FT_Error (0x%02x) : %s\n", FT_Errors[error].code, FT_Errors[error].message); return NULL; } float outlineWidth = 0.25f; - FT_Stroker_Set(stroker, - (int)(outlineWidth * 64), - FT_STROKER_LINECAP_ROUND, - FT_STROKER_LINEJOIN_ROUND, - 0); + FT_Stroker_Set(stroker, (int)(outlineWidth * 64), FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); error = FT_Get_Glyph(face->glyph, &ftGlyph); if (error) { @@ -433,34 +444,40 @@ cOglGlyph* cOglFont::Glyph(FT_ULong charCode) const { return NULL; } - error = FT_Glyph_StrokeBorder( &ftGlyph, stroker, 0, 1 ); - if ( error ) { - esyslog("[softhddev]FT_Glyph_StrokeBorder FT_Error (0x%02x) : %s\n", FT_Errors[error].code, FT_Errors[error].message); + error = FT_Glyph_StrokeBorder(&ftGlyph, stroker, 0, 1); + if (error) { + esyslog("[softhddev]FT_Glyph_StrokeBorder FT_Error (0x%02x) : %s\n", FT_Errors[error].code, + FT_Errors[error].message); return NULL; } FT_Stroker_Done(stroker); - error = FT_Glyph_To_Bitmap( &ftGlyph, FT_RENDER_MODE_NORMAL, 0, 1); + error = FT_Glyph_To_Bitmap(&ftGlyph, FT_RENDER_MODE_NORMAL, 0, 1); if (error) { - esyslog("[softhddev]FT_Glyph_To_Bitmap FT_Error (0x%02x) : %s\n", FT_Errors[error].code, FT_Errors[error].message); + esyslog("[softhddev]FT_Glyph_To_Bitmap FT_Error (0x%02x) : %s\n", FT_Errors[error].code, + FT_Errors[error].message); return NULL; } - cOglGlyph *Glyph = new cOglGlyph(charCode, (FT_BitmapGlyph)ftGlyph); + cOglGlyph *Glyph = new cOglGlyph(charCode, (FT_BitmapGlyph) ftGlyph); + glyphCache.Add(Glyph); FT_Done_Glyph(ftGlyph); return Glyph; } -int cOglFont::Kerning(cOglGlyph *glyph, FT_ULong prevSym) const { +int cOglFont::Kerning(cOglGlyph * glyph, FT_ULong prevSym) const +{ int kerning = 0; + if (glyph && prevSym) { kerning = glyph->GetKerningCache(prevSym); if (kerning == KERNING_UNKNOWN) { FT_Vector delta; FT_UInt glyph_index = FT_Get_Char_Index(face, glyph->CharCode()); FT_UInt glyph_index_prev = FT_Get_Char_Index(face, prevSym); + FT_Get_Kerning(face, glyph_index_prev, glyph_index, FT_KERNING_DEFAULT, &delta); kerning = delta.x / 64; glyph->SetKerningCache(prevSym, kerning); @@ -472,7 +489,8 @@ int cOglFont::Kerning(cOglGlyph *glyph, FT_ULong prevSym) const { /**************************************************************************************** * cOglFb ****************************************************************************************/ -cOglFb::cOglFb(GLint width, GLint height, GLint viewPortWidth, GLint viewPortHeight) { +cOglFb::cOglFb(GLint width, GLint height, GLint viewPortWidth, GLint viewPortHeight) +{ initiated = false; fb = 0; texture = 0; @@ -487,17 +505,18 @@ cOglFb::cOglFb(GLint width, GLint height, GLint viewPortWidth, GLint viewPortHei scrollable = false; } -cOglFb::~cOglFb(void) { +cOglFb::~cOglFb(void) +{ if (texture) glDeleteTextures(1, &texture); if (fb) glDeleteFramebuffers(1, &fb); } - -bool cOglFb::Init(void) { +bool cOglFb::Init(void) +{ initiated = true; - glGenTextures(1, &texture); + glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -510,8 +529,8 @@ bool cOglFb::Init(void) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); - if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - esyslog("[softhddev]ERROR: %d Framebuffer is not complete!\n",__LINE__); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + esyslog("[softhddev]ERROR: %d Framebuffer is not complete!\n", __LINE__); return false; } @@ -519,34 +538,40 @@ bool cOglFb::Init(void) { return true; } -void cOglFb::Bind(void) { +void cOglFb::Bind(void) +{ if (!initiated) Init(); glViewport(0, 0, width, height); glBindFramebuffer(GL_FRAMEBUFFER, fb); } -void cOglFb::BindRead(void) { +void cOglFb::BindRead(void) +{ glBindFramebuffer(GL_READ_FRAMEBUFFER, fb); } -void cOglFb::BindWrite(void) { +void cOglFb::BindWrite(void) +{ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb); } -void cOglFb::Unbind(void) { +void cOglFb::Unbind(void) +{ glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); } -bool cOglFb::BindTexture(void) { +bool cOglFb::BindTexture(void) +{ if (!initiated) return false; glBindTexture(GL_TEXTURE_2D, texture); return true; } -void cOglFb::Blit(GLint destX1, GLint destY1, GLint destX2, GLint destY2) { +void cOglFb::Blit(GLint destX1, GLint destY1, GLint destX2, GLint destY2) +{ glBlitFramebuffer(0, 0, width, height, destX1, destY1, destX2, destY2, GL_COLOR_BUFFER_BIT, GL_NEAREST); glFlush(); } @@ -554,20 +579,23 @@ void cOglFb::Blit(GLint destX1, GLint destY1, GLint destX2, GLint destY2) { /**************************************************************************************** * cOglOutputFb ****************************************************************************************/ -cOglOutputFb::cOglOutputFb(GLint width, GLint height) : cOglFb(width, height, width, height) { +cOglOutputFb::cOglOutputFb(GLint width, GLint height):cOglFb(width, height, width, height) +{ // surface = 0; initiated = false; fb = 0; texture = 0; } -cOglOutputFb::~cOglOutputFb(void) { +cOglOutputFb::~cOglOutputFb(void) +{ // glVDPAUUnregisterSurfaceNV(surface); glDeleteTextures(1, &texture); glDeleteFramebuffers(1, &fb); } -bool cOglOutputFb::Init(void) { +bool cOglOutputFb::Init(void) +{ initiated = true; glGenTextures(1, &texture); @@ -581,20 +609,22 @@ bool cOglOutputFb::Init(void) { glGenFramebuffers(1, &fb); glBindFramebuffer(GL_FRAMEBUFFER, fb); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); - if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { esyslog("[softhddev]ERROR::cOglOutputFb: Framebuffer is not complete!"); return false; } return true; } -void cOglOutputFb::BindWrite(void) { +void cOglOutputFb::BindWrite(void) +{ if (!initiated) Init(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb); } -void cOglOutputFb::Unbind(void) { +void cOglOutputFb::Unbind(void) +{ glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -603,8 +633,9 @@ void cOglOutputFb::Unbind(void) { ****************************************************************************************/ static cOglVb *VertexBuffers[vbCount]; -cOglVb::cOglVb(int type) { - this->type = (eVertexBufferType)type; +cOglVb::cOglVb(int type) +{ + this->type = (eVertexBufferType) type; vao = 0; vbo = 0; sizeVertex1 = 0; @@ -613,10 +644,12 @@ cOglVb::cOglVb(int type) { drawMode = 0; } -cOglVb::~cOglVb(void) { +cOglVb::~cOglVb(void) +{ } -bool cOglVb::Init(void) { +bool cOglVb::Init(void) +{ if (type == vbTexture) { // Texture VBO definition @@ -662,10 +695,12 @@ bool cOglVb::Init(void) { glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (sizeVertex1 + sizeVertex2) * numVertices, NULL, GL_DYNAMIC_DRAW); glEnableVertexAttribArray(0); - glVertexAttribPointer(0, sizeVertex1, GL_FLOAT, GL_FALSE, (sizeVertex1 + sizeVertex2) * sizeof(GLfloat), (GLvoid*)0); + glVertexAttribPointer(0, sizeVertex1, GL_FLOAT, GL_FALSE, (sizeVertex1 + sizeVertex2) * sizeof(GLfloat), + (GLvoid *) 0); if (sizeVertex2 > 0) { glEnableVertexAttribArray(1); - glVertexAttribPointer(1, sizeVertex2, GL_FLOAT, GL_FALSE, (sizeVertex1 + sizeVertex2) * sizeof(GLfloat), (GLvoid*)(sizeVertex1 * sizeof(GLfloat))); + glVertexAttribPointer(1, sizeVertex2, GL_FLOAT, GL_FALSE, (sizeVertex1 + sizeVertex2) * sizeof(GLfloat), + (GLvoid *) (sizeVertex1 * sizeof(GLfloat))); } glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -674,43 +709,52 @@ bool cOglVb::Init(void) { return true; } -void cOglVb::Bind(void) { +void cOglVb::Bind(void) +{ glBindVertexArray(vao); } -void cOglVb::Unbind(void) { +void cOglVb::Unbind(void) +{ glBindVertexArray(0); } -void cOglVb::ActivateShader(void) { +void cOglVb::ActivateShader(void) +{ Shaders[shader]->Use(); } -void cOglVb::EnableBlending(void) { +void cOglVb::EnableBlending(void) +{ glEnable(GL_BLEND); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } -void cOglVb::DisableBlending(void) { +void cOglVb::DisableBlending(void) +{ glDisable(GL_BLEND); } -void cOglVb::SetShaderColor(GLint color) { +void cOglVb::SetShaderColor(GLint color) +{ glm::vec4 col; ConvertColor(color, col); Shaders[shader]->SetVector4f("inColor", col.r, col.g, col.b, col.a); } -void cOglVb::SetShaderAlpha(GLint alpha) { - Shaders[shader]->SetVector4f("alpha", 1.0f, 1.0f, 1.0f, (GLfloat)(alpha) / 255.0f); +void cOglVb::SetShaderAlpha(GLint alpha) +{ + Shaders[shader]->SetVector4f("alpha", 1.0f, 1.0f, 1.0f, (GLfloat) (alpha) / 255.0f); } -void cOglVb::SetShaderProjectionMatrix(GLint width, GLint height) { - glm::mat4 projection = glm::ortho(0.0f, (GLfloat)width, (GLfloat)height, 0.0f, -1.0f, 1.0f); +void cOglVb::SetShaderProjectionMatrix(GLint width, GLint height) +{ + glm::mat4 projection = glm::ortho(0.0f, (GLfloat) width, (GLfloat) height, 0.0f, -1.0f, 1.0f); Shaders[shader]->SetMatrix4("projection", projection); } -void cOglVb::SetVertexData(GLfloat *vertices, int count) { +void cOglVb::SetVertexData(GLfloat * vertices, int count) +{ if (count == 0) count = numVertices; glBindBuffer(GL_ARRAY_BUFFER, vbo); @@ -718,35 +762,41 @@ void cOglVb::SetVertexData(GLfloat *vertices, int count) { glBindBuffer(GL_ARRAY_BUFFER, 0); } -void cOglVb::DrawArrays(int count) { +void cOglVb::DrawArrays(int count) +{ if (count == 0) count = numVertices; glDrawArrays(drawMode, 0, count); glFlush(); } - /**************************************************************************************** * cOpenGLCmd ****************************************************************************************/ //------------------ cOglCmdInitOutputFb -------------------- -cOglCmdInitOutputFb::cOglCmdInitOutputFb(cOglOutputFb *oFb) : cOglCmd(NULL) { +cOglCmdInitOutputFb::cOglCmdInitOutputFb(cOglOutputFb * oFb):cOglCmd(NULL) +{ this->oFb = oFb; } -bool cOglCmdInitOutputFb::Execute(void) { +bool cOglCmdInitOutputFb::Execute(void) +{ bool ok = oFb->Init(); + oFb->Unbind(); return ok; } //------------------ cOglCmdInitFb -------------------- -cOglCmdInitFb::cOglCmdInitFb(cOglFb *fb, cCondWait *wait) : cOglCmd(fb) { +cOglCmdInitFb::cOglCmdInitFb(cOglFb * fb, cCondWait * wait):cOglCmd(fb) +{ this->wait = wait; } -bool cOglCmdInitFb::Execute(void) { +bool cOglCmdInitFb::Execute(void) +{ bool ok = fb->Init(); + fb->Unbind(); if (wait) wait->Signal(); @@ -754,52 +804,59 @@ bool cOglCmdInitFb::Execute(void) { } //------------------ cOglCmdDeleteFb -------------------- -cOglCmdDeleteFb::cOglCmdDeleteFb(cOglFb *fb) : cOglCmd(fb) { +cOglCmdDeleteFb::cOglCmdDeleteFb(cOglFb * fb):cOglCmd(fb) +{ } -bool cOglCmdDeleteFb::Execute(void) { +bool cOglCmdDeleteFb::Execute(void) +{ if (fb) delete fb; + return true; } //------------------ cOglCmdRenderFbToBufferFb -------------------- -cOglCmdRenderFbToBufferFb::cOglCmdRenderFbToBufferFb(cOglFb *fb, cOglFb *buffer, GLint x, GLint y, GLint transparency, GLint drawPortX, GLint drawPortY) : cOglCmd(fb) { +cOglCmdRenderFbToBufferFb::cOglCmdRenderFbToBufferFb(cOglFb * fb, cOglFb * buffer, GLint x, GLint y, GLint transparency, GLint drawPortX, GLint drawPortY):cOglCmd + (fb) +{ this->buffer = buffer; - this->x = (GLfloat)x; - this->y = (GLfloat)y; - this->drawPortX = (GLfloat)drawPortX; - this->drawPortY = (GLfloat)drawPortY; + this->x = (GLfloat) x; + this->y = (GLfloat) y; + this->drawPortX = (GLfloat) drawPortX; + this->drawPortY = (GLfloat) drawPortY; this->transparency = transparency; } -bool cOglCmdRenderFbToBufferFb::Execute(void) { - GLfloat x2 = x + fb->ViewportWidth(); //right - GLfloat y2 = y + fb->ViewportHeight(); //bottom +bool cOglCmdRenderFbToBufferFb::Execute(void) +{ + GLfloat x2 = x + fb->ViewportWidth(); //right + GLfloat y2 = y + fb->ViewportHeight(); //bottom - GLfloat texX1 = drawPortX / (GLfloat)fb->Width(); - GLfloat texY1 = drawPortY / (GLfloat)fb->Height(); + GLfloat texX1 = drawPortX / (GLfloat) fb->Width(); + GLfloat texY1 = drawPortY / (GLfloat) fb->Height(); GLfloat texX2 = texX1 + 1.0f; GLfloat texY2 = texY1 + 1.0f; - + if (fb->Scrollable()) { - GLfloat pageHeight = (GLfloat)fb->ViewportHeight() / (GLfloat)fb->Height(); - texX1 = abs(drawPortX) / (GLfloat)fb->Width(); - texY1 = 1.0f - pageHeight - abs(drawPortY) / (GLfloat)fb->Height(); - texX2 = texX1 + (GLfloat)fb->ViewportWidth() / (GLfloat)fb->Width(); + GLfloat pageHeight = (GLfloat) fb->ViewportHeight() / (GLfloat) fb->Height(); + + texX1 = abs(drawPortX) / (GLfloat) fb->Width(); + texY1 = 1.0f - pageHeight - abs(drawPortY) / (GLfloat) fb->Height(); + texX2 = texX1 + (GLfloat) fb->ViewportWidth() / (GLfloat) fb->Width(); // x2 = x + fb->Width(); texY2 = texY1 + pageHeight; } GLfloat quadVertices[] = { // Pos // TexCoords - x , y , texX1, texY2, //left top - x , y2, texX1, texY1, //left bottom - x2, y2, texX2, texY1, //right bottom + x, y, texX1, texY2, //left top + x, y2, texX1, texY1, //left bottom + x2, y2, texX2, texY1, //right bottom - x , y , texX1, texY2, //left top - x2, y2, texX2, texY1, //right bottom - x2, y , texX2, texY2 //right top + x, y, texX1, texY2, //left top + x2, y2, texX2, texY1, //right bottom + x2, y, texX2, texY2 //right top }; VertexBuffers[vbTexture]->ActivateShader(); @@ -810,8 +867,8 @@ bool cOglCmdRenderFbToBufferFb::Execute(void) { if (!fb->BindTexture()) return false; - - VertexBuffers[vbTexture]->Bind(); + + VertexBuffers[vbTexture]->Bind(); VertexBuffers[vbTexture]->SetVertexData(quadVertices); VertexBuffers[vbTexture]->DrawArrays(); VertexBuffers[vbTexture]->Unbind(); @@ -821,36 +878,40 @@ bool cOglCmdRenderFbToBufferFb::Execute(void) { } //------------------ cOglCmdCopyBufferToOutputFb -------------------- -cOglCmdCopyBufferToOutputFb::cOglCmdCopyBufferToOutputFb(cOglFb *fb, cOglOutputFb *oFb, GLint x, GLint y) : cOglCmd(fb) { +cOglCmdCopyBufferToOutputFb::cOglCmdCopyBufferToOutputFb(cOglFb * fb, cOglOutputFb * oFb, GLint x, GLint y):cOglCmd(fb) +{ this->oFb = oFb; this->x = x; this->y = y; } -extern unsigned char *posd; +extern unsigned char *posd; + +bool cOglCmdCopyBufferToOutputFb::Execute(void) +{ -bool cOglCmdCopyBufferToOutputFb::Execute(void) { - pthread_mutex_lock(&OSDMutex); fb->BindRead(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); if (posd) - glReadPixels(0, 0 ,fb->Width(), fb->Height(),GL_RGBA,GL_UNSIGNED_BYTE,posd); - glFlush(); + glReadPixels(0, 0, fb->Width(), fb->Height(), GL_RGBA, GL_UNSIGNED_BYTE, posd); + glFlush(); pthread_mutex_unlock(&OSDMutex); - ActivateOsd(oFb->texture,x, y, fb->Width() ,fb->Height()); + ActivateOsd(oFb->texture, x, y, fb->Width(), fb->Height()); return true; } //------------------ cOglCmdFill -------------------- -cOglCmdFill::cOglCmdFill(cOglFb *fb, GLint color) : cOglCmd(fb) { +cOglCmdFill::cOglCmdFill(cOglFb * fb, GLint color):cOglCmd(fb) +{ this->color = color; } -bool cOglCmdFill::Execute(void) { +bool cOglCmdFill::Execute(void) +{ glm::vec4 col; ConvertColor(color, col); fb->Bind(); @@ -861,7 +922,9 @@ bool cOglCmdFill::Execute(void) { } //------------------ cOglCmdDrawRectangle -------------------- -cOglCmdDrawRectangle::cOglCmdDrawRectangle( cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color) : cOglCmd(fb) { +cOglCmdDrawRectangle::cOglCmdDrawRectangle(cOglFb * fb, GLint x, GLint y, GLint width, GLint height, GLint color):cOglCmd + (fb) +{ this->x = x; this->y = y; this->width = width; @@ -869,17 +932,18 @@ cOglCmdDrawRectangle::cOglCmdDrawRectangle( cOglFb *fb, GLint x, GLint y, GLint this->color = color; } -bool cOglCmdDrawRectangle::Execute(void) { +bool cOglCmdDrawRectangle::Execute(void) +{ GLfloat x1 = x; GLfloat y1 = y; GLfloat x2 = x + width; GLfloat y2 = y + height; GLfloat vertices[] = { - x1, y1, //left top - x2, y1, //right top - x2, y2, //right bottom - x1, y2 //left bottom + x1, y1, //left top + x2, y1, //right top + x2, y2, //right bottom + x1, y2 //left bottom }; VertexBuffers[vbRect]->ActivateShader(); @@ -904,7 +968,9 @@ bool cOglCmdDrawRectangle::Execute(void) { ///< 1..4 draws only the first, second, third or fourth quadrant, respectively ///< 5..8 draws the right, top, left or bottom half, respectively ///< -1..-4 draws the inverted part of the given quadrant -cOglCmdDrawEllipse::cOglCmdDrawEllipse( cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint quadrants) : cOglCmd(fb) { +cOglCmdDrawEllipse::cOglCmdDrawEllipse(cOglFb * fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint quadrants):cOglCmd + (fb) +{ this->x = x; this->y = y; this->width = width; @@ -913,7 +979,8 @@ cOglCmdDrawEllipse::cOglCmdDrawEllipse( cOglFb *fb, GLint x, GLint y, GLint widt this->quadrants = quadrants; } -bool cOglCmdDrawEllipse::Execute(void) { +bool cOglCmdDrawEllipse::Execute(void) +{ int numVertices = 0; GLfloat *vertices = NULL; @@ -921,10 +988,20 @@ bool cOglCmdDrawEllipse::Execute(void) { case 0: vertices = CreateVerticesFull(numVertices); break; - case 1: case 2: case 3: case 4: case -1: case -2: case -3: case -4: + case 1: + case 2: + case 3: + case 4: + case -1: + case -2: + case -3: + case -4: vertices = CreateVerticesQuadrant(numVertices); break; - case 5: case 6: case 7: case 8: + case 5: + case 6: + case 7: + case 8: vertices = CreateVerticesHalf(numVertices); break; default: @@ -945,34 +1022,40 @@ bool cOglCmdDrawEllipse::Execute(void) { VertexBuffers[vbEllipse]->EnableBlending(); fb->Unbind(); - delete[] vertices; + delete[]vertices; return true; } -GLfloat *cOglCmdDrawEllipse::CreateVerticesFull(int &numVertices) { +GLfloat *cOglCmdDrawEllipse::CreateVerticesFull(int &numVertices) +{ int size = 364; - numVertices = size/2; - GLfloat radiusX = (GLfloat)width/2; - GLfloat radiusY = (GLfloat)height/2; + + numVertices = size / 2; + GLfloat radiusX = (GLfloat) width / 2; + GLfloat radiusY = (GLfloat) height / 2; GLfloat *vertices = new GLfloat[size]; + vertices[0] = x + radiusX; vertices[1] = y + radiusY; - for (int i=0; i <= 180; i++) { - vertices[2*i+2] = x + radiusX + (GLfloat)cos(2*i * M_PI / 180.0f)*radiusX; - vertices[2*i+3] = y + radiusY - (GLfloat)sin(2*i * M_PI / 180.0f)*radiusY; + for (int i = 0; i <= 180; i++) { + vertices[2 * i + 2] = x + radiusX + (GLfloat) cos(2 * i * M_PI / 180.0f) * radiusX; + vertices[2 * i + 3] = y + radiusY - (GLfloat) sin(2 * i * M_PI / 180.0f) * radiusY; } return vertices; } -GLfloat *cOglCmdDrawEllipse::CreateVerticesQuadrant(int &numVertices) { +GLfloat *cOglCmdDrawEllipse::CreateVerticesQuadrant(int &numVertices) +{ int size = 94; - numVertices = size/2; - GLfloat radiusX = (GLfloat)width; - GLfloat radiusY = (GLfloat)height; + + numVertices = size / 2; + GLfloat radiusX = (GLfloat) width; + GLfloat radiusY = (GLfloat) height; GLint transX = 0; GLint transY = 0; GLint startAngle = 0; GLfloat *vertices = new GLfloat[size]; + switch (quadrants) { case 1: vertices[0] = x; @@ -1023,34 +1106,37 @@ GLfloat *cOglCmdDrawEllipse::CreateVerticesQuadrant(int &numVertices) { default: break; } - for (int i=0; i <= 45; i++) { - vertices[2*i+2] = x + transX + (GLfloat)cos((2*i + startAngle) * M_PI / 180.0f)*radiusX; - vertices[2*i+3] = y + transY - (GLfloat)sin((2*i + startAngle) * M_PI / 180.0f)*radiusY; + for (int i = 0; i <= 45; i++) { + vertices[2 * i + 2] = x + transX + (GLfloat) cos((2 * i + startAngle) * M_PI / 180.0f) * radiusX; + vertices[2 * i + 3] = y + transY - (GLfloat) sin((2 * i + startAngle) * M_PI / 180.0f) * radiusY; } return vertices; } -GLfloat *cOglCmdDrawEllipse::CreateVerticesHalf(int &numVertices) { +GLfloat *cOglCmdDrawEllipse::CreateVerticesHalf(int &numVertices) +{ int size = 184; - numVertices = size/2; + + numVertices = size / 2; GLfloat radiusX = 0.0f; GLfloat radiusY = 0.0f; GLint transX = 0; GLint transY = 0; GLint startAngle = 0; GLfloat *vertices = new GLfloat[size]; + switch (quadrants) { case 5: - radiusX = (GLfloat)width; - radiusY = (GLfloat)height/2; + radiusX = (GLfloat) width; + radiusY = (GLfloat) height / 2; vertices[0] = x; vertices[1] = y + radiusY; startAngle = 270; transY = radiusY; break; case 6: - radiusX = (GLfloat)width/2; - radiusY = (GLfloat)height; + radiusX = (GLfloat) width / 2; + radiusY = (GLfloat) height; vertices[0] = x + radiusX; vertices[1] = y + radiusY; startAngle = 0; @@ -1058,8 +1144,8 @@ GLfloat *cOglCmdDrawEllipse::CreateVerticesHalf(int &numVertices) { transY = radiusY; break; case 7: - radiusX = (GLfloat)width; - radiusY = (GLfloat)height/2; + radiusX = (GLfloat) width; + radiusY = (GLfloat) height / 2; vertices[0] = x + radiusX; vertices[1] = y + radiusY; startAngle = 90; @@ -1067,8 +1153,8 @@ GLfloat *cOglCmdDrawEllipse::CreateVerticesHalf(int &numVertices) { transY = radiusY; break; case 8: - radiusX = (GLfloat)width/2; - radiusY = (GLfloat)height; + radiusX = (GLfloat) width / 2; + radiusY = (GLfloat) height; vertices[0] = x + radiusX; vertices[1] = y; startAngle = 180; @@ -1077,9 +1163,9 @@ GLfloat *cOglCmdDrawEllipse::CreateVerticesHalf(int &numVertices) { default: break; } - for (int i=0; i <= 90; i++) { - vertices[2*i+2] = x + transX + (GLfloat)cos((2*i + startAngle) * M_PI / 180.0f)*radiusX; - vertices[2*i+3] = y + transY - (GLfloat)sin((2*i + startAngle) * M_PI / 180.0f)*radiusY; + for (int i = 0; i <= 90; i++) { + vertices[2 * i + 2] = x + transX + (GLfloat) cos((2 * i + startAngle) * M_PI / 180.0f) * radiusX; + vertices[2 * i + 3] = y + transY - (GLfloat) sin((2 * i + startAngle) * M_PI / 180.0f) * radiusY; } return vertices; } @@ -1094,7 +1180,9 @@ GLfloat *cOglCmdDrawEllipse::CreateVerticesHalf(int &numVertices) { ///< 5: vertical, rising, upper ///< 6: vertical, falling, lower ///< 7: vertical, falling, upper -cOglCmdDrawSlope::cOglCmdDrawSlope( cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint type) : cOglCmd(fb) { +cOglCmdDrawSlope::cOglCmdDrawSlope(cOglFb * fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint type):cOglCmd + (fb) +{ this->x = x; this->y = y; this->width = width; @@ -1103,49 +1191,56 @@ cOglCmdDrawSlope::cOglCmdDrawSlope( cOglFb *fb, GLint x, GLint y, GLint width, G this->type = type; } -bool cOglCmdDrawSlope::Execute(void) { - bool falling = type & 0x02; +bool cOglCmdDrawSlope::Execute(void) +{ + bool falling = type & 0x02; bool vertical = type & 0x04; int steps = 100; + if (width < 100) steps = 25; int numVertices = steps + 2; - GLfloat *vertices = new GLfloat[numVertices*2]; + GLfloat *vertices = new GLfloat[numVertices * 2]; switch (type) { - case 0: case 4: - vertices[0] = (GLfloat)(x + width); - vertices[1] = (GLfloat)(y + height); + case 0: + case 4: + vertices[0] = (GLfloat) (x + width); + vertices[1] = (GLfloat) (y + height); break; - case 1: case 5: - vertices[0] = (GLfloat)x; - vertices[1] = (GLfloat)y; + case 1: + case 5: + vertices[0] = (GLfloat) x; + vertices[1] = (GLfloat) y; break; - case 2: case 6: - vertices[0] = (GLfloat)x; - vertices[1] = (GLfloat)(y + height); + case 2: + case 6: + vertices[0] = (GLfloat) x; + vertices[1] = (GLfloat) (y + height); break; - case 3: case 7: - vertices[0] = (GLfloat)(x + width); - vertices[1] = (GLfloat)y; + case 3: + case 7: + vertices[0] = (GLfloat) (x + width); + vertices[1] = (GLfloat) y; break; default: - vertices[0] = (GLfloat)(x); - vertices[1] = (GLfloat)(y); + vertices[0] = (GLfloat) (x); + vertices[1] = (GLfloat) (y); break; } for (int i = 0; i <= steps; i++) { GLfloat c = cos(i * M_PI / steps); + if (falling) c = -c; if (vertical) { - vertices[2*i+2] = (GLfloat)x + (GLfloat)width / 2.0f + (GLfloat)width * c / 2.0f; - vertices[2*i+3] = (GLfloat)y + (GLfloat)i * ((GLfloat)height) / steps ; + vertices[2 * i + 2] = (GLfloat) x + (GLfloat) width / 2.0f + (GLfloat) width *c / 2.0f; + vertices[2 * i + 3] = (GLfloat) y + (GLfloat) i *((GLfloat) height) / steps; } else { - vertices[2*i+2] = (GLfloat)x + (GLfloat)i * ((GLfloat)width) / steps ; - vertices[2*i+3] = (GLfloat)y + (GLfloat)height / 2.0f + (GLfloat)height * c / 2.0f; + vertices[2 * i + 2] = (GLfloat) x + (GLfloat) i *((GLfloat) width) / steps; + vertices[2 * i + 3] = (GLfloat) y + (GLfloat) height / 2.0f + (GLfloat) height *c / 2.0f; } } @@ -1163,28 +1258,32 @@ bool cOglCmdDrawSlope::Execute(void) { VertexBuffers[vbSlope]->EnableBlending(); fb->Unbind(); - delete[] vertices; + delete[]vertices; return true; } //------------------ cOglCmdDrawText -------------------- -cOglCmdDrawText::cOglCmdDrawText( cOglFb *fb, GLint x, GLint y, unsigned int *symbols, GLint limitX, - const char *name, int fontSize, tColor colorText) : cOglCmd(fb), fontName(name) { +cOglCmdDrawText::cOglCmdDrawText(cOglFb * fb, GLint x, GLint y, unsigned int *symbols, GLint limitX, const char *name, + int fontSize, tColor colorText):cOglCmd(fb), fontName(name) +{ this->x = x; this->y = y; this->limitX = limitX; this->colorText = colorText; this->fontSize = fontSize; this->symbols = symbols; - this->fontName = name; + this->fontName = name; } -cOglCmdDrawText::~cOglCmdDrawText(void) { +cOglCmdDrawText::~cOglCmdDrawText(void) +{ free(symbols); } -bool cOglCmdDrawText::Execute(void) { +bool cOglCmdDrawText::Execute(void) +{ cOglFont *f = cOglFont::Get(*fontName, fontSize); + if (!f) return false; @@ -1205,30 +1304,31 @@ bool cOglCmdDrawText::Execute(void) { for (int i = 0; symbols[i]; i++) { sym = symbols[i]; cOglGlyph *g = f->Glyph(sym); + if (!g) { esyslog("[softhddev]ERROR: could not load glyph %lx", sym); } - if ( limitX && xGlyph + g->AdvanceX() > limitX ) { + if (limitX && xGlyph + g->AdvanceX() > limitX) { break; - } + } kerning = f->Kerning(g, prevSym); prevSym = sym; - GLfloat x1 = xGlyph + kerning + g->BearingLeft(); //left - GLfloat y1 = y + (fontHeight - bottom - g->BearingTop()); //top - GLfloat x2 = x1 + g->Width(); //right - GLfloat y2 = y1 + g->Height(); //bottom + GLfloat x1 = xGlyph + kerning + g->BearingLeft(); //left + GLfloat y1 = y + (fontHeight - bottom - g->BearingTop()); //top + GLfloat x2 = x1 + g->Width(); //right + GLfloat y2 = y1 + g->Height(); //bottom GLfloat vertices[] = { - x1, y2, 0.0, 1.0, // left bottom - x1, y1, 0.0, 0.0, // left top - x2, y1, 1.0, 0.0, // right top + x1, y2, 0.0, 1.0, // left bottom + x1, y1, 0.0, 0.0, // left top + x2, y1, 1.0, 0.0, // right top - x1, y2, 0.0, 1.0, // left bottom - x2, y1, 1.0, 0.0, // right top - x2, y2, 1.0, 1.0 // right bottom + x1, y2, 0.0, 1.0, // left bottom + x2, y1, 1.0, 0.0, // right top + x2, y2, 1.0, 1.0 // right bottom }; g->BindTexture(); @@ -1237,7 +1337,7 @@ bool cOglCmdDrawText::Execute(void) { xGlyph += kerning + g->AdvanceX(); - if ( xGlyph > fb->Width() - 1 ) + if (xGlyph > fb->Width() - 1) break; } glBindTexture(GL_TEXTURE_2D, 0); @@ -1247,7 +1347,9 @@ bool cOglCmdDrawText::Execute(void) { } //------------------ cOglCmdDrawImage -------------------- -cOglCmdDrawImage::cOglCmdDrawImage(cOglFb *fb, tColor *argb, GLint width, GLint height, GLint x, GLint y, bool overlay, double scaleX, double scaleY): cOglCmd(fb) { +cOglCmdDrawImage::cOglCmdDrawImage(cOglFb * fb, tColor * argb, GLint width, GLint height, GLint x, GLint y, + bool overlay, double scaleX, double scaleY):cOglCmd(fb) +{ this->argb = argb; this->x = x; this->y = y; @@ -1259,62 +1361,54 @@ cOglCmdDrawImage::cOglCmdDrawImage(cOglFb *fb, tColor *argb, GLint width, GLint } -cOglCmdDrawImage::~cOglCmdDrawImage(void) { +cOglCmdDrawImage::~cOglCmdDrawImage(void) +{ free(argb); } -bool cOglCmdDrawImage::Execute(void) { +bool cOglCmdDrawImage::Execute(void) +{ GLuint texture; + #ifdef USE_DRM -// pthread_mutex_lock(&OSDMutex); - GlxDrawopengl(); // here we need the Shared Context for upload - GlxCheck(); +// pthread_mutex_lock(&OSDMutex); + GlxDrawopengl(); // here we need the Shared Context for upload + GlxCheck(); #endif glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RGBA8, - width, - height, - 0, - GL_BGRA, - GL_UNSIGNED_INT_8_8_8_8_REV, - argb - ); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, argb); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 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_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); - glFlush(); + glFlush(); #ifdef USE_DRM - GlxInitopengl(); // Reset Context - GlxCheck(); -// pthread_mutex_unlock(&OSDMutex); + GlxInitopengl(); // Reset Context + GlxCheck(); +// pthread_mutex_unlock(&OSDMutex); #endif - GLfloat x1 = x; //left - GLfloat y1 = y; //top - GLfloat x2 = x + width; //right - GLfloat y2 = y + height; //bottom + GLfloat x1 = x; //left + GLfloat y1 = y; //top + GLfloat x2 = x + width; //right + GLfloat y2 = y + height; //bottom GLfloat quadVertices[] = { - x1, y2, 0.0, 1.0, // left bottom - x1, y1, 0.0, 0.0, // left top - x2, y1, 1.0, 0.0, // right top + x1, y2, 0.0, 1.0, // left bottom + x1, y1, 0.0, 0.0, // left top + x2, y1, 1.0, 0.0, // right top - x1, y2, 0.0, 1.0, // left bottom - x2, y1, 1.0, 0.0, // right top - x2, y2, 1.0, 1.0 // right bottom + x1, y2, 0.0, 1.0, // left bottom + x2, y1, 1.0, 0.0, // right top + x2, y2, 1.0, 1.0 // right bottom }; VertexBuffers[vbTexture]->ActivateShader(); VertexBuffers[vbTexture]->SetShaderAlpha(255); VertexBuffers[vbTexture]->SetShaderProjectionMatrix(fb->Width(), fb->Height()); - fb->Bind(); glBindTexture(GL_TEXTURE_2D, texture); if (overlay) @@ -1333,27 +1427,29 @@ bool cOglCmdDrawImage::Execute(void) { } //------------------ cOglCmdDrawTexture -------------------- -cOglCmdDrawTexture::cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x, GLint y): cOglCmd(fb) { +cOglCmdDrawTexture::cOglCmdDrawTexture(cOglFb * fb, sOglImage * imageRef, GLint x, GLint y):cOglCmd(fb) +{ this->imageRef = imageRef; this->x = x; this->y = y; } -bool cOglCmdDrawTexture::Execute(void) { - GLfloat x1 = x; //top - GLfloat y1 = y; //left - GLfloat x2 = x + imageRef->width; //right - GLfloat y2 = y + imageRef->height; //bottom +bool cOglCmdDrawTexture::Execute(void) +{ + GLfloat x1 = x; //top + GLfloat y1 = y; //left + GLfloat x2 = x + imageRef->width; //right + GLfloat y2 = y + imageRef->height; //bottom GLfloat quadVertices[] = { // Pos // TexCoords - x1, y1, 0.0f, 0.0f, //left bottom - x1, y2, 0.0f, 1.0f, //left top - x2, y2, 1.0f, 1.0f, //right top + x1, y1, 0.0f, 0.0f, //left bottom + x1, y2, 0.0f, 1.0f, //left top + x2, y2, 1.0f, 1.0f, //right top - x1, y1, 0.0f, 0.0f, //left bottom - x2, y2, 1.0f, 1.0f, //right top - x2, y1, 1.0f, 0.0f //right bottom + x1, y1, 0.0f, 0.0f, //left bottom + x2, y2, 1.0f, 1.0f, //right top + x2, y1, 1.0f, 0.0f //right bottom }; VertexBuffers[vbTexture]->ActivateShader(); @@ -1371,57 +1467,52 @@ bool cOglCmdDrawTexture::Execute(void) { return true; } - //------------------ cOglCmdStoreImage -------------------- -cOglCmdStoreImage::cOglCmdStoreImage(sOglImage *imageRef, tColor *argb) : cOglCmd(NULL) { +cOglCmdStoreImage::cOglCmdStoreImage(sOglImage * imageRef, tColor * argb):cOglCmd(NULL) +{ this->imageRef = imageRef; data = argb; } -cOglCmdStoreImage::~cOglCmdStoreImage(void) { +cOglCmdStoreImage::~cOglCmdStoreImage(void) +{ free(data); } -bool cOglCmdStoreImage::Execute(void) { +bool cOglCmdStoreImage::Execute(void) +{ #ifdef USE_DRM -// pthread_mutex_lock(&OSDMutex); - GlxDrawopengl(); // here we need the Shared Context for upload - GlxCheck(); +// pthread_mutex_lock(&OSDMutex); + GlxDrawopengl(); // here we need the Shared Context for upload + GlxCheck(); #endif glGenTextures(1, &imageRef->texture); glBindTexture(GL_TEXTURE_2D, imageRef->texture); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RGBA8, - imageRef->width, - imageRef->height, - 0, - GL_BGRA, - GL_UNSIGNED_INT_8_8_8_8_REV, - data - ); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageRef->width, imageRef->height, 0, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8_REV, data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 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_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); - glFlush(); + glFlush(); #ifdef USE_DRM - GlxInitopengl(); // Reset Context - GlxCheck(); -// pthread_mutex_lock(&OSDMutex); + GlxInitopengl(); // Reset Context + GlxCheck(); +// pthread_mutex_lock(&OSDMutex); #endif return true; } //------------------ cOglCmdDropImage -------------------- -cOglCmdDropImage::cOglCmdDropImage(sOglImage *imageRef, cCondWait *wait) : cOglCmd(NULL) { +cOglCmdDropImage::cOglCmdDropImage(sOglImage * imageRef, cCondWait * wait):cOglCmd(NULL) +{ this->imageRef = imageRef; this->wait = wait; } -bool cOglCmdDropImage::Execute(void) { +bool cOglCmdDropImage::Execute(void) +{ if (imageRef->texture != GL_NONE) glDeleteTextures(1, &imageRef->texture); wait->Signal(); @@ -1431,7 +1522,8 @@ bool cOglCmdDropImage::Execute(void) { /****************************************************************************** * cOglThread ******************************************************************************/ -cOglThread::cOglThread(cCondWait *startWait, int maxCacheSize) : cThread("oglThread") { +cOglThread::cOglThread(cCondWait * startWait, int maxCacheSize):cThread("oglThread") +{ stalled = false; memCached = 0; @@ -1450,12 +1542,15 @@ cOglThread::cOglThread(cCondWait *startWait, int maxCacheSize) : cThread("oglThr } -cOglThread::~cOglThread() { +cOglThread::~cOglThread() +{ delete wait; + wait = NULL; } -void cOglThread::Stop(void) { +void cOglThread::Stop(void) +{ for (int i = 0; i < OGL_MAX_OSDIMAGES; i++) { if (imageCache[i].used) { DropImageData(i); @@ -1465,11 +1560,13 @@ void cOglThread::Stop(void) { stalled = false; } -void cOglThread::DoCmd(cOglCmd* cmd) { +void cOglThread::DoCmd(cOglCmd * cmd) +{ while (stalled) cCondWait::SleepMs(10); bool doSignal = false; + Lock(); if (commands.size() == 0) doSignal = true; @@ -1484,37 +1581,39 @@ void cOglThread::DoCmd(cOglCmd* cmd) { wait->Signal(); } -int cOglThread::StoreImage(const cImage &image) { - - if (!maxCacheSize) { - return 0; - } +int cOglThread::StoreImage(const cImage & image) +{ + + if (!maxCacheSize) { + return 0; + } if (image.Width() > maxTextureSize || image.Height() > maxTextureSize) { - esyslog("[softhddev] cannot store image of %dpx x %dpx " - "(maximum size is %dpx x %dpx) - falling back to " - "cOsdProvider::StoreImageData()", - image.Width(), image.Height(), - maxTextureSize, maxTextureSize); + esyslog("[softhddev] cannot store image of %dpx x %dpx " "(maximum size is %dpx x %dpx) - falling back to " + "cOsdProvider::StoreImageData()", image.Width(), image.Height(), maxTextureSize, maxTextureSize); return 0; } int imgSize = image.Width() * image.Height(); int newMemUsed = imgSize * sizeof(tColor) + memCached; + if (newMemUsed > maxCacheSize) { float cachedMB = memCached / 1024.0f / 1024.0f; float maxMB = maxCacheSize / 1024.0f / 1024.0f; + esyslog("[softhddev]Maximum size for GPU cache reached. Used: %.2fMB Max: %.2fMB", cachedMB, maxMB); return 0; } int slot = GetFreeSlot(); + if (!slot) return 0; tColor *argb = MALLOC(tColor, imgSize); + if (!argb) { - esyslog("[softhddev]memory allocation of %ld kb for OSD image failed", (imgSize * sizeof(tColor)) / 1024); + esyslog("[softhddev]memory allocation of %ld kb for OSD image failed", (imgSize * sizeof(tColor)) / 1024); ClearSlot(slot); slot = 0; return 0; @@ -1523,27 +1622,32 @@ int cOglThread::StoreImage(const cImage &image) { memcpy(argb, image.Data(), sizeof(tColor) * imgSize); sOglImage *imageRef = GetImageRef(slot); + imageRef->width = image.Width(); imageRef->height = image.Height(); DoCmd(new cOglCmdStoreImage(imageRef, argb)); cTimeMs timer(5000); + while (imageRef->used && imageRef->texture == 0 && !timer.TimedOut()) cCondWait::SleepMs(2); if (imageRef->texture == GL_NONE) { - esyslog("[softhddev]failed to store OSD image texture! (%s)", timer.TimedOut() ? "timed out" : "allocation failed"); + esyslog("[softhddev]failed to store OSD image texture! (%s)", + timer.TimedOut()? "timed out" : "allocation failed"); DropImageData(slot); slot = 0; } - memCached += imgSize * sizeof(tColor); + memCached += imgSize * sizeof(tColor); return slot; } -int cOglThread::GetFreeSlot(void) { +int cOglThread::GetFreeSlot(void) +{ Lock(); int slot = 0; + for (int i = 0; i < OGL_MAX_OSDIMAGES && !slot; i++) { if (!imageCache[i].used) { imageCache[i].used = true; @@ -1554,8 +1658,10 @@ int cOglThread::GetFreeSlot(void) { return slot; } -void cOglThread::ClearSlot(int slot) { +void cOglThread::ClearSlot(int slot) +{ int i = -slot - 1; + if (i >= 0 && i < OGL_MAX_OSDIMAGES) { Lock(); imageCache[i].used = false; @@ -1566,27 +1672,33 @@ void cOglThread::ClearSlot(int slot) { } } -sOglImage *cOglThread::GetImageRef(int slot) { +sOglImage *cOglThread::GetImageRef(int slot) +{ int i = -slot - 1; + if (0 <= i && i < OGL_MAX_OSDIMAGES) return &imageCache[i]; return 0; } -void cOglThread::DropImageData(int imageHandle) { +void cOglThread::DropImageData(int imageHandle) +{ sOglImage *imageRef = GetImageRef(imageHandle); + if (!imageRef) return; int imgSize = imageRef->width * imageRef->height * sizeof(tColor); + memCached -= imgSize; cCondWait dropWait; + DoCmd(new cOglCmdDropImage(imageRef, &dropWait)); dropWait.Wait(); ClearSlot(imageHandle); } - -void cOglThread::Action(void) { +void cOglThread::Action(void) +{ if (!InitOpenGL()) { esyslog("[softhddev]Could not initiate OpenGL Context"); Cleanup(); @@ -1626,7 +1738,7 @@ void cOglThread::Action(void) { startWait->Signal(); stalled = false; - while(Running()) { + while (Running()) { if (commands.empty()) { wait->Wait(20); @@ -1634,13 +1746,15 @@ void cOglThread::Action(void) { } Lock(); - cOglCmd* cmd = commands.front(); + cOglCmd *cmd = commands.front(); + commands.pop(); Unlock(); // uint64_t start = cTimeMs::Now(); cmd->Execute(); // esyslog("[softhddev]\"%s\", %dms, %d commands left, time %" PRIu64 "", cmd->Description(), (int)(cTimeMs::Now() - start), commands.size(), cTimeMs::Now()); delete cmd; + if (stalled && commands.size() < OGL_CMDQUEUE_SIZE / 2) stalled = false; } @@ -1650,13 +1764,13 @@ void cOglThread::Action(void) { dsyslog("[softhddev]OpenGL Worker Thread Ended"); } - - -bool cOglThread::InitOpenGL(void) { +bool cOglThread::InitOpenGL(void) +{ #ifdef USE_DRM - GlxInitopengl(); + GlxInitopengl(); #else const char *displayName = X11DisplayName; + if (!displayName) { displayName = getenv("DISPLAY"); if (!displayName) { @@ -1667,16 +1781,18 @@ bool cOglThread::InitOpenGL(void) { dsyslog("[softhddev]OpenGL using display %s", displayName); int argc = 3; - char* buffer[3]; + char *buffer[3]; + buffer[0] = strdup("openglosd"); buffer[1] = strdup("-display"); buffer[2] = strdup(displayName); char **argv = buffer; + glutInit(&argc, argv); - glutInitDisplayMode (GLUT_SINGLE | GLUT_RGBA | GLUT_ALPHA); - glutInitWindowSize (1, 1); - glutInitWindowPosition (0, 0); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_ALPHA); + glutInitWindowSize(1, 1); + glutInitWindowPosition(0, 0); glutCreateWindow("openglosd"); glutHideWindow(); free(buffer[0]); @@ -1684,38 +1800,44 @@ bool cOglThread::InitOpenGL(void) { free(buffer[2]); GLenum err = glewInit(); - if( err != GLEW_OK) { + + if (err != GLEW_OK) { esyslog("[softhddev]glewInit failed, aborting\n"); return false; } #endif - + VertexBuffers[vbText]->EnableBlending(); glDisable(GL_DEPTH_TEST); return true; } -bool cOglThread::InitShaders(void) { - for (int i=0; i < stCount; i++) { +bool cOglThread::InitShaders(void) +{ + for (int i = 0; i < stCount; i++) { cShader *shader = new cShader(); - if (!shader->Load((eShaderType)i)) + + if (!shader->Load((eShaderType) i)) return false; Shaders[i] = shader; } return true; } -void cOglThread::DeleteShaders(void) { - for (int i=0; i < stCount; i++) +void cOglThread::DeleteShaders(void) +{ + for (int i = 0; i < stCount; i++) delete Shaders[i]; } -bool cOglThread::InitVdpauInterop(void) { +bool cOglThread::InitVdpauInterop(void) +{ #if 0 void *vdpDevice = GetVDPAUDevice(); void *procAdress = GetVDPAUProcAdress(); - while (glGetError() != GL_NO_ERROR); + + while (glGetError() != GL_NO_ERROR) ; glVDPAUInitNV(vdpDevice, procAdress); if (glGetError() != GL_NO_ERROR) return false; @@ -1723,9 +1845,11 @@ bool cOglThread::InitVdpauInterop(void) { return true; } -bool cOglThread::InitVertexBuffers(void) { - for (int i=0; i < vbCount; i++) { +bool cOglThread::InitVertexBuffers(void) +{ + for (int i = 0; i < vbCount; i++) { cOglVb *vb = new cOglVb(i); + if (!vb->Init()) return false; VertexBuffers[i] = vb; @@ -1733,13 +1857,15 @@ bool cOglThread::InitVertexBuffers(void) { return true; } -void cOglThread::DeleteVertexBuffers(void) { - for (int i=0; i < vbCount; i++) { +void cOglThread::DeleteVertexBuffers(void) +{ + for (int i = 0; i < vbCount; i++) { delete VertexBuffers[i]; } } -void cOglThread::Cleanup(void) { +void cOglThread::Cleanup(void) +{ esyslog("[softhddev]OglThread cleanup\n"); pthread_mutex_lock(&OSDMutex); OsdClose(); @@ -1754,7 +1880,7 @@ void cOglThread::Cleanup(void) { #ifndef USE_DRM glutExit(); #else - GlxDestroy(); + GlxDestroy(); #endif pthread_mutex_unlock(&OSDMutex); } @@ -1763,21 +1889,26 @@ void cOglThread::Cleanup(void) { * cOglPixmap ****************************************************************************************/ -cOglPixmap::cOglPixmap(std::shared_ptr oglThread, int Layer, const cRect &ViewPort, const cRect &DrawPort) : cPixmap(Layer, ViewPort, DrawPort) { +cOglPixmap::cOglPixmap(std::shared_ptr < cOglThread > oglThread, int Layer, const cRect & ViewPort, + const cRect & DrawPort):cPixmap(Layer, ViewPort, DrawPort) +{ this->oglThread = oglThread; - int width = DrawPort.IsEmpty() ? ViewPort.Width() : DrawPort.Width(); - int height = DrawPort.IsEmpty() ? ViewPort.Height() : DrawPort.Height(); + int width = DrawPort.IsEmpty()? ViewPort.Width() : DrawPort.Width(); + int height = DrawPort.IsEmpty()? ViewPort.Height() : DrawPort.Height(); + fb = new cOglFb(width, height, ViewPort.Width(), ViewPort.Height()); dirty = true; } -cOglPixmap::~cOglPixmap(void) { +cOglPixmap::~cOglPixmap(void) +{ if (!oglThread->Active()) return; oglThread->DoCmd(new cOglCmdDeleteFb(fb)); } -void cOglPixmap::SetAlpha(int Alpha) { +void cOglPixmap::SetAlpha(int Alpha) +{ Alpha = constrain(Alpha, ALPHA_TRANSPARENT, ALPHA_OPAQUE); if (Alpha != cPixmap::Alpha()) { cPixmap::SetAlpha(Alpha); @@ -1785,23 +1916,27 @@ void cOglPixmap::SetAlpha(int Alpha) { } } -void cOglPixmap::SetTile(bool Tile) { +void cOglPixmap::SetTile(bool Tile) +{ cPixmap::SetTile(Tile); SetDirty(); } -void cOglPixmap::SetViewPort(const cRect &Rect) { +void cOglPixmap::SetViewPort(const cRect & Rect) +{ cPixmap::SetViewPort(Rect); SetDirty(); } -void cOglPixmap::SetDrawPortPoint(const cPoint &Point, bool Dirty) { +void cOglPixmap::SetDrawPortPoint(const cPoint & Point, bool Dirty) +{ cPixmap::SetDrawPortPoint(Point, Dirty); if (Dirty) SetDirty(); } -void cOglPixmap::Clear(void) { +void cOglPixmap::Clear(void) +{ if (!oglThread->Active()) return; LOCK_PIXMAPS; @@ -1810,7 +1945,8 @@ void cOglPixmap::Clear(void) { MarkDrawPortDirty(DrawPort()); } -void cOglPixmap::Fill(tColor Color) { +void cOglPixmap::Fill(tColor Color) +{ if (!oglThread->Active()) return; LOCK_PIXMAPS; @@ -1819,10 +1955,12 @@ void cOglPixmap::Fill(tColor Color) { MarkDrawPortDirty(DrawPort()); } -void cOglPixmap::DrawImage(const cPoint &Point, const cImage &Image) { +void cOglPixmap::DrawImage(const cPoint & Point, const cImage & Image) +{ if (!oglThread->Active()) return; tColor *argb = MALLOC(tColor, Image.Width() * Image.Height()); + if (!argb) return; memcpy(argb, Image.Data(), sizeof(tColor) * Image.Width() * Image.Height()); @@ -1832,62 +1970,73 @@ void cOglPixmap::DrawImage(const cPoint &Point, const cImage &Image) { MarkDrawPortDirty(cRect(Point, cSize(Image.Width(), Image.Height())).Intersected(DrawPort().Size())); } -void cOglPixmap::DrawImage(const cPoint &Point, int ImageHandle) { +void cOglPixmap::DrawImage(const cPoint & Point, int ImageHandle) +{ if (!oglThread->Active()) return; if (ImageHandle < 0 && oglThread->GetImageRef(ImageHandle)) { - sOglImage *img = oglThread->GetImageRef(ImageHandle); - oglThread->DoCmd(new cOglCmdDrawTexture(fb, img, Point.X(), Point.Y())); + sOglImage *img = oglThread->GetImageRef(ImageHandle); + + oglThread->DoCmd(new cOglCmdDrawTexture(fb, img, Point.X(), Point.Y())); } /* - Fallback to VDR implementation, needs to separate cSoftOsdProvider from softhddevice.cpp - else { - if (cSoftOsdProvider::GetImageData(ImageHandle)) - DrawImage(Point, *cSoftOsdProvider::GetImageData(ImageHandle)); - } - */ + Fallback to VDR implementation, needs to separate cSoftOsdProvider from softhddevice.cpp + else { + if (cSoftOsdProvider::GetImageData(ImageHandle)) + DrawImage(Point, *cSoftOsdProvider::GetImageData(ImageHandle)); + } + */ SetDirty(); MarkDrawPortDirty(DrawPort()); } -void cOglPixmap::DrawPixel(const cPoint &Point, tColor Color) { +void cOglPixmap::DrawPixel(const cPoint & Point, tColor Color) +{ cRect r(Point.X(), Point.Y(), 1, 1); + oglThread->DoCmd(new cOglCmdDrawRectangle(fb, r.X(), r.Y(), r.Width(), r.Height(), Color)); SetDirty(); MarkDrawPortDirty(r); } -void cOglPixmap::DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool Overlay) { +void cOglPixmap::DrawBitmap(const cPoint & Point, const cBitmap & Bitmap, tColor ColorFg, tColor ColorBg, bool Overlay) +{ if (!oglThread->Active()) return; LOCK_PIXMAPS; bool specialColors = ColorFg || ColorBg; tColor *argb = MALLOC(tColor, Bitmap.Width() * Bitmap.Height()); + if (!argb) return; tColor *p = argb; + for (int py = 0; py < Bitmap.Height(); py++) for (int px = 0; px < Bitmap.Width(); px++) { - tIndex index = *Bitmap.Data(px, py); - *p++ = (!index && Overlay) ? clrTransparent : (specialColors ? - (index == 0 ? ColorBg : index == 1 ? ColorFg : - Bitmap.Color(index)) : Bitmap.Color(index)); + tIndex index = *Bitmap.Data(px, py); + + *p++ = (!index + && Overlay) ? clrTransparent : (specialColors ? (index == 0 ? ColorBg : index == + 1 ? ColorFg : Bitmap.Color(index)) : Bitmap.Color(index)); } - + oglThread->DoCmd(new cOglCmdDrawImage(fb, argb, Bitmap.Width(), Bitmap.Height(), Point.X(), Point.Y(), Overlay)); SetDirty(); MarkDrawPortDirty(cRect(Point, cSize(Bitmap.Width(), Bitmap.Height())).Intersected(DrawPort().Size())); } -void cOglPixmap::DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment) { +void cOglPixmap::DrawText(const cPoint & Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont * Font, + int Width, int Height, int Alignment) +{ if (!oglThread->Active()) return; LOCK_PIXMAPS; int len = s ? Utf8StrLen(s) : 0; unsigned int *symbols = MALLOC(unsigned int, len + 1); + if (!symbols) return; @@ -1913,26 +2062,25 @@ void cOglPixmap::DrawText(const cPoint &Point, const char *s, tColor ColorFg, tC if ((Alignment & taLeft) != 0) { if ((Alignment & taBorder) != 0) x += std::max(h / TEXT_ALIGN_BORDER, 1); - } else if ((Alignment & taRight) != 0) { - if (w < Width) - x += Width - w; - if ((Alignment & taBorder) != 0) - x -= std::max(h / TEXT_ALIGN_BORDER, 1); - } else { // taCentered - if (w < Width) - x += (Width - w) / 2; - } + } else if ((Alignment & taRight) != 0) { + if (w < Width) + x += Width - w; + if ((Alignment & taBorder) != 0) + x -= std::max(h / TEXT_ALIGN_BORDER, 1); + } else { // taCentered + if (w < Width) + x += (Width - w) / 2; + } } if (Height) { - if ((Alignment & taTop) != 0) - ; + if ((Alignment & taTop) != 0) ; else if ((Alignment & taBottom) != 0) { if (h < Height) y += Height - h; - } else { // taCentered + } else { // taCentered if (h < Height) - y += (Height - h) / 2; + y += (Height - h) / 2; } } } @@ -1942,7 +2090,8 @@ void cOglPixmap::DrawText(const cPoint &Point, const char *s, tColor ColorFg, tC MarkDrawPortDirty(r); } -void cOglPixmap::DrawRectangle(const cRect &Rect, tColor Color) { +void cOglPixmap::DrawRectangle(const cRect & Rect, tColor Color) +{ if (!oglThread->Active()) return; LOCK_PIXMAPS; @@ -1951,7 +2100,8 @@ void cOglPixmap::DrawRectangle(const cRect &Rect, tColor Color) { MarkDrawPortDirty(Rect); } -void cOglPixmap::DrawEllipse(const cRect &Rect, tColor Color, int Quadrants) { +void cOglPixmap::DrawEllipse(const cRect & Rect, tColor Color, int Quadrants) +{ if (!oglThread->Active()) return; LOCK_PIXMAPS; @@ -1960,7 +2110,8 @@ void cOglPixmap::DrawEllipse(const cRect &Rect, tColor Color, int Quadrants) { MarkDrawPortDirty(Rect); } -void cOglPixmap::DrawSlope(const cRect &Rect, tColor Color, int Type) { +void cOglPixmap::DrawSlope(const cRect & Rect, tColor Color, int Type) +{ if (!oglThread->Active()) return; LOCK_PIXMAPS; @@ -1969,19 +2120,23 @@ void cOglPixmap::DrawSlope(const cRect &Rect, tColor Color, int Type) { MarkDrawPortDirty(Rect); } -void cOglPixmap::Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) { +void cOglPixmap::Render(const cPixmap * Pixmap, const cRect & Source, const cPoint & Dest) +{ esyslog("[softhddev] Render %d %d %d not implemented in OpenGl OSD", Pixmap->ViewPort().X(), Source.X(), Dest.X()); } -void cOglPixmap::Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest) { +void cOglPixmap::Copy(const cPixmap * Pixmap, const cRect & Source, const cPoint & Dest) +{ esyslog("[softhddev] Copy %d %d %d not implemented in OpenGl OSD", Pixmap->ViewPort().X(), Source.X(), Dest.X()); } -void cOglPixmap::Scroll(const cPoint &Dest, const cRect &Source) { +void cOglPixmap::Scroll(const cPoint & Dest, const cRect & Source) +{ esyslog("[softhddev] Scroll %d %d not implemented in OpenGl OSD", Source.X(), Dest.X()); } -void cOglPixmap::Pan(const cPoint &Dest, const cRect &Source) { +void cOglPixmap::Pan(const cPoint & Dest, const cRect & Source) +{ esyslog("[softhddev] Pan %d %d not implemented in OpenGl OSD", Source.X(), Dest.X()); } @@ -1990,7 +2145,8 @@ void cOglPixmap::Pan(const cPoint &Dest, const cRect &Source) { ******************************************************************************/ cOglOutputFb *cOglOsd::oFb = NULL; -cOglOsd::cOglOsd(int Left, int Top, uint Level, std::shared_ptr oglThread) : cOsd(Left, Top, Level) { +cOglOsd::cOglOsd(int Left, int Top, uint Level, std::shared_ptr < cOglThread > oglThread):cOsd(Left, Top, Level) +{ this->oglThread = oglThread; bFb = NULL; isSubtitleOsd = false; @@ -2007,7 +2163,7 @@ cOglOsd::cOglOsd(int Left, int Top, uint Level, std::shared_ptr oglT #if 0 if (posd) free(posd); - posd = (unsigned char *)calloc( osdWidth * osdHeight * 4, 1 ); + posd = (unsigned char *)calloc(osdWidth * osdHeight * 4, 1); #endif // create output framebuffer @@ -2015,19 +2171,21 @@ cOglOsd::cOglOsd(int Left, int Top, uint Level, std::shared_ptr oglT oFb = new cOglOutputFb(osdWidth, osdHeight); oglThread->DoCmd(new cOglCmdInitOutputFb(oFb)); } - // pthread_mutex_unlock(&OSDMutex); } -cOglOsd::~cOglOsd() { +cOglOsd::~cOglOsd() +{ OsdClose(); SetActive(false); oglThread->DoCmd(new cOglCmdDeleteFb(bFb)); } -eOsdError cOglOsd::SetAreas(const tArea *Areas, int NumAreas) { +eOsdError cOglOsd::SetAreas(const tArea * Areas, int NumAreas) +{ cRect r; + if (NumAreas > 1) isSubtitleOsd = true; for (int i = 0; i < NumAreas; i++) @@ -2042,22 +2200,24 @@ eOsdError cOglOsd::SetAreas(const tArea *Areas, int NumAreas) { } bFb = new cOglFb(r.Width(), r.Height(), r.Width(), r.Height()); cCondWait initiated; + oglThread->DoCmd(new cOglCmdInitFb(bFb, &initiated)); initiated.Wait(); return cOsd::SetAreas(&area, 1); } -cPixmap *cOglOsd::CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort) { +cPixmap *cOglOsd::CreatePixmap(int Layer, const cRect & ViewPort, const cRect & DrawPort) +{ if (!oglThread->Active()) return NULL; LOCK_PIXMAPS; - int width = DrawPort.IsEmpty() ? ViewPort.Width() : DrawPort.Width(); - int height = DrawPort.IsEmpty() ? ViewPort.Height() : DrawPort.Height(); + int width = DrawPort.IsEmpty()? ViewPort.Width() : DrawPort.Width(); + int height = DrawPort.IsEmpty()? ViewPort.Height() : DrawPort.Height(); if (width > oglThread->MaxTextureSize() || height > oglThread->MaxTextureSize()) { - esyslog("[softhddev] cannot allocate pixmap of %dpx x %dpx, clipped to %dpx x %dpx!", - width, height, std::min(width, oglThread->MaxTextureSize()), std::min(height, oglThread->MaxTextureSize())); + esyslog("[softhddev] cannot allocate pixmap of %dpx x %dpx, clipped to %dpx x %dpx!", width, height, + std::min(width, oglThread->MaxTextureSize()), std::min(height, oglThread->MaxTextureSize())); width = std::min(width, oglThread->MaxTextureSize()); height = std::min(height, oglThread->MaxTextureSize()); } @@ -2074,10 +2234,12 @@ cPixmap *cOglOsd::CreatePixmap(int Layer, const cRect &ViewPort, const cRect &Dr return p; } delete p; + return NULL; } -void cOglOsd::DestroyPixmap(cPixmap *Pixmap) { +void cOglOsd::DestroyPixmap(cPixmap * Pixmap) +{ if (!oglThread->Active()) return; if (!Pixmap) @@ -2085,6 +2247,7 @@ void cOglOsd::DestroyPixmap(cPixmap *Pixmap) { LOCK_PIXMAPS; int start = 1; + if (isSubtitleOsd) start = 0; for (int i = start; i < oglPixmaps.Size(); i++) { @@ -2098,12 +2261,14 @@ void cOglOsd::DestroyPixmap(cPixmap *Pixmap) { } } -void cOglOsd::Flush(void) { +void cOglOsd::Flush(void) +{ if (!oglThread->Active()) return; LOCK_PIXMAPS; // check if any pixmap is dirty bool dirty = false; + for (int i = 0; i < oglPixmaps.Size() && !dirty; i++) if (oglPixmaps[i] && oglPixmaps[i]->Layer() >= 0 && oglPixmaps[i]->IsDirty()) dirty = true; @@ -2113,7 +2278,6 @@ void cOglOsd::Flush(void) { // uint64_t start = cTimeMs::Now(); // dsyslog("[softhddev]Start Flush at %" PRIu64 "", cTimeMs::Now()); - oglThread->DoCmd(new cOglCmdFill(bFb, clrTransparent)); // render pixmap textures blended to buffer @@ -2121,13 +2285,9 @@ void cOglOsd::Flush(void) { for (int i = 0; i < oglPixmaps.Size(); i++) { if (oglPixmaps[i]) { if (oglPixmaps[i]->Layer() == layer) { - oglThread->DoCmd(new cOglCmdRenderFbToBufferFb( oglPixmaps[i]->Fb(), - bFb, - oglPixmaps[i]->ViewPort().X(), - (!isSubtitleOsd) ? oglPixmaps[i]->ViewPort().Y() : 0, - oglPixmaps[i]->Alpha(), - oglPixmaps[i]->DrawPort().X(), - oglPixmaps[i]->DrawPort().Y())); + oglThread->DoCmd(new cOglCmdRenderFbToBufferFb(oglPixmaps[i]->Fb(), bFb, + oglPixmaps[i]->ViewPort().X(), (!isSubtitleOsd) ? oglPixmaps[i]->ViewPort().Y() : 0, + oglPixmaps[i]->Alpha(), oglPixmaps[i]->DrawPort().X(), oglPixmaps[i]->DrawPort().Y())); oglPixmaps[i]->SetDirty(false); } } @@ -2138,11 +2298,12 @@ void cOglOsd::Flush(void) { // dsyslog("[softhddev]End Flush at %" PRIu64 ", duration %d", cTimeMs::Now(), (int)(cTimeMs::Now()-start)); } -void cOglOsd::DrawScaledBitmap(int x, int y, const cBitmap &Bitmap, double FactorX, double FactorY, bool AntiAlias) { +void cOglOsd::DrawScaledBitmap(int x, int y, const cBitmap & Bitmap, double FactorX, double FactorY, bool AntiAlias) +{ (void)FactorX; (void)FactorY; (void)AntiAlias; int yNew = y - oglPixmaps[0]->ViewPort().Y(); + oglPixmaps[0]->DrawBitmap(cPoint(x, yNew), Bitmap); } - diff --git a/po/de_DE.po b/po/de_DE.po index 8d388ca..6556250 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-10-26 18:41+0200\n" +"POT-Creation-Date: 2020-04-13 16:26+0200\n" "PO-Revision-Date: blabla\n" "Last-Translator: blabla\n" "Language-Team: blabla\n" @@ -263,9 +263,6 @@ 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 "" @@ -306,24 +303,6 @@ msgstr "" msgid "codec/audio: decoded data smaller than encoded\n" msgstr "" -msgid "codec/audio: resample setup error\n" -msgstr "" - -msgid "codec/audio: overwrite resample\n" -msgstr "" - -msgid "codec/audio: AvResample setup error\n" -msgstr "" - -msgid "codec: latm\n" -msgstr "" - -msgid "codec: error audio data\n" -msgstr "" - -msgid "codec: error more than one frame data\n" -msgstr "" - msgid "codec/audio: can't setup resample\n" msgstr "" @@ -642,7 +621,7 @@ msgid " Frames missed(%d) duped(%d) dropped(%d) total(%d)" msgstr " Frames verloren(%d) verdoppelt(%d) übersprungen(%d) Gesamt(%d)" #, c-format -msgid " Frame Process time %2.2fms" +msgid " Video %dx%d Color: %s Gamma: %s" msgstr "" msgid "pass-through disabled" @@ -807,10 +786,6 @@ msgstr "" msgid "video/glx: no GLX support\n" msgstr "" -#, c-format -msgid "video/glx: glx version %d.%d\n" -msgstr "" - msgid "did not get FBconfig" msgstr "" @@ -898,11 +873,10 @@ msgid "Failed rendering frame!\n" msgstr "" #, c-format -msgid "video/vdpau: output buffer full, dropping frame (%d/%d)\n" +msgid "video/cuvid: output buffer full, dropping frame (%d/%d)\n" msgstr "" -#, c-format -msgid "video/vdpau: pixel format %d not supported\n" +msgid "Could not dynamically load CUDA\n" msgstr "" msgid "Kein Cuda device gefunden" @@ -943,12 +917,6 @@ msgstr "" msgid "video/egl: can't create thread egl context\n" msgstr "" -msgid "video: can't queue cancel video display thread\n" -msgstr "" - -msgid "video: can't cancel video display thread\n" -msgstr "" - #, c-format msgid "video: repeated pict %d found, but not handled\n" msgstr "" diff --git a/shaders.h b/shaders.h index 8bf79cf..fb92b70 100644 --- a/shaders.h +++ b/shaders.h @@ -11,7 +11,6 @@ const char *gl_version = "#version 300 es "; #endif #endif - /* Color conversion matrix: RGB = m * YUV + c * m is in row-major matrix, with m[row][col], e.g.: * [ a11 a12 a13 ] float m[3][3] = { { a11, a12, a13 }, @@ -71,16 +70,11 @@ float cms_matrix[3][3] = { {1.660497, -0.124547, -0.018154}, }; // Common constants for SMPTE ST.2084 (PQ) -static const float PQ_M1 = 2610./4096 * 1./4, - PQ_M2 = 2523./4096 * 128, - PQ_C1 = 3424./4096, - PQ_C2 = 2413./4096 * 32, - PQ_C3 = 2392./4096 * 32; +static const float PQ_M1 = 2610. / 4096 * 1. / 4, PQ_M2 = 2523. / 4096 * 128, PQ_C1 = 3424. / 4096, PQ_C2 = + 2413. / 4096 * 32, PQ_C3 = 2392. / 4096 * 32; // Common constants for ARIB STD-B67 (HLG) -static const float HLG_A = 0.17883277, - HLG_B = 0.28466892, - HLG_C = 0.55991073; +static const float HLG_A = 0.17883277, HLG_B = 0.28466892, HLG_C = 0.55991073; struct gl_vao_entry { @@ -124,48 +118,55 @@ static const struct gl_vao_entry vertex_vao[] = { char sh[SHADER_LENGTH]; char shv[SHADER_LENGTH]; -GL_init() { - sh[0] = 0; +GL_init() +{ + sh[0] = 0; } -GLV_init() { - shv[0] = 0; + +GLV_init() +{ + shv[0] = 0; } -pl_shader_append(const char *fmt, ...) { - char temp[1000]; - va_list ap; - + +pl_shader_append(const char *fmt, ...) +{ + char temp[1000]; + va_list ap; + va_start(ap, fmt); - vsprintf(temp,fmt,ap); - va_end(ap); - - if (strlen(sh) + strlen(temp) > SHADER_LENGTH) - Fatal(_("Shaderlenght fault\n")); - strcat(sh,temp); + vsprintf(temp, fmt, ap); + va_end(ap); + + if (strlen(sh) + strlen(temp) > SHADER_LENGTH) + Fatal(_("Shaderlenght fault\n")); + strcat(sh, temp); } -pl_shader_append_v(const char *fmt, ...) { - char temp[1000]; - va_list ap; - +pl_shader_append_v(const char *fmt, ...) +{ + char temp[1000]; + va_list ap; + va_start(ap, fmt); - vsprintf(temp,fmt,ap); - va_end(ap); - - if (strlen(shv) + strlen(temp) > SHADER_LENGTH) - Fatal(_("Shaderlenght fault\n")); - strcat(shv,temp); + vsprintf(temp, fmt, ap); + va_end(ap); + + if (strlen(shv) + strlen(temp) > SHADER_LENGTH) + Fatal(_("Shaderlenght fault\n")); + strcat(shv, temp); } + static void compile_attach_shader(GLuint program, GLenum type, const char *source) { GLuint shader; - GLint status=1234, log_length; + GLint status = 1234, log_length; char log[4000]; GLsizei len; shader = glCreateShader(type); - glShaderSource(shader, 1, (const GLchar **)&source, NULL); // &buffer, NULL); + glShaderSource(shader, 1, (const GLchar **)&source, NULL); // &buffer, NULL); glCompileShader(shader); status = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); @@ -198,42 +199,42 @@ static GLuint sc_generate_osd(GLuint gl_prog) Debug(3, "vor create osd\n"); gl_prog = glCreateProgram(); - GL_init(); - GLSL("%s\n",gl_version); - GLSL("in vec2 vertex_position;\n"); - GLSL("in vec2 vertex_texcoord0;\n"); - GLSL("out vec2 texcoord0;\n"); - GLSL("void main() {\n"); - GLSL("gl_Position = vec4(vertex_position, 1.0, 1.0);\n"); - GLSL("texcoord0 = vertex_texcoord0;\n"); - GLSL("}\n"); - + GL_init(); + GLSL("%s\n", gl_version); + GLSL("in vec2 vertex_position;\n"); + GLSL("in vec2 vertex_texcoord0;\n"); + GLSL("out vec2 texcoord0;\n"); + GLSL("void main() {\n"); + GLSL("gl_Position = vec4(vertex_position, 1.0, 1.0);\n"); + GLSL("texcoord0 = vertex_texcoord0;\n"); + GLSL("}\n"); + Debug(3, "vor compile vertex osd\n"); - compile_attach_shader(gl_prog, GL_VERTEX_SHADER, sh); // vertex_osd); - GL_init(); - GLSL("%s\n",gl_version); - GLSL("#define texture1D texture\n"); - GLSL("precision mediump float; \n"); - GLSL("layout(location = 0) out vec4 out_color;\n"); - GLSL("in vec2 texcoord0;\n"); - GLSL("uniform sampler2D texture0;\n"); - GLSL("void main() {\n"); - GLSL("vec4 color; \n"); - GLSL("color = vec4(texture(texture0, texcoord0));\n"); + compile_attach_shader(gl_prog, GL_VERTEX_SHADER, sh); // vertex_osd); + GL_init(); + GLSL("%s\n", gl_version); + GLSL("#define texture1D texture\n"); + GLSL("precision mediump float; \n"); + GLSL("layout(location = 0) out vec4 out_color;\n"); + GLSL("in vec2 texcoord0;\n"); + GLSL("uniform sampler2D texture0;\n"); + GLSL("void main() {\n"); + GLSL("vec4 color; \n"); + GLSL("color = vec4(texture(texture0, texcoord0));\n"); #ifdef GAMMA - GLSL("// delinearize gamma \n"); - GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n"); // delinearize gamma - GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n"); + GLSL("// delinearize gamma \n"); + GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n"); // delinearize gamma + GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n"); #endif - GLSL("out_color = color;\n"); - GLSL("}\n"); + GLSL("out_color = color;\n"); + GLSL("}\n"); Debug(3, "vor compile fragment osd \n"); compile_attach_shader(gl_prog, GL_FRAGMENT_SHADER, sh); //fragment_osd); glBindAttribLocation(gl_prog, 0, "vertex_position"); glBindAttribLocation(gl_prog, 1, "vertex_texcoord0"); link_shader(gl_prog); - + return gl_prog; } @@ -245,34 +246,33 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) GLint cmsLoc; float *m, *c, *cms; char *frag; - - GL_init(); - GLSL("%s\n",gl_version); - GLSL("in vec2 vertex_position; \n"); - GLSL("in vec2 vertex_texcoord0; \n"); - GLSL("out vec2 texcoord0; \n"); - GLSL("in vec2 vertex_texcoord1; \n"); - GLSL("out vec2 texcoord1; \n"); - if (Planes == 3) { - GLSL("in vec2 vertex_texcoord2; \n"); - GLSL("out vec2 texcoord2; \n"); - } - GLSL("void main() { \n"); - GLSL("gl_Position = vec4(vertex_position, 1.0, 1.0);\n"); - GLSL("texcoord0 = vertex_texcoord0; \n"); - GLSL("texcoord1 = vertex_texcoord1; \n"); - if (Planes == 3) { - GLSL("texcoord2 = vertex_texcoord1; \n"); // texcoord1 ist hier richtig - } - GLSL("} \n"); - + + GL_init(); + GLSL("%s\n", gl_version); + GLSL("in vec2 vertex_position; \n"); + GLSL("in vec2 vertex_texcoord0; \n"); + GLSL("out vec2 texcoord0; \n"); + GLSL("in vec2 vertex_texcoord1; \n"); + GLSL("out vec2 texcoord1; \n"); + if (Planes == 3) { + GLSL("in vec2 vertex_texcoord2; \n"); + GLSL("out vec2 texcoord2; \n"); + } + GLSL("void main() { \n"); + GLSL("gl_Position = vec4(vertex_position, 1.0, 1.0);\n"); + GLSL("texcoord0 = vertex_texcoord0; \n"); + GLSL("texcoord1 = vertex_texcoord1; \n"); + if (Planes == 3) { + GLSL("texcoord2 = vertex_texcoord1; \n"); // texcoord1 ist hier richtig + } + GLSL("} \n"); + Debug(3, "vor create\n"); gl_prog = glCreateProgram(); Debug(3, "vor compile vertex\n"); -// printf("%s",sh); - compile_attach_shader(gl_prog, GL_VERTEX_SHADER, sh ); - - +// printf("%s",sh); + compile_attach_shader(gl_prog, GL_VERTEX_SHADER, sh); + switch (colorspace) { case AVCOL_SPC_RGB: m = &yuv_bt601.m[0][0]; @@ -297,86 +297,85 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) Debug(3, "default BT709 Colorspace used %d\n", colorspace); break; } - - GL_init(); - - GLSL("%s\n",gl_version); - GLSL("precision mediump float; \n"); - GLSL("layout(location = 0) out vec4 out_color;\n"); - GLSL("in vec2 texcoord0; \n"); - GLSL("in vec2 texcoord1; \n"); - if (Planes == 3) - GLSL("in vec2 texcoord2; \n"); - GLSL("uniform mat3 colormatrix; \n"); - GLSL("uniform vec3 colormatrix_c; \n"); - if (colorspace == AVCOL_SPC_BT2020_NCL) - GLSL("uniform mat3 cms_matrix;\n"); - GLSL("uniform sampler2D texture0; \n"); - GLSL("uniform sampler2D texture1; \n"); - if (Planes == 3) - GLSL("uniform sampler2D texture2; \n"); - GLSL("void main() { \n"); - GLSL("vec4 color; \n"); - - if (colorspace == AVCOL_SPC_BT2020_NCL) { - GLSL("color.r = 1.003906 * vec4(texture(texture0, texcoord0)).r; \n"); - if (Planes == 3) { - GLSL("color.g = 1.003906 * vec4(texture(texture1, texcoord1)).r; \n"); - GLSL("color.b = 1.003906 * vec4(texture(texture2, texcoord2)).r; \n"); - } else { - GLSL("color.gb = 1.003906 * vec4(texture(texture1, texcoord1)).rg;\n"); - } - GLSL("// color conversion\n"); - GLSL("color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c; \n"); - GLSL("color.a = 1.0; \n"); - GLSL("// pl_shader_linearize \n"); + GL_init(); + + GLSL("%s\n", gl_version); + GLSL("precision mediump float; \n"); + GLSL("layout(location = 0) out vec4 out_color;\n"); + GLSL("in vec2 texcoord0; \n"); + GLSL("in vec2 texcoord1; \n"); + if (Planes == 3) + GLSL("in vec2 texcoord2; \n"); + GLSL("uniform mat3 colormatrix; \n"); + GLSL("uniform vec3 colormatrix_c; \n"); + if (colorspace == AVCOL_SPC_BT2020_NCL) + GLSL("uniform mat3 cms_matrix;\n"); + GLSL("uniform sampler2D texture0; \n"); + GLSL("uniform sampler2D texture1; \n"); + if (Planes == 3) + GLSL("uniform sampler2D texture2; \n"); + GLSL("void main() { \n"); + GLSL("vec4 color; \n"); + + if (colorspace == AVCOL_SPC_BT2020_NCL) { + GLSL("color.r = 1.003906 * vec4(texture(texture0, texcoord0)).r; \n"); + if (Planes == 3) { + GLSL("color.g = 1.003906 * vec4(texture(texture1, texcoord1)).r; \n"); + GLSL("color.b = 1.003906 * vec4(texture(texture2, texcoord2)).r; \n"); + } else { + GLSL("color.gb = 1.003906 * vec4(texture(texture1, texcoord1)).rg;\n"); + } + GLSL("// color conversion\n"); + GLSL("color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c; \n"); + GLSL("color.a = 1.0; \n"); + + GLSL("// pl_shader_linearize \n"); GLSL("color.rgb = max(color.rgb, 0.0); \n"); -// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n"); -// GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n"); -// GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(%f)) * vec3(1.0/%f)) + vec3(%f),bvec3(lessThan(vec3(0.5), color.rgb)));\n",HLG_C, HLG_A, HLG_B); - GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(0.55991073)) * vec3(1.0/0.17883277)) + vec3(0.28466892), bvec3(lessThan(vec3(0.5), color.rgb)));\n"); - GLSL("// color mapping \n"); - GLSL("color.rgb = cms_matrix * color.rgb; \n"); -#ifndef GAMMA - GLSL("// pl_shader_delinearize \n"); - GLSL("color.rgb = max(color.rgb, 0.0); \n"); -// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n"); -// GLSL("color.rgb = pow(color.rgb, vec3(1.0/2.4)); \n"); - GLSL("color.rgb = mix(vec3(0.5) * sqrt(color.rgb), vec3(0.17883277) * log(color.rgb - vec3(0.28466892)) + vec3(0.55991073), bvec3(lessThan(vec3(1.0), color.rgb))); \n"); +// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n"); +// GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n"); +// GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(%f)) * vec3(1.0/%f)) + vec3(%f),bvec3(lessThan(vec3(0.5), color.rgb)));\n",HLG_C, HLG_A, HLG_B); + GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(0.55991073)) * vec3(1.0/0.17883277)) + vec3(0.28466892), bvec3(lessThan(vec3(0.5), color.rgb)));\n"); + GLSL("// color mapping \n"); + GLSL("color.rgb = cms_matrix * color.rgb; \n"); +#ifndef GAMMA + GLSL("// pl_shader_delinearize \n"); + GLSL("color.rgb = max(color.rgb, 0.0); \n"); +// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n"); +// GLSL("color.rgb = pow(color.rgb, vec3(1.0/2.4)); \n"); + GLSL("color.rgb = mix(vec3(0.5) * sqrt(color.rgb), vec3(0.17883277) * log(color.rgb - vec3(0.28466892)) + vec3(0.55991073), bvec3(lessThan(vec3(1.0), color.rgb))); \n"); #endif - GLSL("out_color = color; \n"); - GLSL("} \n"); - } - else { + GLSL("out_color = color; \n"); + GLSL("} \n"); + } else { - GLSL("color.r = 1.000000 * vec4(texture(texture0, texcoord0)).r; \n"); - if (Planes == 3) { - GLSL("color.g = 1.000000 * vec4(texture(texture1, texcoord1)).r;\n"); - GLSL("color.b = 1.000000 * vec4(texture(texture2, texcoord2)).r;\n"); - } else { - GLSL("color.gb = 1.000000 * vec4(texture(texture1, texcoord1)).rg; \n"); - } - GLSL("// color conversion \n"); - GLSL("color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c; \n"); - GLSL("color.a = 1.0; \n"); + GLSL("color.r = 1.000000 * vec4(texture(texture0, texcoord0)).r; \n"); + if (Planes == 3) { + GLSL("color.g = 1.000000 * vec4(texture(texture1, texcoord1)).r;\n"); + GLSL("color.b = 1.000000 * vec4(texture(texture2, texcoord2)).r;\n"); + } else { + GLSL("color.gb = 1.000000 * vec4(texture(texture1, texcoord1)).rg; \n"); + } + GLSL("// color conversion \n"); + GLSL("color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c; \n"); + GLSL("color.a = 1.0; \n"); - GLSL("// linearize gamma \n"); - GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n"); // linearize gamma - GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n"); -#ifndef GAMMA - GLSL("// delinearize gamma to sRGB \n"); - GLSL("color.rgb = max(color.rgb, 0.0); \n"); - GLSL("color.rgb = mix(color.rgb * vec3(12.92), vec3(1.055) * pow(color.rgb, vec3(1.0/2.4)) - vec3(0.055), bvec3(lessThanEqual(vec3(0.0031308), color.rgb))); \n"); + GLSL("// linearize gamma \n"); + GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n"); // linearize gamma + GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n"); +#ifndef GAMMA + GLSL("// delinearize gamma to sRGB \n"); + GLSL("color.rgb = max(color.rgb, 0.0); \n"); + GLSL("color.rgb = mix(color.rgb * vec3(12.92), vec3(1.055) * pow(color.rgb, vec3(1.0/2.4)) - vec3(0.055), bvec3(lessThanEqual(vec3(0.0031308), color.rgb))); \n"); #endif - GLSL("// color mapping \n"); - GLSL("out_color = color; \n"); - GLSL("} \n"); - } + GLSL("// color mapping \n"); + GLSL("out_color = color; \n"); + GLSL("} \n"); + } //printf(">%s<",sh); Debug(3, "vor compile fragment\n"); - compile_attach_shader(gl_prog, GL_FRAGMENT_SHADER, sh); + compile_attach_shader(gl_prog, GL_FRAGMENT_SHADER, sh); glBindAttribLocation(gl_prog, 0, "vertex_position"); for (n = 0; n < 6; n++) { diff --git a/softhdcuvid.cpp b/softhdcuvid.cpp index 7c61251..80743f7 100644 --- a/softhdcuvid.cpp +++ b/softhdcuvid.cpp @@ -1096,10 +1096,10 @@ void cMenuSetupSoft::Create(void) "auto", "1920x1080", "1280x720", "custom", }; static const char *const video_display_formats_4_3[] = { - "pan&scan", "letterbox", "center cut-out", + "pan&scan", "letterbox", "center cut-out", "original" }; static const char *const video_display_formats_16_9[] = { - "pan&scan", "pillarbox", "center cut-out", + "pan&scan", "pillarbox", "center cut-out", "original" }; #ifdef YADIF static const char *const deinterlace[] = { @@ -1133,7 +1133,7 @@ void cMenuSetupSoft::Create(void) static char *scalingtest[100]; if (scalers == 0) { - scalingtest[0] = (char *) "Off"; + scalingtest[0] = (char *)"Off"; for (scalers = 0; pl_named_filters[scalers].filter != NULL; scalers++) { scaling[scalers] = (char *)pl_named_filters[scalers].name; scalingtest[scalers + 1] = (char *)pl_named_filters[scalers].name; @@ -1182,9 +1182,9 @@ void cMenuSetupSoft::Create(void) Add(new cMenuEditBoolItem(tr("Enable Screensaver(DPMS) at black screen"), &EnableDPMSatBlackScreen, trVDR("no"), trVDR("yes"))); #endif - Add(new cMenuEditStraItem(trVDR("4:3 video display format"), &Video4to3DisplayFormat, 3, + Add(new cMenuEditStraItem(trVDR("4:3 video display format"), &Video4to3DisplayFormat, 4, video_display_formats_4_3)); - Add(new cMenuEditStraItem(trVDR("16:9+other video display format"), &VideoOtherDisplayFormat, 3, + Add(new cMenuEditStraItem(trVDR("16:9+other video display format"), &VideoOtherDisplayFormat, 4, video_display_formats_16_9)); #if 0 @@ -2153,10 +2153,10 @@ void cSoftHdMenu::Create(void) int dropped; int counter; float frametime; - int width,height; - int color; - int eotf; - char *colorstr, *eotfstr; + int width, height; + int color; + int eotf; + char *colorstr, *eotfstr; current = Current(); // get current menu item index Clear(); // clear the menu @@ -2191,8 +2191,8 @@ void cSoftHdMenu::Create(void) #endif Add(new cOsdItem(NULL, osUnknown, false)); Add(new cOsdItem(NULL, osUnknown, false)); - GetStats(&missed, &duped, &dropped, &counter, &frametime, &width, &height, &color,&eotf); - switch (color) { + GetStats(&missed, &duped, &dropped, &counter, &frametime, &width, &height, &color, &eotf); + switch (color) { case AVCOL_SPC_RGB: colorstr = strdup("BT 601"); eotfstr = strdup("BT 1886"); @@ -2213,8 +2213,9 @@ void cSoftHdMenu::Create(void) } Add(new cOsdItem(cString::sprintf(tr(" Frames missed(%d) duped(%d) dropped(%d) total(%d)"), missed, duped, dropped, counter), osUnknown, false)); - Add(new cOsdItem(cString::sprintf(tr(" Video %dx%d Color: %s Gamma: %s"), width, height, colorstr, eotfstr), osUnknown, false)); - // Add(new cOsdItem(cString::sprintf(tr(" Frame Process time %2.2fms"), frametime), osUnknown, false)); + Add(new cOsdItem(cString::sprintf(tr(" Video %dx%d Color: %s Gamma: %s"), width, height, colorstr, eotfstr), + osUnknown, false)); + // Add(new cOsdItem(cString::sprintf(tr(" Frame Process time %2.2fms"), frametime), osUnknown, false)); SetCurrent(Get(current)); // restore selected menu entry Display(); // display build menu } diff --git a/softhddev.c b/softhddev.c index 7b95ea9..9eff45b 100644 --- a/softhddev.c +++ b/softhddev.c @@ -645,7 +645,7 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size, int is_st q = pesdx->Buffer + pesdx->Skip; n = pesdx->Index - pesdx->Skip; while (n >= 5) { - int r=0; + int r = 0; unsigned codec_id = AV_CODEC_ID_NONE; // 4 bytes 0xFFExxxxx Mpeg audio @@ -2871,11 +2871,10 @@ const char *CommandLineHelp(void) " -p device\taudio device for pass-through (hw:0,1 or /dev/dsp1)\n" " -c channel\taudio mixer channel name (fe. PCM)\n" " -d display\tdisplay of x11 server (fe. :0.0)\n" " -f\t\tstart with fullscreen window (only with window manager)\n" - " -g geometry\tx11 window geometry wxh+x+y\n" - " -r Refresh\tRefreshrate for DRM (default is 50 Hz)\n" - " -C Connector\tConnector for DRM (default is current Connector)\n" - " -v device\tvideo driver device (cuvid)\n" - " -s\t\tstart in suspended mode\n" " -x\t\tstart x11 server, with -xx try to connect, if this fails\n" + " -g geometry\tx11 window geometry wxh+x+y\n" " -r Refresh\tRefreshrate for DRM (default is 50 Hz)\n" + " -C Connector\tConnector for DRM (default is current Connector)\n" + " -v device\tvideo driver device (cuvid)\n" " -s\t\tstart in suspended mode\n" + " -x\t\tstart x11 server, with -xx try to connect, if this fails\n" " -X args\tX11 server arguments (f.e. -nocursor)\n" " -w workaround\tenable/disable workarounds\n" "\tno-hw-decoder\t\tdisable hw decoder, use software decoder only\n" "\tno-mpeg-hw-decoder\tdisable hw decoder for mpeg only\n" @@ -2916,10 +2915,10 @@ int ProcessArgs(int argc, char *const argv[]) continue; case 'C': // Connector for DRM VideoSetConnector(optarg); - continue; - case 'r': // Connector for DRM + continue; + case 'r': // Connector for DRM VideoSetRefresh(optarg); - continue; + continue; case 'p': // pass-through audio device AudioSetPassthroughDevice(optarg); continue; @@ -3369,19 +3368,21 @@ void Resume(void) ** @param[out] dropped dropped frames ** @param[out] count number of decoded frames */ -void GetStats(int *missed, int *duped, int *dropped, int *counter, float *frametime, int *width, int *height, int *color, int *eotf) +void GetStats(int *missed, int *duped, int *dropped, int *counter, float *frametime, int *width, int *height, + int *color, int *eotf) { *missed = 0; *duped = 0; *dropped = 0; *counter = 0; *frametime = 0.0f; - *width = 0; - *height = 0; - *color = NULL; - *eotf = NULL; + *width = 0; + *height = 0; + *color = NULL; + *eotf = NULL; if (MyVideoStream->HwDecoder) { - VideoGetStats(MyVideoStream->HwDecoder, missed, duped, dropped, counter, frametime, width, height, color, eotf); + VideoGetStats(MyVideoStream->HwDecoder, missed, duped, dropped, counter, frametime, width, height, color, + eotf); } } diff --git a/video.c b/video.c index 49029f2..2dae7a0 100644 --- a/video.c +++ b/video.c @@ -253,7 +253,7 @@ typedef enum _video_zoom_modes_ VideoNormal, ///< normal VideoStretch, ///< stretch to all edges VideoCenterCutOut, ///< center and cut out - VideoAnamorphic, ///< anamorphic scaled (unsupported) + VideoNone, ///< no scaling } VideoZoomModes; /// @@ -384,7 +384,7 @@ static char VideoSurfaceModesChanged; ///< flag surface modes changed static const char VideoTransparentOsd = 1; static uint32_t VideoBackground; ///< video background color -char VideoStudioLevels; ///< flag use studio levels +char VideoStudioLevels; ///< flag use studio levels /// Default deinterlace mode. static VideoDeinterlaceModes VideoDeinterlace[VideoResolutionMax]; @@ -495,7 +495,6 @@ static int GlxVSyncEnabled = 1; ///< enable/disable v-sync static GLXContext glxSharedContext; ///< shared gl context static GLXContext glxContext; ///< our gl context - static GLXContext glxThreadContext; ///< our gl context for the thread static XVisualInfo *GlxVisualInfo; ///< our gl visual @@ -503,7 +502,7 @@ static void GlxSetupWindow(xcb_window_t window, int width, int height, GLXContex GLXContext OSDcontext; #else static EGLContext eglSharedContext; ///< shared gl context -static EGLContext eglOSDContext = NULL; ///< our gl context for the thread +static EGLContext eglOSDContext = NULL; ///< our gl context for the thread static EGLContext eglContext; ///< our gl context static EGLConfig eglConfig; static EGLDisplay eglDisplay; @@ -543,7 +542,6 @@ static void X11DPMSReenable(xcb_connection_t *); static void X11DPMSDisable(xcb_connection_t *); #endif - char *eglErrorString(EGLint error) { switch (error) { @@ -681,44 +679,35 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width, in AVRational display_aspect_ratio; AVRational tmp_ratio; + // input not initialized yet, return immediately if (!input_aspect_ratio.num || !input_aspect_ratio.den) { - input_aspect_ratio.num = 1; - input_aspect_ratio.den = 1; - Debug(3, "video: aspect defaults to %d:%d\n", input_aspect_ratio.num, input_aspect_ratio.den); - - } - - av_reduce(&input_aspect_ratio.num, &input_aspect_ratio.den, input_width * input_aspect_ratio.num, - input_height * input_aspect_ratio.den, 1024 * 1024); - - // InputWidth/Height can be zero = uninitialized - if (!input_aspect_ratio.num || !input_aspect_ratio.den) { - input_aspect_ratio.num = 1; - input_aspect_ratio.den = 1; + output_width = video_width; + output_height = video_height; + return; } #ifdef USE_DRM - get_drm_aspect(&display_aspect_ratio.num,&display_aspect_ratio.den); + get_drm_aspect(&display_aspect_ratio.num, &display_aspect_ratio.den); #else - Debug(3,"mmHeight %d mm Width %d VideoHeight %d VideoWidth %d\n",VideoScreen->height_in_millimeters,VideoScreen->width_in_millimeters, - VideoScreen->height_in_pixels,VideoScreen->width_in_pixels); - display_aspect_ratio.num = VideoScreen->width_in_pixels * VideoScreen->height_in_millimeters; - display_aspect_ratio.den = VideoScreen->height_in_pixels * VideoScreen->width_in_millimeters; + display_aspect_ratio.num = VideoScreen->width_in_pixels; + display_aspect_ratio.den = VideoScreen->height_in_pixels; #endif - display_aspect_ratio = av_mul_q(input_aspect_ratio, display_aspect_ratio); - Debug(3, "video: aspect %d:%d Resolution %d\n", display_aspect_ratio.num, display_aspect_ratio.den, resolution); + av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, display_aspect_ratio.num, display_aspect_ratio.den, + 1024 * 1024); + + Debug(3, "video: input %dx%d (%d:%d)\n", input_width, input_height, input_aspect_ratio.num, + input_aspect_ratio.den); + Debug(3, "video: display aspect %d:%d Resolution %d\n", display_aspect_ratio.num, display_aspect_ratio.den, + resolution); + Debug(3, "video: video %+d%+d %dx%d\n", video_x, video_y, video_width, video_height); *crop_x = VideoCutLeftRight[resolution]; *crop_y = VideoCutTopBottom[resolution]; *crop_width = input_width - VideoCutLeftRight[resolution] * 2; *crop_height = input_height - VideoCutTopBottom[resolution] * 2; + CuvidMessage(2, "video: crop to %+d%+d %dx%d\n", *crop_x, *crop_y, *crop_width, *crop_height); - // FIXME: store different positions for the ratios tmp_ratio.num = 4; tmp_ratio.den = 3; -#ifdef DEBUG - Debug(4, "ratio: %d:%d %d:%d\n", input_aspect_ratio.num, input_aspect_ratio.den, display_aspect_ratio.num, - display_aspect_ratio.den); -#endif if (!av_cmp_q(input_aspect_ratio, tmp_ratio)) { switch (Video4to3ZoomMode) { case VideoNormal: @@ -727,9 +716,8 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width, in goto stretch; case VideoCenterCutOut: goto center_cut_out; - case VideoAnamorphic: - // FIXME: rest should be done by hardware - goto stretch; + case VideoNone: + goto video_none; } } switch (VideoOtherZoomMode) { @@ -739,28 +727,24 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width, in goto stretch; case VideoCenterCutOut: goto center_cut_out; - case VideoAnamorphic: - // FIXME: rest should be done by hardware - goto stretch; + case VideoNone: + goto video_none; } normal: *output_x = video_x; *output_y = video_y; - *output_width = - (video_height * display_aspect_ratio.num + display_aspect_ratio.den - 1) / display_aspect_ratio.den; - *output_height = - (video_width * display_aspect_ratio.den + display_aspect_ratio.num - 1) / display_aspect_ratio.num; + *output_height = video_height; + *output_width = (*crop_width * *output_height * input_aspect_ratio.num) / (input_aspect_ratio.den * *crop_height); if (*output_width > video_width) { *output_width = video_width; + *output_height = + (*crop_height * *output_width * input_aspect_ratio.den) / (input_aspect_ratio.num * *crop_width); *output_y += (video_height - *output_height) / 2; - } else if (*output_height > video_height) { - *output_height = video_height; + } else if (*output_width < video_width) { *output_x += (video_width - *output_width) / 2; } - - CuvidMessage(2, "video: normal aspect output %dx%d%+d%+d Video %dx%d\n", *output_width, *output_height, *output_x, - *output_y, video_width, video_height); + CuvidMessage(2, "video: normal aspect output %dx%d%+d%+d\n", *output_width, *output_height, *output_x, *output_y); return; stretch: @@ -768,49 +752,34 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width, in *output_y = video_y; *output_width = video_width; *output_height = video_height; - Debug(3, "video: stretch output %dx%d%+d%+d\n", *output_width, *output_height, *output_x, *output_y); + CuvidMessage(2, "video: stretch output %dx%d%+d%+d\n", *output_width, *output_height, *output_x, *output_y); return; center_cut_out: *output_x = video_x; *output_y = video_y; *output_height = video_height; - *output_width = video_width; - - *crop_width = (video_height * display_aspect_ratio.num + display_aspect_ratio.den - 1) / display_aspect_ratio.den; - *crop_height = (video_width * display_aspect_ratio.den + display_aspect_ratio.num - 1) / display_aspect_ratio.num; - - // look which side must be cut - if (*crop_width > video_width) { - int tmp; - - *crop_height = input_height - VideoCutTopBottom[resolution] * 2; - - // adjust scaling - tmp = ((*crop_width - video_width) * input_width) / (2 * video_width); - // FIXME: round failure? - if (tmp > *crop_x) { - *crop_x = tmp; - } - *crop_width = input_width - *crop_x * 2; - } else if (*crop_height > video_height) { - int tmp; - - *crop_width = input_width - VideoCutLeftRight[resolution] * 2; - - // adjust scaling - tmp = ((*crop_height - video_height) * input_height) - / (2 * video_height); - // FIXME: round failure? - if (tmp > *crop_y) { - *crop_y = tmp; - } - *crop_height = input_height - *crop_y * 2; - } else { - *crop_width = input_width - VideoCutLeftRight[resolution] * 2; - *crop_height = input_height - VideoCutTopBottom[resolution] * 2; + *output_width = (*crop_width * *output_height * input_aspect_ratio.num) / (input_aspect_ratio.den * *crop_height); + if (*output_width > video_width) { + // fix height cropping + *crop_width = (int)((*crop_width * video_width) / (*output_width * 2.0) + 0.5) * 2; + *crop_x = (input_width - *crop_width) / 2; + *output_width = video_width; + } else if (*output_width < video_width) { + // fix width cropping + *crop_height = (int)((*crop_height * *output_width) / (video_width * 2.0) + 0.5) * 2; + *crop_y = (input_height - *crop_height) / 2; + *output_width = video_width; } - Debug(3, "video: aspect crop %dx%d%+d%+d\n", *crop_width, *crop_height, *crop_x, *crop_y); + CuvidMessage(2, "video: aspect crop %dx%d%+d%+d\n", *crop_width, *crop_height, *crop_x, *crop_y); + return; + + video_none: + *output_height = *crop_height; + *output_width = (*crop_width * input_aspect_ratio.num) / input_aspect_ratio.den; // normalize pixel aspect ratio + *output_x = video_x + (video_width - *output_width) / 2; + *output_y = video_y + (video_height - *output_height) / 2; + CuvidMessage(2, "video: original aspect output %dx%d%+d%+d\n", *output_width, *output_height, *output_x, *output_y); return; } @@ -873,9 +842,6 @@ static PFNGLXSWAPINTERVALSGIPROC GlxSwapIntervalSGI; }\ } - - - /// /// GLX check if a GLX extension is supported. /// @@ -974,11 +940,10 @@ static void EglInit(void) XVisualInfo *vi = NULL; - #ifdef PLACEBO return; #endif - + // The desired 30-bit color visual int attributeList10[] = { GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, @@ -1013,7 +978,7 @@ static void EglInit(void) if (!glXQueryVersion(XlibDisplay, &major, &minor)) { Fatal(_("video/glx: no GLX support\n")); } - Debug(3,"video/glx: glx version %d.%d\n", major, minor); + Debug(3, "video/glx: glx version %d.%d\n", major, minor); // // check which extension are supported @@ -1152,25 +1117,26 @@ static void EglInit(void) { int redSize, greenSize, blueSize, alphaSize; static int glewdone = 0; - + #ifdef PLACEBO return; #endif EGLContext context; // create egl context - setenv("MESA_GL_VERSION_OVERRIDE","3.3",0); - setenv("V3D_DOUBLE_BUFFER","1",0); + setenv("MESA_GL_VERSION_OVERRIDE", "3.3", 0); + setenv("V3D_DOUBLE_BUFFER", "1", 0); make_egl(); - - if (!glewdone) { + + if (!glewdone) { GLenum err = glewInit(); - glewdone = 1; - if (err != GLEW_OK) { - Debug(3, "Error: %s\n", glewGetErrorString(err)); - } - } - + + glewdone = 1; + if (err != GLEW_OK) { + Debug(3, "Error: %s\n", glewGetErrorString(err)); + } + } + eglGetConfigAttrib(eglDisplay, eglConfig, EGL_BLUE_SIZE, &blueSize); eglGetConfigAttrib(eglDisplay, eglConfig, EGL_RED_SIZE, &redSize); eglGetConfigAttrib(eglDisplay, eglConfig, EGL_GREEN_SIZE, &greenSize); @@ -1237,16 +1203,16 @@ static void EglExit(void) if (eglContext) { eglDestroyContext(eglDisplay, eglContext); EglCheck(); - eglContext = NULL; + eglContext = NULL; } eglTerminate(eglDisplay); #endif - + #ifdef USE_DRM - drm_clean_up(); -#endif - + drm_clean_up(); +#endif + #endif } @@ -1398,7 +1364,7 @@ typedef struct _cuvid_decoder_ AVFilterContext *buffersrc_ctx; AVFilterGraph *filter_graph; #endif - AVBufferRef *cached_hw_frames_ctx; + AVBufferRef *cached_hw_frames_ctx; int LastAVDiff; ///< last audio - video difference int SyncCounter; ///< counter to sync frames int StartCounter; ///< counter for video start @@ -1509,7 +1475,8 @@ int CuvidMessage(int level, const char *format, ...) static inline void __checkCudaErrors(CUresult err, const char *file, const int line) { if (CUDA_SUCCESS != err) { - CuvidMessage(2, "checkCudaErrors() Driver API error = %04d >%s< from file <%s>, line %i.\n", err, getCudaDrvErrorString(err), file, line); + CuvidMessage(2, "checkCudaErrors() Driver API error = %04d >%s< from file <%s>, line %i.\n", err, + getCudaDrvErrorString(err), file, line); exit(EXIT_FAILURE); } } @@ -1589,13 +1556,13 @@ static void CuvidDestroySurfaces(CuvidDecoder * decoder) checkCudaErrors(cu->cuGraphicsUnregisterResource(decoder->cu_res[i][j])); #endif #ifdef VAAPI - if (decoder->images[i*Planes+j]) { - DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[i*Planes+j]); - if (decoder->fds[i*Planes+j]) - close(decoder->fds[i*Planes+j]); - } - decoder->fds[i*Planes+j] = 0; - decoder->images[i*Planes+j] = 0; + if (decoder->images[i * Planes + j]) { + DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[i * Planes + j]); + if (decoder->fds[i * Planes + j]) + close(decoder->fds[i * Planes + j]); + } + decoder->fds[i * Planes + j] = 0; + decoder->images[i * Planes + j] = 0; #endif #endif } @@ -1604,7 +1571,7 @@ static void CuvidDestroySurfaces(CuvidDecoder * decoder) pl_renderer_destroy(&p->renderer); p->renderer = pl_renderer_create(p->ctx, p->gpu); #else - glDeleteTextures(CODEC_SURFACES_MAX * 2, (GLuint *) &decoder->gl_textures); + glDeleteTextures(CODEC_SURFACES_MAX * 2, (GLuint *) & decoder->gl_textures); GlxCheck(); if (CuvidDecoderN == 1) { // only wenn last decoder closes @@ -1687,25 +1654,25 @@ static void CuvidReleaseSurface(CuvidDecoder * decoder, int surface) } } #else -#ifdef VAAPI - if (decoder->images[surface*Planes]) { - DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface*Planes]); - DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface*Planes+1]); +#ifdef VAAPI + if (decoder->images[surface * Planes]) { + DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface * Planes]); + DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface * Planes + 1]); #ifdef RASPI - DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface*Planes+2]); + DestroyImageKHR(eglGetCurrentDisplay(), decoder->images[surface * Planes + 2]); #endif - if (decoder->fds[surface*Planes]) { - close(decoder->fds[surface*Planes]); -// close(decoder->fds[surface*Planes+1]); + if (decoder->fds[surface * Planes]) { + close(decoder->fds[surface * Planes]); +// close(decoder->fds[surface*Planes+1]); #ifdef RASPI - close(decoder->fds[surface*Planes+2]); + close(decoder->fds[surface * Planes + 2]); #endif - } - } - decoder->fds[surface*Planes] = 0; - decoder->fds[surface*Planes+1] = 0; - decoder->images[surface*Planes] = 0; - decoder->images[surface*Planes+1] = 0; + } + } + decoder->fds[surface * Planes] = 0; + decoder->fds[surface * Planes + 1] = 0; + decoder->images[surface * Planes] = 0; + decoder->images[surface * Planes + 1] = 0; #endif #endif for (i = 0; i < decoder->SurfaceUsedN; ++i) { @@ -1735,9 +1702,10 @@ static void CuvidPrintFrames(const CuvidDecoder * decoder) int CuvidTestSurfaces() { - int i=0; + int i = 0; + if (CuvidDecoders[0] != NULL) { - if (i = atomic_read(&CuvidDecoders[0]->SurfacesFilled) < VIDEO_SURFACES_MAX-1) + if (i = atomic_read(&CuvidDecoders[0]->SurfacesFilled) < VIDEO_SURFACES_MAX - 1) return i; return 0; } else @@ -1779,13 +1747,13 @@ const int mpgl_preferred_gl_versions[] = { 0 }; -static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * out_context, EGLConfig * out_config, int *bpp) +static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * out_context, EGLConfig * out_config, + int *bpp) { EGLenum api; EGLint rend, *attribs; const char *name; - switch (es_version) { case 0: @@ -1831,7 +1799,8 @@ static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * o EGL_RENDERABLE_TYPE, rend, EGL_NONE }; - EGLint num_configs=0; + EGLint num_configs = 0; + #ifndef RASPI attribs = attributes10; *bpp = 10; @@ -1842,9 +1811,9 @@ static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * o if (!eglChooseConfig(display, attributes8, NULL, 0, &num_configs)) { // try 8 Bit num_configs = 0; } - } else + } else #endif - if (num_configs == 0) { + if (num_configs == 0) { EglCheck(); Debug(3, " 10 Bit egl Failed\n"); attribs = attributes8; @@ -1909,6 +1878,7 @@ static bool create_context_cb(EGLDisplay display, int es_version, EGLContext * o make_egl() { int bpp; + CreateImageKHR = (void *)eglGetProcAddress("eglCreateImageKHR"); DestroyImageKHR = (void *)eglGetProcAddress("eglDestroyImageKHR"); EGLImageTargetTexture2DOES = (void *)eglGetProcAddress("glEGLImageTargetTexture2DOES"); @@ -1917,7 +1887,7 @@ make_egl() eglWaitSyncKHR = (void *)eglGetProcAddress("eglWaitSyncKHR"); eglClientWaitSyncKHR = (void *)eglGetProcAddress("eglClientWaitSyncKHR"); eglDupNativeFenceFDANDROID = (void *)eglGetProcAddress("eglDupNativeFenceFDANDROID"); - + if (!CreateImageKHR || !DestroyImageKHR || !EGLImageTargetTexture2DOES || !eglCreateSyncKHR) Fatal(_("Can't get EGL Extentions\n")); #ifndef USE_DRM @@ -1933,7 +1903,7 @@ make_egl() int vID, n; eglGetConfigAttrib(eglDisplay, eglConfig, EGL_NATIVE_VISUAL_ID, &vID); - Debug(3, "chose visual 0x%x bpp %d\n", vID,bpp); + Debug(3, "chose visual 0x%x bpp %d\n", vID, bpp); #ifdef USE_DRM InitBo(bpp); #else @@ -1976,7 +1946,7 @@ static CuvidDecoder *CuvidNewHwDecoder(VideoStream * stream) Fatal("codec: can't allocate HW video codec context err %04x", i); } #endif -#if defined (VAAPI) && !defined (RASPI) +#if defined (VAAPI) && !defined (RASPI) // if ((i = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, ":0.0" , 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); @@ -1990,7 +1960,7 @@ static CuvidDecoder *CuvidNewHwDecoder(VideoStream * stream) Error(_("video/cuvid: out of memory\n")); return NULL; } -#if defined (VAAPI) && !defined (RASPI) +#if defined (VAAPI) && !defined (RASPI) VaDisplay = TO_VAAPI_DEVICE_CTX(HwDeviceContext)->display; decoder->VaDisplay = VaDisplay; #endif @@ -2085,12 +2055,12 @@ static void CuvidDelHwDecoder(CuvidDecoder * decoder) eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext); EglCheck(); #endif -#endif +#endif #if defined PLACEBO || defined VAAPI if (decoder->SurfaceFreeN || decoder->SurfaceUsedN) { CuvidDestroySurfaces(decoder); } -#endif +#endif if (decoder == CuvidDecoders[0]) VideoThreadUnlock(); @@ -2263,7 +2233,7 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi // make planes for image pl = &decoder->pl_images[i].planes[n]; pl->components = n == 0 ? 1 : 2; - pl->shift_x = 0.0f; + pl->shift_x = 0.0f; pl->shift_y = 0.0f; if (n == 0) { pl->component_mapping[0] = PL_CHANNEL_Y; @@ -2271,7 +2241,7 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi pl->component_mapping[2] = -1; pl->component_mapping[3] = -1; } else { - pl->shift_x = -0.5f; // PL_CHROMA_LEFT + pl->shift_x = -0.5f; // PL_CHROMA_LEFT pl->component_mapping[0] = PL_CHANNEL_U; pl->component_mapping[1] = PL_CHANNEL_V; pl->component_mapping[2] = -1; @@ -2406,18 +2376,18 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi Debug(3, "video: create %d Textures Format %s w %d h %d \n", anz, PixFmt == AV_PIX_FMT_NV12 ? "NV12" : "P010", size_x, size_y); - + #ifdef USE_DRM - //set_video_mode(size_x,size_y); // switch Mode here (highly experimental) + //set_video_mode(size_x,size_y); // switch Mode here (highly experimental) #endif - + #ifdef CUVID glXMakeCurrent(XlibDisplay, VideoWindow, glxSharedContext); GlxCheck(); #else #ifdef USE_DRM pthread_mutex_lock(&OSDMutex); -#endif +#endif eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext); #endif @@ -2428,7 +2398,7 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi GlxCheck(); for (i = 0; i < anz; i++) { - for (n = 0; n < Planes; n++) { // number of planes + for (n = 0; n < Planes; n++) { // number of planes glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[i * Planes + n]); GlxCheck(); @@ -2438,15 +2408,19 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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); + 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) - 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); - else - 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); + if (PixFmt == AV_PIX_FMT_NV12) + 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); + else + 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); #endif SDK_CHECK_ERROR_GL(); // register this texture with CUDA @@ -2489,28 +2463,32 @@ void createTextureDst(CuvidDecoder * decoder, int anz, unsigned int size_x, unsi desc.layers[n].pitch[plane]); \ } while (0) -void generateVAAPIImage(CuvidDecoder * decoder, VASurfaceID index, const AVFrame * frame, int image_width, int image_height) +void generateVAAPIImage(CuvidDecoder * decoder, VASurfaceID index, const AVFrame * frame, int image_width, + int image_height) { VAStatus status; uint64_t first_time; + #if defined (VAAPI) && !defined (RASPI) VADRMPRIMESurfaceDescriptor desc; status = - vaExportSurfaceHandle(decoder->VaDisplay, (VASurfaceID)(uintptr_t)frame->data[3], VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, - VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS, &desc); + vaExportSurfaceHandle(decoder->VaDisplay, (VASurfaceID) (uintptr_t) frame->data[3], + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS, + &desc); if (status != VA_STATUS_SUCCESS) { printf("Fehler beim export VAAPI Handle\n"); return; } - vaSyncSurface(decoder->VaDisplay, (VASurfaceID)(uintptr_t)frame->data[3]); + vaSyncSurface(decoder->VaDisplay, (VASurfaceID) (uintptr_t) frame->data[3]); #endif #ifdef RASPI - AVDRMFrameDescriptor desc; - memcpy(&desc,frame->data[0],sizeof(desc)); - + AVDRMFrameDescriptor desc; + + memcpy(&desc, frame->data[0], sizeof(desc)); + #endif eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext); @@ -2519,45 +2497,46 @@ void generateVAAPIImage(CuvidDecoder * decoder, VASurfaceID index, const AVFrame for (int n = 0; n < Planes; n++) { int attribs[20] = { EGL_NONE }; uint num_attribs = 0; - int fd; + int fd; + #if defined (VAAPI) && !defined (RASPI) - ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, desc.layers[n].drm_format); - ADD_ATTRIB(EGL_WIDTH, n==0?image_width:image_width/2); - ADD_ATTRIB(EGL_HEIGHT, n==0?image_height:image_height/2); - ADD_PLANE_ATTRIBS(0); + ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, desc.layers[n].drm_format); + ADD_ATTRIB(EGL_WIDTH, n == 0 ? image_width : image_width / 2); + ADD_ATTRIB(EGL_HEIGHT, n == 0 ? image_height : image_height / 2); + ADD_PLANE_ATTRIBS(0); #endif #ifdef RASPI - ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_R8); - ADD_ATTRIB(EGL_WIDTH, n==0?image_width:image_width/2); - ADD_ATTRIB(EGL_HEIGHT, n==0?image_height:image_height/2); - if (n==0) { - fd = dup(desc.objects[0].fd); - ADD_ATTRIB( EGL_DMA_BUF_PLANE0_FD_EXT,fd); - ADD_ATTRIB( EGL_DMA_BUF_PLANE0_OFFSET_EXT,desc.layers[0].planes[n].offset); - ADD_ATTRIB( EGL_DMA_BUF_PLANE0_PITCH_EXT,desc.layers[0].planes[n].pitch); - } else { - fd = dup(desc.objects[0].fd); - ADD_ATTRIB( EGL_DMA_BUF_PLANE0_FD_EXT,fd); - ADD_ATTRIB( EGL_DMA_BUF_PLANE0_OFFSET_EXT,desc.layers[0].planes[n].offset); - ADD_ATTRIB( EGL_DMA_BUF_PLANE0_PITCH_EXT,desc.layers[0].planes[n].pitch); - } -// Debug(3,"n %d fd %d nb_planes %d nb_layers %d plane %d offeset %d offset2 %d pitch %d \n",n, fd, -// desc.layers[0].nb_planes,desc.nb_layers,n,desc.layers[0].planes[n].offset,desc.layers[0].planes[n+1].offset,desc.layers[0].planes[n].pitch); + ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_R8); + ADD_ATTRIB(EGL_WIDTH, n == 0 ? image_width : image_width / 2); + ADD_ATTRIB(EGL_HEIGHT, n == 0 ? image_height : image_height / 2); + if (n == 0) { + fd = dup(desc.objects[0].fd); + ADD_ATTRIB(EGL_DMA_BUF_PLANE0_FD_EXT, fd); + ADD_ATTRIB(EGL_DMA_BUF_PLANE0_OFFSET_EXT, desc.layers[0].planes[n].offset); + ADD_ATTRIB(EGL_DMA_BUF_PLANE0_PITCH_EXT, desc.layers[0].planes[n].pitch); + } else { + fd = dup(desc.objects[0].fd); + ADD_ATTRIB(EGL_DMA_BUF_PLANE0_FD_EXT, fd); + ADD_ATTRIB(EGL_DMA_BUF_PLANE0_OFFSET_EXT, desc.layers[0].planes[n].offset); + ADD_ATTRIB(EGL_DMA_BUF_PLANE0_PITCH_EXT, desc.layers[0].planes[n].pitch); + } +// Debug(3,"n %d fd %d nb_planes %d nb_layers %d plane %d offeset %d offset2 %d pitch %d \n",n, fd, +// desc.layers[0].nb_planes,desc.nb_layers,n,desc.layers[0].planes[n].offset,desc.layers[0].planes[n+1].offset,desc.layers[0].planes[n].pitch); #endif decoder->images[index * Planes + n] = CreateImageKHR(eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs); - + if (!decoder->images[index * Planes + n]) goto esh_failed; glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[index * Planes + n]); EGLImageTargetTexture2DOES(GL_TEXTURE_2D, decoder->images[index * Planes + n]); #ifdef RASPI - decoder->fds[index*Planes+n] = fd; + decoder->fds[index * Planes + n] = fd; #endif } - decoder->fds[index*Planes] = desc.objects[0].fd; + decoder->fds[index * Planes] = desc.objects[0].fd; glBindTexture(GL_TEXTURE_2D, 0); eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); EglCheck(); @@ -2610,10 +2589,9 @@ static unsigned CuvidGetVideoSurface(CuvidDecoder * decoder, const AVCodecContex #if defined (VAAPI) || defined (YADIF) static void CuvidSyncRenderFrame(CuvidDecoder * decoder, const AVCodecContext * video_ctx, AVFrame * frame); - int push_filters(AVCodecContext * dec_ctx, CuvidDecoder * decoder, AVFrame * frame) { - + int ret; AVFrame *filt_frame = av_frame_alloc(); @@ -2622,12 +2600,12 @@ int push_filters(AVCodecContext * dec_ctx, CuvidDecoder * decoder, AVFrame * fra av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n"); } -// printf("Interlaced %d tff %d\n",frame->interlaced_frame,frame->top_field_first); + // printf("Interlaced %d tff %d\n",frame->interlaced_frame,frame->top_field_first); /* pull filtered frames from the filtergraph */ - while ((ret = av_buffersink_get_frame(decoder->buffersink_ctx, filt_frame)) >= 0 ) { + while ((ret = av_buffersink_get_frame(decoder->buffersink_ctx, filt_frame)) >= 0) { filt_frame->pts /= 2; decoder->Interlaced = 0; - // printf("vaapideint video:new %#012" PRIx64 " old %#012" PRIx64 "\n",filt_frame->pts,frame->pts); + // printf("vaapideint video:new %#012" PRIx64 " old %#012" PRIx64 "\n",filt_frame->pts,frame->pts); CuvidSyncRenderFrame(decoder, dec_ctx, filt_frame); filt_frame = av_frame_alloc(); // get new frame @@ -2642,7 +2620,7 @@ int init_filters(AVCodecContext * dec_ctx, CuvidDecoder * decoder, AVFrame * fra enum AVPixelFormat format = PIXEL_FORMAT; #ifdef VAAPI - const char *filters_descr = "deinterlace_vaapi=rate=field:auto=1"; // + const char *filters_descr = "deinterlace_vaapi=rate=field:auto=1"; #endif #ifdef YADIF const char *filters_descr = "yadif_cuda=1:0:1"; // mode=send_field,parity=tff,deint=interlaced"; @@ -2751,9 +2729,9 @@ int init_filters(AVCodecContext * dec_ctx, CuvidDecoder * decoder, AVFrame * fra #endif #ifdef VAAPI -static int init_generic_hwaccel(CuvidDecoder * decoder, enum AVPixelFormat hw_fmt,AVCodecContext * video_ctx) +static int init_generic_hwaccel(CuvidDecoder * decoder, enum AVPixelFormat hw_fmt, AVCodecContext * video_ctx) { - + AVBufferRef *new_frames_ctx = NULL; if (!hw_device_ctx) { @@ -2761,9 +2739,7 @@ static int init_generic_hwaccel(CuvidDecoder * decoder, enum AVPixelFormat hw_fm goto error; } - if (avcodec_get_hw_frames_parameters(video_ctx, - hw_device_ctx, hw_fmt, &new_frames_ctx) < 0) - { + if (avcodec_get_hw_frames_parameters(video_ctx, hw_device_ctx, hw_fmt, &new_frames_ctx) < 0) { Debug(3, "Hardware decoding of this stream is unsupported?\n"); goto error; } @@ -2773,20 +2749,17 @@ static int init_generic_hwaccel(CuvidDecoder * decoder, enum AVPixelFormat hw_fm // We might be able to reuse a previously allocated frame pool. if (decoder->cached_hw_frames_ctx) { AVHWFramesContext *old_fctx = (void *)decoder->cached_hw_frames_ctx->data; - Debug(3,"CMP %d:%d %d:%d %d:%d %d:%d %d:%d\,",new_fctx->format, old_fctx->format, - new_fctx->sw_format,old_fctx->sw_format , - new_fctx->width, old_fctx->width , - new_fctx->height, old_fctx->height , - new_fctx->initial_pool_size, old_fctx->initial_pool_size); - if (new_fctx->format != old_fctx->format || - new_fctx->sw_format != old_fctx->sw_format || - new_fctx->width != old_fctx->width || - new_fctx->height != old_fctx->height || - new_fctx->initial_pool_size != old_fctx->initial_pool_size) { - Debug(3,"delete old cache"); - if (decoder->filter_graph) - avfilter_graph_free(&decoder->filter_graph); - av_buffer_unref(&decoder->cached_hw_frames_ctx); + + Debug(3, "CMP %d:%d %d:%d %d:%d %d:%d %d:%d\,", new_fctx->format, old_fctx->format, new_fctx->sw_format, + old_fctx->sw_format, new_fctx->width, old_fctx->width, new_fctx->height, old_fctx->height, + new_fctx->initial_pool_size, old_fctx->initial_pool_size); + if (new_fctx->format != old_fctx->format || new_fctx->sw_format != old_fctx->sw_format + || new_fctx->width != old_fctx->width || new_fctx->height != old_fctx->height + || new_fctx->initial_pool_size != old_fctx->initial_pool_size) { + Debug(3, "delete old cache"); + if (decoder->filter_graph) + avfilter_graph_free(&decoder->filter_graph); + av_buffer_unref(&decoder->cached_hw_frames_ctx); } } @@ -2808,8 +2781,8 @@ static int init_generic_hwaccel(CuvidDecoder * decoder, enum AVPixelFormat hw_fm av_buffer_unref(&new_frames_ctx); return 0; -error: - Debug(3,"Error with hwframes\n"); + error: + Debug(3, "Error with hwframes\n"); av_buffer_unref(&new_frames_ctx); av_buffer_unref(&decoder->cached_hw_frames_ctx); return -1; @@ -2866,17 +2839,17 @@ static enum AVPixelFormat Cuvid_get_format(CuvidDecoder * decoder, AVCodecContex if (*fmt_idx != PIXEL_FORMAT) { Fatal(_("video: no valid profile found\n")); } - -// decoder->newchannel = 1; + + // decoder->newchannel = 1; #ifdef VAAPI - init_generic_hwaccel(decoder, PIXEL_FORMAT,video_ctx); + init_generic_hwaccel(decoder, PIXEL_FORMAT, video_ctx); #endif if (ist->GetFormatDone) { return PIXEL_FORMAT; - } + } ist->GetFormatDone = 1; - + Debug(3, "video: create decoder 16bit?=%d %dx%d old %d %d\n", bitformat16, video_ctx->width, video_ctx->height, decoder->InputWidth, decoder->InputHeight); @@ -2892,10 +2865,10 @@ static enum AVPixelFormat Cuvid_get_format(CuvidDecoder * decoder, AVCodecContex ist->hwaccel_output_format = AV_PIX_FMT_NV12; } - if ((video_ctx->width != decoder->InputWidth - || video_ctx->height != decoder->InputHeight) && decoder->TrickSpeed == 0) { + if ((video_ctx->width != decoder->InputWidth || video_ctx->height != decoder->InputHeight) + && decoder->TrickSpeed == 0) { - // if (decoder->TrickSpeed == 0) { + // if (decoder->TrickSpeed == 0) { #ifdef PLACEBO VideoThreadLock(); #endif @@ -2924,7 +2897,7 @@ static enum AVPixelFormat Cuvid_get_format(CuvidDecoder * decoder, AVCodecContex Fatal(_("codec: can't set option deint to video codec!\n")); } #endif - } else { + } else { decoder->SyncCounter = 0; decoder->FrameCounter = 0; decoder->FramesDisplayed = 0; @@ -2939,10 +2912,10 @@ static enum AVPixelFormat Cuvid_get_format(CuvidDecoder * decoder, AVCodecContex #ifdef CUVID ist->active_hwaccel_id = HWACCEL_CUVID; #else - if (VideoDeinterlace[decoder->Resolution]) // need deinterlace - ist->filter = 1; // init deint vaapi - else - ist->filter = 0; + if (VideoDeinterlace[decoder->Resolution]) // need deinterlace + ist->filter = 1; // init deint vaapi + else + ist->filter = 0; ist->active_hwaccel_id = HWACCEL_VAAPI; #endif @@ -3018,16 +2991,16 @@ int get_RGB(CuvidDecoder * decoder) texLoc = glGetUniformLocation(gl_prog, "texture1"); glUniform1i(texLoc, 1); #ifdef RASPI - texLoc = glGetUniformLocation(gl_prog, "texture2"); - glUniform1i(texLoc, 2); + texLoc = glGetUniformLocation(gl_prog, "texture2"); + glUniform1i(texLoc, 2); #endif glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 0]); glActiveTexture(GL_TEXTURE1); 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]); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 2]); #endif glBindFramebuffer(GL_FRAMEBUFFER, fb); @@ -3094,7 +3067,7 @@ int get_RGB(CuvidDecoder * decoder) glDeleteFramebuffers(1, &fb); glDeleteTextures(1, &texture); -#else // Placebo +#else // Placebo faktorx = (float)width / (float)VideoWindowWidth; faktory = (float)height / (float)VideoWindowHeight; fmt = pl_find_named_fmt(p->gpu, "bgra8"); @@ -3358,11 +3331,11 @@ static void CuvidRenderFrame(CuvidDecoder * decoder, const AVCodecContext * vide av_frame_free(&frame); return; } - + if (!decoder->Closing) { VideoSetPts(&decoder->PTS, decoder->Interlaced, video_ctx, frame); } - + // update aspect ratio changes if (decoder->InputWidth && decoder->InputHeight && av_cmp_q(decoder->InputAspect, frame->sample_aspect_ratio)) { Debug(3, "video/cuvid: aspect ratio changed\n"); @@ -3376,28 +3349,29 @@ static void CuvidRenderFrame(CuvidDecoder * decoder, const AVCodecContext * vide if (color == AVCOL_SPC_UNSPECIFIED) // if unknown color = AVCOL_SPC_BT709; #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); + // + // 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 // #ifdef RASPI - if (video_ctx->pix_fmt == 0) { + if (video_ctx->pix_fmt == 0) { #else if (video_ctx->pix_fmt == PIXEL_FORMAT) { #endif @@ -3465,9 +3439,9 @@ Debug(3,"fmt %02d:%02d width %d:%d hight %d:%d\n",decoder->ColorSpace,frame->co } -// Debug(3,"video/cuvid: pixel format %d not supported\n", video_ctx->pix_fmt); - av_frame_free(&frame); - return; + // Debug(3,"video/cuvid: pixel format %d not supported\n", video_ctx->pix_fmt); + av_frame_free(&frame); + return; } /// @@ -3477,7 +3451,7 @@ Debug(3,"fmt %02d:%02d width %d:%d hight %d:%d\n",decoder->ColorSpace,frame->co /// static void *CuvidGetHwAccelContext(CuvidDecoder * decoder) { - unsigned int version,ret; + unsigned int version, ret; Debug(3, "Initializing cuvid hwaccel thread ID:%ld\n", (long int)syscall(186)); // turn NULL; @@ -3486,7 +3460,7 @@ static void *CuvidGetHwAccelContext(CuvidDecoder * decoder) Debug(3, "schon passiert\n"); return NULL; } - + if (!cu) { ret = cuda_load_functions(&cu, NULL); if (ret < 0) { @@ -3596,7 +3570,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused)) GLint texLoc; AVFrame *frame; AVFrameSideData *FrameSideData = NULL; - + #ifdef PLACEBO if (level) { dst_rect.x0 = decoder->VideoX; // video window output (clip) @@ -3625,18 +3599,18 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused)) ycropf = (float)decoder->CropY / (float)decoder->InputHeight; current = decoder->SurfacesRb[decoder->SurfaceRead]; - -#ifdef USE_DRM + +#ifdef USE_DRM if (!decoder->Closing) { - frame = decoder->frames[current]; - AVFrameSideData *sd1 = av_frame_get_side_data (frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); - AVFrameSideData *sd2 = av_frame_get_side_data (frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); - set_hdr_metadata(frame->color_primaries,frame->color_trc,sd1,sd2); + frame = decoder->frames[current]; + AVFrameSideData *sd1 = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); + AVFrameSideData *sd2 = av_frame_get_side_data(frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); + + set_hdr_metadata(frame->color_primaries, frame->color_trc, sd1, sd2); } #endif - - - // Render Progressive frame + + // Render Progressive frame #ifndef PLACEBO y = VideoWindowHeight - decoder->OutputY - decoder->OutputHeight; if (y < 0) @@ -3652,19 +3626,19 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused)) texLoc = glGetUniformLocation(gl_prog, "texture1"); glUniform1i(texLoc, 1); #ifdef RASPI - texLoc = glGetUniformLocation(gl_prog, "texture2"); - glUniform1i(texLoc, 2); + texLoc = glGetUniformLocation(gl_prog, "texture2"); + glUniform1i(texLoc, 2); #endif - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 0]); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 1]); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 0]); + glActiveTexture(GL_TEXTURE1); + 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]); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, decoder->gl_textures[current * Planes + 2]); #endif - + render_pass_quad(0, xcropf, ycropf); glUseProgram(0); @@ -3673,12 +3647,12 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused)) #else img = &decoder->pl_images[current]; pl = &decoder->pl_images[current].planes[1]; - + memcpy(&deband, &pl_deband_default_params, sizeof(deband)); memcpy(&render_params, &pl_render_default_params, sizeof(render_params)); switch (decoder->ColorSpace) { - case AVCOL_SPC_RGB: // BT 601 is reportet as RGB + case AVCOL_SPC_RGB: // BT 601 is reportet as RGB img->repr.sys = PL_COLOR_SYSTEM_BT_601; img->repr.levels = PL_COLOR_LEVELS_TV; img->color.primaries = PL_COLOR_PRIM_BT_601_625; @@ -3803,13 +3777,12 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused)) colors.contrast = 0.0f; if (!pl_render_image(p->renderer, &decoder->pl_images[current], target, &render_params)) { Debug(3, "Failed rendering frame!\n"); - } + } return; } decoder->newchannel = 0; - - + if (!pl_render_image(p->renderer, &decoder->pl_images[current], target, &render_params)) { Debug(3, "Failed rendering frame!\n"); } @@ -3848,7 +3821,6 @@ void make_osd_overlay(int x, int y, int width, int height) { const struct pl_fmt *fmt; struct pl_overlay *pl; - int offset = VideoWindowHeight - (VideoWindowHeight - height - y) - (VideoWindowHeight - y); @@ -3914,14 +3886,14 @@ static void CuvidDisplayFrame(void) float ldiff; static int first = 1; float turnaround; - + #ifdef PLACEBO uint64_t diff; static float fdiff = 23000.0; struct pl_swapchain_frame frame; struct pl_render_target target; bool ok; - + VkImage Image; const struct pl_fmt *fmt; const float black[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; @@ -3942,7 +3914,7 @@ static void CuvidDisplayFrame(void) #endif glClear(GL_COLOR_BUFFER_BIT); -#else // PLACEBO +#else // PLACEBO if (CuvidDecoderN) { ldiff = (float)(GetusTicks() - round_time) / 1000000.0; @@ -4008,7 +3980,7 @@ static void CuvidDisplayFrame(void) else target.repr.levels = PL_COLOR_LEVELS_TV; target.repr.alpha = PL_ALPHA_UNKNOWN; - + // target.repr.bits.sample_depth = 16; // target.repr.bits.color_depth = 16; // target.repr.bits.bit_shift =0; @@ -4168,14 +4140,14 @@ static void CuvidDisplayFrame(void) #endif VideoThreadUnlock(); -#else // not PLACEBO +#else // not PLACEBO #ifdef CUVID glXGetVideoSyncSGI(&Count); // get current frame glXSwapBuffers(XlibDisplay, VideoWindow); glXMakeCurrent(XlibDisplay, None, NULL); #else -#ifndef USE_DRM - eglSwapBuffers(eglDisplay, eglSurface); +#ifndef USE_DRM + eglSwapBuffers(eglDisplay, eglSurface); eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); #else drm_swap_buffers(); @@ -4275,7 +4247,8 @@ static void CuvidSetTrickSpeed(CuvidDecoder * decoder, int speed) /// @param[out] dropped dropped frames /// @param[out] count number of decoded frames /// -void CuvidGetStats(CuvidDecoder * decoder, int *missed, int *duped, int *dropped, int *counter, float *frametime, int *width, int *height, int *color, int * eotf) +void CuvidGetStats(CuvidDecoder * decoder, int *missed, int *duped, int *dropped, int *counter, float *frametime, + int *width, int *height, int *color, int *eotf) { *missed = decoder->FramesMissed; *duped = decoder->FramesDuped; @@ -4307,15 +4280,14 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder) int64_t audio_clock; int64_t video_clock; int err = 0; - static int speedup=3; + static int speedup = 3; #ifdef GAMMA Get_Gamma(); #endif - - + video_clock = CuvidGetClock(decoder); - + filled = atomic_read(&decoder->SurfacesFilled); if (!decoder->SyncOnAudio) { @@ -4373,19 +4345,19 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder) } #endif if (abs(diff) > 5000 * 90) { // more than 5s - err = CuvidMessage(2, "video: audio/video difference too big %d\n",diff/90); + err = CuvidMessage(2, "video: audio/video difference too big %d\n", diff / 90); // decoder->SyncCounter = 1; // usleep(10); goto skip_sync; } else if (diff > 100 * 90) { - + err = CuvidMessage(4, "video: slow down video, duping frame %d\n", diff / 90); ++decoder->FramesDuped; if ((speedup && --speedup) || VideoSoftStartSync) decoder->SyncCounter = 1; - else - decoder->SyncCounter = 0; + else + decoder->SyncCounter = 0; goto out; } else if (diff > 25 * 90) { @@ -4398,13 +4370,12 @@ static void CuvidSyncDecoder(CuvidDecoder * decoder) err = CuvidMessage(3, "video: speed up video, droping frame %d\n", diff / 90); ++decoder->FramesDropped; CuvidAdvanceDecoderFrame(decoder); - } else if ((diff < -100 * 90)) { // give it some time to get frames to drop + } else if ((diff < -100 * 90)) { // give it some time to get frames to drop Debug(3, "Delay Audio %d ms\n", abs(diff / 90)); AudioDelayms(abs(diff / 90)); } decoder->SyncCounter = 1; - } - else { + } else { speedup = 2; } #if defined(DEBUG) || defined(AV_INFO) @@ -4575,7 +4546,6 @@ static void CuvidDisplayHandlerThread(void) allfull = 1; decoded = 0; - for (i = 0; i < CuvidDecoderN; ++i) { decoder = CuvidDecoders[i]; @@ -4607,7 +4577,7 @@ static void CuvidDisplayHandlerThread(void) } decoded = 1; } - + if (!decoded) { // nothing decoded, sleep // FIXME: sleep on wakeup usleep(1 * 1000); @@ -4669,14 +4639,14 @@ static const VideoModule CuvidModule = { .RenderFrame = (void (*const) (VideoHwDecoder *, const AVCodecContext *, const AVFrame *))CuvidSyncRenderFrame, .GetHwAccelContext = (void *(*const)(VideoHwDecoder *))CuvidGetHwAccelContext, - .SetClock = (void (*const)(VideoHwDecoder *, int64_t))CuvidSetClock, + .SetClock = (void(*const)(VideoHwDecoder *, int64_t))CuvidSetClock, .GetClock = (int64_t(*const)(const VideoHwDecoder *))CuvidGetClock, - .SetClosing = (void (*const)(const VideoHwDecoder *))CuvidSetClosing, - .ResetStart = (void (*const)(const VideoHwDecoder *))CuvidResetStart, - .SetTrickSpeed = (void (*const)(const VideoHwDecoder *, int))CuvidSetTrickSpeed, + .SetClosing = (void(*const)(const VideoHwDecoder *))CuvidSetClosing, + .ResetStart = (void(*const)(const VideoHwDecoder *))CuvidResetStart, + .SetTrickSpeed = (void(*const)(const VideoHwDecoder *, int))CuvidSetTrickSpeed, .GrabOutput = CuvidGrabOutputSurface, - .GetStats = (void (*const)(VideoHwDecoder *, int *, int *, int *, - int *, float *, int *, int *, int * , int *))CuvidGetStats, + .GetStats = (void(*const)(VideoHwDecoder *, int *, int *, int *, + int *, float *, int *, int *, int *, int *))CuvidGetStats, .SetBackground = CuvidSetBackground, .SetVideoMode = CuvidSetVideoMode, @@ -4837,14 +4807,14 @@ static const VideoModule NoopModule = { const AVCodecContext *, const AVFrame *))NoopSyncRenderFrame, .GetHwAccelContext = (void *(*const)(VideoHwDecoder *)) DummyGetHwAccelContext, - .SetClock = (void (*const)(VideoHwDecoder *, int64_t))NoopSetClock, + .SetClock = (void(*const)(VideoHwDecoder *, int64_t))NoopSetClock, .GetClock = (int64_t(*const)(const VideoHwDecoder *))NoopGetClock, - .SetClosing = (void (*const)(const VideoHwDecoder *))NoopSetClosing, - .ResetStart = (void (*const)(const VideoHwDecoder *))NoopResetStart, - .SetTrickSpeed =(void (*const)(const VideoHwDecoder *, int))NoopSetTrickSpeed, + .SetClosing = (void(*const)(const VideoHwDecoder *))NoopSetClosing, + .ResetStart = (void(*const)(const VideoHwDecoder *))NoopResetStart, + .SetTrickSpeed = (void(*const)(const VideoHwDecoder *, int))NoopSetTrickSpeed, .GrabOutput = NoopGrabOutputSurface, - .GetStats = (void (*const)(VideoHwDecoder *, int *, int *, int *, - int *, float *, int *, int *, int * , int *))NoopGetStats, + .GetStats = (void(*const)(VideoHwDecoder *, int *, int *, int *, + int *, float *, int *, int *, int *, int *))NoopGetStats, #endif .SetBackground = NoopSetBackground, .SetVideoMode = NoopVoid, @@ -4999,7 +4969,7 @@ void VideoOsdInit(void) if (posd) free(posd); - posd = (unsigned char *)calloc( (OsdWidth+1) * (OsdHeight+1) * 4, 1 ); + posd = (unsigned char *)calloc((OsdWidth + 1) * (OsdHeight + 1) * 4, 1); VideoOsdClear(); } @@ -5010,7 +4980,7 @@ void VideoOsdExit(void) { OsdDirtyWidth = 0; OsdDirtyHeight = 0; - VideoOsdClear(); + VideoOsdClear(); } //---------------------------------------------------------------------------- @@ -5199,8 +5169,6 @@ void pl_log_intern(void *stream, enum pl_log_level level, const char *msg) printf("%5s: %s\n", prefix[level], msg); } - - void InitPlacebo() { @@ -5211,7 +5179,7 @@ void InitPlacebo() char xcbext[] = { "VK_KHR_xcb_surface" }; char surfext[] = { "VK_KHR_surface" }; - Debug(3, "Init Placebo mit API %d\n",PL_API_VER); + Debug(3, "Init Placebo mit API %d\n", PL_API_VER); p = calloc(1, sizeof(struct priv)); if (!p) @@ -5299,17 +5267,18 @@ void InitPlacebo() /// /// Video render thread. /// - -void delete_decode() { - Debug(3,"decoder thread exit\n"); + +void delete_decode() +{ + Debug(3, "decoder thread exit\n"); } - + static void *VideoDisplayHandlerThread(void *dummy) { prctl(PR_SET_NAME, "video decoder", 0, 0, 0); sleep(2); - pthread_cleanup_push(delete_decode, NULL); + pthread_cleanup_push(delete_decode, NULL); for (;;) { // fix dead-lock with CuvidExit pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); @@ -5318,17 +5287,17 @@ static void *VideoDisplayHandlerThread(void *dummy) VideoUsedModule->DisplayHandlerThread(); } - pthread_cleanup_pop(NULL); + pthread_cleanup_pop(NULL); return dummy; } void exit_display() { - + #ifdef GAMMA Exit_Gamma(); #endif - + #ifdef PLACEBO Debug(3, "delete placebo\n"); if (p == NULL) @@ -5352,45 +5321,45 @@ void exit_display() p = NULL; #endif #ifdef CUVID - if (glxThreadContext) { + if (glxThreadContext) { glXDestroyContext(XlibDisplay, glxThreadContext); GlxCheck(); glxThreadContext = NULL; } #else - if (eglThreadContext) { + if (eglThreadContext) { eglDestroyContext(eglDisplay, eglThreadContext); EglCheck(); - eglThreadContext = NULL; + eglThreadContext = NULL; } #endif - Debug(3,"display thread exit\n"); + Debug(3, "display thread exit\n"); } - + static void *VideoHandlerThread(void *dummy) { EGLint contextAttrs[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE }; - + prctl(PR_SET_NAME, "video display", 0, 0, 0); #ifdef GAMMA Init_Gamma(); - Set_Gamma(0.0,6500); + Set_Gamma(0.0, 6500); #endif - + #ifdef PLACEBO InitPlacebo(); #else -#ifdef CUVID +#ifdef CUVID if (EglEnabled) { glxThreadContext = glXCreateContext(XlibDisplay, GlxVisualInfo, glxSharedContext, GL_TRUE); GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight, glxThreadContext); } -#endif +#endif #ifdef VAAPI eglThreadContext = eglCreateContext(eglDisplay, eglConfig, eglSharedContext, contextAttrs); if (!eglThreadContext) { @@ -5401,7 +5370,7 @@ static void *VideoHandlerThread(void *dummy) eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglThreadContext); #endif #endif - pthread_cleanup_push(exit_display, NULL); + pthread_cleanup_push(exit_display, NULL); for (;;) { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); @@ -5416,7 +5385,7 @@ static void *VideoHandlerThread(void *dummy) } pthread_cleanup_pop(NULL); - + return dummy; } @@ -5438,7 +5407,7 @@ static void VideoThreadInit(void) pthread_mutex_init(&OSDMutex, NULL); pthread_cond_init(&VideoWakeupCond, NULL); pthread_create(&VideoThread, NULL, VideoDisplayHandlerThread, NULL); - + pthread_create(&VideoDisplayThread, NULL, VideoHandlerThread, NULL); } @@ -5455,20 +5424,20 @@ static void VideoThreadExit(void) // FIXME: can't cancel locked if (pthread_cancel(VideoThread)) { - Debug(3,"video: can't queue cancel video display thread\n"); + Debug(3, "video: can't queue cancel video display thread\n"); } - usleep(200000); // 200ms + usleep(200000); // 200ms if (pthread_join(VideoThread, &retval) || retval != PTHREAD_CANCELED) { - Debug(3,"video: can't cancel video decoder thread\n"); + Debug(3, "video: can't cancel video decoder thread\n"); } - + if (VideoDisplayThread) { if (pthread_cancel(VideoDisplayThread)) { - Debug(3,"video: can't queue cancel video display thread\n"); - } + Debug(3, "video: can't queue cancel video display thread\n"); + } usleep(200000); // 200ms if (pthread_join(VideoDisplayThread, &retval) || retval != PTHREAD_CANCELED) { - Debug(3,"video: can't cancel video display thread\n"); + Debug(3, "video: can't cancel video display thread\n"); } VideoDisplayThread = 0; } @@ -5885,9 +5854,10 @@ uint8_t *VideoGrabService(int *size, int *width, int *height) /// @param[out] dropped dropped frames /// @param[out] count number of decoded frames /// -void VideoGetStats(VideoHwDecoder * hw_decoder, int *missed, int *duped, int *dropped, int *counter, float *frametime, int *width, int *height, int *color, int *eotf) +void VideoGetStats(VideoHwDecoder * hw_decoder, int *missed, int *duped, int *dropped, int *counter, float *frametime, + int *width, int *height, int *color, int *eotf) { - VideoUsedModule->GetStats(hw_decoder, missed, duped, dropped, counter, frametime, width, height , color, eotf); + VideoUsedModule->GetStats(hw_decoder, missed, duped, dropped, counter, frametime, width, height, color, eotf); } /// @@ -6162,9 +6132,8 @@ void VideoSetDevice(const char *device) { VideoDriverName = device; } - - -void VideoSetConnector( char *c) + +void VideoSetConnector(char *c) { DRMConnector = c; } @@ -6173,7 +6142,7 @@ void VideoSetRefresh(char *r) { DRMRefresh = atoi(r); } - + /// /// Get video driver name. /// @@ -6517,15 +6486,15 @@ void VideoSetDeinterlace(int mode[VideoResolutionMax]) VideoDeinterlace[1] = 1; //mode[1]; // 720p VideoDeinterlace[2] = mode[2]; // fake 1080 VideoDeinterlace[3] = mode[3]; // 1080 - VideoDeinterlace[4] = 1, //mode[4]; 2160p + VideoDeinterlace[4] = 1; //mode[4]; 2160p #else - VideoDeinterlace[0] = 1; // 576i + VideoDeinterlace[0] = 1; // 576i VideoDeinterlace[1] = 0; //mode[1]; // 720p - VideoDeinterlace[2] = 1; // fake 1080 - VideoDeinterlace[3] = 1; // 1080 - VideoDeinterlace[4] = 0, //mode[4]; 2160p + VideoDeinterlace[2] = 1; // fake 1080 + VideoDeinterlace[3] = 1; // 1080 + VideoDeinterlace[4] = 0; //mode[4]; 2160p #endif - VideoSurfaceModesChanged = 1; + VideoSurfaceModesChanged = 1; } /// @@ -6634,9 +6603,9 @@ void VideoSetStudioLevels(int onoff) { VideoStudioLevels = onoff; #ifdef GAMMA - Set_Gamma(2.4,6500); + Set_Gamma(2.4, 6500); #endif - + } /// @@ -6736,7 +6705,7 @@ void VideoInit(const char *display_name) #ifdef USE_DRM VideoInitDrm(); #else - + if (XlibDisplay) { // allow multiple calls Debug(3, "video: x11 already setup\n"); return; @@ -6865,7 +6834,7 @@ void VideoInit(const char *display_name) /// void VideoExit(void) { - Debug(3,"Video Exit\n"); + Debug(3, "Video Exit\n"); #ifndef USE_DRM if (!XlibDisplay) { // no init or failed return; @@ -6926,83 +6895,88 @@ void VideoExit(void) } -#ifdef USE_DRM -int GlxInitopengl () { +#ifdef USE_DRM +int GlxInitopengl() +{ EGLint contextAttrs[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE }; - while (!eglSharedContext) - sleep(1); + while (!eglSharedContext) + sleep(1); if (!eglOSDContext) { eglOSDContext = eglCreateContext(eglDisplay, eglConfig, eglSharedContext, contextAttrs); if (!eglOSDContext) { - EglCheck(); - Fatal(_("video/egl: can't create thread egl context\n")); - return NULL; - } + EglCheck(); + Fatal(_("video/egl: can't create thread egl context\n")); + return NULL; + } } eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglOSDContext); return; } - -int GlxDrawopengl () { + +int GlxDrawopengl() +{ eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglSharedContext); return; } - -void GlxDestroy() { - eglDestroyContext (eglDisplay, eglOSDContext); - eglOSDContext = NULL; + +void GlxDestroy() +{ + eglDestroyContext(eglDisplay, eglOSDContext); + eglOSDContext = NULL; } #endif - -#if 0 // for debug only -#include + +#if 0 // for debug only +#include extern uint8_t *CreateJpeg(uint8_t *, int *, int, int, int); -void makejpg(uint8_t *data, int width, int height) { - static int count=0; - int i,n=0,gpu=0;; - char buf[32],FileName[32]; - uint8_t *rgb; +void makejpg(uint8_t * data, int width, int height) +{ + static int count = 0; + int i, n = 0, gpu = 0;; + char buf[32], FileName[32]; + uint8_t *rgb; uint8_t *jpg_image; - int size,size1; - + int size, size1; + if (data == NULL) { - data = malloc(width*height*4); - gpu=1; + data = malloc(width * height * 4); + gpu = 1; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, data); } - -// n = snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", width, height); - sprintf(FileName,"/tmp/test%d.jpg",count++); - - rgb = malloc(width * height * 3 + n); - if (!rgb) { - printf("Unable to get RGB Memory \n"); - return; - } -// memcpy(rgb, buf, n); // header + + // n = snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", width, height); + sprintf(FileName, "/tmp/test%d.jpg", count++); + + rgb = malloc(width * height * 3 + n); + if (!rgb) { + printf("Unable to get RGB Memory \n"); + return; + } +// memcpy(rgb, buf, n); // header size = width * height * 4; - - for (i = 0; i < size / 4; ++i) { // convert bgra -> rgb - rgb[n + i * 3 + 0] = data[i * 4 + 2]; - rgb[n + i * 3 + 1] = data[i * 4 + 1]; - rgb[n + i * 3 + 2] = data[i * 4 + 0]; - } + + for (i = 0; i < size / 4; ++i) { // convert bgra -> rgb + rgb[n + i * 3 + 0] = data[i * 4 + 2]; + rgb[n + i * 3 + 1] = data[i * 4 + 1]; + rgb[n + i * 3 + 2] = data[i * 4 + 0]; + } if (gpu) free(data); - + jpg_image = CreateJpeg(rgb, &size1, 90, width, height); - int fd = open(FileName, O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC, DEFFILEMODE); - write(fd,jpg_image,size1); - close(fd); - free(rgb); + int fd = open(FileName, O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC, DEFFILEMODE); + + write(fd, jpg_image, size1); + close(fd); + free(rgb); } -#endif \ No newline at end of file +#endif