all: clean up cDemux headers

This commit is contained in:
max_10
2018-03-21 01:53:22 +01:00
committed by Thilo Graf
parent f4ad480fc0
commit 6a3abc86d8
85 changed files with 759 additions and 1285 deletions

View File

@@ -9,8 +9,6 @@ libstb_hal_la_LIBADD = \
common/libcommon.la \ common/libcommon.la \
libthread/libthread.la libthread/libthread.la
AM_CPPFLAGS = \
-I$(top_srcdir)/include
#libstb_hal_test_SOURCES = libtest.cpp #libstb_hal_test_SOURCES = libtest.cpp
#libstb_hal_test_LDADD = libstb-hal.la #libstb_hal_test_LDADD = libstb-hal.la
@@ -67,3 +65,24 @@ libstb_hal_la_LIBADD += \
endif endif
endif endif
pkginclude_HEADERS = \
include/audio_hal.h \
include/ca_cs.h \
include/ca.h \
include/cs_api.h \
include/ca_ci.h \
include/cs_types.h \
include/dmx_cs.h \
include/dmx_hal.h \
include/glfb.h \
include/hardware_caps.h \
include/init_cs.h \
include/init_td.h \
include/mmi.h \
include/playback.h \
include/playback_hal.h \
include/pwrmngr.h \
include/record_hal.h \
include/video_cs.h \
include/video_hal.h

View File

@@ -1 +0,0 @@
../libspark/cs_api.h

View File

@@ -30,11 +30,12 @@
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include "dmx_lib.h" #include <sys/ioctl.h>
#include "dmx_hal.h"
#include "lt_debug.h" #include "lt_debug.h"
/* Ugh... see comment in destructor for details... */
#include "video_lib.h" #include "video_lib.h"
/* needed for getSTC... */
extern cVideo *videoDecoder; extern cVideo *videoDecoder;
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args)
@@ -42,14 +43,8 @@ extern cVideo *videoDecoder;
#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args) #define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args)
#define dmx_err(_errfmt, _errstr, _revents) do { \ #define dmx_err(_errfmt, _errstr, _revents) do { \
uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\
if (dmx_type == DMX_PSI_CHANNEL) { \
_pid = s_flt.pid; _f = s_flt.filter.filter[0]; \
} else { \
_pid = p_flt.pid; \
}; \
lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \
} while(0); } while(0);
cDemux *videoDemux = NULL; cDemux *videoDemux = NULL;
@@ -88,9 +83,6 @@ cDemux::cDemux(int n)
else else
num = n; num = n;
fd = -1; fd = -1;
measure = false;
last_measure = 0;
last_data = 0;
} }
cDemux::~cDemux() cDemux::~cDemux()
@@ -165,8 +157,6 @@ void cDemux::Close(void)
ioctl(fd, DMX_STOP); ioctl(fd, DMX_STOP);
close(fd); close(fd);
fd = -1; fd = -1;
if (measure)
return;
if (dmx_type == DMX_TP_CHANNEL) if (dmx_type == DMX_TP_CHANNEL)
{ {
dmx_tp_count--; dmx_tp_count--;
@@ -273,11 +263,13 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
return rc; return rc;
} }
bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter,
const unsigned char * const mask, int len, int timeout, const unsigned char * const mask, int len, int timeout,
const unsigned char * const negmask) const unsigned char * const negmask)
{ {
struct dmx_sct_filter_params s_flt;
memset(&s_flt, 0, sizeof(s_flt)); memset(&s_flt, 0, sizeof(s_flt));
pid = _pid;
if (len > DMX_FILTER_SIZE) if (len > DMX_FILTER_SIZE)
{ {
@@ -286,6 +278,7 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
} }
s_flt.pid = pid; s_flt.pid = pid;
s_flt.timeout = timeout; s_flt.timeout = timeout;
flt = filter[0];
memcpy(s_flt.filter.filter, filter, len); memcpy(s_flt.filter.filter, filter, len);
memcpy(s_flt.filter.mask, mask, len); memcpy(s_flt.filter.mask, mask, len);
if (negmask != NULL) if (negmask != NULL)
@@ -389,8 +382,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
return true; return true;
} }
bool cDemux::pesFilter(const unsigned short pid) bool cDemux::pesFilter(const unsigned short _pid)
{ {
struct dmx_pes_filter_params p_flt;
pid = _pid;
flt = 0;
/* allow PID 0 for web streaming e.g. /* allow PID 0 for web streaming e.g.
* this check originally is from tuxbox cvs but I'm not sure * this check originally is from tuxbox cvs but I'm not sure
* what it is good for... * what it is good for...

View File

@@ -1 +0,0 @@
#include "dmx_lib.h"

View File

@@ -1,70 +0,0 @@
#ifndef __DEMUX_TD_H
#define __DEMUX_TD_H
#include <cstdlib>
#include <vector>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include "../common/cs_types.h"
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,
DMX_VIDEO_CHANNEL = 1,
DMX_AUDIO_CHANNEL,
DMX_PES_CHANNEL,
DMX_PSI_CHANNEL,
DMX_PIP_CHANNEL,
DMX_TP_CHANNEL,
DMX_PCR_ONLY_CHANNEL
} DMX_CHANNEL_TYPE;
typedef struct
{
int fd;
unsigned short pid;
} pes_pids;
class cDemux
{
private:
int num;
int fd;
int buffersize;
bool measure;
uint64_t last_measure, last_data;
DMX_CHANNEL_TYPE dmx_type;
std::vector<pes_pids> pesfds;
struct dmx_sct_filter_params s_flt;
struct dmx_pes_filter_params p_flt;
public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0);
void Close(void);
bool Start(bool record = false);
bool Stop(void);
int Read(unsigned char *buff, int len, int Timeout = 0);
bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL);
bool pesFilter(const unsigned short pid);
void SetSyncMode(AVSYNC_TYPE mode);
void * getBuffer();
void * getChannel();
DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; };
bool addPid(unsigned short pid);
void getSTC(int64_t * STC);
int getUnit(void);
static bool SetSource(int unit, int source);
static int GetSource(int unit);
// TD only functions
int getFD(void) { return fd; }; /* needed by cPlayback class */
void removePid(unsigned short Pid); /* needed by cRecord class */
std::vector<pes_pids> getPesPids(void) { return pesfds; };
//
cDemux(int num = 0);
~cDemux();
};
#endif //__DEMUX_H

View File

@@ -1,5 +1,7 @@
#include <unistd.h> #include <unistd.h>
#include "init_lib.h"
#include "init_td.h"
#include "lt_debug.h" #include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_INIT, NULL, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_INIT, NULL, args)

View File

@@ -1,5 +0,0 @@
#ifndef __INIT_TD_H
#define __INIT_TD_H
void init_td_api();
void shutdown_td_api();
#endif

View File

@@ -1,9 +1,9 @@
#ifndef _VIDEO_TD_H #ifndef _VIDEO_LIB_H
#define _VIDEO_TD_H #define _VIDEO_LIB_H
#include <linux/dvb/video.h> #include <linux/dvb/video.h>
#include "../common/cs_types.h" #include "cs_types.h"
#include "dmx_lib.h" #include "dmx_hal.h"
typedef enum { typedef enum {
ANALOG_SD_RGB_CINCH = 0x00, ANALOG_SD_RGB_CINCH = 0x00,
@@ -97,7 +97,7 @@ typedef enum {
/* not used, for dummy functions */ /* not used, for dummy functions */
typedef enum { typedef enum {
VIDEO_HDMI_CEC_MODE_OFF = 0, VIDEO_HDMI_CEC_MODE_OFF = 0,
VIDEO_HDMI_CEC_MODE_TUNER, VIDEO_HDMI_CEC_MODE_TUNER,
VIDEO_HDMI_CEC_MODE_RECORDER VIDEO_HDMI_CEC_MODE_RECORDER
} VIDEO_HDMI_CEC_MODE; } VIDEO_HDMI_CEC_MODE;
@@ -127,11 +127,11 @@ class cVideo
int /*vidOutFmt_t*/ outputformat; int /*vidOutFmt_t*/ outputformat;
int scartvoltage; int scartvoltage;
VIDEO_FORMAT StreamType; VIDEO_FORMAT StreamType;
VIDEO_DEFINITION VideoDefinition; VIDEO_DEFINITION VideoDefinition;
DISPLAY_AR DisplayAR; DISPLAY_AR DisplayAR;
VIDEO_PLAY_MODE SyncMode; VIDEO_PLAY_MODE SyncMode;
DISPLAY_AR_MODE ARMode; DISPLAY_AR_MODE ARMode;
VIDEO_DB_DR eDbDr; VIDEO_DB_DR eDbDr;
DISPLAY_AR PictureAR; DISPLAY_AR PictureAR;
VIDEO_FRAME_RATE FrameRate; VIDEO_FRAME_RATE FrameRate;

View File

@@ -1,17 +1,19 @@
noinst_LTLIBRARIES = libcommon.la noinst_LTLIBRARIES = libcommon.la
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
AM_CXXFLAGS += \
-I $(top_srcdir)/include
AM_LDFLAGS = -lpthread AM_LDFLAGS = -lpthread
if BOXTYPE_DUCKBOX if BOXTYPE_DUCKBOX
AM_CXXFLAGS += \ AM_CXXFLAGS += \
-I $(top_srcdir)/include \
-I $(top_srcdir)/libdvbci -I $(top_srcdir)/libdvbci
endif endif
if BOXTYPE_ARMBOX if BOXTYPE_ARMBOX
AM_CXXFLAGS += \ AM_CXXFLAGS += \
-I $(top_srcdir)/include \
-I $(top_srcdir)/libdvbci -I $(top_srcdir)/libdvbci
endif endif

View File

@@ -1 +0,0 @@
../include/hardware_caps.h

View File

@@ -1,9 +1,8 @@
noinst_LTLIBRARIES = libgeneric.la noinst_LTLIBRARIES = libgeneric.la
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS AM_CPPFLAGS = \
AM_CPPFLAGS += \ -I$(top_srcdir)/common \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include
-I$(top_srcdir)/common
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing
@@ -45,3 +44,4 @@ libgeneric_la_SOURCES += \
endif endif
endif endif
AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS

View File

@@ -23,7 +23,7 @@
#include <cstdlib> #include <cstdlib>
#include "audio_lib.h" #include "audio_lib.h"
#include "dmx_lib.h" #include "dmx_hal.h"
#include "lt_debug.h" #include "lt_debug.h"
#define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args) #define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args)

View File

@@ -5,13 +5,13 @@
#include <stdint.h> #include <stdint.h>
#include <thread_abstraction.h> #include <thread_abstraction.h>
#include "../common/cs_types.h" #include "cs_types.h"
typedef enum typedef enum
{ {
AUDIO_SYNC_WITH_PTS, AUDIO_SYNC_WITH_PTS,
AUDIO_NO_SYNC, AUDIO_NO_SYNC,
AUDIO_SYNC_AUDIO_MASTER AUDIO_SYNC_AUDIO_MASTER
} AUDIO_SYNC_MODE; } AUDIO_SYNC_MODE;
typedef enum { typedef enum {
@@ -22,20 +22,20 @@ typedef enum {
typedef enum typedef enum
{ {
AUDIO_FMT_AUTO = 0, AUDIO_FMT_AUTO = 0,
AUDIO_FMT_MPEG, AUDIO_FMT_MPEG,
AUDIO_FMT_MP3, AUDIO_FMT_MP3,
AUDIO_FMT_DOLBY_DIGITAL, AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL, AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_AAC, AUDIO_FMT_AAC,
AUDIO_FMT_AAC_PLUS, AUDIO_FMT_AAC_PLUS,
AUDIO_FMT_DD_PLUS, AUDIO_FMT_DD_PLUS,
AUDIO_FMT_DTS, AUDIO_FMT_DTS,
AUDIO_FMT_AVS, AUDIO_FMT_AVS,
AUDIO_FMT_MLP, AUDIO_FMT_MLP,
AUDIO_FMT_WMA, AUDIO_FMT_WMA,
AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT; } AUDIO_FORMAT;
class cAudio : public Thread class cAudio : public Thread
@@ -63,6 +63,7 @@ class cAudio : public Thread
int do_mute(bool enable, bool remember); int do_mute(bool enable, bool remember);
void setBypassMode(bool disable); void setBypassMode(bool disable);
void run(); void run();
public: public:
/* construct & destruct */ /* construct & destruct */
cAudio(void *, void *, void *); cAudio(void *, void *, void *);
@@ -102,4 +103,3 @@ class cAudio : public Thread
}; };
#endif #endif

View File

@@ -1 +0,0 @@
../libspark/cs_api.h

View File

@@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "config.h" #include "config.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -32,11 +31,12 @@
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <unistd.h> #include <unistd.h>
#include "dmx_lib.h" #include <sys/ioctl.h>
#include "dmx_hal.h"
#include "lt_debug.h" #include "lt_debug.h"
/* needed for getSTC :-( */
#include "video_lib.h" #include "video_lib.h"
/* needed for getSTC... */
extern cVideo *videoDecoder; extern cVideo *videoDecoder;
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args)
@@ -44,14 +44,8 @@ extern cVideo *videoDecoder;
#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args) #define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args)
#define dmx_err(_errfmt, _errstr, _revents) do { \ #define dmx_err(_errfmt, _errstr, _revents) do { \
uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\
if (dmx_type == DMX_PSI_CHANNEL) { \
_pid = s_flt.pid; _f = s_flt.filter.filter[0]; \
} else { \
_pid = p_flt.pid; \
}; \
lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \
} while(0); } while(0);
cDemux *videoDemux = NULL; cDemux *videoDemux = NULL;
@@ -95,9 +89,6 @@ cDemux::cDemux(int n)
else else
num = n; num = n;
fd = -1; fd = -1;
measure = false;
last_measure = 0;
last_data = 0;
} }
cDemux::~cDemux() cDemux::~cDemux()
@@ -163,8 +154,6 @@ void cDemux::Close(void)
ioctl(fd, DMX_STOP); ioctl(fd, DMX_STOP);
close(fd); close(fd);
fd = -1; fd = -1;
if (measure)
return;
if (dmx_type == DMX_TP_CHANNEL) if (dmx_type == DMX_TP_CHANNEL)
{ {
dmx_tp_count--; dmx_tp_count--;
@@ -256,11 +245,13 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
return rc; return rc;
} }
bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter,
const unsigned char * const mask, int len, int timeout, const unsigned char * const mask, int len, int timeout,
const unsigned char * const negmask) const unsigned char * const negmask)
{ {
struct dmx_sct_filter_params s_flt;
memset(&s_flt, 0, sizeof(s_flt)); memset(&s_flt, 0, sizeof(s_flt));
pid = _pid;
if (len > DMX_FILTER_SIZE) if (len > DMX_FILTER_SIZE)
{ {
@@ -269,6 +260,7 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
} }
s_flt.pid = pid; s_flt.pid = pid;
s_flt.timeout = timeout; s_flt.timeout = timeout;
flt = filter[0];
memcpy(s_flt.filter.filter, filter, len); memcpy(s_flt.filter.filter, filter, len);
memcpy(s_flt.filter.mask, mask, len); memcpy(s_flt.filter.mask, mask, len);
if (negmask != NULL) if (negmask != NULL)
@@ -369,8 +361,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
return true; return true;
} }
bool cDemux::pesFilter(const unsigned short pid) bool cDemux::pesFilter(const unsigned short _pid)
{ {
struct dmx_pes_filter_params p_flt;
pid = _pid;
flt = 0;
/* allow PID 0 for web streaming e.g. /* allow PID 0 for web streaming e.g.
* this check originally is from tuxbox cvs but I'm not sure * this check originally is from tuxbox cvs but I'm not sure
* what it is good for... * what it is good for...

View File

@@ -1 +0,0 @@
#include "dmx_lib.h"

View File

@@ -1,70 +0,0 @@
#ifndef __DEMUX_TD_H
#define __DEMUX_TD_H
#include <cstdlib>
#include <vector>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include "../common/cs_types.h"
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,
DMX_VIDEO_CHANNEL = 1,
DMX_AUDIO_CHANNEL,
DMX_PES_CHANNEL,
DMX_PSI_CHANNEL,
DMX_PIP_CHANNEL,
DMX_TP_CHANNEL,
DMX_PCR_ONLY_CHANNEL
} DMX_CHANNEL_TYPE;
typedef struct
{
int fd;
unsigned short pid;
} pes_pids;
class cDemux
{
private:
int num;
int fd;
int buffersize;
bool measure;
uint64_t last_measure, last_data;
DMX_CHANNEL_TYPE dmx_type;
std::vector<pes_pids> pesfds;
struct dmx_sct_filter_params s_flt;
struct dmx_pes_filter_params p_flt;
public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0);
void Close(void);
bool Start(bool record = false);
bool Stop(void);
int Read(unsigned char *buff, int len, int Timeout = 0);
bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL);
bool pesFilter(const unsigned short pid);
void SetSyncMode(AVSYNC_TYPE mode);
void * getBuffer();
void * getChannel();
DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; };
bool addPid(unsigned short pid);
void getSTC(int64_t * STC);
int getUnit(void);
static bool SetSource(int unit, int source);
static int GetSource(int unit);
// TD only functions
int getFD(void) { return fd; }; /* needed by cPlayback class */
void removePid(unsigned short Pid); /* needed by cRecord class */
std::vector<pes_pids> getPesPids(void) { return pesfds; };
//
cDemux(int num = 0);
~cDemux();
};
#endif //__DEMUX_H

View File

@@ -1,9 +1,10 @@
#include <cstring> #include <cstring>
#include <unistd.h> #include <unistd.h>
#include "init_lib.h" #include "init_td.h"
#include "lt_debug.h"
#include "glfb.h" #include "glfb.h"
#include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_INIT, NULL, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_INIT, NULL, args)

View File

@@ -1,5 +0,0 @@
#ifndef __INIT_TD_H
#define __INIT_TD_H
void init_td_api();
void shutdown_td_api();
#endif

View File

@@ -40,7 +40,7 @@ extern "C" {
#define DMX_BUF_SZ 0x20000 #define DMX_BUF_SZ 0x20000
#include "video_lib.h" #include "video_lib.h"
#include "dmx_lib.h" #include "dmx_hal.h"
#include "glfb.h" #include "glfb.h"
#include "lt_debug.h" #include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args)

View File

@@ -1,12 +1,12 @@
#ifndef _VIDEO_TD_H #ifndef _VIDEO_LIB_H
#define _VIDEO_TD_H #define _VIDEO_LIB_H
#include <thread_abstraction.h> #include <thread_abstraction.h>
#include <mutex_abstraction.h> #include <mutex_abstraction.h>
#include <vector> #include <vector>
#include <linux/dvb/video.h> #include <linux/dvb/video.h>
#include "../common/cs_types.h" #include "cs_types.h"
#include "dmx_lib.h" #include "dmx_hal.h"
extern "C" { extern "C" {
#include <libavutil/rational.h> #include <libavutil/rational.h>
} }
@@ -60,7 +60,7 @@ typedef enum {
DISPLAY_AR_14_9, DISPLAY_AR_14_9,
DISPLAY_AR_16_9, DISPLAY_AR_16_9,
DISPLAY_AR_20_9, DISPLAY_AR_20_9,
DISPLAY_AR_RAW, DISPLAY_AR_RAW
} DISPLAY_AR; } DISPLAY_AR;
typedef enum { typedef enum {
@@ -104,7 +104,7 @@ typedef enum {
/* not used, for dummy functions */ /* not used, for dummy functions */
typedef enum { typedef enum {
VIDEO_HDMI_CEC_MODE_OFF = 0, VIDEO_HDMI_CEC_MODE_OFF = 0,
VIDEO_HDMI_CEC_MODE_TUNER, VIDEO_HDMI_CEC_MODE_TUNER,
VIDEO_HDMI_CEC_MODE_RECORDER VIDEO_HDMI_CEC_MODE_RECORDER
} VIDEO_HDMI_CEC_MODE; } VIDEO_HDMI_CEC_MODE;

View File

@@ -1 +1 @@
#include "../common/ca.h" #include "ca.h"

View File

@@ -1,20 +1,37 @@
/* compatibility header for tripledragon. I'm lazy, so I just left it
as "cs_api.h" so that I don't need too many ifdefs in the code */
#ifndef __CS_API_H_
#define __CS_API_H_
#include "init_td.h"
#include <config.h> #include <config.h>
#if HAVE_TRIPLEDRAGON
#include "../libtriple/cs_api.h" typedef void (*cs_messenger) (unsigned int msg, unsigned int data);
#elif HAVE_DUCKBOX_HARDWARE
#include "../libduckbox/cs_api.h" inline void cs_api_init()
#elif HAVE_SPARK_HARDWARE {
#include "../libspark/cs_api.h" init_td_api();
#elif HAVE_ARM_HARDWARE };
#include "../libarmbox/cs_api.h"
#elif HAVE_AZBOX_HARDWARE inline void cs_api_exit()
#include "../azbox/cs_api.h" {
#elif HAVE_GENERIC_HARDWARE shutdown_td_api();
#if BOXMODEL_RASPI };
#include "../raspi/cs_api.h"
#define cs_malloc_uncached malloc
#define cs_free_uncached free
// Callback function helpers
#if HAVE_DUCKBOX_HARDWARE || HAVE_ARM_HARDWARE
void cs_register_messenger(cs_messenger messenger);
#else #else
#include "../generic-pc/cs_api.h" static inline void cs_register_messenger(cs_messenger) { return; };
#endif
#else
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined
#endif #endif
static inline void cs_deregister_messenger(void) { return; };
/* compat... HD1 seems to be version 6. everything newer ist > 6... */
static inline unsigned int cs_get_revision(void) { return 1; };
static inline unsigned int cs_get_chip_type(void) { return 0; };
extern int cnxt_debug;
#endif //__CS_API_H_

View File

@@ -1,20 +1,97 @@
#include <config.h> /*
#if HAVE_TRIPLEDRAGON * (C) 2010-2013 Stefan Seyfried
#include "../libtriple/dmx_td.h" *
#elif HAVE_DUCKBOX_HARDWARE * This program is free software; you can redistribute it and/or modify
#include "../libduckbox/dmx_lib.h" * it under the terms of the GNU General Public License as published by
#elif HAVE_SPARK_HARDWARE * the Free Software Foundation; either version 2 of the License, or
#include "../libspark/dmx_lib.h" * (at your option) any later version.
#elif HAVE_AZBOX_HARDWARE *
#include "../azbox/dmx_lib.h" * This program is distributed in the hope that it will be useful,
#elif HAVE_ARM_HARDWARE * but WITHOUT ANY WARRANTY; without even the implied warranty of
#include "../libarmbox/dmx_lib.h" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#elif HAVE_GENERIC_HARDWARE * GNU General Public License for more details.
#if BOXMODEL_RASPI *
#include "../raspi/dmx_lib.h" * You should have received a copy of the GNU General Public License
#else * along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "../generic-pc/dmx_lib.h" */
#endif
#else #ifndef __dmx_hal__
#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined #define __dmx_hal__
#include <cstdlib>
#include <vector>
#include <inttypes.h>
/* at least on td, config.h needs to be included before... */
#ifndef HAVE_TRIPLEDRAGON
#include <linux/dvb/dmx.h>
#else /* TRIPLEDRAGON */
extern "C" {
#include <hardware/xp/xp_osd_user.h>
}
#if defined DMX_FILTER_SIZE
#undef DMX_FILTER_SIZE
#endif #endif
#define DMX_FILTER_SIZE FILTER_LENGTH
#endif /* TRIPLEDRAGON */
#include <cs_types.h>
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,
DMX_VIDEO_CHANNEL = 1,
DMX_AUDIO_CHANNEL,
DMX_PES_CHANNEL,
DMX_PSI_CHANNEL,
DMX_PIP_CHANNEL,
DMX_TP_CHANNEL,
DMX_PCR_ONLY_CHANNEL
} DMX_CHANNEL_TYPE;
typedef struct
{
int fd;
unsigned short pid;
} pes_pids;
class cRecord;
class cPlayback;
class cDemux
{
friend class cRecord;
friend class cPlayback;
public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0);
void Close(void);
bool Start(bool record = false);
bool Stop(void);
int Read(unsigned char *buff, int len, int Timeout = 0);
bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL);
bool pesFilter(const unsigned short pid);
void SetSyncMode(AVSYNC_TYPE mode);
void * getBuffer();
void * getChannel();
DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; };
bool addPid(unsigned short pid);
void getSTC(int64_t * STC);
int getUnit(void);
static bool SetSource(int unit, int source);
static int GetSource(int unit);
int getFD(void) { return fd; }; /* needed by cPlayback class */
cDemux(int num = 0);
~cDemux();
private:
void removePid(unsigned short Pid); /* needed by cRecord class */
int num;
int fd;
int buffersize;
uint16_t pid;
uint8_t flt;
std::vector<pes_pids> pesfds;
DMX_CHANNEL_TYPE dmx_type;
void *pdata;
};
#endif //__dmx_hal__

View File

@@ -6,7 +6,7 @@
#define MAX_MMI_CHOICE_TEXT_LEN 255 #define MAX_MMI_CHOICE_TEXT_LEN 255
typedef enum { typedef enum {
MMI_TOP_MENU_SUBS = 1, MMI_TOP_MENU_SUBS = 1,
MMI_TOP_MENU_EVENTS, MMI_TOP_MENU_EVENTS,
MMI_TOP_MENU_TOKENS, MMI_TOP_MENU_TOKENS,
MMI_TOP_MENU_PIN, MMI_TOP_MENU_PIN,
@@ -15,13 +15,13 @@ typedef enum {
} MMI_MENU_CURRENT; } MMI_MENU_CURRENT;
typedef enum { typedef enum {
MMI_MENU_LEVEL_MAIN = 0, MMI_MENU_LEVEL_MAIN = 0,
MMI_MENU_LEVEL_MATURE, MMI_MENU_LEVEL_MATURE,
MMI_MENU_LEVEL_ASK_PIN_MATURE MMI_MENU_LEVEL_ASK_PIN_MATURE
} MMI_MENU_LEVEL; } MMI_MENU_LEVEL;
typedef enum { typedef enum {
MMI_PIN_LEVEL_ASK_OLD = 0, MMI_PIN_LEVEL_ASK_OLD = 0,
MMI_PIN_LEVEL_CHECK_CURRENT, MMI_PIN_LEVEL_CHECK_CURRENT,
MMI_PIN_LEVEL_ASK_REPEAT, MMI_PIN_LEVEL_ASK_REPEAT,
MMI_PIN_LEVEL_CHECK_AND_CHANGE MMI_PIN_LEVEL_CHECK_AND_CHANGE
@@ -44,7 +44,7 @@ typedef struct {
} MMI_ENQUIRY_INFO; } MMI_ENQUIRY_INFO;
/* compat */ /* compat */
#define enguiryText enquiryText #define enguiryText enquiryText
#define MMI_ENGUIRY_INFO MMI_ENQUIRY_INFO #define MMI_ENGUIRY_INFO MMI_ENQUIRY_INFO
#endif // __MMI_H_ #endif // __MMI_H_

View File

@@ -1,7 +1,6 @@
noinst_LTLIBRARIES = libarmbox.la noinst_LTLIBRARIES = libarmbox.la
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS AM_CPPFLAGS = \
AM_CPPFLAGS += \
-I$(top_srcdir)/common \ -I$(top_srcdir)/common \
-I$(top_srcdir)/include -I$(top_srcdir)/include
@@ -13,7 +12,7 @@ AM_LDFLAGS = \
@AVUTIL_LIBS@ \ @AVUTIL_LIBS@ \
@AVCODEC_LIBS@ \ @AVCODEC_LIBS@ \
@SWRESAMPLE_LIBS@ \ @SWRESAMPLE_LIBS@ \
-lpthread -lasound -lrt -lpthread -lass -lrt
libarmbox_la_SOURCES = \ libarmbox_la_SOURCES = \
hardware_caps.c \ hardware_caps.c \
@@ -42,3 +41,5 @@ AM_CPPFLAGS += \
AM_LDFLAGS += \ AM_LDFLAGS += \
-lass -lass
endif endif
AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS

View File

@@ -9,8 +9,8 @@
#include <linux/dvb/audio.h> #include <linux/dvb/audio.h>
#include <proc_tools.h> #include <proc_tools.h>
#include "audio_lib.h" #include "audio_lib.h"
//#include "audio_mixer.h"
#include "lt_debug.h" #include "lt_debug.h"
#define AUDIO_DEVICE "/dev/dvb/adapter0/audio0" #define AUDIO_DEVICE "/dev/dvb/adapter0/audio0"
@@ -26,7 +26,6 @@ cAudio::cAudio(void *, void *, void *)
fd = -1; fd = -1;
clipfd = -1; clipfd = -1;
mixer_fd = -1; mixer_fd = -1;
openDevice(); openDevice();
Muted = false; Muted = false;
} }
@@ -147,8 +146,6 @@ void cAudio::SetSyncMode(AVSYNC_TYPE Mode)
ioctl(fd, AUDIO_SET_AV_SYNC, Mode); ioctl(fd, AUDIO_SET_AV_SYNC, Mode);
} }
// E2 streamtype values. These correspond to
// player2/linux/drivers/media/dvb/stm/dvb/dvb_audio.c:AudioIoctlSetBypassMode
#define AUDIO_STREAMTYPE_AC3 0 #define AUDIO_STREAMTYPE_AC3 0
#define AUDIO_STREAMTYPE_MPEG 1 #define AUDIO_STREAMTYPE_MPEG 1
#define AUDIO_STREAMTYPE_DTS 2 #define AUDIO_STREAMTYPE_DTS 2

View File

@@ -1,8 +1,9 @@
/* public header file */ /* public header file */
#ifndef _AUDIO_TD_H_ #ifndef _AUDIO_LIB_H_
#define _AUDIO_TD_H_ #define _AUDIO_LIB_H_
#include "../common/cs_types.h"
#include "cs_types.h"
typedef enum typedef enum
{ {

View File

@@ -1,67 +0,0 @@
/* compatibility header for tripledragon. I'm lazy, so I just left it
as "cs_api.h" so that I don't need too many ifdefs in the code */
#ifndef __CS_API_H_
#define __CS_API_H_
#include "init_lib.h"
typedef void (*cs_messenger) (unsigned int msg, unsigned int data);
#if 0
enum CS_LOG_MODULE {
CS_LOG_CI = 0,
CS_LOG_HDMI_CEC,
CS_LOG_HDMI,
CS_LOG_VIDEO,
CS_LOG_VIDEO_DRM,
CS_LOG_AUDIO,
CS_LOG_DEMUX,
CS_LOG_DENC,
CS_LOG_PVR_RECORD,
CS_LOG_PVR_PLAY,
CS_LOG_POWER_CTRL,
CS_LOG_POWER_CLK,
CS_LOG_MEM,
CS_LOG_API,
};
#endif
inline void cs_api_init()
{
init_td_api();
};
inline void cs_api_exit()
{
shutdown_td_api();
};
#define cs_malloc_uncached malloc
#define cs_free_uncached free
// Callback function helpers
void cs_register_messenger(cs_messenger messenger);
static inline void cs_deregister_messenger(void) { return; };
//cs_messenger cs_get_messenger(void);
#if 0
// Logging functions
void cs_log_enable(void);
void cs_log_disable(void);
void cs_log_message(const char *prefix, const char *fmt, ...);
void cs_log_module_enable(enum CS_LOG_MODULE module);
void cs_log_module_disable(enum CS_LOG_MODULE module);
void cs_log_module_message(enum CS_LOG_MODULE module, const char *fmt, ...);
// TS Routing
unsigned int cs_get_ts_output(void);
int cs_set_ts_output(unsigned int port);
// Serial nr and revision accessors
unsigned long long cs_get_serial(void);
#endif
/* compat... HD1 seems to be version 6. everything newer ist > 6... */
static inline unsigned int cs_get_revision(void) { return 1; };
static inline unsigned int cs_get_chip_type(void) { return 0; };
extern int cnxt_debug;
#endif //__CS_API_H_

View File

@@ -31,7 +31,10 @@
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include "dmx_lib.h" #include <sys/ioctl.h>
#include <OpenThreads/Mutex>
#include <OpenThreads/ScopedLock>
#include "dmx_hal.h"
#include "lt_debug.h" #include "lt_debug.h"
#include "video_lib.h" #include "video_lib.h"
@@ -40,21 +43,19 @@ extern cVideo *videoDecoder;
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args)
#define lt_debug_c(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, NULL, args)
#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args) #define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args)
#define lt_info_z(args...) _lt_info(TRIPLE_DEBUG_DEMUX, thiz, args)
#define lt_debug_z(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, thiz, args)
#define dmx_err(_errfmt, _errstr, _revents) do { \ #define dmx_err(_errfmt, _errstr, _revents) do { \
uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\
if (dmx_type == DMX_PSI_CHANNEL) { \
_pid = s_flt.pid; _f = s_flt.filter.filter[0]; \
} else { \
_pid = p_flt.pid; \
}; \
lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \
} while(0); } while(0);
cDemux *videoDemux = NULL; cDemux *videoDemux = NULL;
cDemux *audioDemux = NULL; cDemux *audioDemux = NULL;
//cDemux *pcrDemux = NULL;
static const char *DMX_T[] = { static const char *DMX_T[] = {
"DMX_INVALID", "DMX_INVALID",
@@ -88,6 +89,12 @@ static const char *devname[NUM_DEMUXDEV] = {
/* did we already DMX_SET_SOURCE on that demux device? */ /* did we already DMX_SET_SOURCE on that demux device? */
static bool init[NUM_DEMUXDEV] = { false, false, false, false, false, false, false, false }; static bool init[NUM_DEMUXDEV] = { false, false, false, false, false, false, false, false };
typedef struct dmx_pdata {
int last_source;
OpenThreads::Mutex *mutex;
} dmx_pdata;
#define P ((dmx_pdata *)pdata)
cDemux::cDemux(int n) cDemux::cDemux(int n)
{ {
if (n < 0 || n >= NUM_DEMUX) if (n < 0 || n >= NUM_DEMUX)
@@ -98,16 +105,22 @@ cDemux::cDemux(int n)
else else
num = n; num = n;
fd = -1; fd = -1;
measure = false; pdata = (void *)calloc(1, sizeof(dmx_pdata));
last_measure = 0; P->last_source = -1;
last_data = 0; P->mutex = new OpenThreads::Mutex;
last_source = -1; dmx_type = DMX_INVALID;
} }
cDemux::~cDemux() cDemux::~cDemux()
{ {
lt_debug("%s #%d fd: %d\n", __FUNCTION__, num, fd); lt_debug("%s #%d fd: %d\n", __FUNCTION__, num, fd);
Close(); Close();
/* wait until Read() has released the mutex */
(*P->mutex).lock();
(*P->mutex).unlock();
free(P->mutex);
free(pdata);
pdata = NULL;
} }
bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBufferSize) bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBufferSize)
@@ -122,18 +135,18 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe
return true; return true;
} }
bool cDemux::_open(void) static bool _open(cDemux *thiz, int num, int &fd, int &last_source, DMX_CHANNEL_TYPE dmx_type, int buffersize)
{ {
int flags = O_RDWR|O_CLOEXEC; int flags = O_RDWR|O_CLOEXEC;
int devnum = dmx_source[num]; int devnum = dmx_source[num];
if (last_source == devnum) { if (last_source == devnum) {
lt_debug("%s #%d: source (%d) did not change\n", __func__, num, last_source); lt_debug_z("%s #%d: source (%d) did not change\n", __func__, num, last_source);
if (fd > -1) if (fd > -1)
return true; return true;
} }
if (fd > -1) { if (fd > -1) {
/* we changed source -> close and reopen the fd */ /* we changed source -> close and reopen the fd */
lt_debug("%s #%d: FD ALREADY OPENED fd = %d lastsource %d devnum %d\n", lt_debug_z("%s #%d: FD ALREADY OPENED fd = %d lastsource %d devnum %d\n",
__func__, num, fd, last_source, devnum); __func__, num, fd, last_source, devnum);
close(fd); close(fd);
} }
@@ -144,10 +157,10 @@ bool cDemux::_open(void)
fd = open(devname[devnum], flags); fd = open(devname[devnum], flags);
if (fd < 0) if (fd < 0)
{ {
lt_info("%s %s: %m\n", __FUNCTION__, devname[devnum]); lt_info_z("%s %s: %m\n", __FUNCTION__, devname[devnum]);
return false; return false;
} }
lt_debug("%s #%d pes_type: %s(%d), uBufferSize: %d fd: %d\n", __func__, lt_debug_z("%s #%d pes_type: %s(%d), uBufferSize: %d fd: %d\n", __func__,
num, DMX_T[dmx_type], dmx_type, buffersize, fd); num, DMX_T[dmx_type], dmx_type, buffersize, fd);
/* this would actually need locking, but the worst that weill happen is, that /* this would actually need locking, but the worst that weill happen is, that
@@ -156,9 +169,9 @@ bool cDemux::_open(void)
{ {
/* this should not change anything... */ /* this should not change anything... */
int n = DMX_SOURCE_FRONT0 + devnum; int n = DMX_SOURCE_FRONT0 + devnum;
lt_info("%s: setting %s to source %d\n", __func__, devname[devnum], n); lt_info_z("%s: setting %s to source %d\n", __func__, devname[devnum], n);
if (ioctl(fd, DMX_SET_SOURCE, &n) < 0) if (ioctl(fd, DMX_SET_SOURCE, &n) < 0)
lt_info("%s DMX_SET_SOURCE failed!\n", __func__); lt_info_z("%s DMX_SET_SOURCE failed!\n", __func__);
else else
init[devnum] = true; init[devnum] = true;
} }
@@ -168,7 +181,7 @@ bool cDemux::_open(void)
{ {
/* probably uBufferSize == 0 means "use default size". TODO: find a reasonable default */ /* probably uBufferSize == 0 means "use default size". TODO: find a reasonable default */
if (ioctl(fd, DMX_SET_BUFFER_SIZE, buffersize) < 0) if (ioctl(fd, DMX_SET_BUFFER_SIZE, buffersize) < 0)
lt_info("%s DMX_SET_BUFFER_SIZE failed (%m)\n", __func__); lt_info_z("%s DMX_SET_BUFFER_SIZE failed (%m)\n", __func__);
} }
last_source = devnum; last_source = devnum;
@@ -188,12 +201,11 @@ void cDemux::Close(void)
ioctl(fd, DMX_STOP); ioctl(fd, DMX_STOP);
close(fd); close(fd);
fd = -1; fd = -1;
if (measure)
return;
} }
bool cDemux::Start(bool) bool cDemux::Start(bool)
{ {
lt_debug("%s #%d fd: %d type: %s\n", __func__, num, fd, DMX_T[dmx_type]);
if (fd < 0) if (fd < 0)
{ {
lt_info("%s #%d: not open!\n", __FUNCTION__, num); lt_info("%s #%d: not open!\n", __FUNCTION__, num);
@@ -205,6 +217,7 @@ bool cDemux::Start(bool)
bool cDemux::Stop(void) bool cDemux::Stop(void)
{ {
lt_debug("%s #%d fd: %d type: %s\n", __func__, num, fd, DMX_T[dmx_type]);
if (fd < 0) if (fd < 0)
{ {
lt_info("%s #%d: not open!\n", __FUNCTION__, num); lt_info("%s #%d: not open!\n", __FUNCTION__, num);
@@ -226,6 +239,8 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
lt_info("%s #%d: not open!\n", __func__, num); lt_info("%s #%d: not open!\n", __func__, num);
return -1; return -1;
} }
/* avoid race in destructor: ~cDemux needs to wait until Read() returns */
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(*P->mutex);
int rc; int rc;
int to = timeout; int to = timeout;
struct pollfd ufds; struct pollfd ufds;
@@ -243,6 +258,12 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
{ {
retry: retry:
rc = ::poll(&ufds, 1, to); rc = ::poll(&ufds, 1, to);
if (ufds.fd != fd)
{
/* Close() will set fd to -1, this is normal. Everything else is not. */
lt_info("%s:1 ========== fd has changed, %d->%d ==========\n", __func__, ufds.fd, fd);
return -1;
}
if (!rc) if (!rc)
{ {
if (timeout == 0) /* we took the emergency exit */ if (timeout == 0) /* we took the emergency exit */
@@ -280,6 +301,11 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
return 0; return 0;
} }
} }
if (ufds.fd != fd) /* does this ever happen? and if, is it harmful? */
{ /* read(-1,...) will just return EBADF anyway... */
lt_info("%s:2 ========== fd has changed, %d->%d ==========\n", __func__, ufds.fd, fd);
return -1;
}
rc = ::read(fd, buff, len); rc = ::read(fd, buff, len);
//fprintf(stderr, "fd %d ret: %d\n", fd, rc); //fprintf(stderr, "fd %d ret: %d\n", fd, rc);
@@ -289,19 +315,22 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
return rc; return rc;
} }
bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter,
const unsigned char * const mask, int len, int timeout, const unsigned char * const mask, int len, int timeout,
const unsigned char * const negmask) const unsigned char * const negmask)
{ {
struct dmx_sct_filter_params s_flt;
memset(&s_flt, 0, sizeof(s_flt)); memset(&s_flt, 0, sizeof(s_flt));
pid = _pid;
_open(); _open(this, num, fd, P->last_source, dmx_type, buffersize);
if (len > DMX_FILTER_SIZE) if (len > DMX_FILTER_SIZE)
{ {
lt_info("%s #%d: len too long: %d, DMX_FILTER_SIZE %d\n", __func__, num, len, DMX_FILTER_SIZE); lt_info("%s #%d: len too long: %d, DMX_FILTER_SIZE %d\n", __func__, num, len, DMX_FILTER_SIZE);
len = DMX_FILTER_SIZE; len = DMX_FILTER_SIZE;
} }
flt = filter[0];
s_flt.pid = pid; s_flt.pid = pid;
s_flt.timeout = timeout; s_flt.timeout = timeout;
memcpy(s_flt.filter.filter, filter, len); memcpy(s_flt.filter.filter, filter, len);
@@ -312,79 +341,80 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
s_flt.flags = DMX_IMMEDIATE_START|DMX_CHECK_CRC; s_flt.flags = DMX_IMMEDIATE_START|DMX_CHECK_CRC;
int to = 0; int to = 0;
switch (filter[0]) { switch (filter[0])
case 0x00: /* program_association_section */ {
to = 2000; case 0x00: /* program_association_section */
break; to = 2000;
case 0x01: /* conditional_access_section */ break;
to = 6000; case 0x01: /* conditional_access_section */
break; to = 6000;
case 0x02: /* program_map_section */ break;
to = 1500; case 0x02: /* program_map_section */
break; to = 1500;
case 0x03: /* transport_stream_description_section */ break;
to = 10000; case 0x03: /* transport_stream_description_section */
break; to = 10000;
/* 0x04 - 0x3F: reserved */ break;
case 0x40: /* network_information_section - actual_network */ /* 0x04 - 0x3F: reserved */
to = 10000; case 0x40: /* network_information_section - actual_network */
break; to = 10000;
case 0x41: /* network_information_section - other_network */ break;
to = 15000; case 0x41: /* network_information_section - other_network */
break; to = 15000;
case 0x42: /* service_description_section - actual_transport_stream */ break;
to = 10000; case 0x42: /* service_description_section - actual_transport_stream */
break; to = 10000;
/* 0x43 - 0x45: reserved for future use */ break;
case 0x46: /* service_description_section - other_transport_stream */ /* 0x43 - 0x45: reserved for future use */
to = 10000; case 0x46: /* service_description_section - other_transport_stream */
break; to = 10000;
/* 0x47 - 0x49: reserved for future use */ break;
case 0x4A: /* bouquet_association_section */ /* 0x47 - 0x49: reserved for future use */
to = 11000; case 0x4A: /* bouquet_association_section */
break; to = 11000;
/* 0x4B - 0x4D: reserved for future use */ break;
case 0x4E: /* event_information_section - actual_transport_stream, present/following */ /* 0x4B - 0x4D: reserved for future use */
to = 2000; case 0x4E: /* event_information_section - actual_transport_stream, present/following */
break; to = 2000;
case 0x4F: /* event_information_section - other_transport_stream, present/following */ break;
to = 10000; case 0x4F: /* event_information_section - other_transport_stream, present/following */
break; to = 10000;
/* 0x50 - 0x5F: event_information_section - actual_transport_stream, schedule */ break;
/* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */ /* 0x50 - 0x5F: event_information_section - actual_transport_stream, schedule */
case 0x70: /* time_date_section */ /* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ case 0x70: /* time_date_section */
s_flt.flags |= DMX_ONESHOT; s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
//s_flt.pid = 0x0014; s_flt.flags |= DMX_ONESHOT;
to = 30000; //s_flt.pid = 0x0014;
break; to = 30000;
case 0x71: /* running_status_section */ break;
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ case 0x71: /* running_status_section */
to = 0; s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
break; to = 0;
case 0x72: /* stuffing_section */ break;
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ case 0x72: /* stuffing_section */
to = 0; s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
break; to = 0;
case 0x73: /* time_offset_section */ break;
s_flt.flags |= DMX_ONESHOT; case 0x73: /* time_offset_section */
//s_flt.pid = 0x0014; s_flt.flags |= DMX_ONESHOT;
to = 30000; //s_flt.pid = 0x0014;
break; to = 30000;
/* 0x74 - 0x7D: reserved for future use */ break;
case 0x7E: /* discontinuity_information_section */ /* 0x74 - 0x7D: reserved for future use */
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ case 0x7E: /* discontinuity_information_section */
to = 0; s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
break; to = 0;
case 0x7F: /* selection_information_section */ break;
to = 0; case 0x7F: /* selection_information_section */
break; to = 0;
/* 0x80 - 0x8F: ca_message_section */ break;
/* 0x90 - 0xFE: user defined */ /* 0x80 - 0x8F: ca_message_section */
/* 0xFF: reserved */ /* 0x90 - 0xFE: user defined */
default: /* 0xFF: reserved */
break; default:
// return -1; //return -1;
break;
} }
/* the negmask == NULL is a hack: the users of negmask are PMT-update /* the negmask == NULL is a hack: the users of negmask are PMT-update
* and sectionsd EIT-Version change. And they really want no timeout * and sectionsd EIT-Version change. And they really want no timeout
@@ -406,8 +436,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
return true; return true;
} }
bool cDemux::pesFilter(const unsigned short pid) bool cDemux::pesFilter(const unsigned short _pid)
{ {
struct dmx_pes_filter_params p_flt;
pid = _pid;
flt = 0;
/* allow PID 0 for web streaming e.g. /* allow PID 0 for web streaming e.g.
* this check originally is from tuxbox cvs but I'm not sure * this check originally is from tuxbox cvs but I'm not sure
* what it is good for... * what it is good for...
@@ -419,7 +452,7 @@ bool cDemux::pesFilter(const unsigned short pid)
lt_debug("%s #%d pid: 0x%04hx fd: %d type: %s\n", __FUNCTION__, num, pid, fd, DMX_T[dmx_type]); lt_debug("%s #%d pid: 0x%04hx fd: %d type: %s\n", __FUNCTION__, num, pid, fd, DMX_T[dmx_type]);
_open(); _open(this, num, fd, P->last_source, dmx_type, buffersize);
memset(&p_flt, 0, sizeof(p_flt)); memset(&p_flt, 0, sizeof(p_flt));
p_flt.pid = pid; p_flt.pid = pid;
@@ -427,30 +460,31 @@ bool cDemux::pesFilter(const unsigned short pid)
p_flt.input = DMX_IN_FRONTEND; p_flt.input = DMX_IN_FRONTEND;
p_flt.flags = 0; p_flt.flags = 0;
switch (dmx_type) { switch (dmx_type)
case DMX_PCR_ONLY_CHANNEL: {
p_flt.pes_type = DMX_PES_PCR; case DMX_PCR_ONLY_CHANNEL:
break; p_flt.pes_type = DMX_PES_PCR;
case DMX_AUDIO_CHANNEL: break;
p_flt.pes_type = DMX_PES_AUDIO; case DMX_AUDIO_CHANNEL:
break; p_flt.pes_type = DMX_PES_AUDIO;
case DMX_VIDEO_CHANNEL: break;
p_flt.pes_type = DMX_PES_VIDEO; case DMX_VIDEO_CHANNEL:
break; p_flt.pes_type = DMX_PES_VIDEO;
case DMX_PIP_CHANNEL: /* PIP is a special version of DMX_VIDEO_CHANNEL */ break;
p_flt.pes_type = DMX_PES_VIDEO1; case DMX_PIP_CHANNEL: /* PIP is a special version of DMX_VIDEO_CHANNEL */
break; p_flt.pes_type = DMX_PES_VIDEO1;
case DMX_PES_CHANNEL: break;
p_flt.pes_type = DMX_PES_OTHER; case DMX_PES_CHANNEL:
p_flt.output = DMX_OUT_TAP; p_flt.pes_type = DMX_PES_OTHER;
break; p_flt.output = DMX_OUT_TAP;
case DMX_TP_CHANNEL: break;
p_flt.pes_type = DMX_PES_OTHER; case DMX_TP_CHANNEL:
p_flt.output = DMX_OUT_TSDEMUX_TAP; p_flt.pes_type = DMX_PES_OTHER;
break; p_flt.output = DMX_OUT_TSDEMUX_TAP;
default: break;
lt_info("%s #%d invalid dmx_type %d!\n", __func__, num, dmx_type); default:
return false; lt_info("%s #%d invalid dmx_type %d!\n", __func__, num, dmx_type);
return false;
} }
return (ioctl(fd, DMX_SET_PES_FILTER, &p_flt) >= 0); return (ioctl(fd, DMX_SET_PES_FILTER, &p_flt) >= 0);
} }
@@ -482,7 +516,7 @@ bool cDemux::addPid(unsigned short Pid)
lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid); lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid);
return false; return false;
} }
_open(); _open(this, num, fd, P->last_source, dmx_type, buffersize);
if (fd == -1) if (fd == -1)
lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid); lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid);
pfd.fd = fd; /* dummy */ pfd.fd = fd; /* dummy */
@@ -540,7 +574,7 @@ bool cDemux::SetSource(int unit, int source)
lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX); lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX);
return false; return false;
} }
lt_info_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source); lt_debug_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source);
if (source < 0 || source >= NUM_DEMUXDEV) if (source < 0 || source >= NUM_DEMUXDEV)
lt_info_c("%s(%d, %d) ERROR: source %d out of range!\n", __func__, unit, source, source); lt_info_c("%s(%d, %d) ERROR: source %d out of range!\n", __func__, unit, source, source);
else else
@@ -554,6 +588,6 @@ int cDemux::GetSource(int unit)
lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX); lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX);
return -1; return -1;
} }
lt_info_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]); lt_debug_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]);
return dmx_source[unit]; return dmx_source[unit];
} }

View File

@@ -1 +0,0 @@
#include "dmx_lib.h"

View File

@@ -1,72 +0,0 @@
#ifndef __DEMUX_TD_H
#define __DEMUX_TD_H
#include <cstdlib>
#include <vector>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include "../common/cs_types.h"
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,
DMX_VIDEO_CHANNEL = 1,
DMX_AUDIO_CHANNEL,
DMX_PES_CHANNEL,
DMX_PSI_CHANNEL,
DMX_PIP_CHANNEL,
DMX_TP_CHANNEL,
DMX_PCR_ONLY_CHANNEL
} DMX_CHANNEL_TYPE;
typedef struct
{
int fd;
unsigned short pid;
} pes_pids;
class cDemux
{
private:
int num;
int fd;
int buffersize;
bool measure;
uint64_t last_measure, last_data;
DMX_CHANNEL_TYPE dmx_type;
std::vector<pes_pids> pesfds;
struct dmx_sct_filter_params s_flt;
struct dmx_pes_filter_params p_flt;
int last_source;
bool _open(void);
public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * unused = NULL, int bufsize = 0);
void Close(void);
bool Start(bool record = false);
bool Stop(void);
int Read(unsigned char *buff, int len, int Timeout = 0);
bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL);
bool pesFilter(const unsigned short pid);
void SetSyncMode(AVSYNC_TYPE mode);
void * getBuffer();
void * getChannel();
DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; };
bool addPid(unsigned short pid);
void getSTC(int64_t * STC);
int getUnit(void);
static bool SetSource(int unit, int source);
static int GetSource(int unit);
// TD only functions
int getFD(void) { return fd; }; /* needed by cPlayback class */
void removePid(unsigned short Pid); /* needed by cRecord class */
std::vector<pes_pids> getPesPids(void) { return pesfds; };
//
cDemux(int num = 0);
~cDemux();
};
#endif //__DEMUX_H

View File

@@ -1,6 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include "init_lib.h"
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/types.h> #include <sys/types.h>
@@ -9,6 +8,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include "init_td.h"
#include "pwrmngr.h" #include "pwrmngr.h"
#include <proc_tools.h> #include <proc_tools.h>

View File

@@ -1,2 +0,0 @@
#warning using init_cs.h from libspark
#include "init_lib.h"

View File

@@ -1,5 +0,0 @@
#ifndef __INIT_TD_H
#define __INIT_TD_H
void init_td_api();
void shutdown_td_api();
#endif

View File

@@ -1,3 +1,19 @@
/*
* (C)
*
* 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/>.
*/
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <malloc.h> #include <malloc.h>
@@ -8,6 +24,7 @@
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
#include <pthread.h>
#include <aio.h> #include <aio.h>
#include "record_lib.h" #include "record_lib.h"
@@ -15,7 +32,7 @@
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_RECORD, this, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_RECORD, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_RECORD, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_RECORD, this, args)
/* helper functions to call the cpp thread loops */ /* helper function to call the cpp thread loop */
void *execute_record_thread(void *c) void *execute_record_thread(void *c)
{ {
cRecord *obj = (cRecord *)c; cRecord *obj = (cRecord *)c;
@@ -137,7 +154,7 @@ bool cRecord::ChangePids(unsigned short /*vpid*/, unsigned short *apids, int num
lt_info("%s: DMX = NULL\n", __func__); lt_info("%s: DMX = NULL\n", __func__);
return false; return false;
} }
pids = dmx->getPesPids(); pids = dmx->pesfds;
/* the first PID is the video pid, so start with the second PID... */ /* the first PID is the video pid, so start with the second PID... */
for (std::vector<pes_pids>::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) { for (std::vector<pes_pids>::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) {
found = false; found = false;
@@ -173,7 +190,7 @@ bool cRecord::AddPid(unsigned short pid)
lt_info("%s: DMX = NULL\n", __func__); lt_info("%s: DMX = NULL\n", __func__);
return false; return false;
} }
pids = dmx->getPesPids(); pids = dmx->pesfds;
for (std::vector<pes_pids>::const_iterator i = pids.begin(); i != pids.end(); ++i) { for (std::vector<pes_pids>::const_iterator i = pids.begin(); i != pids.end(); ++i) {
if ((*i).pid == pid) if ((*i).pid == pid)
return true; /* or is it an error to try to add the same PID twice? */ return true; /* or is it an error to try to add the same PID twice? */
@@ -214,7 +231,7 @@ void cRecord::RecordThread()
strncpy(threadname, "RecordThread", sizeof(threadname)); strncpy(threadname, "RecordThread", sizeof(threadname));
threadname[16] = 0; threadname[16] = 0;
prctl (PR_SET_NAME, (unsigned long)&threadname); prctl (PR_SET_NAME, (unsigned long)&threadname);
int readsize = bufsize/16; int readsize = bufsize / 16;
int buf_pos = 0; int buf_pos = 0;
int count = 0; int count = 0;
int queued = 0; int queued = 0;
@@ -257,13 +274,15 @@ void cRecord::RecordThread()
if (toread > readsize) if (toread > readsize)
toread = readsize; toread = readsize;
ssize_t s = dmx->Read(buf + buf_pos, toread, 50); ssize_t s = dmx->Read(buf + buf_pos, toread, 50);
lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__, buf_pos, (int)s, bufsize - buf_pos); lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__,
buf_pos, (int)s, bufsize - buf_pos);
if (s < 0) if (s < 0)
{ {
if (errno != EAGAIN && (errno != EOVERFLOW || !overflow)) if (errno != EAGAIN && (errno != EOVERFLOW || !overflow))
{ {
lt_info("%s: read failed: %m\n", __func__); lt_info("%s: read failed: %m\n", __func__);
exit_flag = RECORD_FAILED_READ; exit_flag = RECORD_FAILED_READ;
state = REC_STATUS_OVERFLOW;
break; break;
} }
} }
@@ -289,6 +308,7 @@ void cRecord::RecordThread()
overflow = true; overflow = true;
if (!(overflow_count % 10)) if (!(overflow_count % 10))
lt_info("%s: buffer full! Overflow? (%d)\n", __func__, ++overflow_count); lt_info("%s: buffer full! Overflow? (%d)\n", __func__, ++overflow_count);
state = REC_STATUS_SLOW;
} }
r = aio_error(&a); r = aio_error(&a);
if (r == EINPROGRESS) if (r == EINPROGRESS)

View File

@@ -1,9 +1,8 @@
#ifndef __RECORD_TD_H #ifndef __record_hal__
#define __RECORD_TD_H #define __record_hal__
#include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#include "dmx_lib.h" #include "dmx_hal.h"
#define REC_STATUS_OK 0 #define REC_STATUS_OK 0
#define REC_STATUS_SLOW 1 #define REC_STATUS_SLOW 1

View File

@@ -479,30 +479,6 @@ int cVideo::setBlank(int)
return Stop(1); return Stop(1);
} }
int cVideo::GetVideoSystem(void)
{
char current[32];
proc_get("/proc/stb/video/videomode", current, 32);
for (int i = 0; vid_modes[i]; i++)
{
if (strcmp(current, vid_modes[i]) == 0)
return i;
}
lt_info("%s: could not find '%s' mode, returning VIDEO_STD_720P50\n", __func__, current);
return VIDEO_STD_720P50;
}
void cVideo::GetVideoSystemFormatName(cs_vs_format_t *format, int system)
{
if (system == -1)
system = GetVideoSystem();
if (system < 0 || system > VIDEO_STD_1080P50) {
lt_info("%s: invalid system %d\n", __func__, system);
strcpy(format->format, "invalid");
} else
strcpy(format->format, vid_modes[system]);
}
int cVideo::SetVideoSystem(int video_system, bool remember) int cVideo::SetVideoSystem(int video_system, bool remember)
{ {
lt_debug("%s(%d, %d)\n", __func__, video_system, remember); lt_debug("%s(%d, %d)\n", __func__, video_system, remember);
@@ -534,6 +510,30 @@ int cVideo::SetVideoSystem(int video_system, bool remember)
return ret; return ret;
} }
int cVideo::GetVideoSystem(void)
{
char current[32];
proc_get("/proc/stb/video/videomode", current, 32);
for (int i = 0; vid_modes[i]; i++)
{
if (strcmp(current, vid_modes[i]) == 0)
return i;
}
lt_info("%s: could not find '%s' mode, returning VIDEO_STD_720P50\n", __func__, current);
return VIDEO_STD_720P50;
}
void cVideo::GetVideoSystemFormatName(cs_vs_format_t *format, int system)
{
if (system == -1)
system = GetVideoSystem();
if (system < 0 || system > VIDEO_STD_1080P50) {
lt_info("%s: invalid system %d\n", __func__, system);
strcpy(format->format, "invalid");
} else
strcpy(format->format, vid_modes[system]);
}
int cVideo::getPlayState(void) int cVideo::getPlayState(void)
{ {
return playstate; return playstate;

View File

@@ -1,9 +1,9 @@
#ifndef _VIDEO_TD_H #ifndef _VIDEO_LIB_H
#define _VIDEO_TD_H #define _VIDEO_LIB_H
#include <linux/dvb/video.h> #include <linux/dvb/video.h>
#include "../common/cs_types.h" #include "cs_types.h"
#include "dmx_lib.h" #include "dmx_hal.h"
typedef struct cs_vs_format_t typedef struct cs_vs_format_t
{ {
@@ -119,7 +119,7 @@ typedef enum {
} VIDEO_STD; } VIDEO_STD;
typedef enum { typedef enum {
VIDEO_HDMI_CEC_MODE_OFF = 0, VIDEO_HDMI_CEC_MODE_OFF = 0,
VIDEO_HDMI_CEC_MODE_TUNER = 3, VIDEO_HDMI_CEC_MODE_TUNER = 3,
VIDEO_HDMI_CEC_MODE_RECORDER = 1 VIDEO_HDMI_CEC_MODE_RECORDER = 1
} VIDEO_HDMI_CEC_MODE; } VIDEO_HDMI_CEC_MODE;
@@ -148,10 +148,13 @@ struct addressinfo
unsigned char type; unsigned char type;
}; };
class cDemux;
class cPlayback;
class cVideo class cVideo
{ {
friend class cDemux;
friend class cPlayback; friend class cPlayback;
friend class cDemux;
private: private:
/* video device */ /* video device */
int fd; int fd;

View File

@@ -1,7 +1,6 @@
noinst_LTLIBRARIES = libduckbox.la noinst_LTLIBRARIES = libduckbox.la
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS AM_CPPFLAGS = \
AM_CPPFLAGS += \
-I$(top_srcdir)/common \ -I$(top_srcdir)/common \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-I$(top_srcdir)/libeplayer3/include -I$(top_srcdir)/libeplayer3/include
@@ -25,3 +24,5 @@ libduckbox_la_SOURCES = \
playback_libeplayer3.cpp \ playback_libeplayer3.cpp \
pwrmngr.cpp \ pwrmngr.cpp \
record.cpp record.cpp
AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS

View File

@@ -1,31 +0,0 @@
/* compatibility header for tripledragon. I'm lazy, so I just left it
as "cs_api.h" so that I don't need too many ifdefs in the code */
#ifndef __CS_API_H_
#define __CS_API_H_
#include "init_lib.h"
typedef void (*cs_messenger) (unsigned int msg, unsigned int data);
inline void cs_api_init()
{
init_td_api();
};
inline void cs_api_exit()
{
shutdown_td_api();
};
#define cs_malloc_uncached malloc
#define cs_free_uncached free
// Callback function helpers
void cs_register_messenger(cs_messenger messenger);
static inline void cs_deregister_messenger(void) { return; };
/* compat... HD1 seems to be version 6. everything newer ist > 6... */
static inline unsigned int cs_get_revision(void) { return 1; };
static inline unsigned int cs_get_chip_type(void) { return 0; };
extern int cnxt_debug;
#endif //__CS_API_H_

View File

@@ -1 +0,0 @@
../libspark/dmx_cs.h

View File

@@ -1 +0,0 @@
../libspark/dmx_lib.h

View File

@@ -1,6 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include "init_lib.h"
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/types.h> #include <sys/types.h>
@@ -11,6 +10,7 @@
#include <linux/dvb/dmx.h> #include <linux/dvb/dmx.h>
#include "init_td.h"
#include "pwrmngr.h" #include "pwrmngr.h"
#include "lt_debug.h" #include "lt_debug.h"

View File

@@ -1 +0,0 @@
../libspark/init_cs.h

View File

@@ -1 +0,0 @@
../libspark/init_lib.h

View File

@@ -1,7 +1,6 @@
noinst_LTLIBRARIES = libspark.la noinst_LTLIBRARIES = libspark.la
AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS AM_CPPFLAGS = \
AM_CPPFLAGS += \
-I$(top_srcdir)/common \ -I$(top_srcdir)/common \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-I$(top_srcdir)/libeplayer3/include -I$(top_srcdir)/libeplayer3/include
@@ -26,3 +25,5 @@ libspark_la_SOURCES = \
playback_libeplayer3.cpp \ playback_libeplayer3.cpp \
pwrmngr.cpp \ pwrmngr.cpp \
record.cpp record.cpp
AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS

View File

@@ -1,72 +0,0 @@
libtriple reimplements the interfaces of the libcoolstrem library for
the Tripledragon receiver.
There are a few debugging or configuration helpers which affect the
way libtriple does some things. They are all configured by exporting
environment variables, which are described here:
TRIPLE_NOSCART=1 - makes neutrino *not* do any voltage switching on
SCART pin 8, probably not useful for anyone but me
TRIPLE_DEBUG=... - controls various debugging levels in libtriple
valid values for the different component:
audio 0x01
video 0x02
demux 0x04
play 0x08
power 0x10
init 0x20
ca 0x40
record 0x80
all 0xff
multiple levels are added / ORed together, so if you want to
debug record and playback code, do "export TRIPLE_DEBUG=0x88"
for audio & video use TRIPLE_DEBUG=0x3
DSP_DEVICE
MIX_DEVICE - alternative audio devices for the audioplayer and internet
radio. Those are used to output music to e.g. USB audio devices.
Here is what you need to do:
* look in /dev/sound which devices are already there. Probably
/dev/sound/dsp and /dev/sound/mixer, created by the tdoss driver
* make sure that the USB HC driver is loaded:
modprobe ohci-hcd
* load the USB audio driver:
modprobe audio
* plug in your USB audio device, check with "dmesg" that it is
recognised by the kernel
* look in /dev/sound which new devices are there. Probably it's
/dev/sound/dsp1 and /dev/sound/mixer1. If there are more - well
it's time to experiment ;)
* export DSP_DEVICE=/dev/sound/dsp1 and MIX_DEVICE=/dev/sound/mixer1
(of course the devices you found in the last step)
* from the same shell you exported the variables, start neutrino
(make sure that an already running neutrino is stopped before you
do that)
* start the audioplayer, play a track. Look for log lines like
[LT:106b5788:audio ] PrepareClipPlay: dsp_dev /dev/sound/dsp1 mix_dev /dev/sound/mixer1
* if it works - fine :-)
* if it does not work, look for:
PrepareClipPlay: DSP_DEVICE is set (/dev/sound/dsp1) but cannot be opened, fall back to /dev/sound/dsp
PrepareClipPlay: dsp_dev /dev/sound/dsp mix_dev /dev/sound/mixer1
PrepareClipPlay: open mixer /dev/sound/mixer1 failed (No such file or directory)
* this basically means that the device is not there. Different errors
will get different messages - I cannot trigger those now, so you'll
need to find them out by yourself ;)
* another possible messag you may get is:
PrepareClipPlay: more than one mixer control: devmask 00000021 stereo 00000021
This means that your device has more than one mixer. The set bit
numbers in the devmask are the different mixers, in this case
it would be number 0 and 5. To select one of those, export
MIX_NUMBER=5 or MIX_NUMBER=0 (this code is untested, there may
be bugs)
So now I found out what devices to use, but how do I make that permanent?
That's easy:
* create or extend /etc/rcS.local with
modprobe ohci-hcd
modprobe audio
* create or extend /etc/profile.local with
export DSP_DEVICE=/dev/sound/dsp1
export MIX_DEVICE=/dev/sound/mixer1
* reboot. Enjoy.

View File

@@ -9,6 +9,7 @@
#include <linux/dvb/audio.h> #include <linux/dvb/audio.h>
#include <proc_tools.h> #include <proc_tools.h>
#include "audio_lib.h" #include "audio_lib.h"
#include "audio_mixer.h" #include "audio_mixer.h"
#include "lt_debug.h" #include "lt_debug.h"
@@ -224,7 +225,7 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian)
if ((!dsp_dev) || (access(dsp_dev, W_OK))) { if ((!dsp_dev) || (access(dsp_dev, W_OK))) {
if (dsp_dev) if (dsp_dev)
lt_info("%s: DSP_DEVICE is set (%s) but cannot be opened," lt_info("%s: DSP_DEVICE is set (%s) but cannot be opened,"
" fall back to /dev/dsp1\n", __func__, dsp_dev); " fall back to /dev/dsp1\n", __func__, dsp_dev);
dsp_dev = "/dev/dsp1"; dsp_dev = "/dev/dsp1";
} }
lt_info("%s: dsp_dev %s mix_dev %s\n", __func__, dsp_dev, mix_dev); /* NULL mix_dev is ok */ lt_info("%s: dsp_dev %s mix_dev %s\n", __func__, dsp_dev, mix_dev); /* NULL mix_dev is ok */

View File

@@ -2,7 +2,7 @@
#ifndef _AUDIO_TD_H_ #ifndef _AUDIO_TD_H_
#define _AUDIO_TD_H_ #define _AUDIO_TD_H_
#include "../common/cs_types.h" #include "cs_types.h"
typedef enum typedef enum
{ {

View File

@@ -1,67 +0,0 @@
/* compatibility header for tripledragon. I'm lazy, so I just left it
as "cs_api.h" so that I don't need too many ifdefs in the code */
#ifndef __CS_API_H_
#define __CS_API_H_
#include "init_lib.h"
typedef void (*cs_messenger) (unsigned int msg, unsigned int data);
#if 0
enum CS_LOG_MODULE {
CS_LOG_CI = 0,
CS_LOG_HDMI_CEC,
CS_LOG_HDMI,
CS_LOG_VIDEO,
CS_LOG_VIDEO_DRM,
CS_LOG_AUDIO,
CS_LOG_DEMUX,
CS_LOG_DENC,
CS_LOG_PVR_RECORD,
CS_LOG_PVR_PLAY,
CS_LOG_POWER_CTRL,
CS_LOG_POWER_CLK,
CS_LOG_MEM,
CS_LOG_API,
};
#endif
inline void cs_api_init()
{
init_td_api();
};
inline void cs_api_exit()
{
shutdown_td_api();
};
#define cs_malloc_uncached malloc
#define cs_free_uncached free
// Callback function helpers
static inline void cs_register_messenger(cs_messenger) { return; };
static inline void cs_deregister_messenger(void) { return; };
//cs_messenger cs_get_messenger(void);
#if 0
// Logging functions
void cs_log_enable(void);
void cs_log_disable(void);
void cs_log_message(const char *prefix, const char *fmt, ...);
void cs_log_module_enable(enum CS_LOG_MODULE module);
void cs_log_module_disable(enum CS_LOG_MODULE module);
void cs_log_module_message(enum CS_LOG_MODULE module, const char *fmt, ...);
// TS Routing
unsigned int cs_get_ts_output(void);
int cs_set_ts_output(unsigned int port);
// Serial nr and revision accessors
unsigned long long cs_get_serial(void);
#endif
/* compat... HD1 seems to be version 6. everything newer ist > 6... */
static inline unsigned int cs_get_revision(void) { return 1; };
static inline unsigned int cs_get_chip_type(void) { return 0; };
extern int cnxt_debug;
#endif //__CS_API_H_

View File

@@ -66,9 +66,10 @@
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <sys/ioctl.h>
#include <OpenThreads/Mutex> #include <OpenThreads/Mutex>
#include <OpenThreads/ScopedLock> #include <OpenThreads/ScopedLock>
#include "dmx_lib.h" #include "dmx_hal.h"
#include "lt_debug.h" #include "lt_debug.h"
#include "video_lib.h" #include "video_lib.h"
@@ -77,17 +78,14 @@ extern cVideo *videoDecoder;
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args)
#define lt_debug_c(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, NULL, args)
#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args) #define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args)
#define lt_info_z(args...) _lt_info(TRIPLE_DEBUG_DEMUX, thiz, args)
#define lt_debug_z(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, thiz, args)
#define dmx_err(_errfmt, _errstr, _revents) do { \ #define dmx_err(_errfmt, _errstr, _revents) do { \
uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\
if (dmx_type == DMX_PSI_CHANNEL) { \
_pid = s_flt.pid; _f = s_flt.filter.filter[0]; \
} else { \
_pid = p_flt.pid; \
}; \
lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \
} while(0); } while(0);
cDemux *videoDemux = NULL; cDemux *videoDemux = NULL;
@@ -137,11 +135,6 @@ cDemux::cDemux(int n)
else else
num = n; num = n;
fd = -1; fd = -1;
measure = false;
last_measure = 0;
last_data = 0;
last_source = -1;
pdata = (void *)calloc(1, sizeof(dmx_pdata)); pdata = (void *)calloc(1, sizeof(dmx_pdata));
P->last_source = -1; P->last_source = -1;
P->mutex = new OpenThreads::Mutex; P->mutex = new OpenThreads::Mutex;
@@ -172,18 +165,18 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe
return true; return true;
} }
bool cDemux::_open(void) static bool _open(cDemux *thiz, int num, int &fd, int &last_source, DMX_CHANNEL_TYPE dmx_type, int buffersize)
{ {
int flags = O_RDWR|O_CLOEXEC; int flags = O_RDWR|O_CLOEXEC;
int devnum = dmx_source[num]; int devnum = dmx_source[num];
if (last_source == devnum) { if (last_source == devnum) {
lt_debug("%s #%d: source (%d) did not change\n", __func__, num, last_source); lt_debug_z("%s #%d: source (%d) did not change\n", __func__, num, last_source);
if (fd > -1) if (fd > -1)
return true; return true;
} }
if (fd > -1) { if (fd > -1) {
/* we changed source -> close and reopen the fd */ /* we changed source -> close and reopen the fd */
lt_debug("%s #%d: FD ALREADY OPENED fd = %d lastsource %d devnum %d\n", lt_debug_z("%s #%d: FD ALREADY OPENED fd = %d lastsource %d devnum %d\n",
__func__, num, fd, last_source, devnum); __func__, num, fd, last_source, devnum);
close(fd); close(fd);
} }
@@ -194,10 +187,10 @@ bool cDemux::_open(void)
fd = open(devname[devnum], flags); fd = open(devname[devnum], flags);
if (fd < 0) if (fd < 0)
{ {
lt_info("%s %s: %m\n", __FUNCTION__, devname[devnum]); lt_info_z("%s %s: %m\n", __FUNCTION__, devname[devnum]);
return false; return false;
} }
lt_debug("%s #%d pes_type: %s(%d), uBufferSize: %d fd: %d\n", __func__, lt_debug_z("%s #%d pes_type: %s(%d), uBufferSize: %d fd: %d\n", __func__,
num, DMX_T[dmx_type], dmx_type, buffersize, fd); num, DMX_T[dmx_type], dmx_type, buffersize, fd);
/* this would actually need locking, but the worst that weill happen is, that /* this would actually need locking, but the worst that weill happen is, that
@@ -206,9 +199,9 @@ bool cDemux::_open(void)
{ {
/* this should not change anything... */ /* this should not change anything... */
int n = DMX_SOURCE_FRONT0 + devnum; int n = DMX_SOURCE_FRONT0 + devnum;
lt_info("%s: setting %s to source %d\n", __func__, devname[devnum], n); lt_info_z("%s: setting %s to source %d\n", __func__, devname[devnum], n);
if (ioctl(fd, DMX_SET_SOURCE, &n) < 0) if (ioctl(fd, DMX_SET_SOURCE, &n) < 0)
lt_info("%s DMX_SET_SOURCE failed!\n", __func__); lt_info_z("%s DMX_SET_SOURCE failed!\n", __func__);
else else
init[devnum] = true; init[devnum] = true;
} }
@@ -218,7 +211,7 @@ bool cDemux::_open(void)
{ {
/* probably uBufferSize == 0 means "use default size". TODO: find a reasonable default */ /* probably uBufferSize == 0 means "use default size". TODO: find a reasonable default */
if (ioctl(fd, DMX_SET_BUFFER_SIZE, buffersize) < 0) if (ioctl(fd, DMX_SET_BUFFER_SIZE, buffersize) < 0)
lt_info("%s DMX_SET_BUFFER_SIZE failed (%m)\n", __func__); lt_info_z("%s DMX_SET_BUFFER_SIZE failed (%m)\n", __func__);
} }
last_source = devnum; last_source = devnum;
@@ -238,8 +231,6 @@ void cDemux::Close(void)
ioctl(fd, DMX_STOP); ioctl(fd, DMX_STOP);
close(fd); close(fd);
fd = -1; fd = -1;
if (measure)
return;
} }
bool cDemux::Start(bool) bool cDemux::Start(bool)
@@ -354,19 +345,22 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
return rc; return rc;
} }
bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter,
const unsigned char * const mask, int len, int timeout, const unsigned char * const mask, int len, int timeout,
const unsigned char * const negmask) const unsigned char * const negmask)
{ {
struct dmx_sct_filter_params s_flt;
memset(&s_flt, 0, sizeof(s_flt)); memset(&s_flt, 0, sizeof(s_flt));
pid = _pid;
_open(); _open(this, num, fd, P->last_source, dmx_type, buffersize);
if (len > DMX_FILTER_SIZE) if (len > DMX_FILTER_SIZE)
{ {
lt_info("%s #%d: len too long: %d, DMX_FILTER_SIZE %d\n", __func__, num, len, DMX_FILTER_SIZE); lt_info("%s #%d: len too long: %d, DMX_FILTER_SIZE %d\n", __func__, num, len, DMX_FILTER_SIZE);
len = DMX_FILTER_SIZE; len = DMX_FILTER_SIZE;
} }
flt = filter[0];
s_flt.pid = pid; s_flt.pid = pid;
s_flt.timeout = timeout; s_flt.timeout = timeout;
memcpy(s_flt.filter.filter, filter, len); memcpy(s_flt.filter.filter, filter, len);
@@ -377,79 +371,80 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
s_flt.flags = DMX_IMMEDIATE_START|DMX_CHECK_CRC; s_flt.flags = DMX_IMMEDIATE_START|DMX_CHECK_CRC;
int to = 0; int to = 0;
switch (filter[0]) { switch (filter[0])
case 0x00: /* program_association_section */ {
to = 2000; case 0x00: /* program_association_section */
break; to = 2000;
case 0x01: /* conditional_access_section */ break;
to = 6000; case 0x01: /* conditional_access_section */
break; to = 6000;
case 0x02: /* program_map_section */ break;
to = 1500; case 0x02: /* program_map_section */
break; to = 1500;
case 0x03: /* transport_stream_description_section */ break;
to = 10000; case 0x03: /* transport_stream_description_section */
break; to = 10000;
/* 0x04 - 0x3F: reserved */ break;
case 0x40: /* network_information_section - actual_network */ /* 0x04 - 0x3F: reserved */
to = 10000; case 0x40: /* network_information_section - actual_network */
break; to = 10000;
case 0x41: /* network_information_section - other_network */ break;
to = 15000; case 0x41: /* network_information_section - other_network */
break; to = 15000;
case 0x42: /* service_description_section - actual_transport_stream */ break;
to = 10000; case 0x42: /* service_description_section - actual_transport_stream */
break; to = 10000;
/* 0x43 - 0x45: reserved for future use */ break;
case 0x46: /* service_description_section - other_transport_stream */ /* 0x43 - 0x45: reserved for future use */
to = 10000; case 0x46: /* service_description_section - other_transport_stream */
break; to = 10000;
/* 0x47 - 0x49: reserved for future use */ break;
case 0x4A: /* bouquet_association_section */ /* 0x47 - 0x49: reserved for future use */
to = 11000; case 0x4A: /* bouquet_association_section */
break; to = 11000;
/* 0x4B - 0x4D: reserved for future use */ break;
case 0x4E: /* event_information_section - actual_transport_stream, present/following */ /* 0x4B - 0x4D: reserved for future use */
to = 2000; case 0x4E: /* event_information_section - actual_transport_stream, present/following */
break; to = 2000;
case 0x4F: /* event_information_section - other_transport_stream, present/following */ break;
to = 10000; case 0x4F: /* event_information_section - other_transport_stream, present/following */
break; to = 10000;
/* 0x50 - 0x5F: event_information_section - actual_transport_stream, schedule */ break;
/* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */ /* 0x50 - 0x5F: event_information_section - actual_transport_stream, schedule */
case 0x70: /* time_date_section */ /* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ case 0x70: /* time_date_section */
s_flt.flags |= DMX_ONESHOT; s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
//s_flt.pid = 0x0014; s_flt.flags |= DMX_ONESHOT;
to = 30000; //s_flt.pid = 0x0014;
break; to = 30000;
case 0x71: /* running_status_section */ break;
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ case 0x71: /* running_status_section */
to = 0; s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
break; to = 0;
case 0x72: /* stuffing_section */ break;
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ case 0x72: /* stuffing_section */
to = 0; s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
break; to = 0;
case 0x73: /* time_offset_section */ break;
s_flt.flags |= DMX_ONESHOT; case 0x73: /* time_offset_section */
//s_flt.pid = 0x0014; s_flt.flags |= DMX_ONESHOT;
to = 30000; //s_flt.pid = 0x0014;
break; to = 30000;
/* 0x74 - 0x7D: reserved for future use */ break;
case 0x7E: /* discontinuity_information_section */ /* 0x74 - 0x7D: reserved for future use */
s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ case 0x7E: /* discontinuity_information_section */
to = 0; s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */
break; to = 0;
case 0x7F: /* selection_information_section */ break;
to = 0; case 0x7F: /* selection_information_section */
break; to = 0;
/* 0x80 - 0x8F: ca_message_section */ break;
/* 0x90 - 0xFE: user defined */ /* 0x80 - 0x8F: ca_message_section */
/* 0xFF: reserved */ /* 0x90 - 0xFE: user defined */
default: /* 0xFF: reserved */
break; default:
// return -1; //return -1;
break;
} }
/* the negmask == NULL is a hack: the users of negmask are PMT-update /* the negmask == NULL is a hack: the users of negmask are PMT-update
* and sectionsd EIT-Version change. And they really want no timeout * and sectionsd EIT-Version change. And they really want no timeout
@@ -471,8 +466,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
return true; return true;
} }
bool cDemux::pesFilter(const unsigned short pid) bool cDemux::pesFilter(const unsigned short _pid)
{ {
struct dmx_pes_filter_params p_flt;
pid = _pid;
flt = 0;
/* allow PID 0 for web streaming e.g. /* allow PID 0 for web streaming e.g.
* this check originally is from tuxbox cvs but I'm not sure * this check originally is from tuxbox cvs but I'm not sure
* what it is good for... * what it is good for...
@@ -484,38 +482,39 @@ bool cDemux::pesFilter(const unsigned short pid)
lt_debug("%s #%d pid: 0x%04hx fd: %d type: %s\n", __FUNCTION__, num, pid, fd, DMX_T[dmx_type]); lt_debug("%s #%d pid: 0x%04hx fd: %d type: %s\n", __FUNCTION__, num, pid, fd, DMX_T[dmx_type]);
_open(); _open(this, num, fd, P->last_source, dmx_type, buffersize);
memset(&p_flt, 0, sizeof(p_flt)); memset(&p_flt, 0, sizeof(p_flt));
p_flt.pid = pid; p_flt.pid = pid;
p_flt.output = DMX_OUT_DECODER; p_flt.output = DMX_OUT_DECODER;
p_flt.input = DMX_IN_FRONTEND; p_flt.input = DMX_IN_FRONTEND;
p_flt.flags = DMX_IMMEDIATE_START; p_flt.flags = DMX_IMMEDIATE_START;
switch (dmx_type) { switch (dmx_type)
case DMX_PCR_ONLY_CHANNEL: {
p_flt.pes_type = DMX_PES_PCR; case DMX_PCR_ONLY_CHANNEL:
break; p_flt.pes_type = DMX_PES_PCR;
case DMX_AUDIO_CHANNEL: break;
p_flt.pes_type = DMX_PES_AUDIO; case DMX_AUDIO_CHANNEL:
break; p_flt.pes_type = DMX_PES_AUDIO;
case DMX_VIDEO_CHANNEL: break;
p_flt.pes_type = DMX_PES_VIDEO; case DMX_VIDEO_CHANNEL:
break; p_flt.pes_type = DMX_PES_VIDEO;
case DMX_PIP_CHANNEL: /* PIP is a special version of DMX_VIDEO_CHANNEL */ break;
p_flt.pes_type = DMX_PES_VIDEO1; case DMX_PIP_CHANNEL: /* PIP is a special version of DMX_VIDEO_CHANNEL */
break; p_flt.pes_type = DMX_PES_VIDEO1;
case DMX_PES_CHANNEL: break;
p_flt.pes_type = DMX_PES_OTHER; case DMX_PES_CHANNEL:
p_flt.output = DMX_OUT_TAP; p_flt.pes_type = DMX_PES_OTHER;
break; p_flt.output = DMX_OUT_TAP;
case DMX_TP_CHANNEL: break;
p_flt.pes_type = DMX_PES_OTHER; case DMX_TP_CHANNEL:
p_flt.output = DMX_OUT_TSDEMUX_TAP; p_flt.pes_type = DMX_PES_OTHER;
break; p_flt.output = DMX_OUT_TSDEMUX_TAP;
default: break;
lt_info("%s #%d invalid dmx_type %d!\n", __func__, num, dmx_type); default:
return false; lt_info("%s #%d invalid dmx_type %d!\n", __func__, num, dmx_type);
return false;
} }
return (ioctl(fd, DMX_SET_PES_FILTER, &p_flt) >= 0); return (ioctl(fd, DMX_SET_PES_FILTER, &p_flt) >= 0);
} }
@@ -547,7 +546,7 @@ bool cDemux::addPid(unsigned short Pid)
lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid); lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid);
return false; return false;
} }
_open(); _open(this, num, fd, P->last_source, dmx_type, buffersize);
if (fd == -1) if (fd == -1)
lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid); lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid);
pfd.fd = fd; /* dummy */ pfd.fd = fd; /* dummy */
@@ -605,7 +604,7 @@ bool cDemux::SetSource(int unit, int source)
lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX); lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX);
return false; return false;
} }
lt_info_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source); lt_debug_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source);
if (source < 0 || source >= NUM_DEMUXDEV) if (source < 0 || source >= NUM_DEMUXDEV)
lt_info_c("%s(%d, %d) ERROR: source %d out of range!\n", __func__, unit, source, source); lt_info_c("%s(%d, %d) ERROR: source %d out of range!\n", __func__, unit, source, source);
else else
@@ -619,6 +618,6 @@ int cDemux::GetSource(int unit)
lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX); lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX);
return -1; return -1;
} }
lt_info_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]); lt_debug_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]);
return dmx_source[unit]; return dmx_source[unit];
} }

View File

@@ -1 +0,0 @@
#include "dmx_lib.h"

View File

@@ -1,73 +0,0 @@
#ifndef __DEMUX_TD_H
#define __DEMUX_TD_H
#include <cstdlib>
#include <vector>
#include <inttypes.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include "../common/cs_types.h"
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,
DMX_VIDEO_CHANNEL = 1,
DMX_AUDIO_CHANNEL,
DMX_PES_CHANNEL,
DMX_PSI_CHANNEL,
DMX_PIP_CHANNEL,
DMX_TP_CHANNEL,
DMX_PCR_ONLY_CHANNEL
} DMX_CHANNEL_TYPE;
typedef struct
{
int fd;
unsigned short pid;
} pes_pids;
class cDemux
{
private:
int num;
int fd;
int buffersize;
bool measure;
uint64_t last_measure, last_data;
DMX_CHANNEL_TYPE dmx_type;
std::vector<pes_pids> pesfds;
struct dmx_sct_filter_params s_flt;
struct dmx_pes_filter_params p_flt;
int last_source;
bool _open(void);
void *pdata;
public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * unused = NULL, int bufsize = 0);
void Close(void);
bool Start(bool record = false);
bool Stop(void);
int Read(unsigned char *buff, int len, int Timeout = 0);
bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL);
bool pesFilter(const unsigned short pid);
void SetSyncMode(AVSYNC_TYPE mode);
void * getBuffer();
void * getChannel();
DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; };
bool addPid(unsigned short pid);
void getSTC(int64_t * STC);
int getUnit(void);
static bool SetSource(int unit, int source);
static int GetSource(int unit);
// TD only functions
int getFD(void) { return fd; }; /* needed by cPlayback class */
void removePid(unsigned short Pid); /* needed by cRecord class */
std::vector<pes_pids> getPesPids(void) { return pesfds; };
//
cDemux(int num = 0);
~cDemux();
};
#endif //__DEMUX_H

View File

@@ -3,7 +3,6 @@
#include <stdio.h> #include <stdio.h>
#include "init_lib.h"
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/types.h> #include <sys/types.h>
@@ -14,6 +13,7 @@
#include <linux/dvb/dmx.h> #include <linux/dvb/dmx.h>
#include "init_td.h"
#include "pwrmngr.h" #include "pwrmngr.h"
#include "lt_debug.h" #include "lt_debug.h"

View File

@@ -1,2 +0,0 @@
#warning using init_cs.h from libspark
#include "init_lib.h"

View File

@@ -1,5 +0,0 @@
#ifndef __INIT_TD_H
#define __INIT_TD_H
void init_td_api();
void shutdown_td_api();
#endif

View File

@@ -8,6 +8,7 @@
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
#include <pthread.h>
#include <aio.h> #include <aio.h>
#include "record_lib.h" #include "record_lib.h"
@@ -15,7 +16,7 @@
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_RECORD, this, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_RECORD, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_RECORD, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_RECORD, this, args)
/* helper functions to call the cpp thread loops */ /* helper function to call the cpp thread loop */
void *execute_record_thread(void *c) void *execute_record_thread(void *c)
{ {
cRecord *obj = (cRecord *)c; cRecord *obj = (cRecord *)c;
@@ -137,7 +138,7 @@ bool cRecord::ChangePids(unsigned short /*vpid*/, unsigned short *apids, int num
lt_info("%s: DMX = NULL\n", __func__); lt_info("%s: DMX = NULL\n", __func__);
return false; return false;
} }
pids = dmx->getPesPids(); pids = dmx->pesfds;
/* the first PID is the video pid, so start with the second PID... */ /* the first PID is the video pid, so start with the second PID... */
for (std::vector<pes_pids>::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) { for (std::vector<pes_pids>::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) {
found = false; found = false;
@@ -173,7 +174,7 @@ bool cRecord::AddPid(unsigned short pid)
lt_info("%s: DMX = NULL\n", __func__); lt_info("%s: DMX = NULL\n", __func__);
return false; return false;
} }
pids = dmx->getPesPids(); pids = dmx->pesfds;
for (std::vector<pes_pids>::const_iterator i = pids.begin(); i != pids.end(); ++i) { for (std::vector<pes_pids>::const_iterator i = pids.begin(); i != pids.end(); ++i) {
if ((*i).pid == pid) if ((*i).pid == pid)
return true; /* or is it an error to try to add the same PID twice? */ return true; /* or is it an error to try to add the same PID twice? */
@@ -214,7 +215,7 @@ void cRecord::RecordThread()
strncpy(threadname, "RecordThread", sizeof(threadname)); strncpy(threadname, "RecordThread", sizeof(threadname));
threadname[16] = 0; threadname[16] = 0;
prctl (PR_SET_NAME, (unsigned long)&threadname); prctl (PR_SET_NAME, (unsigned long)&threadname);
int readsize = bufsize/16; int readsize = bufsize / 16;
int buf_pos = 0; int buf_pos = 0;
int count = 0; int count = 0;
int queued = 0; int queued = 0;
@@ -257,13 +258,15 @@ void cRecord::RecordThread()
if (toread > readsize) if (toread > readsize)
toread = readsize; toread = readsize;
ssize_t s = dmx->Read(buf + buf_pos, toread, 50); ssize_t s = dmx->Read(buf + buf_pos, toread, 50);
lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__, buf_pos, (int)s, bufsize - buf_pos); lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__,
buf_pos, (int)s, bufsize - buf_pos);
if (s < 0) if (s < 0)
{ {
if (errno != EAGAIN && (errno != EOVERFLOW || !overflow)) if (errno != EAGAIN && (errno != EOVERFLOW || !overflow))
{ {
lt_info("%s: read failed: %m\n", __func__); lt_info("%s: read failed: %m\n", __func__);
exit_flag = RECORD_FAILED_READ; exit_flag = RECORD_FAILED_READ;
state = REC_STATUS_OVERFLOW;
break; break;
} }
} }
@@ -289,6 +292,7 @@ void cRecord::RecordThread()
overflow = true; overflow = true;
if (!(overflow_count % 10)) if (!(overflow_count % 10))
lt_info("%s: buffer full! Overflow? (%d)\n", __func__, ++overflow_count); lt_info("%s: buffer full! Overflow? (%d)\n", __func__, ++overflow_count);
state = REC_STATUS_SLOW;
} }
r = aio_error(&a); r = aio_error(&a);
if (r == EINPROGRESS) if (r == EINPROGRESS)

View File

@@ -1,9 +1,8 @@
#ifndef __RECORD_TD_H #ifndef __record_hal__
#define __RECORD_TD_H #define __record_hal__
#include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#include "dmx_lib.h" #include "dmx_hal.h"
#define REC_STATUS_OK 0 #define REC_STATUS_OK 0
#define REC_STATUS_SLOW 1 #define REC_STATUS_SLOW 1

View File

@@ -1,9 +1,9 @@
#ifndef _VIDEO_TD_H #ifndef _VIDEO_LIB_H
#define _VIDEO_TD_H #define _VIDEO_LIB_H
#include <linux/dvb/video.h> #include <linux/dvb/video.h>
#include "../common/cs_types.h" #include "cs_types.h"
#include "dmx_lib.h" #include "dmx_hal.h"
typedef struct cs_vs_format_t typedef struct cs_vs_format_t
{ {

View File

@@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libtriple.la
AM_CPPFLAGS = \ AM_CPPFLAGS = \
-I$(top_srcdir)/common \ -I$(top_srcdir)/common \
-I$(top_srcdir)/include \
@DIRECTFB_CFLAGS@ @DIRECTFB_CFLAGS@
AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing

View File

@@ -4,7 +4,7 @@
#define _AUDIO_TD_H_ #define _AUDIO_TD_H_
#include <hardware/aud/aud_inf.h> #include <hardware/aud/aud_inf.h>
#include "../common/cs_types.h" #include "cs_types.h"
typedef enum typedef enum
{ {

View File

@@ -1,67 +0,0 @@
/* compatibility header for tripledragon. I'm lazy, so I just left it
as "cs_api.h" so that I don't need too many ifdefs in the code */
#ifndef __CS_API_H_
#define __CS_API_H_
#include "init_td.h"
typedef void (*cs_messenger) (unsigned int msg, unsigned int data);
#if 0
enum CS_LOG_MODULE {
CS_LOG_CI = 0,
CS_LOG_HDMI_CEC,
CS_LOG_HDMI,
CS_LOG_VIDEO,
CS_LOG_VIDEO_DRM,
CS_LOG_AUDIO,
CS_LOG_DEMUX,
CS_LOG_DENC,
CS_LOG_PVR_RECORD,
CS_LOG_PVR_PLAY,
CS_LOG_POWER_CTRL,
CS_LOG_POWER_CLK,
CS_LOG_MEM,
CS_LOG_API,
};
#endif
inline void cs_api_init()
{
init_td_api();
};
inline void cs_api_exit()
{
shutdown_td_api();
};
#define cs_malloc_uncached malloc
#define cs_free_uncached free
// Callback function helpers
static inline void cs_register_messenger(cs_messenger) { return; };
static inline void cs_deregister_messenger(void) { return; };
//cs_messenger cs_get_messenger(void);
#if 0
// Logging functions
void cs_log_enable(void);
void cs_log_disable(void);
void cs_log_message(const char *prefix, const char *fmt, ...);
void cs_log_module_enable(enum CS_LOG_MODULE module);
void cs_log_module_disable(enum CS_LOG_MODULE module);
void cs_log_module_message(enum CS_LOG_MODULE module, const char *fmt, ...);
// TS Routing
unsigned int cs_get_ts_output(void);
int cs_set_ts_output(unsigned int port);
// Serial nr and revision accessors
unsigned long long cs_get_serial(void);
#endif
/* compat... HD1 seems to be version 6. everything newer ist > 6... */
static inline unsigned int cs_get_revision(void) { return 1; };
static inline unsigned int cs_get_chip_type(void) { return 0; };
extern int cnxt_debug;
#endif //__CS_API_H_

View File

@@ -1 +0,0 @@
#include "dmx_td.h"

View File

@@ -17,18 +17,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <config.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <poll.h> #include <poll.h>
#include <sys/ioctl.h>
#include <errno.h> #include <errno.h>
#include <inttypes.h> #include <inttypes.h>
#include <unistd.h>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <hardware/tddevices.h> #include <hardware/tddevices.h>
#include "dmx_td.h" #include "dmx_hal.h"
#include "lt_debug.h" #include "lt_debug.h"
/* Ugh... see comment in destructor for details... */ /* Ugh... see comment in destructor for details... */
@@ -39,14 +42,8 @@ extern cVideo *videoDecoder;
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args)
#define dmx_err(_errfmt, _errstr, _revents) do { \ #define dmx_err(_errfmt, _errstr, _revents) do { \
uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\
if (dmx_type == DMX_PSI_CHANNEL) { \
_pid = s_flt.pid; _f = s_flt.filter[0]; \
} else { \
_pid = p_flt.pid; \
}; \
lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \
} while(0); } while(0);
cDemux *videoDemux = NULL; cDemux *videoDemux = NULL;
@@ -75,6 +72,15 @@ static const char *devname[] = {
static int dmx_tp_count = 0; static int dmx_tp_count = 0;
#define MAX_TS_COUNT 1 #define MAX_TS_COUNT 1
typedef struct dmx_pdata {
bool measure;
int last_measure;
int last_data;
int devnum;
bool running;
} dmx_pdata;
#define P ((dmx_pdata *)pdata)
cDemux::cDemux(int n) cDemux::cDemux(int n)
{ {
if (n < 0 || n > 2) if (n < 0 || n > 2)
@@ -85,32 +91,24 @@ cDemux::cDemux(int n)
else else
num = n; num = n;
fd = -1; fd = -1;
measure = false; pdata = calloc(1, sizeof(dmx_pdata));
last_measure = 0; P->measure = false;
last_data = 0; P->last_measure = 0;
P->last_data = 0;
P->running = false;
} }
cDemux::~cDemux() cDemux::~cDemux()
{ {
lt_debug("%s #%d fd: %d\n", __FUNCTION__, num, fd); lt_debug("%s #%d fd: %d\n", __FUNCTION__, num, fd);
Close(); Close();
/* in zapit.cpp, videoDemux is deleted after videoDecoder free(pdata);
* in the video watchdog, we access videoDecoder pdata = NULL;
* the thread still runs after videoDecoder has been deleted
* => set videoDecoder to NULL here to make the check in the
* watchdog thread pick this up.
* This is ugly, but it saves me from changing neutrino
*
* if the delete order in neutrino will ever be changed, this
* will blow up badly :-(
*/
if (dmx_type == DMX_VIDEO_CHANNEL)
videoDecoder = NULL;
} }
bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBufferSize) bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBufferSize)
{ {
devnum = num; P->devnum = num;
int flags = O_RDWR; int flags = O_RDWR;
if (fd > -1) if (fd > -1)
lt_info("%s FD ALREADY OPENED? fd = %d\n", __FUNCTION__, fd); lt_info("%s FD ALREADY OPENED? fd = %d\n", __FUNCTION__, fd);
@@ -120,10 +118,10 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe
if (num == 0 && uBufferSize == 3 * 3008 * 62) /* streaminfo measurement, let's cheat... */ if (num == 0 && uBufferSize == 3 * 3008 * 62) /* streaminfo measurement, let's cheat... */
{ {
lt_info("%s num=0 and DMX_TP_CHANNEL => measurement demux\n", __func__); lt_info("%s num=0 and DMX_TP_CHANNEL => measurement demux\n", __func__);
devnum = 2; /* demux 0 is used for live, demux 1 for recording */ P->devnum = 2; /* demux 0 is used for live, demux 1 for recording */
measure = true; P->measure = true;
last_measure = 0; P->last_measure = 0;
last_data = 0; P->last_data = 0;
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
} }
else else
@@ -137,18 +135,18 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe
return false; return false;
} }
dmx_tp_count++; dmx_tp_count++;
devnum = dmx_tp_count; P->devnum = dmx_tp_count;
} }
} }
fd = open(devname[devnum], flags); fd = open(devname[P->devnum], flags);
if (fd < 0) if (fd < 0)
{ {
lt_info("%s %s: %m\n", __FUNCTION__, devname[devnum]); lt_info("%s %s: %m\n", __FUNCTION__, devname[P->devnum]);
return false; return false;
} }
fcntl(fd, F_SETFD, FD_CLOEXEC); fcntl(fd, F_SETFD, FD_CLOEXEC);
lt_debug("%s #%d pes_type: %s(%d), uBufferSize: %d dev:%s fd: %d\n", __func__, lt_debug("%s #%d pes_type: %s(%d), uBufferSize: %d dev:%s fd: %d\n", __func__,
num, DMX_T[pes_type], pes_type, uBufferSize, devname[devnum] + strlen("/dev/stb/"), fd); num, DMX_T[pes_type], pes_type, uBufferSize, devname[P->devnum] + strlen("/dev/stb/"), fd);
dmx_type = pes_type; dmx_type = pes_type;
@@ -159,7 +157,7 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe
} }
if (pes_type == DMX_TP_CHANNEL) if (pes_type == DMX_TP_CHANNEL)
{ {
if (measure) if (P->measure)
return true; return true;
struct demux_bucket_para bp; struct demux_bucket_para bp;
bp.unloader.unloader_type = UNLOADER_TYPE_TRANSPORT; bp.unloader.unloader_type = UNLOADER_TYPE_TRANSPORT;
@@ -201,7 +199,7 @@ void cDemux::Close(void)
ioctl(fd, DEMUX_STOP); ioctl(fd, DEMUX_STOP);
close(fd); close(fd);
fd = -1; fd = -1;
if (measure) if (P->measure)
return; return;
if (dmx_type == DMX_TP_CHANNEL) if (dmx_type == DMX_TP_CHANNEL)
{ {
@@ -229,6 +227,7 @@ bool cDemux::Start(bool)
perror("DEMUX_START"); perror("DEMUX_START");
} }
ioctl(fd, DEMUX_START); ioctl(fd, DEMUX_START);
P->running = true;
return true; return true;
} }
@@ -246,6 +245,7 @@ bool cDemux::Stop(void)
perror("DEMUX_STOP"); perror("DEMUX_STOP");
} }
ioctl(fd, DEMUX_STOP); ioctl(fd, DEMUX_STOP);
P->running = false;
return true; return true;
} }
@@ -262,7 +262,15 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
ufds.events = POLLIN; ufds.events = POLLIN;
ufds.revents = 0; ufds.revents = 0;
if (measure) if (dmx_type == DMX_INVALID) /* happens, if too many DMX_TP are requested, because */
{ /* nobody checks the return value of Open or Start... */
lt_debug("%s #%d: DMX_INVALID\n", __func__, num);
usleep(timeout * 1000); /* rate-limit the debug message */
errno = EINVAL;
return -1;
}
if (P->measure)
{ {
if (timeout) if (timeout)
usleep(timeout * 1000); usleep(timeout * 1000);
@@ -271,7 +279,7 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
clock_gettime(CLOCK_MONOTONIC, &t); clock_gettime(CLOCK_MONOTONIC, &t);
now = t.tv_sec * 1000; now = t.tv_sec * 1000;
now += t.tv_nsec / 1000000; now += t.tv_nsec / 1000000;
if (now - last_measure < 333) if (now - P->last_measure < 333)
return 0; return 0;
unsigned char dummy[12]; unsigned char dummy[12];
unsigned long long bit_s = 0; unsigned long long bit_s = 0;
@@ -295,17 +303,17 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
bit_s = (m.rx_bytes * 7816793ULL + (m.rx_time_us / 2ULL)) / m.rx_time_us; bit_s = (m.rx_bytes * 7816793ULL + (m.rx_time_us / 2ULL)) / m.rx_time_us;
*/ */
bit_s = (m.rx_bytes * 8000ULL + (m.rx_time_us / 2ULL)) / m.rx_time_us; bit_s = (m.rx_bytes * 8000ULL + (m.rx_time_us / 2ULL)) / m.rx_time_us;
if (now - last_data < 5000) if (now - P->last_data < 5000)
rc = bit_s * (now - last_data) / 8ULL; rc = bit_s * (now - P->last_data) / 8ULL;
else else
rc = 0; rc = 0;
lt_debug("%s measure bit_s: %llu rc: %d timediff: %lld\n", lt_debug("%s measure bit_s: %llu rc: %d timediff: %lld\n",
__func__, bit_s, rc, (now - last_data)); __func__, bit_s, rc, (now - P->last_data));
last_data = now; P->last_data = now;
} else } else
rc = 0; rc = 0;
} }
last_measure = now; P->last_measure = now;
ioctl(fd, DEMUX_START); ioctl(fd, DEMUX_START);
return rc; return rc;
} }
@@ -350,13 +358,14 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
return rc; return rc;
} }
bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter,
const unsigned char * const mask, int len, int timeout, const unsigned char * const mask, int len, int timeout,
const unsigned char * const negmask) const unsigned char * const negmask)
{ {
int length; int length;
struct demux_filter_para s_flt;
memset(&s_flt, 0, sizeof(s_flt)); memset(&s_flt, 0, sizeof(s_flt));
pid = _pid;
if (len > FILTER_LENGTH - 2) if (len > FILTER_LENGTH - 2)
lt_info("%s #%d: len too long: %d, FILTER_LENGTH: %d\n", __func__, num, len, FILTER_LENGTH); lt_info("%s #%d: len too long: %d, FILTER_LENGTH: %d\n", __func__, num, len, FILTER_LENGTH);
if (len < 1) /* memcpy below will be unhappy */ if (len < 1) /* memcpy below will be unhappy */
@@ -365,6 +374,7 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
length = (len + 2 + 1) & 0xfe; /* reportedly, the TD drivers don't handle odd filter */ length = (len + 2 + 1) & 0xfe; /* reportedly, the TD drivers don't handle odd filter */
if (length > FILTER_LENGTH) /* lengths well. So make sure the length is a multiple */ if (length > FILTER_LENGTH) /* lengths well. So make sure the length is a multiple */
length = FILTER_LENGTH; /* of 2. The unused mask is zeroed anyway. */ length = FILTER_LENGTH; /* of 2. The unused mask is zeroed anyway. */
flt = filter[0];
s_flt.pid = pid; s_flt.pid = pid;
s_flt.filter_length = length; s_flt.filter_length = length;
s_flt.filter[0] = filter[0]; s_flt.filter[0] = filter[0];
@@ -467,11 +477,15 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
if (ioctl(fd, DEMUX_FILTER_SET, &s_flt) < 0) if (ioctl(fd, DEMUX_FILTER_SET, &s_flt) < 0)
return false; return false;
P->running = true;
return true; return true;
} }
bool cDemux::pesFilter(const unsigned short pid) bool cDemux::pesFilter(const unsigned short _pid)
{ {
demux_pes_para p_flt;
pid = _pid;
flt = 0;
/* allow PID 0 for web streaming e.g. /* allow PID 0 for web streaming e.g.
* this check originally is from tuxbox cvs but I'm not sure * this check originally is from tuxbox cvs but I'm not sure
* what it is good for... * what it is good for...
@@ -483,7 +497,7 @@ bool cDemux::pesFilter(const unsigned short pid)
lt_debug("%s #%d pid: 0x%04hx fd: %d type: %s\n", __FUNCTION__, num, pid, fd, DMX_T[dmx_type]); lt_debug("%s #%d pid: 0x%04hx fd: %d type: %s\n", __FUNCTION__, num, pid, fd, DMX_T[dmx_type]);
if (dmx_type == DMX_TP_CHANNEL && !measure) if (dmx_type == DMX_TP_CHANNEL && !P->measure)
{ {
unsigned int n = pesfds.size(); unsigned int n = pesfds.size();
addPid(pid); addPid(pid);
@@ -533,6 +547,8 @@ void cDemux::SetSyncMode(AVSYNC_TYPE /*mode*/)
void *cDemux::getBuffer() void *cDemux::getBuffer()
{ {
lt_debug("%s #%d\n", __FUNCTION__, num); lt_debug("%s #%d\n", __FUNCTION__, num);
if (P->running)
return (void *)1;
return NULL; return NULL;
} }
@@ -552,14 +568,14 @@ bool cDemux::addPid(unsigned short Pid)
lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid); lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid);
return false; return false;
} }
if (measure) if (P->measure)
{ {
lt_info("%s measurement demux -> skipping\n", __func__); lt_info("%s measurement demux -> skipping\n", __func__);
return true; return true;
} }
if (fd == -1) if (fd == -1)
lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid); lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid);
pfd.fd = open(devname[devnum], O_RDWR); pfd.fd = open(devname[P->devnum], O_RDWR);
if (pfd.fd < 0) if (pfd.fd < 0)
{ {
lt_info("%s #%d Pid = %hx open failed (%m)\n", __FUNCTION__, num, Pid); lt_info("%s #%d Pid = %hx open failed (%m)\n", __FUNCTION__, num, Pid);

View File

@@ -1,78 +0,0 @@
#ifndef __DEMUX_TD_H
#define __DEMUX_TD_H
#include <cstdlib>
#include <vector>
extern "C" {
#include <inttypes.h>
#include <sys/ioctl.h>
#include <hardware/xp/xp_osd_user.h>
}
#include "../common/cs_types.h"
#if defined DMX_FILTER_SIZE
#undef DMX_FILTER_SIZE
#endif
#define DMX_FILTER_SIZE FILTER_LENGTH
#define MAX_DMX_UNITS 4
typedef enum
{
DMX_INVALID = 0,
DMX_VIDEO_CHANNEL = 1,
DMX_AUDIO_CHANNEL,
DMX_PES_CHANNEL,
DMX_PSI_CHANNEL,
DMX_PIP_CHANNEL,
DMX_TP_CHANNEL,
DMX_PCR_ONLY_CHANNEL
} DMX_CHANNEL_TYPE;
typedef struct
{
int fd;
unsigned short pid;
} pes_pids;
class cDemux
{
private:
int num;
int devnum;
int fd;
int buffersize;
bool measure;
uint64_t last_measure, last_data;
DMX_CHANNEL_TYPE dmx_type;
std::vector<pes_pids> pesfds;
struct demux_filter_para s_flt;
demux_pes_para p_flt;
public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0);
void Close(void);
bool Start(bool record = false);
bool Stop(void);
int Read(unsigned char *buff, int len, int Timeout = 0);
bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL);
bool pesFilter(const unsigned short pid);
void SetSyncMode(AVSYNC_TYPE mode);
void * getBuffer();
void * getChannel();
DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; };
bool addPid(unsigned short pid);
void getSTC(int64_t * STC);
int getUnit(void);
/* tripledragon is unlikely to get a second tuner, so stub it out right here */
static bool SetSource(int /*unit*/, int /*source*/) { return true; };
static int GetSource(int /*unit*/) { return 0; };
// TD only functions
int getFD(void) { return fd; }; /* needed by cPlayback class */
void removePid(unsigned short Pid); /* needed by cRecord class */
std::vector<pes_pids> getPesPids(void) { return pesfds; };
//
cDemux(int num = 0);
~cDemux();
};
#endif //__DEMUX_H

View File

@@ -1,2 +0,0 @@
#warning using init_cs.h from libtriple
#include "init_td.h"

View File

@@ -36,7 +36,7 @@ int gfxfd = -1;
#define DFBCHECK(x...) \ #define DFBCHECK(x...) \
err = x; \ err = x; \
if (err != DFB_OK) { \ if (err != DFB_OK) { \
fprintf(stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ fprintf(stderr, "init_td.cpp:%d:\n\t", __LINE__); \
DirectFBErrorFatal(#x, err ); \ DirectFBErrorFatal(#x, err ); \
} }

View File

@@ -1,5 +0,0 @@
#ifndef __INIT_TD_H
#define __INIT_TD_H
void init_td_api();
void shutdown_td_api();
#endif

View File

@@ -58,7 +58,7 @@ extern cVideo *videoDecoder;
#define DFBCHECK(x...) \ #define DFBCHECK(x...) \
err = x; \ err = x; \
if (err != DFB_OK) { \ if (err != DFB_OK) { \
fprintf(stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ fprintf(stderr, "lt_dfbinput.cpp:%d:\n\t", __LINE__); \
DirectFBErrorFatal(#x, err ); \ DirectFBErrorFatal(#x, err ); \
} }

View File

@@ -1,13 +1,18 @@
#include <config.h>
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include <cstring> #include <cstring>
#include <map>
#include "playback_td.h" #include "playback_td.h"
#include "dmx_td.h" #include "dmx_hal.h"
#include "audio_td.h" #include "audio_td.h"
#include "video_td.h" #include "video_td.h"
#include "lt_debug.h" #include "lt_debug.h"

View File

@@ -6,7 +6,11 @@
#include <inttypes.h> #include <inttypes.h>
#include <cstdio> #include <cstdio>
#include <cstring> #include <cstring>
#include <pthread.h>
#include "record_td.h" #include "record_td.h"
#include "dmx_hal.h"
#include "lt_debug.h" #include "lt_debug.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_RECORD, this, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_RECORD, this, args)
#define lt_info(args...) _lt_info(TRIPLE_DEBUG_RECORD, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_RECORD, this, args)
@@ -121,7 +125,7 @@ bool cRecord::ChangePids(unsigned short /*vpid*/, unsigned short *apids, int num
lt_info("%s: DMX = NULL\n", __func__); lt_info("%s: DMX = NULL\n", __func__);
return false; return false;
} }
pids = dmx->getPesPids(); pids = dmx->pesfds;
/* the first PID is the video pid, so start with the second PID... */ /* the first PID is the video pid, so start with the second PID... */
for (std::vector<pes_pids>::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) { for (std::vector<pes_pids>::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) {
found = false; found = false;
@@ -157,7 +161,7 @@ bool cRecord::AddPid(unsigned short pid)
lt_info("%s: DMX = NULL\n", __func__); lt_info("%s: DMX = NULL\n", __func__);
return false; return false;
} }
pids = dmx->getPesPids(); pids = dmx->pesfds;
for (std::vector<pes_pids>::const_iterator i = pids.begin(); i != pids.end(); ++i) { for (std::vector<pes_pids>::const_iterator i = pids.begin(); i != pids.end(); ++i) {
if ((*i).pid == pid) if ((*i).pid == pid)
return true; /* or is it an error to try to add the same PID twice? */ return true; /* or is it an error to try to add the same PID twice? */

View File

@@ -2,7 +2,7 @@
#define __RECORD_TD_H #define __RECORD_TD_H
#include <pthread.h> #include <pthread.h>
#include "dmx_td.h" #include "dmx_hal.h"
#define REC_STATUS_OK 0 #define REC_STATUS_OK 0
#define REC_STATUS_SLOW 1 #define REC_STATUS_SLOW 1

View File

@@ -4,7 +4,7 @@
#include <hardware/vid/vid_inf.h> #include <hardware/vid/vid_inf.h>
#define video_format_t vidDispSize_t #define video_format_t vidDispSize_t
//#define video_displayformat_t vidDispMode_t //#define video_displayformat_t vidDispMode_t
#include "../common/cs_types.h" #include "cs_types.h"
#include "dmx_td.h" #include "dmx_td.h"
#define STB_HAL_VIDEO_HAS_GETSCREENIMAGE 1 #define STB_HAL_VIDEO_HAS_GETSCREENIMAGE 1

View File

@@ -21,7 +21,7 @@
#include <cstdlib> #include <cstdlib>
#include "audio_lib.h" #include "audio_lib.h"
#include "dmx_lib.h" #include "dmx_hal.h"
#include "lt_debug.h" #include "lt_debug.h"
#define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args) #define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args)
@@ -151,4 +151,3 @@ void cAudio::setBypassMode(bool disable)
{ {
lt_debug("%s %d\n", __func__, disable); lt_debug("%s %d\n", __func__, disable);
} }

View File

@@ -4,13 +4,13 @@
#define _AUDIO_LIB_H_ #define _AUDIO_LIB_H_
#include <stdint.h> #include <stdint.h>
#include "../common/cs_types.h" #include "cs_types.h"
typedef enum typedef enum
{ {
AUDIO_SYNC_WITH_PTS, AUDIO_SYNC_WITH_PTS,
AUDIO_NO_SYNC, AUDIO_NO_SYNC,
AUDIO_SYNC_AUDIO_MASTER AUDIO_SYNC_AUDIO_MASTER
} AUDIO_SYNC_MODE; } AUDIO_SYNC_MODE;
typedef enum { typedef enum {
@@ -21,20 +21,20 @@ typedef enum {
typedef enum typedef enum
{ {
AUDIO_FMT_AUTO = 0, AUDIO_FMT_AUTO = 0,
AUDIO_FMT_MPEG, AUDIO_FMT_MPEG,
AUDIO_FMT_MP3, AUDIO_FMT_MP3,
AUDIO_FMT_DOLBY_DIGITAL, AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL, AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL,
AUDIO_FMT_AAC, AUDIO_FMT_AAC,
AUDIO_FMT_AAC_PLUS, AUDIO_FMT_AAC_PLUS,
AUDIO_FMT_DD_PLUS, AUDIO_FMT_DD_PLUS,
AUDIO_FMT_DTS, AUDIO_FMT_DTS,
AUDIO_FMT_AVS, AUDIO_FMT_AVS,
AUDIO_FMT_MLP, AUDIO_FMT_MLP,
AUDIO_FMT_WMA, AUDIO_FMT_WMA,
AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback
AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP
} AUDIO_FORMAT; } AUDIO_FORMAT;
class cAudio class cAudio
@@ -61,6 +61,7 @@ class cAudio
int do_mute(bool enable, bool remember); int do_mute(bool enable, bool remember);
void setBypassMode(bool disable); void setBypassMode(bool disable);
public: public:
/* construct & destruct */ /* construct & destruct */
cAudio(void *, void *, void *); cAudio(void *, void *, void *);

View File

@@ -1 +0,0 @@
../libspark/cs_api.h

View File

@@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "config.h" #include "config.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -27,16 +26,17 @@
#include <poll.h> #include <poll.h>
#include <errno.h> #include <errno.h>
#include <inttypes.h> #include <inttypes.h>
#include <unistd.h>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <unistd.h> #include <sys/ioctl.h>
#include "dmx_lib.h" #include "dmx_hal.h"
#include "lt_debug.h" #include "lt_debug.h"
/* needed for getSTC :-( */
#include "video_lib.h" #include "video_lib.h"
/* needed for getSTC... */
extern cVideo *videoDecoder; extern cVideo *videoDecoder;
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args)
@@ -44,14 +44,8 @@ extern cVideo *videoDecoder;
#define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args) #define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args)
#define dmx_err(_errfmt, _errstr, _revents) do { \ #define dmx_err(_errfmt, _errstr, _revents) do { \
uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\
if (dmx_type == DMX_PSI_CHANNEL) { \
_pid = s_flt.pid; _f = s_flt.filter.filter[0]; \
} else { \
_pid = p_flt.pid; \
}; \
lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \
__func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \
} while(0); } while(0);
cDemux *videoDemux = NULL; cDemux *videoDemux = NULL;
@@ -90,9 +84,6 @@ cDemux::cDemux(int n)
else else
num = n; num = n;
fd = -1; fd = -1;
measure = false;
last_measure = 0;
last_data = 0;
} }
cDemux::~cDemux() cDemux::~cDemux()
@@ -154,12 +145,11 @@ void cDemux::Close(void)
lt_info("%s #%d: not open!\n", __FUNCTION__, num); lt_info("%s #%d: not open!\n", __FUNCTION__, num);
return; return;
} }
pesfds.clear(); pesfds.clear();
ioctl(fd, DMX_STOP); ioctl(fd, DMX_STOP);
close(fd); close(fd);
fd = -1; fd = -1;
if (measure)
return;
if (dmx_type == DMX_TP_CHANNEL) if (dmx_type == DMX_TP_CHANNEL)
{ {
dmx_tp_count--; dmx_tp_count--;
@@ -251,17 +241,20 @@ int cDemux::Read(unsigned char *buff, int len, int timeout)
return rc; return rc;
} }
bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter,
const unsigned char * const mask, int len, int timeout, const unsigned char * const mask, int len, int timeout,
const unsigned char * const negmask) const unsigned char * const negmask)
{ {
struct dmx_sct_filter_params s_flt;
memset(&s_flt, 0, sizeof(s_flt)); memset(&s_flt, 0, sizeof(s_flt));
pid = _pid;
if (len > DMX_FILTER_SIZE) if (len > DMX_FILTER_SIZE)
{ {
lt_info("%s #%d: len too long: %d, DMX_FILTER_SIZE %d\n", __func__, num, len, DMX_FILTER_SIZE); lt_info("%s #%d: len too long: %d, DMX_FILTER_SIZE %d\n", __func__, num, len, DMX_FILTER_SIZE);
len = DMX_FILTER_SIZE; len = DMX_FILTER_SIZE;
} }
flt = filter[0];
s_flt.pid = pid; s_flt.pid = pid;
s_flt.timeout = timeout; s_flt.timeout = timeout;
memcpy(s_flt.filter.filter, filter, len); memcpy(s_flt.filter.filter, filter, len);
@@ -364,8 +357,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte
return true; return true;
} }
bool cDemux::pesFilter(const unsigned short pid) bool cDemux::pesFilter(const unsigned short _pid)
{ {
struct dmx_pes_filter_params p_flt;
pid = _pid;
flt = 0;
/* allow PID 0 for web streaming e.g. /* allow PID 0 for web streaming e.g.
* this check originally is from tuxbox cvs but I'm not sure * this check originally is from tuxbox cvs but I'm not sure
* what it is good for... * what it is good for...
@@ -382,20 +378,19 @@ bool cDemux::pesFilter(const unsigned short pid)
p_flt.output = DMX_OUT_DECODER; p_flt.output = DMX_OUT_DECODER;
p_flt.input = DMX_IN_FRONTEND; p_flt.input = DMX_IN_FRONTEND;
/* for now, output to TS_TAP for live mode,
* test playback with "omxplayer /dev/dvb/adapter0/dvr0" */
switch (dmx_type) { switch (dmx_type) {
case DMX_PCR_ONLY_CHANNEL: case DMX_PCR_ONLY_CHANNEL:
p_flt.pes_type = DMX_PES_OTHER; p_flt.pes_type = DMX_PES_OTHER;
p_flt.output = DMX_OUT_TS_TAP; p_flt.output = DMX_OUT_TAP;
return true;
break; break;
case DMX_AUDIO_CHANNEL: case DMX_AUDIO_CHANNEL:
p_flt.pes_type = DMX_PES_OTHER; p_flt.pes_type = DMX_PES_OTHER;
p_flt.output = DMX_OUT_TS_TAP; p_flt.output = DMX_OUT_TSDEMUX_TAP;
break; break;
case DMX_VIDEO_CHANNEL: case DMX_VIDEO_CHANNEL:
p_flt.pes_type = DMX_PES_OTHER; p_flt.pes_type = DMX_PES_OTHER;
p_flt.output = DMX_OUT_TS_TAP; p_flt.output = DMX_OUT_TSDEMUX_TAP;
break; break;
case DMX_PES_CHANNEL: case DMX_PES_CHANNEL:
p_flt.pes_type = DMX_PES_OTHER; p_flt.pes_type = DMX_PES_OTHER;

View File

@@ -1,10 +1,9 @@
#ifndef __DEMUX_TD_H #ifndef __dmx_hal__
#define __DEMUX_TD_H #define __dmx_hal__
#include <cstdlib> #include <cstdlib>
#include <vector> #include <vector>
#include <inttypes.h> #include <inttypes.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h> #include <linux/dvb/dmx.h>
#include "../common/cs_types.h" #include "../common/cs_types.h"
@@ -28,20 +27,13 @@ typedef struct
unsigned short pid; unsigned short pid;
} pes_pids; } pes_pids;
class cRecord;
class cPlayback;
class cDemux class cDemux
{ {
private: friend class cRecord;
int num; friend class cPlayback;
int fd;
int buffersize;
bool measure;
uint64_t last_measure, last_data;
DMX_CHANNEL_TYPE dmx_type;
std::vector<pes_pids> pesfds;
struct dmx_sct_filter_params s_flt;
struct dmx_pes_filter_params p_flt;
public: public:
bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0); bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0);
void Close(void); void Close(void);
bool Start(bool record = false); bool Start(bool record = false);
@@ -58,13 +50,20 @@ class cDemux
int getUnit(void); int getUnit(void);
static bool SetSource(int unit, int source); static bool SetSource(int unit, int source);
static int GetSource(int unit); static int GetSource(int unit);
// TD only functions
int getFD(void) { return fd; }; /* needed by cPlayback class */ int getFD(void) { return fd; }; /* needed by cPlayback class */
void removePid(unsigned short Pid); /* needed by cRecord class */
std::vector<pes_pids> getPesPids(void) { return pesfds; };
//
cDemux(int num = 0); cDemux(int num = 0);
~cDemux(); ~cDemux();
private:
void removePid(unsigned short Pid); /* needed by cRecord class */
int num;
int fd;
int buffersize;
uint16_t pid;
uint8_t flt;
std::vector<pes_pids> pesfds;
DMX_CHANNEL_TYPE dmx_type;
void *pdata;
}; };
#endif //__DEMUX_H #endif //__dmx_hal__

View File

@@ -34,7 +34,7 @@
#include <map> #include <map>
#include <thread_abstraction.h> #include <thread_abstraction.h>
#include "init_lib.h" #include "init_td.h"
#include "lt_debug.h" #include "lt_debug.h"
#include "glfb.h" #include "glfb.h"
#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args) #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args)

View File

@@ -1,5 +0,0 @@
#ifndef __INIT_TD_H
#define __INIT_TD_H
void init_td_api();
void shutdown_td_api();
#endif

View File

@@ -1,10 +1,11 @@
#ifndef _VIDEO_TD_H #ifndef _VIDEO_LIB_H
#define _VIDEO_TD_H #define _VIDEO_LIB_H
#include <vector> #include <vector>
#include <linux/dvb/video.h> #include <linux/dvb/video.h>
#include "../common/cs_types.h" #include "cs_types.h"
#include "dmx_lib.h" #include "dmx_hal.h"
extern "C" { extern "C" {
#include <libavutil/rational.h> #include <libavutil/rational.h>
} }
@@ -57,7 +58,7 @@ typedef enum {
DISPLAY_AR_14_9, DISPLAY_AR_14_9,
DISPLAY_AR_16_9, DISPLAY_AR_16_9,
DISPLAY_AR_20_9, DISPLAY_AR_20_9,
DISPLAY_AR_RAW, DISPLAY_AR_RAW
} DISPLAY_AR; } DISPLAY_AR;
typedef enum { typedef enum {
@@ -101,7 +102,7 @@ typedef enum {
/* not used, for dummy functions */ /* not used, for dummy functions */
typedef enum { typedef enum {
VIDEO_HDMI_CEC_MODE_OFF = 0, VIDEO_HDMI_CEC_MODE_OFF = 0,
VIDEO_HDMI_CEC_MODE_TUNER, VIDEO_HDMI_CEC_MODE_TUNER,
VIDEO_HDMI_CEC_MODE_RECORDER VIDEO_HDMI_CEC_MODE_RECORDER
} VIDEO_HDMI_CEC_MODE; } VIDEO_HDMI_CEC_MODE;