git.cweiske.de
/
enigma2.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
5a5f61e
)
add support for rds data on own pids (i.e. hitradio ffh, harmony fm)
author
ghost
<andreas.monzner@multimedia-labs.de>
Tue, 11 Aug 2009 17:28:32 +0000
(19:28 +0200)
committer
ghost
<andreas.monzner@multimedia-labs.de>
Tue, 11 Aug 2009 17:28:32 +0000
(19:28 +0200)
lib/dvb/pmt.cpp
patch
|
blob
|
history
lib/dvb/pmt.h
patch
|
blob
|
history
lib/dvb/radiotext.cpp
patch
|
blob
|
history
lib/dvb/radiotext.h
patch
|
blob
|
history
lib/service/servicedvb.cpp
patch
|
blob
|
history
diff --git
a/lib/dvb/pmt.cpp
b/lib/dvb/pmt.cpp
index fb81fa4c3f45559892bb1b68d750a10b62d564f9..a4fa212d5cc2f3d32605e1fc206c0f65aa6bc4a9 100644
(file)
--- a/
lib/dvb/pmt.cpp
+++ b/
lib/dvb/pmt.cpp
@@
-184,6
+184,8
@@
int eDVBServicePMTHandler::getProgramInfo(struct program &program)
int first_ac3 = -1;
program.defaultAudioStream = 0;
int first_ac3 = -1;
program.defaultAudioStream = 0;
+ int rdsPid = -1;
+ audioStream *prev_audio = 0;
if ( m_service && !m_service->cacheEmpty() )
{
if ( m_service && !m_service->cacheEmpty() )
{
@@
-215,13
+217,15
@@
int eDVBServicePMTHandler::getProgramInfo(struct program &program)
for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
{
int isaudio = 0, isvideo = 0, issubtitle = 0, forced_video = 0, forced_audio = 0, isteletext = 0;
for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
{
int isaudio = 0, isvideo = 0, issubtitle = 0, forced_video = 0, forced_audio = 0, isteletext = 0;
+ int streamtype = (*es)->getType();
videoStream video;
audioStream audio;
audio.component_tag=video.component_tag=-1;
video.type = videoStream::vtMPEG2;
audio.type = audioStream::atMPEG;
videoStream video;
audioStream audio;
audio.component_tag=video.component_tag=-1;
video.type = videoStream::vtMPEG2;
audio.type = audioStream::atMPEG;
+ audio.rdsPid = -1;
- switch (
(*es)->getType()
)
+ switch (
streamtype
)
{
case 0x1b: // AVC Video Stream (MPEG4 H264)
video.type = videoStream::vtMPEG4_H264;
{
case 0x1b: // AVC Video Stream (MPEG4 H264)
video.type = videoStream::vtMPEG4_H264;
@@
-285,11
+289,14
@@
int eDVBServicePMTHandler::getProgramInfo(struct program &program)
}
case 0x06: // PES Private
case 0xEA: // TS_PSI_ST_SMPTE_VC1
}
case 0x06: // PES Private
case 0xEA: // TS_PSI_ST_SMPTE_VC1
+ {
+ int num_descriptors = 0;
for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
desc != (*es)->getDescriptors()->end(); ++desc)
{
uint8_t tag = (*desc)->getTag();
/* check descriptors to get the exakt stream type. */
for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
desc != (*es)->getDescriptors()->end(); ++desc)
{
uint8_t tag = (*desc)->getTag();
/* check descriptors to get the exakt stream type. */
+ ++num_descriptors;
if (!forced_video && !forced_audio)
{
switch (tag)
if (!forced_video && !forced_audio)
{
switch (tag)
@@
-458,6
+465,13
@@
int eDVBServicePMTHandler::getProgramInfo(struct program &program)
break;
}
}
break;
}
}
+ if (!num_descriptors && streamtype == 0x06 && prev_audio)
+ {
+ prev_audio->rdsPid = (*es)->getPid();
+ eDebug("Rds PID %04x detected ? ! ?", prev_audio->rdsPid);
+ }
+ prev_audio = 0;
+ }
default:
break;
}
default:
break;
}
@@
-496,6
+510,7
@@
int eDVBServicePMTHandler::getProgramInfo(struct program &program)
first_ac3 = program.audioStreams.size();
program.audioStreams.push_back(audio);
first_ac3 = program.audioStreams.size();
program.audioStreams.push_back(audio);
+ prev_audio = &program.audioStreams.back();
}
else
continue;
}
else
continue;
@@
-548,6
+563,7
@@
int eDVBServicePMTHandler::getProgramInfo(struct program &program)
audioStream s;
s.type = audioStream::atAC3;
s.pid = cached_apid_ac3;
audioStream s;
s.type = audioStream::atAC3;
s.pid = cached_apid_ac3;
+ s.rdsPid = -1;
program.audioStreams.push_back(s);
++cnt;
}
program.audioStreams.push_back(s);
++cnt;
}
@@
-556,6
+572,7
@@
int eDVBServicePMTHandler::getProgramInfo(struct program &program)
audioStream s;
s.type = audioStream::atMPEG;
s.pid = cached_apid_mpeg;
audioStream s;
s.type = audioStream::atMPEG;
s.pid = cached_apid_mpeg;
+ s.rdsPid = -1;
program.audioStreams.push_back(s);
++cnt;
}
program.audioStreams.push_back(s);
++cnt;
}
diff --git
a/lib/dvb/pmt.h
b/lib/dvb/pmt.h
index e27135e3c9968bd73cf1cb048485d1684bf034e6..a9ca23f246308b44d750fcaee304b7fa99d5dc2b 100644
(file)
--- a/
lib/dvb/pmt.h
+++ b/
lib/dvb/pmt.h
@@
-141,7
+141,8
@@
public:
struct audioStream
{
struct audioStream
{
- int pid;
+ int pid,
+ rdsPid; // hack for some radio services which transmit radiotext on different pid (i.e. harmony fm, HIT RADIO FFH, ...)
enum { atMPEG, atAC3, atDTS, atAAC, atAACHE, atLPCM };
int type; // mpeg2, ac3, dts, ...
enum { atMPEG, atAC3, atDTS, atAAC, atAACHE, atLPCM };
int type; // mpeg2, ac3, dts, ...
@@
-188,7
+189,6
@@
public:
int pmtPid;
int textPid;
bool isCrypted() { return !caids.empty(); }
int pmtPid;
int textPid;
bool isCrypted() { return !caids.empty(); }
-
PyObject *createPythonObject();
};
PyObject *createPythonObject();
};
diff --git
a/lib/dvb/radiotext.cpp
b/lib/dvb/radiotext.cpp
index 9f8cf5f0dee2aa2b343097c71daadbf7846f300e..e9bdd63a860052f0261cdca9897355fe392ce7ed 100644
(file)
--- a/
lib/dvb/radiotext.cpp
+++ b/
lib/dvb/radiotext.cpp
@@
-5,9
+5,9
@@
DEFINE_REF(eDVBRdsDecoder);
DEFINE_REF(eDVBRdsDecoder);
-eDVBRdsDecoder::eDVBRdsDecoder(iDVBDemux *demux)
+eDVBRdsDecoder::eDVBRdsDecoder(iDVBDemux *demux
, int type
)
:msgPtr(0), bsflag(0), qdar_pos(0), t_ptr(0), qdarmvi_show(0), state(0)
:msgPtr(0), bsflag(0), qdar_pos(0), t_ptr(0), qdarmvi_show(0), state(0)
- ,m_abortTimer(eTimer::create(eApp))
+ ,m_
type(type), m_pid(-1), m_
abortTimer(eTimer::create(eApp))
{
setStreamID(0xC0, 0xC0);
{
setStreamID(0xC0, 0xC0);
@@
-16,8
+16,10
@@
eDVBRdsDecoder::eDVBRdsDecoder(iDVBDemux *demux)
if (demux->createPESReader(eApp, m_pes_reader))
eDebug("failed to create PES reader!");
if (demux->createPESReader(eApp, m_pes_reader))
eDebug("failed to create PES reader!");
- else
+ else
if (type == 0)
m_pes_reader->connectRead(slot(*this, &eDVBRdsDecoder::processData), m_read_connection);
m_pes_reader->connectRead(slot(*this, &eDVBRdsDecoder::processData), m_read_connection);
+ else
+ m_pes_reader->connectRead(slot(*this, &eDVBRdsDecoder::gotAncillaryData), m_read_connection);
CONNECT(m_abortTimer->timeout, eDVBRdsDecoder::abortNonAvail);
}
CONNECT(m_abortTimer->timeout, eDVBRdsDecoder::abortNonAvail);
}
@@
-196,7
+198,7
@@
void eDVBRdsDecoder::processPESPacket(__u8 *data, int len)
m_abortTimer->stop();
int ancillary_len = 1 + data[offs - 1];
offs -= ancillary_len;
m_abortTimer->stop();
int ancillary_len = 1 + data[offs - 1];
offs -= ancillary_len;
- gotAncillaryData(data+offs, ancillary_len);
+ gotAncillaryData(data+offs, ancillary_len
-1
);
}
}
}
}
}
}
@@
-310,13
+312,19
@@
void eDVBRdsDecoder::process_qdar(unsigned char *buf)
}
}
}
}
-
inline void eDVBRdsDecoder::gotAncillaryData(
__u8 *buf, int len)
+
void eDVBRdsDecoder::gotAncillaryData(const
__u8 *buf, int len)
{
{
- int cnt=buf[--len];
- while ( cnt-- > 0 )
+ if (len <= 0)
+ return;
+ int pos = m_type ? 0 : len-1;
+ while ( len )
{
{
- unsigned char c = buf[--len];
-
+ unsigned char c = buf[pos];
+
+ pos += m_type ? 1 : -1;
+
+ --len;
+
if (bsflag == 1) // byte stuffing
{
bsflag=2;
if (bsflag == 1) // byte stuffing
{
bsflag=2;
@@
-638,8
+646,9
@@
std::string eDVBRdsDecoder::getRassPicture(int page, int subpage)
int eDVBRdsDecoder::start(int pid)
{
int ret = -1;
int eDVBRdsDecoder::start(int pid)
{
int ret = -1;
- if (m_pes_reader && !(ret = m_pes_reader->start(pid)))
+ if (m_pes_reader && !(ret = m_pes_reader->start(pid))
&& m_type == 0
)
m_abortTimer->startLongTimer(20);
m_abortTimer->startLongTimer(20);
+ m_pid = pid;
return ret;
}
return ret;
}
diff --git
a/lib/dvb/radiotext.h
b/lib/dvb/radiotext.h
index ace7b6ece88f4dca670ad8732ce07ebd2d52a184..7a73eea3371afd3d08f3ac7af34a74bb9450373f 100644
(file)
--- a/
lib/dvb/radiotext.h
+++ b/
lib/dvb/radiotext.h
@@
-18,9
+18,11
@@
class eDVBRdsDecoder: public iObject, public ePESParser, public Object
unsigned char rass_picture_mask[5]; // 40 bits... (10 * 4 pictures)
void addToPictureMask(int id);
void removeFromPictureMask(int id);
unsigned char rass_picture_mask[5]; // 40 bits... (10 * 4 pictures)
void addToPictureMask(int id);
void removeFromPictureMask(int id);
+ int m_type;
+ int m_pid;
public:
enum { RadioTextChanged, RtpTextChanged, RassInteractivePicMaskChanged, RecvRassSlidePic };
public:
enum { RadioTextChanged, RtpTextChanged, RassInteractivePicMaskChanged, RecvRassSlidePic };
- eDVBRdsDecoder(iDVBDemux *demux);
+ eDVBRdsDecoder(iDVBDemux *demux
, int type
);
~eDVBRdsDecoder();
int start(int pid);
void connectEvent(const Slot1<void, int> &slot, ePtr<eConnection> &connection);
~eDVBRdsDecoder();
int start(int pid);
void connectEvent(const Slot1<void, int> &slot, ePtr<eConnection> &connection);
@@
-29,10
+31,11
@@
public:
ePyObject getRassPictureMask();
std::string getRassPicture(int page, int subpage);
std::string getRassSlideshowPicture() { return "/tmp/RassLast.mvi"; }
ePyObject getRassPictureMask();
std::string getRassPicture(int page, int subpage);
std::string getRassSlideshowPicture() { return "/tmp/RassLast.mvi"; }
+ int getPid() { return m_pid; }
private:
void abortNonAvail();
void processPESPacket(__u8 *pkt, int len);
private:
void abortNonAvail();
void processPESPacket(__u8 *pkt, int len);
-
inline void gotAncillaryData(
__u8 *data, int len);
+
void gotAncillaryData(const
__u8 *data, int len);
void process_qdar(unsigned char*);
ePtr<iDVBPESReader> m_pes_reader;
ePtr<eConnection> m_read_connection;
void process_qdar(unsigned char*);
ePtr<iDVBPESReader> m_pes_reader;
ePtr<eConnection> m_read_connection;
diff --git
a/lib/service/servicedvb.cpp
b/lib/service/servicedvb.cpp
index a75c6cac6d51031a02642da9c423e1d9759f24b1..d04039dfba8ec3a7973fc6de60c1e08574012048 100644
(file)
--- a/
lib/service/servicedvb.cpp
+++ b/
lib/service/servicedvb.cpp
@@
-1758,21
+1758,26
@@
int eDVBServicePlay::selectAudioStream(int i)
return -4;
}
return -4;
}
+ int rdsPid = apid;
+
/* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
/* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
- if (!m_rds_decoder)
+ {
+ int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
+ if (different_pid)
+ rdsPid = program.audioStreams[stream].rdsPid;
+ if (!m_rds_decoder || m_rds_decoder->getPid() != rdsPid)
{
{
+ m_rds_decoder = 0;
ePtr<iDVBDemux> data_demux;
if (!h.getDataDemux(data_demux))
{
ePtr<iDVBDemux> data_demux;
if (!h.getDataDemux(data_demux))
{
- m_rds_decoder = new eDVBRdsDecoder(data_demux);
+ m_rds_decoder = new eDVBRdsDecoder(data_demux
, different_pid
);
m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
+ m_rds_decoder->start(rdsPid);
}
}
}
}
-
- /* if we decided that we need one, update the pid */
- if (m_rds_decoder)
- m_rds_decoder->start(apid);
+ }
/* store new pid as default only when:
a.) we have an entry in the service db for the current service,
/* store new pid as default only when:
a.) we have an entry in the service db for the current service,