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
|
||||
#
|
||||
#
|
||||
# $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:
|
||||
|
||||
|
@ -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
179
codec.c
@ -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;
|
||||
|
||||
|
8
codec.h
8
codec.h
@ -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
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
|
||||
****************************************************************************************/
|
||||
|
||||
|
||||
#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");
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user