00001 #include "mythlogging.h"
00002
00003 #include "mythmainwindow.h"
00004
00005 #ifdef USING_OPENGL
00006 #include "mythrender_opengl.h"
00007 #endif
00008
00009 #ifdef USING_VDPAU
00010 #include "mythrender_vdpau.h"
00011 #endif
00012
00013 extern "C" {
00014 #include "goom/goom_tools.h"
00015 #include "goom/goom_core.h"
00016 }
00017
00018 #include "videovisualgoom.h"
00019
00020 VideoVisualGoom::VideoVisualGoom(AudioPlayer *audio, MythRender *render, bool hd)
00021 : VideoVisual(audio, render), m_buffer(NULL), m_surface(0), m_hd(hd)
00022 {
00023 int max_width = m_hd ? 1200 : 600;
00024 int max_height = m_hd ? 800 : 400;
00025 MythMainWindow *mw = GetMythMainWindow();
00026 QSize sz = mw ? mw->GetUIScreenRect().size() : QSize(600, 400);
00027 int width = (sz.width() > max_width) ? max_width : sz.width();
00028 int height = (sz.height() > max_height) ? max_height : sz.height();
00029 m_area = QRect(0, 0, width, height);
00030 goom_init(width, height, 0);
00031 LOG(VB_GENERAL, LOG_INFO, QString("Initialised Goom (%1x%2)")
00032 .arg(width).arg(height));
00033 }
00034
00035 VideoVisualGoom::~VideoVisualGoom()
00036 {
00037 #ifdef USING_OPENGL
00038 if (m_surface && m_render &&
00039 (m_render->Type() == kRenderOpenGL1 ||
00040 m_render->Type() == kRenderOpenGL2 ||
00041 m_render->Type() == kRenderOpenGL2ES))
00042 {
00043 MythRenderOpenGL *glrender =
00044 static_cast<MythRenderOpenGL*>(m_render);
00045 if (glrender)
00046 glrender->DeleteTexture(m_surface);
00047 m_surface = 0;
00048 }
00049 #endif
00050
00051 #ifdef USING_VDPAU
00052 if (m_surface && m_render &&
00053 (m_render->Type() == kRenderVDPAU))
00054 {
00055 MythRenderVDPAU *render =
00056 static_cast<MythRenderVDPAU*>(m_render);
00057 if (render)
00058 render->DestroyBitmapSurface(m_surface);
00059 m_surface = 0;
00060 }
00061 #endif
00062
00063 goom_close();
00064 }
00065
00066 void VideoVisualGoom::Draw(const QRect &area, MythPainter *painter,
00067 QPaintDevice *device)
00068 {
00069 if (m_disabled || !m_render || area.isEmpty())
00070 return;
00071
00072 QMutexLocker lock(mutex());
00073 unsigned int* last = m_buffer;
00074 VisualNode *node = GetNode();
00075 if (node)
00076 {
00077 int numSamps = 512;
00078 if (node->length < 512)
00079 numSamps = node->length;
00080
00081 signed short int data[2][512];
00082 int i= 0;
00083 for (; i < numSamps; i++)
00084 {
00085 data[0][i] = node->left[i];
00086 data[1][i] = node->right ? node->right[i] : data[0][i];
00087 }
00088
00089 for (; i < 512; i++)
00090 {
00091 data[0][i] = 0;
00092 data[1][i] = 0;
00093 }
00094
00095 m_buffer = goom_update(data, 0);
00096 }
00097
00098 #ifdef USING_OPENGL
00099 if ((m_render->Type() == kRenderOpenGL1) ||
00100 (m_render->Type() == kRenderOpenGL2) ||
00101 (m_render->Type() == kRenderOpenGL2ES))
00102 {
00103 MythRenderOpenGL *glrender =
00104 static_cast<MythRenderOpenGL*>(m_render);
00105 if (!m_surface && glrender && m_buffer)
00106 {
00107 m_surface = glrender->CreateTexture(m_area.size(),
00108 glrender->GetFeatures() & kGLExtPBufObj, 0,
00109 GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA8,
00110 GL_LINEAR_MIPMAP_LINEAR);
00111 }
00112
00113 if (m_surface && glrender && m_buffer)
00114 {
00115 if (m_buffer != last)
00116 {
00117 bool copy = glrender->GetFeatures() & kGLExtPBufObj;
00118 void* buf = glrender->GetTextureBuffer(m_surface, copy);
00119 if (copy)
00120 memcpy(buf, m_buffer, m_area.width() * m_area.height() * 4);
00121 glrender->UpdateTexture(m_surface, (void*)m_buffer);
00122 }
00123 QRectF src(m_area);
00124 QRectF dst(area);
00125 glrender->DrawBitmap(&m_surface, 1, 0, &src, &dst, 0);
00126 }
00127 return;
00128 }
00129 #endif
00130
00131 #ifdef USING_VDPAU
00132 if (m_render->Type() == kRenderVDPAU)
00133 {
00134 MythRenderVDPAU *render =
00135 static_cast<MythRenderVDPAU*>(m_render);
00136
00137 if (!m_surface && render)
00138 m_surface = render->CreateBitmapSurface(m_area.size());
00139
00140 if (m_surface && render && m_buffer)
00141 {
00142 if (m_buffer != last)
00143 {
00144 void *plane[1] = { m_buffer };
00145 uint32_t pitch[1] = { m_area.width() * 4 };
00146 render->UploadBitmap(m_surface, plane, pitch);
00147 }
00148 render->DrawBitmap(m_surface, 0, NULL, NULL, kVDPBlendNull, 255, 255, 255, 255);
00149 }
00150 return;
00151 }
00152 #endif
00153 }
00154
00155 static class VideoVisualGoomFactory : public VideoVisualFactory
00156 {
00157 public:
00158 const QString &name(void) const
00159 {
00160 static QString name("Goom");
00161 return name;
00162 }
00163
00164 VideoVisual *Create(AudioPlayer *audio,
00165 MythRender *render) const
00166 {
00167 return new VideoVisualGoom(audio, render, false);
00168 }
00169
00170 virtual bool SupportedRenderer(RenderType type)
00171 {
00172 return (type == kRenderVDPAU ||
00173 type == kRenderOpenGL1 ||
00174 type == kRenderOpenGL2 ||
00175 type == kRenderOpenGL2ES);
00176 }
00177 } VideoVisualGoomFactory;
00178
00179 static class VideoVisualGoomHDFactory : public VideoVisualFactory
00180 {
00181 public:
00182 const QString &name(void) const
00183 {
00184 static QString name("Goom HD");
00185 return name;
00186 }
00187
00188 VideoVisual *Create(AudioPlayer *audio,
00189 MythRender *render) const
00190 {
00191 return new VideoVisualGoom(audio, render, true);
00192 }
00193
00194 virtual bool SupportedRenderer(RenderType type)
00195 {
00196 return (type == kRenderVDPAU ||
00197 type == kRenderOpenGL1 ||
00198 type == kRenderOpenGL2 ||
00199 type == kRenderOpenGL2ES);
00200 }
00201 } VideoVisualGoomHDFactory;