mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-26 23:13:16 +02:00
sync
This commit is contained in:
@@ -19,9 +19,7 @@
|
|||||||
based on Carjay's neutrino-hd-dvbapi work, see
|
based on Carjay's neutrino-hd-dvbapi work, see
|
||||||
http://gitorious.org/neutrino-hd/neutrino-hd-dvbapi
|
http://gitorious.org/neutrino-hd/neutrino-hd-dvbapi
|
||||||
|
|
||||||
TODO: AV-Sync code is not existent yet
|
TODO: AV-Sync code is "experimental" at best
|
||||||
cleanup carjay's crazy 3D stuff :-)
|
|
||||||
video mode setting (4:3, 16:9, panscan...)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -60,9 +58,19 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn
|
|||||||
{
|
{
|
||||||
mState.width = x;
|
mState.width = x;
|
||||||
mState.height = y;
|
mState.height = y;
|
||||||
mX = y * 16 / 9; /* hard coded 16:9 initial aspect ratio for now */
|
mX = &_mX[0];
|
||||||
mY = y;
|
mY = &_mY[0];
|
||||||
mVA = 1.0;
|
*mX = x;
|
||||||
|
*mY = y;
|
||||||
|
av_reduce(&mOA.num, &mOA.den, x, y, INT_MAX);
|
||||||
|
mVA = mOA; /* initial aspect ratios are from the FB resolution, those */
|
||||||
|
_mVA = mVA; /* will be updated by the videoDecoder functions anyway */
|
||||||
|
mVAchanged = true;
|
||||||
|
mCrop = DISPLAY_AR_MODE_PANSCAN;
|
||||||
|
zoom = 1.0;
|
||||||
|
xscale = 1.0;
|
||||||
|
const char *tmp = getenv("GLFB_FULLSCREEN");
|
||||||
|
mFullscreen = !!(tmp);
|
||||||
|
|
||||||
mState.blit = true;
|
mState.blit = true;
|
||||||
last_apts = 0;
|
last_apts = 0;
|
||||||
@@ -118,6 +126,7 @@ void GLFramebuffer::initKeys()
|
|||||||
|
|
||||||
mKeyMap[0x0d] = KEY_OK;
|
mKeyMap[0x0d] = KEY_OK;
|
||||||
mKeyMap[0x1b] = KEY_EXIT;
|
mKeyMap[0x1b] = KEY_EXIT;
|
||||||
|
mKeyMap['e'] = KEY_EPG;
|
||||||
mKeyMap['i'] = KEY_INFO;
|
mKeyMap['i'] = KEY_INFO;
|
||||||
mKeyMap['m'] = KEY_MENU;
|
mKeyMap['m'] = KEY_MENU;
|
||||||
|
|
||||||
@@ -159,9 +168,11 @@ void GLFramebuffer::run()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
gThiz = this;
|
gThiz = this;
|
||||||
|
glutSetCursor(GLUT_CURSOR_NONE);
|
||||||
glutDisplayFunc(GLFramebuffer::rendercb);
|
glutDisplayFunc(GLFramebuffer::rendercb);
|
||||||
glutKeyboardFunc(GLFramebuffer::keyboardcb);
|
glutKeyboardFunc(GLFramebuffer::keyboardcb);
|
||||||
glutSpecialFunc(GLFramebuffer::specialcb);
|
glutSpecialFunc(GLFramebuffer::specialcb);
|
||||||
|
glutReshapeFunc(GLFramebuffer::resizecb);
|
||||||
setupGLObjects(); /* needs GLEW prototypes */
|
setupGLObjects(); /* needs GLEW prototypes */
|
||||||
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
|
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
|
||||||
glutMainLoop();
|
glutMainLoop();
|
||||||
@@ -181,7 +192,7 @@ void GLFramebuffer::setupCtx()
|
|||||||
char const *argv[2] = { "neutrino", 0 };
|
char const *argv[2] = { "neutrino", 0 };
|
||||||
lt_info("GLFB: GL thread starting\n");
|
lt_info("GLFB: GL thread starting\n");
|
||||||
glutInit(&argc, const_cast<char **>(argv));
|
glutInit(&argc, const_cast<char **>(argv));
|
||||||
glutInitWindowSize(mX, mY);
|
glutInitWindowSize(mX[0], mY[0]);
|
||||||
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
|
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
|
||||||
glutCreateWindow("Neutrino");
|
glutCreateWindow("Neutrino");
|
||||||
}
|
}
|
||||||
@@ -247,6 +258,13 @@ void GLFramebuffer::releaseGLObjects()
|
|||||||
{
|
{
|
||||||
lt_debug_c("GLFB::%s: 0x%x\n", __func__, key);
|
lt_debug_c("GLFB::%s: 0x%x\n", __func__, key);
|
||||||
struct input_event ev;
|
struct input_event ev;
|
||||||
|
if (key == 'f')
|
||||||
|
{
|
||||||
|
lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, gThiz->mFullscreen?"off":"on");
|
||||||
|
gThiz->mFullscreen = !(gThiz->mFullscreen);
|
||||||
|
gThiz->mReInit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::map<unsigned char, int>::const_iterator i = gThiz->mKeyMap.find(key);
|
std::map<unsigned char, int>::const_iterator i = gThiz->mKeyMap.find(key);
|
||||||
if (i == gThiz->mKeyMap.end())
|
if (i == gThiz->mKeyMap.end())
|
||||||
return;
|
return;
|
||||||
@@ -281,34 +299,44 @@ int sleep_us = 30000;
|
|||||||
|
|
||||||
void GLFramebuffer::render()
|
void GLFramebuffer::render()
|
||||||
{
|
{
|
||||||
if (!mReInit) /* for example if window is resized */
|
|
||||||
checkReinit();
|
|
||||||
|
|
||||||
if(mShutDown)
|
if(mShutDown)
|
||||||
glutLeaveMainLoop();
|
glutLeaveMainLoop();
|
||||||
|
|
||||||
|
mReInitLock.lock();
|
||||||
if (mReInit)
|
if (mReInit)
|
||||||
{
|
{
|
||||||
|
int xoff = 0;
|
||||||
|
int yoff = 0;
|
||||||
|
mVAchanged = true;
|
||||||
mReInit = false;
|
mReInit = false;
|
||||||
glViewport(0, 0, mX, mY);
|
mX = &_mX[mFullscreen];
|
||||||
glutReshapeWindow(mX, mY);
|
mY = &_mY[mFullscreen];
|
||||||
|
if (mFullscreen) {
|
||||||
|
int x = glutGet(GLUT_SCREEN_WIDTH);
|
||||||
|
int y = glutGet(GLUT_SCREEN_HEIGHT);
|
||||||
|
*mX = x;
|
||||||
|
*mY = y;
|
||||||
|
AVRational a = { x, y };
|
||||||
|
if (av_cmp_q(a, mOA) < 0)
|
||||||
|
*mY = x * mOA.den / mOA.num;
|
||||||
|
else if (av_cmp_q(a, mOA) > 0)
|
||||||
|
*mX = y * mOA.num / mOA.den;
|
||||||
|
xoff = (x - *mX) / 2;
|
||||||
|
yoff = (y - *mY) / 2;
|
||||||
|
glutFullScreen();
|
||||||
|
} else
|
||||||
|
*mX = *mY * mOA.num / mOA.den;
|
||||||
|
lt_info("%s: reinit mX:%d mY:%d xoff:%d yoff:%d fs %d\n",
|
||||||
|
__func__, *mX, *mY, xoff, yoff, mFullscreen);
|
||||||
|
glViewport(xoff, yoff, *mX, *mY);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
float aspect = static_cast<float>(mX)/mY;
|
float aspect = static_cast<float>(*mX)/ *mY;
|
||||||
float osdaspect = 1.0/(static_cast<float>(16.0)/9);
|
float osdaspect = static_cast<float>(mOA.den) / mOA.num;
|
||||||
// if(!mState.go3d)
|
|
||||||
{
|
glOrtho(aspect*-osdaspect, aspect*osdaspect, -1.0, 1.0, -1.0, 1.0 );
|
||||||
glOrtho(aspect*-osdaspect, aspect*osdaspect, -1.0, 1.0, -1.0, 1.0 );
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
else
|
|
||||||
{ /* carjay is crazy... :-) */
|
|
||||||
gluPerspective(45.0, static_cast<float>(mX)/mY, 0.05, 1000.0);
|
|
||||||
glTranslatef(0.0, 0.0, -2.0);
|
|
||||||
glClearColor(0.25, 0.25, 0.25, 1.0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
@@ -316,6 +344,9 @@ void GLFramebuffer::render()
|
|||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
}
|
}
|
||||||
|
mReInitLock.unlock();
|
||||||
|
if (!mFullscreen && (*mX != glutGet(GLUT_WINDOW_WIDTH) || *mY != glutGet(GLUT_WINDOW_HEIGHT)))
|
||||||
|
glutReshapeWindow(*mX, *mY);
|
||||||
|
|
||||||
bltDisplayBuffer(); /* decoded video stream */
|
bltDisplayBuffer(); /* decoded video stream */
|
||||||
if (mState.blit) {
|
if (mState.blit) {
|
||||||
@@ -327,30 +358,61 @@ void GLFramebuffer::render()
|
|||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, mState.osdtex);
|
glBindTexture(GL_TEXTURE_2D, mState.osdtex);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
#if 0
|
|
||||||
// cube test
|
if (mVAchanged)
|
||||||
if(mState.go3d)
|
|
||||||
{
|
{
|
||||||
glEnable(GL_DEPTH_TEST);
|
mVAchanged = false;
|
||||||
static float ydeg = 0.0;
|
zoom = 1.0;
|
||||||
glPushMatrix();
|
xscale = 1.0;
|
||||||
glRotatef(ydeg, 0.0, 1.0, 0.0);
|
int cmp = (mCrop == DISPLAY_AR_MODE_NONE) ? 0 : av_cmp_q(mVA, mOA);
|
||||||
glBindTexture(GL_TEXTURE_2D, mState.displaytex);
|
const AVRational a149 = { 14, 9 };
|
||||||
drawCube(0.5);
|
switch (cmp) {
|
||||||
glScalef(1.01, 1.01, 1.01);
|
default:
|
||||||
glBindTexture(GL_TEXTURE_2D, mState.osdtex);
|
case INT_MIN: /* invalid */
|
||||||
drawCube(0.5);
|
case 0: /* identical */
|
||||||
glPopMatrix();
|
lt_debug("%s: mVA == mOA (or fullscreen mode :-)\n", __func__);
|
||||||
ydeg += 0.75f;
|
break;
|
||||||
}
|
case 1: /* mVA > mOA -- video is wider than display */
|
||||||
else
|
lt_debug("%s: mVA > mOA\n", __func__);
|
||||||
#endif
|
xscale = av_q2d(mVA) / av_q2d(mOA);
|
||||||
{
|
switch (mCrop) {
|
||||||
glBindTexture(GL_TEXTURE_2D, mState.displaytex);
|
case DISPLAY_AR_MODE_PANSCAN:
|
||||||
drawSquare(1.0, mVA / (16.0/9));
|
break;
|
||||||
glBindTexture(GL_TEXTURE_2D, mState.osdtex);
|
case DISPLAY_AR_MODE_LETTERBOX:
|
||||||
drawSquare(1.0);
|
zoom = av_q2d(mOA) / av_q2d(mVA);
|
||||||
|
break;
|
||||||
|
case DISPLAY_AR_MODE_PANSCAN2:
|
||||||
|
zoom = av_q2d(mOA) / av_q2d(a149);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case -1: /* mVA < mOA -- video is taller than display */
|
||||||
|
lt_debug("%s: mVA < mOA\n", __func__);
|
||||||
|
xscale = av_q2d(mVA) / av_q2d(mOA);
|
||||||
|
switch (mCrop) {
|
||||||
|
case DISPLAY_AR_MODE_LETTERBOX:
|
||||||
|
break;
|
||||||
|
case DISPLAY_AR_MODE_PANSCAN2:
|
||||||
|
if (av_cmp_q(a149, mOA) < 0) {
|
||||||
|
zoom = av_q2d(mVA) * av_q2d(a149) / av_q2d(mOA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fallthrough for output format 14:9 */
|
||||||
|
case DISPLAY_AR_MODE_PANSCAN:
|
||||||
|
zoom = av_q2d(mOA) / av_q2d(mVA);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mState.displaytex);
|
||||||
|
drawSquare(zoom, xscale);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, mState.osdtex);
|
||||||
|
drawSquare(1.0);
|
||||||
|
|
||||||
glFlush();
|
glFlush();
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
@@ -363,71 +425,31 @@ void GLFramebuffer::render()
|
|||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ void GLFramebuffer::resizecb(int w, int h)
|
||||||
void GLFramebuffer::checkReinit()
|
|
||||||
{
|
{
|
||||||
int x = glutGet(GLUT_WINDOW_WIDTH);
|
gThiz->checkReinit(w, h);
|
||||||
int y = glutGet(GLUT_WINDOW_HEIGHT);
|
}
|
||||||
if ( x != mX || y != mY )
|
|
||||||
{
|
void GLFramebuffer::checkReinit(int x, int y)
|
||||||
mX = x;
|
{
|
||||||
mY = y;
|
static int last_x = 0, last_y = 0;
|
||||||
/* fix aspect ratio */
|
|
||||||
if (x < mY * 16 / 9)
|
mReInitLock.lock();
|
||||||
mX = mY * 16 / 9;
|
if (!mFullscreen && !mReInit && (x != *mX || y != *mY)) {
|
||||||
else
|
if (x != *mX && abs(x - last_x) > 2) {
|
||||||
mY = mX * 9 / 16;
|
*mX = x;
|
||||||
|
*mY = *mX * mOA.den / mOA.num;
|
||||||
|
} else if (y != *mY && abs(y - last_y) > 2) {
|
||||||
|
*mY = y;
|
||||||
|
*mX = *mY * mOA.num / mOA.den;
|
||||||
|
}
|
||||||
mReInit = true;
|
mReInit = true;
|
||||||
}
|
}
|
||||||
|
mReInitLock.unlock();
|
||||||
|
last_x = x;
|
||||||
|
last_y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void GLFramebuffer::drawCube(float size)
|
|
||||||
{
|
|
||||||
GLfloat vertices[] = {
|
|
||||||
1.0f, 1.0f, 1.0f,
|
|
||||||
-1.0f, 1.0f, 1.0f,
|
|
||||||
-1.0f, -1.0f, 1.0f,
|
|
||||||
1.0f, -1.0f, 1.0f,
|
|
||||||
1.0f, -1.0f, -1.0f,
|
|
||||||
1.0f, 1.0f, -1.0f,
|
|
||||||
-1.0f, 1.0f, -1.0f,
|
|
||||||
-1.0f, -1.0f, -1.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
GLubyte indices[] = {
|
|
||||||
0, 1, 2, 3, /* front */
|
|
||||||
0, 3, 4, 5, /* right */
|
|
||||||
0, 5, 6, 1, /* top */
|
|
||||||
1, 6, 7, 2, /* left */
|
|
||||||
7, 4, 3, 2, /* bottom */
|
|
||||||
4, 7, 6, 5 /* back */
|
|
||||||
};
|
|
||||||
|
|
||||||
GLfloat texcoords[] = {
|
|
||||||
1.0, 0.0, // v0
|
|
||||||
0.0, 0.0, // v1
|
|
||||||
0.0, 1.0, // v2
|
|
||||||
1.0, 1.0, // v3
|
|
||||||
0.0, 1.0, // v4
|
|
||||||
0.0, 0.0, // v5
|
|
||||||
1.0, 0.0, // v6
|
|
||||||
1.0, 1.0 // v7
|
|
||||||
};
|
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
glScalef(size, size, size);
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glVertexPointer(3, GL_FLOAT, 0, vertices);
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
|
|
||||||
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, indices);
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void GLFramebuffer::drawSquare(float size, float x_factor)
|
void GLFramebuffer::drawSquare(float size, float x_factor)
|
||||||
{
|
{
|
||||||
GLfloat vertices[] = {
|
GLfloat vertices[] = {
|
||||||
@@ -489,8 +511,12 @@ void GLFramebuffer::bltDisplayBuffer()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
AVRational a = buf->AR();
|
AVRational a = buf->AR();
|
||||||
if (a.den != 0)
|
if (a.den != 0 && a.num != 0 && av_cmp_q(a, _mVA)) {
|
||||||
mVA = static_cast<float>(w * a.num) / h / a.den;
|
_mVA = a;
|
||||||
|
/* _mVA is the raw buffer's aspect, mVA is the real scaled output aspect */
|
||||||
|
av_reduce(&mVA.num, &mVA.den, w * a.num, h * a.den, INT_MAX);
|
||||||
|
mVAchanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mState.displaypbo);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mState.displaypbo);
|
||||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, buf->size(), &(*buf)[0], GL_STREAM_DRAW_ARB);
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, buf->size(), &(*buf)[0], GL_STREAM_DRAW_ARB);
|
||||||
|
@@ -19,12 +19,16 @@
|
|||||||
#ifndef __glthread__
|
#ifndef __glthread__
|
||||||
#define __glthread__
|
#define __glthread__
|
||||||
#include <OpenThreads/Thread>
|
#include <OpenThreads/Thread>
|
||||||
|
#include <OpenThreads/Mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GL/freeglut.h>
|
#include <GL/freeglut.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <linux/fb.h> /* for screeninfo etc. */
|
#include <linux/fb.h> /* for screeninfo etc. */
|
||||||
|
extern "C" {
|
||||||
|
#include <libavutil/rational.h>
|
||||||
|
}
|
||||||
|
|
||||||
class GLFramebuffer : public OpenThreads::Thread
|
class GLFramebuffer : public OpenThreads::Thread
|
||||||
{
|
{
|
||||||
@@ -39,16 +43,28 @@ public:
|
|||||||
int getOSDHeight() { return mState.height; }
|
int getOSDHeight() { return mState.height; }
|
||||||
void blit() { mState.blit = true; }
|
void blit() { mState.blit = true; }
|
||||||
|
|
||||||
|
void setOutputFormat(AVRational a, int h, int c) { mOA = a; *mY = h; mCrop = c; mReInit = true; }
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
fb_var_screeninfo getScreenInfo() { return screeninfo; }
|
fb_var_screeninfo getScreenInfo() { return screeninfo; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
fb_var_screeninfo screeninfo;
|
fb_var_screeninfo screeninfo;
|
||||||
int mX; /* window size */
|
int *mX;
|
||||||
int mY;
|
int *mY;
|
||||||
float mVA; /* video aspect ratio */;
|
int _mX[2]; /* output window size */
|
||||||
|
int _mY[2]; /* [0] = normal, [1] = fullscreen */
|
||||||
|
AVRational mOA; /* output window aspect ratio */
|
||||||
|
AVRational mVA; /* video aspect ratio */
|
||||||
|
AVRational _mVA; /* for detecting changes in mVA */
|
||||||
|
bool mVAchanged;
|
||||||
|
float zoom; /* for cropping */
|
||||||
|
float xscale; /* and aspect ratio */
|
||||||
|
int mCrop; /* DISPLAY_AR_MODE */
|
||||||
|
|
||||||
|
bool mFullscreen; /* fullscreen? */
|
||||||
bool mReInit; /* setup things for GL */
|
bool mReInit; /* setup things for GL */
|
||||||
|
OpenThreads::Mutex mReInitLock;
|
||||||
bool mShutDown; /* if set main loop is left */
|
bool mShutDown; /* if set main loop is left */
|
||||||
bool mInitDone; /* condition predicate */
|
bool mInitDone; /* condition predicate */
|
||||||
// OpenThreads::Condition mInitCond; /* condition variable for init */
|
// OpenThreads::Condition mInitCond; /* condition variable for init */
|
||||||
@@ -61,18 +77,18 @@ private:
|
|||||||
int input_fd;
|
int input_fd;
|
||||||
int64_t last_apts;
|
int64_t last_apts;
|
||||||
|
|
||||||
void checkReinit(); /* e.g. in case window was resized */
|
|
||||||
static void rendercb(); /* callback for GLUT */
|
static void rendercb(); /* callback for GLUT */
|
||||||
void render(); /* actual render function */
|
void render(); /* actual render function */
|
||||||
static void keyboardcb(unsigned char key, int x, int y);
|
static void keyboardcb(unsigned char key, int x, int y);
|
||||||
static void specialcb(int key, int x, int y);
|
static void specialcb(int key, int x, int y);
|
||||||
|
static void resizecb(int w, int h);
|
||||||
|
void checkReinit(int w, int h); /* e.g. in case window was resized */
|
||||||
|
|
||||||
void initKeys(); /* setup key bindings for window */
|
void initKeys(); /* setup key bindings for window */
|
||||||
void setupCtx(); /* create the window and make the context current */
|
void setupCtx(); /* create the window and make the context current */
|
||||||
void setupOSDBuffer(); /* create the OSD buffer */
|
void setupOSDBuffer(); /* create the OSD buffer */
|
||||||
void setupGLObjects(); /* PBOs, textures and stuff */
|
void setupGLObjects(); /* PBOs, textures and stuff */
|
||||||
void releaseGLObjects();
|
void releaseGLObjects();
|
||||||
// void drawCube(float size); /* cubes are the building blocks of our society */
|
|
||||||
void drawSquare(float size, float x_factor = 1); /* do not be square */
|
void drawSquare(float size, float x_factor = 1); /* do not be square */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -82,7 +98,6 @@ private:
|
|||||||
GLuint pbo; /* PBO we use for transfer to texture */
|
GLuint pbo; /* PBO we use for transfer to texture */
|
||||||
GLuint displaytex; /* holds the display texture */
|
GLuint displaytex; /* holds the display texture */
|
||||||
GLuint displaypbo;
|
GLuint displaypbo;
|
||||||
//int go3d;
|
|
||||||
bool blit;
|
bool blit;
|
||||||
} mState;
|
} mState;
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
#include <cstring>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "init_lib.h"
|
#include "init_lib.h"
|
||||||
@@ -14,8 +15,26 @@ void init_td_api()
|
|||||||
if (!initialized)
|
if (!initialized)
|
||||||
lt_debug_init();
|
lt_debug_init();
|
||||||
lt_info("%s begin, initialized=%d, debug=0x%02x\n", __func__, (int)initialized, debuglevel);
|
lt_info("%s begin, initialized=%d, debug=0x%02x\n", __func__, (int)initialized, debuglevel);
|
||||||
if (! glfb)
|
if (! glfb) {
|
||||||
glfb = new GLFramebuffer(720, 576); /* hard coded to PAL resolution for now */
|
int x = 1280, y = 720; /* default OSD FB resolution */
|
||||||
|
/*
|
||||||
|
* export GLFB_RESOLUTION=720,576
|
||||||
|
* to restore old default behviour
|
||||||
|
*/
|
||||||
|
const char *tmp = getenv("GLFB_RESOLUTION");
|
||||||
|
const char *p = NULL;
|
||||||
|
if (tmp)
|
||||||
|
p = strchr(tmp, ',');
|
||||||
|
if (p) {
|
||||||
|
x = atoi(tmp);
|
||||||
|
y = atoi(p + 1);
|
||||||
|
}
|
||||||
|
lt_info("%s: setting GL Framebuffer size to %dx%d\n", __func__, x, y);
|
||||||
|
if (!p)
|
||||||
|
lt_info("%s: export GLFB_RESOLUTION=\"<w>,<h>\" to set another resolution\n", __func__);
|
||||||
|
|
||||||
|
glfb = new GLFramebuffer(x, y); /* hard coded to PAL resolution for now */
|
||||||
|
}
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -40,17 +40,28 @@ extern "C" {
|
|||||||
|
|
||||||
#include "video_lib.h"
|
#include "video_lib.h"
|
||||||
#include "dmx_lib.h"
|
#include "dmx_lib.h"
|
||||||
|
#include "glfb.h"
|
||||||
#include "lt_debug.h"
|
#include "lt_debug.h"
|
||||||
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args)
|
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args)
|
||||||
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_VIDEO, this, args)
|
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_VIDEO, this, args)
|
||||||
|
|
||||||
cVideo *videoDecoder = NULL;
|
cVideo *videoDecoder = NULL;
|
||||||
extern cDemux *videoDemux;
|
extern cDemux *videoDemux;
|
||||||
|
extern GLFramebuffer *glfb;
|
||||||
int system_rev = 0;
|
int system_rev = 0;
|
||||||
|
|
||||||
static uint8_t *dmxbuf;
|
static uint8_t *dmxbuf;
|
||||||
static int bufpos;
|
static int bufpos;
|
||||||
|
|
||||||
|
static const AVRational aspect_ratios[6] = {
|
||||||
|
{ 1, 1 },
|
||||||
|
{ 4, 3 },
|
||||||
|
{ 14, 9 },
|
||||||
|
{ 16, 9 },
|
||||||
|
{ 20, 9 },
|
||||||
|
{ -1,-1 }
|
||||||
|
};
|
||||||
|
|
||||||
cVideo::cVideo(int, void *, void *)
|
cVideo::cVideo(int, void *, void *)
|
||||||
{
|
{
|
||||||
lt_debug("%s\n", __func__);
|
lt_debug("%s\n", __func__);
|
||||||
@@ -63,6 +74,8 @@ cVideo::cVideo(int, void *, void *)
|
|||||||
buf_num = 0;
|
buf_num = 0;
|
||||||
buf_in = 0;
|
buf_in = 0;
|
||||||
buf_out = 0;
|
buf_out = 0;
|
||||||
|
display_aspect = DISPLAY_AR_16_9;
|
||||||
|
display_crop = DISPLAY_AR_MODE_LETTERBOX;
|
||||||
v_format = VIDEO_FORMAT_MPEG2;
|
v_format = VIDEO_FORMAT_MPEG2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,8 +86,15 @@ cVideo::~cVideo(void)
|
|||||||
videoDecoder = NULL;
|
videoDecoder = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cVideo::setAspectRatio(int, int)
|
int cVideo::setAspectRatio(int vformat, int cropping)
|
||||||
{
|
{
|
||||||
|
lt_info("%s(%d, %d)\n", __func__, vformat, cropping);
|
||||||
|
if (vformat >= 0)
|
||||||
|
display_aspect = (DISPLAY_AR) vformat;
|
||||||
|
if (cropping >= 0)
|
||||||
|
display_crop = (DISPLAY_AR_MODE) cropping;
|
||||||
|
if (display_aspect < DISPLAY_AR_RAW) /* don't know what to do with this */
|
||||||
|
glfb->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,8 +157,43 @@ int cVideo::setBlank(int)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cVideo::SetVideoSystem(int, bool)
|
int cVideo::SetVideoSystem(int system, bool)
|
||||||
{
|
{
|
||||||
|
int h;
|
||||||
|
switch(system)
|
||||||
|
{
|
||||||
|
case VIDEO_STD_NTSC:
|
||||||
|
case VIDEO_STD_480P:
|
||||||
|
h = 480;
|
||||||
|
break;
|
||||||
|
case VIDEO_STD_1080I60:
|
||||||
|
case VIDEO_STD_1080I50:
|
||||||
|
case VIDEO_STD_1080P30:
|
||||||
|
case VIDEO_STD_1080P24:
|
||||||
|
case VIDEO_STD_1080P25:
|
||||||
|
case VIDEO_STD_1080P50:
|
||||||
|
h = 1080;
|
||||||
|
break;
|
||||||
|
case VIDEO_STD_720P50:
|
||||||
|
case VIDEO_STD_720P60:
|
||||||
|
h = 720;
|
||||||
|
break;
|
||||||
|
case VIDEO_STD_AUTO:
|
||||||
|
lt_info("%s: VIDEO_STD_AUTO not implemented\n", __func__);
|
||||||
|
// fallthrough
|
||||||
|
case VIDEO_STD_SECAM:
|
||||||
|
case VIDEO_STD_PAL:
|
||||||
|
case VIDEO_STD_576P:
|
||||||
|
h = 576;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
lt_info("%s: unhandled value %d\n", __func__, system);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
v_std = (VIDEO_STD) system;
|
||||||
|
output_h = h;
|
||||||
|
if (display_aspect < DISPLAY_AR_RAW) /* don't know what to do with this */
|
||||||
|
glfb->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,7 +389,6 @@ void cVideo::run(void)
|
|||||||
sws_scale(convert, frame->data, frame->linesize, 0, c->height,
|
sws_scale(convert, frame->data, frame->linesize, 0, c->height,
|
||||||
rgbframe->data, rgbframe->linesize);
|
rgbframe->data, rgbframe->linesize);
|
||||||
sws_freeContext(convert);
|
sws_freeContext(convert);
|
||||||
// TODO: locking needed!
|
|
||||||
if (dec_w != c->width || dec_h != c->height) {
|
if (dec_w != c->width || dec_h != c->height) {
|
||||||
lt_info("%s: pic changed %dx%d -> %dx%d\n", __func__,
|
lt_info("%s: pic changed %dx%d -> %dx%d\n", __func__,
|
||||||
dec_w, dec_h, c->width, c->height);
|
dec_w, dec_h, c->width, c->height);
|
||||||
|
@@ -6,7 +6,9 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <linux/dvb/video.h>
|
#include <linux/dvb/video.h>
|
||||||
#include "../common/cs_types.h"
|
#include "../common/cs_types.h"
|
||||||
|
extern "C" {
|
||||||
#include <libavutil/rational.h>
|
#include <libavutil/rational.h>
|
||||||
|
}
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ANALOG_SD_RGB_CINCH = 0x00,
|
ANALOG_SD_RGB_CINCH = 0x00,
|
||||||
@@ -197,7 +199,11 @@ class cVideo : public OpenThreads::Thread
|
|||||||
bool w_h_changed;
|
bool w_h_changed;
|
||||||
bool thread_running;
|
bool thread_running;
|
||||||
VIDEO_FORMAT v_format;
|
VIDEO_FORMAT v_format;
|
||||||
|
VIDEO_STD v_std;
|
||||||
OpenThreads::Mutex buf_m;
|
OpenThreads::Mutex buf_m;
|
||||||
|
DISPLAY_AR display_aspect;
|
||||||
|
DISPLAY_AR_MODE display_crop;
|
||||||
|
int output_h;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -199,7 +199,6 @@ void cRecord::RecordThread()
|
|||||||
#define BUFSIZE (1 << 20) /* 1MB */
|
#define BUFSIZE (1 << 20) /* 1MB */
|
||||||
#define READSIZE (BUFSIZE / 16)
|
#define READSIZE (BUFSIZE / 16)
|
||||||
#endif
|
#endif
|
||||||
ssize_t r = 0;
|
|
||||||
int buf_pos = 0;
|
int buf_pos = 0;
|
||||||
int queued = 0;
|
int queued = 0;
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
@@ -235,6 +234,7 @@ void cRecord::RecordThread()
|
|||||||
int overflow_count = 0;
|
int overflow_count = 0;
|
||||||
#endif
|
#endif
|
||||||
bool overflow = false;
|
bool overflow = false;
|
||||||
|
int r = 0;
|
||||||
while (exit_flag == RECORD_RUNNING)
|
while (exit_flag == RECORD_RUNNING)
|
||||||
{
|
{
|
||||||
#ifdef MARTII
|
#ifdef MARTII
|
||||||
@@ -251,18 +251,18 @@ void cRecord::RecordThread()
|
|||||||
int toread = bufsize - buf_pos;
|
int toread = bufsize - buf_pos;
|
||||||
if (toread > readsize)
|
if (toread > readsize)
|
||||||
toread = readsize;
|
toread = readsize;
|
||||||
r = dmx->Read(buf + buf_pos, toread, 50);
|
ssize_t s = dmx->Read(buf + buf_pos, toread, 50);
|
||||||
lt_debug("%s: buf_pos %6d r %6d / %6d\n", __func__,
|
lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__,
|
||||||
buf_pos, (int)r, bufsize - buf_pos);
|
buf_pos, (int)s, bufsize - buf_pos);
|
||||||
#else
|
#else
|
||||||
int toread = BUFSIZE - buf_pos;
|
int toread = BUFSIZE - buf_pos;
|
||||||
if (toread > READSIZE)
|
if (toread > READSIZE)
|
||||||
toread = READSIZE;
|
toread = READSIZE;
|
||||||
r = dmx->Read(buf + buf_pos, toread, 50);
|
ssize_t s = dmx->Read(buf + buf_pos, toread, 50);
|
||||||
lt_debug("%s: buf_pos %6d r %6d / %6d\n", __func__,
|
lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__,
|
||||||
buf_pos, (int)r, BUFSIZE - buf_pos);
|
buf_pos, (int)s, BUFSIZE - buf_pos);
|
||||||
#endif
|
#endif
|
||||||
if (r < 0)
|
if (s < 0)
|
||||||
{
|
{
|
||||||
if (errno != EAGAIN && (errno != EOVERFLOW || !overflow))
|
if (errno != EAGAIN && (errno != EOVERFLOW || !overflow))
|
||||||
{
|
{
|
||||||
@@ -277,7 +277,7 @@ void cRecord::RecordThread()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
overflow = false;
|
overflow = false;
|
||||||
buf_pos += r;
|
buf_pos += s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user