Ticket #1469: deint_patch.txt

File deint_patch.txt, 21.1 KB (added by anonymous, 15 years ago)
Line 
1Index: libs/libmythtv/NuppelVideoPlayer.h
2===================================================================
3--- libs/libmythtv/NuppelVideoPlayer.h  (revision 9292)
4+++ libs/libmythtv/NuppelVideoPlayer.h  (working copy)
5@@ -136,7 +136,7 @@
6     void SetBookmark(void);
7     void SetKeyframeDistance(int keyframedistance);
8     void SetVideoParams(int w, int h, double fps, int keydist,
9-                        float a = 1.33333, FrameScanType scan = kScan_Ignore);
10+                        float a = 1.33333);
11     void SetAudioParams(int bits, int channels, int samplerate, bool passthru);
12     void SetEffDsp(int dsprate);
13     void SetFileLength(int total, int frames);
14@@ -144,6 +144,17 @@
15     void ClearBookmark(void);
16     void SetForcedAspectRatio(int mpeg2_aspect_value, int letterbox_permission);
17 
18+    // functions for user to force deinterlace settings
19+    enum DeintMode {
20+        DeintAuto,
21+        DeintOn,
22+        DeintOff,
23+        DeintUnknown
24+    };
25+    void      CycleDeinterlaceMode();
26+    void      SetDeinterlaceMode(DeintMode mode);
27+    DeintMode GetDeinterlaceMode();
28+
29     void SetOSDFontName(const QString osdfonts[22], const QString &prefix);
30     void SetOSDThemeName(const QString themename);
31 
32@@ -505,7 +516,12 @@
33     mutable bool     limitKeyRepeat;
34     bool     errored;
35     int      m_DeintSetting;
36+    int      frame_scan_cnt;
37 
38+    void EnableDeinterlace();
39+    void DisableDeinterlace();
40+    void SetDeinterlaceMode(DeintMode new_mode, DeintMode cur_mode);
41+
42     // Bookmark stuff
43     long long bookmarkseek;
44     bool      previewFromBookmark;
45@@ -544,6 +560,7 @@
46     float    forced_video_aspect;
47     /// Video (input) Scan Type (interlaced, progressive, detect, ignore...)
48     FrameScanType m_scan;
49+    bool m_scan_locked;
50     /// Video (input) Number of frames between key frames (often inaccurate)
51     int keyframedist;
52 
53Index: libs/libmythtv/nuppeldecoder.cpp
54===================================================================
55--- libs/libmythtv/nuppeldecoder.cpp    (revision 9292)
56+++ libs/libmythtv/nuppeldecoder.cpp    (working copy)
57@@ -204,7 +204,7 @@
58 
59     GetNVP()->SetVideoParams(fileheader.width, fileheader.height,
60                              fileheader.fps, fileheader.keyframedist,
61-                             fileheader.aspect, kScan_Detect);
62+                             fileheader.aspect);
63 
64     video_width = fileheader.width;
65     video_height = fileheader.height;
66Index: libs/libmythtv/NuppelVideoPlayer.cpp
67===================================================================
68--- libs/libmythtv/NuppelVideoPlayer.cpp        (revision 9292)
69+++ libs/libmythtv/NuppelVideoPlayer.cpp        (working copy)
70@@ -141,6 +141,7 @@
71       hasFullPositionMap(false),    limitKeyRepeat(false),
72       errored(false),
73       m_DeintSetting(0),
74+      frame_scan_cnt(0),
75       // Bookmark stuff
76       bookmarkseek(0),              previewFromBookmark(false),
77       // Seek
78@@ -154,7 +155,8 @@
79       video_width(0), video_height(0), video_size(0),
80       video_frame_rate(29.97f), video_aspect(4.0f / 3.0f),
81       forced_video_aspect(-1),
82-      m_scan(kScan_Detect), keyframedist(30),
83+      m_scan(kScan_Interlaced), m_scan_locked(false),
84+      keyframedist(30),
85       // RingBuffer stuff
86       filename("output.nuv"), weMadeBuffer(false), ringBuffer(NULL),
87       // Prebuffering (RingBuffer) control
88@@ -685,9 +687,130 @@
89      }
90 }
91 
92+/** \fn NuppelVideoPlayer::EnableDeinterlace(void)
93+ *  \brief enable current deinterlacing method
94+ */
95+void NuppelVideoPlayer::EnableDeinterlace(void)
96+{
97+    m_scan = kScan_Interlaced;
98+
99+    videoOutput->EnableDeinterlace();
100+
101+    if (videoOutput->NeedsDoubleFramerate())
102+    {
103+        videosync->SetFrameInterval(frame_interval, true);
104+        m_double_framerate = true;
105+        m_can_double       = true;
106+    }
107+
108+    VERBOSE(VB_PLAYBACK, "Enabled deinterlacing");
109+}
110+
111+/** \fn NuppelVideoPlayer::DisableDeinterlace(void)
112+ *  \brief leave current deinterlacing method in place, but disable
113+ */
114+void NuppelVideoPlayer::DisableDeinterlace(void)
115+{
116+    m_scan = kScan_Progressive;
117+
118+    if (m_double_framerate)
119+    {
120+        m_double_framerate = false;
121+        m_can_double = false;
122+        videosync->SetFrameInterval(frame_interval, false);
123+    }
124+    videoOutput->DisableDeinterlace();
125+
126+    VERBOSE(VB_PLAYBACK, "Disabled deinterlacing");
127+}
128+
129+void NuppelVideoPlayer::CycleDeinterlaceMode()
130+{
131+    // Cycle through autodetect, deinterlace forced on, deinterlace forced off
132+    //
133+    // Autodetect is m_scan_locked == false
134+    // deinterlace on is kScan_Interlaced, m_scan_locked = true
135+    // deinterlace off is kScan_Progressive, m_scan_locked = true
136+    //
137+    if (!m_scan_locked)
138+    {
139+        // previous state autodetect
140+        //
141+        // next state forced on
142+        SetDeinterlaceMode(DeintOn);
143+    }
144+    else if (m_scan == kScan_Interlaced)
145+    {
146+        // previous state forced on
147+        //
148+        // next state forced off
149+        SetDeinterlaceMode(DeintOff);
150+    }
151+    else if (m_scan == kScan_Progressive)
152+    {
153+        // previous state forced off
154+        //
155+        // next state autodetect
156+        SetDeinterlaceMode(DeintAuto);
157+    }
158+    else
159+    {
160+        VERBOSE(VB_IMPORTANT, "Unknown deinterlace state, no change made");
161+    }
162+}
163+
164+void NuppelVideoPlayer::SetDeinterlaceMode(DeintMode new_mode)
165+{
166+    FrameScanType new_scan = kScan_Ignore;
167+
168+    if (new_mode == DeintAuto)
169+    {
170+        if (frame_scan_cnt > 0)
171+            new_scan = kScan_Interlaced;
172+        if (frame_scan_cnt < 0)
173+            new_scan = kScan_Progressive;
174+    }
175+    else if (new_mode == DeintOn)
176+        new_scan = kScan_Interlaced;
177+    else if (new_mode == DeintOff)
178+        new_scan = kScan_Progressive;
179+    else
180+        return; // shouldn't happen
181+
182+    videofiltersLock.lock();
183+
184+    m_scan_locked = (new_mode != DeintAuto);
185+
186+    if (new_scan != m_scan)
187+    {
188+        if (new_scan == kScan_Interlaced)
189+            EnableDeinterlace();
190+        if (new_scan == kScan_Progressive)
191+            DisableDeinterlace();
192+    }
193+       
194+    videofiltersLock.unlock();
195+}
196+
197+NuppelVideoPlayer::DeintMode NuppelVideoPlayer::GetDeinterlaceMode()
198+{
199+    DeintMode mode = DeintUnknown;
200+
201+    if (m_scan_locked)
202+    {
203+        if (m_scan == kScan_Interlaced)
204+            mode = DeintOn;
205+        if (m_scan == kScan_Progressive)
206+            mode = DeintOff;
207+    }
208+    else
209+        mode = DeintAuto;
210+
211+    return mode;
212+}
213+
214 void NuppelVideoPlayer::SetVideoParams(int width, int height, double fps,
215-                                       int keyframedistance, float aspect,
216-                                       FrameScanType scan)
217+                                       int keyframedistance, float aspect)
218 {
219     if (width == 0 || height == 0 || isnan(aspect) || isnan(fps))
220         return;
221@@ -715,45 +838,6 @@
222 
223     if (videoOutput)
224         ReinitVideo();
225-
226-    if (IsErrored())
227-        return;
228-
229-    videofiltersLock.lock();
230-
231-    m_scan = detectInterlace(scan, m_scan, video_frame_rate, video_height);
232-    VERBOSE(VB_PLAYBACK, QString("Interlaced: %1  video_height: %2  fps: %3")
233-            .arg(toQString(m_scan)).arg(video_height)
234-            .arg(fps));
235-
236-    // Set up deinterlacing in the video output method
237-    m_double_framerate = false;
238-    if (videoOutput)
239-    {
240-        videoOutput->SetupDeinterlace(false);
241-        if ((m_scan == kScan_Interlaced)        &&
242-            m_DeintSetting                      &&
243-            videoOutput->SetupDeinterlace(true) &&
244-            videoOutput->NeedsDoubleFramerate())
245-        {
246-            m_double_framerate = true;
247-            m_can_double = true;
248-        }
249-    }
250-
251-    // Make sure video sync can double frame rate
252-    if (videosync && m_double_framerate)
253-    {
254-        videosync->SetFrameInterval(frame_interval, m_double_framerate);
255-        if (videosync->UsesFrameInterval())
256-        {
257-            VERBOSE(VB_IMPORTANT, "Video sync method can't support double "
258-                    "framerate (refresh rate too low for bob deint)");
259-            FallbackDeint();
260-        }
261-    }
262-
263-    videofiltersLock.unlock();
264 }
265 
266 void NuppelVideoPlayer::SetFileLength(int total, int frames)
267@@ -2254,7 +2338,40 @@
268     else if (osdHasSubtitles || nonDisplayedSubtitles.size() > 20)
269         ClearSubtitles();
270 
271+    if (frame)
272+    {
273+        if (frame->interlaced_frame)
274+        {
275+            if (frame_scan_cnt < 0)
276+            {
277+                VERBOSE(VB_PLAYBACK, LOC + "interlaced  frame seen after " << (-1 * frame_scan_cnt) << " progressive frames");
278+                frame_scan_cnt = 0;
279+            }
280+            frame_scan_cnt += 1;
281+        }
282+        else
283+        {
284+            if (frame_scan_cnt > 0)
285+            {
286+                VERBOSE(VB_PLAYBACK, LOC + "progressive frame seen after " << frame_scan_cnt << " interlaced  frames");
287+                frame_scan_cnt = 0;
288+            }
289+            frame_scan_cnt -= 1;
290+           
291+        }
292+       
293+        if ((frame_scan_cnt % 480) == 0)
294+        {
295+            int temp = (frame_scan_cnt < 0) ? (-1 * frame_scan_cnt) : frame_scan_cnt;
296+            VERBOSE(VB_PLAYBACK, LOC + "" << temp << " " << ((frame_scan_cnt < 0) ? "progressive" : "interlaced") << " frames");
297+        }
298+    }
299+
300     videofiltersLock.lock();
301+    if (!m_scan_locked && m_DeintSetting && (m_scan == kScan_Progressive) && (frame_scan_cnt >  2))
302+      EnableDeinterlace();
303+    if (!m_scan_locked && (m_scan == kScan_Interlaced) && (frame_scan_cnt < -2))
304+      DisableDeinterlace();
305     videoOutput->ProcessFrame(frame, osd, videoFilters, pipplayer);
306     videofiltersLock.unlock();
307 
308@@ -2290,6 +2407,20 @@
309     if (videoOutput)
310         rf_int = videoOutput->GetRefreshRate();
311 
312+    // Default to Interlaced playback to allocate the deinterlacer structures
313+    m_scan = kScan_Interlaced;
314+
315+    // Enable autodetection of interlaced/progressive from video stream
316+    m_scan_locked = false;
317+
318+    // init to non-Bob
319+    m_double_framerate = false;
320+    m_can_double = false;
321+
322+    // Init to a value which will cause an immediate switch to
323+    // progressive if the first frame is progressive.
324+    frame_scan_cnt = 2;
325+
326     if (using_null_videoout)
327     {
328         videosync = new USleepVideoSync(videoOutput, (int)fr_int, 0, false);
329@@ -2297,8 +2428,8 @@
330     else if (videoOutput)
331     {
332         // Set up deinterlacing in the video output method
333-        m_double_framerate = false;
334-        if (m_scan == kScan_Interlaced && m_DeintSetting &&
335+        if (m_scan == kScan_Interlaced &&
336+            m_DeintSetting &&
337             videoOutput->SetupDeinterlace(true) &&
338             videoOutput->NeedsDoubleFramerate())
339         {
340Index: libs/libmythtv/avformatdecoder.cpp
341===================================================================
342--- libs/libmythtv/avformatdecoder.cpp  (revision 9292)
343+++ libs/libmythtv/avformatdecoder.cpp  (working copy)
344@@ -495,7 +495,7 @@
345     // Skip all the desired number of skipFrames
346     for (;skipFrames > 0 && !ateof; skipFrames--)
347     {
348-       GetFrame(0);
349+        GetFrame(0);
350         if (decoded_video_frame)
351             GetNVP()->DiscardVideoFrame(decoded_video_frame);
352     }
353@@ -957,7 +957,7 @@
354     }
355 
356     GetNVP()->SetVideoParams(align_width, align_height, fps,
357-                             keyframedist, aspect_ratio, kScan_Detect);
358+                             keyframedist, aspect_ratio);
359 }
360 
361 #ifdef USING_XVMC
362@@ -1783,8 +1783,7 @@
363                 align_dimensions(context, awidth, aheight);
364 
365                 GetNVP()->SetVideoParams(awidth, aheight, seqFPS,
366-                                         keyframedist, aspect,
367-                                         kScan_Detect);
368+                                         keyframedist, aspect);
369 
370                 current_width  = width;
371                 current_height = height;
372Index: libs/libmythtv/tv_play.cpp
373===================================================================
374--- libs/libmythtv/tv_play.cpp  (revision 9292)
375+++ libs/libmythtv/tv_play.cpp  (working copy)
376@@ -185,6 +185,7 @@
377     REG_KEY("TV Playback", "JUMPREC", "Display menu of recorded programs to jump to", "");
378     REG_KEY("TV Playback", "SIGNALMON", "Monitor Signal Quality", "F7");
379     REG_KEY("TV Playback", "JUMPTODVDROOTMENU", "Jump to the DVD Root Menu", "");   
380+    REG_KEY("TV Playback", "CYCLEDEINTERLACE", "Cycle deinterlacing state through auto, on, off", "");   
381 
382     REG_KEY("TV Editing", "CLEARMAP", "Clear editing cut points", "C,Q,Home");
383     REG_KEY("TV Editing", "INVERTMAP", "Invert Begin/End cut points", "I");
384@@ -2242,6 +2243,8 @@
385                 DoTogglePictureAttribute();
386             }
387         }
388+        else if (action == "CYCLEDEINTERLACE")
389+            nvp->CycleDeinterlaceMode();
390         else if (action == "ARBSEEK")
391         {
392             if (asInputMode)
393@@ -5691,6 +5694,12 @@
394 
395         ChangeTimeStretch(0, !floatRead);   // just display
396     }
397+    else if (action == "DEINTERLACEAUTO")
398+      nvp->SetDeinterlaceMode(NuppelVideoPlayer::DeintAuto);
399+    else if (action == "DEINTERLACEON")
400+      nvp->SetDeinterlaceMode(NuppelVideoPlayer::DeintOn);
401+    else if (action == "DEINTERLACEOFF")
402+      nvp->SetDeinterlaceMode(NuppelVideoPlayer::DeintOff);
403     else if (action.left(15) == "TOGGLEAUDIOSYNC")
404         ChangeAudioSync(0);
405     else if (action.left(11) == "TOGGLESLEEP")
406@@ -6045,6 +6054,14 @@
407                                  (speedX100 == 150) ? 1 : 0, NULL,
408                                  "STRETCHGROUP");
409 
410+    // add deinterlacing mode setting to menu
411+
412+    NuppelVideoPlayer::DeintMode deint_mode = activenvp ? activenvp->GetDeinterlaceMode() : NuppelVideoPlayer::DeintUnknown;
413+    item = new OSDGenericTree(treeMenu, tr("Deinterlace Mode"), "DEINTERLACEMODE");
414+    subitem = new OSDGenericTree(item, tr("Auto"), "DEINTERLACEAUTO", (deint_mode == NuppelVideoPlayer::DeintAuto) ? 1 : 0, NULL, "DEINTERLACEGROUP");
415+    subitem = new OSDGenericTree(item, tr("On"),   "DEINTERLACEON",   (deint_mode == NuppelVideoPlayer::DeintOn) ?   1 : 0, NULL, "DEINTERLACEGROUP");
416+    subitem = new OSDGenericTree(item, tr("Off"),  "DEINTERLACEOFF",  (deint_mode == NuppelVideoPlayer::DeintOff) ?  1 : 0, NULL, "DEINTERLACEGROUP");
417+   
418     // add sleep items to menu
419 
420     item = new OSDGenericTree(treeMenu, tr("Sleep"), "TOGGLESLEEPON");
421Index: libs/libmythtv/videoout_null.cpp
422===================================================================
423--- libs/libmythtv/videoout_null.cpp    (revision 9292)
424+++ libs/libmythtv/videoout_null.cpp    (working copy)
425@@ -109,6 +109,20 @@
426     return true;
427 }
428 
429+bool VideoOutputNull::SetupDeinterlace(bool i, const QString& ovrf)
430+{
431+  return !i;
432+}
433+void VideoOutputNull::EnableDeinterlace()
434+{
435+  return;
436+}
437+void VideoOutputNull::DisableDeinterlace()
438+{
439+  return;
440+}
441+
442+
443 void VideoOutputNull::Exit(void)
444 {
445     if (XJ_started)
446Index: libs/libmythtv/videooutbase.cpp
447===================================================================
448--- libs/libmythtv/videooutbase.cpp     (revision 9292)
449+++ libs/libmythtv/videooutbase.cpp     (working copy)
450@@ -181,7 +181,8 @@
451     m_deinterlaceBeforeOSD(true),
452 
453     // Various state variables
454-    embedding(false),         needrepaint(false),
455+    embedding(false),         
456+    needrepaint(false),       needbobrepaint(false),
457     allowpreviewepg(true),    framesPlayed(0),
458 
459     errored(false)
460@@ -279,13 +280,6 @@
461 bool VideoOutput::SetupDeinterlace(bool interlaced,
462                                    const QString& overridefilter)
463 {
464-    if (VideoOutputNull *null = dynamic_cast<VideoOutputNull *>(this))
465-    {
466-        (void)null;
467-        // null vidout doesn't deinterlace
468-        return !interlaced;
469-    }
470-
471     if (m_deinterlacing == interlaced)
472         return m_deinterlacing;
473 
474@@ -343,6 +337,42 @@
475 }
476 
477 /**
478+ * \fn VideoOutput::EnableDeinterlace()
479+ * \brief Attempts to enable deinterlacing with existing deinterlace method.
480+ */
481+void VideoOutput::EnableDeinterlace()
482+{
483+    if (m_deinterlacing)
484+        return;
485+
486+    // if no deinterlacer allocated, attempt allocate one
487+    if (!m_deintFiltMan || !m_deintFilter)
488+    {
489+      (void)SetupDeinterlace(true);
490+      return;
491+    }
492+
493+    m_deinterlacing = true;
494+
495+    if (m_deintfiltername == "bobdeint")
496+        m_deinterlaceBeforeOSD = false;
497+    else
498+        m_deinterlaceBeforeOSD = true;
499+
500+    return;
501+}
502+
503+/**
504+ * \fn VideoOutput::DisableDeinterlace()
505+ * \brief Disables deinterlacing without deallocating existing deinterlace method.
506+ */
507+void VideoOutput::DisableDeinterlace()
508+{
509+    m_deinterlacing = false;
510+    return;
511+}
512+
513+/**
514  * \fn VideoOutput::NeedsDoubleFramerate() const
515  * \brief Should Prepare() and Show() be called twice for every ProcessFrame().
516  *
517Index: libs/libmythtv/videoout_xv.h
518===================================================================
519--- libs/libmythtv/videoout_xv.h        (revision 9292)
520+++ libs/libmythtv/videoout_xv.h        (working copy)
521@@ -51,6 +51,8 @@
522               int winx, int winy, int winw, int winh, WId embedid = 0);
523     bool SetupDeinterlace(bool interlaced, const QString& ovrf="");
524     bool ApproveDeintFilter(const QString& filtername) const;
525+    void EnableDeinterlace();
526+    void DisableDeinterlace();
527 
528     void ProcessFrame(VideoFrame *frame, OSD *osd,
529                       FilterChain *filterList,
530Index: libs/libmythtv/videoout_xv.cpp
531===================================================================
532--- libs/libmythtv/videoout_xv.cpp      (revision 9292)
533+++ libs/libmythtv/videoout_xv.cpp      (working copy)
534@@ -1383,6 +1383,19 @@
535     return deint;
536 }
537 
538+void VideoOutputXv::EnableDeinterlace()
539+{
540+    VideoOutput::EnableDeinterlace();
541+    return;
542+}
543+
544+void VideoOutputXv::DisableDeinterlace()
545+{
546+    VideoOutput::DisableDeinterlace();
547+    needbobrepaint = (m_deintfiltername == "bobdeint");
548+    return;
549+}
550+
551 /**
552  * \fn VideoOutput::NeedsDoubleFramerate() const
553  * Approves bobdeint filter for XVideo and XvMC surfaces,
554@@ -2469,7 +2482,7 @@
555         return;
556     }
557 
558-    if (needrepaint && (VideoOutputSubType() >= XVideo))
559+    if ((needrepaint || needbobrepaint) && (VideoOutputSubType() >= XVideo))
560         DrawUnusedRects(/* don't do a sync*/false);
561 
562     if (VideoOutputSubType() > XVideo)
563@@ -2483,10 +2496,10 @@
564 void VideoOutputXv::DrawUnusedRects(bool sync)
565 {
566     // boboff assumes the smallest interlaced resolution is 480 lines - 5%
567-    int boboff = (int)round(((double)disphoff) / 456 - 0.00001);
568-    boboff = (m_deinterlacing && m_deintfiltername == "bobdeint") ? boboff : 0;
569+    int boboff_raw = (int)round(((double)disphoff) / 456 - 0.00001);
570+    int boboff = (m_deinterlacing && m_deintfiltername == "bobdeint") ? boboff_raw : 0;
571 
572-    if (chroma_osd && chroma_osd->GetImage() && needrepaint)
573+    if (chroma_osd && chroma_osd->GetImage() && (needrepaint || needbobrepaint/*needed?*/))
574     {
575         X11L;
576         XShmPutImage(XJ_disp, XJ_curwin, XJ_gc, chroma_osd->GetImage(),
577@@ -2496,17 +2509,30 @@
578         X11U;
579 
580         needrepaint = false;
581+        needbobrepaint = false;
582         return;
583     }
584 
585     X11L;
586 
587-    if (xv_draw_colorkey && needrepaint)
588+    if (xv_draw_colorkey && (needrepaint || needbobrepaint))
589     {
590         XSetForeground(XJ_disp, XJ_gc, xv_colorkey);
591-        XFillRectangle(XJ_disp, XJ_curwin, XJ_gc, dispx,
592-                       dispy + boboff, dispw, disph - 2 * boboff);
593+        if (needrepaint)
594+            XFillRectangle(XJ_disp, XJ_curwin, XJ_gc, dispx,
595+                           dispy + boboff, dispw, disph - 2 * boboff);
596+        else { /* needbobrepaint */
597+            // we enter here if bobdeinterlacing was just turned off.
598+            // in this case we need to fill the rectangles outside the
599+            // smaller bob region with the colorkey.
600+            XFillRectangle(XJ_disp, XJ_curwin, XJ_gc, dispx,
601+                           dispy, dispw, boboff_raw);
602+            XFillRectangle(XJ_disp, XJ_curwin, XJ_gc, dispx,
603+                           disph - 2 * boboff_raw, dispw, disph);
604+        }
605+
606         needrepaint = false;
607+        needbobrepaint = false;
608     }
609 
610     // Draw black in masked areas
611Index: libs/libmythtv/videooutbase.h
612===================================================================
613--- libs/libmythtv/videooutbase.h       (revision 9292)
614+++ libs/libmythtv/videooutbase.h       (working copy)
615@@ -132,6 +132,8 @@
616     virtual bool SetupDeinterlace(bool i, const QString& ovrf="");
617     virtual bool NeedsDoubleFramerate(void) const;
618     virtual bool ApproveDeintFilter(const QString& filtername) const;
619+    virtual void EnableDeinterlace();
620+    virtual void DisableDeinterlace();
621 
622     virtual void PrepareFrame(VideoFrame *buffer, FrameScanType) = 0;
623     virtual void Show(FrameScanType) = 0;
624@@ -363,6 +365,7 @@
625     // Various state variables
626     bool embedding;
627     bool needrepaint;
628+    bool needbobrepaint;
629     bool allowpreviewepg;
630     long long framesPlayed;
631 
632Index: libs/libmythtv/videoout_null.h
633===================================================================
634--- libs/libmythtv/videoout_null.h      (revision 9292)
635+++ libs/libmythtv/videoout_null.h      (working copy)
636@@ -11,6 +11,11 @@
637 
638     bool Init(int width, int height, float aspect, WId winid,
639               int winx, int winy, int winw, int winh, WId embedid = 0);
640+
641+    bool SetupDeinterlace(bool i, const QString& ovrf="");
642+    void EnableDeinterlace();
643+    void DisableDeinterlace();
644+
645     void PrepareFrame(VideoFrame *buffer, FrameScanType);
646     void Show(FrameScanType );
647