diff options
Diffstat (limited to 'indra/media_plugins')
-rw-r--r-- | indra/media_plugins/CMakeLists.txt | 7 | ||||
-rw-r--r-- | indra/media_plugins/cef/media_plugin_cef.cpp | 60 | ||||
-rw-r--r-- | indra/media_plugins/libvlc/CMakeLists.txt | 86 | ||||
-rw-r--r-- | indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 618 | ||||
-rwxr-xr-x[-rw-r--r--] | indra/media_plugins/quicktime/CMakeLists.txt | 10 | ||||
-rwxr-xr-x[-rw-r--r--] | indra/media_plugins/quicktime/media_plugin_quicktime.cpp | 7 |
6 files changed, 770 insertions, 18 deletions
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt index 24eb3947b4..9055e0111a 100644 --- a/indra/media_plugins/CMakeLists.txt +++ b/indra/media_plugins/CMakeLists.txt @@ -4,15 +4,18 @@ add_subdirectory(base) if (LINUX) add_subdirectory(gstreamer010) + add_subdirectory(libvlc) endif (LINUX) -if (WINDOWS OR DARWIN) +if (DARWIN) add_subdirectory(quicktime) add_subdirectory(cef) -endif (WINDOWS OR DARWIN) +endif (DARWIN) if (WINDOWS) + add_subdirectory(cef) add_subdirectory(winmmshim) + add_subdirectory(libvlc) endif (WINDOWS) ### add_subdirectory(example) diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 8d9d1dd975..28a8a5886a 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -100,6 +100,12 @@ private: LLCEFLib* mLLCEFLib; VolumeCatcher mVolumeCatcher; + + U8 *mPopupBuffer; + U32 mPopupW; + U32 mPopupH; + U32 mPopupX; + U32 mPopupY; }; //////////////////////////////////////////////////////////////////////////////// @@ -127,12 +133,19 @@ MediaPluginBase(host_send_func, host_user_data) mCookiePath = ""; mPickedFile = ""; mLLCEFLib = new LLCEFLib(); + + mPopupBuffer = NULL; + mPopupW = 0; + mPopupH = 0; + mPopupX = 0; + mPopupY = 0; } //////////////////////////////////////////////////////////////////////////////// // MediaPluginCEF::~MediaPluginCEF() { + delete[] mPopupBuffer; } //////////////////////////////////////////////////////////////////////////////// @@ -155,20 +168,28 @@ void MediaPluginCEF::postDebugMessage(const std::string& msg) // void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, int width, int height, bool is_popup) { - if (mPixels && pixels) + if( is_popup ) + { + delete mPopupBuffer; + mPopupBuffer = NULL; + mPopupH = 0; + mPopupW = 0; + mPopupX = 0; + mPopupY = 0; + } + + if( mPixels && pixels ) { if (is_popup) { - for (int line = 0; line < height; ++line) + if( width > 0 && height> 0 ) { - int inverted_y = mHeight - y - height; - int src = line * width * mDepth; - int dst = (inverted_y + line) * mWidth * mDepth + x * mDepth; - - if (dst + width * mDepth < mWidth * mHeight * mDepth) - { - memcpy(mPixels + dst, pixels + src, width * mDepth); - } + mPopupBuffer = new U8[ width * height * mDepth ]; + memcpy( mPopupBuffer, pixels, width * height * mDepth ); + mPopupH = height; + mPopupW = width; + mPopupX = x; + mPopupY = mHeight - y - height; } } else @@ -177,6 +198,23 @@ void MediaPluginCEF::onPageChangedCallback(unsigned char* pixels, int x, int y, { memcpy(mPixels, pixels, mWidth * mHeight * mDepth); } + if( mPopupBuffer && mPopupH && mPopupW ) + { + U32 bufferSize = mWidth * mHeight * mDepth; + U32 popupStride = mPopupW * mDepth; + U32 bufferStride = mWidth * mDepth; + int dstY = mPopupY; + + int src = 0; + int dst = dstY * mWidth * mDepth + mPopupX * mDepth; + + for( int line = 0; dst + popupStride < bufferSize && line < mPopupH; ++line ) + { + memcpy( mPixels + dst, mPopupBuffer + src, popupStride ); + src += popupStride; + dst += bufferStride; + } + } } setDirty(0, 0, mWidth, mHeight); @@ -559,6 +597,8 @@ void MediaPluginCEF::receiveMessage(const char* message_string) S32 x = message_in.getValueS32("x"); S32 y = message_in.getValueS32("y"); + y = mHeight - y; + // only even send left mouse button events to LLCEFLib // (partially prompted by crash in OS X CEF when sending right button events) // we catch the right click in viewer and display our own context menu anyway diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt new file mode 100644 index 0000000000..535d29125b --- /dev/null +++ b/indra/media_plugins/libvlc/CMakeLists.txt @@ -0,0 +1,86 @@ +# -*- cmake -*- + +project(media_plugin_libvlc) + +include(00-Common) +include(LLCommon) +include(LLImage) +include(LLPlugin) +include(LLMath) +include(LLRender) +include(LLWindow) +include(Linking) +include(PluginAPI) +include(MediaPluginBase) +include(OpenGL) + +include(LibVLCPlugin) + +include_directories( + ${LLPLUGIN_INCLUDE_DIRS} + ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} + ${LLCOMMON_INCLUDE_DIRS} + ${LLMATH_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} + ${VLC_INCLUDE_DIR} +) +include_directories(SYSTEM + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ) + + +### media_plugin_libvlc + +if(NOT WORD_SIZE EQUAL 32) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif(NOT WORD_SIZE EQUAL 32) + +set(media_plugin_libvlc_SOURCE_FILES + media_plugin_libvlc.cpp + ) + +add_library(media_plugin_libvlc + SHARED + ${media_plugin_libvlc_SOURCE_FILES} +) + +target_link_libraries(media_plugin_libvlc + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${VLC_PLUGIN_LIBRARIES} + ${PLUGIN_API_WINDOWS_LIBRARIES} +) + +add_dependencies(media_plugin_libvlc + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} +) + +if (WINDOWS) + set_target_properties( + media_plugin_libvlc + PROPERTIES + LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /LTCG /NODEFAULTLIB:LIBCMT" + ) +endif (WINDOWS) + +if (DARWIN) + # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name + set_target_properties( + media_plugin_libvlc + PROPERTIES + PREFIX "" + BUILD_WITH_INSTALL_RPATH 1 + INSTALL_NAME_DIR "@executable_path" + LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" + ) + +endif (DARWIN) diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp new file mode 100644 index 0000000000..0bd323eb58 --- /dev/null +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -0,0 +1,618 @@ +/** +* @file media_plugin_libvlc.cpp +* @brief LibVLC plugin for LLMedia API plugin system +* +* @cond +* $LicenseInfo:firstyear=2008&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2010, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +* @endcond +*/ + +#include "linden_common.h" + +#include "llgl.h" +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#include "vlc/vlc.h" +#include "vlc/libvlc_version.h" + +//////////////////////////////////////////////////////////////////////////////// +// +class MediaPluginLibVLC : + public MediaPluginBase +{ +public: + MediaPluginLibVLC(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginLibVLC(); + + /*virtual*/ void receiveMessage(const char* message_string); + +private: + bool init(); + + void initVLC(); + void playMedia(); + void resetVLC(); + void setVolume(const F64 volume); + void updateTitle(const char* title); + + static void* lock(void* data, void** p_pixels); + static void unlock(void* data, void* id, void* const* raw_pixels); + static void display(void* data, void* id); + + /*virtual*/ void setDirty(int left, int top, int right, int bottom) /* override, but that is not supported in gcc 4.6 */; + + static void eventCallbacks(const libvlc_event_t* event, void* ptr); + + libvlc_instance_t* mLibVLC; + libvlc_media_t* mLibVLCMedia; + libvlc_media_player_t* mLibVLCMediaPlayer; + + struct mLibVLCContext + { + unsigned char* texture_pixels; + libvlc_media_player_t* mp; + MediaPluginLibVLC* parent; + }; + struct mLibVLCContext mLibVLCCallbackContext; + + std::string mURL; + F64 mCurVolume; + + bool mIsLooping; + + float mCurTime; + float mDuration; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginLibVLC::MediaPluginLibVLC(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : +MediaPluginBase(host_send_func, host_user_data) +{ + mTextureWidth = 0; + mTextureHeight = 0; + mWidth = 0; + mHeight = 0; + mDepth = 4; + mPixels = 0; + + mLibVLC = 0; + mLibVLCMedia = 0; + mLibVLCMediaPlayer = 0; + + mCurVolume = 0.0; + + mIsLooping = false; + + mCurTime = 0.0; + mDuration = 0.0; + + mURL = std::string(); + + setStatus(STATUS_NONE); +} + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginLibVLC::~MediaPluginLibVLC() +{ +} + +///////////////////////////////////////////////////////////////////////////////// +// +void* MediaPluginLibVLC::lock(void* data, void** p_pixels) +{ + struct mLibVLCContext* context = (mLibVLCContext*)data; + + *p_pixels = context->texture_pixels; + + return NULL; +} + +///////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::unlock(void* data, void* id, void* const* raw_pixels) +{ + // nothing to do here for the moment + // we *could* modify pixels here to, for example, Y flip, but this is done with + // a VLC video filter transform. +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::display(void* data, void* id) +{ + struct mLibVLCContext* context = (mLibVLCContext*)data; + + context->parent->setDirty(0, 0, context->parent->mWidth, context->parent->mHeight); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::initVLC() +{ + char const* vlc_argv[] = + { + "--no-xlib", + "--video-filter=transform{type=vflip}", // MAINT-6578 Y flip textures in plugin vs client + }; + + int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); + mLibVLC = libvlc_new(vlc_argc, vlc_argv); + + if (!mLibVLC) + { + // for the moment, if this fails, the plugin will fail and + // the media sub-system will tell the viewer something went wrong. + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::resetVLC() +{ + libvlc_media_player_stop(mLibVLCMediaPlayer); + libvlc_media_player_release(mLibVLCMediaPlayer); + libvlc_release(mLibVLC); +} + +//////////////////////////////////////////////////////////////////////////////// +// *virtual* +void MediaPluginLibVLC::setDirty(int left, int top, int right, int bottom) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); + + message.setValueS32("left", left); + message.setValueS32("top", top); + message.setValueS32("right", right); + message.setValueS32("bottom", bottom); + + message.setValueReal("current_time", mCurTime); + message.setValueReal("duration", mDuration); + message.setValueReal("current_rate", 1.0f); + + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) +{ + MediaPluginLibVLC* parent = (MediaPluginLibVLC*)ptr; + if (parent == 0) + { + return; + } + + switch (event->type) + { + case libvlc_MediaPlayerOpening: + parent->setStatus(STATUS_LOADING); + break; + + case libvlc_MediaPlayerPlaying: + parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f; + parent->setStatus(STATUS_PLAYING); + break; + + case libvlc_MediaPlayerPaused: + parent->setStatus(STATUS_PAUSED); + break; + + case libvlc_MediaPlayerStopped: + parent->setStatus(STATUS_DONE); + break; + + case libvlc_MediaPlayerEndReached: + parent->setStatus(STATUS_DONE); + break; + + case libvlc_MediaPlayerEncounteredError: + parent->setStatus(STATUS_ERROR); + break; + + case libvlc_MediaPlayerTimeChanged: + parent->mCurTime = (float)libvlc_media_player_get_time(parent->mLibVLCMediaPlayer) / 1000.0f; + break; + + case libvlc_MediaPlayerPositionChanged: + break; + + case libvlc_MediaPlayerLengthChanged: + parent->mDuration = (float)libvlc_media_get_duration(parent->mLibVLCMedia) / 1000.0f; + break; + + case libvlc_MediaPlayerTitleChanged: + { + char* title = libvlc_media_get_meta(parent->mLibVLCMedia, libvlc_meta_Title); + if (title) + { + parent->updateTitle(title); + } + } + break; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::playMedia() +{ + if (mURL.length() == 0) + { + return; + } + + if (mLibVLCMediaPlayer) + { + // stop listening to events while we reset things + libvlc_event_manager_t* em = libvlc_media_player_event_manager(mLibVLCMediaPlayer); + if (em) + { + libvlc_event_detach(em, libvlc_MediaPlayerOpening, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerPlaying, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerPaused, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerStopped, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerEndReached, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerEncounteredError, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerTimeChanged, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerPositionChanged, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerLengthChanged, eventCallbacks, NULL); + libvlc_event_detach(em, libvlc_MediaPlayerTitleChanged, eventCallbacks, NULL); + }; + + libvlc_media_player_stop(mLibVLCMediaPlayer); + libvlc_media_player_release(mLibVLCMediaPlayer); + + mLibVLCMediaPlayer = 0; + } + + if (mLibVLCMedia) + { + libvlc_media_release(mLibVLCMedia); + + mLibVLCMedia = 0; + } + + mLibVLCMedia = libvlc_media_new_location(mLibVLC, mURL.c_str()); + if (!mLibVLCMedia) + { + mLibVLCMediaPlayer = 0; + setStatus(STATUS_ERROR); + return; + } + + mLibVLCMediaPlayer = libvlc_media_player_new_from_media(mLibVLCMedia); + if (!mLibVLCMediaPlayer) + { + setStatus(STATUS_ERROR); + return; + } + + // listen to events + libvlc_event_manager_t* em = libvlc_media_player_event_manager(mLibVLCMediaPlayer); + if (em) + { + libvlc_event_attach(em, libvlc_MediaPlayerOpening, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerPlaying, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerPaused, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerStopped, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerEndReached, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerEncounteredError, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerPositionChanged, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerLengthChanged, eventCallbacks, this); + libvlc_event_attach(em, libvlc_MediaPlayerTitleChanged, eventCallbacks, this); + } + + mLibVLCCallbackContext.parent = this; + mLibVLCCallbackContext.texture_pixels = mPixels; + mLibVLCCallbackContext.mp = mLibVLCMediaPlayer; + + // Send a "navigate begin" event. + // This is really a browser message but the QuickTime plugin did it and + // the media system relies on this message to update internal state so we must send it too + // Note: see "navigate_complete" message below too + // https://jira.secondlife.com/browse/MAINT-6528 + LLPluginMessage message_begin(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); + message_begin.setValue("uri", mURL); + message_begin.setValueBoolean("history_back_available", false); + message_begin.setValueBoolean("history_forward_available", false); + sendMessage(message_begin); + + // volume level gets set before VLC is initialized (thanks media system) so we have to record + // it in mCurVolume and set it again here so that volume levels are correctly initialized + setVolume(mCurVolume); + + setStatus(STATUS_LOADED); + + libvlc_video_set_callbacks(mLibVLCMediaPlayer, lock, unlock, display, &mLibVLCCallbackContext); + libvlc_video_set_format(mLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth); + + // note this relies on the "set_loop" message arriving before the "start" (play) one + // but that appears to always be the case + if (mIsLooping) + { + libvlc_media_add_option(mLibVLCMedia, "input-repeat=-1"); + } + + libvlc_media_player_play(mLibVLCMediaPlayer); + + // send a "location_changed" message - this informs the media system + // that a new URL is the 'current' one and is used extensively. + // Again, this is really a browser message but we will use it here. + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); + message.setValue("uri", mURL); + sendMessage(message); + + // Send a "navigate complete" event. + // This is really a browser message but the QuickTime plugin did it and + // the media system relies on this message to update internal state so we must send it too + // Note: see "navigate_begin" message above too + // https://jira.secondlife.com/browse/MAINT-6528 + LLPluginMessage message_complete(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); + message_complete.setValue("uri", mURL); + message_complete.setValueS32("result_code", 200); + message_complete.setValue("result_string", "OK"); + sendMessage(message_complete); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::updateTitle(const char* title) +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", title); + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::setVolume(const F64 volume) +{ + mCurVolume = volume; + + if (mLibVLCMediaPlayer) + { + int result = libvlc_audio_set_volume(mLibVLCMediaPlayer, (int)(volume * 100)); + if (result != 0) + { + // volume wasn't set but not much to be done here + } + } + else + { + // volume change was requested but VLC wasn't ready. + // that's okay thought because we saved the value in mCurVolume and + // the next volume change after the VLC system is initilzied will set it + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::receiveMessage(const char* message_string) +{ + LLPluginMessage message_in; + + if (message_in.parse(message_string) >= 0) + { + std::string message_class = message_in.getClass(); + std::string message_name = message_in.getName(); + if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE) + { + if (message_name == "init") + { + initVLC(); + + LLPluginMessage message("base", "init_response"); + LLSD versions = LLSD::emptyMap(); + versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; + message.setValueLLSD("versions", versions); + + std::ostringstream s; + s << "LibVLC plugin "; + s << LIBVLC_VERSION_MAJOR; + s << "."; + s << LIBVLC_VERSION_MINOR; + s << "."; + s << LIBVLC_VERSION_REVISION; + + message.setValue("plugin_version", s.str()); + sendMessage(message); + } + else if (message_name == "idle") + { + } + else if (message_name == "cleanup") + { + resetVLC(); + } + else if (message_name == "shm_added") + { + SharedSegmentInfo info; + info.mAddress = message_in.getValuePointer("address"); + info.mSize = (size_t)message_in.getValueS32("size"); + std::string name = message_in.getValue("name"); + + mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); + + } + else if (message_name == "shm_remove") + { + std::string name = message_in.getValue("name"); + + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + if (mPixels == iter->second.mAddress) + { + libvlc_media_player_stop(mLibVLCMediaPlayer); + libvlc_media_player_release(mLibVLCMediaPlayer); + mLibVLCMediaPlayer = 0; + + mPixels = NULL; + mTextureSegmentName.clear(); + } + mSharedSegments.erase(iter); + } + else + { + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; + } + + // Send the response so it can be cleaned up. + LLPluginMessage message("base", "shm_remove_response"); + message.setValue("name", name); + sendMessage(message); + } + else + { + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; + } + } + else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) + { + if (message_name == "init") + { + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); + message.setValueS32("default_width", 1024); + message.setValueS32("default_height", 1024); + message.setValueS32("depth", mDepth); + message.setValueU32("internalformat", GL_RGB); + message.setValueU32("format", GL_BGRA_EXT); + message.setValueU32("type", GL_UNSIGNED_BYTE); + message.setValueBoolean("coords_opengl", true); + sendMessage(message); + } + else if (message_name == "size_change") + { + std::string name = message_in.getValue("name"); + S32 width = message_in.getValueS32("width"); + S32 height = message_in.getValueS32("height"); + S32 texture_width = message_in.getValueS32("texture_width"); + S32 texture_height = message_in.getValueS32("texture_height"); + + if (!name.empty()) + { + // Find the shared memory region with this name + SharedSegmentMap::iterator iter = mSharedSegments.find(name); + if (iter != mSharedSegments.end()) + { + mPixels = (unsigned char*)iter->second.mAddress; + mWidth = width; + mHeight = height; + mTextureWidth = texture_width; + mTextureHeight = texture_height; + + playMedia(); + }; + }; + + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); + message.setValue("name", name); + message.setValueS32("width", width); + message.setValueS32("height", height); + message.setValueS32("texture_width", texture_width); + message.setValueS32("texture_height", texture_height); + sendMessage(message); + } + else if (message_name == "load_uri") + { + mURL = message_in.getValue("uri"); + playMedia(); + } + } + else + if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if (message_name == "stop") + { + if (mLibVLCMediaPlayer) + { + libvlc_media_player_stop(mLibVLCMediaPlayer); + } + } + else if (message_name == "start") + { + if (mLibVLCMediaPlayer) + { + libvlc_media_player_play(mLibVLCMediaPlayer); + } + } + else if (message_name == "pause") + { + if (mLibVLCMediaPlayer) + { + libvlc_media_player_pause(mLibVLCMediaPlayer); + } + } + else if (message_name == "seek") + { + if (mDuration > 0) + { + F64 normalized_offset = message_in.getValueReal("time") / mDuration; + libvlc_media_player_set_position(mLibVLCMediaPlayer, normalized_offset); + } + } + else if (message_name == "set_loop") + { + mIsLooping = true; + } + else if (message_name == "set_volume") + { + // volume comes in 0 -> 1.0 + F64 volume = message_in.getValueReal("volume"); + setVolume(volume); + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +bool MediaPluginLibVLC::init() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", "LibVLC Plugin"); + sendMessage(message); + + return true; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, + void* host_user_data, + LLPluginInstance::sendMessageFunction *plugin_send_func, + void **plugin_user_data) +{ + MediaPluginLibVLC* self = new MediaPluginLibVLC(host_send_func, host_user_data); + *plugin_send_func = MediaPluginLibVLC::staticReceiveMessage; + *plugin_user_data = (void*)self; + + return 0; +} diff --git a/indra/media_plugins/quicktime/CMakeLists.txt b/indra/media_plugins/quicktime/CMakeLists.txt index c5615145be..58391007ff 100644..100755 --- a/indra/media_plugins/quicktime/CMakeLists.txt +++ b/indra/media_plugins/quicktime/CMakeLists.txt @@ -14,7 +14,6 @@ include(PluginAPI) include(MediaPluginBase) include(OpenGL) include(QuickTimePlugin) -include(Boost) include_directories( ${LLPLUGIN_INCLUDE_DIRS} @@ -54,12 +53,17 @@ target_link_libraries(media_plugin_quicktime ${PLUGIN_API_WINDOWS_LIBRARIES} ) +add_dependencies(media_plugin_quicktime + ${LLPLUGIN_LIBRARIES} + ${MEDIA_PLUGIN_BASE_LIBRARIES} + ${LLCOMMON_LIBRARIES} +) + if (WINDOWS) set_target_properties( media_plugin_quicktime PROPERTIES - LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT" - LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD" + LINK_FLAGS "/MANIFEST:NO" ) endif (WINDOWS) diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index 7ef5a0fe44..b43598e4a5 100644..100755 --- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -837,9 +837,7 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) else if(message_name == "cleanup") { // TODO: clean up here - LLPluginMessage message("base", "goodbye"); - sendMessage(message); - } + } else if(message_name == "shm_added") { SharedSegmentInfo info; @@ -921,6 +919,9 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string) #endif message.setValueS32("depth", mDepth); message.setValueU32("internalformat", GL_RGB); + + // note this apparently only has an effect when media is opened in 2D browser. + // see https://jira.secondlife.com/browse/BUG-18252 - media flipped in 2D so flipping it back. message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. message.setValueBoolean("allow_downsample", true); sendMessage(message); |