diff -r 9539c10021ba -r 52b800cc01fc autobuild.xml
--- a/autobuild.xml Tue Sep 25 13:04:14 2012 -0400
+++ b/autobuild.xml Sun Nov 11 17:27:32 2012 -0600
@@ -843,30 +843,6 @@
- gstreamer
-
gtk-atk-pango-glib
license
@@ -903,6 +879,42 @@
+ gstreamer
+
+ license
+ lgpl
+ license_file
+ LICENSES/gstreamer.txt
+ name
+ gstreamer
+ platforms
+
+ linux
+
+ archive
+
+ hash
+ ddbc0a64ad788107877fee777403592c
+ url
+ http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/gstreamer-linux-20101013.tar.bz2
+
+ name
+ linux
+
+ windows
+
+ archive
+
+ hash
+ 063358a877595303075ccca8c546266f
+ url
+ http://download.kokuaviewer.org/files/libs/gstreamer-glib-iconv-libxml-plugins-autobuild-windows-20110816.tar.bz2
+
+ name
+ windows
+
+
+
havok-source
license
diff -r 9539c10021ba -r 52b800cc01fc doc/contributions.txt
--- a/doc/contributions.txt Tue Sep 25 13:04:14 2012 -0400
+++ b/doc/contributions.txt Sun Nov 11 17:27:32 2012 -0600
@@ -186,6 +186,7 @@
STORM-1532
Armin Weatherwax
VWR-8436
+ OPEN-151
ArminasX Saiman
Arya Braveheart
Asaeda Meltingdots
@@ -255,6 +256,7 @@
VWR-26066
VWR-26458
WEB-262
+ OPEN-151
Bryn Oh
Buckaroo Mu
Bulli Schumann
@@ -519,6 +521,7 @@
VWR-2948
VWR-3605
VWR-8617
+ OPEN-151
Jack Abraham
Jagga Meredith
JB Kraft
@@ -770,6 +773,7 @@
VWR-8454
VWR-8689
VWR-9007
+ OPEN-151
Medhue Simoni
Mel Vanbeeck
Melinda Latynina
@@ -895,6 +899,7 @@
STORM-1087
STORM-1090
STORM-1828
+ OPEN-151
Nicoladie Gymnast
Nounouch Hapmouche
VWR-238
diff -r 9539c10021ba -r 52b800cc01fc indra/cmake/Copy3rdPartyLibs.cmake
--- a/indra/cmake/Copy3rdPartyLibs.cmake Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/cmake/Copy3rdPartyLibs.cmake Sun Nov 11 17:27:32 2012 -0600
@@ -33,10 +33,74 @@
set(debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}")
set(debug_files
+ alut.dll
+ openal32.dll
openjpegd.dll
libapr-1.dll
libaprutil-1.dll
libapriconv-1.dll
+
+ # gstreamer dlls - not plugins
+ avcodec-gpl-52.dll
+ avdevice-gpl-52.dll
+ avfilter-gpl-1.dll
+ avformat-gpl-52.dll
+ avutil-gpl-50.dll
+ iconv.dll
+ liba52-0.dll
+ libbz2.dll
+ libcelt-0.dll
+ libdca-0.dll
+ libexpat-1.dll
+ libfaad-2.dll
+ libFLAC-8.dll
+ libgcrypt-11.dll
+ libgio-2.0-0.dll
+ libglib-2.0-0.dll
+ libgmodule-2.0-0.dll
+ libgnutls-26.dll
+ libgobject-2.0-0.dll
+ libgpg-error-0.dll
+ libgstapp-0.10.dll
+ libgstaudio-0.10.dll
+ libgstbase-0.10.dll
+ libgstcontroller-0.10.dll
+ libgstdataprotocol-0.10.dll
+ libgstfft-0.10.dll
+ libgstinterfaces-0.10.dll
+ libgstnet-0.10.dll
+ libgstnetbuffer-0.10.dll
+ libgstpbutils-0.10.dll
+ libgstphotography-0.10.dll
+ libgstreamer-0.10.dll
+ libgstriff-0.10.dll
+ libgstrtp-0.10.dll
+ libgstrtsp-0.10.dll
+ libgstsdp-0.10.dll
+ libgstsignalprocessor-0.10.dll
+ libgsttag-0.10.dll
+ libgstvideo-0.10.dll
+ libgthread-2.0-0.dll
+ libmms-0.dll
+ libmpeg2-0.dll
+ libneon-27.dll
+ libogg-0.dll
+ liboil-0.3-0.dll
+ libsoup-2.4-1.dll
+ libtasn1-3.dll
+ libtheora-0.dll
+ libtheoradec-1.dll
+ libvorbis-0.dll
+ libvorbisenc-2.dll
+ libvorbisfile-3.dll
+ libwavpack-1.dll
+ libx264-67.dll
+ libxml2-2.dll
+ libxml2.dll
+ SDL.dll
+ xvidcore.dll
+ z.dll
+
ssleay32.dll
libeay32.dll
libcollada14dom22-d.dll
@@ -46,10 +110,74 @@
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
set(release_files
+ alut.dll
+ openal32.dll
openjpeg.dll
libapr-1.dll
libaprutil-1.dll
libapriconv-1.dll
+
+ # gstreamer dlls - not plugins
+ avcodec-gpl-52.dll
+ avdevice-gpl-52.dll
+ avfilter-gpl-1.dll
+ avformat-gpl-52.dll
+ avutil-gpl-50.dll
+ iconv.dll
+ liba52-0.dll
+ libbz2.dll
+ libcelt-0.dll
+ libdca-0.dll
+ libexpat-1.dll
+ libfaad-2.dll
+ libFLAC-8.dll
+ libgcrypt-11.dll
+ libgio-2.0-0.dll
+ libglib-2.0-0.dll
+ libgmodule-2.0-0.dll
+ libgnutls-26.dll
+ libgobject-2.0-0.dll
+ libgpg-error-0.dll
+ libgstapp-0.10.dll
+ libgstaudio-0.10.dll
+ libgstbase-0.10.dll
+ libgstcontroller-0.10.dll
+ libgstdataprotocol-0.10.dll
+ libgstfft-0.10.dll
+ libgstinterfaces-0.10.dll
+ libgstnet-0.10.dll
+ libgstnetbuffer-0.10.dll
+ libgstpbutils-0.10.dll
+ libgstphotography-0.10.dll
+ libgstreamer-0.10.dll
+ libgstriff-0.10.dll
+ libgstrtp-0.10.dll
+ libgstrtsp-0.10.dll
+ libgstsdp-0.10.dll
+ libgstsignalprocessor-0.10.dll
+ libgsttag-0.10.dll
+ libgstvideo-0.10.dll
+ libgthread-2.0-0.dll
+ libmms-0.dll
+ libmpeg2-0.dll
+ libneon-27.dll
+ libogg-0.dll
+ liboil-0.3-0.dll
+ libsoup-2.4-1.dll
+ libtasn1-3.dll
+ libtheora-0.dll
+ libtheoradec-1.dll
+ libvorbis-0.dll
+ libvorbisenc-2.dll
+ libvorbisfile-3.dll
+ libwavpack-1.dll
+ libx264-67.dll
+ libxml2-2.dll
+ libxml2.dll
+ SDL.dll
+ xvidcore.dll
+ z.dll
+
ssleay32.dll
libeay32.dll
libcollada14dom22.dll
@@ -217,6 +345,7 @@
libllqtwebkit.dylib
libminizip.a
libndofdev.dylib
+ libopenal.1.dylib
libhunspell-1.3.0.dylib
libexception_handler.dylib
libcollada14dom.dylib
diff -r 9539c10021ba -r 52b800cc01fc indra/cmake/GStreamer010Plugin.cmake
--- a/indra/cmake/GStreamer010Plugin.cmake Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/cmake/GStreamer010Plugin.cmake Sun Nov 11 17:27:32 2012 -0600
@@ -6,33 +6,69 @@
pkg_check_modules(GSTREAMER010 REQUIRED gstreamer-0.10)
pkg_check_modules(GSTREAMER010_PLUGINS_BASE REQUIRED gstreamer-plugins-base-0.10)
-elseif (LINUX)
- use_prebuilt_binary(gstreamer)
- # possible libxml should have its own .cmake file instead
- use_prebuilt_binary(libxml)
+
+else (STANDALONE)
+
+ # Possibly libxml and glib should have their own .cmake file instead...
+ use_prebuilt_binary(gstreamer) # includes glib, libxml, and iconv on Windows
set(GSTREAMER010_FOUND ON FORCE BOOL)
set(GSTREAMER010_PLUGINS_BASE_FOUND ON FORCE BOOL)
+
+ if (WINDOWS)
+ # gstreamer-plugins are packaged with gstreamer now.
+ # In case someone wants to have 2 packages again in future uncomment:
+ # use_prebuilt_binary(gst_plugins)
+ set(GSTREAMER010_INCLUDE_DIRS
+ ${LIBS_PREBUILT_DIR}/include/gstreamer-0.10
+ ${LIBS_PREBUILT_DIR}/include/glib
+ ${LIBS_PREBUILT_DIR}/include/libxml2
+ )
+ else (WINDOWS)
+ use_prebuilt_binary(glib) # gstreamer needs glib
+ use_prebuilt_binary(libxml)
set(GSTREAMER010_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/gstreamer-0.10
${LIBS_PREBUILT_DIR}/include/glib-2.0
${LIBS_PREBUILT_DIR}/include/libxml2
)
+ endif (WINDOWS)
+
+endif (STANDALONE)
+
+if (WINDOWS)
+
# We don't need to explicitly link against gstreamer itself, because
# LLMediaImplGStreamer probes for the system's copy at runtime.
set(GSTREAMER010_LIBRARIES
+ gstaudio-0.10.lib
+ gstbase-0.10.lib
+ gstreamer-0.10.lib
+ gstvideo-0.10.lib #slvideoplugin
+ gstinterfaces-0.10.lib
+ gobject-2.0
+ gmodule-2.0
+ gthread-2.0
+ glib-2.0
+ )
+else (WINDOWS)
+ set(GSTREAMER010_LIBRARIES
+ gstvideo-0.10
+ gstaudio-0.10
+ gstbase-0.10
+ gstreamer-0.10
gobject-2.0
gmodule-2.0
dl
gthread-2.0
+ rt
glib-2.0
)
-endif (STANDALONE)
+endif (WINDOWS)
+
if (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND)
+ if (NOT DARWIN)
set(GSTREAMER010 ON CACHE BOOL "Build with GStreamer-0.10 streaming media support.")
+ add_definitions(-DLL_GSTREAMER010_ENABLED=1)
+ endif (NOT DARWIN)
endif (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND)
-
-if (GSTREAMER010)
- add_definitions(-DLL_GSTREAMER010_ENABLED=1)
-endif (GSTREAMER010)
-
diff -r 9539c10021ba -r 52b800cc01fc indra/cmake/OPENAL.cmake
--- a/indra/cmake/OPENAL.cmake Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/cmake/OPENAL.cmake Sun Nov 11 17:27:32 2012 -0600
@@ -2,11 +2,7 @@
include(Linking)
include(Prebuilt)
-if (LINUX)
set(OPENAL ON CACHE BOOL "Enable OpenAL")
-else (LINUX)
- set(OPENAL OFF CACHE BOOL "Enable OpenAL")
-endif (LINUX)
if (OPENAL)
set(OPENAL_LIB_INCLUDE_DIRS "${LIBS_PREBUILT_DIR}/include/AL")
diff -r 9539c10021ba -r 52b800cc01fc indra/llmessage/llcurl.h
--- a/indra/llmessage/llcurl.h Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/llmessage/llcurl.h Sun Nov 11 17:27:32 2012 -0600
@@ -252,7 +252,7 @@
CURL* mCurlEasyHandle;
struct curl_slist* mHeaders;
-
+ struct curl_slist* mAliases;
std::stringstream mRequest;
LLChannelDescriptors mChannels;
LLIOPipe::buffer_ptr_t mOutput;
diff -r 9539c10021ba -r 52b800cc01fc indra/llmessage/llcurl.cpp
--- a/indra/llmessage/llcurl.cpp Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/llmessage/llcurl.cpp Sun Nov 11 17:27:32 2012 -0600
@@ -286,6 +286,7 @@
LLCurl::Easy::Easy()
: mHeaders(NULL),
+ mAliases(NULL),
mCurlEasyHandle(NULL)
{
mErrorBuffer[0] = 0;
@@ -318,6 +319,7 @@
releaseEasyHandle(mCurlEasyHandle);
--gCurlEasyCount;
curl_slist_free_all(mHeaders);
+ curl_slist_free_all(mAliases);
for_each(mStrings.begin(), mStrings.end(), DeletePointerArray());
if (mResponder && LLCurl::sNotQuitting) //aborted
@@ -338,6 +340,11 @@
curl_slist_free_all(mHeaders);
mHeaders = NULL;
}
+ if (mAliases)
+ {
+ curl_slist_free_all(mAliases);
+ mAliases = NULL;
+ }
mRequest.str("");
mRequest.clear();
@@ -378,6 +385,7 @@
void LLCurl::Easy::setHeaders()
{
setopt(CURLOPT_HTTPHEADER, mHeaders);
+ setopt(CURLOPT_HTTP200ALIASES, mAliases); // Just in case -- MC
}
void LLCurl::Easy::getTransferInfo(LLCurl::TransferInfo* info)
@@ -525,6 +533,11 @@
setopt(CURLOPT_SSL_VERIFYHOST, 0);
setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT));
+ mAliases = curl_slist_append(mAliases, "ICY 200 OK");
+ mAliases = curl_slist_append(mAliases, "ICY 402 Service Unavailabe");
+ setopt(CURLOPT_HTTP200ALIASES, mAliases);
+ //setopt(CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); // Possible streaming fix? -- MC
+
setoptString(CURLOPT_URL, url);
mResponder = responder;
diff -r 9539c10021ba -r 52b800cc01fc indra/llplugin/llpluginclassmedia.h
--- a/indra/llplugin/llpluginclassmedia.h Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/llplugin/llpluginclassmedia.h Sun Nov 11 17:27:32 2012 -0600
@@ -36,6 +36,7 @@
#include
#include "v4color.h"
+
class LLPluginClassMedia : public LLPluginProcessParentOwner
{
LOG_CLASS(LLPluginClassMedia);
@@ -249,6 +250,11 @@
// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE
std::string getClickUUID() const { return mClickUUID; };
+ #if LL_WINDOWS
+ //Open a debug console for this plugin.
+ void showConsole();
+ #endif
+
// These are valid during MEDIA_EVENT_DEBUG_MESSAGE
std::string getDebugMessageText() const { return mDebugMessageText; };
std::string getDebugMessageLevel() const { return mDebugMessageLevel; };
@@ -279,6 +285,11 @@
// Hang the plugin. If you use this outside of a testbed, you will be punished.
void hangPlugin();
+ // This sends the message "base", "cleanup" to the plugin
+ // Don't call this unless you know what you're doing
+ // and you know this is exactly what you want to do
+ void forceCleanUpPlugin();
+
///////////////////////////////////
// media time class functions
bool pluginSupportsMediaTime(void);
diff -r 9539c10021ba -r 52b800cc01fc indra/llplugin/llpluginclassmedia.cpp
--- a/indra/llplugin/llpluginclassmedia.cpp Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/llplugin/llpluginclassmedia.cpp Sun Nov 11 17:27:32 2012 -0600
@@ -1230,6 +1230,15 @@
return !version.empty();
}
+#if LL_WINDOWS
+void LLPluginClassMedia::showConsole()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "show_console");
+
+ sendMessage(message);
+}
+#endif
+
void LLPluginClassMedia::focus(bool focused)
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "focus");
@@ -1374,6 +1383,12 @@
sendMessage(message);
}
+void LLPluginClassMedia::forceCleanUpPlugin()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_BASE, "cleanup");
+
+ sendMessage(message);
+}
////////////////////////////////////////////////////////////
// MARK: media_time class functions
diff -r 9539c10021ba -r 52b800cc01fc indra/llplugin/llplugininstance.cpp
--- a/indra/llplugin/llplugininstance.cpp Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/llplugin/llplugininstance.cpp Sun Nov 11 17:27:32 2012 -0600
@@ -123,7 +123,7 @@
{
result = init_function(staticReceiveMessage, (void*)this, &mPluginSendMessageFunction, &mPluginUserData);
- if(result != APR_SUCCESS)
+ if((result != APR_SUCCESS) || (mPluginUserData == NULL))
{
LL_WARNS("Plugin") << "call to init function failed with error " << result << LL_ENDL;
}
@@ -139,7 +139,8 @@
*/
void LLPluginInstance::sendMessage(const std::string &message)
{
- if(mPluginSendMessageFunction)
+ // Don't check for a NULL mPluginUserData *ON PAIN OF DEATH* -- MC
+ if (mPluginSendMessageFunction && mPluginUserData)
{
LL_DEBUGS("Plugin") << "sending message to plugin: \"" << message << "\"" << LL_ENDL;
mPluginSendMessageFunction(message.c_str(), &mPluginUserData);
diff -r 9539c10021ba -r 52b800cc01fc indra/llplugin/llpluginprocesschild.h
--- a/indra/llplugin/llpluginprocesschild.h Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/llplugin/llpluginprocesschild.h Sun Nov 11 17:27:32 2012 -0600
@@ -29,6 +29,8 @@
#ifndef LL_LLPLUGINPROCESSCHILD_H
#define LL_LLPLUGINPROCESSCHILD_H
+#include
+
#include "llpluginmessage.h"
#include "llpluginmessagepipe.h"
#include "llplugininstance.h"
@@ -68,6 +70,10 @@
// Inherited from LLPluginInstanceMessageListener
/* virtual */ void receivePluginMessage(const std::string &message);
+#if LL_WINDOWS
+ void createConsole();
+#endif
+
private:
enum EState
@@ -80,6 +86,7 @@
STATE_PLUGIN_INITIALIZING, // plugin is processing init message
STATE_RUNNING, // steady state (processing messages)
STATE_UNLOADING, // plugin has sent shutdown_response and needs to be unloaded
+ STATE_UNLOADING_CLEANED, // plugin has (hopefully) cleaned up what it has allocated, now it wants to be cleaned
STATE_UNLOADED, // plugin has been unloaded
STATE_ERROR, // generic bailout state
STATE_DONE // state machine will sit in this state after either error or normal termination.
diff -r 9539c10021ba -r 52b800cc01fc indra/llplugin/llpluginprocesschild.cpp
--- a/indra/llplugin/llpluginprocesschild.cpp Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/llplugin/llpluginprocesschild.cpp Sun Nov 11 17:27:32 2012 -0600
@@ -32,6 +32,15 @@
#include "llplugininstance.h"
#include "llpluginmessagepipe.h"
#include "llpluginmessageclasses.h"
+#include "llpluginclassmedia.h"
+
+#if LL_WINDOWS
+#include
+#include
+#include
+#include
+#include
+#endif
static const F32 HEARTBEAT_SECONDS = 1.0f;
static const F32 PLUGIN_IDLE_SECONDS = 1.0f / 100.0f; // Each call to idle will give the plugin this much time.
@@ -205,6 +214,16 @@
}
setState(STATE_UNLOADED);
break;
+
+ // Special case for when the plugin knows it's cleaned up -- MC
+ case STATE_UNLOADING_CLEANED:
+ if (mInstance)
+ {
+ delete mInstance;
+ mInstance = NULL;
+ }
+ setState(STATE_UNLOADED);
+ break;
case STATE_UNLOADED:
killSockets();
@@ -410,8 +429,14 @@
}
else if(message_name == "sleep_time")
{
- mSleepTime = llmax(parsed.getValueReal("time"), 1.0 / 100.0); // clamp to maximum of 100Hz
+ mSleepTime = parsed.getValueReal("time");
}
+ #if LL_WINDOWS
+ else if(message_name == "show_console")
+ {
+ createConsole();
+ }
+ #endif
else if(message_name == "crash")
{
// Crash the plugin
@@ -520,6 +545,17 @@
LL_WARNS("Plugin") << "shm_remove_response for unknown memory segment!" << LL_ENDL;
}
}
+ else if (message_name == "cleanup_reply")
+ {
+ LL_DEBUGS("PluginChild") << "cleanup_reply message received" << LL_ENDL;
+ passMessage = false;
+
+ setState(STATE_UNLOADING_CLEANED);
+
+ // Clean up this and tell the parent
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "cleanup_reply");
+ sendMessageToParent(message);
+ }
}
}
@@ -561,3 +597,63 @@
}
}
}
+
+#if LL_WINDOWS
+void LLPluginProcessChild::createConsole()
+{
+ if (!AttachConsole(-1))
+ {
+ // error creating console
+ TCHAR buffer[1024];
+ if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL , GetLastError(), 0, buffer, 1024, NULL))
+ {
+ LL_WARNS("PluginChild") << "Error creating console: " << buffer << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("PluginChild") << "Error creating console, error code: " << GetLastError() << LL_ENDL;
+ }
+ return;
+ }
+
+ HANDLE std_o_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ HANDLE std_e_handle = GetStdHandle(STD_ERROR_HANDLE);
+ if ((std_o_handle == INVALID_HANDLE_VALUE) || (std_e_handle == INVALID_HANDLE_VALUE))
+ {
+ LL_WARNS("PluginChild") << "couldn't create console, std out or err not available" << LL_ENDL;
+ return;
+ }
+
+ int crt_o_filedesc = _open_osfhandle((long)std_o_handle, _O_TEXT);
+ int crt_e_filedesc = _open_osfhandle((long)std_e_handle, _O_TEXT);
+ if ((crt_o_filedesc == -1) || (crt_e_filedesc == -1))
+ {
+ LL_WARNS("PluginChild") << "_open_osfhandle failed" << LL_ENDL;
+ return;
+ }
+ // replace stdout handle
+ FILE* fp_crt_o = _fdopen(crt_o_filedesc, "w");
+ if (!fp_crt_o)
+ {
+ LL_WARNS("PluginChild") << "_fdopen stdout handle failed" << LL_ENDL;
+ return;
+ }
+ *stdout = *fp_crt_o;
+ std::cout.clear(); // clear anything before AllocCo
+
+ // replace stderr handle
+ FILE* fp_crt_e = _fdopen(crt_e_filedesc, "w");
+ if (!fp_crt_e)
+ {
+ LL_WARNS("PluginChild") << "_fdopen stderr handle failed" << LL_ENDL;
+ return;
+ }
+ *stderr = *fp_crt_e;
+ std::cerr.clear(); // clear anything before AllocConsole();
+
+ // set the screen buffer to be big enough to let us scroll text
+ CONSOLE_SCREEN_BUFFER_INFO coninfo;
+ GetConsoleScreenBufferInfo(std_o_handle, &coninfo);
+ coninfo.dwSize.Y = 500; // max console lines
+ SetConsoleScreenBufferSize(std_o_handle, coninfo.dwSize);}
+#endif
\ No newline at end of file
diff -r 9539c10021ba -r 52b800cc01fc indra/llplugin/llpluginprocessparent.h
--- a/indra/llplugin/llpluginprocessparent.h Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/llplugin/llpluginprocessparent.h Sun Nov 11 17:27:32 2012 -0600
@@ -81,6 +81,11 @@
// Go to the proper error state
void errorState(void);
+ // Go to STATE_CLEANUP
+ // Don't call this unless you know what you're doing
+ // and you know this is exactly what you want to do
+ void cleanupState();
+
void setSleepTime(F64 sleep_time, bool force_send = false);
F64 getSleepTime(void) const { return mSleepTime; };
@@ -172,6 +177,8 @@
bool mDebug;
bool mBlocked;
bool mPolledInput;
+ U32 mPortToBind;
+ U32 mBindRetryCount;
LLProcessPtr mDebugger;
diff -r 9539c10021ba -r 52b800cc01fc indra/llplugin/llpluginprocessparent.cpp
--- a/indra/llplugin/llpluginprocessparent.cpp Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/llplugin/llpluginprocessparent.cpp Sun Nov 11 17:27:32 2012 -0600
@@ -34,6 +34,7 @@
#include "stringize.h"
#include "llapr.h"
+#include "llrand.h"
//virtual
LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
@@ -156,6 +157,12 @@
setState(STATE_LAUNCH_FAILURE);
else
setState(STATE_ERROR);
+ mBindRetryCount = 0;
+}
+
+void LLPluginProcessParent::cleanupState()
+{
+ setState(STATE_CLEANUP);
}
void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug)
@@ -165,7 +172,9 @@
mPluginFile = plugin_filename;
mPluginDir = plugin_dir;
mCPUUsage = 0.0f;
- mDebug = debug;
+ mDebug = debug;
+ mPortToBind = 0;
+ mBindRetryCount = 0;
setState(STATE_INITIALIZED);
}
@@ -275,7 +284,6 @@
case STATE_INITIALIZED:
{
-
apr_status_t status = APR_SUCCESS;
apr_sockaddr_t* addr = NULL;
mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
@@ -287,14 +295,28 @@
&addr,
"127.0.0.1",
APR_INET,
- 0, // port 0 = ephemeral ("find me a port")
+ mPortToBind, // initially port 0 = ephemeral ("find me a port")
0,
gAPRPoolp);
if(ll_apr_warn_status(status))
{
+ // A non-zero value for mPortToBind could get us here
killSockets();
- errorState();
+ if (mBindRetryCount > 9)
+ {
+ LL_WARNS("PluginParent") << "apr_sockaddr_info_get could not return successful, out of retries. Bailing out" << LL_ENDL;
+ errorState();
+ }
+ else
+ {
+ LL_WARNS("PluginParent") << "Port " << mPortToBind
+ << " is possibly in use, retrying with a different port. Retry count " << mBindRetryCount+1 << " of 10" << LL_ENDL;
+ ++mBindRetryCount;
+ mPortToBind = ll_rand(16383) + 49152; // See comment on dynamic ports
+ setState(STATE_INITIALIZED); // Necessary?
+ idle_again = true;
+ }
break;
}
@@ -324,7 +346,7 @@
{
LL_WARNS("Plugin") << "Bound port number unknown, bailing out." << LL_ENDL;
- killSockets();
+ //killSockets();
errorState();
break;
}
@@ -964,6 +986,11 @@
mSharedMemoryRegions.erase(iter);
}
}
+ else if (message_name == "cleanup_reply")
+ {
+ LL_DEBUGS("PluginParent") << "cleanup_reply message received" << LL_ENDL;
+ cleanupState();
+ }
else
{
LL_WARNS("Plugin") << "Unknown internal message from child: " << message_name << LL_ENDL;
diff -r 9539c10021ba -r 52b800cc01fc indra/media_plugins/gstreamer010/CMakeLists.txt
--- a/indra/media_plugins/gstreamer010/CMakeLists.txt Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/media_plugins/gstreamer010/CMakeLists.txt Sun Nov 11 17:27:32 2012 -0600
@@ -45,10 +45,16 @@
)
set(media_plugin_gstreamer010_HEADER_FILES
+ llmediaimplgstreamer.h
llmediaimplgstreamervidplug.h
llmediaimplgstreamer_syms.h
llmediaimplgstreamertriviallogging.h
)
+
+set_source_files_properties(${media_plugin_gstreamer010_HEADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND media_plugin_gstreamer010_SOURCE_FILES ${media_plugin_gstreamer010_HEADER_FILES})
add_library(media_plugin_gstreamer010
SHARED
diff -r 9539c10021ba -r 52b800cc01fc indra/media_plugins/gstreamer010/llmediaimplgstreamer.h
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h Sun Nov 11 17:27:32 2012 -0600
@@ -36,9 +36,6 @@
extern "C" {
#include
#include
-
-#include "apr_pools.h"
-#include "apr_dso.h"
}
diff -r 9539c10021ba -r 52b800cc01fc indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h Sun Nov 11 17:27:32 2012 -0600
@@ -31,16 +31,21 @@
#include
-extern "C" {
-#include
-#include
-}
/////////////////////////////////////////////////////////////////////////
// Debug/Info/Warning macros.
+#if LL_WINDOWS
+#include // !impru
+#include // impru
+#define LL_GETPID GetCurrentProcessId
+#else
+#include
+#include
+#define LL_GETPID getpid
+#endif
#define MSGMODULEFOO "(media plugin)"
#define STDERRMSG(...) do{\
- fprintf(stderr, " pid:%d: ", (int)getpid());\
+ fprintf(stderr, " pid:%d: ", (int)LL_GETPID());\
fprintf(stderr, MSGMODULEFOO " %s:%d: ", __FUNCTION__, __LINE__);\
fprintf(stderr, __VA_ARGS__);\
fputc('\n',stderr);\
diff -r 9539c10021ba -r 52b800cc01fc indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h Sun Nov 11 17:27:32 2012 -0600
@@ -35,6 +35,9 @@
#include
#include
#include
+#ifdef LL_LINUX
+ #include
+#endif
}
G_BEGIN_DECLS
diff -r 9539c10021ba -r 52b800cc01fc indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp Sun Nov 11 17:27:32 2012 -0600
@@ -34,15 +34,29 @@
#include
#include
-#include "llmediaimplgstreamer_syms.h"
#include "llmediaimplgstreamertriviallogging.h"
+// #include "llthread.h"
#include "llmediaimplgstreamervidplug.h"
-
GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug);
#define GST_CAT_DEFAULT gst_slvideo_debug
+/* Filter signals and args *//*
+enum
+{
+ *//* FILL ME *//*
+ LAST_SIGNAL
+};
+
+enum
+{
+ ARG_0
+};
+
+#define SLV_SIZECAPS ", width=(int){1,2,4,8,16,32,64,128,256,512,1024}, height=(int){1,2,4,8,16,32,64,128,256,512,1024} "
+#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS ";" GST_VIDEO_CAPS_BGRx SLV_SIZECAPS
+*/
#define SLV_SIZECAPS ", width=(int)[1,2048], height=(int)[1,2048] "
#define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS
@@ -74,9 +88,9 @@
};
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
- llgst_element_class_add_pad_template (element_class,
- llgst_static_pad_template_get (&sink_factory));
- llgst_element_class_set_details (element_class, &element_details);
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_factory));
+ gst_element_class_set_details (element_class, &element_details);
}
@@ -87,7 +101,7 @@
slvideo = GST_SLVIDEO (object);
if (slvideo->caps)
{
- llgst_caps_unref(slvideo->caps);
+ gst_caps_unref(slvideo->caps);
}
G_OBJECT_CLASS(parent_class)->finalize (object);
@@ -98,7 +112,7 @@
gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf)
{
GstSLVideo *slvideo;
- llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
+ g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
slvideo = GST_SLVIDEO(bsink);
@@ -190,7 +204,7 @@
GstSLVideo *slvideo;
slvideo = GST_SLVIDEO(bsink);
- return llgst_caps_ref (slvideo->caps);
+ return gst_caps_ref (slvideo->caps);
}
@@ -200,21 +214,32 @@
{
GstSLVideo *filter;
GstStructure *structure;
+// GstCaps *intersection;
GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
filter = GST_SLVIDEO(bsink);
- int width, height;
+/*
+ intersection = gst_caps_intersect (filter->caps, caps);
+ if (gst_caps_is_empty (intersection))
+ {
+ // no overlap between our caps and requested caps
+ return FALSE;
+ }
+ gst_caps_unref(intersection);
+*/
+ int width = 0;
+ int height = 0;
gboolean ret;
const GValue *fps;
const GValue *par;
- structure = llgst_caps_get_structure (caps, 0);
- ret = llgst_structure_get_int (structure, "width", &width);
- ret = ret && llgst_structure_get_int (structure, "height", &height);
- fps = llgst_structure_get_value (structure, "framerate");
+ structure = gst_caps_get_structure (caps, 0);
+ ret = gst_structure_get_int (structure, "width", &width);
+ ret = ret && gst_structure_get_int (structure, "height", &height);
+ fps = gst_structure_get_value (structure, "framerate");
ret = ret && (fps != NULL);
- par = llgst_structure_get_value (structure, "pixel-aspect-ratio");
+ par = gst_structure_get_value (structure, "pixel-aspect-ratio");
if (!ret)
return FALSE;
@@ -224,34 +249,35 @@
filter->width = width;
filter->height = height;
-
- filter->fps_n = llgst_value_get_fraction_numerator(fps);
- filter->fps_d = llgst_value_get_fraction_denominator(fps);
+ filter->fps_n = gst_value_get_fraction_numerator(fps);
+ filter->fps_d = gst_value_get_fraction_denominator(fps);
if (par)
{
- filter->par_n = llgst_value_get_fraction_numerator(par);
- filter->par_d = llgst_value_get_fraction_denominator(par);
+ filter->par_n = gst_value_get_fraction_numerator(par);
+ filter->par_d = gst_value_get_fraction_denominator(par);
}
else
{
filter->par_n = 1;
filter->par_d = 1;
}
+
GST_VIDEO_SINK_WIDTH(filter) = width;
GST_VIDEO_SINK_HEIGHT(filter) = height;
-
+
// crufty lump - we *always* accept *only* RGBX now.
/*
+
filter->format = SLV_PF_UNKNOWN;
- if (0 == strcmp(llgst_structure_get_name(structure),
+ if (0 == strcmp(gst_structure_get_name(structure),
"video/x-raw-rgb"))
{
int red_mask;
int green_mask;
int blue_mask;
- llgst_structure_get_int(structure, "red_mask", &red_mask);
- llgst_structure_get_int(structure, "green_mask", &green_mask);
- llgst_structure_get_int(structure, "blue_mask", &blue_mask);
+ gst_structure_get_int(structure, "red_mask", &red_mask);
+ gst_structure_get_int(structure, "green_mask", &green_mask);
+ gst_structure_get_int(structure, "blue_mask", &blue_mask);
if ((unsigned int)red_mask == 0xFF000000 &&
(unsigned int)green_mask == 0x00FF0000 &&
(unsigned int)blue_mask == 0x0000FF00)
@@ -265,12 +291,13 @@
filter->format = SLV_PF_BGRX;
//fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n");
}
- }*/
-
+
+ }*/
+
filter->format = SLV_PF_RGBX;
GST_OBJECT_UNLOCK(filter);
-
+
return TRUE;
}
@@ -317,15 +344,15 @@
// we can ignore these and reverse-negotiate our preferred dimensions with
// the peer if we like - we need to do this to obey dynamic resize requests
// flowing in from the app.
- structure = llgst_caps_get_structure (caps, 0);
- if (!llgst_structure_get_int(structure, "width", &width) ||
- !llgst_structure_get_int(structure, "height", &height))
+ structure = gst_caps_get_structure (caps, 0);
+ if (!gst_structure_get_int(structure, "width", &width) ||
+ !gst_structure_get_int(structure, "height", &height))
{
GST_WARNING_OBJECT (slvideo, "no width/height in caps %" GST_PTR_FORMAT, caps);
return GST_FLOW_NOT_NEGOTIATED;
}
- GstBuffer *newbuf = llgst_buffer_new();
+ GstBuffer *newbuf = gst_buffer_new();
bool made_bufferdata_ptr = false;
#define MAXDEPTHHACK 4
@@ -345,19 +372,19 @@
GstCaps *desired_caps;
GstStructure *desired_struct;
- desired_caps = llgst_caps_copy (caps);
- desired_struct = llgst_caps_get_structure (desired_caps, 0);
+ desired_caps = gst_caps_copy (caps);
+ desired_struct = gst_caps_get_structure (desired_caps, 0);
GValue value = {0};
g_value_init(&value, G_TYPE_INT);
g_value_set_int(&value, slwantwidth);
- llgst_structure_set_value (desired_struct, "width", &value);
+ gst_structure_set_value (desired_struct, "width", &value);
g_value_unset(&value);
g_value_init(&value, G_TYPE_INT);
g_value_set_int(&value, slwantheight);
- llgst_structure_set_value (desired_struct, "height", &value);
+ gst_structure_set_value (desired_struct, "height", &value);
- if (llgst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo),
+ if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo),
desired_caps))
{
// todo: re-use buffers from a pool?
@@ -368,13 +395,13 @@
GST_BUFFER_SIZE(newbuf) = slwantwidth * slwantheight * MAXDEPTHHACK;
GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf));
GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf);
- llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps);
+ gst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps);
made_bufferdata_ptr = true;
} else {
// peer hates our cap suggestion
INFOMSG("peer hates us :(");
- llgst_caps_unref(desired_caps);
+ gst_caps_unref(desired_caps);
}
}
}
@@ -386,7 +413,7 @@
GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK;
GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf));
GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf);
- llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps);
+ gst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps);
}
*buf = GST_BUFFER_CAST(newbuf);
@@ -428,6 +455,20 @@
#undef LLGST_DEBUG_FUNCPTR
}
+/*
+static void
+gst_slvideo_update_caps (GstSLVideo * slvideo)
+{
+ GstCaps *caps;
+
+ // GStreamer will automatically convert colourspace if necessary.
+ // GStreamer will automatically resize media to one of these enumerated
+ // powers-of-two that we ask for (yay GStreamer!)
+ caps = gst_caps_from_string (SLV_ALLCAPS);
+
+ gst_caps_replace (&slvideo->caps, caps);
+}
+*/
/* initialize the new element
* instantiate pads and add them to element
@@ -450,24 +491,24 @@
filter->retained_frame_width = filter->width;
filter->retained_frame_height = filter->height;
filter->retained_frame_format = SLV_PF_UNKNOWN;
- GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS);
- llgst_caps_replace (&filter->caps, caps);
+ GstCaps *caps = gst_caps_from_string (SLV_ALLCAPS);
+ gst_caps_replace (&filter->caps, caps);
filter->resize_forced_always = false;
filter->resize_try_width = -1;
filter->resize_try_height = -1;
GST_OBJECT_UNLOCK(filter);
+
+ //gst_slvideo_update_caps(filter);
}
static void
gst_slvideo_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
- llg_return_if_fail (GST_IS_SLVIDEO (object));
+ g_return_if_fail (GST_IS_SLVIDEO (object));
- switch (prop_id) {
- default:
+ if (prop_id) {
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
}
}
@@ -475,12 +516,10 @@
gst_slvideo_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
- llg_return_if_fail (GST_IS_SLVIDEO (object));
+ g_return_if_fail (GST_IS_SLVIDEO (object));
- switch (prop_id) {
- default:
+ if (prop_id) {
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
}
}
@@ -498,7 +537,7 @@
GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin",
0, (gchar*)"Second Life Video Sink");
- return llgst_element_register (plugin, "private-slvideo",
+ return gst_element_register (plugin, "private-slvideo",
GST_RANK_NONE, GST_TYPE_SLVIDEO);
}
@@ -508,20 +547,19 @@
some g++ versions buggily avoid __attribute__((constructor)) functions -
so we provide an explicit plugin init function.
*/
-#define PACKAGE (gchar*)"packagehack"
-// this macro quietly refers to PACKAGE internally
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- (gchar*)"private-slvideoplugin",
- (gchar*)"SL Video sink plugin",
- plugin_init, (gchar*)"1.0", (gchar*)"LGPL",
- (gchar*)"Second Life",
- (gchar*)"http://www.secondlife.com/");
-#undef PACKAGE
+
void gst_slvideo_init_class (void)
{
- ll_gst_plugin_register_static (&gst_plugin_desc);
- DEBUGMSG("CLASS INIT");
+ gst_plugin_register_static( GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ (const gchar *)"private-slvideoplugin",
+ (gchar *)"SL Video sink plugin",
+ plugin_init,
+ (const gchar *)"0.1",
+ GST_LICENSE_UNKNOWN,
+ (const gchar *)"Second Life",
+ (const gchar *)"Second Life",
+ (const gchar *)"http://www.secondlife.com/" );
}
#endif // LL_GSTREAMER010_ENABLED
diff -r 9539c10021ba -r 52b800cc01fc indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp
--- a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp Sun Nov 11 17:27:32 2012 -0600
@@ -28,6 +28,19 @@
#include "linden_common.h"
+
+
+// Needed for _getcwd() RC
+#ifdef LL_WINDOWS
+#include
+#include
+#include
+#endif
+
+#ifdef LL_DARWIN
+#include
+#endif
+
#include "llgl.h"
#include "llplugininstance.h"
@@ -35,36 +48,40 @@
#include "llpluginmessageclasses.h"
#include "media_plugin_base.h"
-#if LL_GSTREAMER010_ENABLED
+//#if LL_GSTREAMER010_ENABLED
extern "C" {
#include
+#include
}
#include "llmediaimplgstreamer.h"
#include "llmediaimplgstreamertriviallogging.h"
#include "llmediaimplgstreamervidplug.h"
-
-#include "llmediaimplgstreamer_syms.h"
-
//////////////////////////////////////////////////////////////////////////////
//
class MediaPluginGStreamer010 : public MediaPluginBase
{
public:
MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~MediaPluginGStreamer010();
/* virtual */ void receiveMessage(const char *message_string);
static bool startup();
static bool closedown();
+ static void set_gst_plugin_path();
+
gboolean processGSTEvents(GstBus *bus,
GstMessage *message);
+ // basic log file writing
+ static bool writeToLog(const char* str, ...);
+
private:
+ ~MediaPluginGStreamer010();
+
std::string getVersion();
bool navigateTo( const std::string urlIn );
bool seek( double time_sec );
@@ -76,7 +93,7 @@
bool play(double rate);
bool getTimePos(double &sec_out);
- static const double MIN_LOOP_SEC = 1.0F;
+ #define MIN_LOOP_SEC 1.0F
bool mIsLooping;
@@ -132,11 +149,12 @@
bool mSeekWanted;
double mSeekDestination;
+
+ std::string mLastTitle;
// Very GStreamer-specific
GMainLoop *mPump; // event pump for this media
GstElement *mPlaybin;
- GstElement *mVisualizer;
GstSLVideo *mVideoSink;
};
@@ -155,12 +173,11 @@
mSeekDestination(0.0),
mPump ( NULL ),
mPlaybin ( NULL ),
- mVisualizer ( NULL ),
+
mVideoSink ( NULL ),
mCommand ( COMMAND_NONE )
{
- std::ostringstream str;
- INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(getpid()));
+ writeToLog((char*)"MediaPluginGStreamer010 PID=%u", U32(LL_GETPID()));
}
///////////////////////////////////////////////////////////////////////////////
@@ -180,6 +197,38 @@
}
#endif // LL_GST_REPORT_STATE_CHANGES
+// static
+bool MediaPluginGStreamer010::writeToLog(const char* str, ...)
+{
+ LLFILE* fp = LLFile::fopen("media_plugin_gstreamer010.log", "a");
+
+ if (!fp)
+ {
+ return false;
+ }
+
+ time_t timeptr = time(NULL);
+ struct tm* ltime = localtime(&timeptr);
+ char strbuf[1024];
+ char strmsg[1024];
+ sprintf(strbuf, "[%d:%d:%d] ", ltime->tm_hour, ltime->tm_min, ltime->tm_sec);
+ va_list arglist;
+ va_start(arglist, str);
+ vsprintf(strmsg, str, arglist);
+ strcat(strbuf, strmsg);
+
+ // write to log file
+ fprintf(fp, strbuf);
+ fprintf(fp, "\n");
+ fclose(fp);
+
+ // mirror in console window if we have one
+ puts(strbuf);
+
+ return true;
+}
+
+// static
gboolean
MediaPluginGStreamer010::processGSTEvents(GstBus *bus,
GstMessage *message)
@@ -188,152 +237,176 @@
return TRUE; // shield against GStreamer bug
if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED &&
- GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
+ GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING &&
+ GST_MESSAGE_TYPE(message) != GST_MESSAGE_TAG)
{
- 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));
+ writeToLog((char*)"Got GST message type: %s", GST_MESSAGE_TYPE_NAME (message));
}
- switch (GST_MESSAGE_TYPE (message)) {
- case GST_MESSAGE_BUFFERING: {
- // NEEDS GST 0.10.11+
- if (llgst_message_parse_buffering)
+ switch (GST_MESSAGE_TYPE (message))
+ {
+ case GST_MESSAGE_BUFFERING:
{
+ // NEEDS GST 0.10.11+ and America discovered by C.Columbus
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,,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
+ gst_message_parse_buffering(message, &percent);
+ writeToLog((char*)"GST buffering: %d%%", percent);
- 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;
+ 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.
+ writeToLog((char*)"state change (old,,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
- 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)
+ 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);
+ writeToLog((char*)"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;
- llgst_message_parse_info (message, &err, &debug);
- INFOMSG("GST info: %s", err?err->message:"(unknown)");
+ gst_message_parse_info (message, &err, &debug);
+ writeToLog((char*)"GST info: %s", err?err->message:"(unknown)");
if (err)
g_error_free (err);
g_free (debug);
+
+ break;
}
- break;
- }
- case GST_MESSAGE_WARNING: {
- GError *err = NULL;
- gchar *debug = NULL;
+ case GST_MESSAGE_WARNING:
+ {
+ GError *err = NULL;
+ gchar *debug = NULL;
+
+ gst_message_parse_warning (message, &err, &debug);
+ writeToLog((char*)"GST warning: %s", err?err->message:"(unknown)");
+ if (err)
+ g_error_free (err);
+ g_free (debug);
+
+ break;
+ }
+ case GST_MESSAGE_TAG:
+ {
+ GstTagList *new_tags;
- llgst_message_parse_warning (message, &err, &debug);
- WARNMSG("GST warning: %s", err?err->message:"(unknown)");
- if (err)
- g_error_free (err);
- g_free (debug);
+ gst_message_parse_tag( message, &new_tags );
- break;
- }
- case GST_MESSAGE_EOS:
- /* end-of-stream */
- DEBUGMSG("GST end-of-stream.");
- if (mIsLooping)
+ gchar *title = NULL;
+
+ if ( gst_tag_list_get_string(new_tags, GST_TAG_TITLE, &title) )
+ {
+ //writeToLog((char*)"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:
{
- 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)
+ /* end-of-stream */
+ writeToLog((char*)"GST end-of-stream.");
+ if (mIsLooping)
{
- // 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)
+ //writeToLog((char*)"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)
{
- play(1.0);
+ // 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
+ writeToLog((char*)"really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec);
+ // inject a COMMAND_PAUSE
+ mCommand = COMMAND_PAUSE;
}
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);
+ {
+ #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
+ writeToLog((char*)"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;
+ 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
@@ -364,7 +437,7 @@
setStatus(STATUS_LOADING);
- DEBUGMSG("Setting media URI: %s", urlIn.c_str());
+ writeToLog((char*)"Setting media URI: %s", urlIn.c_str());
mSeekWanted = false;
@@ -392,13 +465,13 @@
if (!mDoneInit)
return false; // error
- DEBUGMSG("updating media...");
+ //writeToLog((char*)"updating media...");
// sanity check
if (NULL == mPump ||
NULL == mPlaybin)
{
- DEBUGMSG("dead media...");
+ writeToLog((char*)"dead media...");
return false;
}
@@ -428,7 +501,7 @@
GST_OBJECT_LOCK(mVideoSink);
if (mVideoSink->retained_frame_ready)
{
- DEBUGMSG("NEW FRAME READY");
+ writeToLog((char*)"NEW FRAME READY");
if (mVideoSink->retained_frame_width != mCurrentWidth ||
mVideoSink->retained_frame_height != mCurrentHeight)
@@ -459,7 +532,7 @@
GST_OBJECT_UNLOCK(mVideoSink);
mCurrentRowbytes = neww * newd;
- DEBUGMSG("video container resized to %dx%d",
+ writeToLog((char*)"video container resized to %dx%d",
neww, newh);
mDepth = newd;
@@ -487,7 +560,7 @@
}
GST_OBJECT_UNLOCK(mVideoSink);
- DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST");
+ writeToLog((char*)"NEW FRAME REALLY TRULY CONSUMED, TELLING HOST");
setDirty(0,0,mCurrentWidth,mCurrentHeight);
}
@@ -498,7 +571,7 @@
GST_OBJECT_UNLOCK(mVideoSink);
- DEBUGMSG("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize");
+ writeToLog((char*)"NEW FRAME not consumed, still waiting for a shm segment and/or shm resize");
}
return true;
@@ -537,11 +610,11 @@
bool
MediaPluginGStreamer010::pause()
{
- DEBUGMSG("pausing media...");
+ writeToLog((char*)"pausing media...");
// todo: error-check this?
if (mDoneInit && mPlaybin)
{
- llgst_element_set_state(mPlaybin, GST_STATE_PAUSED);
+ gst_element_set_state(mPlaybin, GST_STATE_PAUSED);
return true;
}
return false;
@@ -550,11 +623,11 @@
bool
MediaPluginGStreamer010::stop()
{
- DEBUGMSG("stopping media...");
+ writeToLog((char*)"stopping media...");
// todo: error-check this?
if (mDoneInit && mPlaybin)
{
- llgst_element_set_state(mPlaybin, GST_STATE_READY);
+ gst_element_set_state(mPlaybin, GST_STATE_READY);
return true;
}
return false;
@@ -564,12 +637,11 @@
MediaPluginGStreamer010::play(double rate)
{
// NOTE: we don't actually support non-natural rate.
-
- DEBUGMSG("playing media... rate=%f", rate);
+ writeToLog((char*)"playing media... rate=%f", rate);
// todo: error-check this?
if (mDoneInit && mPlaybin)
{
- llgst_element_set_state(mPlaybin, GST_STATE_PLAYING);
+ gst_element_set_state(mPlaybin, GST_STATE_PLAYING);
return true;
}
return false;
@@ -582,11 +654,14 @@
// possible, as many gst-plugins-base versions up to at least
// November 2008 have critical race-conditions in setting volume - sigh
if (mVolume == volume)
+ {
return true; // nothing to do, everything's fine
+ }
mVolume = volume;
if (mDoneInit && mPlaybin)
{
+ writeToLog("MediaPluginGStreamer010::receiveMessage: set_volume: %f", volume);
g_object_set(mPlaybin, "volume", mVolume, NULL);
return true;
}
@@ -600,13 +675,13 @@
bool success = false;
if (mDoneInit && mPlaybin)
{
- success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME,
+ success = gst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME,
GstSeekFlags(GST_SEEK_FLAG_FLUSH |
GST_SEEK_FLAG_KEY_UNIT),
GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND),
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
}
- DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d",
+ writeToLog((char*)"MEDIA SEEK REQUEST to %f sec result was %d",
float(time_sec), int(success));
return success;
}
@@ -619,11 +694,9 @@
{
gint64 pos;
GstFormat timefmt = GST_FORMAT_TIME;
- got_position =
- llgst_element_query_position &&
- llgst_element_query_position(mPlaybin,
- &timefmt,
- &pos);
+ got_position = gst_element_query_position(mPlaybin,
+ &timefmt,
+ &pos);
got_position = got_position
&& (timefmt == GST_FORMAT_TIME);
// GStreamer may have other ideas, but we consider the current position
@@ -662,10 +735,10 @@
setStatus(STATUS_LOADING);
- DEBUGMSG("setting up media...");
+ writeToLog((char*)"setting up media...");
mIsLooping = false;
- mVolume = 0.1234567; // minor hack to force an initial volume update
+ mVolume = (float) 0.1234567; // minor hack to force an initial volume update
// Create a pumpable main-loop for this media
mPump = g_main_loop_new (NULL, FALSE);
@@ -676,7 +749,7 @@
}
// instantiate a playbin element to do the hard work
- mPlaybin = llgst_element_factory_make ("playbin", "play");
+ mPlaybin = gst_element_factory_make ("playbin", "play");
if (!mPlaybin)
{
setStatus(STATUS_ERROR);
@@ -684,53 +757,25 @@
}
// get playbin's bus
- GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin));
+ GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (mPlaybin));
if (!bus)
{
setStatus(STATUS_ERROR);
return false; // error
}
- mBusWatchID = llgst_bus_add_watch (bus,
+ mBusWatchID = gst_bus_add_watch (bus,
llmediaimplgstreamer_bus_callback,
this);
- llgst_object_unref (bus);
+ gst_object_unref (bus);
-#if 0 // not quite stable/correct yet
- // get a visualizer element (bonus feature!)
- char* vis_name = getenv("LL_GST_VIS_NAME");
- if (!vis_name ||
- (vis_name && std::string(vis_name)!="none"))
- {
- if (vis_name)
- {
- mVisualizer = llgst_element_factory_make (vis_name, "vis");
- }
- if (!mVisualizer)
- {
- mVisualizer = llgst_element_factory_make ("libvisual_jess", "vis");
- if (!mVisualizer)
- {
- mVisualizer = llgst_element_factory_make ("goom", "vis");
- if (!mVisualizer)
- {
- mVisualizer = llgst_element_factory_make ("libvisual_lv_scope", "vis");
- if (!mVisualizer)
- {
- // That's okay, we don't NEED this.
- }
- }
- }
- }
- }
-#endif
if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) {
// instantiate a custom video sink
mVideoSink =
- GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo"));
+ GST_SLVIDEO(gst_element_factory_make ("private-slvideo", "slvideo"));
if (!mVideoSink)
{
- WARNMSG("Could not instantiate private-slvideo element.");
+ writeToLog((char*)"Could not instantiate private-slvideo element.");
// todo: cleanup.
setStatus(STATUS_ERROR);
return false; // error
@@ -740,11 +785,6 @@
g_object_set(mPlaybin, "video-sink", mVideoSink, NULL);
}
- if (mVisualizer)
- {
- g_object_set(mPlaybin, "vis-plugin", mVisualizer, NULL);
- }
-
return true;
}
@@ -754,7 +794,7 @@
if (!mDoneInit)
return false; // error
- DEBUGMSG("unloading media...");
+ writeToLog((char*)"unloading media...");
// stop getting callbacks for this bus
g_source_remove(mBusWatchID);
@@ -762,17 +802,11 @@
if (mPlaybin)
{
- llgst_element_set_state (mPlaybin, GST_STATE_NULL);
- llgst_object_unref (GST_OBJECT (mPlaybin));
+ gst_element_set_state (mPlaybin, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (mPlaybin));
mPlaybin = NULL;
}
-
- if (mVisualizer)
- {
- llgst_object_unref (GST_OBJECT (mVisualizer));
- mVisualizer = NULL;
- }
-
+
if (mPump)
{
g_main_loop_quit(mPump);
@@ -802,7 +836,13 @@
// Init the glib type system - we need it.
g_type_init();
+ set_gst_plugin_path();
+ // removed case gst_segtrap_set_enabled doesn't exist
+ // Because: Latest stable gstreamer at the time writing this: 0.10.31
+// gst_segtrap_set_enabled(FALSE);// Since 0.10.10 , was released Sep 2006
+
+/*
// Get symbols!
#if LL_DARWIN
if (! grab_gst_syms("libgstreamer-0.10.dylib",
@@ -815,27 +855,27 @@
"libgstvideo-0.10.so.0") )
#endif
{
- WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled.");
+ writeToLog((char*)"Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled.");
return false;
}
-
- if (llgst_segtrap_set_enabled)
- {
- llgst_segtrap_set_enabled(FALSE);
- }
- else
- {
- WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught.");
- }
-
+*/
+// if (gst_segtrap_set_enabled)
+// {
+ gst_segtrap_set_enabled(FALSE);
+// }
+// else
+// {
+// writeToLog((char*)"gst_segtrap_set_enabled() is not available; plugin crashes won't be caught.");
+// }
+/*
#if LL_LINUX
// Gstreamer tries a fork during init, waitpid-ing on it,
// which conflicts with any installed SIGCHLD handler...
struct sigaction tmpact, oldact;
- if (llgst_registry_fork_set_enabled) {
- // if we can disable SIGCHLD-using forking behaviour,
- // do it.
- llgst_registry_fork_set_enabled(false);
+ if (gst_registry_fork_set_enabled) {
+ // if we can disable SIGCHLD-using forking behaviour,
+ // do it.
+ gst_registry_fork_set_enabled(false);
}
else {
// else temporarily install default SIGCHLD handler
@@ -846,47 +886,164 @@
sigaction(SIGCHLD, &tmpact, &oldact);
}
#endif // LL_LINUX
-
+*/
// Protect against GStreamer resetting the locale, yuck.
static std::string saved_locale;
saved_locale = setlocale(LC_ALL, NULL);
// finally, try to initialize GStreamer!
GError *err = NULL;
- gboolean init_gst_success = llgst_init_check(NULL, NULL, &err);
+ gboolean init_gst_success = gst_init_check(NULL, NULL, &err);
// restore old locale
setlocale(LC_ALL, saved_locale.c_str() );
-#if LL_LINUX
- // restore old SIGCHLD handler
- if (!llgst_registry_fork_set_enabled)
- sigaction(SIGCHLD, &oldact, NULL);
-#endif // LL_LINUX
+
if (!init_gst_success) // fail
{
if (err)
{
- WARNMSG("GST init failed: %s", err->message);
+ writeToLog((char*)"GST init failed: %s", err->message);
g_error_free(err);
}
else
{
- WARNMSG("GST init failed for unspecified reason.");
+ writeToLog((char*)"GST init failed for unspecified reason.");
}
return false;
}
-
+
+ // Set up logging facilities
+ gst_debug_remove_log_function( gst_debug_log_default );
+// gst_debug_add_log_function( gstreamer_log, NULL );
+
// Init our custom plugins - only really need do this once.
gst_slvideo_init_class();
+ // List the plugins GStreamer can find
+ writeToLog((char*)"Found GStreamer plugins:");
+ GList *list;
+ GstRegistry *registry = gst_registry_get_default();
+ std::string loaded = "No";
+ for (list = gst_registry_get_plugin_list(registry);
+ list != NULL;
+ list = g_list_next(list))
+ {
+ GstPlugin *list_plugin = (GstPlugin *)list->data;
+ if (gst_plugin_is_loaded(list_plugin)) loaded = "Yes";
+ writeToLog((char*)"%s, loaded? %s", gst_plugin_get_name(list_plugin), loaded.c_str());
+ }
+ gst_plugin_list_free(list);
+
mDoneInit = true;
}
return true;
}
+void MediaPluginGStreamer010::set_gst_plugin_path()
+{
+ // Linux sets GST_PLUGIN_PATH in wrapper.sh, not here.
+#if LL_WINDOWS || LL_DARWIN
+
+ std::string imp_dir = "";
+
+ // Get the current working directory:
+#if LL_WINDOWS
+ char* raw_dir;
+ raw_dir = _getcwd(NULL,0);
+ if( raw_dir != NULL )
+ {
+ imp_dir = std::string( raw_dir );
+ }
+
+
+#elif LL_DARWIN
+ CFBundleRef main_bundle = CFBundleGetMainBundle();
+ if( main_bundle != NULL )
+ {
+ CFURLRef bundle_url = CFBundleCopyBundleURL( main_bundle );
+ if( bundle_url != NULL )
+ {
+ #ifndef MAXPATHLEN
+ #define MAXPATHLEN 1024
+ #endif
+ char raw_dir[MAXPATHLEN];
+ if( CFURLGetFileSystemRepresentation( bundle_url, true, (UInt8 *)raw_dir, MAXPATHLEN) )
+ {
+ imp_dir = std::string( raw_dir ) + "/Contents/MacOS/";
+ }
+ CFRelease(bundle_url);
+ }
+ }
+#endif
+
+ if( imp_dir == "" )
+ {
+ writeToLog((char*)"Could not get application directory, not setting GST_PLUGIN_PATH.");
+ return;
+ }
+
+ writeToLog((char*)"Install directory is at %s", imp_dir.c_str());
+
+ // ":" on Mac and 'Nix, ";" on Windows
+ std::string separator = G_SEARCHPATH_SEPARATOR_S;
+
+ // Grab the current path, if it's set.
+ std::string old_plugin_path = "";
+ char *old_path = getenv("GST_PLUGIN_PATH");
+ if(old_path == NULL)
+ {
+ writeToLog((char*)"Did not find user-set GST_PLUGIN_PATH.");
+ }
+ else
+ {
+ old_plugin_path = separator + std::string( old_path );
+ }
+ std::string plugin_path =
+ "GST_PLUGIN_PATH=" +
+#if LL_WINDOWS
+ imp_dir + "\\gstreamer-plugins" +
+#elif LL_DARWIN
+ imp_dir + separator +
+ imp_dir + "/../Resources/lib/gstreamer-plugins" +
+#endif
+ old_plugin_path;
+
+ int put_result;
+
+ // Place GST_PLUGIN_PATH in the environment settings
+#if LL_WINDOWS
+ put_result = _putenv( (char*)plugin_path.c_str() );
+#elif LL_DARWIN
+ put_result = putenv( (char*)plugin_path.c_str() );
+#endif
+
+ if( put_result == -1 )
+ {
+ writeToLog((char*)"Setting GST_PLUGIN_PATH failed!");
+ }
+ else
+ {
+ writeToLog((char*)"GST_PLUGIN_PATH set to %s", getenv("GST_PLUGIN_PATH"));
+ }
+
+ // Don't load system plugins. We only want to use ours, to avoid conflicts.
+#if LL_WINDOWS
+ put_result = _putenv( "GST_PLUGIN_SYSTEM_PATH=\"\"" );
+#elif LL_DARWIN
+ put_result = putenv( "GST_PLUGIN_SYSTEM_PATH=\"\"" );
+#endif
+
+ if( put_result == -1 )
+ {
+ writeToLog((char*)"Setting GST_PLUGIN_SYSTEM_PATH=\"\" failed!");
+ }
+
+#endif // LL_WINDOWS || LL_DARWIN
+}
+
void
MediaPluginGStreamer010::sizeChanged()
@@ -899,7 +1056,7 @@
{
mNaturalWidth = mCurrentWidth;
mNaturalHeight = mCurrentHeight;
- DEBUGMSG("Media NATURAL size better detected as %dx%d",
+ writeToLog((char*)"Media NATURAL size better detected as %dx%d",
mNaturalWidth, mNaturalHeight);
}
@@ -914,7 +1071,7 @@
message.setValue("name", mTextureSegmentName);
message.setValueS32("width", mNaturalWidth);
message.setValueS32("height", mNaturalHeight);
- DEBUGMSG("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight);
+ writeToLog((char*)"<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight);
sendMessage(message);
}
}
@@ -925,23 +1082,25 @@
bool
MediaPluginGStreamer010::closedown()
{
+
if (!mDoneInit)
return false; // error
- ungrab_gst_syms();
mDoneInit = false;
+ writeToLog("GStreamer010 closed down");
+
return true;
}
MediaPluginGStreamer010::~MediaPluginGStreamer010()
{
- DEBUGMSG("MediaPluginGStreamer010 destructor");
+ //writeToLog((char*)"MediaPluginGStreamer010 destructor");
closedown();
- DEBUGMSG("GStreamer010 closing down");
+ writeToLog("GStreamer010 destructor");
}
@@ -949,11 +1108,10 @@
MediaPluginGStreamer010::getVersion()
{
std::string plugin_version = "GStreamer010 media plugin, GStreamer version ";
- if (mDoneInit &&
- llgst_version)
+ if (mDoneInit) // && gst_version)
{
guint major, minor, micro, nano;
- llgst_version(&major, &minor, µ, &nano);
+ gst_version(&major, &minor, µ, &nano);
plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO);
}
else
@@ -965,7 +1123,7 @@
void MediaPluginGStreamer010::receiveMessage(const char *message_string)
{
- //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+ //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"";
LLPluginMessage message_in;
@@ -986,11 +1144,11 @@
if ( load() )
{
- DEBUGMSG("GStreamer010 media instance set up");
+ writeToLog((char*)"GStreamer010 media instance set up");
}
else
{
- WARNMSG("GStreamer010 media instance failed to set up");
+ writeToLog((char*)"GStreamer010 media instance failed to set up");
}
message.setValue("plugin_version", getVersion());
@@ -1006,8 +1164,19 @@
}
else if(message_name == "cleanup")
{
+ writeToLog("MediaPluginGStreamer010::receiveMessage: cleanup");
unload();
closedown();
+
+ // Reply once we're done
+ LLPluginMessage message("base", "cleanup_reply");
+ sendMessage(message);
+
+ // Now suicide. Because It is the only honorable thing to do.
+ // JUST BE CAREFUL!
+ // http://www.parashift.com/c++-faq-lite/delete-this.html
+ delete this;
+ return;
}
else if(message_name == "shm_added")
{
@@ -1017,7 +1186,7 @@
std::string name = message_in.getValue("name");
std::ostringstream str;
- INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress);
+ writeToLog((char*)"MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress);
mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
}
@@ -1025,7 +1194,7 @@
{
std::string name = message_in.getValue("name");
- DEBUGMSG("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str());
+ writeToLog((char*)"MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str());
SharedSegmentMap::iterator iter = mSharedSegments.find(name);
if(iter != mSharedSegments.end())
@@ -1043,7 +1212,7 @@
}
else
{
- WARNMSG("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!");
+ writeToLog((char*)"MediaPluginGStreamer010::receiveMessage: unknown shared memory region!");
}
// Send the response so it can be cleaned up.
@@ -1054,7 +1223,7 @@
else
{
std::ostringstream str;
- INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str());
+ writeToLog((char*)"MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str());
}
}
else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
@@ -1097,7 +1266,7 @@
S32 texture_height = message_in.getValueS32("texture_height");
std::ostringstream str;
- INFOMSG("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height);
+ writeToLog((char*)"---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height);
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
message.setValue("name", name);
@@ -1113,8 +1282,8 @@
SharedSegmentMap::iterator iter = mSharedSegments.find(name);
if(iter != mSharedSegments.end())
{
- INFOMSG("*** Got size change with matching shm, new size is %d x %d", width, height);
- INFOMSG("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height);
+ writeToLog((char*)"*** Got size change with matching shm, new size is %d x %d", width, height);
+ writeToLog((char*)"*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height);
mPixels = (unsigned char*)iter->second.mAddress;
mTextureSegmentName = name;
@@ -1124,7 +1293,7 @@
if (texture_width > 1 ||
texture_height > 1) // not a dummy size from the app, a real explicit forced size
{
- INFOMSG("**** = REAL RESIZE REQUEST FROM APP");
+ writeToLog((char*)"**** = REAL RESIZE REQUEST FROM APP");
GST_OBJECT_LOCK(mVideoSink);
mVideoSink->resize_forced_always = true;
@@ -1206,13 +1375,23 @@
}
else
{
- INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str());
+ writeToLog((char*)"MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str());
}
}
}
int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
{
+ // init log file
+ LLFILE* fp = LLFile::fopen("media_plugin_gstreamer010.log", "w");
+ if (fp)
+ {
+ time_t timeptr = time(NULL);
+ fprintf(fp, "%s", asctime(localtime(&timeptr)));
+ fprintf(fp, "<--- Begin media_plugin_gstreamer010 initialization --->\n");
+ fclose(fp);
+ }
+
if (MediaPluginGStreamer010::startup())
{
MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data);
@@ -1227,40 +1406,40 @@
}
}
-#else // LL_GSTREAMER010_ENABLED
+//#else // LL_GSTREAMER010_ENABLED
+//
+//// Stubbed-out class with constructor/destructor (necessary or windows linker
+//// will just think its dead code and optimize it all out)
+//class MediaPluginGStreamer010 : public MediaPluginBase
+//{
+//public:
+// MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+// ~MediaPluginGStreamer010();
+// /* virtual */ void receiveMessage(const char *message_string);
+//};
+//
+//MediaPluginGStreamer010::MediaPluginGStreamer010(
+// LLPluginInstance::sendMessageFunction host_send_func,
+// void *host_user_data ) :
+// MediaPluginBase(host_send_func, host_user_data)
+//{
+// // no-op
+//}
+//
+//MediaPluginGStreamer010::~MediaPluginGStreamer010()
+//{
+// // no-op
+//}
+//
+//void MediaPluginGStreamer010::receiveMessage(const char *message_string)
+//{
+// // no-op
+//}
+//
+//// We're building without GStreamer enabled. Just refuse to initialize.
+//int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
+//{
+// return -1;
+//}
-// Stubbed-out class with constructor/destructor (necessary or windows linker
-// will just think its dead code and optimize it all out)
-class MediaPluginGStreamer010 : public MediaPluginBase
-{
-public:
- MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~MediaPluginGStreamer010();
- /* virtual */ void receiveMessage(const char *message_string);
-};
-
-MediaPluginGStreamer010::MediaPluginGStreamer010(
- LLPluginInstance::sendMessageFunction host_send_func,
- void *host_user_data ) :
- MediaPluginBase(host_send_func, host_user_data)
-{
- // no-op
-}
-
-MediaPluginGStreamer010::~MediaPluginGStreamer010()
-{
- // no-op
-}
-
-void MediaPluginGStreamer010::receiveMessage(const char *message_string)
-{
- // no-op
-}
-
-// We're building without GStreamer enabled. Just refuse to initialize.
-int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
-{
- return -1;
-}
-
-#endif // LL_GSTREAMER010_ENABLED
+//#endif // LL_GSTREAMER010_ENABLED
diff -r 9539c10021ba -r 52b800cc01fc indra/media_plugins/webkit/media_plugin_webkit.cpp
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp Sun Nov 11 17:27:32 2012 -0600
@@ -52,6 +52,8 @@
#if LL_WINDOWS
# include
+# include
+# include
#else
# include
# include
@@ -136,7 +138,7 @@
void setInitState(int state)
{
-// std::cerr << "changing init state to " << state << std::endl;
+ std::cout << "changing init state to " << state << std::endl;
mInitState = state;
}
@@ -180,12 +182,12 @@
unsigned int buffer_size = rowspan * height;
#endif // !LL_QTWEBKIT_USES_PIXMAPS
-// std::cerr << "webkit plugin: updating" << std::endl;
+ //std::cout << "webkit plugin: updating" << std::endl;
// TODO: should get rid of this memcpy if possible
if ( mPixels && browser_pixels )
{
-// std::cerr << " memcopy of " << buffer_size << " bytes" << std::endl;
+ //std::cout << " memcopy of " << buffer_size << " bytes" << std::endl;
#if LL_QTWEBKIT_USES_PIXMAPS
// copy the pixel data upside-down because of the co-ord system
@@ -200,7 +202,7 @@
if ( mWidth > 0 && mHeight > 0 )
{
-// std::cerr << "Setting dirty, " << mWidth << " x " << mHeight << std::endl;
+ //std::cout << "Setting dirty, " << mWidth << " x " << mHeight << std::endl;
setDirty( 0, 0, mWidth, mHeight );
}
@@ -220,7 +222,7 @@
char cwd[ FILENAME_MAX ]; // I *think* this is defined on all platforms we use
if (NULL == getcwd( cwd, FILENAME_MAX - 1 ))
{
- llwarns << "Couldn't get cwd - probably too long - failing to init." << llendl;
+ std::cout << "Couldn't get cwd - probably too long - failing to init." << std::endl;
return false;
}
std::string application_dir = std::string( cwd );
@@ -274,7 +276,7 @@
#if LL_WINDOWS
char window_title[ MAX_PATH ];
GetConsoleTitleA( window_title, MAX_PATH );
- void* native_window_handle = (void*)FindWindowA( NULL, window_title );
+ void* native_window_handle = (void*)FindWindowA( NULL, window_title );
#else
void* native_window_handle = 0;
#endif
@@ -768,7 +770,7 @@
break;
}
-// std::cerr << "key event " << (int)key_event << ", native_key_data = " << native_key_data << std::endl;
+ std::cout << "key event " << (int)key_event << ", native_key_data = " << native_key_data << std::endl;
uint32_t native_scan_code = 0;
uint32_t native_virtual_key = 0;
@@ -786,7 +788,7 @@
{
uint32_t key = LLQtWebKit::KEY_NONE;
-// std::cerr << "unicode input, native_key_data = " << native_key_data << std::endl;
+ std::cout << "unicode input, native_key_data = " << native_key_data << std::endl;
if(utf8str.size() == 1)
{
@@ -864,7 +866,7 @@
MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
MediaPluginBase(host_send_func, host_user_data)
{
-// std::cerr << "MediaPluginWebKit constructor" << std::endl;
+ std::cout << "MediaPluginWebKit constructor" << std::endl;
mBrowserWindowId = 0;
mInitState = INIT_STATE_UNINITIALIZED;
@@ -896,12 +898,12 @@
// clean up
LLQtWebKit::getInstance()->reset();
-// std::cerr << "MediaPluginWebKit destructor" << std::endl;
+ std::cout << "MediaPluginWebKit destructor" << std::endl;
}
void MediaPluginWebKit::receiveMessage(const char *message_string)
{
-// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+ //std::cout << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
LLPluginMessage message_in;
if(message_in.parse(message_string) >= 0)
@@ -947,10 +949,10 @@
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");
-// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory added, name: " << name
-// << ", size: " << info.mSize
-// << ", address: " << info.mAddress
-// << std::endl;
+ std::cout << "MediaPluginWebKit::receiveMessage: shared memory added, name: " << name
+ << ", size: " << info.mSize
+ << ", address: " << info.mAddress
+ << std::endl;
mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
@@ -959,7 +961,7 @@
{
std::string name = message_in.getValue("name");
-// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory remove, name = " << name << std::endl;
+ std::cout << "MediaPluginWebKit::receiveMessage: shared memory remove, name = " << name << std::endl;
SharedSegmentMap::iterator iter = mSharedSegments.find(name);
if(iter != mSharedSegments.end())
@@ -974,7 +976,7 @@
}
else
{
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
+ std::cout << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
}
// Send the response so it can be cleaned up.
@@ -984,7 +986,7 @@
}
else
{
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
+ std::cout << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
}
}
else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
@@ -997,6 +999,12 @@
}
else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
{
+ // These are spammy, comment out the line below if you need 'em -- MC
+ if (message_name != "mouse_event")
+ {
+ std::cout << "MediaPluginWebKit::receiveMessage: LLPLUGIN_MESSAGE_CLASS_MEDIA (non mouse_event) message: " << message_string << std::endl;
+ }
+
if(message_name == "init")
{
mTarget = message_in.getValue("target");
@@ -1025,6 +1033,7 @@
else
{
// if initialization failed, we're done.
+ std::cerr << "Fatal error: initialization failed" << std::endl;
mDeleteMe = true;
}
@@ -1078,8 +1087,8 @@
// size changed so tell the browser
LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );
- // std::cerr << "webkit plugin: set size to " << mWidth << " x " << mHeight
- // << ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl;
+ std::cout << "webkit plugin: set size to " << mWidth << " x " << mHeight
+ << ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl;
S32 real_width = LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) / LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId);
@@ -1091,7 +1100,7 @@
else
{
// This won't work -- it'll be bigger than the allocated memory. This is a fatal error.
- // std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl;
+ std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl;
mDeleteMe = true;
return;
}
@@ -1099,6 +1108,7 @@
else
{
// Setting up the browser window failed. This is a fatal error.
+ std::cerr << "Fatal error: setting up the browser window failed" << std::endl;
mDeleteMe = true;
}
@@ -1122,7 +1132,7 @@
{
std::string uri = message_in.getValue("uri");
-// std::cout << "loading URI: " << uri << std::endl;
+ std::cout << "loading URI: " << uri << std::endl;
if(!uri.empty())
{
@@ -1205,22 +1215,22 @@
unicodeInput(text, decodeModifiers(modifiers), native_key_data);
}
- if(message_name == "edit_cut")
+ else if(message_name == "edit_cut")
{
LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT );
checkEditState();
}
- if(message_name == "edit_copy")
+ else if(message_name == "edit_copy")
{
LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY );
checkEditState();
}
- if(message_name == "edit_paste")
+ else if(message_name == "edit_paste")
{
LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE );
checkEditState();
}
- if(message_name == "pick_file_response")
+ else if(message_name == "pick_file_response")
{
onPickFileResponse(message_in.getValue("file"));
}
@@ -1301,7 +1311,7 @@
}
else
{
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
+ std::cout << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
}
}
else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
@@ -1454,12 +1464,12 @@
}
else
{
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl;
+ std::cout << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl;
};
}
else
{
-// std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
+ std::cout << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
};
}
}
@@ -1471,6 +1481,36 @@
int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
{
+#ifdef LL_WINDOWS
+ // Make sure no files in a user's PATH interfere with the plugin. Even if
+ // their PATH is empty, set it anyway before anything is initialized
+ // getcwd can put us in llplugin or the .exe directory, depending-- MC
+ char* raw_dir = _getcwd(NULL, 0);
+ if (raw_dir != NULL)
+ {
+ std::string cur_dir(raw_dir);
+ std::string new_path = "PATH=";
+ char* old_path = getenv("PATH");
+ if (old_path != NULL)
+ {
+ new_path += cur_dir + ";" + cur_dir + "\\llplugin" + ";" + std::string(old_path);
+ }
+ else
+ {
+ new_path += cur_dir + ";" + cur_dir + "\\llplugin";
+ }
+
+ if (_putenv(new_path.c_str()) == -1)
+ {
+ std::cout << "Setting PATH environment variable to " << new_path << " failed!" << std::endl;
+ }
+ else
+ {
+ std::cout << "Setting PATH environment variable to " << new_path << std::endl;
+ }
+ }
+#endif // LL_WINDOWS
+
MediaPluginWebKit *self = new MediaPluginWebKit(host_send_func, host_user_data);
*plugin_send_func = MediaPluginWebKit::staticReceiveMessage;
*plugin_user_data = (void*)self;
diff -r 9539c10021ba -r 52b800cc01fc indra/newview/CMakeLists.txt
--- a/indra/newview/CMakeLists.txt Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/newview/CMakeLists.txt Sun Nov 11 17:27:32 2012 -0600
@@ -1675,6 +1675,7 @@
SLPlugin
media_plugin_quicktime
media_plugin_webkit
+ media_plugin_gstreamer010
winmm_shim
windows-crash-logger
windows-updater
diff -r 9539c10021ba -r 52b800cc01fc indra/newview/llviewermedia.cpp
--- a/indra/newview/llviewermedia.cpp Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/newview/llviewermedia.cpp Sun Nov 11 17:27:32 2012 -0600
@@ -27,7 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llviewermedia.h"
-
+#include "llpluginclassmedia.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llappviewer.h"
@@ -76,6 +76,7 @@
#include // for SkinFolder listener
#include
+
/*static*/ const char* LLViewerMedia::AUTO_PLAY_MEDIA_SETTING = "ParcelMediaAutoPlayEnable";
/*static*/ const char* LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING = "MediaShowOnOthers";
/*static*/ const char* LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING = "MediaShowWithinParcel";
@@ -1875,7 +1876,13 @@
const std::string plugin_dir = gDirUtilp->getLLPluginDir();
if (media_source->init(launcher_name, plugin_dir, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins")))
{
- return media_source;
+ #if LL_WINDOWS
+ if (gSavedSettings.getBOOL("ShowConsoleWindow"))
+ {
+ media_source->showConsole();
+ }
+ #endif
+ return media_source;
}
else
{
@@ -3169,9 +3176,27 @@
resetPreviousMediaState();
LLSD args;
- args["PLUGIN"] = LLMIMETypes::implType(mCurrentMimeType);
- // SJB: This is getting called every frame if the plugin fails to load, continuously respawining the alert!
- //LLNotificationsUtil::add("MediaPluginFailed", args);
+ std::string plugin_name = LLMIMETypes::implType(mMimeType);
+ args["PLUGIN"] = plugin_name;
+
+ // These should really be hardcoded in LLMimeTypes, if anywhere -- MC
+ std::string notification_name;
+ LLStringUtil::toLower(plugin_name);
+ if (plugin_name.find("quicktime") != std::string::npos)
+ {
+ notification_name = "MediaPluginFailedQuickTime";
+ }
+ else if (plugin_name.find("webkit") != std::string::npos)
+ {
+ notification_name = "MediaPluginFailedWebkit";
+ }
+ else
+ {
+ notification_name = "MediaPluginFailed";
+ }
+
+ LLNotificationsUtil::add(notification_name, args);
+
}
break;
diff -r 9539c10021ba -r 52b800cc01fc indra/newview/llviewermedia_streamingaudio.cpp
--- a/indra/newview/llviewermedia_streamingaudio.cpp Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/newview/llviewermedia_streamingaudio.cpp Sun Nov 11 17:27:32 2012 -0600
@@ -53,34 +53,100 @@
void LLStreamingAudio_MediaPlugins::start(const std::string& url)
{
+ if (url.empty())
+ {
+ return;
+ }
+
+ std::string test_url(url);
+ //llinfos << "Starting internet stream: " << test_url << llendl;
+ // note: it's okay if mURL is empty here
+ if (mURL != test_url)
+ {
+ // stop any previous stream that was playing
+ // this happens on parcel crossings, usually
+ stop();
+
+ if (mMediaPlugin)
+ {
+ mMediaPlugin->reset();
+ mMediaPlugin = initializeMedia("audio/mpeg");
+ }
+ }
+ mURL = test_url;
+
+#ifdef LL_DARWIN
+ // We need to change http:// streams to icy:// in order to use them with quicktime.
+ // This isn't a good place to put this, but none of this is good, so... -- MC
+ LLURI uri(test_url);
+ std::string scheme = uri.scheme();
+ if ((scheme.empty() || "http" == scheme || "https" == scheme) &&
+ ((test_url.length() > 4) &&
+ (test_url.substr(test_url.length()-4, 4) != ".pls") && // Shoutcast listen.pls playlists
+ (test_url.substr(test_url.length()-4, 4) != ".m3u")) // Icecast liten.m3u playlists
+ )
+ {
+ std::string temp_url = "icy:" + uri.opaque();
+ test_url = temp_url;
+ }
+#endif //LL_DARWIN
+
if (!mMediaPlugin) // lazy-init the underlying media plugin
{
mMediaPlugin = initializeMedia("audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis.
llinfos << "streaming audio mMediaPlugin is now " << mMediaPlugin << llendl;
}
+ else if (mMediaPlugin->isPluginExited()) // If our reset didn't work right, try again
+ {
+ mMediaPlugin->reset();
+ mMediaPlugin = initializeMedia("audio/mpeg");
+ }
if(!mMediaPlugin)
return;
- if (!url.empty()) {
- llinfos << "Starting internet stream: " << url << llendl;
- mURL = url;
- mMediaPlugin->loadURI ( url );
+ if (!url.empty())
+ {
+ std::string test_url(url);
+ // We need to change http:// streams to icy:// in order to use them with quicktime.
+ // This isn't a good place to put this, but none of this is good, so... -- MC
+#ifdef LL_DARWIN
+ LLURI uri(test_url);
+ std::string scheme = uri.scheme();
+ if ((scheme.empty() || "http" == scheme || "https" == scheme) &&
+ ((test_url.length() > 4) &&
+ (test_url.substr(test_url.length()-4, 4) != ".pls") && // Shoutcast listen.pls playlists
+ (test_url.substr(test_url.length()-4, 4) != ".m3u")) // Icecast liten.m3u playlists
+ )
+ {
+ std::string temp_url = "icy:" + uri.opaque();
+ test_url = temp_url;
+ }
+#endif //LL_DARWIN
+ //llinfos << "Starting internet stream: " << test_url << llendl;
+ mURL = test_url;
+ mMediaPlugin->loadURI ( test_url );
mMediaPlugin->start();
- llinfos << "Playing stream..." << llendl;
- } else {
- llinfos << "setting stream to NULL"<< llendl;
- mURL.clear();
- mMediaPlugin->stop();
+ llinfos << "Playing internet stream: " << mURL << llendl;
+ mMediaPlugin->start();
+ llinfos << "Attempting to play internet stream: " << mURL << llendl;
+ }
+ else
+ {
+ //llinfos << "setting stream to NULL"<< llendl;
+ stop();
}
}
void LLStreamingAudio_MediaPlugins::stop()
{
+
llinfos << "Stopping internet stream." << llendl;
if(mMediaPlugin)
{
mMediaPlugin->stop();
+ // MURDER DEATH KILL -- MC
+ //mMediaPlugin->forceCleanUpPlugin();
}
mURL.clear();
diff -r 9539c10021ba -r 52b800cc01fc indra/newview/skins/default/xui/en/mime_types.xml
--- a/indra/newview/skins/default/xui/en/mime_types.xml Tue Sep 25 13:04:14 2012 -0400
+++ b/indra/newview/skins/default/xui/en/mime_types.xml Sun Nov 11 17:27:32 2012 -0600
@@ -142,7 +142,7 @@
audio
- media_plugin_quicktime
+ media_plugin_gstreamer010
@@ -197,7 +197,7 @@
audio
- media_plugin_quicktime
+ media_plugin_gstreamer010
@@ -274,7 +274,7 @@
audio
- media_plugin_quicktime
+ media_plugin_gstreamer010
@@ -285,7 +285,7 @@
audio
- media_plugin_quicktime
+ media_plugin_gstreamer010
@@ -296,7 +296,7 @@
audio
- media_plugin_quicktime
+ media_plugin_gstreamer010
@@ -307,7 +307,7 @@
audio
- media_plugin_quicktime
+ media_plugin_gstreamer010
@@ -431,6 +431,17 @@
media_plugin_quicktime
+
+
+
+ movie
+
+
+ media_plugin_quicktime
+
+
+
+
+
+ audio
+
+
+ media_plugin_quicktime
+
+
+
+
+
+ audio
+
+
+ media_plugin_quicktime
+
+
+
+
+
+ audio
+
+
+ media_plugin_quicktime
+
+
+
+
+
+ audio
+
+
+ media_plugin_quicktime
+
+