mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Initial opengl support with va-api only.
This commit is contained in:
parent
c0286b3ab4
commit
8f99f80d44
@ -1,6 +1,7 @@
|
|||||||
User johns
|
User johns
|
||||||
Date:
|
Date:
|
||||||
|
|
||||||
|
Initial opengl support with va-api only.
|
||||||
Fix "broken driver" message if empty ring buffer.
|
Fix "broken driver" message if empty ring buffer.
|
||||||
Enable seamless audio track change.
|
Enable seamless audio track change.
|
||||||
Fix bug #1302: Unsupported pixel format crash.
|
Fix bug #1302: Unsupported pixel format crash.
|
||||||
|
12
Makefile
12
Makefile
@ -19,6 +19,8 @@ OSS ?= 1
|
|||||||
VDPAU ?= $(shell pkg-config --exists vdpau && echo 1)
|
VDPAU ?= $(shell pkg-config --exists vdpau && echo 1)
|
||||||
# support VA-API video output modue
|
# support VA-API video output modue
|
||||||
VAAPI ?= $(shell pkg-config --exists libva && echo 1)
|
VAAPI ?= $(shell pkg-config --exists libva && echo 1)
|
||||||
|
# support glx output
|
||||||
|
#OPENGL ?= $(shell pkg-config --exists gl glu && echo 1)
|
||||||
# screensaver disable/enable
|
# screensaver disable/enable
|
||||||
SCREENSAVER ?= 1
|
SCREENSAVER ?= 1
|
||||||
# use ffmpeg libswresample
|
# use ffmpeg libswresample
|
||||||
@ -34,6 +36,7 @@ CONFIG += -DUSE_PIP # PIP support
|
|||||||
#CONFIG += -DUSE_TS_VIDEO # build new ts video parser
|
#CONFIG += -DUSE_TS_VIDEO # build new ts video parser
|
||||||
#CONFIG += -DUSE_MPEG_COMPLETE # support only complete mpeg packets
|
#CONFIG += -DUSE_MPEG_COMPLETE # support only complete mpeg packets
|
||||||
#CONFIG += -DUSE_VDR_SPU # use VDR SPU decoder.
|
#CONFIG += -DUSE_VDR_SPU # use VDR SPU decoder.
|
||||||
|
#CONFIG += -DUSE_SOFTLIMIT # (tobe removed) limit the buffer fill
|
||||||
|
|
||||||
ifeq ($(ALSA),1)
|
ifeq ($(ALSA),1)
|
||||||
CONFIG += -DUSE_ALSA
|
CONFIG += -DUSE_ALSA
|
||||||
@ -52,6 +55,15 @@ ifeq ($(VAAPI),1)
|
|||||||
CONFIG += -DUSE_VAAPI
|
CONFIG += -DUSE_VAAPI
|
||||||
_CFLAGS += $(shell pkg-config --cflags libva-x11 libva)
|
_CFLAGS += $(shell pkg-config --cflags libva-x11 libva)
|
||||||
LIBS += $(shell pkg-config --libs libva-x11 libva)
|
LIBS += $(shell pkg-config --libs libva-x11 libva)
|
||||||
|
ifeq ($(OPENGL),1)
|
||||||
|
_CFLAGS += $(shell pkg-config --cflags libva-glx)
|
||||||
|
LIBS += $(shell pkg-config --libs libva-glx)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifeq ($(OPENGL),1)
|
||||||
|
CONFIG += -DUSE_GLX
|
||||||
|
_CFLAGS += $(shell pkg-config --cflags gl glu)
|
||||||
|
LIBS += $(shell pkg-config --libs gl glu)
|
||||||
endif
|
endif
|
||||||
ifeq ($(SCREENSAVER),1)
|
ifeq ($(SCREENSAVER),1)
|
||||||
CONFIG += -DUSE_SCREENSAVER
|
CONFIG += -DUSE_SCREENSAVER
|
||||||
|
2
Todo
2
Todo
@ -1,6 +1,6 @@
|
|||||||
@file Todo @brief A software HD output device for VDR
|
@file Todo @brief A software HD output device for VDR
|
||||||
|
|
||||||
Copyright (c) 2011, 2012 by Johns. All Rights Reserved.
|
Copyright (c) 2011 - 2013 by Johns. All Rights Reserved.
|
||||||
|
|
||||||
Contributor(s):
|
Contributor(s):
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: VDR \n"
|
"Project-Id-Version: VDR \n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\n"
|
||||||
"POT-Creation-Date: 2013-03-09 19:20+0100\n"
|
"POT-Creation-Date: 2013-04-16 15:10+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -895,6 +895,9 @@ msgstr ""
|
|||||||
msgid "unsupported"
|
msgid "unsupported"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "video/glx: glx error\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "video/vaapi: unsupported pixel format %d\n"
|
msgid "video/vaapi: unsupported pixel format %d\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -1355,6 +1358,10 @@ msgstr ""
|
|||||||
msgid "video: Can't connect to X11 server on '%s'\n"
|
msgid "video: Can't connect to X11 server on '%s'\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#, c-format
|
||||||
|
msgid "video: Can't initialize X11 thread support on '%s'\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "video: Can't convert XLIB display to XCB connection\n"
|
msgid "video: Can't convert XLIB display to XCB connection\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
606
video.c
606
video.c
@ -43,7 +43,7 @@
|
|||||||
#define USE_AUTOCROP ///< compile auto-crop support
|
#define USE_AUTOCROP ///< compile auto-crop support
|
||||||
#define USE_GRAB ///< experimental grab code
|
#define USE_GRAB ///< experimental grab code
|
||||||
#define noUSE_GLX ///< outdated GLX code
|
#define noUSE_GLX ///< outdated GLX code
|
||||||
#define noUSE_DOUBLEBUFFER ///< use GLX double buffers
|
#define USE_DOUBLEBUFFER ///< use GLX double buffers
|
||||||
//#define USE_VAAPI ///< enable vaapi support
|
//#define USE_VAAPI ///< enable vaapi support
|
||||||
//#define USE_VDPAU ///< enable vdpau support
|
//#define USE_VDPAU ///< enable vdpau support
|
||||||
#define noUSE_BITMAP ///< use vdpau bitmap surface
|
#define noUSE_BITMAP ///< use vdpau bitmap surface
|
||||||
@ -137,7 +137,7 @@ typedef enum
|
|||||||
#include <va/va_glx.h>
|
#include <va/va_glx.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef VA_SURFACE_ATTRIB_SETTABLE
|
#ifndef VA_SURFACE_ATTRIB_SETTABLE
|
||||||
/// make source compatible with old libva
|
/// make source compatible with stable libva
|
||||||
#define vaCreateSurfaces(d, f, w, h, s, ns, a, na) \
|
#define vaCreateSurfaces(d, f, w, h, s, ns, a, na) \
|
||||||
vaCreateSurfaces(d, w, h, f, ns, s)
|
vaCreateSurfaces(d, w, h, f, ns, s)
|
||||||
#endif
|
#endif
|
||||||
@ -622,10 +622,15 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width,
|
|||||||
|
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
|
|
||||||
static int GlxEnabled = 1; ///< use GLX
|
static int GlxEnabled; ///< use GLX
|
||||||
static int GlxVSyncEnabled = 0; ///< enable/disable v-sync
|
static int GlxVSyncEnabled; ///< enable/disable v-sync
|
||||||
static GLXContext GlxSharedContext; ///< shared gl context
|
static GLXContext GlxSharedContext; ///< shared gl context
|
||||||
static GLXContext GlxContext; ///< our gl context
|
static GLXContext GlxContext; ///< our gl context
|
||||||
|
|
||||||
|
#ifdef USE_VIDEO_THREAD
|
||||||
|
static GLXContext GlxThreadContext; ///< our gl context for the thread
|
||||||
|
#endif
|
||||||
|
|
||||||
static XVisualInfo *GlxVisualInfo; ///< our gl visual
|
static XVisualInfo *GlxVisualInfo; ///< our gl visual
|
||||||
|
|
||||||
static GLuint OsdGlTextures[2]; ///< gl texture for OSD
|
static GLuint OsdGlTextures[2]; ///< gl texture for OSD
|
||||||
@ -681,26 +686,22 @@ static int GlxIsExtensionSupported(const char *ext)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
///
|
///
|
||||||
/// Setup GLX decoder
|
/// Setup GLX decoder
|
||||||
///
|
///
|
||||||
/// @param decoder VA-API decoder
|
/// @param width input video textures width
|
||||||
|
/// @param height input video textures height
|
||||||
|
/// @param[OUT] textures created and prepared textures
|
||||||
///
|
///
|
||||||
void GlxSetupDecoder(VaapiDecoder * decoder)
|
static void GlxSetupDecoder(int width, int height, GLuint * textures)
|
||||||
{
|
{
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
width = decoder->InputWidth;
|
|
||||||
height = decoder->InputHeight;
|
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D); // create 2d texture
|
glEnable(GL_TEXTURE_2D); // create 2d texture
|
||||||
glGenTextures(2, decoder->GlTexture);
|
glGenTextures(2, textures);
|
||||||
GlxCheck();
|
GlxCheck();
|
||||||
for (i = 0; i < 2; ++i) {
|
for (i = 0; i < 2; ++i) {
|
||||||
glBindTexture(GL_TEXTURE_2D, decoder->GlTexture[i]);
|
glBindTexture(GL_TEXTURE_2D, textures[i]);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
@ -714,12 +715,15 @@ void GlxSetupDecoder(VaapiDecoder * decoder)
|
|||||||
|
|
||||||
GlxCheck();
|
GlxCheck();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Render texture.
|
/// Render texture.
|
||||||
///
|
///
|
||||||
/// @param texture 2d texture
|
/// @param texture 2d texture
|
||||||
|
/// @param x window x
|
||||||
|
/// @param y window y
|
||||||
|
/// @param width window width
|
||||||
|
/// @param height window height
|
||||||
///
|
///
|
||||||
static inline void GlxRenderTexture(GLuint texture, int x, int y, int width,
|
static inline void GlxRenderTexture(GLuint texture, int x, int y, int width,
|
||||||
int height)
|
int height)
|
||||||
@ -737,16 +741,6 @@ static inline void GlxRenderTexture(GLuint texture, int x, int y, int width,
|
|||||||
glVertex2i(x, y);
|
glVertex2i(x, y);
|
||||||
glTexCoord2f(1.0f, 0.0f);
|
glTexCoord2f(1.0f, 0.0f);
|
||||||
glVertex2i(x + width, y);
|
glVertex2i(x + width, y);
|
||||||
#if 0
|
|
||||||
glTexCoord2f(0.0f, 0.0f);
|
|
||||||
glVertex2i(x, y);
|
|
||||||
glTexCoord2f(0.0f, 1.0f);
|
|
||||||
glVertex2i(x, y + height);
|
|
||||||
glTexCoord2f(1.0f, 1.0f);
|
|
||||||
glVertex2i(x + width, y + height);
|
|
||||||
glTexCoord2f(1.0f, 0.0f);
|
|
||||||
glVertex2i(x + width, y);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
@ -755,15 +749,20 @@ static inline void GlxRenderTexture(GLuint texture, int x, int y, int width,
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Upload texture.
|
/// Upload OSD texture.
|
||||||
///
|
///
|
||||||
static void GlxUploadTexture(int x, int y, int width, int height,
|
/// @param x x coordinate texture
|
||||||
|
/// @param y y coordinate texture
|
||||||
|
/// @param width argb image width
|
||||||
|
/// @param height argb image height
|
||||||
|
/// @param argb argb image
|
||||||
|
///
|
||||||
|
static void GlxUploadOsdTexture(int x, int y, int width, int height,
|
||||||
const uint8_t * argb)
|
const uint8_t * argb)
|
||||||
{
|
{
|
||||||
// FIXME: use other / faster uploads
|
// FIXME: use other / faster uploads
|
||||||
// ARB_pixelbuffer_object GL_PIXEL_UNPACK_BUFFER glBindBufferARB()
|
// ARB_pixelbuffer_object GL_PIXEL_UNPACK_BUFFER glBindBufferARB()
|
||||||
// glMapBuffer() glUnmapBuffer()
|
// glMapBuffer() glUnmapBuffer()
|
||||||
// glTexSubImage2D
|
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D); // upload 2d texture
|
glEnable(GL_TEXTURE_2D); // upload 2d texture
|
||||||
|
|
||||||
@ -776,59 +775,164 @@ static void GlxUploadTexture(int x, int y, int width, int height,
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Render to glx texture.
|
/// GLX initialize OSD.
|
||||||
///
|
///
|
||||||
static void GlxRender(int osd_width, int osd_height)
|
/// @param width osd width
|
||||||
|
/// @param height osd height
|
||||||
|
///
|
||||||
|
static void GlxOsdInit(int width, int height)
|
||||||
{
|
{
|
||||||
static uint8_t *image;
|
int i;
|
||||||
static uint8_t cycle;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
|
|
||||||
if (!OsdGlTextures[0] || !OsdGlTextures[1]) {
|
#ifdef DEBUG
|
||||||
|
if (!GlxEnabled) {
|
||||||
|
Debug(3, "video/glx: %s called without glx enabled\n", __FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// render each frame kills performance
|
#endif
|
||||||
|
|
||||||
// osd 1920 * 1080 * 4 (RGBA) * 50 (HZ) = 396 Mb/s
|
Debug(3, "video/glx: osd init context %p <-> %p\n", glXGetCurrentContext(),
|
||||||
|
GlxContext);
|
||||||
|
|
||||||
// too big for alloca
|
|
||||||
if (!image) {
|
|
||||||
image = malloc(4 * osd_width * osd_height);
|
|
||||||
memset(image, 0x00, 4 * osd_width * osd_height);
|
|
||||||
}
|
|
||||||
for (y = 0; y < osd_height; ++y) {
|
|
||||||
for (x = 0; x < osd_width; ++x) {
|
|
||||||
((uint32_t *) image)[x + y * osd_width] =
|
|
||||||
0x00FFFFFF | (cycle++) << 24;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cycle++;
|
|
||||||
|
|
||||||
// FIXME: convert is for GLX texture unneeded
|
|
||||||
// convert internal osd to image
|
|
||||||
//GfxConvert(image, 0, 4 * osd_width);
|
|
||||||
//
|
//
|
||||||
|
// create a RGBA texture.
|
||||||
|
//
|
||||||
|
glEnable(GL_TEXTURE_2D); // create 2d texture(s)
|
||||||
|
|
||||||
GlxUploadTexture(0, 0, osd_width, osd_height, image);
|
glGenTextures(2, OsdGlTextures);
|
||||||
|
for (i = 0; i < 2; ++i) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, OsdGlTextures[i]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA,
|
||||||
|
GL_UNSIGNED_BYTE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// GLX cleanup osd.
|
||||||
|
///
|
||||||
|
static void GlxOsdExit(void)
|
||||||
|
{
|
||||||
|
if (OsdGlTextures[0]) {
|
||||||
|
glDeleteTextures(2, OsdGlTextures);
|
||||||
|
OsdGlTextures[0] = 0;
|
||||||
|
OsdGlTextures[1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Upload ARGB image to texture.
|
||||||
|
///
|
||||||
|
/// @param x x coordinate of image in osd texture
|
||||||
|
/// @param y y coordinate of image in osd texture
|
||||||
|
/// @param width width of image
|
||||||
|
/// @param height height of image
|
||||||
|
/// @param argb argb image
|
||||||
|
///
|
||||||
|
/// @note looked by caller
|
||||||
|
///
|
||||||
|
static void GlxOsdDrawARGB(int x, int y, int width, int height,
|
||||||
|
const uint8_t * argb)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t end;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (!GlxEnabled) {
|
||||||
|
Debug(3, "video/glx: %s called without glx enabled\n", __FUNCTION__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
start = GetMsTicks();
|
||||||
|
Debug(3, "video/glx: osd context %p <-> %p\n", glXGetCurrentContext(),
|
||||||
|
GlxContext);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// set glx context
|
||||||
|
if (!glXMakeCurrent(XlibDisplay, VideoWindow, GlxContext)) {
|
||||||
|
Error(_("video/glx: can't make glx context current\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GlxUploadOsdTexture(x, y, width, height, argb);
|
||||||
|
glXMakeCurrent(XlibDisplay, None, NULL);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
end = GetMsTicks();
|
||||||
|
|
||||||
|
Debug(3, "video/glx: osd upload %dx%d%+d%+d %dms %d\n", width, height, x,
|
||||||
|
y, end - start, width * height * 4);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Clear OSD texture.
|
||||||
|
///
|
||||||
|
/// @note looked by caller
|
||||||
|
///
|
||||||
|
static void GlxOsdClear(void)
|
||||||
|
{
|
||||||
|
void *texbuf;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (!GlxEnabled) {
|
||||||
|
Debug(3, "video/glx: %s called without glx enabled\n", __FUNCTION__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug(3, "video/glx: osd context %p <-> %p\n", glXGetCurrentContext(),
|
||||||
|
GlxContext);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// FIXME: any opengl function to clear an area?
|
||||||
|
// FIXME: if not; use zero buffer
|
||||||
|
// FIXME: if not; use dirty area
|
||||||
|
|
||||||
|
texbuf = calloc(OsdWidth * OsdHeight, 4);
|
||||||
|
|
||||||
|
// set glx context
|
||||||
|
if (!glXMakeCurrent(XlibDisplay, VideoWindow, GlxContext)) {
|
||||||
|
Error(_("video/glx: can't make glx context current\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GlxUploadOsdTexture(0, 0, OsdWidth, OsdHeight, texbuf);
|
||||||
|
glXMakeCurrent(XlibDisplay, None, NULL);
|
||||||
|
|
||||||
|
free(texbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Setup GLX window.
|
/// Setup GLX window.
|
||||||
///
|
///
|
||||||
static void GlxSetupWindow(xcb_window_t window, int width, int height)
|
/// @param window xcb window id
|
||||||
|
/// @param width window width
|
||||||
|
/// @param height window height
|
||||||
|
/// @param context GLX context
|
||||||
|
///
|
||||||
|
static void GlxSetupWindow(xcb_window_t window, int width, int height,
|
||||||
|
GLXContext context)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
uint32_t start;
|
uint32_t start;
|
||||||
uint32_t end;
|
uint32_t end;
|
||||||
int i;
|
int i;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
|
#endif
|
||||||
|
|
||||||
Debug(3, "video/glx: %s\n %x %dx%d", __FUNCTION__, window, width, height);
|
Debug(3, "video/glx: %s %x %dx%d context:%p", __FUNCTION__, window, width,
|
||||||
|
height, context);
|
||||||
|
|
||||||
// set glx context
|
// set glx context
|
||||||
if (!glXMakeCurrent(XlibDisplay, window, GlxContext)) {
|
if (!glXMakeCurrent(XlibDisplay, window, context)) {
|
||||||
Fatal(_("video/glx: can't make glx context current\n"));
|
Error(_("video/glx: can't make glx context current\n"));
|
||||||
// FIXME: disable glx
|
GlxEnabled = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -996,7 +1100,8 @@ static void GlxInit(void)
|
|||||||
if (!context) {
|
if (!context) {
|
||||||
Error(_("video/glx: can't create glx context\n"));
|
Error(_("video/glx: can't create glx context\n"));
|
||||||
GlxEnabled = 0;
|
GlxEnabled = 0;
|
||||||
// FIXME: destroy GlxSharedContext
|
glXDestroyContext(XlibDisplay, GlxSharedContext);
|
||||||
|
GlxSharedContext = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GlxContext = context;
|
GlxContext = context;
|
||||||
@ -1093,12 +1198,10 @@ static void GlxExit(void)
|
|||||||
if (GlxContext) {
|
if (GlxContext) {
|
||||||
glXDestroyContext(XlibDisplay, GlxContext);
|
glXDestroyContext(XlibDisplay, GlxContext);
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
if (GlxThreadContext) {
|
if (GlxThreadContext) {
|
||||||
glXDestroyContext(XlibDisplay, GlxThreadContext);
|
glXDestroyContext(XlibDisplay, GlxThreadContext);
|
||||||
}
|
}
|
||||||
// FIXME: must free GlxVisualInfo
|
// FIXME: must free GlxVisualInfo
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -1394,8 +1497,8 @@ struct _vaapi_decoder_
|
|||||||
AutoCropCtx AutoCrop[1]; ///< auto-crop variables
|
AutoCropCtx AutoCrop[1]; ///< auto-crop variables
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
GLuint GlTexture[2]; ///< gl texture for VA-API
|
GLuint GlTextures[2]; ///< gl texture for VA-API
|
||||||
void *GlxSurface[2]; ///< VA-API/GLX surface
|
void *GlxSurfaces[2]; ///< VA-API/GLX surface
|
||||||
#endif
|
#endif
|
||||||
VASurfaceID BlackSurface; ///< empty black surface
|
VASurfaceID BlackSurface; ///< empty black surface
|
||||||
|
|
||||||
@ -1852,8 +1955,8 @@ static VaapiDecoder *VaapiNewHwDecoder(VideoStream * stream)
|
|||||||
decoder->VaapiContext->context_id = VA_INVALID_ID;
|
decoder->VaapiContext->context_id = VA_INVALID_ID;
|
||||||
|
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
decoder->GlxSurface[0] = VA_INVALID_ID;
|
decoder->GlxSurfaces[0] = NULL;
|
||||||
decoder->GlxSurface[1] = VA_INVALID_ID;
|
decoder->GlxSurfaces[1] = NULL;
|
||||||
if (GlxEnabled) {
|
if (GlxEnabled) {
|
||||||
// FIXME: create GLX context here
|
// FIXME: create GLX context here
|
||||||
}
|
}
|
||||||
@ -2009,20 +2112,22 @@ static void VaapiDelHwDecoder(VaapiDecoder * decoder)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
if (decoder->GlxSurface[0] != VA_INVALID_ID) {
|
if (decoder->GlxSurfaces[0]) {
|
||||||
if (vaDestroySurfaceGLX(VaDisplay, decoder->GlxSurface[0])
|
if (vaDestroySurfaceGLX(VaDisplay, decoder->GlxSurfaces[0])
|
||||||
!= VA_STATUS_SUCCESS) {
|
!= VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't destroy glx surface!\n"));
|
Error(_("video/vaapi: can't destroy glx surface!\n"));
|
||||||
}
|
}
|
||||||
|
decoder->GlxSurfaces[0] = NULL;
|
||||||
}
|
}
|
||||||
if (decoder->GlxSurface[1] != VA_INVALID_ID) {
|
if (decoder->GlxSurfaces[1]) {
|
||||||
if (vaDestroySurfaceGLX(VaDisplay, decoder->GlxSurface[1])
|
if (vaDestroySurfaceGLX(VaDisplay, decoder->GlxSurfaces[1])
|
||||||
!= VA_STATUS_SUCCESS) {
|
!= VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/vaapi: can't destroy glx surface!\n"));
|
Error(_("video/vaapi: can't destroy glx surface!\n"));
|
||||||
}
|
}
|
||||||
|
decoder->GlxSurfaces[0] = NULL;
|
||||||
}
|
}
|
||||||
if (decoder->GlTexture[0]) {
|
if (decoder->GlTextures[0]) {
|
||||||
glDeleteTextures(2, decoder->GlTexture);
|
glDeleteTextures(2, decoder->GlTextures);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2244,6 +2349,33 @@ static int VaapiInit(const char *display_name)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_GLX
|
||||||
|
|
||||||
|
///
|
||||||
|
/// VA-API GLX setup.
|
||||||
|
///
|
||||||
|
/// @param display_name x11/xcb display name
|
||||||
|
///
|
||||||
|
/// @returns true if VA-API could be initialized, false otherwise.
|
||||||
|
///
|
||||||
|
static int VaapiGlxInit(const char *display_name)
|
||||||
|
{
|
||||||
|
GlxEnabled = 1;
|
||||||
|
|
||||||
|
GlxInit();
|
||||||
|
if (GlxEnabled) {
|
||||||
|
GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight,
|
||||||
|
GlxContext);
|
||||||
|
}
|
||||||
|
if (!GlxEnabled) {
|
||||||
|
Error(_("video/glx: glx error\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return VaapiInit(display_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
/// VA-API cleanup
|
/// VA-API cleanup
|
||||||
///
|
///
|
||||||
@ -2251,7 +2383,7 @@ static void VaapiExit(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// FIXME: more VA-API cleanups...
|
// FIXME: more VA-API cleanups...
|
||||||
|
|
||||||
for (i = 0; i < VaapiDecoderN; ++i) {
|
for (i = 0; i < VaapiDecoderN; ++i) {
|
||||||
if (VaapiDecoders[i]) {
|
if (VaapiDecoders[i]) {
|
||||||
@ -2405,16 +2537,18 @@ static void VaapiSetup(VaapiDecoder * decoder,
|
|||||||
if (GlxEnabled) {
|
if (GlxEnabled) {
|
||||||
// FIXME: destroy old context
|
// FIXME: destroy old context
|
||||||
|
|
||||||
GlxSetupDecoder(decoder);
|
GlxSetupDecoder(decoder->InputWidth, decoder->InputHeight,
|
||||||
|
decoder->GlTextures);
|
||||||
// FIXME: try two textures
|
// FIXME: try two textures
|
||||||
if (vaCreateSurfaceGLX(decoder->VaDisplay, GL_TEXTURE_2D,
|
if (vaCreateSurfaceGLX(decoder->VaDisplay, GL_TEXTURE_2D,
|
||||||
decoder->GlTexture[0], &decoder->GlxSurface[0])
|
decoder->GlTextures[0], &decoder->GlxSurfaces[0])
|
||||||
!= VA_STATUS_SUCCESS) {
|
!= VA_STATUS_SUCCESS) {
|
||||||
Fatal(_("video/glx: can't create glx surfaces\n"));
|
Fatal(_("video/glx: can't create glx surfaces\n"));
|
||||||
|
// FIXME: no fatal here
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
if (vaCreateSurfaceGLX(decoder->VaDisplay, GL_TEXTURE_2D,
|
if (vaCreateSurfaceGLX(decoder->VaDisplay, GL_TEXTURE_2D,
|
||||||
decoder->GlTexture[1], &decoder->GlxSurface[1])
|
decoder->GlTextures[1], &decoder->GlxSurfaces[1])
|
||||||
!= VA_STATUS_SUCCESS) {
|
!= VA_STATUS_SUCCESS) {
|
||||||
Fatal(_("video/glx: can't create glx surfaces\n"));
|
Fatal(_("video/glx: can't create glx surfaces\n"));
|
||||||
}
|
}
|
||||||
@ -2827,44 +2961,6 @@ static void VaapiPutSurfaceX11(VaapiDecoder * decoder, VASurfaceID surface,
|
|||||||
|
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
|
|
||||||
///
|
|
||||||
/// Render texture.
|
|
||||||
///
|
|
||||||
/// @param texture 2d texture
|
|
||||||
///
|
|
||||||
static inline void VideoRenderTexture(GLuint texture, int x, int y, int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
|
||||||
|
|
||||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // no color
|
|
||||||
glBegin(GL_QUADS); {
|
|
||||||
glTexCoord2f(1.0f, 1.0f);
|
|
||||||
glVertex2i(x + width, y + height);
|
|
||||||
glTexCoord2f(0.0f, 1.0f);
|
|
||||||
glVertex2i(x, y + height);
|
|
||||||
glTexCoord2f(0.0f, 0.0f);
|
|
||||||
glVertex2i(x, y);
|
|
||||||
glTexCoord2f(1.0f, 0.0f);
|
|
||||||
glVertex2i(x + width, y);
|
|
||||||
#if 0
|
|
||||||
glTexCoord2f(0.0f, 0.0f);
|
|
||||||
glVertex2i(x, y);
|
|
||||||
glTexCoord2f(0.0f, 1.0f);
|
|
||||||
glVertex2i(x, y + height);
|
|
||||||
glTexCoord2f(1.0f, 1.0f);
|
|
||||||
glVertex2i(x + width, y + height);
|
|
||||||
glTexCoord2f(1.0f, 0.0f);
|
|
||||||
glVertex2i(x + width, y);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Draw surface of the VA-API decoder with glx.
|
/// Draw surface of the VA-API decoder with glx.
|
||||||
///
|
///
|
||||||
@ -2878,12 +2974,14 @@ static void VaapiPutSurfaceGLX(VaapiDecoder * decoder, VASurfaceID surface,
|
|||||||
int interlaced, int top_field_first, int field)
|
int interlaced, int top_field_first, int field)
|
||||||
{
|
{
|
||||||
unsigned type;
|
unsigned type;
|
||||||
uint32_t start;
|
|
||||||
uint32_t copy;
|
//uint32_t start;
|
||||||
uint32_t end;
|
//uint32_t copy;
|
||||||
|
//uint32_t end;
|
||||||
|
|
||||||
// deinterlace
|
// deinterlace
|
||||||
if (interlaced
|
if (interlaced
|
||||||
|
&& VideoDeinterlace[decoder->Resolution] < VideoDeinterlaceSoftBob
|
||||||
&& VideoDeinterlace[decoder->Resolution] != VideoDeinterlaceWeave) {
|
&& VideoDeinterlace[decoder->Resolution] != VideoDeinterlaceWeave) {
|
||||||
if (top_field_first) {
|
if (top_field_first) {
|
||||||
if (field) {
|
if (field) {
|
||||||
@ -2901,18 +2999,20 @@ static void VaapiPutSurfaceGLX(VaapiDecoder * decoder, VASurfaceID surface,
|
|||||||
} else {
|
} else {
|
||||||
type = VA_FRAME_PICTURE;
|
type = VA_FRAME_PICTURE;
|
||||||
}
|
}
|
||||||
start = GetMsTicks();
|
|
||||||
if (vaCopySurfaceGLX(decoder->VaDisplay, decoder->GlxSurface[0], surface,
|
//start = GetMsTicks();
|
||||||
|
if (vaCopySurfaceGLX(decoder->VaDisplay, decoder->GlxSurfaces[0], surface,
|
||||||
type | decoder->SurfaceFlagsTable[decoder->Resolution]) !=
|
type | decoder->SurfaceFlagsTable[decoder->Resolution]) !=
|
||||||
VA_STATUS_SUCCESS) {
|
VA_STATUS_SUCCESS) {
|
||||||
Error(_("video/glx: vaCopySurfaceGLX failed\n"));
|
Error(_("video/glx: vaCopySurfaceGLX failed\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
copy = GetMsTicks();
|
//copy = GetMsTicks();
|
||||||
// hardware surfaces are always busy
|
// hardware surfaces are always busy
|
||||||
VideoRenderTexture(decoder->GlTexture[0], decoder->OutputX,
|
// FIXME: CropX, ...
|
||||||
|
GlxRenderTexture(decoder->GlTextures[0], decoder->OutputX,
|
||||||
decoder->OutputY, decoder->OutputWidth, decoder->OutputHeight);
|
decoder->OutputY, decoder->OutputWidth, decoder->OutputHeight);
|
||||||
end = GetMsTicks();
|
//end = GetMsTicks();
|
||||||
//Debug(3, "video/vaapi/glx: %d copy %d render\n", copy - start, end - copy);
|
//Debug(3, "video/vaapi/glx: %d copy %d render\n", copy - start, end - copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4577,8 +4677,16 @@ static void VaapiDisplayFrame(void)
|
|||||||
put2 = GetMsTicks();
|
put2 = GetMsTicks();
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef USE_GLX
|
||||||
|
if (GlxEnabled) {
|
||||||
|
VaapiPutSurfaceGLX(decoder, surface, decoder->Interlaced,
|
||||||
|
decoder->TopFieldFirst, decoder->SurfaceField);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
VaapiPutSurfaceX11(decoder, surface, decoder->Interlaced,
|
VaapiPutSurfaceX11(decoder, surface, decoder->Interlaced,
|
||||||
decoder->TopFieldFirst, decoder->SurfaceField);
|
decoder->TopFieldFirst, decoder->SurfaceField);
|
||||||
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
put1 = GetMsTicks();
|
put1 = GetMsTicks();
|
||||||
put2 = put1;
|
put2 = put1;
|
||||||
@ -4611,6 +4719,22 @@ static void VaapiDisplayFrame(void)
|
|||||||
|
|
||||||
decoder->FrameTime = nowtime;
|
decoder->FrameTime = nowtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_GLX
|
||||||
|
//
|
||||||
|
// add OSD
|
||||||
|
//
|
||||||
|
if (OsdShown) {
|
||||||
|
GlxRenderTexture(OsdGlTextures[OsdIndex], 0, 0, VideoWindowWidth,
|
||||||
|
VideoWindowHeight);
|
||||||
|
// FIXME: toggle osd
|
||||||
|
}
|
||||||
|
//glFinish();
|
||||||
|
glXSwapBuffers(XlibDisplay, VideoWindow);
|
||||||
|
GlxCheck();
|
||||||
|
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -5230,6 +5354,44 @@ static const VideoModule VaapiModule = {
|
|||||||
.Exit = VaapiExit,
|
.Exit = VaapiExit,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef USE_GLX
|
||||||
|
|
||||||
|
///
|
||||||
|
/// VA-API module.
|
||||||
|
///
|
||||||
|
static const VideoModule VaapiGlxModule = {
|
||||||
|
.Name = "va-api-glx",
|
||||||
|
.Enabled = 1,
|
||||||
|
.NewHwDecoder =
|
||||||
|
(VideoHwDecoder * (*const)(VideoStream *)) VaapiNewHwDecoder,
|
||||||
|
.DelHwDecoder = (void (*const) (VideoHwDecoder *))VaapiDelHwDecoder,
|
||||||
|
.GetSurface = (unsigned (*const) (VideoHwDecoder *,
|
||||||
|
const AVCodecContext *))VaapiGetSurface,
|
||||||
|
.ReleaseSurface =
|
||||||
|
(void (*const) (VideoHwDecoder *, unsigned))VaapiReleaseSurface,
|
||||||
|
.get_format = (enum PixelFormat(*const) (VideoHwDecoder *,
|
||||||
|
AVCodecContext *, const enum PixelFormat *))Vaapi_get_format,
|
||||||
|
.RenderFrame = (void (*const) (VideoHwDecoder *,
|
||||||
|
const AVCodecContext *, const AVFrame *))VaapiSyncRenderFrame,
|
||||||
|
.SetClock = (void (*const) (VideoHwDecoder *, int64_t))VaapiSetClock,
|
||||||
|
.GetClock = (int64_t(*const) (const VideoHwDecoder *))VaapiGetClock,
|
||||||
|
.SetTrickSpeed =
|
||||||
|
(void (*const) (const VideoHwDecoder *, int))VaapiSetTrickSpeed,
|
||||||
|
.GrabOutput = NULL,
|
||||||
|
.SetBackground = VaapiSetBackground,
|
||||||
|
.SetVideoMode = VaapiSetVideoMode,
|
||||||
|
.ResetAutoCrop = VaapiResetAutoCrop,
|
||||||
|
.DisplayHandlerThread = VaapiDisplayHandlerThread,
|
||||||
|
.OsdClear = GlxOsdClear,
|
||||||
|
.OsdDrawARGB = GlxOsdDrawARGB,
|
||||||
|
.OsdInit = GlxOsdInit,
|
||||||
|
.OsdExit = GlxOsdExit,
|
||||||
|
.Init = VaapiGlxInit,
|
||||||
|
.Exit = VaapiExit,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -5276,8 +5438,8 @@ typedef struct _vdpau_decoder_
|
|||||||
AutoCropCtx AutoCrop[1]; ///< auto-crop variables
|
AutoCropCtx AutoCrop[1]; ///< auto-crop variables
|
||||||
#endif
|
#endif
|
||||||
#ifdef noyetUSE_GLX
|
#ifdef noyetUSE_GLX
|
||||||
GLuint GlTexture[2]; ///< gl texture for VDPAU
|
GLuint GlTextures[2]; ///< gl texture for VDPAU
|
||||||
void *GlxSurface[2]; ///< VDPAU/GLX surface
|
void *GlxSurfaces[2]; ///< VDPAU/GLX surface
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VdpDecoderProfile Profile; ///< vdp decoder profile
|
VdpDecoderProfile Profile; ///< vdp decoder profile
|
||||||
@ -9029,26 +9191,9 @@ static const VideoModule NoopModule = {
|
|||||||
void VideoOsdClear(void)
|
void VideoOsdClear(void)
|
||||||
{
|
{
|
||||||
VideoThreadLock();
|
VideoThreadLock();
|
||||||
#ifdef USE_GLX
|
|
||||||
if (GlxEnabled) {
|
|
||||||
void *texbuf;
|
|
||||||
|
|
||||||
texbuf = calloc(OsdWidth * OsdHeight, 4);
|
|
||||||
glEnable(GL_TEXTURE_2D); // 2d texture
|
|
||||||
glBindTexture(GL_TEXTURE_2D, OsdGlTextures[OsdIndex]);
|
|
||||||
// upload no image data, clears texture (on some drivers only)
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, OsdWidth, OsdHeight, 0,
|
|
||||||
GL_BGRA, GL_UNSIGNED_BYTE, texbuf);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
GlxCheck();
|
|
||||||
free(texbuf);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VideoUsedModule->OsdClear();
|
VideoUsedModule->OsdClear();
|
||||||
|
|
||||||
OsdDirtyX = OsdWidth;
|
OsdDirtyX = OsdWidth; // reset dirty area
|
||||||
OsdDirtyY = OsdHeight;
|
OsdDirtyY = OsdHeight;
|
||||||
OsdDirtyWidth = 0;
|
OsdDirtyWidth = 0;
|
||||||
OsdDirtyHeight = 0;
|
OsdDirtyHeight = 0;
|
||||||
@ -9092,14 +9237,6 @@ void VideoOsdDrawARGB(int x, int y, int width, int height,
|
|||||||
Debug(4, "video: osd dirty %dx%d%+d%+d -> %dx%d%+d%+d\n", width, height, x,
|
Debug(4, "video: osd dirty %dx%d%+d%+d -> %dx%d%+d%+d\n", width, height, x,
|
||||||
y, OsdDirtyWidth, OsdDirtyHeight, OsdDirtyX, OsdDirtyY);
|
y, OsdDirtyWidth, OsdDirtyHeight, OsdDirtyX, OsdDirtyY);
|
||||||
|
|
||||||
#ifdef USE_GLX
|
|
||||||
if (GlxEnabled) {
|
|
||||||
Debug(3, "video: %p <-> %p\n", glXGetCurrentContext(), GlxContext);
|
|
||||||
GlxUploadTexture(x, y, height, width, argb);
|
|
||||||
VideoThreadUnlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
VideoUsedModule->OsdDrawARGB(x, y, width, height, argb);
|
VideoUsedModule->OsdDrawARGB(x, y, width, height, argb);
|
||||||
OsdShown = 1;
|
OsdShown = 1;
|
||||||
|
|
||||||
@ -9163,38 +9300,6 @@ void VideoOsdInit(void)
|
|||||||
OsdHeight = VideoWindowHeight;
|
OsdHeight = VideoWindowHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_GLX
|
|
||||||
// FIXME: make an extra function for this
|
|
||||||
if (GlxEnabled) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
Debug(3, "video/glx: %p <-> %p\n", glXGetCurrentContext(), GlxContext);
|
|
||||||
|
|
||||||
//
|
|
||||||
// create a RGBA texture.
|
|
||||||
//
|
|
||||||
glEnable(GL_TEXTURE_2D); // create 2d texture(s)
|
|
||||||
|
|
||||||
glGenTextures(2, OsdGlTextures);
|
|
||||||
for (i = 0; i < 2; ++i) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, OsdGlTextures[i]);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
|
||||||
GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
|
||||||
GL_CLAMP_TO_EDGE);
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, OsdWidth, OsdHeight, 0,
|
|
||||||
GL_BGRA, GL_UNSIGNED_BYTE, NULL);
|
|
||||||
}
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VideoThreadLock();
|
VideoThreadLock();
|
||||||
VideoUsedModule->OsdInit(OsdWidth, OsdHeight);
|
VideoUsedModule->OsdInit(OsdWidth, OsdHeight);
|
||||||
VideoThreadUnlock();
|
VideoThreadUnlock();
|
||||||
@ -9213,84 +9318,6 @@ void VideoOsdExit(void)
|
|||||||
OsdDirtyHeight = 0;
|
OsdDirtyHeight = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// Overlay
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Render osd surface.
|
|
||||||
///
|
|
||||||
void VideoRenderOverlay(void)
|
|
||||||
{
|
|
||||||
#ifdef USE_GLX
|
|
||||||
if (GlxEnabled) {
|
|
||||||
GlxRender(OsdWidth, OsdHeight);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Display overlay surface.
|
|
||||||
///
|
|
||||||
void VideoDisplayOverlay(void)
|
|
||||||
{
|
|
||||||
#ifdef USE_GLX
|
|
||||||
if (GlxEnabled) {
|
|
||||||
int osd_x1;
|
|
||||||
int osd_y1;
|
|
||||||
|
|
||||||
osd_x1 = 0;
|
|
||||||
osd_y1 = 0;
|
|
||||||
#ifdef noDEBUG
|
|
||||||
osd_x1 = 100;
|
|
||||||
osd_y1 = 100;
|
|
||||||
#endif
|
|
||||||
GlxRenderTexture(OsdGlTextures[OsdIndex], osd_x1, osd_y1,
|
|
||||||
VideoWindowWidth, VideoWindowHeight);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VAAPI
|
|
||||||
{
|
|
||||||
void *image_buffer;
|
|
||||||
static int counter;
|
|
||||||
|
|
||||||
// upload needs long time
|
|
||||||
if (counter == 5) {
|
|
||||||
//return;
|
|
||||||
}
|
|
||||||
// osd image available?
|
|
||||||
if (VaOsdImage.image_id == VA_INVALID_ID) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// FIXME: this version hangups
|
|
||||||
//return;
|
|
||||||
|
|
||||||
// map osd surface/image into memory.
|
|
||||||
if (vaMapBuffer(VaDisplay, VaOsdImage.buf,
|
|
||||||
&image_buffer) != VA_STATUS_SUCCESS) {
|
|
||||||
Error(_("video/vaapi: can't map osd image buffer\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 100% transparent
|
|
||||||
memset(image_buffer, 0x80 | counter++, VaOsdImage.data_size);
|
|
||||||
|
|
||||||
// convert internal osd to VA-API image
|
|
||||||
//GfxConvert(image_buffer, VaOsdImage.offsets[0], VaOsdImage.pitches[0]);
|
|
||||||
|
|
||||||
if (vaUnmapBuffer(VaDisplay, VaOsdImage.buf) != VA_STATUS_SUCCESS) {
|
|
||||||
Error(_("video/vaapi: can't unmap osd image buffer\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Events
|
// Events
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -9438,10 +9465,6 @@ void VideoPollEvent(void)
|
|||||||
|
|
||||||
#ifdef USE_VIDEO_THREAD
|
#ifdef USE_VIDEO_THREAD
|
||||||
|
|
||||||
#ifdef USE_GLX
|
|
||||||
static GLXContext GlxThreadContext; ///< our gl context for the thread
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Lock video thread.
|
/// Lock video thread.
|
||||||
///
|
///
|
||||||
@ -9475,20 +9498,21 @@ static void *VideoDisplayHandlerThread(void *dummy)
|
|||||||
|
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
if (GlxEnabled) {
|
if (GlxEnabled) {
|
||||||
Debug(3, "video: %p <-> %p\n", glXGetCurrentContext(),
|
Debug(3, "video/glx: thread context %p <-> %p\n",
|
||||||
GlxThreadContext);
|
glXGetCurrentContext(), GlxThreadContext);
|
||||||
|
Debug(3, "video/glx: context %p <-> %p\n", glXGetCurrentContext(),
|
||||||
|
GlxContext);
|
||||||
|
|
||||||
GlxThreadContext =
|
GlxThreadContext =
|
||||||
glXCreateContext(XlibDisplay, GlxVisualInfo, GlxContext, GL_TRUE);
|
glXCreateContext(XlibDisplay, GlxVisualInfo, GlxSharedContext,
|
||||||
|
GL_TRUE);
|
||||||
if (!GlxThreadContext) {
|
if (!GlxThreadContext) {
|
||||||
Error(_("video/glx: can't create glx context\n"));
|
Error(_("video/glx: can't create glx context\n"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// set glx context
|
// set glx context
|
||||||
if (!glXMakeCurrent(XlibDisplay, VideoWindow, GlxThreadContext)) {
|
GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight,
|
||||||
GlxCheck();
|
GlxThreadContext);
|
||||||
Error(_("video/glx: can't make glx context current\n"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -9511,6 +9535,9 @@ static void *VideoDisplayHandlerThread(void *dummy)
|
|||||||
///
|
///
|
||||||
static void VideoThreadInit(void)
|
static void VideoThreadInit(void)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_GLX
|
||||||
|
glXMakeCurrent(XlibDisplay, None, NULL);
|
||||||
|
#endif
|
||||||
pthread_mutex_init(&VideoMutex, NULL);
|
pthread_mutex_init(&VideoMutex, NULL);
|
||||||
pthread_mutex_init(&VideoLockMutex, NULL);
|
pthread_mutex_init(&VideoLockMutex, NULL);
|
||||||
pthread_cond_init(&VideoWakeupCond, NULL);
|
pthread_cond_init(&VideoWakeupCond, NULL);
|
||||||
@ -9568,7 +9595,7 @@ void VideoDisplayWakeup(void)
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Table of all audio modules.
|
/// Table of all video modules.
|
||||||
///
|
///
|
||||||
static const VideoModule *VideoModules[] = {
|
static const VideoModule *VideoModules[] = {
|
||||||
#ifdef USE_VDPAU
|
#ifdef USE_VDPAU
|
||||||
@ -9576,6 +9603,9 @@ static const VideoModule *VideoModules[] = {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_VAAPI
|
#ifdef USE_VAAPI
|
||||||
&VaapiModule,
|
&VaapiModule,
|
||||||
|
#endif
|
||||||
|
#ifdef USE_GLX
|
||||||
|
&VaapiGlxModule, // FIXME: if working, prefer this
|
||||||
#endif
|
#endif
|
||||||
&NoopModule
|
&NoopModule
|
||||||
};
|
};
|
||||||
@ -9712,6 +9742,8 @@ void VideoRenderFrame(VideoHwDecoder * hw_decoder,
|
|||||||
///
|
///
|
||||||
/// Get VA-API ffmpeg context
|
/// Get VA-API ffmpeg context
|
||||||
///
|
///
|
||||||
|
/// FIXME: new ffmpeg supports vdpau hw context
|
||||||
|
///
|
||||||
/// @param hw_decoder video hardware decoder (must be VA-API)
|
/// @param hw_decoder video hardware decoder (must be VA-API)
|
||||||
///
|
///
|
||||||
struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder * hw_decoder)
|
struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder * hw_decoder)
|
||||||
@ -9720,6 +9752,11 @@ struct vaapi_context *VideoGetVaapiContext(VideoHwDecoder * hw_decoder)
|
|||||||
if (VideoUsedModule == &VaapiModule) {
|
if (VideoUsedModule == &VaapiModule) {
|
||||||
return hw_decoder->Vaapi.VaapiContext;
|
return hw_decoder->Vaapi.VaapiContext;
|
||||||
}
|
}
|
||||||
|
#ifdef USE_GLX
|
||||||
|
if (VideoUsedModule == &VaapiGlxModule) {
|
||||||
|
return hw_decoder->Vaapi.VaapiContext;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
(void)hw_decoder;
|
(void)hw_decoder;
|
||||||
Error(_("video/vaapi: get vaapi context, without vaapi enabled\n"));
|
Error(_("video/vaapi: get vaapi context, without vaapi enabled\n"));
|
||||||
@ -10864,7 +10901,12 @@ void VideoInit(const char *display_name)
|
|||||||
// FIXME: we need to retry connection
|
// FIXME: we need to retry connection
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//XInitThreads();
|
#ifdef USE_GLX_doesn_t_help_still_crash
|
||||||
|
if (!XInitThreads()) {
|
||||||
|
Error(_("video: Can't initialize X11 thread support on '%s'\n"),
|
||||||
|
display_name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// Register error handler
|
// Register error handler
|
||||||
XSetIOErrorHandler(VideoIOErrorHandler);
|
XSetIOErrorHandler(VideoIOErrorHandler);
|
||||||
|
|
||||||
@ -10912,13 +10954,15 @@ void VideoInit(const char *display_name)
|
|||||||
// prepare opengl
|
// prepare opengl
|
||||||
//
|
//
|
||||||
#ifdef USE_GLX
|
#ifdef USE_GLX
|
||||||
if (GlxEnabled) {
|
// FIXME: module selected below
|
||||||
|
if (0) {
|
||||||
|
|
||||||
GlxInit();
|
GlxInit();
|
||||||
// FIXME: use root window?
|
// FIXME: use root window?
|
||||||
VideoCreateWindow(screen->root, GlxVisualInfo->visualid,
|
VideoCreateWindow(screen->root, GlxVisualInfo->visualid,
|
||||||
GlxVisualInfo->depth);
|
GlxVisualInfo->depth);
|
||||||
GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight);
|
GlxSetupWindow(VideoWindow, VideoWindowWidth, VideoWindowHeight,
|
||||||
|
GlxContext);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -11177,16 +11221,6 @@ int main(int argc, char *const argv[])
|
|||||||
start_tick = GetMsTicks();
|
start_tick = GetMsTicks();
|
||||||
n = 0;
|
n = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if 0
|
|
||||||
VideoRenderOverlay();
|
|
||||||
VideoDisplayOverlay();
|
|
||||||
glXSwapBuffers(XlibDisplay, VideoWindow);
|
|
||||||
GlxCheck();
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
XSync(XlibDisplay, False);
|
|
||||||
XFlush(XlibDisplay);
|
|
||||||
#endif
|
|
||||||
#ifdef USE_VAAPI
|
#ifdef USE_VAAPI
|
||||||
if (VideoVaapiEnabled) {
|
if (VideoVaapiEnabled) {
|
||||||
VaapiDisplayFrame();
|
VaapiDisplayFrame();
|
||||||
|
Loading…
Reference in New Issue
Block a user