1 #include <lib/base/eerror.h>
2 #include <lib/dvb/radiotext.h>
3 #include <lib/dvb/idemux.h>
4 #include <lib/gdi/gpixmap.h>
6 DEFINE_REF(eDVBRdsDecoder);
8 eDVBRdsDecoder::eDVBRdsDecoder(iDVBDemux *demux, int type)
9 :msgPtr(0), bsflag(0), qdar_pos(0), t_ptr(0), qdarmvi_show(0), state(0)
10 ,m_type(type), m_pid(-1), m_abortTimer(eTimer::create(eApp))
12 setStreamID(0xC0, 0xC0);
14 memset(rass_picture_mask, 0, sizeof(rass_picture_mask));
15 memset(rtp_item, 0, sizeof(rtp_item));
17 if (demux->createPESReader(eApp, m_pes_reader))
18 eDebug("failed to create PES reader!");
20 m_pes_reader->connectRead(slot(*this, &eDVBRdsDecoder::processData), m_read_connection);
22 m_pes_reader->connectRead(slot(*this, &eDVBRdsDecoder::gotAncillaryData), m_read_connection);
23 CONNECT(m_abortTimer->timeout, eDVBRdsDecoder::abortNonAvail);
26 eDVBRdsDecoder::~eDVBRdsDecoder()
28 // delete cached rass slides
29 for (int page=0; page < 10; ++page)
31 unsigned char mask = rass_picture_mask[(page*4)/8];
39 std::string filename = getRassPicture(page, subpage);
40 if (filename.length())
41 remove(filename.c_str());
47 remove("/tmp/RassLast.mvi");
50 #define SWAP(x) ((x<<8)|(x>>8))
51 #define LO(x) (x&0xFF)
53 static inline unsigned short crc_ccitt_byte( unsigned short crc, unsigned char c )
56 crc = crc ^ (LO(crc) >> 4);
57 crc = crc ^ (SWAP(LO(crc)) << 4) ^ (LO(crc) << 5);
61 static int bitrate[3][3][16] = {
64 {-1,8000,16000,24000,32000,40000,48000,56000,64000,80000,96000,112000,128000,144000,160000,0},
66 {-1,8000,16000,24000,32000,40000,48000,56000,64000,80000,96000,112000,128000,144000,160000,0},
68 {-1,32000,48000,56000,64000,80000,96000,112000,128000,144000,160000,176000,192000,224000,256000,0}
72 {-1,32000,40000,48000,56000,64000,80000,96000,112000,128000,160000,192000,224000,256000,320000,0},
74 {-1,32000,48000,56000,64000,80000,96000,112000,128000,160000,192000,224000,256000,320000,384000,0},
76 {-1,32000,64000,96000,128000,160000,192000,224000,256000,288000,320000,352000,384000,416000,448000,0}
80 {-1,6000,8000,10000,12000,16000,20000,24000,28000,320000,40000,48000,56000,64000,80000,0},
82 {-1,6000,8000,10000,12000,16000,20000,24000,28000,320000,40000,48000,56000,64000,80000,0},
84 {-1,8000,12000,16000,20000,24000,32000,40000,48000,560000,64000,80000,96000,112000,128000,0}
88 static int frequency[3][4] = {
89 // MPEG2 - 22.05, 24, 16khz
90 { 22050,24000,16000,0 },
91 // MPEG1 - 44.1, 48, 32khz
92 { 44100,48000,32000,0 },
93 // MPEG2.5 - 11.025, 12, 8khz
94 { 11025,12000,8000,0 }
97 void eDVBRdsDecoder::connectEvent(const Slot1<void, int> &slot, ePtr<eConnection> &connection)
99 connection = new eConnection(this, m_event.connect(slot));
102 void eDVBRdsDecoder::addToPictureMask(int id)
104 int page = id / 1000;
105 int tmp = page > 0 ? id / page : id;
113 int index = (page*4+subpage)/8;
114 int val = (page%2) ? 16 * (1 << subpage) : (1 << subpage);
115 if (rass_picture_mask[index] & val) // already have this picture
117 rass_picture_mask[index] |= val;
118 /* emit */ m_event(RassInteractivePicMaskChanged);
121 void eDVBRdsDecoder::removeFromPictureMask(int id)
123 int page = id / 1000;
124 int tmp = page > 0 ? id / page : id;
132 int index = (page*4)/8;
133 int val = (page%2) ? 16 * (1 << subpage) : (1 << subpage);
134 if (rass_picture_mask[index] & val) // have this picture
136 rass_picture_mask[index] &= ~val;
137 /* emit */ m_event(RassInteractivePicMaskChanged);
141 void eDVBRdsDecoder::processPESPacket(__u8 *data, int len)
143 int pos=9+data[8];// skip pes header
147 if ((0xFF & data[pos]) != 0xFF || (0xF0 & data[pos + 1]) != 0xF0)
150 int padding_bit = (data[pos + 2]>>1) & 1;
151 int mode = (data[pos + 3]>>6) & 3;
152 int channel = mode == 3 ? 1 : 2;
153 int id = (data[pos + 1] >> 3) & 1;
154 int emphasis_bit = data[pos + 3] & 3;
155 //int protection_bit = data[pos + 1] & 1;
157 int sample_freq = -1;
160 if (emphasis_bit == 2 && id == 1 )
163 if ((layer = (data[pos + 1]>>1) & 3) < 1)
166 if ((rate = bitrate[id][layer - 1][(data[pos + 2]>>4) & 0xf]) < 1)
169 if ((sample_freq = frequency[id][(data[pos + 2]>>2) & 3]) == 0)
172 if (id == 1 && layer == 2)
174 if (rate / channel < 32000)
176 if (rate / channel > 192000)
180 int frame_size = layer < 3 ?
181 (144 * rate / sample_freq) + padding_bit :
182 ((12 * rate / sample_freq) * 4) + (4 * padding_bit);
187 // eDebug("protection_bit ? %d", protection_bit);
188 // int offs = protection_bit ? pos - 1 : pos - 3;
189 // if (data[offs] != 0xFD)
191 // eDebug("%02x %02x %02x %02x %02x", data[offs-2], data[offs-1], data[offs], data[offs+1], data[offs+2]);
196 if (data[offs] == 0xFD)
198 m_abortTimer->stop();
199 int ancillary_len = 1 + data[offs - 1];
200 offs -= ancillary_len;
201 gotAncillaryData(data+offs, ancillary_len-1);
206 void eDVBRdsDecoder::process_qdar(unsigned char *buf)
208 if (buf[0] == 0x40 && buf[1] == 0xDA)
210 unsigned int item,cnt,ctrl,item_type;
211 unsigned long item_length,id,item_no,ptr,tmp;
212 unsigned short crc_qdar,crc_read;
215 item=buf[2]<<8; // Number of Items
218 while ( cnt++ < item ) //read in items
220 id=buf[ptr++]<<8; //QDarID
223 item_no=buf[ptr++]<<8; // Item Number
226 ctrl=buf[ptr++]; //controlbyte
227 item_type=buf[ptr++]; //item type
229 item_length=buf[ptr++]<<24; // Item length
230 item_length|=buf[ptr++]<<16;
231 item_length|=buf[ptr++]<<8;
232 item_length|=buf[ptr++];
234 ptr=ptr+4; // rfu Bytes ... not used
237 while (tmp < ptr+item_length)
238 crc_qdar = crc_ccitt_byte(crc_qdar, buf[tmp++]);
240 crc_read=buf[ptr+item_length]<<8;
241 crc_read|=buf[ptr+item_length+1];
242 //eDebug("[RDS/Rass] CRC read: %04X calculated: %04X",crc_read,crc_qdar^0xFFFF);
244 if (crc_read == (crc_qdar^0xFFFF)) // process item
248 case 0x01: //Stillframe
249 if (ctrl&0x01) // display slide
251 sprintf(fname,"/tmp/RassLast.mvi");
252 FILE *fh=fopen(fname,"wb");
253 fwrite(buf+ptr,1,item_length-2,fh);
255 /*emit*/ m_event(RecvRassSlidePic);
258 if (ctrl&0x02) // save slide for interactive mode
260 if (id == 0 || id >= 1000)
262 sprintf(fname,"/tmp/Rass%04d.mvi",(int)id);
263 FILE *fh=fopen(fname,"wb");
264 fwrite(buf+ptr,1,item_length-2,fh);
266 addToPictureMask(id);
269 eDebug("ignore recv interactive picture id %lu", id);
271 if (ctrl&0x04) // display slide if nothing had been displayed yet
273 if (qdarmvi_show != 1)
275 sprintf(fname,"/tmp/RassLast.mvi");
276 FILE *fh=fopen(fname,"wb");
277 fwrite(buf+ptr,1,item_length-2,fh);
279 /*emit*/ m_event(RecvRassSlidePic);
283 if (ctrl&0x08) // delete slide
285 eDebug("delete slide id %lu, item_no %lu", id, item_no);
286 if (id == 0 || id >= 1000)
288 eDebug("delete %lu", id);
289 removeFromPictureMask(id);
290 sprintf(fname,"/tmp/Rass%04d.mvi",(int)id); // was item_no ? ! ?
294 eDebug("ignore del interactive picture id %lu", id);
297 default: //nothing more yet defined
303 eDebug("[RDS/Rass] CRC error, skip Rass-Qdar-Item");
311 eDebug("[RDS/Rass] No Rass-QDAR archive (%02X %02X) so skipping !\n",buf[0],buf[1]);
315 void eDVBRdsDecoder::gotAncillaryData(const __u8 *buf, int len)
319 int pos = m_type ? 0 : len-1;
322 unsigned char c = buf[pos];
324 pos += m_type ? 1 : -1;
328 if (bsflag == 1) // byte stuffing
333 case 0x00: c=0xFD; break;
334 case 0x01: c=0xFE; break;
335 case 0x02: c=0xFF; break;
339 if (c == 0xFD && bsflag ==0)
348 if (( state >= 1 && state < 11 ) || ( state >=26 && state < 36 ))
349 crc = crc_ccitt_byte(crc, c);
354 if ( c==0xFE ) // Startkennung
357 case 1: // 10bit Site Address + 6bit Encoder Address
359 case 3: // Sequence Counter
369 case 0x0A: // Radiotext
372 case 0x46: // Radiotext Plus tags
378 default: // reset to state 0
384 case 6: // Data Set Number ... ignore
385 case 7: // Program Service Number ... ignore
388 case 8: // Message Element Length
390 if ( !text_len || text_len > 65 || text_len > leninfo-4)
399 case 9: // Radio Text Status bit:
400 // 0 = AB-flagcontrol
401 // 1-4 = Transmission-Number
402 // 5-6 = Buffer-Config
403 ++state; // ignore ...
406 // TODO build a complete radiotext charcode to UTF8 conversion table for all character > 0x80
409 case 0 ... 0x7f: break;
410 case 0x8d: c='ß'; break;
411 case 0x91: c='ä'; break;
412 case 0xd1: c='Ä'; break;
413 case 0x97: c='ö'; break;
414 case 0xd7: c='Ö'; break;
415 case 0x99: c='ü'; break;
416 case 0xd9: c='Ü'; break;
417 default: c=' '; break; // convert all unknown to space
432 while(message[msgPtr] == ' ' && msgPtr > 0)
433 message[msgPtr--] = 0;
434 if ( crc16 == (crc^0xFFFF) )
436 eDebug("radiotext: (%s)", message);
437 /*emit*/ m_event(RadioTextChanged);
438 memcpy(lastmessage,message,66);
441 eDebug("invalid radiotext crc (%s)", message);
454 case 27: // SID not used atm
457 case 28: // SID not used atm
460 case 29: // PNR packet number
464 case 30: // PNR packet number
468 case 31: // PNR packet number
472 case 32: // NOP number of packets
476 case 33: // NOP number of packets
480 case 34: // NOP number of packets
485 datamessage[t_ptr++]=c;
497 //eDebug("[RDS/Rass] CRC read: %04X CRC calculated: %04X",crc16,crc^0xFFFF);
499 if ( crc16 == (crc^0xFFFF) )
505 memcpy(qdar+qdar_pos,datamessage,text_len2+1);
506 qdar_pos=qdar_pos+text_len2+1;
507 if (partcnt == parts)
509 process_qdar(qdar); // decode qdar archive
524 eDebug("[RDS/Rass] CRC error, skip Rass-Qdar-Packet");
525 eDebug("[RDS/Rass] CRC read: %04X CRC calculated: %04X",crc16,crc^0xFFFF);
531 // process RT plus tags ...
532 case 38: // Message Element Length
536 case 39: // Application ID
537 case 40: // always 0x4BD7 so we ignore it ;)
538 case 41: // Applicationgroup Typecode/PTY ... ignore
557 case 46: // bit 10#4 = Item Togglebit
558 // bit 10#3 = Item Runningbit
559 // Tag1: bit 10#2..11#5 = Contenttype, 11#4..12#7 = Startmarker, 12#6..12#1 = Length
561 if (lastmessage[0] == 0) // no rds message till now ? quit ...
563 int rtp_typ[2],rtp_start[2],rtp_len[2];
564 rtp_typ[0] = (0x38 & rtp_buf[0]<<3) | rtp_buf[1]>>5;
565 rtp_start[0] = (0x3e & rtp_buf[1]<<1) | rtp_buf[2]>>7;
566 rtp_len[0] = 0x3f & rtp_buf[2]>>1;
567 // Tag2: bit 12#0..13#3 = Contenttype, 13#2..14#5 = Startmarker, 14#4..14#0 = Length(5bit)
568 rtp_typ[1] = (0x20 & rtp_buf[2]<<5) | rtp_buf[3]>>3;
569 rtp_start[1] = (0x38 & rtp_buf[3]<<3) | rtp_buf[4]>>5;
570 rtp_len[1] = 0x1f & rtp_buf[4];
572 unsigned char rtplus_osd_tmp[64];
574 if (rtp_start[0] < 66 && (rtp_len[0]+rtp_start[0]) < 66)
576 memcpy(rtp_item[rtp_typ[0]],lastmessage+rtp_start[0],rtp_len[0]+1);
577 rtp_item[rtp_typ[0]][rtp_len[0]+1]=0;
580 if (rtp_typ[0] != rtp_typ[1])
582 if (rtp_start[1] < 66 && (rtp_len[1]+rtp_start[1]) < 66)
584 memcpy(rtp_item[rtp_typ[1]],lastmessage+rtp_start[1],rtp_len[1]+1);
585 rtp_item[rtp_typ[1]][rtp_len[1]+1]=0;
589 // main RTPlus item_types used by the radio stations:
598 // todo: make a window to display all saved items ...
600 //create RTPlus OSD for title/artist
603 if ( rtp_item[4][0] != 0 )//artist
604 sprintf((char*)rtplus_osd_tmp," (%s)",rtp_item[4]);
606 if ( rtp_item[1][0] != 0 )//title
607 sprintf((char*)rtplus_osd,"%s%s",rtp_item[1],rtplus_osd_tmp);
609 if ( rtplus_osd[0] != 0 )
611 /*emit*/ m_event(RtpTextChanged);
612 eDebug("RTPlus: %s",rtplus_osd);
622 std::string eDVBRdsDecoder::getRassPicture(int page, int subpage)
642 sprintf(fname,"/tmp/Rass%04d.mvi",val);
646 int eDVBRdsDecoder::start(int pid)
649 if (m_pes_reader && !(ret = m_pes_reader->start(pid)) && m_type == 0)
650 m_abortTimer->startLongTimer(20);
655 void eDVBRdsDecoder::abortNonAvail()
657 eDebug("no ancillary data in audio stream... abort radiotext pes parser");
659 m_pes_reader->stop();
662 ePyObject eDVBRdsDecoder::getRassPictureMask()
664 ePyObject ret = PyTuple_New(5);
665 PyTuple_SET_ITEM(ret, 0, PyInt_FromLong(rass_picture_mask[0]));
666 PyTuple_SET_ITEM(ret, 1, PyInt_FromLong(rass_picture_mask[1]));
667 PyTuple_SET_ITEM(ret, 2, PyInt_FromLong(rass_picture_mask[2]));
668 PyTuple_SET_ITEM(ret, 3, PyInt_FromLong(rass_picture_mask[3]));
669 PyTuple_SET_ITEM(ret, 4, PyInt_FromLong(rass_picture_mask[4]));