Origin commit data
------------------
Branch: master
Commit: dddd094e2b
Author: TangoCash <eric@loxat.de>
Date: 2018-10-02 (Tue, 02 Oct 2018)


------------------
No further description and justification available within origin commit message!

------------------
This commit was generated by Migit
This commit is contained in:
TangoCash
2018-10-02 10:05:27 +02:00
56 changed files with 1192 additions and 672 deletions

View File

@@ -2,12 +2,11 @@ ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libstb-hal.la
libstb_hal_la_SOURCES =
SUBDIRS = common tools libthread
SUBDIRS = common tools
#bin_PROGRAMS = libstb-hal-test
libstb_hal_la_LIBADD = \
common/libcommon.la \
libthread/libthread.la
common/libcommon.la
#libstb_hal_test_SOURCES = libtest.cpp

View File

@@ -152,11 +152,11 @@ AC_SUBST(PLUGINDIR)
AC_SUBST(THEMESDIR)
dnl end workaround
AC_DEFUN([TUXBOX_BOXTYPE],[
AC_DEFUN([TUXBOX_BOXTYPE], [
AC_ARG_WITH(boxtype,
[ --with-boxtype valid values: tripledragon,spark,azbox,generic,duckbox,spark7162,armbox],
AS_HELP_STRING([--with-boxtype], [valid values: tripledragon, spark, azbox, generic, armbox, duckbox, spark7162]),
[case "${withval}" in
tripledragon|azbox|generic)
tripledragon|azbox|generic|armbox)
BOXTYPE="$withval"
;;
spark|spark7162)

View File

@@ -1652,6 +1652,13 @@ FROM_FIRST:
bool cCA::SendCaPMT(eDVBCISlot* slot)
{
printf("%s -> %s\n", FILENAME, __func__);
if (slot->fd > 0)
{
#if HAVE_ARM_HARDWARE
setInputSource(slot, true);
#endif
setSource(slot);
}
if ((slot->fd > 0) && (slot->camIsReady))
{
if (slot->hasCAManager)
@@ -1667,14 +1674,6 @@ bool cCA::SendCaPMT(eDVBCISlot* slot)
slot->camgrSession->sendSPDU(0x90, 0, 0, slot->pmtdata, slot->pmtlen);
}
}
if (slot->fd > 0)
{
#if HAVE_ARM_HARDWARE
setInputSource(slot, true);
#endif
setSource(slot);
}
return true;
}

View File

@@ -20,6 +20,18 @@ AC_DISABLE_STATIC
AC_SYS_LARGEFILE
AC_PROG_LIBTOOL
AC_ARG_ENABLE(clutter,
AS_HELP_STRING(--enable-clutter, use clutter instead of OpenGL),
,[enable_clutter=no])
AM_CONDITIONAL(USE_CLUTTER,test "$enable_clutter" = "yes")
AM_CONDITIONAL(USE_OPENGL,test "$enable_clutter" = "no")
if test "$enable_clutter" = "yes"; then
AC_DEFINE(USE_CLUTTER,1,[use clutter instead of opengl])
else
AC_DEFINE(USE_OPENGL,1,[use opengl instead of clutter])
fi
if test x"$BOXTYPE" = x"tripledragon"; then
PKG_CHECK_MODULES([DIRECTFB], [directfb])
fi
@@ -54,6 +66,9 @@ if test x$BOXTYPE = xarmbox -a "$enable_gstreamer_10" = "yes"; then
fi
if test x$BOXTYPE = xgeneric -a x$BOXMODEL != xraspi; then
if test x"$enable_clutter" = xyes; then
PKG_CHECK_MODULES([CLUTTER], [clutter-1.0])
fi
PKG_CHECK_MODULES([AVFORMAT], [libavformat >= 53.21.1])
PKG_CHECK_MODULES([AVCODEC], [libavcodec >= 54.28.0])
# don't know which version is exactly needed here...
@@ -62,12 +77,20 @@ if test x$BOXTYPE = xgeneric -a x$BOXMODEL != xraspi; then
PKG_CHECK_MODULES([SWRESAMPLE], [libswresample])
fi
AC_ARG_ENABLE(flv2mpeg4,
AS_HELP_STRING(--enable-flv2mpeg4, use flv2mpeg4 libeplayer3-arm),
,[enable_flv2mpeg4=no])
AM_CONDITIONAL(ENABLE_FLV2MPEG4, test "$enable_flv2mpeg4" = "yes")
if test "$enable_flv2mpeg4" = "yes"; then
AC_DEFINE(ENABLE_FLV2MPEG4, 1, [use flv2mpeg4 libeplayer3-arm])
fi
AC_OUTPUT([
Makefile
common/Makefile
libeplayer3/Makefile
libeplayer3-arm/Makefile
libthread/Makefile
azbox/Makefile
generic-pc/Makefile
libduckbox/Makefile

View File

@@ -1,29 +1,44 @@
noinst_LTLIBRARIES = libgeneric.la
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
AM_CPPFLAGS += -Wfatal-errors
AM_CPPFLAGS += \
-I$(top_srcdir)/common \
-I$(top_srcdir)/include
-I$(top_srcdir)/include \
@AVUTIL_CFLAGS@ \
@CLUTTER_CFLAGS@
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = \
-lglut -lGL -lGLU -lGLEW -lao \
-lao \
-lOpenThreads \
@AVFORMAT_LIBS@ \
@AVUTIL_LIBS@ \
@AVCODEC_LIBS@ \
@SWRESAMPLE_LIBS@ \
@SWSCALE_LIBS@
@SWSCALE_LIBS@ \
@CLUTTER_LIBS@
if USE_OPENGL
AM_LDFLAGS += -lglut -lGL -lGLU -lGLEW -lao
endif
libgeneric_la_SOURCES = \
hardware_caps.c \
dmx.cpp \
video.cpp \
audio.cpp \
glfb.cpp \
init.cpp \
record.cpp
if USE_CLUTTER
libgeneric_la_SOURCES += clutterfb.cpp
endif
if USE_OPENGL
libgeneric_la_SOURCES += glfb.cpp
endif
if ENABLE_GSTREAMER_01
libgeneric_la_SOURCES += \
playback_gst_01.cpp

View File

@@ -29,6 +29,7 @@
#define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args)
#define lt_info(args...) _lt_info(HAL_DEBUG_AUDIO, this, args)
#include <OpenThreads/Thread>
extern "C" {
#include <libavformat/avformat.h>
@@ -104,7 +105,7 @@ int cAudio::Start(void)
{
lt_debug("%s >\n", __func__);
if (! HAL_nodec)
Thread::startThread();
OpenThreads::Thread::start();
lt_debug("%s <\n", __func__);
return 0;
}
@@ -115,7 +116,7 @@ int cAudio::Stop(void)
if (thread_started)
{
thread_started = false;
Thread::joinThread();
OpenThreads::Thread::join();
}
lt_debug("%s <\n", __func__);
return 0;
@@ -201,8 +202,34 @@ void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &m
freq = 0;
bitrate = 0; /* not used, but easy to get :-) */
mode = 0; /* default: stereo */
printf("cAudio::getAudioInfo c %p\n", c);
if (c) {
type = (c->codec_id != AV_CODEC_ID_MP2); /* only mpeg / not mpeg is indicated */
switch (c->codec_id) {
case AV_CODEC_ID_MP2:
type = AUDIO_FMT_MPEG;
break;
case AV_CODEC_ID_MP3:
type = AUDIO_FMT_MP3;
break;
case AV_CODEC_ID_AC3:
case AV_CODEC_ID_TRUEHD:
type = AUDIO_FMT_DOLBY_DIGITAL;
break;
case AV_CODEC_ID_EAC3:
type = AUDIO_FMT_DD_PLUS;
break;
case AV_CODEC_ID_AAC:
type = AUDIO_FMT_AAC;
break;
case AV_CODEC_ID_DTS:
type = AUDIO_FMT_DTS;
break;
case AV_CODEC_ID_MLP:
type = AUDIO_FMT_MLP;
break;
default:
break;
}
freq = c->sample_rate;
bitrate = c->bit_rate;
if (c->channels == 1)
@@ -240,7 +267,7 @@ void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &m
}
}
lt_debug("%s t: %d l: %d f: %d b: %d m: %d codec_id: %x\n",
__func__, type, layer, freq, bitrate, mode, c ? c->codec_id : 0);
__func__, type, layer, freq, bitrate, mode, c?c->codec_id:-1);
};
void cAudio::SetSRS(int /*iq_enable*/, int /*nmgr_enable*/, int /*iq_mode*/, int /*iq_level*/)

View File

@@ -4,7 +4,7 @@
#define _AUDIO_LIB_H_
#include <stdint.h>
#include <thread_abstraction.h>
#include <OpenThreads/Thread>
#include "cs_types.h"
typedef enum
@@ -38,7 +38,7 @@ typedef enum
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT;
class cAudio : public Thread
class cAudio : public OpenThreads::Thread
{
friend class cPlayback;
private:

481
generic-pc/clutterfb.cpp Normal file
View File

@@ -0,0 +1,481 @@
/*
Framebuffer implementation using clutter https://developer.gnome.org/clutter/
Copyright (C) 2016 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
based on the openGL framebuffer implementation
Copyright 2010 Carsten Juttner <carjay@gmx.net>
Copyright 2012,2013 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
TODO: AV-Sync code is "experimental" at best
*/
#include "config.h"
#include <vector>
#include <sys/types.h>
#include <signal.h>
#include <cstdio>
#include <cstring>
#include <errno.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include "glfb_priv.h"
#include "video_priv.h"
#include "audio_priv.h"
#include <clutter/x11/clutter-x11.h>
#include "lt_debug.h"
#define lt_debug_c(args...) _lt_debug(HAL_DEBUG_INIT, NULL, args)
#define lt_info_c(args...) _lt_info(HAL_DEBUG_INIT, NULL, args)
#define lt_debug(args...) _lt_debug(HAL_DEBUG_INIT, this, args)
#define lt_info(args...) _lt_info(HAL_DEBUG_INIT, this, args)
extern VDec *vdec;
extern ADec *adec;
/* the private class that does stuff only needed inside libstb-hal.
* is used e.g. by cVideo... */
GLFbPC *glfb_priv = NULL;
GLFramebuffer::GLFramebuffer(int x, int y)
{
Init();
glfb_priv = new GLFbPC(x, y, osd_buf);
si = glfb_priv->getScreenInfo();
start();
while (!glfb_priv->mInitDone)
usleep(1);
}
GLFramebuffer::~GLFramebuffer()
{
glfb_priv->mShutDown = true;
join();
delete glfb_priv;
glfb_priv = NULL;
}
void GLFramebuffer::blit()
{
glfb_priv->blit();
}
GLFbPC::GLFbPC(int x, int y, std::vector<unsigned char> &buf): mReInit(true), mShutDown(false), mInitDone(false)
{
osd_buf = &buf;
mState.width = x;
mState.height = y;
mX = &_mX[0];
mY = &_mY[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;
last_apts = 0;
/* linux framebuffer compat mode */
si.bits_per_pixel = 32;
si.xres = mState.width;
si.xres_virtual = si.xres;
si.yres = mState.height;
si.yres_virtual = si.yres;
si.blue.length = 8;
si.blue.offset = 0;
si.green.length = 8;
si.green.offset = 8;
si.red.length = 8;
si.red.offset = 16;
si.transp.length = 8;
si.transp.offset = 24;
unlink("/tmp/neutrino.input");
mkfifo("/tmp/neutrino.input", 0600);
input_fd = open("/tmp/neutrino.input", O_RDWR|O_CLOEXEC|O_NONBLOCK);
if (input_fd < 0)
lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__);
initKeys();
}
GLFbPC::~GLFbPC()
{
mShutDown = true;
if (input_fd >= 0)
close(input_fd);
osd_buf->clear();
}
void GLFbPC::initKeys()
{
mKeyMap[CLUTTER_KEY_Up] = KEY_UP;
mKeyMap[CLUTTER_KEY_Down] = KEY_DOWN;
mKeyMap[CLUTTER_KEY_Left] = KEY_LEFT;
mKeyMap[CLUTTER_KEY_Right] = KEY_RIGHT;
mKeyMap[CLUTTER_KEY_F1] = KEY_RED;
mKeyMap[CLUTTER_KEY_F2] = KEY_GREEN;
mKeyMap[CLUTTER_KEY_F3] = KEY_YELLOW;
mKeyMap[CLUTTER_KEY_F4] = KEY_BLUE;
mKeyMap[CLUTTER_KEY_F5] = KEY_WWW;
mKeyMap[CLUTTER_KEY_F6] = KEY_SUBTITLE;
mKeyMap[CLUTTER_KEY_F7] = KEY_MOVE;
mKeyMap[CLUTTER_KEY_F8] = KEY_SLEEP;
mKeyMap[CLUTTER_KEY_Page_Up] = KEY_PAGEUP;
mKeyMap[CLUTTER_KEY_Page_Down] = KEY_PAGEDOWN;
mKeyMap[CLUTTER_KEY_Return] = KEY_OK;
mKeyMap[CLUTTER_KEY_Escape] = KEY_EXIT;
mKeyMap['e'] = KEY_EPG;
mKeyMap['i'] = KEY_INFO;
mKeyMap['m'] = KEY_MENU;
mKeyMap['+'] = KEY_VOLUMEUP;
mKeyMap['-'] = KEY_VOLUMEDOWN;
mKeyMap['.'] = KEY_MUTE;
mKeyMap['h'] = KEY_HELP;
mKeyMap['p'] = KEY_POWER;
mKeyMap['0'] = KEY_0;
mKeyMap['1'] = KEY_1;
mKeyMap['2'] = KEY_2;
mKeyMap['3'] = KEY_3;
mKeyMap['4'] = KEY_4;
mKeyMap['5'] = KEY_5;
mKeyMap['6'] = KEY_6;
mKeyMap['7'] = KEY_7;
mKeyMap['8'] = KEY_8;
mKeyMap['9'] = KEY_9;
}
static ClutterActor *stage = NULL;
static ClutterActor *fb_actor = NULL;
static ClutterActor *vid_actor = NULL;
static ClutterTimeline *tl = NULL;
void GLFramebuffer::run()
{
int argc = 1;
int x = glfb_priv->mState.width;
int y = glfb_priv->mState.height;
/* some dummy commandline for GLUT to be happy */
char *a = (char *)"neutrino";
char **argv = (char **)malloc(sizeof(char *) * 2);
argv[0] = a;
argv[1] = NULL;
lt_info("GLFB: GL thread starting x %d y %d\n", x, y);
if (clutter_init(&argc, &argv) != CLUTTER_INIT_SUCCESS) {
lt_info("GLFB: error initializing clutter\n");
return;
}
lt_info("GLFB: %s:%d\n", __func__, __LINE__);
ClutterColor stage_color = { 0, 0, 0, 255 };
stage = clutter_stage_new();
clutter_actor_set_size(stage, x, y);
clutter_actor_set_background_color(stage, &stage_color);
clutter_actor_set_content_gravity(stage, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);
//g_signal_connect(stage, "destroy", G_CALLBACK(clutter_main_quit), NULL);
g_signal_connect(stage, "key-press-event", G_CALLBACK(GLFbPC::keyboardcb), (void *)1);
g_signal_connect(stage, "key-release-event", G_CALLBACK(GLFbPC::keyboardcb), NULL);
clutter_stage_set_user_resizable(CLUTTER_STAGE (stage), TRUE);
clutter_actor_grab_key_focus(stage);
clutter_actor_show(stage);
/* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */
int fbmem = x * y * 4 * 2;
osd_buf.resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes at 0x%p\n", fbmem, osd_buf.data());
/* video plane is below FB plane, so it comes first */
vid_actor = clutter_actor_new();
ClutterContent *fb = clutter_image_new();
/* osd_buf, because it starts up black */
if (!clutter_image_set_data(CLUTTER_IMAGE(fb), osd_buf.data(), COGL_PIXEL_FORMAT_BGR_888, x, y, x*3, NULL)) {
lt_info("GLFB::%s clutter_image_set_data failed? (vid)\n", __func__);
_exit(1); /* life is hard */
}
clutter_actor_set_content(vid_actor, fb);
g_object_unref(fb);
clutter_actor_set_size(vid_actor, x, y);
clutter_actor_set_position(vid_actor, 0, 0);
clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_WIDTH, 0));
clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_HEIGHT, 0));
clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_X, 0));
clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_Y, 0));
clutter_actor_set_content_gravity(vid_actor, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);
clutter_actor_set_pivot_point(vid_actor, 0.5, 0.5);
clutter_actor_add_child(stage, vid_actor);
clutter_actor_show(vid_actor);
fb_actor = clutter_actor_new();
fb = clutter_image_new();
if (!clutter_image_set_data(CLUTTER_IMAGE(fb), osd_buf.data(), COGL_PIXEL_FORMAT_BGRA_8888, x, y, x*4, NULL)) {
lt_info("GLFB::%s clutter_image_set_data failed? (osd)\n", __func__);
_exit(1); /* life is hard */
}
clutter_actor_set_content(fb_actor, fb);
g_object_unref(fb);
clutter_actor_set_size(fb_actor, x, y);
clutter_actor_set_position(fb_actor, 0, 0);
clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_WIDTH, 0));
clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_HEIGHT, 0));
clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_X, 0));
clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_Y, 0));
clutter_actor_set_content_gravity(fb_actor, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);
clutter_actor_add_child(stage, fb_actor);
clutter_actor_show(fb_actor);
glfb_priv->mInitDone = true; /* signal that setup is finished */
tl = clutter_timeline_new(100);
g_signal_connect(tl, "new-frame", G_CALLBACK(GLFbPC::rendercb), NULL);
clutter_timeline_set_repeat_count(tl, -1);
clutter_timeline_start(tl);
clutter_main();
lt_info("GLFB: GL thread stopping\n");
}
/* static */ void GLFbPC::rendercb()
{
glfb_priv->render();
}
/* static */ bool GLFbPC::keyboardcb(ClutterActor * /*actor*/, ClutterEvent *event, gpointer user_data)
{
guint key = clutter_event_get_key_symbol (event);
int keystate = user_data ? 1 : 0;
lt_info_c("GLFB::%s: 0x%x, %d\n", __func__, key, keystate);
struct input_event ev;
if (key == 'f' && keystate)
{
lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, glfb_priv->mFullscreen?"off":"on");
glfb_priv->mFullscreen = !(glfb_priv->mFullscreen);
glfb_priv->mReInit = true;
return true;
}
std::map<int, int>::const_iterator i = glfb_priv->mKeyMap.find(key);
if (i == glfb_priv->mKeyMap.end())
return true;
ev.code = i->second;
ev.value = keystate; /* key own */
ev.type = EV_KEY;
gettimeofday(&ev.time, NULL);
lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code);
write(glfb_priv->input_fd, &ev, sizeof(ev));
return true;
}
int sleep_us = 30000;
void GLFbPC::render()
{
if(mShutDown)
clutter_main_quit();
mReInitLock.lock();
if (mReInit)
{
int xoff = 0;
int yoff = 0;
mVAchanged = true;
mReInit = false;
#if 0
mX = &_mX[mFullscreen];
mY = &_mY[mFullscreen];
#endif
*mX = *mY * mOA.num / mOA.den;
if (mFullscreen) {
clutter_stage_set_fullscreen(CLUTTER_STAGE(stage), TRUE);
clutter_actor_show(stage);
clutter_stage_ensure_redraw(CLUTTER_STAGE(stage));
} else {
clutter_stage_set_fullscreen(CLUTTER_STAGE(stage), FALSE);
// *mX = *mY * mOA.num / mOA.den;
clutter_actor_set_size(stage, *mX, *mY);
}
lt_info("%s: reinit mX:%d mY:%d xoff:%d yoff:%d fs %d\n",
__func__, *mX, *mY, xoff, yoff, mFullscreen);
}
mReInitLock.unlock();
bltDisplayBuffer(); /* decoded video stream */
if (mState.blit) {
/* only blit manually after fb->blit(), this helps to find missed blit() calls */
mState.blit = false;
lt_debug("GLFB::%s blit!\n", __func__);
bltOSDBuffer(); /* OSD */
}
if (mVAchanged)
{
mVAchanged = false;
zoom = 1.0;
float xzoom = 1.0;
//xscale = 1.0;
int cmp = av_cmp_q(mVA, mOA);
const AVRational a149 = { 14, 9 };
switch (cmp) {
default:
case INT_MIN: /* invalid */
case 0: /* identical */
lt_debug("%s: mVA == mOA (or fullscreen mode :-)\n", __func__);
break;
case 1: /* mVA > mOA -- video is wider than display */
lt_debug("%s: mVA > mOA\n", __func__);
switch (mCrop) {
case DISPLAY_AR_MODE_PANSCAN:
zoom = av_q2d(mVA) / av_q2d(mOA);
break;
case DISPLAY_AR_MODE_LETTERBOX:
break;
case DISPLAY_AR_MODE_PANSCAN2:
zoom = av_q2d(a149) / av_q2d(mOA);
break;
case DISPLAY_AR_MODE_NONE:
xzoom = av_q2d(mOA) / av_q2d(mVA);
zoom = av_q2d(mVA) / av_q2d(mOA);
break;
default:
break;
}
break;
case -1: /* mVA < mOA -- video is taller than display */
lt_debug("%s: mVA < mOA\n", __func__);
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;
case DISPLAY_AR_MODE_NONE:
xzoom = av_q2d(mOA) / av_q2d(mVA);
break;
default:
break;
}
break;
}
lt_debug("zoom: %f xscale: %f xzoom: %f\n", zoom, xscale,xzoom);
clutter_actor_set_scale(vid_actor, xscale*zoom*xzoom, zoom);
}
clutter_timeline_stop(tl);
clutter_timeline_set_delay(tl, sleep_us/1000);
clutter_timeline_start(tl);
}
void GLFbPC::bltOSDBuffer()
{
// lt_info("%s\n", __func__);
int x = glfb_priv->mState.width;
int y = glfb_priv->mState.height;
ClutterContent *fb = clutter_image_new();
if (!clutter_image_set_data(CLUTTER_IMAGE(fb), osd_buf->data(), COGL_PIXEL_FORMAT_BGRA_8888, x, y, x*4, NULL)) {
lt_info("GLFB::%s clutter_image_set_data failed?\n", __func__);
_exit(1); /* life is hard */
}
clutter_actor_set_content(fb_actor, fb);
g_object_unref(fb);
clutter_actor_show(fb_actor);
}
void GLFbPC::bltDisplayBuffer()
{
// lt_info("GLFB::%s vdec: %p\n", __func__, vdec);
if (!vdec) /* cannot start yet */
return;
static bool warn = true;
VDec::SWFramebuffer *buf = vdec->getDecBuf();
if (!buf) {
if (warn)
lt_info("GLFB::%s did not get a buffer...\n", __func__);
warn = false;
return;
}
warn = true;
int w = buf->width(), h = buf->height();
if (w == 0 || h == 0)
return;
AVRational a = buf->AR();
if (a.den != 0 && a.num != 0 && av_cmp_q(a, _mVA)) {
_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);
// mVA.num: 16 mVA.den: 9 w: 720 h: 576
// 16*576/720/9 = 1.42222
xscale = (double)mVA.num*h/(double)mVA.den/w;
mVAchanged = true;
}
ClutterContent *fb = clutter_image_new();
if (!clutter_image_set_data(CLUTTER_IMAGE(fb), &(*buf)[0], COGL_PIXEL_FORMAT_BGR_888, w, h, w*3, NULL)) {
lt_info("GLFB::%s clutter_image_set_data failed?\n", __func__);
_exit(1); /* life is hard */
}
clutter_actor_set_content(vid_actor, fb);
g_object_unref(fb);
clutter_actor_show(vid_actor);
/* "rate control" mechanism starts here...
* this implementation is pretty naive and not working too well, but
* better this than nothing... :-) */
int64_t apts = 0;
int64_t vpts = buf->pts();
if (adec)
apts = adec->getPts();
if (apts != last_apts) {
int rate, dummy1, dummy2;
if (apts < vpts)
sleep_us = (sleep_us * 2 + (vpts - apts)*10/9) / 3;
else if (sleep_us > 1000)
sleep_us -= 1000;
last_apts = apts;
vdec->getPictureInfo(dummy1, dummy2, rate);
if (rate > 0)
rate = 2000000 / rate; /* limit to half the frame rate */
else
rate = 50000; /* minimum 20 fps */
if (sleep_us > rate)
sleep_us = rate;
else if (sleep_us < 1)
sleep_us = 1;
}
lt_debug("vpts: 0x%" PRIx64 " apts: 0x%" PRIx64 " diff: %6.3f sleep_us %d buf %d\n",
buf->pts(), apts, (buf->pts() - apts)/90000.0, sleep_us, vdec->buf_num);
}

View File

@@ -64,15 +64,12 @@ static const char *DMX_T[] = {
};
/* map the device numbers. for now only demux0 is used */
#define NUM_DEMUXDEV 1
static const char *devname[NUM_DEMUXDEV] = {
static const char *devname[] = {
"/dev/dvb/adapter0/demux0",
"/dev/dvb/adapter0/demux0",
"/dev/dvb/adapter0/demux0"
};
#define NUM_DEMUX 1
static int dmx_source[NUM_DEMUX] = { 0 };
static bool init[NUM_DEMUXDEV] = { false };
/* uuuugly */
static int dmx_tp_count = 0;
#define MAX_TS_COUNT 8
@@ -492,28 +489,12 @@ int cDemux::getUnit(void)
bool cDemux::SetSource(int unit, int source)
{
//lt_info_c("%s(%d, %d): not implemented yet\n", __func__, unit, source);
//return true;
if (unit >= NUM_DEMUX || unit < 0) {
lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX);
return false;
}
lt_info_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source);
if (source < 0 || source >= NUM_DEMUXDEV)
lt_info_c("%s(%d, %d) ERROR: source %d out of range!\n", __func__, unit, source, source);
else
dmx_source[unit] = source;
lt_info_c("%s(%d, %d): not implemented yet\n", __func__, unit, source);
return true;
}
int cDemux::GetSource(int unit)
{
//lt_info_c("%s(%d): not implemented yet\n", __func__, unit);
//return 0;
if (unit >= NUM_DEMUX || unit < 0) {
lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX);
return -1;
}
lt_info_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]);
return dmx_source[unit];
lt_info_c("%s(%d): not implemented yet\n", __func__, unit);
return 0;
}

View File

@@ -22,6 +22,7 @@
TODO: AV-Sync code is "experimental" at best
*/
#include "config.h"
#include <vector>
#include <sys/types.h>
@@ -37,8 +38,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
#include "glfb.h"
#include <GL/glx.h>
#include "glfb_priv.h"
#include "video_lib.h"
#include "audio_lib.h"
@@ -53,10 +53,36 @@
extern cVideo *videoDecoder;
extern cAudio *audioDecoder;
static GLFramebuffer *gThiz = 0; /* GLUT does not allow for an arbitrary argument to the render func */
/* the private class that does stuff only needed inside libstb-hal.
* is used e.g. by cVideo... */
GLFbPC *glfb_priv = NULL;
GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mInitDone(false)
GLFramebuffer::GLFramebuffer(int x, int y)
{
Init();
glfb_priv = new GLFbPC(x, y, osd_buf);
si = glfb_priv->getScreenInfo();
start();
while (!glfb_priv->mInitDone)
usleep(1);
}
GLFramebuffer::~GLFramebuffer()
{
glfb_priv->mShutDown = true;
join();
delete glfb_priv;
glfb_priv = NULL;
}
void GLFramebuffer::blit()
{
glfb_priv->blit();
}
GLFbPC::GLFbPC(int x, int y, std::vector<unsigned char> &buf): mReInit(true), mShutDown(false), mInitDone(false)
{
osd_buf = &buf;
mState.width = x;
mState.height = y;
mX = &_mX[0];
@@ -77,19 +103,19 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn
last_apts = 0;
/* linux framebuffer compat mode */
screeninfo.bits_per_pixel = 32;
screeninfo.xres = mState.width;
screeninfo.xres_virtual = screeninfo.xres;
screeninfo.yres = mState.height;
screeninfo.yres_virtual = screeninfo.yres;
screeninfo.blue.length = 8;
screeninfo.blue.offset = 0;
screeninfo.green.length = 8;
screeninfo.green.offset = 8;
screeninfo.red.length = 8;
screeninfo.red.offset = 16;
screeninfo.transp.length = 8;
screeninfo.transp.offset = 24;
si.bits_per_pixel = 32;
si.xres = mState.width;
si.xres_virtual = si.xres;
si.yres = mState.height;
si.yres_virtual = si.yres;
si.blue.length = 8;
si.blue.offset = 0;
si.green.length = 8;
si.green.offset = 8;
si.red.length = 8;
si.red.offset = 16;
si.transp.length = 8;
si.transp.offset = 24;
unlink("/tmp/neutrino.input");
mkfifo("/tmp/neutrino.input", 0600);
@@ -97,21 +123,22 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn
if (input_fd < 0)
lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__);
initKeys();
Thread::startThread();
while (!mInitDone)
usleep(1);
}
GLFramebuffer::~GLFramebuffer()
GLFbPC::~GLFbPC()
{
mShutDown = true;
Thread::joinThread();
if (input_fd >= 0)
close(input_fd);
osd_buf->clear();
}
void GLFramebuffer::initKeys()
void GLFbPC::initKeys()
{
/*
Keep in sync with initKeys() in clutterfb.cpp
*/
mSpecialMap[GLUT_KEY_UP] = KEY_UP;
mSpecialMap[GLUT_KEY_DOWN] = KEY_DOWN;
mSpecialMap[GLUT_KEY_LEFT] = KEY_LEFT;
@@ -132,8 +159,8 @@ void GLFramebuffer::initKeys()
mSpecialMap[GLUT_KEY_F11] = KEY_NEXT;
mSpecialMap[GLUT_KEY_F12] = KEY_PREVIOUS;
mSpecialMap[GLUT_KEY_PAGE_UP] = KEY_PAGEUP;
mSpecialMap[GLUT_KEY_PAGE_DOWN] = KEY_PAGEDOWN;
mSpecialMap[GLUT_KEY_PAGE_UP] = KEY_PAGEUP;
mSpecialMap[GLUT_KEY_PAGE_DOWN] = KEY_PAGEDOWN;
mKeyMap[0x0d] = KEY_OK;
mKeyMap[0x1b] = KEY_EXIT;
@@ -176,9 +203,21 @@ void GLFramebuffer::initKeys()
void GLFramebuffer::run()
{
setupCtx();
setupOSDBuffer();
mInitDone = true; /* signal that setup is finished */
int argc = 1;
int x = glfb_priv->mState.width;
int y = glfb_priv->mState.height;
/* some dummy commandline for GLUT to be happy */
char const *argv[2] = { "neutrino", 0 };
lt_info("GLFB: GL thread starting x %d y %d\n", x, y);
glutInit(&argc, const_cast<char **>(argv));
glutInitWindowSize(x, y);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Neutrino");
/* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */
int fbmem = x * y * 4 * 2;
osd_buf.resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes at 0x%p\n", fbmem, osd_buf.data());
glfb_priv->mInitDone = true; /* signal that setup is finished */
/* init the good stuff */
GLenum err = glewInit();
@@ -193,16 +232,15 @@ void GLFramebuffer::run()
}
else
{
gThiz = this;
glutSetCursor(GLUT_CURSOR_NONE);
glutDisplayFunc(GLFramebuffer::rendercb);
glutKeyboardFunc(GLFramebuffer::keyboardcb);
glutSpecialFunc(GLFramebuffer::specialcb);
glutReshapeFunc(GLFramebuffer::resizecb);
setupGLObjects(); /* needs GLEW prototypes */
glutDisplayFunc(GLFbPC::rendercb);
glutKeyboardFunc(GLFbPC::keyboardcb);
glutSpecialFunc(GLFbPC::specialcb);
glutReshapeFunc(GLFbPC::resizecb);
glfb_priv->setupGLObjects(); /* needs GLEW prototypes */
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
glutMainLoop();
releaseGLObjects();
glfb_priv->releaseGLObjects();
}
}
else
@@ -210,21 +248,20 @@ void GLFramebuffer::run()
lt_info("GLFB: GL thread stopping\n");
}
void GLFramebuffer::setupCtx()
#if 0
void GLFbPC::setupCtx()
{
int argc = 1;
/* some dummy commandline for GLUT to be happy */
char const *argv[2] = { "neutrino", 0 };
lt_info("GLFB: GL thread starting\n");
lt_info("GLFB: GL thread starting x %d y %d\n", mX[0], mY[0]);
glutInit(&argc, const_cast<char **>(argv));
glutInitWindowSize(mX[0], mY[0]);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Neutrino");
GLWinID = glXGetCurrentDrawable(); // this was the holy grail to get the right window handle for gstreamer :D
}
void GLFramebuffer::setupOSDBuffer()
void GLFbPC::setupOSDBuffer()
{ /* the OSD buffer size can be decoupled from the actual
window size since the GL can blit-stretch with no
trouble at all, ah, the luxury of ignorance... */
@@ -233,12 +270,13 @@ void GLFramebuffer::setupOSDBuffer()
{
/* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */
int fbmem = mState.width * mState.height * 4 * 2;
mOSDBuffer.resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes\n", fbmem);
osd_buf->resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes at 0x%p\n", fbmem, osd_buf->data());
}
}
#endif
void GLFramebuffer::setupGLObjects()
void GLFbPC::setupGLObjects()
{
unsigned char buf[4] = { 0, 0, 0, 0 }; /* 1 black pixel */
glGenTextures(1, &mState.osdtex);
@@ -266,7 +304,7 @@ void GLFramebuffer::setupGLObjects()
}
void GLFramebuffer::releaseGLObjects()
void GLFbPC::releaseGLObjects()
{
glDeleteBuffers(1, &mState.pbo);
glDeleteBuffers(1, &mState.displaypbo);
@@ -275,56 +313,56 @@ void GLFramebuffer::releaseGLObjects()
}
/* static */ void GLFramebuffer::rendercb()
/* static */ void GLFbPC::rendercb()
{
gThiz->render();
glfb_priv->render();
}
/* static */ void GLFramebuffer::keyboardcb(unsigned char key, int /*x*/, int /*y*/)
/* static */ void GLFbPC::keyboardcb(unsigned char key, int /*x*/, int /*y*/)
{
lt_debug_c("GLFB::%s: 0x%x\n", __func__, key);
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;
lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, glfb_priv->mFullscreen?"off":"on");
glfb_priv->mFullscreen = !(glfb_priv->mFullscreen);
glfb_priv->mReInit = true;
return;
}
std::map<unsigned char, int>::const_iterator i = gThiz->mKeyMap.find(key);
if (i == gThiz->mKeyMap.end())
std::map<unsigned char, int>::const_iterator i = glfb_priv->mKeyMap.find(key);
if (i == glfb_priv->mKeyMap.end())
return;
ev.code = i->second;
ev.value = 1; /* key own */
ev.type = EV_KEY;
gettimeofday(&ev.time, NULL);
lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code);
write(gThiz->input_fd, &ev, sizeof(ev));
write(glfb_priv->input_fd, &ev, sizeof(ev));
ev.value = 0; /* neutrino is stupid, so push key up directly after key down */
write(gThiz->input_fd, &ev, sizeof(ev));
write(glfb_priv->input_fd, &ev, sizeof(ev));
}
/* static */ void GLFramebuffer::specialcb(int key, int /*x*/, int /*y*/)
/* static */ void GLFbPC::specialcb(int key, int /*x*/, int /*y*/)
{
lt_debug_c("GLFB::%s: 0x%x\n", __func__, key);
struct input_event ev;
std::map<int, int>::const_iterator i = gThiz->mSpecialMap.find(key);
if (i == gThiz->mSpecialMap.end())
std::map<int, int>::const_iterator i = glfb_priv->mSpecialMap.find(key);
if (i == glfb_priv->mSpecialMap.end())
return;
ev.code = i->second;
ev.value = 1;
ev.type = EV_KEY;
gettimeofday(&ev.time, NULL);
lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code);
write(gThiz->input_fd, &ev, sizeof(ev));
write(glfb_priv->input_fd, &ev, sizeof(ev));
ev.value = 0;
write(gThiz->input_fd, &ev, sizeof(ev));
write(glfb_priv->input_fd, &ev, sizeof(ev));
}
int sleep_us = 30000;
void GLFramebuffer::render()
void GLFbPC::render()
{
if(mShutDown)
glutLeaveMainLoop();
@@ -452,12 +490,12 @@ void GLFramebuffer::render()
glutPostRedisplay();
}
/* static */ void GLFramebuffer::resizecb(int w, int h)
/* static */ void GLFbPC::resizecb(int w, int h)
{
gThiz->checkReinit(w, h);
glfb_priv->checkReinit(w, h);
}
void GLFramebuffer::checkReinit(int x, int y)
void GLFbPC::checkReinit(int x, int y)
{
static int last_x = 0, last_y = 0;
@@ -477,7 +515,7 @@ void GLFramebuffer::checkReinit(int x, int y)
last_y = y;
}
void GLFramebuffer::drawSquare(float size, float x_factor)
void GLFbPC::drawSquare(float size, float x_factor)
{
GLfloat vertices[] = {
1.0f, 1.0f,
@@ -533,11 +571,11 @@ void GLFramebuffer::drawSquare(float size, float x_factor)
}
void GLFramebuffer::bltOSDBuffer()
void GLFbPC::bltOSDBuffer()
{
/* FIXME: copy each time */
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mState.pbo);
glBufferData(GL_PIXEL_UNPACK_BUFFER, mOSDBuffer.size(), &mOSDBuffer[0], GL_STREAM_DRAW_ARB);
glBufferData(GL_PIXEL_UNPACK_BUFFER, osd_buf->size(), osd_buf->data(), GL_STREAM_DRAW_ARB);
glBindTexture(GL_TEXTURE_2D, mState.osdtex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mState.width, mState.height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
@@ -545,7 +583,7 @@ void GLFramebuffer::bltOSDBuffer()
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
void GLFramebuffer::bltDisplayBuffer()
void GLFbPC::bltDisplayBuffer()
{
if (!videoDecoder) /* cannot start yet */
return;
@@ -553,7 +591,7 @@ void GLFramebuffer::bltDisplayBuffer()
cVideo::SWFramebuffer *buf = videoDecoder->getDecBuf();
if (!buf) {
if (warn)
lt_debug("GLFB::%s did not get a buffer...\n", __func__);
lt_info("GLFB::%s did not get a buffer...\n", __func__);
warn = false;
return;
}
@@ -606,9 +644,3 @@ void GLFramebuffer::bltDisplayBuffer()
lt_debug("vpts: 0x%" PRIx64 " apts: 0x%" PRIx64 " diff: %6.3f sleep_us %d buf %d\n",
buf->pts(), apts, (buf->pts() - apts)/90000.0, sleep_us, videoDecoder->buf_num);
}
void GLFramebuffer::clear()
{
/* clears front and back buffer */
memset(&mOSDBuffer[0], 0, mOSDBuffer.size());
}

View File

@@ -1,6 +1,6 @@
/*
Copyright 2010 Carsten Juttner <carjay@gmx.net>
Copyright 2012,2013 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
Copyright 2012,2013,2016 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -14,44 +14,46 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
********************************************************************
private stuff of the GLFB thread that is only used inside libstb-hal
and not exposed to the application.
*/
#ifndef __glthread__
#define __glthread__
#include <thread_abstraction.h>
#include <mutex_abstraction.h>
#ifndef __glfb_priv__
#define __glfb_priv__
#include <OpenThreads/Mutex>
#include <vector>
#include <map>
#if USE_OPENGL
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/gl.h>
#include <linux/fb.h> /* for screeninfo etc. */
#endif
#if USE_CLUTTER
#include <clutter/clutter.h>
#endif
#include "glfb.h"
extern "C" {
#include <libavutil/rational.h>
}
class GLFramebuffer : public Thread
class GLFbPC
{
public:
GLFramebuffer(int x, int y);
~GLFramebuffer();
void run();
std::vector<unsigned char> *getOSDBuffer() { return &mOSDBuffer; } /* pointer to OSD bounce buffer */
GLFbPC(int x, int y, std::vector<unsigned char> &buf);
~GLFbPC();
std::vector<unsigned char> *getOSDBuffer() { return osd_buf; } /* pointer to OSD bounce buffer */
int getOSDWidth() { return mState.width; }
int getOSDHeight() { return mState.height; }
void blit() { mState.blit = true; }
void blit() { mState.blit = true; };
fb_var_screeninfo getScreenInfo() { return si; }
void setOutputFormat(AVRational a, int h, int c) { mOA = a; *mY = h; mCrop = c; mReInit = true; }
void clear();
fb_var_screeninfo getScreenInfo() { return screeninfo; }
int getWindowID() { return GLWinID; }
/* just make everything public for simplicity - this is only used inside libstb-hal anyway
private:
fb_var_screeninfo screeninfo;
*/
fb_var_screeninfo si;
int *mX;
int *mY;
int _mX[2]; /* output window size */
@@ -63,45 +65,59 @@ private:
float zoom; /* for cropping */
float xscale; /* and aspect ratio */
int mCrop; /* DISPLAY_AR_MODE */
int GLWinID;
bool mFullscreen; /* fullscreen? */
bool mReInit; /* setup things for GL */
Mutex mReInitLock;
OpenThreads::Mutex mReInitLock;
bool mShutDown; /* if set main loop is left */
bool mInitDone; /* condition predicate */
// OpenThreads::Condition mInitCond; /* condition variable for init */
// mutable OpenThreads::Mutex mMutex; /* lock our data */
std::vector<unsigned char> mOSDBuffer; /* silly bounce buffer */
std::vector<unsigned char> *osd_buf; /* silly bounce buffer */
#if USE_OPENGL
std::map<unsigned char, int> mKeyMap;
std::map<int, int> mSpecialMap;
#endif
#if USE_CLUTTER
std::map<int, int> mKeyMap;
#endif
int input_fd;
int64_t last_apts;
void run();
static void rendercb(); /* callback for GLUT */
void render(); /* actual render function */
#if USE_OPENGL
static void keyboardcb(unsigned char 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 setupCtx(); /* create the window and make the context current */
void setupOSDBuffer(); /* create the OSD buffer */
void setupGLObjects(); /* PBOs, textures and stuff */
void releaseGLObjects();
void drawSquare(float size, float x_factor = 1); /* do not be square */
#endif
#if USE_CLUTTER
static bool keyboardcb(ClutterActor *actor, ClutterEvent *event, gpointer user_data);
#endif
void initKeys(); /* setup key bindings for window */
#if 0
void setupCtx(); /* create the window and make the context current */
void setupOSDBuffer(); /* create the OSD buffer */
#endif
struct {
int width; /* width and height, fixed for a framebuffer instance */
int height;
bool blit;
#if USE_OPENGL
GLuint osdtex; /* holds the OSD texture */
GLuint pbo; /* PBO we use for transfer to texture */
GLuint displaytex; /* holds the display texture */
GLuint displaypbo;
bool blit;
#endif
} mState;
void bltOSDBuffer();

View File

@@ -1,4 +1,5 @@
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include "init_td.h"

View File

@@ -23,6 +23,7 @@
* TODO: buffer handling surely needs some locking...
*/
#include "config.h"
#include <unistd.h>
#include <cstring>
#include <cstdio>
@@ -39,9 +40,16 @@ extern "C" {
/* my own buf 256k */
#define DMX_BUF_SZ 0x20000
#if USE_OPENGL
#define VDEC_PIXFMT AV_PIX_FMT_RGB32
#endif
#if USE_CLUTTER
#define VDEC_PIXFMT AV_PIX_FMT_BGR24
#endif
#include "video_lib.h"
#include "dmx_hal.h"
#include "glfb.h"
#include "glfb_priv.h"
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_VIDEO, this, args)
@@ -49,7 +57,7 @@ extern "C" {
cVideo *videoDecoder = NULL;
extern cDemux *videoDemux;
extern GLFramebuffer *glfb;
extern GLFbPC *glfb_priv;
int system_rev = 0;
extern bool HAL_nodec;
@@ -103,7 +111,7 @@ int cVideo::setAspectRatio(int vformat, int cropping)
if (cropping >= 0)
display_crop = (DISPLAY_AR_MODE) cropping;
if (display_aspect < DISPLAY_AR_RAW && output_h > 0) /* don't know what to do with this */
glfb->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
glfb_priv->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
return 0;
}
@@ -145,7 +153,7 @@ int cVideo::Start(void *, unsigned short, unsigned short, void *)
{
lt_debug("%s running %d >\n", __func__, thread_running);
if (!thread_running && !HAL_nodec)
Thread::startThread();
OpenThreads::Thread::start();
lt_debug("%s running %d <\n", __func__, thread_running);
return 0;
}
@@ -155,7 +163,7 @@ int cVideo::Stop(bool)
lt_debug("%s running %d >\n", __func__, thread_running);
if (thread_running) {
thread_running = false;
Thread::joinThread();
OpenThreads::Thread::join();
}
lt_debug("%s running %d <\n", __func__, thread_running);
return 0;
@@ -214,7 +222,7 @@ int cVideo::SetVideoSystem(int system, bool)
// v_std = (VIDEO_STD) system;
output_h = h;
if (display_aspect < DISPLAY_AR_RAW && output_h > 0) /* don't know what to do with this */
glfb->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
glfb_priv->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop);
return 0;
}
@@ -294,9 +302,9 @@ void cVideo::ShowPicture(const char *fname)
if (avpkt.size > len)
lt_info("%s: WARN: pkt->size %d != len %d\n", __func__, avpkt.size, len);
if (got_frame) {
unsigned int need = av_image_get_buffer_size(AV_PIX_FMT_RGB32, c->width, c->height, 1);
unsigned int need = av_image_get_buffer_size(VDEC_PIXFMT, c->width, c->height, 1);
struct SwsContext *convert = sws_getContext(c->width, c->height, c->pix_fmt,
c->width, c->height, AV_PIX_FMT_RGB32,
c->width, c->height, VDEC_PIXFMT,
SWS_BICUBIC, 0, 0, 0);
if (!convert)
lt_info("%s: ERROR setting up SWS context\n", __func__);
@@ -305,7 +313,7 @@ void cVideo::ShowPicture(const char *fname)
SWFramebuffer *f = &buffers[buf_in];
if (f->size() < need)
f->resize(need);
av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], AV_PIX_FMT_RGB32,
av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], VDEC_PIXFMT,
c->width, c->height, 1);
sws_scale(convert, frame->data, frame->linesize, 0, c->height,
rgbframe->data, rgbframe->linesize);
@@ -361,6 +369,7 @@ void cVideo::Pig(int x, int y, int w, int h, int /*osd_w*/, int /*osd_h*/, int /
pig_y = y;
pig_w = w;
pig_h = h;
pig_changed = true;
}
void cVideo::getPictureInfo(int &width, int &height, int &rate)
@@ -538,10 +547,10 @@ void cVideo::run(void)
lt_info("%s: WARN: pkt->size %d != len %d\n", __func__, avpkt.size, len);
still_m.lock();
if (got_frame && ! stillpicture) {
unsigned int need = av_image_get_buffer_size(AV_PIX_FMT_RGB32, c->width, c->height, 1);
unsigned int need = av_image_get_buffer_size(VDEC_PIXFMT, c->width, c->height, 1);
convert = sws_getCachedContext(convert,
c->width, c->height, c->pix_fmt,
c->width, c->height, AV_PIX_FMT_RGB32,
c->width, c->height, VDEC_PIXFMT,
SWS_BICUBIC, 0, 0, 0);
if (!convert)
lt_info("%s: ERROR setting up SWS context\n", __func__);
@@ -550,7 +559,7 @@ void cVideo::run(void)
SWFramebuffer *f = &buffers[buf_in];
if (f->size() < need)
f->resize(need);
av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], AV_PIX_FMT_RGB32,
av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], VDEC_PIXFMT,
c->width, c->height, 1);
sws_scale(convert, frame->data, frame->linesize, 0, c->height,
rgbframe->data, rgbframe->linesize);
@@ -564,10 +573,18 @@ void cVideo::run(void)
f->width(c->width);
f->height(c->height);
int64_t vpts = av_frame_get_best_effort_timestamp(frame);
/* a/v delay determined experimentally :-) */
#if USE_OPENGL
if (v_format == VIDEO_FORMAT_MPEG2)
vpts += 90000*4/10; /* 400ms */
else
vpts += 90000*3/10; /* 300ms */
#endif
#if USE_CLUTTER
/* no idea why there's a difference between OpenGL and clutter rendering... */
if (v_format == VIDEO_FORMAT_MPEG2)
vpts += 90000*3/10; /* 300ms */
#endif
f->pts(vpts);
AVRational a = av_guess_sample_aspect_ratio(avfc, avfc->streams[0], frame);
f->AR(a);
@@ -667,8 +684,8 @@ bool cVideo::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool ge
std::vector<unsigned char> *osd = NULL;
std::vector<unsigned char> s_osd; /* scaled OSD */
int vid_w = 0, vid_h = 0;
int osd_w = glfb->getOSDWidth();
int osd_h = glfb->getOSDHeight();
int osd_w = glfb_priv->getOSDWidth();
int osd_h = glfb_priv->getOSDHeight();
xres = osd_w;
yres = osd_h;
if (get_video) {
@@ -692,24 +709,26 @@ bool cVideo::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool ge
yres = osd_h;
}
if (get_osd)
osd = glfb->getOSDBuffer();
osd = glfb_priv->getOSDBuffer();
unsigned int need = av_image_get_buffer_size(AV_PIX_FMT_RGB32, xres, yres, 1);
data = (unsigned char *)realloc(data, need); /* will be freed by caller */
if (data == NULL) /* out of memory? */
return false;
if (get_video) {
//memcpy dont work with copy BGR24 to RGB32
#if USE_OPENGL //memcpy dont work with copy BGR24 to RGB32
if (vid_w != xres || vid_h != yres){ /* scale video into data... */
bool ret = swscale(&video[0], data, vid_w, vid_h, xres, yres, AV_PIX_FMT_RGB32);
#endif
bool ret = swscale(&video[0], data, vid_w, vid_h, xres, yres,VDEC_PIXFMT);
if(!ret){
free(data);
return false;
}
//memcpy dont work with copy BGR24 to RGB32
} else { /* get_video and no fancy scaling needed */
#if USE_OPENGL //memcpy dont work with copy BGR24 to RGB32
}else{ /* get_video and no fancy scaling needed */
memcpy(data, &video[0], xres * yres * sizeof(uint32_t));
}
#endif
}
if (get_osd && (osd_w != xres || osd_h != yres)) {

View File

@@ -1,8 +1,8 @@
#ifndef _VIDEO_LIB_H
#define _VIDEO_LIB_H
#include <thread_abstraction.h>
#include <mutex_abstraction.h>
#include <OpenThreads/Thread>
#include <OpenThreads/Mutex>
#include <vector>
#include <linux/dvb/video.h>
#include "cs_types.h"
@@ -120,10 +120,10 @@ typedef enum
} VIDEO_CONTROL;
#define VDEC_MAXBUFS 0x30
class cVideo : public Thread
#define VDEC_MAXBUFS 0x40
class cVideo : public OpenThreads::Thread
{
friend class GLFramebuffer;
friend class GLFbPC;
friend class cDemux;
private:
/* called from GL thread */
@@ -211,8 +211,7 @@ class cVideo : public Thread
bool thread_running;
VIDEO_FORMAT v_format;
VIDEO_STD v_std;
//OpenThreads::Mutex buf_m;
Mutex buf_m;
OpenThreads::Mutex buf_m;
DISPLAY_AR display_aspect;
DISPLAY_AR_MODE display_crop;
int output_h;
@@ -221,7 +220,7 @@ class cVideo : public Thread
int pig_w;
int pig_h;
bool pig_changed;
Mutex still_m;
OpenThreads::Mutex still_m;
bool stillpicture;
};

View File

@@ -1,23 +0,0 @@
#ifndef _CONDITION_ABSTRACTION_H
#define _CONDITION_ABSTRACTION_H
#include <pthread.h>
#include "mutex_abstraction.h"
class Condition
{
pthread_cond_t mCondition;
Condition(const Condition&);
const Condition& operator=(const Condition&);
public:
Condition();
virtual ~Condition();
virtual int wait(Mutex* const aMutex);
virtual int broadcast();
virtual int signal();
};
#endif

View File

@@ -1,10 +1,42 @@
#include <config.h>
#if HAVE_GENERIC_HARDWARE
#if BOXMODEL_RASPI
#include "../raspi/glfb.h"
#else
#include "../generic-pc/glfb.h"
#endif
#else
#error glfb.h only works with HAVE_GENERIC_HARDWARE defined
/*
Copyright 2010 Carsten Juttner <carjay@gmx.net>
Copyright 2012,2013 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __glfb__
#define __glfb__
#include <OpenThreads/Thread>
#include <vector>
#include <linux/fb.h> /* for screeninfo etc. */
class GLFramebuffer : public OpenThreads::Thread
{
public:
GLFramebuffer(int x, int y);
~GLFramebuffer();
std::vector<unsigned char> *getOSDBuffer() { return &osd_buf; } /* pointer to OSD bounce buffer */
void blit();
fb_var_screeninfo getScreenInfo() { return si; }
private:
fb_var_screeninfo si;
std::vector<unsigned char> osd_buf; /* silly bounce buffer */
void run(); /* for OpenThreads::Thread */
void setup();
void blit_osd();
void *pdata; /* not yet used */
};
#endif

View File

@@ -1,25 +0,0 @@
#ifndef _MUTEX_ABSTRACTION_H
#define _MUTEX_ABSTRACTION_H
#include <pthread.h>
class Mutex
{
friend class Condition;
pthread_mutex_t mMutex;
Mutex(const Mutex&);
const Mutex& operator=(const Mutex&);
protected:
explicit Mutex(int);
public:
Mutex();
virtual ~Mutex();
virtual void lock();
virtual void unlock();
};
#endif

View File

@@ -1,16 +0,0 @@
#ifndef _REENTRANT_MUTEX_H
#define _REENTRANT_MUTEX_H
#include "mutex_abstraction.h"
class ReentrantMutex : public Mutex
{
ReentrantMutex(const ReentrantMutex&);
const ReentrantMutex& operator=(const ReentrantMutex&);
public:
ReentrantMutex();
virtual ~ReentrantMutex();
};
#endif

View File

@@ -1,18 +0,0 @@
#ifndef _SCOPED_LOCK_H
#define _SCOPED_LOCK_H
#include "mutex_abstraction.h"
class ScopedLock
{
Mutex& mMutex;
ScopedLock(const ScopedLock&);
const ScopedLock& operator=(const ScopedLock&);
public:
ScopedLock(Mutex&);
~ScopedLock();
};
#endif

View File

@@ -1,30 +0,0 @@
#ifndef _THREAD_ABSTRACTION_H
#define _THREAD_ABSTRACTION_H
#include <pthread.h>
class Thread
{
bool mIsRunning;
pthread_t mThread;
static void* runThread(void*);
Thread(const Thread&);
const Thread& operator=(const Thread&);
public:
Thread();
virtual ~Thread();
int startThread();
int cancelThread();
int detachThread();
int joinThread();
int setCancelModeDisable();
int setSchedulePriority(int);
protected:
virtual void run() = 0;
};
#endif

View File

@@ -47,33 +47,42 @@ bool cPlayback::Open(playmode_t PlayMode)
last_size = 0;
nPlaybackSpeed = 0;
init_jump = -1;
if (player)
free(player);
player = NULL;
player = (Context_t *) malloc(sizeof(Context_t));
if (player)
{
player->playback = &PlaybackHandler;
player->output = &OutputHandler;
player->container = &ContainerHandler;
player->manager = &ManagerHandler;
lt_info("%s - player output name: %s PlayMode: %s\n", __func__, player->output->Name, aPLAYMODE[PlayMode]);
}
//Registration of output devices
if (player && player->output)
{
player->output->Command(player, OUTPUT_ADD, (void *)"audio");
player->output->Command(player, OUTPUT_ADD, (void *)"video");
player->output->Command(player, OUTPUT_ADD, (void *)"subtitle");
}
return 0;
}
void cPlayback::Close(void)
{
lt_info("%s\n", __func__);
//Dagobert: movieplayer does not call stop, it calls close ;)
if(playing)
Stop();
if (decoders_closed)
{
audioDecoder->openDevice();
@@ -92,7 +101,9 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
bool ret = false;
bool isHTTP = false;
no_probe = false;
lt_info("%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d\n", __func__, filename, vpid, vtype, apid, ac3);
init_jump = -1;
//create playback path
mAudioStream = 0;
@@ -100,11 +111,14 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
mTeletextStream = -1;
unlink("/tmp/.id3coverart");
std::string file;
if (*filename == '/')
file = "file://";
file += filename;
if ((file.find(":31339/id=") != std::string::npos) || (file.find(":10000") != std::string::npos) || (file.find(":8001/") != std::string::npos)) // for LocalTV and Entertain-TV streaming
no_probe = true;
if (file.substr(0, 7) == "file://")
{
if (file.substr(file.length() - 3) == ".ts")
@@ -117,6 +131,7 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
}
else
isHTTP = true;
PlayFiles_t playbackFiles = { (char *) file.c_str(), NULL, NULL, NULL, 0, 0, 0, 0};
if (player->playback->Command(player, PLAYBACK_OPEN, &playbackFiles) == 0)
{
@@ -140,15 +155,16 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
{
printf("AudioTrack List\n");
int i = 0;
for (i = 0; TrackList[i] != NULL; i+=2)
for (i = 0; TrackList[i] != NULL; i += 2)
{
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
printf("\t%s - %s\n", TrackList[i], TrackList[i + 1]);
free(TrackList[i]);
free(TrackList[i+1]);
free(TrackList[i + 1]);
}
free(TrackList);
}
}
//SUB
if (player && player->manager && player->manager->subtitle)
{
@@ -160,13 +176,14 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
int i = 0;
for (i = 0; TrackList[i] != NULL; i+=2)
{
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
printf("\t%s - %s\n", TrackList[i], TrackList[i + 1]);
free(TrackList[i]);
free(TrackList[i+1]);
free(TrackList[i + 1]);
}
free(TrackList);
}
}
/*
//Teletext
if (player && player->manager && player->manager->teletext)
@@ -177,15 +194,16 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
{
printf("TeletextTrack List\n");
int i = 0;
for (i = 0; TrackList[i] != NULL; i+=2)
for (i = 0; TrackList[i] != NULL; i += 2)
{
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
printf("\t%s - %s\n", TrackList[i], TrackList[i + 1]);
free(TrackList[i]);
free(TrackList[i+1]);
free(TrackList[i + 1]);
}
free(TrackList);
}
}
*/
//Chapters
if (player && player->manager && player->manager->chapter)
@@ -196,19 +214,21 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
{
printf("Chapter List\n");
int i = 0;
for (i = 0; TrackList[i] != NULL; i+=2)
for (i = 0; TrackList[i] != NULL; i += 2)
{
printf("\t%s - %s\n", TrackList[i], TrackList[i+1]);
printf("\t%s - %s\n", TrackList[i], TrackList[i + 1]);
free(TrackList[i]);
free(TrackList[i+1]);
free(TrackList[i + 1]);
}
free(TrackList);
}
}
playing = true;
first = true;
player->output->Command(player, OUTPUT_OPEN, NULL);
ret = (player->playback->Command(player, PLAYBACK_PLAY, NULL) == 0);
if (ret && !isHTTP)
playing = ret = (player->playback->Command(player, PLAYBACK_PAUSE, NULL) == 0);
}
@@ -219,17 +239,23 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
bool cPlayback::Stop(void)
{
lt_info("%s playing %d\n", __func__, playing);
if (player && player->playback)
player->playback->Command(player, PLAYBACK_STOP, NULL);
if (player && player->output)
player->output->Command(player, OUTPUT_CLOSE, NULL);
if (player && player->output)
{
player->output->Command(player, OUTPUT_DEL, (void *)"audio");
player->output->Command(player, OUTPUT_DEL, (void *)"video");
player->output->Command(player, OUTPUT_DEL, (void *)"subtitle");
}
if (player && player->playback)
player->playback->Command(player, PLAYBACK_CLOSE, NULL);
playing = false;
return true;
}
@@ -238,6 +264,7 @@ bool cPlayback::SetAPid(int pid, bool /* ac3 */)
{
lt_info("%s\n", __func__);
int i = pid;
if (pid != mAudioStream)
{
if (player && player->playback)
@@ -257,6 +284,7 @@ bool cPlayback::SetSubtitlePid(int pid)
{
lt_info("%s\n", __func__);
int i = pid;
if (pid != mSubtitleStream)
{
if (player && player->playback)
@@ -269,11 +297,13 @@ bool cPlayback::SetSubtitlePid(int pid)
bool cPlayback::SetTeletextPid(int pid)
{
lt_info("%s\n", __func__);
//int i = pid;
if (pid != mTeletextStream)
{
//if(player && player->playback)
//player->playback->Command(player, PLAYBACK_SWITCH_TELETEXT, (void*)&i);
//if (player && player->playback)
// player->playback->Command(player, PLAYBACK_SWITCH_TELETEXT, (void*)&i);
mTeletextStream = pid;
}
return true;
@@ -282,6 +312,7 @@ bool cPlayback::SetTeletextPid(int pid)
bool cPlayback::SetSpeed(int speed)
{
lt_info("%s playing %d speed %d\n", __func__, playing, speed);
if (!decoders_closed)
{
audioDecoder->closeDevice();
@@ -295,12 +326,15 @@ bool cPlayback::SetSpeed(int speed)
playing = true;
}
}
if (!playing)
return false;
if (player && player->playback)
{
int result = 0;
nPlaybackSpeed = speed;
if (speed > 1)
{
/* direction switch ? */
@@ -337,11 +371,13 @@ bool cPlayback::SetSpeed(int speed)
{
result = player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
}
if (init_jump > -1)
{
SetPosition(init_jump);
init_jump = -1;
}
if (result != 0)
{
printf("returning false\n");
@@ -369,6 +405,7 @@ bool cPlayback::GetPosition(int &position, int &duration)
{
bool got_duration = false;
lt_debug("%s %d %d\n", __func__, position, duration);
/* hack: if the file is growing (timeshift), then determine its length
* by comparing the mtime with the mtime of the xml file */
if (pm == PLAYMODE_TS)
@@ -390,17 +427,21 @@ bool cPlayback::GetPosition(int &position, int &duration)
}
}
}
if (!playing)
return false;
if (player && player->playback && !player->playback->isPlaying)
{
lt_info("%s !!!!EOF!!!! < -1\n", __func__);
position = duration + 1000;
return false;
}
int64_t vpts = 0;
if (player && player->playback)
player->playback->Command(player, PLAYBACK_PTS, &vpts);
if (vpts <= 0)
{
//printf("ERROR: vpts==0");
@@ -410,21 +451,31 @@ bool cPlayback::GetPosition(int &position, int &duration)
/* len is in nanoseconds. we have 90 000 pts per second. */
position = vpts / 90;
}
if (got_duration)
return true;
int64_t length = 0;
if (player && player->playback)
player->playback->Command(player, PLAYBACK_LENGTH, &length);
if (length <= 0)
{
duration = duration + 1000;
}
else
{
duration = length * 1000;
}
return true;
}
bool cPlayback::SetPosition(int position, bool absolute)
{
lt_info("%s %d\n", __func__, position);
if (playing && first)
{
/* the calling sequence is:
@@ -437,9 +488,12 @@ bool cPlayback::SetPosition(int position, bool absolute)
first = false;
return false;
}
int64_t pos = (position / 1000.0);
if (player && player->playback)
player->playback->Command(player, absolute ? PLAYBACK_SEEK_ABS : PLAYBACK_SEEK, (void *)&pos);
return true;
}
@@ -448,6 +502,7 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu
lt_info("%s\n", __func__);
int max_numpida = *numpida;
*numpida = 0;
if (player && player->manager && player->manager->audio)
{
char **TrackList = NULL;
@@ -467,9 +522,9 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu
{
apids[j] = _pid;
// atUnknown, atMPEG, atMP3, atAC3, atDTS, atAAC, atPCM, atOGG, atFLAC
if (!strncmp("A_MPEG/L3", TrackList[i + 1], 9))
if (!strncmp("A_MPEG/L3", TrackList[i + 1], 9))
ac3flags[j] = 3;
if (!strncmp("A_MP3", TrackList[i + 1], 5))
if (!strncmp("A_MP3", TrackList[i + 1], 5))
ac3flags[j] = 4;
else if (!strncmp("A_AC3", TrackList[i + 1], 5))
ac3flags[j] = 1;
@@ -502,8 +557,10 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu
void cPlayback::FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language)
{
lt_info("%s\n", __func__);
int max_numpids = *numpids;
*numpids = 0;
if (player && player->manager && player->manager->subtitle)
{
char **TrackList = NULL;
@@ -539,8 +596,8 @@ void cPlayback::FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpids
lt_info("%s\n", __func__);
//int max_numpids = *numpids;
*numpids = 0;
/*
if (player && player->manager && player->manager->teletext)
/* if (player && player->manager && player->manager->teletext)
{
char **TrackList = NULL;
player->manager->teletext->Command(player, MANAGER_LIST, &TrackList);
@@ -569,16 +626,15 @@ void cPlayback::FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpids
free(TrackList);
*numpids = j;
}
}
*/
} */
}
int cPlayback::GetTeletextPid(void)
{
lt_info("%s\n", __func__);
int pid = -1;
/*
if (player && player->manager && player->manager->teletext)
/* if (player && player->manager && player->manager->teletext)
{
char **TrackList = NULL;
player->manager->teletext->Command(player, MANAGER_LIST, &TrackList);
@@ -602,8 +658,8 @@ int cPlayback::GetTeletextPid(void)
}
free(TrackList);
}
}
*/
} */
printf("teletext pid id %d (0x%x)\n", pid, pid);
return pid;
}
@@ -625,6 +681,7 @@ void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string
{
positions.clear();
titles.clear();
if (player && player->manager && player->manager->chapter)
{
char **TrackList = NULL;
@@ -681,6 +738,7 @@ cPlayback::cPlayback(int num __attribute__((unused)))
cPlayback::~cPlayback()
{
lt_info("%s\n", __func__);
if (player)
free(player);
player = NULL;
@@ -727,6 +785,7 @@ void cPlayback::ReleaseAVFormatContext()
bool cPlayback::IsPlaying(void) const
{
lt_info("%s\n", __func__);
/* konfetti: there is no event/callback mechanism in libeplayer2
* so in case of ending playback we have no information on a
* terminated stream currently (or did I oversee it?).
@@ -736,6 +795,7 @@ bool cPlayback::IsPlaying(void) const
{
return player->playback->isPlaying;
}
return playing;
}
#endif

View File

@@ -1,30 +1,45 @@
AUTOMAKE_OPTIONS = subdir-objects
AM_CFLAGS = -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
CXXFLAGS = -Wall
noinst_LTLIBRARIES = libeplayer3_arm.la
AM_CFLAGS = -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
AM_CPPFLAGS = -I$(srcdir)/include
AM_CPPFLAGS += -I$(top_srcdir)/include
AM_CPPFLAGS += -I$(srcdir)/external
AM_CPPFLAGS = -I$(srcdir)/include
AM_CPPFLAGS += -I$(top_srcdir)/include
AM_CPPFLAGS += -I$(srcdir)/external
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
SOURCE_FILES = container/container.c
SOURCE_FILES += container/container_ffmpeg.c
SOURCE_FILES += manager/manager.c
SOURCE_FILES += manager/audio.c
SOURCE_FILES += manager/video.c
SOURCE_FILES += manager/chapter.c
SOURCE_FILES += manager/subtitle.c
SOURCE_FILES += output/output_subtitle.c
SOURCE_FILES += output/output.c
SOURCE_FILES += output/writer/common/pes.c
SOURCE_FILES += output/writer/common/misc.c
SOURCE_FILES += output/writer/common/writer.c
SOURCE_FILES += output/linuxdvb_buffering.c
SOURCE_FILES += playback/playback.c
SOURCE_FILES += external/ffmpeg/src/bitstream.c
SOURCE_FILES += external/ffmpeg/src/latmenc.c
SOURCE_FILES += external/ffmpeg/src/mpeg4audio.c
libeplayer3_arm_la_SOURCES = \
container/container.c \
container/container_ffmpeg.c \
manager/manager.c \
manager/audio.c \
manager/video.c \
manager/subtitle.c \
manager/chapter.c \
if ENABLE_FLV2MPEG4
AM_CFLAGS += -DHAVE_FLV2MPEG4_CONVERTER
AM_CPPFLAGS += -I$(srcdir)/external/flv2mpeg4
SOURCE_FILES += external/flv2mpeg4/src/m4vencode.c
SOURCE_FILES += external/flv2mpeg4/src/flvdecoder.c
SOURCE_FILES += external/flv2mpeg4/src/dcprediction.c
SOURCE_FILES += external/flv2mpeg4/src/flv2mpeg4.c
endif
SOURCE_FILES += \
output/linuxdvb_mipsel.c \
output/linuxdvb_buffering.c \
output/output_subtitle.c \
output/output.c \
output/writer/common/pes.c \
output/writer/common/misc.c \
output/writer/common/writer.c \
output/writer/mipsel/writer.c \
output/writer/mipsel/aac.c \
output/writer/mipsel/ac3.c \
@@ -42,15 +57,13 @@ libeplayer3_arm_la_SOURCES = \
output/writer/mipsel/divx3.c \
output/writer/mipsel/vp.c \
output/writer/mipsel/wmv.c \
output/writer/mipsel/vc1.c \
playback/playback.c \
external/ffmpeg/src/bitstream.c \
external/ffmpeg/src/latmenc.c \
external/ffmpeg/src/mpeg4audio.c
output/writer/mipsel/vc1.c
libeplayer3_arm_la_SOURCES = $(SOURCE_FILES)
LIBEPLAYER3_LIBS = libeplayer3_arm.la -lpthread -lavformat -lavcodec -lavutil -lswresample -lz -lm
LIBEPLAYER3_LIBS = libeplayer3_arm.la -lpthread -lavformat -lavcodec -lavutil -lswresample
bin_PROGRAMS = eplayer3
eplayer3_SOURCES = main/exteplayer.c
eplayer3_LDADD = $(LIBEPLAYER3_LIBS)
eplayer3_DEPENDENCIES = libeplayer3_arm.la

View File

@@ -80,13 +80,13 @@
static short debug_level = 1;
#define ffmpeg_printf(level, fmt, x...) do { \
if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
if (debug_level >= level) printf("[%s::%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
#else
#define ffmpeg_printf(level, fmt, x...)
#endif
#ifndef FFMPEG_SILENT
#define ffmpeg_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
#define ffmpeg_err(fmt, x...) do { printf("[%s::%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
#else
#define ffmpeg_err(fmt, x...)
#endif
@@ -105,6 +105,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x);
#define cERR_CONTAINER_FFMPEG_END_OF_FILE -10
#define IPTV_AV_CONTEXT_MAX_NUM 2
/* ***************************** */
/* Types */
/* ***************************** */
@@ -548,8 +549,7 @@ static void FFMPEGThread(Context_t *context)
threadname[16] = 0;
prctl(PR_SET_NAME, (unsigned long)&threadname);
AVPacket packet;
//off_t lastSeek = -1;
//int64_t lastPts = -1;
int64_t currentVideoPts = -1;
int64_t currentAudioPts = -1;
@@ -561,7 +561,6 @@ static void FFMPEGThread(Context_t *context)
int64_t showtime = 0;
int64_t bofcount = 0;
//int32_t err = 0;
AudioVideoOut_t avOut;
g_context = context;
@@ -583,13 +582,14 @@ static void FFMPEGThread(Context_t *context)
memset(&flv2mpeg4_context, 0, sizeof(Flv2Mpeg4Context));
#endif
ffmpeg_printf(10, "\n");
while (context->playback->isCreationPhase)
{
ffmpeg_printf(10, "Thread waiting for end of init phase...\n");
usleep(1000);
}
ffmpeg_printf(10, "Running!\n");
#ifdef __sh__
uint32_t bufferSize = 0;
context->output->Command(context, OUTPUT_GET_BUFFER_SIZE, &bufferSize);
@@ -597,6 +597,7 @@ static void FFMPEGThread(Context_t *context)
#endif
int8_t isWaitingForFinish = 0;
while (context && context->playback && context->playback->isPlaying)
{
/* When user press PAUSE we call pause on AUDIO and VIDEO decoders,
@@ -636,19 +637,24 @@ static void FFMPEGThread(Context_t *context)
}
continue;
}
if (context->playback->BackWard && av_gettime() >= showtime) {
if (context->playback->BackWard && av_gettime() >= showtime)
{
context->output->Command(context, OUTPUT_CLEAR, "video");
if (bofcount == 1) {
showtime = av_gettime();
usleep(100000);
continue;
if (bofcount == 1)
{
showtime = av_gettime();
usleep(100000);
continue;
}
if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) {
if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
{
off_t pos = avio_tell(avContextTab[0]->pb);
if (pos > 0) {
if (pos > 0)
{
float br;
if (avContextTab[0]->bit_rate)
br = avContextTab[0]->bit_rate / 8.0;
@@ -669,7 +675,7 @@ static void FFMPEGThread(Context_t *context)
seek_target_seconds = AV_TIME_BASE;
do_seek_target_seconds = 1;
}
showtime = av_gettime() + 300000; //jump back every 300ms
showtime = av_gettime() + 300000; //jump back every 300ms
}
else
{
@@ -770,15 +776,16 @@ static void FFMPEGThread(Context_t *context)
if (!isWaitingForFinish && (ffmpegStatus = av_read_frame(avContextTab[cAVIdx], &packet)) == 0)
{
int64_t pts = 0;
int64_t dts = 0;
Track_t *videoTrack = NULL;
Track_t *audioTrack = NULL;
int64_t pts = 0;
int64_t dts = 0;
Track_t *videoTrack = NULL;
Track_t *audioTrack = NULL;
Track_t *subtitleTrack = NULL;
int32_t pid = avContextTab[cAVIdx]->streams[packet.stream_index]->id;
reset_finish_timeout();
if (avContextTab[cAVIdx]->streams[packet.stream_index]->discard != AVDISCARD_ALL)
{
if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0)
@@ -992,6 +999,7 @@ static void FFMPEGThread(Context_t *context)
decoded_frame = NULL;
}
}
#if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32))
while (packet.size > 0 || (!packet.size && !packet.data))
#else
@@ -1059,6 +1067,7 @@ static void FFMPEGThread(Context_t *context)
continue;
}
#endif
int32_t e = 0;
if (!swr)
{
@@ -1085,6 +1094,7 @@ static void FFMPEGThread(Context_t *context)
{
c->channel_layout = av_get_default_channel_layout(c->channels);
}
out_channel_layout = c->channel_layout;
uint8_t downmix = stereo_software_decoder && out_channels > 2 ? 1 : 0;
@@ -1108,7 +1118,6 @@ static void FFMPEGThread(Context_t *context)
av_opt_set_int(swr, "in_sample_fmt", c->sample_fmt, 0);
av_opt_set_int(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
e = swr_init(swr);
if (e < 0)
{
@@ -1346,6 +1355,7 @@ static void FFMPEGThread(Context_t *context)
seek_target_seconds = 0;
do_seek_target_seconds = 0;
PlaybackDieNow(1);
ffmpeg_printf(10, "terminating\n");
}
@@ -1888,13 +1898,16 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
}
ffmpeg_printf(10, "filename %s\n", playFilesNames->szFirstFile);
if (playFilesNames->szSecondFile)
{
ffmpeg_printf(10, "second filename %s\n", playFilesNames->szSecondFile);
}
/* initialize ffmpeg */
avcodec_register_all();
av_register_all();
avformat_network_init();
// SULGE DEBUG ENABLED
@@ -1904,7 +1917,8 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
context->playback->abortRequested = 0;
int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \
playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0);
playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0);
if (0 != res)
{
return res;
@@ -1913,7 +1927,7 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
if (playFilesNames->szSecondFile && playFilesNames->szSecondFile[0] != '\0')
{
res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, playFilesNames->iSecondFileSize, \
playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1);
playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1);
}
if (0 != res)
@@ -1972,6 +1986,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
uint32_t cAVIdx = 0;
for (cAVIdx = 0; cAVIdx < IPTV_AV_CONTEXT_MAX_NUM; cAVIdx += 1)
{
if (NULL == avContextTab[cAVIdx])
@@ -2082,6 +2097,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
case AVMEDIA_TYPE_VIDEO:
ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n", get_codecpar(stream)->codec_type);
stream->discard = AVDISCARD_ALL; /* by default we discard all video streams */
if (encoding != NULL)
{
track.type = eTypeES;
@@ -2098,6 +2114,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
*/
track.aspect_ratio_num = stream->sample_aspect_ratio.num;
track.aspect_ratio_den = stream->sample_aspect_ratio.den;
if (0 == track.aspect_ratio_num || 0 == track.aspect_ratio_den)
{
track.aspect_ratio_num = get_codecpar(stream)->sample_aspect_ratio.num;
@@ -2117,6 +2134,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
}
/* fixme: revise this */
if (track.frame_rate < 23970)
{
track.TimeScale = 1001;
@@ -2181,6 +2199,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
case AVMEDIA_TYPE_AUDIO:
ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n", get_codecpar(stream)->codec_type);
stream->discard = AVDISCARD_ALL;
if (encoding != NULL)
{
AVDictionaryEntry *lang;
@@ -2199,6 +2218,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
track.have_aacheader = -1;
track.duration = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den);
if (stream->duration == AV_NOPTS_VALUE)
{
ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
@@ -2516,7 +2536,9 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
ffmpeg_printf(10, "CODEC_TYPE_SUBTITLE %d\n", get_codecpar(stream)->codec_type);
lang = av_dict_get(stream->metadata, "language", NULL, 0);
track.Name = lang ? lang->value : "und";
ffmpeg_printf(10, "Language %s\n", track.Name);
track.Encoding = encoding;
@@ -2597,6 +2619,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
}
releaseMutex(__FILE__, __FUNCTION__, __LINE__);
return cERR_CONTAINER_FFMPEG_NO_ERROR;
}
@@ -2625,14 +2648,12 @@ static int32_t container_ffmpeg_play(Context_t *context)
if ((error = pthread_create(&PlayThread, &attr, (void *)&FFMPEGThread, context)) != 0)
{
ffmpeg_printf(10, "Error creating thread, error:%d:%s\n", error, strerror(error));
hasPlayThreadStarted = 0;
ret = cERR_CONTAINER_FFMPEG_ERR;
}
else
{
ffmpeg_printf(10, "Created thread\n");
hasPlayThreadStarted = 1;
}
}
@@ -2643,6 +2664,7 @@ static int32_t container_ffmpeg_play(Context_t *context)
}
ffmpeg_printf(10, "exiting with value %d\n", ret);
return ret;
}
@@ -2672,6 +2694,7 @@ static int32_t container_ffmpeg_stop(Context_t *context)
{
/* force close */
ffmpeg_err("Timeout waiting for thread!\n");
ret = cERR_CONTAINER_FFMPEG_ERR;
/* to speed up close - we are in separate process for the moment this process will
* be closed and whole resources will be free by the system
@@ -2923,15 +2946,16 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab
}
ffmpeg_printf(10, "iformat->flags 0x%08x\n", avContextTab[0]->iformat->flags);
#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
{
/* konfetti: for ts streams seeking frame per seconds does not work (why?).
* I take this algo partly from ffplay.c.
*
* seeking per HTTP does still not work very good. forward seeks everytime
* about 10 seconds, backward does not work.
*/
* I take this algo partly from ffplay.c.
*
* seeking per HTTP does still not work very good. forward seeks everytime
* about 10 seconds, backward does not work.
*/
getMutex(__FILE__, __FUNCTION__, __LINE__);
off_t pos = avio_tell(avContextTab[0]->pb);
@@ -3029,6 +3053,7 @@ static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg __
{
ffmpeg_printf(10, "track %d\n", *arg);
getMutex(__FILE__, __FUNCTION__, __LINE__);
if (context->manager->audio)
{
Track_t *Tracks = NULL;
@@ -3129,7 +3154,7 @@ static int32_t container_ffmpeg_get_info(Context_t *context, char **infoString)
return cERR_CONTAINER_FFMPEG_NO_ERROR;
}
static int container_ffmpeg_get_metadata(Context_t * context, char ***p)
static int container_ffmpeg_get_metadata(Context_t *context, char ***p)
{
Track_t *videoTrack = NULL;
Track_t *audioTrack = NULL;
@@ -3251,12 +3276,12 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen
}
case CONTAINER_SWITCH_AUDIO:
{
ret = container_ffmpeg_switch_audio(context, (int32_t *) argument);
ret = container_ffmpeg_switch_audio(context, (int32_t *)argument);
break;
}
case CONTAINER_SWITCH_SUBTITLE:
{
ret = container_ffmpeg_switch_subtitle(context, (int32_t *) argument);
ret = container_ffmpeg_switch_subtitle(context, (int32_t *)argument);
break;
}
case CONTAINER_INFO:
@@ -3288,7 +3313,7 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen
}
case CONTAINER_GET_METADATA:
{
ret = container_ffmpeg_get_metadata(context, (char ***) argument);
ret = container_ffmpeg_get_metadata(context, (char ***)argument);
break;
}
default:
@@ -3298,6 +3323,7 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen
}
ffmpeg_printf(50, "exiting with value %d\n", ret);
return ret;
}

View File

@@ -45,7 +45,6 @@ typedef struct ContainerHandler_s
{
char *Name;
Container_t *selectedContainer;
int (* Command)(Context_t *, ContainerCmd_t, void *);
} ContainerHandler_t;

View File

@@ -44,7 +44,7 @@ typedef struct Track_s
/* new field for ffmpeg - add at the end so no problem
* can occur with not changed srt saa container
*/
char *language;
char *language;
/* length of track */
int64_t duration;

View File

@@ -4,7 +4,7 @@
#include <stdint.h>
#include <stdbool.h>
typedef void( * PlaybackDieNowCallback )();
typedef void(* PlaybackDieNowCallback)();
bool PlaybackDieNowRegisterCallback(PlaybackDieNowCallback callback);
typedef enum {

View File

@@ -252,11 +252,12 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
ptrManager->Command(g_player, MANAGER_LIST, &TrackList);
if (NULL != TrackList)
{
int i = 0, Id = -1;
int i = 0;
int Id = -1;
char * pch;
char Name[] = " ";
fprintf(stderr, "{\"%c_%c\": [", argvBuff[0], argvBuff[1]);
for (i = 0; TrackList[i] != NULL; i+=2)
for (i = 0; TrackList[i] != NULL; i += 2)
{
pch = strtok(TrackList[i], " ");
if (pch != NULL) {
@@ -272,7 +273,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
}
fprintf(stderr, "{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}", Id, TrackList[i+1], Name);
free(TrackList[i]);
free(TrackList[i+1]);
free(TrackList[i + 1]);
}
fprintf(stderr, "]}\n");
free(TrackList);
@@ -297,7 +298,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
else // video
{
fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d,\"an\":%d,\"ad\":%d}}\n", \
argvBuff[0], argvBuff[1], track->Id, track->Encoding, track->Name, track->width, track->height, track->frame_rate, track->progressive, track->aspect_ratio_num, track->aspect_ratio_den);
argvBuff[0], argvBuff[1], track->Id, track->Encoding, track->Name, track->width, track->height, track->frame_rate, track->progressive, track->aspect_ratio_num, track->aspect_ratio_den);
}
free(track->Encoding);
free(track->Name);
@@ -336,7 +337,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
{
int i = 0;
char * pch;
for (i = 0; TrackList[i] != NULL; i+=2)
for (i = 0; TrackList[i] != NULL; i += 2)
{
if (idx == i)
{
@@ -345,7 +346,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
id = atoi(pch);
}
free(TrackList[i]);
free(TrackList[i+1]);
free(TrackList[i + 1]);
}
free(TrackList);
}
@@ -501,7 +502,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
static void UpdateVideoTrack()
{
HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc");
HandleTracks(g_player->manager->video, (PlaybackCmd_t) -1, "vc");
}
static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int *pAudioTrackIdx, int *subtitleTrackIdx, uint32_t *linuxDvbBufferSizeMB)
@@ -657,6 +658,7 @@ static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int *
ret = 0;
playbackFiles->szFirstFile = malloc(IPTV_MAX_FILE_PATH);
playbackFiles->szFirstFile[0] = '\0';
if (NULL == strstr(argv[optind], "://"))
{
strcpy(playbackFiles->szFirstFile, "file://");
@@ -693,6 +695,7 @@ int main(int argc, char *argv[])
PlayFiles_t playbackFiles;
memset(&playbackFiles, 0x00, sizeof(playbackFiles));
if (0 != ParseParams(argc, argv, &playbackFiles, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB))
{
printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n");
@@ -816,24 +819,24 @@ int main(int argc, char *argv[])
{
PlaybackDieNowRegisterCallback(TerminateWakeUp);
HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc");
HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "al");
HandleTracks(g_player->manager->video, (PlaybackCmd_t) -1, "vc");
HandleTracks(g_player->manager->audio, (PlaybackCmd_t) -1, "al");
if (audioTrackIdx >= 0)
{
static char cmd[128] = ""; // static to not allocate on stack
sprintf(cmd, "ai%d\n", audioTrackIdx);
commandRetVal = HandleTracks(g_player->manager->audio, PLAYBACK_SWITCH_AUDIO, cmd);
}
HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "ac");
HandleTracks(g_player->manager->audio, (PlaybackCmd_t) -1, "ac");
HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sl");
HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) -1, "sl");
if (subtitleTrackIdx >= 0)
{
static char cmd[128] = ""; // static to not allocate on stack
sprintf(cmd, "si%d\n", subtitleTrackIdx);
commandRetVal = HandleTracks(g_player->manager->subtitle, PLAYBACK_SWITCH_SUBTITLE, cmd);
}
HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sc");
HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) -1, "sc");
}
while (g_player->playback->isPlaying && 0 == PlaybackDieNow(0))
@@ -855,7 +858,7 @@ int main(int argc, char *argv[])
{
case 'v':
{
HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, argvBuff);
HandleTracks(g_player->manager->video, (PlaybackCmd_t) -1, argvBuff);
break;
}
case 'a':
@@ -966,10 +969,12 @@ int main(int argc, char *argv[])
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts);
CurrentSec = (int32_t)(pts / 90000);
if (0 == commandRetVal)
{
fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90);
}
if (0 == commandRetVal || force)
{
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length);
@@ -1016,6 +1021,7 @@ int main(int argc, char *argv[])
{
int64_t lastPts = 0;
commandRetVal = 1;
if (g_player->container && g_player->container->selectedContainer)
{
commandRetVal = g_player->container->selectedContainer->Command((Context_t*)g_player->container, CONTAINER_LAST_PTS, &lastPts);

View File

@@ -46,7 +46,7 @@
static short debug_level = 40;
#define audio_mgr_printf(level, fmt, x...) do { \
if (debug_level >= level) printf("[%s:%s] \n" fmt, __FILE__, __FUNCTION__, ## x); } while (0)
if (debug_level >= level) printf("[%s::%s] \n" fmt, __FILE__, __FUNCTION__, ## x); } while (0)
#else
#define audio_mgr_printf(level, x...)
#endif
@@ -97,7 +97,7 @@ static int ManagerAdd(Context_t *context, Track_t track)
if (Tracks == NULL)
{
audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__);
audio_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__);
return cERR_AUDIO_MGR_ERROR;
}
@@ -118,7 +118,7 @@ static int ManagerAdd(Context_t *context, Track_t track)
}
else
{
audio_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP);
audio_mgr_err("%s::%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP);
return cERR_AUDIO_MGR_ERROR;
}
@@ -128,6 +128,7 @@ static int ManagerAdd(Context_t *context, Track_t track)
}
audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
return cERR_AUDIO_MGR_NO_ERROR;
}
@@ -137,13 +138,14 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
char **tracklist = NULL;
audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
if (Tracks != NULL)
{
tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1));
if (tracklist == NULL)
{
audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__);
audio_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__);
return NULL;
}
@@ -160,9 +162,9 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
tracklist[j] = strdup(tmp);
tracklist[j + 1] = strdup(Tracks[i].Encoding);
}
tracklist[j] = NULL;
}
audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount);
return tracklist;
@@ -181,7 +183,7 @@ static TrackDescription_t *ManagerList(Context_t *context __attribute__((unused
if (tracklist == NULL)
{
audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__);
audio_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__);
return NULL;
}
@@ -256,7 +258,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
{
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
// *((TrackDescription_t **)argument) = ManagerList(context);
*((char ** *) argument) = (char **) ManagerList(context);
*((char ***)argument) = (char **)ManagerList(context);
break;
}
case MANAGER_REF_LIST:
@@ -279,7 +281,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
}
else
{
*((int *)argument) = (int) - 1;
*((int *)argument) = (int) -1;
}
break;
}
@@ -292,9 +294,9 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
if (track)
{
memset(track, 0, sizeof(TrackDescription_t));
track->Id = Tracks[CurrentTrack].Id;
track->Name = strdup(Tracks[CurrentTrack].Name);
track->Encoding = strdup(Tracks[CurrentTrack].Encoding);
track->Id = Tracks[CurrentTrack].Id;
track->Name = strdup(Tracks[CurrentTrack].Name);
track->Encoding = strdup(Tracks[CurrentTrack].Encoding);
}
}
else
@@ -382,7 +384,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
break;
}
audio_mgr_printf(10, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret);
audio_mgr_printf(10, "%s::%s returning %d\n", __FILE__, __FUNCTION__, ret);
return ret;
}

View File

@@ -118,7 +118,7 @@ static int ManagerAdd(Context_t *context __attribute__((unused)), Track_t track)
}
else
{
subtitle_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP);
subtitle_mgr_err("%s::%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP);
return cERR_SUBTITLE_MGR_ERROR;
}
@@ -134,8 +134,8 @@ static int ManagerAdd(Context_t *context __attribute__((unused)), Track_t track)
static char **ManagerList(Context_t *context __attribute__((unused)))
{
char **tracklist = NULL;
int i = 0, j = 0;
char **tracklist = NULL;
subtitle_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
@@ -145,7 +145,7 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
if (tracklist == NULL)
{
subtitle_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__);
subtitle_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__);
return NULL;
}
@@ -162,7 +162,6 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
tracklist[j] = strdup(tmp);
tracklist[j + 1] = strdup(Tracks[i].Encoding);
}
tracklist[j] = NULL;
}
@@ -219,18 +218,20 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
case MANAGER_LIST:
{
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
*((char ** *)argument) = (char **)ManagerList(context);
*((char ***)argument) = (char **)ManagerList(context);
break;
}
case MANAGER_GET:
{
subtitle_mgr_printf(20, "%s::%s MANAGER_GET\n", FILENAME, __FUNCTION__);
if (TrackCount > 0 && CurrentTrack >= 0)
{
*((int *)argument) = (int)Tracks[CurrentTrack].Id;
}
else
{
*((int *)argument) = (int) - 1;
*((int *)argument) = (int) -1;
}
break;
}
@@ -243,9 +244,9 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
if (track)
{
memset(track, 0, sizeof(TrackDescription_t));
track->Id = Tracks[CurrentTrack].Id;
track->Name = strdup(Tracks[CurrentTrack].Name);
track->Encoding = strdup(Tracks[CurrentTrack].Encoding);
track->Id = Tracks[CurrentTrack].Id;
track->Name = strdup(Tracks[CurrentTrack].Name);
track->Encoding = strdup(Tracks[CurrentTrack].Encoding);
}
}
else
@@ -256,6 +257,8 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
}
case MANAGER_GET_TRACK:
{
subtitle_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME, __FUNCTION__);
if ((TrackCount > 0) && (CurrentTrack >= 0))
{
*((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack];
@@ -293,6 +296,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
case MANAGER_SET:
{
int i;
subtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", __FILE__, __FUNCTION__, *((int *)argument));
if (*((int *)argument) < 0)
@@ -332,12 +336,12 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
break;
}
default:
subtitle_mgr_err("%s:%s: ContainerCmd not supported!", __FILE__, __FUNCTION__);
subtitle_mgr_err("%s::%s ContainerCmd not supported!", __FILE__, __FUNCTION__);
ret = cERR_SUBTITLE_MGR_ERROR;
break;
}
subtitle_mgr_printf(50, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret);
subtitle_mgr_printf(50, "%s::%s returning %d\n", __FILE__, __FUNCTION__, ret);
return ret;
}

View File

@@ -97,7 +97,7 @@ static int ManagerAdd(Context_t *context, Track_t track)
if (Tracks == NULL)
{
video_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__);
video_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__);
return cERR_VIDEO_MGR_ERROR;
}
@@ -118,7 +118,7 @@ static int ManagerAdd(Context_t *context, Track_t track)
}
else
{
video_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP);
video_mgr_err("%s::%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP);
return cERR_VIDEO_MGR_ERROR;
}
@@ -128,6 +128,7 @@ static int ManagerAdd(Context_t *context, Track_t track)
}
video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
return cERR_VIDEO_MGR_NO_ERROR;
}
@@ -144,7 +145,7 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
if (tracklist == NULL)
{
video_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__);
video_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__);
return NULL;
}
@@ -164,6 +165,7 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
}
video_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount);
return tracklist;
}
@@ -213,7 +215,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
case MANAGER_LIST:
{
container_ffmpeg_update_tracks(context, context->playback->uri, 0);
*((char ** *)argument) = (char **)ManagerList(context);
*((char ***)argument) = (char **)ManagerList(context);
break;
}
case MANAGER_GET:
@@ -224,7 +226,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
}
else
{
*((int *)argument) = (int) - 1;
*((int *)argument) = (int) -1;
}
break;
}
@@ -342,7 +344,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
break;
}
video_mgr_printf(10, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret);
video_mgr_printf(10, "%s::%s returning %d\n", __FILE__, __FUNCTION__, ret);
return ret;
}

View File

@@ -252,6 +252,7 @@ int LinuxDvbPlay(Context_t *context, char *type)
linuxdvb_printf(10, "V %s\n", Encoding);
writer = getWriter(Encoding);
if (writer == NULL)
{
linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding);
@@ -324,7 +325,6 @@ int LinuxDvbPlay(Context_t *context, char *type)
ret = cERR_LINUXDVB_NO_ERROR;
return ret;
//return 0;
}
int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
@@ -354,6 +354,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type)
ioctl(videofd, VIDEO_FAST_FORWARD, 0);
ioctl(videofd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
}
if (audio && audiofd != -1)
{
if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1)
@@ -634,6 +635,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i
}
*((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS;
return ret;
}
@@ -1095,7 +1097,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
case OUTPUT_GET_BUFFER_SIZE:
{
ret = cERR_LINUXDVB_NO_ERROR;
*((uint32_t*)argument) = LinuxDvbBuffGetSize();
*((uint32_t *)argument) = LinuxDvbBuffGetSize();
break;
}
default:

View File

@@ -90,6 +90,7 @@ static void printOutputCapabilities()
for (i = 0; AvailableOutput[i] != NULL; i++)
{
output_printf(10, "\t%s : ", AvailableOutput[i]->Name);
for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++)
{
output_printf(10, "%s ", AvailableOutput[i]->Capabilities[j]);
@@ -191,10 +192,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
ret |= context->output->video->Command(context, OUTPUT_CLOSE, "video");
}
if (context->playback->isAudio)
{
ret |= context->output->audio->Command(context, OUTPUT_CLOSE, "audio");
}
if (context->playback->isSubtitle)
{
ret |= context->output->subtitle->Command(context, OUTPUT_CLOSE, "subtitle");
@@ -238,6 +241,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio");
}
if (!ret)
{
if (context->playback->isSubtitle)
@@ -260,10 +264,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
ret |= context->output->video->Command(context, OUTPUT_STOP, "video");
}
if (context->playback->isAudio)
{
ret |= context->output->audio->Command(context, OUTPUT_STOP, "audio");
}
if (context->playback->isSubtitle)
{
ret |= context->output->subtitle->Command(context, OUTPUT_STOP, "subtitle");
@@ -283,10 +289,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
ret |= context->output->video->Command(context, OUTPUT_FLUSH, "video");
}
if (context->playback->isAudio)
{
ret |= context->output->audio->Command(context, OUTPUT_FLUSH, "audio");
}
if (context->playback->isSubtitle)
{
ret |= context->output->subtitle->Command(context, OUTPUT_FLUSH, "subtitle");
@@ -306,10 +314,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
ret |= context->output->video->Command(context, OUTPUT_PAUSE, "video");
}
if (context->playback->isAudio)
{
ret |= context->output->audio->Command(context, OUTPUT_PAUSE, "audio");
}
if (context->playback->isSubtitle)
{
ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle");
@@ -329,6 +339,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
ret |= context->output->video->Command(context, OUTPUT_FASTFORWARD, "video");
}
if (context->playback->isAudio)
{
ret |= context->output->audio->Command(context, OUTPUT_FASTFORWARD, "audio");
@@ -348,6 +359,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
ret |= context->output->video->Command(context, OUTPUT_REVERSE, "video");
}
if (context->playback->isAudio)
{
ret |= context->output->audio->Command(context, OUTPUT_REVERSE, "audio");
@@ -367,10 +379,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
ret |= context->output->video->Command(context, OUTPUT_CONTINUE, "video");
}
if (context->playback->isAudio)
{
ret |= context->output->audio->Command(context, OUTPUT_CONTINUE, "audio");
}
if (context->playback->isSubtitle)
{
ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle");
@@ -405,10 +419,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
ret |= context->output->video->Command(context, OUTPUT_CLEAR, "video");
}
if (context->playback->isAudio && (argument == NULL || *(char *) argument == 'a'))
{
ret |= context->output->audio->Command(context, OUTPUT_CLEAR, "audio");
}
if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's'))
{
ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle");
@@ -428,6 +444,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
return context->output->video->Command(context, OUTPUT_PTS, argument);
}
if (context->playback->isAudio)
{
return context->output->audio->Command(context, OUTPUT_PTS, argument);
@@ -447,10 +464,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
return context->output->audio->Command(context, OUTPUT_SWITCH, "audio");
}
if (context->playback->isVideo)
{
return context->output->video->Command(context, OUTPUT_SWITCH, "video");
}
if (context->playback->isSubtitle)
{
return context->output->subtitle->Command(context, OUTPUT_SWITCH, "subtitle");
@@ -470,6 +489,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
ret |= context->output->video->Command(context, OUTPUT_SLOWMOTION, "video");
}
if (context->playback->isAudio)
{
ret |= context->output->audio->Command(context, OUTPUT_SLOWMOTION, "audio");
@@ -519,6 +539,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument)
{
return context->output->video->Command(context, OUTPUT_GET_FRAME_COUNT, argument);
}
if (context->playback->isAudio)
{
return context->output->audio->Command(context, OUTPUT_GET_FRAME_COUNT, argument);

View File

@@ -266,8 +266,6 @@ static int32_t subtitle_Open(Context_t *context __attribute__((unused)))
static int32_t subtitle_Close(Context_t *context __attribute__((unused)))
{
//uint32_t i = 0 ;
subtitle_printf(10, "\n");
getMutex(__LINE__);
@@ -341,6 +339,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument __att
}
subtitle_printf(50, "exiting with value %d\n", ret);
return ret;
}

View File

@@ -70,5 +70,5 @@ if (debug_level >= level) printf(x); } while (0)
void FlushPipe(int pipefd)
{
char tmp;
while(1 == read(pipefd, &tmp, 1));
while (1 == read(pipefd, &tmp, 1));
}

View File

@@ -52,6 +52,7 @@
/* ***************************** */
/* Makros/Constants */
/* ***************************** */
#define PES_AUDIO_PRIVATE_HEADER_SIZE 16 // consider maximum private header size.
#define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE)
#define PES_AUDIO_PACKET_SIZE 2028

View File

@@ -169,6 +169,7 @@ static int writeData(WriterAVCallData_t *call)
iov[0].iov_len = headerSize;
iov[1].iov_base = call->data;
iov[1].iov_len = call->len;
return call->WriteV(call->fd, iov, 2);
}

View File

@@ -54,7 +54,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x);
#define cERR_PLAYBACK_NO_ERROR 0
#define cERR_PLAYBACK_ERROR -1
#define cMaxSpeed_ff 128 /* fixme: revise */
#define cMaxSpeed_ff 128 /* fixme: revise */
#define cMaxSpeed_fr -320 /* fixme: revise */
#define MAX_PLAYBACK_DIE_NOW_CALLBACKS 10
@@ -140,6 +140,7 @@ static void SupervisorThread(Context_t *context)
{
usleep(100000);
}
playback_printf(10, "<\n");
hasThreadStarted = 2;
PlaybackTerminate(context);
@@ -293,6 +294,7 @@ static int PlaybackPlay(Context_t *context)
{
playback_err("OUTPUT_PLAY failed!\n");
playback_err("clearing isCreationPhase!\n");
context->playback->isCreationPhase = 0; // allow thread to go into next state
context->playback->isPlaying = 0;
context->playback->isPaused = 0;
@@ -300,6 +302,7 @@ static int PlaybackPlay(Context_t *context)
context->playback->BackWard = 0;
context->playback->SlowMotion = 0;
context->playback->Speed = 0;
if (context->container && context->container->selectedContainer)
ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
}
@@ -317,7 +320,8 @@ static int PlaybackPlay(Context_t *context)
int error;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if ((error = pthread_create(&supervisorThread, &attr, (void *) &SupervisorThread, context)) != 0)
if ((error = pthread_create(&supervisorThread, &attr, (void *)&SupervisorThread, context)) != 0)
{
playback_printf(10, "Error creating thread, error:%d:%s\n", error, strerror(error));
ret = cERR_PLAYBACK_ERROR;
@@ -334,11 +338,11 @@ static int PlaybackPlay(Context_t *context)
if (context->container && context->container->selectedContainer)
ret = context->container->selectedContainer->Command(context, CONTAINER_PLAY, NULL);
if (ret != 0)
{
playback_err("CONTAINER_PLAY failed!\n");
}
}
}
else
@@ -363,10 +367,9 @@ static int PlaybackPause(Context_t *context)
if (context->playback->SlowMotion)
context->output->Command(context, OUTPUT_CLEAR, NULL);
context->playback->isPaused = 1;
context->output->Command(context, OUTPUT_PAUSE, NULL);
context->playback->isPaused = 1;
//context->playback->isPlaying = 1;
context->playback->isForwarding = 0;
context->playback->BackWard = 0;
@@ -396,6 +399,8 @@ static int32_t PlaybackContinue(Context_t *context)
if (context->playback->SlowMotion || context->playback->isForwarding || context->playback->BackWard)
context->output->Command(context, OUTPUT_CLEAR, NULL);
context->output->Command(context, OUTPUT_CONTINUE, NULL);
if (context->playback->BackWard)
context->output->Command(context, OUTPUT_AUDIOMUTE, "0");
@@ -405,7 +410,6 @@ static int32_t PlaybackContinue(Context_t *context)
context->playback->BackWard = 0;
context->playback->SlowMotion = 0;
context->playback->Speed = 1;
context->output->Command(context, OUTPUT_CONTINUE, NULL);
}
else
{
@@ -414,6 +418,7 @@ static int32_t PlaybackContinue(Context_t *context)
}
playback_printf(10, "exiting with value %d\n", ret);
return ret;
}
@@ -428,7 +433,6 @@ static int32_t PlaybackStop(Context_t *context)
if (context && context->playback && context->playback->isPlaying)
{
context->playback->isPaused = 0;
context->playback->isPlaying = 0;
context->playback->isForwarding = 0;
@@ -438,7 +442,6 @@ static int32_t PlaybackStop(Context_t *context)
context->output->Command(context, OUTPUT_STOP, NULL);
context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
}
else
{
@@ -459,13 +462,13 @@ static int32_t PlaybackStop(Context_t *context)
}
playback_printf(10, "exiting with value %d\n", ret);
return ret;
}
static int32_t PlaybackTerminate(Context_t *context)
{
int32_t ret = cERR_PLAYBACK_NO_ERROR;
int wait_time = 20;
playback_printf(20, "\n");
@@ -475,12 +478,13 @@ static int32_t PlaybackTerminate(Context_t *context)
if (context && context->playback && context->playback->isPlaying)
{
//First Flush and than delete container, else e2 cant read length of file anymore
if (context->output->Command(context, OUTPUT_FLUSH, NULL) < 0)
{
playback_err("failed to flush output.\n");
}
ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
context->playback->isPaused = 0;
context->playback->isPlaying = 0;
context->playback->isForwarding = 0;
@@ -488,7 +492,6 @@ static int32_t PlaybackTerminate(Context_t *context)
context->playback->SlowMotion = 0;
context->playback->Speed = 0;
context->output->Command(context, OUTPUT_STOP, NULL);
ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
}
else
{
@@ -513,6 +516,7 @@ static int32_t PlaybackTerminate(Context_t *context)
}
playback_printf(20, "exiting with value %d\n", ret);
return ret;
}
@@ -530,6 +534,7 @@ static int PlaybackFastForward(Context_t *context, int *speed)
playback_err("speed %d out of range (1 - %d) \n", *speed, cMaxSpeed_ff);
return cERR_PLAYBACK_ERROR;
}
context->playback->isForwarding = 1;
context->playback->Speed = *speed;
playback_printf(20, "Speed: %d x {%d}\n", *speed, context->playback->Speed);
@@ -562,19 +567,30 @@ static int PlaybackFastBackward(Context_t *context, int *speed)
playback_err("speed %d out of range (0 - %d) \n", *speed, cMaxSpeed_fr);
return cERR_PLAYBACK_ERROR;
}
PlaybackContinue(context);
if (*speed == 0)
{
context->playback->BackWard = 0;
context->playback->Speed = 0; /* reverse end */
context->playback->isPaused = 0;
//context->playback->isPlaying = 0;
context->playback->isForwarding = 0;
context->playback->BackWard = 0;
context->playback->SlowMotion = 0;
context->playback->Speed = 0;
context->output->Command(context, OUTPUT_AUDIOMUTE, "0");
}
else
{
context->playback->isSeeking = 1;
context->playback->Speed = *speed;
context->playback->BackWard = 1;
context->playback->isPaused = 0;
//context->playback->isPlaying = 0;
context->playback->isForwarding = 0;
context->playback->BackWard = 1;
context->playback->SlowMotion = 0;
context->playback->Speed = *speed;
context->playback->isSeeking = 1;
context->output->Command(context, OUTPUT_AUDIOMUTE, "1");
playback_printf(1, "S %d B %d\n", context->playback->Speed, context->playback->BackWard);
playback_printf(1, "Speed: %d, Backward: %d\n", context->playback->Speed, context->playback->BackWard);
}
context->output->Command(context, OUTPUT_CLEAR, NULL);
@@ -602,6 +618,7 @@ static int32_t PlaybackSlowMotion(Context_t *context, int *speed)
{
if (context->playback->isPaused)
PlaybackContinue(context);
switch (*speed)
{
case 2:
@@ -614,7 +631,9 @@ static int32_t PlaybackSlowMotion(Context_t *context, int *speed)
context->playback->SlowMotion = 8;
break;
}
playback_printf(20, "SlowMotion: %d x {%d}\n", *speed, context->playback->SlowMotion);
context->output->Command(context, OUTPUT_SLOWMOTION, NULL);
}
else
@@ -727,6 +746,7 @@ static int32_t PlaybackLength(Context_t *context, int64_t *length)
}
playback_printf(20, "exiting with value %d\n", ret);
return ret;
}
@@ -754,7 +774,6 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track)
if (nextrackid != curtrackid)
{
//PlaybackPause(context);
if (context->output && context->output->audio)
{
@@ -775,6 +794,7 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track)
}
playback_printf(10, "exiting with value %d\n", ret);
return ret;
}
@@ -861,7 +881,6 @@ static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument
playback_printf(20, "Command %d\n", command);
switch (command)
{
case PLAYBACK_OPEN:
@@ -899,6 +918,11 @@ static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument
ret = PlaybackTerminate(context);
break;
}
case PLAYBACK_FASTFORWARD:
{
ret = PlaybackFastForward(context, (int *)argument);
break;
}
case PLAYBACK_SEEK:
{
ret = PlaybackSeek(context, (int64_t *)argument, 0);
@@ -944,11 +968,6 @@ static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument
ret = PlaybackFastBackward(context, (int *)argument);
break;
}
case PLAYBACK_FASTFORWARD:
{
ret = PlaybackFastForward(context, (int *)argument);
break;
}
case PLAYBACK_GET_FRAME_COUNT:
{
ret = PlaybackGetFrameCount(context, (uint64_t *)argument);

View File

@@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libeplayer3.la
AM_CPPFLAGS = -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
AM_CPPFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
AM_CPPFLAGS += -I$(srcdir)/include -I$(top_srcdir)/include
AM_CPPFLAGS += -I$(srcdir)/include
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
libeplayer3_la_SOURCES = \

View File

@@ -26,7 +26,9 @@
#include <vector>
#include <map>
#include <scoped_lock.h>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Thread>
#include <OpenThreads/Condition>
extern "C" {
#include <libavutil/avutil.h>
@@ -46,7 +48,7 @@ class Input
friend int interrupt_cb(void *arg);
private:
Mutex mutex;
OpenThreads::Mutex mutex;
Track *videoTrack;
Track *audioTrack;

View File

@@ -26,7 +26,9 @@
#include <vector>
#include <map>
#include <scoped_lock.h>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Thread>
#include <OpenThreads/Condition>
extern "C" {
#include <libavutil/avutil.h>
@@ -64,7 +66,7 @@ class Manager
private:
Player *player;
Mutex mutex;
OpenThreads::Mutex mutex;
std::map<int,Track*> videoTracks, audioTracks, subtitleTracks, teletextTracks;
std::map<int,Program> Programs;
void addTrack(std::map<int,Track*> &tracks, Track &track);

View File

@@ -26,7 +26,9 @@
#include <vector>
#include <map>
#include <scoped_lock.h>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Thread>
#include <OpenThreads/Condition>
extern "C" {
#include <libavutil/avutil.h>
@@ -48,7 +50,7 @@ class Output
int videofd;
int audiofd;
Writer *videoWriter, *audioWriter;
Mutex audioMutex, videoMutex;
OpenThreads::Mutex audioMutex, videoMutex;
Track *audioTrack, *videoTrack;
Player *player;
public:

View File

@@ -21,7 +21,9 @@
#ifndef __PLAYER_H__
#define __PLAYER_H__
#include <scoped_lock.h>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Thread>
#include <OpenThreads/Condition>
extern "C" {
#include <libavutil/avutil.h>
@@ -61,7 +63,7 @@ class Player {
Input input;
Output output;
Manager manager;
Mutex chapterMutex;
OpenThreads::Mutex chapterMutex;
std::vector<Chapter> chapters;
pthread_t playThread;

View File

@@ -290,17 +290,17 @@ static int lock_callback(void **mutex, enum AVLockOp op)
{
switch (op) {
case AV_LOCK_CREATE:
*mutex = (void *) new Mutex;
*mutex = (void *) new OpenThreads::Mutex;
return !*mutex;
case AV_LOCK_DESTROY:
delete static_cast<Mutex *>(*mutex);
delete static_cast<OpenThreads::Mutex *>(*mutex);
*mutex = NULL;
return 0;
case AV_LOCK_OBTAIN:
static_cast<Mutex *>(*mutex)->lock();
static_cast<OpenThreads::Mutex *>(*mutex)->lock();
return 0;
case AV_LOCK_RELEASE:
static_cast<Mutex *>(*mutex)->unlock();
static_cast<OpenThreads::Mutex *>(*mutex)->unlock();
return 0;
default:
return -1;
@@ -656,7 +656,7 @@ bool Input::Stop()
av_log(NULL, AV_LOG_QUIET, "%s", "");
if (avfc) {
ScopedLock lock(mutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mutex);
for (unsigned int i = 0; i < avfc->nb_streams; i++)
avcodec_close(avfc->streams[i]->codec);
avformat_close_input(&avfc);

View File

@@ -25,7 +25,7 @@
void Manager::addTrack(std::map<int,Track*> &tracks, Track &track)
{
ScopedLock m_lock(mutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
std::map<int,Track*>::iterator it = tracks.find(track.pid);
if (it == tracks.end()) {
Track *t = new Track;
@@ -59,7 +59,7 @@ std::vector<Track> Manager::getTracks(std::map<int,Track*> &tracks)
{
player->input.UpdateTracks();
std::vector<Track> res;
ScopedLock m_lock(mutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
for(std::map<int,Track*>::iterator it = tracks.begin(); it != tracks.end(); ++it)
if (!it->second->inactive && !it->second->hidden)
res.push_back(*it->second);
@@ -88,7 +88,7 @@ std::vector<Track> Manager::getTeletextTracks()
Track *Manager::getTrack(std::map<int,Track*> &tracks, int pid)
{
ScopedLock m_lock(mutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
std::map<int,Track*>::iterator it = tracks.find(pid);
if (it != tracks.end() && !it->second->inactive)
return it->second;
@@ -116,7 +116,7 @@ Track *Manager::getTeletextTrack(int pid)
bool Manager::initTrackUpdate()
{
ScopedLock m_lock(mutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
for (std::map<int,Track*>::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it)
it->second->inactive = !it->second->is_static;
@@ -140,7 +140,7 @@ void Manager::addProgram(Program &program)
std::vector<Program> Manager::getPrograms(void)
{
ScopedLock m_lock(mutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
std::vector<Program> res;
for (std::map<int,Program>::iterator it = Programs.begin(); it != Programs.end(); ++it)
res.push_back(it->second);
@@ -149,7 +149,7 @@ std::vector<Program> Manager::getPrograms(void)
bool Manager::selectProgram(const int id)
{
ScopedLock m_lock(mutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
std::map<int,Program>::iterator i = Programs.find(id);
if (i != Programs.end()) {
@@ -236,7 +236,7 @@ bool Manager::selectProgram(const int id)
void Manager::clearTracks()
{
ScopedLock m_lock(mutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
for (std::map<int,Track*>::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it)
delete it->second;

View File

@@ -68,9 +68,9 @@ Output::~Output()
bool Output::Open()
{
ScopedLock v_lock(videoMutex);
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
if (videofd < 0)
videofd = open(VIDEODEV, O_RDWR);
@@ -102,8 +102,8 @@ bool Output::Close()
{
Stop();
ScopedLock v_lock(videoMutex);
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
if (videofd > -1) {
close(videofd);
@@ -124,8 +124,8 @@ bool Output::Play()
{
bool ret = true;
ScopedLock v_lock(videoMutex);
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
AVCodecContext *avcc;
@@ -154,8 +154,8 @@ bool Output::Stop()
{
bool ret = true;
ScopedLock v_lock(videoMutex);
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
if (videofd > -1) {
ioctl(videofd, VIDEO_CLEAR_BUFFER, NULL);
@@ -180,8 +180,8 @@ bool Output::Pause()
{
bool ret = true;
ScopedLock v_lock(videoMutex);
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
if (videofd > -1) {
if (dioctl(videofd, VIDEO_FREEZE, NULL))
@@ -200,8 +200,8 @@ bool Output::Continue()
{
bool ret = true;
ScopedLock v_lock(videoMutex);
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
if (videofd > -1 && dioctl(videofd, VIDEO_CONTINUE, NULL))
ret = false;
@@ -214,7 +214,7 @@ bool Output::Continue()
bool Output::Mute(bool b)
{
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
//AUDIO_SET_MUTE has no effect with new player
return audiofd > -1 && !dioctl(audiofd, b ? AUDIO_STOP : AUDIO_PLAY, NULL);
}
@@ -224,8 +224,8 @@ bool Output::Flush()
{
bool ret = true;
ScopedLock v_lock(videoMutex);
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
if (videofd > -1 && ioctl(videofd, VIDEO_FLUSH, NULL))
ret = false;
@@ -246,31 +246,31 @@ bool Output::Flush()
bool Output::FastForward(int speed)
{
ScopedLock v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
return videofd > -1 && !dioctl(videofd, VIDEO_FAST_FORWARD, speed);
}
bool Output::SlowMotion(int speed)
{
ScopedLock v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
return videofd > -1 && !dioctl(videofd, VIDEO_SLOWMOTION, speed);
}
bool Output::AVSync(bool b)
{
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
return audiofd > -1 && !dioctl(audiofd, AUDIO_SET_AV_SYNC, b);
}
bool Output::ClearAudio()
{
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
return audiofd > -1 && !ioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL);
}
bool Output::ClearVideo()
{
ScopedLock v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
return videofd > -1 && !ioctl(videofd, VIDEO_CLEAR_BUFFER, NULL);
}
@@ -302,7 +302,7 @@ bool Output::GetFrameCount(int64_t &framecount)
bool Output::SwitchAudio(Track *track)
{
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
if (audioTrack && track->stream == audioTrack->stream)
return true;
if (audiofd > -1) {
@@ -329,7 +329,7 @@ bool Output::SwitchAudio(Track *track)
bool Output::SwitchVideo(Track *track)
{
ScopedLock v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
if (videoTrack && track->stream == videoTrack->stream)
return true;
if (videofd > -1) {
@@ -355,11 +355,11 @@ bool Output::Write(AVStream *stream, AVPacket *packet, int64_t pts)
{
switch (stream->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO: {
ScopedLock v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
return videofd > -1 && videoWriter && videoWriter->Write(packet, pts);
}
case AVMEDIA_TYPE_AUDIO: {
ScopedLock a_lock(audioMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
return audiofd > -1 && audioWriter && audioWriter->Write(packet, pts);
}
default:

View File

@@ -372,7 +372,7 @@ bool Player::GetChapters(std::vector<int> &positions, std::vector<std::string> &
positions.clear();
titles.clear();
input.UpdateTracks();
ScopedLock m_lock(chapterMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(chapterMutex);
for (std::vector<Chapter>::iterator it = chapters.begin(); it != chapters.end(); ++it) {
positions.push_back(it->start/1000);
titles.push_back(it->title);
@@ -382,7 +382,7 @@ bool Player::GetChapters(std::vector<int> &positions, std::vector<std::string> &
void Player::SetChapters(std::vector<Chapter> &Chapters)
{
ScopedLock m_lock(chapterMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(chapterMutex);
chapters = Chapters;
}

View File

@@ -1,16 +0,0 @@
noinst_LTLIBRARIES = libthread.la
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS
AM_CPPFLAGS += \
-I$(top_srcdir)/include
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = -lpthread -lrt
libthread_la_SOURCES = \
condition_abstraction.cpp \
reentrant_mutex.cpp \
scoped_lock.cpp \
thread_abstraction.cpp \
mutex_abstraction.cpp

View File

@@ -1,27 +0,0 @@
#include <condition_abstraction.h>
Condition::Condition() :
mCondition()
{
pthread_cond_init(&mCondition, 0);
}
Condition::~Condition()
{
pthread_cond_destroy(&mCondition);
}
int Condition::wait(Mutex* const aMutex)
{
return pthread_cond_wait(&mCondition, &(aMutex->mMutex));
}
int Condition::broadcast()
{
return pthread_cond_broadcast(&mCondition);
}
int Condition::signal()
{
return pthread_cond_signal(&mCondition);
}

View File

@@ -1,32 +0,0 @@
#include <mutex_abstraction.h>
Mutex::Mutex() :
mMutex()
{
pthread_mutex_init(&mMutex, 0);
}
Mutex::Mutex(int attr) :
mMutex()
{
pthread_mutexattr_t Attr;
pthread_mutexattr_init(&Attr);
pthread_mutexattr_settype(&Attr, attr);
pthread_mutex_init(&mMutex, &Attr);
}
Mutex::~Mutex()
{
pthread_mutex_destroy(&mMutex);
}
void Mutex::lock()
{
pthread_mutex_lock(&mMutex);
}
void Mutex::unlock()
{
pthread_mutex_unlock(&mMutex);
}

View File

@@ -1,11 +0,0 @@
#include <reentrant_mutex.h>
ReentrantMutex::ReentrantMutex() :
Mutex(PTHREAD_MUTEX_RECURSIVE)
{
}
ReentrantMutex::~ReentrantMutex()
{
//safely destroyed in ~Mutex();
}

View File

@@ -1,12 +0,0 @@
#include <scoped_lock.h>
ScopedLock::ScopedLock(Mutex& aMutex) :
mMutex(aMutex)
{
mMutex.lock();
}
ScopedLock::~ScopedLock()
{
mMutex.unlock();
}

View File

@@ -1,58 +0,0 @@
#include <thread_abstraction.h>
Thread::Thread() :
mIsRunning(false),
mThread()
{
}
Thread::~Thread()
{
// if thread is still running on object destruction, cancel thread the hard way:
if (mIsRunning)
{
pthread_cancel(mThread);
}
}
int Thread::startThread()
{
mIsRunning = true;
return pthread_create(&mThread, 0, &Thread::runThread, this);
}
int Thread::cancelThread()
{
return pthread_cancel(mThread);
mIsRunning = false;
}
int Thread::detachThread()
{
mIsRunning = false; // thread shall not cancel on object destruction!
return pthread_detach(mThread);
}
int Thread::joinThread()
{
int ret = pthread_join(mThread, 0);
mIsRunning = false;
return ret;
}
int Thread::setCancelModeDisable()
{
return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
}
int Thread::setSchedulePriority(int prio)
{
return pthread_setschedprio(mThread, prio);
}
void* Thread::runThread(void* ptr)
{
Thread* t = static_cast<Thread*>(ptr);
t->run();
return 0;
}

View File

@@ -10,7 +10,8 @@ AM_CPPFLAGS += \
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = \
-L/opt/vc/lib/ -lopenmaxil -lbcm_host -lvcos -lvchiq_arm -lpthread -lrt
-L/opt/vc/lib/ -lopenmaxil -lbcm_host -lvcos -lvchiq_arm -lpthread -lrt \
-lOpenThreads
libraspi_la_SOURCES = \
hardware_caps.c \

View File

@@ -19,7 +19,7 @@
*/
#include <vector>
#include <condition_abstraction.h>
#include <OpenThreads/Condition>
#include "glfb.h"
#include "bcm_host.h"
@@ -47,8 +47,8 @@ static int curr_res;
static int pitch;
static VC_IMAGE_TYPE_T type = VC_IMAGE_ARGB8888;
static Mutex blit_mutex;
static Condition blit_cond;
static OpenThreads::Mutex blit_mutex;
static OpenThreads::Condition blit_cond;
static bool goodbye = false; /* if set main loop is left */
static bool ready = false; /* condition predicate */
@@ -71,7 +71,7 @@ GLFramebuffer::GLFramebuffer(int x, int y)
si.red.offset = 16;
si.transp.offset = 24;
Thread::start();
OpenThreads::Thread::start();
while (!ready)
usleep(1);
}
@@ -80,7 +80,7 @@ GLFramebuffer::~GLFramebuffer()
{
goodbye = true;
blit(); /* wake up thread */
Thread::join();
OpenThreads::Thread::join();
}
void GLFramebuffer::run()

View File

@@ -17,11 +17,11 @@
#ifndef __glthread__
#define __glthread__
#include <thread_abstraction.h>
#include <OpenThreads/Thread>
#include <vector>
#include <linux/fb.h> /* for screeninfo etc. */
class GLFramebuffer : public Thread
class GLFramebuffer : public OpenThreads::Thread
{
public:
GLFramebuffer(int x, int y);
@@ -34,7 +34,7 @@ private:
void *pdata; /* not yet used */
fb_var_screeninfo si;
std::vector<unsigned char> osd_buf; /* silly bounce buffer */
void run(); /* for Thread */
void run(); /* for OpenThreads::Thread */
void setup();
void blit_osd();

View File

@@ -32,7 +32,7 @@
#include <set>
#include <map>
#include <thread_abstraction.h>
#include <OpenThreads/Thread>
#include "init_td.h"
#include "lt_debug.h"
@@ -69,7 +69,7 @@ static void init_keymap(void)
kmap[KEY_F8] = KEY_SLEEP;
}
class Input: public Thread
class Input: public OpenThreads::Thread
{
public:
Input();
@@ -82,13 +82,13 @@ class Input: public Thread
Input::Input()
{
Init();
Thread::start();
start();
}
Input::~Input()
{
running = false;
Thread::join();
join();
}
static int dirfilter(const struct dirent *d)