void loop() { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, WIDTH, HEIGHT, 0, -1, 1); glEnable(GL_LINE_SMOOTH); glEnable(GL_POINT_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); physics_start(); while (!glfwWindowShouldClose(window) && running) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (pthread_mutex_trylock(&lock) == 0) { for (int i = 0; i < PARTICLES_MAX; i++) { struct particle *p = &array[i]; if (!p->m) continue; glPointSize(particle_radius(p) * 2.0f); double x, y; double alpha = particle_getcoords(*p, &x, &y); glColor4d(p->color[0], p->color[1], p->color[2], alpha); glBegin(GL_POINTS); glVertex2d(x, y); glEnd(); } pthread_mutex_unlock(&lock); } if (mouse.is_dragging) { double x, y; glfwGetCursorPos(window, &x, &y); glBegin(GL_LINES); glColor3dv(next_color); glVertex2d(mouse.xp, mouse.yp); glVertex2d(x, y); glEnd(); } glfwSwapBuffers(window); glfwPollEvents(); glfwSetWindowTitle(window, newtitle()); } physics_stop(); }
//static gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gpointer data) { #ifdef LL_GST_REPORT_STATE_CHANGES LL_DEBUGS("MediaCallback") << "Got GST message type: " << GST_MESSAGE_TYPE_NAME (message) << LL_ENDL; #endif LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_BUFFERING: { gint percent = 0; gst_message_parse_buffering(message, &percent); #ifdef LL_GST_REPORT_STATE_CHANGES LL_DEBUGS("MediaBuffering") << "GST buffering: " << percent << "%%" << LL_ENDL; #endif LLMediaEvent event( impl, percent ); impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); } break; case GST_MESSAGE_STATE_CHANGED: { GstState old_state; GstState new_state; GstState pending_state; gst_message_parse_state_changed(message, &old_state, &new_state, &pending_state); #ifdef LL_GST_REPORT_STATE_CHANGES // not generally very useful, and rather spammy. LL_DEBUGS("MediaState") << "GST state change (old,<new>,pending): "<< get_gst_state_name(old_state) << ",<" << get_gst_state_name(new_state) << ">," << get_gst_state_name(pending_state) << LL_ENDL; #endif // LL_GST_REPORT_STATE_CHANGES switch (new_state) { case GST_STATE_VOID_PENDING: break; case GST_STATE_NULL: #ifdef LL_GST_REPORT_STATE_CHANGES LL_DEBUGS("MediaImpl") << "State changed to NULL" << LL_ENDL; #endif if (impl->getState() == GST_STATE_PLAYING) { // Stream was probably dropped, trying to restart impl->play(); #ifdef LL_GST_REPORT_STATE_CHANGES LL_DEBUGS("MediaImpl") << "Trying to restart." << LL_ENDL; #endif } break; case GST_STATE_READY: break; case GST_STATE_PAUSED: break; case GST_STATE_PLAYING: //impl->mLastTitle = ""; LLMediaEvent event( impl, 100 ); impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); // emit an event to say that a media source was loaded LLMediaEvent event2( impl ); impl->getEventEmitter().update( &LLMediaObserver::onMediaLoaded, event2 ); break; } break; } case GST_MESSAGE_ERROR: { GError *err = NULL; gchar *debug = NULL; gst_message_parse_error (message, &err, &debug); LL_WARNS("MediaImpl") << "GST Error: " << err->message << LL_ENDL; g_error_free (err); g_free (debug); impl->addCommand(LLMediaBase::COMMAND_STOP); //impl->addCommand(LLMediaBase::COMMAND_START); break; } case GST_MESSAGE_INFO: { GError *err = NULL; gchar *debug = NULL; gst_message_parse_info (message, &err, &debug); LL_INFOS("MediaImpl") << "GST info: " << err->message << LL_ENDL; g_error_free (err); g_free (debug); break; } case GST_MESSAGE_WARNING: { GError *err = NULL; gchar *debug = NULL; gst_message_parse_warning (message, &err, &debug); LL_WARNS("MediaImpl") << "GST warning: " << err->message << LL_ENDL; g_error_free (err); g_free (debug); break; } case GST_MESSAGE_TAG: { GstTagList *new_tags; gst_message_parse_tag( message, &new_tags ); gchar *title; if ( gst_tag_list_get_string(new_tags, GST_TAG_TITLE, &title) ) { LL_INFOS("MediaInfo") << "Title: " << title << LL_ENDL; std::string newtitle(title); gst_tag_list_free(new_tags); if ( newtitle != impl->mLastTitle && newtitle != "" ) { impl->mLastTitle = newtitle; LLMediaEvent event( impl, impl->mLastTitle ); impl->getEventEmitter().update( &LLMediaObserver::onMediaTitleChange, event ); } g_free(title); } break; } case GST_MESSAGE_EOS: { /* end-of-stream */ LL_DEBUGS("MediaImpl") << "GST end-of-stream." << LL_ENDL; if (impl->isLooping()) { LL_DEBUGS("MediaImpl") << "looping media..." << LL_ENDL; impl->stop(); impl->play(); } else { // inject a COMMAND_STOP impl->addCommand(LLMediaBase::COMMAND_STOP); } break; } default: /* unhandled message */ break; } /* we want to be notified again the next time there is a message * on the bus, so return true (false means we want to stop watching * for messages on the bus and our callback should not be called again) */ return TRUE; }
gboolean MediaPluginGStreamer010::processGSTEvents(GstBus *bus, GstMessage *message) { if (!message) return TRUE; // shield against GStreamer bug if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) { DEBUGMSG("Got GST message type: %s", GST_MESSAGE_TYPE_NAME (message)); } else { // TODO: grok 'duration' message type DEBUGMSG("Got GST message type: %s", GST_MESSAGE_TYPE_NAME (message)); } switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_BUFFERING: { // NEEDS GST 0.10.11+ and America discovered by C.Columbus gint percent = 0; gst_message_parse_buffering(message, &percent); DEBUGMSG("GST buffering: %d%%", percent); break; } case GST_MESSAGE_STATE_CHANGED: { GstState old_state; GstState new_state; GstState pending_state; gst_message_parse_state_changed(message, &old_state, &new_state, &pending_state); #ifdef LL_GST_REPORT_STATE_CHANGES // not generally very useful, and rather spammy. DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", get_gst_state_name(old_state), get_gst_state_name(new_state), get_gst_state_name(pending_state)); #endif // LL_GST_REPORT_STATE_CHANGES switch (new_state) { case GST_STATE_VOID_PENDING: break; case GST_STATE_NULL: break; case GST_STATE_READY: setStatus(STATUS_LOADED); break; case GST_STATE_PAUSED: setStatus(STATUS_PAUSED); break; case GST_STATE_PLAYING: setStatus(STATUS_PLAYING); break; } break; } case GST_MESSAGE_ERROR: { GError *err = NULL; gchar *debug = NULL; gst_message_parse_error (message, &err, &debug); WARNMSG("GST error: %s", err?err->message:"(unknown)"); if (err) g_error_free (err); g_free (debug); mCommand = COMMAND_STOP; setStatus(STATUS_ERROR); break; } case GST_MESSAGE_INFO: { GError *err = NULL; gchar *debug = NULL; gst_message_parse_info (message, &err, &debug); INFOMSG("GST info: %s", err?err->message:"(unknown)"); if (err) g_error_free (err); g_free (debug); break; } case GST_MESSAGE_WARNING: { GError *err = NULL; gchar *debug = NULL; gst_message_parse_warning (message, &err, &debug); WARNMSG("GST warning: %s", err?err->message:"(unknown)"); if (err) g_error_free (err); g_free (debug); break; } case GST_MESSAGE_TAG: { GstTagList *new_tags; gst_message_parse_tag( message, &new_tags ); gchar *title = NULL; if ( gst_tag_list_get_string(new_tags, GST_TAG_TITLE, &title) ) { //WARMING("Title: %s", title); std::string newtitle(title); gst_tag_list_free(new_tags); if ( newtitle != mLastTitle && !newtitle.empty() ) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); message.setValue("name", newtitle ); sendMessage( message ); mLastTitle = newtitle; } g_free(title); } break; } case GST_MESSAGE_EOS: { /* end-of-stream */ DEBUGMSG("GST end-of-stream."); if (mIsLooping) { DEBUGMSG("looping media..."); double eos_pos_sec = 0.0F; bool got_eos_position = getTimePos(eos_pos_sec); if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) { // if we know that the movie is really short, don't // loop it else it can easily become a time-hog // because of GStreamer spin-up overhead DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); // inject a COMMAND_PAUSE mCommand = COMMAND_PAUSE; } else { #undef LLGST_LOOP_BY_SEEKING // loop with a stop-start instead of a seek, because it actually seems rather // faster than seeking on remote streams. #ifdef LLGST_LOOP_BY_SEEKING // first, try looping by an explicit rewind bool seeksuccess = seek(0.0); if (seeksuccess) { play(1.0); } else #endif // LLGST_LOOP_BY_SEEKING { // use clumsy stop-start to loop DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); stop(); play(1.0); } } } else // not a looping media { // inject a COMMAND_STOP mCommand = COMMAND_STOP; } } break; default: /* unhandled message */ break; } /* we want to be notified again the next time there is a message * on the bus, so return true (false means we want to stop watching * for messages on the bus and our callback should not be called again) */ return TRUE; }