diff options
Diffstat (limited to 'linden/indra')
42 files changed, 716 insertions, 599 deletions
diff --git a/linden/indra/cmake/00-Common.cmake b/linden/indra/cmake/00-Common.cmake index c41591f..27838d6 100644 --- a/linden/indra/cmake/00-Common.cmake +++ b/linden/indra/cmake/00-Common.cmake | |||
@@ -57,6 +57,21 @@ if (WINDOWS) | |||
57 | /Zc:wchar_t- | 57 | /Zc:wchar_t- |
58 | ) | 58 | ) |
59 | endif (MSVC80 OR MSVC90) | 59 | endif (MSVC80 OR MSVC90) |
60 | |||
61 | # VS optimization flags | ||
62 | if(MSVC80) | ||
63 | |||
64 | set(NUMBER_OF_CORES $ENV{NUMBER_OF_PROCESSORS}) | ||
65 | |||
66 | set(CMAKE_CXX_FLAGS_RELEASE | ||
67 | "${CMAKE_CXX_FLAGS_RELEASE} /Ob2 /Oi /Ot /GT" | ||
68 | CACHE STRING "C++ compiler release options" FORCE) | ||
69 | |||
70 | add_definitions( | ||
71 | /MP${NUMBER_OF_CORES} | ||
72 | ) | ||
73 | |||
74 | endif (MSVC80) | ||
60 | 75 | ||
61 | # Are we using the crummy Visual Studio KDU build workaround? | 76 | # Are we using the crummy Visual Studio KDU build workaround? |
62 | if (NOT VS_DISABLE_FATAL_WARNINGS) | 77 | if (NOT VS_DISABLE_FATAL_WARNINGS) |
diff --git a/linden/indra/cmake/GStreamer.cmake b/linden/indra/cmake/GStreamer.cmake index b4b984d..7b380a8 100644 --- a/linden/indra/cmake/GStreamer.cmake +++ b/linden/indra/cmake/GStreamer.cmake | |||
@@ -54,10 +54,6 @@ if (WINDOWS) | |||
54 | 54 | ||
55 | else (WINDOWS) | 55 | else (WINDOWS) |
56 | 56 | ||
57 | include(FindPkgConfig) | ||
58 | |||
59 | pkg_check_modules(GSTREAMER REQUIRED gstreamer-0.10) | ||
60 | pkg_check_modules(GSTREAMER_PLUGINS_BASE REQUIRED gstreamer-plugins-base-0.10) | ||
61 | set(GSTREAMER_INCLUDE_DIRS | 57 | set(GSTREAMER_INCLUDE_DIRS |
62 | ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gstreamer-0.10 | 58 | ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gstreamer-0.10 |
63 | ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0 | 59 | ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0 |
@@ -66,9 +62,11 @@ else (WINDOWS) | |||
66 | ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2 | 62 | ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2 |
67 | ) | 63 | ) |
68 | 64 | ||
69 | # We don't need to explicitly link against gstreamer itself, because | ||
70 | # LLMediaImplGStreamer probes for the system's copy at runtime. | ||
71 | set(GSTREAMER_LIBRARIES | 65 | set(GSTREAMER_LIBRARIES |
66 | gstvideo-0.10 | ||
67 | gstaudio-0.10 | ||
68 | gstbase-0.10 | ||
69 | gstreamer-0.10 | ||
72 | gobject-2.0 | 70 | gobject-2.0 |
73 | gmodule-2.0 | 71 | gmodule-2.0 |
74 | dl | 72 | dl |
diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/audioengine.cpp index 7bb65e9..438aefc 100644 --- a/linden/indra/llaudio/audioengine.cpp +++ b/linden/indra/llaudio/audioengine.cpp | |||
@@ -191,39 +191,43 @@ void LLAudioEngine::startInternetStream(const std::string& url) | |||
191 | if (mgr) | 191 | if (mgr) |
192 | { | 192 | { |
193 | mInternetStreamMedia = mgr->createSourceFromMimeType(LLURI(url).scheme(), "audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis. | 193 | mInternetStreamMedia = mgr->createSourceFromMimeType(LLURI(url).scheme(), "audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis. |
194 | //LL_INFOS("AudioEngine") << "mInternetStreamMedia is now " << mInternetStreamMedia << llendl; | 194 | LL_INFOS("AudioEngine") << "mInternetStreamMedia is now " << mInternetStreamMedia << llendl; |
195 | } | 195 | } |
196 | } | 196 | } |
197 | 197 | ||
198 | if(!mInternetStreamMedia) | 198 | if(!mInternetStreamMedia) |
199 | { | ||
199 | return; | 200 | return; |
200 | 201 | } | |
201 | // Check for a dead stream, just in case | 202 | // Check for a dead stream from gstreamer, just in case |
202 | if(getStatus() == LLMediaBase::STATUS_DEAD) | 203 | else if(getStatus() == LLMediaBase::STATUS_DEAD) |
203 | { | 204 | { |
204 | LL_INFOS("AudioEngine") << "don't play dead stream urls"<< llendl; | 205 | LL_INFOS("AudioEngine") << "don't play dead stream urls"<< llendl; |
205 | mInternetStreamURL.clear(); | 206 | mInternetStreamURL.clear(); |
206 | mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP); | 207 | mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP); |
207 | mInternetStreamMedia->updateMedia(); | 208 | mInternetStreamMedia->updateMedia(); |
208 | stopInternetStream(); | 209 | stopInternetStream(); |
209 | return; | ||
210 | } | 210 | } |
211 | 211 | else if (url.empty()) | |
212 | if (!url.empty()) | ||
213 | { | 212 | { |
214 | LL_INFOS("AudioEngine") << "Starting internet stream: " << url << llendl; | 213 | LL_INFOS("AudioEngine") << "url is emptly. Setting stream to NULL"<< llendl; |
215 | mInternetStreamURL = url; | 214 | mInternetStreamURL.clear(); |
216 | mInternetStreamMedia->navigateTo ( url ); | 215 | mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP); |
217 | LL_INFOS("AudioEngine") << "Playing....." << llendl; | ||
218 | mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START); | ||
219 | mInternetStreamMedia->updateMedia(); | 216 | mInternetStreamMedia->updateMedia(); |
220 | } | 217 | } |
218 | // Stream appears to be good, attempting to play | ||
221 | else | 219 | else |
222 | { | 220 | { |
223 | LL_INFOS("AudioEngine") << "setting stream to NULL"<< llendl; | 221 | // stop any other stream first |
224 | mInternetStreamURL.clear(); | 222 | stopInternetStream(); |
225 | mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP); | 223 | |
224 | LL_INFOS("AudioEngine") << "Starting internet stream: " << url << llendl; | ||
225 | mInternetStreamURL = url; | ||
226 | mInternetStreamMedia->navigateTo(url); | ||
227 | //LL_INFOS("AudioEngine") << "Playing....." << llendl; | ||
228 | mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START); | ||
226 | mInternetStreamMedia->updateMedia(); | 229 | mInternetStreamMedia->updateMedia(); |
230 | mStatus = LLMediaBase::STATUS_STARTED; | ||
227 | } | 231 | } |
228 | } | 232 | } |
229 | 233 | ||
@@ -231,7 +235,8 @@ void LLAudioEngine::startInternetStream(const std::string& url) | |||
231 | void LLAudioEngine::stopInternetStream() | 235 | void LLAudioEngine::stopInternetStream() |
232 | { | 236 | { |
233 | LL_INFOS("AudioEngine") << "entered stopInternetStream()" << llendl; | 237 | LL_INFOS("AudioEngine") << "entered stopInternetStream()" << llendl; |
234 | 238 | mInternetStreamURL.clear(); | |
239 | |||
235 | if(mInternetStreamMedia) | 240 | if(mInternetStreamMedia) |
236 | { | 241 | { |
237 | if(!mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP)) | 242 | if(!mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP)) |
@@ -240,8 +245,6 @@ void LLAudioEngine::stopInternetStream() | |||
240 | } | 245 | } |
241 | mInternetStreamMedia->updateMedia(); | 246 | mInternetStreamMedia->updateMedia(); |
242 | } | 247 | } |
243 | |||
244 | mInternetStreamURL.clear(); | ||
245 | } | 248 | } |
246 | 249 | ||
247 | // virtual | 250 | // virtual |
@@ -879,7 +882,8 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i | |||
879 | // Create a new source (since this can't be associated with an existing source. | 882 | // Create a new source (since this can't be associated with an existing source. |
880 | //LL_INFOS("AudioEngine") << "Localized: " << audio_uuid << llendl; | 883 | //LL_INFOS("AudioEngine") << "Localized: " << audio_uuid << llendl; |
881 | 884 | ||
882 | if (mMuted) | 885 | //If we cannot hear it, dont even try to load the sound. |
886 | if (mMuted || gain == 0.0) | ||
883 | { | 887 | { |
884 | return; | 888 | return; |
885 | } | 889 | } |
diff --git a/linden/indra/llcharacter/llbvhloader.cpp b/linden/indra/llcharacter/llbvhloader.cpp index cd1f492..938f47d 100644 --- a/linden/indra/llcharacter/llbvhloader.cpp +++ b/linden/indra/llcharacter/llbvhloader.cpp | |||
@@ -1133,6 +1133,8 @@ void LLBVHLoader::optimize() | |||
1133 | 1133 | ||
1134 | F32 rot_threshold = ROTATION_KEYFRAME_THRESHOLD / llmax((F32)joint->mChildTreeMaxDepth * 0.33f, 1.f); | 1134 | F32 rot_threshold = ROTATION_KEYFRAME_THRESHOLD / llmax((F32)joint->mChildTreeMaxDepth * 0.33f, 1.f); |
1135 | 1135 | ||
1136 | double diff_max = 0; | ||
1137 | KeyVector::iterator ki_max = ki; | ||
1136 | for (; ki != joint->mKeys.end(); ++ki) | 1138 | for (; ki != joint->mKeys.end(); ++ki) |
1137 | { | 1139 | { |
1138 | if (ki_prev == ki_last_good_pos) | 1140 | if (ki_prev == ki_last_good_pos) |
@@ -1193,30 +1195,55 @@ void LLBVHLoader::optimize() | |||
1193 | F32 x_delta; | 1195 | F32 x_delta; |
1194 | F32 y_delta; | 1196 | F32 y_delta; |
1195 | F32 rot_test; | 1197 | F32 rot_test; |
1196 | 1198 | ||
1199 | // Test if the rotation has changed significantly since the very first frame. If false | ||
1200 | // for all frames, then we'll just throw out this joint's rotation entirely. | ||
1197 | x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot); | 1201 | x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot); |
1198 | y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot); | 1202 | y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot); |
1199 | rot_test = x_delta + y_delta; | 1203 | rot_test = x_delta + y_delta; |
1200 | |||
1201 | if (rot_test > ROTATION_MOTION_THRESHOLD) | 1204 | if (rot_test > ROTATION_MOTION_THRESHOLD) |
1202 | { | 1205 | { |
1203 | rot_changed = TRUE; | 1206 | rot_changed = TRUE; |
1204 | } | 1207 | } |
1205 | |||
1206 | x_delta = dist_vec(LLVector3::x_axis * interp_rot, LLVector3::x_axis * test_rot); | 1208 | x_delta = dist_vec(LLVector3::x_axis * interp_rot, LLVector3::x_axis * test_rot); |
1207 | y_delta = dist_vec(LLVector3::y_axis * interp_rot, LLVector3::y_axis * test_rot); | 1209 | y_delta = dist_vec(LLVector3::y_axis * interp_rot, LLVector3::y_axis * test_rot); |
1208 | rot_test = x_delta + y_delta; | 1210 | rot_test = x_delta + y_delta; |
1209 | 1211 | ||
1210 | if (rot_test < rot_threshold) | 1212 | // Draw a line between the last good keyframe and current. Test the distance between the last frame (current-1, i.e. ki_prev) |
1211 | { | 1213 | // and the line. If it's greater than some threshold, then it represents a significant frame and we want to include it. |
1212 | ki_prev->mIgnoreRot = TRUE; | 1214 | if (rot_test >= rot_threshold || |
1213 | numRotFramesConsidered++; | 1215 | (ki+1 == joint->mKeys.end() && numRotFramesConsidered > 2)) |
1214 | } | ||
1215 | else | ||
1216 | { | 1216 | { |
1217 | // Add the current test keyframe (which is technically the previous key, i.e. ki_prev). | ||
1217 | numRotFramesConsidered = 2; | 1218 | numRotFramesConsidered = 2; |
1218 | ki_last_good_rot = ki_prev; | 1219 | ki_last_good_rot = ki_prev; |
1219 | joint->mNumRotKeys++; | 1220 | joint->mNumRotKeys++; |
1221 | |||
1222 | // Add another keyframe between the last good keyframe and current, at whatever point was the most "significant" (i.e. | ||
1223 | // had the largest deviation from the earlier tests). Note that a more robust approach would be test all intermediate | ||
1224 | // keyframes against the line between the last good keyframe and current, but we're settling for this other method | ||
1225 | // because it's significantly faster. | ||
1226 | if (diff_max > 0) | ||
1227 | { | ||
1228 | if (ki_max->mIgnoreRot == TRUE) | ||
1229 | { | ||
1230 | ki_max->mIgnoreRot = FALSE; | ||
1231 | joint->mNumRotKeys++; | ||
1232 | } | ||
1233 | diff_max = 0; | ||
1234 | } | ||
1235 | } | ||
1236 | else | ||
1237 | { | ||
1238 | // This keyframe isn't significant enough, throw it away. | ||
1239 | ki_prev->mIgnoreRot = TRUE; | ||
1240 | numRotFramesConsidered++; | ||
1241 | // Store away the keyframe that has the largest deviation from the interpolated line, for insertion later. | ||
1242 | if (rot_test > diff_max) | ||
1243 | { | ||
1244 | diff_max = rot_test; | ||
1245 | ki_max = ki; | ||
1246 | } | ||
1220 | } | 1247 | } |
1221 | } | 1248 | } |
1222 | 1249 | ||
diff --git a/linden/indra/llimagej2coj/llimagej2coj.cpp b/linden/indra/llimagej2coj/llimagej2coj.cpp index 983241c..a0c61d8 100644 --- a/linden/indra/llimagej2coj/llimagej2coj.cpp +++ b/linden/indra/llimagej2coj/llimagej2coj.cpp | |||
@@ -151,9 +151,11 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod | |||
151 | // dereference the array. | 151 | // dereference the array. |
152 | if(!image || !image->numcomps) | 152 | if(!image || !image->numcomps) |
153 | { | 153 | { |
154 | fprintf(stderr, "ERROR -> decodeImpl: failed to decode image!\n"); | 154 | llwarns << "ERROR -> decodeImpl: failed to decode image!" << llendl; |
155 | if (image) | 155 | if (image) |
156 | { | ||
156 | opj_image_destroy(image); | 157 | opj_image_destroy(image); |
158 | } | ||
157 | 159 | ||
158 | return TRUE; // done | 160 | return TRUE; // done |
159 | } | 161 | } |
@@ -169,6 +171,17 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod | |||
169 | return TRUE; | 171 | return TRUE; |
170 | } | 172 | } |
171 | } | 173 | } |
174 | |||
175 | if(image->numcomps <= first_channel) | ||
176 | { | ||
177 | llwarns << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << llendl; | ||
178 | if (image) | ||
179 | { | ||
180 | opj_image_destroy(image); | ||
181 | } | ||
182 | |||
183 | return TRUE; | ||
184 | } | ||
172 | 185 | ||
173 | // Copy image data into our raw image format (instead of the separate channel format | 186 | // Copy image data into our raw image format (instead of the separate channel format |
174 | 187 | ||
@@ -211,7 +224,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod | |||
211 | } | 224 | } |
212 | else // Some rare OpenJPEG versions have this bug. | 225 | else // Some rare OpenJPEG versions have this bug. |
213 | { | 226 | { |
214 | fprintf(stderr, "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)\n"); | 227 | llwarns << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << llendl; |
215 | opj_image_destroy(image); | 228 | opj_image_destroy(image); |
216 | 229 | ||
217 | return TRUE; // done | 230 | return TRUE; // done |
@@ -430,7 +443,7 @@ BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base) | |||
430 | 443 | ||
431 | if(!image) | 444 | if(!image) |
432 | { | 445 | { |
433 | fprintf(stderr, "ERROR -> getMetadata: failed to decode image!\n"); | 446 | llwarns << "ERROR -> getMetadata: failed to decode image!" << llendl; |
434 | return FALSE; | 447 | return FALSE; |
435 | } | 448 | } |
436 | 449 | ||
diff --git a/linden/indra/llmedia/CMakeLists.txt b/linden/indra/llmedia/CMakeLists.txt index 026afc1..0e5b261 100644 --- a/linden/indra/llmedia/CMakeLists.txt +++ b/linden/indra/llmedia/CMakeLists.txt | |||
@@ -30,8 +30,8 @@ set(llmedia_SOURCE_FILES | |||
30 | llmediaimplfactory.cpp | 30 | llmediaimplfactory.cpp |
31 | llmediamanager.cpp | 31 | llmediamanager.cpp |
32 | llmediaimplgstreamer.cpp | 32 | llmediaimplgstreamer.cpp |
33 | llmediaimplgstreamer_syms.cpp | ||
34 | llmediaimplgstreamervidplug.cpp | 33 | llmediaimplgstreamervidplug.cpp |
34 | llgstplaythread.cpp | ||
35 | ) | 35 | ) |
36 | 36 | ||
37 | set(llmedia_HEADER_FILES | 37 | set(llmedia_HEADER_FILES |
@@ -48,7 +48,7 @@ set(llmedia_HEADER_FILES | |||
48 | llmediaobserver.h | 48 | llmediaobserver.h |
49 | llmediaimplgstreamer.h | 49 | llmediaimplgstreamer.h |
50 | llmediaimplgstreamervidplug.h | 50 | llmediaimplgstreamervidplug.h |
51 | llmediaimplgstreamer_syms.h | 51 | llgstplaythread.h |
52 | ) | 52 | ) |
53 | 53 | ||
54 | # Work around a bad interaction between broken gstreamer headers and | 54 | # Work around a bad interaction between broken gstreamer headers and |
diff --git a/linden/indra/llmedia/llgstplaythread.cpp b/linden/indra/llmedia/llgstplaythread.cpp new file mode 100644 index 0000000..152f9d9 --- /dev/null +++ b/linden/indra/llmedia/llgstplaythread.cpp | |||
@@ -0,0 +1,54 @@ | |||
1 | /** | ||
2 | * @file llgstplaythread.cpp | ||
3 | * @author Jacek Antonelli | ||
4 | * @brief GStreamer playback management thread class | ||
5 | * | ||
6 | * $LicenseInfo:firstyear=2009&license=viewergpl$ | ||
7 | * | ||
8 | * Copyright (c) 2009, Jacek Antonelli | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of version 2 of the GNU General Public | ||
12 | * License as published by the Free Software Foundation. Terms of | ||
13 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
14 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
15 | * | ||
16 | * There are special exceptions to the terms and conditions of the GPL as | ||
17 | * it is applied to this Source Code. View the full text of the exception | ||
18 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
19 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License along | ||
27 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
28 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
29 | * | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #include "llgstplaythread.h" | ||
34 | #include "llmediaimplgstreamer.h" | ||
35 | |||
36 | LLGstPlayThread:: | ||
37 | LLGstPlayThread( LLMediaImplCommon *impl, | ||
38 | const std::string& name, apr_pool_t *poolp ): | ||
39 | LLThread( name, poolp ), | ||
40 | mMediaImpl( impl ) | ||
41 | { | ||
42 | } | ||
43 | |||
44 | |||
45 | LLGstPlayThread::~LLGstPlayThread() | ||
46 | { | ||
47 | } | ||
48 | |||
49 | |||
50 | // virtual | ||
51 | void LLGstPlayThread::run() | ||
52 | { | ||
53 | ((LLMediaImplGStreamer *)mMediaImpl)->startPlay(); | ||
54 | } | ||
diff --git a/linden/indra/llmedia/llgstplaythread.h b/linden/indra/llmedia/llgstplaythread.h new file mode 100644 index 0000000..c3c36a7 --- /dev/null +++ b/linden/indra/llmedia/llgstplaythread.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /** | ||
2 | * @file llgstplaythread.h | ||
3 | * @author Jacek Antonelli | ||
4 | * @brief GStreamer playback management thread class | ||
5 | * | ||
6 | * $LicenseInfo:firstyear=2009&license=viewergpl$ | ||
7 | * | ||
8 | * Copyright (c) 2009, Jacek Antonelli | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of version 2 of the GNU General Public | ||
12 | * License as published by the Free Software Foundation. Terms of | ||
13 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
14 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
15 | * | ||
16 | * There are special exceptions to the terms and conditions of the GPL as | ||
17 | * it is applied to this Source Code. View the full text of the exception | ||
18 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
19 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
20 | * | ||
21 | * This program is distributed in the hope that it will be useful, | ||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
24 | * GNU General Public License for more details. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License along | ||
27 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
28 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
29 | * | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | |||
34 | #ifndef LL_LLGSTPLAYTHREAD_H | ||
35 | #define LL_LLGSTPLAYTHREAD_H | ||
36 | |||
37 | #include "linden_common.h" | ||
38 | |||
39 | #include "llthread.h" | ||
40 | #include "llmediaimplcommon.h" | ||
41 | |||
42 | class LLGstPlayThread: public LLThread | ||
43 | { | ||
44 | public: | ||
45 | |||
46 | LLGstPlayThread( LLMediaImplCommon *impl, | ||
47 | const std::string& name, apr_pool_t *poolp ); | ||
48 | |||
49 | ~LLGstPlayThread(); | ||
50 | |||
51 | virtual void run(); | ||
52 | |||
53 | private: | ||
54 | |||
55 | // Actually, this will really only be an LLMediaImplGStreamer. | ||
56 | // But we have to jump through some hoops to mutual pointer-holding. | ||
57 | // There may be a better way, but I don't have the motivation to find it. | ||
58 | LLMediaImplCommon *mMediaImpl; | ||
59 | }; | ||
60 | |||
61 | |||
62 | #endif // LL_LLGSTPLAYTHREAD_H | ||
diff --git a/linden/indra/llmedia/llmediabase.h b/linden/indra/llmedia/llmediabase.h index b5b9420..bf54a22 100644 --- a/linden/indra/llmedia/llmediabase.h +++ b/linden/indra/llmedia/llmediabase.h | |||
@@ -61,6 +61,21 @@ class LLMediaBase | |||
61 | // undoes everything init() didm called by the media manager when destroying a source | 61 | // undoes everything init() didm called by the media manager when destroying a source |
62 | virtual bool reset() = 0; | 62 | virtual bool reset() = 0; |
63 | 63 | ||
64 | |||
65 | /* Mirrors GStreamer debug levels. */ | ||
66 | enum EDebugLevel { | ||
67 | DEBUG_LEVEL_NONE = 0, | ||
68 | DEBUG_LEVEL_ERROR, | ||
69 | DEBUG_LEVEL_WARNING, | ||
70 | DEBUG_LEVEL_INFO, | ||
71 | DEBUG_LEVEL_DEBUG, | ||
72 | DEBUG_LEVEL_LOG, | ||
73 | DEBUG_LEVEL_COUNT, | ||
74 | }; | ||
75 | |||
76 | /* Set the debug verbosity level. Only implemented for GStreamer. */ | ||
77 | virtual bool setDebugLevel( EDebugLevel level ) = 0; | ||
78 | |||
64 | // accessor for MIME type | 79 | // accessor for MIME type |
65 | virtual bool setMimeType( const std::string mime_type ) = 0; | 80 | virtual bool setMimeType( const std::string mime_type ) = 0; |
66 | virtual std::string getMimeType() const = 0; | 81 | virtual std::string getMimeType() const = 0; |
diff --git a/linden/indra/llmedia/llmediaimplcommon.cpp b/linden/indra/llmedia/llmediaimplcommon.cpp index abb61e1..48b3973 100644 --- a/linden/indra/llmedia/llmediaimplcommon.cpp +++ b/linden/indra/llmedia/llmediaimplcommon.cpp | |||
@@ -66,7 +66,8 @@ LLMediaImplCommon::LLMediaImplCommon() : | |||
66 | mCommand( LLMediaBase::COMMAND_NONE ), | 66 | mCommand( LLMediaBase::COMMAND_NONE ), |
67 | mStatus( LLMediaBase::STATUS_UNKNOWN ), | 67 | mStatus( LLMediaBase::STATUS_UNKNOWN ), |
68 | mVolume( 0 ), | 68 | mVolume( 0 ), |
69 | mLooping( false ) | 69 | mLooping( false ), |
70 | mDebugLevel( LLMediaBase::DEBUG_LEVEL_NONE ) | ||
70 | { | 71 | { |
71 | } | 72 | } |
72 | 73 | ||
@@ -92,6 +93,15 @@ bool LLMediaImplCommon::reset() | |||
92 | 93 | ||
93 | //////////////////////////////////////////////////////////////////////////////// | 94 | //////////////////////////////////////////////////////////////////////////////// |
94 | // virtual (derives from LLMediaBase) | 95 | // virtual (derives from LLMediaBase) |
96 | bool LLMediaImplCommon::setDebugLevel( LLMediaBase::EDebugLevel level ) | ||
97 | { | ||
98 | mDebugLevel = level; | ||
99 | |||
100 | return true; | ||
101 | } | ||
102 | |||
103 | //////////////////////////////////////////////////////////////////////////////// | ||
104 | // virtual (derives from LLMediaBase) | ||
95 | bool LLMediaImplCommon::setMimeType( const std::string mime_type ) | 105 | bool LLMediaImplCommon::setMimeType( const std::string mime_type ) |
96 | { | 106 | { |
97 | mMimeType = mime_type; | 107 | mMimeType = mime_type; |
diff --git a/linden/indra/llmedia/llmediaimplcommon.h b/linden/indra/llmedia/llmediaimplcommon.h index aa6c4d5..8a726f1 100644 --- a/linden/indra/llmedia/llmediaimplcommon.h +++ b/linden/indra/llmedia/llmediaimplcommon.h | |||
@@ -54,6 +54,7 @@ class LLMediaImplCommon : | |||
54 | // housekeeping | 54 | // housekeeping |
55 | virtual bool init(); | 55 | virtual bool init(); |
56 | virtual bool reset(); | 56 | virtual bool reset(); |
57 | virtual bool setDebugLevel( LLMediaBase::EDebugLevel level ); | ||
57 | virtual bool setMimeType( const std::string url ); | 58 | virtual bool setMimeType( const std::string url ); |
58 | virtual std::string getMimeType() const; | 59 | virtual std::string getMimeType() const; |
59 | virtual std::string getMediaURL() const; | 60 | virtual std::string getMediaURL() const; |
@@ -156,6 +157,7 @@ class LLMediaImplCommon : | |||
156 | LLMediaBase::ECommand mCommand; | 157 | LLMediaBase::ECommand mCommand; |
157 | LLMediaBase::EStatus mStatus; | 158 | LLMediaBase::EStatus mStatus; |
158 | bool mLooping; | 159 | bool mLooping; |
160 | LLMediaBase::EDebugLevel mDebugLevel; | ||
159 | }; | 161 | }; |
160 | 162 | ||
161 | #endif // LLMEDIAIMPLCOMMON_H | 163 | #endif // LLMEDIAIMPLCOMMON_H |
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.cpp b/linden/indra/llmedia/llmediaimplgstreamer.cpp index 30706f1..7ae6b02 100644 --- a/linden/indra/llmedia/llmediaimplgstreamer.cpp +++ b/linden/indra/llmedia/llmediaimplgstreamer.cpp | |||
@@ -30,23 +30,35 @@ | |||
30 | * $/LicenseInfo$ | 30 | * $/LicenseInfo$ |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include "llmediaimplgstreamer.h" | ||
34 | |||
35 | ///#if LL_GSTREAMER_ENABLED | 33 | ///#if LL_GSTREAMER_ENABLED |
36 | 34 | ||
35 | #if LL_WINDOWS | ||
36 | // GStreamer 0.10.22 - gstutils.h - conversion from 'guint64' to 'guint8'. | ||
37 | // This was an intentional change to make GStreamer more threadsafe, and | ||
38 | // is okay. Delete this bit if GStreamer ever gets more VS-friendly -- McCabe | ||
39 | #pragma warning(disable : 4244) | ||
40 | #endif | ||
41 | |||
42 | #include "linden_common.h" | ||
43 | #include "llmediaimplgstreamer.h" | ||
44 | |||
37 | extern "C" { | 45 | extern "C" { |
38 | #include <gst/gst.h> | 46 | #include <gst/gst.h> |
39 | #include <gst/gstelement.h> | 47 | #include <gst/gstelement.h> |
40 | } | 48 | } |
41 | 49 | ||
50 | #if LL_WINDOWS | ||
51 | #pragma warning(default : 4244) | ||
52 | #include <direct.h> | ||
53 | #include <stdlib.h> | ||
54 | #endif | ||
55 | |||
42 | #include "llmediamanager.h" | 56 | #include "llmediamanager.h" |
43 | #include "llmediaimplregister.h" | 57 | #include "llmediaimplregister.h" |
44 | 58 | ||
45 | #include "llmediaimplgstreamervidplug.h" | 59 | #include "llmediaimplgstreamervidplug.h" |
60 | #include "llgstplaythread.h" | ||
46 | 61 | ||
47 | #include "llmediaimplgstreamer_syms.h" | ||
48 | |||
49 | #include "llerror.h" | ||
50 | 62 | ||
51 | // register this impl with media manager factory | 63 | // register this impl with media manager factory |
52 | static LLMediaImplRegister sLLMediaImplGStreamerReg( "LLMediaImplGStreamer", new LLMediaImplGStreamerMaker() ); | 64 | static LLMediaImplRegister sLLMediaImplGStreamerReg( "LLMediaImplGStreamer", new LLMediaImplGStreamerMaker() ); |
@@ -73,7 +85,8 @@ LLMediaImplGStreamer () : | |||
73 | mPump ( NULL ), | 85 | mPump ( NULL ), |
74 | mPlaybin ( NULL ), | 86 | mPlaybin ( NULL ), |
75 | mVideoSink ( NULL ), | 87 | mVideoSink ( NULL ), |
76 | mState( GST_STATE_NULL ) | 88 | mState( GST_STATE_NULL ), |
89 | mPlayThread ( NULL ) | ||
77 | { | 90 | { |
78 | startup( NULL ); // Startup gstreamer if it hasn't been already. | 91 | startup( NULL ); // Startup gstreamer if it hasn't been already. |
79 | 92 | ||
@@ -90,7 +103,7 @@ LLMediaImplGStreamer () : | |||
90 | } | 103 | } |
91 | 104 | ||
92 | // instantiate a playbin element to do the hard work | 105 | // instantiate a playbin element to do the hard work |
93 | mPlaybin = llgst_element_factory_make ("playbin", "play"); | 106 | mPlaybin = gst_element_factory_make ("playbin", "play"); |
94 | if (!mPlaybin) | 107 | if (!mPlaybin) |
95 | { | 108 | { |
96 | // todo: cleanup pump | 109 | // todo: cleanup pump |
@@ -104,7 +117,7 @@ LLMediaImplGStreamer () : | |||
104 | 117 | ||
105 | // Plays inworld instead of in external player | 118 | // Plays inworld instead of in external player |
106 | mVideoSink = | 119 | mVideoSink = |
107 | GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); | 120 | GST_SLVIDEO(gst_element_factory_make ("private-slvideo", "slvideo")); |
108 | if (!mVideoSink) | 121 | if (!mVideoSink) |
109 | { | 122 | { |
110 | LL_WARNS("MediaImpl") << "Could not instantiate private-slvideo element." << LL_ENDL; | 123 | LL_WARNS("MediaImpl") << "Could not instantiate private-slvideo element." << LL_ENDL; |
@@ -148,7 +161,7 @@ LLMediaImplGStreamer:: | |||
148 | std::string LLMediaImplGStreamer::getVersion() | 161 | std::string LLMediaImplGStreamer::getVersion() |
149 | { | 162 | { |
150 | guint major, minor, micro, nano; | 163 | guint major, minor, micro, nano; |
151 | llgst_version(&major, &minor, µ, &nano); | 164 | gst_version(&major, &minor, µ, &nano); |
152 | std::string version = llformat("%d.%d.%d.%d",major,minor,micro,nano); | 165 | std::string version = llformat("%d.%d.%d.%d",major,minor,micro,nano); |
153 | return version; | 166 | return version; |
154 | } | 167 | } |
@@ -165,50 +178,163 @@ bool LLMediaImplGStreamer::startup (LLMediaManagerData* init_data) | |||
165 | // Init the glib type system - we need it. | 178 | // Init the glib type system - we need it. |
166 | g_type_init(); | 179 | g_type_init(); |
167 | 180 | ||
168 | // Get symbols! | 181 | set_gst_plugin_path(); |
169 | #if LL_WINDOWS | ||
170 | if (! grab_gst_syms("libgstreamer-0.10.dll", "libgstvideo-0.10.dll", "libgstaudio-0.10.dll") ) | ||
171 | { | ||
172 | LL_WARNS("MediaImpl") << "Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled." << LL_ENDL; | ||
173 | return false; | ||
174 | } | ||
175 | #else | ||
176 | if (! grab_gst_syms("libgstreamer-0.10.so.0", "libgstvideo-0.10.so.0", "libgstaudio-0.10.so.0") ) | ||
177 | { | ||
178 | LL_WARNS("MediaImpl") << "Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled." << LL_ENDL; | ||
179 | return false; | ||
180 | } | ||
181 | #endif | ||
182 | if (llgst_segtrap_set_enabled) | ||
183 | llgst_segtrap_set_enabled(FALSE); | ||
184 | else | ||
185 | { | ||
186 | LL_WARNS("MediaImpl") << "gst_segtrap_set_enabled() is not available; Automated crash-reporter may cease to function until next restart." << LL_ENDL; | ||
187 | } | ||
188 | 182 | ||
189 | // Protect against GStreamer resetting the locale, yuck. | 183 | // Protect against GStreamer resetting the locale, yuck. |
190 | static std::string saved_locale; | 184 | static std::string saved_locale; |
191 | saved_locale = setlocale(LC_ALL, NULL); | 185 | saved_locale = setlocale(LC_ALL, NULL); |
192 | if (0 == llgst_init_check(NULL, NULL, NULL)) | 186 | if (0 == gst_init_check(NULL, NULL, NULL)) |
193 | { | 187 | { |
194 | LL_WARNS("MediaImpl") << "GStreamer library failed to initialize and load standard plugins." << LL_ENDL; | 188 | LL_WARNS("MediaImpl") << "GStreamer library failed to initialize and load standard plugins." << LL_ENDL; |
195 | setlocale(LC_ALL, saved_locale.c_str() ); | 189 | setlocale(LC_ALL, saved_locale.c_str() ); |
196 | return false; | 190 | return false; |
197 | } | 191 | } |
198 | setlocale(LC_ALL, saved_locale.c_str() ); | 192 | setlocale(LC_ALL, saved_locale.c_str() ); |
199 | 193 | ||
194 | // Set up logging facilities | ||
195 | gst_debug_remove_log_function( gst_debug_log_default ); | ||
196 | gst_debug_add_log_function( gstreamer_log, NULL ); | ||
197 | |||
200 | // Init our custom plugins - only really need do this once. | 198 | // Init our custom plugins - only really need do this once. |
201 | gst_slvideo_init_class(); | 199 | gst_slvideo_init_class(); |
202 | 200 | ||
201 | |||
202 | // List the plugins GStreamer can find | ||
203 | LL_DEBUGS("MediaImpl") << "Found GStreamer plugins:" << LL_ENDL; | ||
204 | GList *list; | ||
205 | GstRegistry *registry = gst_registry_get_default(); | ||
206 | std::string loaded = ""; | ||
207 | for (list = gst_registry_get_plugin_list(registry); | ||
208 | list != NULL; | ||
209 | list = g_list_next(list)) | ||
210 | { | ||
211 | GstPlugin *list_plugin = (GstPlugin *)list->data; | ||
212 | (bool)gst_plugin_is_loaded(list_plugin) ? loaded = "Yes" : loaded = "No"; | ||
213 | LL_DEBUGS("MediaImpl") << gst_plugin_get_name(list_plugin) << ", loaded? " << loaded << LL_ENDL; | ||
214 | } | ||
215 | gst_plugin_list_free(list); | ||
216 | |||
217 | |||
203 | done_init = true; | 218 | done_init = true; |
204 | } | 219 | } |
205 | return true; | 220 | return true; |
206 | } | 221 | } |
207 | 222 | ||
208 | 223 | ||
224 | void LLMediaImplGStreamer::set_gst_plugin_path() | ||
225 | { | ||
226 | // Only needed for Windows. | ||
227 | // Linux sets in wrapper.sh, Mac sets in Info-Imprudence.plist | ||
228 | #ifdef LL_WINDOWS | ||
229 | |||
230 | char* imp_cwd; | ||
231 | |||
232 | // Get the current working directory: | ||
233 | imp_cwd = _getcwd(NULL,0); | ||
234 | |||
235 | if(imp_cwd == NULL) | ||
236 | { | ||
237 | LL_DEBUGS("MediaImpl") << "_getcwd failed, not setting GST_PLUGIN_PATH." | ||
238 | << LL_ENDL; | ||
239 | } | ||
240 | else | ||
241 | { | ||
242 | LL_DEBUGS("MediaImpl") << "Imprudence is installed at " | ||
243 | << imp_cwd << LL_ENDL; | ||
244 | |||
245 | // Grab the current path, if it's set. | ||
246 | std::string old_plugin_path = ""; | ||
247 | char *old_path = getenv("GST_PLUGIN_PATH"); | ||
248 | if(old_path == NULL) | ||
249 | { | ||
250 | LL_DEBUGS("MediaImpl") << "Did not find user-set GST_PLUGIN_PATH." | ||
251 | << LL_ENDL; | ||
252 | } | ||
253 | else | ||
254 | { | ||
255 | old_plugin_path = ";" + std::string( old_path ); | ||
256 | } | ||
257 | |||
258 | |||
259 | // Search both Imprudence and Imprudence\lib\gstreamer-plugins. | ||
260 | // If those fail, search the path the user has set, if any. | ||
261 | std::string plugin_path = | ||
262 | "GST_PLUGIN_PATH=" + | ||
263 | std::string(imp_cwd) + "\\lib\\gstreamer-plugins;" + | ||
264 | std::string(imp_cwd) + | ||
265 | old_plugin_path; | ||
266 | |||
267 | // Place GST_PLUGIN_PATH in the environment settings for imprudence.exe | ||
268 | // Returns 0 on success | ||
269 | if(_putenv( (char*)plugin_path.c_str() )) | ||
270 | { | ||
271 | LL_WARNS("MediaImpl") << "Setting environment variable failed!" << LL_ENDL; | ||
272 | } | ||
273 | else | ||
274 | { | ||
275 | LL_DEBUGS("MediaImpl") << "GST_PLUGIN_PATH set to " | ||
276 | << getenv("GST_PLUGIN_PATH") << LL_ENDL; | ||
277 | } | ||
278 | } | ||
279 | |||
280 | #endif //LL_WINDOWS | ||
281 | } | ||
282 | |||
283 | |||
284 | void LLMediaImplGStreamer::gstreamer_log(GstDebugCategory *category, | ||
285 | GstDebugLevel level, | ||
286 | const gchar *file, | ||
287 | const gchar *function, | ||
288 | gint line, | ||
289 | GObject *object, | ||
290 | GstDebugMessage *message, | ||
291 | gpointer data) | ||
292 | { | ||
293 | std::stringstream log(std::stringstream::out); | ||
294 | |||
295 | // Log format example: | ||
296 | // | ||
297 | // GST_ELEMENT_PADS: removing pad 'sink' (in gstelement.c:757:gst_element_remove_pad) | ||
298 | // | ||
299 | log << gst_debug_category_get_name( category ) << ": " | ||
300 | << gst_debug_message_get(message) << " " | ||
301 | << "(in " << file << ":" << line << ":" << function << ")"; | ||
302 | |||
303 | switch( level ) | ||
304 | { | ||
305 | case GST_LEVEL_ERROR: | ||
306 | LL_ERRS("MediaImpl") << log.str() << LL_ENDL; | ||
307 | break; | ||
308 | case GST_LEVEL_WARNING: | ||
309 | LL_WARNS("MediaImpl") << log.str() << LL_ENDL; | ||
310 | break; | ||
311 | case GST_LEVEL_DEBUG: | ||
312 | LL_DEBUGS("MediaImpl") << log.str() << LL_ENDL; | ||
313 | break; | ||
314 | case GST_LEVEL_INFO: | ||
315 | LL_INFOS("MediaImpl") << log.str() << LL_ENDL; | ||
316 | break; | ||
317 | default: | ||
318 | // Do nothing. | ||
319 | break; | ||
320 | } | ||
321 | } | ||
322 | |||
323 | |||
209 | bool LLMediaImplGStreamer::closedown() | 324 | bool LLMediaImplGStreamer::closedown() |
210 | { | 325 | { |
211 | ungrab_gst_syms(); | 326 | return true; |
327 | } | ||
328 | |||
329 | |||
330 | bool LLMediaImplGStreamer::setDebugLevel( LLMediaBase::EDebugLevel level ) | ||
331 | { | ||
332 | // Do parent class stuff. | ||
333 | LLMediaImplCommon::setDebugLevel(level); | ||
334 | |||
335 | // Set GStreamer verbosity. | ||
336 | gst_debug_set_default_threshold( (GstDebugLevel)level ); | ||
337 | |||
212 | return true; | 338 | return true; |
213 | } | 339 | } |
214 | 340 | ||
@@ -236,7 +362,7 @@ static const char* get_gst_state_name(GstState state) | |||
236 | gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gpointer data) | 362 | gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gpointer data) |
237 | { | 363 | { |
238 | #ifdef LL_GST_REPORT_STATE_CHANGES | 364 | #ifdef LL_GST_REPORT_STATE_CHANGES |
239 | LL_DEBUGS("MediaCallback") << "Got GST message type: " << LLGST_MESSAGE_TYPE_NAME (message) << LL_ENDL; | 365 | LL_DEBUGS("MediaCallback") << "Got GST message type: " << GST_MESSAGE_TYPE_NAME (message) << LL_ENDL; |
240 | #endif | 366 | #endif |
241 | 367 | ||
242 | LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; | 368 | LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; |
@@ -245,17 +371,13 @@ gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gp | |||
245 | { | 371 | { |
246 | case GST_MESSAGE_BUFFERING: | 372 | case GST_MESSAGE_BUFFERING: |
247 | { | 373 | { |
248 | // NEEDS GST 0.10.11+ | 374 | gint percent = 0; |
249 | if (llgst_message_parse_buffering) | 375 | gst_message_parse_buffering(message, &percent); |
250 | { | ||
251 | gint percent = 0; | ||
252 | llgst_message_parse_buffering(message, &percent); | ||
253 | #ifdef LL_GST_REPORT_STATE_CHANGES | 376 | #ifdef LL_GST_REPORT_STATE_CHANGES |
254 | LL_DEBUGS("MediaBuffering") << "GST buffering: " << percent << "%%" << LL_ENDL; | 377 | LL_DEBUGS("MediaBuffering") << "GST buffering: " << percent << "%%" << LL_ENDL; |
255 | #endif | 378 | #endif |
256 | LLMediaEvent event( impl, percent ); | 379 | LLMediaEvent event( impl, percent ); |
257 | impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); | 380 | impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); |
258 | } | ||
259 | } | 381 | } |
260 | break; | 382 | break; |
261 | case GST_MESSAGE_STATE_CHANGED: | 383 | case GST_MESSAGE_STATE_CHANGED: |
@@ -263,7 +385,7 @@ gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gp | |||
263 | GstState old_state; | 385 | GstState old_state; |
264 | GstState new_state; | 386 | GstState new_state; |
265 | GstState pending_state; | 387 | GstState pending_state; |
266 | llgst_message_parse_state_changed(message, | 388 | gst_message_parse_state_changed(message, |
267 | &old_state, | 389 | &old_state, |
268 | &new_state, | 390 | &new_state, |
269 | &pending_state); | 391 | &pending_state); |
@@ -308,7 +430,7 @@ gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gp | |||
308 | GError *err = NULL; | 430 | GError *err = NULL; |
309 | gchar *debug = NULL; | 431 | gchar *debug = NULL; |
310 | 432 | ||
311 | llgst_message_parse_error (message, &err, &debug); | 433 | gst_message_parse_error (message, &err, &debug); |
312 | LL_WARNS("MediaImpl") << "GST Error: " << err->message << LL_ENDL; | 434 | LL_WARNS("MediaImpl") << "GST Error: " << err->message << LL_ENDL; |
313 | g_error_free (err); | 435 | g_error_free (err); |
314 | g_free (debug); | 436 | g_free (debug); |
@@ -320,17 +442,14 @@ gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gp | |||
320 | } | 442 | } |
321 | case GST_MESSAGE_INFO: | 443 | case GST_MESSAGE_INFO: |
322 | { | 444 | { |
323 | if (llgst_message_parse_info) | 445 | GError *err = NULL; |
324 | { | 446 | gchar *debug = NULL; |
325 | GError *err = NULL; | ||
326 | gchar *debug = NULL; | ||
327 | 447 | ||
328 | llgst_message_parse_info (message, &err, &debug); | 448 | gst_message_parse_info (message, &err, &debug); |
329 | LL_INFOS("MediaImpl") << "GST info: " << err->message | 449 | LL_INFOS("MediaImpl") << "GST info: " << err->message |
330 | << LL_ENDL; | 450 | << LL_ENDL; |
331 | g_error_free (err); | 451 | g_error_free (err); |
332 | g_free (debug); | 452 | g_free (debug); |
333 | } | ||
334 | break; | 453 | break; |
335 | } | 454 | } |
336 | case GST_MESSAGE_WARNING: | 455 | case GST_MESSAGE_WARNING: |
@@ -338,7 +457,7 @@ gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gp | |||
338 | GError *err = NULL; | 457 | GError *err = NULL; |
339 | gchar *debug = NULL; | 458 | gchar *debug = NULL; |
340 | 459 | ||
341 | llgst_message_parse_warning (message, &err, &debug); | 460 | gst_message_parse_warning (message, &err, &debug); |
342 | LL_WARNS("MediaImpl") << "GST warning: " << err->message | 461 | LL_WARNS("MediaImpl") << "GST warning: " << err->message |
343 | << LL_ENDL; | 462 | << LL_ENDL; |
344 | g_error_free (err); | 463 | g_error_free (err); |
@@ -351,10 +470,10 @@ gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gp | |||
351 | GstTagList *tag_list; | 470 | GstTagList *tag_list; |
352 | gchar *title; | 471 | gchar *title; |
353 | gchar *artist; | 472 | gchar *artist; |
354 | llgst_message_parse_tag(message, &tag_list); | 473 | gst_message_parse_tag(message, &tag_list); |
355 | gboolean hazTitle = llgst_tag_list_get_string(tag_list, | 474 | gboolean hazTitle = gst_tag_list_get_string(tag_list, |
356 | GST_TAG_TITLE, &title); | 475 | GST_TAG_TITLE, &title); |
357 | gboolean hazArtist = llgst_tag_list_get_string(tag_list, | 476 | gboolean hazArtist = gst_tag_list_get_string(tag_list, |
358 | GST_TAG_ARTIST, &artist); | 477 | GST_TAG_ARTIST, &artist); |
359 | if(hazTitle) | 478 | if(hazTitle) |
360 | LL_INFOS("MediaInfo") << "Title: " << title << LL_ENDL; | 479 | LL_INFOS("MediaInfo") << "Title: " << title << LL_ENDL; |
@@ -408,13 +527,13 @@ bool LLMediaImplGStreamer::navigateTo (const std::string urlIn) | |||
408 | g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); | 527 | g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); |
409 | 528 | ||
410 | // get playbin's bus - perhaps this can/should be done in ctor | 529 | // get playbin's bus - perhaps this can/should be done in ctor |
411 | GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); | 530 | GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); |
412 | if (!bus) | 531 | if (!bus) |
413 | { | 532 | { |
414 | return false; | 533 | return false; |
415 | } | 534 | } |
416 | llgst_bus_add_watch (bus, bus_callback, this); | 535 | gst_bus_add_watch (bus, bus_callback, this); |
417 | llgst_object_unref (bus); | 536 | gst_object_unref (bus); |
418 | 537 | ||
419 | mState = GST_STATE_READY; | 538 | mState = GST_STATE_READY; |
420 | 539 | ||
@@ -431,9 +550,9 @@ bool LLMediaImplGStreamer::unload() | |||
431 | LL_DEBUGS("MediaImpl") << "unloading media..." << LL_ENDL; | 550 | LL_DEBUGS("MediaImpl") << "unloading media..." << LL_ENDL; |
432 | if (mPlaybin) | 551 | if (mPlaybin) |
433 | { | 552 | { |
434 | llgst_element_set_state (mPlaybin, GST_STATE_NULL); | 553 | gst_element_set_state (mPlaybin, GST_STATE_NULL); |
435 | mState = GST_STATE_NULL; | 554 | mState = GST_STATE_NULL; |
436 | llgst_object_unref (GST_OBJECT (mPlaybin)); | 555 | gst_object_unref (GST_OBJECT (mPlaybin)); |
437 | mPlaybin = NULL; | 556 | mPlaybin = NULL; |
438 | } | 557 | } |
439 | 558 | ||
@@ -591,20 +710,23 @@ bool LLMediaImplGStreamer::stop() | |||
591 | if (!mPlaybin || mState == GST_STATE_NULL) | 710 | if (!mPlaybin || mState == GST_STATE_NULL) |
592 | return true; | 711 | return true; |
593 | 712 | ||
594 | GstElement *pipeline = (GstElement *)llgst_object_ref(GST_OBJECT(mPlaybin)); | 713 | GstStateChangeReturn state_change; |
595 | llgst_object_unref(pipeline); | ||
596 | |||
597 | llgst_element_set_state(pipeline, GST_STATE_READY); | ||
598 | 714 | ||
599 | if (mState == GST_STATE_PLAYING) | 715 | state_change = gst_element_set_state(mPlaybin, GST_STATE_READY); |
600 | mState = GST_STATE_VOID_PENDING; | ||
601 | else | ||
602 | mState = GST_STATE_READY; | ||
603 | 716 | ||
604 | GstStateChangeReturn state_change = llgst_element_get_state(mPlaybin, NULL, NULL, GST_CLOCK_TIME_NONE); | 717 | LL_DEBUGS("MediaImpl") << gst_element_state_change_return_get_name(state_change) << LL_ENDL; |
605 | LL_DEBUGS("MediaImpl") << "get_state: " << llgst_element_state_change_return_get_name(state_change) << LL_ENDL; | ||
606 | 718 | ||
607 | return true; | 719 | if (state_change == GST_STATE_CHANGE_FAILURE) |
720 | { | ||
721 | LL_WARNS("MediaImpl") << "could not stop stream!" << LL_ENDL; | ||
722 | return false; | ||
723 | } | ||
724 | else | ||
725 | { | ||
726 | // Going into pending after play keeps dead streams from looping | ||
727 | (mState == GST_STATE_PLAYING) ? (mState = GST_STATE_VOID_PENDING) : (mState = GST_STATE_READY); | ||
728 | return true; | ||
729 | } | ||
608 | } | 730 | } |
609 | 731 | ||
610 | /////////////////////////////////////////////////////////////////////////////// | 732 | /////////////////////////////////////////////////////////////////////////////// |
@@ -616,25 +738,47 @@ bool LLMediaImplGStreamer::play() | |||
616 | if (!mPlaybin || mState == GST_STATE_NULL) | 738 | if (!mPlaybin || mState == GST_STATE_NULL) |
617 | return true; | 739 | return true; |
618 | 740 | ||
619 | GstElement *pipeline = (GstElement *)llgst_object_ref(GST_OBJECT(mPlaybin)); | 741 | // Clean up the existing thread, if any. |
620 | llgst_object_unref(pipeline); | 742 | if( mPlayThread != NULL && mPlayThread->isStopped()) |
743 | { | ||
744 | delete mPlayThread; | ||
745 | mPlayThread = NULL; | ||
746 | } | ||
747 | |||
748 | if( mPlayThread == NULL ) | ||
749 | { | ||
750 | // Make a new thread to start playing. This keeps the viewer | ||
751 | // responsive while the stream is resolved and buffered. | ||
752 | mPlayThread = new LLGstPlayThread( (LLMediaImplCommon *)this, "GstPlayThread", NULL); | ||
753 | mPlayThread->start(); | ||
754 | } | ||
755 | |||
756 | return true; | ||
757 | } | ||
758 | |||
759 | |||
760 | void LLMediaImplGStreamer::startPlay() | ||
761 | { | ||
762 | GstElement *pipeline = (GstElement *)gst_object_ref(GST_OBJECT(mPlaybin)); | ||
763 | gst_object_unref(pipeline); | ||
621 | 764 | ||
622 | llgst_element_set_state(pipeline, GST_STATE_PLAYING); | 765 | GstStateChangeReturn state_change; |
766 | |||
767 | state_change = gst_element_set_state(mPlaybin, GST_STATE_PLAYING); | ||
623 | mState = GST_STATE_PLAYING; | 768 | mState = GST_STATE_PLAYING; |
624 | /*llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); | ||
625 | mState = GST_STATE_PLAYING;*/ | ||
626 | 769 | ||
627 | GstStateChangeReturn state_change = llgst_element_get_state(mPlaybin, NULL, NULL, GST_CLOCK_TIME_NONE); | 770 | LL_DEBUGS("MediaImpl") << gst_element_state_change_return_get_name(state_change) << LL_ENDL; |
628 | LL_DEBUGS("MediaImpl") << "get_state: " << llgst_element_state_change_return_get_name(state_change) << LL_ENDL; | ||
629 | 771 | ||
630 | // Check to make sure playing was successful. If not, stop. | 772 | // Check to make sure playing was successful. If not, stop. |
773 | // NOTE: state_change is almost always GST_STATE_CHANGE_ASYNC | ||
631 | if (state_change == GST_STATE_CHANGE_FAILURE) | 774 | if (state_change == GST_STATE_CHANGE_FAILURE) |
632 | { | 775 | { |
633 | setStatus(LLMediaBase::STATUS_STOPPED); | 776 | // If failing from a bad stream, go into an unknown |
777 | // state to stop bus_callback from looping back. | ||
778 | // We also force a stop in case the operations don't sync | ||
779 | setStatus(LLMediaBase::STATUS_UNKNOWN); | ||
634 | stop(); | 780 | stop(); |
635 | } | 781 | } |
636 | |||
637 | return true; | ||
638 | } | 782 | } |
639 | 783 | ||
640 | /////////////////////////////////////////////////////////////////////////////// | 784 | /////////////////////////////////////////////////////////////////////////////// |
@@ -646,13 +790,22 @@ bool LLMediaImplGStreamer::pause() | |||
646 | if (!mPlaybin || mState == GST_STATE_NULL) | 790 | if (!mPlaybin || mState == GST_STATE_NULL) |
647 | return true; | 791 | return true; |
648 | 792 | ||
649 | llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); | 793 | GstStateChangeReturn state_change; |
650 | mState = GST_STATE_PAUSED; | ||
651 | |||
652 | GstStateChangeReturn state_change = llgst_element_get_state(mPlaybin, NULL, NULL, GST_CLOCK_TIME_NONE); | ||
653 | LL_DEBUGS("MediaImpl") << "get_state: " << llgst_element_state_change_return_get_name(state_change) << LL_ENDL; | ||
654 | 794 | ||
655 | return true; | 795 | state_change = gst_element_set_state(mPlaybin, GST_STATE_PAUSED); |
796 | |||
797 | LL_DEBUGS("MediaImpl") << gst_element_state_change_return_get_name(state_change) << LL_ENDL; | ||
798 | |||
799 | if (state_change == GST_STATE_CHANGE_FAILURE) | ||
800 | { | ||
801 | LL_WARNS("MediaImpl") << "could not pause stream!" << LL_ENDL; | ||
802 | return false; | ||
803 | } | ||
804 | else | ||
805 | { | ||
806 | mState = GST_STATE_PAUSED; | ||
807 | return true; | ||
808 | } | ||
656 | }; | 809 | }; |
657 | 810 | ||
658 | 811 | ||
@@ -671,7 +824,7 @@ bool LLMediaImplGStreamer::seek(double time) | |||
671 | bool success = false; | 824 | bool success = false; |
672 | if (mPlaybin) | 825 | if (mPlaybin) |
673 | { | 826 | { |
674 | success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, | 827 | success = gst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, |
675 | GstSeekFlags(GST_SEEK_FLAG_FLUSH | | 828 | GstSeekFlags(GST_SEEK_FLAG_FLUSH | |
676 | GST_SEEK_FLAG_KEY_UNIT), | 829 | GST_SEEK_FLAG_KEY_UNIT), |
677 | GST_SEEK_TYPE_SET, gint64(time*1000000000.0F), | 830 | GST_SEEK_TYPE_SET, gint64(time*1000000000.0F), |
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.h b/linden/indra/llmedia/llmediaimplgstreamer.h index dec970a..32e6bd1 100644 --- a/linden/indra/llmedia/llmediaimplgstreamer.h +++ b/linden/indra/llmedia/llmediaimplgstreamer.h | |||
@@ -48,6 +48,7 @@ extern "C" { | |||
48 | } | 48 | } |
49 | 49 | ||
50 | #include "llmediaimplgstreamervidplug.h" | 50 | #include "llmediaimplgstreamervidplug.h" |
51 | #include "llgstplaythread.h" | ||
51 | 52 | ||
52 | class LLMediaManagerData; | 53 | class LLMediaManagerData; |
53 | class LLMediaImplMaker; | 54 | class LLMediaImplMaker; |
@@ -66,6 +67,26 @@ class LLMediaImplGStreamer: | |||
66 | static bool startup( LLMediaManagerData* init_data ); | 67 | static bool startup( LLMediaManagerData* init_data ); |
67 | static bool closedown(); | 68 | static bool closedown(); |
68 | 69 | ||
70 | // Sets GST_PLUGIN_PATH env var for GStreamer. | ||
71 | static void set_gst_plugin_path(); | ||
72 | |||
73 | /* virtual */ bool setDebugLevel( LLMediaBase::EDebugLevel level ); | ||
74 | |||
75 | // Function given to GStreamer for handling debug messages | ||
76 | static void gstreamer_log(GstDebugCategory *category, | ||
77 | GstDebugLevel level, | ||
78 | const gchar *file, | ||
79 | const gchar *function, | ||
80 | gint line, | ||
81 | GObject *object, | ||
82 | GstDebugMessage *message, | ||
83 | gpointer data) | ||
84 | #if __GNUC__ | ||
85 | // recommended by the gstreamer docs | ||
86 | G_GNUC_NO_INSTRUMENT | ||
87 | #endif | ||
88 | ; | ||
89 | |||
69 | /* virtual */ std::string getVersion(); | 90 | /* virtual */ std::string getVersion(); |
70 | /* virtual */ bool navigateTo( const std::string url ); | 91 | /* virtual */ bool navigateTo( const std::string url ); |
71 | /* virtual */ bool updateMedia(); | 92 | /* virtual */ bool updateMedia(); |
@@ -76,9 +97,13 @@ class LLMediaImplGStreamer: | |||
76 | /* virtual */ bool seek( double time ); | 97 | /* virtual */ bool seek( double time ); |
77 | /* virtual */ bool setVolume( float volume ); | 98 | /* virtual */ bool setVolume( float volume ); |
78 | 99 | ||
100 | void startPlay(); | ||
101 | |||
102 | |||
79 | LLMediaEmitter< LLMediaObserver > getEventEmitter() const {return mEventEmitter;}; | 103 | LLMediaEmitter< LLMediaObserver > getEventEmitter() const {return mEventEmitter;}; |
80 | 104 | ||
81 | private: | 105 | private: |
106 | |||
82 | // misc | 107 | // misc |
83 | bool unload(); | 108 | bool unload(); |
84 | bool pause(); | 109 | bool pause(); |
@@ -100,6 +125,8 @@ class LLMediaImplGStreamer: | |||
100 | GstSLVideo *mVideoSink; | 125 | GstSLVideo *mVideoSink; |
101 | GstState mState; | 126 | GstState mState; |
102 | GstState getState() const { return mState; } | 127 | GstState getState() const { return mState; } |
128 | |||
129 | LLGstPlayThread *mPlayThread; | ||
103 | }; | 130 | }; |
104 | 131 | ||
105 | class LLMediaImplGStreamerMaker : public LLMediaImplMaker | 132 | class LLMediaImplGStreamerMaker : public LLMediaImplMaker |
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp b/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp deleted file mode 100644 index fb1949a..0000000 --- a/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp +++ /dev/null | |||
@@ -1,188 +0,0 @@ | |||
1 | /** | ||
2 | * @file llmediaimplgstreamer_syms.cpp | ||
3 | * @brief dynamic GStreamer symbol-grabbing code | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2007-2008, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | |||
32 | ///#if LL_GSTREAMER_ENABLED | ||
33 | |||
34 | extern "C" { | ||
35 | #include <gst/gst.h> | ||
36 | |||
37 | #include "apr_pools.h" | ||
38 | #include "apr_dso.h" | ||
39 | } | ||
40 | |||
41 | #include "llmediaimplgstreamer.h" | ||
42 | |||
43 | #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL | ||
44 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
45 | #include "llmediaimplgstreamer_syms_rawa.inc" | ||
46 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
47 | #undef LL_GST_SYM | ||
48 | |||
49 | |||
50 | static bool sSymsGrabbed = false; | ||
51 | static apr_pool_t *sSymGSTDSOMemoryPool = NULL; | ||
52 | static apr_dso_handle_t *sSymGSTDSOHandleG = NULL; | ||
53 | static apr_dso_handle_t *sSymGSTDSOHandleV = NULL; | ||
54 | static apr_dso_handle_t *sSymGSTDSOHandleA = NULL; | ||
55 | |||
56 | |||
57 | bool grab_gst_syms(std::string gst_dso_name, | ||
58 | std::string gst_dso_name_vid, | ||
59 | std::string gst_dso_name_aud) | ||
60 | { | ||
61 | if (sSymsGrabbed) | ||
62 | { | ||
63 | // already have grabbed good syms | ||
64 | return TRUE; | ||
65 | } | ||
66 | |||
67 | bool sym_error = false; | ||
68 | bool rtn = false; | ||
69 | apr_status_t rv; | ||
70 | apr_dso_handle_t *sSymGSTDSOHandle = NULL; | ||
71 | |||
72 | #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##GSTSYM, sSymGSTDSOHandle, #GSTSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #GSTSYM); if (REQ) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #GSTSYM, (void*)ll##GSTSYM);}while(0) | ||
73 | |||
74 | //attempt to load the shared libraries | ||
75 | apr_pool_create(&sSymGSTDSOMemoryPool, NULL); | ||
76 | |||
77 | if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, | ||
78 | gst_dso_name.c_str(), | ||
79 | sSymGSTDSOMemoryPool) )) | ||
80 | { | ||
81 | INFOMSG("Found DSO: %s", gst_dso_name.c_str()); | ||
82 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
83 | |||
84 | if ( sSymGSTDSOHandle ) | ||
85 | { | ||
86 | sSymGSTDSOHandleG = sSymGSTDSOHandle; | ||
87 | sSymGSTDSOHandle = NULL; | ||
88 | } | ||
89 | |||
90 | if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, | ||
91 | gst_dso_name_aud.c_str(), | ||
92 | sSymGSTDSOMemoryPool) )) | ||
93 | { | ||
94 | INFOMSG("Found DSO: %s", gst_dso_name_aud.c_str()); | ||
95 | #include "llmediaimplgstreamer_syms_rawa.inc" | ||
96 | |||
97 | if ( sSymGSTDSOHandle ) | ||
98 | { | ||
99 | sSymGSTDSOHandleA = sSymGSTDSOHandle; | ||
100 | sSymGSTDSOHandle = NULL; | ||
101 | } | ||
102 | |||
103 | if ( APR_SUCCESS == | ||
104 | (rv = apr_dso_load(&sSymGSTDSOHandle, | ||
105 | gst_dso_name_vid.c_str(), | ||
106 | sSymGSTDSOMemoryPool) )) | ||
107 | { | ||
108 | INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str()); | ||
109 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
110 | } | ||
111 | else | ||
112 | { | ||
113 | INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str()); | ||
114 | rtn = false; // failure | ||
115 | } | ||
116 | } | ||
117 | else | ||
118 | { | ||
119 | INFOMSG("Couldn't load DSO: %s", gst_dso_name_aud.c_str()); | ||
120 | rtn = false; // failure | ||
121 | } | ||
122 | |||
123 | rtn = !sym_error; | ||
124 | } | ||
125 | else | ||
126 | { | ||
127 | INFOMSG("Couldn't load DSO: %s", gst_dso_name.c_str()); | ||
128 | rtn = false; // failure | ||
129 | } | ||
130 | |||
131 | if (sym_error) | ||
132 | { | ||
133 | WARNMSG("Failed to find necessary symbols in GStreamer libraries."); | ||
134 | } | ||
135 | |||
136 | if ( sSymGSTDSOHandle ) | ||
137 | { | ||
138 | sSymGSTDSOHandleV = sSymGSTDSOHandle; | ||
139 | sSymGSTDSOHandle = NULL; | ||
140 | } | ||
141 | #undef LL_GST_SYM | ||
142 | |||
143 | sSymsGrabbed = !!rtn; | ||
144 | return rtn; | ||
145 | } | ||
146 | |||
147 | |||
148 | void ungrab_gst_syms() | ||
149 | { | ||
150 | // should be safe to call regardless of whether we've | ||
151 | // actually grabbed syms. | ||
152 | |||
153 | if ( sSymGSTDSOHandleG ) | ||
154 | { | ||
155 | apr_dso_unload(sSymGSTDSOHandleG); | ||
156 | sSymGSTDSOHandleG = NULL; | ||
157 | } | ||
158 | |||
159 | if ( sSymGSTDSOHandleA ) | ||
160 | { | ||
161 | apr_dso_unload(sSymGSTDSOHandleA); | ||
162 | sSymGSTDSOHandleA = NULL; | ||
163 | } | ||
164 | |||
165 | if ( sSymGSTDSOHandleV ) | ||
166 | { | ||
167 | apr_dso_unload(sSymGSTDSOHandleV); | ||
168 | sSymGSTDSOHandleV = NULL; | ||
169 | } | ||
170 | |||
171 | if ( sSymGSTDSOMemoryPool ) | ||
172 | { | ||
173 | apr_pool_destroy(sSymGSTDSOMemoryPool); | ||
174 | sSymGSTDSOMemoryPool = NULL; | ||
175 | } | ||
176 | |||
177 | // NULL-out all of the symbols we'd grabbed | ||
178 | #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0) | ||
179 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
180 | #include "llmediaimplgstreamer_syms_rawa.inc" | ||
181 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
182 | #undef LL_GST_SYM | ||
183 | |||
184 | sSymsGrabbed = false; | ||
185 | } | ||
186 | |||
187 | |||
188 | ///#endif // LL_GSTREAMER_ENABLED | ||
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms.h b/linden/indra/llmedia/llmediaimplgstreamer_syms.h deleted file mode 100644 index ebebd80..0000000 --- a/linden/indra/llmedia/llmediaimplgstreamer_syms.h +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | /** | ||
2 | * @file llmediaimplgstreamer_syms.h | ||
3 | * @brief dynamic GStreamer symbol-grabbing code | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2007-2008, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | |||
32 | #include "linden_common.h" | ||
33 | |||
34 | ///#if LL_GSTREAMER_ENABLED | ||
35 | |||
36 | extern "C" { | ||
37 | #include <gst/gst.h> | ||
38 | } | ||
39 | |||
40 | bool grab_gst_syms(std::string gst_dso_name, | ||
41 | std::string gst_dso_name_vid, | ||
42 | std::string gst_dso_name_aud); | ||
43 | void ungrab_gst_syms(); | ||
44 | |||
45 | #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__) | ||
46 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
47 | #include "llmediaimplgstreamer_syms_rawa.inc" | ||
48 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
49 | #undef LL_GST_SYM | ||
50 | |||
51 | // regrettable hacks to give us better runtime compatibility with older systems | ||
52 | #define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0) | ||
53 | #define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0) | ||
54 | |||
55 | // regrettable hacks because GStreamer was not designed for runtime loading | ||
56 | #undef GST_TYPE_MESSAGE | ||
57 | #define GST_TYPE_MESSAGE (llgst_message_get_type()) | ||
58 | #undef GST_TYPE_OBJECT | ||
59 | #define GST_TYPE_OBJECT (llgst_object_get_type()) | ||
60 | #undef GST_TYPE_PIPELINE | ||
61 | #define GST_TYPE_PIPELINE (llgst_pipeline_get_type()) | ||
62 | #undef GST_TYPE_ELEMENT | ||
63 | #define GST_TYPE_ELEMENT (llgst_element_get_type()) | ||
64 | #undef GST_TYPE_AUDIO_SINK | ||
65 | #define GST_TYPE_AUDIO_SINK (llgst_audio_sink_get_type()) | ||
66 | #undef GST_TYPE_VIDEO_SINK | ||
67 | #define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type()) | ||
68 | #undef _gst_debug_register_funcptr | ||
69 | #define _gst_debug_register_funcptr ll_gst_debug_register_funcptr | ||
70 | #undef _gst_debug_category_new | ||
71 | #define _gst_debug_category_new ll_gst_debug_category_new | ||
72 | #undef __gst_debug_enabled | ||
73 | #define __gst_debug_enabled (0) | ||
74 | |||
75 | // more hacks | ||
76 | #define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M))) | ||
77 | |||
78 | ///#endif // LL_GSTREAMER_ENABLED | ||
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc b/linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc deleted file mode 100644 index 0d0d764..0000000 --- a/linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | |||
2 | // required symbols to grab | ||
3 | LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err); | ||
4 | LL_GST_SYM(true, gst_message_get_type, GType, void); | ||
5 | LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type); | ||
6 | LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug); | ||
7 | LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug); | ||
8 | LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending); | ||
9 | LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state); | ||
10 | LL_GST_SYM(true, gst_element_get_state, GstStateChangeReturn, GstElement *element, GstState *state, GstState *pending, GstClockTime timeout); | ||
11 | LL_GST_SYM(true, gst_object_unref, void, gpointer object); | ||
12 | LL_GST_SYM(true, gst_object_ref, gpointer, gpointer object); | ||
13 | LL_GST_SYM(true, gst_object_get_type, GType, void); | ||
14 | LL_GST_SYM(true, gst_pipeline_get_type, GType, void); | ||
15 | LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline); | ||
16 | LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data); | ||
17 | LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name); | ||
18 | LL_GST_SYM(true, gst_element_get_type, GType, void); | ||
19 | LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template); | ||
20 | LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp); | ||
21 | LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details); | ||
22 | LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps); | ||
23 | LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps); | ||
24 | LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname); | ||
25 | LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description); | ||
26 | LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps); | ||
27 | LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string); | ||
28 | LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps); | ||
29 | LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index); | ||
30 | LL_GST_SYM(true, gst_caps_copy, GstCaps *, const GstCaps * caps); | ||
31 | LL_GST_SYM(true, gst_caps_intersect, GstCaps *, const GstCaps *caps1, const GstCaps *caps2); | ||
32 | LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type); | ||
33 | LL_GST_SYM(true, _gst_plugin_register_static, void, GstPluginDesc *desc); | ||
34 | LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value); | ||
35 | LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname); | ||
36 | LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value); | ||
37 | LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value); | ||
38 | LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure); | ||
39 | LL_GST_SYM(true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64); | ||
40 | LL_GST_SYM(true, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano); | ||
41 | LL_GST_SYM(true, gst_element_state_change_return_get_name, const gchar *, GstStateChangeReturn state_ret); | ||
42 | |||
43 | // optional symbols to grab | ||
44 | LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled); | ||
45 | LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent); | ||
46 | LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug); | ||
47 | |||
48 | //aw tag infos (Artist, Title, ...tbc...) | ||
49 | LL_GST_SYM(true, gst_message_parse_tag, void, GstMessage *message, GstTagList **tag_list); | ||
50 | LL_GST_SYM(true, gst_tag_list_get_string, gboolean, const GstTagList *list, const gchar *tag, gchar **value); | ||
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc b/linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc deleted file mode 100644 index 0be99b5..0000000 --- a/linden/indra/llmedia/llmediaimplgstreamer_syms_rawa.inc +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | |||
2 | // required symbols to grab | ||
3 | LL_GST_SYM(true, gst_audio_sink_get_type, GType, void); | ||
4 | |||
5 | // optional symbols to grab | ||
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc b/linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc deleted file mode 100644 index 14fbcb4..0000000 --- a/linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | |||
2 | // required symbols to grab | ||
3 | LL_GST_SYM(true, gst_video_sink_get_type, GType, void); | ||
4 | |||
5 | // optional symbols to grab | ||
diff --git a/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp b/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp index c95ef36..eaf2c84 100644 --- a/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp +++ b/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp | |||
@@ -37,8 +37,6 @@ | |||
37 | #include <gst/video/video.h> | 37 | #include <gst/video/video.h> |
38 | #include <gst/video/gstvideosink.h> | 38 | #include <gst/video/gstvideosink.h> |
39 | 39 | ||
40 | #include "llmediaimplgstreamer_syms.h" | ||
41 | |||
42 | #include "llthread.h" | 40 | #include "llthread.h" |
43 | 41 | ||
44 | #include "llmediaimplgstreamervidplug.h" | 42 | #include "llmediaimplgstreamervidplug.h" |
@@ -88,9 +86,9 @@ gst_slvideo_base_init (gpointer gclass) | |||
88 | }; | 86 | }; |
89 | GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); | 87 | GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); |
90 | 88 | ||
91 | llgst_element_class_add_pad_template (element_class, | 89 | gst_element_class_add_pad_template (element_class, |
92 | llgst_static_pad_template_get (&sink_factory)); | 90 | gst_static_pad_template_get (&sink_factory)); |
93 | llgst_element_class_set_details (element_class, &element_details); | 91 | gst_element_class_set_details (element_class, &element_details); |
94 | } | 92 | } |
95 | 93 | ||
96 | 94 | ||
@@ -101,7 +99,7 @@ gst_slvideo_finalize (GObject * object) | |||
101 | slvideo = GST_SLVIDEO (object); | 99 | slvideo = GST_SLVIDEO (object); |
102 | if (slvideo->caps) | 100 | if (slvideo->caps) |
103 | { | 101 | { |
104 | llgst_caps_unref(slvideo->caps); | 102 | gst_caps_unref(slvideo->caps); |
105 | } | 103 | } |
106 | 104 | ||
107 | G_OBJECT_CLASS(parent_class)->finalize (object); | 105 | G_OBJECT_CLASS(parent_class)->finalize (object); |
@@ -112,7 +110,7 @@ static GstFlowReturn | |||
112 | gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) | 110 | gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) |
113 | { | 111 | { |
114 | GstSLVideo *slvideo; | 112 | GstSLVideo *slvideo; |
115 | llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); | 113 | g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); |
116 | 114 | ||
117 | slvideo = GST_SLVIDEO(bsink); | 115 | slvideo = GST_SLVIDEO(bsink); |
118 | 116 | ||
@@ -205,7 +203,7 @@ gst_slvideo_get_caps (GstBaseSink * bsink) | |||
205 | GstSLVideo *slvideo; | 203 | GstSLVideo *slvideo; |
206 | slvideo = GST_SLVIDEO(bsink); | 204 | slvideo = GST_SLVIDEO(bsink); |
207 | 205 | ||
208 | return llgst_caps_ref (slvideo->caps); | 206 | return gst_caps_ref (slvideo->caps); |
209 | } | 207 | } |
210 | 208 | ||
211 | 209 | ||
@@ -221,36 +219,36 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) | |||
221 | 219 | ||
222 | filter = GST_SLVIDEO(bsink); | 220 | filter = GST_SLVIDEO(bsink); |
223 | 221 | ||
224 | intersection = llgst_caps_intersect (filter->caps, caps); | 222 | intersection = gst_caps_intersect (filter->caps, caps); |
225 | if (llgst_caps_is_empty (intersection)) | 223 | if (gst_caps_is_empty (intersection)) |
226 | { | 224 | { |
227 | // no overlap between our caps and requested caps | 225 | // no overlap between our caps and requested caps |
228 | return FALSE; | 226 | return FALSE; |
229 | } | 227 | } |
230 | llgst_caps_unref(intersection); | 228 | gst_caps_unref(intersection); |
231 | 229 | ||
232 | int width = 0; | 230 | int width = 0; |
233 | int height = 0; | 231 | int height = 0; |
234 | gboolean ret; | 232 | gboolean ret; |
235 | const GValue *fps; | 233 | const GValue *fps; |
236 | const GValue *par; | 234 | const GValue *par; |
237 | structure = llgst_caps_get_structure (caps, 0); | 235 | structure = gst_caps_get_structure (caps, 0); |
238 | ret = llgst_structure_get_int (structure, "width", &width); | 236 | ret = gst_structure_get_int (structure, "width", &width); |
239 | ret = ret && llgst_structure_get_int (structure, "height", &height); | 237 | ret = ret && gst_structure_get_int (structure, "height", &height); |
240 | fps = llgst_structure_get_value (structure, "framerate"); | 238 | fps = gst_structure_get_value (structure, "framerate"); |
241 | ret = ret && (fps != NULL); | 239 | ret = ret && (fps != NULL); |
242 | par = llgst_structure_get_value (structure, "pixel-aspect-ratio"); | 240 | par = gst_structure_get_value (structure, "pixel-aspect-ratio"); |
243 | if (!ret) | 241 | if (!ret) |
244 | return FALSE; | 242 | return FALSE; |
245 | 243 | ||
246 | filter->width = width; | 244 | filter->width = width; |
247 | filter->height = height; | 245 | filter->height = height; |
248 | filter->fps_n = llgst_value_get_fraction_numerator(fps); | 246 | filter->fps_n = gst_value_get_fraction_numerator(fps); |
249 | filter->fps_d = llgst_value_get_fraction_denominator(fps); | 247 | filter->fps_d = gst_value_get_fraction_denominator(fps); |
250 | if (par) | 248 | if (par) |
251 | { | 249 | { |
252 | filter->par_n = llgst_value_get_fraction_numerator(par); | 250 | filter->par_n = gst_value_get_fraction_numerator(par); |
253 | filter->par_d = llgst_value_get_fraction_denominator(par); | 251 | filter->par_d = gst_value_get_fraction_denominator(par); |
254 | } | 252 | } |
255 | else | 253 | else |
256 | { | 254 | { |
@@ -261,15 +259,15 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) | |||
261 | GST_VIDEO_SINK_HEIGHT(filter) = height; | 259 | GST_VIDEO_SINK_HEIGHT(filter) = height; |
262 | 260 | ||
263 | filter->format = SLV_PF_UNKNOWN; | 261 | filter->format = SLV_PF_UNKNOWN; |
264 | if (0 == strcmp(llgst_structure_get_name(structure), | 262 | if (0 == strcmp(gst_structure_get_name(structure), |
265 | "video/x-raw-rgb")) | 263 | "video/x-raw-rgb")) |
266 | { | 264 | { |
267 | int red_mask; | 265 | int red_mask; |
268 | int green_mask; | 266 | int green_mask; |
269 | int blue_mask; | 267 | int blue_mask; |
270 | llgst_structure_get_int(structure, "red_mask", &red_mask); | 268 | gst_structure_get_int(structure, "red_mask", &red_mask); |
271 | llgst_structure_get_int(structure, "green_mask", &green_mask); | 269 | gst_structure_get_int(structure, "green_mask", &green_mask); |
272 | llgst_structure_get_int(structure, "blue_mask", &blue_mask); | 270 | gst_structure_get_int(structure, "blue_mask", &blue_mask); |
273 | if ((unsigned int)red_mask == 0xFF000000 && | 271 | if ((unsigned int)red_mask == 0xFF000000 && |
274 | (unsigned int)green_mask == 0x00FF0000 && | 272 | (unsigned int)green_mask == 0x00FF0000 && |
275 | (unsigned int)blue_mask == 0x0000FF00) | 273 | (unsigned int)blue_mask == 0x0000FF00) |
@@ -366,9 +364,9 @@ gst_slvideo_update_caps (GstSLVideo * slvideo) | |||
366 | // GStreamer will automatically convert colourspace if necessary. | 364 | // GStreamer will automatically convert colourspace if necessary. |
367 | // GStreamer will automatically resize media to one of these enumerated | 365 | // GStreamer will automatically resize media to one of these enumerated |
368 | // powers-of-two that we ask for (yay GStreamer!) | 366 | // powers-of-two that we ask for (yay GStreamer!) |
369 | caps = llgst_caps_from_string (SLV_ALLCAPS); | 367 | caps = gst_caps_from_string (SLV_ALLCAPS); |
370 | 368 | ||
371 | llgst_caps_replace (&slvideo->caps, caps); | 369 | gst_caps_replace (&slvideo->caps, caps); |
372 | } | 370 | } |
373 | 371 | ||
374 | 372 | ||
@@ -401,7 +399,7 @@ static void | |||
401 | gst_slvideo_set_property (GObject * object, guint prop_id, | 399 | gst_slvideo_set_property (GObject * object, guint prop_id, |
402 | const GValue * value, GParamSpec * pspec) | 400 | const GValue * value, GParamSpec * pspec) |
403 | { | 401 | { |
404 | llg_return_if_fail (GST_IS_SLVIDEO (object)); | 402 | g_return_if_fail (GST_IS_SLVIDEO (object)); |
405 | 403 | ||
406 | if (prop_id) { | 404 | if (prop_id) { |
407 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 405 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
@@ -412,7 +410,7 @@ static void | |||
412 | gst_slvideo_get_property (GObject * object, guint prop_id, | 410 | gst_slvideo_get_property (GObject * object, guint prop_id, |
413 | GValue * value, GParamSpec * pspec) | 411 | GValue * value, GParamSpec * pspec) |
414 | { | 412 | { |
415 | llg_return_if_fail (GST_IS_SLVIDEO (object)); | 413 | g_return_if_fail (GST_IS_SLVIDEO (object)); |
416 | 414 | ||
417 | if (prop_id) { | 415 | if (prop_id) { |
418 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 416 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
@@ -433,30 +431,23 @@ plugin_init (GstPlugin * plugin) | |||
433 | GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, "private-slvideo-plugin", | 431 | GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, "private-slvideo-plugin", |
434 | 0, "Second Life Video Sink"); | 432 | 0, "Second Life Video Sink"); |
435 | 433 | ||
436 | return llgst_element_register (plugin, "private-slvideo", | 434 | return gst_element_register (plugin, "private-slvideo", |
437 | GST_RANK_NONE, GST_TYPE_SLVIDEO); | 435 | GST_RANK_NONE, GST_TYPE_SLVIDEO); |
438 | } | 436 | } |
439 | 437 | ||
440 | /* this is the structure that gstreamer looks for to register plugins | ||
441 | */ | ||
442 | /* NOTE: Can't rely upon GST_PLUGIN_DEFINE_STATIC to self-register, since | ||
443 | some g++ versions buggily avoid __attribute__((constructor)) functions - | ||
444 | so we provide an explicit plugin init function. | ||
445 | */ | ||
446 | #define PACKAGE "packagehack" | ||
447 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, | ||
448 | GST_VERSION_MINOR, | ||
449 | "private-slvideoplugin", | ||
450 | "SL Video sink plugin", | ||
451 | plugin_init, "0.1", GST_LICENSE_UNKNOWN, | ||
452 | "Second Life", | ||
453 | "http://www.secondlife.com/"); | ||
454 | #undef PACKAGE | ||
455 | 438 | ||
456 | void gst_slvideo_init_class (void) | 439 | void gst_slvideo_init_class (void) |
457 | { | 440 | { |
458 | ll_gst_plugin_register_static (&gst_plugin_desc); | 441 | gst_plugin_register_static( GST_VERSION_MAJOR, |
459 | //fprintf(stderr, "\n\n\nCLASS INIT\n\n\n"); | 442 | GST_VERSION_MINOR, |
443 | "private-slvideoplugin", | ||
444 | "SL Video sink plugin", | ||
445 | plugin_init, | ||
446 | "0.1", | ||
447 | GST_LICENSE_UNKNOWN, | ||
448 | "Second Life", | ||
449 | "Second Life", | ||
450 | "http://www.secondlife.com/" ); | ||
460 | } | 451 | } |
461 | 452 | ||
462 | ///#endif // LL_GSTREAMER_ENABLED | 453 | ///#endif // LL_GSTREAMER_ENABLED |
diff --git a/linden/indra/llmedia/llmediamanager.cpp b/linden/indra/llmedia/llmediamanager.cpp index 5394b62..7fe0df3 100644 --- a/linden/indra/llmedia/llmediamanager.cpp +++ b/linden/indra/llmedia/llmediamanager.cpp | |||
@@ -30,12 +30,24 @@ | |||
30 | */ | 30 | */ |
31 | 31 | ||
32 | #include "llmediamanager.h" | 32 | #include "llmediamanager.h" |
33 | |||
34 | #if LL_WINDOWS | ||
35 | // GStreamer 0.10.22 - gstutils.h - conversion from 'guint64' to 'guint8'. | ||
36 | // This was an intentional change to make GStreamer more threadsafe, and | ||
37 | // is okay. Delete this bit if GStreamer ever gets more VS-friendly -- McCabe | ||
38 | #pragma warning(disable : 4244) | ||
39 | #endif | ||
40 | #include "llmediaimplgstreamer.h" | ||
41 | #if LL_WINDOWS | ||
42 | #pragma warning(default : 4244) | ||
43 | #endif | ||
44 | |||
33 | #include "llmediaimplfactory.h" | 45 | #include "llmediaimplfactory.h" |
34 | 46 | ||
35 | #include "llmediaimplexample1.h" | 47 | #include "llmediaimplexample1.h" |
36 | #include "llmediaimplexample2.h" | 48 | #include "llmediaimplexample2.h" |
37 | #include "llmediaimplquicktime.h" | 49 | #include "llmediaimplquicktime.h" |
38 | #include "llmediaimplgstreamer.h" | 50 | |
39 | #if LL_LLMOZLIB_ENABLED | 51 | #if LL_LLMOZLIB_ENABLED |
40 | # include "llmediaimplllmozlib.h" | 52 | # include "llmediaimplllmozlib.h" |
41 | #endif | 53 | #endif |
diff --git a/linden/indra/llmessage/llhttpclient.cpp b/linden/indra/llmessage/llhttpclient.cpp index a07f379..8a4b063 100644 --- a/linden/indra/llmessage/llhttpclient.cpp +++ b/linden/indra/llmessage/llhttpclient.cpp | |||
@@ -160,10 +160,9 @@ namespace | |||
160 | fstream.seekg(0, std::ios::end); | 160 | fstream.seekg(0, std::ios::end); |
161 | U32 fileSize = fstream.tellg(); | 161 | U32 fileSize = fstream.tellg(); |
162 | fstream.seekg(0, std::ios::beg); | 162 | fstream.seekg(0, std::ios::beg); |
163 | char* fileBuffer; | 163 | std::vector<char> fileBuffer(fileSize); |
164 | fileBuffer = new char [fileSize]; | 164 | fstream.read(&fileBuffer[0], fileSize); |
165 | fstream.read(fileBuffer, fileSize); | 165 | ostream.write(&fileBuffer[0], fileSize); |
166 | ostream.write(fileBuffer, fileSize); | ||
167 | fstream.close(); | 166 | fstream.close(); |
168 | eos = true; | 167 | eos = true; |
169 | return STATUS_DONE; | 168 | return STATUS_DONE; |
@@ -190,10 +189,9 @@ namespace | |||
190 | 189 | ||
191 | LLVFile vfile(gVFS, mUUID, mAssetType, LLVFile::READ); | 190 | LLVFile vfile(gVFS, mUUID, mAssetType, LLVFile::READ); |
192 | S32 fileSize = vfile.getSize(); | 191 | S32 fileSize = vfile.getSize(); |
193 | U8* fileBuffer; | 192 | std::vector<U8> fileBuffer(fileSize); |
194 | fileBuffer = new U8 [fileSize]; | 193 | vfile.read(&fileBuffer[0], fileSize); |
195 | vfile.read(fileBuffer, fileSize); | 194 | ostream.write((char*)&fileBuffer[0], fileSize); |
196 | ostream.write((char*)fileBuffer, fileSize); | ||
197 | eos = true; | 195 | eos = true; |
198 | return STATUS_DONE; | 196 | return STATUS_DONE; |
199 | } | 197 | } |
diff --git a/linden/indra/llui/llfloater.cpp b/linden/indra/llui/llfloater.cpp index 9f8cd65..2f4e873 100644 --- a/linden/indra/llui/llfloater.cpp +++ b/linden/indra/llui/llfloater.cpp | |||
@@ -1580,6 +1580,7 @@ void LLFloater::updateButtons() | |||
1580 | S32 button_count = 0; | 1580 | S32 button_count = 0; |
1581 | for (S32 i = 0; i < BUTTON_COUNT; i++) | 1581 | for (S32 i = 0; i < BUTTON_COUNT; i++) |
1582 | { | 1582 | { |
1583 | if(!mButtons[i]) continue; | ||
1583 | mButtons[i]->setEnabled(mButtonsEnabled[i]); | 1584 | mButtons[i]->setEnabled(mButtonsEnabled[i]); |
1584 | 1585 | ||
1585 | if (mButtonsEnabled[i] | 1586 | if (mButtonsEnabled[i] |
diff --git a/linden/indra/newview/app_settings/keywords.ini b/linden/indra/newview/app_settings/keywords.ini index 2a911ba..56acf4c 100644 --- a/linden/indra/newview/app_settings/keywords.ini +++ b/linden/indra/newview/app_settings/keywords.ini | |||
@@ -455,6 +455,7 @@ PARCEL_FLAG_ALLOW_LANDMARK Used with llGetParcelFlags to find if a parcel allo | |||
455 | PARCEL_FLAG_ALLOW_TERRAFORM Used with llGetParcelFlags to find if a parcel allows anyone to terraform the land | 455 | PARCEL_FLAG_ALLOW_TERRAFORM Used with llGetParcelFlags to find if a parcel allows anyone to terraform the land |
456 | PARCEL_FLAG_ALLOW_DAMAGE Used with llGetParcelFlags to find if a parcel allows damage | 456 | PARCEL_FLAG_ALLOW_DAMAGE Used with llGetParcelFlags to find if a parcel allows damage |
457 | PARCEL_FLAG_ALLOW_CREATE_OBJECTS Used with llGetParcelFlags to find if a parcel allows anyone to create objects | 457 | PARCEL_FLAG_ALLOW_CREATE_OBJECTS Used with llGetParcelFlags to find if a parcel allows anyone to create objects |
458 | PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS Used with llGetParcelFlags to find if a parcel allows group members or objects to create objects | ||
458 | PARCEL_FLAG_USE_ACCESS_GROUP Used with llGetParcelFlags to find if a parcel limits access to a group | 459 | PARCEL_FLAG_USE_ACCESS_GROUP Used with llGetParcelFlags to find if a parcel limits access to a group |
459 | PARCEL_FLAG_USE_ACCESS_LIST Used with llGetParcelFlags to find if a parcel limits access to a list of residents | 460 | PARCEL_FLAG_USE_ACCESS_LIST Used with llGetParcelFlags to find if a parcel limits access to a list of residents |
460 | PARCEL_FLAG_USE_BAN_LIST Used with llGetParcelFlags to find if a parcel uses a ban list | 461 | PARCEL_FLAG_USE_BAN_LIST Used with llGetParcelFlags to find if a parcel uses a ban list |
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 0f15236..55ff208 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml | |||
@@ -4659,6 +4659,17 @@ | |||
4659 | <key>Value</key> | 4659 | <key>Value</key> |
4660 | <integer>0</integer> | 4660 | <integer>0</integer> |
4661 | </map> | 4661 | </map> |
4662 | <key>MediaDebugLevel</key> | ||
4663 | <map> | ||
4664 | <key>Comment</key> | ||
4665 | <string>How spammy media (GStreamer) debug output should be. (0-4)</string> | ||
4666 | <key>Persist</key> | ||
4667 | <integer>1</integer> | ||
4668 | <key>Type</key> | ||
4669 | <string>U32</string> | ||
4670 | <key>Value</key> | ||
4671 | <integer>0</integer> | ||
4672 | </map> | ||
4662 | <key>MemoryLogFrequency</key> | 4673 | <key>MemoryLogFrequency</key> |
4663 | <map> | 4674 | <map> |
4664 | <key>Comment</key> | 4675 | <key>Comment</key> |
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 15ce1a3..b2bfccf 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp | |||
@@ -75,9 +75,6 @@ | |||
75 | 75 | ||
76 | #if LL_WINDOWS | 76 | #if LL_WINDOWS |
77 | #include "llwindebug.h" | 77 | #include "llwindebug.h" |
78 | #include <direct.h> | ||
79 | #include <errno.h> | ||
80 | #include <stdlib.h> | ||
81 | #endif | 78 | #endif |
82 | 79 | ||
83 | #if LL_WINDOWS | 80 | #if LL_WINDOWS |
@@ -320,30 +317,6 @@ std::vector<std::string> gLoginURIs; | |||
320 | static std::string gHelperURI; | 317 | static std::string gHelperURI; |
321 | 318 | ||
322 | 319 | ||
323 | void LLAppViewer::gst_plugin_path() | ||
324 | { | ||
325 | #ifdef LL_WINDOWS | ||
326 | char* buffer; | ||
327 | |||
328 | // Get the current working directory: | ||
329 | if((buffer = _getcwd(NULL,0)) == NULL) | ||
330 | { | ||
331 | LL_INFOS("InitInfo") << "_getcwd error" << LL_ENDL; | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | LL_INFOS("InitInfo") << "Imprudence is installed at " << buffer << LL_ENDL; | ||
336 | |||
337 | std::string plugin_path = "GST_PLUGIN_PATH=" + std::string(buffer) + "\\lib\\gstreamer-plugins"; | ||
338 | |||
339 | // Place GST_PLUGIN_PATH in the environment settings for imprudence.exe | ||
340 | const char* gst_plugin_path = plugin_path.c_str(); | ||
341 | putenv(gst_plugin_path); | ||
342 | LL_INFOS("InitInfo") << "GST_PLUGIN_PATH set to " << getenv("GST_PLUGIN_PATH") << LL_ENDL; | ||
343 | } | ||
344 | #endif //LL_WINDOWS | ||
345 | } | ||
346 | |||
347 | void idle_afk_check() | 320 | void idle_afk_check() |
348 | { | 321 | { |
349 | // check idle timers | 322 | // check idle timers |
@@ -643,8 +616,6 @@ bool LLAppViewer::init() | |||
643 | LL_VERSION_PATCH, | 616 | LL_VERSION_PATCH, |
644 | LL_VERSION_BUILD ); | 617 | LL_VERSION_BUILD ); |
645 | 618 | ||
646 | gst_plugin_path(); | ||
647 | |||
648 | ////////////////////////////////////////////////////////////////////////////// | 619 | ////////////////////////////////////////////////////////////////////////////// |
649 | ////////////////////////////////////////////////////////////////////////////// | 620 | ////////////////////////////////////////////////////////////////////////////// |
650 | ////////////////////////////////////////////////////////////////////////////// | 621 | ////////////////////////////////////////////////////////////////////////////// |
diff --git a/linden/indra/newview/llappviewer.h b/linden/indra/newview/llappviewer.h index 2083a93..58dc835 100644 --- a/linden/indra/newview/llappviewer.h +++ b/linden/indra/newview/llappviewer.h | |||
@@ -138,8 +138,6 @@ public: | |||
138 | 138 | ||
139 | protected: | 139 | protected: |
140 | 140 | ||
141 | void gst_plugin_path(); // Sets GST_PLUGIN_PATH environment variable for GStreamer. | ||
142 | |||
143 | virtual bool initWindow(); // Initialize the viewer's window. | 141 | virtual bool initWindow(); // Initialize the viewer's window. |
144 | virtual bool initLogging(); // Initialize log files, logging system, return false on failure. | 142 | virtual bool initLogging(); // Initialize log files, logging system, return false on failure. |
145 | virtual void initConsole() {}; // Initialize OS level debugging console. | 143 | virtual void initConsole() {}; // Initialize OS level debugging console. |
diff --git a/linden/indra/newview/llcompilequeue.cpp b/linden/indra/newview/llcompilequeue.cpp index fc2742f..b4f1a22 100644 --- a/linden/indra/newview/llcompilequeue.cpp +++ b/linden/indra/newview/llcompilequeue.cpp | |||
@@ -59,6 +59,7 @@ | |||
59 | #include "llfloaterchat.h" | 59 | #include "llfloaterchat.h" |
60 | #include "llviewerstats.h" | 60 | #include "llviewerstats.h" |
61 | #include "lluictrlfactory.h" | 61 | #include "lluictrlfactory.h" |
62 | #include "llselectmgr.h" | ||
62 | 63 | ||
63 | ///---------------------------------------------------------------------------- | 64 | ///---------------------------------------------------------------------------- |
64 | /// Local function declarations, constants, enums, and typedefs | 65 | /// Local function declarations, constants, enums, and typedefs |
@@ -194,7 +195,20 @@ BOOL LLFloaterScriptQueue::start() | |||
194 | { | 195 | { |
195 | //llinfos << "LLFloaterCompileQueue::start()" << llendl; | 196 | //llinfos << "LLFloaterCompileQueue::start()" << llendl; |
196 | std::string buffer; | 197 | std::string buffer; |
197 | buffer = llformat("Starting %s of %d items.", mStartString.c_str(), mObjectIDs.count()); // *TODO: Translate | 198 | |
199 | LLSelectMgr *mgr = LLSelectMgr::getInstance(); | ||
200 | LLObjectSelectionHandle selectHandle = mgr->getSelection(); | ||
201 | U32 n_objects = 0; | ||
202 | if (gSavedSettings.getBOOL("EditLinkedParts")) | ||
203 | { | ||
204 | n_objects = selectHandle->getObjectCount(); | ||
205 | } | ||
206 | else | ||
207 | { | ||
208 | n_objects = selectHandle->getRootObjectCount(); | ||
209 | } | ||
210 | |||
211 | buffer = llformat("Starting %s of %d items.", mStartString.c_str(), n_objects); // *TODO: Translate | ||
198 | 212 | ||
199 | LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); | 213 | LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); |
200 | list->addCommentText(buffer); | 214 | list->addCommentText(buffer); |
diff --git a/linden/indra/newview/lldrawable.cpp b/linden/indra/newview/lldrawable.cpp index 5e4aafc..e058681 100644 --- a/linden/indra/newview/lldrawable.cpp +++ b/linden/indra/newview/lldrawable.cpp | |||
@@ -497,7 +497,7 @@ F32 LLDrawable::updateXform(BOOL undamped) | |||
497 | F32 dist_squared = 0.f; | 497 | F32 dist_squared = 0.f; |
498 | F32 camdist2 = (mDistanceWRTCamera * mDistanceWRTCamera); | 498 | F32 camdist2 = (mDistanceWRTCamera * mDistanceWRTCamera); |
499 | 499 | ||
500 | if (damped && mDistanceWRTCamera > 0.0f) | 500 | if (damped && isVisible()) |
501 | { | 501 | { |
502 | F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); | 502 | F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); |
503 | LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt); | 503 | LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt); |
@@ -521,11 +521,19 @@ F32 LLDrawable::updateXform(BOOL undamped) | |||
521 | { | 521 | { |
522 | // snap to final position | 522 | // snap to final position |
523 | dist_squared = 0.0f; | 523 | dist_squared = 0.0f; |
524 | if (!isRoot()) | ||
525 | { //child prim snapping to some position, needs a rebuild | ||
526 | gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); | ||
527 | } | ||
524 | } | 528 | } |
525 | } | 529 | } |
526 | 530 | ||
527 | if ((mCurrentScale != target_scale) || | 531 | if ((mCurrentScale != target_scale) || |
528 | (!isRoot() && (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED) || !mVObjp->getAngularVelocity().isExactlyZero())) | 532 | (!isRoot() && |
533 | (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED) || | ||
534 | !mVObjp->getAngularVelocity().isExactlyZero() || | ||
535 | target_pos != mXform.getPosition() || | ||
536 | target_rot != mXform.getRotation())) | ||
529 | { //child prim moving or scale change requires immediate rebuild | 537 | { //child prim moving or scale change requires immediate rebuild |
530 | gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); | 538 | gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); |
531 | } | 539 | } |
diff --git a/linden/indra/newview/llfilepicker.cpp b/linden/indra/newview/llfilepicker.cpp index bbcfba6..1edfbe6 100644 --- a/linden/indra/newview/llfilepicker.cpp +++ b/linden/indra/newview/llfilepicker.cpp | |||
@@ -899,12 +899,41 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) | |||
899 | // static | 899 | // static |
900 | void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data) | 900 | void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data) |
901 | { | 901 | { |
902 | LLFilePicker* picker = (LLFilePicker*) user_data; | 902 | // We need to run g_filename_to_utf8 in the user's locale |
903 | std::string old_locale(setlocale(LC_ALL, NULL)); | ||
904 | setlocale(LC_ALL, ""); | ||
905 | |||
906 | LLFilePicker* picker = (LLFilePicker*) user_data; | ||
907 | GError *error = NULL; | ||
903 | gchar* filename_utf8 = g_filename_to_utf8((gchar*)data, | 908 | gchar* filename_utf8 = g_filename_to_utf8((gchar*)data, |
904 | -1, NULL, NULL, NULL); | 909 | -1, NULL, NULL, &error); |
905 | picker->mFiles.push_back(std::string(filename_utf8)); | 910 | if (error) |
906 | lldebugs << "ADDED FILE " << filename_utf8 << llendl; | 911 | { |
907 | g_free(filename_utf8); | 912 | // This condition should really be notified to the user, e.g., |
913 | // through a message box. Just logging it is inapropriate. | ||
914 | // FIXME. | ||
915 | |||
916 | // Ghhhh. g_filename_display_name is new to glib 2.6, and it | ||
917 | // is too new for SL! (Note that the latest glib as of this | ||
918 | // writing is 2.22. *sigh*) LL supplied *makeASCII family are | ||
919 | // also unsuitable since they allow control characters... | ||
920 | |||
921 | std::string display_name; | ||
922 | for (const gchar *str = (const gchar *)data; *str; str++) | ||
923 | { | ||
924 | display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?'); | ||
925 | } | ||
926 | llwarns << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << llendl; | ||
927 | } | ||
928 | |||
929 | if (filename_utf8) | ||
930 | { | ||
931 | picker->mFiles.push_back(std::string(filename_utf8)); | ||
932 | lldebugs << "ADDED FILE " << filename_utf8 << llendl; | ||
933 | g_free(filename_utf8); | ||
934 | } | ||
935 | |||
936 | setlocale(LC_ALL, old_locale.c_str()); | ||
908 | } | 937 | } |
909 | 938 | ||
910 | // static | 939 | // static |
diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp index a626ad3..14f9a10 100644 --- a/linden/indra/newview/llfloaterchat.cpp +++ b/linden/indra/newview/llfloaterchat.cpp | |||
@@ -385,7 +385,11 @@ void LLFloaterChat::addChat(const LLChat& chat, | |||
385 | text_color = gSavedSettings.getColor("IMChatColor"); | 385 | text_color = gSavedSettings.getColor("IMChatColor"); |
386 | size = INSTANT_MSG_SIZE; | 386 | size = INSTANT_MSG_SIZE; |
387 | } | 387 | } |
388 | gConsole->addLine(chat.mText, size, text_color); | 388 | // We display anything if it's not an IM. If it's an IM, check pref... |
389 | if ( !from_instant_message || gSavedSettings.getBOOL("IMInChatHistory") ) | ||
390 | { | ||
391 | gConsole->addLine(chat.mText, size, text_color); | ||
392 | } | ||
389 | } | 393 | } |
390 | 394 | ||
391 | if(from_instant_message && gSavedPerAccountSettings.getBOOL("LogChatIM")) | 395 | if(from_instant_message && gSavedPerAccountSettings.getBOOL("LogChatIM")) |
diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp index 7a30b22..a8a3b16 100644 --- a/linden/indra/newview/llviewercontrol.cpp +++ b/linden/indra/newview/llviewercontrol.cpp | |||
@@ -70,6 +70,7 @@ | |||
70 | #include "llvosurfacepatch.h" | 70 | #include "llvosurfacepatch.h" |
71 | #include "llvowlsky.h" | 71 | #include "llvowlsky.h" |
72 | #include "llrender.h" | 72 | #include "llrender.h" |
73 | #include "llmediamanager.h" | ||
73 | 74 | ||
74 | #ifdef TOGGLE_HACKED_GODLIKE_VIEWER | 75 | #ifdef TOGGLE_HACKED_GODLIKE_VIEWER |
75 | BOOL gHackGodmode = FALSE; | 76 | BOOL gHackGodmode = FALSE; |
@@ -429,6 +430,22 @@ bool handleVoiceClientPrefsChanged(const LLSD& newvalue) | |||
429 | return true; | 430 | return true; |
430 | } | 431 | } |
431 | 432 | ||
433 | bool handleMediaDebugLevelChanged(const LLSD& newvalue) | ||
434 | { | ||
435 | LLMediaManager *mgr = LLMediaManager::getInstance(); | ||
436 | if (mgr) | ||
437 | { | ||
438 | LLMediaBase *impl = | ||
439 | mgr->createSourceFromMimeType("http", "audio/mpeg"); | ||
440 | |||
441 | if (impl) | ||
442 | { | ||
443 | impl->setDebugLevel( (LLMediaBase::EDebugLevel)newvalue.asInteger() ); | ||
444 | } | ||
445 | } | ||
446 | return true; | ||
447 | } | ||
448 | |||
432 | //////////////////////////////////////////////////////////////////////////// | 449 | //////////////////////////////////////////////////////////////////////////// |
433 | 450 | ||
434 | void settings_setup_listeners() | 451 | void settings_setup_listeners() |
@@ -556,6 +573,7 @@ void settings_setup_listeners() | |||
556 | gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); | 573 | gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); |
557 | gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); | 574 | gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); |
558 | gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); | 575 | gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1)); |
576 | gSavedSettings.getControl("MediaDebugLevel")->getSignal()->connect(boost::bind(&handleMediaDebugLevelChanged, _1)); | ||
559 | } | 577 | } |
560 | 578 | ||
561 | template <> eControlType get_control_type<U32>(const U32& in, LLSD& out) | 579 | template <> eControlType get_control_type<U32>(const U32& in, LLSD& out) |
diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp index e99c838..d8fcdcb 100644 --- a/linden/indra/newview/llviewermedia.cpp +++ b/linden/indra/newview/llviewermedia.cpp | |||
@@ -496,6 +496,13 @@ void LLViewerMedia::initClass() | |||
496 | const LLMIMETypes::LLMIMEInfo& info = it->second; | 496 | const LLMIMETypes::LLMIMEInfo& info = it->second; |
497 | mm->addMimeTypeImplNameMap( mime_type, info.mImpl ); | 497 | mm->addMimeTypeImplNameMap( mime_type, info.mImpl ); |
498 | } | 498 | } |
499 | |||
500 | LLMediaBase *impl = mm->createSourceFromMimeType("http", "audio/mpeg"); | ||
501 | if (impl) | ||
502 | { | ||
503 | U32 level = gSavedSettings.getU32("MediaDebugLevel"); | ||
504 | impl->setDebugLevel( (LLMediaBase::EDebugLevel)level ); | ||
505 | } | ||
499 | } | 506 | } |
500 | 507 | ||
501 | ////////////////////////////////////////////////////////////////////////////////////////// | 508 | ////////////////////////////////////////////////////////////////////////////////////////// |
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 31fdcc3..486e4f1 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp | |||
@@ -5963,8 +5963,9 @@ void queue_actions(LLFloaterScriptQueue* q, const std::string& noscriptmsg, cons | |||
5963 | { | 5963 | { |
5964 | // Apply until an object fails | 5964 | // Apply until an object fails |
5965 | QueueObjects func(q); | 5965 | QueueObjects func(q); |
5966 | const bool firstonly = true; | 5966 | LLSelectMgr *mgr = LLSelectMgr::getInstance(); |
5967 | bool fail = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func, firstonly); | 5967 | LLObjectSelectionHandle selectHandle = mgr->getSelection(); |
5968 | bool fail = selectHandle->applyToObjects(&func); | ||
5968 | if(fail) | 5969 | if(fail) |
5969 | { | 5970 | { |
5970 | if ( !func.scripted ) | 5971 | if ( !func.scripted ) |
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index b947f95..221de59 100644 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp | |||
@@ -3286,6 +3286,10 @@ void process_sound_trigger(LLMessageSystem *msg, void **) | |||
3286 | msg->getVector3Fast(_PREHASH_SoundData, _PREHASH_Position, pos_local); | 3286 | msg->getVector3Fast(_PREHASH_SoundData, _PREHASH_Position, pos_local); |
3287 | msg->getF32Fast(_PREHASH_SoundData, _PREHASH_Gain, gain); | 3287 | msg->getF32Fast(_PREHASH_SoundData, _PREHASH_Gain, gain); |
3288 | 3288 | ||
3289 | //If we have sounds muted, don't even try to load or trigger the sound. | ||
3290 | if(gSavedSettings.getBOOL("MuteSounds") || gain == 0.0) | ||
3291 | return; | ||
3292 | |||
3289 | // adjust sound location to true global coords | 3293 | // adjust sound location to true global coords |
3290 | LLVector3d pos_global = from_region_handle(region_handle); | 3294 | LLVector3d pos_global = from_region_handle(region_handle); |
3291 | pos_global.mdV[VX] += pos_local.mV[VX]; | 3295 | pos_global.mdV[VX] += pos_local.mV[VX]; |
@@ -3317,7 +3321,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **) | |||
3317 | 3321 | ||
3318 | void process_preload_sound(LLMessageSystem *msg, void **user_data) | 3322 | void process_preload_sound(LLMessageSystem *msg, void **user_data) |
3319 | { | 3323 | { |
3320 | if (!gAudiop) | 3324 | if (!gAudiop || gSavedSettings.getBOOL("MuteSounds")) |
3321 | { | 3325 | { |
3322 | return; | 3326 | return; |
3323 | } | 3327 | } |
@@ -3363,6 +3367,9 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data) | |||
3363 | msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain); | 3367 | msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain); |
3364 | msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags); | 3368 | msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags); |
3365 | 3369 | ||
3370 | if(gSavedSettings.getBOOL("MuteSounds") || gain == 0.0) | ||
3371 | return; | ||
3372 | |||
3366 | LLViewerObject *objectp = gObjectList.findObject(object_id); | 3373 | LLViewerObject *objectp = gObjectList.findObject(object_id); |
3367 | if (!objectp) | 3374 | if (!objectp) |
3368 | { | 3375 | { |
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index fd2487b..7d70dd2 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp | |||
@@ -3096,69 +3096,62 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) | |||
3096 | (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) | 3096 | (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) |
3097 | || is_appearance != mNameAppearance) | 3097 | || is_appearance != mNameAppearance) |
3098 | { | 3098 | { |
3099 | char line[MAX_STRING]; /* Flawfinder: ignore */ | 3099 | std::string line; |
3100 | if (!sRenderGroupTitles) | 3100 | if (title && title->getString() && title->getString()[0] != '\0') |
3101 | { | ||
3102 | // If all group titles are turned off, stack first name | ||
3103 | // on a line above last name | ||
3104 | strncpy(line, firstname->getString(), MAX_STRING -1 ); /* Flawfinder: ignore */ | ||
3105 | line[MAX_STRING -1] = '\0'; | ||
3106 | strcat(line, "\n"); | ||
3107 | } | ||
3108 | else if (title && title->getString() && title->getString()[0] != '\0') | ||
3109 | { | 3101 | { |
3110 | strncpy(line, title->getString(), MAX_STRING -1 ); /* Flawfinder: ignore */ | 3102 | line += title->getString(); |
3111 | line[MAX_STRING -1] = '\0'; | 3103 | LLStringFn::replace_nonprintable(line,LL_UNKNOWN_CHAR); |
3112 | strcat(line, "\n"); /* Flawfinder: ignore */ | 3104 | line += "\n"; |
3113 | strncat(line, firstname->getString(), MAX_STRING - strlen(line) -1 ); /* Flawfinder: ignore */ | 3105 | line += firstname->getString(); |
3114 | } | 3106 | } |
3115 | else | 3107 | else |
3116 | { | 3108 | { |
3117 | strncpy(line, firstname->getString(), MAX_STRING -1 ); /* Flawfinder: ignore */ | 3109 | line += firstname->getString(); |
3118 | line[MAX_STRING -1] = '\0'; | ||
3119 | } | 3110 | } |
3120 | 3111 | ||
3121 | strcat(line, " "); /* Flawfinder: ignore */ | 3112 | line += " "; |
3122 | strncat(line, lastname->getString(), MAX_STRING - strlen(line) -1); /* Flawfinder: ignore */ | 3113 | line += lastname->getString(); |
3123 | BOOL need_comma = FALSE; | 3114 | BOOL need_comma = FALSE; |
3124 | 3115 | ||
3125 | if (is_away || is_muted || is_busy) | 3116 | if (is_away || is_muted || is_busy) |
3126 | { | 3117 | { |
3127 | strcat(line, " ("); /* Flawfinder: ignore */ | 3118 | line += " ("; |
3128 | if (is_away) | 3119 | if (is_away) |
3129 | { | 3120 | { |
3130 | strcat(line, "Away"); /* Flawfinder: ignore */ | 3121 | line += "Away"; |
3131 | need_comma = TRUE; | 3122 | need_comma = TRUE; |
3132 | } | 3123 | } |
3133 | if (is_busy) | 3124 | if (is_busy) |
3134 | { | 3125 | { |
3135 | if (need_comma) | 3126 | if (need_comma) |
3136 | { | 3127 | { |
3137 | strcat(line, ", "); /* Flawfinder: ignore */ | 3128 | line += ", "; |
3138 | } | 3129 | } |
3139 | strcat(line, "Busy"); /* Flawfinder: ignore */ | 3130 | line += "Busy"; |
3140 | need_comma = TRUE; | 3131 | need_comma = TRUE; |
3141 | } | 3132 | } |
3142 | if (is_muted) | 3133 | if (is_muted) |
3143 | { | 3134 | { |
3144 | if (need_comma) | 3135 | if (need_comma) |
3145 | { | 3136 | { |
3146 | strcat(line, ", "); /* Flawfinder: ignore */ | 3137 | line += ", "; |
3147 | } | 3138 | } |
3148 | strcat(line, "Muted"); /* Flawfinder: ignore */ | 3139 | line += "Muted"; |
3149 | need_comma = TRUE; | 3140 | need_comma = TRUE; |
3150 | } | 3141 | } |
3151 | strcat(line,")"); /* Flawfinder: ignore */ | 3142 | line += ")"; |
3152 | } | 3143 | } |
3153 | if (is_appearance) | 3144 | if (is_appearance) |
3154 | { | 3145 | { |
3155 | strcat(line, "\n(Editing Appearance)"); /* Flawfinder: ignore */ | 3146 | line += "\n"; |
3147 | line += "(Editing Appearance)"; | ||
3156 | } | 3148 | } |
3157 | mNameAway = is_away; | 3149 | mNameAway = is_away; |
3158 | mNameBusy = is_busy; | 3150 | mNameBusy = is_busy; |
3159 | mNameMute = is_muted; | 3151 | mNameMute = is_muted; |
3160 | mNameAppearance = is_appearance; | 3152 | mNameAppearance = is_appearance; |
3161 | mTitle = title ? title->getString() : ""; | 3153 | mTitle = title ? title->getString() : ""; |
3154 | LLStringFn::replace_nonprintable(mTitle,LL_UNKNOWN_CHAR); | ||
3162 | mNameString = utf8str_to_wstring(line); | 3155 | mNameString = utf8str_to_wstring(line); |
3163 | new_name = TRUE; | 3156 | new_name = TRUE; |
3164 | } | 3157 | } |
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index 3523635..e7db166 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp | |||
@@ -2665,6 +2665,18 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render | |||
2665 | LLGLState::checkClientArrays(); | 2665 | LLGLState::checkClientArrays(); |
2666 | U32 last_type = 0; | 2666 | U32 last_type = 0; |
2667 | 2667 | ||
2668 | // If we don't do this, we crash something on changing graphics settings | ||
2669 | // from Medium -> Low, because we unload all the shaders and the | ||
2670 | // draw pools aren't aware. I don't know if this has to be a separate | ||
2671 | // loop before actual rendering. JC | ||
2672 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
2673 | { | ||
2674 | LLDrawPool *poolp = *iter; | ||
2675 | if (poolp->isFacePool() && hasRenderType(poolp->getType())) | ||
2676 | { | ||
2677 | poolp->prerender(); | ||
2678 | } | ||
2679 | } | ||
2668 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | 2680 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) |
2669 | { | 2681 | { |
2670 | LLDrawPool *poolp = *iter; | 2682 | LLDrawPool *poolp = *iter; |
diff --git a/linden/indra/newview/skins/default/xui/de/panel_media_controls.xml b/linden/indra/newview/skins/default/xui/de/panel_media_controls.xml index eb47fa2..d15d186 100644 --- a/linden/indra/newview/skins/default/xui/de/panel_media_controls.xml +++ b/linden/indra/newview/skins/default/xui/de/panel_media_controls.xml | |||
@@ -2,7 +2,6 @@ | |||
2 | <panel name="media_controls"> | 2 | <panel name="media_controls"> |
3 | <icon name="music_icon" tool_tip="Streaming-Musik abspielen/unterbrechen" /> | 3 | <icon name="music_icon" tool_tip="Streaming-Musik abspielen/unterbrechen" /> |
4 | <button name="music_play" tool_tip="Streaming-Musik spielen/unterbrechen" /> | 4 | <button name="music_play" tool_tip="Streaming-Musik spielen/unterbrechen" /> |
5 | <button name="music_pause" tool_tip="Streaming-Musik unterbrechen" /> | ||
6 | <button name="music_stop" tool_tip="Streaming-Musik beenden" /> | 5 | <button name="music_stop" tool_tip="Streaming-Musik beenden" /> |
7 | <icon name="media_icon" tool_tip="Streaming-Musik abspielen/unterbrechen" /> | 6 | <icon name="media_icon" tool_tip="Streaming-Musik abspielen/unterbrechen" /> |
8 | <button name="media_play" tool_tip="Streaming-Musik abspielen/unterbrechen" /> | 7 | <button name="media_play" tool_tip="Streaming-Musik abspielen/unterbrechen" /> |
diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml index d3174af..8020e9a 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml | |||
@@ -28,7 +28,7 @@ | |||
28 | width="350" /> | 28 | width="350" /> |
29 | <check_box bottom="-65" control_name="IMInChatHistory" enabled="true" follows="left|top" | 29 | <check_box bottom="-65" control_name="IMInChatHistory" enabled="true" follows="left|top" |
30 | font="SansSerifSmall" height="16" initial_value="false" | 30 | font="SansSerifSmall" height="16" initial_value="false" |
31 | label="Include IM in Local Chat" left="148" mouse_opaque="true" | 31 | label="Show IMs with Chat" left="148" mouse_opaque="true" |
32 | name="include_im_in_chat_history" radio_style="false" width="237" /> | 32 | name="include_im_in_chat_history" radio_style="false" width="237" /> |
33 | <check_box bottom="-85" control_name="IMShowTimestamps" enabled="true" follows="left|top" | 33 | <check_box bottom="-85" control_name="IMShowTimestamps" enabled="true" follows="left|top" |
34 | font="SansSerifSmall" height="16" initial_value="false" | 34 | font="SansSerifSmall" height="16" initial_value="false" |
diff --git a/linden/indra/newview/skins/default/xui/fr/panel_media_controls.xml b/linden/indra/newview/skins/default/xui/fr/panel_media_controls.xml index ff498ba..7b601b4 100644 --- a/linden/indra/newview/skins/default/xui/fr/panel_media_controls.xml +++ b/linden/indra/newview/skins/default/xui/fr/panel_media_controls.xml | |||
@@ -2,7 +2,6 @@ | |||
2 | <panel name="media_controls"> | 2 | <panel name="media_controls"> |
3 | <icon name="music_icon" tool_tip="Jouer/pauser le flux musical" /> | 3 | <icon name="music_icon" tool_tip="Jouer/pauser le flux musical" /> |
4 | <button name="music_play" tool_tip="Jouer/pauser le flux musical" /> | 4 | <button name="music_play" tool_tip="Jouer/pauser le flux musical" /> |
5 | <button name="music_pause" tool_tip="Pauser le flux musical" /> | ||
6 | <button name="music_stop" tool_tip="Arrêter le flux musical" /> | 5 | <button name="music_stop" tool_tip="Arrêter le flux musical" /> |
7 | <icon name="media_icon" tool_tip="Jouer/pauser le flux musical" /> | 6 | <icon name="media_icon" tool_tip="Jouer/pauser le flux musical" /> |
8 | <button name="media_play" tool_tip="Jouer/pauser le flux musical" /> | 7 | <button name="media_play" tool_tip="Jouer/pauser le flux musical" /> |
diff --git a/linden/indra/newview/skins/default/xui/ja/panel_media_controls.xml b/linden/indra/newview/skins/default/xui/ja/panel_media_controls.xml index 7c87dc3..89791a5 100644 --- a/linden/indra/newview/skins/default/xui/ja/panel_media_controls.xml +++ b/linden/indra/newview/skins/default/xui/ja/panel_media_controls.xml | |||
@@ -4,8 +4,6 @@ | |||
4 | tool_tip="ストリーミング・ミュージックの再生/一時停止" /> | 4 | tool_tip="ストリーミング・ミュージックの再生/一時停止" /> |
5 | <button name="music_play" | 5 | <button name="music_play" |
6 | tool_tip="ストリーミング・ミュージックの再生/一時停止" /> | 6 | tool_tip="ストリーミング・ミュージックの再生/一時停止" /> |
7 | <button name="music_pause" | ||
8 | tool_tip="ストリーミング・ミュージックの一時停止" /> | ||
9 | <button name="music_stop" | 7 | <button name="music_stop" |
10 | tool_tip="ストリーミング・ミュージックの停止" /> | 8 | tool_tip="ストリーミング・ミュージックの停止" /> |
11 | <icon name="media_icon" | 9 | <icon name="media_icon" |
diff --git a/linden/indra/newview/skins/default/xui/ko/panel_media_controls.xml b/linden/indra/newview/skins/default/xui/ko/panel_media_controls.xml index 3b3aa0e..fa5a010 100644 --- a/linden/indra/newview/skins/default/xui/ko/panel_media_controls.xml +++ b/linden/indra/newview/skins/default/xui/ko/panel_media_controls.xml | |||
@@ -2,7 +2,6 @@ | |||
2 | <panel name="media_controls"> | 2 | <panel name="media_controls"> |
3 | <icon name="music_icon" tool_tip="스트리밍 음악 재생/일시 정지" /> | 3 | <icon name="music_icon" tool_tip="스트리밍 음악 재생/일시 정지" /> |
4 | <button name="music_play" tool_tip="스트리밍 음악 재생/일시 정지" /> | 4 | <button name="music_play" tool_tip="스트리밍 음악 재생/일시 정지" /> |
5 | <button name="music_pause" tool_tip="스트리밍 음악 일시 정지" /> | ||
6 | <button name="music_stop" tool_tip="스트리밍 음악 중지" /> | 5 | <button name="music_stop" tool_tip="스트리밍 음악 중지" /> |
7 | <icon name="media_icon" tool_tip="스트리밍 음악 재생/일시 정지" /> | 6 | <icon name="media_icon" tool_tip="스트리밍 음악 재생/일시 정지" /> |
8 | <button name="media_play" tool_tip="스트리밍 음악 재생/일시 정지" /> | 7 | <button name="media_play" tool_tip="스트리밍 음악 재생/일시 정지" /> |
diff --git a/linden/indra/newview/skins/silver/xui/en-us/panel_media_controls.xml b/linden/indra/newview/skins/silver/xui/en-us/panel_media_controls.xml index d62fe09..466db79 100644 --- a/linden/indra/newview/skins/silver/xui/en-us/panel_media_controls.xml +++ b/linden/indra/newview/skins/silver/xui/en-us/panel_media_controls.xml | |||
@@ -4,7 +4,7 @@ | |||
4 | name="media_controls" width="220"> | 4 | name="media_controls" width="220"> |
5 | <icon bottom="-18" enabled="true" follows="left|top" height="14" | 5 | <icon bottom="-18" enabled="true" follows="left|top" height="14" |
6 | image_name="icn_label_music.tga" label="" left_delta="6" mouse_opaque="true" | 6 | image_name="icn_label_music.tga" label="" left_delta="6" mouse_opaque="true" |
7 | name="music_icon" scale_image="true" tool_tip="Play/pause streaming music" | 7 | name="music_icon" scale_image="true" tool_tip="Play streaming music" |
8 | width="14" /> | 8 | width="14" /> |
9 | <button bottom="-21" enabled="true" follows="left|top" height="20" | 9 | <button bottom="-21" enabled="true" follows="left|top" height="20" |
10 | image_overlay="icn_play.tga" | 10 | image_overlay="icn_play.tga" |
@@ -13,15 +13,7 @@ | |||
13 | image_disabled="flyout_btn_left_disabled.tga" | 13 | image_disabled="flyout_btn_left_disabled.tga" |
14 | label="" left_delta="16" | 14 | label="" left_delta="16" |
15 | mouse_opaque="true" name="music_play" scale_image="true" toggle="false" | 15 | mouse_opaque="true" name="music_play" scale_image="true" toggle="false" |
16 | tool_tip="Play/pause streaming music" width="20" /> | 16 | tool_tip="Play streaming music" width="20" /> |
17 | <button bottom="-21" enabled="false" follows="left|top" height="20" | ||
18 | image_overlay="icn_pause.tga" | ||
19 | image_unselected="flyout_btn_left.tga" | ||
20 | image_selected="flyout_btn_left_selected.tga" | ||
21 | image_disabled="flyout_btn_left_disabled.tga" | ||
22 | label="" left_delta="0" | ||
23 | mouse_opaque="true" name="music_pause" scale_image="true" toggle="false" | ||
24 | tool_tip="Pause streaming music" width="20" /> | ||
25 | <button bottom="-21" enabled="true" follows="left|top" height="20" | 17 | <button bottom="-21" enabled="true" follows="left|top" height="20" |
26 | image_overlay="icn_stop.tga" | 18 | image_overlay="icn_stop.tga" |
27 | image_unselected="flyout_btn_right.tga" | 19 | image_unselected="flyout_btn_right.tga" |
@@ -33,7 +25,7 @@ | |||
33 | <icon bottom="-18" enabled="true" follows="left|top" height="14" | 25 | <icon bottom="-18" enabled="true" follows="left|top" height="14" |
34 | image_name="icn_label_media.tga" | 26 | image_name="icn_label_media.tga" |
35 | label="" left_delta="22" mouse_opaque="true" | 27 | label="" left_delta="22" mouse_opaque="true" |
36 | name="media_icon" scale_image="true" tool_tip="Play/pause streaming music" | 28 | name="media_icon" scale_image="true" tool_tip="Play/pause streaming media" |
37 | width="17" /> | 29 | width="17" /> |
38 | <button bottom="-21" enabled="true" follows="left|top" height="20" | 30 | <button bottom="-21" enabled="true" follows="left|top" height="20" |
39 | image_overlay="icn_play.tga" | 31 | image_overlay="icn_play.tga" |