On Tue, 1 Feb 2005, Isaac Richards wrote:
]Doesn't seem like it does the right thing for source = output = 480 lines of
]resolution with no overscan compensation, though.
Your right, I divided by 2 one too many times in my formula.
it's now:
int halfLineSrc = (int) round(((float)disphoff)/imgh - 0.001f);
so when the input and output is 480, we get
round( 480.0f/480 - 0.001f) -> 1
with an output of 1440 we get
round( 1440.0f/480 - 0.001f) -> 3
It looks absolutely beautiful now!
In DrawUnusedRects, I've also changed:
int boboff = (m_deinterlacing && m_deintfiltername == "bobdeint") ? 2 : 0;
to
// boboff assumes the smallest interlaced resolution is 480 lines
int boboff = (int) round(((float)disphoff)/480 - 0.001f);
boboff = (m_deinterlacing && m_deintfiltername == "bobdeint") ? boboff : 0;
This lets it adapt better to large differences in output resolutions.
Also, I found another bug.. In the xv videoout class there is never a
check on needrepaint. I've added this to the xv path, so we can deal
with expose events. (I noticed this because kde pops up an info message
when MythTV changes the resolution to 640x480, which was clearing part
of the colorkey painted background.) I'm guessing this bug was hidden
from the developers because we all have XV_AUTOPAINT_COLORKEY capable
cards/drivers.
Basically, I added
if (needrepaint)
{
DrawUnusedRects();
needrepaint = false;
}
I didn't add it to the shared memory path, because it could cause
flicker there, and I'm not sure it's needed there.
-- DanielIndex: 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 2 Feb 2005 15:34:37 -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,26 @@
// Show bottom field
src_y = (buffer->height + imgy) / 2;
src_h = imgh / 2;
- dest_y++;
+ int halfLineSrc = (int) round(((float)disphoff)/imgh - 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);
}
}
+ 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);
+ }
- 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);
+ if (needrepaint)
+ {
+ DrawUnusedRects();
+ needrepaint = false;
+ }
pthread_mutex_unlock(&lock);
}
@@ -1000,11 +1036,15 @@
void VideoOutputXv::DrawUnusedRects(void)
{
+ // boboff assumes the smallest interlaced resolution is 480 lines
+ int boboff = (int) round(((float)disphoff)/480 - 0.001f);
+ boboff = (m_deinterlacing && m_deintfiltername == "bobdeint") ? boboff : 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 +1057,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.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 2 Feb 2005 15:34:37 -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(((float)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,16 @@
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);
+ // boboff assumes the smallest interlaced resolution is 480 lines
+ int boboff = (int) round(((float)disphoff)/480 - 0.001f);
+ boboff = (m_deinterlacing && m_deintfiltername == "bobdeint") ? boboff : 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 +1104,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 2 Feb 2005 15:34:37 -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.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 2 Feb 2005 15:34:37 -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;
};
_______________________________________________
mythtv-dev mailing list
[email protected]
http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev