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", LLGST_MESSAGE_TYPE_NAME (message)); } else { // TODO: grok 'duration' message type DEBUGMSG("Got GST message type: %s", LLGST_MESSAGE_TYPE_NAME (message)); } switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_BUFFERING: { // NEEDS GST 0.10.11+ if (llgst_message_parse_buffering) { gint percent = 0; llgst_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; llgst_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; llgst_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: { if (llgst_message_parse_info) { GError *err = NULL; gchar *debug = NULL; llgst_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; llgst_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_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; }
static gboolean my_bus_callback (GstBus *bus, GstMessage *message, gpointer data) { if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) { llinfos << "Got GST message type: " << LLGST_MESSAGE_TYPE_NAME (message) << llendl; } else { lldebugs << "Got GST message type: " << LLGST_MESSAGE_TYPE_NAME (message) << llendl; } LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_BUFFERING: { // NEEDS GST 0.10.11+ if (llgst_message_parse_buffering) { gint percent = 0; llgst_message_parse_buffering(message, &percent); llinfos << "GST buffering: " << percent << "%" << llendl; // ModeBuffering seems to do nothing except make // the UI worse /*if (percent < 100) impl->setCurrentMode(LLMediaImplGStreamer::ModeBuffering);*/ } break; } case GST_MESSAGE_STATE_CHANGED: { GstState old_state; GstState new_state; GstState pending_state; llgst_message_parse_state_changed(message, &old_state, &new_state, &pending_state); #ifdef LL_GST_REPORT_STATE_CHANGES // not generally very useful, and rather spammy. llinfos << "state change (old,<new>,pending): " << get_gst_state_name(old_state) << ", <" << get_gst_state_name(new_state) << ">, " << get_gst_state_name(pending_state) << llendl; #endif // LL_GST_REPORT_STATE_CHANGES switch (new_state) { case GST_STATE_VOID_PENDING: impl->setCurrentMode(LLMediaImplGStreamer::ModeNone); break; case GST_STATE_NULL: impl->setCurrentMode(LLMediaImplGStreamer::ModeNone); break; case GST_STATE_READY: impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped); break; case GST_STATE_PAUSED: impl->setCurrentMode(LLMediaImplGStreamer::ModePaused); break; case GST_STATE_PLAYING: impl->setCurrentMode(LLMediaImplGStreamer::ModePlaying); break; } break; } case GST_MESSAGE_ERROR: { GError *err; gchar *debug; llgst_message_parse_error (message, &err, &debug); llinfos << "GST error: " << err->message << llendl; g_error_free (err); g_free (debug); impl->setCurrentMode(LLMediaImplGStreamer::ModeError); impl->stop(); break; } case GST_MESSAGE_INFO: { if (llgst_message_parse_info) { GError *err; gchar *debug; llgst_message_parse_info (message, &err, &debug); llinfos << "GST info: " << err->message << llendl; g_error_free (err); g_free (debug); } break; } case GST_MESSAGE_WARNING: { GError *err; gchar *debug; llgst_message_parse_warning (message, &err, &debug); llinfos << "GST warning: " << err->message << llendl; g_error_free (err); g_free (debug); break; } case GST_MESSAGE_EOS: /* end-of-stream */ llinfos << "GST EOS." << llendl; impl->setCurrentMode(LLMediaImplGStreamer::ModeStopped);//? impl->stop(); break; default: /* unhandled message */ break; } /* we want to be notified again the next time there is a message * on the bus, so returning TRUE (FALSE means we want to stop watching * for messages on the bus and our callback should not be called again) */ return TRUE; }
//static gboolean LLMediaImplGStreamer::bus_callback (GstBus *bus, GstMessage *message, gpointer data) { if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) { DEBUGMSG("Got GST message type: %s", LLGST_MESSAGE_TYPE_NAME (message)); } else { DEBUGMSG("Got GST message type: %s", LLGST_MESSAGE_TYPE_NAME (message)); } LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_BUFFERING: { // NEEDS GST 0.10.11+ if (llgst_message_parse_buffering) { gint percent = 0; llgst_message_parse_buffering(message, &percent); DEBUGMSG("GST buffering: %d%%", percent); 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; llgst_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: break; case GST_STATE_PAUSED: break; case GST_STATE_PLAYING: 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; llgst_message_parse_error (message, &err, &debug); WARNMSG("GST error: %s", err->message); g_error_free (err); g_free (debug); impl->addCommand(LLMediaBase::COMMAND_STOP); break; } case GST_MESSAGE_INFO: { if (llgst_message_parse_info) { GError *err = NULL; gchar *debug = NULL; llgst_message_parse_info (message, &err, &debug); INFOMSG("GST info: %s", err->message); g_error_free (err); g_free (debug); } break; } case GST_MESSAGE_WARNING: { GError *err = NULL; gchar *debug = NULL; llgst_message_parse_warning (message, &err, &debug); WARNMSG("GST warning: %s", err->message); g_error_free (err); g_free (debug); break; } case GST_MESSAGE_EOS: /* end-of-stream */ DEBUGMSG("GST end-of-stream."); if (impl->isLooping()) { DEBUGMSG("looping media..."); 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; }