Permalink
Browse files

Generate PSI packets for broken firmware cable boxes

Fixes #7205

If the firewire_gen_psip option is set for the capture device, generate
MPEG2-TS PAT and PMT packets (aka Program Specific Information (PSI)
packets).
  • Loading branch information...
1 parent b588a4f commit b91b487222c806e650ec64929f9f14a639d492cc @txase committed Jul 31, 2011
@@ -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);
@@ -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");
@@ -308,6 +327,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;
@@ -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();

0 comments on commit b91b487

Please sign in to comment.