Generate MPEG2-TS Program Specific Information (PSI) packets #10

Open
wants to merge 5 commits into
from
+491 −28
Split
@@ -114,7 +114,7 @@ package MythTV;
# schema version supported in the main code. We need to check that the schema
# version in the database is as expected by the bindings, which are expected
# to be kept in sync with the main code.
- our $SCHEMA_VERSION = "1280";
+ our $SCHEMA_VERSION = "1281";
# NUMPROGRAMLINES is defined in mythtv/libs/libmythtv/programinfo.h and is
# the number of items in a ProgramInfo QStringList group used by
@@ -5,7 +5,7 @@
"""
OWN_VERSION = (0,25,-1,2)
-SCHEMA_VERSION = 1280
+SCHEMA_VERSION = 1281
NVSCHEMA_VERSION = 1007
MUSICSCHEMA_VERSION = 1018
PROTO_VERSION = '69'
@@ -51,7 +51,7 @@
* MythTV Python Bindings
* mythtv/bindings/python/MythTV/static.py
*/
-#define MYTH_DATABASE_VERSION "1280"
+#define MYTH_DATABASE_VERSION "1281"
MBASE_PUBLIC const char *GetMythSourceVersion();
@@ -114,8 +114,8 @@ class DFDPriv
};
DarwinFirewireDevice::DarwinFirewireDevice(
- uint64_t guid, uint subunitid, uint speed) :
- FirewireDevice(guid, subunitid, speed),
+ uint64_t guid, uint subunitid, uint speed, bool gen_psip) :
+ FirewireDevice(guid, subunitid, speed, gen_psip),
m_local_node(-1), m_remote_node(-1), m_priv(new DFDPriv())
{
@@ -20,7 +20,8 @@ class DarwinFirewireDevice : public FirewireDevice
public:
- DarwinFirewireDevice(uint64_t guid, uint subunitid, uint speed);
+ DarwinFirewireDevice(uint64_t guid, uint subunitid, uint speed,
+ bool gen_psip = false);
~DarwinFirewireDevice();
virtual bool OpenPort(void);
@@ -151,15 +151,16 @@ are all "DVB" specific configuration parameters.
Both 'dvb_recordts' and 'dvb_hw_decoder' are unused, and
will be dropped in future versions of MythTV.
-The 'firewire_port', 'firewire_node', 'firewire_speed',
-'firewire_model', 'firewire_connection' are all "FIREWIRE" specific
-configuration parameters. The first three define the connection,
-and function much like 'videodevice' does for other capture "cards".
-The 'firewire_model' describes the cable box model, for example
-"DCT-6000" describes a box that communicates using the same protocol
-as the Motorola DCT-6000. The 'firewire_connection' field describes
-the overall communication protocol, i.e. are we using "Broadcast"
-or "Point-to-Point" communication.
+The 'firewire_speed', 'firewire_model', 'firewire_connection',
+and 'firewire_gen_psip' are all "FIREWIRE" specific configuration
+parameters. The 'firewire_speed' describes the speed of the firewire
+link. The 'firewire_model' describes the cable box model, for
+example "DCT-6000" describes a box that communicates using the same
+protocol as the Motorola DCT-6000. The 'firewire_connection' field
+describes the overall communication protocol, i.e. are we using
+"Broadcast" or "Point-to-Point" communication. The
+'firewire_gen_psip' field specifies whether MythTV should generate
+MPEG2-TS PAT and PMT packets for broken cable boxes that do not.
\section dtv_multiplex_table Digital Television Multiplex Table (dtv_multiplex)
This table contains the information needed to tune to a particular
@@ -5848,6 +5849,16 @@ NULL
return false;
}
+ if (dbver == "1280")
+ {
+ const char *updates[] = {
+"ALTER TABLE capturecard ADD COLUMN firewire_gen_psip tinyint(1) default '0';",
+NULL
+};
+ if (!performActualUpdate(updates, "1281", dbver))
+ return false;
+ }
+
return true;
}
@@ -5930,6 +5941,7 @@ tmp.constData(),
" firewire_speed int(10) unsigned NOT NULL default '0',"
" firewire_model varchar(32) default NULL,"
" firewire_connection int(10) unsigned NOT NULL default '0',"
+" firewire_gen_psip tinyint(1) default '0',"
" dbox2_port int(10) unsigned NOT NULL default '31338',"
" dbox2_httpport int(10) unsigned NOT NULL default '80',"
" dbox2_host varchar(32) default NULL,"
@@ -28,11 +28,13 @@ FirewireChannel::FirewireChannel(TVRec *parent, const QString &_videodevice,
#ifdef USING_LINUX_FIREWIRE
device = new LinuxFirewireDevice(
guid, subunitid, fw_opts.speed,
- LinuxFirewireDevice::kConnectionP2P == (uint) fw_opts.connection);
+ LinuxFirewireDevice::kConnectionP2P == (uint) fw_opts.connection,
+ fw_opts.gen_psip);
#endif // USING_LINUX_FIREWIRE
#ifdef USING_OSX_FIREWIRE
- device = new DarwinFirewireDevice(guid, subunitid, fw_opts.speed);
+ device = new DarwinFirewireDevice(guid, subunitid, fw_opts.speed,
+ fw_opts.gen_psip);
#endif // USING_OSX_FIREWIRE
}
@@ -15,6 +15,7 @@
#include "darwinfirewiredevice.h"
#include "mythlogging.h"
#include "pespacket.h"
+#include "psipgenerator.h"
#define LOC QString("FireDev(%1): ").arg(guid_to_string(m_guid))
@@ -23,13 +24,28 @@ static void fw_init(QMap<uint64_t,QString> &id_to_model);
QMap<uint64_t,QString> FirewireDevice::s_id_to_model;
QMutex FirewireDevice::s_static_lock;
-FirewireDevice::FirewireDevice(uint64_t guid, uint subunitid, uint speed) :
+FirewireDevice::FirewireDevice(uint64_t guid, uint subunitid, uint speed,
+ bool gen_psip) :
m_guid(guid), m_subunitid(subunitid),
m_speed(speed),
m_last_channel(0), m_last_crc(0),
m_buffer_cleared(true), m_open_port_cnt(0),
- m_lock()
+ m_lock(), m_psip_generator(NULL)
{
+ if (gen_psip)
+ {
+ m_psip_generator = new PSIPGenerator;
+ if (!m_psip_generator->Initialize())
+ {
+ delete m_psip_generator;
+ m_psip_generator = NULL;
+ }
+ }
+}
+
+FirewireDevice::~FirewireDevice()
+{
+ delete m_psip_generator;
}
void FirewireDevice::AddListener(TSDataListener *listener)
@@ -152,6 +168,9 @@ bool FirewireDevice::SetChannel(const QString &panel_model,
LOG(VB_CHANNEL, LOG_INFO, QString("SetChannel(model %1, alt %2, chan %3)")
.arg(panel_model).arg(alt_method).arg(channel));
+ if (m_psip_generator)
+ m_psip_generator->Reset();
+
QMutexLocker locker(&m_lock);
LOG(VB_CHANNEL, LOG_INFO, "SetChannel() -- locked");
@@ -309,6 +328,35 @@ bool FirewireDevice::SetChannel(const QString &panel_model,
void FirewireDevice::BroadcastToListeners(
const unsigned char *data, uint dataSize)
{
+ if (m_psip_generator)
+ {
+ if (!m_psip_generator->IsPSIAvailable()) {
+ m_psip_generator->AddData(data, dataSize);
+ m_psip_generator->CheckPSIAvailable();
+ }
+
+ if (m_psip_generator->IsPSIAvailable())
+ {
+ const vector<TSPacket> pat_pkts = m_psip_generator->PATPackets();
+ for (vector<TSPacket>::const_iterator it = pat_pkts.begin();
+ it != pat_pkts.end();
+ ++it)
+ SendDataToListeners(it->data(), TSPacket::kSize);
+
+ const vector<TSPacket> pmt_pkts = m_psip_generator->PMTPackets();
+ for (vector<TSPacket>::const_iterator it = pmt_pkts.begin();
+ it != pmt_pkts.end();
+ ++it)
+ SendDataToListeners(it->data(), TSPacket::kSize);
+ }
+ }
+
+ SendDataToListeners(data, dataSize);
+}
+
+void FirewireDevice::SendDataToListeners(const unsigned char *data,
+ uint dataSize)
+{
if ((dataSize >= TSPacket::kSize) && (data[0] == SYNC_BYTE) &&
((data[1] & 0x1f) == 0) && (data[2] == 0))
{
@@ -19,6 +19,7 @@ using namespace std;
#include "streamlisteners.h"
#include "avcinfo.h"
+class PSIPGenerator;
class TSPacket;
class FirewireDevice
@@ -190,7 +191,7 @@ class FirewireDevice
} IEEE1394PanelPassThroughParam0;
- virtual ~FirewireDevice() { }
+ virtual ~FirewireDevice();
// Commands
virtual bool OpenPort(void) = 0;
@@ -218,7 +219,7 @@ class FirewireDevice
static vector<AVCInfo> GetSTBList(void);
protected:
- FirewireDevice(uint64_t guid, uint subunitid, uint speed);
+ FirewireDevice(uint64_t guid, uint subunitid, uint speed, bool gen_psip);
virtual bool SendAVCCommand(const vector<uint8_t> &cmd,
vector<uint8_t> &result,
@@ -229,6 +230,7 @@ class FirewireDevice
void ProcessPATPacket(const TSPacket&);
virtual void BroadcastToListeners(
const unsigned char *data, uint dataSize);
+ void SendDataToListeners(const unsigned char *data, uint dataSize);
uint64_t m_guid;
uint m_subunitid;
@@ -241,6 +243,8 @@ class FirewireDevice
vector<TSDataListener*> m_listeners;
mutable QMutex m_lock;
+ PSIPGenerator* m_psip_generator;
+
/// Vendor ID + Model ID to FirewireDevice STB model string
static QMap<uint64_t,QString> s_id_to_model;
static QMutex s_static_lock;
@@ -504,10 +504,10 @@ using_backend {
using_firewire {
HEADERS += firewirechannel.h firewirerecorder.h
HEADERS += firewiresignalmonitor.h firewiredevice.h
- HEADERS += avcinfo.h
+ HEADERS += avcinfo.h psipgenerator.h
SOURCES += firewirechannel.cpp firewirerecorder.cpp
SOURCES += firewiresignalmonitor.cpp firewiredevice.cpp
- SOURCES += avcinfo.cpp
+ SOURCES += avcinfo.cpp psipgenerator.cpp
macx {
HEADERS += darwinfirewiredevice.h darwinavcinfo.h
@@ -129,8 +129,8 @@ static int linux_firewire_device_bus_reset_handler(
LinuxFirewireDevice::LinuxFirewireDevice(
uint64_t guid, uint subunitid,
- uint speed, bool use_p2p, uint av_buffer_size_in_bytes) :
- FirewireDevice(guid, subunitid, speed),
+ uint speed, bool use_p2p, bool gen_psip, uint av_buffer_size_in_bytes) :
+ FirewireDevice(guid, subunitid, speed, gen_psip),
m_bufsz(av_buffer_size_in_bytes),
m_db_reset_disabled(false),
m_use_p2p(use_p2p), m_priv(new LFDPriv())
@@ -23,7 +23,7 @@ class LinuxFirewireDevice : public FirewireDevice, public QRunnable
public:
LinuxFirewireDevice(uint64_t guid, uint subunitid,
- uint speed, bool use_p2p,
+ uint speed, bool use_p2p, bool gen_psip = false,
uint av_buffer_size_in_bytes = 0);
~LinuxFirewireDevice();
Oops, something went wrong.