Ticket #1469: deint_patch.txt

File deint_patch.txt, 21.1 KB (added by anonymous, 20 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