[mythtv] [patch] bugfix for 166 & 167

Daniel Thor Kristjansson danielk at mrl.nyu.edu
Tue Feb 1 22:26:24 UTC 2005


I decided to go looking for bugs in the database since there is a
release forthcoming. I found 166 and went about finding a better
fix than running "xvattr -a XV_COLORKEY -v 0" because I knew that
solution made the video show through on my konsole...

This turned out to be caused by two problems. First, didn't set the 
frame size properly when painting the second frame. But fixing this
leaves the line at the top. The only way to fix this is to disable
the "XV_AUTOPAINT_COLORKEY" attribute, and not paint that line
at the top to the colorkey color. Since this was being enabled
before videoout_xv is told if the video is interlaced, I broke
out the colorkey code from Init() into InitColorKey(). Then I just
call this again after any call to VideoOutput::SetupDeinterlace().

But this investigation led me to discover that bug 167 wasn't
actually a duplicate. This is caused by always moving the second
frame down 1 line. In fact we should be moving it down half a line in 
the source resolution. If the source is 480 lines, and our output is 
1080 lines, then this is 2 lines in the output resolution.

When I tried to apply these same fixes to videoout_xvmc the fields
were displayed in the wrong order, so I fixed this as well. But 
otherwise that fix is basically the same.

-- Daniel
-------------- next part --------------
Index: libs/libmythtv/videoout_xv.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/videoout_xv.cpp,v
retrieving revision 1.113
diff -u -r1.113 videoout_xv.cpp
--- libs/libmythtv/videoout_xv.cpp	21 Jan 2005 06:30:35 -0000	1.113
+++ libs/libmythtv/videoout_xv.cpp	1 Feb 2005 21:39:42 -0000
@@ -503,6 +503,24 @@
     pauseFrame.qstride = 0;
     pauseFrame.frameNumber = scratchFrame->frameNumber;
 
+    InitColorKey();
+    
+    if (gContext->GetNumSetting("UseOutputPictureControls", 0))
+    {
+        ChangePictureAttribute(kPictureAttribute_Brightness, brightness);
+        ChangePictureAttribute(kPictureAttribute_Contrast, contrast);
+        ChangePictureAttribute(kPictureAttribute_Colour, colour);
+        ChangePictureAttribute(kPictureAttribute_Hue, hue);
+    }
+
+    XJ_started = true;
+
+    return true;
+}
+
+void VideoOutputXv::InitColorKey(void)
+{
+    int ret = Success;
     data->needdrawcolor = true;
 
     Atom xv_atom;
@@ -518,7 +536,12 @@
             {
                 xv_atom = XInternAtom(data->XJ_disp, "XV_AUTOPAINT_COLORKEY",
                                       False);
-                if (xv_atom != None)
+                if (xv_atom == None)
+                    continue;
+
+                if (m_deinterlacing && m_deintfiltername == "bobdeint")
+                    XvSetPortAttribute(data->XJ_disp, xv_port, xv_atom, 0);
+                else
                 {
                     ret = XvSetPortAttribute(data->XJ_disp, xv_port, xv_atom,
                                              1);
@@ -539,27 +562,24 @@
                                      &data->colorkey);
             if (ret != Success)
             {
-                cerr << "Couldn't get the color key color, and we need it.\n";
-                cerr << "You likely won't get any video.\n";
+                VERBOSE(VB_IMPORTANT,
+                        "Couldn't get the color key color, and we need it.\n"
+                        "You likely won't get any video.");
                 data->colorkey = 0;
             }
         }
     }
 
     MoveResize();
+}
 
-    if (gContext->GetNumSetting("UseOutputPictureControls", 0))
-    {
-        ChangePictureAttribute(kPictureAttribute_Brightness, brightness);
-        ChangePictureAttribute(kPictureAttribute_Contrast, contrast);
-        ChangePictureAttribute(kPictureAttribute_Colour, colour);
-        ChangePictureAttribute(kPictureAttribute_Hue, hue);
-    }
-
-    XJ_started = true;
-
-    return true;
+bool VideoOutputXv::SetupDeinterlace(bool interlaced)
+{
+    bool deint = VideoOutput::SetupDeinterlace(interlaced);
+    InitColorKey();
+    return deint;
 }
+
 bool VideoOutputXv::ApproveDeintFilter(const QString& filtername) const
 {
     if (filtername == "bobdeint")
@@ -875,7 +895,7 @@
         int src_x = imgx, src_y = imgy, src_w = imgw, src_h = imgh;
         int dest_y = dispyoff;
 
-        if (m_deinterlacing)
+        if (m_deinterlacing && (m_deintfiltername == "bobdeint"))
         {
             if ((t == kScan_Interlaced && buffer->top_field_first == 1) ||
                 (t == kScan_Intr2ndField && buffer->top_field_first == 0))
@@ -883,6 +903,9 @@
                 // Show top field
                 src_y = imgy / 2;
                 src_h = imgh / 2;
+                XvShmPutImage(data->XJ_disp, xv_port, data->XJ_curwin,
+                              data->XJ_gc, image, src_x, src_y, src_w, src_h,
+                              dispxoff, dest_y, dispwoff, disphoff, False);
             }
             else if ((t == kScan_Interlaced && buffer->top_field_first == 0) ||
                      (t == kScan_Intr2ndField && buffer->top_field_first == 1))
@@ -890,13 +913,20 @@
                 // Show bottom field
                 src_y = (buffer->height + imgy) / 2;
                 src_h = imgh / 2;
-                dest_y++;
+                int halfLineSrc = (int) round((0.25*disphoff)/src_h - 0.001f);
+                src_h -= (halfLineSrc) ? 1 : 0;
+                XvShmPutImage(data->XJ_disp, xv_port, data->XJ_curwin,
+                              data->XJ_gc, image, src_x, src_y, src_w, src_h,
+                              dispxoff, dest_y   + halfLineSrc,
+                              dispwoff, disphoff - halfLineSrc, False);
             }
         }
-
-        XvShmPutImage(data->XJ_disp, xv_port, data->XJ_curwin, data->XJ_gc,
-                      image, src_x, src_y, src_w, src_h, dispxoff, dest_y,
-                      dispwoff, disphoff, False);
+        else
+        {
+            XvShmPutImage(data->XJ_disp, xv_port, data->XJ_curwin, data->XJ_gc,
+                          image, src_x, src_y, src_w, src_h, dispxoff, dest_y,
+                          dispwoff, disphoff, False);
+        }
 
         pthread_mutex_unlock(&lock);
     }
@@ -1000,11 +1030,12 @@
 
 void VideoOutputXv::DrawUnusedRects(void)
 {
+    int boboff = (m_deinterlacing && m_deintfiltername == "bobdeint") ? 2 : 0;
     if (data->needdrawcolor)
     {
         XSetForeground(data->XJ_disp, data->XJ_gc, data->colorkey);
         XFillRectangle(data->XJ_disp, data->XJ_curwin, data->XJ_gc, dispx, 
-                       dispy, dispw, disph);
+                       dispy+boboff, dispw, disph);
     }
 
     // Draw black in masked areas
@@ -1017,10 +1048,10 @@
         XFillRectangle(data->XJ_disp, data->XJ_curwin, data->XJ_gc, 
                        dispxoff+dispwoff, dispy, 
                        (dispx+dispw)-(dispxoff+dispwoff), disph);
-    if (dispyoff > dispy) // bottom
+    if (dispyoff+boboff > dispy) // top of screen
         XFillRectangle(data->XJ_disp, data->XJ_curwin, data->XJ_gc, 
-                       dispx, dispy, dispw, dispyoff-dispy);
-    if (dispyoff+disphoff < dispy+disph) // top
+                       dispx, dispy, dispw, dispyoff+boboff-dispy);
+    if (dispyoff+disphoff < dispy+disph) // bottom of screen
         XFillRectangle(data->XJ_disp, data->XJ_curwin, data->XJ_gc, 
                        dispx, dispyoff+disphoff, 
                        dispw, (dispy+disph)-(dispyoff+disphoff));
Index: libs/libmythtv/videoout_xv.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/videoout_xv.h,v
retrieving revision 1.44
diff -u -r1.44 videoout_xv.h
--- libs/libmythtv/videoout_xv.h	5 Aug 2004 07:35:01 -0000	1.44
+++ libs/libmythtv/videoout_xv.h	1 Feb 2005 21:39:42 -0000
@@ -16,6 +16,7 @@
 
     bool Init(int width, int height, float aspect, WId winid,
               int winx, int winy, int winw, int winh, WId embedid = 0);
+    bool SetupDeinterlace(bool interlaced);
     bool ApproveDeintFilter(const QString& filtername) const;
     void PrepareFrame(VideoFrame *buffer, FrameScanType);
     void Show(FrameScanType );
@@ -41,6 +42,7 @@
     int ChangePictureAttribute(int attributeType, int newValue);
 
   private:
+    void InitColorKey(void);
     void Exit(void);
     bool CreateXvBuffers(void);
     bool CreateShmBuffers(void);
Index: libs/libmythtv/videoout_xvmc.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/videoout_xvmc.cpp,v
retrieving revision 1.39
diff -u -r1.39 videoout_xvmc.cpp
--- libs/libmythtv/videoout_xvmc.cpp	30 Nov 2004 02:32:22 -0000	1.39
+++ libs/libmythtv/videoout_xvmc.cpp	1 Feb 2005 21:39:43 -0000
@@ -122,6 +122,9 @@
     XShmSegmentInfo shminfo;
     XvImage *xvimage;
     unsigned char *palette;
+
+    int colorkey;
+    bool needdrawcolor;
 };
 
 static int XJ_error_catcher(Display * d, XErrorEvent * xeev)
@@ -510,10 +513,29 @@
         return false;
     }
 
-    Atom xv_atom;  
+    InitColorKey();
+
+    if (gContext->GetNumSetting("UseOutputPictureControls", 0))
+    {
+        ChangePictureAttribute(kPictureAttribute_Brightness, brightness);
+        ChangePictureAttribute(kPictureAttribute_Contrast, contrast);
+        ChangePictureAttribute(kPictureAttribute_Colour, colour);
+        ChangePictureAttribute(kPictureAttribute_Hue, hue);
+    }
+
+    XJ_started = true;
+
+    return true;
+}
+
+void VideoOutputXvMC::InitColorKey(void)
+{
+    int ret = Success;
+    data->needdrawcolor = true;
+
+    Atom xv_atom;
     XvAttribute *attributes;
     int attrib_count;
-    bool needdrawcolor = true;
 
     attributes = XvQueryPortAttributes(data->XJ_disp, xv_port, &attrib_count);
     if (attributes)
@@ -524,41 +546,48 @@
             {
                 xv_atom = XInternAtom(data->XJ_disp, "XV_AUTOPAINT_COLORKEY",
                                       False);
-                if (xv_atom != None)
+                if (xv_atom == None)
+                    continue;
+
+                if (m_deinterlacing && m_deintfiltername == "bobdeint")
+                    XvSetPortAttribute(data->XJ_disp, xv_port, xv_atom, 0);
+                else
                 {
                     ret = XvSetPortAttribute(data->XJ_disp, xv_port, xv_atom,
                                              1);
                     if (ret == Success)
-                        needdrawcolor = false;
+                        data->needdrawcolor = false;
                 }
             }
         }
         XFree(attributes);
     }
 
-    xv_atom = XInternAtom(data->XJ_disp, "XV_COLORKEY", False);
-    if (xv_atom != None)
+    if (data->needdrawcolor)
     {
-        ret = XvGetPortAttribute(data->XJ_disp, xv_port, xv_atom, &colorkey);
-        if (ret == Success)
+        xv_atom = XInternAtom(data->XJ_disp, "XV_COLORKEY", False);
+        if (xv_atom != None)
         {
-            needdrawcolor = true;
+            ret = XvGetPortAttribute(data->XJ_disp, xv_port, xv_atom, 
+                                     &data->colorkey);
+            if (ret != Success)
+            {
+                VERBOSE(VB_IMPORTANT,
+                        "Couldn't get the color key color, and we need it.\n"
+                        "You likely won't get any video.");
+                data->colorkey = 0;
+            }
         }
     }
 
     MoveResize();
+}
 
-    if (gContext->GetNumSetting("UseOutputPictureControls", 0))
-    {
-        ChangePictureAttribute(kPictureAttribute_Brightness, brightness);
-        ChangePictureAttribute(kPictureAttribute_Contrast, contrast);
-        ChangePictureAttribute(kPictureAttribute_Colour, colour);
-        ChangePictureAttribute(kPictureAttribute_Hue, hue);
-    }
-
-    XJ_started = true;
-
-    return true;
+bool VideoOutputXvMC::SetupDeinterlace(bool interlaced)
+{
+    bool deint = VideoOutput::SetupDeinterlace(interlaced);
+    InitColorKey();
+    return deint;
 }
 
 bool VideoOutputXvMC::NeedsDoubleFramerate() const
@@ -890,16 +919,20 @@
 void VideoOutputXvMC::Show(FrameScanType scan)
 {
     int field = 3;
+    int src_h = imgh;
+    int halfLineSrc = 0;
 
     if (m_deinterlacing)
     {
         switch (scan) 
         {
             case kScan_Interlaced:
-                field = 1;
+                field = 2;
                 break;
             case kScan_Intr2ndField:
-                field = 2;
+                field = 1;
+                halfLineSrc = (int) round((0.5*disphoff)/imgh - 0.001f);
+                src_h -= (halfLineSrc) ? 2 : 0;
                 break;
             default:
                 field = 3;
@@ -929,8 +962,10 @@
     if (data->p_render_surface_visible != NULL)
         data->p_render_surface_visible->state &= ~MP_XVMC_STATE_DISPLAY_PENDING;
 
-    XvMCPutSurface(data->XJ_disp, surf, data->XJ_curwin, imgx, imgy, imgw, 
-                   imgh, dispxoff, dispyoff, dispwoff, disphoff, field);
+    XvMCPutSurface(data->XJ_disp, surf, data->XJ_curwin,
+                   imgx, imgy, imgw, src_h,
+                   dispxoff, dispyoff + halfLineSrc,
+                   dispwoff, disphoff - halfLineSrc, field);
 
     if (data->p_render_surface_visible && 
         (data->p_render_surface_visible != showingsurface))
@@ -1050,9 +1085,13 @@
 
 void VideoOutputXvMC::DrawUnusedRects(void)
 {
-    XSetForeground(data->XJ_disp, data->XJ_gc, colorkey);
-    XFillRectangle(data->XJ_disp, data->XJ_curwin, data->XJ_gc, dispx, dispy,
-                   dispw, disph);
+    int boboff = (m_deinterlacing && m_deintfiltername == "bobdeint") ? 2 : 0;
+    if (data->needdrawcolor)
+    {
+        XSetForeground(data->XJ_disp, data->XJ_gc, data->colorkey);
+        XFillRectangle(data->XJ_disp, data->XJ_curwin, data->XJ_gc,
+                       dispx, dispy+boboff, dispw, disph);
+    }
 
     XSetForeground(data->XJ_disp, data->XJ_gc, XJ_black);
     if (dispxoff > dispx) // left
@@ -1062,10 +1101,10 @@
         XFillRectangle(data->XJ_disp, data->XJ_curwin, data->XJ_gc, 
                        dispxoff+dispwoff, dispy, 
                        (dispx+dispw)-(dispxoff+dispwoff), disph);
-    if (dispyoff > dispy) // bottom
+    if (dispyoff+boboff > dispy) // top of screen
         XFillRectangle(data->XJ_disp, data->XJ_curwin, data->XJ_gc, 
-                       dispx, dispy, dispw, dispyoff-dispy);
-    if (dispyoff+disphoff < dispy+disph) // top
+                       dispx, dispy, dispw, dispyoff+boboff-dispy);
+    if (dispyoff+disphoff < dispy+disph) // bottom of screen
         XFillRectangle(data->XJ_disp, data->XJ_curwin, data->XJ_gc, 
                        dispx, dispyoff+disphoff, 
                        dispw, (dispy+disph)-(dispyoff+disphoff));
Index: libs/libmythtv/videoout_xvmc.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/videoout_xvmc.h,v
retrieving revision 1.13
diff -u -r1.13 videoout_xvmc.h
--- libs/libmythtv/videoout_xvmc.h	13 Sep 2004 06:09:24 -0000	1.13
+++ libs/libmythtv/videoout_xvmc.h	1 Feb 2005 21:39:43 -0000
@@ -14,6 +14,7 @@
 
     bool Init(int width, int height, float aspect, WId winid,
               int winx, int winy, int winw, int winh, WId embedid = 0);
+    bool SetupDeinterlace(bool interlaced);
     bool NeedsDoubleFramerate() const;
     bool ApproveDeintFilter(const QString& filtername) const;
     void PrepareFrame(VideoFrame *buffer, FrameScanType);
@@ -45,6 +46,7 @@
     inline bool hasVLDAcceleration() const;
 
   private:
+    void InitColorKey(void);
     void Exit(void);
     bool CreateXvMCBuffers(void);
     void DeleteXvMCBuffers(void);
@@ -67,7 +69,6 @@
 
     pthread_mutex_t lock;
 
-    int colorkey;
     int chroma;
 };
 


More information about the mythtv-dev mailing list