From e11ab0240a0262fd722f04f104eabbf3949a8cef Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 6 May 2016 17:43:47 -0700 Subject: Moving to a private repo --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 445 +++++++++++++++++++++ 1 file changed, 445 insertions(+) create mode 100644 indra/media_plugins/libvlc/media_plugin_libvlc.cpp (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') 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..47ba6f48b4 --- /dev/null +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -0,0 +1,445 @@ +/** + * @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 + +//////////////////////////////////////////////////////////////////////////////// +// +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 update( F64 milliseconds ); + bool mFirstTime; + + time_t mLastUpdateTime; + enum Constants { ENumObjects = 10 }; + unsigned char* mBackgroundPixels; + int mColorR[ ENumObjects ]; + int mColorG[ ENumObjects ]; + int mColorB[ ENumObjects ]; + int mXpos[ ENumObjects ]; + int mYpos[ ENumObjects ]; + int mXInc[ ENumObjects ]; + int mYInc[ ENumObjects ]; + int mBlockSize[ ENumObjects ]; + + libvlc_instance_t* gLibVLC = 0; + libvlc_media_t* gLibVLCMedia = 0; + libvlc_media_player_t* gLibVLCMediaPlayer = 0; +}; + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginLibVLC::MediaPluginLibVLC( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) : + MediaPluginBase( host_send_func, host_user_data ) +{ + mFirstTime = true; + mTextureWidth = 64; + mTextureHeight = 64; + mWidth = 0; + mHeight = 0; + mDepth = 4; + mPixels = 0; + mLastUpdateTime = 0; + mBackgroundPixels = 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// +MediaPluginLibVLC::~MediaPluginLibVLC() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::receiveMessage( const char* message_string ) +{ +// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + 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") + { + char const* vlc_argv[] = + { + "--no-xlib", + }; + + int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); + gLibVLC = libvlc_new(vlc_argc, vlc_argv); + + if (!gLibVLC) + { + } + + //if (gLibVLCMediaPlayer) + //{ + // libvlc_media_player_stop(gLibVLCMediaPlayer); + // libvlc_media_player_release(gLibVLCMediaPlayer); + //} + + const char* url = "https://callum-linden.s3.amazonaws.com/sample_media/jb.mp4"; + + gLibVLCMedia = libvlc_media_new_location(gLibVLC, url); + if (!gLibVLCMedia) + { + printf("libvlc_media_new_location failed\n"); + } + else + { + printf("libvlc_media_new_location ok\n"); + } + + gLibVLCMediaPlayer = libvlc_media_player_new_from_media(gLibVLCMedia); + if (!gLibVLCMediaPlayer) + { + printf("libvlc_media_player_new_from_media failed\n"); + } + else + { + printf("libvlc_media_player_new_from_media ok...\n"); + } + + libvlc_media_release(gLibVLCMedia); + +// gVLCCallbackContext.texture_pixels = gTexturePixels; +// gVLCCallbackContext.mp = gLibVLCMediaPlayer; + +// libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, unlock, display, &gVLCCallbackContext); + libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mTextureWidth, mTextureHeight, mTextureWidth * 4); + libvlc_media_player_play(gLibVLCMediaPlayer); + + 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_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + message.setValueLLSD("versions", versions); + + std::string plugin_version = "LibVLC plugin 0.0.0"; + message.setValue("plugin_version", plugin_version); + sendMessage(message); + } + else if(message_name == "idle") + { + // no response is necessary here. + F64 time = message_in.getValueReal("time"); + + // Convert time to milliseconds for update() + update((int)(time * 1000.0f)); + } + else if(message_name == "cleanup") + { + libvlc_media_player_stop(gLibVLCMediaPlayer); + libvlc_media_player_release(gLibVLCMediaPlayer); + libvlc_release(gLibVLC); + } + 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) + { + // This is the currently active pixel buffer. Make sure we stop drawing to it. + 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") + { + // Plugin gets to decide the texture parameters to use. + mDepth = 4; + 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_RGBA); + 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; + }; + }; + + 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); + + mLastUpdateTime = 0; + mFirstTime = true; + + } + else if(message_name == "load_uri") + { + } + else if(message_name == "mouse_event") + { + std::string event = message_in.getValue("event"); + if(event == "down") + { + + } + else if(event == "up") + { + } + else if(event == "double_click") + { + } + } + } + else + { + }; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::update( F64 milliseconds ) +{ + if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 ) + return; + + if ( mPixels == 0 ) + return; + + if ( mFirstTime ) + { + for( int n = 0; n < ENumObjects; ++n ) + { + mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 ); + mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 ); + + mColorR[ n ] = rand() % 0x60 + 0x60; + mColorG[ n ] = rand() % 0x60 + 0x60; + mColorB[ n ] = rand() % 0x60 + 0x60; + + mXInc[ n ] = 0; + while ( mXInc[ n ] == 0 ) + mXInc[ n ] = rand() % 7 - 3; + + mYInc[ n ] = 0; + while ( mYInc[ n ] == 0 ) + mYInc[ n ] = rand() % 9 - 4; + + mBlockSize[ n ] = rand() % 0x30 + 0x10; + }; + + delete [] mBackgroundPixels; + + mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ]; + + mFirstTime = false; + }; + + if ( time( NULL ) > mLastUpdateTime + 3 ) + { + const int num_squares = rand() % 20 + 4; + int sqr1_r = rand() % 0x80 + 0x20; + int sqr1_g = rand() % 0x80 + 0x20; + int sqr1_b = rand() % 0x80 + 0x20; + int sqr2_r = rand() % 0x80 + 0x20; + int sqr2_g = rand() % 0x80 + 0x20; + int sqr2_b = rand() % 0x80 + 0x20; + + for ( int y1 = 0; y1 < num_squares; ++y1 ) + { + for ( int x1 = 0; x1 < num_squares; ++x1 ) + { + int px_start = mWidth * x1 / num_squares; + int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares; + int py_start = mHeight * y1 / num_squares; + int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares; + + for( int y2 = py_start; y2 < py_end; ++y2 ) + { + for( int x2 = px_start; x2 < px_end; ++x2 ) + { + int rowspan = mWidth * mDepth; + + if ( ( y1 % 2 ) ^ ( x1 % 2 ) ) + { + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b; + } + else + { + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g; + mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b; + }; + }; + }; + }; + }; + + time( &mLastUpdateTime ); + }; + + memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth ); + + for( int n = 0; n < ENumObjects; ++n ) + { + if ( rand() % 50 == 0 ) + { + mXInc[ n ] = 0; + while ( mXInc[ n ] == 0 ) + mXInc[ n ] = rand() % 7 - 3; + + mYInc[ n ] = 0; + while ( mYInc[ n ] == 0 ) + mYInc[ n ] = rand() % 9 - 4; + }; + + if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] ) + mXInc[ n ]= -mXInc[ n ]; + + if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] ) + mYInc[ n ]= -mYInc[ n ]; + + mXpos[ n ] += mXInc[ n ]; + mYpos[ n ] += mYInc[ n ]; + + for( int y = 0; y < mBlockSize[ n ]; ++y ) + { + for( int x = 0; x < mBlockSize[ n ]; ++x ) + { + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ]; + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ]; + mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ]; + }; + }; + }; + + setDirty( 0, 0, mWidth, mHeight ); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +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; +} -- cgit v1.2.3 From d15da192311bbef38b27a07cf27bbf4e33b99b0b Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 9 May 2016 17:11:10 -0700 Subject: Added restart on resize - kind of works --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 345 ++++++++------------- 1 file changed, 134 insertions(+), 211 deletions(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 47ba6f48b4..91744798e7 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -35,8 +35,7 @@ #include "media_plugin_base.h" #include "vlc/vlc.h" - -#include +#include "vlc/libvlc_version.h" //////////////////////////////////////////////////////////////////////////////// // @@ -52,23 +51,26 @@ class MediaPluginLibVLC : private: bool init(); void update( F64 milliseconds ); - bool mFirstTime; - - time_t mLastUpdateTime; - enum Constants { ENumObjects = 10 }; - unsigned char* mBackgroundPixels; - int mColorR[ ENumObjects ]; - int mColorG[ ENumObjects ]; - int mColorB[ ENumObjects ]; - int mXpos[ ENumObjects ]; - int mYpos[ ENumObjects ]; - int mXInc[ ENumObjects ]; - int mYInc[ ENumObjects ]; - int mBlockSize[ ENumObjects ]; - - libvlc_instance_t* gLibVLC = 0; - libvlc_media_t* gLibVLCMedia = 0; - libvlc_media_player_t* gLibVLCMediaPlayer = 0; + + + static void* lock(void* data, void** p_pixels); + void initVLC(); + void playMedia(const std::string url); + void resetVLC(); + + libvlc_instance_t* gLibVLC; + libvlc_media_t* gLibVLCMedia; + libvlc_media_player_t* gLibVLCMediaPlayer; + + + //float mCurVideoPosition; + + struct gVLCContext + { + unsigned char* texture_pixels; + libvlc_media_player_t* mp; + }; + struct gVLCContext gVLCCallbackContext; }; //////////////////////////////////////////////////////////////////////////////// @@ -76,15 +78,18 @@ class MediaPluginLibVLC : MediaPluginLibVLC::MediaPluginLibVLC( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) : MediaPluginBase( host_send_func, host_user_data ) { - mFirstTime = true; mTextureWidth = 64; mTextureHeight = 64; mWidth = 0; mHeight = 0; mDepth = 4; mPixels = 0; - mLastUpdateTime = 0; - mBackgroundPixels = 0; + + gLibVLC = 0; + gLibVLCMedia = 0; + gLibVLCMediaPlayer = 0; + + //mCurVideoPosition = 0; } //////////////////////////////////////////////////////////////////////////////// @@ -93,6 +98,88 @@ MediaPluginLibVLC::~MediaPluginLibVLC() { } +///////////////////////////////////////////////////////////////////////////////// +// +void* MediaPluginLibVLC::lock(void* data, void** p_pixels) +{ + struct gVLCContext* context = (gVLCContext*)data; + + *p_pixels = context->texture_pixels; + + return NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::initVLC() +{ + char const* vlc_argv[] = + { + "--no-xlib", + }; + + int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); + gLibVLC = libvlc_new(vlc_argc, vlc_argv); + + if (!gLibVLC) + { + // TODO: do we need to do anything herE? + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::resetVLC() +{ + libvlc_media_player_stop(gLibVLCMediaPlayer); + libvlc_media_player_release(gLibVLCMediaPlayer); + libvlc_release(gLibVLC); +} + +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::playMedia(const std::string url) +{ + std::string tmp_url = std::string("https://callum-linden.s3.amazonaws.com/sample_media/jb.mp4"); + + if (gLibVLCMediaPlayer) + { + libvlc_media_player_stop(gLibVLCMediaPlayer); + libvlc_media_player_release(gLibVLCMediaPlayer); + } + + gLibVLCMedia = libvlc_media_new_location(gLibVLC, tmp_url.c_str()); + if (!gLibVLCMedia) + { + printf("libvlc_media_new_location failed\n"); + } + else + { + printf("libvlc_media_new_location ok\n"); + } + + gLibVLCMediaPlayer = libvlc_media_player_new_from_media(gLibVLCMedia); + if (!gLibVLCMediaPlayer) + { + printf("libvlc_media_player_new_from_media failed\n"); + } + else + { + printf("libvlc_media_player_new_from_media ok...\n"); + } + + libvlc_media_release(gLibVLCMedia); + + gVLCCallbackContext.texture_pixels = mPixels; + gVLCCallbackContext.mp = gLibVLCMediaPlayer; + + libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, NULL, NULL, &gVLCCallbackContext); + libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * 4); + libvlc_media_player_play(gLibVLCMediaPlayer); + + //libvlc_media_player_set_position(gLibVLCMediaPlayer, mCurVideoPosition); +} + //////////////////////////////////////////////////////////////////////////////// // void MediaPluginLibVLC::receiveMessage( const char* message_string ) @@ -108,54 +195,7 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) { if(message_name == "init") { - char const* vlc_argv[] = - { - "--no-xlib", - }; - - int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); - gLibVLC = libvlc_new(vlc_argc, vlc_argv); - - if (!gLibVLC) - { - } - - //if (gLibVLCMediaPlayer) - //{ - // libvlc_media_player_stop(gLibVLCMediaPlayer); - // libvlc_media_player_release(gLibVLCMediaPlayer); - //} - - const char* url = "https://callum-linden.s3.amazonaws.com/sample_media/jb.mp4"; - - gLibVLCMedia = libvlc_media_new_location(gLibVLC, url); - if (!gLibVLCMedia) - { - printf("libvlc_media_new_location failed\n"); - } - else - { - printf("libvlc_media_new_location ok\n"); - } - - gLibVLCMediaPlayer = libvlc_media_player_new_from_media(gLibVLCMedia); - if (!gLibVLCMediaPlayer) - { - printf("libvlc_media_player_new_from_media failed\n"); - } - else - { - printf("libvlc_media_player_new_from_media ok...\n"); - } - - libvlc_media_release(gLibVLCMedia); - -// gVLCCallbackContext.texture_pixels = gTexturePixels; -// gVLCCallbackContext.mp = gLibVLCMediaPlayer; - -// libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, unlock, display, &gVLCCallbackContext); - libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mTextureWidth, mTextureHeight, mTextureWidth * 4); - libvlc_media_player_play(gLibVLCMediaPlayer); + initVLC(); LLPluginMessage message("base", "init_response"); LLSD versions = LLSD::emptyMap(); @@ -164,23 +204,25 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; message.setValueLLSD("versions", versions); - std::string plugin_version = "LibVLC plugin 0.0.0"; - message.setValue("plugin_version", plugin_version); + 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") { - // no response is necessary here. - F64 time = message_in.getValueReal("time"); - - // Convert time to milliseconds for update() - update((int)(time * 1000.0f)); + // TODO move to VLC callback when VLC wants to draw a frame + setDirty(0, 0, mWidth, mHeight); } else if(message_name == "cleanup") { - libvlc_media_player_stop(gLibVLCMediaPlayer); - libvlc_media_player_release(gLibVLCMediaPlayer); - libvlc_release(gLibVLC); + resetVLC(); } else if(message_name == "shm_added") { @@ -201,6 +243,13 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) { if(mPixels == iter->second.mAddress) { + /// only do thisis URLs are the same if ( ) + //mCurVideoPosition = libvlc_media_player_get_position(gLibVLCMediaPlayer); + + libvlc_media_player_stop(gLibVLCMediaPlayer); + libvlc_media_player_release(gLibVLCMediaPlayer); + gLibVLCMediaPlayer = 0; + // This is the currently active pixel buffer. Make sure we stop drawing to it. mPixels = NULL; mTextureSegmentName.clear(); @@ -233,9 +282,9 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) message.setValueS32("default_height", 1024); message.setValueS32("depth", mDepth); message.setValueU32("internalformat", GL_RGB); - message.setValueU32("format", GL_RGBA); + message.setValueU32("format", GL_BGRA_EXT); message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", true); + message.setValueBoolean("coords_opengl", false); sendMessage(message); } else if(message_name == "size_change") @@ -255,10 +304,11 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) 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"); @@ -268,10 +318,6 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) message.setValueS32("texture_width", texture_width); message.setValueS32("texture_height", texture_height); sendMessage(message); - - mLastUpdateTime = 0; - mFirstTime = true; - } else if(message_name == "load_uri") { @@ -281,7 +327,6 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) std::string event = message_in.getValue("event"); if(event == "down") { - } else if(event == "up") { @@ -297,128 +342,6 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) } } -//////////////////////////////////////////////////////////////////////////////// -// -void MediaPluginLibVLC::update( F64 milliseconds ) -{ - if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 ) - return; - - if ( mPixels == 0 ) - return; - - if ( mFirstTime ) - { - for( int n = 0; n < ENumObjects; ++n ) - { - mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 ); - mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 ); - - mColorR[ n ] = rand() % 0x60 + 0x60; - mColorG[ n ] = rand() % 0x60 + 0x60; - mColorB[ n ] = rand() % 0x60 + 0x60; - - mXInc[ n ] = 0; - while ( mXInc[ n ] == 0 ) - mXInc[ n ] = rand() % 7 - 3; - - mYInc[ n ] = 0; - while ( mYInc[ n ] == 0 ) - mYInc[ n ] = rand() % 9 - 4; - - mBlockSize[ n ] = rand() % 0x30 + 0x10; - }; - - delete [] mBackgroundPixels; - - mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ]; - - mFirstTime = false; - }; - - if ( time( NULL ) > mLastUpdateTime + 3 ) - { - const int num_squares = rand() % 20 + 4; - int sqr1_r = rand() % 0x80 + 0x20; - int sqr1_g = rand() % 0x80 + 0x20; - int sqr1_b = rand() % 0x80 + 0x20; - int sqr2_r = rand() % 0x80 + 0x20; - int sqr2_g = rand() % 0x80 + 0x20; - int sqr2_b = rand() % 0x80 + 0x20; - - for ( int y1 = 0; y1 < num_squares; ++y1 ) - { - for ( int x1 = 0; x1 < num_squares; ++x1 ) - { - int px_start = mWidth * x1 / num_squares; - int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares; - int py_start = mHeight * y1 / num_squares; - int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares; - - for( int y2 = py_start; y2 < py_end; ++y2 ) - { - for( int x2 = px_start; x2 < px_end; ++x2 ) - { - int rowspan = mWidth * mDepth; - - if ( ( y1 % 2 ) ^ ( x1 % 2 ) ) - { - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b; - } - else - { - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g; - mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b; - }; - }; - }; - }; - }; - - time( &mLastUpdateTime ); - }; - - memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth ); - - for( int n = 0; n < ENumObjects; ++n ) - { - if ( rand() % 50 == 0 ) - { - mXInc[ n ] = 0; - while ( mXInc[ n ] == 0 ) - mXInc[ n ] = rand() % 7 - 3; - - mYInc[ n ] = 0; - while ( mYInc[ n ] == 0 ) - mYInc[ n ] = rand() % 9 - 4; - }; - - if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] ) - mXInc[ n ]= -mXInc[ n ]; - - if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] ) - mYInc[ n ]= -mYInc[ n ]; - - mXpos[ n ] += mXInc[ n ]; - mYpos[ n ] += mYInc[ n ]; - - for( int y = 0; y < mBlockSize[ n ]; ++y ) - { - for( int x = 0; x < mBlockSize[ n ]; ++x ) - { - mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ]; - mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ]; - mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ]; - }; - }; - }; - - setDirty( 0, 0, mWidth, mHeight ); -}; - //////////////////////////////////////////////////////////////////////////////// // bool MediaPluginLibVLC::init() -- cgit v1.2.3 From ed73eae302d3178dd37163e74902fe149baa2c9c Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 10 May 2016 13:07:34 -0700 Subject: Added support for arbitrary URLs and cleaned up code --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 79 ++++++++++------------ 1 file changed, 35 insertions(+), 44 deletions(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 91744798e7..ceb42c0f13 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -50,27 +50,27 @@ class MediaPluginLibVLC : private: bool init(); - void update( F64 milliseconds ); - - static void* lock(void* data, void** p_pixels); void initVLC(); - void playMedia(const std::string url); + void playMedia(); void resetVLC(); + static void* lock(void* data, void** p_pixels); + static void display(void* data, void* id); + libvlc_instance_t* gLibVLC; libvlc_media_t* gLibVLCMedia; libvlc_media_player_t* gLibVLCMediaPlayer; - - //float mCurVideoPosition; - struct gVLCContext { unsigned char* texture_pixels; libvlc_media_player_t* mp; + MediaPluginLibVLC* parent; }; struct gVLCContext gVLCCallbackContext; + + std::string mURL; }; //////////////////////////////////////////////////////////////////////////////// @@ -78,8 +78,8 @@ class MediaPluginLibVLC : MediaPluginLibVLC::MediaPluginLibVLC( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) : MediaPluginBase( host_send_func, host_user_data ) { - mTextureWidth = 64; - mTextureHeight = 64; + mTextureWidth = 0; + mTextureHeight = 0; mWidth = 0; mHeight = 0; mDepth = 4; @@ -89,7 +89,7 @@ MediaPluginLibVLC::MediaPluginLibVLC( LLPluginInstance::sendMessageFunction host gLibVLCMedia = 0; gLibVLCMediaPlayer = 0; - //mCurVideoPosition = 0; + mURL = std::string(); } //////////////////////////////////////////////////////////////////////////////// @@ -109,6 +109,15 @@ void* MediaPluginLibVLC::lock(void* data, void** p_pixels) return NULL; } +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::display(void* data, void* id) +{ + struct gVLCContext* context = (gVLCContext*)data; + + context->parent->setDirty(0, 0, context->parent->mWidth, context->parent->mHeight); +} + //////////////////////////////////////////////////////////////////////////////// // void MediaPluginLibVLC::initVLC() @@ -123,7 +132,8 @@ void MediaPluginLibVLC::initVLC() if (!gLibVLC) { - // TODO: do we need to do anything herE? + // for the moment, if this fails, the plugin will fail and + // the media sub-system will tell the viewer something went wrong. } } @@ -138,9 +148,12 @@ void MediaPluginLibVLC::resetVLC() //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginLibVLC::playMedia(const std::string url) +void MediaPluginLibVLC::playMedia() { - std::string tmp_url = std::string("https://callum-linden.s3.amazonaws.com/sample_media/jb.mp4"); + if (mURL.length() == 0) + { + return; + } if (gLibVLCMediaPlayer) { @@ -148,7 +161,7 @@ void MediaPluginLibVLC::playMedia(const std::string url) libvlc_media_player_release(gLibVLCMediaPlayer); } - gLibVLCMedia = libvlc_media_new_location(gLibVLC, tmp_url.c_str()); + gLibVLCMedia = libvlc_media_new_location(gLibVLC, mURL.c_str()); if (!gLibVLCMedia) { printf("libvlc_media_new_location failed\n"); @@ -170,21 +183,20 @@ void MediaPluginLibVLC::playMedia(const std::string url) libvlc_media_release(gLibVLCMedia); + + gVLCCallbackContext.parent = this; gVLCCallbackContext.texture_pixels = mPixels; gVLCCallbackContext.mp = gLibVLCMediaPlayer; - libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, NULL, NULL, &gVLCCallbackContext); + libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, NULL, display, &gVLCCallbackContext); libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * 4); libvlc_media_player_play(gLibVLCMediaPlayer); - - //libvlc_media_player_set_position(gLibVLCMediaPlayer, mCurVideoPosition); } //////////////////////////////////////////////////////////////////////////////// // void MediaPluginLibVLC::receiveMessage( const char* message_string ) { -// std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl; LLPluginMessage message_in; if(message_in.parse(message_string) >= 0) @@ -217,8 +229,6 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) } else if(message_name == "idle") { - // TODO move to VLC callback when VLC wants to draw a frame - setDirty(0, 0, mWidth, mHeight); } else if(message_name == "cleanup") { @@ -243,14 +253,10 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) { if(mPixels == iter->second.mAddress) { - /// only do thisis URLs are the same if ( ) - //mCurVideoPosition = libvlc_media_player_get_position(gLibVLCMediaPlayer); - libvlc_media_player_stop(gLibVLCMediaPlayer); libvlc_media_player_release(gLibVLCMediaPlayer); gLibVLCMediaPlayer = 0; - // This is the currently active pixel buffer. Make sure we stop drawing to it. mPixels = NULL; mTextureSegmentName.clear(); } @@ -258,7 +264,7 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) } else { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl; } // Send the response so it can be cleaned up. @@ -268,14 +274,13 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) } else { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; + //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl; } } else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) { if(message_name == "init") { - // Plugin gets to decide the texture parameters to use. mDepth = 4; LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); message.setValueS32("default_width", 1024); @@ -307,7 +312,7 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) mTextureWidth = texture_width; mTextureHeight = texture_height; - playMedia(""); + playMedia(); }; }; @@ -321,24 +326,10 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) } else if(message_name == "load_uri") { - } - else if(message_name == "mouse_event") - { - std::string event = message_in.getValue("event"); - if(event == "down") - { - } - else if(event == "up") - { - } - else if(event == "double_click") - { - } + mURL = message_in.getValue("uri"); + playMedia(); } } - else - { - }; } } -- cgit v1.2.3 From bceafa5062db394048312aa7fe0a7706fb9524b7 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 10 May 2016 17:16:24 -0700 Subject: working test button in web browser floater - video inverted --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index ceb42c0f13..08716e1a1c 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -289,7 +289,7 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) message.setValueU32("internalformat", GL_RGB); message.setValueU32("format", GL_BGRA_EXT); message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", false); + message.setValueBoolean("coords_opengl", true); sendMessage(message); } else if(message_name == "size_change") -- cgit v1.2.3 From f0e9566b90183081daef4ff8b534093fbcf73e6d Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 13 May 2016 13:09:12 -0700 Subject: pull in unflipped version of LLCEFLib --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 08716e1a1c..920c32f1f7 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -56,6 +56,7 @@ class MediaPluginLibVLC : void resetVLC(); 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); libvlc_instance_t* gLibVLC; @@ -109,6 +110,14 @@ void* MediaPluginLibVLC::lock(void* data, void** p_pixels) return NULL; } +///////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::unlock(void* data, void* id, void* const* raw_pixels) +{ + // nothing to do here for the moment. + // we can modify the raw_pixels here if we want to. +} + //////////////////////////////////////////////////////////////////////////////// // void MediaPluginLibVLC::display(void* data, void* id) @@ -188,7 +197,7 @@ void MediaPluginLibVLC::playMedia() gVLCCallbackContext.texture_pixels = mPixels; gVLCCallbackContext.mp = gLibVLCMediaPlayer; - libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, NULL, display, &gVLCCallbackContext); + libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, unlock, display, &gVLCCallbackContext); libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * 4); libvlc_media_player_play(gLibVLCMediaPlayer); } @@ -281,7 +290,6 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) { if(message_name == "init") { - mDepth = 4; LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); message.setValueS32("default_width", 1024); message.setValueS32("default_height", 1024); @@ -289,7 +297,7 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) message.setValueU32("internalformat", GL_RGB); message.setValueU32("format", GL_BGRA_EXT); message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", true); + message.setValueBoolean("coords_opengl", false); sendMessage(message); } else if(message_name == "size_change") -- cgit v1.2.3 From 50ab1e57ec21f2009013b3bc061047887cdd07d5 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Mon, 16 May 2016 10:58:39 -0700 Subject: Added support for some transport controls (pause/play/stop) and setting media volume level. --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 41 +++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 920c32f1f7..92bfc15113 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -198,7 +198,7 @@ void MediaPluginLibVLC::playMedia() gVLCCallbackContext.mp = gLibVLCMediaPlayer; libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, unlock, display, &gVLCCallbackContext); - libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * 4); + libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth); libvlc_media_player_play(gLibVLCMediaPlayer); } @@ -338,6 +338,45 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) playMedia(); } } + else + if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if (message_name == "stop") + { + if (gLibVLCMediaPlayer) + { + libvlc_media_player_stop(gLibVLCMediaPlayer); + } + } + else if (message_name == "start") + { + if (gLibVLCMediaPlayer) + { + libvlc_media_player_play(gLibVLCMediaPlayer); + } + } + else if (message_name == "pause") + { + if (gLibVLCMediaPlayer) + { + libvlc_media_player_pause(gLibVLCMediaPlayer); + } + } + else if (message_name == "seek") + { + } + else if (message_name == "set_loop") + { + } + else if (message_name == "set_volume") + { + if (gLibVLCMediaPlayer) + { + F64 volume = message_in.getValueReal("volume"); + libvlc_audio_set_volume(gLibVLCMediaPlayer, (int)(volume * 100)); + } + } + } } } -- cgit v1.2.3 From 282956e7688169e539059385962cbd6a295255f6 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 27 May 2016 16:53:16 -0700 Subject: Some simple tidy up and added a proper URL for video test button in web content floater --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 92bfc15113..43d4e95243 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -173,26 +173,18 @@ void MediaPluginLibVLC::playMedia() gLibVLCMedia = libvlc_media_new_location(gLibVLC, mURL.c_str()); if (!gLibVLCMedia) { - printf("libvlc_media_new_location failed\n"); - } - else - { - printf("libvlc_media_new_location ok\n"); + gLibVLCMediaPlayer = 0; + return; } gLibVLCMediaPlayer = libvlc_media_player_new_from_media(gLibVLCMedia); if (!gLibVLCMediaPlayer) { - printf("libvlc_media_player_new_from_media failed\n"); - } - else - { - printf("libvlc_media_player_new_from_media ok...\n"); + return; } libvlc_media_release(gLibVLCMedia); - gVLCCallbackContext.parent = this; gVLCCallbackContext.texture_pixels = mPixels; gVLCCallbackContext.mp = gLibVLCMediaPlayer; -- cgit v1.2.3 From 69174fcc58e0a2e67a417c2e0060d9f36a0ba238 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Tue, 31 May 2016 14:51:40 -0700 Subject: Fix windows line endings --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 78 +++++++++++----------- 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 43d4e95243..3852d10c44 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -330,45 +330,45 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) playMedia(); } } - else - if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) - { - if (message_name == "stop") - { - if (gLibVLCMediaPlayer) - { - libvlc_media_player_stop(gLibVLCMediaPlayer); - } - } - else if (message_name == "start") - { - if (gLibVLCMediaPlayer) - { - libvlc_media_player_play(gLibVLCMediaPlayer); - } - } - else if (message_name == "pause") - { - if (gLibVLCMediaPlayer) - { - libvlc_media_player_pause(gLibVLCMediaPlayer); - } - } - else if (message_name == "seek") - { - } - else if (message_name == "set_loop") - { - } - else if (message_name == "set_volume") - { - if (gLibVLCMediaPlayer) - { - F64 volume = message_in.getValueReal("volume"); - libvlc_audio_set_volume(gLibVLCMediaPlayer, (int)(volume * 100)); - } - } - } + else + if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) + { + if (message_name == "stop") + { + if (gLibVLCMediaPlayer) + { + libvlc_media_player_stop(gLibVLCMediaPlayer); + } + } + else if (message_name == "start") + { + if (gLibVLCMediaPlayer) + { + libvlc_media_player_play(gLibVLCMediaPlayer); + } + } + else if (message_name == "pause") + { + if (gLibVLCMediaPlayer) + { + libvlc_media_player_pause(gLibVLCMediaPlayer); + } + } + else if (message_name == "seek") + { + } + else if (message_name == "set_loop") + { + } + else if (message_name == "set_volume") + { + if (gLibVLCMediaPlayer) + { + F64 volume = message_in.getValueReal("volume"); + libvlc_audio_set_volume(gLibVLCMediaPlayer, (int)(volume * 100)); + } + } + } } } -- cgit v1.2.3 From 5f57257185f1535aae1967b2b6d8a40c154bef83 Mon Sep 17 00:00:00 2001 From: callum_linden Date: Fri, 1 Jul 2016 14:52:51 -0700 Subject: MAINT-6481 FIX Media controls not present --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 3852d10c44..5dd866db80 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -214,7 +214,7 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) 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_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION; + versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; message.setValueLLSD("versions", versions); std::ostringstream s; -- cgit v1.2.3 From d59ce04495be43ab1dc68c1a78b3ca6eb2e7b01e Mon Sep 17 00:00:00 2001 From: callum_linden Date: Thu, 7 Jul 2016 09:10:39 -0700 Subject: MAINT-6527 FIX -volume plays at full amount +50m away - volume was not set for media outside attenuation zone so played at random value --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 5dd866db80..fdad990b7c 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -189,6 +189,7 @@ void MediaPluginLibVLC::playMedia() gVLCCallbackContext.texture_pixels = mPixels; gVLCCallbackContext.mp = gLibVLCMediaPlayer; + libvlc_audio_set_volume(gLibVLCMediaPlayer, 0); libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, unlock, display, &gVLCCallbackContext); libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth); libvlc_media_player_play(gLibVLCMediaPlayer); -- cgit v1.2.3 From 8ae7828643fbb04a52a52abefa2133a761dd4179 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Mon, 11 Jul 2016 19:46:11 -0700 Subject: MAINT-6527 and MAINT-6528 FIX - max volume and media playing prior URLs --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index fdad990b7c..e00602bad8 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -189,10 +189,35 @@ void MediaPluginLibVLC::playMedia() gVLCCallbackContext.texture_pixels = mPixels; gVLCCallbackContext.mp = gLibVLCMediaPlayer; + // 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 should be initialized - when media is in range, the distance based attenuation + // will set the correct value + // https://jira.secondlife.com/browse/MAINT-6527 libvlc_audio_set_volume(gLibVLCMediaPlayer, 0); libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, unlock, display, &gVLCCallbackContext); libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth); libvlc_media_player_play(gLibVLCMediaPlayer); + + // 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); } //////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 1c4dbc64abc7ff176b5dcbbc64d0454968efad74 Mon Sep 17 00:00:00 2001 From: Callum Linden Date: Fri, 15 Jul 2016 12:18:00 -0700 Subject: MAINT-6577 FIX No sound in MOAP or browser video --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 42 +++++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index e00602bad8..8ef4ee2a27 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -54,6 +54,7 @@ class MediaPluginLibVLC : void initVLC(); void playMedia(); void resetVLC(); + void setVolume(const F64 volume); static void* lock(void* data, void** p_pixels); static void unlock(void* data, void* id, void* const* raw_pixels); @@ -72,6 +73,7 @@ class MediaPluginLibVLC : struct gVLCContext gVLCCallbackContext; std::string mURL; + F64 mCurVolume; }; //////////////////////////////////////////////////////////////////////////////// @@ -90,6 +92,8 @@ MediaPluginLibVLC::MediaPluginLibVLC( LLPluginInstance::sendMessageFunction host gLibVLCMedia = 0; gLibVLCMediaPlayer = 0; + mCurVolume = 0.0; + mURL = std::string(); } @@ -200,10 +204,10 @@ void MediaPluginLibVLC::playMedia() message_begin.setValueBoolean("history_forward_available", false); sendMessage(message_begin); - // volume should be initialized - when media is in range, the distance based attenuation - // will set the correct value - // https://jira.secondlife.com/browse/MAINT-6527 - libvlc_audio_set_volume(gLibVLCMediaPlayer, 0); + // 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); + libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, unlock, display, &gVLCCallbackContext); libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth); libvlc_media_player_play(gLibVLCMediaPlayer); @@ -220,6 +224,28 @@ void MediaPluginLibVLC::playMedia() sendMessage(message_complete); } +//////////////////////////////////////////////////////////////////////////////// +// +void MediaPluginLibVLC::setVolume(const F64 volume) +{ + mCurVolume = volume; + + if (gLibVLCMediaPlayer) + { + int result = libvlc_audio_set_volume(gLibVLCMediaPlayer, (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 ) @@ -388,11 +414,9 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) } else if (message_name == "set_volume") { - if (gLibVLCMediaPlayer) - { - F64 volume = message_in.getValueReal("volume"); - libvlc_audio_set_volume(gLibVLCMediaPlayer, (int)(volume * 100)); - } + // volume comes in 0 -> 1.0 + F64 volume = message_in.getValueReal("volume"); + setVolume(volume); } } } -- cgit v1.2.3 From 8a25489591d6f7c6c8aa95c98bbdcfe06d075c00 Mon Sep 17 00:00:00 2001 From: Callum Linden Date: Wed, 20 Jul 2016 19:54:54 -0700 Subject: MAINT-6578 Broken texture batching - fixed along with misc LibVLC plugin additions (status, titles, looping) --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 635 +++++++++++++-------- 1 file changed, 402 insertions(+), 233 deletions(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 8ef4ee2a27..f2e8252d3a 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -1,30 +1,30 @@ /** - * @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 - */ +* @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" @@ -40,61 +40,78 @@ //////////////////////////////////////////////////////////////////////////////// // class MediaPluginLibVLC : - public MediaPluginBase + public MediaPluginBase { - public: - MediaPluginLibVLC( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ); - ~MediaPluginLibVLC(); +public: + MediaPluginLibVLC(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + ~MediaPluginLibVLC(); - /*virtual*/ void receiveMessage( const char* message_string ); + /*virtual*/ void receiveMessage(const char* message_string); - private: - bool init(); +private: + bool init(); - void initVLC(); - void playMedia(); - void resetVLC(); - void setVolume(const F64 volume); + 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); + 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); - libvlc_instance_t* gLibVLC; - libvlc_media_t* gLibVLCMedia; - libvlc_media_player_t* gLibVLCMediaPlayer; + /*virtual*/ void setDirty(int left, int top, int right, int bottom) override; - struct gVLCContext - { - unsigned char* texture_pixels; - libvlc_media_player_t* mp; - MediaPluginLibVLC* parent; - }; - struct gVLCContext gVLCCallbackContext; + 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; - std::string mURL; - F64 mCurVolume; + float mCurTime; + float mDuration; }; //////////////////////////////////////////////////////////////////////////////// // -MediaPluginLibVLC::MediaPluginLibVLC( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) : - MediaPluginBase( host_send_func, host_user_data ) +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; + mWidth = 0; + mHeight = 0; + mDepth = 4; + mPixels = 0; - gLibVLC = 0; - gLibVLCMedia = 0; - gLibVLCMediaPlayer = 0; + mLibVLC = 0; + mLibVLCMedia = 0; + mLibVLCMediaPlayer = 0; mCurVolume = 0.0; + mIsLooping = false; + + mCurTime = 0.0; + mDuration = 0.0; + mURL = std::string(); + + setStatus(STATUS_NONE); } //////////////////////////////////////////////////////////////////////////////// @@ -107,7 +124,7 @@ MediaPluginLibVLC::~MediaPluginLibVLC() // void* MediaPluginLibVLC::lock(void* data, void** p_pixels) { - struct gVLCContext* context = (gVLCContext*)data; + struct mLibVLCContext* context = (mLibVLCContext*)data; *p_pixels = context->texture_pixels; @@ -118,15 +135,16 @@ void* MediaPluginLibVLC::lock(void* data, void** p_pixels) // void MediaPluginLibVLC::unlock(void* data, void* id, void* const* raw_pixels) { - // nothing to do here for the moment. - // we can modify the raw_pixels here if we want to. + // 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 gVLCContext* context = (gVLCContext*)data; + struct mLibVLCContext* context = (mLibVLCContext*)data; context->parent->setDirty(0, 0, context->parent->mWidth, context->parent->mHeight); } @@ -138,12 +156,13 @@ 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); - gLibVLC = libvlc_new(vlc_argc, vlc_argv); + mLibVLC = libvlc_new(vlc_argc, vlc_argv); - if (!gLibVLC) + if (!mLibVLC) { // for the moment, if this fails, the plugin will fail and // the media sub-system will tell the viewer something went wrong. @@ -154,9 +173,91 @@ void MediaPluginLibVLC::initVLC() // void MediaPluginLibVLC::resetVLC() { - libvlc_media_player_stop(gLibVLCMediaPlayer); - libvlc_media_player_release(gLibVLCMediaPlayer); - libvlc_release(gLibVLC); + 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_MediaPlayerBuffering: + parent->setStatus(STATUS_BUFFERING); + 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; + } } //////////////////////////////////////////////////////////////////////////////// @@ -168,30 +269,73 @@ void MediaPluginLibVLC::playMedia() return; } - if (gLibVLCMediaPlayer) + 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_MediaPlayerBuffering, 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_player_stop(gLibVLCMediaPlayer); - libvlc_media_player_release(gLibVLCMediaPlayer); + libvlc_media_release(mLibVLCMedia); + + mLibVLCMedia = 0; } - gLibVLCMedia = libvlc_media_new_location(gLibVLC, mURL.c_str()); - if (!gLibVLCMedia) + mLibVLCMedia = libvlc_media_new_location(mLibVLC, mURL.c_str()); + if (!mLibVLCMedia) { - gLibVLCMediaPlayer = 0; + mLibVLCMediaPlayer = 0; + setStatus(STATUS_ERROR); return; } - gLibVLCMediaPlayer = libvlc_media_player_new_from_media(gLibVLCMedia); - if (!gLibVLCMediaPlayer) + mLibVLCMediaPlayer = libvlc_media_player_new_from_media(mLibVLCMedia); + if (!mLibVLCMediaPlayer) { + setStatus(STATUS_ERROR); return; } - libvlc_media_release(gLibVLCMedia); + // 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_MediaPlayerBuffering, 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); + } - gVLCCallbackContext.parent = this; - gVLCCallbackContext.texture_pixels = mPixels; - gVLCCallbackContext.mp = gLibVLCMediaPlayer; + 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 @@ -208,9 +352,24 @@ void MediaPluginLibVLC::playMedia() // it in mCurVolume and set it again here so that volume levels are correctly initialized setVolume(mCurVolume); - libvlc_video_set_callbacks(gLibVLCMediaPlayer, lock, unlock, display, &gVLCCallbackContext); - libvlc_video_set_format(gLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth); - libvlc_media_player_play(gLibVLCMediaPlayer); + setStatus(STATUS_LOADED); + + libvlc_video_set_callbacks(mLibVLCMediaPlayer, lock, unlock, display, &mLibVLCCallbackContext); + libvlc_video_set_format(mLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth); + + 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 @@ -224,15 +383,24 @@ void MediaPluginLibVLC::playMedia() 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 (gLibVLCMediaPlayer) + if (mLibVLCMediaPlayer) { - int result = libvlc_audio_set_volume(gLibVLCMediaPlayer, (int)(volume * 100)); + int result = libvlc_audio_set_volume(mLibVLCMediaPlayer, (int)(volume * 100)); if (result != 0) { // volume wasn't set but not much to be done here @@ -248,26 +416,26 @@ void MediaPluginLibVLC::setVolume(const F64 volume) //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginLibVLC::receiveMessage( const char* message_string ) +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") - { + 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; + 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); + message.setValueLLSD("versions", versions); std::ostringstream s; s << "LibVLC plugin "; @@ -277,96 +445,96 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) s << "."; s << LIBVLC_VERSION_REVISION; - message.setValue("plugin_version", s.str()); - sendMessage(message); - } - else if(message_name == "idle") - { - } - else if(message_name == "cleanup") - { + 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(gLibVLCMediaPlayer); - libvlc_media_player_release(gLibVLCMediaPlayer); - gLibVLCMediaPlayer = 0; - - mPixels = NULL; - mTextureSegmentName.clear(); - } - mSharedSegments.erase(iter); - } - else - { + } + 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 - { + } + + // 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); + } + } + 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", false); - 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; + 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); @@ -375,74 +543,75 @@ void MediaPluginLibVLC::receiveMessage( const char* message_string ) message.setValueS32("texture_width", texture_width); message.setValueS32("texture_height", texture_height); sendMessage(message); - } - else if(message_name == "load_uri") - { + } + 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") + } + } + else + if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) { - if (gLibVLCMediaPlayer) + if (message_name == "stop") { - libvlc_media_player_stop(gLibVLCMediaPlayer); + if (mLibVLCMediaPlayer) + { + libvlc_media_player_stop(mLibVLCMediaPlayer); + } } - } - else if (message_name == "start") - { - if (gLibVLCMediaPlayer) + else if (message_name == "start") { - libvlc_media_player_play(gLibVLCMediaPlayer); + if (mLibVLCMediaPlayer) + { + libvlc_media_player_play(mLibVLCMediaPlayer); + } } - } - else if (message_name == "pause") - { - if (gLibVLCMediaPlayer) + else if (message_name == "pause") { - libvlc_media_player_pause(gLibVLCMediaPlayer); + if (mLibVLCMediaPlayer) + { + libvlc_media_player_pause(mLibVLCMediaPlayer); + } + } + else if (message_name == "seek") + { + } + 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); } } - else if (message_name == "seek") - { - } - else if (message_name == "set_loop") - { - } - 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 ); + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); + message.setValue("name", "LibVLC Plugin"); + sendMessage(message); - return true; + return true; }; //////////////////////////////////////////////////////////////////////////////// // -int init_media_plugin( LLPluginInstance::sendMessageFunction host_send_func, - void* host_user_data, - LLPluginInstance::sendMessageFunction *plugin_send_func, - void **plugin_user_data ) +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; + MediaPluginLibVLC* self = new MediaPluginLibVLC(host_send_func, host_user_data); + *plugin_send_func = MediaPluginLibVLC::staticReceiveMessage; + *plugin_user_data = (void*)self; - return 0; + return 0; } -- cgit v1.2.3 From f0eab8b36ff6ffcb2e76d3e23b0cd35346cb4a3b Mon Sep 17 00:00:00 2001 From: Callum Linden Date: Thu, 21 Jul 2016 09:46:42 -0700 Subject: Add a comment about order of operation that might be important for those that follow --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index f2e8252d3a..948639f125 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -357,6 +357,8 @@ void MediaPluginLibVLC::playMedia() 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"); -- cgit v1.2.3 From befb0446c50cd950315f12d9f545d0e072e8e87b Mon Sep 17 00:00:00 2001 From: Callum Linden Date: Thu, 21 Jul 2016 15:20:00 -0700 Subject: Remove new 'buffering' state for video media - seemed like it'd be useful but it broke things --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 948639f125..9b5b51f56a 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -212,10 +212,6 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) parent->setStatus(STATUS_LOADING); break; - case libvlc_MediaPlayerBuffering: - parent->setStatus(STATUS_BUFFERING); - break; - case libvlc_MediaPlayerPlaying: parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f; parent->setStatus(STATUS_PLAYING); @@ -276,7 +272,6 @@ void MediaPluginLibVLC::playMedia() if (em) { libvlc_event_detach(em, libvlc_MediaPlayerOpening, eventCallbacks, NULL); - libvlc_event_detach(em, libvlc_MediaPlayerBuffering, 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); @@ -321,7 +316,6 @@ void MediaPluginLibVLC::playMedia() if (em) { libvlc_event_attach(em, libvlc_MediaPlayerOpening, eventCallbacks, this); - libvlc_event_attach(em, libvlc_MediaPlayerBuffering, 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); -- cgit v1.2.3 From 8cd9569cefdd7877859e87a67dd93d1962328e6d Mon Sep 17 00:00:00 2001 From: Callum Linden Date: Thu, 21 Jul 2016 21:06:06 -0700 Subject: First pass at enabling time based media (videos) scrubbing controls --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 9b5b51f56a..c1e34b5c8f 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -572,6 +572,11 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string) } 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") { -- cgit v1.2.3 From 781cf7fac47812d8f779113e61fa02daa97b67fe Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 27 Jul 2016 09:53:20 -0400 Subject: remove use of "override" C++11 feature not supported on gcc 4.6 --- indra/media_plugins/libvlc/media_plugin_libvlc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/media_plugins/libvlc/media_plugin_libvlc.cpp') diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index c1e34b5c8f..0bd323eb58 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -61,7 +61,7 @@ private: 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; + /*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); -- cgit v1.2.3