mirror of
https://github.com/jojo61/vdr-plugin-softhdcuvid.git
synced 2023-10-10 13:37:41 +02:00
First support for VAAPI
This commit is contained in:
parent
fae0d3a9bd
commit
5c2b801a45
118
Makefile
118
Makefile
@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Makefile for a Video Disk Recorder plugin
|
# Makefile for a Video Disk Recorder plugin
|
||||||
#
|
#
|
||||||
# $Id: 2a41981a57e5e83036463c6a08c84b86ed9d2be3 $
|
# $Id: 2a41981a57e5e83036463c6a08c84b86ed9d2be3 $
|
||||||
|
|
||||||
# The official name of this plugin.
|
# The official name of this plugin.
|
||||||
@ -11,35 +11,46 @@ PLUGIN = softhdcuvid
|
|||||||
|
|
||||||
### Configuration (edit this for your needs)
|
### Configuration (edit this for your needs)
|
||||||
|
|
||||||
|
# what kind of driver do we make -
|
||||||
|
# if VAAPI is enabled the drivername is softhdvaapi
|
||||||
|
# if CUVID is enabled the drivername is softhdcuvid
|
||||||
|
#VAAPI=1
|
||||||
|
CUVID=1
|
||||||
|
|
||||||
|
|
||||||
|
# support OPENGLOSD - only configurable with cuvid
|
||||||
|
OPENGLOSD=1
|
||||||
|
|
||||||
|
# use Libplacebo - only configurable with cuvid
|
||||||
|
LIBPLACEBO=1
|
||||||
|
|
||||||
|
# use YADIF deint - only configurable with cuvid
|
||||||
|
YADIF=0
|
||||||
|
|
||||||
|
#--------------------- no more config needed past this point--------------------------------
|
||||||
# support alsa audio output module
|
# support alsa audio output module
|
||||||
ALSA ?= $(shell pkg-config --exists alsa && echo 1)
|
ALSA ?= $(shell pkg-config --exists alsa && echo 1)
|
||||||
# support OSS audio output module
|
# support OSS audio output module
|
||||||
OSS ?= 1
|
OSS ?= 1
|
||||||
# support OPENGLOSD
|
|
||||||
OPENGLOSD=1
|
|
||||||
|
|
||||||
# use Libplacebo
|
# use DMPS
|
||||||
LIBPLACEBO=0
|
|
||||||
|
|
||||||
# use DMPS
|
|
||||||
SCREENSAVER=1
|
SCREENSAVER=1
|
||||||
|
|
||||||
OPENGL=1
|
OPENGL=1
|
||||||
# use ffmpeg libswresample
|
|
||||||
#SWRESAMPLE ?= $(shell pkg-config --exists libswresample && echo 1)
|
|
||||||
SWRESAMPLE = 1
|
|
||||||
# use libav libavresample
|
|
||||||
ifneq ($(SWRESAMPLE),1)
|
|
||||||
AVRESAMPLE ?= $(shell pkg-config --exists libavresample && echo 1)
|
|
||||||
AVRESAMPLE = 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
CONFIG := #-DDEBUG #-DOSD_DEBUG # enable debug output+functions
|
# use ffmpeg libswresample
|
||||||
CONFIG += -DCUVID # enable CUVID decoder
|
SWRESAMPLE ?= $(shell pkg-config --exists libswresample && echo 1)
|
||||||
#CONFIG += -DYADIF # enable yadif_cuda deinterlacer
|
SWRESAMPLE = 1
|
||||||
|
|
||||||
|
# use libav libavresample
|
||||||
|
#ifneq ($(SWRESAMPLE),1)
|
||||||
|
#AVRESAMPLE ?= $(shell pkg-config --exists libavresample && echo 1#)
|
||||||
|
#AVRESAMPLE = 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CONFIG := -DDEBUG #-DOSD_DEBUG # enable debug output+functions
|
||||||
CONFIG += -DHAVE_GL # needed for mpv libs
|
CONFIG += -DHAVE_GL # needed for mpv libs
|
||||||
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
|
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
|
||||||
|
|
||||||
CONFIG += -DAV_INFO -DAV_INFO_TIME=3000 # info/debug a/v sync
|
CONFIG += -DAV_INFO -DAV_INFO_TIME=3000 # info/debug a/v sync
|
||||||
CONFIG += -DUSE_PIP # PIP support
|
CONFIG += -DUSE_PIP # PIP support
|
||||||
#CONFIG += -DHAVE_PTHREAD_NAME # supports new pthread_setname_np
|
#CONFIG += -DHAVE_PTHREAD_NAME # supports new pthread_setname_np
|
||||||
@ -54,8 +65,9 @@ CONFIG += -DUSE_VDR_SPU # use VDR SPU decoder.
|
|||||||
|
|
||||||
### The version number of this plugin (taken from the main source file):
|
### The version number of this plugin (taken from the main source file):
|
||||||
|
|
||||||
VERSION = $(shell grep 'static const char \*const VERSION *=' $(PLUGIN).cpp | awk '{ print $$7 }' | sed -e 's/[";]//g')
|
VERSION = $(shell grep 'static const char \*const VERSION *=' softhdcuvid.cpp | awk '{ print $$7 }' | sed -e 's/[";]//g')
|
||||||
GIT_REV = $(shell git describe --always 2>/dev/null)
|
GIT_REV = $(shell git describe --always 2>/dev/null)
|
||||||
|
### The name of the distribution archive:
|
||||||
|
|
||||||
### The directory environment:
|
### The directory environment:
|
||||||
|
|
||||||
@ -87,14 +99,7 @@ APIVERSION = $(call PKGCFG,apiversion)
|
|||||||
|
|
||||||
-include $(PLGCFG)
|
-include $(PLGCFG)
|
||||||
|
|
||||||
### The name of the distribution archive:
|
|
||||||
|
|
||||||
ARCHIVE = $(PLUGIN)-$(VERSION)
|
|
||||||
PACKAGE = vdr-$(ARCHIVE)
|
|
||||||
|
|
||||||
### The name of the shared object file:
|
|
||||||
|
|
||||||
SOFILE = libvdr-$(PLUGIN).so
|
|
||||||
|
|
||||||
### Parse softhddevice config
|
### Parse softhddevice config
|
||||||
|
|
||||||
@ -103,16 +108,20 @@ CONFIG += -DUSE_ALSA
|
|||||||
_CFLAGS += $(shell pkg-config --cflags alsa)
|
_CFLAGS += $(shell pkg-config --cflags alsa)
|
||||||
LIBS += $(shell pkg-config --libs alsa)
|
LIBS += $(shell pkg-config --libs alsa)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(OSS),1)
|
ifeq ($(OSS),1)
|
||||||
CONFIG += -DUSE_OSS
|
CONFIG += -DUSE_OSS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(OPENGL),1)
|
ifeq ($(OPENGL),1)
|
||||||
_CFLAGS += $(shell pkg-config --cflags libva-glx)
|
_CFLAGS += $(shell pkg-config --cflags libva-glx)
|
||||||
LIBS += $(shell pkg-config --libs libva-glx)
|
LIBS += $(shell pkg-config --libs libva-glx)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(OPENGLOSD),1)
|
ifeq ($(OPENGLOSD),1)
|
||||||
CONFIG += -DUSE_OPENGLOSD
|
CONFIG += -DUSE_OPENGLOSD
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(OPENGL),1)
|
ifeq ($(OPENGL),1)
|
||||||
CONFIG += -DUSE_GLX
|
CONFIG += -DUSE_GLX
|
||||||
_CFLAGS += $(shell pkg-config --cflags gl glu glew)
|
_CFLAGS += $(shell pkg-config --cflags gl glu glew)
|
||||||
@ -122,18 +131,43 @@ LIBS += $(shell pkg-config --libs glew)
|
|||||||
_CFLAGS += $(shell pkg-config --cflags freetype2)
|
_CFLAGS += $(shell pkg-config --cflags freetype2)
|
||||||
LIBS += $(shell pkg-config --libs freetype2)
|
LIBS += $(shell pkg-config --libs freetype2)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(VAAPI),1)
|
||||||
|
CONFIG += -DVAAPI
|
||||||
|
LIBPLACEBO=1
|
||||||
|
PLUGIN = softhdvaapi
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(LIBPLACEBO),1)
|
ifeq ($(LIBPLACEBO),1)
|
||||||
CONFIG += -DPLACEBO
|
CONFIG += -DPLACEBO
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CUVID),1)
|
||||||
|
CONFIG += -DCUVID # enable CUVID decoder
|
||||||
|
ifeq ($(YADIF),1)
|
||||||
|
CONFIG += -DYADIF # Yadif only with CUVID
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ARCHIVE = $(PLUGIN)-$(VERSION)
|
||||||
|
PACKAGE = vdr-$(ARCHIVE)
|
||||||
|
|
||||||
|
### The name of the shared object file:
|
||||||
|
|
||||||
|
SOFILE = libvdr-$(PLUGIN).so
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test that libswresample is available
|
# Test that libswresample is available
|
||||||
#
|
#
|
||||||
ifneq (exists, $(shell pkg-config libswresample && echo exists))
|
#ifneq (exists, $(shell pkg-config libswresample && echo exists))
|
||||||
$(warning ******************************************************************)
|
# $(warning ******************************************************************)
|
||||||
$(warning 'libswresample' not found!)
|
# $(warning 'libswresample' not found!)
|
||||||
$(error ******************************************************************)
|
# $(error ******************************************************************)
|
||||||
endif
|
#endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test and set config for libavutil
|
# Test and set config for libavutil
|
||||||
@ -179,11 +213,11 @@ CONFIG += -DUSE_SWRESAMPLE
|
|||||||
_CFLAGS += $(shell pkg-config --cflags libswresample)
|
_CFLAGS += $(shell pkg-config --cflags libswresample)
|
||||||
LIBS += $(shell pkg-config --libs libswresample)
|
LIBS += $(shell pkg-config --libs libswresample)
|
||||||
endif
|
endif
|
||||||
#ifeq ($(AVRESAMPLE),1)
|
ifeq ($(AVRESAMPLE),1)
|
||||||
#CONFIG += -DUSE_AVRESAMPLE
|
CONFIG += -DUSE_AVRESAMPLE
|
||||||
#_CFLAGS += $(shell pkg-config --cflags libavresample)
|
_CFLAGS += $(shell pkg-config --cflags libavresample)
|
||||||
#LIBS += $(shell pkg-config --libs libavresample)
|
LIBS += $(shell pkg-config --libs libavresample)
|
||||||
#endif
|
endif
|
||||||
|
|
||||||
#_CFLAGS += $(shell pkg-config --cflags libavcodec x11 x11-xcb xcb xcb-icccm)
|
#_CFLAGS += $(shell pkg-config --cflags libavcodec x11 x11-xcb xcb xcb-icccm)
|
||||||
#LIBS += -lrt $(shell pkg-config --libs libavcodec x11 x11-xcb xcb xcb-icccm)
|
#LIBS += -lrt $(shell pkg-config --libs libavcodec x11 x11-xcb xcb xcb-icccm)
|
||||||
@ -200,7 +234,11 @@ ifeq ($(LIBPLACEBO),1)
|
|||||||
LIBS += -lplacebo -lglut
|
LIBS += -lplacebo -lglut
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LIBS += -lGLEW -lGLX -ldl -lcuda -L/usr/local/cuda/targets/x86_64-linux/lib -lcudart -lnvcuvid
|
ifeq ($(CUVID),1)
|
||||||
|
LIBS += -lcuda -L/usr/local/cuda/targets/x86_64-linux/lib -lcudart -lnvcuvid
|
||||||
|
endif
|
||||||
|
|
||||||
|
LIBS += -lGLEW -lGLX -ldl
|
||||||
### Includes and Defines (add further entries here):
|
### Includes and Defines (add further entries here):
|
||||||
|
|
||||||
INCLUDES +=
|
INCLUDES +=
|
||||||
@ -218,12 +256,12 @@ override CFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
|
|||||||
|
|
||||||
### The object files (add further files here):
|
### The object files (add further files here):
|
||||||
|
|
||||||
OBJS = $(PLUGIN).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)
|
ifeq ($(OPENGLOSD),1)
|
||||||
OBJS += openglosd.o
|
OBJS += openglosd.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SRCS = $(wildcard $(OBJS:.o=.c)) $(PLUGIN).cpp
|
SRCS = $(wildcard $(OBJS:.o=.c)) softhdcuvid.cpp
|
||||||
|
|
||||||
### The main target:
|
### The main target:
|
||||||
|
|
||||||
|
@ -40,13 +40,17 @@ A software and GPU emulated UHD output device plugin for VDR.
|
|||||||
To compile you must have the 'requires' installed.
|
To compile you must have the 'requires' installed.
|
||||||
|
|
||||||
|
|
||||||
This is a fork of johns original softhddevice work and I reworked ist to support HEVC with CUDA and opengl output.
|
This is a fork of johns original softhddevice work and I reworked it to support HEVC with CUDA and opengl output.
|
||||||
Currently I have tested it with a GTX 1050 from NVIDIA. SD, HD and UHD is working.
|
Currently I have tested it with a GTX 1050 from NVIDIA. SD, HD and UHD is working.
|
||||||
|
|
||||||
Current Status NVIDA:
|
Current Status NVIDIA:
|
||||||
The CUDA driver supports HEVC with 8 Bit and 10 Bit up to UHD resolution. Opengl is able to output also 10 Bit, but NVIDIA does not support to output 10 Bit via HDMI.
|
The CUDA driver supports HEVC with 8 Bit and 10 Bit up to UHD resolution. Opengl is able to output also 10 Bit, but NVIDIA does not support to output 10 Bit via HDMI.
|
||||||
Only via DisplayPort you can get 10 Bit output to a compatible screen. This is a restriction from NVIDIA.
|
Only via DisplayPort you can get 10 Bit output to a compatible screen. This is a restriction from NVIDIA.
|
||||||
|
|
||||||
|
Current Status with VAAPI
|
||||||
|
You need libplacebo.
|
||||||
|
It is still beta and 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. The vaapi_deinterlace is broken and the amdgpu driver is instable. I have not testet with amdgpupro
|
||||||
|
|
||||||
You have to adapt the Makefile to your needs. I use FFMPEG 4.0
|
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
|
The Makefile expects the CUDA SDK in /usr/local/cuda. Currently it is tested with CUDA 10
|
||||||
|
179
codec.c
179
codec.c
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// @file codec.c @brief Codec functions
|
/// @file codec.c @brief Codec functions
|
||||||
///
|
///
|
||||||
@ -200,16 +201,20 @@ static int Codec_get_buffer2(AVCodecContext * video_ctx, AVFrame * frame, int fl
|
|||||||
if (!decoder->GetFormatDone) { // get_format missing
|
if (!decoder->GetFormatDone) { // get_format missing
|
||||||
enum AVPixelFormat fmts[2];
|
enum AVPixelFormat fmts[2];
|
||||||
|
|
||||||
fprintf(stderr, "codec: buggy libav, use ffmpeg\n");
|
// fprintf(stderr, "codec: buggy libav, use ffmpeg\n");
|
||||||
Warning(_("codec: buggy libav, use ffmpeg\n"));
|
// Warning(_("codec: buggy libav, use ffmpeg\n"));
|
||||||
fmts[0] = video_ctx->pix_fmt;
|
fmts[0] = video_ctx->pix_fmt;
|
||||||
fmts[1] = AV_PIX_FMT_NONE;
|
fmts[1] = AV_PIX_FMT_NONE;
|
||||||
Codec_get_format(video_ctx, fmts);
|
Codec_get_format(video_ctx, fmts);
|
||||||
}
|
}
|
||||||
if (decoder->hwaccel_get_buffer && (AV_PIX_FMT_VDPAU == decoder->hwaccel_pix_fmt || AV_PIX_FMT_CUDA == decoder->hwaccel_pix_fmt)) {
|
#if 0
|
||||||
|
if (decoder->hwaccel_get_buffer && (AV_PIX_FMT_VDPAU == decoder->hwaccel_pix_fmt ||
|
||||||
|
AV_PIX_FMT_CUDA == decoder->hwaccel_pix_fmt ||
|
||||||
|
AV_PIX_FMT_VAAPI == decoder->hwaccel_pix_fmt)) {
|
||||||
//Debug(3,"hwaccel get_buffer\n");
|
//Debug(3,"hwaccel get_buffer\n");
|
||||||
return decoder->hwaccel_get_buffer(video_ctx, frame, flags);
|
return decoder->hwaccel_get_buffer(video_ctx, frame, flags);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
//Debug(3, "codec: fallback to default get_buffer\n");
|
//Debug(3, "codec: fallback to default get_buffer\n");
|
||||||
return avcodec_default_get_buffer2(video_ctx, frame, flags);
|
return avcodec_default_get_buffer2(video_ctx, frame, flags);
|
||||||
}
|
}
|
||||||
@ -268,6 +273,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
name = "NULL";
|
name = "NULL";
|
||||||
|
#ifdef CUVID
|
||||||
if (!strcasecmp(VideoGetDriverName(), "cuvid")) {
|
if (!strcasecmp(VideoGetDriverName(), "cuvid")) {
|
||||||
switch (codec_id) {
|
switch (codec_id) {
|
||||||
case AV_CODEC_ID_MPEG2VIDEO:
|
case AV_CODEC_ID_MPEG2VIDEO:
|
||||||
@ -281,11 +287,11 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (name && (video_codec = avcodec_find_decoder_by_name(name))) {
|
if (name && (video_codec = avcodec_find_decoder_by_name(name))) {
|
||||||
Debug(3, "codec: decoder found\n");
|
Debug(3, "codec: decoder found\n");
|
||||||
} else {
|
} else if ((video_codec = avcodec_find_decoder(codec_id))==NULL) {
|
||||||
Debug(3,"Decoder %s not supported\n",name);
|
Debug(3,"Decoder %s not supported %p\n",name,video_codec);
|
||||||
Fatal(_(" No decoder found"));
|
Fatal(_(" No decoder found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,13 +315,45 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
decoder->VideoCtx->pkt_timebase.den = 90000;
|
decoder->VideoCtx->pkt_timebase.den = 90000;
|
||||||
decoder->VideoCtx->framerate.num = 50;
|
decoder->VideoCtx->framerate.num = 50;
|
||||||
decoder->VideoCtx->framerate.den = 1;
|
decoder->VideoCtx->framerate.den = 1;
|
||||||
|
decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1
|
||||||
|
|
||||||
pthread_mutex_lock(&CodecLockMutex);
|
pthread_mutex_lock(&CodecLockMutex);
|
||||||
// open codec
|
// open codec
|
||||||
#ifdef YADIF
|
#ifdef YADIF
|
||||||
deint = 0;
|
deint = 2;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef VAAPI
|
||||||
|
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");
|
||||||
|
//decoder->VideoCtx->flags |= CODEC_FLAG_TRUNCATED;
|
||||||
|
}
|
||||||
|
// FIXME: own memory management for video frames.
|
||||||
|
if (video_codec->capabilities & AV_CODEC_CAP_DR1) {
|
||||||
|
Debug(3,"codec: can use own buffer management");
|
||||||
|
}
|
||||||
|
if (video_codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
|
||||||
|
Debug(3,"codec: supports frame threads");
|
||||||
|
decoder->VideoCtx->thread_count = 0;
|
||||||
|
// decoder->VideoCtx->thread_type |= FF_THREAD_FRAME;
|
||||||
|
}
|
||||||
|
if (video_codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
|
||||||
|
Debug(3,"codec: supports slice threads");
|
||||||
|
decoder->VideoCtx->thread_count = 0;
|
||||||
|
// decoder->VideoCtx->thread_type |= FF_THREAD_SLICE;
|
||||||
|
}
|
||||||
|
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 CUVID
|
||||||
if (strcmp(decoder->VideoCodec->long_name,"Nvidia CUVID MPEG2VIDEO decoder") == 0) { // deinterlace for mpeg2 is somehow broken
|
if (strcmp(decoder->VideoCodec->long_name,"Nvidia CUVID MPEG2VIDEO decoder") == 0) { // deinterlace for mpeg2 is somehow broken
|
||||||
if (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", deint ,0) < 0) { // adaptive
|
if (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", deint ,0) < 0) { // adaptive
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
@ -348,7 +386,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
Fatal(_("codec: can't set option drop 2.field to video codec!\n"));
|
Fatal(_("codec: can't set option drop 2.field to video codec!\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((ret = avcodec_open2(decoder->VideoCtx, video_codec, NULL)) < 0) {
|
if ((ret = avcodec_open2(decoder->VideoCtx, video_codec, NULL)) < 0) {
|
||||||
pthread_mutex_unlock(&CodecLockMutex);
|
pthread_mutex_unlock(&CodecLockMutex);
|
||||||
@ -363,24 +401,25 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
|||||||
//decoder->VideoCtx->debug = FF_DEBUG_STARTCODE;
|
//decoder->VideoCtx->debug = FF_DEBUG_STARTCODE;
|
||||||
//decoder->VideoCtx->err_recognition |= AV_EF_EXPLODE;
|
//decoder->VideoCtx->err_recognition |= AV_EF_EXPLODE;
|
||||||
|
|
||||||
|
// av_log_set_level(AV_LOG_DEBUG);
|
||||||
|
av_log_set_level(0);
|
||||||
|
|
||||||
decoder->VideoCtx->get_format = Codec_get_format;
|
decoder->VideoCtx->get_format = Codec_get_format;
|
||||||
decoder->VideoCtx->get_buffer2 = Codec_get_buffer2;
|
decoder->VideoCtx->get_buffer2 = Codec_get_buffer2;
|
||||||
decoder->VideoCtx->thread_count = 1;
|
// decoder->VideoCtx->active_thread_type = 0;
|
||||||
decoder->VideoCtx->active_thread_type = 0;
|
|
||||||
decoder->VideoCtx->draw_horiz_band = NULL;
|
decoder->VideoCtx->draw_horiz_band = NULL;
|
||||||
if (strstr(decoder->VideoCodec->long_name,"Nvidia CUVID") != NULL)
|
decoder->VideoCtx->hwaccel_context = VideoGetHwAccelContext(decoder->HwDecoder);
|
||||||
decoder->VideoCtx->hwaccel_context = VideoGetHwAccelContext(decoder->HwDecoder);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Prepare frame buffer for decoder
|
// Prepare frame buffer for decoder
|
||||||
//
|
//
|
||||||
|
#if 0
|
||||||
if (!(decoder->Frame = av_frame_alloc())) {
|
if (!(decoder->Frame = av_frame_alloc())) {
|
||||||
Fatal(_("codec: can't allocate video decoder frame buffer\n"));
|
Fatal(_("codec: can't allocate video decoder frame buffer\n"));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// reset buggy ffmpeg/libav flag
|
// reset buggy ffmpeg/libav flag
|
||||||
decoder->GetFormatDone = 0;
|
decoder->GetFormatDone = 0;
|
||||||
#ifdef YADIF
|
#ifdef YADIF
|
||||||
@ -401,7 +440,7 @@ void CodecVideoClose(VideoDecoder *video_decoder)
|
|||||||
{
|
{
|
||||||
|
|
||||||
// FIXME: play buffered data
|
// FIXME: play buffered data
|
||||||
av_frame_free(&video_decoder->Frame); // callee does checks
|
// av_frame_free(&video_decoder->Frame); // callee does checks
|
||||||
|
|
||||||
Debug(3,"CodecVideoClose\n");
|
Debug(3,"CodecVideoClose\n");
|
||||||
if (video_decoder->VideoCtx) {
|
if (video_decoder->VideoCtx) {
|
||||||
@ -465,37 +504,100 @@ extern int CuvidTestSurfaces();
|
|||||||
extern int init_filters(AVCodecContext * dec_ctx,void * decoder,AVFrame *frame);
|
extern int init_filters(AVCodecContext * dec_ctx,void * decoder,AVFrame *frame);
|
||||||
extern int push_filters(AVCodecContext * dec_ctx,void * decoder,AVFrame *frame);
|
extern int push_filters(AVCodecContext * dec_ctx,void * decoder,AVFrame *frame);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef VAAPI
|
||||||
|
void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
||||||
|
{
|
||||||
|
AVCodecContext *video_ctx = decoder->VideoCtx;
|
||||||
|
|
||||||
|
if (video_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||||
|
int ret;
|
||||||
|
AVPacket pkt[1];
|
||||||
|
AVFrame *frame;
|
||||||
|
|
||||||
|
*pkt = *avpkt; // use copy
|
||||||
|
ret = avcodec_send_packet(video_ctx, pkt);
|
||||||
|
if (ret < 0) {
|
||||||
|
Debug(4,"codec: sending video packet failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
frame = av_frame_alloc();
|
||||||
|
ret = avcodec_receive_frame(video_ctx, frame);
|
||||||
|
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
|
||||||
|
Debug(4,"codec: receiving video frame failed");
|
||||||
|
av_frame_free(&frame);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ret >= 0) {
|
||||||
|
if (decoder->filter ) {
|
||||||
|
if (decoder->filter == 1) {
|
||||||
|
if (init_filters(video_ctx,decoder->HwDecoder,frame) < 0) {
|
||||||
|
Debug(3,"video: Init of VAAPI deint Filter failed\n");
|
||||||
|
decoder->filter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Debug(3,"Init VAAPI deint ok\n");
|
||||||
|
decoder->filter = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (frame->interlaced_frame && decoder->filter == 2 && (frame->height != 720)) { // broken ZDF sends Interlaced flag
|
||||||
|
ret = push_filters(video_ctx,decoder->HwDecoder,frame);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
av_frame_free(&frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef CUVID
|
||||||
|
|
||||||
void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
void CodecVideoDecode(VideoDecoder * decoder, const AVPacket * avpkt)
|
||||||
{
|
{
|
||||||
AVCodecContext *video_ctx;
|
AVCodecContext *video_ctx;
|
||||||
AVFrame *frame;
|
AVFrame *frame
|
||||||
|
|
||||||
|
;
|
||||||
int ret,ret1;
|
int ret,ret1;
|
||||||
int got_frame;
|
int got_frame;
|
||||||
int consumed = 0;
|
int consumed = 0;
|
||||||
|
static uint64_t first_time = 0;
|
||||||
const AVPacket *pkt;
|
const AVPacket *pkt;
|
||||||
|
|
||||||
next_part:
|
next_part:
|
||||||
video_ctx = decoder->VideoCtx;
|
video_ctx = decoder->VideoCtx;
|
||||||
frame = decoder->Frame;
|
|
||||||
pkt = avpkt; // use copy
|
pkt = avpkt; // use copy
|
||||||
got_frame = 0;
|
got_frame = 0;
|
||||||
|
|
||||||
|
// printf("decode packet %d\n",(GetusTicks()-first_time)/1000000);
|
||||||
ret1 = avcodec_send_packet(video_ctx, pkt);
|
ret1 = avcodec_send_packet(video_ctx, pkt);
|
||||||
|
|
||||||
|
// first_time = GetusTicks();
|
||||||
|
|
||||||
if (ret1 >= 0) {
|
if (ret1 >= 0) {
|
||||||
consumed = 1;
|
consumed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!CuvidTestSurfaces())
|
||||||
|
usleep(1000);
|
||||||
|
|
||||||
|
//printf("send packet to decode %s\n",consumed?"ok":"Full");
|
||||||
|
|
||||||
if ((ret1 == AVERROR(EAGAIN) || ret1 == AVERROR_EOF || ret1 >= 0) && CuvidTestSurfaces()) {
|
if ((ret1 == AVERROR(EAGAIN) || ret1 == AVERROR_EOF || ret1 >= 0) && CuvidTestSurfaces()) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
while ((ret >= 0) && CuvidTestSurfaces()) { // get frames until empty snd Surfaces avail.
|
while ((ret >= 0) && CuvidTestSurfaces()) { // get frames until empty snd Surfaces avail.
|
||||||
|
frame = av_frame_alloc();
|
||||||
ret = avcodec_receive_frame(video_ctx, frame); // get new frame
|
ret = avcodec_receive_frame(video_ctx, frame); // get new frame
|
||||||
if (ret >= 0) { // one is avail.
|
if (ret >= 0) { // one is avail.
|
||||||
got_frame = 1;
|
got_frame = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
got_frame = 0;
|
got_frame = 0;
|
||||||
}
|
}
|
||||||
|
// printf("got %s packet from decoder\n",got_frame?"1":"no");
|
||||||
if (got_frame) { // frame completed
|
if (got_frame) { // frame completed
|
||||||
#ifdef YADIF
|
#ifdef YADIF
|
||||||
if (decoder->filter ) {
|
if (decoder->filter ) {
|
||||||
@ -511,12 +613,13 @@ next_part:
|
|||||||
}
|
}
|
||||||
if (frame->interlaced_frame && decoder->filter == 2 && (frame->height != 720)) { // broken ZDF sends Interlaced flag
|
if (frame->interlaced_frame && decoder->filter == 2 && (frame->height != 720)) { // broken ZDF sends Interlaced flag
|
||||||
ret = push_filters(video_ctx,decoder->HwDecoder,frame);
|
ret = push_filters(video_ctx,decoder->HwDecoder,frame);
|
||||||
av_frame_unref(frame);
|
// av_frame_unref(frame);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef FFMPEG_WORKAROUND_ARTIFACTS
|
#ifdef FFMPEG_WORKAROUND_ARTIFACTS
|
||||||
|
|
||||||
if (!CodecUsePossibleDefectFrames && decoder->FirstKeyFrame) {
|
if (!CodecUsePossibleDefectFrames && decoder->FirstKeyFrame) {
|
||||||
decoder->FirstKeyFrame++;
|
decoder->FirstKeyFrame++;
|
||||||
if (frame->key_frame || (decoder->FirstKeyFrame > 3)) { // key frame is not reliable
|
if (frame->key_frame || (decoder->FirstKeyFrame > 3)) { // key frame is not reliable
|
||||||
@ -524,31 +627,35 @@ next_part:
|
|||||||
decoder->FirstKeyFrame = 0;
|
decoder->FirstKeyFrame = 0;
|
||||||
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
|
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
|
||||||
}
|
}
|
||||||
av_frame_unref(frame);
|
// av_frame_unref(frame);
|
||||||
} else {
|
} else {
|
||||||
//DisplayPts(video_ctx, frame);
|
//DisplayPts(video_ctx, frame);
|
||||||
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
|
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
|
||||||
av_frame_unref(frame);
|
// av_frame_unref(frame);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
//DisplayPts(video_ctx, frame);
|
//DisplayPts(video_ctx, frame);
|
||||||
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
|
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
|
||||||
av_frame_unref(frame);
|
// av_frame_unref(frame);
|
||||||
#endif
|
#endif
|
||||||
// printf("got frame\n");
|
} else {
|
||||||
} else {
|
av_frame_free(&frame);
|
||||||
// printf("codec: got no frame %d send %d\n",ret,ret1);
|
// printf("codec: got no frame %d send %d\n",ret,ret1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!CuvidTestSurfaces()) {
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// consumed = 1;
|
// consumed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!consumed) {
|
if (!consumed) {
|
||||||
goto next_part; // try again to stuff decoder
|
goto next_part; // try again to stuff decoder
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
** Flush the video decoder.
|
** Flush the video decoder.
|
||||||
@ -702,7 +809,7 @@ void CodecAudioOpen(AudioDecoder * audio_decoder, int codec_id)
|
|||||||
|
|
||||||
Debug(3, "codec: using audio codec ID %#06x (%s)\n", codec_id,
|
Debug(3, "codec: using audio codec ID %#06x (%s)\n", codec_id,
|
||||||
avcodec_get_name(codec_id));
|
avcodec_get_name(codec_id));
|
||||||
if (!(audio_codec = avcodec_find_decoder_by_name(avcodec_get_name(codec_id)))) {
|
if (!(audio_codec = avcodec_find_decoder(codec_id))) {
|
||||||
// if (!(audio_codec = avcodec_find_decoder(codec_id))) {
|
// if (!(audio_codec = avcodec_find_decoder(codec_id))) {
|
||||||
Fatal(_("codec: codec ID %#06x not found\n"), codec_id);
|
Fatal(_("codec: codec ID %#06x not found\n"), codec_id);
|
||||||
// FIXME: errors aren't fatal
|
// FIXME: errors aren't fatal
|
||||||
@ -1291,7 +1398,7 @@ void CodecAudioEnqueue(AudioDecoder * audio_decoder, int16_t * data, int count)
|
|||||||
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
#ifdef USE_AUDIO_DRIFT_CORRECTION
|
||||||
if ((CodecAudioDrift & CORRECT_PCM) && audio_decoder->AvResample) {
|
if ((CodecAudioDrift & CORRECT_PCM) && audio_decoder->AvResample) {
|
||||||
int16_t buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
int16_t buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
||||||
FF_INPUT_BUFFER_PADDING_SIZE] __attribute__ ((aligned(16)));
|
AV_INPUT_BUFFER_PADDING_SIZE] __attribute__ ((aligned(16)));
|
||||||
int16_t buftmp[MAX_CHANNELS][(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4];
|
int16_t buftmp[MAX_CHANNELS][(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4];
|
||||||
int consumed;
|
int consumed;
|
||||||
int i;
|
int i;
|
||||||
@ -1383,7 +1490,7 @@ int myavcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
|
|||||||
// in the caller may be able to be optimized.
|
// in the caller may be able to be optimized.
|
||||||
ret = avcodec_receive_frame(avctx,frame);
|
ret = avcodec_receive_frame(avctx,frame);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
got_frame = true;
|
got_frame = 1;
|
||||||
if (ret == AVERROR(EAGAIN))
|
if (ret == AVERROR(EAGAIN))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
@ -1392,7 +1499,7 @@ int myavcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
else if (ret < 0)
|
else if (ret < 0)
|
||||||
{
|
{
|
||||||
Debug(3, "codec/audio: audio decode error: %1 (%2)\n",av_make_error_string(error, sizeof(error), ret),got_frame);
|
// Debug(3, "codec/audio: audio decode error: %1 (%2)\n",av_make_error_string(error, sizeof(error), ret),got_frame);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1434,7 +1541,7 @@ int myavcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
|
|||||||
void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||||
{
|
{
|
||||||
int16_t buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
int16_t buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
||||||
FF_INPUT_BUFFER_PADDING_SIZE] __attribute__ ((aligned(16)));
|
AV_INPUT_BUFFER_PADDING_SIZE] __attribute__ ((aligned(16)));
|
||||||
int buf_sz;
|
int buf_sz;
|
||||||
int l;
|
int l;
|
||||||
AVCodecContext *audio_ctx;
|
AVCodecContext *audio_ctx;
|
||||||
@ -1470,7 +1577,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
|||||||
// need to resample audio
|
// need to resample audio
|
||||||
if (audio_decoder->ReSample) {
|
if (audio_decoder->ReSample) {
|
||||||
int16_t outbuf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
int16_t outbuf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
|
||||||
FF_INPUT_BUFFER_PADDING_SIZE]
|
AV_INPUT_BUFFER_PADDING_SIZE]
|
||||||
__attribute__ ((aligned(16)));
|
__attribute__ ((aligned(16)));
|
||||||
int outlen;
|
int outlen;
|
||||||
|
|
||||||
|
8
codec.h
8
codec.h
@ -61,10 +61,10 @@ struct _video_decoder_
|
|||||||
//#ifdef FFMPEG_WORKAROUND_ARTIFACTS
|
//#ifdef FFMPEG_WORKAROUND_ARTIFACTS
|
||||||
int FirstKeyFrame; ///< flag first frame
|
int FirstKeyFrame; ///< flag first frame
|
||||||
//#endif
|
//#endif
|
||||||
AVFrame *Frame; ///< decoded video frame
|
// AVFrame *Frame; ///< decoded video frame
|
||||||
#ifdef YADIF
|
|
||||||
int filter; // flag for yadif filter
|
int filter; // flag for deint filter
|
||||||
#endif
|
|
||||||
/* hwaccel options */
|
/* hwaccel options */
|
||||||
enum HWAccelID hwaccel_id;
|
enum HWAccelID hwaccel_id;
|
||||||
char *hwaccel_device;
|
char *hwaccel_device;
|
||||||
|
28
drirc
Normal file
28
drirc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<driconf>
|
||||||
|
<device screen="0" driver="i965">
|
||||||
|
<application name="Default">
|
||||||
|
<option name="always_flush_cache" value="false" />
|
||||||
|
<option name="mesa_no_error" value="false" />
|
||||||
|
<option name="precise_trig" value="false" />
|
||||||
|
<option name="mesa_glthread" value="false" />
|
||||||
|
<option name="disable_glsl_line_continuations" value="false" />
|
||||||
|
<option name="disable_blend_func_extended" value="false" />
|
||||||
|
<option name="shader_precompile" value="true" />
|
||||||
|
<option name="clamp_max_samples" value="-1" />
|
||||||
|
<option name="allow_glsl_extension_directive_midshader" value="false" />
|
||||||
|
<option name="allow_rgb10_configs" value="true" />
|
||||||
|
<option name="allow_glsl_cross_stage_interpolation_mismatch" value="false" />
|
||||||
|
<option name="force_glsl_abs_sqrt" value="false" />
|
||||||
|
<option name="dual_color_blend_by_location" value="false" />
|
||||||
|
<option name="bo_reuse" value="1" />
|
||||||
|
<option name="always_flush_batch" value="false" />
|
||||||
|
<option name="allow_rgb565_configs" value="true" />
|
||||||
|
<option name="allow_glsl_builtin_variable_redeclaration" value="true" />
|
||||||
|
<option name="force_glsl_extensions_warn" value="false" />
|
||||||
|
<option name="disable_throttling" value="false" />
|
||||||
|
<option name="force_glsl_version" value="330" />
|
||||||
|
<option name="glsl_zero_init" value="false" />
|
||||||
|
<option name="allow_higher_compat_version" value="true" />
|
||||||
|
</application>
|
||||||
|
</device>
|
||||||
|
</driconf>
|
104
openglosd.cpp
104
openglosd.cpp
@ -18,7 +18,7 @@ void ConvertColor(const GLint &colARGB, glm::vec4 &col) {
|
|||||||
* cShader
|
* cShader
|
||||||
****************************************************************************************/
|
****************************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CUVID
|
||||||
const char *rectVertexShader =
|
const char *rectVertexShader =
|
||||||
"#version 330 core \n\
|
"#version 330 core \n\
|
||||||
\
|
\
|
||||||
@ -116,6 +116,106 @@ void main() \
|
|||||||
} \
|
} \
|
||||||
";
|
";
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
const char *rectVertexShader =
|
||||||
|
"\n\
|
||||||
|
|
||||||
|
\
|
||||||
|
layout (location = 0) in vec2 position; \
|
||||||
|
out vec4 rectCol; \
|
||||||
|
uniform vec4 inColor; \
|
||||||
|
uniform mat4 projection; \
|
||||||
|
\
|
||||||
|
void main() \
|
||||||
|
{ \
|
||||||
|
gl_Position = projection * vec4(position.x, position.y, 0.0, 1.0); \
|
||||||
|
rectCol = inColor; \
|
||||||
|
} \
|
||||||
|
";
|
||||||
|
|
||||||
|
const char *rectFragmentShader =
|
||||||
|
"#version 330 core \n\
|
||||||
|
\
|
||||||
|
in vec4 rectCol; \
|
||||||
|
out vec4 color; \
|
||||||
|
\
|
||||||
|
void main() \
|
||||||
|
{ \
|
||||||
|
color = rectCol; \
|
||||||
|
} \
|
||||||
|
";
|
||||||
|
|
||||||
|
const char *textureVertexShader =
|
||||||
|
"\n\
|
||||||
|
\
|
||||||
|
layout (location = 0) in vec2 position; \
|
||||||
|
layout (location = 1) in vec2 texCoords; \
|
||||||
|
\
|
||||||
|
out vec2 TexCoords; \
|
||||||
|
out vec4 alphaValue;\
|
||||||
|
\
|
||||||
|
uniform mat4 projection; \
|
||||||
|
uniform vec4 alpha; \
|
||||||
|
\
|
||||||
|
void main() \
|
||||||
|
{ \
|
||||||
|
gl_Position = projection * vec4(position.x, position.y, 0.0, 1.0); \
|
||||||
|
TexCoords = texCoords; \
|
||||||
|
alphaValue = alpha; \
|
||||||
|
} \
|
||||||
|
";
|
||||||
|
|
||||||
|
const char *textureFragmentShader =
|
||||||
|
"\n\
|
||||||
|
in vec2 TexCoords; \
|
||||||
|
in vec4 alphaValue; \
|
||||||
|
out vec4 color; \
|
||||||
|
\
|
||||||
|
uniform sampler2D screenTexture; \
|
||||||
|
\
|
||||||
|
void main() \
|
||||||
|
{ \
|
||||||
|
color = texture(screenTexture, TexCoords) * alphaValue; \
|
||||||
|
} \
|
||||||
|
";
|
||||||
|
|
||||||
|
const char *textVertexShader =
|
||||||
|
"\n\
|
||||||
|
\
|
||||||
|
layout (location = 0) in vec2 position; \
|
||||||
|
layout (location = 1) in vec2 texCoords; \
|
||||||
|
\
|
||||||
|
out vec2 TexCoords; \
|
||||||
|
out vec4 textColor; \
|
||||||
|
\
|
||||||
|
uniform mat4 projection; \
|
||||||
|
uniform vec4 inColor; \
|
||||||
|
\
|
||||||
|
void main() \
|
||||||
|
{ \
|
||||||
|
gl_Position = projection * vec4(position.x, position.y, 0.0, 1.0); \
|
||||||
|
TexCoords = texCoords; \
|
||||||
|
textColor = inColor; \
|
||||||
|
} \
|
||||||
|
";
|
||||||
|
|
||||||
|
const char *textFragmentShader =
|
||||||
|
"\n\
|
||||||
|
in vec2 TexCoords; \
|
||||||
|
in vec4 textColor; \
|
||||||
|
\
|
||||||
|
out vec4 color; \
|
||||||
|
\
|
||||||
|
uniform sampler2D glyphTexture; \
|
||||||
|
\
|
||||||
|
void main() \
|
||||||
|
{ \
|
||||||
|
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(glyphTexture, TexCoords).r); \
|
||||||
|
color = textColor * sampled; \
|
||||||
|
} \
|
||||||
|
";
|
||||||
|
#endif
|
||||||
static cShader *Shaders[stCount];
|
static cShader *Shaders[stCount];
|
||||||
|
|
||||||
void cShader::Use(void) {
|
void cShader::Use(void) {
|
||||||
@ -1588,7 +1688,7 @@ extern "C" int GlxInitopengl();
|
|||||||
bool cOglThread::InitOpenGL(void) {
|
bool cOglThread::InitOpenGL(void) {
|
||||||
|
|
||||||
|
|
||||||
#ifdef PLACEBO
|
#ifdef PLACEBO
|
||||||
const char *displayName = X11DisplayName;
|
const char *displayName = X11DisplayName;
|
||||||
if (!displayName) {
|
if (!displayName) {
|
||||||
displayName = getenv("DISPLAY");
|
displayName = getenv("DISPLAY");
|
||||||
|
@ -67,7 +67,7 @@ extern "C"
|
|||||||
/// vdr-plugin version number.
|
/// vdr-plugin version number.
|
||||||
/// Makefile extracts the version number for generating the file name
|
/// Makefile extracts the version number for generating the file name
|
||||||
/// for the distribution archive.
|
/// for the distribution archive.
|
||||||
static const char *const VERSION = "1.1.0"
|
static const char *const VERSION = "2.0.0"
|
||||||
#ifdef GIT_REV
|
#ifdef GIT_REV
|
||||||
"-GIT" GIT_REV
|
"-GIT" GIT_REV
|
||||||
#endif
|
#endif
|
||||||
@ -75,7 +75,7 @@ static const char *const VERSION = "1.1.0"
|
|||||||
|
|
||||||
/// vdr-plugin description.
|
/// vdr-plugin description.
|
||||||
static const char *const DESCRIPTION =
|
static const char *const DESCRIPTION =
|
||||||
trNOOP("A software and GPU emulated HD device");
|
trNOOP("A software and GPU emulated UHD device");
|
||||||
|
|
||||||
/// vdr-plugin text of main menu entry
|
/// vdr-plugin text of main menu entry
|
||||||
static const char *MAINMENUENTRY = trNOOP("SoftUHD");
|
static const char *MAINMENUENTRY = trNOOP("SoftUHD");
|
||||||
@ -232,7 +232,7 @@ class cSoftRemote:public cRemote
|
|||||||
** @param release flag key released
|
** @param release flag key released
|
||||||
*/
|
*/
|
||||||
bool Put(const char *code, bool repeat = false, bool release = false) {
|
bool Put(const char *code, bool repeat = false, bool release = false) {
|
||||||
return cRemote::Put(code, repeat, release);
|
return cRemote::Put(code, repeat, release);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -249,40 +249,38 @@ extern "C" void FeedKeyPress(const char *keymap, const char *key, int repeat,
|
|||||||
int release, const char *letter)
|
int release, const char *letter)
|
||||||
{
|
{
|
||||||
cRemote *remote;
|
cRemote *remote;
|
||||||
cSoftRemote *csoft;
|
cSoftRemote *csoft;
|
||||||
|
|
||||||
if (!keymap || !key) {
|
if (!keymap || !key) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// find remote
|
// find remote
|
||||||
for (remote = Remotes.First(); remote; remote = Remotes.Next(remote)) {
|
for (remote = Remotes.First(); remote; remote = Remotes.Next(remote)) {
|
||||||
if (!strcmp(remote->Name(), keymap)) {
|
if (!strcmp(remote->Name(), keymap)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if remote not already exists, create it
|
// if remote not already exists, create it
|
||||||
if (remote) {
|
if (remote) {
|
||||||
csoft = (cSoftRemote *) remote;
|
csoft = (cSoftRemote *) remote;
|
||||||
} else {
|
} else {
|
||||||
dsyslog("[softhddev]%s: remote '%s' not found\n", __FUNCTION__,
|
dsyslog("[softhddev]%s: remote '%s' not found\n", __FUNCTION__, keymap);
|
||||||
keymap);
|
csoft = new cSoftRemote(keymap);
|
||||||
csoft = new cSoftRemote(keymap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//dsyslog("[softhddev]%s %s, %s, %s\n", __FUNCTION__, keymap, key, letter);
|
//dsyslog("[softhddev]%s %s, %s, %s\n", __FUNCTION__, keymap, key, letter);
|
||||||
if (key[1]) { // no single character
|
if (key[1]) { // no single character
|
||||||
if (!csoft->Put(key, repeat, release) && letter
|
if (!csoft->Put(key, repeat, release) && letter && !cRemote::IsLearning()) {
|
||||||
&& !cRemote::IsLearning()) {
|
cCharSetConv conv;
|
||||||
cCharSetConv conv;
|
unsigned code;
|
||||||
unsigned code;
|
|
||||||
|
|
||||||
code = Utf8CharGet(conv.Convert(letter));
|
code = Utf8CharGet(conv.Convert(letter));
|
||||||
if (code <= 0xFF) {
|
if (code <= 0xFF) {
|
||||||
cRemote::Put(KBDKEY(code)); // feed it for edit mode
|
cRemote::Put(KBDKEY(code)); // feed it for edit mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!csoft->Put(key, repeat, release)) {
|
} else if (!csoft->Put(key, repeat, release)) {
|
||||||
cRemote::Put(KBDKEY(key[0])); // feed it for edit mode
|
cRemote::Put(KBDKEY(key[0])); // feed it for edit mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user