add a radiomode background picture (mvi file.. changable in
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Sat, 24 Mar 2007 00:49:20 +0000 (00:49 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Sat, 24 Mar 2007 00:49:20 +0000 (00:49 +0000)
/etc/enigma2/config ... config.misc.radiopic = /bla/blubber.mvi
add support for radio text plus,
add rass (radio screen show) support (yes used by SWR3, cont.ra and DASDING)
thanks to seddi for some piece of code
for better single iframe support its recommend to update in
dreambox-dvb-modules.bb CVSDATE for dm7025 to 20070323

26 files changed:
data/Makefile.am
data/keymap.xml
data/radio.mvi [new file with mode: 0755]
data/rass_logo.png [moved from lib/python/Components/Converter/RadioText.py with 100% similarity]
data/rass_page1.png [moved from lib/python/Components/Sources/RadioText.py with 100% similarity]
data/rass_page2.png [new file with mode: 0644]
data/rass_page3.png [new file with mode: 0644]
data/rass_page4.png [new file with mode: 0644]
data/skin.xml
data/skin_default.xml
lib/dvb/radiotext.cpp
lib/dvb/radiotext.h
lib/python/Components/Converter/Makefile.am
lib/python/Components/Converter/RdsInfo.py [new file with mode: 0644]
lib/python/Components/Sources/Makefile.am
lib/python/Components/Sources/RdsDecoder.py [new file with mode: 0644]
lib/python/Screens/ChannelSelection.py
lib/python/Screens/InfoBar.py
lib/python/Screens/InfoBarGenerics.py
lib/python/Screens/Makefile.am
lib/python/Screens/RdsDisplay.py [new file with mode: 0644]
lib/service/iservice.h
lib/service/servicedvb.cpp
lib/service/servicedvb.h
lib/service/servicemp3.h
lib/service/servicexine.h

index c866eacd7392f327c5d9e2678bbaf2c5ad820889..ed26ec5c429a12a7d552b75e883c57702ea4ea7b 100644 (file)
@@ -5,4 +5,4 @@ SUBDIRS = countries fonts defaults extensions
 installdir = $(DATADIR)/enigma2
 
 install_DATA = \
 installdir = $(DATADIR)/enigma2
 
 install_DATA = \
-       *.xml *.png encoding.conf
+       *.xml *.png encoding.conf radio.mvi
index 835c52183c5164816656878a41c44c3e5f51ab83..5c0cb54b9755a9b1a9d73b4707e3c21bb3dbdfe9 100644 (file)
                <key id="KEY_TEXT" mapto="startTeletext" flags="m" />
        </map>
 
                <key id="KEY_TEXT" mapto="startTeletext" flags="m" />
        </map>
 
+       <map context="InfobarRdsActions">
+               <key id="KEY_TEXT" mapto="startRassInteractive" flags="m" />
+       </map>
+
+       <map context="RassInteractiveActions">
+               <key id="KEY_LEFT" mapto="prevSubPage" flags="mr" />
+               <key id="KEY_RIGHT" mapto="nextSubPage" flags="mr" />
+               <key id="KEY_UP" mapto="prevPage" flags="mr" />
+               <key id="KEY_DOWN" mapto="nextPage" flags="mr" />
+               <key id="KEY_EXIT" mapto="exit" flags="m" />
+       </map>
+
        <map context="ChannelSelectBaseActions">
                <key id="KEY_RED" mapto="showAllServices" flags="m" />
                <key id="KEY_GREEN" mapto="showSatellites" flags="m" />
        <map context="ChannelSelectBaseActions">
                <key id="KEY_RED" mapto="showAllServices" flags="m" />
                <key id="KEY_GREEN" mapto="showSatellites" flags="m" />
diff --git a/data/radio.mvi b/data/radio.mvi
new file mode 100755 (executable)
index 0000000..bbd8016
Binary files /dev/null and b/data/radio.mvi differ
diff --git a/data/rass_page2.png b/data/rass_page2.png
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/data/rass_page3.png b/data/rass_page3.png
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/data/rass_page4.png b/data/rass_page4.png
new file mode 100644 (file)
index 0000000..e69de29
index 36f732558d9c681690a027b917fd869f0c083796..cf2d2c7336d9a062399398f85d18c9650c3836df 100644 (file)
                <font filename="ae_AlMateen.ttf" name="Replacement" scale="90" replacement="1" />
        </fonts>
 
                <font filename="ae_AlMateen.ttf" name="Replacement" scale="90" replacement="1" />
        </fonts>
 
-               <screen name="InfoBar" flags="wfNoBorder" position="0,330" size="720,198" title="InfoBar" backgroundColor="transparent" >
-                       
-                       <widget source="RadioText" render="Label" position="50,0" size="620,50" font="LCD;25" backgroundColor="transparent">
-                               <convert type="RadioText">RadioText</convert>
-                       </widget>
-
-                       <ePixmap position="0,50" zPosition="-1" size="720,148" pixmap="info-bg.png" />
+               <screen name="InfoBar" flags="wfNoBorder" position="0,380" size="720,148" title="InfoBar" backgroundColor="transparent" >
+                       <ePixmap position="0,0" zPosition="-1" size="720,148" pixmap="info-bg.png" />
 <!-- not used in this skin yet -->                     
 <!-- not used in this skin yet -->                     
-                       <widget name="NimA" position="0,50" size="0,0" />
-                       <widget name="NimB" position="0,50" size="0,0" />
-                       <widget name="NimA_Active" position="0,50" size="0,0" />
-                       <widget name="NimB_Active" position="0,50" size="0,0" />
+                       <widget name="NimA" position="0,0" size="0,0" />
+                       <widget name="NimB" position="0,0" size="0,0" />
+                       <widget name="NimA_Active" position="0,0" size="0,0" />
+                       <widget name="NimB_Active" position="0,0" size="0,0" />
 
 <!--                   'teletext available'
                        <widget source="CurrentService" render="Pixmap" pixmap="format.png" position="613,40" size="28,15">
 
 <!--                   'teletext available'
                        <widget source="CurrentService" render="Pixmap" pixmap="format.png" position="613,40" size="28,15">
 -->
 
 <!-- ............................................................................. -->
 -->
 
 <!-- ............................................................................. -->
-                       <eLabel text="SNR:" position="195,50" size="40,22" font="Regular;15" transparent="1" />
-                       <eLabel text="AGC:" position="275,50" size="40,22" font="Regular;15" transparent="1" />
-                       <eLabel text="BER:" position="355,50" size="40,22" font="Regular;15" transparent="1" />
+                       <eLabel text="SNR:" position="195,0" size="40,22" font="Regular;15" transparent="1" />
+                       <eLabel text="AGC:" position="275,0" size="40,22" font="Regular;15" transparent="1" />
+                       <eLabel text="BER:" position="355,0" size="40,22" font="Regular;15" transparent="1" />
                        
                        
-                       <widget source="FrontendStatus" render="Label" position="232,50" size="40,22" font="Regular;15" transparent="1" >
+                       <widget source="FrontendStatus" render="Label" position="232,0" size="40,22" font="Regular;15" transparent="1" >
                                <convert type="FrontendInfo">SNR</convert>
                        </widget>
                                <convert type="FrontendInfo">SNR</convert>
                        </widget>
-                       <widget source="FrontendStatus" render="Label" position="314,50" size="40,22" font="Regular;15" transparent="1" >
+                       <widget source="FrontendStatus" render="Label" position="314,0" size="40,22" font="Regular;15" transparent="1" >
                                <convert type="FrontendInfo">AGC</convert>
                        </widget>
                                <convert type="FrontendInfo">AGC</convert>
                        </widget>
-                       <widget source="FrontendStatus" render="Label" position="392,50" size="53,22" font="Regular;15" transparent="1" >
+                       <widget source="FrontendStatus" render="Label" position="392,0" size="53,22" font="Regular;15" transparent="1" >
                                <convert type="FrontendInfo">BER</convert>
                        </widget>
                        
                                <convert type="FrontendInfo">BER</convert>
                        </widget>
                        
-                       <widget source="FrontendStatus" render="Progress" position="447,51" size="88,6" pixmap="rtgbar.png" >
+                       <widget source="FrontendStatus" render="Progress" position="447,1" size="88,6" pixmap="rtgbar.png" >
                                <convert type="FrontendInfo">SNR</convert>
                        </widget>
                                <convert type="FrontendInfo">SNR</convert>
                        </widget>
-                       <widget source="FrontendStatus" render="Progress" position="447,58" size="88,6" pixmap="rtgbar.png" >
+                       <widget source="FrontendStatus" render="Progress" position="447,8" size="88,6" pixmap="rtgbar.png" >
                                <convert type="FrontendInfo">AGC</convert>
                        </widget> 
                                <convert type="FrontendInfo">AGC</convert>
                        </widget> 
-                       <widget source="FrontendStatus" render="Progress" position="447,65" size="88,6" >
+                       <widget source="FrontendStatus" render="Progress" position="447,15" size="88,6" >
                                <convert type="FrontendInfo">BER</convert>
                        </widget>
 
                                <convert type="FrontendInfo">BER</convert>
                        </widget>
 
-                       <widget name="BlinkingPoint" pixmap="record.png" position="430,81" zPosition="2" size="58,25" alphatest="on" />
+                       <widget name="BlinkingPoint" pixmap="record.png" position="430,31" zPosition="2" size="58,25" alphatest="on" />
                        
                                <!-- show 'is crypted' icon when service is crypted. -->
                        
                                <!-- show 'is crypted' icon when service is crypted. -->
-                       <widget source="CurrentService" render="Pixmap" pixmap="crypt.png" position="570,90" size="12,15" >
+                       <widget source="CurrentService" render="Pixmap" pixmap="crypt.png" position="570,40" size="12,15" >
                                <convert type="ServiceInfo">IsCrypted</convert>
                                <convert type="ConditionalShowHide" />
                        </widget>
                        
                                <!-- show 'multichannel' icon when service has multichannel 
                                     audio. -->
                                <convert type="ServiceInfo">IsCrypted</convert>
                                <convert type="ConditionalShowHide" />
                        </widget>
                        
                                <!-- show 'multichannel' icon when service has multichannel 
                                     audio. -->
-                       <widget source="CurrentService" render="Pixmap" pixmap="dolby.png" position="585,90" size="25,15">
+                       <widget source="CurrentService" render="Pixmap" pixmap="dolby.png" position="585,40" size="25,15">
                                <convert type="ServiceInfo">IsMultichannel</convert>
                                <convert type="ConditionalShowHide" />
                        </widget>
                        
                                <convert type="ServiceInfo">IsMultichannel</convert>
                                <convert type="ConditionalShowHide" />
                        </widget>
                        
-                       <widget source="CurrentService" render="Pixmap" pixmap="format.png" position="613,90" size="28,15">
+                       <widget source="CurrentService" render="Pixmap" pixmap="format.png" position="613,40" size="28,15">
                                <convert type="ServiceInfo">IsWidescreen</convert>
                                <convert type="ConditionalShowHide" />
                        </widget>
 
                                <convert type="ServiceInfo">IsWidescreen</convert>
                                <convert type="ConditionalShowHide" />
                        </widget>
 
-                       <widget source="CurrentService" render="Label" position="69,76" size="427,34" font="Regular;22" backgroundColor="#101258" >
+                       <widget source="CurrentService" render="Label" position="69,26" size="427,34" font="Regular;22" backgroundColor="#101258" >
                                <convert type="ServiceName">Name</convert>
                                <!-- <convert type="ServiceName">Provider</convert> -->
                        </widget>
                        
                                <convert type="ServiceName">Name</convert>
                                <!-- <convert type="ServiceName">Provider</convert> -->
                        </widget>
                        
-                       <widget source="CurrentTime" render="Label" position="575,60" size="90,30" backgroundColor="dark" font="Regular;19" >
+                       <widget source="CurrentTime" render="Label" position="575,10" size="90,30" backgroundColor="dark" font="Regular;19" >
                                <convert type="ClockToText">WithSeconds</convert>
                        </widget>
                        
                                <convert type="ClockToText">WithSeconds</convert>
                        </widget>
                        
-                       <widget source="Event_Now" render="Label" position="210,118" size="60,22" font="Regular;20" backgroundColor="dark">
+                       <widget source="Event_Now" render="Label" position="210,68" size="60,22" font="Regular;20" backgroundColor="dark">
                                <convert type="EventTime">StartTime</convert>
                                <convert type="ClockToText">Default</convert>
                        </widget>
                                <convert type="EventTime">StartTime</convert>
                                <convert type="ClockToText">Default</convert>
                        </widget>
-                       <widget source="Event_Next" render="Label" position="210,148" size="60,22" font="Regular;20" backgroundColor="dark">
+                       <widget source="Event_Next" render="Label" position="210,98" size="60,22" font="Regular;20" backgroundColor="dark">
                                <convert type="EventTime">StartTime</convert>
                                <convert type="ClockToText">Default</convert>
                        </widget>
                                <convert type="EventTime">StartTime</convert>
                                <convert type="ClockToText">Default</convert>
                        </widget>
-                       <widget source="Event_Now" render="Label" position="273,118" size="282,22" font="Regular;20" backgroundColor="dark">
+                       <widget source="Event_Now" render="Label" position="273,68" size="282,22" font="Regular;20" backgroundColor="dark">
                                <convert type="EventName">Name</convert>
                        </widget>
                                <convert type="EventName">Name</convert>
                        </widget>
-                       <widget source="Event_Next" render="Label" position="273,148" size="282,22" font="Regular;20" backgroundColor="dark">
+                       <widget source="Event_Next" render="Label" position="273,98" size="282,22" font="Regular;20" backgroundColor="dark">
                                <convert type="EventName">Name</convert>
                        </widget>
                                <convert type="EventName">Name</convert>
                        </widget>
-                       <widget source="Event_Now" render="Label" position="555,118" size="100,26" font="Regular;22" backgroundColor="dark" halign="right">
+                       <widget source="Event_Now" render="Label" position="555,68" size="100,26" font="Regular;22" backgroundColor="dark" halign="right">
                                <convert type="EventTime">Remaining</convert>
                                <convert type="RemainingToText">InMinutes</convert>
                        </widget>
                                <convert type="EventTime">Remaining</convert>
                                <convert type="RemainingToText">InMinutes</convert>
                        </widget>
-                       <widget source="Event_Next" render="Label" position="555,148" size="100,26" font="Regular;22" backgroundColor="dark" halign="right">
+                       <widget source="Event_Next" render="Label" position="555,98" size="100,26" font="Regular;22" backgroundColor="dark" halign="right">
                                <convert type="EventTime">Duration</convert>
                                <convert type="ClockToText">InMinutes</convert>
                        </widget>
                                <convert type="EventTime">Duration</convert>
                                <convert type="ClockToText">InMinutes</convert>
                        </widget>
-                       <widget source="Event_Now" render="Progress" position="304,110" size="121,8" zPosition="1">
+                       <widget source="Event_Now" render="Progress" position="304,60" size="121,8" zPosition="1">
                                <convert type="EventTime">Progress</convert>
                        </widget>
 
                                <!-- red button: is recording possible? -->
                                <convert type="EventTime">Progress</convert>
                        </widget>
 
                                <!-- red button: is recording possible? -->
-                       <widget source="RecordingPossible" render="Pixmap" pixmap="button_red.png" position="210,182" size="27,12" >
+                       <widget source="RecordingPossible" render="Pixmap" pixmap="button_red.png" position="210,132" size="27,12" >
                                <convert type="ConditionalShowHide" />
                        </widget>
                        
                                <convert type="ConditionalShowHide" />
                        </widget>
                        
-                       <widget source="RecordingPossible" render="FixedLabel" text="Record" position="240,180" size="85,22" font="Regular;14" backgroundColor="blue" transparent="1">
+                       <widget source="RecordingPossible" render="FixedLabel" text="Record" position="240,130" size="85,22" font="Regular;14" backgroundColor="blue" transparent="1">
                                <convert type="ConditionalShowHide" />
                        </widget>
                        
                                <convert type="ConditionalShowHide" />
                        </widget>
                        
-                       <widget source="CurrentService" render="Pixmap" pixmap="button_green.png" position="320,182" size="27,12" >
+                       <widget source="CurrentService" render="Pixmap" pixmap="button_green.png" position="320,132" size="27,12" >
                                <convert type="ServiceInfo">SubservicesAvailable</convert>
                                <convert type="ConditionalShowHide" />
                        </widget>
                                <convert type="ServiceInfo">SubservicesAvailable</convert>
                                <convert type="ConditionalShowHide" />
                        </widget>
-                       <widget source="CurrentService" render="FixedLabel" text="Subservices" position="350,180" size="85,22" font="Regular;14" backgroundColor="blue" transparent="1" >
+                       <widget source="CurrentService" render="FixedLabel" text="Subservices" position="350,130" size="85,22" font="Regular;14" backgroundColor="blue" transparent="1" >
                                <convert type="ServiceInfo">SubservicesAvailable</convert> 
                                <convert type="ConditionalShowHide" />
                        </widget>
                        
                                <convert type="ServiceInfo">SubservicesAvailable</convert> 
                                <convert type="ConditionalShowHide" />
                        </widget>
                        
-                       <widget source="TimeshiftPossible" render="Pixmap" pixmap="button_yellow.png" position="430,182" size="27,12" >
+                       <widget source="TimeshiftPossible" render="Pixmap" pixmap="button_yellow.png" position="430,132" size="27,12" >
                                <convert type="ConditionalShowHide" />
                        </widget>
                                <convert type="ConditionalShowHide" />
                        </widget>
-                       <widget source="TimeshiftPossible" render="FixedLabel" text="Timeshift" position="460,180" size="85,22" font="Regular;14" backgroundColor="blue" transparent="1" >
+                       <widget source="TimeshiftPossible" render="FixedLabel" text="Timeshift" position="460,130" size="85,22" font="Regular;14" backgroundColor="blue" transparent="1" >
                                <convert type="ConditionalShowHide" />
                        </widget>
                                <convert type="ConditionalShowHide" />
                        </widget>
-                       <widget source="ExtensionsAvailable" render="Pixmap" pixmap="button_blue.png" position="540,182" size="27,12" >
+                       <widget source="ExtensionsAvailable" render="Pixmap" pixmap="button_blue.png" position="540,132" size="27,12" >
                                <convert type="ConditionalShowHide" />
                        </widget>
                                <convert type="ConditionalShowHide" />
                        </widget>
-                       <widget source="ExtensionsAvailable" render="FixedLabel" text="Extensions" position="570,180" size="95,22" font="Regular;14" backgroundColor="blue" transparent="1" >
+                       <widget source="ExtensionsAvailable" render="FixedLabel" text="Extensions" position="570,130" size="95,22" font="Regular;14" backgroundColor="blue" transparent="1" >
                                <convert type="ConditionalShowHide" />
                        </widget>
                </screen>
                                <convert type="ConditionalShowHide" />
                        </widget>
                </screen>
index 4bdc5c160f055f7a9763b88e6e46b8c164692b50..65e810d97e633b24b4340eaf0cf8fcde5bc1dc04 100644 (file)
@@ -3,8 +3,7 @@
                <font filename="lcd.ttf" name="LCD" scale="100" />
        </fonts>
 
                <font filename="lcd.ttf" name="LCD" scale="100" />
        </fonts>
 
-       <screen name="Standby" flags="wfNoBorder" position="0,0" size="720,576" title="Standby">
-       </screen>
+       <screen name="Standby" flags="wfNoBorder" position="0,0" size="720,576" title="Standby" />
        <screen name="Menu" position="210,150" size="300,285" title="Main menu">
                <widget name="title" position="10,10" size="280,35" font="Regular;23" />
                <!--<widget name="menu" position="10,55" size="280,150" font="Regular;23" />-->
        <screen name="Menu" position="210,150" size="300,285" title="Main menu">
                <widget name="title" position="10,10" size="280,35" font="Regular;23" />
                <!--<widget name="menu" position="10,55" size="280,150" font="Regular;23" />-->
@@ -18,8 +17,7 @@
        <screen name="ChannelContextMenu" position="210,150" size="300,250" title="Channellist menu">
                <widget name="menu" position="10,10" size="300,230" scrollbarMode="showOnDemand" />
        </screen>
        <screen name="ChannelContextMenu" position="210,150" size="300,250" title="Channellist menu">
                <widget name="menu" position="10,10" size="300,230" scrollbarMode="showOnDemand" />
        </screen>
-       <screen name="Scart" position="0,0" size="720,576">
-       </screen>
+       <screen name="Scart" position="0,0" size="720,576" />
        <screen name="MediaPlayer" position="104,83" size="512,442" title="MediaPlayer">
                <eLabel position="11,9" zPosition="1" size="359,78" backgroundColor="#182C40" />
                <widget name="artisttext" position="13,11" zPosition="3" size="65,17" font="Regular;16" valign="top" foregroundColor="#cccccc" backgroundColor="#33294a6b" shadowColor="#000000" shadowOffset="-2,-2"/>
        <screen name="MediaPlayer" position="104,83" size="512,442" title="MediaPlayer">
                <eLabel position="11,9" zPosition="1" size="359,78" backgroundColor="#182C40" />
                <widget name="artisttext" position="13,11" zPosition="3" size="65,17" font="Regular;16" valign="top" foregroundColor="#cccccc" backgroundColor="#33294a6b" shadowColor="#000000" shadowOffset="-2,-2"/>
@@ -75,7 +73,7 @@
                <widget name="model" position="20,10" size="380,25" font="Regular;23"  />
                <widget name="capacity" position="20,40" size="380,25" font="Regular;23"  />
                <widget name="bus" position="20,70" size="380,25" font="Regular;23"  />
                <widget name="model" position="20,10" size="380,25" font="Regular;23"  />
                <widget name="capacity" position="20,40" size="380,25" font="Regular;23"  />
                <widget name="bus" position="20,70" size="380,25" font="Regular;23"  />
-               <widget name="initialize" position="150,120" zPosition="1" size="120,30" pixmap="init.png"  transparent="1" alphatest="on" />
+               <widget name="initialize" position="150,120" zPosition="1" size="120,30" pixmap="init.png" transparent="1" alphatest="on" />
                <widget name="initializetext" position="150,120" size="120,30" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" />
        </screen>
        <screen name="Setup" position="90,148" size="540,280" title="Setup">
                <widget name="initializetext" position="150,120" size="120,30" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" />
        </screen>
        <screen name="Setup" position="90,148" size="540,280" title="Setup">
                <widget name="key_yellow" position="280,0" size="140,40" backgroundColor="yellow" font="Regular;21" />
                <widget name="key_blue" position="420,0" size="140,40" backgroundColor="blue" font="Regular;21" />
                <widget name="list" position="0,45" size="560,196" scrollbarMode="showOnDemand" />
                <widget name="key_yellow" position="280,0" size="140,40" backgroundColor="yellow" font="Regular;21" />
                <widget name="key_blue" position="420,0" size="140,40" backgroundColor="blue" font="Regular;21" />
                <widget name="list" position="0,45" size="560,196" scrollbarMode="showOnDemand" />
-               <widget source="RadioText" render="Label" position="0,241" size="560,66" font="LCD;25" >
-                       <convert type="RadioText">RadioText</convert>
+               <widget source="RdsDecoder" render="Label" position="0,241" size="560,66" font="LCD;25" >
+                       <convert type="RdsInfo">RadioText</convert>
                </widget>
        </screen>
        <screen name="RadioInfoBar" position="90,420" size="560,105" zPosition="-1">
                <widget source="CurrentService" render="Label" position="0,0" size="390,26" font="Regular;22" backgroundColor="dark" >
                        <convert type="ServiceName">Name</convert>
                </widget>
                </widget>
        </screen>
        <screen name="RadioInfoBar" position="90,420" size="560,105" zPosition="-1">
                <widget source="CurrentService" render="Label" position="0,0" size="390,26" font="Regular;22" backgroundColor="dark" >
                        <convert type="ServiceName">Name</convert>
                </widget>
-               <widget name="BlinkingPoint" pixmap="record.png" position="400,0" zPosition="2" size="58,25" />
                <widget source="CurrentTime" render="Label" position="465,0" size="95,28" font="Regular;22" backgroundColor="dark" >
                        <convert type="ClockToText">WithSeconds</convert>
                </widget>
                <widget source="Event_Now" render="Progress" position="465,27" size="90,9" zPosition="1" borderWidth="2" >
                        <convert type="EventTime">Progress</convert>
                </widget>
                <widget source="CurrentTime" render="Label" position="465,0" size="95,28" font="Regular;22" backgroundColor="dark" >
                        <convert type="ClockToText">WithSeconds</convert>
                </widget>
                <widget source="Event_Now" render="Progress" position="465,27" size="90,9" zPosition="1" borderWidth="2" >
                        <convert type="EventTime">Progress</convert>
                </widget>
-               <widget source="Event_Now" render="Label" position="0,44" size="60,22" font="Regular;20" backgroundColor="dark" >
-                       <convert type="EventTime">StartTime</convert>
-                       <convert type="ClockToText">Default</convert>
+               <widget source="RdsDecoder" render="Pixmap" pixmap="rass_logo.png" position="0,27" size="50,21" >
+                       <convert type="RdsInfo">RasInteractiveAvailable</convert>
+                       <convert type="ConditionalShowHide" />
                </widget>
                </widget>
-               <widget source="Event_Next" render="Label" position="0,74" size="60,22" font="Regular;20" backgroundColor="dark" >
+               <widget source="Event_Now" render="Label" position="0,49" size="60,22" font="Regular;20" backgroundColor="dark" >
                        <convert type="EventTime">StartTime</convert>
                        <convert type="ClockToText">Default</convert>
                </widget>
                        <convert type="EventTime">StartTime</convert>
                        <convert type="ClockToText">Default</convert>
                </widget>
-               <widget source="Event_Now" render="Label" position="80,44" size="380,22" font="Regular;20" backgroundColor="dark" >
-                       <convert type="EventName">Name</convert>
-               </widget>
-               <widget source="Event_Next" render="Label" position="80,74" size="380,22" font="Regular;20" backgroundColor="dark" >
+               <widget source="Event_Now" render="Label" position="80,49" size="380,22" font="Regular;20" backgroundColor="dark" >
                        <convert type="EventName">Name</convert>
                </widget>
                        <convert type="EventName">Name</convert>
                </widget>
-
-               <widget source="Event_Now" render="Label" position="470,44" size="150,22" font="Regular;20" backgroundColor="dark" >
+               <widget source="Event_Now" render="Label" position="470,49" size="150,22" font="Regular;20" backgroundColor="dark" >
                        <convert type="EventTime">Remaining</convert>
                        <convert type="RemainingToText">InMinutes</convert>
                </widget>
                        <convert type="EventTime">Remaining</convert>
                        <convert type="RemainingToText">InMinutes</convert>
                </widget>
-               <widget source="Event_Next" render="Label" position="470,74" size="150,22" font="Regular;20" backgroundColor="dark" >
+               <widget source="Event_Next" render="Label" position="80,79" size="380,22" font="Regular;20" backgroundColor="dark" >
+                       <convert type="EventName">Name</convert>
+               </widget>
+               <widget source="Event_Next" render="Label" position="0,79" size="60,22" font="Regular;20" backgroundColor="dark" >
+                       <convert type="EventTime">StartTime</convert>
+                       <convert type="ClockToText">Default</convert>
+               </widget>
+               <widget source="Event_Next" render="Label" position="470,79" size="150,22" font="Regular;20" backgroundColor="dark" >
                        <convert type="EventTime">Duration</convert>
                        <convert type="ClockToText">InMinutes</convert>
                </widget>
                        <convert type="EventTime">Duration</convert>
                        <convert type="ClockToText">InMinutes</convert>
                </widget>
        <screen name="PictureInPicture" position="400,60" size="240,192" zPosition="-1" flags="wfNoBorder" >
                <widget name="video" position="0,0" size="240,192" />
        </screen>
        <screen name="PictureInPicture" position="400,60" size="240,192" zPosition="-1" flags="wfNoBorder" >
                <widget name="video" position="0,0" size="240,192" />
        </screen>
-       <screen name="SubtitleDisplay" position="0,0" size="720,568" zPosition="-1" flags="wfNoBorder" >
+
+       <screen name="SubtitleDisplay" position="0,0" size="720,568" zPosition="-1" flags="wfNoBorder" />
+
+       <colors>
+               <color name="rds_bg" value="#77ffffff" />
+               <color name="rds_fg" value="#000000" />
+               <color name="rds_text_bg" value="#003258" />
+       </colors>
+
+       <screen name="RdsInfoDisplay" backgroundColor="transparent" position="0,0" size="720,568" zPosition="-2" flags="wfNoBorder" >
+               <widget name="RadioText" backgroundColor="rds_text_bg" position="50,481" size="620,29" font="Regular;21" noWrap="1" shadowOffset="-2,-2" shadowColor="transpBlack" />
+               <widget name="RtpText" backgroundColor="rds_text_bg" position="50,510" size="620,29" font="Regular;21" halign="right" noWrap="1" shadowOffset="-2,-2" shadowColor="transpBlack" />
+               <widget name="RassLogo" pixmap="rass_logo.png" position="50,445" size="50,21" />
        </screen>
        </screen>
+
+       <screen name="RassInteractive" backgroundColor="rds_bg" position="50,180" size="100,275" flags="wfNoBorder" >
+               <ePixmap pixmap="rass_logo.png" position="0,0" size="100,21" />
+               <eLabel text="Index" position="36,25" size="60,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <eLabel text="0" position="5,25" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <widget name="Marker" position="21,25" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <eLabel text="1" position="5,50" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <widget name="subpages_1" position="35,50" size="36,20" alphatest="on" />
+               <eLabel text="2" position="5,75" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <widget name="subpages_2" position="35,75" size="36,20" alphatest="on" />
+               <eLabel text="3" position="5,100" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <widget name="subpages_3" position="35,100" size="36,20" alphatest="on" />
+               <eLabel text="4" position="5,125" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <widget name="subpages_4" position="35,125" size="36,20" alphatest="on" />
+               <eLabel text="5" position="5,150" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <widget name="subpages_5" position="35,150" size="36,20" alphatest="on" />
+               <eLabel text="6" position="5,175" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <widget name="subpages_6" position="35,175" size="36,20" alphatest="on" />
+               <eLabel text="7" position="5,200" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <widget name="subpages_7" position="35,200" size="36,20" alphatest="on" />
+               <eLabel text="8" position="5,225" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <widget name="subpages_8" position="35,225" size="36,20" alphatest="on" />
+               <eLabel text="9" position="5,250" size="16,25" font="Regular;21" foregroundColor="rds_fg" backgroundColor="rds_bg" />
+               <widget name="subpages_9" position="35,250" size="36,20" alphatest="on" />
+       </screen>
+
        <screen name="PiPSetup" backgroundColor="transparent" position="70,400" size="600,150" title="PiPSetup" flags="wfNoBorder">
                <widget name="text" position="0,0" size="600,150" font="Regular;23" />
        </screen>
        <screen name="PiPSetup" backgroundColor="transparent" position="70,400" size="600,150" title="PiPSetup" flags="wfNoBorder">
                <widget name="text" position="0,0" size="600,150" font="Regular;23" />
        </screen>
+
        <screen name="MovieSelection" position="90,78" size="560,455" title="Select a movie">
                <widget name="key_red" position="0,0" size="140,40" backgroundColor="red" font="Regular;21" />
                <widget name="key_green" position="140,0" size="140,40" backgroundColor="green" font="Regular;21" />
        <screen name="MovieSelection" position="90,78" size="560,455" title="Select a movie">
                <widget name="key_red" position="0,0" size="140,40" backgroundColor="red" font="Regular;21" />
                <widget name="key_green" position="140,0" size="140,40" backgroundColor="green" font="Regular;21" />
index 87498da973e558b2c3170978cc567c354dbce879..eff40e9299f4627279e3ca41155130f7a449d93d 100644 (file)
@@ -3,19 +3,45 @@
 #include <lib/dvb/idemux.h>
 #include <lib/gdi/gpixmap.h>
 
 #include <lib/dvb/idemux.h>
 #include <lib/gdi/gpixmap.h>
 
-DEFINE_REF(eDVBRadioTextParser);
+DEFINE_REF(eDVBRdsDecoder);
 
 
-eDVBRadioTextParser::eDVBRadioTextParser(iDVBDemux *demux)
-       :bytesread(0), ptr(0), p1(-1), p2(-1), msgPtr(0), state(0)
+eDVBRdsDecoder::eDVBRdsDecoder(iDVBDemux *demux)
+       :msgPtr(0), bsflag(0), qdar_pos(0), t_ptr(0), qdarmvi_show(0), state(0)
        ,m_abortTimer(eApp)
 {
        setStreamID(0xC0, 0xC0);
 
        ,m_abortTimer(eApp)
 {
        setStreamID(0xC0, 0xC0);
 
+       memset(rass_picture_mask, 0, sizeof(rass_picture_mask));
+
        if (demux->createPESReader(eApp, m_pes_reader))
                eDebug("failed to create PES reader!");
        else
        if (demux->createPESReader(eApp, m_pes_reader))
                eDebug("failed to create PES reader!");
        else
-               m_pes_reader->connectRead(slot(*this, &eDVBRadioTextParser::processData), m_read_connection);
-       CONNECT(m_abortTimer.timeout, eDVBRadioTextParser::abortNonAvail);
+               m_pes_reader->connectRead(slot(*this, &eDVBRdsDecoder::processData), m_read_connection);
+       CONNECT(m_abortTimer.timeout, eDVBRdsDecoder::abortNonAvail);
+}
+
+eDVBRdsDecoder::~eDVBRdsDecoder()
+{
+       // delete cached rass slides
+       for (int page=0; page < 10; ++page)
+       {
+               unsigned char mask = rass_picture_mask[(page*4)/8];
+               if (page % 2)
+                       mask >>= 4;
+               int subpage=0;
+               while(mask)
+               {
+                       if (mask & 1)
+                       {
+                               std::string filename = getRassPicture(page, subpage);
+                               if (filename.length())
+                                       remove(filename.c_str());
+                       }
+                       mask >>= 1;
+                       ++subpage;
+               }
+       }
+       remove("/tmp/RassLast.mvi");
 }
 
 #define SWAP(x)        ((x<<8)|(x>>8))
 }
 
 #define SWAP(x)        ((x<<8)|(x>>8))
@@ -65,14 +91,54 @@ static int frequency[3][4] = {
        { 11025,12000,8000,0 }
 };
 
        { 11025,12000,8000,0 }
 };
 
-void eDVBRadioTextParser::connectUpdatedRadiotext(const Slot0<void> &slot, ePtr<eConnection> &connection)
+void eDVBRdsDecoder::connectEvent(const Slot1<void, int> &slot, ePtr<eConnection> &connection)
 {
 {
-       connection = new eConnection(this, m_updated_radiotext.connect(slot));
+       connection = new eConnection(this, m_event.connect(slot));
 }
 
 }
 
-void eDVBRadioTextParser::processPESPacket(__u8 *data, int len)
+void eDVBRdsDecoder::addToPictureMask(int id)
+{
+       int page = id / 1000;
+       int tmp = page > 0 ? id / page : id;
+       int subpage = 0;
+       while(tmp > 1000)
+       {
+               ++subpage;
+               tmp -= 1000;
+               tmp *= 10;
+       }
+       int index = (page*4+subpage)/8;
+       int val = (page%2) ? 16 * (1 << subpage) : (1 << subpage);
+       if (rass_picture_mask[index] & val) // already have this picture
+               return;
+       rass_picture_mask[index] |= val;
+       /* emit */ m_event(RassInteractivePicMaskChanged);
+}
+
+void eDVBRdsDecoder::removeFromPictureMask(int id)
+{
+       int page = id / 1000;
+       int tmp = page > 0 ? id / page : id;
+       int subpage = 0;
+       while(tmp > 1000)
+       {
+               ++subpage;
+               tmp -= 1000;
+               tmp *= 10;
+       }
+       int index = (page*4)/8;
+       int val = (page%2) ? 16 * (1 << subpage) : (1 << subpage);
+       if (rass_picture_mask[index] & val) // have this picture
+       {
+               rass_picture_mask[index] &= ~val;
+               /* emit */ m_event(RassInteractivePicMaskChanged);
+       }
+}
+
+void eDVBRdsDecoder::processPESPacket(__u8 *data, int len)
 {
        int pos=9+data[8];// skip pes header
 {
        int pos=9+data[8];// skip pes header
+       int cnt=0;
 
        while (pos < len)
        {
 
        while (pos < len)
        {
@@ -130,137 +196,440 @@ void eDVBRadioTextParser::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;
-                       while(offs < pos)
-                               gotAncillaryByte(data[offs++]);
+                       gotAncillaryData(data+offs, ancillary_len);
                }
        }
 }
 
                }
        }
 }
 
-inline void eDVBRadioTextParser::gotAncillaryByte(__u8 data)
+void eDVBRdsDecoder::process_qdar(unsigned char *buf)
 {
 {
-       buf[bytesread]=data;
-       bytesread+=1;
-       if ( bytesread == 128 )
+       if (buf[0] == 0x40 && buf[1] == 0xDA)
        {
        {
-               while(ptr<128)
+               unsigned int item,cnt,ctrl,item_type;
+               unsigned long item_length,id,item_no,ptr,tmp;
+               unsigned short crc_qdar,crc_read;
+               char fname[50];
+               ptr=4;cnt=0;
+               item=buf[2]<<8; // Number of Items
+               item|=buf[3];
+               
+               while ( cnt++ < item ) //read in items
                {
                {
-                       if ( buf[ptr] == 0xFD )
-                       {
-                               if (p1 == -1)
-                                       p1 = ptr;
-                               else
-                                       p2 = ptr;
-                       }
-                       if ( p1 != -1 && p2 != -1 )
+                       id=buf[ptr++]<<8; //QDarID
+                       id|=buf[ptr++];
+                       
+                       item_no=buf[ptr++]<<8; // Item Number
+                       item_no|=buf[ptr++];
+                       
+                       ctrl=buf[ptr++]; //controlbyte
+                       item_type=buf[ptr++]; //item type
+                       
+                       item_length=buf[ptr++]<<24; // Item length
+                       item_length|=buf[ptr++]<<16;
+                       item_length|=buf[ptr++]<<8;
+                       item_length|=buf[ptr++];
+                       
+                       ptr=ptr+4; // rfu Bytes ... not used
+                       tmp=ptr; // calc crc
+                       crc_qdar=0xFFFF;
+                       while (tmp < ptr+item_length)
+                               crc_qdar = crc_ccitt_byte(crc_qdar, buf[tmp++]);
+               
+                       crc_read=buf[ptr+item_length]<<8;
+                       crc_read|=buf[ptr+item_length+1];
+                       //eDebug("[RDS/Rass] CRC read: %04X calculated: %04X",crc_read,crc_qdar^0xFFFF);
+
+                       if (crc_read == (crc_qdar^0xFFFF)) // process item
                        {
                        {
-                               int cnt=buf[--p2];
-                               while ( cnt-- > 0 )
+                               switch(item_type)
                                {
                                {
-                                       unsigned char c = buf[--p2];
-                                       if ( state == 1 )
-                                               crc=0xFFFF;
-                                       if ( state >= 1 && state < 11 )
-                                               crc = crc_ccitt_byte(crc, c);
-
-                                       switch (state)
-                                       {
-                                               case 0:
-                                                       if ( c==0xFE )  // Startkennung
-                                                               state=1;
-                                                       break;
-                                               case 1: // 10bit Site Address + 6bit Encoder Address
-                                               case 2:
-                                               case 3: // Sequence Counter
-                                                       ++state;
-                                                       break;
-                                               case 4:
-                                                       leninfo=c;
-                                                       ++state;
-                                                       break;
-                                               case 5:
-                                                       if ( c==0x0A ) // message element code 0x0A Radio Text
-                                                               ++state;
-                                                       else
-                                                               state=0;
-                                                       break;
-                                               case 6: // Data Set Number ... ignore
-                                               case 7: // Program Service Number ... ignore
-                                                       ++state;
-                                                       break;
-                                               case 8: // Message Element Length
-                                                       todo=c;
-                                                       if ( !todo || todo > 65 || todo > leninfo-4)
-                                                               state=0;
+                                       case 0x01: //Stillframe
+                                               if (ctrl&0x01) // display slide
+                                               {
+                                                       sprintf(fname,"/tmp/RassLast.mvi");
+                                                       FILE *fh=fopen(fname,"wb");
+                                                       fwrite(buf+ptr,1,item_length-2,fh);
+                                                       fclose(fh);
+                                                       /*emit*/ m_event(RecvRassSlidePic);
+                                                       qdarmvi_show=1;
+                                               }
+                                               if (ctrl&0x02) // save slide for interactive mode
+                                               {
+                                                       if (id == 0 || id >= 1000)
+                                                       {
+                                                               sprintf(fname,"/tmp/Rass%04d.mvi",(int)id);
+                                                               FILE *fh=fopen(fname,"wb");
+                                                               fwrite(buf+ptr,1,item_length-2,fh);
+                                                               fclose(fh);
+                                                               addToPictureMask(id);
+                                                       }
                                                        else
                                                        else
+                                                               eDebug("ignore recv interactive picture id %lu", id);
+                                               }
+                                               if (ctrl&0x04) // display slide if nothing had been displayed yet
+                                               {
+                                                       if (qdarmvi_show != 1)
                                                        {
                                                        {
-                                                               ++state;
-                                                               todo-=2;
-                                                               msgPtr=0;
+                                                               sprintf(fname,"/tmp/RassLast.mvi");
+                                                               FILE *fh=fopen(fname,"wb");
+                                                               fwrite(buf+ptr,1,item_length-2,fh);
+                                                               fclose(fh);
+                                                               /*emit*/ m_event(RecvRassSlidePic);
+                                                               qdarmvi_show=1;
                                                        }
                                                        }
-                                                       break;
-                                               case 9: // Radio Text Status bit:
-                                                       // 0   = AB-flagcontrol
-                                                       // 1-4 = Transmission-Number
-                                                       // 5-6 = Buffer-Config
-                                                       ++state; // ignore ...
-                                                       break;
-                                               case 10:
-       // TODO build a complete radiotext charcode to UTF8 conversion table for all character > 0x80
-                                                       switch (c)
+                                               }
+                                               if (ctrl&0x08) // delete slide
+                                               {
+                                                       eDebug("delete slide id %lu, item_no %lu", id, item_no);
+                                                       if (id == 0 || id >= 1000)
                                                        {
                                                        {
-                                                               case 0 ... 0x7f: break;
-                                                               case 0x8d: c='ß'; break;
-                                                               case 0x91: c='ä'; break;
-                                                               case 0xd1: c='Ä'; break;
-                                                               case 0x97: c='ö'; break;
-                                                               case 0xd7: c='Ö'; break;
-                                                               case 0x99: c='ü'; break;
-                                                               case 0xd9: c='Ãœ'; break;
-                                                               default: c=' '; break;  // convert all unknown to space
+                                                               eDebug("delete %lu", id);
+                                                               removeFromPictureMask(id);
+                                                               sprintf(fname,"/tmp/Rass%04d.mvi",(int)id); // was item_no ? ! ?
+                                                               remove(fname);
                                                        }
                                                        }
-                                                       message[msgPtr++]=c;
-                                                       if(todo)
-                                                               --todo;
                                                        else
                                                        else
-                                                               ++state;
-                                                       break;
-                                               case 11:
-                                                       crc16=c<<8;
+                                                               eDebug("ignore del interactive picture id %lu", id);
+                                               }
+                                               break;
+                                       default: //nothing more yet defined
+                                               break;
+                               }
+                       } 
+                       else
+                       {
+                               eDebug("[RDS/Rass] CRC error, skip Rass-Qdar-Item");
+                       }
+                       
+                       ptr=+item_length;
+               }
+       }
+       else
+       {
+               eDebug("[RDS/Rass] No Rass-QDAR archive (%02X %02X) so skipping !\n",buf[0],buf[1]);
+       }
+}
+
+inline void eDVBRdsDecoder::gotAncillaryData(__u8 *buf, int len)
+{
+       int cnt=buf[--len];
+       while ( cnt-- > 0 )
+       {
+               unsigned char c = buf[--len];
+       
+               if (bsflag == 1) // byte stuffing
+               {
+                       bsflag=2;
+                       switch (c)
+                       {
+                               case 0x00: c=0xFD; break;
+                               case 0x01: c=0xFE; break;
+                               case 0x02: c=0xFF; break;
+                       }
+               }
+
+               if (c == 0xFD && bsflag ==0) 
+                       bsflag=1;
+               else
+                       bsflag=0;
+                                       
+               if (bsflag == 0) 
+               {
+                       if ( state == 1 )
+                               crc=0xFFFF;
+                       if (( state >= 1 && state < 11 ) || ( state >=26 && state < 36 ))
+                               crc = crc_ccitt_byte(crc, c);
+
+                       switch (state)
+                       {
+                               case 0:
+                                       if ( c==0xFE )  // Startkennung
+                                               state=1;
+                                       break;
+                               case 1: // 10bit Site Address + 6bit Encoder Address
+                               case 2:
+                               case 3: // Sequence Counter
+                                       ++state;
+                                       break;
+                               case 4:
+                                       leninfo=c;
+                                       ++state;
+                                       break;
+                               case 5:
+                                       switch (c)
+                                       {
+                                               case 0x0A: // Radiotext
                                                        ++state;
                                                        break;
                                                        ++state;
                                                        break;
-                                               case 12:
-                                                       crc16|=c;
-                                                       message[msgPtr--]=0;
-                                                       while(message[msgPtr] == ' ' && msgPtr > 0)
-                                                               message[msgPtr--] = 0;
-                                                       if ( crc16 == (crc^0xFFFF) )
+                                               case 0x46: // Radiotext Plus tags
+                                                       state=38;
+                                                       break;
+                                               case 0xDA: // Rass
+                                                       state=26;
+                                                       break;
+                                               default: // reset to state 0
+                                                       state=0;
+                                       }
+                                       break;
+
+                                       // process Radiotext
+                               case 6: // Data Set Number ... ignore
+                               case 7: // Program Service Number ... ignore
+                                       ++state;
+                                       break;
+                               case 8: // Message Element Length
+                                       text_len=c;
+                                       if ( !text_len || text_len > 65 || text_len > leninfo-4)
+                                               state=0;
+                                       else
+                                       {
+                                               ++state;
+                                               text_len-=2;
+                                               msgPtr=0;
+                                       }
+                                       break;
+                               case 9: // Radio Text Status bit:
+                                       // 0   = AB-flagcontrol
+                                       // 1-4 = Transmission-Number
+                                       // 5-6 = Buffer-Config
+                                       ++state; // ignore ...
+                                       break;
+                               case 10:
+                                       // TODO build a complete radiotext charcode to UTF8 conversion table for all character > 0x80
+                                       switch (c)
+                                       {
+                                               case 0 ... 0x7f: break;
+                                               case 0x8d: c='ß'; break;
+                                               case 0x91: c='ä'; break;
+                                               case 0xd1: c='Ä'; break;
+                                               case 0x97: c='ö'; break;
+                                               case 0xd7: c='Ö'; break;
+                                               case 0x99: c='ü'; break;
+                                               case 0xd9: c='Ãœ'; break;
+                                               default: c=' '; break;  // convert all unknown to space
+                                       }
+                                       message[msgPtr++]=c;
+                                       if(text_len)
+                                               --text_len;
+                                       else
+                                               ++state;
+                                       break;
+                               case 11:
+                                       crc16=c<<8;
+                                       ++state;
+                                       break;
+                               case 12:
+                                       crc16|=c;
+                                       message[msgPtr--]=0;
+                                       while(message[msgPtr] == ' ' && msgPtr > 0)
+                                               message[msgPtr--] = 0;
+                                       if ( crc16 == (crc^0xFFFF) )
+                                       {
+                                               eDebug("radiotext: (%s)", message);
+                                               /*emit*/ m_event(RadioTextChanged);
+                                               memcpy(lastmessage,message,66);
+                                       }
+                                       else
+                                               eDebug("invalid radiotext crc (%s)", message);
+                                       state=0;
+                                       break;
+
+                               // process Rass
+                               case 26: //MEL
+                                       text_len = c;
+                                       text_len2 = c;
+                                       ++state;
+                                       text_len-=9;
+                                       text_len2-=9;
+                                       t_ptr=0;
+                                       break;
+                               case 27: // SID not used atm
+                                       ++state;
+                                       break;
+                               case 28: // SID not used atm
+                                       ++state;
+                                       break;
+                               case 29: // PNR packet number
+                                       part=c<<16;
+                                       ++state;
+                                       break;
+                               case 30: // PNR packet number
+                                       part|=c<<8;
+                                       ++state;
+                                       break;
+                               case 31: // PNR packet number
+                                       part|=c;
+                                       ++state;
+                                       break;
+                               case 32: // NOP number of packets
+                                       parts=c<<16;
+                                       ++state;
+                                       break;
+                               case 33: // NOP number of packets
+                                       parts|=c<<8;
+                                       ++state;
+                                       break;
+                               case 34: // NOP number of packets
+                                       parts|=c;
+                                       ++state;
+                                       break;
+                               case 35:
+                                       datamessage[t_ptr++]=c;
+                                       if(text_len) 
+                                               --text_len;
+                                       else
+                                               ++state;
+                                       break;
+                               case 36:
+                                       crc16=c<<8;
+                                       ++state;
+                                       break;
+                               case 37:
+                                       crc16|=c;
+                                       //eDebug("[RDS/Rass] CRC read: %04X CRC calculated: %04X",crc16,crc^0xFFFF);
+                                       state=0;
+                                       if ( crc16 == (crc^0xFFFF) ) 
+                                       {
+                                               if (partcnt == -1) 
+                                                       partcnt=1;
+                                               if (partcnt == part)
+                                               {
+                                                       memcpy(qdar+qdar_pos,datamessage,text_len2+1);
+                                                       qdar_pos=qdar_pos+text_len2+1;
+                                                       if (partcnt == parts)
                                                        {
                                                        {
-                                                               eDebug("radiotext: (%s)", message);
-                                                               /*emit*/ m_updated_radiotext();
+                                                               process_qdar(qdar); // decode qdar archive
+                                                               qdar_pos=0;
+                                                               partcnt=-1;
                                                        }
                                                        else
                                                        }
                                                        else
-                                                               eDebug("invalid radiotext crc (%s)", message);
-                                                       state=0;
-                                                       break;
+                                                               ++partcnt;
+                                               }
+                                               else
+                                               {
+                                                       qdar_pos=0;
+                                                       partcnt=-1;
+                                               }
                                        }
                                        }
-                               }
-                               p1=ptr;
-                               p2=-1;
+                                       else
+                                       {
+                                               eDebug("[RDS/Rass] CRC error, skip Rass-Qdar-Packet");
+                                               eDebug("[RDS/Rass] CRC read: %04X CRC calculated: %04X",crc16,crc^0xFFFF);
+                                               partcnt=-1;
+                                       }
+                                       state=0;
+                                       break;
+
+                               // process RT plus tags ... 
+                               case 38: // Message Element Length
+                                       text_len=c;     
+                                       ++state;
+                                       break;
+                               case 39: // Application ID 
+                               case 40: // always 0x4BD7 so we ignore it ;)
+                               case 41: // Applicationgroup Typecode/PTY ... ignore
+                                       ++state;
+                                       break;
+                               case 42:
+                                       rtp_buf[0]=c;
+                                       ++state;
+                                       break;
+                               case 43:
+                                       rtp_buf[1]=c;
+                                       ++state;
+                                       break;
+                               case 44:
+                                       rtp_buf[2]=c;
+                                       ++state;
+                                       break;
+                               case 45:
+                                       rtp_buf[3]=c;
+                                       ++state;
+                                       break;
+                               case 46: // bit 10#4 = Item Togglebit
+                                       // bit 10#3 = Item Runningbit
+                                       // Tag1: bit 10#2..11#5 = Contenttype, 11#4..12#7 = Startmarker, 12#6..12#1 = Length
+                                       rtp_buf[4]=c;
+                                       if (lastmessage[0] == 0) // no rds message till now ? quit ...
+                                               break;
+                                       int rtp_typ[2],rtp_start[2],rtp_len[2];
+                                       rtp_typ[0]   = (0x38 & rtp_buf[0]<<3) | rtp_buf[1]>>5;
+                                       rtp_start[0] = (0x3e & rtp_buf[1]<<1) | rtp_buf[2]>>7;
+                                       rtp_len[0]   = 0x3f & rtp_buf[2]>>1;
+                                       // Tag2: bit 12#0..13#3 = Contenttype, 13#2..14#5 = Startmarker, 14#4..14#0 = Length(5bit)
+                                       rtp_typ[1]   = (0x20 & rtp_buf[2]<<5) | rtp_buf[3]>>3;
+                                       rtp_start[1] = (0x38 & rtp_buf[3]<<3) | rtp_buf[4]>>5;
+                                       rtp_len[1]   = 0x1f & rtp_buf[4];
+                                                                       
+                                       unsigned char rtplus_osd_tmp[64];
+                                                                       
+                                       memcpy(rtp_item[rtp_typ[0]],lastmessage+rtp_start[0],rtp_len[0]+1);
+                                       rtp_item[rtp_typ[0]][rtp_len[0]+1]=0;
+                                                                       
+                                       if (rtp_typ[0] != rtp_typ[1])
+                                       {
+                                               memcpy(rtp_item[rtp_typ[1]],lastmessage+rtp_start[1],rtp_len[1]+1);
+                                               rtp_item[rtp_typ[1]][rtp_len[1]+1]=0;
+                                       }
+
+                                       // main RTPlus item_types used by the radio stations:
+                                       // 1 title
+                                       // 4 artist
+                                       // 24 info.date_time
+                                       // 31 stationname
+                                       // 32 program.now
+                                       // 39 homepage
+                                       // 41 phone.hotline
+                                       // 46 email.hotline
+                                       // todo: make a window to display all saved items ...
+       
+                                       //create RTPlus OSD for title/artist
+                                       rtplus_osd[0]=0;
+                                                               
+                                       if ( rtp_item[4][0] != 0 )//artist
+                                               sprintf((char*)rtplus_osd_tmp," (%s)",rtp_item[4]);
+                                                               
+                                       if ( rtp_item[1][0] != 0 )//title
+                                               sprintf((char*)rtplus_osd,"%s%s",rtp_item[1],rtplus_osd_tmp);
+                                                                       
+                                       if ( rtplus_osd[0] != 0 )
+                                       {
+                                               /*emit*/ m_event(RtpTextChanged);
+                                               eDebug("RTPlus: %s",rtplus_osd);
+                                       }
+                                               
+                                       state=0;
+                                       break;
                        }
                        }
-                       ++ptr;
                }
                }
-               if (p1 != -1 && (128-p1) != 128)
-               {
-                       bytesread=ptr=128-p1;
-                       memcpy(buf, buf+p1, ptr);
-                       p1=0;
-               }
-               else
-                       bytesread=ptr=0;
        }
 }
 
        }
 }
 
-int eDVBRadioTextParser::start(int pid)
+std::string eDVBRdsDecoder::getRassPicture(int page, int subpage)
+{
+       int val=0;
+       
+       switch(subpage)
+       {
+               case 0:
+                       val=page*1000;
+                       break;
+               case 1:
+                       val=page*1100;
+                       break;
+               case 2:
+                       val=page*1110;
+                       break;
+               case 3:
+                       val=page*1111;
+                       break;
+       }
+       char fname[50];
+       sprintf(fname,"/tmp/Rass%04d.mvi",val);
+       return fname;
+}
+
+int eDVBRdsDecoder::start(int pid)
 {
        int ret = -1;
        if (m_pes_reader && !(ret = m_pes_reader->start(pid)))
 {
        int ret = -1;
        if (m_pes_reader && !(ret = m_pes_reader->start(pid)))
@@ -268,9 +637,20 @@ int eDVBRadioTextParser::start(int pid)
        return ret;
 }
 
        return ret;
 }
 
-void eDVBRadioTextParser::abortNonAvail()
+void eDVBRdsDecoder::abortNonAvail()
 {
        eDebug("no ancillary data in audio stream... abort radiotext pes parser");
        if (m_pes_reader)
                m_pes_reader->stop();
 }
 {
        eDebug("no ancillary data in audio stream... abort radiotext pes parser");
        if (m_pes_reader)
                m_pes_reader->stop();
 }
+
+ePyObject eDVBRdsDecoder::getRassPictureMask()
+{
+       ePyObject ret = PyTuple_New(5);
+       PyTuple_SET_ITEM(ret, 0, PyInt_FromLong(rass_picture_mask[0]));
+       PyTuple_SET_ITEM(ret, 1, PyInt_FromLong(rass_picture_mask[1]));
+       PyTuple_SET_ITEM(ret, 2, PyInt_FromLong(rass_picture_mask[2]));
+       PyTuple_SET_ITEM(ret, 3, PyInt_FromLong(rass_picture_mask[3]));
+       PyTuple_SET_ITEM(ret, 4, PyInt_FromLong(rass_picture_mask[4]));
+       return ret;
+}
index b4ae0e2675f39efd6df8c1848cb306a49bf28c94..8c354ff15435dcb5fe8b41e09b259f3cc62fced6 100644 (file)
@@ -6,24 +6,37 @@
 #include <lib/dvb/pesparse.h>
 #include <lib/gdi/gpixmap.h>
 
 #include <lib/dvb/pesparse.h>
 #include <lib/gdi/gpixmap.h>
 
-class eDVBRadioTextParser: public iObject, public ePESParser, public Object
+class eDVBRdsDecoder: public iObject, public ePESParser, public Object
 {
 {
-       DECLARE_REF(eDVBRadioTextParser);
-       int bytesread, ptr, p1, p2, msgPtr;
-       unsigned char buf[128], message[66], leninfo, todo, state;
+       DECLARE_REF(eDVBRdsDecoder);
+       int msgPtr, bsflag, qdar_pos, t_ptr, qdarmvi_show;
+       unsigned char message[66], lastmessage[66], datamessage[256], rtp_buf[5], leninfo, text_len, text_len2, state;
+       unsigned char rtp_item[64][64], rtplus_osd[64]; //rtp
+       unsigned char qdar[60*1024]; //60 kB for holding Rass qdar archive
        unsigned short crc16, crc;
        unsigned short crc16, crc;
+       long part, parts, partcnt;
+       enum { RadioTextChanged, RtpTextChanged, RassInteractivePicMaskChanged, RecvRassSlidePic };
+       unsigned char rass_picture_mask[5];  // 40 bits... (10 * 4 pictures)
+       void addToPictureMask(int id);
+       void removeFromPictureMask(int id);
 public:
 public:
-       eDVBRadioTextParser(iDVBDemux *demux);
+       eDVBRdsDecoder(iDVBDemux *demux);
+       ~eDVBRdsDecoder();
        int start(int pid);
        int start(int pid);
-       void connectUpdatedRadiotext(const Slot0<void> &slot, ePtr<eConnection> &connection);
-       const char *getCurrentText() { return msgPtr ? (const char*)message : ""; }
+       void connectEvent(const Slot1<void, int> &slot, ePtr<eConnection> &connection);
+       const char *getRadioText() { return (const char*)message; }
+       const char *getRtpText() { return (const char*)rtplus_osd; }
+       ePyObject getRassPictureMask();
+       std::string getRassPicture(int page, int subpage);
+       std::string getRassSlideshowPicture() { return "/tmp/RassLast.mvi"; }
 private:
        void abortNonAvail();
        void processPESPacket(__u8 *pkt, int len);
 private:
        void abortNonAvail();
        void processPESPacket(__u8 *pkt, int len);
-       inline void gotAncillaryByte(__u8 data);
+       inline void gotAncillaryData(__u8 *data, int len);
+       void process_qdar(unsigned char*);
        ePtr<iDVBPESReader> m_pes_reader;
        ePtr<eConnection> m_read_connection;
        ePtr<iDVBPESReader> m_pes_reader;
        ePtr<eConnection> m_read_connection;
-       Signal0<void> m_updated_radiotext;
+       Signal1<void, int> m_event;
        eTimer m_abortTimer;
 };
 
        eTimer m_abortTimer;
 };
 
index b25a32d899e8ce7e93ca51ce4662812751157066..a5d95f53e50b1f3709c0f5704f0bc679414e5eb5 100644 (file)
@@ -3,5 +3,5 @@ installdir = $(LIBDIR)/enigma2/python/Components/Converter
 install_PYTHON = \
        __init__.py ClockToText.py Converter.py EventName.py StaticText.py EventTime.py \
        Poll.py RemainingToText.py StringList.py ServiceName.py FrontendInfo.py ServiceInfo.py \
 install_PYTHON = \
        __init__.py ClockToText.py Converter.py EventName.py StaticText.py EventTime.py \
        Poll.py RemainingToText.py StringList.py ServiceName.py FrontendInfo.py ServiceInfo.py \
-       ConditionalShowHide.py ServicePosition.py ValueRange.py RadioText.py Streaming.py
+       ConditionalShowHide.py ServicePosition.py ValueRange.py RdsInfo.py Streaming.py
 
 
diff --git a/lib/python/Components/Converter/RdsInfo.py b/lib/python/Components/Converter/RdsInfo.py
new file mode 100644 (file)
index 0000000..3a7b2be
--- /dev/null
@@ -0,0 +1,53 @@
+from enigma import iRdsDecoder, iPlayableService
+from Components.Converter.Converter import Converter
+from Components.Element import cached
+
+class RdsInfo(Converter, object):
+       RASS_INTERACTIVE_AVAILABLE = 0
+       RTP_TEXT_CHANGED = 1
+       RADIO_TEXT_CHANGED = 2
+
+       def __init__(self, type):
+               Converter.__init__(self, type)
+               self.type = {
+                               "RadioText": self.RADIO_TEXT_CHANGED,
+                               "RtpText": self.RTP_TEXT_CHANGED,
+                               "RasInteractiveAvailable": self.RASS_INTERACTIVE_AVAILABLE
+                       }[type]
+
+               self.interesting_events = {
+                               self.RADIO_TEXT_CHANGED: [iPlayableService.evUpdatedRadioText],
+                               self.RTP_TEXT_CHANGED: [iPlayableService.evUpdatedRtpText],
+                               self.RASS_INTERACTIVE_AVAILABLE: [iPlayableService.evUpdatedRassInteractivePicMask]
+                       }[self.type]
+
+       @cached
+       def getText(self):
+               decoder = self.source.decoder
+               text = ""
+               if decoder:
+                       if self.type == self.RADIO_TEXT_CHANGED:
+                               text = decoder.getText(iRdsDecoder.RadioText)
+                       elif self.type == self.RTP_TEXT_CHANGED:
+                               text = decoder.getText(iRdsDecoder.RtpText)
+                       else:
+                               print "unknown RdsInfo Converter type", self.type
+               return text
+
+       text = property(getText)
+
+       @cached
+       def getBoolean(self):
+               decoder = self.source.decoder
+               if self.type == self.RASS_INTERACTIVE_AVAILABLE:
+                       mask = decoder and decoder.getRassInteractiveMask()
+                       return (mask and mask[0] & 1 and True) or False
+               elif self.type == self.RADIO_TEXT_CHANGED:
+                       return (len(decoder.getText(iRdsDecoder.RadioText)) and True) or False
+               elif self.type == self.RTP_TEXT_CHANGED:
+                       return (len(decoder.getText(iRdsDecoder.RtpText)) and True) or False
+       boolean = property(getBoolean)
+
+       def changed(self, what):
+               if what[0] != self.CHANGED_SPECIFIC or what[1] in self.interesting_events:
+                       Converter.changed(self, what)
index 5e6a30a5784b5509127ffbfbeea81ced94d46313..b5e16d98445446c765c50265aaacdb5eb4f0723b 100644 (file)
@@ -2,5 +2,5 @@ installdir = $(LIBDIR)/enigma2/python/Components/Sources
 
 install_PYTHON = \
        __init__.py Clock.py EventInfo.py Source.py MenuList.py CurrentService.py \
 
 install_PYTHON = \
        __init__.py Clock.py EventInfo.py Source.py MenuList.py CurrentService.py \
-       FrontendStatus.py Boolean.py Config.py ServiceList.py RadioText.py StreamService.py \
+       FrontendStatus.py Boolean.py Config.py ServiceList.py RdsDecoder.py StreamService.py \
        StaticText.py
        StaticText.py
diff --git a/lib/python/Components/Sources/RdsDecoder.py b/lib/python/Components/Sources/RdsDecoder.py
new file mode 100644 (file)
index 0000000..886f81f
--- /dev/null
@@ -0,0 +1,29 @@
+from Components.PerServiceDisplay import PerServiceBase
+from Components.Element import cached
+from enigma import iPlayableService
+from Source import Source
+
+class RdsDecoder(PerServiceBase, Source, object):
+       def __init__(self, navcore):
+               Source.__init__(self)
+               PerServiceBase.__init__(self, navcore,
+                       {
+                               iPlayableService.evStart: self.gotEvent,
+                               iPlayableService.evUpdatedRadioText: self.gotEvent,
+                               iPlayableService.evUpdatedRtpText: self.gotEvent,
+                               iPlayableService.evUpdatedRassInteractivePicMask: self.gotEvent,
+                               iPlayableService.evEnd: self.gotEvent
+                       }, with_event=True)
+
+       @cached
+       def getDecoder(self):
+               service = self.navcore.getCurrentService()
+               return service and service.rdsDecoder()
+
+       decoder = property(getDecoder)
+
+       def gotEvent(self, what):
+               if what in [iPlayableService.evStart, iPlayableService.evEnd]:
+                       self.changed((self.CHANGED_CLEAR,))
+               else:
+                       self.changed((self.CHANGED_SPECIFIC, what))
index 5a0f11775781c8e107ef690067850d06595b6956..7f9f797e618e04f3a7e8b7a85119c99c0bca6465 100644 (file)
@@ -1,7 +1,7 @@
 from Screen import Screen
 from Components.Button import Button
 from Components.ServiceList import ServiceList
 from Screen import Screen
 from Components.Button import Button
 from Components.ServiceList import ServiceList
-from Components.ActionMap import NumberActionMap, ActionMap
+from Components.ActionMap import NumberActionMap, ActionMap, HelpableActionMap
 from Components.MenuList import MenuList
 from Components.ServiceEventTracker import ServiceEventTracker
 from EpgSelection import EPGSelection
 from Components.MenuList import MenuList
 from Components.ServiceEventTracker import ServiceEventTracker
 from EpgSelection import EPGSelection
@@ -11,11 +11,13 @@ from Screens.FixedMenu import FixedMenu
 from Tools.NumericalTextInput import NumericalTextInput
 from Components.NimManager import nimmanager
 from Components.Sources.Clock import Clock
 from Tools.NumericalTextInput import NumericalTextInput
 from Components.NimManager import nimmanager
 from Components.Sources.Clock import Clock
+from Components.Sources.RdsDecoder import RdsDecoder
 from Components.Input import Input
 from Components.ParentalControl import parentalControl
 from Screens.InputBox import InputBox, PinInput
 from Screens.MessageBox import MessageBox
 from Screens.ServiceInfo import ServiceInfo
 from Components.Input import Input
 from Components.ParentalControl import parentalControl
 from Screens.InputBox import InputBox, PinInput
 from Screens.MessageBox import MessageBox
 from Screens.ServiceInfo import ServiceInfo
+from Screens.RdsDisplay import RassInteractive
 from ServiceReference import ServiceReference
 from Tools.BoundFunction import boundFunction
 from re import *
 from ServiceReference import ServiceReference
 from Tools.BoundFunction import boundFunction
 from re import *
@@ -1256,32 +1258,30 @@ class ChannelSelection(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelect
                self.revertMode = None
                self.close(None)
 
                self.revertMode = None
                self.close(None)
 
-from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarRadioText
+from Screens.InfoBarGenerics import InfoBarEvent, InfoBarServiceName
 
 
-class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord):
+class RadioInfoBar(Screen, InfoBarEvent, InfoBarServiceName):
        def __init__(self, session):
                Screen.__init__(self, session)
                InfoBarEvent.__init__(self)
                InfoBarServiceName.__init__(self)
        def __init__(self, session):
                Screen.__init__(self, session)
                InfoBarEvent.__init__(self)
                InfoBarServiceName.__init__(self)
-               InfoBarInstantRecord.__init__(self)
                self["CurrentTime"] = Clock()
                self["CurrentTime"] = Clock()
+               self["RdsDecoder"] = RdsDecoder(self.session.nav)
 
 
-class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG, InfoBarRadioText):
-
+class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelSelectionEPG):
        ALLOW_SUSPEND = True
 
        ALLOW_SUSPEND = True
 
-       def __init__(self, session):
+       def __init__(self, session, infobar):
                ChannelSelectionBase.__init__(self, session)
                ChannelSelectionEdit.__init__(self)
                ChannelSelectionEPG.__init__(self)
                ChannelSelectionBase.__init__(self, session)
                ChannelSelectionEdit.__init__(self)
                ChannelSelectionEPG.__init__(self)
-               InfoBarRadioText.__init__(self)
-
+               self.infobar = infobar
                config.radio = ConfigSubsection();
                config.radio.lastservice = ConfigText()
                config.radio.lastroot = ConfigText()
                self.onLayoutFinish.append(self.onCreate)
 
                config.radio = ConfigSubsection();
                config.radio.lastservice = ConfigText()
                config.radio.lastroot = ConfigText()
                self.onLayoutFinish.append(self.onCreate)
 
-               self.info = session.instantiateDialog(RadioInfoBar)
+               self.info = session.instantiateDialog(RadioInfoBar) # our simple infobar
 
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
 
                self["actions"] = ActionMap(["OkCancelActions", "TvRadioActions"],
                        {
@@ -1297,6 +1297,37 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                                iPlayableService.evEnd: self.__evServiceEnd
                        })
 
                                iPlayableService.evEnd: self.__evServiceEnd
                        })
 
+########## RDS Radiotext / Rass Support BEGIN
+               self.infobar = infobar # reference to real infobar (the one and only)
+               self["RdsDecoder"] = self.info["RdsDecoder"]
+               self["RdsActions"] = HelpableActionMap(self, "InfobarRdsActions",
+               {
+                       "startRassInteractive": (self.startRassInteractive, _("View Rass interactive..."))
+               },-1)
+               self["RdsActions"].setEnabled(False)
+               infobar.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
+
+       def startRassInteractive(self):
+               self.info.hide();
+               self.infobar.rass_interactive = self.session.openWithCallback(self.RassInteractiveClosed, RassInteractive)
+
+       def RassInteractiveClosed(self):
+               self.info.show()
+               self.infobar.rass_interactive = None
+               self.infobar.RassSlidePicChanged()
+
+       def RassInteractivePossibilityChanged(self, state):
+               self["RdsActions"].setEnabled(state)
+########## RDS Radiotext / Rass Support END
+
+       def closeRadio(self):
+               self.infobar.rds_display.onRassInteractivePossibilityChanged.remove(self.RassInteractivePossibilityChanged)
+               self.info.hide()
+               #set previous tv service
+               lastservice=eServiceReference(config.tv.lastservice.value)
+               self.session.nav.playService(lastservice)
+               self.close(None)
+
        def __evServiceStart(self):
                service = self.session.nav.getCurrentService()
                if service:
        def __evServiceStart(self):
                service = self.session.nav.getCurrentService()
                if service:
@@ -1371,13 +1402,6 @@ class ChannelSelectionRadio(ChannelSelectionBase, ChannelSelectionEdit, ChannelS
                                        config.radio.lastservice.save()
                                self.saveRoot()
 
                                        config.radio.lastservice.save()
                                self.saveRoot()
 
-       def closeRadio(self):
-               self.info.hide()
-               #set previous tv service
-               lastservice=eServiceReference(config.tv.lastservice.value)
-               self.session.nav.playService(lastservice)
-               self.close(None)
-
 class SimpleChannelSelection(ChannelSelectionBase):
        def __init__(self, session, title):
                ChannelSelectionBase.__init__(self, session)
 class SimpleChannelSelection(ChannelSelectionBase):
        def __init__(self, session, title):
                ChannelSelectionBase.__init__(self, session)
index 24c2b40bc5fdb296056ae360249f74429c99e86f..ab40838d53d13921f516f4294664007ffad77eb7 100644 (file)
@@ -12,7 +12,7 @@ from Components.config import config
 from Tools.Notifications import AddNotificationWithCallback
 
 from Screens.InfoBarGenerics import InfoBarShowHide, \
 from Tools.Notifications import AddNotificationWithCallback
 
 from Screens.InfoBarGenerics import InfoBarShowHide, \
-       InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarRadioText, \
+       InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarRdsDecoder, \
        InfoBarEPG, InfoBarEvent, InfoBarServiceName, InfoBarSeek, InfoBarInstantRecord, \
        InfoBarAudioSelection, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, \
        InfoBarSubserviceSelection, InfoBarTuner, InfoBarShowMovies, InfoBarTimeshift,  \
        InfoBarEPG, InfoBarEvent, InfoBarServiceName, InfoBarSeek, InfoBarInstantRecord, \
        InfoBarAudioSelection, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, \
        InfoBarSubserviceSelection, InfoBarTuner, InfoBarShowMovies, InfoBarTimeshift,  \
@@ -23,7 +23,7 @@ from Screens.InfoBarGenerics import InfoBarShowHide, \
 from Screens.HelpMenu import HelpableScreen, HelpMenu
 
 class InfoBar(InfoBarShowHide,
 from Screens.HelpMenu import HelpableScreen, HelpMenu
 
 class InfoBar(InfoBarShowHide,
-       InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRadioText,
+       InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder,
        InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarAudioSelection, 
        HelpableScreen, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish,
        InfoBarSubserviceSelection, InfoBarTuner, InfoBarTimeshift, InfoBarSeek,
        InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarAudioSelection, 
        HelpableScreen, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish,
        InfoBarSubserviceSelection, InfoBarTuner, InfoBarTimeshift, InfoBarSeek,
@@ -47,7 +47,7 @@ class InfoBar(InfoBarShowHide,
                
                for x in HelpableScreen, \
                                InfoBarShowHide, \
                
                for x in HelpableScreen, \
                                InfoBarShowHide, \
-                               InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRadioText, \
+                               InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder, \
                                InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarAudioSelection, \
                                InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarSubserviceSelection, \
                                InfoBarTuner, InfoBarTimeshift, InfoBarSeek, InfoBarSummarySupport, InfoBarTimeshiftState, \
                                InfoBarEvent, InfoBarServiceName, InfoBarInstantRecord, InfoBarAudioSelection, \
                                InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarSubserviceSelection, \
                                InfoBarTuner, InfoBarTimeshift, InfoBarSeek, InfoBarSummarySupport, InfoBarTimeshiftState, \
@@ -67,7 +67,11 @@ class InfoBar(InfoBarShowHide,
                if config.usage.e1like_radio_mode.value:
                        self.showRadioChannelList(True)
                else:
                if config.usage.e1like_radio_mode.value:
                        self.showRadioChannelList(True)
                else:
-                       self.session.open(ChannelSelectionRadio)
+                       self.rds_display.hide() # in InfoBarRdsDecoder
+                       self.session.openWithCallback(self.ChannelSelectionRadioClosed, ChannelSelectionRadio, self)
+
+       def ChannelSelectionRadioClosed(self, *arg):
+               self.rds_display.show()  # in InfoBarRdsDecoder
 
        def showMovies(self):
                self.session.openWithCallback(self.movieSelected, MovieSelection)
 
        def showMovies(self):
                self.session.openWithCallback(self.movieSelected, MovieSelection)
index 2ccd52de7fc263b1196734d02c78c4d8dbdd9f29..78a67b7ce54dac83f8e2051290e8c09168607824 100644 (file)
@@ -12,7 +12,6 @@ from Components.ProgressBar import *
 from Components.ServiceEventTracker import ServiceEventTracker
 from Components.Sources.CurrentService import CurrentService
 from Components.Sources.EventInfo import EventInfo
 from Components.ServiceEventTracker import ServiceEventTracker
 from Components.Sources.CurrentService import CurrentService
 from Components.Sources.EventInfo import EventInfo
-from Components.Sources.RadioText import RadioText
 from Components.Sources.FrontendStatus import FrontendStatus
 from Components.Sources.Boolean import Boolean
 from Components.Sources.Clock import Clock
 from Components.Sources.FrontendStatus import FrontendStatus
 from Components.Sources.Boolean import Boolean
 from Components.Sources.Clock import Clock
@@ -32,6 +31,7 @@ from Screens.MinuteInput import MinuteInput
 from Screens.TimerSelection import TimerSelection
 from Screens.PictureInPicture import PictureInPicture
 from Screens.SubtitleDisplay import SubtitleDisplay
 from Screens.TimerSelection import TimerSelection
 from Screens.PictureInPicture import PictureInPicture
 from Screens.SubtitleDisplay import SubtitleDisplay
+from Screens.RdsDisplay import RdsInfoDisplay, RassInteractive
 from Screens.SleepTimerEdit import SleepTimerEdit
 from ServiceReference import ServiceReference
 
 from Screens.SleepTimerEdit import SleepTimerEdit
 from ServiceReference import ServiceReference
 
@@ -538,10 +538,53 @@ class InfoBarEvent:
                self["Event_Now"] = EventInfo(self.session.nav, EventInfo.NOW)
                self["Event_Next"] = EventInfo(self.session.nav, EventInfo.NEXT)
 
                self["Event_Now"] = EventInfo(self.session.nav, EventInfo.NOW)
                self["Event_Next"] = EventInfo(self.session.nav, EventInfo.NEXT)
 
-class InfoBarRadioText:
-       """provides radio (RDS) text info display"""
+class InfoBarRdsDecoder:
+       """provides RDS and Rass support/display"""
        def __init__(self):
        def __init__(self):
-               self["RadioText"] = RadioText(self.session.nav)
+               self.rds_display = self.session.instantiateDialog(RdsInfoDisplay)
+               self.rass_interactive = None
+               
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evEnd: self.__serviceStopped,
+                               iPlayableService.evUpdatedRassSlidePic: self.RassSlidePicChanged
+                       })
+               
+               self["RdsActions"] = HelpableActionMap(self, "InfobarRdsActions",
+               {
+                       "startRassInteractive": (self.startRassInteractive, _("View Rass interactive..."))
+               },-1)
+
+               self["RdsActions"].setEnabled(False)
+
+               self.onLayoutFinish.append(self.rds_display.show)
+               self.rds_display.onRassInteractivePossibilityChanged.append(self.RassInteractivePossibilityChanged)
+
+       def RassInteractivePossibilityChanged(self, state):
+               self["RdsActions"].setEnabled(state)
+
+       def RassSlidePicChanged(self):
+               if not self.rass_interactive:
+                       service = self.session.nav.getCurrentService()
+                       decoder = service and service.rdsDecoder()
+                       if decoder:
+                               decoder.showRassSlidePicture()
+
+       def __serviceStopped(self):
+               if self.rass_interactive is not None:
+                       rass_interactive = self.rass_interactive
+                       self.rass_interactive = None
+                       rass_interactive.close()
+
+       def startRassInteractive(self):
+               self.rds_display.hide()
+               self.rass_interactive = self.session.openWithCallback(self.RassInteractiveClosed, RassInteractive)
+
+       def RassInteractiveClosed(self, *val):
+               if self.rass_interactive is not None:
+                       self.rass_interactive = None
+                       self.RassSlidePicChanged()
+               self.rds_display.show()
 
 class InfoBarServiceName:
        def __init__(self):
 
 class InfoBarServiceName:
        def __init__(self):
index d5512e7e9af08e16f1a32d50e0d30e194c9aaad9..920a97fbeb77b6f1fb6eedeb8548aa43bc9850a5 100644 (file)
@@ -12,4 +12,4 @@ install_PYTHON = \
        Console.py InputBox.py ChoiceBox.py SimpleSummary.py ImageWizard.py \
        MediaPlayer.py TimerSelection.py PictureInPicture.py TimeDateInput.py \
        SubtitleDisplay.py SubservicesQuickzap.py ParentalControlSetup.py NumericalTextInputHelpDialog.py \
        Console.py InputBox.py ChoiceBox.py SimpleSummary.py ImageWizard.py \
        MediaPlayer.py TimerSelection.py PictureInPicture.py TimeDateInput.py \
        SubtitleDisplay.py SubservicesQuickzap.py ParentalControlSetup.py NumericalTextInputHelpDialog.py \
-       SleepTimerEdit.py Ipkg.py
+       SleepTimerEdit.py Ipkg.py RdsDisplay.py
diff --git a/lib/python/Screens/RdsDisplay.py b/lib/python/Screens/RdsDisplay.py
new file mode 100644 (file)
index 0000000..4190b94
--- /dev/null
@@ -0,0 +1,272 @@
+from enigma import iPlayableService, loadPNG, iRdsDecoder, ePoint, gRGB
+from Screens.Screen import Screen
+from Components.Sources.RdsDecoder import RdsDecoder
+from Components.ActionMap import NumberActionMap
+from Components.ServiceEventTracker import ServiceEventTracker
+from Components.Pixmap import Pixmap
+from Components.Label import Label
+from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE
+
+class RdsInfoDisplay(Screen):
+       ALLOW_SUSPEND = True
+       
+       def __init__(self, session):
+               Screen.__init__(self, session)
+
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evEnd: self.__serviceStopped,
+                               iPlayableService.evUpdatedRadioText: self.RadioTextChanged,
+                               iPlayableService.evUpdatedRtpText: self.RtpTextChanged,
+                               iPlayableService.evUpdatedRassInteractivePicMask: self.RassInteractivePicMaskChanged,
+                       })
+
+               self["RadioText"] = Label()
+               self["RtpText"] = Label()
+               self["RassLogo"] = Pixmap()
+
+               self.onLayoutFinish.append(self.hideWidgets)
+               self.rassInteractivePossible=False
+               self.onRassInteractivePossibilityChanged = [ ]
+
+       def hideWidgets(self):
+               for x in (self["RadioText"],self["RtpText"],self["RassLogo"]):
+                       x.hide()
+
+       def RadioTextChanged(self):
+               service = self.session.nav.getCurrentService()
+               decoder = service and service.rdsDecoder()
+               rdsText = decoder and decoder.getText(iRdsDecoder.RadioText)
+               if rdsText and len(rdsText):
+                       self["RadioText"].setText(rdsText)
+                       self["RadioText"].show()
+               else:
+                       self["RadioText"].hide()
+
+       def RtpTextChanged(self):
+               service = self.session.nav.getCurrentService()
+               decoder = service and service.rdsDecoder()
+               rtpText = decoder and decoder.getText(iRdsDecoder.RtpText)
+               if rtpText and len(rtpText):
+                       self["RtpText"].setText(rtpText)
+                       self["RtpText"].show()
+               else:
+                       self["RtpText"].hide()
+
+       def RassInteractivePicMaskChanged(self):
+               if not self.rassInteractivePossible:
+                       service = self.session.nav.getCurrentService()
+                       decoder = service and service.rdsDecoder()
+                       mask = decoder and decoder.getRassInteractiveMask()
+                       if mask[0] & 1: #rass interactive index page available
+                               self["RassLogo"].show()
+                               self.rassInteractivePossible = True
+                               for x in self.onRassInteractivePossibilityChanged:
+                                       x(True)
+
+       def __serviceStopped(self):
+               self.hideWidgets()
+               if self.rassInteractivePossible:
+                       self.rassInteractivePossible = False
+                       for x in self.onRassInteractivePossibilityChanged:
+                               x(False)
+
+class RassInteractive(Screen):
+       def __init__(self, session):
+               Screen.__init__(self, session)
+
+               self["actions"] = NumberActionMap( [ "NumberActions", "RassInteractiveActions" ],
+                       {
+                               "exit": self.close,
+                               "0": lambda x : self.numPressed(0),
+                               "1": lambda x : self.numPressed(1),
+                               "2": lambda x : self.numPressed(2),
+                               "3": lambda x : self.numPressed(3),
+                               "4": lambda x : self.numPressed(4),
+                               "5": lambda x : self.numPressed(5),
+                               "6": lambda x : self.numPressed(6),
+                               "7": lambda x : self.numPressed(7),
+                               "8": lambda x : self.numPressed(8),
+                               "9": lambda x : self.numPressed(9),
+                               "nextPage": self.nextPage,
+                               "prevPage": self.prevPage,
+                               "nextSubPage": self.nextSubPage,
+                               "prevSubPage": self.prevSubPage
+                       })
+
+               self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+                       {
+                               iPlayableService.evUpdatedRassInteractivePicMask: self.recvRassInteractivePicMaskChanged
+                       })
+
+               self["subpages_1"] = Pixmap()
+               self["subpages_2"] = Pixmap()
+               self["subpages_3"] = Pixmap()
+               self["subpages_4"] = Pixmap()
+               self["subpages_5"] = Pixmap()
+               self["subpages_6"] = Pixmap()
+               self["subpages_7"] = Pixmap()
+               self["subpages_8"] = Pixmap()
+               self["subpages_9"] = Pixmap()
+               self["Marker"] = Label(">")
+
+               self.subpage = {
+                       1 : self["subpages_1"],
+                       2 : self["subpages_2"],
+                       3 : self["subpages_3"],
+                       4 : self["subpages_4"],
+                       5 : self["subpages_5"],
+                       6 : self["subpages_6"],
+                       7 : self["subpages_7"],
+                       8 : self["subpages_8"],
+                       9 : self["subpages_9"] }
+
+               self.subpage_png = {
+                       1 : loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "rass_page1.png")),
+                       2 : loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "rass_page2.png")),
+                       3 : loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "rass_page3.png")),
+                       4 : loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "rass_page4.png")) }
+
+               self.current_page=0;
+               self.current_subpage=0;
+               self.showRassPage(0,0)
+               self.onLayoutFinish.append(self.updateSubPagePixmaps)
+
+       def updateSubPagePixmaps(self):
+               service = self.session.nav.getCurrentService()
+               decoder = service and service.rdsDecoder()
+               if not decoder: # this should never happen
+                       print "NO RDS DECODER in showRassPage"
+               else:
+                       mask = decoder.getRassInteractiveMask()
+                       page = 1
+                       while page < 10:
+                               subpage_cnt = self.countAvailSubpages(page, mask)
+                               subpage = self.subpage[page]
+                               if subpage_cnt > 0:
+                                       if subpage.instance:
+                                               png = self.subpage_png[subpage_cnt]
+                                               if png:
+                                                       subpage.instance.setPixmap(png)
+                                                       subpage.show()
+                                               else:
+                                                       print "rass png missing"
+                               else:
+                                       subpage.hide()
+                               page += 1
+
+       def recvRassInteractivePicMaskChanged(self):
+               self.updateSubPagePixmaps()
+
+       def showRassPage(self, page, subpage):
+               service = self.session.nav.getCurrentService()
+               decoder = service and service.rdsDecoder()
+               if not decoder: # this should never happen
+                       print "NO RDS DECODER in showRassPage"
+               else:
+                       decoder.showRassInteractivePic(page, subpage)
+                       page_diff = page - self.current_page
+                       self.current_page = page
+                       if page_diff:
+                               current_pos = self["Marker"].getPosition()
+                               y = current_pos[1]
+                               y += page_diff * 25
+                               self["Marker"].setPosition(current_pos[0],y)
+
+       def getMaskForPage(self, page, masks=None):
+               if not masks:
+                       service = self.session.nav.getCurrentService()
+                       decoder = service and service.rdsDecoder()
+                       if not decoder: # this should never happen
+                               print "NO RDS DECODER in getMaskForPage"
+                       masks = decoder.getRassInteractiveMask()
+               if masks:
+                       mask = masks[(page*4)/8]
+                       if page % 2:
+                               mask >>= 4
+                       else:
+                               mask &= 0xF
+               return mask
+
+       def countAvailSubpages(self, page, masks):
+               mask = self.getMaskForPage(page, masks)
+               cnt = 0
+               while mask:
+                       if mask & 1:
+                               cnt += 1
+                       mask >>= 1
+               return cnt
+
+       def nextPage(self):
+               mask = 0
+               page = self.current_page
+               while mask == 0:
+                       page += 1
+                       if page > 9:
+                               page = 0
+                       mask = self.getMaskForPage(page)
+               self.numPressed(page)
+
+       def prevPage(self):
+               mask = 0
+               page = self.current_page
+               while mask == 0:
+                       if page > 0:
+                               page -= 1
+                       else:
+                               page = 9
+                       mask = self.getMaskForPage(page)
+               self.numPressed(page)
+
+       def nextSubPage(self):
+               self.numPressed(self.current_page)
+
+       def prevSubPage(self):
+               num = self.current_page
+               mask = self.getMaskForPage(num)
+               cur_bit = 1 << self.current_subpage
+               tmp = cur_bit
+               while True:
+                       if tmp == 1:
+                               tmp = 8
+                       else:
+                               tmp >>= 1
+                       if tmp == cur_bit: # no other subpage avail
+                               return
+                       if mask & tmp: # next subpage found
+                               subpage = 0
+                               while tmp > 1: # convert bit to subpage
+                                       subpage += 1
+                                       tmp >>= 1
+                               self.current_subpage = subpage
+                               self.showRassPage(num, subpage)
+                               return
+
+       def numPressed(self, num):
+               mask = self.getMaskForPage(num)
+               if self.current_page == num:
+                       self.skip = 0
+                       cur_bit = 1 << self.current_subpage
+                       tmp = cur_bit
+               else:
+                       self.skip = 1
+                       cur_bit = 16
+                       tmp = 1
+               while True:
+                       if not self.skip:
+                               if tmp == 8 and cur_bit < 16:
+                                       tmp = 1
+                               else:
+                                       tmp <<= 1
+                       else:
+                               self.skip = 0
+                       if tmp == cur_bit: # no other subpage avail
+                               return
+                       if mask & tmp: # next subpage found
+                               subpage = 0
+                               while tmp > 1: # convert bit to subpage
+                                       subpage += 1
+                                       tmp >>= 1
+                               self.current_subpage = subpage
+                               self.showRassPage(num, subpage)
+                               return
index feaa771eae5cb7ff02fc41675c2a544b775c1507..df4e302f12b5fd50c4f0863fd14e1258fda3d78a 100644 (file)
@@ -483,17 +483,30 @@ public:
 };
 SWIG_TEMPLATE_TYPEDEF(ePtr<iAudioDelay>, iAudioDelayPtr);
 
 };
 SWIG_TEMPLATE_TYPEDEF(ePtr<iAudioDelay>, iAudioDelayPtr);
 
-SWIG_IGNORE(iRadioText);
-class iRadioText: public iObject
+class iRdsDecoder_ENUMS
 {
 #ifdef SWIG
 {
 #ifdef SWIG
-       iRadioText();
-       ~iRadioText();
+       iRdsDecoder_ENUMS();
+       ~iRdsDecoder_ENUMS();
 #endif
 public:
 #endif
 public:
-       virtual std::string getRadioText(int x=0)=0;
+       enum { RadioText, RtpText };
 };
 };
-SWIG_TEMPLATE_TYPEDEF(ePtr<iRadioText>, iRadioTextPtr);
+
+SWIG_IGNORE(iRdsDecoder);
+class iRdsDecoder: public iObject, public iRdsDecoder_ENUMS
+{
+#ifdef SWIG
+       iRdsDecoder();
+       ~iRdsDecoder();
+#endif
+public:
+       virtual std::string getText(int x=RadioText)=0;
+       virtual void showRassSlidePicture()=0;
+       virtual void showRassInteractivePic(int page, int subpage)=0;
+       virtual SWIG_PYOBJECT(ePyObject) getRassInteractiveMask()=0;
+};
+SWIG_TEMPLATE_TYPEDEF(ePtr<iRdsDecoder>, iRdsDecoderPtr);
 
 SWIG_IGNORE(iSubserviceList);
 class iSubserviceList: public iObject
 
 SWIG_IGNORE(iSubserviceList);
 class iSubserviceList: public iObject
@@ -676,8 +689,13 @@ public:
                        /* when cueSheet is implemented */
                evCuesheetChanged,
 
                        /* when cueSheet is implemented */
                evCuesheetChanged,
 
-                       /* when radioText is implemented */
+                       /* when rdsDecoder is implemented */
                evUpdatedRadioText,
                evUpdatedRadioText,
+               evUpdatedRtpText,
+
+                       /* Radio Screenshow Support */
+               evUpdatedRassSlidePic,
+               evUpdatedRassInteractivePicMask,
 
                evVideoSizeChanged,
 
 
                evVideoSizeChanged,
 
@@ -712,7 +730,7 @@ public:
        virtual SWIG_VOID(RESULT) cueSheet(ePtr<iCueSheet> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) subtitle(ePtr<iSubtitleOutput> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) audioDelay(ePtr<iAudioDelay> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) cueSheet(ePtr<iCueSheet> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) subtitle(ePtr<iSubtitleOutput> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) audioDelay(ePtr<iAudioDelay> &SWIG_OUTPUT)=0;
-       virtual SWIG_VOID(RESULT) radioText(ePtr<iRadioText> &SWIG_OUTPUT)=0;
+       virtual SWIG_VOID(RESULT) rdsDecoder(ePtr<iRdsDecoder> &SWIG_OUTPUT)=0;
 };
 SWIG_TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
 
 };
 SWIG_TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
 
index 9d9f2d1f385597716afff8ddf58e7ea88666dbd6..e47ae52c7a69cf7ded41de486bec997241a243a7 100644 (file)
@@ -1475,7 +1475,7 @@ RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
        return 0;
 }
 
        return 0;
 }
 
-RESULT eDVBServicePlay::radioText(ePtr<iRadioText> &ptr)
+RESULT eDVBServicePlay::rdsDecoder(ePtr<iRdsDecoder> &ptr)
 {
        ptr = this;
        return 0;
 {
        ptr = this;
        return 0;
@@ -1705,8 +1705,8 @@ int eDVBServicePlay::selectAudioStream(int i)
        if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type))
                return -4;
 
        if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type))
                return -4;
 
-       if (m_radiotext_parser)
-               m_radiotext_parser->start(program.audioStreams[i].pid);
+       if (m_rds_decoder)
+               m_rds_decoder->start(program.audioStreams[i].pid);
 
        if (m_dvb_service && !m_is_pvr)
        {
 
        if (m_dvb_service && !m_is_pvr)
        {
@@ -1743,20 +1743,81 @@ RESULT eDVBServicePlay::selectChannel(int i)
        return 0;
 }
 
        return 0;
 }
 
-std::string eDVBServicePlay::getRadioText(int x)
+std::string eDVBServicePlay::getText(int x)
 {
 {
-       if (m_radiotext_parser)
+       if (m_rds_decoder)
                switch(x)
                {
                switch(x)
                {
-                       case 0:
-                               return convertLatin1UTF8(m_radiotext_parser->getCurrentText());
+                       case RadioText:
+                               return convertLatin1UTF8(m_rds_decoder->getRadioText());
+                       case RtpText:
+                               return convertLatin1UTF8(m_rds_decoder->getRtpText());
                }
        return "";
 }
 
                }
        return "";
 }
 
-void eDVBServicePlay::radioTextUpdated()
+void eDVBServicePlay::rdsDecoderEvent(int what)
 {
 {
-       m_event((iPlayableService*)this, evUpdatedRadioText);
+       switch(what)
+       {
+               case eDVBRdsDecoder::RadioTextChanged:
+                       m_event((iPlayableService*)this, evUpdatedRadioText);
+                       break;
+               case eDVBRdsDecoder::RtpTextChanged:
+                       m_event((iPlayableService*)this, evUpdatedRtpText);
+                       break;
+               case eDVBRdsDecoder::RassInteractivePicMaskChanged:
+                       m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
+                       break;
+               case eDVBRdsDecoder::RecvRassSlidePic:
+                       m_event((iPlayableService*)this, evUpdatedRassSlidePic);
+                       break;
+       }
+}
+
+void eDVBServicePlay::showRassSlidePicture()
+{
+       if (m_rds_decoder)
+       {
+               if (m_decoder)
+               {
+                       std::string rass_slide_pic = m_rds_decoder->getRassSlideshowPicture();
+                       if (rass_slide_pic.length())
+                               m_decoder->showSinglePic(rass_slide_pic.c_str());
+                       else
+                               eDebug("empty filename for rass slide picture received!!");
+               }
+               else
+                       eDebug("no MPEG Decoder to show iframes avail");
+       }
+       else
+               eDebug("showRassSlidePicture called.. but not decoder");
+}
+
+void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
+{
+       if (m_rds_decoder)
+       {
+               if (m_decoder)
+               {
+                       std::string rass_interactive_pic = m_rds_decoder->getRassPicture(page, subpage);
+                       if (rass_interactive_pic.length())
+                               m_decoder->showSinglePic(rass_interactive_pic.c_str());
+                       else
+                               eDebug("empty filename for rass interactive picture %d/%d received!!", page, subpage);
+               }
+               else
+                       eDebug("no MPEG Decoder to show iframes avail");
+       }
+       else
+               eDebug("showRassInteractivePic called.. but not decoder");
+}
+
+ePyObject eDVBServicePlay::getRassInteractiveMask()
+{
+       if (m_rds_decoder)
+               return m_rds_decoder->getRassPictureMask();
+       Py_RETURN_NONE;
 }
 
 int eDVBServiceBase::getFrontendInfo(int w)
 }
 
 int eDVBServiceBase::getFrontendInfo(int w)
@@ -2089,11 +2150,11 @@ void eDVBServicePlay::switchToLive()
        m_decoder = 0;
        m_decode_demux = 0;
        m_teletext_parser = 0;
        m_decoder = 0;
        m_decode_demux = 0;
        m_teletext_parser = 0;
-       m_radiotext_parser = 0;
+       m_rds_decoder = 0;
        m_subtitle_parser = 0;
        m_new_dvb_subtitle_page_connection = 0;
        m_new_subtitle_page_connection = 0;
        m_subtitle_parser = 0;
        m_new_dvb_subtitle_page_connection = 0;
        m_new_subtitle_page_connection = 0;
-       m_radiotext_updated_connection = 0;
+       m_rds_decoder_event_connection = 0;
        m_video_event_connection = 0;
 
                /* free the timeshift service handler, we need the resources */
        m_video_event_connection = 0;
 
                /* free the timeshift service handler, we need the resources */
@@ -2113,11 +2174,11 @@ void eDVBServicePlay::switchToTimeshift()
        m_decode_demux = 0;
        m_decoder = 0;
        m_teletext_parser = 0;
        m_decode_demux = 0;
        m_decoder = 0;
        m_teletext_parser = 0;
-       m_radiotext_parser = 0;
+       m_rds_decoder = 0;
        m_subtitle_parser = 0;
        m_new_subtitle_page_connection = 0;
        m_new_dvb_subtitle_page_connection = 0;
        m_subtitle_parser = 0;
        m_new_subtitle_page_connection = 0;
        m_new_dvb_subtitle_page_connection = 0;
-       m_radiotext_updated_connection = 0;
+       m_rds_decoder_event_connection = 0;
        m_video_event_connection = 0;
 
        m_timeshift_active = 1;
        m_video_event_connection = 0;
 
        m_timeshift_active = 1;
@@ -2259,9 +2320,9 @@ void eDVBServicePlay::updateDecoder()
                                ePtr<iDVBDemux> data_demux;
                                if (!h.getDataDemux(data_demux))
                                {
                                ePtr<iDVBDemux> data_demux;
                                if (!h.getDataDemux(data_demux))
                                {
-                                       m_radiotext_parser = new eDVBRadioTextParser(data_demux);
-                                       m_radiotext_parser->connectUpdatedRadiotext(slot(*this, &eDVBServicePlay::radioTextUpdated), m_radiotext_updated_connection);
-                                       m_radiotext_parser->start(apid);
+                                       m_rds_decoder = new eDVBRdsDecoder(data_demux);
+                                       m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
+                                       m_rds_decoder->start(apid);
                                }
                        }
                }
                                }
                        }
                }
index 34ed9720f082393997e6dbdb521e1d16d090bb65..7c785c4efe51c050050f0a3f7608fe3266f04874 100644 (file)
@@ -89,7 +89,7 @@ class eDVBServicePlay: public eDVBServiceBase,
                public iAudioTrackSelection, public iAudioChannelSelection,
                public iSubserviceList, public iTimeshiftService,
                public iCueSheet, public iSubtitleOutput, public iAudioDelay,
                public iAudioTrackSelection, public iAudioChannelSelection,
                public iSubserviceList, public iTimeshiftService,
                public iCueSheet, public iSubtitleOutput, public iAudioDelay,
-               public iRadioText
+               public iRdsDecoder
 {
 DECLARE_REF(eDVBServicePlay);
 public:
 {
 DECLARE_REF(eDVBServicePlay);
 public:
@@ -112,7 +112,7 @@ public:
        RESULT cueSheet(ePtr<iCueSheet> &ptr);
        RESULT subtitle(ePtr<iSubtitleOutput> &ptr);
        RESULT audioDelay(ePtr<iAudioDelay> &ptr);
        RESULT cueSheet(ePtr<iCueSheet> &ptr);
        RESULT subtitle(ePtr<iSubtitleOutput> &ptr);
        RESULT audioDelay(ePtr<iAudioDelay> &ptr);
-       RESULT radioText(ePtr<iRadioText> &ptr);
+       RESULT rdsDecoder(ePtr<iRdsDecoder> &ptr);
 
                // iPauseableService
        RESULT pause();
 
                // iPauseableService
        RESULT pause();
@@ -144,8 +144,11 @@ public:
        int getCurrentChannel();
        RESULT selectChannel(int i);
 
        int getCurrentChannel();
        RESULT selectChannel(int i);
 
-               // iRadioText
-       std::string getRadioText(int i=0);
+               // iRdsDecoder
+       std::string getText(int i=0);
+       void showRassSlidePicture();
+       void showRassInteractivePic(int page, int subpage);
+       ePyObject getRassInteractiveMask();
 
                // iSubserviceList
        int getNumberOfSubservices();
 
                // iSubserviceList
        int getNumberOfSubservices();
@@ -267,9 +270,9 @@ private:
        void checkSubtitleTiming();
 
                /* radiotext */
        void checkSubtitleTiming();
 
                /* radiotext */
-       ePtr<eDVBRadioTextParser> m_radiotext_parser;
-       ePtr<eConnection> m_radiotext_updated_connection;
-       void radioTextUpdated();
+       ePtr<eDVBRdsDecoder> m_rds_decoder;
+       ePtr<eConnection> m_rds_decoder_event_connection;
+       void rdsDecoderEvent(int);
 
        ePtr<eConnection> m_video_event_connection;
        void video_event(struct iTSMPEGDecoder::videoEvent);
 
        ePtr<eConnection> m_video_event_connection;
        void video_event(struct iTSMPEGDecoder::videoEvent);
index 4245c816f0c823e0c39c104d46289e887e53e8eb..49964883004ff253975d364e3c3b25d3a556692d 100644 (file)
@@ -66,7 +66,7 @@ public:
        RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
        RESULT subtitle(ePtr<iSubtitleOutput> &ptr) { ptr = 0; return -1; }
        RESULT audioDelay(ePtr<iAudioDelay> &ptr) { ptr = 0; return -1; }
        RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
        RESULT subtitle(ePtr<iSubtitleOutput> &ptr) { ptr = 0; return -1; }
        RESULT audioDelay(ePtr<iAudioDelay> &ptr) { ptr = 0; return -1; }
-       RESULT radioText(ePtr<iRadioText> &ptr) { ptr = 0; return -1; }
+       RESULT rdsDecoder(ePtr<iRdsDecoder> &ptr) { ptr = 0; return -1; }
 
                // iPausableService
        RESULT pause();
 
                // iPausableService
        RESULT pause();
index 4a50b11f9c5e283e9a0d4181c36b2e397dc1acd6..b56a48588b48940c3c24b280a02afbe2edb62cb4 100644 (file)
@@ -69,7 +69,7 @@ public:
        RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
        RESULT subtitle(ePtr<iSubtitleOutput> &ptr) { ptr = 0; return -1; }
        RESULT audioDelay(ePtr<iAudioDelay> &ptr) { ptr = 0; return -1; }
        RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
        RESULT subtitle(ePtr<iSubtitleOutput> &ptr) { ptr = 0; return -1; }
        RESULT audioDelay(ePtr<iAudioDelay> &ptr) { ptr = 0; return -1; }
-       RESULT radioText(ePtr<iRadioText> &ptr) { ptr = 0; return -1; }
+       RESULT rdsDecoder(ePtr<iRdsDecoder> &ptr) { ptr = 0; return -1; }
 
                // iPausableService
        RESULT pause();
 
                // iPausableService
        RESULT pause();