[mythtv] [debugging patch] chatty XvMC IDCT patch,
please test if you have GeForce 4Ti
Daniel Thor Kristjansson
danielk at cat.nyu.edu
Mon Aug 23 23:33:14 EDT 2004
A few months ago a small part of the IDCT patch didn't make it in
because it didn't work with cards without IDCT acceleration. This
patch tries to solve that problem. I consolidated some similar code for
finding XvMC surfaces into a new less buggy find() method in
XvMCSurfaces, and I also made all the methods involved emit more
debugging info.
What I need someone with a MC acceleration only card (GeForce 4Ti) to do
is view some MPEG2 videos with XvMC acceleration enabled, if this works
just e-mail me or the list. If it doesn't, send me the output of
"mythfrontend --verbose playback" so I can track down the problem.
Thanks,
Daniel
BTW this also includes a new "#define DISABLE_IDCT" in videoout_xvmc.h
which you can uncomment if you want to disable IDCT acceleration on a
card that supports IDCT.
-------------- next part --------------
Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp,v
retrieving revision 1.357
diff -u -r1.357 NuppelVideoPlayer.cpp
--- libs/libmythtv/NuppelVideoPlayer.cpp 20 Aug 2004 06:29:48 -0000 1.357
+++ libs/libmythtv/NuppelVideoPlayer.cpp 24 Aug 2004 03:15:13 -0000
@@ -404,9 +404,13 @@
// an IDCT or MC pixel format.
if (kVideoOutput_XvMC == forceVideoOutput)
{
+#ifdef DISABLE_IDCT
+ decoder->SetPixelFormat(PIX_FMT_XVMC_MPEG2_MC);
+#else
bool idct = videoOutput->hasIDCTAcceleration();
decoder->SetPixelFormat((idct) ? PIX_FMT_XVMC_MPEG2_IDCT :
- PIX_FMT_XVMC_MPEG2_MC);
+ PIX_FMT_XVMC_MPEG2_MC);
+#endif
}
#endif
Index: libs/libmythtv/XvMCSurfaceTypes.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/XvMCSurfaceTypes.cpp,v
retrieving revision 1.1
diff -u -r1.1 XvMCSurfaceTypes.cpp
--- libs/libmythtv/XvMCSurfaceTypes.cpp 19 Aug 2004 05:17:26 -0000 1.1
+++ libs/libmythtv/XvMCSurfaceTypes.cpp 24 Aug 2004 03:15:13 -0000
@@ -75,95 +75,100 @@
return -1;
}
-void XvMCSurfaceTypes::find(int minWidth, int minHeight,
+void XvMCSurfaceTypes::find(Display *display,
+ int minWidth, int minHeight,
int chroma, bool idct, int mpeg,
- int minSubpictureWidth,
- int minSubpictureHeight,
- Display *dpy, XvPortID portMin,
- XvPortID portMax, XvPortID& port,
- int& surfNum)
+ int minSubpictWidth, int minSubpictHeight,
+ XvPortID portMin, XvPortID portMax,
+ XvPortID& port, int& surfNum)
{
- VERBOSE(VB_PLAYBACK,
- QString("XvMCSurfaceTypes::find(w %1, h %2, c %3, i %4, m %5,"
- "sw %6, sh %7, disp, p<= %9, %10 <=p, port, surfNum)")
- .arg(minWidth).arg(minHeight).arg(chroma).arg(idct).arg(mpeg)
- .arg(minSubpictureWidth).arg(minSubpictureHeight)
+ VERBOSE(VB_PLAYBACK,
+ QString("XvMCSurfaceTypes::find(wxh %1x%2, chroma %3, w/idct %4,")
+ .arg(minWidth).arg(minHeight).arg(chroma).arg(idct));
+ VERBOSE(VB_PLAYBACK,
+ QString("... mpeg%1, sub wxh %2x%3, %4<=port<=%5)")
+ .arg(mpeg).arg(minSubpictWidth).arg(minSubpictHeight)
.arg(portMin).arg(portMax));
- port = 0;
- surfNum = -1;
+ port = surfNum = 0;
+
for (XvPortID p = portMin; p <= portMax; p++)
{
VERBOSE(VB_PLAYBACK, QString("Trying XvMC port %1").arg(p));
- XvMCSurfaceTypes surf(dpy, p);
+ XvMCSurfaceTypes surf(display, p);
int s = surf.find(minWidth, minHeight, chroma, idct, mpeg,
- minSubpictureWidth, minSubpictureHeight);
+ minSubpictWidth, minSubpictHeight);
if (s >= 0)
{
- VERBOSE(VB_PLAYBACK, QString("Found a suitable XvMC surface %1")
- .arg(s));
+ VERBOSE(VB_PLAYBACK, QString("Found a suitable XvMC surface %1, on port %2").arg(s).arg(p));
port = p;
surfNum = s;
return;
}
}
}
-
-inline bool XvMCSurfaceTypes::hasIDCT(int width, int height,
- int chroma, Display *pdisp)
-{
- Display* disp = pdisp;
- if (!pdisp)
- disp = createXvMCDisplay();
- XvAdaptorInfo *ai = 0;
- unsigned int p_num_adaptors = 0;
+void XvMCSurfaceTypes::find(Display* display, Window win,
+ int minWidth, int minHeight,
+ int chroma, bool idct, int mpeg,
+ int minSubpictWidth, int minSubpictHeight,
+ XvPortID& port, int& surfNum) {
+ unsigned int err, num_adaptors, i;
+ XvAdaptorInfo *ai;
- Window root = DefaultRootWindow(disp);
- int ret = XvQueryAdaptors(disp, root, &p_num_adaptors, &ai);
+ port = surfNum = 0;
- if (ret != Success)
+ err = XvQueryAdaptors(display, win, &num_adaptors, &ai);
+
+ if (err != Success)
{
- printf("XvQueryAdaptors failed.\n");
- if (!pdisp)
- XCloseDisplay(disp);
- return false;
+ VERBOSE(VB_IMPORTANT, QString("XvQueryAdaptors failed. err=%1").arg(err));
+ num_adaptors = 0;
}
- if (!ai)
+ for (i = 0; i < num_adaptors; i++)
{
- if (!pdisp)
- XCloseDisplay(disp);
- return false; // huh? no xv capable video adaptors?
+ if (ai[i].type)
+ {
+ find(display, minWidth, minHeight, chroma, idct, mpeg,
+ minSubpictWidth, minSubpictHeight,
+ ai[i].base_id, ai[i].base_id + ai[i].num_ports - 1, port, surfNum);
+ if (port) {
+ VERBOSE(VB_PLAYBACK, QString("Found XvMC surf %1 on adaptor %2, port %3")
+ .arg(surfNum).arg(i).arg(port));
+ break;
+ }
+ }
}
- for (unsigned int i = 0; i < p_num_adaptors; i++)
+ if (num_adaptors > 0)
+ XvFreeAdaptorInfo(ai);
+
+ return;
+}
+
+
+inline bool XvMCSurfaceTypes::hasIDCT(int width, int height,
+ int chroma, Display *display)
+{
+ XvPortID port;
+ int surfNum;
+
+ if (display)
+ find(display, DefaultRootWindow(display), width, height, chroma, true,
+ /*mpeg*/2, width, height/3, port, surfNum);
+ else
{
- XvPortID p = 0;
- int s;
- if (ai[i].type == 0)
- continue;
- XvMCSurfaceTypes::find(width, height, chroma,
- true, 2, 0, 0,
- disp, ai[i].base_id,
- ai[i].base_id + ai[i].num_ports - 1,
- p, s);
- if (0 != p)
- {
- if (p_num_adaptors > 0)
- XvFreeAdaptorInfo(ai);
- if (!pdisp)
- XCloseDisplay(disp);
- return true;
- }
+ display = createXvMCDisplay();
+ find(display, DefaultRootWindow(display), width, height, chroma, true,
+ /*mpeg*/2, width, height/3, port, surfNum);
+ XCloseDisplay(display);
}
- if (p_num_adaptors > 0)
- XvFreeAdaptorInfo(ai);
- if (!pdisp)
- XCloseDisplay(disp);
+ VERBOSE(VB_PLAYBACK, QString("hasIDCT(WxH %1x%2) --> %3")
+ .arg(width).arg(height).arg(port>0));
- return false;
+ return bool(port > 0);
}
ostream& XvMCSurfaceTypes::print(ostream& os, int s) const
Index: libs/libmythtv/XvMCSurfaceTypes.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/XvMCSurfaceTypes.h,v
retrieving revision 1.2
diff -u -r1.2 XvMCSurfaceTypes.h
--- libs/libmythtv/XvMCSurfaceTypes.h 19 Aug 2004 05:17:26 -0000 1.2
+++ libs/libmythtv/XvMCSurfaceTypes.h 24 Aug 2004 03:15:13 -0000
@@ -131,13 +131,21 @@
int size() const { return num; }
- /// Find an appropriate surface on the current display.
- static void find(int minWidth, int minHeight, int chroma, bool idct,
- int mpeg, int minSubpictureWidth,
- int minSubpictureHeight, Display *dpy,
+ /// Find an appropriate surface on the current adaptor.
+ static void find(Display *display,
+ int minWidth, int minHeight,
+ int chroma, bool idct, int mpeg,
+ int minSubpictWidth, int minSubpictHeight,
XvPortID portMin, XvPortID portMax,
XvPortID& port, int& surfNum);
+ /// Find an appropriate surface on the current display
+ static void find(Display* display, Window win,
+ int minWidth, int minHeight,
+ int chroma, bool idct, int mpeg,
+ int minSubpictWidth, int minSubpictHeight,
+ XvPortID& port, int& surfNum);
+
/// Find out if there is an IDCT Acceleration capable surface on any port.
static bool hasIDCT(int width, int height,
int chroma = XVMC_CHROMA_FORMAT_420,
Index: libs/libmythtv/avformatdecoder.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/avformatdecoder.cpp,v
retrieving revision 1.93
diff -u -r1.93 avformatdecoder.cpp
--- libs/libmythtv/avformatdecoder.cpp 19 Aug 2004 01:32:25 -0000 1.93
+++ libs/libmythtv/avformatdecoder.cpp 24 Aug 2004 03:15:13 -0000
@@ -244,19 +244,24 @@
static QMap<void*, enum PixelFormat> _PixelFormatsMap;
-/*
static enum PixelFormat getFormat(struct AVCodecContext *cc,
const enum PixelFormat *pixfmts)
{
+ PixelFormat fmt=pixfmts[0];
if (_PixelFormatsMap.end() != _PixelFormatsMap.find(cc))
- {
- return _PixelFormatsMap[cc];
- }
+ fmt = *_PixelFormatsMap.find(cc);
+ else
+ VERBOSE(VB_IMPORTANT, "Pixel format not set, returning pixfmts[0]");
+
+ if (PIX_FMT_XVMC_MPEG2_MC == fmt)
+ VERBOSE(VB_PLAYBACK, "getFormat() returning PIX_FMT_XVMC_MPEG2_MC");
+ else if (PIX_FMT_XVMC_MPEG2_IDCT == fmt)
+ VERBOSE(VB_PLAYBACK, "getFormat() returning PIX_FMT_XVMC_MPEG2_IDCT");
+ else
+ VERBOSE(VB_PLAYBACK, QString("getFormat() returning UNEXPECTED %1").arg(fmt));
- VERBOSE(VB_IMPORTANT, "Pixel format not set, returning pixfmts[0]");
- return pixfmts[0];
+ return fmt;
}
-*/
void AvFormatDecoder::SetPixelFormat(const int pixFormat)
{
@@ -365,7 +370,7 @@
if (gContext->GetNumSetting("UseXVMC", 1))
{
enc->codec_id = CODEC_ID_MPEG2VIDEO_XVMC;
- //enc->get_format = getFormat;
+ enc->get_format = getFormat;
}
#endif
#ifdef USING_VIASLICE
Index: libs/libmythtv/videoout_xvmc.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/videoout_xvmc.cpp,v
retrieving revision 1.33
diff -u -r1.33 videoout_xvmc.cpp
--- libs/libmythtv/videoout_xvmc.cpp 5 Aug 2004 07:35:02 -0000 1.33
+++ libs/libmythtv/videoout_xvmc.cpp 24 Aug 2004 03:15:13 -0000
@@ -134,7 +134,7 @@
: VideoOutput()
{
XJ_started = 0;
- xv_port = -1;
+ xv_port = 0;
chroma = XVMC_CHROMA_FORMAT_420;
@@ -235,16 +235,14 @@
pthread_mutex_init(&lock, NULL);
int (*old_handler)(Display *, XErrorEvent *);
- int i, ret;
+ int ret;
XJ_caught_error = 0;
unsigned int p_version, p_release, p_request_base, p_event_base,
p_error_base;
- int p_num_adaptors;
- bool usingXinerama;
- int event_base, error_base;
- XvAdaptorInfo *ai;
+ bool usingXinerama;
+ int event_base, error_base, surf_num;
VideoOutput::InitBuffers(kNumBuffers, false, kNeedFreeFrames,
kPrebufferFrames, kKeepPrebuffer);
@@ -347,63 +345,36 @@
printf("Using XvMC version: %d.%d\n", mc_version, mc_release);
}
- ai = NULL;
- xv_port = -1;
- ret = XvQueryAdaptors(data->XJ_disp, data->XJ_root,
- (unsigned int *)&p_num_adaptors, &ai);
-
- if (ret != Success)
- {
- printf("XvQueryAdaptors failed.\n");
- ai = NULL;
- }
+ xv_port = 0;
+#ifndef DISABLE_IDCT
+ XvMCSurfaceTypes::find(data->XJ_disp, data->XJ_root,
+ width, height, chroma, true/*idct*/, 2,
+ width, height/3, xv_port, surf_num);
+#endif
+ if (xv_port > 0)
+ VERBOSE(VB_PLAYBACK,
+ QString("Found XvMC Surface with IDCT support."
+ " port=%1, surf=%2").arg(xv_port).arg(surf_num));
else
{
- if ( ai )
- {
- for (i = 0; i < p_num_adaptors; i++)
- {
- if (ai[i].type == 0)
- continue;
-
- XvPortID p = 0;
- int s;
- XvMCSurfaceTypes::find(width, height, chroma,
- true, 2, 0, 0,
- data->XJ_disp, ai[i].base_id,
- ai[i].base_id + ai[i].num_ports - 1,
- p, s);
- if (0 == p)
- {
- // No IDCT surface found, try to find MC surface
- XvMCSurfaceTypes::find(width, height, chroma,
- false, 2, 0, 0,
- data->XJ_disp, ai[i].base_id,
- ai[i].base_id + ai[i].num_ports - 1,
- p, s);
- }
-
- if (p != 0)
- {
- xv_port = p;
- XvMCSurfaceTypes surf(data->XJ_disp, p);
- assert(surf.size()>0);
- surf.set(s, &data->surface_info);
- data->mode_id = surf.surfaceTypeID(s);
- break;
- }
- }
-
- if (p_num_adaptors > 0)
- XvFreeAdaptorInfo(ai);
- }
- }
-
- if (xv_port <= 0)
- {
- VERBOSE(VB_ALL, "Invalid xv port");
- return false;
- }
+ XvMCSurfaceTypes::find(data->XJ_disp, data->XJ_root,
+ width, height, chroma, false/*mc*/, 2,
+ width, height/3, xv_port, surf_num);
+ if (xv_port > 0)
+ VERBOSE(VB_PLAYBACK,
+ QString("Found XvMC Surface with MC support."
+ " port=%1, surf=%2").arg(xv_port).arg(surf_num));
+ else
+ {
+ VERBOSE(VB_ALL, "Invalid xv port");
+ return false;
+ }
+ }
+
+ XvMCSurfaceTypes surf(data->XJ_disp, xv_port);
+ assert(surf.size()>0);
+ surf.set(surf_num, &data->surface_info);
+ data->mode_id = surf.surfaceTypeID(surf_num);
if (display_res)
{
@@ -550,7 +521,8 @@
if (ret != Success)
{
- cerr << "Unable to create XvMC Context return status:" << ret ;
+ cerr << "Unable to create XvMC Context on port "
+ << xv_port << "return status:" << ret ;
switch (ret)
{
case XvBadPort: cerr << " XvBadPort"; break;
Index: libs/libmythtv/videoout_xvmc.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/videoout_xvmc.h,v
retrieving revision 1.12
diff -u -r1.12 videoout_xvmc.h
--- libs/libmythtv/videoout_xvmc.h 5 Aug 2004 07:35:02 -0000 1.12
+++ libs/libmythtv/videoout_xvmc.h 24 Aug 2004 03:15:13 -0000
@@ -5,6 +5,12 @@
#include <DisplayRes.h>
#include "videooutbase.h"
+extern "C" {
+#include "../libavcodec/avcodec.h"
+#include "../libavcodec/xvmc_render.h"
+}
+
+//#define DISABLE_IDCT // disable IDCT acceleration, for debugging
class VideoOutputXvMC : public VideoOutput
{
@@ -61,7 +67,7 @@
int XJ_screenwidth, XJ_screenheight;
int XJ_fullscreen;
- int xv_port;
+ XvPortID xv_port;
int colorid;
pthread_mutex_t lock;
More information about the mythtv-dev
mailing list