diff options
Diffstat (limited to 'linden/indra/llmedia')
-rw-r--r-- | linden/indra/llmedia/CMakeLists.txt | 34 | ||||
-rw-r--r-- | linden/indra/llmedia/llgstplaythread.cpp | 54 | ||||
-rw-r--r-- | linden/indra/llmedia/llgstplaythread.h | 62 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediabase.h | 18 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediaimplcommon.cpp | 12 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediaimplcommon.h | 2 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediaimplgstreamer.cpp | 847 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediaimplgstreamer.h | 90 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediaimplgstreamer_syms.cpp | 169 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediaimplgstreamer_syms.h | 78 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc | 46 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediaimplgstreamer_syms_rawv.inc | 5 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediaimplgstreamervidplug.cpp | 99 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediaimplgstreamervidplug.h | 5 | ||||
-rw-r--r-- | linden/indra/llmedia/llmediamanager.cpp | 26 |
15 files changed, 770 insertions, 777 deletions
diff --git a/linden/indra/llmedia/CMakeLists.txt b/linden/indra/llmedia/CMakeLists.txt index 0c892f9..c7b5cd1 100644 --- a/linden/indra/llmedia/CMakeLists.txt +++ b/linden/indra/llmedia/CMakeLists.txt | |||
@@ -11,7 +11,6 @@ include(LLMedia) | |||
11 | include(LLMessage) | 11 | include(LLMessage) |
12 | include(LLWindow) | 12 | include(LLWindow) |
13 | include(Mozlib) | 13 | include(Mozlib) |
14 | include(QuickTime) | ||
15 | 14 | ||
16 | include_directories( | 15 | include_directories( |
17 | ${GSTREAMER_INCLUDE_DIRS} | 16 | ${GSTREAMER_INCLUDE_DIRS} |
@@ -30,6 +29,9 @@ set(llmedia_SOURCE_FILES | |||
30 | llmediaimplexample2.cpp | 29 | llmediaimplexample2.cpp |
31 | llmediaimplfactory.cpp | 30 | llmediaimplfactory.cpp |
32 | llmediamanager.cpp | 31 | llmediamanager.cpp |
32 | llmediaimplgstreamer.cpp | ||
33 | llmediaimplgstreamervidplug.cpp | ||
34 | llgstplaythread.cpp | ||
33 | ) | 35 | ) |
34 | 36 | ||
35 | set(llmedia_HEADER_FILES | 37 | set(llmedia_HEADER_FILES |
@@ -44,21 +46,11 @@ set(llmedia_HEADER_FILES | |||
44 | llmediaimplregister.h | 46 | llmediaimplregister.h |
45 | llmediamanager.h | 47 | llmediamanager.h |
46 | llmediaobserver.h | 48 | llmediaobserver.h |
49 | llmediaimplgstreamer.h | ||
50 | llmediaimplgstreamervidplug.h | ||
51 | llgstplaythread.h | ||
47 | ) | 52 | ) |
48 | 53 | ||
49 | if (GSTREAMER) | ||
50 | list(APPEND llmedia_SOURCE_FILES | ||
51 | llmediaimplgstreamer.cpp | ||
52 | llmediaimplgstreamer_syms.cpp | ||
53 | llmediaimplgstreamervidplug.cpp | ||
54 | ) | ||
55 | |||
56 | list(APPEND llmedia_HEADER_FILES | ||
57 | llmediaimplgstreamer.h | ||
58 | llmediaimplgstreamervidplug.h | ||
59 | llmediaimplgstreamer_syms.h | ||
60 | ) | ||
61 | |||
62 | # Work around a bad interaction between broken gstreamer headers and | 54 | # Work around a bad interaction between broken gstreamer headers and |
63 | # g++ 4.3's increased strictness. | 55 | # g++ 4.3's increased strictness. |
64 | 56 | ||
@@ -66,7 +58,6 @@ if (GSTREAMER) | |||
66 | set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES | 58 | set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES |
67 | COMPILE_FLAGS -Wno-error=write-strings) | 59 | COMPILE_FLAGS -Wno-error=write-strings) |
68 | endif (${CXX_VERSION} MATCHES "4.[23]") | 60 | endif (${CXX_VERSION} MATCHES "4.[23]") |
69 | endif (GSTREAMER) | ||
70 | 61 | ||
71 | if (MOZLIB) | 62 | if (MOZLIB) |
72 | list(APPEND llmedia_SOURCE_FILES llmediaimplllmozlib.cpp) | 63 | list(APPEND llmedia_SOURCE_FILES llmediaimplllmozlib.cpp) |
@@ -74,19 +65,6 @@ if (MOZLIB) | |||
74 | list(APPEND llmedia_HEADER_FILES llmediaimplllmozlib.h) | 65 | list(APPEND llmedia_HEADER_FILES llmediaimplllmozlib.h) |
75 | endif (MOZLIB) | 66 | endif (MOZLIB) |
76 | 67 | ||
77 | if (QUICKTIME) | ||
78 | list(APPEND llmedia_SOURCE_FILES llmediaimplquicktime.cpp) | ||
79 | list(APPEND llmedia_HEADER_FILES llmediaimplquicktime.h) | ||
80 | |||
81 | # We use a bunch of deprecated system APIs. | ||
82 | if (DARWIN) | ||
83 | set_source_files_properties( | ||
84 | llmediaimplquicktime.cpp PROPERTIES | ||
85 | COMPILE_FLAGS -Wno-deprecated-declarations | ||
86 | ) | ||
87 | endif (DARWIN) | ||
88 | endif (QUICKTIME) | ||
89 | |||
90 | set_source_files_properties(${llmedia_HEADER_FILES} | 68 | set_source_files_properties(${llmedia_HEADER_FILES} |
91 | PROPERTIES HEADER_FILE_ONLY TRUE) | 69 | PROPERTIES HEADER_FILE_ONLY TRUE) |
92 | 70 | ||
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 68e6677..3bcee4e 100644 --- a/linden/indra/llmedia/llmediabase.h +++ b/linden/indra/llmedia/llmediabase.h | |||
@@ -62,6 +62,21 @@ class LLMediaBase | |||
62 | // undoes everything init() didm called by the media manager when destroying a source | 62 | // undoes everything init() didm called by the media manager when destroying a source |
63 | virtual bool reset() = 0; | 63 | virtual bool reset() = 0; |
64 | 64 | ||
65 | |||
66 | /* Mirrors GStreamer debug levels. */ | ||
67 | enum EDebugLevel { | ||
68 | DEBUG_LEVEL_NONE = 0, | ||
69 | DEBUG_LEVEL_ERROR, | ||
70 | DEBUG_LEVEL_WARNING, | ||
71 | DEBUG_LEVEL_INFO, | ||
72 | DEBUG_LEVEL_DEBUG, | ||
73 | DEBUG_LEVEL_LOG, | ||
74 | DEBUG_LEVEL_COUNT, | ||
75 | }; | ||
76 | |||
77 | /* Set the debug verbosity level. Only implemented for GStreamer. */ | ||
78 | virtual bool setDebugLevel( EDebugLevel level ) = 0; | ||
79 | |||
65 | // accessor for MIME type | 80 | // accessor for MIME type |
66 | virtual bool setMimeType( const std::string mime_type ) = 0; | 81 | virtual bool setMimeType( const std::string mime_type ) = 0; |
67 | virtual std::string getMimeType() const = 0; | 82 | virtual std::string getMimeType() const = 0; |
@@ -154,7 +169,8 @@ class LLMediaBase | |||
154 | STATUS_STARTED = 3, | 169 | STATUS_STARTED = 3, |
155 | STATUS_STOPPED = 4, | 170 | STATUS_STOPPED = 4, |
156 | STATUS_PAUSED = 6, | 171 | STATUS_PAUSED = 6, |
157 | STATUS_RESETTING = 7 | 172 | STATUS_RESETTING = 7, |
173 | STATUS_DEAD = 8 | ||
158 | }; | 174 | }; |
159 | virtual bool addCommand( ECommand cmd ) = 0; | 175 | virtual bool addCommand( ECommand cmd ) = 0; |
160 | virtual bool clearCommand() = 0; | 176 | virtual bool clearCommand() = 0; |
diff --git a/linden/indra/llmedia/llmediaimplcommon.cpp b/linden/indra/llmedia/llmediaimplcommon.cpp index 87838f7..166e86d 100644 --- a/linden/indra/llmedia/llmediaimplcommon.cpp +++ b/linden/indra/llmedia/llmediaimplcommon.cpp | |||
@@ -67,7 +67,8 @@ LLMediaImplCommon::LLMediaImplCommon() : | |||
67 | mCommand( LLMediaBase::COMMAND_NONE ), | 67 | mCommand( LLMediaBase::COMMAND_NONE ), |
68 | mStatus( LLMediaBase::STATUS_UNKNOWN ), | 68 | mStatus( LLMediaBase::STATUS_UNKNOWN ), |
69 | mVolume( 0 ), | 69 | mVolume( 0 ), |
70 | mLooping( false ) | 70 | mLooping( false ), |
71 | mDebugLevel( LLMediaBase::DEBUG_LEVEL_NONE ) | ||
71 | { | 72 | { |
72 | } | 73 | } |
73 | 74 | ||
@@ -93,6 +94,15 @@ bool LLMediaImplCommon::reset() | |||
93 | 94 | ||
94 | //////////////////////////////////////////////////////////////////////////////// | 95 | //////////////////////////////////////////////////////////////////////////////// |
95 | // virtual (derives from LLMediaBase) | 96 | // virtual (derives from LLMediaBase) |
97 | bool LLMediaImplCommon::setDebugLevel( LLMediaBase::EDebugLevel level ) | ||
98 | { | ||
99 | mDebugLevel = level; | ||
100 | |||
101 | return true; | ||
102 | } | ||
103 | |||
104 | //////////////////////////////////////////////////////////////////////////////// | ||
105 | // virtual (derives from LLMediaBase) | ||
96 | bool LLMediaImplCommon::setMimeType( const std::string mime_type ) | 106 | bool LLMediaImplCommon::setMimeType( const std::string mime_type ) |
97 | { | 107 | { |
98 | mMimeType = mime_type; | 108 | mMimeType = mime_type; |
diff --git a/linden/indra/llmedia/llmediaimplcommon.h b/linden/indra/llmedia/llmediaimplcommon.h index 2e60a1a..845429c 100644 --- a/linden/indra/llmedia/llmediaimplcommon.h +++ b/linden/indra/llmedia/llmediaimplcommon.h | |||
@@ -55,6 +55,7 @@ class LLMediaImplCommon : | |||
55 | // housekeeping | 55 | // housekeeping |
56 | virtual bool init(); | 56 | virtual bool init(); |
57 | virtual bool reset(); | 57 | virtual bool reset(); |
58 | virtual bool setDebugLevel( LLMediaBase::EDebugLevel level ); | ||
58 | virtual bool setMimeType( const std::string url ); | 59 | virtual bool setMimeType( const std::string url ); |
59 | virtual std::string getMimeType() const; | 60 | virtual std::string getMimeType() const; |
60 | virtual std::string getMediaURL() const; | 61 | virtual std::string getMediaURL() const; |
@@ -157,6 +158,7 @@ class LLMediaImplCommon : | |||
157 | LLMediaBase::ECommand mCommand; | 158 | LLMediaBase::ECommand mCommand; |
158 | LLMediaBase::EStatus mStatus; | 159 | LLMediaBase::EStatus mStatus; |
159 | bool mLooping; | 160 | bool mLooping; |
161 | LLMediaBase::EDebugLevel mDebugLevel; | ||
160 | }; | 162 | }; |
161 | 163 | ||
162 | #endif // LLMEDIAIMPLCOMMON_H | 164 | #endif // LLMEDIAIMPLCOMMON_H |
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.cpp b/linden/indra/llmedia/llmediaimplgstreamer.cpp index a4fe930..d1bab29 100644 --- a/linden/indra/llmedia/llmediaimplgstreamer.cpp +++ b/linden/indra/llmedia/llmediaimplgstreamer.cpp | |||
@@ -18,8 +18,7 @@ | |||
18 | * There are special exceptions to the terms and conditions of the GPL as | 18 | * There are special exceptions to the terms and conditions of the GPL as |
19 | * it is applied to this Source Code. View the full text of the exception | 19 | * it is applied to this Source Code. View the full text of the exception |
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 20 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
21 | * online at | 21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
22 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
23 | * | 22 | * |
24 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
25 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -31,20 +30,39 @@ | |||
31 | * $/LicenseInfo$ | 30 | * $/LicenseInfo$ |
32 | */ | 31 | */ |
33 | 32 | ||
34 | #include "llmediaimplgstreamer.h" | 33 | ///#if LL_GSTREAMER_ENABLED |
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 | ||
35 | 41 | ||
36 | #if LL_GSTREAMER_ENABLED | 42 | #include "linden_common.h" |
43 | #include "llmediaimplgstreamer.h" | ||
37 | 44 | ||
38 | extern "C" { | 45 | extern "C" { |
39 | #include <gst/gst.h> | 46 | #include <gst/gst.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" | 62 | |
63 | #if LL_DARWIN | ||
64 | #include <CoreFoundation/CoreFoundation.h> // For CF functions used in set_gst_plugin_path | ||
65 | #endif | ||
48 | 66 | ||
49 | // register this impl with media manager factory | 67 | // register this impl with media manager factory |
50 | static LLMediaImplRegister sLLMediaImplGStreamerReg( "LLMediaImplGStreamer", new LLMediaImplGStreamerMaker() ); | 68 | static LLMediaImplRegister sLLMediaImplGStreamerReg( "LLMediaImplGStreamer", new LLMediaImplGStreamerMaker() ); |
@@ -64,21 +82,20 @@ LLMediaImplGStreamerMaker::LLMediaImplGStreamerMaker() | |||
64 | // | 82 | // |
65 | LLMediaImplGStreamer:: | 83 | LLMediaImplGStreamer:: |
66 | LLMediaImplGStreamer () : | 84 | LLMediaImplGStreamer () : |
67 | mBusWatchID ( 0 ), | ||
68 | mediaData ( NULL ), | 85 | mediaData ( NULL ), |
69 | mMediaRowbytes ( 1 ), | 86 | mMediaRowbytes ( 1 ), |
70 | mTextureFormatPrimary ( LL_MEDIA_BGRA ), | 87 | mTextureFormatPrimary ( LL_MEDIA_BGRA ), |
71 | mTextureFormatType ( LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV ), | 88 | mTextureFormatType ( LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV ), |
72 | mPump ( NULL ), | 89 | mPump ( NULL ), |
73 | mPlaybin ( NULL ), | 90 | mPlaybin ( NULL ), |
74 | mVideoSink ( NULL ) | 91 | mVideoSink ( NULL ), |
92 | mState( GST_STATE_NULL ), | ||
93 | mPlayThread ( NULL ) | ||
75 | { | 94 | { |
76 | if (!mDoneInit) | 95 | startup( NULL ); // Startup gstreamer if it hasn't been already. |
77 | return; // error | ||
78 | 96 | ||
79 | DEBUGMSG("constructing media..."); | 97 | LL_DEBUGS("MediaManager") << "constructing media..." << LL_ENDL; |
80 | 98 | mVolume = -1.0; // XXX Hack to make the vould change happend first time | |
81 | mVolume = 0.1234567; // minor hack to force an initial volume update | ||
82 | 99 | ||
83 | setMediaDepth(4); | 100 | setMediaDepth(4); |
84 | 101 | ||
@@ -90,30 +107,24 @@ LLMediaImplGStreamer () : | |||
90 | } | 107 | } |
91 | 108 | ||
92 | // instantiate a playbin element to do the hard work | 109 | // instantiate a playbin element to do the hard work |
93 | mPlaybin = llgst_element_factory_make ("playbin", "play"); | 110 | mPlaybin = gst_element_factory_make ("playbin", "play"); |
94 | if (!mPlaybin) | 111 | if (!mPlaybin) |
95 | { | 112 | { |
113 | // todo: cleanup pump | ||
96 | return; // error | 114 | return; // error |
97 | } | 115 | } |
98 | 116 | ||
99 | // get playbin's bus | 117 | if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) |
100 | GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); | ||
101 | if (!bus) | ||
102 | { | 118 | { |
103 | return; // error | ||
104 | } | ||
105 | mBusWatchID = llgst_bus_add_watch (bus, | ||
106 | llmediaimplgstreamer_bus_callback, | ||
107 | this); | ||
108 | llgst_object_unref (bus); | ||
109 | |||
110 | if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { | ||
111 | // instantiate and connect a custom video sink | 119 | // instantiate and connect a custom video sink |
120 | LL_DEBUGS("MediaManager") << "extrenal video sink..." << LL_ENDL; | ||
121 | |||
122 | // Plays inworld instead of in external player | ||
112 | mVideoSink = | 123 | mVideoSink = |
113 | GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); | 124 | GST_SLVIDEO(gst_element_factory_make ("private-slvideo", "slvideo")); |
114 | if (!mVideoSink) | 125 | if (!mVideoSink) |
115 | { | 126 | { |
116 | WARNMSG("Could not instantiate private-slvideo element."); | 127 | LL_WARNS("MediaImpl") << "Could not instantiate private-slvideo element." << LL_ENDL; |
117 | // todo: cleanup. | 128 | // todo: cleanup. |
118 | return; // error | 129 | return; // error |
119 | } | 130 | } |
@@ -145,7 +156,7 @@ int LLMediaImplGStreamer::getTextureFormatInternal() const | |||
145 | LLMediaImplGStreamer:: | 156 | LLMediaImplGStreamer:: |
146 | ~LLMediaImplGStreamer () | 157 | ~LLMediaImplGStreamer () |
147 | { | 158 | { |
148 | DEBUGMSG("dtor of media..."); | 159 | LL_DEBUGS("MediaImpl") << ("dtor of media...") << LL_ENDL; |
149 | unload(); | 160 | unload(); |
150 | } | 161 | } |
151 | 162 | ||
@@ -153,116 +164,230 @@ LLMediaImplGStreamer:: | |||
153 | // virtual | 164 | // virtual |
154 | std::string LLMediaImplGStreamer::getVersion() | 165 | std::string LLMediaImplGStreamer::getVersion() |
155 | { | 166 | { |
156 | std::string rtn; | 167 | guint major, minor, micro, nano; |
157 | rtn = "[" + sLLMediaImplGStreamerReg.getImplName() + "] - GStreamer 0.10.x"; | 168 | gst_version(&major, &minor, µ, &nano); |
158 | return rtn; | 169 | std::string version = llformat("%d.%d.%d.%d",major,minor,micro,nano); |
170 | return version; | ||
159 | } | 171 | } |
160 | 172 | ||
173 | // | ||
174 | // STARTUP | ||
161 | /////////////////////////////////////////////////////////////////////////////// | 175 | /////////////////////////////////////////////////////////////////////////////// |
162 | // (static) super-initialization - called once at application startup | 176 | // (static) super-initialization - called once at application startup |
163 | 177 | bool LLMediaImplGStreamer::startup (LLMediaManagerData* init_data) | |
164 | //static | ||
165 | bool LLMediaImplGStreamer::mDoneInit = false; | ||
166 | |||
167 | //static | ||
168 | bool | ||
169 | LLMediaImplGStreamer:: | ||
170 | startup ( LLMediaManagerData* init_data ) | ||
171 | { | 178 | { |
172 | // first - check if GStreamer is explicitly disabled | 179 | static bool done_init = false; |
173 | if (NULL != getenv("LL_DISABLE_GSTREAMER")) | 180 | if (!done_init) |
174 | return false; | ||
175 | |||
176 | // only do global GStreamer initialization once. | ||
177 | if (!mDoneInit) | ||
178 | { | 181 | { |
179 | // Init the glib type system - we need it. | 182 | // Init the glib type system - we need it. |
180 | g_type_init(); | 183 | g_type_init(); |
181 | 184 | ||
182 | // Get symbols! | 185 | set_gst_plugin_path(); |
183 | if (! grab_gst_syms("libgstreamer-0.10.so.0", | 186 | |
184 | "libgstvideo-0.10.so.0") ) | 187 | // Protect against GStreamer resetting the locale, yuck. |
188 | static std::string saved_locale; | ||
189 | saved_locale = setlocale(LC_ALL, NULL); | ||
190 | if (0 == gst_init_check(NULL, NULL, NULL)) | ||
185 | { | 191 | { |
186 | WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); | 192 | LL_WARNS("MediaImpl") << "GStreamer library failed to initialize and load standard plugins." << LL_ENDL; |
193 | setlocale(LC_ALL, saved_locale.c_str() ); | ||
187 | return false; | 194 | return false; |
188 | } | 195 | } |
196 | setlocale(LC_ALL, saved_locale.c_str() ); | ||
189 | 197 | ||
190 | if (llgst_segtrap_set_enabled) | 198 | // Set up logging facilities |
191 | { | 199 | gst_debug_remove_log_function( gst_debug_log_default ); |
192 | llgst_segtrap_set_enabled(FALSE); | 200 | gst_debug_add_log_function( gstreamer_log, NULL ); |
193 | } | ||
194 | else | ||
195 | { | ||
196 | WARNMSG("gst_segtrap_set_enabled() is not available; Automated crash-reporter may cease to function until next restart."); | ||
197 | } | ||
198 | 201 | ||
199 | #if LL_LINUX | 202 | // Init our custom plugins - only really need do this once. |
200 | // Gstreamer tries a fork during init, waitpid-ing on it, | 203 | gst_slvideo_init_class(); |
201 | // which conflicts with any installed SIGCHLD handler... | 204 | |
202 | struct sigaction tmpact, oldact; | 205 | |
203 | if (llgst_registry_fork_set_enabled) { | 206 | // List the plugins GStreamer can find |
204 | // if we can disable SIGCHLD-using forking behaviour, | 207 | LL_DEBUGS("MediaImpl") << "Found GStreamer plugins:" << LL_ENDL; |
205 | // do it. | 208 | GList *list; |
206 | llgst_registry_fork_set_enabled(false); | 209 | GstRegistry *registry = gst_registry_get_default(); |
207 | } | 210 | std::string loaded = ""; |
208 | else { | 211 | for (list = gst_registry_get_plugin_list(registry); |
209 | // else temporarily install default SIGCHLD handler | 212 | list != NULL; |
210 | // while GStreamer initialises | 213 | list = g_list_next(list)) |
211 | tmpact.sa_handler = SIG_DFL; | 214 | { |
212 | sigemptyset( &tmpact.sa_mask ); | 215 | GstPlugin *list_plugin = (GstPlugin *)list->data; |
213 | tmpact.sa_flags = SA_SIGINFO; | 216 | (bool)gst_plugin_is_loaded(list_plugin) ? loaded = "Yes" : loaded = "No"; |
214 | sigaction(SIGCHLD, &tmpact, &oldact); | 217 | LL_DEBUGS("MediaImpl") << gst_plugin_get_name(list_plugin) << ", loaded? " << loaded << LL_ENDL; |
215 | } | 218 | } |
216 | #endif // LL_LINUX | 219 | gst_plugin_list_free(list); |
217 | 220 | ||
218 | // Protect against GStreamer resetting the locale, yuck. | ||
219 | static std::string saved_locale; | ||
220 | saved_locale = setlocale(LC_ALL, NULL); | ||
221 | 221 | ||
222 | // finally, try to initialize GStreamer! | 222 | done_init = true; |
223 | GError *err = NULL; | 223 | } |
224 | gboolean init_gst_success = llgst_init_check(NULL, NULL, &err); | 224 | return true; |
225 | } | ||
226 | |||
225 | 227 | ||
226 | // restore old locale | 228 | void LLMediaImplGStreamer::set_gst_plugin_path() |
227 | setlocale(LC_ALL, saved_locale.c_str() ); | 229 | { |
230 | // Linux sets GST_PLUGIN_PATH in wrapper.sh, not here. | ||
231 | #if LL_WINDOWS || LL_DARWIN | ||
228 | 232 | ||
229 | #if LL_LINUX | 233 | std::string imp_dir = ""; |
230 | // restore old SIGCHLD handler | ||
231 | if (!llgst_registry_fork_set_enabled) | ||
232 | sigaction(SIGCHLD, &oldact, NULL); | ||
233 | #endif // LL_LINUX | ||
234 | 234 | ||
235 | if (!init_gst_success) // fail | 235 | // Get the current working directory: |
236 | #if LL_WINDOWS | ||
237 | char* raw_dir; | ||
238 | raw_dir = _getcwd(NULL,0); | ||
239 | if( raw_dir != NULL ) | ||
240 | { | ||
241 | imp_dir = std::string( raw_dir ); | ||
242 | } | ||
243 | #elif LL_DARWIN | ||
244 | CFBundleRef main_bundle = CFBundleGetMainBundle(); | ||
245 | if( main_bundle != NULL ) | ||
246 | { | ||
247 | CFURLRef bundle_url = CFBundleCopyBundleURL( main_bundle ); | ||
248 | if( bundle_url != NULL ) | ||
236 | { | 249 | { |
237 | if (err) | 250 | #ifndef MAXPATHLEN |
238 | { | 251 | #define MAXPATHLEN 1024 |
239 | WARNMSG("GST init failed: %s", err->message); | 252 | #endif |
240 | g_error_free(err); | 253 | char raw_dir[MAXPATHLEN]; |
241 | } | 254 | if( CFURLGetFileSystemRepresentation( bundle_url, true, (UInt8 *)raw_dir, MAXPATHLEN) ) |
242 | else | ||
243 | { | 255 | { |
244 | WARNMSG("GST init failed for unspecified reason."); | 256 | imp_dir = std::string( raw_dir ) + "/Contents/MacOS/"; |
245 | } | 257 | } |
246 | return false; | 258 | CFRelease(bundle_url); |
247 | } | 259 | } |
260 | } | ||
261 | #endif | ||
262 | |||
263 | if( imp_dir == "" ) | ||
264 | { | ||
265 | LL_WARNS("MediaImpl") << "Could not get application directory, not setting GST_PLUGIN_PATH." | ||
266 | << LL_ENDL; | ||
267 | return; | ||
268 | } | ||
269 | |||
270 | LL_DEBUGS("MediaImpl") << "Imprudence is installed at " | ||
271 | << imp_dir << LL_ENDL; | ||
272 | |||
273 | // ":" on Mac and 'Nix, ";" on Windows | ||
274 | std::string separator = G_SEARCHPATH_SEPARATOR_S; | ||
275 | |||
276 | // Grab the current path, if it's set. | ||
277 | std::string old_plugin_path = ""; | ||
278 | char *old_path = getenv("GST_PLUGIN_PATH"); | ||
279 | if(old_path == NULL) | ||
280 | { | ||
281 | LL_DEBUGS("MediaImpl") << "Did not find user-set GST_PLUGIN_PATH." | ||
282 | << LL_ENDL; | ||
283 | } | ||
284 | else | ||
285 | { | ||
286 | old_plugin_path = separator + std::string( old_path ); | ||
287 | } | ||
288 | |||
289 | |||
290 | // Search both Imprudence and Imprudence\lib\gstreamer-plugins. | ||
291 | // But we also want to search the path the user has set, if any. | ||
292 | std::string plugin_path = | ||
293 | "GST_PLUGIN_PATH=" + | ||
294 | #if LL_WINDOWS | ||
295 | imp_dir + "\\lib\\gstreamer-plugins" + | ||
296 | #elif LL_DARWIN | ||
297 | imp_dir + separator + | ||
298 | imp_dir + "/../Resources/lib/gstreamer-plugins" + | ||
299 | #endif | ||
300 | old_plugin_path; | ||
301 | |||
302 | int put_result; | ||
303 | |||
304 | // Place GST_PLUGIN_PATH in the environment settings | ||
305 | #if LL_WINDOWS | ||
306 | put_result = _putenv( (char*)plugin_path.c_str() ); | ||
307 | #elif LL_DARWIN | ||
308 | put_result = putenv( (char*)plugin_path.c_str() ); | ||
309 | #endif | ||
310 | |||
311 | if( put_result == -1 ) | ||
312 | { | ||
313 | LL_WARNS("MediaImpl") << "Setting GST_PLUGIN_PATH failed!" << LL_ENDL; | ||
314 | } | ||
315 | else | ||
316 | { | ||
317 | LL_DEBUGS("MediaImpl") << "GST_PLUGIN_PATH set to " | ||
318 | << getenv("GST_PLUGIN_PATH") << LL_ENDL; | ||
319 | } | ||
248 | 320 | ||
249 | // Init our custom plugins - only really need do this once. | 321 | // Don't load system plugins. We only want to use ours, to avoid conflicts. |
250 | gst_slvideo_init_class(); | 322 | #if LL_WINDOWS |
323 | put_result = _putenv( "GST_PLUGIN_SYSTEM_PATH=\"\"" ); | ||
324 | #elif LL_DARWIN | ||
325 | put_result = putenv( "GST_PLUGIN_SYSTEM_PATH=\"\"" ); | ||
326 | #endif | ||
327 | |||
328 | if( put_result == -1 ) | ||
329 | { | ||
330 | LL_WARNS("MediaImpl") << "Setting GST_PLUGIN_SYSTEM_PATH=\"\" failed!" | ||
331 | << LL_ENDL; | ||
332 | } | ||
333 | |||
334 | #endif // LL_WINDOWS || LL_DARWIN | ||
335 | } | ||
336 | |||
337 | |||
338 | void LLMediaImplGStreamer::gstreamer_log(GstDebugCategory *category, | ||
339 | GstDebugLevel level, | ||
340 | const gchar *file, | ||
341 | const gchar *function, | ||
342 | gint line, | ||
343 | GObject *object, | ||
344 | GstDebugMessage *message, | ||
345 | gpointer data) | ||
346 | { | ||
347 | std::stringstream log(std::stringstream::out); | ||
348 | |||
349 | // Log format example: | ||
350 | // | ||
351 | // GST_ELEMENT_PADS: removing pad 'sink' (in gstelement.c:757:gst_element_remove_pad) | ||
352 | // | ||
353 | log << gst_debug_category_get_name( category ) << ": " | ||
354 | << gst_debug_message_get(message) << " " | ||
355 | << "(in " << file << ":" << line << ":" << function << ")"; | ||
251 | 356 | ||
252 | mDoneInit = true; | 357 | switch( level ) |
358 | { | ||
359 | case GST_LEVEL_ERROR: | ||
360 | LL_WARNS("MediaImpl") << "(ERROR) " << log.str() << LL_ENDL; | ||
361 | break; | ||
362 | case GST_LEVEL_WARNING: | ||
363 | LL_WARNS("MediaImpl") << log.str() << LL_ENDL; | ||
364 | break; | ||
365 | case GST_LEVEL_DEBUG: | ||
366 | LL_DEBUGS("MediaImpl") << log.str() << LL_ENDL; | ||
367 | break; | ||
368 | case GST_LEVEL_INFO: | ||
369 | LL_INFOS("MediaImpl") << log.str() << LL_ENDL; | ||
370 | break; | ||
371 | default: | ||
372 | // Do nothing. | ||
373 | break; | ||
253 | } | 374 | } |
375 | } | ||
376 | |||
254 | 377 | ||
378 | bool LLMediaImplGStreamer::closedown() | ||
379 | { | ||
255 | return true; | 380 | return true; |
256 | } | 381 | } |
257 | 382 | ||
258 | 383 | ||
259 | bool LLMediaImplGStreamer:: | 384 | bool LLMediaImplGStreamer::setDebugLevel( LLMediaBase::EDebugLevel level ) |
260 | closedown() | ||
261 | { | 385 | { |
262 | if (!mDoneInit) | 386 | // Do parent class stuff. |
263 | return false; // error | 387 | LLMediaImplCommon::setDebugLevel(level); |
264 | 388 | ||
265 | ungrab_gst_syms(); | 389 | // Set GStreamer verbosity. |
390 | gst_debug_set_default_threshold( (GstDebugLevel)level ); | ||
266 | 391 | ||
267 | return true; | 392 | return true; |
268 | } | 393 | } |
@@ -270,230 +395,215 @@ closedown() | |||
270 | 395 | ||
271 | /////////////////////////////////////////////////////////////////////////////// | 396 | /////////////////////////////////////////////////////////////////////////////// |
272 | // | 397 | // |
398 | // Uncomment the line below to enable spammy debug data. | ||
273 | //#define LL_GST_REPORT_STATE_CHANGES | 399 | //#define LL_GST_REPORT_STATE_CHANGES |
274 | #ifdef LL_GST_REPORT_STATE_CHANGES | 400 | #ifdef LL_GST_REPORT_STATE_CHANGES |
275 | static char* get_gst_state_name(GstState state) | 401 | static const char* get_gst_state_name(GstState state) |
276 | { | 402 | { |
277 | switch (state) { | 403 | switch (state) |
278 | case GST_STATE_VOID_PENDING: return "VOID_PENDING"; | 404 | { |
279 | case GST_STATE_NULL: return "NULL"; | 405 | case GST_STATE_VOID_PENDING: return "VOID_PENDING"; |
280 | case GST_STATE_READY: return "READY"; | 406 | case GST_STATE_NULL: return "NULL"; |
281 | case GST_STATE_PAUSED: return "PAUSED"; | 407 | case GST_STATE_READY: return "READY"; |
282 | case GST_STATE_PLAYING: return "PLAYING"; | 408 | case GST_STATE_PAUSED: return "PAUSED"; |
409 | case GST_STATE_PLAYING: return "PLAYING"; | ||
283 | } | 410 | } |
284 | return "(unknown)"; | 411 | return "(unknown)"; |
285 | } | 412 | } |
286 | #endif // LL_GST_REPORT_STATE_CHANGES | 413 | #endif // LL_GST_REPORT_STATE_CHANGES |
287 | 414 | ||
288 | extern "C" { | 415 | //static |
289 | gboolean | 416 | gboolean LLMediaImplGStreamer::bus_callback(GstBus *bus, GstMessage *message, gpointer data) |
290 | llmediaimplgstreamer_bus_callback (GstBus *bus, | ||
291 | GstMessage *message, | ||
292 | gpointer data) | ||
293 | { | 417 | { |
294 | if (!message) | 418 | #ifdef LL_GST_REPORT_STATE_CHANGES |
295 | return TRUE; // shield against GStreamer bug | 419 | LL_DEBUGS("MediaCallback") << "Got GST message type: " << GST_MESSAGE_TYPE_NAME (message) << LL_ENDL; |
296 | 420 | #endif | |
297 | if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && | ||
298 | GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) | ||
299 | { | ||
300 | DEBUGMSG("Got GST message type: %s", | ||
301 | LLGST_MESSAGE_TYPE_NAME (message)); | ||
302 | } | ||
303 | else | ||
304 | { | ||
305 | DEBUGMSG("Got GST message type: %s", | ||
306 | LLGST_MESSAGE_TYPE_NAME (message)); | ||
307 | } | ||
308 | 421 | ||
309 | LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; | 422 | LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; |
310 | 423 | ||
311 | switch (GST_MESSAGE_TYPE (message)) { | 424 | switch (GST_MESSAGE_TYPE (message)) |
312 | case GST_MESSAGE_BUFFERING: { | 425 | { |
313 | // NEEDS GST 0.10.11+ | 426 | case GST_MESSAGE_BUFFERING: |
314 | if (llgst_message_parse_buffering) | ||
315 | { | 427 | { |
316 | gint percent = 0; | 428 | gint percent = 0; |
317 | llgst_message_parse_buffering(message, &percent); | 429 | gst_message_parse_buffering(message, &percent); |
318 | DEBUGMSG("GST buffering: %d%%", percent); | 430 | #ifdef LL_GST_REPORT_STATE_CHANGES |
431 | LL_DEBUGS("MediaBuffering") << "GST buffering: " << percent << "%%" << LL_ENDL; | ||
432 | #endif | ||
319 | LLMediaEvent event( impl, percent ); | 433 | LLMediaEvent event( impl, percent ); |
320 | impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); | 434 | impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); |
321 | |||
322 | } | 435 | } |
323 | break; | 436 | break; |
324 | } | 437 | case GST_MESSAGE_STATE_CHANGED: |
325 | case GST_MESSAGE_STATE_CHANGED: { | 438 | { |
326 | GstState old_state; | 439 | GstState old_state; |
327 | GstState new_state; | 440 | GstState new_state; |
328 | GstState pending_state; | 441 | GstState pending_state; |
329 | llgst_message_parse_state_changed(message, | 442 | gst_message_parse_state_changed(message, |
330 | &old_state, | 443 | &old_state, |
331 | &new_state, | 444 | &new_state, |
332 | &pending_state); | 445 | &pending_state); |
333 | #ifdef LL_GST_REPORT_STATE_CHANGES | 446 | #ifdef LL_GST_REPORT_STATE_CHANGES |
334 | // not generally very useful, and rather spammy. | 447 | // not generally very useful, and rather spammy. |
335 | DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", | 448 | LL_DEBUGS("MediaState") << "GST state change (old,<new>,pending): "<< get_gst_state_name(old_state) << ",<" << get_gst_state_name(new_state) << ">," << get_gst_state_name(pending_state) << LL_ENDL; |
336 | get_gst_state_name(old_state), | ||
337 | get_gst_state_name(new_state), | ||
338 | get_gst_state_name(pending_state)); | ||
339 | #endif // LL_GST_REPORT_STATE_CHANGES | 449 | #endif // LL_GST_REPORT_STATE_CHANGES |
340 | 450 | ||
341 | switch (new_state) { | 451 | switch (new_state) |
342 | case GST_STATE_VOID_PENDING: | 452 | { |
343 | break; | 453 | case GST_STATE_VOID_PENDING: |
344 | case GST_STATE_NULL: | 454 | break; |
345 | break; | 455 | case GST_STATE_NULL: |
346 | case GST_STATE_READY: | 456 | #ifdef LL_GST_REPORT_STATE_CHANGES |
347 | break; | 457 | LL_DEBUGS("MediaImpl") << "State changed to NULL" << LL_ENDL; |
348 | case GST_STATE_PAUSED: | 458 | #endif |
349 | break; | 459 | if (impl->getState() == GST_STATE_PLAYING) |
350 | case GST_STATE_PLAYING: | 460 | { |
351 | LLMediaEvent event( impl, 100 ); | 461 | // Stream was probably dropped, trying to restart |
352 | impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); | 462 | impl->play(); |
353 | // emit an event to say that a media source was loaded | 463 | #ifdef LL_GST_REPORT_STATE_CHANGES |
354 | LLMediaEvent event2( impl ); | 464 | LL_DEBUGS("MediaImpl") << "Trying to restart." << LL_ENDL; |
355 | impl->getEventEmitter().update( &LLMediaObserver::onMediaLoaded, event2 ); | 465 | #endif |
466 | } | ||
467 | break; | ||
468 | case GST_STATE_READY: | ||
469 | break; | ||
470 | case GST_STATE_PAUSED: | ||
471 | break; | ||
472 | case GST_STATE_PLAYING: | ||
473 | LLMediaEvent event( impl, 100 ); | ||
474 | impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); | ||
475 | // emit an event to say that a media source was loaded | ||
476 | LLMediaEvent event2( impl ); | ||
477 | impl->getEventEmitter().update( &LLMediaObserver::onMediaLoaded, event2 ); | ||
478 | break; | ||
479 | } | ||
356 | break; | 480 | break; |
357 | } | 481 | } |
358 | break; | 482 | case GST_MESSAGE_ERROR: |
359 | } | 483 | { |
360 | case GST_MESSAGE_ERROR: { | 484 | GError *err = NULL; |
361 | GError *err = NULL; | 485 | gchar *debug = NULL; |
362 | gchar *debug = NULL; | ||
363 | 486 | ||
364 | llgst_message_parse_error (message, &err, &debug); | 487 | gst_message_parse_error (message, &err, &debug); |
365 | WARNMSG("GST error: %s", err->message); | 488 | LL_WARNS("MediaImpl") << "GST Error: " << err->message << LL_ENDL; |
366 | g_error_free (err); | 489 | g_error_free (err); |
367 | g_free (debug); | 490 | g_free (debug); |
368 | 491 | ||
369 | impl->addCommand(LLMediaBase::COMMAND_STOP); | 492 | impl->addCommand(LLMediaBase::COMMAND_STOP); |
493 | //impl->addCommand(LLMediaBase::COMMAND_START); | ||
370 | 494 | ||
371 | break; | 495 | break; |
372 | } | 496 | } |
373 | case GST_MESSAGE_INFO: { | 497 | case GST_MESSAGE_INFO: |
374 | if (llgst_message_parse_info) | ||
375 | { | 498 | { |
376 | GError *err = NULL; | 499 | GError *err = NULL; |
377 | gchar *debug = NULL; | 500 | gchar *debug = NULL; |
378 | 501 | ||
379 | llgst_message_parse_info (message, &err, &debug); | 502 | gst_message_parse_info (message, &err, &debug); |
380 | INFOMSG("GST info: %s", err->message); | 503 | LL_INFOS("MediaImpl") << "GST info: " << err->message |
504 | << LL_ENDL; | ||
381 | g_error_free (err); | 505 | g_error_free (err); |
382 | g_free (debug); | 506 | g_free (debug); |
507 | break; | ||
383 | } | 508 | } |
384 | break; | 509 | case GST_MESSAGE_WARNING: |
385 | } | 510 | { |
386 | case GST_MESSAGE_WARNING: { | 511 | GError *err = NULL; |
387 | GError *err = NULL; | 512 | gchar *debug = NULL; |
388 | gchar *debug = NULL; | ||
389 | 513 | ||
390 | llgst_message_parse_warning (message, &err, &debug); | 514 | gst_message_parse_warning (message, &err, &debug); |
391 | WARNMSG("GST warning: %s", err->message); | 515 | LL_WARNS("MediaImpl") << "GST warning: " << err->message |
392 | g_error_free (err); | 516 | << LL_ENDL; |
393 | g_free (debug); | 517 | g_error_free (err); |
518 | g_free (debug); | ||
394 | 519 | ||
395 | break; | 520 | break; |
396 | } | 521 | } |
397 | case GST_MESSAGE_EOS: | 522 | case GST_MESSAGE_TAG: |
398 | /* end-of-stream */ | ||
399 | DEBUGMSG("GST end-of-stream."); | ||
400 | if (impl->isLooping()) | ||
401 | { | 523 | { |
402 | DEBUGMSG("looping media..."); | 524 | GstTagList *tag_list; |
403 | double eos_pos_sec = 0.0F; | 525 | gchar *title; |
404 | bool got_eos_position = impl->getTimePos(eos_pos_sec); | 526 | gchar *artist; |
405 | 527 | gst_message_parse_tag(message, &tag_list); | |
406 | if (got_eos_position && eos_pos_sec < impl->MIN_LOOP_SEC) | 528 | gboolean hazTitle = gst_tag_list_get_string(tag_list, |
529 | GST_TAG_TITLE, &title); | ||
530 | gboolean hazArtist = gst_tag_list_get_string(tag_list, | ||
531 | GST_TAG_ARTIST, &artist); | ||
532 | if(hazTitle) | ||
533 | LL_INFOS("MediaInfo") << "Title: " << title << LL_ENDL; | ||
534 | if(hazArtist) | ||
535 | LL_INFOS("MediaInfo") << "Artist: " << artist << LL_ENDL; | ||
536 | break; | ||
537 | } | ||
538 | case GST_MESSAGE_EOS: | ||
539 | { | ||
540 | /* end-of-stream */ | ||
541 | LL_DEBUGS("MediaImpl") << "GST end-of-stream." << LL_ENDL; | ||
542 | if (impl->isLooping()) | ||
407 | { | 543 | { |
408 | // if we know that the movie is really short, don't | 544 | LL_DEBUGS("MediaImpl") << "looping media..." << LL_ENDL; |
409 | // loop it else it can easily become a time-hog | 545 | impl->stop(); |
410 | // because of GStreamer spin-up overhead | 546 | impl->play(); |
411 | DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); | ||
412 | // inject a COMMAND_PAUSE | ||
413 | impl->addCommand(LLMediaBase::COMMAND_PAUSE); | ||
414 | } | 547 | } |
415 | else | 548 | else |
416 | { | 549 | { |
417 | // first try looping by an explicit rewind | 550 | // inject a COMMAND_STOP |
418 | bool seeksuccess = impl->seek(0.0); | 551 | impl->addCommand(LLMediaBase::COMMAND_STOP); |
419 | if (seeksuccess) | ||
420 | { | ||
421 | impl->play(); | ||
422 | } | ||
423 | else // use clumsy stop-start to loop | ||
424 | { | ||
425 | DEBUGMSG("couldn't loop by rewinding - stopping and starting instead..."); | ||
426 | impl->stop(); | ||
427 | impl->play(); | ||
428 | } | ||
429 | } | 552 | } |
553 | break; | ||
554 | default: | ||
555 | /* unhandled message */ | ||
556 | break; | ||
430 | } | 557 | } |
431 | else // not a looping media | ||
432 | { | ||
433 | // inject a COMMAND_STOP | ||
434 | impl->addCommand(LLMediaBase::COMMAND_STOP); | ||
435 | } | ||
436 | break; | ||
437 | default: | ||
438 | /* unhandled message */ | ||
439 | break; | ||
440 | } | 558 | } |
441 | |||
442 | /* we want to be notified again the next time there is a message | 559 | /* we want to be notified again the next time there is a message |
443 | * on the bus, so return true (false means we want to stop watching | 560 | * on the bus, so return true (false means we want to stop watching |
444 | * for messages on the bus and our callback should not be called again) | 561 | * for messages on the bus and our callback should not be called again) |
445 | */ | 562 | */ |
446 | return TRUE; | 563 | return TRUE; |
447 | } | 564 | } |
448 | } // extern "C" | ||
449 | 565 | ||
450 | /////////////////////////////////////////////////////////// | 566 | /////////////////////////////////////////////////////////// |
451 | // virtual | 567 | // virtual |
452 | bool | 568 | bool LLMediaImplGStreamer::navigateTo (const std::string urlIn) |
453 | LLMediaImplGStreamer:: | ||
454 | navigateTo ( const std::string urlIn ) | ||
455 | { | 569 | { |
456 | if (!mDoneInit) | 570 | LL_DEBUGS("MediaImpl") << "Setting media URI: " << urlIn.c_str() |
457 | return false; // error | 571 | << LL_ENDL; |
458 | |||
459 | DEBUGMSG("Setting media URI: %s", urlIn.c_str()); | ||
460 | 572 | ||
461 | if (NULL == mPump || | 573 | if (mPump == NULL || mPlaybin == NULL) |
462 | NULL == mPlaybin) | ||
463 | { | 574 | { |
464 | return false; // error | 575 | return false; |
465 | } | 576 | } |
466 | 577 | ||
467 | setStatus( LLMediaBase::STATUS_NAVIGATING ); | 578 | setStatus( LLMediaBase::STATUS_NAVIGATING ); |
468 | 579 | ||
469 | // set URI | 580 | // set URI |
470 | g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); | 581 | g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); |
471 | //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL); | ||
472 | 582 | ||
473 | // navigateTo implicitly plays, too. | 583 | // get playbin's bus - perhaps this can/should be done in ctor |
474 | play(); | 584 | GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); |
585 | if (!bus) | ||
586 | { | ||
587 | return false; | ||
588 | } | ||
589 | gst_bus_add_watch (bus, bus_callback, this); | ||
590 | gst_object_unref (bus); | ||
591 | |||
592 | mState = GST_STATE_READY; | ||
475 | 593 | ||
476 | return true; | 594 | return true; |
477 | } | 595 | } |
478 | 596 | ||
479 | /////////////////////////////////////////////////////////////////////////////// | 597 | /////////////////////////////////////////////////////////////////////////////// |
480 | // | 598 | // |
481 | bool | 599 | bool LLMediaImplGStreamer::unload() |
482 | LLMediaImplGStreamer:: | ||
483 | unload () | ||
484 | { | 600 | { |
485 | if (!mDoneInit) | 601 | LL_DEBUGS("MediaImpl") << "unloading media..." << LL_ENDL; |
486 | return false; // error | ||
487 | |||
488 | DEBUGMSG("unloading media..."); | ||
489 | |||
490 | // stop getting callbacks for this bus | ||
491 | g_source_remove(mBusWatchID); | ||
492 | |||
493 | if (mPlaybin) | 602 | if (mPlaybin) |
494 | { | 603 | { |
495 | llgst_element_set_state (mPlaybin, GST_STATE_NULL); | 604 | gst_element_set_state (mPlaybin, GST_STATE_NULL); |
496 | llgst_object_unref (GST_OBJECT (mPlaybin)); | 605 | mState = GST_STATE_NULL; |
606 | gst_object_unref (GST_OBJECT (mPlaybin)); | ||
497 | mPlaybin = NULL; | 607 | mPlaybin = NULL; |
498 | } | 608 | } |
499 | 609 | ||
@@ -510,63 +620,63 @@ unload () | |||
510 | } | 620 | } |
511 | 621 | ||
512 | mVideoSink = NULL; | 622 | mVideoSink = NULL; |
623 | mState = GST_STATE_NULL; | ||
624 | setStatus(LLMediaBase::STATUS_UNKNOWN); | ||
513 | 625 | ||
514 | return true; | 626 | return true; |
515 | } | 627 | } |
516 | 628 | ||
517 | /////////////////////////////////////////////////////////////////////////////// | 629 | /////////////////////////////////////////////////////////////////////////////// |
518 | // virtual | 630 | // virtual |
519 | bool | 631 | bool LLMediaImplGStreamer::updateMedia() |
520 | LLMediaImplGStreamer:: | ||
521 | updateMedia () | ||
522 | { | 632 | { |
523 | if (!mDoneInit) | 633 | //LL_DEBUGS("MediaImpl") << "updating media..." << LL_ENDL; |
524 | return false; // error | ||
525 | |||
526 | DEBUGMSG("updating media..."); | ||
527 | 634 | ||
528 | // sanity check | 635 | // sanity check |
529 | if (NULL == mPump || | 636 | if (mPump == NULL || mPlaybin == NULL) |
530 | NULL == mPlaybin) | ||
531 | { | 637 | { |
532 | DEBUGMSG("dead media..."); | 638 | #ifdef LL_GST_REPORT_STATE_CHANGES |
639 | LL_DEBUGS("MediaImpl") << "dead media..." << LL_ENDL; | ||
640 | #endif | ||
641 | mState = GST_STATE_NULL; | ||
642 | setStatus(LLMediaBase::STATUS_DEAD); | ||
533 | return false; | 643 | return false; |
534 | } | 644 | } |
535 | 645 | ||
646 | if (mState == GST_STATE_VOID_PENDING || mState == GST_STATE_NULL) | ||
647 | return false; | ||
648 | |||
536 | // process next outstanding command | 649 | // process next outstanding command |
537 | switch (nextCommand()) | 650 | switch (nextCommand()) |
538 | { | 651 | { |
539 | case LLMediaBase::COMMAND_START: | 652 | case LLMediaBase::COMMAND_START: |
540 | DEBUGMSG("COMMAND_START"); | 653 | LL_DEBUGS("MediaImpl") << "COMMAND_START" << LL_ENDL; |
541 | if (getStatus() == LLMediaBase::STATUS_PAUSED || | 654 | if (getStatus() == LLMediaBase::STATUS_PAUSED || |
542 | getStatus() == LLMediaBase::STATUS_NAVIGATING || | 655 | getStatus() == LLMediaBase::STATUS_NAVIGATING || |
543 | getStatus() == LLMediaBase::STATUS_STOPPED) | 656 | getStatus() == LLMediaBase::STATUS_STOPPED) |
544 | { | 657 | { |
545 | DEBUGMSG("doing COMMAND_START"); | ||
546 | play(); | 658 | play(); |
547 | setStatus(LLMediaBase::STATUS_STARTED); | 659 | setStatus(LLMediaBase::STATUS_STARTED); |
548 | clearCommand(); | 660 | clearCommand(); |
549 | } | 661 | } |
550 | break; | 662 | break; |
551 | case LLMediaBase::COMMAND_STOP: | 663 | case LLMediaBase::COMMAND_STOP: |
552 | DEBUGMSG("COMMAND_STOP"); | 664 | LL_DEBUGS("MediaImpl") << "COMMAND_STOP" << LL_ENDL; |
553 | DEBUGMSG("doing COMMAND_STOP"); | ||
554 | stop(); | 665 | stop(); |
555 | setStatus(LLMediaBase::STATUS_STOPPED); | 666 | setStatus(LLMediaBase::STATUS_STOPPED); |
556 | clearCommand(); | 667 | clearCommand(); |
557 | break; | 668 | break; |
558 | case LLMediaBase::COMMAND_PAUSE: | 669 | case LLMediaBase::COMMAND_PAUSE: |
559 | DEBUGMSG("COMMAND_PAUSE"); | 670 | LL_DEBUGS("MediaImpl") << "COMMAND_PAUSE" << LL_ENDL; |
560 | if (getStatus() == LLMediaBase::STATUS_STARTED) | 671 | if (getStatus() == LLMediaBase::STATUS_STARTED) |
561 | { | 672 | { |
562 | DEBUGMSG("doing COMMAND_PAUSE"); | ||
563 | pause(); | 673 | pause(); |
564 | setStatus(LLMediaBase::STATUS_PAUSED); | 674 | setStatus(LLMediaBase::STATUS_PAUSED); |
565 | clearCommand(); | 675 | clearCommand(); |
566 | } | 676 | } |
567 | break; | 677 | break; |
568 | default: | 678 | default: |
569 | DEBUGMSG("COMMAND_?"); | 679 | LL_INFOS("MediaImpl") << "Unknown command" << LL_ENDL; |
570 | clearCommand(); | 680 | clearCommand(); |
571 | break; | 681 | break; |
572 | case LLMediaBase::COMMAND_NONE: | 682 | case LLMediaBase::COMMAND_NONE: |
@@ -584,12 +694,14 @@ updateMedia () | |||
584 | GST_OBJECT_LOCK(mVideoSink); | 694 | GST_OBJECT_LOCK(mVideoSink); |
585 | if (mVideoSink->retained_frame_ready) | 695 | if (mVideoSink->retained_frame_ready) |
586 | { | 696 | { |
587 | DEBUGMSG("NEW FRAME "); | 697 | #ifdef LL_GST_REPORT_STATE_CHANGES |
698 | LL_DEBUGS("MediaImpl") <<"NEW FRAME " << LL_ENDL; | ||
699 | #endif | ||
588 | if (mVideoSink->retained_frame_width != getMediaWidth() || | 700 | if (mVideoSink->retained_frame_width != getMediaWidth() || |
589 | mVideoSink->retained_frame_height != getMediaHeight()) | 701 | mVideoSink->retained_frame_height != getMediaHeight()) |
590 | // *TODO: also check for change in format | 702 | // *TODO: also check for change in format |
591 | { | 703 | { |
592 | // just resize container | 704 | // just resize containe |
593 | int neww = mVideoSink->retained_frame_width; | 705 | int neww = mVideoSink->retained_frame_width; |
594 | int newh = mVideoSink->retained_frame_height; | 706 | int newh = mVideoSink->retained_frame_height; |
595 | int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format]; | 707 | int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format]; |
@@ -604,8 +716,9 @@ updateMedia () | |||
604 | mTextureFormatType = LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV; | 716 | mTextureFormatType = LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV; |
605 | } | 717 | } |
606 | mMediaRowbytes = neww * newd; | 718 | mMediaRowbytes = neww * newd; |
607 | DEBUGMSG("video container resized to %dx%d", | 719 | LL_DEBUGS("MediaImpl") |
608 | neww, newh); | 720 | << "video container resized to " << |
721 | neww <<"x"<< newh << LL_ENDL; | ||
609 | 722 | ||
610 | delete[] mediaData; | 723 | delete[] mediaData; |
611 | mediaData = new unsigned char[mMediaRowbytes * | 724 | mediaData = new unsigned char[mMediaRowbytes * |
@@ -641,46 +754,119 @@ updateMedia () | |||
641 | 754 | ||
642 | /////////////////////////////////////////////////////////////////////////////// | 755 | /////////////////////////////////////////////////////////////////////////////// |
643 | // | 756 | // |
644 | bool | 757 | bool LLMediaImplGStreamer::stop() |
645 | LLMediaImplGStreamer:: | ||
646 | stop () | ||
647 | { | 758 | { |
648 | DEBUGMSG("stopping media..."); | 759 | LL_DEBUGS("MediaImpl") << "attempting to stop..." << LL_ENDL; |
649 | // todo: error-check this? | 760 | |
650 | llgst_element_set_state(mPlaybin, GST_STATE_READY); | 761 | if (!mPlaybin || mState == GST_STATE_NULL) |
651 | return true; | 762 | return true; |
763 | |||
764 | GstStateChangeReturn state_change; | ||
765 | |||
766 | state_change = gst_element_set_state(mPlaybin, GST_STATE_READY); | ||
767 | |||
768 | LL_DEBUGS("MediaImpl") << gst_element_state_change_return_get_name(state_change) << LL_ENDL; | ||
769 | |||
770 | if (state_change == GST_STATE_CHANGE_FAILURE) | ||
771 | { | ||
772 | LL_WARNS("MediaImpl") << "could not stop stream!" << LL_ENDL; | ||
773 | return false; | ||
774 | } | ||
775 | else | ||
776 | { | ||
777 | // Going into pending after play keeps dead streams from looping | ||
778 | (mState == GST_STATE_PLAYING) ? (mState = GST_STATE_VOID_PENDING) : (mState = GST_STATE_READY); | ||
779 | return true; | ||
780 | } | ||
652 | } | 781 | } |
653 | 782 | ||
654 | /////////////////////////////////////////////////////////////////////////////// | 783 | /////////////////////////////////////////////////////////////////////////////// |
655 | // | 784 | // |
656 | bool | 785 | bool LLMediaImplGStreamer::play() |
657 | LLMediaImplGStreamer:: | ||
658 | play () | ||
659 | { | 786 | { |
660 | DEBUGMSG("playing media..."); | 787 | LL_DEBUGS("MediaImpl") << "attempting to play..." << LL_ENDL; |
661 | // todo: error-check this? | 788 | |
662 | llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); | 789 | if (!mPlaybin || mState == GST_STATE_NULL) |
790 | return true; | ||
791 | |||
792 | |||
793 | if( getState() == GST_STATE_PLAYING ) | ||
794 | { | ||
795 | LL_DEBUGS("MediaImpl") << "... but already playing." << LL_ENDL; | ||
796 | return true; | ||
797 | } | ||
798 | |||
799 | // Clean up the existing thread, if any. | ||
800 | if( mPlayThread != NULL && mPlayThread->isStopped()) | ||
801 | { | ||
802 | delete mPlayThread; | ||
803 | mPlayThread = NULL; | ||
804 | } | ||
805 | |||
806 | if( mPlayThread == NULL ) | ||
807 | { | ||
808 | // Make a new thread to start playing. This keeps the viewer | ||
809 | // responsive while the stream is resolved and buffered. | ||
810 | mPlayThread = new LLGstPlayThread( (LLMediaImplCommon *)this, "GstPlayThread", NULL); | ||
811 | mPlayThread->start(); | ||
812 | } | ||
813 | |||
663 | return true; | 814 | return true; |
664 | } | 815 | } |
665 | 816 | ||
817 | |||
818 | void LLMediaImplGStreamer::startPlay() | ||
819 | { | ||
820 | GstStateChangeReturn state_change; | ||
821 | |||
822 | state_change = gst_element_set_state(mPlaybin, GST_STATE_PLAYING); | ||
823 | mState = GST_STATE_PLAYING; | ||
824 | |||
825 | LL_DEBUGS("MediaImpl") << gst_element_state_change_return_get_name(state_change) << LL_ENDL; | ||
826 | |||
827 | // Check to make sure playing was successful. If not, stop. | ||
828 | // NOTE: state_change is almost always GST_STATE_CHANGE_ASYNC | ||
829 | if (state_change == GST_STATE_CHANGE_FAILURE) | ||
830 | { | ||
831 | // If failing from a bad stream, go into an unknown | ||
832 | // state to stop bus_callback from looping back. | ||
833 | // We also force a stop in case the operations don't sync | ||
834 | setStatus(LLMediaBase::STATUS_UNKNOWN); | ||
835 | stop(); | ||
836 | } | ||
837 | } | ||
838 | |||
666 | /////////////////////////////////////////////////////////////////////////////// | 839 | /////////////////////////////////////////////////////////////////////////////// |
667 | // | 840 | // |
668 | bool | 841 | bool LLMediaImplGStreamer::pause() |
669 | LLMediaImplGStreamer:: | ||
670 | pause () | ||
671 | { | 842 | { |
672 | DEBUGMSG("pausing media..."); | 843 | LL_DEBUGS("MediaImpl") << "attempting to pause..." << LL_ENDL; |
673 | // todo: error-check this? | 844 | |
674 | llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); | 845 | if (!mPlaybin || mState == GST_STATE_NULL) |
675 | return true; | 846 | return true; |
847 | |||
848 | GstStateChangeReturn state_change; | ||
849 | |||
850 | state_change = gst_element_set_state(mPlaybin, GST_STATE_PAUSED); | ||
851 | |||
852 | LL_DEBUGS("MediaImpl") << gst_element_state_change_return_get_name(state_change) << LL_ENDL; | ||
853 | |||
854 | if (state_change == GST_STATE_CHANGE_FAILURE) | ||
855 | { | ||
856 | LL_WARNS("MediaImpl") << "could not pause stream!" << LL_ENDL; | ||
857 | return false; | ||
858 | } | ||
859 | else | ||
860 | { | ||
861 | mState = GST_STATE_PAUSED; | ||
862 | return true; | ||
863 | } | ||
676 | }; | 864 | }; |
677 | 865 | ||
678 | 866 | ||
679 | /////////////////////////////////////////////////////////////////////////////// | 867 | /////////////////////////////////////////////////////////////////////////////// |
680 | // virtual | 868 | // virtual |
681 | unsigned char* | 869 | unsigned char* LLMediaImplGStreamer::getMediaData() |
682 | LLMediaImplGStreamer:: | ||
683 | getMediaData () | ||
684 | { | 870 | { |
685 | return mediaData; | 871 | return mediaData; |
686 | } | 872 | } |
@@ -688,73 +874,26 @@ getMediaData () | |||
688 | 874 | ||
689 | /////////////////////////////////////////////////////////////////////////////// | 875 | /////////////////////////////////////////////////////////////////////////////// |
690 | // virtual | 876 | // virtual |
691 | bool | 877 | bool LLMediaImplGStreamer::seek(double time) |
692 | LLMediaImplGStreamer:: | ||
693 | seek( double time ) | ||
694 | { | 878 | { |
695 | bool success = false; | 879 | bool success = false; |
696 | if (mDoneInit && mPlaybin) | 880 | if (mPlaybin) |
697 | { | 881 | { |
698 | success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, | 882 | success = gst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, |
699 | GstSeekFlags(GST_SEEK_FLAG_FLUSH | | 883 | GstSeekFlags(GST_SEEK_FLAG_FLUSH | |
700 | GST_SEEK_FLAG_KEY_UNIT), | 884 | GST_SEEK_FLAG_KEY_UNIT), |
701 | GST_SEEK_TYPE_SET, gint64(time*GST_SECOND), | 885 | GST_SEEK_TYPE_SET, gint64(time*1000000000.0F), |
702 | GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); | 886 | GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); |
703 | } | 887 | } |
704 | DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d", | 888 | LL_DEBUGS("MediaImpl") << "MEDIA SEEK REQUEST to " << float(time) |
705 | float(time), int(success)); | 889 | << "sec result was " << int(success) << LL_ENDL; |
706 | return success; | 890 | return success; |
707 | } | 891 | } |
708 | 892 | ||
709 | bool | ||
710 | LLMediaImplGStreamer:: | ||
711 | getTimePos(double &sec_out) | ||
712 | { | ||
713 | bool got_position = false; | ||
714 | if (mPlaybin) | ||
715 | { | ||
716 | gint64 pos; | ||
717 | GstFormat timefmt = GST_FORMAT_TIME; | ||
718 | got_position = | ||
719 | llgst_element_query_position && | ||
720 | llgst_element_query_position(mPlaybin, | ||
721 | &timefmt, | ||
722 | &pos); | ||
723 | got_position = got_position | ||
724 | && (timefmt == GST_FORMAT_TIME); | ||
725 | // GStreamer may have other ideas, but we consider the current position | ||
726 | // undefined if not PLAYING or PAUSED | ||
727 | got_position = got_position && | ||
728 | (GST_STATE(mPlaybin) == GST_STATE_PLAYING || | ||
729 | GST_STATE(mPlaybin) == GST_STATE_PAUSED); | ||
730 | if (got_position && !GST_CLOCK_TIME_IS_VALID(pos)) | ||
731 | { | ||
732 | if (GST_STATE(mPlaybin) == GST_STATE_PLAYING) | ||
733 | { | ||
734 | // if we're playing then we treat an invalid clock time | ||
735 | // as 0, for complicated reasons (insert reason here) | ||
736 | pos = 0; | ||
737 | } | ||
738 | else | ||
739 | { | ||
740 | got_position = false; | ||
741 | } | ||
742 | |||
743 | } | ||
744 | // If all the preconditions succeeded... we can trust the result. | ||
745 | if (got_position) | ||
746 | { | ||
747 | sec_out = double(pos) / double(GST_SECOND); // gst to sec | ||
748 | } | ||
749 | } | ||
750 | return got_position; | ||
751 | } | ||
752 | 893 | ||
753 | /////////////////////////////////////////////////////////////////////////////// | 894 | /////////////////////////////////////////////////////////////////////////////// |
754 | // virtual | 895 | // virtual |
755 | bool | 896 | bool LLMediaImplGStreamer::setVolume(float volume) |
756 | LLMediaImplGStreamer:: | ||
757 | setVolume(float volume) | ||
758 | { | 897 | { |
759 | // we try to only update volume as conservatively as | 898 | // we try to only update volume as conservatively as |
760 | // possible, as many gst-plugins-base versions up to at least | 899 | // possible, as many gst-plugins-base versions up to at least |
@@ -763,7 +902,7 @@ setVolume(float volume) | |||
763 | return true; // nothing to do, everything's fine | 902 | return true; // nothing to do, everything's fine |
764 | 903 | ||
765 | mVolume = volume; | 904 | mVolume = volume; |
766 | if (mDoneInit && mPlaybin) | 905 | if (mPlaybin) |
767 | { | 906 | { |
768 | g_object_set(mPlaybin, "volume", mVolume, NULL); | 907 | g_object_set(mPlaybin, "volume", mVolume, NULL); |
769 | return true; | 908 | return true; |
@@ -772,4 +911,6 @@ setVolume(float volume) | |||
772 | return false; | 911 | return false; |
773 | } | 912 | } |
774 | 913 | ||
775 | #endif // LL_GSTREAMER_ENABLED | 914 | |
915 | |||
916 | ///#endif // LL_GSTREAMER_ENABLED | ||
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.h b/linden/indra/llmedia/llmediaimplgstreamer.h index 07b698d..baefdaf 100644 --- a/linden/indra/llmedia/llmediaimplgstreamer.h +++ b/linden/indra/llmedia/llmediaimplgstreamer.h | |||
@@ -18,8 +18,7 @@ | |||
18 | * There are special exceptions to the terms and conditions of the GPL as | 18 | * There are special exceptions to the terms and conditions of the GPL as |
19 | * it is applied to this Source Code. View the full text of the exception | 19 | * it is applied to this Source Code. View the full text of the exception |
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 20 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
21 | * online at | 21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception |
22 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
23 | * | 22 | * |
24 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
25 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -38,7 +37,7 @@ | |||
38 | #include "llmediaimplcommon.h" | 37 | #include "llmediaimplcommon.h" |
39 | #include "llmediaimplfactory.h" | 38 | #include "llmediaimplfactory.h" |
40 | 39 | ||
41 | #if LL_GSTREAMER_ENABLED | 40 | ///#if LL_GSTREAMER_ENABLED |
42 | 41 | ||
43 | extern "C" { | 42 | extern "C" { |
44 | #include <stdio.h> | 43 | #include <stdio.h> |
@@ -49,6 +48,7 @@ extern "C" { | |||
49 | } | 48 | } |
50 | 49 | ||
51 | #include "llmediaimplgstreamervidplug.h" | 50 | #include "llmediaimplgstreamervidplug.h" |
51 | #include "llgstplaythread.h" | ||
52 | 52 | ||
53 | class LLMediaManagerData; | 53 | class LLMediaManagerData; |
54 | class LLMediaImplMaker; | 54 | class LLMediaImplMaker; |
@@ -57,6 +57,8 @@ class LLMediaImplMaker; | |||
57 | class LLMediaImplGStreamer: | 57 | class LLMediaImplGStreamer: |
58 | public LLMediaImplCommon | 58 | public LLMediaImplCommon |
59 | { | 59 | { |
60 | friend class LLGstPlayThread; | ||
61 | |||
60 | public: | 62 | public: |
61 | LLMediaImplGStreamer (); | 63 | LLMediaImplGStreamer (); |
62 | virtual ~LLMediaImplGStreamer (); | 64 | virtual ~LLMediaImplGStreamer (); |
@@ -67,6 +69,26 @@ class LLMediaImplGStreamer: | |||
67 | static bool startup( LLMediaManagerData* init_data ); | 69 | static bool startup( LLMediaManagerData* init_data ); |
68 | static bool closedown(); | 70 | static bool closedown(); |
69 | 71 | ||
72 | // Sets GST_PLUGIN_PATH env var for GStreamer. | ||
73 | static void set_gst_plugin_path(); | ||
74 | |||
75 | /* virtual */ bool setDebugLevel( LLMediaBase::EDebugLevel level ); | ||
76 | |||
77 | // Function given to GStreamer for handling debug messages | ||
78 | static void gstreamer_log(GstDebugCategory *category, | ||
79 | GstDebugLevel level, | ||
80 | const gchar *file, | ||
81 | const gchar *function, | ||
82 | gint line, | ||
83 | GObject *object, | ||
84 | GstDebugMessage *message, | ||
85 | gpointer data) | ||
86 | #if __GNUC__ | ||
87 | // recommended by the gstreamer docs | ||
88 | G_GNUC_NO_INSTRUMENT | ||
89 | #endif | ||
90 | ; | ||
91 | |||
70 | /* virtual */ std::string getVersion(); | 92 | /* virtual */ std::string getVersion(); |
71 | /* virtual */ bool navigateTo( const std::string url ); | 93 | /* virtual */ bool navigateTo( const std::string url ); |
72 | /* virtual */ bool updateMedia(); | 94 | /* virtual */ bool updateMedia(); |
@@ -75,50 +97,50 @@ class LLMediaImplGStreamer: | |||
75 | /* virtual */ int getTextureFormatType() const; | 97 | /* virtual */ int getTextureFormatType() const; |
76 | /* virtual */ int getTextureFormatInternal() const; | 98 | /* virtual */ int getTextureFormatInternal() const; |
77 | /* virtual */ bool seek( double time ); | 99 | /* virtual */ bool seek( double time ); |
78 | /* virtual */ bool setVolume( float volume ); | 100 | /* virtual */ bool setVolume( float volume ); |
101 | |||
102 | LLMediaEmitter< LLMediaObserver > getEventEmitter() const {return mEventEmitter;}; | ||
79 | 103 | ||
80 | LLMediaEmitter< LLMediaObserver > getEventEmitter() const {return mEventEmitter;}; | 104 | protected: |
105 | |||
106 | void startPlay(); | ||
81 | 107 | ||
82 | // misc | ||
83 | bool pause(); | ||
84 | bool stop(); | ||
85 | bool play(); | ||
86 | bool getTimePos(double &sec_out); | ||
87 | static const double MIN_LOOP_SEC = 1.0F; | ||
88 | 108 | ||
89 | private: | 109 | private: |
90 | bool unload(); | ||
91 | 110 | ||
92 | static bool mDoneInit; | 111 | // misc |
112 | bool unload(); | ||
113 | bool pause(); | ||
114 | bool stop(); | ||
115 | bool play(); | ||
93 | 116 | ||
94 | guint mBusWatchID; | 117 | static gboolean bus_callback (GstBus *bus, |
118 | GstMessage *message, | ||
119 | gpointer data); | ||
95 | 120 | ||
96 | unsigned char* mediaData; | 121 | unsigned char* mediaData; |
97 | int mMediaRowbytes; | 122 | int mMediaRowbytes; |
98 | 123 | int mTextureFormatPrimary; | |
99 | int mTextureFormatPrimary; | 124 | int mTextureFormatType; |
100 | int mTextureFormatType; | ||
101 | 125 | ||
102 | // Very GStreamer-specific | 126 | // GStreamer-specific |
103 | GMainLoop *mPump; // event pump for this media | 127 | GMainLoop *mPump; // event pump for this media |
104 | GstElement *mPlaybin; | 128 | GstElement *mPlaybin; |
105 | GstSLVideo *mVideoSink; | 129 | GstSLVideo *mVideoSink; |
106 | }; | 130 | GstState mState; |
131 | GstState getState() const { return mState; } | ||
107 | 132 | ||
108 | extern "C" { | 133 | LLGstPlayThread *mPlayThread; |
109 | gboolean llmediaimplgstreamer_bus_callback (GstBus *bus, | 134 | }; |
110 | GstMessage *message, | ||
111 | gpointer data); | ||
112 | } | ||
113 | 135 | ||
114 | class LLMediaImplGStreamerMaker : public LLMediaImplMaker | 136 | class LLMediaImplGStreamerMaker : public LLMediaImplMaker |
115 | { | 137 | { |
116 | public: | 138 | public: |
117 | LLMediaImplGStreamerMaker(); | 139 | LLMediaImplGStreamerMaker(); |
118 | LLMediaImplGStreamer* create() | 140 | LLMediaImplGStreamer* create() |
119 | { | 141 | { |
120 | return new LLMediaImplGStreamer(); | 142 | return new LLMediaImplGStreamer(); |
121 | } | 143 | } |
122 | }; | 144 | }; |
123 | 145 | ||
124 | ///////////////////////////////////////////////////////////////////////// | 146 | ///////////////////////////////////////////////////////////////////////// |
@@ -135,6 +157,6 @@ public: | |||
135 | #define WARNMSG STDERRMSG | 157 | #define WARNMSG STDERRMSG |
136 | ///////////////////////////////////////////////////////////////////////// | 158 | ///////////////////////////////////////////////////////////////////////// |
137 | 159 | ||
138 | #endif // LL_GSTREAMER_ENABLED | 160 | ///#endif // LL_GSTREAMER_ENABLED |
139 | 161 | ||
140 | #endif // llmediaimplgstreamer_h | 162 | #endif // llmediaimplgstreamer_h |
diff --git a/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp b/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp deleted file mode 100644 index db26dda..0000000 --- a/linden/indra/llmedia/llmediaimplgstreamer_syms.cpp +++ /dev/null | |||
@@ -1,169 +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-2009, 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 | ||
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #if LL_GSTREAMER_ENABLED | ||
34 | |||
35 | extern "C" { | ||
36 | #include <gst/gst.h> | ||
37 | |||
38 | #include "apr_pools.h" | ||
39 | #include "apr_dso.h" | ||
40 | } | ||
41 | |||
42 | #include "llmediaimplgstreamer.h" | ||
43 | |||
44 | #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL | ||
45 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
46 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
47 | #undef LL_GST_SYM | ||
48 | |||
49 | // a couple of stubs for disgusting reasons | ||
50 | GstDebugCategory* | ||
51 | ll_gst_debug_category_new(gchar *name, guint color, gchar *description) | ||
52 | { | ||
53 | static GstDebugCategory dummy; | ||
54 | return &dummy; | ||
55 | } | ||
56 | void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname) | ||
57 | { | ||
58 | } | ||
59 | |||
60 | static bool sSymsGrabbed = false; | ||
61 | static apr_pool_t *sSymGSTDSOMemoryPool = NULL; | ||
62 | static apr_dso_handle_t *sSymGSTDSOHandleG = NULL; | ||
63 | static apr_dso_handle_t *sSymGSTDSOHandleV = NULL; | ||
64 | |||
65 | |||
66 | bool grab_gst_syms(std::string gst_dso_name, | ||
67 | std::string gst_dso_name_vid) | ||
68 | { | ||
69 | if (sSymsGrabbed) | ||
70 | { | ||
71 | // already have grabbed good syms | ||
72 | return TRUE; | ||
73 | } | ||
74 | |||
75 | bool sym_error = false; | ||
76 | bool rtn = false; | ||
77 | apr_status_t rv; | ||
78 | apr_dso_handle_t *sSymGSTDSOHandle = NULL; | ||
79 | |||
80 | #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) | ||
81 | |||
82 | //attempt to load the shared libraries | ||
83 | apr_pool_create(&sSymGSTDSOMemoryPool, NULL); | ||
84 | |||
85 | if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, | ||
86 | gst_dso_name.c_str(), | ||
87 | sSymGSTDSOMemoryPool) )) | ||
88 | { | ||
89 | INFOMSG("Found DSO: %s", gst_dso_name.c_str()); | ||
90 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
91 | |||
92 | if ( sSymGSTDSOHandle ) | ||
93 | { | ||
94 | sSymGSTDSOHandleG = sSymGSTDSOHandle; | ||
95 | sSymGSTDSOHandle = NULL; | ||
96 | } | ||
97 | |||
98 | if ( APR_SUCCESS == | ||
99 | (rv = apr_dso_load(&sSymGSTDSOHandle, | ||
100 | gst_dso_name_vid.c_str(), | ||
101 | sSymGSTDSOMemoryPool) )) | ||
102 | { | ||
103 | INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str()); | ||
104 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
105 | rtn = !sym_error; | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str()); | ||
110 | rtn = false; // failure | ||
111 | } | ||
112 | } | ||
113 | else | ||
114 | { | ||
115 | INFOMSG("Couldn't load DSO: %s", gst_dso_name.c_str()); | ||
116 | rtn = false; // failure | ||
117 | } | ||
118 | |||
119 | if (sym_error) | ||
120 | { | ||
121 | WARNMSG("Failed to find necessary symbols in GStreamer libraries."); | ||
122 | } | ||
123 | |||
124 | if ( sSymGSTDSOHandle ) | ||
125 | { | ||
126 | sSymGSTDSOHandleV = sSymGSTDSOHandle; | ||
127 | sSymGSTDSOHandle = NULL; | ||
128 | } | ||
129 | #undef LL_GST_SYM | ||
130 | |||
131 | sSymsGrabbed = !!rtn; | ||
132 | return rtn; | ||
133 | } | ||
134 | |||
135 | |||
136 | void ungrab_gst_syms() | ||
137 | { | ||
138 | // should be safe to call regardless of whether we've | ||
139 | // actually grabbed syms. | ||
140 | |||
141 | if ( sSymGSTDSOHandleG ) | ||
142 | { | ||
143 | apr_dso_unload(sSymGSTDSOHandleG); | ||
144 | sSymGSTDSOHandleG = NULL; | ||
145 | } | ||
146 | |||
147 | if ( sSymGSTDSOHandleV ) | ||
148 | { | ||
149 | apr_dso_unload(sSymGSTDSOHandleV); | ||
150 | sSymGSTDSOHandleV = NULL; | ||
151 | } | ||
152 | |||
153 | if ( sSymGSTDSOMemoryPool ) | ||
154 | { | ||
155 | apr_pool_destroy(sSymGSTDSOMemoryPool); | ||
156 | sSymGSTDSOMemoryPool = NULL; | ||
157 | } | ||
158 | |||
159 | // NULL-out all of the symbols we'd grabbed | ||
160 | #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0) | ||
161 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
162 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
163 | #undef LL_GST_SYM | ||
164 | |||
165 | sSymsGrabbed = false; | ||
166 | } | ||
167 | |||
168 | |||
169 | #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 4220bdb..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-2009, 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 | ||
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #include "linden_common.h" | ||
34 | |||
35 | #if LL_GSTREAMER_ENABLED | ||
36 | |||
37 | extern "C" { | ||
38 | #include <gst/gst.h> | ||
39 | } | ||
40 | |||
41 | bool grab_gst_syms(std::string gst_dso_name, | ||
42 | std::string gst_dso_name_vid); | ||
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_rawv.inc" | ||
48 | #undef LL_GST_SYM | ||
49 | |||
50 | // regrettable hacks to give us better runtime compatibility with older systems | ||
51 | #define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0) | ||
52 | #define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0) | ||
53 | |||
54 | // regrettable hacks because GStreamer was not designed for runtime loading | ||
55 | #undef GST_TYPE_MESSAGE | ||
56 | #define GST_TYPE_MESSAGE (llgst_message_get_type()) | ||
57 | #undef GST_TYPE_OBJECT | ||
58 | #define GST_TYPE_OBJECT (llgst_object_get_type()) | ||
59 | #undef GST_TYPE_PIPELINE | ||
60 | #define GST_TYPE_PIPELINE (llgst_pipeline_get_type()) | ||
61 | #undef GST_TYPE_ELEMENT | ||
62 | #define GST_TYPE_ELEMENT (llgst_element_get_type()) | ||
63 | #undef GST_TYPE_VIDEO_SINK | ||
64 | #define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type()) | ||
65 | // more regrettable hacks to stub-out these .h-exposed GStreamer internals | ||
66 | void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname); | ||
67 | #undef _gst_debug_register_funcptr | ||
68 | #define _gst_debug_register_funcptr ll_gst_debug_register_funcptr | ||
69 | GstDebugCategory* ll_gst_debug_category_new(gchar *name, guint color, gchar *description); | ||
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 b81872a..0000000 --- a/linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc +++ /dev/null | |||
@@ -1,46 +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_object_unref, void, gpointer object); | ||
11 | LL_GST_SYM(true, gst_object_get_type, GType, void); | ||
12 | LL_GST_SYM(true, gst_pipeline_get_type, GType, void); | ||
13 | LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline); | ||
14 | LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data); | ||
15 | LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name); | ||
16 | LL_GST_SYM(true, gst_element_get_type, GType, void); | ||
17 | LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template); | ||
18 | LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp); | ||
19 | LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details); | ||
20 | LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps); | ||
21 | LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps); | ||
22 | LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps); | ||
23 | LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string); | ||
24 | LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps); | ||
25 | LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index); | ||
26 | LL_GST_SYM(true, gst_caps_copy, GstCaps *, const GstCaps * caps); | ||
27 | LL_GST_SYM(true, gst_caps_intersect, GstCaps *, const GstCaps *caps1, const GstCaps *caps2); | ||
28 | LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type); | ||
29 | LL_GST_SYM(true, _gst_plugin_register_static, void, GstPluginDesc *desc); | ||
30 | LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value); | ||
31 | LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname); | ||
32 | LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value); | ||
33 | LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value); | ||
34 | LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure); | ||
35 | LL_GST_SYM(true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64); | ||
36 | |||
37 | // optional symbols to grab | ||
38 | LL_GST_SYM(false, gst_registry_fork_set_enabled, void, gboolean enabled); | ||
39 | LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled); | ||
40 | LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent); | ||
41 | LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug); | ||
42 | LL_GST_SYM(false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur); | ||
43 | |||
44 | // GStreamer 'internal' symbols which may not be visible in some runtimes but are still used in expanded GStreamer header macros - yuck! We'll substitute our own stubs for these. | ||
45 | //LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname); | ||
46 | //LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description); | ||
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 5e96666..36c503a 100644 --- a/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp +++ b/linden/indra/llmedia/llmediaimplgstreamervidplug.cpp | |||
@@ -30,7 +30,7 @@ | |||
30 | * $/LicenseInfo$ | 30 | * $/LicenseInfo$ |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #if LL_GSTREAMER_ENABLED | 33 | ///#if LL_GSTREAMER_ENABLED |
34 | 34 | ||
35 | #include "linden_common.h" | 35 | #include "linden_common.h" |
36 | 36 | ||
@@ -38,8 +38,6 @@ | |||
38 | #include <gst/video/video.h> | 38 | #include <gst/video/video.h> |
39 | #include <gst/video/gstvideosink.h> | 39 | #include <gst/video/gstvideosink.h> |
40 | 40 | ||
41 | #include "llmediaimplgstreamer_syms.h" | ||
42 | |||
43 | #include "llthread.h" | 41 | #include "llthread.h" |
44 | 42 | ||
45 | #include "llmediaimplgstreamervidplug.h" | 43 | #include "llmediaimplgstreamervidplug.h" |
@@ -89,9 +87,9 @@ gst_slvideo_base_init (gpointer gclass) | |||
89 | }; | 87 | }; |
90 | GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); | 88 | GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); |
91 | 89 | ||
92 | llgst_element_class_add_pad_template (element_class, | 90 | gst_element_class_add_pad_template (element_class, |
93 | llgst_static_pad_template_get (&sink_factory)); | 91 | gst_static_pad_template_get (&sink_factory)); |
94 | llgst_element_class_set_details (element_class, &element_details); | 92 | gst_element_class_set_details (element_class, &element_details); |
95 | } | 93 | } |
96 | 94 | ||
97 | 95 | ||
@@ -102,7 +100,7 @@ gst_slvideo_finalize (GObject * object) | |||
102 | slvideo = GST_SLVIDEO (object); | 100 | slvideo = GST_SLVIDEO (object); |
103 | if (slvideo->caps) | 101 | if (slvideo->caps) |
104 | { | 102 | { |
105 | llgst_caps_unref(slvideo->caps); | 103 | gst_caps_unref(slvideo->caps); |
106 | } | 104 | } |
107 | 105 | ||
108 | G_OBJECT_CLASS(parent_class)->finalize (object); | 106 | G_OBJECT_CLASS(parent_class)->finalize (object); |
@@ -113,7 +111,7 @@ static GstFlowReturn | |||
113 | gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) | 111 | gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) |
114 | { | 112 | { |
115 | GstSLVideo *slvideo; | 113 | GstSLVideo *slvideo; |
116 | llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); | 114 | g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); |
117 | 115 | ||
118 | slvideo = GST_SLVIDEO(bsink); | 116 | slvideo = GST_SLVIDEO(bsink); |
119 | 117 | ||
@@ -206,7 +204,7 @@ gst_slvideo_get_caps (GstBaseSink * bsink) | |||
206 | GstSLVideo *slvideo; | 204 | GstSLVideo *slvideo; |
207 | slvideo = GST_SLVIDEO(bsink); | 205 | slvideo = GST_SLVIDEO(bsink); |
208 | 206 | ||
209 | return llgst_caps_ref (slvideo->caps); | 207 | return gst_caps_ref (slvideo->caps); |
210 | } | 208 | } |
211 | 209 | ||
212 | 210 | ||
@@ -222,35 +220,36 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) | |||
222 | 220 | ||
223 | filter = GST_SLVIDEO(bsink); | 221 | filter = GST_SLVIDEO(bsink); |
224 | 222 | ||
225 | intersection = llgst_caps_intersect (filter->caps, caps); | 223 | intersection = gst_caps_intersect (filter->caps, caps); |
226 | if (llgst_caps_is_empty (intersection)) | 224 | if (gst_caps_is_empty (intersection)) |
227 | { | 225 | { |
228 | // no overlap between our caps and requested caps | 226 | // no overlap between our caps and requested caps |
229 | return FALSE; | 227 | return FALSE; |
230 | } | 228 | } |
231 | llgst_caps_unref(intersection); | 229 | gst_caps_unref(intersection); |
232 | 230 | ||
233 | int width, height; | 231 | int width = 0; |
232 | int height = 0; | ||
234 | gboolean ret; | 233 | gboolean ret; |
235 | const GValue *fps; | 234 | const GValue *fps; |
236 | const GValue *par; | 235 | const GValue *par; |
237 | structure = llgst_caps_get_structure (caps, 0); | 236 | structure = gst_caps_get_structure (caps, 0); |
238 | ret = llgst_structure_get_int (structure, "width", &width); | 237 | ret = gst_structure_get_int (structure, "width", &width); |
239 | ret = ret && llgst_structure_get_int (structure, "height", &height); | 238 | ret = ret && gst_structure_get_int (structure, "height", &height); |
240 | fps = llgst_structure_get_value (structure, "framerate"); | 239 | fps = gst_structure_get_value (structure, "framerate"); |
241 | ret = ret && (fps != NULL); | 240 | ret = ret && (fps != NULL); |
242 | par = llgst_structure_get_value (structure, "pixel-aspect-ratio"); | 241 | par = gst_structure_get_value (structure, "pixel-aspect-ratio"); |
243 | if (!ret) | 242 | if (!ret) |
244 | return FALSE; | 243 | return FALSE; |
245 | 244 | ||
246 | filter->width = width; | 245 | filter->width = width; |
247 | filter->height = height; | 246 | filter->height = height; |
248 | filter->fps_n = llgst_value_get_fraction_numerator(fps); | 247 | filter->fps_n = gst_value_get_fraction_numerator(fps); |
249 | filter->fps_d = llgst_value_get_fraction_denominator(fps); | 248 | filter->fps_d = gst_value_get_fraction_denominator(fps); |
250 | if (par) | 249 | if (par) |
251 | { | 250 | { |
252 | filter->par_n = llgst_value_get_fraction_numerator(par); | 251 | filter->par_n = gst_value_get_fraction_numerator(par); |
253 | filter->par_d = llgst_value_get_fraction_denominator(par); | 252 | filter->par_d = gst_value_get_fraction_denominator(par); |
254 | } | 253 | } |
255 | else | 254 | else |
256 | { | 255 | { |
@@ -261,15 +260,15 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) | |||
261 | GST_VIDEO_SINK_HEIGHT(filter) = height; | 260 | GST_VIDEO_SINK_HEIGHT(filter) = height; |
262 | 261 | ||
263 | filter->format = SLV_PF_UNKNOWN; | 262 | filter->format = SLV_PF_UNKNOWN; |
264 | if (0 == strcmp(llgst_structure_get_name(structure), | 263 | if (0 == strcmp(gst_structure_get_name(structure), |
265 | "video/x-raw-rgb")) | 264 | "video/x-raw-rgb")) |
266 | { | 265 | { |
267 | int red_mask; | 266 | int red_mask; |
268 | int green_mask; | 267 | int green_mask; |
269 | int blue_mask; | 268 | int blue_mask; |
270 | llgst_structure_get_int(structure, "red_mask", &red_mask); | 269 | gst_structure_get_int(structure, "red_mask", &red_mask); |
271 | llgst_structure_get_int(structure, "green_mask", &green_mask); | 270 | gst_structure_get_int(structure, "green_mask", &green_mask); |
272 | llgst_structure_get_int(structure, "blue_mask", &blue_mask); | 271 | gst_structure_get_int(structure, "blue_mask", &blue_mask); |
273 | if ((unsigned int)red_mask == 0xFF000000 && | 272 | if ((unsigned int)red_mask == 0xFF000000 && |
274 | (unsigned int)green_mask == 0x00FF0000 && | 273 | (unsigned int)green_mask == 0x00FF0000 && |
275 | (unsigned int)blue_mask == 0x0000FF00) | 274 | (unsigned int)blue_mask == 0x0000FF00) |
@@ -360,9 +359,9 @@ gst_slvideo_update_caps (GstSLVideo * slvideo) | |||
360 | // GStreamer will automatically convert colourspace if necessary. | 359 | // GStreamer will automatically convert colourspace if necessary. |
361 | // GStreamer will automatically resize media to one of these enumerated | 360 | // GStreamer will automatically resize media to one of these enumerated |
362 | // powers-of-two that we ask for (yay GStreamer!) | 361 | // powers-of-two that we ask for (yay GStreamer!) |
363 | caps = llgst_caps_from_string (SLV_ALLCAPS); | 362 | caps = gst_caps_from_string (SLV_ALLCAPS); |
364 | 363 | ||
365 | llgst_caps_replace (&slvideo->caps, caps); | 364 | gst_caps_replace (&slvideo->caps, caps); |
366 | } | 365 | } |
367 | 366 | ||
368 | 367 | ||
@@ -395,12 +394,10 @@ static void | |||
395 | gst_slvideo_set_property (GObject * object, guint prop_id, | 394 | gst_slvideo_set_property (GObject * object, guint prop_id, |
396 | const GValue * value, GParamSpec * pspec) | 395 | const GValue * value, GParamSpec * pspec) |
397 | { | 396 | { |
398 | llg_return_if_fail (GST_IS_SLVIDEO (object)); | 397 | g_return_if_fail (GST_IS_SLVIDEO (object)); |
399 | 398 | ||
400 | switch (prop_id) { | 399 | if (prop_id) { |
401 | default: | ||
402 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 400 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
403 | break; | ||
404 | } | 401 | } |
405 | } | 402 | } |
406 | 403 | ||
@@ -408,12 +405,10 @@ static void | |||
408 | gst_slvideo_get_property (GObject * object, guint prop_id, | 405 | gst_slvideo_get_property (GObject * object, guint prop_id, |
409 | GValue * value, GParamSpec * pspec) | 406 | GValue * value, GParamSpec * pspec) |
410 | { | 407 | { |
411 | llg_return_if_fail (GST_IS_SLVIDEO (object)); | 408 | g_return_if_fail (GST_IS_SLVIDEO (object)); |
412 | 409 | ||
413 | switch (prop_id) { | 410 | if (prop_id) { |
414 | default: | ||
415 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 411 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
416 | break; | ||
417 | } | 412 | } |
418 | } | 413 | } |
419 | 414 | ||
@@ -431,29 +426,23 @@ plugin_init (GstPlugin * plugin) | |||
431 | GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", | 426 | GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", |
432 | 0, (gchar*)"Second Life Video Sink"); | 427 | 0, (gchar*)"Second Life Video Sink"); |
433 | 428 | ||
434 | return llgst_element_register (plugin, "private-slvideo", | 429 | return gst_element_register (plugin, "private-slvideo", |
435 | GST_RANK_NONE, GST_TYPE_SLVIDEO); | 430 | GST_RANK_NONE, GST_TYPE_SLVIDEO); |
436 | } | 431 | } |
437 | 432 | ||
438 | /* this is the structure that gstreamer looks for to register plugins | 433 | |
439 | */ | ||
440 | /* NOTE: Can't rely upon GST_PLUGIN_DEFINE_STATIC to self-register, since | ||
441 | some g++ versions buggily avoid __attribute__((constructor)) functions - | ||
442 | so we provide an explicit plugin init function. | ||
443 | */ | ||
444 | void gst_slvideo_init_class (void) | 434 | void gst_slvideo_init_class (void) |
445 | { | 435 | { |
446 | #define PACKAGE "packagehack" | 436 | gst_plugin_register_static( GST_VERSION_MAJOR, |
447 | static GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, | 437 | GST_VERSION_MINOR, |
448 | GST_VERSION_MINOR, | 438 | "private-slvideoplugin", |
449 | "private-slvideoplugin", | 439 | "SL Video sink plugin", |
450 | "SL Video sink plugin", | 440 | plugin_init, |
451 | plugin_init, "0.1", GST_LICENSE_UNKNOWN, | 441 | "0.1", |
452 | "Second Life", | 442 | GST_LICENSE_UNKNOWN, |
453 | "http://www.secondlife.com/"); | 443 | "Second Life", |
454 | #undef PACKAGE | 444 | "Second Life", |
455 | ll_gst_plugin_register_static (&gst_plugin_desc); | 445 | "http://www.secondlife.com/" ); |
456 | //fprintf(stderr, "\n\n\nCLASS INIT\n\n\n"); | ||
457 | } | 446 | } |
458 | 447 | ||
459 | #endif // LL_GSTREAMER_ENABLED | 448 | ///#endif // LL_GSTREAMER_ENABLED |
diff --git a/linden/indra/llmedia/llmediaimplgstreamervidplug.h b/linden/indra/llmedia/llmediaimplgstreamervidplug.h index 3db064c..3a984a9 100644 --- a/linden/indra/llmedia/llmediaimplgstreamervidplug.h +++ b/linden/indra/llmedia/llmediaimplgstreamervidplug.h | |||
@@ -33,12 +33,13 @@ | |||
33 | #ifndef __GST_SLVIDEO_H__ | 33 | #ifndef __GST_SLVIDEO_H__ |
34 | #define __GST_SLVIDEO_H__ | 34 | #define __GST_SLVIDEO_H__ |
35 | 35 | ||
36 | #if LL_GSTREAMER_ENABLED | 36 | ///#if LL_GSTREAMER_ENABLED |
37 | 37 | ||
38 | extern "C" { | 38 | extern "C" { |
39 | #include <gst/gst.h> | 39 | #include <gst/gst.h> |
40 | #include <gst/video/video.h> | 40 | #include <gst/video/video.h> |
41 | #include <gst/video/gstvideosink.h> | 41 | #include <gst/video/gstvideosink.h> |
42 | #include <glib/gthread.h> | ||
42 | } | 43 | } |
43 | 44 | ||
44 | G_BEGIN_DECLS | 45 | G_BEGIN_DECLS |
@@ -100,6 +101,6 @@ void gst_slvideo_init_class (void); | |||
100 | 101 | ||
101 | G_END_DECLS | 102 | G_END_DECLS |
102 | 103 | ||
103 | #endif // LL_GSTREAMER_ENABLED | 104 | ///#endif // LL_GSTREAMER_ENABLED |
104 | 105 | ||
105 | #endif /* __GST_SLVIDEO_H__ */ | 106 | #endif /* __GST_SLVIDEO_H__ */ |
diff --git a/linden/indra/llmedia/llmediamanager.cpp b/linden/indra/llmedia/llmediamanager.cpp index e1c7608..48da808 100644 --- a/linden/indra/llmedia/llmediamanager.cpp +++ b/linden/indra/llmedia/llmediamanager.cpp | |||
@@ -31,16 +31,29 @@ | |||
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include "llmediamanager.h" | 33 | #include "llmediamanager.h" |
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 | #include "llmediaimplgstreamer.h" | ||
42 | #if LL_WINDOWS | ||
43 | #pragma warning(default : 4244) | ||
44 | #endif | ||
45 | |||
34 | #include "llmediaimplfactory.h" | 46 | #include "llmediaimplfactory.h" |
35 | 47 | ||
36 | #include "llmediaimplexample1.h" | 48 | #include "llmediaimplexample1.h" |
37 | #include "llmediaimplexample2.h" | 49 | #include "llmediaimplexample2.h" |
38 | #include "llmediaimplquicktime.h" | 50 | #include "llmediaimplquicktime.h" |
39 | #include "llmediaimplgstreamer.h" | 51 | |
40 | #if LL_LLMOZLIB_ENABLED | 52 | #if LL_LLMOZLIB_ENABLED |
41 | # include "llmediaimplllmozlib.h" | 53 | # include "llmediaimplllmozlib.h" |
42 | #endif | 54 | #endif |
43 | 55 | ||
56 | #include "llerror.h" | ||
44 | LLMediaManager* LLMediaManager::sInstance = 0; | 57 | LLMediaManager* LLMediaManager::sInstance = 0; |
45 | 58 | ||
46 | 59 | ||
@@ -76,6 +89,7 @@ void LLMediaManager::initClass( LLMediaManagerData* init_data ) | |||
76 | if ( ! sInstance ) | 89 | if ( ! sInstance ) |
77 | sInstance = new LLMediaManager(); | 90 | sInstance = new LLMediaManager(); |
78 | 91 | ||
92 | LL_DEBUGS("MediaManager") << "LLMediaManager::initClass" << LL_ENDL; | ||
79 | // Initialize impl classes here - this breaks the encapsulation model | 93 | // Initialize impl classes here - this breaks the encapsulation model |
80 | // but some of the initialization takes a long time and we only want to | 94 | // but some of the initialization takes a long time and we only want to |
81 | // do it once at app startup before any of the impls have been created | 95 | // do it once at app startup before any of the impls have been created |
@@ -85,12 +99,14 @@ void LLMediaManager::initClass( LLMediaManagerData* init_data ) | |||
85 | LLMediaImplExample2::startup( init_data ); | 99 | LLMediaImplExample2::startup( init_data ); |
86 | 100 | ||
87 | #if LL_QUICKTIME_ENABLED | 101 | #if LL_QUICKTIME_ENABLED |
102 | LL_DEBUGS("MediaManager") << "LLMediaManager::initClass: starting quicktime." << LL_ENDL; | ||
88 | LLMediaImplQuickTime::startup( init_data ); | 103 | LLMediaImplQuickTime::startup( init_data ); |
89 | #endif // LL_QUICKTIME_ENABLED | 104 | #endif // LL_QUICKTIME_ENABLED |
90 | 105 | ||
91 | #if LL_GSTREAMER_ENABLED | 106 | ///#if LL_GSTREAMER_ENABLED |
107 | LL_DEBUGS("MediaManager") << "LLMediaManager::initClass: starting gstreamer" << LL_ENDL; | ||
92 | LLMediaImplGStreamer::startup( init_data ); | 108 | LLMediaImplGStreamer::startup( init_data ); |
93 | #endif // LL_GSTREAMER_ENABLED | 109 | ///#endif // LL_GSTREAMER_ENABLED |
94 | } | 110 | } |
95 | 111 | ||
96 | //////////////////////////////////////////////////////////////////////////////// | 112 | //////////////////////////////////////////////////////////////////////////////// |
@@ -130,9 +146,9 @@ void LLMediaManager::cleanupClass() | |||
130 | LLMediaImplQuickTime::closedown(); | 146 | LLMediaImplQuickTime::closedown(); |
131 | #endif // LL_QUICKTIME_ENABLED | 147 | #endif // LL_QUICKTIME_ENABLED |
132 | 148 | ||
133 | #if LL_GSTREAMER_ENABLED | 149 | ///#if LL_GSTREAMER_ENABLED |
134 | LLMediaImplGStreamer::closedown(); | 150 | LLMediaImplGStreamer::closedown(); |
135 | #endif // LL_QUICKTIME_ENABLED | 151 | ///#endif // LL_QUICKTIME_ENABLED |
136 | 152 | ||
137 | if ( sInstance ) | 153 | if ( sInstance ) |
138 | delete sInstance; | 154 | delete sInstance; |