Origin commit data
------------------
Branch: master
Commit: c6876f3996
Author: Frankenstone <dampf_acc@online.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:
Frankenstone
2018-10-02 13:27:50 +02:00
56 changed files with 1185 additions and 665 deletions

View File

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

View File

@@ -152,11 +152,11 @@ AC_SUBST(PLUGINDIR)
AC_SUBST(THEMESDIR) AC_SUBST(THEMESDIR)
dnl end workaround dnl end workaround
AC_DEFUN([TUXBOX_BOXTYPE],[ AC_DEFUN([TUXBOX_BOXTYPE], [
AC_ARG_WITH(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 [case "${withval}" in
tripledragon|azbox|generic) tripledragon|azbox|generic|armbox)
BOXTYPE="$withval" BOXTYPE="$withval"
;; ;;
spark|spark7162) spark|spark7162)

View File

@@ -20,6 +20,18 @@ AC_DISABLE_STATIC
AC_SYS_LARGEFILE AC_SYS_LARGEFILE
AC_PROG_LIBTOOL 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 if test x"$BOXTYPE" = x"tripledragon"; then
PKG_CHECK_MODULES([DIRECTFB], [directfb]) PKG_CHECK_MODULES([DIRECTFB], [directfb])
fi fi
@@ -54,6 +66,9 @@ if test x$BOXTYPE = xarmbox -a "$enable_gstreamer_10" = "yes"; then
fi fi
if test x$BOXTYPE = xgeneric -a x$BOXMODEL != xraspi; then 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([AVFORMAT], [libavformat >= 53.21.1])
PKG_CHECK_MODULES([AVCODEC], [libavcodec >= 54.28.0]) PKG_CHECK_MODULES([AVCODEC], [libavcodec >= 54.28.0])
# don't know which version is exactly needed here... # 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]) PKG_CHECK_MODULES([SWRESAMPLE], [libswresample])
fi 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([ AC_OUTPUT([
Makefile Makefile
common/Makefile common/Makefile
libeplayer3/Makefile libeplayer3/Makefile
libeplayer3-arm/Makefile libeplayer3-arm/Makefile
libthread/Makefile
azbox/Makefile azbox/Makefile
generic-pc/Makefile generic-pc/Makefile
libduckbox/Makefile libduckbox/Makefile

View File

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

View File

@@ -29,6 +29,7 @@
#define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args) #define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args)
#define lt_info(args...) _lt_info(HAL_DEBUG_AUDIO, this, args) #define lt_info(args...) _lt_info(HAL_DEBUG_AUDIO, this, args)
#include <OpenThreads/Thread>
extern "C" { extern "C" {
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
@@ -104,7 +105,7 @@ int cAudio::Start(void)
{ {
lt_debug("%s >\n", __func__); lt_debug("%s >\n", __func__);
if (! HAL_nodec) if (! HAL_nodec)
Thread::startThread(); OpenThreads::Thread::start();
lt_debug("%s <\n", __func__); lt_debug("%s <\n", __func__);
return 0; return 0;
} }
@@ -115,7 +116,7 @@ int cAudio::Stop(void)
if (thread_started) if (thread_started)
{ {
thread_started = false; thread_started = false;
Thread::joinThread(); OpenThreads::Thread::join();
} }
lt_debug("%s <\n", __func__); lt_debug("%s <\n", __func__);
return 0; return 0;
@@ -201,8 +202,34 @@ void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &m
freq = 0; freq = 0;
bitrate = 0; /* not used, but easy to get :-) */ bitrate = 0; /* not used, but easy to get :-) */
mode = 0; /* default: stereo */ mode = 0; /* default: stereo */
printf("cAudio::getAudioInfo c %p\n", c);
if (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; freq = c->sample_rate;
bitrate = c->bit_rate; bitrate = c->bit_rate;
if (c->channels == 1) 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", 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*/) 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_ #define _AUDIO_LIB_H_
#include <stdint.h> #include <stdint.h>
#include <thread_abstraction.h> #include <OpenThreads/Thread>
#include "cs_types.h" #include "cs_types.h"
typedef enum typedef enum
@@ -38,7 +38,7 @@ typedef enum
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT; } AUDIO_FORMAT;
class cAudio : public Thread class cAudio : public OpenThreads::Thread
{ {
friend class cPlayback; friend class cPlayback;
private: 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 */ /* map the device numbers. for now only demux0 is used */
#define NUM_DEMUXDEV 1 static const char *devname[] = {
static const char *devname[NUM_DEMUXDEV] = {
"/dev/dvb/adapter0/demux0", "/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 */ /* uuuugly */
static int dmx_tp_count = 0; static int dmx_tp_count = 0;
#define MAX_TS_COUNT 8 #define MAX_TS_COUNT 8
@@ -492,28 +489,12 @@ int cDemux::getUnit(void)
bool cDemux::SetSource(int unit, int source) bool cDemux::SetSource(int unit, int source)
{ {
//lt_info_c("%s(%d, %d): not implemented yet\n", __func__, unit, 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;
return true; return true;
} }
int cDemux::GetSource(int unit) int cDemux::GetSource(int unit)
{ {
//lt_info_c("%s(%d): not implemented yet\n", __func__, unit); lt_info_c("%s(%d): not implemented yet\n", __func__, unit);
//return 0; 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];
} }

View File

@@ -22,6 +22,7 @@
TODO: AV-Sync code is "experimental" at best TODO: AV-Sync code is "experimental" at best
*/ */
#include "config.h"
#include <vector> #include <vector>
#include <sys/types.h> #include <sys/types.h>
@@ -37,8 +38,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <linux/input.h> #include <linux/input.h>
#include "glfb.h" #include "glfb_priv.h"
#include <GL/glx.h>
#include "video_lib.h" #include "video_lib.h"
#include "audio_lib.h" #include "audio_lib.h"
@@ -53,10 +53,36 @@
extern cVideo *videoDecoder; extern cVideo *videoDecoder;
extern cAudio *audioDecoder; 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.width = x;
mState.height = y; mState.height = y;
mX = &_mX[0]; mX = &_mX[0];
@@ -77,19 +103,19 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn
last_apts = 0; last_apts = 0;
/* linux framebuffer compat mode */ /* linux framebuffer compat mode */
screeninfo.bits_per_pixel = 32; si.bits_per_pixel = 32;
screeninfo.xres = mState.width; si.xres = mState.width;
screeninfo.xres_virtual = screeninfo.xres; si.xres_virtual = si.xres;
screeninfo.yres = mState.height; si.yres = mState.height;
screeninfo.yres_virtual = screeninfo.yres; si.yres_virtual = si.yres;
screeninfo.blue.length = 8; si.blue.length = 8;
screeninfo.blue.offset = 0; si.blue.offset = 0;
screeninfo.green.length = 8; si.green.length = 8;
screeninfo.green.offset = 8; si.green.offset = 8;
screeninfo.red.length = 8; si.red.length = 8;
screeninfo.red.offset = 16; si.red.offset = 16;
screeninfo.transp.length = 8; si.transp.length = 8;
screeninfo.transp.offset = 24; si.transp.offset = 24;
unlink("/tmp/neutrino.input"); unlink("/tmp/neutrino.input");
mkfifo("/tmp/neutrino.input", 0600); mkfifo("/tmp/neutrino.input", 0600);
@@ -97,21 +123,22 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn
if (input_fd < 0) if (input_fd < 0)
lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__); lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__);
initKeys(); initKeys();
Thread::startThread();
while (!mInitDone)
usleep(1);
} }
GLFramebuffer::~GLFramebuffer() GLFbPC::~GLFbPC()
{ {
mShutDown = true; mShutDown = true;
Thread::joinThread();
if (input_fd >= 0) if (input_fd >= 0)
close(input_fd); 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_UP] = KEY_UP;
mSpecialMap[GLUT_KEY_DOWN] = KEY_DOWN; mSpecialMap[GLUT_KEY_DOWN] = KEY_DOWN;
mSpecialMap[GLUT_KEY_LEFT] = KEY_LEFT; mSpecialMap[GLUT_KEY_LEFT] = KEY_LEFT;
@@ -176,9 +203,21 @@ void GLFramebuffer::initKeys()
void GLFramebuffer::run() void GLFramebuffer::run()
{ {
setupCtx(); int argc = 1;
setupOSDBuffer(); int x = glfb_priv->mState.width;
mInitDone = true; /* signal that setup is finished */ 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 */ /* init the good stuff */
GLenum err = glewInit(); GLenum err = glewInit();
@@ -193,16 +232,15 @@ void GLFramebuffer::run()
} }
else else
{ {
gThiz = this;
glutSetCursor(GLUT_CURSOR_NONE); glutSetCursor(GLUT_CURSOR_NONE);
glutDisplayFunc(GLFramebuffer::rendercb); glutDisplayFunc(GLFbPC::rendercb);
glutKeyboardFunc(GLFramebuffer::keyboardcb); glutKeyboardFunc(GLFbPC::keyboardcb);
glutSpecialFunc(GLFramebuffer::specialcb); glutSpecialFunc(GLFbPC::specialcb);
glutReshapeFunc(GLFramebuffer::resizecb); glutReshapeFunc(GLFbPC::resizecb);
setupGLObjects(); /* needs GLEW prototypes */ glfb_priv->setupGLObjects(); /* needs GLEW prototypes */
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
glutMainLoop(); glutMainLoop();
releaseGLObjects(); glfb_priv->releaseGLObjects();
} }
} }
else else
@@ -210,21 +248,20 @@ void GLFramebuffer::run()
lt_info("GLFB: GL thread stopping\n"); lt_info("GLFB: GL thread stopping\n");
} }
#if 0
void GLFramebuffer::setupCtx() void GLFbPC::setupCtx()
{ {
int argc = 1; int argc = 1;
/* some dummy commandline for GLUT to be happy */ /* some dummy commandline for GLUT to be happy */
char const *argv[2] = { "neutrino", 0 }; char const *argv[2] = { "neutrino", 0 };
lt_info("GLFB: GL thread starting\n"); lt_info("GLFB: GL thread starting x %d y %d\n", mX[0], mY[0]);
glutInit(&argc, const_cast<char **>(argv)); glutInit(&argc, const_cast<char **>(argv));
glutInitWindowSize(mX[0], mY[0]); glutInitWindowSize(mX[0], mY[0]);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Neutrino"); 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 { /* the OSD buffer size can be decoupled from the actual
window size since the GL can blit-stretch with no window size since the GL can blit-stretch with no
trouble at all, ah, the luxury of ignorance... */ 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 */ /* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */
int fbmem = mState.width * mState.height * 4 * 2; int fbmem = mState.width * mState.height * 4 * 2;
mOSDBuffer.resize(fbmem); osd_buf->resize(fbmem);
lt_info("GLFB: OSD buffer set to %d bytes\n", 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 */ unsigned char buf[4] = { 0, 0, 0, 0 }; /* 1 black pixel */
glGenTextures(1, &mState.osdtex); glGenTextures(1, &mState.osdtex);
@@ -266,7 +304,7 @@ void GLFramebuffer::setupGLObjects()
} }
void GLFramebuffer::releaseGLObjects() void GLFbPC::releaseGLObjects()
{ {
glDeleteBuffers(1, &mState.pbo); glDeleteBuffers(1, &mState.pbo);
glDeleteBuffers(1, &mState.displaypbo); 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); lt_debug_c("GLFB::%s: 0x%x\n", __func__, key);
struct input_event ev; struct input_event ev;
if (key == 'f') if (key == 'f')
{ {
lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, gThiz->mFullscreen?"off":"on"); lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, glfb_priv->mFullscreen?"off":"on");
gThiz->mFullscreen = !(gThiz->mFullscreen); glfb_priv->mFullscreen = !(glfb_priv->mFullscreen);
gThiz->mReInit = true; glfb_priv->mReInit = true;
return; return;
} }
std::map<unsigned char, int>::const_iterator i = gThiz->mKeyMap.find(key); std::map<unsigned char, int>::const_iterator i = glfb_priv->mKeyMap.find(key);
if (i == gThiz->mKeyMap.end()) if (i == glfb_priv->mKeyMap.end())
return; return;
ev.code = i->second; ev.code = i->second;
ev.value = 1; /* key own */ ev.value = 1; /* key own */
ev.type = EV_KEY; ev.type = EV_KEY;
gettimeofday(&ev.time, NULL); gettimeofday(&ev.time, NULL);
lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code); 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 */ 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); lt_debug_c("GLFB::%s: 0x%x\n", __func__, key);
struct input_event ev; struct input_event ev;
std::map<int, int>::const_iterator i = gThiz->mSpecialMap.find(key); std::map<int, int>::const_iterator i = glfb_priv->mSpecialMap.find(key);
if (i == gThiz->mSpecialMap.end()) if (i == glfb_priv->mSpecialMap.end())
return; return;
ev.code = i->second; ev.code = i->second;
ev.value = 1; ev.value = 1;
ev.type = EV_KEY; ev.type = EV_KEY;
gettimeofday(&ev.time, NULL); gettimeofday(&ev.time, NULL);
lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code); 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; ev.value = 0;
write(gThiz->input_fd, &ev, sizeof(ev)); write(glfb_priv->input_fd, &ev, sizeof(ev));
} }
int sleep_us = 30000; int sleep_us = 30000;
void GLFramebuffer::render() void GLFbPC::render()
{ {
if(mShutDown) if(mShutDown)
glutLeaveMainLoop(); glutLeaveMainLoop();
@@ -452,12 +490,12 @@ void GLFramebuffer::render()
glutPostRedisplay(); 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; static int last_x = 0, last_y = 0;
@@ -477,7 +515,7 @@ void GLFramebuffer::checkReinit(int x, int y)
last_y = y; last_y = y;
} }
void GLFramebuffer::drawSquare(float size, float x_factor) void GLFbPC::drawSquare(float size, float x_factor)
{ {
GLfloat vertices[] = { GLfloat vertices[] = {
1.0f, 1.0f, 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 */ /* FIXME: copy each time */
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mState.pbo); 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); glBindTexture(GL_TEXTURE_2D, mState.osdtex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mState.width, mState.height, GL_BGRA, GL_UNSIGNED_BYTE, 0); 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); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
} }
void GLFramebuffer::bltDisplayBuffer() void GLFbPC::bltDisplayBuffer()
{ {
if (!videoDecoder) /* cannot start yet */ if (!videoDecoder) /* cannot start yet */
return; return;
@@ -553,7 +591,7 @@ void GLFramebuffer::bltDisplayBuffer()
cVideo::SWFramebuffer *buf = videoDecoder->getDecBuf(); cVideo::SWFramebuffer *buf = videoDecoder->getDecBuf();
if (!buf) { if (!buf) {
if (warn) 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; warn = false;
return; 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", 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); 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 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 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 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 You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. 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__ #ifndef __glfb_priv__
#define __glthread__ #define __glfb_priv__
#include <thread_abstraction.h> #include <OpenThreads/Mutex>
#include <mutex_abstraction.h>
#include <vector> #include <vector>
#include <map> #include <map>
#if USE_OPENGL
#include <GL/glew.h> #include <GL/glew.h>
#include <GL/freeglut.h> #include <GL/freeglut.h>
#include <GL/gl.h> #include <GL/gl.h>
#include <linux/fb.h> /* for screeninfo etc. */ #include <linux/fb.h> /* for screeninfo etc. */
#endif
#if USE_CLUTTER
#include <clutter/clutter.h>
#endif
#include "glfb.h"
extern "C" { extern "C" {
#include <libavutil/rational.h> #include <libavutil/rational.h>
} }
class GLFramebuffer : public Thread class GLFbPC
{ {
public: public:
GLFramebuffer(int x, int y); GLFbPC(int x, int y, std::vector<unsigned char> &buf);
~GLFramebuffer(); ~GLFbPC();
std::vector<unsigned char> *getOSDBuffer() { return osd_buf; } /* pointer to OSD bounce buffer */
void run();
std::vector<unsigned char> *getOSDBuffer() { return &mOSDBuffer; } /* pointer to OSD bounce buffer */
int getOSDWidth() { return mState.width; } int getOSDWidth() { return mState.width; }
int getOSDHeight() { return mState.height; } 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 setOutputFormat(AVRational a, int h, int c) { mOA = a; *mY = h; mCrop = c; mReInit = true; }
/* just make everything public for simplicity - this is only used inside libstb-hal anyway
void clear();
fb_var_screeninfo getScreenInfo() { return screeninfo; }
int getWindowID() { return GLWinID; }
private: private:
fb_var_screeninfo screeninfo; */
fb_var_screeninfo si;
int *mX; int *mX;
int *mY; int *mY;
int _mX[2]; /* output window size */ int _mX[2]; /* output window size */
@@ -63,45 +65,59 @@ private:
float zoom; /* for cropping */ float zoom; /* for cropping */
float xscale; /* and aspect ratio */ float xscale; /* and aspect ratio */
int mCrop; /* DISPLAY_AR_MODE */ int mCrop; /* DISPLAY_AR_MODE */
int GLWinID;
bool mFullscreen; /* fullscreen? */ bool mFullscreen; /* fullscreen? */
bool mReInit; /* setup things for GL */ bool mReInit; /* setup things for GL */
Mutex mReInitLock; OpenThreads::Mutex mReInitLock;
bool mShutDown; /* if set main loop is left */ bool mShutDown; /* if set main loop is left */
bool mInitDone; /* condition predicate */ bool mInitDone; /* condition predicate */
// OpenThreads::Condition mInitCond; /* condition variable for init */ // OpenThreads::Condition mInitCond; /* condition variable for init */
// mutable OpenThreads::Mutex mMutex; /* lock our data */ // 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<unsigned char, int> mKeyMap;
std::map<int, int> mSpecialMap; std::map<int, int> mSpecialMap;
#endif
#if USE_CLUTTER
std::map<int, int> mKeyMap;
#endif
int input_fd; int input_fd;
int64_t last_apts; int64_t last_apts;
void run();
static void rendercb(); /* callback for GLUT */ static void rendercb(); /* callback for GLUT */
void render(); /* actual render function */ void render(); /* actual render function */
#if USE_OPENGL
static void keyboardcb(unsigned char key, int x, int y); static void keyboardcb(unsigned char key, int x, int y);
static void specialcb(int key, int x, int y); static void specialcb(int key, int x, int y);
static void resizecb(int w, int h); static void resizecb(int w, int h);
void checkReinit(int w, int h); /* e.g. in case window was resized */ 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 setupGLObjects(); /* PBOs, textures and stuff */
void releaseGLObjects(); void releaseGLObjects();
void drawSquare(float size, float x_factor = 1); /* do not be square */ 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 { struct {
int width; /* width and height, fixed for a framebuffer instance */ int width; /* width and height, fixed for a framebuffer instance */
int height; int height;
bool blit;
#if USE_OPENGL
GLuint osdtex; /* holds the OSD texture */ GLuint osdtex; /* holds the OSD texture */
GLuint pbo; /* PBO we use for transfer to texture */ GLuint pbo; /* PBO we use for transfer to texture */
GLuint displaytex; /* holds the display texture */ GLuint displaytex; /* holds the display texture */
GLuint displaypbo; GLuint displaypbo;
bool blit; #endif
} mState; } mState;
void bltOSDBuffer(); void bltOSDBuffer();

View File

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

View File

@@ -30,7 +30,6 @@
#include <pthread.h> #include <pthread.h>
#include <syscall.h> #include <syscall.h>
#include "dmx_lib.h"
#include "audio_lib.h" #include "audio_lib.h"
#include "video_lib.h" #include "video_lib.h"
#include "glfb.h" #include "glfb.h"

View File

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

View File

@@ -1,8 +1,8 @@
#ifndef _VIDEO_LIB_H #ifndef _VIDEO_LIB_H
#define _VIDEO_LIB_H #define _VIDEO_LIB_H
#include <thread_abstraction.h> #include <OpenThreads/Thread>
#include <mutex_abstraction.h> #include <OpenThreads/Mutex>
#include <vector> #include <vector>
#include <linux/dvb/video.h> #include <linux/dvb/video.h>
#include "cs_types.h" #include "cs_types.h"
@@ -120,10 +120,10 @@ typedef enum
} VIDEO_CONTROL; } VIDEO_CONTROL;
#define VDEC_MAXBUFS 0x30 #define VDEC_MAXBUFS 0x40
class cVideo : public Thread class cVideo : public OpenThreads::Thread
{ {
friend class GLFramebuffer; friend class GLFbPC;
friend class cDemux; friend class cDemux;
private: private:
/* called from GL thread */ /* called from GL thread */
@@ -211,8 +211,7 @@ class cVideo : public Thread
bool thread_running; bool thread_running;
VIDEO_FORMAT v_format; VIDEO_FORMAT v_format;
VIDEO_STD v_std; VIDEO_STD v_std;
//OpenThreads::Mutex buf_m; OpenThreads::Mutex buf_m;
Mutex buf_m;
DISPLAY_AR display_aspect; DISPLAY_AR display_aspect;
DISPLAY_AR_MODE display_crop; DISPLAY_AR_MODE display_crop;
int output_h; int output_h;
@@ -221,7 +220,7 @@ class cVideo : public Thread
int pig_w; int pig_w;
int pig_h; int pig_h;
bool pig_changed; bool pig_changed;
Mutex still_m; OpenThreads::Mutex still_m;
bool stillpicture; 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 Copyright 2010 Carsten Juttner <carjay@gmx.net>
#if BOXMODEL_RASPI Copyright 2012,2013 Stefan Seyfried <seife@tuxboxcvs.slipkontur.de>
#include "../raspi/glfb.h"
#else This program is free software; you can redistribute it and/or modify
#include "../generic-pc/glfb.h" it under the terms of the GNU General Public License as published by
#endif the Free Software Foundation; either version 2 of the License, or
#else (at your option) any later version.
#error glfb.h only works with HAVE_GENERIC_HARDWARE defined
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 #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; last_size = 0;
nPlaybackSpeed = 0; nPlaybackSpeed = 0;
init_jump = -1; init_jump = -1;
if (player) if (player)
free(player); free(player);
player = NULL; player = NULL;
player = (Context_t *) malloc(sizeof(Context_t)); player = (Context_t *) malloc(sizeof(Context_t));
if (player) if (player)
{ {
player->playback = &PlaybackHandler; player->playback = &PlaybackHandler;
player->output = &OutputHandler; player->output = &OutputHandler;
player->container = &ContainerHandler; player->container = &ContainerHandler;
player->manager = &ManagerHandler; player->manager = &ManagerHandler;
lt_info("%s - player output name: %s PlayMode: %s\n", __func__, player->output->Name, aPLAYMODE[PlayMode]); lt_info("%s - player output name: %s PlayMode: %s\n", __func__, player->output->Name, aPLAYMODE[PlayMode]);
} }
//Registration of output devices //Registration of output devices
if (player && player->output) if (player && player->output)
{ {
player->output->Command(player, OUTPUT_ADD, (void *)"audio"); player->output->Command(player, OUTPUT_ADD, (void *)"audio");
player->output->Command(player, OUTPUT_ADD, (void *)"video"); player->output->Command(player, OUTPUT_ADD, (void *)"video");
player->output->Command(player, OUTPUT_ADD, (void *)"subtitle");
} }
return 0; return 0;
} }
void cPlayback::Close(void) void cPlayback::Close(void)
{ {
lt_info("%s\n", __func__); lt_info("%s\n", __func__);
//Dagobert: movieplayer does not call stop, it calls close ;) //Dagobert: movieplayer does not call stop, it calls close ;)
if(playing) if(playing)
Stop(); Stop();
if (decoders_closed) if (decoders_closed)
{ {
audioDecoder->openDevice(); audioDecoder->openDevice();
@@ -92,7 +101,9 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
bool ret = false; bool ret = false;
bool isHTTP = false; bool isHTTP = false;
no_probe = false; no_probe = false;
lt_info("%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d\n", __func__, filename, vpid, vtype, apid, ac3); lt_info("%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d\n", __func__, filename, vpid, vtype, apid, ac3);
init_jump = -1; init_jump = -1;
//create playback path //create playback path
mAudioStream = 0; mAudioStream = 0;
@@ -100,11 +111,14 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
mTeletextStream = -1; mTeletextStream = -1;
unlink("/tmp/.id3coverart"); unlink("/tmp/.id3coverart");
std::string file; std::string file;
if (*filename == '/') if (*filename == '/')
file = "file://"; file = "file://";
file += filename; 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 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; no_probe = true;
if (file.substr(0, 7) == "file://") if (file.substr(0, 7) == "file://")
{ {
if (file.substr(file.length() - 3) == ".ts") 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 else
isHTTP = true; isHTTP = true;
PlayFiles_t playbackFiles = { (char *) file.c_str(), NULL, NULL, NULL, 0, 0, 0, 0}; PlayFiles_t playbackFiles = { (char *) file.c_str(), NULL, NULL, NULL, 0, 0, 0, 0};
if (player->playback->Command(player, PLAYBACK_OPEN, &playbackFiles) == 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"); printf("AudioTrack List\n");
int i = 0; 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]);
free(TrackList[i+1]); free(TrackList[i + 1]);
} }
free(TrackList); free(TrackList);
} }
} }
//SUB //SUB
if (player && player->manager && player->manager->subtitle) 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; 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]);
free(TrackList[i+1]); free(TrackList[i + 1]);
} }
free(TrackList); free(TrackList);
} }
} }
/* /*
//Teletext //Teletext
if (player && player->manager && player->manager->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"); printf("TeletextTrack List\n");
int i = 0; 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]);
free(TrackList[i+1]); free(TrackList[i + 1]);
} }
free(TrackList); free(TrackList);
} }
} }
*/ */
//Chapters //Chapters
if (player && player->manager && player->manager->chapter) 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"); printf("Chapter List\n");
int i = 0; 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]);
free(TrackList[i+1]); free(TrackList[i + 1]);
} }
free(TrackList); free(TrackList);
} }
} }
playing = true; playing = true;
first = true; first = true;
player->output->Command(player, OUTPUT_OPEN, NULL); player->output->Command(player, OUTPUT_OPEN, NULL);
ret = (player->playback->Command(player, PLAYBACK_PLAY, NULL) == 0); ret = (player->playback->Command(player, PLAYBACK_PLAY, NULL) == 0);
if (ret && !isHTTP) if (ret && !isHTTP)
playing = ret = (player->playback->Command(player, PLAYBACK_PAUSE, NULL) == 0); 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) bool cPlayback::Stop(void)
{ {
lt_info("%s playing %d\n", __func__, playing); lt_info("%s playing %d\n", __func__, playing);
if (player && player->playback) if (player && player->playback)
player->playback->Command(player, PLAYBACK_STOP, NULL); player->playback->Command(player, PLAYBACK_STOP, NULL);
if (player && player->output) if (player && player->output)
player->output->Command(player, OUTPUT_CLOSE, NULL); player->output->Command(player, OUTPUT_CLOSE, NULL);
if (player && player->output) if (player && player->output)
{ {
player->output->Command(player, OUTPUT_DEL, (void *)"audio"); player->output->Command(player, OUTPUT_DEL, (void *)"audio");
player->output->Command(player, OUTPUT_DEL, (void *)"video"); player->output->Command(player, OUTPUT_DEL, (void *)"video");
player->output->Command(player, OUTPUT_DEL, (void *)"subtitle");
} }
if (player && player->playback) if (player && player->playback)
player->playback->Command(player, PLAYBACK_CLOSE, NULL); player->playback->Command(player, PLAYBACK_CLOSE, NULL);
playing = false; playing = false;
return true; return true;
} }
@@ -238,6 +264,7 @@ bool cPlayback::SetAPid(int pid, bool /* ac3 */)
{ {
lt_info("%s\n", __func__); lt_info("%s\n", __func__);
int i = pid; int i = pid;
if (pid != mAudioStream) if (pid != mAudioStream)
{ {
if (player && player->playback) if (player && player->playback)
@@ -257,6 +284,7 @@ bool cPlayback::SetSubtitlePid(int pid)
{ {
lt_info("%s\n", __func__); lt_info("%s\n", __func__);
int i = pid; int i = pid;
if (pid != mSubtitleStream) if (pid != mSubtitleStream)
{ {
if (player && player->playback) if (player && player->playback)
@@ -269,11 +297,13 @@ bool cPlayback::SetSubtitlePid(int pid)
bool cPlayback::SetTeletextPid(int pid) bool cPlayback::SetTeletextPid(int pid)
{ {
lt_info("%s\n", __func__); lt_info("%s\n", __func__);
//int i = pid; //int i = pid;
if (pid != mTeletextStream) if (pid != mTeletextStream)
{ {
//if(player && player->playback) //if (player && player->playback)
//player->playback->Command(player, PLAYBACK_SWITCH_TELETEXT, (void*)&i); // player->playback->Command(player, PLAYBACK_SWITCH_TELETEXT, (void*)&i);
mTeletextStream = pid; mTeletextStream = pid;
} }
return true; return true;
@@ -282,6 +312,7 @@ bool cPlayback::SetTeletextPid(int pid)
bool cPlayback::SetSpeed(int speed) bool cPlayback::SetSpeed(int speed)
{ {
lt_info("%s playing %d speed %d\n", __func__, playing, speed); lt_info("%s playing %d speed %d\n", __func__, playing, speed);
if (!decoders_closed) if (!decoders_closed)
{ {
audioDecoder->closeDevice(); audioDecoder->closeDevice();
@@ -295,12 +326,15 @@ bool cPlayback::SetSpeed(int speed)
playing = true; playing = true;
} }
} }
if (!playing) if (!playing)
return false; return false;
if (player && player->playback) if (player && player->playback)
{ {
int result = 0; int result = 0;
nPlaybackSpeed = speed; nPlaybackSpeed = speed;
if (speed > 1) if (speed > 1)
{ {
/* direction switch ? */ /* direction switch ? */
@@ -337,11 +371,13 @@ bool cPlayback::SetSpeed(int speed)
{ {
result = player->playback->Command(player, PLAYBACK_CONTINUE, NULL); result = player->playback->Command(player, PLAYBACK_CONTINUE, NULL);
} }
if (init_jump > -1) if (init_jump > -1)
{ {
SetPosition(init_jump); SetPosition(init_jump);
init_jump = -1; init_jump = -1;
} }
if (result != 0) if (result != 0)
{ {
printf("returning false\n"); printf("returning false\n");
@@ -369,6 +405,7 @@ bool cPlayback::GetPosition(int &position, int &duration)
{ {
bool got_duration = false; bool got_duration = false;
lt_debug("%s %d %d\n", __func__, position, duration); lt_debug("%s %d %d\n", __func__, position, duration);
/* hack: if the file is growing (timeshift), then determine its length /* hack: if the file is growing (timeshift), then determine its length
* by comparing the mtime with the mtime of the xml file */ * by comparing the mtime with the mtime of the xml file */
if (pm == PLAYMODE_TS) if (pm == PLAYMODE_TS)
@@ -390,17 +427,21 @@ bool cPlayback::GetPosition(int &position, int &duration)
} }
} }
} }
if (!playing) if (!playing)
return false; return false;
if (player && player->playback && !player->playback->isPlaying) if (player && player->playback && !player->playback->isPlaying)
{ {
lt_info("%s !!!!EOF!!!! < -1\n", __func__); lt_info("%s !!!!EOF!!!! < -1\n", __func__);
position = duration + 1000; position = duration + 1000;
return false; return false;
} }
int64_t vpts = 0; int64_t vpts = 0;
if (player && player->playback) if (player && player->playback)
player->playback->Command(player, PLAYBACK_PTS, &vpts); player->playback->Command(player, PLAYBACK_PTS, &vpts);
if (vpts <= 0) if (vpts <= 0)
{ {
//printf("ERROR: 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. */ /* len is in nanoseconds. we have 90 000 pts per second. */
position = vpts / 90; position = vpts / 90;
} }
if (got_duration) if (got_duration)
return true; return true;
int64_t length = 0; int64_t length = 0;
if (player && player->playback) if (player && player->playback)
player->playback->Command(player, PLAYBACK_LENGTH, &length); player->playback->Command(player, PLAYBACK_LENGTH, &length);
if (length <= 0) if (length <= 0)
{
duration = duration + 1000; duration = duration + 1000;
}
else else
{
duration = length * 1000; duration = length * 1000;
}
return true; return true;
} }
bool cPlayback::SetPosition(int position, bool absolute) bool cPlayback::SetPosition(int position, bool absolute)
{ {
lt_info("%s %d\n", __func__, position); lt_info("%s %d\n", __func__, position);
if (playing && first) if (playing && first)
{ {
/* the calling sequence is: /* the calling sequence is:
@@ -437,9 +488,12 @@ bool cPlayback::SetPosition(int position, bool absolute)
first = false; first = false;
return false; return false;
} }
int64_t pos = (position / 1000.0); int64_t pos = (position / 1000.0);
if (player && player->playback) if (player && player->playback)
player->playback->Command(player, absolute ? PLAYBACK_SEEK_ABS : PLAYBACK_SEEK, (void *)&pos); player->playback->Command(player, absolute ? PLAYBACK_SEEK_ABS : PLAYBACK_SEEK, (void *)&pos);
return true; return true;
} }
@@ -448,6 +502,7 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu
lt_info("%s\n", __func__); lt_info("%s\n", __func__);
int max_numpida = *numpida; int max_numpida = *numpida;
*numpida = 0; *numpida = 0;
if (player && player->manager && player->manager->audio) if (player && player->manager && player->manager->audio)
{ {
char **TrackList = NULL; char **TrackList = NULL;
@@ -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) void cPlayback::FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language)
{ {
lt_info("%s\n", __func__); lt_info("%s\n", __func__);
int max_numpids = *numpids; int max_numpids = *numpids;
*numpids = 0; *numpids = 0;
if (player && player->manager && player->manager->subtitle) if (player && player->manager && player->manager->subtitle)
{ {
char **TrackList = NULL; char **TrackList = NULL;
@@ -539,8 +596,8 @@ void cPlayback::FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpids
lt_info("%s\n", __func__); lt_info("%s\n", __func__);
//int max_numpids = *numpids; //int max_numpids = *numpids;
*numpids = 0; *numpids = 0;
/*
if (player && player->manager && player->manager->teletext) /* if (player && player->manager && player->manager->teletext)
{ {
char **TrackList = NULL; char **TrackList = NULL;
player->manager->teletext->Command(player, MANAGER_LIST, &TrackList); player->manager->teletext->Command(player, MANAGER_LIST, &TrackList);
@@ -569,16 +626,15 @@ void cPlayback::FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpids
free(TrackList); free(TrackList);
*numpids = j; *numpids = j;
} }
} } */
*/
} }
int cPlayback::GetTeletextPid(void) int cPlayback::GetTeletextPid(void)
{ {
lt_info("%s\n", __func__); lt_info("%s\n", __func__);
int pid = -1; int pid = -1;
/*
if (player && player->manager && player->manager->teletext) /* if (player && player->manager && player->manager->teletext)
{ {
char **TrackList = NULL; char **TrackList = NULL;
player->manager->teletext->Command(player, MANAGER_LIST, &TrackList); player->manager->teletext->Command(player, MANAGER_LIST, &TrackList);
@@ -602,8 +658,8 @@ int cPlayback::GetTeletextPid(void)
} }
free(TrackList); free(TrackList);
} }
} } */
*/
printf("teletext pid id %d (0x%x)\n", pid, pid); printf("teletext pid id %d (0x%x)\n", pid, pid);
return pid; return pid;
} }
@@ -625,6 +681,7 @@ void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string
{ {
positions.clear(); positions.clear();
titles.clear(); titles.clear();
if (player && player->manager && player->manager->chapter) if (player && player->manager && player->manager->chapter)
{ {
char **TrackList = NULL; char **TrackList = NULL;
@@ -681,6 +738,7 @@ cPlayback::cPlayback(int num __attribute__((unused)))
cPlayback::~cPlayback() cPlayback::~cPlayback()
{ {
lt_info("%s\n", __func__); lt_info("%s\n", __func__);
if (player) if (player)
free(player); free(player);
player = NULL; player = NULL;
@@ -727,6 +785,7 @@ void cPlayback::ReleaseAVFormatContext()
bool cPlayback::IsPlaying(void) const bool cPlayback::IsPlaying(void) const
{ {
lt_info("%s\n", __func__); lt_info("%s\n", __func__);
/* konfetti: there is no event/callback mechanism in libeplayer2 /* konfetti: there is no event/callback mechanism in libeplayer2
* so in case of ending playback we have no information on a * so in case of ending playback we have no information on a
* terminated stream currently (or did I oversee it?). * terminated stream currently (or did I oversee it?).
@@ -736,6 +795,7 @@ bool cPlayback::IsPlaying(void) const
{ {
return player->playback->isPlaying; return player->playback->isPlaying;
} }
return playing; return playing;
} }
#endif #endif

View File

@@ -1,30 +1,45 @@
AUTOMAKE_OPTIONS = subdir-objects 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 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$(srcdir)/include
AM_CPPFLAGS += -I$(top_srcdir)/include AM_CPPFLAGS += -I$(top_srcdir)/include
AM_CPPFLAGS += -I$(srcdir)/external AM_CPPFLAGS += -I$(srcdir)/external
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
libeplayer3_arm_la_SOURCES = \ SOURCE_FILES = container/container.c
container/container.c \ SOURCE_FILES += container/container_ffmpeg.c
container/container_ffmpeg.c \ SOURCE_FILES += manager/manager.c
manager/manager.c \ SOURCE_FILES += manager/audio.c
manager/audio.c \ SOURCE_FILES += manager/video.c
manager/video.c \ SOURCE_FILES += manager/chapter.c
manager/subtitle.c \ SOURCE_FILES += manager/subtitle.c
manager/chapter.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
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_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/writer.c \
output/writer/mipsel/aac.c \ output/writer/mipsel/aac.c \
output/writer/mipsel/ac3.c \ output/writer/mipsel/ac3.c \
@@ -42,15 +57,13 @@ libeplayer3_arm_la_SOURCES = \
output/writer/mipsel/divx3.c \ output/writer/mipsel/divx3.c \
output/writer/mipsel/vp.c \ output/writer/mipsel/vp.c \
output/writer/mipsel/wmv.c \ output/writer/mipsel/wmv.c \
output/writer/mipsel/vc1.c \ output/writer/mipsel/vc1.c
playback/playback.c \
external/ffmpeg/src/bitstream.c \
external/ffmpeg/src/latmenc.c \
external/ffmpeg/src/mpeg4audio.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 bin_PROGRAMS = eplayer3
eplayer3_SOURCES = main/exteplayer.c eplayer3_SOURCES = main/exteplayer.c
eplayer3_LDADD = $(LIBEPLAYER3_LIBS) eplayer3_LDADD = $(LIBEPLAYER3_LIBS)
eplayer3_DEPENDENCIES = libeplayer3_arm.la

View File

@@ -80,13 +80,13 @@
static short debug_level = 1; static short debug_level = 1;
#define ffmpeg_printf(level, fmt, x...) do { \ #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 #else
#define ffmpeg_printf(level, fmt, x...) #define ffmpeg_printf(level, fmt, x...)
#endif #endif
#ifndef FFMPEG_SILENT #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 #else
#define ffmpeg_err(fmt, x...) #define ffmpeg_err(fmt, x...)
#endif #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 cERR_CONTAINER_FFMPEG_END_OF_FILE -10
#define IPTV_AV_CONTEXT_MAX_NUM 2 #define IPTV_AV_CONTEXT_MAX_NUM 2
/* ***************************** */ /* ***************************** */
/* Types */ /* Types */
/* ***************************** */ /* ***************************** */
@@ -548,8 +549,7 @@ static void FFMPEGThread(Context_t *context)
threadname[16] = 0; threadname[16] = 0;
prctl(PR_SET_NAME, (unsigned long)&threadname); prctl(PR_SET_NAME, (unsigned long)&threadname);
AVPacket packet; AVPacket packet;
//off_t lastSeek = -1;
//int64_t lastPts = -1;
int64_t currentVideoPts = -1; int64_t currentVideoPts = -1;
int64_t currentAudioPts = -1; int64_t currentAudioPts = -1;
@@ -561,7 +561,6 @@ static void FFMPEGThread(Context_t *context)
int64_t showtime = 0; int64_t showtime = 0;
int64_t bofcount = 0; int64_t bofcount = 0;
//int32_t err = 0;
AudioVideoOut_t avOut; AudioVideoOut_t avOut;
g_context = context; g_context = context;
@@ -583,6 +582,7 @@ static void FFMPEGThread(Context_t *context)
memset(&flv2mpeg4_context, 0, sizeof(Flv2Mpeg4Context)); memset(&flv2mpeg4_context, 0, sizeof(Flv2Mpeg4Context));
#endif #endif
ffmpeg_printf(10, "\n"); ffmpeg_printf(10, "\n");
while (context->playback->isCreationPhase) while (context->playback->isCreationPhase)
{ {
ffmpeg_printf(10, "Thread waiting for end of init phase...\n"); ffmpeg_printf(10, "Thread waiting for end of init phase...\n");
@@ -597,6 +597,7 @@ static void FFMPEGThread(Context_t *context)
#endif #endif
int8_t isWaitingForFinish = 0; int8_t isWaitingForFinish = 0;
while (context && context->playback && context->playback->isPlaying) while (context && context->playback && context->playback->isPlaying)
{ {
/* When user press PAUSE we call pause on AUDIO and VIDEO decoders, /* When user press PAUSE we call pause on AUDIO and VIDEO decoders,
@@ -636,19 +637,24 @@ static void FFMPEGThread(Context_t *context)
} }
continue; continue;
} }
if (context->playback->BackWard && av_gettime() >= showtime) {
if (context->playback->BackWard && av_gettime() >= showtime)
{
context->output->Command(context, OUTPUT_CLEAR, "video"); context->output->Command(context, OUTPUT_CLEAR, "video");
if (bofcount == 1) { if (bofcount == 1)
{
showtime = av_gettime(); showtime = av_gettime();
usleep(100000); usleep(100000);
continue; 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); off_t pos = avio_tell(avContextTab[0]->pb);
if (pos > 0) { if (pos > 0)
{
float br; float br;
if (avContextTab[0]->bit_rate) if (avContextTab[0]->bit_rate)
br = avContextTab[0]->bit_rate / 8.0; br = avContextTab[0]->bit_rate / 8.0;
@@ -779,6 +785,7 @@ static void FFMPEGThread(Context_t *context)
int32_t pid = avContextTab[cAVIdx]->streams[packet.stream_index]->id; int32_t pid = avContextTab[cAVIdx]->streams[packet.stream_index]->id;
reset_finish_timeout(); reset_finish_timeout();
if (avContextTab[cAVIdx]->streams[packet.stream_index]->discard != AVDISCARD_ALL) if (avContextTab[cAVIdx]->streams[packet.stream_index]->discard != AVDISCARD_ALL)
{ {
if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0) if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0)
@@ -992,6 +999,7 @@ static void FFMPEGThread(Context_t *context)
decoded_frame = NULL; decoded_frame = NULL;
} }
} }
#if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32)) #if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32))
while (packet.size > 0 || (!packet.size && !packet.data)) while (packet.size > 0 || (!packet.size && !packet.data))
#else #else
@@ -1059,6 +1067,7 @@ static void FFMPEGThread(Context_t *context)
continue; continue;
} }
#endif #endif
int32_t e = 0; int32_t e = 0;
if (!swr) if (!swr)
{ {
@@ -1085,6 +1094,7 @@ static void FFMPEGThread(Context_t *context)
{ {
c->channel_layout = av_get_default_channel_layout(c->channels); c->channel_layout = av_get_default_channel_layout(c->channels);
} }
out_channel_layout = c->channel_layout; out_channel_layout = c->channel_layout;
uint8_t downmix = stereo_software_decoder && out_channels > 2 ? 1 : 0; 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, "in_sample_fmt", c->sample_fmt, 0);
av_opt_set_int(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
e = swr_init(swr); e = swr_init(swr);
if (e < 0) if (e < 0)
{ {
@@ -1346,6 +1355,7 @@ static void FFMPEGThread(Context_t *context)
seek_target_seconds = 0; seek_target_seconds = 0;
do_seek_target_seconds = 0; do_seek_target_seconds = 0;
PlaybackDieNow(1); PlaybackDieNow(1);
ffmpeg_printf(10, "terminating\n"); 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); ffmpeg_printf(10, "filename %s\n", playFilesNames->szFirstFile);
if (playFilesNames->szSecondFile) if (playFilesNames->szSecondFile)
{ {
ffmpeg_printf(10, "second filename %s\n", playFilesNames->szSecondFile); ffmpeg_printf(10, "second filename %s\n", playFilesNames->szSecondFile);
} }
/* initialize ffmpeg */ /* initialize ffmpeg */
avcodec_register_all(); avcodec_register_all();
av_register_all(); av_register_all();
avformat_network_init(); avformat_network_init();
// SULGE DEBUG ENABLED // SULGE DEBUG ENABLED
@@ -1905,6 +1918,7 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
context->playback->abortRequested = 0; context->playback->abortRequested = 0;
int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \ 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) if (0 != res)
{ {
return res; return res;
@@ -1972,6 +1986,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
uint32_t cAVIdx = 0; uint32_t cAVIdx = 0;
for (cAVIdx = 0; cAVIdx < IPTV_AV_CONTEXT_MAX_NUM; cAVIdx += 1) for (cAVIdx = 0; cAVIdx < IPTV_AV_CONTEXT_MAX_NUM; cAVIdx += 1)
{ {
if (NULL == avContextTab[cAVIdx]) if (NULL == avContextTab[cAVIdx])
@@ -2082,6 +2097,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n", get_codecpar(stream)->codec_type); ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n", get_codecpar(stream)->codec_type);
stream->discard = AVDISCARD_ALL; /* by default we discard all video streams */ stream->discard = AVDISCARD_ALL; /* by default we discard all video streams */
if (encoding != NULL) if (encoding != NULL)
{ {
track.type = eTypeES; 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_num = stream->sample_aspect_ratio.num;
track.aspect_ratio_den = stream->sample_aspect_ratio.den; track.aspect_ratio_den = stream->sample_aspect_ratio.den;
if (0 == track.aspect_ratio_num || 0 == track.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; 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 */ /* fixme: revise this */
if (track.frame_rate < 23970) if (track.frame_rate < 23970)
{ {
track.TimeScale = 1001; track.TimeScale = 1001;
@@ -2181,6 +2199,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
case AVMEDIA_TYPE_AUDIO: case AVMEDIA_TYPE_AUDIO:
ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n", get_codecpar(stream)->codec_type); ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n", get_codecpar(stream)->codec_type);
stream->discard = AVDISCARD_ALL; stream->discard = AVDISCARD_ALL;
if (encoding != NULL) if (encoding != NULL)
{ {
AVDictionaryEntry *lang; AVDictionaryEntry *lang;
@@ -2199,6 +2218,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
track.have_aacheader = -1; track.have_aacheader = -1;
track.duration = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den); 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) if (stream->duration == AV_NOPTS_VALUE)
{ {
ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n"); 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); ffmpeg_printf(10, "CODEC_TYPE_SUBTITLE %d\n", get_codecpar(stream)->codec_type);
lang = av_dict_get(stream->metadata, "language", NULL, 0); lang = av_dict_get(stream->metadata, "language", NULL, 0);
track.Name = lang ? lang->value : "und"; track.Name = lang ? lang->value : "und";
ffmpeg_printf(10, "Language %s\n", track.Name); ffmpeg_printf(10, "Language %s\n", track.Name);
track.Encoding = encoding; track.Encoding = encoding;
@@ -2597,6 +2619,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
} }
releaseMutex(__FILE__, __FUNCTION__, __LINE__); releaseMutex(__FILE__, __FUNCTION__, __LINE__);
return cERR_CONTAINER_FFMPEG_NO_ERROR; 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) if ((error = pthread_create(&PlayThread, &attr, (void *)&FFMPEGThread, context)) != 0)
{ {
ffmpeg_printf(10, "Error creating thread, error:%d:%s\n", error, strerror(error)); ffmpeg_printf(10, "Error creating thread, error:%d:%s\n", error, strerror(error));
hasPlayThreadStarted = 0; hasPlayThreadStarted = 0;
ret = cERR_CONTAINER_FFMPEG_ERR; ret = cERR_CONTAINER_FFMPEG_ERR;
} }
else else
{ {
ffmpeg_printf(10, "Created thread\n"); ffmpeg_printf(10, "Created thread\n");
hasPlayThreadStarted = 1; hasPlayThreadStarted = 1;
} }
} }
@@ -2643,6 +2664,7 @@ static int32_t container_ffmpeg_play(Context_t *context)
} }
ffmpeg_printf(10, "exiting with value %d\n", ret); ffmpeg_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -2672,6 +2694,7 @@ static int32_t container_ffmpeg_stop(Context_t *context)
{ {
/* force close */ /* force close */
ffmpeg_err("Timeout waiting for thread!\n"); ffmpeg_err("Timeout waiting for thread!\n");
ret = cERR_CONTAINER_FFMPEG_ERR; ret = cERR_CONTAINER_FFMPEG_ERR;
/* to speed up close - we are in separate process for the moment this process will /* 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 * be closed and whole resources will be free by the system
@@ -2923,6 +2946,7 @@ 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); ffmpeg_printf(10, "iformat->flags 0x%08x\n", avContextTab[0]->iformat->flags);
#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING #if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
{ {
@@ -3029,6 +3053,7 @@ static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg __
{ {
ffmpeg_printf(10, "track %d\n", *arg); ffmpeg_printf(10, "track %d\n", *arg);
getMutex(__FILE__, __FUNCTION__, __LINE__); getMutex(__FILE__, __FUNCTION__, __LINE__);
if (context->manager->audio) if (context->manager->audio)
{ {
Track_t *Tracks = NULL; 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; 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 *videoTrack = NULL;
Track_t *audioTrack = 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: case CONTAINER_SWITCH_AUDIO:
{ {
ret = container_ffmpeg_switch_audio(context, (int32_t *) argument); ret = container_ffmpeg_switch_audio(context, (int32_t *)argument);
break; break;
} }
case CONTAINER_SWITCH_SUBTITLE: case CONTAINER_SWITCH_SUBTITLE:
{ {
ret = container_ffmpeg_switch_subtitle(context, (int32_t *) argument); ret = container_ffmpeg_switch_subtitle(context, (int32_t *)argument);
break; break;
} }
case CONTAINER_INFO: case CONTAINER_INFO:
@@ -3288,7 +3313,7 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen
} }
case CONTAINER_GET_METADATA: case CONTAINER_GET_METADATA:
{ {
ret = container_ffmpeg_get_metadata(context, (char ***) argument); ret = container_ffmpeg_get_metadata(context, (char ***)argument);
break; break;
} }
default: 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); ffmpeg_printf(50, "exiting with value %d\n", ret);
return ret; return ret;
} }

View File

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

View File

@@ -4,7 +4,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
typedef void( * PlaybackDieNowCallback )(); typedef void(* PlaybackDieNowCallback)();
bool PlaybackDieNowRegisterCallback(PlaybackDieNowCallback callback); bool PlaybackDieNowRegisterCallback(PlaybackDieNowCallback callback);
typedef enum { 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); ptrManager->Command(g_player, MANAGER_LIST, &TrackList);
if (NULL != TrackList) if (NULL != TrackList)
{ {
int i = 0, Id = -1; int i = 0;
int Id = -1;
char * pch; char * pch;
char Name[] = " "; char Name[] = " ";
fprintf(stderr, "{\"%c_%c\": [", argvBuff[0], argvBuff[1]); 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], " "); pch = strtok(TrackList[i], " ");
if (pch != NULL) { 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); fprintf(stderr, "{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}", Id, TrackList[i+1], Name);
free(TrackList[i]); free(TrackList[i]);
free(TrackList[i+1]); free(TrackList[i + 1]);
} }
fprintf(stderr, "]}\n"); fprintf(stderr, "]}\n");
free(TrackList); free(TrackList);
@@ -336,7 +337,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
{ {
int i = 0; int i = 0;
char * pch; char * pch;
for (i = 0; TrackList[i] != NULL; i+=2) for (i = 0; TrackList[i] != NULL; i += 2)
{ {
if (idx == i) if (idx == i)
{ {
@@ -345,7 +346,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
id = atoi(pch); id = atoi(pch);
} }
free(TrackList[i]); free(TrackList[i]);
free(TrackList[i+1]); free(TrackList[i + 1]);
} }
free(TrackList); free(TrackList);
} }
@@ -501,7 +502,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac
static void UpdateVideoTrack() 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) 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; ret = 0;
playbackFiles->szFirstFile = malloc(IPTV_MAX_FILE_PATH); playbackFiles->szFirstFile = malloc(IPTV_MAX_FILE_PATH);
playbackFiles->szFirstFile[0] = '\0'; playbackFiles->szFirstFile[0] = '\0';
if (NULL == strstr(argv[optind], "://")) if (NULL == strstr(argv[optind], "://"))
{ {
strcpy(playbackFiles->szFirstFile, "file://"); strcpy(playbackFiles->szFirstFile, "file://");
@@ -693,6 +695,7 @@ int main(int argc, char *argv[])
PlayFiles_t playbackFiles; PlayFiles_t playbackFiles;
memset(&playbackFiles, 0x00, sizeof(playbackFiles)); memset(&playbackFiles, 0x00, sizeof(playbackFiles));
if (0 != ParseParams(argc, argv, &playbackFiles, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB)) 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"); 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); PlaybackDieNowRegisterCallback(TerminateWakeUp);
HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc"); HandleTracks(g_player->manager->video, (PlaybackCmd_t) -1, "vc");
HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "al"); HandleTracks(g_player->manager->audio, (PlaybackCmd_t) -1, "al");
if (audioTrackIdx >= 0) if (audioTrackIdx >= 0)
{ {
static char cmd[128] = ""; // static to not allocate on stack static char cmd[128] = ""; // static to not allocate on stack
sprintf(cmd, "ai%d\n", audioTrackIdx); sprintf(cmd, "ai%d\n", audioTrackIdx);
commandRetVal = HandleTracks(g_player->manager->audio, PLAYBACK_SWITCH_AUDIO, cmd); 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) if (subtitleTrackIdx >= 0)
{ {
static char cmd[128] = ""; // static to not allocate on stack static char cmd[128] = ""; // static to not allocate on stack
sprintf(cmd, "si%d\n", subtitleTrackIdx); sprintf(cmd, "si%d\n", subtitleTrackIdx);
commandRetVal = HandleTracks(g_player->manager->subtitle, PLAYBACK_SWITCH_SUBTITLE, cmd); 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)) while (g_player->playback->isPlaying && 0 == PlaybackDieNow(0))
@@ -855,7 +858,7 @@ int main(int argc, char *argv[])
{ {
case 'v': case 'v':
{ {
HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, argvBuff); HandleTracks(g_player->manager->video, (PlaybackCmd_t) -1, argvBuff);
break; break;
} }
case 'a': case 'a':
@@ -966,10 +969,12 @@ int main(int argc, char *argv[])
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts);
CurrentSec = (int32_t)(pts / 90000); CurrentSec = (int32_t)(pts / 90000);
if (0 == commandRetVal) if (0 == commandRetVal)
{ {
fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90); fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90);
} }
if (0 == commandRetVal || force) if (0 == commandRetVal || force)
{ {
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length); 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; int64_t lastPts = 0;
commandRetVal = 1; commandRetVal = 1;
if (g_player->container && g_player->container->selectedContainer) if (g_player->container && g_player->container->selectedContainer)
{ {
commandRetVal = g_player->container->selectedContainer->Command((Context_t*)g_player->container, CONTAINER_LAST_PTS, &lastPts); 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; static short debug_level = 40;
#define audio_mgr_printf(level, fmt, x...) do { \ #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 #else
#define audio_mgr_printf(level, x...) #define audio_mgr_printf(level, x...)
#endif #endif
@@ -97,7 +97,7 @@ static int ManagerAdd(Context_t *context, Track_t track)
if (Tracks == NULL) 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; return cERR_AUDIO_MGR_ERROR;
} }
@@ -118,7 +118,7 @@ static int ManagerAdd(Context_t *context, Track_t track)
} }
else 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; 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__); audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
return cERR_AUDIO_MGR_NO_ERROR; return cERR_AUDIO_MGR_NO_ERROR;
} }
@@ -137,13 +138,14 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
char **tracklist = NULL; char **tracklist = NULL;
audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
if (Tracks != NULL) if (Tracks != NULL)
{ {
tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1)); tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1));
if (tracklist == NULL) 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; return NULL;
} }
@@ -160,9 +162,9 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
tracklist[j] = strdup(tmp); tracklist[j] = strdup(tmp);
tracklist[j + 1] = strdup(Tracks[i].Encoding); tracklist[j + 1] = strdup(Tracks[i].Encoding);
} }
tracklist[j] = NULL; tracklist[j] = NULL;
} }
audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount); audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount);
return tracklist; return tracklist;
@@ -181,7 +183,7 @@ static TrackDescription_t *ManagerList(Context_t *context __attribute__((unused
if (tracklist == NULL) 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; 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); container_ffmpeg_update_tracks(context, context->playback->uri, 0);
// *((TrackDescription_t **)argument) = ManagerList(context); // *((TrackDescription_t **)argument) = ManagerList(context);
*((char ** *) argument) = (char **) ManagerList(context); *((char ***)argument) = (char **)ManagerList(context);
break; break;
} }
case MANAGER_REF_LIST: case MANAGER_REF_LIST:
@@ -279,7 +281,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
} }
else else
{ {
*((int *)argument) = (int) - 1; *((int *)argument) = (int) -1;
} }
break; break;
} }
@@ -382,7 +384,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
break; 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; return ret;
} }

View File

@@ -118,7 +118,7 @@ static int ManagerAdd(Context_t *context __attribute__((unused)), Track_t track)
} }
else 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; 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))) static char **ManagerList(Context_t *context __attribute__((unused)))
{ {
char **tracklist = NULL;
int i = 0, j = 0; int i = 0, j = 0;
char **tracklist = NULL;
subtitle_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); subtitle_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__);
@@ -145,7 +145,7 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
if (tracklist == NULL) 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; return NULL;
} }
@@ -162,7 +162,6 @@ static char **ManagerList(Context_t *context __attribute__((unused)))
tracklist[j] = strdup(tmp); tracklist[j] = strdup(tmp);
tracklist[j + 1] = strdup(Tracks[i].Encoding); tracklist[j + 1] = strdup(Tracks[i].Encoding);
} }
tracklist[j] = NULL; tracklist[j] = NULL;
} }
@@ -219,18 +218,20 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
case MANAGER_LIST: case MANAGER_LIST:
{ {
container_ffmpeg_update_tracks(context, context->playback->uri, 0); container_ffmpeg_update_tracks(context, context->playback->uri, 0);
*((char ** *)argument) = (char **)ManagerList(context); *((char ***)argument) = (char **)ManagerList(context);
break; break;
} }
case MANAGER_GET: case MANAGER_GET:
{ {
subtitle_mgr_printf(20, "%s::%s MANAGER_GET\n", FILENAME, __FUNCTION__);
if (TrackCount > 0 && CurrentTrack >= 0) if (TrackCount > 0 && CurrentTrack >= 0)
{ {
*((int *)argument) = (int)Tracks[CurrentTrack].Id; *((int *)argument) = (int)Tracks[CurrentTrack].Id;
} }
else else
{ {
*((int *)argument) = (int) - 1; *((int *)argument) = (int) -1;
} }
break; break;
} }
@@ -256,6 +257,8 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
} }
case MANAGER_GET_TRACK: case MANAGER_GET_TRACK:
{ {
subtitle_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME, __FUNCTION__);
if ((TrackCount > 0) && (CurrentTrack >= 0)) if ((TrackCount > 0) && (CurrentTrack >= 0))
{ {
*((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; *((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: case MANAGER_SET:
{ {
int i; int i;
subtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", __FILE__, __FUNCTION__, *((int *)argument)); subtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", __FILE__, __FUNCTION__, *((int *)argument));
if (*((int *)argument) < 0) if (*((int *)argument) < 0)
@@ -332,12 +336,12 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument)
break; break;
} }
default: 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; ret = cERR_SUBTITLE_MGR_ERROR;
break; 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; return ret;
} }

View File

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

View File

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

View File

@@ -90,6 +90,7 @@ static void printOutputCapabilities()
for (i = 0; AvailableOutput[i] != NULL; i++) for (i = 0; AvailableOutput[i] != NULL; i++)
{ {
output_printf(10, "\t%s : ", AvailableOutput[i]->Name); output_printf(10, "\t%s : ", AvailableOutput[i]->Name);
for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++) for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++)
{ {
output_printf(10, "%s ", AvailableOutput[i]->Capabilities[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"); ret |= context->output->video->Command(context, OUTPUT_CLOSE, "video");
} }
if (context->playback->isAudio) if (context->playback->isAudio)
{ {
ret |= context->output->audio->Command(context, OUTPUT_CLOSE, "audio"); ret |= context->output->audio->Command(context, OUTPUT_CLOSE, "audio");
} }
if (context->playback->isSubtitle) if (context->playback->isSubtitle)
{ {
ret |= context->output->subtitle->Command(context, OUTPUT_CLOSE, "subtitle"); 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"); ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio");
} }
if (!ret) if (!ret)
{ {
if (context->playback->isSubtitle) 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"); ret |= context->output->video->Command(context, OUTPUT_STOP, "video");
} }
if (context->playback->isAudio) if (context->playback->isAudio)
{ {
ret |= context->output->audio->Command(context, OUTPUT_STOP, "audio"); ret |= context->output->audio->Command(context, OUTPUT_STOP, "audio");
} }
if (context->playback->isSubtitle) if (context->playback->isSubtitle)
{ {
ret |= context->output->subtitle->Command(context, OUTPUT_STOP, "subtitle"); 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"); ret |= context->output->video->Command(context, OUTPUT_FLUSH, "video");
} }
if (context->playback->isAudio) if (context->playback->isAudio)
{ {
ret |= context->output->audio->Command(context, OUTPUT_FLUSH, "audio"); ret |= context->output->audio->Command(context, OUTPUT_FLUSH, "audio");
} }
if (context->playback->isSubtitle) if (context->playback->isSubtitle)
{ {
ret |= context->output->subtitle->Command(context, OUTPUT_FLUSH, "subtitle"); 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"); ret |= context->output->video->Command(context, OUTPUT_PAUSE, "video");
} }
if (context->playback->isAudio) if (context->playback->isAudio)
{ {
ret |= context->output->audio->Command(context, OUTPUT_PAUSE, "audio"); ret |= context->output->audio->Command(context, OUTPUT_PAUSE, "audio");
} }
if (context->playback->isSubtitle) if (context->playback->isSubtitle)
{ {
ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle"); 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"); ret |= context->output->video->Command(context, OUTPUT_FASTFORWARD, "video");
} }
if (context->playback->isAudio) if (context->playback->isAudio)
{ {
ret |= context->output->audio->Command(context, OUTPUT_FASTFORWARD, "audio"); 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"); ret |= context->output->video->Command(context, OUTPUT_REVERSE, "video");
} }
if (context->playback->isAudio) if (context->playback->isAudio)
{ {
ret |= context->output->audio->Command(context, OUTPUT_REVERSE, "audio"); 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"); ret |= context->output->video->Command(context, OUTPUT_CONTINUE, "video");
} }
if (context->playback->isAudio) if (context->playback->isAudio)
{ {
ret |= context->output->audio->Command(context, OUTPUT_CONTINUE, "audio"); ret |= context->output->audio->Command(context, OUTPUT_CONTINUE, "audio");
} }
if (context->playback->isSubtitle) if (context->playback->isSubtitle)
{ {
ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle"); 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"); ret |= context->output->video->Command(context, OUTPUT_CLEAR, "video");
} }
if (context->playback->isAudio && (argument == NULL || *(char *) argument == 'a')) if (context->playback->isAudio && (argument == NULL || *(char *) argument == 'a'))
{ {
ret |= context->output->audio->Command(context, OUTPUT_CLEAR, "audio"); ret |= context->output->audio->Command(context, OUTPUT_CLEAR, "audio");
} }
if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's')) if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's'))
{ {
ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle"); 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); return context->output->video->Command(context, OUTPUT_PTS, argument);
} }
if (context->playback->isAudio) if (context->playback->isAudio)
{ {
return context->output->audio->Command(context, OUTPUT_PTS, argument); 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"); return context->output->audio->Command(context, OUTPUT_SWITCH, "audio");
} }
if (context->playback->isVideo) if (context->playback->isVideo)
{ {
return context->output->video->Command(context, OUTPUT_SWITCH, "video"); return context->output->video->Command(context, OUTPUT_SWITCH, "video");
} }
if (context->playback->isSubtitle) if (context->playback->isSubtitle)
{ {
return context->output->subtitle->Command(context, OUTPUT_SWITCH, "subtitle"); 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"); ret |= context->output->video->Command(context, OUTPUT_SLOWMOTION, "video");
} }
if (context->playback->isAudio) if (context->playback->isAudio)
{ {
ret |= context->output->audio->Command(context, OUTPUT_SLOWMOTION, "audio"); 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); return context->output->video->Command(context, OUTPUT_GET_FRAME_COUNT, argument);
} }
if (context->playback->isAudio) if (context->playback->isAudio)
{ {
return context->output->audio->Command(context, OUTPUT_GET_FRAME_COUNT, argument); 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))) static int32_t subtitle_Close(Context_t *context __attribute__((unused)))
{ {
//uint32_t i = 0 ;
subtitle_printf(10, "\n"); subtitle_printf(10, "\n");
getMutex(__LINE__); 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); subtitle_printf(50, "exiting with value %d\n", ret);
return ret; return ret;
} }

View File

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

View File

@@ -52,6 +52,7 @@
/* ***************************** */ /* ***************************** */
/* Makros/Constants */ /* Makros/Constants */
/* ***************************** */ /* ***************************** */
#define PES_AUDIO_PRIVATE_HEADER_SIZE 16 // consider maximum private header size. #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_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE)
#define PES_AUDIO_PACKET_SIZE 2028 #define PES_AUDIO_PACKET_SIZE 2028

View File

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

View File

@@ -140,6 +140,7 @@ static void SupervisorThread(Context_t *context)
{ {
usleep(100000); usleep(100000);
} }
playback_printf(10, "<\n"); playback_printf(10, "<\n");
hasThreadStarted = 2; hasThreadStarted = 2;
PlaybackTerminate(context); PlaybackTerminate(context);
@@ -293,6 +294,7 @@ static int PlaybackPlay(Context_t *context)
{ {
playback_err("OUTPUT_PLAY failed!\n"); playback_err("OUTPUT_PLAY failed!\n");
playback_err("clearing isCreationPhase!\n"); playback_err("clearing isCreationPhase!\n");
context->playback->isCreationPhase = 0; // allow thread to go into next state context->playback->isCreationPhase = 0; // allow thread to go into next state
context->playback->isPlaying = 0; context->playback->isPlaying = 0;
context->playback->isPaused = 0; context->playback->isPaused = 0;
@@ -300,6 +302,7 @@ static int PlaybackPlay(Context_t *context)
context->playback->BackWard = 0; context->playback->BackWard = 0;
context->playback->SlowMotion = 0; context->playback->SlowMotion = 0;
context->playback->Speed = 0; context->playback->Speed = 0;
if (context->container && context->container->selectedContainer) if (context->container && context->container->selectedContainer)
ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
} }
@@ -317,7 +320,8 @@ static int PlaybackPlay(Context_t *context)
int error; int error;
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 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)); playback_printf(10, "Error creating thread, error:%d:%s\n", error, strerror(error));
ret = cERR_PLAYBACK_ERROR; ret = cERR_PLAYBACK_ERROR;
@@ -334,11 +338,11 @@ static int PlaybackPlay(Context_t *context)
if (context->container && context->container->selectedContainer) if (context->container && context->container->selectedContainer)
ret = context->container->selectedContainer->Command(context, CONTAINER_PLAY, NULL); ret = context->container->selectedContainer->Command(context, CONTAINER_PLAY, NULL);
if (ret != 0) if (ret != 0)
{ {
playback_err("CONTAINER_PLAY failed!\n"); playback_err("CONTAINER_PLAY failed!\n");
} }
} }
} }
else else
@@ -363,10 +367,9 @@ static int PlaybackPause(Context_t *context)
if (context->playback->SlowMotion) if (context->playback->SlowMotion)
context->output->Command(context, OUTPUT_CLEAR, NULL); context->output->Command(context, OUTPUT_CLEAR, NULL);
context->playback->isPaused = 1;
context->output->Command(context, OUTPUT_PAUSE, NULL); context->output->Command(context, OUTPUT_PAUSE, NULL);
context->playback->isPaused = 1;
//context->playback->isPlaying = 1; //context->playback->isPlaying = 1;
context->playback->isForwarding = 0; context->playback->isForwarding = 0;
context->playback->BackWard = 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) if (context->playback->SlowMotion || context->playback->isForwarding || context->playback->BackWard)
context->output->Command(context, OUTPUT_CLEAR, NULL); context->output->Command(context, OUTPUT_CLEAR, NULL);
context->output->Command(context, OUTPUT_CONTINUE, NULL);
if (context->playback->BackWard) if (context->playback->BackWard)
context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); context->output->Command(context, OUTPUT_AUDIOMUTE, "0");
@@ -405,7 +410,6 @@ static int32_t PlaybackContinue(Context_t *context)
context->playback->BackWard = 0; context->playback->BackWard = 0;
context->playback->SlowMotion = 0; context->playback->SlowMotion = 0;
context->playback->Speed = 1; context->playback->Speed = 1;
context->output->Command(context, OUTPUT_CONTINUE, NULL);
} }
else else
{ {
@@ -414,6 +418,7 @@ static int32_t PlaybackContinue(Context_t *context)
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -428,7 +433,6 @@ static int32_t PlaybackStop(Context_t *context)
if (context && context->playback && context->playback->isPlaying) if (context && context->playback && context->playback->isPlaying)
{ {
context->playback->isPaused = 0; context->playback->isPaused = 0;
context->playback->isPlaying = 0; context->playback->isPlaying = 0;
context->playback->isForwarding = 0; context->playback->isForwarding = 0;
@@ -438,7 +442,6 @@ static int32_t PlaybackStop(Context_t *context)
context->output->Command(context, OUTPUT_STOP, NULL); context->output->Command(context, OUTPUT_STOP, NULL);
context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
} }
else else
{ {
@@ -459,13 +462,13 @@ static int32_t PlaybackStop(Context_t *context)
} }
playback_printf(10, "exiting with value %d\n", ret); playback_printf(10, "exiting with value %d\n", ret);
return ret; return ret;
} }
static int32_t PlaybackTerminate(Context_t *context) static int32_t PlaybackTerminate(Context_t *context)
{ {
int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t ret = cERR_PLAYBACK_NO_ERROR;
int wait_time = 20; int wait_time = 20;
playback_printf(20, "\n"); playback_printf(20, "\n");
@@ -475,12 +478,13 @@ static int32_t PlaybackTerminate(Context_t *context)
if (context && context->playback && context->playback->isPlaying) if (context && context->playback && context->playback->isPlaying)
{ {
//First Flush and than delete container, else e2 cant read length of file anymore //First Flush and than delete container, else e2 cant read length of file anymore
if (context->output->Command(context, OUTPUT_FLUSH, NULL) < 0) if (context->output->Command(context, OUTPUT_FLUSH, NULL) < 0)
{ {
playback_err("failed to flush output.\n"); playback_err("failed to flush output.\n");
} }
ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
context->playback->isPaused = 0; context->playback->isPaused = 0;
context->playback->isPlaying = 0; context->playback->isPlaying = 0;
context->playback->isForwarding = 0; context->playback->isForwarding = 0;
@@ -488,7 +492,6 @@ static int32_t PlaybackTerminate(Context_t *context)
context->playback->SlowMotion = 0; context->playback->SlowMotion = 0;
context->playback->Speed = 0; context->playback->Speed = 0;
context->output->Command(context, OUTPUT_STOP, NULL); context->output->Command(context, OUTPUT_STOP, NULL);
ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL);
} }
else else
{ {
@@ -513,6 +516,7 @@ static int32_t PlaybackTerminate(Context_t *context)
} }
playback_printf(20, "exiting with value %d\n", ret); playback_printf(20, "exiting with value %d\n", ret);
return 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); playback_err("speed %d out of range (1 - %d) \n", *speed, cMaxSpeed_ff);
return cERR_PLAYBACK_ERROR; return cERR_PLAYBACK_ERROR;
} }
context->playback->isForwarding = 1; context->playback->isForwarding = 1;
context->playback->Speed = *speed; context->playback->Speed = *speed;
playback_printf(20, "Speed: %d x {%d}\n", *speed, context->playback->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); playback_err("speed %d out of range (0 - %d) \n", *speed, cMaxSpeed_fr);
return cERR_PLAYBACK_ERROR; return cERR_PLAYBACK_ERROR;
} }
PlaybackContinue(context);
if (*speed == 0) if (*speed == 0)
{ {
context->playback->isPaused = 0;
//context->playback->isPlaying = 0;
context->playback->isForwarding = 0;
context->playback->BackWard = 0; context->playback->BackWard = 0;
context->playback->Speed = 0; /* reverse end */ context->playback->SlowMotion = 0;
context->playback->Speed = 0;
context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); context->output->Command(context, OUTPUT_AUDIOMUTE, "0");
} }
else else
{ {
context->playback->isSeeking = 1; context->playback->isPaused = 0;
context->playback->Speed = *speed; //context->playback->isPlaying = 0;
context->playback->isForwarding = 0;
context->playback->BackWard = 1; context->playback->BackWard = 1;
context->playback->SlowMotion = 0;
context->playback->Speed = *speed;
context->playback->isSeeking = 1;
context->output->Command(context, OUTPUT_AUDIOMUTE, "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); context->output->Command(context, OUTPUT_CLEAR, NULL);
@@ -602,6 +618,7 @@ static int32_t PlaybackSlowMotion(Context_t *context, int *speed)
{ {
if (context->playback->isPaused) if (context->playback->isPaused)
PlaybackContinue(context); PlaybackContinue(context);
switch (*speed) switch (*speed)
{ {
case 2: case 2:
@@ -614,7 +631,9 @@ static int32_t PlaybackSlowMotion(Context_t *context, int *speed)
context->playback->SlowMotion = 8; context->playback->SlowMotion = 8;
break; break;
} }
playback_printf(20, "SlowMotion: %d x {%d}\n", *speed, context->playback->SlowMotion); playback_printf(20, "SlowMotion: %d x {%d}\n", *speed, context->playback->SlowMotion);
context->output->Command(context, OUTPUT_SLOWMOTION, NULL); context->output->Command(context, OUTPUT_SLOWMOTION, NULL);
} }
else else
@@ -727,6 +746,7 @@ static int32_t PlaybackLength(Context_t *context, int64_t *length)
} }
playback_printf(20, "exiting with value %d\n", ret); playback_printf(20, "exiting with value %d\n", ret);
return ret; return ret;
} }
@@ -754,7 +774,6 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track)
if (nextrackid != curtrackid) if (nextrackid != curtrackid)
{ {
//PlaybackPause(context); //PlaybackPause(context);
if (context->output && context->output->audio) 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); playback_printf(10, "exiting with value %d\n", ret);
return 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); playback_printf(20, "Command %d\n", command);
switch (command) switch (command)
{ {
case PLAYBACK_OPEN: case PLAYBACK_OPEN:
@@ -899,6 +918,11 @@ static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument
ret = PlaybackTerminate(context); ret = PlaybackTerminate(context);
break; break;
} }
case PLAYBACK_FASTFORWARD:
{
ret = PlaybackFastForward(context, (int *)argument);
break;
}
case PLAYBACK_SEEK: case PLAYBACK_SEEK:
{ {
ret = PlaybackSeek(context, (int64_t *)argument, 0); 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); ret = PlaybackFastBackward(context, (int *)argument);
break; break;
} }
case PLAYBACK_FASTFORWARD:
{
ret = PlaybackFastForward(context, (int *)argument);
break;
}
case PLAYBACK_GET_FRAME_COUNT: case PLAYBACK_GET_FRAME_COUNT:
{ {
ret = PlaybackGetFrameCount(context, (uint64_t *)argument); 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__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
AM_CPPFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE 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 AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
libeplayer3_la_SOURCES = \ libeplayer3_la_SOURCES = \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -372,7 +372,7 @@ bool Player::GetChapters(std::vector<int> &positions, std::vector<std::string> &
positions.clear(); positions.clear();
titles.clear(); titles.clear();
input.UpdateTracks(); 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) { for (std::vector<Chapter>::iterator it = chapters.begin(); it != chapters.end(); ++it) {
positions.push_back(it->start/1000); positions.push_back(it->start/1000);
titles.push_back(it->title); 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) void Player::SetChapters(std::vector<Chapter> &Chapters)
{ {
ScopedLock m_lock(chapterMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(chapterMutex);
chapters = Chapters; 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_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_LDFLAGS = \ 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 = \ libraspi_la_SOURCES = \
hardware_caps.c \ hardware_caps.c \

View File

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

View File

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

View File

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