First support for VAAPI

This commit is contained in:
jojo61 2019-08-22 12:34:29 +02:00
parent fae0d3a9bd
commit 5c2b801a45
8 changed files with 1058 additions and 290 deletions

118
Makefile
View File

@ -1,6 +1,6 @@
#
# Makefile for a Video Disk Recorder plugin
#
#
# $Id: 2a41981a57e5e83036463c6a08c84b86ed9d2be3 $
# The official name of this plugin.
@ -11,35 +11,46 @@ PLUGIN = softhdcuvid
### 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
ALSA ?= $(shell pkg-config --exists alsa && echo 1)
# support OSS audio output module
OSS ?= 1
# support OPENGLOSD
OPENGLOSD=1
# use Libplacebo
LIBPLACEBO=0
# use DMPS
# use DMPS
SCREENSAVER=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
CONFIG += -DCUVID # enable CUVID decoder
#CONFIG += -DYADIF # enable yadif_cuda deinterlacer
# 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 = 1
#endif
CONFIG := -DDEBUG #-DOSD_DEBUG # enable debug output+functions
CONFIG += -DHAVE_GL # needed for mpv libs
#CONFIG += -DSTILL_DEBUG=2 # still picture debug verbose level
CONFIG += -DAV_INFO -DAV_INFO_TIME=3000 # info/debug a/v sync
CONFIG += -DUSE_PIP # PIP support
#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):
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)
### The name of the distribution archive:
### The directory environment:
@ -87,14 +99,7 @@ APIVERSION = $(call PKGCFG,apiversion)
-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
@ -103,16 +108,20 @@ CONFIG += -DUSE_ALSA
_CFLAGS += $(shell pkg-config --cflags alsa)
LIBS += $(shell pkg-config --libs alsa)
endif
ifeq ($(OSS),1)
CONFIG += -DUSE_OSS
endif
ifeq ($(OPENGL),1)
_CFLAGS += $(shell pkg-config --cflags libva-glx)
LIBS += $(shell pkg-config --libs libva-glx)
endif
ifeq ($(OPENGLOSD),1)
CONFIG += -DUSE_OPENGLOSD
endif
ifeq ($(OPENGL),1)
CONFIG += -DUSE_GLX
_CFLAGS += $(shell pkg-config --cflags gl glu glew)
@ -122,18 +131,43 @@ LIBS += $(shell pkg-config --libs glew)
_CFLAGS += $(shell pkg-config --cflags freetype2)
LIBS += $(shell pkg-config --libs freetype2)
endif
ifeq ($(VAAPI),1)
CONFIG += -DVAAPI
LIBPLACEBO=1
PLUGIN = softhdvaapi
endif
ifeq ($(LIBPLACEBO),1)
CONFIG += -DPLACEBO
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
#
ifneq (exists, $(shell pkg-config libswresample && echo exists))
$(warning ******************************************************************)
$(warning 'libswresample' not found!)
$(error ******************************************************************)
endif
#ifneq (exists, $(shell pkg-config libswresample && echo exists))
# $(warning ******************************************************************)
# $(warning 'libswresample' not found!)
# $(error ******************************************************************)
#endif
#
# Test and set config for libavutil
@ -179,11 +213,11 @@ CONFIG += -DUSE_SWRESAMPLE
_CFLAGS += $(shell pkg-config --cflags libswresample)
LIBS += $(shell pkg-config --libs libswresample)
endif
#ifeq ($(AVRESAMPLE),1)
#CONFIG += -DUSE_AVRESAMPLE
#_CFLAGS += $(shell pkg-config --cflags libavresample)
#LIBS += $(shell pkg-config --libs libavresample)
#endif
ifeq ($(AVRESAMPLE),1)
CONFIG += -DUSE_AVRESAMPLE
_CFLAGS += $(shell pkg-config --cflags libavresample)
LIBS += $(shell pkg-config --libs libavresample)
endif
#_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)
@ -200,7 +234,11 @@ ifeq ($(LIBPLACEBO),1)
LIBS += -lplacebo -lglut
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 +=
@ -218,12 +256,12 @@ override CFLAGS += $(_CFLAGS) $(DEFINES) $(INCLUDES) \
### 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)
OBJS += openglosd.o
endif
SRCS = $(wildcard $(OBJS:.o=.c)) $(PLUGIN).cpp
SRCS = $(wildcard $(OBJS:.o=.c)) softhdcuvid.cpp
### The main target:

View File

@ -40,13 +40,17 @@ A software and GPU emulated UHD output device plugin for VDR.
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.
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.
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
The Makefile expects the CUDA SDK in /usr/local/cuda. Currently it is tested with CUDA 10

179
codec.c
View File

@ -1,3 +1,4 @@
///
/// @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
enum AVPixelFormat fmts[2];
fprintf(stderr, "codec: buggy libav, use ffmpeg\n");
Warning(_("codec: buggy libav, use ffmpeg\n"));
// fprintf(stderr, "codec: buggy libav, use ffmpeg\n");
// Warning(_("codec: buggy libav, use ffmpeg\n"));
fmts[0] = video_ctx->pix_fmt;
fmts[1] = AV_PIX_FMT_NONE;
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");
return decoder->hwaccel_get_buffer(video_ctx, frame, flags);
}
#endif
//Debug(3, "codec: fallback to default get_buffer\n");
return avcodec_default_get_buffer2(video_ctx, frame, flags);
}
@ -268,6 +273,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
}
name = "NULL";
#ifdef CUVID
if (!strcasecmp(VideoGetDriverName(), "cuvid")) {
switch (codec_id) {
case AV_CODEC_ID_MPEG2VIDEO:
@ -281,11 +287,11 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
break;
}
}
#endif
if (name && (video_codec = avcodec_find_decoder_by_name(name))) {
Debug(3, "codec: decoder found\n");
} else {
Debug(3,"Decoder %s not supported\n",name);
} else if ((video_codec = avcodec_find_decoder(codec_id))==NULL) {
Debug(3,"Decoder %s not supported %p\n",name,video_codec);
Fatal(_(" No decoder found"));
}
@ -309,13 +315,45 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
decoder->VideoCtx->pkt_timebase.den = 90000;
decoder->VideoCtx->framerate.num = 50;
decoder->VideoCtx->framerate.den = 1;
decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1
pthread_mutex_lock(&CodecLockMutex);
// open codec
#ifdef YADIF
deint = 0;
deint = 2;
#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 (av_opt_set_int(decoder->VideoCtx->priv_data, "deint", deint ,0) < 0) { // adaptive
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"));
}
}
#endif
if ((ret = avcodec_open2(decoder->VideoCtx, video_codec, NULL)) < 0) {
pthread_mutex_unlock(&CodecLockMutex);
@ -363,24 +401,25 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
//decoder->VideoCtx->debug = FF_DEBUG_STARTCODE;
//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_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;
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
//
#if 0
if (!(decoder->Frame = av_frame_alloc())) {
Fatal(_("codec: can't allocate video decoder frame buffer\n"));
}
#endif
// reset buggy ffmpeg/libav flag
decoder->GetFormatDone = 0;
#ifdef YADIF
@ -401,7 +440,7 @@ void CodecVideoClose(VideoDecoder *video_decoder)
{
// 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");
if (video_decoder->VideoCtx) {
@ -465,37 +504,100 @@ extern int CuvidTestSurfaces();
extern int init_filters(AVCodecContext * dec_ctx,void * decoder,AVFrame *frame);
extern int push_filters(AVCodecContext * dec_ctx,void * decoder,AVFrame *frame);
#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)
{
AVCodecContext *video_ctx;
AVFrame *frame;
AVFrame *frame
;
int ret,ret1;
int got_frame;
int consumed = 0;
static uint64_t first_time = 0;
const AVPacket *pkt;
next_part:
video_ctx = decoder->VideoCtx;
frame = decoder->Frame;
pkt = avpkt; // use copy
got_frame = 0;
// printf("decode packet %d\n",(GetusTicks()-first_time)/1000000);
ret1 = avcodec_send_packet(video_ctx, pkt);
// first_time = GetusTicks();
if (ret1 >= 0) {
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()) {
ret = 0;
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
if (ret >= 0) { // one is avail.
got_frame = 1;
got_frame = 1;
}
else {
got_frame = 0;
}
// printf("got %s packet from decoder\n",got_frame?"1":"no");
if (got_frame) { // frame completed
#ifdef YADIF
if (decoder->filter ) {
@ -511,12 +613,13 @@ next_part:
}
if (frame->interlaced_frame && decoder->filter == 2 && (frame->height != 720)) { // broken ZDF sends Interlaced flag
ret = push_filters(video_ctx,decoder->HwDecoder,frame);
av_frame_unref(frame);
// av_frame_unref(frame);
continue;
}
}
#endif
#ifdef FFMPEG_WORKAROUND_ARTIFACTS
if (!CodecUsePossibleDefectFrames && decoder->FirstKeyFrame) {
decoder->FirstKeyFrame++;
if (frame->key_frame || (decoder->FirstKeyFrame > 3)) { // key frame is not reliable
@ -524,31 +627,35 @@ next_part:
decoder->FirstKeyFrame = 0;
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
}
av_frame_unref(frame);
// av_frame_unref(frame);
} else {
//DisplayPts(video_ctx, frame);
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
av_frame_unref(frame);
// av_frame_unref(frame);
}
#else
//DisplayPts(video_ctx, frame);
VideoRenderFrame(decoder->HwDecoder, video_ctx, frame);
av_frame_unref(frame);
// av_frame_unref(frame);
#endif
// printf("got frame\n");
} else {
} else {
av_frame_free(&frame);
// printf("codec: got no frame %d send %d\n",ret,ret1);
}
}
if (!CuvidTestSurfaces()) {
usleep(1000);
}
} else {
// consumed = 1;
}
if (!consumed) {
goto next_part; // try again to stuff decoder
}
}
}
}
#endif
/**
** 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,
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))) {
Fatal(_("codec: codec ID %#06x not found\n"), codec_id);
// FIXME: errors aren't fatal
@ -1291,7 +1398,7 @@ void CodecAudioEnqueue(AudioDecoder * audio_decoder, int16_t * data, int count)
#ifdef USE_AUDIO_DRIFT_CORRECTION
if ((CodecAudioDrift & CORRECT_PCM) && audio_decoder->AvResample) {
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];
int consumed;
int i;
@ -1383,7 +1490,7 @@ int myavcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
// in the caller may be able to be optimized.
ret = avcodec_receive_frame(avctx,frame);
if (ret == 0)
got_frame = true;
got_frame = 1;
if (ret == AVERROR(EAGAIN))
ret = 0;
if (ret == 0)
@ -1392,7 +1499,7 @@ int myavcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
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;
}
else
@ -1434,7 +1541,7 @@ int myavcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
{
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 l;
AVCodecContext *audio_ctx;
@ -1470,7 +1577,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
// need to resample audio
if (audio_decoder->ReSample) {
int16_t outbuf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 4 +
FF_INPUT_BUFFER_PADDING_SIZE]
AV_INPUT_BUFFER_PADDING_SIZE]
__attribute__ ((aligned(16)));
int outlen;

View File

@ -61,10 +61,10 @@ struct _video_decoder_
//#ifdef FFMPEG_WORKAROUND_ARTIFACTS
int FirstKeyFrame; ///< flag first frame
//#endif
AVFrame *Frame; ///< decoded video frame
#ifdef YADIF
int filter; // flag for yadif filter
#endif
// AVFrame *Frame; ///< decoded video frame
int filter; // flag for deint filter
/* hwaccel options */
enum HWAccelID hwaccel_id;
char *hwaccel_device;

28
drirc Normal file
View 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>

View File

@ -18,7 +18,7 @@ void ConvertColor(const GLint &colARGB, glm::vec4 &col) {
* cShader
****************************************************************************************/
#ifdef CUVID
const char *rectVertexShader =
"#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];
void cShader::Use(void) {
@ -1588,7 +1688,7 @@ extern "C" int GlxInitopengl();
bool cOglThread::InitOpenGL(void) {
#ifdef PLACEBO
#ifdef PLACEBO
const char *displayName = X11DisplayName;
if (!displayName) {
displayName = getenv("DISPLAY");

View File

@ -67,7 +67,7 @@ extern "C"
/// vdr-plugin version number.
/// Makefile extracts the version number for generating the file name
/// for the distribution archive.
static const char *const VERSION = "1.1.0"
static const char *const VERSION = "2.0.0"
#ifdef GIT_REV
"-GIT" GIT_REV
#endif
@ -75,7 +75,7 @@ static const char *const VERSION = "1.1.0"
/// vdr-plugin 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
static const char *MAINMENUENTRY = trNOOP("SoftUHD");
@ -232,7 +232,7 @@ class cSoftRemote:public cRemote
** @param release flag key released
*/
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)
{
cRemote *remote;
cSoftRemote *csoft;
cSoftRemote *csoft;
if (!keymap || !key) {
return;
return;
}
// find remote
for (remote = Remotes.First(); remote; remote = Remotes.Next(remote)) {
if (!strcmp(remote->Name(), keymap)) {
break;
}
if (!strcmp(remote->Name(), keymap)) {
break;
}
}
// if remote not already exists, create it
if (remote) {
csoft = (cSoftRemote *) remote;
csoft = (cSoftRemote *) remote;
} else {
dsyslog("[softhddev]%s: remote '%s' not found\n", __FUNCTION__,
keymap);
csoft = new cSoftRemote(keymap);
dsyslog("[softhddev]%s: remote '%s' not found\n", __FUNCTION__, keymap);
csoft = new cSoftRemote(keymap);
}
//dsyslog("[softhddev]%s %s, %s, %s\n", __FUNCTION__, keymap, key, letter);
if (key[1]) { // no single character
if (!csoft->Put(key, repeat, release) && letter
&& !cRemote::IsLearning()) {
cCharSetConv conv;
unsigned code;
if (!csoft->Put(key, repeat, release) && letter && !cRemote::IsLearning()) {
cCharSetConv conv;
unsigned code;
code = Utf8CharGet(conv.Convert(letter));
if (code <= 0xFF) {
cRemote::Put(KBDKEY(code)); // feed it for edit mode
}
}
code = Utf8CharGet(conv.Convert(letter));
if (code <= 0xFF) {
cRemote::Put(KBDKEY(code)); // feed it for edit mode
}
}
} 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
}
}

861
video.c

File diff suppressed because it is too large Load Diff