aboutsummaryrefslogtreecommitdiff
path: root/lib/dvb
diff options
context:
space:
mode:
authorFelix Domke <tmbinc@elitedvb.net>2009-03-31 15:51:31 +0200
committerFelix Domke <tmbinc@elitedvb.net>2009-03-31 15:51:31 +0200
commitbce53d4a67d1655a496eebe5912c8573e880114e (patch)
tree9b410fbcaf0f4a22f1cf3489b635e3e94e47a6d8 /lib/dvb
parent166db5a9c9222c82939eede51d964c706039ebe8 (diff)
parent54475ce18e43482b2ec1a150f7fa07c3464ec6d2 (diff)
downloadenigma2-bce53d4a67d1655a496eebe5912c8573e880114e.tar.gz
enigma2-bce53d4a67d1655a496eebe5912c8573e880114e.zip
Merge commit 'origin/master' into tmbinc/FixTimingBugs
Diffstat (limited to 'lib/dvb')
-rw-r--r--lib/dvb/db.cpp13
-rw-r--r--lib/dvb/db.h4
-rw-r--r--lib/dvb/dvb.cpp5
-rw-r--r--lib/dvb/dvbtime.cpp42
-rw-r--r--lib/dvb/dvbtime.h3
-rw-r--r--lib/dvb/frontend.cpp2
-rw-r--r--lib/dvb/idvb.h4
-rw-r--r--lib/dvb/scan.cpp33
-rw-r--r--lib/dvb/scan.h4
-rw-r--r--lib/dvb/sec.cpp12
-rw-r--r--lib/dvb/sec.h3
-rw-r--r--lib/dvb/subtitle.cpp5
-rw-r--r--lib/dvb/subtitle.h1
-rw-r--r--lib/dvb/teletext.cpp141
-rw-r--r--lib/dvb/teletext.h4
15 files changed, 207 insertions, 69 deletions
diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp
index e6108ab5..e4d9ad22 100644
--- a/lib/dvb/db.cpp
+++ b/lib/dvb/db.cpp
@@ -839,7 +839,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
PyDict_SetItem(tp_dict, sat_pos, tplist);
for (ElementConstIterator it(sat_elements.begin()); it != sat_elements.end(); ++it)
{
-// eDebug("\telement: %s", (*it)->name().c_str());
+ //eDebug("\telement: %s", (*it)->name().c_str());
const AttributeList &tp_attributes = (*it)->getAttributeList();
AttributeConstIterator end = tp_attributes.end();
modulation = eDVBFrontendParametersSatellite::Modulation_QPSK;
@@ -856,8 +856,8 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
for (AttributeConstIterator it(tp_attributes.begin()); it != end; ++it)
{
- //eDebug("\t\tattr: %s", at->name().c_str());
at = *it;
+ //eDebug("\t\tattr: %s", at->name().c_str());
name = at->name();
if (name == "modulation") dest = &modulation;
else if (name == "system") dest = &system;
@@ -872,6 +872,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
else if (name == "onid") dest = &onid;
if (dest)
{
+ //eDebug("\t\t\tvalue: %s", at->value().c_str());
tmp = strtol(at->value().c_str(), &end_ptr, 10);
if (!*end_ptr)
*dest = tmp;
@@ -1201,15 +1202,17 @@ RESULT eDVBDB::removeServices(eDVBChannelID chid, unsigned int orbpos)
if ((unsigned int)sat.orbital_position != orbpos)
remove=false;
}
- if ( remove && chid.dvbnamespace != eNs )
+ if ( remove && chid.dvbnamespace != eNs ) // namespace given?
{
- if (system == iDVBFrontend::feCable && chid.dvbnamespace.get() == (int)0xFFFF0000)
+ if ( system == iDVBFrontend::feCable && chid.dvbnamespace.get() == (int)0xFFFF0000 )
;
- else if (system == iDVBFrontend::feTerrestrial && chid.dvbnamespace.get() == (int)0xEEEE0000)
+ else if ( system == iDVBFrontend::feTerrestrial && chid.dvbnamespace.get() == (int)0xEEEE0000 )
;
else if ( chid.dvbnamespace != ch.dvbnamespace )
remove=false;
}
+ else if ( system == iDVBFrontend::feCable || system == iDVBFrontend::feTerrestrial )
+ remove=false;
if ( remove && chid.original_network_id != eOnid && chid.original_network_id != ch.original_network_id )
remove=false;
if ( remove && chid.transport_stream_id != eTsid && chid.transport_stream_id != ch.transport_stream_id )
diff --git a/lib/dvb/db.h b/lib/dvb/db.h
index 55e008fb..11fb1ab1 100644
--- a/lib/dvb/db.h
+++ b/lib/dvb/db.h
@@ -51,11 +51,11 @@ public:
RESULT getChannelFrontendData(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &parm);
- RESULT addService(const eServiceReferenceDVB &service, eDVBService *service);
+ RESULT addService(const eServiceReferenceDVB &referenc, eDVBService *service);
RESULT getService(const eServiceReferenceDVB &reference, ePtr<eDVBService> &service);
RESULT flush();
- RESULT startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *query, const eServiceReference &source);
+ RESULT startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *q, const eServiceReference &source);
RESULT getBouquet(const eServiceReference &ref, eBouquet* &bouquet);
//////
diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp
index 4bbed519..1c4eef8a 100644
--- a/lib/dvb/dvb.cpp
+++ b/lib/dvb/dvb.cpp
@@ -1026,11 +1026,6 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s
fts += 188;
}
- /* force payload only */
- ts[3] &= ~0x30;
- ts[3] |= 0x10;
-
-// memset(ts + 4, 0xFF, (offset % 188) - 4);
m_iframe_state = 1;
}
diff --git a/lib/dvb/dvbtime.cpp b/lib/dvb/dvbtime.cpp
index d879cfac..a6830dc0 100644
--- a/lib/dvb/dvbtime.cpp
+++ b/lib/dvb/dvbtime.cpp
@@ -20,7 +20,7 @@ void setRTC(time_t time)
FILE *f = fopen("/proc/stb/fp/rtc", "w");
if (f)
{
- if (fprintf(f, "%u", time))
+ if (fprintf(f, "%u", (unsigned int)time))
prev_time = time;
else
eDebug("write /proc/stb/fp/rtc failed (%m)");
@@ -47,8 +47,11 @@ time_t getRTC()
if (f)
{
// sanity check to detect corrupt atmel firmware
- if (fscanf(f, "%u", &rtc_time) != 1)
+ unsigned int tmp;
+ if (fscanf(f, "%u", &tmp) != 1)
eDebug("read /proc/stb/fp/rtc failed (%m)");
+ else
+ rtc_time=tmp;
fclose(f);
}
else
@@ -145,7 +148,7 @@ eDVBLocalTimeHandler *eDVBLocalTimeHandler::instance;
DEFINE_REF(eDVBLocalTimeHandler);
eDVBLocalTimeHandler::eDVBLocalTimeHandler()
- :m_time_ready(false), m_updateNonTunedTimer(eTimer::create(eApp))
+ :m_use_dvb_time(false), m_updateNonTunedTimer(eTimer::create(eApp)), m_time_ready(false)
{
if ( !instance )
instance=this;
@@ -214,6 +217,33 @@ void eDVBLocalTimeHandler::writeTimeOffsetData( const char* filename )
}
}
+void eDVBLocalTimeHandler::setUseDVBTime(bool b)
+{
+ if (m_use_dvb_time != b) {
+ if (m_use_dvb_time) {
+ eDebug("[eDVBLocalTimeHandler] disable sync local time with transponder time!");
+ std::map<iDVBChannel*, channel_data>::iterator it =
+ m_knownChannels.begin();
+ for (; it != m_knownChannels.end(); ++it) {
+ if (it->second.m_prevChannelState == iDVBChannel::state_ok)
+ it->second.tdt = 0;
+ }
+ }
+ else {
+ eDebug("[eDVBLocalTimeHandler] enable sync local time with transponder time!");
+ std::map<iDVBChannel*, channel_data>::iterator it =
+ m_knownChannels.begin();
+ for (; it != m_knownChannels.end(); ++it) {
+ if (it->second.m_prevChannelState == iDVBChannel::state_ok) {
+ it->second.tdt = new TDT(it->second.channel);
+ it->second.tdt->start();
+ }
+ }
+ }
+ m_use_dvb_time = b;
+ }
+}
+
void eDVBLocalTimeHandler::updateNonTuned()
{
updateTime(-1, 0, 0);
@@ -440,8 +470,10 @@ void eDVBLocalTimeHandler::DVBChannelStateChanged(iDVBChannel *chan)
case iDVBChannel::state_ok:
eDebug("[eDVBLocalTimerHandler] channel %p running", chan);
m_updateNonTunedTimer->stop();
- it->second.tdt = new TDT(it->second.channel);
- it->second.tdt->start();
+ if (m_use_dvb_time) {
+ it->second.tdt = new TDT(it->second.channel);
+ it->second.tdt->start();
+ }
break;
case iDVBChannel::state_release:
eDebug("[eDVBLocalTimerHandler] remove channel %p", chan);
diff --git a/lib/dvb/dvbtime.h b/lib/dvb/dvbtime.h
index 3f8d9b7d..3afff75e 100644
--- a/lib/dvb/dvbtime.h
+++ b/lib/dvb/dvbtime.h
@@ -54,6 +54,7 @@ class eDVBLocalTimeHandler: public Object
ePtr<eConnection> m_stateChangedConn;
int m_prevChannelState;
};
+ bool m_use_dvb_time;
ePtr<eTimer> m_updateNonTunedTimer;
friend class TDT;
std::map<iDVBChannel*, channel_data> m_knownChannels;
@@ -78,6 +79,8 @@ public:
eDVBLocalTimeHandler();
~eDVBLocalTimeHandler();
#endif
+ bool getUseDVBTime() { return m_use_dvb_time; }
+ void setUseDVBTime(bool b);
PSignal0<void> m_timeUpdated;
bool ready() const { return m_time_ready; }
static eDVBLocalTimeHandler *getInstance() { return instance; }
diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp
index 5df17931..f2fc12b3 100644
--- a/lib/dvb/frontend.cpp
+++ b/lib/dvb/frontend.cpp
@@ -858,6 +858,8 @@ int eDVBFrontend::readFrontendData(int type)
if (snr != 0)
ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
}
+ else if (!strcmp(m_description, "BCM4506"))
+ ret = (snr * 100) >> 8;
if (type == signalQuality)
{
diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h
index cfa98ecf..26ab5e53 100644
--- a/lib/dvb/idvb.h
+++ b/lib/dvb/idvb.h
@@ -385,13 +385,13 @@ public:
virtual RESULT getChannelFrontendData(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &parm)=0;
- virtual RESULT addService(const eServiceReferenceDVB &service, eDVBService *service)=0;
+ virtual RESULT addService(const eServiceReferenceDVB &reference, eDVBService *service)=0;
virtual RESULT getService(const eServiceReferenceDVB &reference, ePtr<eDVBService> &service)=0;
virtual RESULT flush()=0;
virtual RESULT getBouquet(const eServiceReference &ref, eBouquet* &bouquet)=0;
- virtual RESULT startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *query, const eServiceReference &source)=0;
+ virtual RESULT startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *q, const eServiceReference &source)=0;
};
#endif // SWIG
diff --git a/lib/dvb/scan.cpp b/lib/dvb/scan.cpp
index 76c71011..379ab8e9 100644
--- a/lib/dvb/scan.cpp
+++ b/lib/dvb/scan.cpp
@@ -740,11 +740,20 @@ void eDVBScan::channelDone()
}
case iDVBFrontend::feTerrestrial:
{
+ ePtr<iDVBFrontend> fe;
eDVBFrontendParametersTerrestrial parm;
m_ch_current->getDVBT(parm);
snprintf(sname, 255, "%d SID 0x%02x",
parm.frequency/1000,
m_pmt_in_progress->first);
+ if (!m_channel->getFrontend(fe))
+ {
+ ePyObject tp_dict = PyDict_New();
+ fe->getTransponderData(tp_dict, false);
+ m_corrected_frequencys[m_chid_current] =
+ PyInt_AsLong(PyDict_GetItemString(tp_dict, "frequency"));
+ Py_DECREF(tp_dict);
+ }
break;
}
case iDVBFrontend::feCable:
@@ -765,7 +774,8 @@ void eDVBScan::channelDone()
if (!(m_flags & scanOnlyFree) || !m_pmt_in_progress->second.scrambled) {
SCAN_eDebug("add not scrambled!");
- std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
+ std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i =
+ m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
if (i.second)
{
m_last_service = i.first;
@@ -922,6 +932,24 @@ void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags)
for (std::map<eDVBChannelID, ePtr<iDVBFrontendParameters> >::const_iterator
ch(m_new_channels.begin()); ch != m_new_channels.end(); ++ch)
{
+ int system;
+ ch->second->getSystem(system);
+ if (system == iDVBFrontend::feTerrestrial)
+ {
+ std::map<eDVBChannelID, unsigned int>::iterator it = m_corrected_frequencys.find(ch->first);
+ if (it != m_corrected_frequencys.end())
+ {
+ eDVBFrontendParameters *p = (eDVBFrontendParameters*)&(*ch->second);
+ eDVBFrontendParametersTerrestrial parm;
+ p->getDVBT(parm);
+ eDebug("corrected freq for tsid %04x, onid %04x, ns %08x is %d, old was %d",
+ ch->first.transport_stream_id.get(), ch->first.original_network_id.get(),
+ ch->first.dvbnamespace.get(), it->second, parm.frequency);
+ parm.frequency = it->second;
+ p->setDVBT(parm);
+ m_corrected_frequencys.erase(it);
+ }
+ }
if (m_flags & scanOnlyFree)
{
eDVBFrontendParameters *ptr = (eDVBFrontendParameters*)&(*ch->second);
@@ -1036,7 +1064,8 @@ RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescription
}
}
- std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
+ std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i =
+ m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
if (i.second)
{
diff --git a/lib/dvb/scan.h b/lib/dvb/scan.h
index 38ac784f..9f0dd6ef 100644
--- a/lib/dvb/scan.h
+++ b/lib/dvb/scan.h
@@ -50,7 +50,9 @@ class eDVBScan: public Object, public iObject
/* scan state variables */
int m_channel_state;
int m_ready, m_ready_all;
-
+
+ std::map<eDVBChannelID, unsigned int> m_corrected_frequencys; // yet just used for DVB-T
+
std::map<eDVBChannelID, ePtr<iDVBFrontendParameters> > m_new_channels;
std::map<eServiceReferenceDVB, ePtr<eDVBService> > m_new_services;
std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator m_last_service;
diff --git a/lib/dvb/sec.cpp b/lib/dvb/sec.cpp
index ac1a2028..d14acc85 100644
--- a/lib/dvb/sec.cpp
+++ b/lib/dvb/sec.cpp
@@ -563,7 +563,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
compare.tone = iDVBFrontend::toneOff;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC]) );
if (diseqc13V)
vlt = iDVBFrontend::voltage13;
@@ -705,7 +705,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
compare.tone = iDVBFrontend::toneOff;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC]) );
compare.voltage = iDVBFrontend::voltageOff;
compare.steps = +4;
@@ -839,7 +839,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
compare.tone = tone;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_CONT_TONE_CHANGE]) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
cmd.direction=1; // check for running rotor
@@ -884,7 +884,7 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
compare.tone = tone;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_CONT_TONE]) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_CONT_TONE_CHANGE]) );
}
sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_SWITCHPARMS) );
@@ -897,11 +897,11 @@ RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPA
compare.voltage = iDVBFrontend::voltageOff;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_NOT_VOLTAGE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50 ) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_SWITCH_CMDS] ) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18_5) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MOTOR_CMD]) ); // wait 150msec after voltage change
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_SWITCH_CMDS]) ); // wait 20 ms after voltage change
eDVBDiseqcCommand diseqc;
memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
diff --git a/lib/dvb/sec.h b/lib/dvb/sec.h
index 5bff6bf7..5d969328 100644
--- a/lib/dvb/sec.h
+++ b/lib/dvb/sec.h
@@ -271,7 +271,8 @@ class eDVBSatelliteEquipmentControl: public iDVBSatelliteEquipmentControl
DECLARE_REF(eDVBSatelliteEquipmentControl);
public:
enum {
- DELAY_AFTER_CONT_TONE=0, // delay after continuous tone change
+ DELAY_AFTER_CONT_TONE_DISABLE_BEFORE_DISEQC=0, // delay after continuous tone disable before diseqc command
+ DELAY_AFTER_FINAL_CONT_TONE_CHANGE, // delay after continuous tone change before tune
DELAY_AFTER_FINAL_VOLTAGE_CHANGE, // delay after voltage change at end of complete sequence
DELAY_BETWEEN_DISEQC_REPEATS, // delay between repeated diseqc commands
DELAY_AFTER_LAST_DISEQC_CMD, // delay after last diseqc command
diff --git a/lib/dvb/subtitle.cpp b/lib/dvb/subtitle.cpp
index f4b5b7e4..642327bb 100644
--- a/lib/dvb/subtitle.cpp
+++ b/lib/dvb/subtitle.cpp
@@ -345,6 +345,8 @@ int eDVBSubtitleParser::subtitle_process_segment(__u8 *segment)
}
}
+ page->state = page_state;
+
//eDebug("page updated: old: %d, new: %d", page->page_version_number, page_version_number);
// when acquisition point or mode change: remove all displayed pages.
if ((page_state == 1) || (page_state == 2))
@@ -804,7 +806,8 @@ void eDVBSubtitleParser::subtitle_redraw_all()
subtitle_page *page = m_pages;
while(page)
{
- subtitle_redraw(page->page_id);
+ if (page->state != 0)
+ subtitle_redraw(page->page_id);
page = page->next;
}
#else
diff --git a/lib/dvb/subtitle.h b/lib/dvb/subtitle.h
index fb9c51a2..09d6cd47 100644
--- a/lib/dvb/subtitle.h
+++ b/lib/dvb/subtitle.h
@@ -71,6 +71,7 @@ struct subtitle_page
int page_id;
time_t page_time_out;
int page_version_number;
+ int state;
int pcs_size;
subtitle_page_region *page_regions;
diff --git a/lib/dvb/teletext.cpp b/lib/dvb/teletext.cpp
index ca0412e3..de4c6d75 100644
--- a/lib/dvb/teletext.cpp
+++ b/lib/dvb/teletext.cpp
@@ -127,7 +127,7 @@ unsigned int Latin_G2_set[6*16] = {
// This is a very simple en300 706 telext decoder.
// It can only decode a single page at a time, thus it's only used
-// for subtitles.
+// for subtitles. And it ONLY support LATIN Charsets yet!
DEFINE_REF(eDVBTeletextParser);
@@ -149,6 +149,15 @@ static inline unsigned char decode_hamming_84(unsigned char *b)
static inline unsigned long decode_hamming_2418(unsigned char *b)
{
+ static const unsigned char rev[16] = {
+ 0x00,0x08,0x04,0x0c,
+ 0x02,0x0a,0x06,0x0e,
+ 0x01,0x09,0x05,0x0d,
+ 0x03,0x0b,0x07,0x0f
+ };
+ b[0] = rev[b[0] >> 4] | (rev[b[0] & 0xf] << 4);
+ b[1] = rev[b[1] >> 4] | (rev[b[1] & 0xf] << 4);
+ b[2] = rev[b[2] >> 4] | (rev[b[2] & 0xf] << 4);
return ((b[0] & 0x04) >> 2) | ((b[0] & 0x70) >> 3) | ((b[1] & 0x7f) << 4) | ((b[2] & 0x7f) << 11);
}
@@ -258,7 +267,7 @@ void eDVBTeletextParser::processPESPacket(__u8 *pkt, int len)
int M = magazine_and_packet_address & 7,
Y = magazine_and_packet_address >> 3;
// eDebug("line %d, framing code: %02x, M=%02x, Y=%02x", line_offset, framing_code, m_M, m_Y);
-
+
if (Y == 0) /* page header */
{
int X = decode_hamming_84(data + 1) * 0x10 + decode_hamming_84(data),
@@ -315,19 +324,10 @@ void eDVBTeletextParser::processPESPacket(__u8 *pkt, int len)
} else if (Y == 26 && m_page_open && M == m_page_M)
{
// int designation_code = decode_hamming_84(data);
- static const unsigned char rev[16] = {
- 0x00,0x08,0x04,0x0c,
- 0x02,0x0a,0x06,0x0e,
- 0x01,0x09,0x05,0x0d,
- 0x03,0x0b,0x07,0x0f
- };
int display_row=-1, display_column=-1;
for (int a = 1; a < 40; a+=3)
{
int val;
- data[a] = rev[data[a] >> 4] | (rev[data[a] & 0xf] << 4);
- data[a+1] = rev[data[a+1] >> 4] | (rev[data[a+1] & 0xf] << 4);
- data[a+2] = rev[data[a+2] >> 4] | (rev[data[a+2] & 0xf] << 4);
if ((val=decode_hamming_2418(data+a)) >= 0)
{
unsigned char addr = val & 0x3F;
@@ -401,12 +401,63 @@ void eDVBTeletextParser::processPESPacket(__u8 *pkt, int len)
}
} else if (Y > 29)
/*eDebug("non handled packet 30, 31", Y, decode_hamming_84(data))*/;
- else if (Y == 29)
- eDebug("non handled packet M/%d/%d", Y, decode_hamming_84(data));
- else if (m_page_open)
+ else if (Y == 29 && M == m_page_M)
{
- if (M == m_page_M)
- eDebug("non handled packet X/%d/%d", Y, decode_hamming_84(data));
+ int designation_code = decode_hamming_84(data++);
+ if (designation_code == 0) // 29/0
+ {
+ m_M29_t1 = decode_hamming_2418(data);
+ m_M29_t2 = decode_hamming_2418(data+3);
+ if ((m_M29_t1 & 0xF) == 0) // format1
+ m_M29_0_valid = 1;
+ else
+ eDebug("non handled packet M/%d/0 format %d", Y, m_M29_t1 & 0xF);
+ }
+ else
+ eDebug("non handled packet M/%d/%d", Y, designation_code);
+ }
+ else if (m_page_open && M == m_page_M)
+ {
+ int designation_code = decode_hamming_84(data++);
+ if (Y == 28 && designation_code == 0) // 28/0
+ {
+#if 1
+ m_X28_t1 = decode_hamming_2418(data);
+ m_X28_t2 = decode_hamming_2418(data+3);
+ if ((m_X28_t1 & 0xF) == 0) // format1
+ m_X28_0_valid = 1;
+ else
+ eDebug("non handled packet X/%d/0 format %d", Y, m_X28_t1 & 0xF);
+#else
+ int i=0;
+ for (; i < 39; i+=3)
+ {
+ int tripletX = decode_hamming_2418(data+i);
+ if (tripletX >= 0)
+ {
+ if (i == 0)
+ {
+ if ((m_X28_t1 & 0xF) == 0) // format1
+ m_X28_0_valid = 1;
+ m_X28_t1 = tripletX;
+ }
+ else if (i == 1)
+ m_X28_t2 = tripletX;
+
+ char *c = get_bits(tripletX, 18);
+ int x=0;
+ for (; x < 18; ++x)
+ eDebugNoNewLine("%c", c[x]);
+ eDebug("");
+ }
+ else
+ eDebug("decode_hamming_2418 failed!\n");
+ data += 3;
+ }
+#endif
+ }
+ else
+ eDebug("non handled packet X/%d/%d", Y, designation_code);
}
}
}
@@ -430,6 +481,7 @@ void eDVBTeletextParser::handlePageStart()
{
m_subtitle_page.clear();
m_modifications.clear();
+ m_X28_0_valid = 0;
// eDebug("erase page!");
}
// else
@@ -463,28 +515,46 @@ void eDVBTeletextParser::handleLine(unsigned char *data, int len)
nat_opts = (m_C & (1<<14) ? 1 : 0) |
(m_C & (1<<13) ? 2 : 0) |
(m_C & (1<<12) ? 4 : 0),
- nat_subset = NationalOptionSubsetsLookup[Gtriplet*8+nat_opts];
-/* eDebug("nat_opts = %d, nat_subset = %d, C121314 = %d%d%d",
- nat_opts, nat_subset,
- (m_C & (1<<12))?1:0,
- (m_C & (1<<13))?1:0,
- (m_C & (1<<14))?1:0);*/
+ nat_subset_2 = NationalOptionSubsetsLookup[Gtriplet*8+nat_opts],
+ nat_subset = nat_subset_2,
+ second_G0_set = 0;
+
+ if (m_X28_0_valid)
+ {
+ nat_subset = NationalOptionSubsetsLookup[(m_X28_t1 >> 7) & 0x7F];
+ nat_subset_2 = NationalOptionSubsetsLookup[((m_X28_t1 >> 14) & 0xF) | ((m_X28_t2 & 7) << 4)];
+// eDebug("X/28/0 nat_subset %d, nat_subset2 %d", nat_subset, nat_subset_2);
+ }
+ else if (m_M29_0_valid)
+ {
+ nat_subset = NationalOptionSubsetsLookup[(m_M29_t1 >> 7) & 0x7F];
+ nat_subset_2 = NationalOptionSubsetsLookup[((m_M29_t1 >> 14) & 0xF) | ((m_M29_t2 & 7) << 4)];
+// eDebug("M/29/0 nat_subset %d, nat_subset2 %d", nat_subset, nat_subset_2);
+ }
+/* else
+ eDebug("nat_opts = %d, nat_subset = %d, C121314 = %d%d%d",
+ nat_opts, nat_subset,
+ (m_C & (1<<12))?1:0,
+ (m_C & (1<<13))?1:0,
+ (m_C & (1<<14))?1:0);*/
// eDebug("handle subtitle line: %d len", len);
for (int i=0; i<len; ++i)
{
+ unsigned char b = decode_odd_parity(data + i);
std::map<int,unsigned int>::iterator it = m_modifications.find((m_Y<<16)|i);
+
if (it != m_modifications.end())
{
unsigned int utf8_code = it->second;
+// eDebugNoNewLine("%c[%d]", b, b);
if (utf8_code < 0x10)
{
int mode = utf8_code;
- unsigned char ch = decode_odd_parity(data + i);
- if (ch > 96 && ch < 123)
- utf8_code = diacr_lower_cmap[(ch-97)*15+mode-1];
- else if (ch > 64 && ch < 91)
- utf8_code = diacr_upper_cmap[(ch-65)*15+mode-1];
+ if (b > 96 && b < 123)
+ utf8_code = diacr_lower_cmap[(b-97)*15+mode-1];
+ else if (b > 64 && b < 91)
+ utf8_code = diacr_upper_cmap[(b-65)*15+mode-1];
}
if (utf8_code > 0xFFFFFF)
out[outidx++]=(utf8_code&0xFF000000)>>24;
@@ -498,8 +568,6 @@ void eDVBTeletextParser::handleLine(unsigned char *data, int len)
continue;
}
- unsigned char b = decode_odd_parity(data + i);
-
if (b < 0x10) /* spacing attribute */
{
if (b < 8) /* colors */
@@ -522,17 +590,11 @@ void eDVBTeletextParser::handleLine(unsigned char *data, int len)
/* ignore other attributes */
} else if (m_box_open>1)
{
- //eDebugNoNewLine("%c", b);
+// eDebugNoNewLine("%c(%d)", b, b);
/* no more than one whitespace, only printable chars */
if (((!last_was_white) || (b != ' ')) && (b >= 0x20))
{
- int cur_nat_subset = nat_subset;
-
- if (b == 0x24) // workaround for currency sign.. the only on non latin1 char in G0 set
- {
- cur_nat_subset = 9;
- b = 36;
- }
+ int cur_nat_subset = second_G0_set ? nat_subset_2 : nat_subset;
unsigned char offs = NationalReplaceMap[b];
if (offs)
@@ -551,9 +613,11 @@ void eDVBTeletextParser::handleLine(unsigned char *data, int len)
out[outidx++] = b;
last_was_white = b == ' ';
}
+ else if (b == 0x1b) // ESC ... switch between default G0 and second G0 charset
+ second_G0_set ^= 1;
}
}
- //eDebug("");
+// eDebug("");
addSubtitleString(color, std::string((const char*)out, outidx));
}
@@ -575,6 +639,7 @@ void eDVBTeletextParser::setPageAndMagazine(int page, int magazine)
eDebug("enable teletext subtitle page %x%02x", magazine, page);
else
eDebug("disable teletext subtitles");
+ m_M29_0_valid = 0;
m_page_M = magazine; /* magazine to look for */
if (magazine != -1)
m_page_M &= 7;
diff --git a/lib/dvb/teletext.h b/lib/dvb/teletext.h
index a07c6aea..880fa569 100644
--- a/lib/dvb/teletext.h
+++ b/lib/dvb/teletext.h
@@ -50,7 +50,9 @@ private:
eDVBTeletextSubtitlePage m_subtitle_page;
int m_C, m_Y, m_pid, m_page_M, m_page_X, m_page_open, m_double_height, m_box_open;
-
+ int m_X28_0_valid, m_X28_t1, m_X28_t2;
+ int m_M29_0_valid, m_M29_t1, m_M29_t2;
+
void handlePageStart();
void handleLine(unsigned char *line, int len);
void handlePageEnd(int have_pts, const pts_t &pts);