Index: themes/defaultosd/osd.xml
===================================================================
--- themes/defaultosd/osd.xml	(revision 16344)
+++ themes/defaultosd/osd.xml	(working copy)
@@ -345,4 +345,16 @@
     </textarea>
   </container>
 
+  <container name="now_playing" priority="20" fademovement="0,0">
+    <image name="background">
+      <filename>now_playing.png</filename>
+      <position>85,124</position>
+    </image>
+    <textarea name="playing">
+      <area>290,150,240,220</area>
+      <font>notifyfont</font>
+      <multiline>yes</multiline>
+    </textarea>
+  </container>
+
 </mythosdtheme>
Index: themes/blueosd/osd.xml
===================================================================
--- themes/blueosd/osd.xml	(revision 16344)
+++ themes/blueosd/osd.xml	(working copy)
@@ -349,6 +349,17 @@
       <fcnfont name="infofontgray" function="inactive"></fcnfont>
     </listtreemenu>
   </container>
-    
 
+  <container name="now_playing" priority="20" fademovement="0,0">
+    <image name="background">
+      <filename>now_playing.png</filename>
+      <position>85,124</position>
+    </image>
+    <textarea name="playing">
+      <area>290,150,240,220</area>
+      <font>infofont</font>  
+      <multiline>yes</multiline>
+    </textarea>
+  </container>    
+
 </mythosdtheme>
Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.cpp	(revision 16344)
+++ libs/libmythtv/NuppelVideoPlayer.cpp	(working copy)
@@ -198,6 +198,10 @@
       interactiveTV(NULL),
       itvEnabled(false),
 
+      // Now Playing visible in OSD
+      has_now_playing(false),
+      now_playing_changed(false),
+
       // OSD stuff
       osd(NULL),                    timedisplay(NULL),
       dialogname(""),               dialogtype(0),
@@ -272,8 +276,11 @@
     commnotifyamount = gContext->GetNumSetting("CommNotifyAmount",0);
     decode_extra_audio=gContext->GetNumSetting("DecodeExtraAudio", 0);
     itvEnabled       = gContext->GetNumSetting("EnableMHEG", 0);
+    nowPlayEnabled   = gContext->GetNumSetting("EnableNowPlaying", 0);
     db_prefer708     = gContext->GetNumSetting("Prefer708Captions", 1);
 
+    osd_now_play_timeout = gContext->GetNumSetting("OSDNowPlayingTimeout", 10);
+
     lastIgnoredManualSkip = QDateTime::currentDateTime().addSecs(-10);
 
     bzero(&txtbuffers, sizeof(txtbuffers));
@@ -2710,6 +2717,9 @@
             ExpireSubtitles();
     }
 
+    if (has_now_playing && nowPlayEnabled)
+        DisplayNowPlaying();
+
     // handle scan type changes
     AutoDeint(frame);
 
@@ -3150,6 +3160,11 @@
     ringBuffer->Pause();
     ringBuffer->WaitForPause();
 
+    SetHasNowPlaying(false);
+
+    if (osd)
+        osd->ResetNowPlaying();
+
     ClearSubtitles();
 
     livetvchain->SetProgram(pginfo);
@@ -6821,6 +6836,62 @@
         osd->ClearTextSubtitles();
 }
 
+/** \fn NuppelVideoPlayer::SetHasNowPlaying(void)
+ *  \brief Enables displaying of Now Playing content
+ */
+void NuppelVideoPlayer::SetHasNowPlaying(bool has)
+{
+    if (nowPlayEnabled)
+    {
+        has_now_playing = has;
+
+        if (has_now_playing != has)
+        {
+            QString which = has ? "Enabling" : "Disabling";
+            VERBOSE(VB_PLAYBACK, LOC + QString("%1 Now Playing processing")
+                    .arg(which));
+        }
+    }
+}
+
+/** \fn NuppelVideoPlayer::HasNowPlaying(void)
+ *  \brief Returns bool stream has Now Playing
+ */
+bool NuppelVideoPlayer::HasNowPlaying(void)
+{
+    return has_now_playing;
+}
+
+/** \fn NuppelVideoPlayer::DisplayNowPlaying(void)
+ *  \brief Displays Now Playing text
+ */
+void NuppelVideoPlayer::DisplayNowPlaying()
+{
+    QMutexLocker locker(&nowPlayingLock);
+
+    if (!nowPlayEnabled ||
+        !has_now_playing ||
+        !now_playing_changed)
+        return;
+
+    QString text = "Now Playing:\n\n";
+
+    // Skip if the first section is empty
+    QString t = now_playing[0].simplifyWhiteSpace();
+    if (t.isEmpty())
+        return;
+
+    int i = 0;
+
+    for (QStringList::Iterator it = now_playing.begin();
+         it != now_playing.end(); ++it )
+        text.append(*it + "\n");
+
+    osd->SetNowPlaying(text, osd_now_play_timeout);
+
+    now_playing_changed = false;
+}
+
 /** \fn NuppelVideoPlayer::ExpireSubtitles(void)
  *  \brief Discard non-displayed subtitles.
  */
@@ -6910,6 +6981,18 @@
     subtitleLock.unlock();
 }
 
+/** \fn void NuppelVideoPlayer::SetNowPlaying(const QStringList playing&)
+ *  \brief Set the Now Playing text in the OSD.
+ */
+void NuppelVideoPlayer::SetNowPlaying(const QStringList &playing)
+{
+    nowPlayingLock.lock();
+    now_playing = QDeepCopy<QStringList>(playing);
+    nowPlayingLock.unlock();
+
+    now_playing_changed = true;
+}
+
 /** \fn NuppelVideoPlayer::SetDecoder(DecoderBase*)
  *  \brief Sets the stream decoder, deleting any existing recorder.
  */
Index: libs/libmythtv/avformatdecoder.cpp
===================================================================
--- libs/libmythtv/avformatdecoder.cpp	(revision 16344)
+++ libs/libmythtv/avformatdecoder.cpp	(working copy)
@@ -437,6 +437,8 @@
     allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
     max_channels = (uint) gContext->GetNumSetting("MaxChannels", 2);
 
+    nowPlayEnabled = gContext->GetNumSetting("EnableNowPlaying", 0);
+
     audioIn.sample_size = -32; // force SetupAudioStream to run once
     itv = GetNVP()->GetInteractiveTV();
 
@@ -1430,6 +1432,8 @@
     tracks[kTrackTypeTeletextCaptions].clear();
     selectedVideoIndex = -1;
 
+    GetNVP()->SetHasNowPlaying(false);
+
     map<int,uint> lang_sub_cnt;
     map<int,uint> lang_aud_cnt;
 
@@ -1655,8 +1659,21 @@
             }
             case CODEC_TYPE_DATA:
             {
-                ScanTeletextCaptions(i);
-                bitrate += enc->bit_rate;
+                switch(enc->codec_id)
+                {
+                    case CODEC_ID_DSMCC_B:
+                        bitrate += enc->bit_rate;
+                        break;
+                    case CODEC_ID_DVB_VBI:
+                        ScanTeletextCaptions(i);
+                        bitrate += enc->bit_rate;
+                        break;
+                    case CODEC_ID_DVB_PRIVSEC:
+                        if (enc->bit_rate == 0)
+                            enc->bit_rate = 175; // 1 TS packet - 13 byte header
+                        break;
+                }
+
                 VERBOSE(VB_PLAYBACK, LOC + QString("data codec (%1)")
                         .arg(codec_type_string(enc->codec_type)));
                 break;
@@ -2423,6 +2440,64 @@
     }
 }
 
+void AvFormatDecoder::ProcessPrivSecDataPacket(const AVPacket *pkt)
+{
+    if (!GetNVP())
+        return;
+
+    if (nowPlayEnabled)
+    {
+        QStringList sections;
+        bool changed = false;
+        uint non_ascii = 0;
+        uint end = 0;
+
+        uint8_t *buf = pkt->data;
+        uint len = pkt->size;
+
+        if (!len || len > 188)
+            return;
+
+        // Sanity checks
+        for (uint x = 0; x < len; x++)
+            if (buf[x] == 0x00)
+                len = end = x;
+            else if (buf[x] > 0x7f)
+                non_ascii++;
+
+        if ((non_ascii / len) > .4)
+            return;
+
+        if (!end)
+            return;
+
+        QString text = (const char*)buf;
+
+        if (text.contains(0x0a) > 10)
+            return;
+
+        GetNVP()->SetHasNowPlaying(true);
+
+        for (int i = 0; i < text.contains(0x0a); i++) {
+            QString section = text.section(0x0a, i, i);
+            if (section == "") section = " ";
+
+            if ((i > now_playing.size()) ||
+                now_playing[i].compare(section))
+            {
+                sections << section;
+                changed = true;
+            }
+        }
+
+        if (changed)
+        {
+            now_playing = sections;
+            GetNVP()->SetNowPlaying(sections);
+        }
+    }
+}
+
 /** \fn AvFormatDecoder::ProcessVBIDataPacket(const AVStream*, const AVPacket*)
  *  \brief Process ivtv proprietary embedded vertical blanking
  *         interval captions.
@@ -3314,6 +3389,16 @@
             continue;
         }
 
+        if (len > 0 &&
+            curstream->codec->codec_type == CODEC_TYPE_DATA &&
+            curstream->codec->codec_id   == CODEC_ID_DVB_PRIVSEC)
+        {
+            ProcessPrivSecDataPacket(pkt);
+
+            av_free_packet(pkt);
+            continue;
+        }
+
         // we don't care about other data streams
         if (curstream->codec->codec_type == CODEC_TYPE_DATA)
         {
Index: libs/libmythtv/tv_play.h
===================================================================
--- libs/libmythtv/tv_play.h	(revision 16344)
+++ libs/libmythtv/tv_play.h	(working copy)
@@ -444,6 +444,7 @@
     bool    arrowAccel;
     int     osd_general_timeout;
     int     osd_prog_info_timeout;
+    int     osd_now_play_timeout;
 
     enum commSkipMode autoCommercialSkip;
     bool    tryUnflaggedSkip;
@@ -683,6 +684,9 @@
     // Network Control stuff
     QValueList<QString> networkControlCommands;
     QMutex ncLock;
+
+    // Now Playing
+    bool nowPlayEnabled;
 };
 
 #endif
Index: libs/libmythtv/NuppelVideoPlayer.h
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.h	(revision 16344)
+++ libs/libmythtv/NuppelVideoPlayer.h	(working copy)
@@ -299,6 +299,12 @@
                      long long timecode, char type);
     void AddAVSubtitle(const AVSubtitle& subtitle);
 
+    // Now Playing data
+    void SetHasNowPlaying(bool has);
+    void SetNowPlaying(const QStringList &playing);
+    void DisplayNowPlaying();
+    bool HasNowPlaying(void);
+
     // Closed caption and teletext stuff
     uint GetCaptionMode(void) const { return textDisplayMode; }
     void ResetCaptions(uint mode_override = 0);
@@ -640,6 +646,7 @@
 
     // Support for captions, teletext, etc. decoded by libav
     QMutex    subtitleLock;
+    QMutex    nowPlayingLock;
     /// This allows us to enable captions/subtitles later if the streams
     /// are not immediately available when the video starts playing.
     bool      textDesired;
@@ -671,6 +678,12 @@
     bool       itvEnabled;
     QMutex     itvLock;
 
+    // Support for Now Playing
+    bool       nowPlayEnabled;
+    QStringList now_playing;
+    bool       has_now_playing;
+    bool       now_playing_changed;
+
     // OSD stuff
     OSD      *osd;
     OSDSet   *timedisplay;
@@ -727,6 +740,8 @@
     long long  lastCommSkipStart;
     time_t     lastSkipTime;
 
+    int osd_now_play_timeout;
+
     long long  deleteframe;
     bool       hasdeletetable;
     bool       hasblanktable;
Index: libs/libmythtv/osd.h
===================================================================
--- libs/libmythtv/osd.h	(revision 16344)
+++ libs/libmythtv/osd.h	(working copy)
@@ -80,6 +80,8 @@
                      const QString &callsign, const QString &iconpath,
                      int length);
     void SetChannumText(const QString &text, int length);
+    void SetNowPlaying(const QString &playing, int length);
+    void ResetNowPlaying(void);
 
     // CC-608 and DVB text captions (not DVB/DVD subtitles).
     void AddCCText(const QString &text, int x, int y, int color, 
Index: libs/libmythtv/tv_play.cpp
===================================================================
--- libs/libmythtv/tv_play.cpp	(revision 16344)
+++ libs/libmythtv/tv_play.cpp	(working copy)
@@ -508,6 +508,7 @@
       jumptime(0), smartChannelChange(false),
       MuteIndividualChannels(false), arrowAccel(false),
       osd_general_timeout(2), osd_prog_info_timeout(3),
+      osd_now_play_timeout(10),
       autoCommercialSkip(CommSkipOff), tryUnflaggedSkip(false),
       smartForward(false), stickykeys(0),
       ff_rew_repos(1.0f), ff_rew_reverse(false),
@@ -635,6 +636,7 @@
     persistentbrowsemode = gContext->GetNumSetting("PersistentBrowseMode", 0);
     osd_general_timeout  = gContext->GetNumSetting("OSDGeneralTimeout", 2);
     osd_prog_info_timeout= gContext->GetNumSetting("OSDProgramInfoTimeout", 3);
+    osd_now_play_timeout = gContext->GetNumSetting("OSDNowPlayingTimeout", 10);
     autoCommercialSkip   = (enum commSkipMode)gContext->GetNumSetting(
                             "AutoCommercialSkip", CommSkipOff);
     tryUnflaggedSkip     = gContext->GetNumSetting("TryUnflaggedSkip", 0);
@@ -642,6 +644,7 @@
     stickykeys           = gContext->GetNumSetting("StickyKeys");
     ff_rew_repos         = gContext->GetNumSetting("FFRewReposTime", 100)/100.0;
     ff_rew_reverse       = gContext->GetNumSetting("FFRewReverse", 1);
+    nowPlayEnabled       = gContext->GetNumSetting("EnableNowPlaying", 0);
     int def[8] = { 3, 5, 10, 20, 30, 60, 120, 180 };
     for (uint i = 0; i < sizeof(def)/sizeof(def[0]); i++)
         ff_rew_speeds.push_back(
@@ -5263,6 +5266,9 @@
     osd->ClearAllText(whichInfo);
     osd->HideAll();
     osd->SetText(whichInfo, infoMap, osd_prog_info_timeout);
+
+    if (nowPlayEnabled && nvp->HasNowPlaying())
+        osd->SetNowPlaying("", osd_now_play_timeout);
 }
 
 void TV::UpdateOSDSeekMessage(const QString &mesg, int disptime)
Index: libs/libmythtv/avformatdecoder.h
===================================================================
--- libs/libmythtv/avformatdecoder.h	(revision 16344)
+++ libs/libmythtv/avformatdecoder.h	(working copy)
@@ -187,6 +187,7 @@
     void MpegPreProcessPkt(AVStream *stream, AVPacket *pkt);
     void H264PreProcessPkt(AVStream *stream, AVPacket *pkt);
 
+    void ProcessPrivSecDataPacket(const AVPacket *pkt);
     void ProcessVBIDataPacket(const AVStream *stream, const AVPacket *pkt);
     void ProcessDVBDataPacket(const AVStream *stream, const AVPacket *pkt);
     void ProcessDSMCCPacket(const AVStream *stream, const AVPacket *pkt);
@@ -278,6 +279,10 @@
     bool mpeg_seq_end_seen;
     /// \brief contains last dvd still frame decoded
     AVPacket *lastDVDStillFrame;
+
+    // Now Playing
+    QStringList now_playing;
+    bool nowPlayEnabled;
 };
 
 #endif
Index: libs/libmythtv/osd.cpp
===================================================================
--- libs/libmythtv/osd.cpp	(revision 16344)
+++ libs/libmythtv/osd.cpp	(working copy)
@@ -1939,6 +1939,75 @@
     osdlock.unlock();
 }
 
+void OSD::ResetNowPlaying(void)
+{
+    osdlock.lock();
+
+    QString my_name = "now_playing";
+
+    OSDSet *container = GetSet(my_name);
+    if (container)
+    {
+        container->Hide();
+
+        OSDTypeText *text = (OSDTypeText *)container->GetType("playing");
+        if (text)
+            text->SetText("");
+
+        m_setsvisible = false;
+        changed = true;
+    }
+
+    osdlock.unlock();
+}
+
+void OSD::SetNowPlaying(const QString &playing, int length)
+{
+    osdlock.lock();
+
+    QString my_name = "now_playing";
+
+    OSDSet *container = GetSet(my_name);
+    if (!container)
+    {
+        OSDSet *set = GetSet("now_playing");
+        if (!set)
+        {
+            VERBOSE(VB_IMPORTANT, "couldn't find now_playing dialog");
+            osdlock.unlock();
+            return;
+        }
+
+        container = new OSDSet(*set);
+        container->SetName(my_name);
+        container->SetCache(true);
+        container->SetPriority(20);
+        container->SetAllowFade(true);
+        AddSet(container, my_name, false);
+    }
+
+    if (container)
+    {
+        OSDTypeText *text = (OSDTypeText *)container->GetType("playing");
+
+        if (!playing.isNull() && !playing.isEmpty())
+            if (text)
+                text->SetText(playing);
+
+        if (length > 0)
+            container->DisplayFor(length * 1000000);
+        else
+            container->Display();
+
+        m_setsvisible = true;
+        changed = true;
+
+        //VERBOSE(VB_PLAYBACK, QString("NOW PLAYING: '%1'").arg(text->GetText()));
+    }
+
+    osdlock.unlock();
+}
+
 void OSD::SetChannumText(const QString &text, int length)
 {
     osdlock.lock();
Index: libs/libavcodec/myth_utils.c
===================================================================
--- libs/libavcodec/myth_utils.c	(revision 16344)
+++ libs/libavcodec/myth_utils.c	(working copy)
@@ -203,6 +203,9 @@
 
         case CODEC_ID_DSMCC_B:          return "DSMCC_B";
 
+            /* private data codecs */
+        case CODEC_ID_DVB_PRIVSEC:      return "DVB_PRIVSEC";
+
         case CODEC_ID_MPEG2TS:          return "MPEG2TS";
     }
     return "Unknown Codec ID";
Index: libs/libavcodec/avcodec.h
===================================================================
--- libs/libavcodec/avcodec.h	(revision 16344)
+++ libs/libavcodec/avcodec.h	(working copy)
@@ -289,6 +289,9 @@
     /* DSMCC codec */
     CODEC_ID_DSMCC_B,
 
+    /* Private Data */
+    CODEC_ID_DVB_PRIVSEC= 0x19000,
+
     CODEC_ID_MPEG2TS= 0x20000, /* _FAKE_ codec to indicate a raw MPEG-2 TS
                                 * stream (only used by libavformat) */
 };
Index: libs/libavformat/mpegts.c
===================================================================
--- libs/libavformat/mpegts.c	(revision 16344)
+++ libs/libavformat/mpegts.c	(working copy)
@@ -866,6 +866,7 @@
         case STREAM_TYPE_AUDIO_AAC:
         case STREAM_TYPE_AUDIO_AC3:
         case STREAM_TYPE_AUDIO_DTS:
+        case STREAM_TYPE_PRIVATE_SECTION:
         case STREAM_TYPE_PRIVATE_DATA:
         case STREAM_TYPE_VBI_DVB:
         case STREAM_TYPE_SUBTITLE_DVB:
@@ -1454,6 +1455,10 @@
             codec_type = CODEC_TYPE_DATA;
             codec_id = CODEC_ID_DSMCC_B;
             break;
+        case STREAM_TYPE_PRIVATE_SECTION:
+            codec_type = CODEC_TYPE_DATA;
+            codec_id = CODEC_ID_DVB_PRIVSEC;
+            break; 
         case STREAM_TYPE_PRIVATE_DATA:
         default:
             if (code >= 0x1c0 && code <= 0x1df) {
@@ -1553,6 +1558,17 @@
                     if (pes->total_size)
                         pes->total_size += 6;
                     pes->pes_header_size = pes->header[8] + 9;
+                } else if (pes->header[0] == 0x00 && pes->header[1] == 0xd3 &&
+                           pes->header[2] == 0xb0) {
+                    /* private sections */
+                    if (!pes->st) {
+                        /* allocate stream */
+                        new_pes_av_stream(pes, code);
+                    }
+                    if (pes->header[7] != 0x00 && pes->header[7] != 0x01)
+                         pes->state = MPEGTS_PESHEADER_FILL;
+                    else
+                         pes->state = MPEGTS_PAYLOAD; /* No PTS/DTS info */
                 } else {
                     /* otherwise, it should be a table */
                     /* skip packet */
Index: programs/mythfrontend/globalsettings.cpp
===================================================================
--- programs/mythfrontend/globalsettings.cpp	(revision 16344)
+++ programs/mythfrontend/globalsettings.cpp	(working copy)
@@ -1571,6 +1571,16 @@
     return gs;
 }
 
+static HostSpinBox *OSDNowPlayingTimeout()
+{
+    HostSpinBox *gs = new HostSpinBox("OSDNowPlayingTimeout", 1, 60, 1);
+    gs->setLabel(QObject::tr("Now Playing OSD time-out"));
+    gs->setValue(10);
+    gs->setHelpText(QObject::tr("If available, length of time the on-screen "
+                    "display will display Now Playing information."));
+    return gs;
+}
+
 static HostSpinBox *ThemeCacheSize()
 {
     HostSpinBox *gs = new HostSpinBox("ThemeCacheSize", 1, 1000, 1, true);
@@ -1898,6 +1908,18 @@
     return gc;
 }
 
+static HostCheckBox *EnableNowPlaying()
+{
+    HostCheckBox *gc = new HostCheckBox("EnableNowPlaying");
+    gc->setLabel(QObject::tr("Enable Now Playing Information"));
+    gc->setValue(false);
+    gc->setHelpText(QObject::tr(
+                        "If enabled and available, Now Playing "
+                        "information will be activated. This is used for "
+                        "some DVB radio channels."));
+    return gc;
+}
+
 static HostCheckBox *PersistentBrowseMode()
 {
     HostCheckBox *gc = new HostCheckBox("PersistentBrowseMode");
@@ -4694,9 +4716,11 @@
     osd->addChild(new ThemeSelector("OSDTheme"));
     osd->addChild(OSDGeneralTimeout());
     osd->addChild(OSDProgramInfoTimeout());
+    osd->addChild(OSDNowPlayingTimeout());
     osd->addChild(OSDFont());
     osd->addChild(OSDThemeFontSizeType());
     osd->addChild(EnableMHEG());
+    osd->addChild(EnableNowPlaying());
     osd->addChild(PersistentBrowseMode());
     addChild(osd);
 
