mirror of
https://github.com/jojo61/vdr-plugin-softhdcuvid.git
synced 2023-10-10 13:37:41 +02:00
Vaapi changed to egl
This commit is contained in:
parent
cdac2bcc3d
commit
4d2735a971
46
Makefile
46
Makefile
@ -7,9 +7,9 @@
|
||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||
# By default the main source file also carries this name.
|
||||
|
||||
PLUGIN = softhdcuvid
|
||||
|
||||
### Configuration (edit this for your needs)
|
||||
# comment out if not needed
|
||||
|
||||
# what kind of driver do we make -
|
||||
# if VAAPI is enabled the drivername is softhdvaapi
|
||||
@ -17,18 +17,30 @@ PLUGIN = softhdcuvid
|
||||
#VAAPI=1
|
||||
CUVID=1
|
||||
|
||||
# use libplacebo - available for both drivers
|
||||
#LIBPLACEBO=1
|
||||
|
||||
# use YADIF deint - only available with cuvid
|
||||
#YADIF=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
|
||||
PLUGIN = softhdcuvid
|
||||
|
||||
# support OPENGLOSD always needed
|
||||
OPENGLOSD=1
|
||||
|
||||
# support alsa audio output module
|
||||
ALSA ?= $(shell pkg-config --exists alsa && echo 1)
|
||||
# support OSS audio output module
|
||||
OSS ?= 1
|
||||
@ -48,7 +60,7 @@ SWRESAMPLE = 1
|
||||
#AVRESAMPLE = 1
|
||||
#endif
|
||||
|
||||
CONFIG := -DDEBUG #-DOSD_DEBUG # enable debug output+functions
|
||||
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
|
||||
@ -114,8 +126,8 @@ CONFIG += -DUSE_OSS
|
||||
endif
|
||||
|
||||
ifeq ($(OPENGL),1)
|
||||
_CFLAGS += $(shell pkg-config --cflags libva-glx)
|
||||
LIBS += $(shell pkg-config --libs libva-glx)
|
||||
#_CFLAGS += $(shell pkg-config --cflags libva-glx)
|
||||
#LIBS += $(shell pkg-config --libs libva-glx)
|
||||
endif
|
||||
|
||||
ifeq ($(OPENGLOSD),1)
|
||||
@ -125,17 +137,16 @@ endif
|
||||
ifeq ($(OPENGL),1)
|
||||
CONFIG += -DUSE_GLX
|
||||
_CFLAGS += $(shell pkg-config --cflags gl glu glew)
|
||||
LIBS += $(shell pkg-config --libs gl glu glew)
|
||||
_CFLAGS += $(shell pkg-config --cflags glew)
|
||||
LIBS += $(shell pkg-config --libs glew)
|
||||
#LIBS += $(shell pkg-config --libs glu glew)
|
||||
_CFLAGS += $(shell pkg-config --cflags freetype2)
|
||||
LIBS += $(shell pkg-config --libs freetype2)
|
||||
endif
|
||||
|
||||
ifeq ($(VAAPI),1)
|
||||
CONFIG += -DVAAPI -DUSE_OPENGLOSD
|
||||
LIBPLACEBO=1
|
||||
CONFIG += -DVAAPI
|
||||
#LIBPLACEBO=1
|
||||
PLUGIN = softhdvaapi
|
||||
LIBS += -lEGL -lEGL_mesa
|
||||
endif
|
||||
|
||||
ifeq ($(LIBPLACEBO),1)
|
||||
@ -144,6 +155,7 @@ endif
|
||||
|
||||
ifeq ($(CUVID),1)
|
||||
CONFIG += -DCUVID # enable CUVID decoder
|
||||
LIBS += -lEGL -lGL
|
||||
ifeq ($(YADIF),1)
|
||||
CONFIG += -DYADIF # Yadif only with CUVID
|
||||
endif
|
||||
@ -238,7 +250,7 @@ ifeq ($(CUVID),1)
|
||||
LIBS += -lcuda -L/usr/local/cuda/targets/x86_64-linux/lib -lcudart -lnvcuvid
|
||||
endif
|
||||
|
||||
LIBS += -lGLEW -lGLX -ldl
|
||||
LIBS += -lGLEW -lGLU -ldl
|
||||
### Includes and Defines (add further entries here):
|
||||
|
||||
INCLUDES +=
|
||||
|
48
audio.c
48
audio.c
@ -143,6 +143,7 @@ static volatile char AudioRunning; ///< thread running / stopped
|
||||
static volatile char AudioPaused; ///< audio paused
|
||||
static volatile char AudioVideoIsReady; ///< video ready start early
|
||||
static int AudioSkip; ///< skip audio to sync to video
|
||||
int AudioDelay; /// delay audio to sync to video
|
||||
|
||||
static const int AudioBytesProSample = 2; ///< number of bytes per sample
|
||||
|
||||
@ -705,6 +706,7 @@ static int AudioRingAdd(unsigned sample_rate, int channels, int passthrough)
|
||||
// tell thread, that there is something todo
|
||||
AudioRunning = 1;
|
||||
pthread_cond_signal(&AudioStartCond);
|
||||
Debug(3,"Start on AudioRingAdd\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -894,8 +896,9 @@ static int AlsaPlayRingbuffer(void)
|
||||
}
|
||||
RingBufferReadAdvance(AudioRing[AudioRingRead].RingBuffer, avail);
|
||||
first = 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1008,8 +1011,7 @@ static snd_pcm_t *AlsaOpenPCM(int passthrough)
|
||||
device = "default";
|
||||
}
|
||||
if (!AudioDoingInit) { // reduce blabla during init
|
||||
Info(_("audio/alsa: using %sdevice '%s'\n"),
|
||||
passthrough ? "pass-through " : "", device);
|
||||
Info(_("audio/alsa: using %sdevice '%s'\n"), passthrough ? "pass-through " : "", device);
|
||||
}
|
||||
//
|
||||
// for AC3 pass-through try to set the non-audio bit, use AES0=6
|
||||
@ -1035,8 +1037,7 @@ static snd_pcm_t *AlsaOpenPCM(int passthrough)
|
||||
if ((err =
|
||||
snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK,
|
||||
SND_PCM_NONBLOCK)) < 0) {
|
||||
Error(_("audio/alsa: playback open '%s' error: %s\n"), device,
|
||||
snd_strerror(err));
|
||||
Error(_("audio/alsa: playback open '%s' error: %s\n"), device, snd_strerror(err));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1064,8 +1065,7 @@ static void AlsaInitPCM(void)
|
||||
snd_pcm_hw_params_alloca(&hw_params);
|
||||
// choose all parameters
|
||||
if ((err = snd_pcm_hw_params_any(handle, hw_params)) < 0) {
|
||||
Error(_
|
||||
("audio: snd_pcm_hw_params_any: no configurations available: %s\n"),
|
||||
Error(_("audio: snd_pcm_hw_params_any: no configurations available: %s\n"),
|
||||
snd_strerror(err));
|
||||
}
|
||||
AlsaCanPause = snd_pcm_hw_params_can_pause(hw_params);
|
||||
@ -1185,8 +1185,7 @@ static int64_t AlsaGetDelay(void)
|
||||
delay = 0L;
|
||||
}
|
||||
|
||||
pts =
|
||||
((int64_t) delay * 90 * 1000) / AudioRing[AudioRingRead].HwSampleRate;
|
||||
pts = ((int64_t) delay * 90 * 1000) / AudioRing[AudioRingRead].HwSampleRate;
|
||||
|
||||
return pts;
|
||||
}
|
||||
@ -1319,8 +1318,7 @@ static int AlsaSetup(int *freq, int *channels, int passthrough)
|
||||
}
|
||||
if (AudioStartThreshold <
|
||||
(*freq * *channels * AudioBytesProSample * delay) / 1000U) {
|
||||
AudioStartThreshold =
|
||||
(*freq * *channels * AudioBytesProSample * delay) / 1000U;
|
||||
AudioStartThreshold = (*freq * *channels * AudioBytesProSample * delay) / 1000U;
|
||||
}
|
||||
// no bigger, than 1/3 the buffer
|
||||
if (AudioStartThreshold > AudioRingBufferSize / 3) {
|
||||
@ -2116,7 +2114,7 @@ static void *AudioPlayHandlerThread(void *dummy)
|
||||
AudioUsedModule->FlushBuffers();
|
||||
atomic_sub(flush, &AudioRingFilled);
|
||||
if (AudioNextRing()) {
|
||||
Debug(3, "audio: break after flush\n");
|
||||
Debug(3, "audio: HandlerThread break after flush\n");
|
||||
break;
|
||||
}
|
||||
Debug(3, "audio: continue after flush\n");
|
||||
@ -2137,6 +2135,7 @@ static void *AudioPlayHandlerThread(void *dummy)
|
||||
|
||||
// underrun, and no new ring buffer, goto sleep.
|
||||
if (!atomic_read(&AudioRingFilled)) {
|
||||
Debug(3,"audio: HandlerThread Underrun with no new data\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2159,6 +2158,7 @@ static void *AudioPlayHandlerThread(void *dummy)
|
||||
|| old_channels != channels) {
|
||||
// FIXME: wait for buffer drain
|
||||
if (AudioNextRing()) {
|
||||
Debug(3,"audio: HandlerThread break on nextring");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -2168,6 +2168,7 @@ static void *AudioPlayHandlerThread(void *dummy)
|
||||
}
|
||||
// FIXME: check AudioPaused ...Thread()
|
||||
if (AudioPaused) {
|
||||
Debug(3,"audio: HandlerThread break on paused");
|
||||
break;
|
||||
}
|
||||
} while (AudioRing[AudioRingRead].HwSampleRate);
|
||||
@ -2333,12 +2334,14 @@ void AudioEnqueue(const void *samples, int count)
|
||||
}
|
||||
// forced start or enough video + audio buffered
|
||||
// for some exotic channels * 4 too small
|
||||
if (AudioStartThreshold * 4 < n || (AudioVideoIsReady
|
||||
// if (AudioStartThreshold * 4 < n || (AudioVideoIsReady
|
||||
if ((AudioVideoIsReady
|
||||
&& AudioStartThreshold < n)) {
|
||||
// restart play-back
|
||||
// no lock needed, can wakeup next time
|
||||
AudioRunning = 1;
|
||||
pthread_cond_signal(&AudioStartCond);
|
||||
Debug(3,"Start on AudioEnque\n");
|
||||
}
|
||||
}
|
||||
// Update audio clock (stupid gcc developers thinks INT64_C is unsigned)
|
||||
@ -2380,29 +2383,27 @@ void AudioVideoReady(int64_t pts)
|
||||
(used * 90 * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
|
||||
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample);
|
||||
|
||||
Debug(3, "audio: a/v sync buf(%d,%4zdms) %s|%s = %dms %s\n",
|
||||
Debug(3, "audio: a/v sync buf(%d,%4zdms) %s | %s = %dms %s\n",
|
||||
atomic_read(&AudioRingFilled),
|
||||
(used * 1000) / (AudioRing[AudioRingWrite].HwSampleRate *
|
||||
AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample),
|
||||
Timestamp2String(pts), Timestamp2String(audio_pts),
|
||||
(int)(pts - audio_pts) / 90, AudioRunning ? "running" : "ready");
|
||||
|
||||
if (!AudioRunning) {
|
||||
if (!AudioRunning || 1) {
|
||||
int skip;
|
||||
|
||||
// buffer ~15 video frames
|
||||
// FIXME: HDTV can use smaller video buffer
|
||||
skip =
|
||||
pts - 15 * 20 * 90 - AudioBufferTime * 90 - audio_pts +
|
||||
VideoAudioDelay;
|
||||
pts - 15 * 20 * 90 - AudioBufferTime * 90 - audio_pts + VideoAudioDelay;
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "%dms %dms %dms\n", (int)(pts - audio_pts) / 90,
|
||||
VideoAudioDelay / 90, skip / 90);
|
||||
#endif
|
||||
// guard against old PTS
|
||||
if (skip > 0 && skip < 2000 * 90) {
|
||||
skip = (((int64_t) skip * AudioRing[AudioRingWrite].HwSampleRate)
|
||||
/ (1000 * 90))
|
||||
if (skip > 0 && skip < 4000 * 90) {
|
||||
skip = (((int64_t) skip * AudioRing[AudioRingWrite].HwSampleRate) / (1000 * 90))
|
||||
* AudioRing[AudioRingWrite].HwChannels * AudioBytesProSample;
|
||||
// FIXME: round to packet size
|
||||
if ((unsigned)skip > used) {
|
||||
@ -2417,12 +2418,18 @@ void AudioVideoReady(int64_t pts)
|
||||
|
||||
used = RingBufferUsedBytes(AudioRing[AudioRingWrite].RingBuffer);
|
||||
}
|
||||
else {
|
||||
Debug(3,"No audio skip -> should skip %d\n",skip/90);
|
||||
AudioRunning = 0;
|
||||
usleep(abs(skip/90)*1000);
|
||||
}
|
||||
// FIXME: skip<0 we need bigger audio buffer
|
||||
|
||||
// enough video + audio buffered
|
||||
if (AudioStartThreshold < used) {
|
||||
AudioRunning = 1;
|
||||
pthread_cond_signal(&AudioStartCond);
|
||||
Debug(3,"Start on AudioVideoReady\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2515,6 +2522,7 @@ void AudioFlushBuffers(void)
|
||||
if (!AudioRunning) { // wakeup thread to flush buffers
|
||||
AudioRunning = 1;
|
||||
pthread_cond_signal(&AudioStartCond);
|
||||
Debug(3,"Start on Flush\n");
|
||||
}
|
||||
// FIXME: waiting on zero isn't correct, but currently works
|
||||
if (!atomic_read(&AudioRingFilled)) {
|
||||
|
4
codec.c
4
codec.c
@ -315,7 +315,7 @@ 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
|
||||
@ -323,6 +323,7 @@ void CodecVideoOpen(VideoDecoder * decoder, int codec_id)
|
||||
deint = 2;
|
||||
#endif
|
||||
#ifdef VAAPI
|
||||
decoder->VideoCtx->extra_hw_frames = 8; // VIDEO_SURFACES_MAX +1
|
||||
if (video_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS)) {
|
||||
Debug(3,"codec: auto threads enabled");
|
||||
decoder->VideoCtx->thread_count = 0;
|
||||
@ -1841,6 +1842,7 @@ void CodecAudioDecode(AudioDecoder * audio_decoder, const AVPacket * avpkt)
|
||||
Debug(3, "codec: receiving audio frame failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
// update audio clock
|
||||
if (avpkt->pts != (int64_t) AV_NOPTS_VALUE) {
|
||||
|
@ -14,6 +14,10 @@ void ConvertColor(const GLint &colARGB, glm::vec4 &col) {
|
||||
col.b = ((colARGB & 0x000000FF) ) / 255.0;
|
||||
}
|
||||
|
||||
extern "C" void OSD_get_context();
|
||||
extern "C" void OSD_get_shared_context();
|
||||
extern "C" void OSD_release_context();
|
||||
|
||||
/****************************************************************************************
|
||||
* cShader
|
||||
****************************************************************************************/
|
||||
@ -119,7 +123,7 @@ void main() \
|
||||
#else
|
||||
|
||||
const char *rectVertexShader =
|
||||
"\n\
|
||||
"\n \
|
||||
\
|
||||
layout (location = 0) in vec2 position; \
|
||||
out vec4 rectCol; \
|
||||
@ -134,8 +138,9 @@ void main() \
|
||||
";
|
||||
|
||||
const char *rectFragmentShader =
|
||||
"\n\
|
||||
"\n \
|
||||
\
|
||||
precision mediump float; \
|
||||
in vec4 rectCol; \
|
||||
out vec4 color; \
|
||||
\
|
||||
@ -146,7 +151,7 @@ void main() \
|
||||
";
|
||||
|
||||
const char *textureVertexShader =
|
||||
"\n\
|
||||
"\n \
|
||||
\
|
||||
layout (location = 0) in vec2 position; \
|
||||
layout (location = 1) in vec2 texCoords; \
|
||||
@ -166,7 +171,8 @@ void main() \
|
||||
";
|
||||
|
||||
const char *textureFragmentShader =
|
||||
"\n\
|
||||
"\n \
|
||||
precision mediump float; \
|
||||
in vec2 TexCoords; \
|
||||
in vec4 alphaValue; \
|
||||
out vec4 color; \
|
||||
@ -180,7 +186,7 @@ void main() \
|
||||
";
|
||||
|
||||
const char *textVertexShader =
|
||||
"\n\
|
||||
"\n \
|
||||
\
|
||||
layout (location = 0) in vec2 position; \
|
||||
layout (location = 1) in vec2 texCoords; \
|
||||
@ -200,7 +206,8 @@ void main() \
|
||||
";
|
||||
|
||||
const char *textFragmentShader =
|
||||
"\n\
|
||||
"\n \
|
||||
precision mediump float; \
|
||||
in vec2 TexCoords; \
|
||||
in vec4 textColor; \
|
||||
\
|
||||
@ -287,12 +294,14 @@ bool cShader::Compile(const char *vertexCode, const char *fragmentCode) {
|
||||
sVertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(sVertex, 1, &vertexCode, NULL);
|
||||
glCompileShader(sVertex);
|
||||
// esyslog("[softhddev]:SHADER:VERTEX %s\n",vertexCode);
|
||||
if (!CheckCompileErrors(sVertex))
|
||||
return false;
|
||||
// Fragment Shader
|
||||
sFragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(sFragment, 1, &fragmentCode, NULL);
|
||||
glCompileShader(sFragment);
|
||||
// esyslog("[softhddev]:SHADER:FRAGMENT %s\n",fragmentCode);
|
||||
if (!CheckCompileErrors(sFragment))
|
||||
return false;
|
||||
// link Program
|
||||
@ -315,14 +324,14 @@ bool cShader::CheckCompileErrors(GLuint object, bool program) {
|
||||
glGetShaderiv(object, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(object, 1024, NULL, infoLog);
|
||||
esyslog("[softhddev]:SHADER: Compile-time error: Type: %d - %s", type, infoLog);
|
||||
esyslog("[softhddev]:SHADER: Compile-time error: Type: %d - \n%s\n", type, infoLog);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
glGetProgramiv(object, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetProgramInfoLog(object, 1024, NULL, infoLog);
|
||||
esyslog("[softhddev]:SHADER: Link-time error: Type: %d", type);
|
||||
esyslog("[softhddev]:SHADER: Link-time error: Type: %d - \n%s\n", type, infoLog);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -365,6 +374,10 @@ void cOglGlyph::BindTexture(void) {
|
||||
|
||||
void cOglGlyph::LoadTexture(FT_BitmapGlyph ftGlyph) {
|
||||
// Disable byte-alignment restriction
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
OSD_get_shared_context();
|
||||
#endif
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
@ -386,6 +399,11 @@ void cOglGlyph::LoadTexture(FT_BitmapGlyph ftGlyph) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
OSD_get_context();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -550,6 +568,10 @@ cOglFb::~cOglFb(void) {
|
||||
|
||||
bool cOglFb::Init(void) {
|
||||
initiated = true;
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
OSD_get_shared_context();
|
||||
#endif
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
@ -562,10 +584,19 @@ bool cOglFb::Init(void) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
||||
|
||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
esyslog("[softhddev]ERROR: Framebuffer is not complete!\n");
|
||||
esyslog("[softhddev]ERROR: %d Framebuffer is not complete!\n",__LINE__);
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
OSD_get_context();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
OSD_get_context();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -619,6 +650,7 @@ cOglOutputFb::~cOglOutputFb(void) {
|
||||
|
||||
bool cOglOutputFb::Init(void) {
|
||||
initiated = true;
|
||||
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
@ -634,19 +666,16 @@ bool cOglOutputFb::Init(void) {
|
||||
esyslog("[softhddev]ERROR::cOglOutputFb: Framebuffer is not complete!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cOglOutputFb::BindWrite(void) {
|
||||
// glVDPAUMapSurfacesNV(1, &surface);
|
||||
if (!initiated)
|
||||
Init();
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
|
||||
}
|
||||
|
||||
void cOglOutputFb::Unbind(void) {
|
||||
// glVDPAUUnmapSurfacesNV(1, &surface);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
@ -882,6 +911,8 @@ extern unsigned char *posd;
|
||||
//}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
bool cOglCmdCopyBufferToOutputFb::Execute(void) {
|
||||
int i;
|
||||
pthread_mutex_lock(&OSDMutex);
|
||||
@ -896,6 +927,7 @@ bool cOglCmdCopyBufferToOutputFb::Execute(void) {
|
||||
glReadPixels(0, 0 ,fb->Width(), fb->Height(),GL_BGRA,GL_UNSIGNED_BYTE,posd);
|
||||
#else
|
||||
fb->Blit(x, y + fb->Height(), x + fb->Width(), y);
|
||||
glFlush();
|
||||
#endif
|
||||
ActivateOsd(oFb->texture,x, y, fb->Width() ,fb->Height());
|
||||
|
||||
@ -1323,6 +1355,10 @@ cOglCmdDrawImage::~cOglCmdDrawImage(void) {
|
||||
|
||||
bool cOglCmdDrawImage::Execute(void) {
|
||||
GLuint texture;
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
OSD_get_shared_context();
|
||||
#endif
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(
|
||||
@ -1341,6 +1377,10 @@ bool cOglCmdDrawImage::Execute(void) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
OSD_get_context();
|
||||
#endif
|
||||
|
||||
GLfloat x1 = x; //left
|
||||
GLfloat y1 = y; //top
|
||||
@ -1430,6 +1470,10 @@ cOglCmdStoreImage::~cOglCmdStoreImage(void) {
|
||||
}
|
||||
|
||||
bool cOglCmdStoreImage::Execute(void) {
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
OSD_get_shared_context();
|
||||
#endif
|
||||
glGenTextures(1, &imageRef->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, imageRef->texture);
|
||||
glTexImage2D(
|
||||
@ -1448,6 +1492,10 @@ bool cOglCmdStoreImage::Execute(void) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
OSD_get_context();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2041,11 +2089,17 @@ cOglOsd::cOglOsd(int Left, int Top, uint Level, std::shared_ptr<cOglThread> oglT
|
||||
posd = MALLOC(unsigned char, osdWidth * osdHeight * 4);
|
||||
#endif
|
||||
//create output framebuffer
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
OSD_get_shared_context();
|
||||
#endif
|
||||
if (!oFb) {
|
||||
oFb = new cOglOutputFb(osdWidth, osdHeight);
|
||||
oglThread->DoCmd(new cOglCmdInitOutputFb(oFb));
|
||||
}
|
||||
|
||||
#ifdef VAAPI
|
||||
OSD_release_context();
|
||||
#endif
|
||||
}
|
||||
|
||||
cOglOsd::~cOglOsd() {
|
||||
|
196
shaders.h
196
shaders.h
@ -1,54 +1,54 @@
|
||||
|
||||
// shader
|
||||
#ifdef CUVID
|
||||
char vertex_osd[] = {"\
|
||||
#version 330\n\
|
||||
in vec2 vertex_position;\n\
|
||||
in vec2 vertex_texcoord0;\n\
|
||||
out vec2 texcoord0;\n\
|
||||
void main() {\n\
|
||||
gl_Position = vec4(vertex_position, 1.0, 1.0);\n\
|
||||
texcoord0 = vertex_texcoord0;\n\
|
||||
}\n"};
|
||||
|
||||
char fragment_osd[] = {"\
|
||||
#version 330\n\
|
||||
#define texture1D texture\n\
|
||||
precision mediump float; \
|
||||
layout(location = 0) out vec4 out_color;\n\
|
||||
in vec2 texcoord0;\n\
|
||||
uniform sampler2D texture0;\n\
|
||||
void main() {\n\
|
||||
vec4 color; \n\
|
||||
color = vec4(texture(texture0, texcoord0));\n\
|
||||
out_color = color;\n\
|
||||
}\n"};
|
||||
|
||||
char vertex[] = {"\
|
||||
#version 330\n\
|
||||
#version 310 es\n\
|
||||
in vec2 vertex_position;\n\
|
||||
in vec2 vertex_texcoord0;\n\
|
||||
out vec2 texcoord0;\n\
|
||||
in vec2 vertex_texcoord1;\n\
|
||||
out vec2 texcoord1;\n\
|
||||
in vec2 vertex_texcoord2;\n\
|
||||
out vec2 texcoord2;\n\
|
||||
in vec2 vertex_texcoord3;\n\
|
||||
out vec2 texcoord3;\n\
|
||||
in vec2 vertex_texcoord4;\n\
|
||||
out vec2 texcoord4;\n\
|
||||
in vec2 vertex_texcoord5;\n\
|
||||
out vec2 texcoord5;\n\
|
||||
void main() {\n\
|
||||
gl_Position = vec4(vertex_position, 1.0, 1.0);\n\
|
||||
texcoord0 = vertex_texcoord0;\n\
|
||||
texcoord1 = vertex_texcoord1;\n\
|
||||
texcoord2 = vertex_texcoord2;\n\
|
||||
texcoord3 = vertex_texcoord3;\n\
|
||||
texcoord4 = vertex_texcoord4;\n\
|
||||
texcoord5 = vertex_texcoord5;\n\
|
||||
}\n"};
|
||||
|
||||
|
||||
char fragment[] = {"\
|
||||
#version 330\n\
|
||||
#version 310 es\n\
|
||||
#define texture1D texture\n\
|
||||
#define texture3D texture\n\
|
||||
precision mediump float; \
|
||||
layout(location = 0) out vec4 out_color;\n\
|
||||
in vec2 texcoord0;\n\
|
||||
in vec2 texcoord1;\n\
|
||||
in vec2 texcoord2;\n\
|
||||
in vec2 texcoord3;\n\
|
||||
in vec2 texcoord4;\n\
|
||||
in vec2 texcoord5;\n\
|
||||
uniform mat3 colormatrix;\n\
|
||||
uniform vec3 colormatrix_c;\n\
|
||||
uniform sampler2D texture0;\n\
|
||||
//uniform vec2 texture_size0;\n\
|
||||
//uniform mat2 texture_rot0;\n\
|
||||
//uniform vec2 pixel_size0;\n\
|
||||
uniform sampler2D texture1;\n\
|
||||
//uniform vec2 texture_size1;\n\
|
||||
//uniform mat2 texture_rot1;\n\
|
||||
//uniform vec2 pixel_size1;\n\
|
||||
//#define LUT_POS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))\n\
|
||||
void main() {\n\
|
||||
vec4 color; // = vec4(0.0, 0.0, 0.0, 1.0);\n\
|
||||
color.r = 1.000000 * vec4(texture(texture0, texcoord0)).r;\n\
|
||||
@ -61,27 +61,18 @@ out_color = color;\n\
|
||||
}\n"};
|
||||
|
||||
char fragment_bt2100[] = {"\
|
||||
#version 330\n\
|
||||
#version 310 es\n \
|
||||
#define texture1D texture\n\
|
||||
#define texture3D texture\n\
|
||||
precision mediump float; \
|
||||
layout(location = 0) out vec4 out_color;\n\
|
||||
in vec2 texcoord0;\n\
|
||||
in vec2 texcoord1;\n\
|
||||
in vec2 texcoord2;\n\
|
||||
in vec2 texcoord3;\n\
|
||||
in vec2 texcoord4;\n\
|
||||
in vec2 texcoord5;\n\
|
||||
uniform mat3 colormatrix;\n\
|
||||
uniform vec3 colormatrix_c;\n\
|
||||
uniform mat3 cms_matrix;\n\
|
||||
uniform sampler2D texture0;\n\
|
||||
//uniform vec2 texture_size0;\n\
|
||||
//uniform mat2 texture_rot0;\n\
|
||||
//uniform vec2 pixel_size0;\n\
|
||||
uniform sampler2D texture1;\n\
|
||||
//uniform vec2 texture_size1;\n\
|
||||
//uniform mat2 texture_rot1;\n\
|
||||
//uniform vec2 pixel_size1;\n\
|
||||
//#define LUT_POS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))\n\
|
||||
void main() {\n\
|
||||
vec4 color; // = vec4(0.0, 0.0, 0.0, 1.0);\n\
|
||||
@ -99,6 +90,98 @@ color.rgb = pow(color.rgb, vec3(1.0/2.4));\n\
|
||||
out_color = color;\n\
|
||||
}\n"};
|
||||
|
||||
|
||||
#else
|
||||
char vertex_osd[] = {"\
|
||||
\n\
|
||||
in vec2 vertex_position;\n\
|
||||
in vec2 vertex_texcoord0;\n\
|
||||
out vec2 texcoord0;\n\
|
||||
void main() {\n\
|
||||
gl_Position = vec4(vertex_position, 1.0, 1.0);\n\
|
||||
texcoord0 = vertex_texcoord0;\n\
|
||||
}\n"};
|
||||
|
||||
char fragment_osd[] = {"\
|
||||
\n\
|
||||
#define texture1D texture\n\
|
||||
precision mediump float; \
|
||||
layout(location = 0) out vec4 out_color;\n\
|
||||
in vec2 texcoord0;\n\
|
||||
uniform sampler2D texture0;\n\
|
||||
void main() {\n\
|
||||
vec4 color; \n\
|
||||
color = vec4(texture(texture0, texcoord0));\n\
|
||||
out_color = color;\n\
|
||||
}\n"};
|
||||
|
||||
char vertex[] = {"\
|
||||
\n\
|
||||
in vec2 vertex_position;\n\
|
||||
in vec2 vertex_texcoord0;\n\
|
||||
out vec2 texcoord0;\n\
|
||||
in vec2 vertex_texcoord1;\n\
|
||||
out vec2 texcoord1;\n\
|
||||
void main() {\n\
|
||||
gl_Position = vec4(vertex_position, 1.0, 1.0);\n\
|
||||
texcoord0 = vertex_texcoord0;\n\
|
||||
texcoord1 = vertex_texcoord1;\n\
|
||||
}\n"};
|
||||
|
||||
char fragment[] = {"\
|
||||
\n\
|
||||
#define texture1D texture\n\
|
||||
#define texture3D texture\n\
|
||||
precision mediump float; \
|
||||
layout(location = 0) out vec4 out_color;\n\
|
||||
in vec2 texcoord0;\n\
|
||||
in vec2 texcoord1;\n\
|
||||
uniform mat3 colormatrix;\n\
|
||||
uniform vec3 colormatrix_c;\n\
|
||||
uniform sampler2D texture0;\n\
|
||||
uniform sampler2D texture1;\n\
|
||||
//#define LUT_POS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))\n\
|
||||
void main() {\n\
|
||||
vec4 color; // = vec4(0.0, 0.0, 0.0, 1.0);\n\
|
||||
color.r = 1.000000 * vec4(texture(texture0, texcoord0)).r;\n\
|
||||
color.gb = 1.000000 * vec4(texture(texture1, texcoord1)).rg;\n\
|
||||
// color conversion\n\
|
||||
color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;\n\
|
||||
color.a = 1.0;\n\
|
||||
// color mapping\n\
|
||||
out_color = color;\n\
|
||||
}\n"};
|
||||
|
||||
char fragment_bt2100[] = {"\
|
||||
\n \
|
||||
#define texture1D texture\n\
|
||||
#define texture3D texture\n\
|
||||
precision mediump float; \
|
||||
layout(location = 0) out vec4 out_color;\n\
|
||||
in vec2 texcoord0;\n\
|
||||
in vec2 texcoord1;\n\
|
||||
uniform mat3 colormatrix;\n\
|
||||
uniform vec3 colormatrix_c;\n\
|
||||
uniform mat3 cms_matrix;\n\
|
||||
uniform sampler2D texture0;\n\
|
||||
uniform sampler2D texture1;\n\
|
||||
//#define LUT_POS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))\n\
|
||||
void main() {\n\
|
||||
vec4 color; // = vec4(0.0, 0.0, 0.0, 1.0);\n\
|
||||
color.r = 1.003906 * vec4(texture(texture0, texcoord0)).r;\n\
|
||||
color.gb = 1.003906 * vec4(texture(texture1, texcoord1)).rg;\n\
|
||||
// color conversion\n\
|
||||
color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;\n\
|
||||
color.a = 1.0;\n\
|
||||
// color mapping\n\
|
||||
color.rgb = clamp(color.rgb, 0.0, 1.0);\n\
|
||||
color.rgb = pow(color.rgb, vec3(2.4));\n\
|
||||
color.rgb = cms_matrix * color.rgb;\n\
|
||||
color.rgb = clamp(color.rgb, 0.0, 1.0);\n\
|
||||
color.rgb = pow(color.rgb, vec3(1.0/2.4));\n\
|
||||
out_color = color;\n\
|
||||
}\n"};
|
||||
#endif
|
||||
/* Color conversion matrix: RGB = m * YUV + c
|
||||
* m is in row-major matrix, with m[row][col], e.g.:
|
||||
* [ a11 a12 a13 ] float m[3][3] = { { a11, a12, a13 },
|
||||
@ -113,12 +196,12 @@ out_color = color;\n\
|
||||
* The matrix might also be used for other conversions and colorspaces.
|
||||
*/
|
||||
struct mp_cmat {
|
||||
float m[3][3]; // colormatrix
|
||||
float c[3]; //colormatrix_c
|
||||
GLfloat m[3][3]; // colormatrix
|
||||
GLfloat c[3]; //colormatrix_c
|
||||
};
|
||||
|
||||
struct mp_mat {
|
||||
float m[3][3];
|
||||
GLfloat m[3][3];
|
||||
};
|
||||
|
||||
// YUV input limited range (16-235 for luma, 16-240 for chroma)
|
||||
@ -185,10 +268,6 @@ static const struct gl_vao_entry vertex_vao[] = {
|
||||
{"position", 2, GL_FLOAT, false, offsetof(struct vertex, position)},
|
||||
{"texcoord0", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[0])},
|
||||
{"texcoord1", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[1])},
|
||||
{"texcoord2", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[2])},
|
||||
{"texcoord3", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[3])},
|
||||
{"texcoord4", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[4])},
|
||||
{"texcoord5", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[5])},
|
||||
{0}
|
||||
};
|
||||
|
||||
@ -198,7 +277,8 @@ static void compile_attach_shader(GLuint program,
|
||||
{
|
||||
GLuint shader;
|
||||
GLint status, log_length;
|
||||
|
||||
char log[4000];
|
||||
GLsizei len;
|
||||
shader = glCreateShader(type);
|
||||
glShaderSource(shader, 1, &source, NULL);
|
||||
glCompileShader(shader);
|
||||
@ -206,9 +286,10 @@ static void compile_attach_shader(GLuint program,
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
log_length = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
|
||||
Debug(3,"compile Status %d loglen %d\n",status,log_length);
|
||||
|
||||
glGetShaderInfoLog(shader,4000,&len,log);
|
||||
GlxCheck();
|
||||
Debug(3,"compile Status %d loglen %d >%s<\n",status,log_length,log);
|
||||
|
||||
glAttachShader(program, shader);
|
||||
glDeleteShader(shader);
|
||||
}
|
||||
@ -223,10 +304,24 @@ static void link_shader(GLuint program)
|
||||
log_length = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
|
||||
Debug(3,"Link Status %d loglen %d\n",status,log_length);
|
||||
|
||||
|
||||
}
|
||||
|
||||
static GLuint sc_generate_osd(GLuint gl_prog) {
|
||||
|
||||
Debug(3,"vor create osd\n");
|
||||
gl_prog = glCreateProgram();
|
||||
Debug(3,"vor compile vertex osd\n");
|
||||
compile_attach_shader(gl_prog, GL_VERTEX_SHADER, vertex_osd);
|
||||
Debug(3,"vor compile fragment osd \n");
|
||||
compile_attach_shader(gl_prog, GL_FRAGMENT_SHADER, fragment_osd);
|
||||
glBindAttribLocation(gl_prog,0,"vertex_position");
|
||||
glBindAttribLocation(gl_prog,1,"vertex_texcoord0");
|
||||
|
||||
link_shader(gl_prog);
|
||||
return gl_prog;
|
||||
}
|
||||
|
||||
|
||||
static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) {
|
||||
|
||||
char vname[80];
|
||||
@ -284,7 +379,8 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) {
|
||||
if (gl_colormatrix != -1)
|
||||
glProgramUniformMatrix3fv(gl_prog,gl_colormatrix,1,0,m);
|
||||
GlxCheck();
|
||||
//glProgramUniform3fv(gl_prog,gl_colormatrix,3,&yuv_bt709.m[0][0]);
|
||||
Debug(3,"nach set colormatrix\n");
|
||||
|
||||
gl_colormatrix_c = glGetUniformLocation(gl_prog,"colormatrix_c");
|
||||
Debug(3,"get uniform colormatrix_c %d %f\n",gl_colormatrix_c,*c);
|
||||
if (gl_colormatrix_c != -1)
|
||||
|
19
softhddev.c
19
softhddev.c
@ -107,6 +107,7 @@ static VideoStream *AudioSyncStream; ///< video stream for audio/video sync
|
||||
#define AUDIO_MIN_BUFFER_FREE (3072 * 8 * 8)
|
||||
#define AUDIO_BUFFER_SIZE (512 * 1024) ///< audio PES buffer default size
|
||||
static AVPacket AudioAvPkt[1]; ///< audio a/v packet
|
||||
int AudioDelay = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Audio codec parser
|
||||
@ -721,8 +722,7 @@ static void PesParse(PesDemux * pesdx, const uint8_t * data, int size,
|
||||
if (AudioCodecID != AV_CODEC_ID_NONE) {
|
||||
// shouldn't happen after we have a vaild codec
|
||||
// detected
|
||||
Debug(4, "pesdemux: skip @%d %02x\n", pesdx->Skip,
|
||||
q[0]);
|
||||
Debug(4, "pesdemux: skip @%d %02x\n", pesdx->Skip,q[0]);
|
||||
}
|
||||
// try next byte
|
||||
++pesdx->Skip;
|
||||
@ -1024,7 +1024,13 @@ int PlayAudio(const uint8_t * data, int size, uint8_t id)
|
||||
if (SkipAudio || !MyAudioDecoder) { // skip audio
|
||||
return size;
|
||||
}
|
||||
if (StreamFreezed) { // stream freezed
|
||||
if (StreamFreezed ) { // stream freezed
|
||||
return 0;
|
||||
}
|
||||
if (AudioDelay) {
|
||||
Debug(3,"AudioDelay %dms\n",AudioDelay);
|
||||
usleep(AudioDelay/90);
|
||||
AudioDelay = 0;
|
||||
return 0;
|
||||
}
|
||||
if (NewAudioStream) {
|
||||
@ -1257,6 +1263,7 @@ int PlayTsAudio(const uint8_t * data, int size)
|
||||
if (StreamFreezed) { // stream freezed
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NewAudioStream) {
|
||||
// this clears the audio ringbuffer indirect, open and setup does it
|
||||
CodecAudioClose(MyAudioDecoder);
|
||||
@ -1279,7 +1286,13 @@ int PlayTsAudio(const uint8_t * data, int size)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (AudioDelay) {
|
||||
Debug(3,"AudioDelay %dms\n",AudioDelay);
|
||||
usleep(AudioDelay*1000);
|
||||
AudioDelay = 0;
|
||||
// TsDemuxer(tsdx, data, size); // insert dummy audio
|
||||
|
||||
}
|
||||
return TsDemuxer(tsdx, data, size);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user