00001
00002 #include <iostream>
00003 using namespace std;
00004
00005 #include <mythtv/mythcontext.h>
00006 #include <mythtv/compat.h>
00007
00008 #include "libvisualplugin.h"
00009
00010 #if defined(SDL_SUPPORT) && defined(LIBVISUAL_SUPPORT)
00011
00012 static char AppName[] = "mythmusic";
00013
00014 LibVisualPlugin::LibVisualPlugin(MainVisual *parent, long int winid, const QString &pluginName)
00015 {
00016 fps = 30;
00017 m_parent = parent;
00018 m_pVisBin = 0;
00019 m_pVisVideo = 0;
00020 m_pSurface = 0;
00021 m_paused = false;
00022
00023
00024 char SDL_windowhack[32];
00025 sprintf(SDL_windowhack, "%ld", winid);
00026 setenv("SDL_WINDOWID", SDL_windowhack, 1);
00027
00028 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0)
00029 {
00030 cerr << "Unable to init SDL\n";
00031 return;
00032 }
00033 SDL_ShowCursor(0);
00034
00035
00036 visual_log_set_verboseness(VISUAL_LOG_VERBOSENESS_LOW);
00037
00038
00039 if (!visual_is_initialized())
00040 {
00041 char **argv;
00042 int argc;
00043 argv = (char**)malloc(sizeof(char*));
00044 argv[0] = AppName;
00045 argc = 1;
00046 visual_init(&argc, &argv);
00047 free(argv);
00048 }
00049
00050
00051
00052 const char *plugin = 0;
00053 while( (plugin = visual_actor_get_next_by_name( plugin )) )
00054 m_pluginList << plugin;
00055
00056 m_currentPlugin = 0;
00057 if (pluginName != "" && (m_pluginList.find(pluginName) != m_pluginList.end()))
00058 switchToPlugin(pluginName);
00059 else
00060 switchToPlugin(m_pluginList[0]);
00061 }
00062
00063 void LibVisualPlugin::handleKeyPress(const QString &action)
00064 {
00065 if (action == "SELECT")
00066 {
00067 m_currentPlugin++;
00068 if (m_currentPlugin >= m_pluginList.count())
00069 m_currentPlugin = 0;
00070
00071
00072 if (m_pluginList[m_currentPlugin] == "gstreamer")
00073 {
00074 m_currentPlugin++;
00075 if (m_currentPlugin >= m_pluginList.count())
00076 m_currentPlugin = 0;
00077 }
00078
00079 if (SDL_MUSTLOCK(m_pSurface) == SDL_TRUE)
00080 SDL_LockSurface(m_pSurface);
00081
00082 visual_bin_set_morph_by_name(m_pVisBin, (char*)"alphablend");
00083 visual_bin_switch_actor_by_name(m_pVisBin,
00084 const_cast<char*>(m_pluginList[m_currentPlugin].ascii()));
00085
00086 if (SDL_MUSTLOCK(m_pSurface) == SDL_TRUE)
00087 SDL_UnlockSurface(m_pSurface);
00088
00089 m_parent->showBanner(QString("Visualizer: ") + m_pluginList[m_currentPlugin], 8000);
00090 }
00091 }
00092
00093 void LibVisualPlugin::switchToPlugin(const QString &pluginName)
00094 {
00095 if (m_pVisVideo)
00096 {
00097 visual_object_unref(VISUAL_OBJECT(m_pVisVideo));
00098 m_pVisVideo = 0;
00099 }
00100
00101 if (m_pVisBin)
00102 {
00103 visual_object_unref(VISUAL_OBJECT(m_pVisBin));
00104 m_pVisBin = 0;
00105 }
00106
00107 if ((m_pVisBin = visual_bin_new()))
00108 {
00109 visual_bin_set_supported_depth(m_pVisBin, VISUAL_VIDEO_DEPTH_ALL);
00110 if ((m_pVisVideo = visual_video_new()))
00111 {
00112 if (visual_bin_set_video(m_pVisBin, m_pVisVideo) == VISUAL_OK)
00113 {
00114 if (visual_bin_connect_by_names(m_pVisBin, const_cast<char*>(pluginName.ascii()), 0) == VISUAL_OK)
00115 {
00116 if (visual_input_set_callback(visual_bin_get_input(m_pVisBin), AudioCallback, this) == VISUAL_OK)
00117 {
00118 visual_bin_switch_set_style(m_pVisBin, VISUAL_SWITCH_STYLE_MORPH);
00119 visual_bin_switch_set_automatic(m_pVisBin, true);
00120 visual_bin_switch_set_steps(m_pVisBin, 100);
00121 visual_bin_realize(m_pVisBin);
00122 }
00123 else
00124 {
00125 cerr << "Error connecting LibVisualPlugin 'Input' object to our data source object" << endl;
00126 }
00127 }
00128 else
00129 {
00130 cerr << "Error connecting LibVisualPlugin 'Plugin' object to 'Bin' object" << endl;
00131 }
00132 }
00133 else
00134 {
00135 cerr << "Error connecting LibVisualPlugin 'Video' object to 'Bin' object" << endl;
00136 }
00137 }
00138 else
00139 {
00140 cerr << "Error allocating LibVisualPlugin 'Video' object" << endl;
00141 }
00142 }
00143 else
00144 {
00145 cerr << "Error allocating LibVisualPlugin 'Bin' object" << endl;
00146 }
00147 }
00148
00149 LibVisualPlugin::~LibVisualPlugin()
00150 {
00151 if (m_pVisVideo)
00152 {
00153 visual_object_unref(VISUAL_OBJECT(m_pVisVideo));
00154 m_pVisVideo = 0;
00155 }
00156
00157 if (m_pVisBin)
00158 {
00159 visual_object_unref(VISUAL_OBJECT(m_pVisBin));
00160 m_pVisBin = 0;
00161 }
00162
00163 SDL_Quit();
00164
00165
00166
00167 unsetenv("SDL_WINDOWID");
00168 }
00169
00170 void LibVisualPlugin::resize(const QSize &size)
00171 {
00172 visual_video_set_dimension(m_pVisVideo, size.width(), size.height());
00173 createScreen(size.width(), size.height());
00174 visual_bin_sync(m_pVisBin, false);
00175 }
00176
00177
00178 bool LibVisualPlugin::process(VisualNode *node)
00179 {
00180 if (!node || node->length == 0 || !m_pSurface)
00181 return true;
00182
00183 int numSamps = 512;
00184 if (node->length < 512)
00185 numSamps = node->length;
00186
00187 int i = 0;
00188 for (i = 0; i < numSamps; i++)
00189 {
00190 m_Audio[0][i] = node->left[i];
00191 if (node->right)
00192 m_Audio[1][i] = node->right[i];
00193 else
00194 m_Audio[1][i] = m_Audio[0][i];
00195 }
00196
00197 for (; i < 512; i++)
00198 {
00199 m_Audio[0][i] = 0;
00200 m_Audio[1][i] = 0;
00201 }
00202
00203 return false;
00204 }
00205
00206 bool LibVisualPlugin::createScreen(int width, int height)
00207 {
00208 SDL_FreeSurface(m_pSurface);
00209
00210 if (visual_bin_get_depth(m_pVisBin) == VISUAL_VIDEO_DEPTH_GL)
00211 {
00212 visual_video_set_depth(m_pVisVideo, VISUAL_VIDEO_DEPTH_GL);
00213
00214 if (const SDL_VideoInfo* VideoInfo = SDL_GetVideoInfo())
00215 {
00216 int VideoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE;
00217 VideoFlags |= VideoInfo->hw_available ? SDL_HWSURFACE : SDL_SWSURFACE;
00218 VideoFlags |= VideoInfo->blit_hw ? SDL_HWACCEL : 0;
00219
00220 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
00221
00222 m_pSurface = SDL_SetVideoMode(width, height, 16, VideoFlags);
00223 }
00224 else
00225 {
00226 cerr << "Error obtaining SDL video information" << endl;
00227 }
00228 }
00229 else
00230 {
00231 m_pSurface = SDL_SetVideoMode(width, height, m_pVisVideo->bpp * 8, 0);
00232 }
00233
00234 visual_video_set_buffer(m_pVisVideo, m_pSurface->pixels);
00235 visual_video_set_pitch(m_pVisVideo, m_pSurface->pitch);
00236
00237 return true;
00238 }
00239
00240 bool LibVisualPlugin::draw(QPainter *, const QColor&)
00241 {
00242 if (visual_bin_depth_changed(m_pVisBin))
00243 {
00244 if (SDL_MUSTLOCK(m_pSurface) == SDL_TRUE)
00245 {
00246 SDL_LockSurface(m_pSurface);
00247 }
00248
00249 createScreen(m_pSurface->w, m_pSurface->h);
00250 visual_bin_sync(m_pVisBin, true);
00251 if (SDL_MUSTLOCK(m_pSurface) == SDL_TRUE)
00252 {
00253 SDL_UnlockSurface(m_pSurface);
00254 }
00255
00256 }
00257
00258 if (visual_bin_get_depth(m_pVisBin) == VISUAL_VIDEO_DEPTH_GL)
00259 {
00260 visual_bin_run(m_pVisBin);
00261 SDL_GL_SwapBuffers();
00262 }
00263 else
00264 {
00265 if (SDL_MUSTLOCK(m_pSurface) == SDL_TRUE)
00266 {
00267 SDL_LockSurface(m_pSurface);
00268 }
00269
00270 visual_video_set_buffer(m_pVisVideo, m_pSurface->pixels);
00271 visual_bin_run(m_pVisBin);
00272
00273 if (SDL_MUSTLOCK(m_pSurface) == SDL_TRUE)
00274 {
00275 SDL_UnlockSurface(m_pSurface);
00276 }
00277
00278 if (VisPalette* pVisPalette = visual_bin_get_palette(m_pVisBin))
00279 {
00280 SDL_Color Palette[256];
00281
00282 for(int i = 0; i < 256; i ++)
00283 {
00284 Palette[i].r = pVisPalette->colors[i].r;
00285 Palette[i].g = pVisPalette->colors[i].g;
00286 Palette[i].b = pVisPalette->colors[i].b;
00287 }
00288 SDL_SetColors(m_pSurface, Palette, 0, 256);
00289 }
00290 SDL_Flip(m_pSurface);
00291 }
00292
00293 return false;
00294 }
00295
00296
00297 int LibVisualPlugin::AudioCallback(VisInput*, VisAudio* audio, void* priv)
00298 {
00299 LibVisualPlugin* that = static_cast<LibVisualPlugin*>(priv);
00300
00301 VisBuffer buf;
00302 visual_buffer_init(&buf, that->m_Audio, 1024, 0);
00303 visual_audio_samplepool_input(audio->samplepool, &buf, VISUAL_AUDIO_SAMPLE_RATE_44100,
00304 VISUAL_AUDIO_SAMPLE_FORMAT_S16, VISUAL_AUDIO_SAMPLE_CHANNEL_STEREO);
00305
00306 return 0;
00307 }
00308
00309
00310 uint LibVisualPlugin::plugins(QStringList *list)
00311 {
00312 visual_log_set_verboseness(VISUAL_LOG_VERBOSENESS_LOW);
00313
00314 if (!visual_is_initialized())
00315 {
00316 char **argv;
00317 int argc;
00318 argv = (char**)malloc(sizeof(char*));
00319 argv[0] = AppName;
00320 argc = 1;
00321 visual_init(&argc, &argv);
00322 free(argv);
00323 }
00324
00325
00326 const char *plugin = 0;
00327 uint count = 0;
00328 while((plugin = visual_actor_get_next_by_name(plugin)))
00329 {
00330 *list << QString("LibVisual-") + plugin;
00331 count++;
00332 }
00333
00334
00335
00336 return count;
00337 }
00338
00339 static class LibVisualFactory : public VisFactory
00340 {
00341 public:
00342 const QString &name(void) const
00343 {
00344 static QString name("LibVisual");
00345 return name;
00346 }
00347
00348 uint plugins(QStringList *list) const
00349 {
00350 return LibVisualPlugin::plugins(list);
00351 }
00352
00353 VisualBase *create(MainVisual *parent, long int winid, const QString &pluginName) const
00354 {
00355 return new LibVisualPlugin(parent, winid, pluginName);
00356 }
00357 }LibVisualFactory;
00358
00359 #endif // SDL_SUPPORT && LIBVISUAL_SUPPORT