Ticket #1684: mhegpatch.txt

File mhegpatch.txt, 22.8 KB (added by dm@…, 18 years ago)
Line 
1Index: libs/libmythtv/NuppelVideoPlayer.cpp
2===================================================================
3--- libs/libmythtv/NuppelVideoPlayer.cpp        (revision 9715)
4+++ libs/libmythtv/NuppelVideoPlayer.cpp        (working copy)
5@@ -41,6 +41,7 @@
6 #include "DVDRingBuffer.h"
7 #include "NuppelVideoRecorder.h"
8 #include "tv_play.h"
9+#include "interactivetv.h"
10 
11 extern "C" {
12 #include "vbitext/vbi.h"
13@@ -176,6 +177,8 @@
14 
15       // MHEG/MHI Interactive TV visible in OSD
16       itvVisible(false),
17+      interactiveTV(NULL),
18+      itvEnabled(false),
19 
20       // OSD stuff
21       osd(NULL),                    timedisplay(NULL),
22@@ -293,6 +296,9 @@
23             delete [] txtbuffers[i].buffer;
24     }
25 
26+    if (interactiveTV)
27+        delete interactiveTV;
28+
29     SetDecoder(NULL);
30 
31     if (FiltMan)
32@@ -318,6 +324,13 @@
33 
34     ShutdownYUVResize();
35 }
36+
37+InteractiveTV *NuppelVideoPlayer::GetInteractiveTV(void)
38+{
39+    if (!interactiveTV && osd && itvEnabled)
40+        interactiveTV = new InteractiveTV(this);
41+    return interactiveTV;
42+}
43 
44 void NuppelVideoPlayer::SetWatchingRecording(bool mode)
45 {
46@@ -524,6 +537,8 @@
47 
48     SetCaptionsEnabled(gContext->GetNumSetting("DefaultCCMode"));
49 
50+    itvEnabled = gContext->GetNumSetting("EnableMHEG");
51+
52     return true;
53 }
54 
55@@ -536,9 +551,9 @@
56         videoOutput->GetOSDBounds(total, visible, aspect, scaling);
57         if (osd)
58             osd->Reinit(total, frame_interval, visible, aspect, scaling);
59-        if (decoder)
60+        if (GetInteractiveTV())
61         {
62-            decoder->ITVReset(total, visible);
63+            GetInteractiveTV()->Reinit(total);
64             itvVisible = false;
65         }
66     }
67@@ -2325,7 +2340,7 @@
68         DisplayDVDButton();
69 
70     // handle Interactive TV
71-    if ((textDisplayMode & kDisplayITV) && GetDecoder())
72+    if (GetInteractiveTV() && GetDecoder())
73         itvVisible = GetDecoder()->ITVUpdate(itvVisible);
74 
75     // handle EIA-608 and Teletext
76@@ -2885,6 +2900,9 @@
77             tt_view->SetDisplaying(false);
78         }
79         GetOSD()->HideSet("teletext");
80+
81+        if (GetInteractiveTV())
82+            GetInteractiveTV()->Reinit(total);
83     }
84 
85     playing = true;
86@@ -5482,7 +5500,7 @@
87 
88 bool NuppelVideoPlayer::ITVHandleAction(const QString &action)
89 {
90-    if (!(textDisplayMode & kDisplayITV))
91+    if (! GetInteractiveTV())
92         return false;
93 
94     if (GetDecoder())
95@@ -5491,10 +5509,10 @@
96     return false;
97 }
98 
99-/* \fn NuppelVideoPlayer::ITVRestart(bool isLive)
100+/* \fn NuppelVideoPlayer::ITVRestart(uint chanid, int cardid, bool isLive)
101  * \brief Restart the MHEG/MHP engine.
102  */
103-void NuppelVideoPlayer::ITVRestart(uint chanid, bool isLiveTV)
104+void NuppelVideoPlayer::ITVRestart(uint chanid, int cardid, bool isLiveTV)
105 {
106     OSD *osd = GetOSD();
107     if (!GetDecoder() || !osd)
108@@ -5507,7 +5525,7 @@
109         return;
110     }
111 
112-    GetDecoder()->ITVRestart(chanid, isLiveTV);
113+    GetDecoder()->ITVRestart(chanid, cardid, isLiveTV);
114         
115     osd->ClearAll("interactive");
116     itvosd->Display();
117Index: libs/libmythtv/avformatdecoder.cpp
118===================================================================
119--- libs/libmythtv/avformatdecoder.cpp  (revision 9715)
120+++ libs/libmythtv/avformatdecoder.cpp  (working copy)
121@@ -275,7 +275,7 @@
122       ccd708(new CC708Decoder(parent)),
123       ttd(new TeletextDecoder()),
124       // Interactive TV
125-      itv(new InteractiveTV(parent)),
126+      itv(NULL),
127       selectedVideoIndex(-1),
128       // Audio
129       audioSamples(new short int[AVCODEC_MAX_AUDIO_FRAME_SIZE]),
130@@ -298,8 +298,8 @@
131 #ifdef CONFIG_DTS
132     allow_dts_passthru = gContext->GetNumSetting("DTSPassThru", false);
133 #endif
134-
135     audioIn.sample_size = -32; // force SetupAudioStream to run once
136+    itv = GetNVP()->GetInteractiveTV();
137 }
138 
139 AvFormatDecoder::~AvFormatDecoder()
140@@ -316,7 +316,6 @@
141     delete ccd608;
142     delete ccd708;
143     delete ttd;
144-    delete itv;
145     delete d;
146     if (audioSamples)
147         delete [] audioSamples;
148@@ -814,7 +813,8 @@
149 
150     {
151         int initialAudio = -1, initialVideo = -1;
152-        itv->GetInitialStreams(initialAudio, initialVideo);
153+        if (itv != NULL)
154+            itv->GetInitialStreams(initialAudio, initialVideo);
155         if (initialAudio >= 0)
156             SetAudioByComponentTag(initialAudio);
157         if (initialVideo >= 0)
158@@ -2107,12 +2107,6 @@
159     return ccd608->GetXDS(key);
160 }
161 
162-void AvFormatDecoder::ITVReset(const QRect &total, const QRect &visible)
163-{
164-    (void) visible;
165-    itv->Reinit(total);
166-}
167-
168 bool AvFormatDecoder::ITVUpdate(bool itvVisible)
169 {
170     QMutexLocker locker(&itvLock);
171@@ -2125,6 +2119,9 @@
172     if (!itvosd)
173         return itvVisible;
174 
175+    if (itv == NULL)
176+        return itvVisible;
177+
178     bool visible = false;
179     if (itv->ImageHasChanged() || !itvVisible)
180     {
181@@ -2142,17 +2139,21 @@
182 bool AvFormatDecoder::ITVHandleAction(const QString &action)
183 {
184     QMutexLocker locker(&itvLock);
185-    return itv->OfferKey(action);
186+    if (itv)
187+        return itv->OfferKey(action);
188+    else
189+        return false;
190 }
191 
192-/* \fn AvFormatDecoder::ITVRestart(bool isLive)
193+/* \fn AvFormatDecoder::ITVRestart(uint chanid, int cardid, bool isLive)
194  * \brief Restart the MHEG/MHP engine.
195  */
196-void AvFormatDecoder::ITVRestart(uint chanid, bool isLiveTV)
197+void AvFormatDecoder::ITVRestart(uint chanid, int cardid, bool isLiveTV)
198 {
199     QMutexLocker locker(&itvLock);
200-    QString chanidStr = (chanid) ? QString::number(chanid) : "-1";
201-    itv->Restart(chanidStr, isLiveTV);
202+    itv = GetNVP()->GetInteractiveTV();
203+    if (itv)
204+        itv->Restart(chanid, cardid, isLiveTV);
205 }
206 
207 bool AvFormatDecoder::SetAudioByComponentTag(int tag)
208Index: libs/libmythtv/decoderbase.h
209===================================================================
210--- libs/libmythtv/decoderbase.h        (revision 9715)
211+++ libs/libmythtv/decoderbase.h        (working copy)
212@@ -129,10 +129,9 @@
213     virtual QString GetXDS(const QString&) const { return QString::null; }
214 
215     // MHEG/MHI stuff
216-    virtual void ITVReset(const QRect& /*total*/, const QRect& /*visible*/) {}
217     virtual bool ITVUpdate(bool /*visible*/) { return false; }
218     virtual bool ITVHandleAction(const QString& /*action*/) { return false; }
219-    virtual void ITVRestart(uint /*chanid*/, bool /*livetv*/) {}
220+    virtual void ITVRestart(uint /*chanid*/, int /*cardid*/, bool /*livetv*/) {}
221 
222     virtual bool SetAudioByComponentTag(int) { return false; }
223     virtual bool SetVideoByComponentTag(int) { return false; }
224Index: libs/libmythtv/interactivetv.cpp
225===================================================================
226--- libs/libmythtv/interactivetv.cpp    (revision 9715)
227+++ libs/libmythtv/interactivetv.cpp    (working copy)
228@@ -17,7 +17,7 @@
229 InteractiveTV::InteractiveTV(NuppelVideoPlayer *nvp)
230     : m_context(new MHIContext(this)), m_nvp(nvp)
231 {
232-    Restart("", false);
233+    Restart(-1, 0, false);
234 
235     if (print_verbose_messages & VB_MHEG)
236     {
237@@ -35,9 +35,9 @@
238 }
239 
240 // Start or restart the MHEG engine.
241-void InteractiveTV::Restart(QString chanid, bool isLive)
242+void InteractiveTV::Restart(uint chanid, int cardid, bool isLive)
243 {
244-    m_context->Restart(chanid, isLive);
245+    m_context->Restart(chanid, cardid, isLive);
246 }
247 
248 // Called by the video player to see if the image needs to be updated
249Index: libs/libmythtv/NuppelVideoPlayer.h
250===================================================================
251--- libs/libmythtv/NuppelVideoPlayer.h  (revision 9715)
252+++ libs/libmythtv/NuppelVideoPlayer.h  (working copy)
253@@ -92,7 +92,7 @@
254     kDisplayCC708               = 0x10,
255     kDisplayNUVCaptions         = kDisplayNUVTeletextCaptions | kDisplayCC608,
256     kDisplayAllCaptions         = 0x1f,
257-    kDisplayITV                 = 0x20,
258+//    kDisplayITV                 = 0x20,
259     kDisplayTeletextMenu        = 0x40,
260 };
261 
262@@ -209,6 +209,7 @@
263     char        *GetScreenGrab(int secondsin, int &buflen,
264                                int &vw, int &vh, float &ar);
265     LiveTVChain *GetTVChain(void)             { return livetvchain; }
266+    InteractiveTV *GetInteractiveTV(void);
267 
268     // Start/Reset/Stop playing
269     void StartPlaying(void);
270@@ -348,7 +349,7 @@
271 
272     // MHEG/MHI stream selection
273     bool ITVHandleAction(const QString &action);
274-    void ITVRestart(uint chanid, bool isLiveTV);
275+    void ITVRestart(uint chanid, int cardid, bool isLiveTV);
276     bool SetAudioByComponentTag(int tag);
277     bool SetVideoByComponentTag(int tag);
278 
279@@ -617,6 +618,8 @@
280 
281     // Support for MHEG/MHI
282     bool       itvVisible;
283+    InteractiveTV *interactiveTV;
284+    bool       itvEnabled;
285 
286     // OSD stuff
287     OSD      *osd;
288Index: libs/libmythtv/tv_play.cpp
289===================================================================
290--- libs/libmythtv/tv_play.cpp  (revision 9715)
291+++ libs/libmythtv/tv_play.cpp  (working copy)
292@@ -210,6 +210,7 @@
293     REG_KEY("ITV Menu", "MENUYELLOW", "Menu Yellow", "F4");
294     REG_KEY("ITV Menu", "MENUBLUE",   "Menu Blue",   "F5");
295     REG_KEY("ITV Menu", "TEXTEXIT",   "Menu Exit",   "F6");
296+    REG_KEY("ITV Menu", "MENUTEXT",   "Menu Text",   "F7");
297 /*
298   keys already used:
299 
300@@ -234,7 +235,7 @@
301   Global:          F1,
302   Playback: Ctrl-B,                  F7,F8,F9,F10,F11
303   Teletext            F2,F3,F4,F5,F6,F7,F8
304-  ITV                 F2,F3,F4,F5,F6
305+  ITV                 F2,F3,F4,F5,F6,F7
306  */
307 }
308 
309@@ -1925,7 +1926,7 @@
310     }
311 
312     // Interactive television
313-    if (activenvp && (activenvp->GetCaptionMode() == kDisplayITV))
314+    if (activenvp && activenvp->GetInteractiveTV())
315     {
316         QStringList itv_actions;
317         if (gContext->GetMainWindow()->TranslateKeyPress(
318@@ -3766,6 +3767,8 @@
319     // If activenvp is main nvp, show input in on-screen-display
320     if (nvp && activenvp == nvp)
321         UpdateOSDInput();
322+
323+    ITVRestart(true);
324 }
325 
326 void TV::ToggleInputs(void)
327@@ -7054,6 +7057,7 @@
328 void TV::ITVRestart(bool isLive)
329 {
330     uint chanid = 0;
331+    int cardid = 0;
332 
333     if (activenvp != nvp || paused || !GetOSD())
334         return;
335@@ -7061,9 +7065,13 @@
336     pbinfoLock.lock();
337     if (playbackinfo)
338         chanid = playbackinfo->chanid.toUInt();
339+
340+    if (activerecorder)
341+        cardid = activerecorder->GetRecorderNumber();
342+
343     pbinfoLock.unlock();
344 
345-    nvp->ITVRestart(chanid, isLive);
346+    nvp->ITVRestart(chanid, cardid, isLive);
347 }
348 
349 /* vim: set expandtab tabstop=4 shiftwidth=4: */
350Index: libs/libmythtv/mhi.h
351===================================================================
352--- libs/libmythtv/mhi.h        (revision 9715)
353+++ libs/libmythtv/mhi.h        (working copy)
354@@ -45,7 +45,7 @@
355     void QueueDSMCCPacket(unsigned char *data, int length, int componentTag,
356         unsigned carouselId, int dataBroadcastId);
357     /// Restart the MHEG engine.
358-    void Restart(QString chanid, bool isLive);
359+    void Restart(uint chanid, int cardid, bool isLive);
360     // Offer a key press.  Returns true if it accepts it.
361     // This will depend on the current profile.
362     bool OfferKey(QString key);
363@@ -164,6 +164,7 @@
364 
365     int              m_currentChannel;
366     bool             m_isLive;
367+    int              m_currentCard;
368 
369     int              m_audioTag;
370     int              m_videoTag;
371Index: libs/libmythtv/interactivetv.h
372===================================================================
373--- libs/libmythtv/interactivetv.h      (revision 9715)
374+++ libs/libmythtv/interactivetv.h      (working copy)
375@@ -15,7 +15,7 @@
376     InteractiveTV(NuppelVideoPlayer *nvp);
377     virtual ~InteractiveTV();
378 
379-    void Restart(QString chanid, bool isLive);
380+    void Restart(uint chanid, int cardid, bool isLive);
381     // Process an incoming DSMCC packet.
382     void ProcessDSMCCSection(unsigned char *data, int length,
383                              int componentTag, unsigned carouselId,
384Index: libs/libmythtv/avformatdecoder.h
385===================================================================
386--- libs/libmythtv/avformatdecoder.h    (revision 9715)
387+++ libs/libmythtv/avformatdecoder.h    (working copy)
388@@ -136,10 +136,9 @@
389     virtual QString GetXDS(const QString&) const;
390 
391     // MHEG stuff
392-    virtual void ITVReset(const QRect &total, const QRect& visible);
393     virtual bool ITVUpdate(bool itvVisible);
394     virtual bool ITVHandleAction(const QString&);
395-    virtual void ITVRestart(uint /*chanid*/, bool /*livetv*/);
396+    virtual void ITVRestart(uint /*chanid*/, int cardid, bool /*livetv*/);
397 
398     virtual bool SetAudioByComponentTag(int tag);
399     virtual bool SetVideoByComponentTag(int tag);
400Index: libs/libmythtv/mhi.cpp
401===================================================================
402--- libs/libmythtv/mhi.cpp      (revision 9715)
403+++ libs/libmythtv/mhi.cpp      (working copy)
404@@ -27,8 +27,9 @@
405       m_stopped(false),     m_updated(false),
406       m_displayWidth(StdDisplayWidth), m_displayHeight(StdDisplayHeight),
407       m_face_loaded(false), m_currentChannel(-1),
408-      m_isLive(false),      m_audioTag(-1),
409-      m_videoTag(-1),       m_tuningTo(-1)
410+      m_isLive(false),      m_currentCard(0),
411+      m_audioTag(-1),       m_videoTag(-1),
412+      m_tuningTo(-1)
413 {
414     m_display.setAutoDelete(true);
415     m_dsmccQueue.setAutoDelete(true);
416@@ -100,12 +101,10 @@
417 
418 
419 // Start or restart the MHEG engine.
420-void MHIContext::Restart(QString chanid, bool isLive)
421+void MHIContext::Restart(uint chanid, int cardid, bool isLive)
422 {
423-    bool ok = false;
424-    m_currentChannel = chanid.toInt(&ok, 10);
425-    if (!ok)
426-        m_currentChannel = -1;
427+    m_currentChannel = chanid;
428+    m_currentCard = cardid;
429 
430     if (m_currentChannel == m_tuningTo && m_currentChannel != -1)
431     {
432@@ -191,6 +190,8 @@
433 
434             // Run the engine and find out how long to pause.
435             toWait = m_engine->RunAll();
436+            if (toWait < 0)
437+                return;
438         } while (key != 0);
439 
440         if (toWait > 1000 || toWait == 0)
441@@ -329,7 +330,7 @@
442         action = 102;
443     else if (key == "MENUBLUE")
444         action = 103;
445-    else if (key == "TOGGLECC")
446+    else if (key == "MENUTEXT")
447         action = 104;
448 
449     if (action != 0)
450@@ -473,14 +474,18 @@
451         int serviceID = list[2].toInt(&ok, 16);
452         if (!ok)
453             return -1;
454+        // We only return channels that match the current capture card.
455         if (list[1].isEmpty()) // TransportID is not specified
456         {
457             query.prepare(
458                 "SELECT chanid "
459-                "FROM channel, dtv_multiplex "
460-                "WHERE networkid       = :NETID AND"
461-                "      channel.mplexid = dtv_multiplex.mplexid AND "
462-                "      serviceid       = :SERVICEID");
463+                "FROM channel, dtv_multiplex, cardinput, capturecard "
464+                "WHERE networkid        = :NETID AND"
465+                "      channel.mplexid  = dtv_multiplex.mplexid AND "
466+                "      serviceid        = :SERVICEID AND "
467+                "      channel.sourceid = cardinput.sourceid AND "
468+                "      cardinput.cardid = capturecard.cardid AND "
469+                "      cardinput.cardid = :CARDID");
470         }
471         else
472         {
473@@ -489,15 +494,19 @@
474                 return -1;
475             query.prepare(
476                 "SELECT chanid "
477-                "FROM channel, dtv_multiplex "
478-                "WHERE networkid       = :NETID AND"
479-                "      channel.mplexid = dtv_multiplex.mplexid AND "
480-                "      serviceid       = :SERVICEID AND "
481-                "      transportid     = :TRANSID");
482+                "FROM channel, dtv_multiplex, cardinput, capturecard "
483+                "WHERE networkid        = :NETID AND"
484+                "      channel.mplexid  = dtv_multiplex.mplexid AND "
485+                "      serviceid        = :SERVICEID AND "
486+                "      transportid      = :TRANSID AND "
487+                "      channel.sourceid = cardinput.sourceid AND "
488+                "      cardinput.cardid = capturecard.cardid AND "
489+                "      cardinput.cardid = :CARDID");
490             query.bindValue(":TRANSID", transportID);
491         }
492         query.bindValue(":NETID", netID);
493         query.bindValue(":SERVICEID", serviceID);
494+        query.bindValue(":CARDID", m_currentCard);
495         if (query.exec() && query.isActive() && query.next())
496         {
497             int nResult = query.value(0).toInt();
498@@ -512,9 +521,13 @@
499         if (!ok) return -1;
500         MSqlQuery query(MSqlQuery::InitCon());
501         query.prepare("SELECT chanid "
502-                      "FROM channel "
503-                      "WHERE channum = :CHAN");
504+                      "FROM channel, cardinput, capturecard "
505+                      "WHERE channum = :CHAN AND "
506+                      "      channel.sourceid = cardinput.sourceid AND "
507+                      "      cardinput.cardid = capturecard.cardid AND "
508+                      "      cardinput.cardid = :CARDID");
509         query.bindValue(":CHAN", channelNo);
510+        query.bindValue(":CARDID", m_currentCard);
511         if (query.exec() && query.isActive() && query.next())
512             return query.value(0).toInt();
513     }
514Index: libs/libmythfreemheg/Engine.cpp
515===================================================================
516--- libs/libmythfreemheg/Engine.cpp     (revision 9715)
517+++ libs/libmythfreemheg/Engine.cpp     (working copy)
518@@ -81,9 +81,12 @@
519         // if one of the containing directories is updated.
520         if (! Launch(startObj))
521         {
522-            startObj.m_GroupId.Copy(MHOctetString("~//startup"));
523-            if (! Launch(startObj))
524-                return CONTENT_CHECK_TIME; // Perhaps we should return failure here.
525+             startObj.m_GroupId.Copy(MHOctetString("~//startup"));
526+             if (! Launch(startObj))
527+             {
528+                 MHLOG(MHLogError, "Unable to launch application");
529+                 return -1;
530+             }
531         }
532         m_fBooting = false;
533     }
534@@ -188,40 +191,46 @@
535     if (! m_Context->GetCarouselData(csPath, text)) return false;
536 
537     m_fInTransition = true; // Starting a transition
538-    if (CurrentApp()) {
539-        if (fIsSpawn) { // Run the CloseDown actions.
540-            AddActions(CurrentApp()->m_CloseDown);
541-            RunActions();
542+    try {
543+        if (CurrentApp()) {
544+            if (fIsSpawn) { // Run the CloseDown actions.
545+                AddActions(CurrentApp()->m_CloseDown);
546+                RunActions();
547+            }
548+            if (CurrentScene()) CurrentScene()->Destruction(this);
549+            CurrentApp()->Destruction(this);
550+            if (! fIsSpawn) m_ApplicationStack.remove(); // Pop and delete the current app.
551         }
552-        if (CurrentScene()) CurrentScene()->Destruction(this);
553-        CurrentApp()->Destruction(this);
554-        if (! fIsSpawn) m_ApplicationStack.remove(); // Pop and delete the current app.
555-    }
556 
557-    MHApplication *pProgram = (MHApplication*)ParseProgram(text);
558+        MHApplication *pProgram = (MHApplication*)ParseProgram(text);
559 
560-    if ((__mhlogoptions & MHLogScenes) && __mhlogStream != 0) { // Print it so we know what's going on.
561-        pProgram->PrintMe(__mhlogStream, 0);
562-    }
563+        if ((__mhlogoptions & MHLogScenes) && __mhlogStream != 0) { // Print it so we know what's going on.
564+            pProgram->PrintMe(__mhlogStream, 0);
565+        }
566 
567-    if (! pProgram->m_fIsApp) MHERROR("Expected an application");
568+        if (! pProgram->m_fIsApp) MHERROR("Expected an application");
569 
570-    // Save the path we use for this app.
571-    pProgram->m_Path = csPath; // Record the path
572-    int nPos = pProgram->m_Path.findRev('/');
573-    if (nPos < 0) pProgram->m_Path = "";
574-    else pProgram->m_Path = pProgram->m_Path.left(nPos);
575-    // Have now got the application.
576-    m_ApplicationStack.push(pProgram);
577+        // Save the path we use for this app.
578+        pProgram->m_Path = csPath; // Record the path
579+        int nPos = pProgram->m_Path.findRev('/');
580+        if (nPos < 0) pProgram->m_Path = "";
581+        else pProgram->m_Path = pProgram->m_Path.left(nPos);
582+       // Have now got the application.
583+       m_ApplicationStack.push(pProgram);
584 
585-    // This isn't in the standard as far as I can tell but we have to do this because
586-    // we may have events referring to the old application.
587-    m_EventQueue.clear();
588+       // This isn't in the standard as far as I can tell but we have to do this because
589+       // we may have events referring to the old application.
590+       m_EventQueue.clear();
591 
592-    // Activate the application. ....
593-    CurrentApp()->Activation(this);
594-    m_fInTransition = false; // The transition is complete
595-    return true;
596+       // Activate the application. ....
597+       CurrentApp()->Activation(this);
598+       m_fInTransition = false; // The transition is complete
599+       return true;
600+    }
601+    catch (...) {
602+       m_fInTransition = false; // The transition is complete
603+       return false;
604+    }
605 }
606 
607 void MHEngine::Quit()
608@@ -579,6 +588,7 @@
609 // Redraw an area of the display.  This will be called via the context from Redraw.
610 void MHEngine::DrawDisplay(QRegion toDraw)
611 {
612+    if (m_fBooting) return;
613     int nTopStack = CurrentApp() == NULL ? -1 : CurrentApp()->m_DisplayStack.Size()-1;
614     DrawRegion(toDraw, nTopStack);
615 }
616Index: libs/libmythfreemheg/Logging.h
617===================================================================
618--- libs/libmythfreemheg/Logging.h      (revision 9715)
619+++ libs/libmythfreemheg/Logging.h      (working copy)
620@@ -28,25 +28,8 @@
621 #undef ASSERT
622 #endif
623 
624-#ifdef _DEBUG
625-
626-#define THIS_FILE          __FILE__
627-#define ASSERT(f) \
628-    do \
629-    { \
630-        if (!(f)) { Q_ASSERT(f); _asm { int 3 } } \
631-    } while (0) \
632-
633-#define VERIFY(f)          ASSERT(f)
634-#else
635 #define ASSERT(f)          Q_ASSERT(f)
636-#define VERIFY(f)          ((void)(f))
637-#endif
638 
639-// A number of MHEG actions do not appear to actually be used.  ASSERT(UNTESTED("Action name")) is used to give
640-// some idea of those that still need to be tested.
641-#define UNTESTED(x) (false)
642-
643 extern int __mhlogoptions;
644 extern void __mhlog(QString logtext);
645 extern FILE *__mhlogStream;
646@@ -61,7 +44,6 @@
647 do { \
648     if (MHLogError & __mhlogoptions) \
649         __mhlog(__text); \
650-    ASSERT(false); \
651     throw "Failed"; \
652 } while (0)
653 
654Index: programs/mythfrontend/globalsettings.cpp
655===================================================================
656--- programs/mythfrontend/globalsettings.cpp    (revision 9715)
657+++ programs/mythfrontend/globalsettings.cpp    (working copy)
658@@ -1080,6 +1080,18 @@
659     return gc;
660 }
661 
662+static HostCheckBox *EnableMHEG()
663+{
664+    HostCheckBox *gc = new HostCheckBox("EnableMHEG");
665+    gc->setLabel(QObject::tr("Enable Interactive TV"));
666+    gc->setValue(false);
667+    gc->setHelpText(QObject::tr(
668+                        "If enabled, interactive TV applications (MHEG) will "
669+                        "be activated.  This is used for teletext and logos for "
670+                        "radio and channels that are currently off-air."));
671+    return gc;
672+}
673+
674 static HostCheckBox *PersistentBrowseMode()
675 {
676     HostCheckBox *gc = new HostCheckBox("PersistentBrowseMode");
677@@ -3327,6 +3339,7 @@
678     osd->addChild(CCBackground());
679     osd->addChild(DefaultCCMode());
680     osd->addChild(PersistentBrowseMode());
681+    osd->addChild(EnableMHEG());
682     addChild(osd);
683 
684     addChild(OSDCC708Settings());