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) { #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; }
//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; }