diff options
Diffstat (limited to '')
12 files changed, 440 insertions, 584 deletions
diff --git a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt index 6eab49c..a031157 100644 --- a/linden/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/linden/indra/media_plugins/gstreamer010/CMakeLists.txt | |||
@@ -44,13 +44,11 @@ endif (NOT CMAKE_SIZEOF_VOID_P MATCHES 4) | |||
44 | 44 | ||
45 | set(media_plugin_gstreamer010_SOURCE_FILES | 45 | set(media_plugin_gstreamer010_SOURCE_FILES |
46 | media_plugin_gstreamer010.cpp | 46 | media_plugin_gstreamer010.cpp |
47 | llmediaimplgstreamer_syms.cpp | ||
48 | llmediaimplgstreamervidplug.cpp | 47 | llmediaimplgstreamervidplug.cpp |
49 | ) | 48 | ) |
50 | 49 | ||
51 | set(media_plugin_gstreamer010_HEADER_FILES | 50 | set(media_plugin_gstreamer010_HEADER_FILES |
52 | llmediaimplgstreamervidplug.h | 51 | llmediaimplgstreamervidplug.h |
53 | llmediaimplgstreamer_syms.h | ||
54 | llmediaimplgstreamertriviallogging.h | 52 | llmediaimplgstreamertriviallogging.h |
55 | ) | 53 | ) |
56 | 54 | ||
diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp deleted file mode 100755 index 82978ad..0000000 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp +++ /dev/null | |||
@@ -1,174 +0,0 @@ | |||
1 | /** | ||
2 | * @file llmediaimplgstreamer_syms.cpp | ||
3 | * @brief dynamic GStreamer symbol-grabbing code | ||
4 | * | ||
5 | * @cond | ||
6 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | ||
7 | * | ||
8 | * Copyright (c) 2007-2010, Linden Research, Inc. | ||
9 | * | ||
10 | * Second Life Viewer Source Code | ||
11 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
12 | * to you under the terms of the GNU General Public License, version 2.0 | ||
13 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
14 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
16 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
17 | * | ||
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 | ||
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
21 | * online at | ||
22 | * http://secondlife.com/developers/opensource/flossexception | ||
23 | * | ||
24 | * By copying, modifying or distributing this software, you acknowledge | ||
25 | * that you have read and understood your obligations described above, | ||
26 | * and agree to abide by those obligations. | ||
27 | * | ||
28 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
29 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
30 | * COMPLETENESS OR PERFORMANCE. | ||
31 | * $/LicenseInfo$ | ||
32 | * | ||
33 | * @endcond | ||
34 | */ | ||
35 | |||
36 | #if LL_GSTREAMER010_ENABLED | ||
37 | |||
38 | #include <string> | ||
39 | |||
40 | extern "C" { | ||
41 | #include <gst/gst.h> | ||
42 | |||
43 | #include "apr_pools.h" | ||
44 | #include "apr_dso.h" | ||
45 | } | ||
46 | |||
47 | #include "llmediaimplgstreamertriviallogging.h" | ||
48 | |||
49 | #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) RTN (*ll##GSTSYM)(__VA_ARGS__) = NULL | ||
50 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
51 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
52 | #undef LL_GST_SYM | ||
53 | |||
54 | // a couple of stubs for disgusting reasons | ||
55 | GstDebugCategory* | ||
56 | ll_gst_debug_category_new(gchar *name, guint color, gchar *description) | ||
57 | { | ||
58 | static GstDebugCategory dummy; | ||
59 | return &dummy; | ||
60 | } | ||
61 | void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname) | ||
62 | { | ||
63 | } | ||
64 | |||
65 | static bool sSymsGrabbed = false; | ||
66 | static apr_pool_t *sSymGSTDSOMemoryPool = NULL; | ||
67 | static apr_dso_handle_t *sSymGSTDSOHandleG = NULL; | ||
68 | static apr_dso_handle_t *sSymGSTDSOHandleV = NULL; | ||
69 | |||
70 | |||
71 | bool grab_gst_syms(std::string gst_dso_name, | ||
72 | std::string gst_dso_name_vid) | ||
73 | { | ||
74 | if (sSymsGrabbed) | ||
75 | { | ||
76 | // already have grabbed good syms | ||
77 | return TRUE; | ||
78 | } | ||
79 | |||
80 | bool sym_error = false; | ||
81 | bool rtn = false; | ||
82 | apr_status_t rv; | ||
83 | apr_dso_handle_t *sSymGSTDSOHandle = NULL; | ||
84 | |||
85 | #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) | ||
86 | |||
87 | //attempt to load the shared libraries | ||
88 | apr_pool_create(&sSymGSTDSOMemoryPool, NULL); | ||
89 | |||
90 | if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, | ||
91 | gst_dso_name.c_str(), | ||
92 | sSymGSTDSOMemoryPool) )) | ||
93 | { | ||
94 | INFOMSG("Found DSO: %s", gst_dso_name.c_str()); | ||
95 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
96 | |||
97 | if ( sSymGSTDSOHandle ) | ||
98 | { | ||
99 | sSymGSTDSOHandleG = sSymGSTDSOHandle; | ||
100 | sSymGSTDSOHandle = NULL; | ||
101 | } | ||
102 | |||
103 | if ( APR_SUCCESS == | ||
104 | (rv = apr_dso_load(&sSymGSTDSOHandle, | ||
105 | gst_dso_name_vid.c_str(), | ||
106 | sSymGSTDSOMemoryPool) )) | ||
107 | { | ||
108 | INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str()); | ||
109 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
110 | rtn = !sym_error; | ||
111 | } | ||
112 | else | ||
113 | { | ||
114 | INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str()); | ||
115 | rtn = false; // failure | ||
116 | } | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 | INFOMSG("Couldn't load DSO: %s", gst_dso_name.c_str()); | ||
121 | rtn = false; // failure | ||
122 | } | ||
123 | |||
124 | if (sym_error) | ||
125 | { | ||
126 | WARNMSG("Failed to find necessary symbols in GStreamer libraries."); | ||
127 | } | ||
128 | |||
129 | if ( sSymGSTDSOHandle ) | ||
130 | { | ||
131 | sSymGSTDSOHandleV = sSymGSTDSOHandle; | ||
132 | sSymGSTDSOHandle = NULL; | ||
133 | } | ||
134 | #undef LL_GST_SYM | ||
135 | |||
136 | sSymsGrabbed = !!rtn; | ||
137 | return rtn; | ||
138 | } | ||
139 | |||
140 | |||
141 | void ungrab_gst_syms() | ||
142 | { | ||
143 | // should be safe to call regardless of whether we've | ||
144 | // actually grabbed syms. | ||
145 | |||
146 | if ( sSymGSTDSOHandleG ) | ||
147 | { | ||
148 | apr_dso_unload(sSymGSTDSOHandleG); | ||
149 | sSymGSTDSOHandleG = NULL; | ||
150 | } | ||
151 | |||
152 | if ( sSymGSTDSOHandleV ) | ||
153 | { | ||
154 | apr_dso_unload(sSymGSTDSOHandleV); | ||
155 | sSymGSTDSOHandleV = NULL; | ||
156 | } | ||
157 | |||
158 | if ( sSymGSTDSOMemoryPool ) | ||
159 | { | ||
160 | apr_pool_destroy(sSymGSTDSOMemoryPool); | ||
161 | sSymGSTDSOMemoryPool = NULL; | ||
162 | } | ||
163 | |||
164 | // NULL-out all of the symbols we'd grabbed | ||
165 | #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0) | ||
166 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
167 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
168 | #undef LL_GST_SYM | ||
169 | |||
170 | sSymsGrabbed = false; | ||
171 | } | ||
172 | |||
173 | |||
174 | #endif // LL_GSTREAMER010_ENABLED | ||
diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h deleted file mode 100755 index c309043..0000000 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h +++ /dev/null | |||
@@ -1,81 +0,0 @@ | |||
1 | /** | ||
2 | * @file llmediaimplgstreamer_syms.h | ||
3 | * @brief dynamic GStreamer symbol-grabbing code | ||
4 | * | ||
5 | * @cond | ||
6 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | ||
7 | * | ||
8 | * Copyright (c) 2007-2010, Linden Research, Inc. | ||
9 | * | ||
10 | * Second Life Viewer Source Code | ||
11 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
12 | * to you under the terms of the GNU General Public License, version 2.0 | ||
13 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
14 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
15 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
16 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
17 | * | ||
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 | ||
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
21 | * online at | ||
22 | * http://secondlife.com/developers/opensource/flossexception | ||
23 | * | ||
24 | * By copying, modifying or distributing this software, you acknowledge | ||
25 | * that you have read and understood your obligations described above, | ||
26 | * and agree to abide by those obligations. | ||
27 | * | ||
28 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
29 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
30 | * COMPLETENESS OR PERFORMANCE. | ||
31 | * $/LicenseInfo$ | ||
32 | * | ||
33 | * @endcond | ||
34 | */ | ||
35 | |||
36 | #include "linden_common.h" | ||
37 | |||
38 | #if LL_GSTREAMER010_ENABLED | ||
39 | |||
40 | extern "C" { | ||
41 | #include <gst/gst.h> | ||
42 | } | ||
43 | |||
44 | bool grab_gst_syms(std::string gst_dso_name, | ||
45 | std::string gst_dso_name_vid); | ||
46 | void ungrab_gst_syms(); | ||
47 | |||
48 | #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__) | ||
49 | #include "llmediaimplgstreamer_syms_raw.inc" | ||
50 | #include "llmediaimplgstreamer_syms_rawv.inc" | ||
51 | #undef LL_GST_SYM | ||
52 | |||
53 | // regrettable hacks to give us better runtime compatibility with older systems | ||
54 | #define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0) | ||
55 | #define llg_return_val_if_fail(COND,V) do{if (!(COND)) return V;}while(0) | ||
56 | |||
57 | // regrettable hacks because GStreamer was not designed for runtime loading | ||
58 | #undef GST_TYPE_MESSAGE | ||
59 | #define GST_TYPE_MESSAGE (llgst_message_get_type()) | ||
60 | #undef GST_TYPE_OBJECT | ||
61 | #define GST_TYPE_OBJECT (llgst_object_get_type()) | ||
62 | #undef GST_TYPE_PIPELINE | ||
63 | #define GST_TYPE_PIPELINE (llgst_pipeline_get_type()) | ||
64 | #undef GST_TYPE_ELEMENT | ||
65 | #define GST_TYPE_ELEMENT (llgst_element_get_type()) | ||
66 | #undef GST_TYPE_VIDEO_SINK | ||
67 | #define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type()) | ||
68 | // more regrettable hacks to stub-out these .h-exposed GStreamer internals | ||
69 | void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname); | ||
70 | #undef _gst_debug_register_funcptr | ||
71 | #define _gst_debug_register_funcptr ll_gst_debug_register_funcptr | ||
72 | GstDebugCategory* ll_gst_debug_category_new(gchar *name, guint color, gchar *description); | ||
73 | #undef _gst_debug_category_new | ||
74 | #define _gst_debug_category_new ll_gst_debug_category_new | ||
75 | #undef __gst_debug_enabled | ||
76 | #define __gst_debug_enabled (0) | ||
77 | |||
78 | // more hacks | ||
79 | #define LLGST_MESSAGE_TYPE_NAME(M) (llgst_message_type_get_name(GST_MESSAGE_TYPE(M))) | ||
80 | |||
81 | #endif // LL_GSTREAMER010_ENABLED | ||
diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc deleted file mode 100755 index b33e593..0000000 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_raw.inc +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | |||
2 | // required symbols to grab | ||
3 | LL_GST_SYM(true, gst_pad_peer_accept_caps, gboolean, GstPad *pad, GstCaps *caps); | ||
4 | LL_GST_SYM(true, gst_buffer_new, GstBuffer*, void); | ||
5 | LL_GST_SYM(true, gst_buffer_set_caps, void, GstBuffer*, GstCaps *); | ||
6 | LL_GST_SYM(true, gst_structure_set_value, void, GstStructure *, const gchar *, const GValue*); | ||
7 | LL_GST_SYM(true, gst_init_check, gboolean, int *argc, char **argv[], GError ** err); | ||
8 | LL_GST_SYM(true, gst_message_get_type, GType, void); | ||
9 | LL_GST_SYM(true, gst_message_type_get_name, const gchar*, GstMessageType type); | ||
10 | LL_GST_SYM(true, gst_message_parse_error, void, GstMessage *message, GError **gerror, gchar **debug); | ||
11 | LL_GST_SYM(true, gst_message_parse_warning, void, GstMessage *message, GError **gerror, gchar **debug); | ||
12 | LL_GST_SYM(true, gst_message_parse_state_changed, void, GstMessage *message, GstState *oldstate, GstState *newstate, GstState *pending); | ||
13 | LL_GST_SYM(true, gst_element_set_state, GstStateChangeReturn, GstElement *element, GstState state); | ||
14 | LL_GST_SYM(true, gst_object_unref, void, gpointer object); | ||
15 | LL_GST_SYM(true, gst_object_get_type, GType, void); | ||
16 | LL_GST_SYM(true, gst_pipeline_get_type, GType, void); | ||
17 | LL_GST_SYM(true, gst_pipeline_get_bus, GstBus*, GstPipeline *pipeline); | ||
18 | LL_GST_SYM(true, gst_bus_add_watch, guint, GstBus * bus, GstBusFunc func, gpointer user_data); | ||
19 | LL_GST_SYM(true, gst_element_factory_make, GstElement*, const gchar *factoryname, const gchar *name); | ||
20 | LL_GST_SYM(true, gst_element_get_type, GType, void); | ||
21 | LL_GST_SYM(true, gst_static_pad_template_get, GstPadTemplate*, GstStaticPadTemplate *pad_template); | ||
22 | LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klass, GstPadTemplate *temp); | ||
23 | LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details); | ||
24 | LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps); | ||
25 | LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps); | ||
26 | //LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps); | ||
27 | LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string); | ||
28 | LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps); | ||
29 | LL_GST_SYM(true, gst_caps_get_structure, GstStructure *, const GstCaps *caps, guint index); | ||
30 | LL_GST_SYM(true, gst_caps_copy, GstCaps *, const GstCaps * caps); | ||
31 | //LL_GST_SYM(true, gst_caps_intersect, GstCaps *, const GstCaps *caps1, const GstCaps *caps2); | ||
32 | LL_GST_SYM(true, gst_element_register, gboolean, GstPlugin *plugin, const gchar *name, guint rank, GType type); | ||
33 | LL_GST_SYM(true, _gst_plugin_register_static, void, GstPluginDesc *desc); | ||
34 | LL_GST_SYM(true, gst_structure_get_int, gboolean, const GstStructure *structure, const gchar *fieldname, gint *value); | ||
35 | LL_GST_SYM(true, gst_structure_get_value, G_CONST_RETURN GValue *, const GstStructure *structure, const gchar *fieldname); | ||
36 | LL_GST_SYM(true, gst_value_get_fraction_numerator, gint, const GValue *value); | ||
37 | LL_GST_SYM(true, gst_value_get_fraction_denominator, gint, const GValue *value); | ||
38 | LL_GST_SYM(true, gst_structure_get_name, G_CONST_RETURN gchar *, const GstStructure *structure); | ||
39 | LL_GST_SYM(true, gst_element_seek, bool, GstElement *, gdouble, GstFormat, GstSeekFlags, GstSeekType, gint64, GstSeekType, gint64); | ||
40 | |||
41 | // optional symbols to grab | ||
42 | LL_GST_SYM(false, gst_registry_fork_set_enabled, void, gboolean enabled); | ||
43 | LL_GST_SYM(false, gst_segtrap_set_enabled, void, gboolean enabled); | ||
44 | LL_GST_SYM(false, gst_message_parse_buffering, void, GstMessage *message, gint *percent); | ||
45 | LL_GST_SYM(false, gst_message_parse_info, void, GstMessage *message, GError **gerror, gchar **debug); | ||
46 | LL_GST_SYM(false, gst_element_query_position, gboolean, GstElement *element, GstFormat *format, gint64 *cur); | ||
47 | LL_GST_SYM(false, gst_version, void, guint *major, guint *minor, guint *micro, guint *nano); | ||
48 | |||
49 | // 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. | ||
50 | //LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname); | ||
51 | //LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description); | ||
diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms_rawv.inc deleted file mode 100755 index 14fbcb4..0000000 --- a/linden/indra/media_plugins/gstreamer010/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/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp index 9242830..1fee545 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp | |||
@@ -33,7 +33,7 @@ | |||
33 | * @endcond | 33 | * @endcond |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #if LL_GSTREAMER010_ENABLED | 36 | ///#if LL_GSTREAMER010_ENABLED |
37 | 37 | ||
38 | #include "linden_common.h" | 38 | #include "linden_common.h" |
39 | 39 | ||
@@ -41,15 +41,29 @@ | |||
41 | #include <gst/video/video.h> | 41 | #include <gst/video/video.h> |
42 | #include <gst/video/gstvideosink.h> | 42 | #include <gst/video/gstvideosink.h> |
43 | 43 | ||
44 | #include "llmediaimplgstreamer_syms.h" | ||
45 | #include "llmediaimplgstreamertriviallogging.h" | 44 | #include "llmediaimplgstreamertriviallogging.h" |
45 | // #include "llthread.h" | ||
46 | 46 | ||
47 | #include "llmediaimplgstreamervidplug.h" | 47 | #include "llmediaimplgstreamervidplug.h" |
48 | 48 | ||
49 | |||
50 | GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug); | 49 | GST_DEBUG_CATEGORY_STATIC (gst_slvideo_debug); |
51 | #define GST_CAT_DEFAULT gst_slvideo_debug | 50 | #define GST_CAT_DEFAULT gst_slvideo_debug |
52 | 51 | ||
52 | /* Filter signals and args *//* | ||
53 | enum | ||
54 | { | ||
55 | *//* FILL ME *//* | ||
56 | LAST_SIGNAL | ||
57 | }; | ||
58 | |||
59 | enum | ||
60 | { | ||
61 | ARG_0 | ||
62 | }; | ||
63 | |||
64 | #define SLV_SIZECAPS ", width=(int){1,2,4,8,16,32,64,128,256,512,1024}, height=(int){1,2,4,8,16,32,64,128,256,512,1024} " | ||
65 | #define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS ";" GST_VIDEO_CAPS_BGRx SLV_SIZECAPS | ||
66 | */ | ||
53 | 67 | ||
54 | #define SLV_SIZECAPS ", width=(int)[1,2048], height=(int)[1,2048] " | 68 | #define SLV_SIZECAPS ", width=(int)[1,2048], height=(int)[1,2048] " |
55 | #define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS | 69 | #define SLV_ALLCAPS GST_VIDEO_CAPS_RGBx SLV_SIZECAPS |
@@ -81,9 +95,9 @@ gst_slvideo_base_init (gpointer gclass) | |||
81 | }; | 95 | }; |
82 | GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); | 96 | GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); |
83 | 97 | ||
84 | llgst_element_class_add_pad_template (element_class, | 98 | gst_element_class_add_pad_template (element_class, |
85 | llgst_static_pad_template_get (&sink_factory)); | 99 | gst_static_pad_template_get (&sink_factory)); |
86 | llgst_element_class_set_details (element_class, &element_details); | 100 | gst_element_class_set_details (element_class, &element_details); |
87 | } | 101 | } |
88 | 102 | ||
89 | 103 | ||
@@ -94,7 +108,7 @@ gst_slvideo_finalize (GObject * object) | |||
94 | slvideo = GST_SLVIDEO (object); | 108 | slvideo = GST_SLVIDEO (object); |
95 | if (slvideo->caps) | 109 | if (slvideo->caps) |
96 | { | 110 | { |
97 | llgst_caps_unref(slvideo->caps); | 111 | gst_caps_unref(slvideo->caps); |
98 | } | 112 | } |
99 | 113 | ||
100 | G_OBJECT_CLASS(parent_class)->finalize (object); | 114 | G_OBJECT_CLASS(parent_class)->finalize (object); |
@@ -105,7 +119,7 @@ static GstFlowReturn | |||
105 | gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) | 119 | gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf) |
106 | { | 120 | { |
107 | GstSLVideo *slvideo; | 121 | GstSLVideo *slvideo; |
108 | llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); | 122 | g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); |
109 | 123 | ||
110 | slvideo = GST_SLVIDEO(bsink); | 124 | slvideo = GST_SLVIDEO(bsink); |
111 | 125 | ||
@@ -197,7 +211,7 @@ gst_slvideo_get_caps (GstBaseSink * bsink) | |||
197 | GstSLVideo *slvideo; | 211 | GstSLVideo *slvideo; |
198 | slvideo = GST_SLVIDEO(bsink); | 212 | slvideo = GST_SLVIDEO(bsink); |
199 | 213 | ||
200 | return llgst_caps_ref (slvideo->caps); | 214 | return gst_caps_ref (slvideo->caps); |
201 | } | 215 | } |
202 | 216 | ||
203 | 217 | ||
@@ -207,21 +221,32 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) | |||
207 | { | 221 | { |
208 | GstSLVideo *filter; | 222 | GstSLVideo *filter; |
209 | GstStructure *structure; | 223 | GstStructure *structure; |
224 | // GstCaps *intersection; | ||
210 | 225 | ||
211 | GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps); | 226 | GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps); |
212 | 227 | ||
213 | filter = GST_SLVIDEO(bsink); | 228 | filter = GST_SLVIDEO(bsink); |
214 | 229 | ||
215 | int width, height; | 230 | /* |
231 | intersection = gst_caps_intersect (filter->caps, caps); | ||
232 | if (gst_caps_is_empty (intersection)) | ||
233 | { | ||
234 | // no overlap between our caps and requested caps | ||
235 | return FALSE; | ||
236 | } | ||
237 | gst_caps_unref(intersection); | ||
238 | */ | ||
239 | int width = 0; | ||
240 | int height = 0; | ||
216 | gboolean ret; | 241 | gboolean ret; |
217 | const GValue *fps; | 242 | const GValue *fps; |
218 | const GValue *par; | 243 | const GValue *par; |
219 | structure = llgst_caps_get_structure (caps, 0); | 244 | structure = gst_caps_get_structure (caps, 0); |
220 | ret = llgst_structure_get_int (structure, "width", &width); | 245 | ret = gst_structure_get_int (structure, "width", &width); |
221 | ret = ret && llgst_structure_get_int (structure, "height", &height); | 246 | ret = ret && gst_structure_get_int (structure, "height", &height); |
222 | fps = llgst_structure_get_value (structure, "framerate"); | 247 | fps = gst_structure_get_value (structure, "framerate"); |
223 | ret = ret && (fps != NULL); | 248 | ret = ret && (fps != NULL); |
224 | par = llgst_structure_get_value (structure, "pixel-aspect-ratio"); | 249 | par = gst_structure_get_value (structure, "pixel-aspect-ratio"); |
225 | if (!ret) | 250 | if (!ret) |
226 | return FALSE; | 251 | return FALSE; |
227 | 252 | ||
@@ -231,34 +256,35 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) | |||
231 | 256 | ||
232 | filter->width = width; | 257 | filter->width = width; |
233 | filter->height = height; | 258 | filter->height = height; |
234 | 259 | filter->fps_n = gst_value_get_fraction_numerator(fps); | |
235 | filter->fps_n = llgst_value_get_fraction_numerator(fps); | 260 | filter->fps_d = gst_value_get_fraction_denominator(fps); |
236 | filter->fps_d = llgst_value_get_fraction_denominator(fps); | ||
237 | if (par) | 261 | if (par) |
238 | { | 262 | { |
239 | filter->par_n = llgst_value_get_fraction_numerator(par); | 263 | filter->par_n = gst_value_get_fraction_numerator(par); |
240 | filter->par_d = llgst_value_get_fraction_denominator(par); | 264 | filter->par_d = gst_value_get_fraction_denominator(par); |
241 | } | 265 | } |
242 | else | 266 | else |
243 | { | 267 | { |
244 | filter->par_n = 1; | 268 | filter->par_n = 1; |
245 | filter->par_d = 1; | 269 | filter->par_d = 1; |
246 | } | 270 | } |
271 | |||
247 | GST_VIDEO_SINK_WIDTH(filter) = width; | 272 | GST_VIDEO_SINK_WIDTH(filter) = width; |
248 | GST_VIDEO_SINK_HEIGHT(filter) = height; | 273 | GST_VIDEO_SINK_HEIGHT(filter) = height; |
249 | 274 | ||
250 | // crufty lump - we *always* accept *only* RGBX now. | 275 | // crufty lump - we *always* accept *only* RGBX now. |
251 | /* | 276 | /* |
277 | |||
252 | filter->format = SLV_PF_UNKNOWN; | 278 | filter->format = SLV_PF_UNKNOWN; |
253 | if (0 == strcmp(llgst_structure_get_name(structure), | 279 | if (0 == strcmp(gst_structure_get_name(structure), |
254 | "video/x-raw-rgb")) | 280 | "video/x-raw-rgb")) |
255 | { | 281 | { |
256 | int red_mask; | 282 | int red_mask; |
257 | int green_mask; | 283 | int green_mask; |
258 | int blue_mask; | 284 | int blue_mask; |
259 | llgst_structure_get_int(structure, "red_mask", &red_mask); | 285 | gst_structure_get_int(structure, "red_mask", &red_mask); |
260 | llgst_structure_get_int(structure, "green_mask", &green_mask); | 286 | gst_structure_get_int(structure, "green_mask", &green_mask); |
261 | llgst_structure_get_int(structure, "blue_mask", &blue_mask); | 287 | gst_structure_get_int(structure, "blue_mask", &blue_mask); |
262 | if ((unsigned int)red_mask == 0xFF000000 && | 288 | if ((unsigned int)red_mask == 0xFF000000 && |
263 | (unsigned int)green_mask == 0x00FF0000 && | 289 | (unsigned int)green_mask == 0x00FF0000 && |
264 | (unsigned int)blue_mask == 0x0000FF00) | 290 | (unsigned int)blue_mask == 0x0000FF00) |
@@ -272,12 +298,13 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps) | |||
272 | filter->format = SLV_PF_BGRX; | 298 | filter->format = SLV_PF_BGRX; |
273 | //fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n"); | 299 | //fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n"); |
274 | } | 300 | } |
275 | }*/ | 301 | |
276 | 302 | }*/ | |
303 | |||
277 | filter->format = SLV_PF_RGBX; | 304 | filter->format = SLV_PF_RGBX; |
278 | 305 | ||
279 | GST_OBJECT_UNLOCK(filter); | 306 | GST_OBJECT_UNLOCK(filter); |
280 | 307 | ||
281 | return TRUE; | 308 | return TRUE; |
282 | } | 309 | } |
283 | 310 | ||
@@ -324,15 +351,15 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, | |||
324 | // we can ignore these and reverse-negotiate our preferred dimensions with | 351 | // we can ignore these and reverse-negotiate our preferred dimensions with |
325 | // the peer if we like - we need to do this to obey dynamic resize requests | 352 | // the peer if we like - we need to do this to obey dynamic resize requests |
326 | // flowing in from the app. | 353 | // flowing in from the app. |
327 | structure = llgst_caps_get_structure (caps, 0); | 354 | structure = gst_caps_get_structure (caps, 0); |
328 | if (!llgst_structure_get_int(structure, "width", &width) || | 355 | if (!gst_structure_get_int(structure, "width", &width) || |
329 | !llgst_structure_get_int(structure, "height", &height)) | 356 | !gst_structure_get_int(structure, "height", &height)) |
330 | { | 357 | { |
331 | GST_WARNING_OBJECT (slvideo, "no width/height in caps %" GST_PTR_FORMAT, caps); | 358 | GST_WARNING_OBJECT (slvideo, "no width/height in caps %" GST_PTR_FORMAT, caps); |
332 | return GST_FLOW_NOT_NEGOTIATED; | 359 | return GST_FLOW_NOT_NEGOTIATED; |
333 | } | 360 | } |
334 | 361 | ||
335 | GstBuffer *newbuf = llgst_buffer_new(); | 362 | GstBuffer *newbuf = gst_buffer_new(); |
336 | bool made_bufferdata_ptr = false; | 363 | bool made_bufferdata_ptr = false; |
337 | #define MAXDEPTHHACK 4 | 364 | #define MAXDEPTHHACK 4 |
338 | 365 | ||
@@ -352,19 +379,19 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, | |||
352 | 379 | ||
353 | GstCaps *desired_caps; | 380 | GstCaps *desired_caps; |
354 | GstStructure *desired_struct; | 381 | GstStructure *desired_struct; |
355 | desired_caps = llgst_caps_copy (caps); | 382 | desired_caps = gst_caps_copy (caps); |
356 | desired_struct = llgst_caps_get_structure (desired_caps, 0); | 383 | desired_struct = gst_caps_get_structure (desired_caps, 0); |
357 | 384 | ||
358 | GValue value = {0}; | 385 | GValue value = {0}; |
359 | g_value_init(&value, G_TYPE_INT); | 386 | g_value_init(&value, G_TYPE_INT); |
360 | g_value_set_int(&value, slwantwidth); | 387 | g_value_set_int(&value, slwantwidth); |
361 | llgst_structure_set_value (desired_struct, "width", &value); | 388 | gst_structure_set_value (desired_struct, "width", &value); |
362 | g_value_unset(&value); | 389 | g_value_unset(&value); |
363 | g_value_init(&value, G_TYPE_INT); | 390 | g_value_init(&value, G_TYPE_INT); |
364 | g_value_set_int(&value, slwantheight); | 391 | g_value_set_int(&value, slwantheight); |
365 | llgst_structure_set_value (desired_struct, "height", &value); | 392 | gst_structure_set_value (desired_struct, "height", &value); |
366 | 393 | ||
367 | if (llgst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo), | 394 | if (gst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo), |
368 | desired_caps)) | 395 | desired_caps)) |
369 | { | 396 | { |
370 | // todo: re-use buffers from a pool? | 397 | // todo: re-use buffers from a pool? |
@@ -375,13 +402,13 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, | |||
375 | GST_BUFFER_SIZE(newbuf) = slwantwidth * slwantheight * MAXDEPTHHACK; | 402 | GST_BUFFER_SIZE(newbuf) = slwantwidth * slwantheight * MAXDEPTHHACK; |
376 | GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); | 403 | GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); |
377 | GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); | 404 | GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); |
378 | llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps); | 405 | gst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps); |
379 | 406 | ||
380 | made_bufferdata_ptr = true; | 407 | made_bufferdata_ptr = true; |
381 | } else { | 408 | } else { |
382 | // peer hates our cap suggestion | 409 | // peer hates our cap suggestion |
383 | INFOMSG("peer hates us :("); | 410 | INFOMSG("peer hates us :("); |
384 | llgst_caps_unref(desired_caps); | 411 | gst_caps_unref(desired_caps); |
385 | } | 412 | } |
386 | } | 413 | } |
387 | } | 414 | } |
@@ -393,7 +420,7 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, | |||
393 | GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK; | 420 | GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK; |
394 | GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); | 421 | GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); |
395 | GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); | 422 | GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); |
396 | llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps); | 423 | gst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps); |
397 | } | 424 | } |
398 | 425 | ||
399 | *buf = GST_BUFFER_CAST(newbuf); | 426 | *buf = GST_BUFFER_CAST(newbuf); |
@@ -435,6 +462,20 @@ gst_slvideo_class_init (GstSLVideoClass * klass) | |||
435 | #undef LLGST_DEBUG_FUNCPTR | 462 | #undef LLGST_DEBUG_FUNCPTR |
436 | } | 463 | } |
437 | 464 | ||
465 | /* | ||
466 | static void | ||
467 | gst_slvideo_update_caps (GstSLVideo * slvideo) | ||
468 | { | ||
469 | GstCaps *caps; | ||
470 | |||
471 | // GStreamer will automatically convert colourspace if necessary. | ||
472 | // GStreamer will automatically resize media to one of these enumerated | ||
473 | // powers-of-two that we ask for (yay GStreamer!) | ||
474 | caps = gst_caps_from_string (SLV_ALLCAPS); | ||
475 | |||
476 | gst_caps_replace (&slvideo->caps, caps); | ||
477 | } | ||
478 | */ | ||
438 | 479 | ||
439 | /* initialize the new element | 480 | /* initialize the new element |
440 | * instantiate pads and add them to element | 481 | * instantiate pads and add them to element |
@@ -457,24 +498,24 @@ gst_slvideo_init (GstSLVideo * filter, | |||
457 | filter->retained_frame_width = filter->width; | 498 | filter->retained_frame_width = filter->width; |
458 | filter->retained_frame_height = filter->height; | 499 | filter->retained_frame_height = filter->height; |
459 | filter->retained_frame_format = SLV_PF_UNKNOWN; | 500 | filter->retained_frame_format = SLV_PF_UNKNOWN; |
460 | GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS); | 501 | GstCaps *caps = gst_caps_from_string (SLV_ALLCAPS); |
461 | llgst_caps_replace (&filter->caps, caps); | 502 | gst_caps_replace (&filter->caps, caps); |
462 | filter->resize_forced_always = false; | 503 | filter->resize_forced_always = false; |
463 | filter->resize_try_width = -1; | 504 | filter->resize_try_width = -1; |
464 | filter->resize_try_height = -1; | 505 | filter->resize_try_height = -1; |
465 | GST_OBJECT_UNLOCK(filter); | 506 | GST_OBJECT_UNLOCK(filter); |
507 | |||
508 | //gst_slvideo_update_caps(filter); | ||
466 | } | 509 | } |
467 | 510 | ||
468 | static void | 511 | static void |
469 | gst_slvideo_set_property (GObject * object, guint prop_id, | 512 | gst_slvideo_set_property (GObject * object, guint prop_id, |
470 | const GValue * value, GParamSpec * pspec) | 513 | const GValue * value, GParamSpec * pspec) |
471 | { | 514 | { |
472 | llg_return_if_fail (GST_IS_SLVIDEO (object)); | 515 | g_return_if_fail (GST_IS_SLVIDEO (object)); |
473 | 516 | ||
474 | switch (prop_id) { | 517 | if (prop_id) { |
475 | default: | ||
476 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 518 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
477 | break; | ||
478 | } | 519 | } |
479 | } | 520 | } |
480 | 521 | ||
@@ -482,12 +523,10 @@ static void | |||
482 | gst_slvideo_get_property (GObject * object, guint prop_id, | 523 | gst_slvideo_get_property (GObject * object, guint prop_id, |
483 | GValue * value, GParamSpec * pspec) | 524 | GValue * value, GParamSpec * pspec) |
484 | { | 525 | { |
485 | llg_return_if_fail (GST_IS_SLVIDEO (object)); | 526 | g_return_if_fail (GST_IS_SLVIDEO (object)); |
486 | 527 | ||
487 | switch (prop_id) { | 528 | if (prop_id) { |
488 | default: | ||
489 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 529 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
490 | break; | ||
491 | } | 530 | } |
492 | } | 531 | } |
493 | 532 | ||
@@ -505,7 +544,7 @@ plugin_init (GstPlugin * plugin) | |||
505 | GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", | 544 | GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", |
506 | 0, (gchar*)"Second Life Video Sink"); | 545 | 0, (gchar*)"Second Life Video Sink"); |
507 | 546 | ||
508 | return llgst_element_register (plugin, "private-slvideo", | 547 | return gst_element_register (plugin, "private-slvideo", |
509 | GST_RANK_NONE, GST_TYPE_SLVIDEO); | 548 | GST_RANK_NONE, GST_TYPE_SLVIDEO); |
510 | } | 549 | } |
511 | 550 | ||
@@ -515,20 +554,19 @@ plugin_init (GstPlugin * plugin) | |||
515 | some g++ versions buggily avoid __attribute__((constructor)) functions - | 554 | some g++ versions buggily avoid __attribute__((constructor)) functions - |
516 | so we provide an explicit plugin init function. | 555 | so we provide an explicit plugin init function. |
517 | */ | 556 | */ |
518 | #define PACKAGE (gchar*)"packagehack" | 557 | |
519 | // this macro quietly refers to PACKAGE internally | ||
520 | GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, | ||
521 | GST_VERSION_MINOR, | ||
522 | (gchar*)"private-slvideoplugin", | ||
523 | (gchar*)"SL Video sink plugin", | ||
524 | plugin_init, (gchar*)"0.1", (gchar*)GST_LICENSE_UNKNOWN, | ||
525 | (gchar*)"Second Life", | ||
526 | (gchar*)"http://www.secondlife.com/"); | ||
527 | #undef PACKAGE | ||
528 | void gst_slvideo_init_class (void) | 558 | void gst_slvideo_init_class (void) |
529 | { | 559 | { |
530 | ll_gst_plugin_register_static (&gst_plugin_desc); | 560 | gst_plugin_register_static( GST_VERSION_MAJOR, |
531 | DEBUGMSG("CLASS INIT"); | 561 | GST_VERSION_MINOR, |
562 | (const gchar *)"private-slvideoplugin", | ||
563 | (gchar *)"SL Video sink plugin", | ||
564 | plugin_init, | ||
565 | (const gchar *)"0.1", | ||
566 | GST_LICENSE_UNKNOWN, | ||
567 | (const gchar *)"Second Life", | ||
568 | (const gchar *)"Second Life", | ||
569 | (const gchar *)"http://www.secondlife.com/" ); | ||
532 | } | 570 | } |
533 | 571 | ||
534 | #endif // LL_GSTREAMER010_ENABLED | 572 | ///#endif // LL_GSTREAMER010_ENABLED |
diff --git a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h index 56f6db9..0ad8cf1 100755 --- a/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h +++ b/linden/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h | |||
@@ -36,12 +36,13 @@ | |||
36 | #ifndef __GST_SLVIDEO_H__ | 36 | #ifndef __GST_SLVIDEO_H__ |
37 | #define __GST_SLVIDEO_H__ | 37 | #define __GST_SLVIDEO_H__ |
38 | 38 | ||
39 | #if LL_GSTREAMER010_ENABLED | 39 | ///#if LL_GSTREAMER010_ENABLED |
40 | 40 | ||
41 | extern "C" { | 41 | extern "C" { |
42 | #include <gst/gst.h> | 42 | #include <gst/gst.h> |
43 | #include <gst/video/video.h> | 43 | #include <gst/video/video.h> |
44 | #include <gst/video/gstvideosink.h> | 44 | #include <gst/video/gstvideosink.h> |
45 | // #include <glib/gthread.h> | ||
45 | } | 46 | } |
46 | 47 | ||
47 | G_BEGIN_DECLS | 48 | G_BEGIN_DECLS |
@@ -107,6 +108,6 @@ void gst_slvideo_init_class (void); | |||
107 | 108 | ||
108 | G_END_DECLS | 109 | G_END_DECLS |
109 | 110 | ||
110 | #endif // LL_GSTREAMER010_ENABLED | 111 | ///#endif // LL_GSTREAMER010_ENABLED |
111 | 112 | ||
112 | #endif /* __GST_SLVIDEO_H__ */ | 113 | #endif /* __GST_SLVIDEO_H__ */ |
diff --git a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 7d34a1e..4dd182e 100755 --- a/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/linden/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | extern "C" { | 47 | extern "C" { |
48 | #include <gst/gst.h> | 48 | #include <gst/gst.h> |
49 | #include <gst/gstelement.h> | ||
49 | } | 50 | } |
50 | 51 | ||
51 | #include "llmediaimplgstreamer.h" | 52 | #include "llmediaimplgstreamer.h" |
@@ -53,8 +54,6 @@ extern "C" { | |||
53 | 54 | ||
54 | #include "llmediaimplgstreamervidplug.h" | 55 | #include "llmediaimplgstreamervidplug.h" |
55 | 56 | ||
56 | #include "llmediaimplgstreamer_syms.h" | ||
57 | |||
58 | ////////////////////////////////////////////////////////////////////////////// | 57 | ////////////////////////////////////////////////////////////////////////////// |
59 | // | 58 | // |
60 | class MediaPluginGStreamer010 : public MediaPluginBase | 59 | class MediaPluginGStreamer010 : public MediaPluginBase |
@@ -68,6 +67,8 @@ public: | |||
68 | static bool startup(); | 67 | static bool startup(); |
69 | static bool closedown(); | 68 | static bool closedown(); |
70 | 69 | ||
70 | static void set_gst_plugin_path(); | ||
71 | |||
71 | gboolean processGSTEvents(GstBus *bus, | 72 | gboolean processGSTEvents(GstBus *bus, |
72 | GstMessage *message); | 73 | GstMessage *message); |
73 | 74 | ||
@@ -139,6 +140,8 @@ private: | |||
139 | 140 | ||
140 | bool mSeekWanted; | 141 | bool mSeekWanted; |
141 | double mSeekDestination; | 142 | double mSeekDestination; |
143 | |||
144 | std::string mLastTitle; | ||
142 | 145 | ||
143 | // Very GStreamer-specific | 146 | // Very GStreamer-specific |
144 | GMainLoop *mPump; // event pump for this media | 147 | GMainLoop *mPump; // event pump for this media |
@@ -196,149 +199,179 @@ MediaPluginGStreamer010::processGSTEvents(GstBus *bus, | |||
196 | GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) | 199 | GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) |
197 | { | 200 | { |
198 | DEBUGMSG("Got GST message type: %s", | 201 | DEBUGMSG("Got GST message type: %s", |
199 | LLGST_MESSAGE_TYPE_NAME (message)); | 202 | GST_MESSAGE_TYPE_NAME (message)); |
200 | } | 203 | } |
201 | else | 204 | else |
202 | { | 205 | { |
203 | // TODO: grok 'duration' message type | 206 | // TODO: grok 'duration' message type |
204 | DEBUGMSG("Got GST message type: %s", | 207 | DEBUGMSG("Got GST message type: %s", |
205 | LLGST_MESSAGE_TYPE_NAME (message)); | 208 | GST_MESSAGE_TYPE_NAME (message)); |
206 | } | 209 | } |
207 | 210 | ||
208 | switch (GST_MESSAGE_TYPE (message)) { | 211 | switch (GST_MESSAGE_TYPE (message)) |
209 | case GST_MESSAGE_BUFFERING: { | 212 | { |
210 | // NEEDS GST 0.10.11+ | 213 | case GST_MESSAGE_BUFFERING: |
211 | if (llgst_message_parse_buffering) | ||
212 | { | 214 | { |
215 | // NEEDS GST 0.10.11+ and America discovered by C.Columbus | ||
213 | gint percent = 0; | 216 | gint percent = 0; |
214 | llgst_message_parse_buffering(message, &percent); | 217 | gst_message_parse_buffering(message, &percent); |
215 | DEBUGMSG("GST buffering: %d%%", percent); | 218 | DEBUGMSG("GST buffering: %d%%", percent); |
216 | } | ||
217 | break; | ||
218 | } | ||
219 | case GST_MESSAGE_STATE_CHANGED: { | ||
220 | GstState old_state; | ||
221 | GstState new_state; | ||
222 | GstState pending_state; | ||
223 | llgst_message_parse_state_changed(message, | ||
224 | &old_state, | ||
225 | &new_state, | ||
226 | &pending_state); | ||
227 | #ifdef LL_GST_REPORT_STATE_CHANGES | ||
228 | // not generally very useful, and rather spammy. | ||
229 | DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", | ||
230 | get_gst_state_name(old_state), | ||
231 | get_gst_state_name(new_state), | ||
232 | get_gst_state_name(pending_state)); | ||
233 | #endif // LL_GST_REPORT_STATE_CHANGES | ||
234 | 219 | ||
235 | switch (new_state) { | ||
236 | case GST_STATE_VOID_PENDING: | ||
237 | break; | ||
238 | case GST_STATE_NULL: | ||
239 | break; | 220 | break; |
240 | case GST_STATE_READY: | 221 | } |
241 | setStatus(STATUS_LOADED); | 222 | case GST_MESSAGE_STATE_CHANGED: { |
242 | break; | 223 | GstState old_state; |
243 | case GST_STATE_PAUSED: | 224 | GstState new_state; |
244 | setStatus(STATUS_PAUSED); | 225 | GstState pending_state; |
226 | gst_message_parse_state_changed(message, | ||
227 | &old_state, | ||
228 | &new_state, | ||
229 | &pending_state); | ||
230 | #ifdef LL_GST_REPORT_STATE_CHANGES | ||
231 | // not generally very useful, and rather spammy. | ||
232 | DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", | ||
233 | get_gst_state_name(old_state), | ||
234 | get_gst_state_name(new_state), | ||
235 | get_gst_state_name(pending_state)); | ||
236 | #endif // LL_GST_REPORT_STATE_CHANGES | ||
237 | |||
238 | switch (new_state) | ||
239 | { | ||
240 | case GST_STATE_VOID_PENDING: | ||
241 | break; | ||
242 | case GST_STATE_NULL: | ||
243 | break; | ||
244 | case GST_STATE_READY: | ||
245 | setStatus(STATUS_LOADED); | ||
246 | break; | ||
247 | case GST_STATE_PAUSED: | ||
248 | setStatus(STATUS_PAUSED); | ||
249 | break; | ||
250 | case GST_STATE_PLAYING: | ||
251 | setStatus(STATUS_PLAYING); | ||
252 | break; | ||
253 | } | ||
245 | break; | 254 | break; |
246 | case GST_STATE_PLAYING: | 255 | } |
247 | setStatus(STATUS_PLAYING); | 256 | case GST_MESSAGE_ERROR: |
257 | { | ||
258 | GError *err = NULL; | ||
259 | gchar *debug = NULL; | ||
260 | |||
261 | gst_message_parse_error (message, &err, &debug); | ||
262 | WARNMSG("GST error: %s", err?err->message:"(unknown)"); | ||
263 | if (err) | ||
264 | g_error_free (err); | ||
265 | g_free (debug); | ||
266 | |||
267 | mCommand = COMMAND_STOP; | ||
268 | |||
269 | setStatus(STATUS_ERROR); | ||
270 | |||
248 | break; | 271 | break; |
249 | } | 272 | } |
250 | break; | 273 | case GST_MESSAGE_INFO: |
251 | } | ||
252 | case GST_MESSAGE_ERROR: { | ||
253 | GError *err = NULL; | ||
254 | gchar *debug = NULL; | ||
255 | |||
256 | llgst_message_parse_error (message, &err, &debug); | ||
257 | WARNMSG("GST error: %s", err?err->message:"(unknown)"); | ||
258 | if (err) | ||
259 | g_error_free (err); | ||
260 | g_free (debug); | ||
261 | |||
262 | mCommand = COMMAND_STOP; | ||
263 | |||
264 | setStatus(STATUS_ERROR); | ||
265 | |||
266 | break; | ||
267 | } | ||
268 | case GST_MESSAGE_INFO: { | ||
269 | if (llgst_message_parse_info) | ||
270 | { | 274 | { |
271 | GError *err = NULL; | 275 | GError *err = NULL; |
272 | gchar *debug = NULL; | 276 | gchar *debug = NULL; |
273 | 277 | ||
274 | llgst_message_parse_info (message, &err, &debug); | 278 | gst_message_parse_info (message, &err, &debug); |
275 | INFOMSG("GST info: %s", err?err->message:"(unknown)"); | 279 | INFOMSG("GST info: %s", err?err->message:"(unknown)"); |
276 | if (err) | 280 | if (err) |
277 | g_error_free (err); | 281 | g_error_free (err); |
278 | g_free (debug); | 282 | g_free (debug); |
283 | |||
284 | break; | ||
279 | } | 285 | } |
280 | break; | 286 | case GST_MESSAGE_WARNING: |
281 | } | 287 | { |
282 | case GST_MESSAGE_WARNING: { | 288 | GError *err = NULL; |
283 | GError *err = NULL; | 289 | gchar *debug = NULL; |
284 | gchar *debug = NULL; | 290 | |
291 | gst_message_parse_warning (message, &err, &debug); | ||
292 | WARNMSG("GST warning: %s", err?err->message:"(unknown)"); | ||
293 | if (err) | ||
294 | g_error_free (err); | ||
295 | g_free (debug); | ||
296 | |||
297 | break; | ||
298 | } | ||
299 | case GST_MESSAGE_TAG: | ||
300 | { | ||
301 | GstTagList *new_tags; | ||
285 | 302 | ||
286 | llgst_message_parse_warning (message, &err, &debug); | 303 | gst_message_parse_tag( message, &new_tags ); |
287 | WARNMSG("GST warning: %s", err?err->message:"(unknown)"); | ||
288 | if (err) | ||
289 | g_error_free (err); | ||
290 | g_free (debug); | ||
291 | 304 | ||
292 | break; | 305 | gchar *title = NULL; |
293 | } | ||
294 | case GST_MESSAGE_EOS: | ||
295 | /* end-of-stream */ | ||
296 | DEBUGMSG("GST end-of-stream."); | ||
297 | if (mIsLooping) | ||
298 | { | ||
299 | DEBUGMSG("looping media..."); | ||
300 | double eos_pos_sec = 0.0F; | ||
301 | bool got_eos_position = getTimePos(eos_pos_sec); | ||
302 | 306 | ||
303 | if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) | 307 | if ( gst_tag_list_get_string(new_tags, GST_TAG_TITLE, &title) ) |
304 | { | 308 | { |
305 | // if we know that the movie is really short, don't | 309 | //WARMING("Title: %s", title); |
306 | // loop it else it can easily become a time-hog | 310 | std::string newtitle(title); |
307 | // because of GStreamer spin-up overhead | 311 | gst_tag_list_free(new_tags); |
308 | DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); | 312 | |
309 | // inject a COMMAND_PAUSE | 313 | if ( newtitle != mLastTitle && !newtitle.empty() ) |
310 | mCommand = COMMAND_PAUSE; | 314 | { |
315 | LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); | ||
316 | message.setValue("name", newtitle ); | ||
317 | sendMessage( message ); | ||
318 | mLastTitle = newtitle; | ||
319 | } | ||
320 | g_free(title); | ||
311 | } | 321 | } |
312 | else | 322 | |
323 | break; | ||
324 | } | ||
325 | case GST_MESSAGE_EOS: | ||
326 | { | ||
327 | /* end-of-stream */ | ||
328 | DEBUGMSG("GST end-of-stream."); | ||
329 | if (mIsLooping) | ||
313 | { | 330 | { |
314 | #undef LLGST_LOOP_BY_SEEKING | 331 | DEBUGMSG("looping media..."); |
315 | // loop with a stop-start instead of a seek, because it actually seems rather | 332 | double eos_pos_sec = 0.0F; |
316 | // faster than seeking on remote streams. | 333 | bool got_eos_position = getTimePos(eos_pos_sec); |
317 | #ifdef LLGST_LOOP_BY_SEEKING | 334 | |
318 | // first, try looping by an explicit rewind | 335 | if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) |
319 | bool seeksuccess = seek(0.0); | ||
320 | if (seeksuccess) | ||
321 | { | 336 | { |
322 | play(1.0); | 337 | // if we know that the movie is really short, don't |
338 | // loop it else it can easily become a time-hog | ||
339 | // because of GStreamer spin-up overhead | ||
340 | DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); | ||
341 | // inject a COMMAND_PAUSE | ||
342 | mCommand = COMMAND_PAUSE; | ||
323 | } | 343 | } |
324 | else | 344 | else |
325 | #endif // LLGST_LOOP_BY_SEEKING | 345 | { |
326 | { // use clumsy stop-start to loop | 346 | #undef LLGST_LOOP_BY_SEEKING |
327 | DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); | 347 | // loop with a stop-start instead of a seek, because it actually seems rather |
328 | stop(); | 348 | // faster than seeking on remote streams. |
329 | play(1.0); | 349 | #ifdef LLGST_LOOP_BY_SEEKING |
350 | // first, try looping by an explicit rewind | ||
351 | bool seeksuccess = seek(0.0); | ||
352 | if (seeksuccess) | ||
353 | { | ||
354 | play(1.0); | ||
355 | } | ||
356 | else | ||
357 | #endif // LLGST_LOOP_BY_SEEKING | ||
358 | { // use clumsy stop-start to loop | ||
359 | DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); | ||
360 | stop(); | ||
361 | play(1.0); | ||
362 | } | ||
330 | } | 363 | } |
331 | } | 364 | } |
332 | } | 365 | else // not a looping media |
333 | else // not a looping media | 366 | { |
334 | { | 367 | // inject a COMMAND_STOP |
335 | // inject a COMMAND_STOP | 368 | mCommand = COMMAND_STOP; |
336 | mCommand = COMMAND_STOP; | 369 | } |
337 | } | 370 | } break; |
338 | break; | 371 | |
339 | default: | 372 | default: |
340 | /* unhandled message */ | 373 | /* unhandled message */ |
341 | break; | 374 | break; |
342 | } | 375 | } |
343 | 376 | ||
344 | /* we want to be notified again the next time there is a message | 377 | /* we want to be notified again the next time there is a message |
@@ -544,7 +577,7 @@ MediaPluginGStreamer010::pause() | |||
544 | { | 577 | { |
545 | DEBUGMSG("pausing media..."); | 578 | DEBUGMSG("pausing media..."); |
546 | // todo: error-check this? | 579 | // todo: error-check this? |
547 | llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); | 580 | gst_element_set_state(mPlaybin, GST_STATE_PAUSED); |
548 | return true; | 581 | return true; |
549 | } | 582 | } |
550 | 583 | ||
@@ -553,7 +586,7 @@ MediaPluginGStreamer010::stop() | |||
553 | { | 586 | { |
554 | DEBUGMSG("stopping media..."); | 587 | DEBUGMSG("stopping media..."); |
555 | // todo: error-check this? | 588 | // todo: error-check this? |
556 | llgst_element_set_state(mPlaybin, GST_STATE_READY); | 589 | gst_element_set_state(mPlaybin, GST_STATE_READY); |
557 | return true; | 590 | return true; |
558 | } | 591 | } |
559 | 592 | ||
@@ -564,7 +597,7 @@ MediaPluginGStreamer010::play(double rate) | |||
564 | 597 | ||
565 | DEBUGMSG("playing media... rate=%f", rate); | 598 | DEBUGMSG("playing media... rate=%f", rate); |
566 | // todo: error-check this? | 599 | // todo: error-check this? |
567 | llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); | 600 | gst_element_set_state(mPlaybin, GST_STATE_PLAYING); |
568 | return true; | 601 | return true; |
569 | } | 602 | } |
570 | 603 | ||
@@ -593,7 +626,7 @@ MediaPluginGStreamer010::seek(double time_sec) | |||
593 | bool success = false; | 626 | bool success = false; |
594 | if (mDoneInit && mPlaybin) | 627 | if (mDoneInit && mPlaybin) |
595 | { | 628 | { |
596 | success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, | 629 | success = gst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, |
597 | GstSeekFlags(GST_SEEK_FLAG_FLUSH | | 630 | GstSeekFlags(GST_SEEK_FLAG_FLUSH | |
598 | GST_SEEK_FLAG_KEY_UNIT), | 631 | GST_SEEK_FLAG_KEY_UNIT), |
599 | GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), | 632 | GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), |
@@ -612,11 +645,9 @@ MediaPluginGStreamer010::getTimePos(double &sec_out) | |||
612 | { | 645 | { |
613 | gint64 pos; | 646 | gint64 pos; |
614 | GstFormat timefmt = GST_FORMAT_TIME; | 647 | GstFormat timefmt = GST_FORMAT_TIME; |
615 | got_position = | 648 | got_position = gst_element_query_position(mPlaybin, |
616 | llgst_element_query_position && | 649 | &timefmt, |
617 | llgst_element_query_position(mPlaybin, | 650 | &pos); |
618 | &timefmt, | ||
619 | &pos); | ||
620 | got_position = got_position | 651 | got_position = got_position |
621 | && (timefmt == GST_FORMAT_TIME); | 652 | && (timefmt == GST_FORMAT_TIME); |
622 | // GStreamer may have other ideas, but we consider the current position | 653 | // GStreamer may have other ideas, but we consider the current position |
@@ -669,7 +700,7 @@ MediaPluginGStreamer010::load() | |||
669 | } | 700 | } |
670 | 701 | ||
671 | // instantiate a playbin element to do the hard work | 702 | // instantiate a playbin element to do the hard work |
672 | mPlaybin = llgst_element_factory_make ("playbin", "play"); | 703 | mPlaybin = gst_element_factory_make ("playbin", "play"); |
673 | if (!mPlaybin) | 704 | if (!mPlaybin) |
674 | { | 705 | { |
675 | setStatus(STATUS_ERROR); | 706 | setStatus(STATUS_ERROR); |
@@ -677,21 +708,21 @@ MediaPluginGStreamer010::load() | |||
677 | } | 708 | } |
678 | 709 | ||
679 | // get playbin's bus | 710 | // get playbin's bus |
680 | GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); | 711 | GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); |
681 | if (!bus) | 712 | if (!bus) |
682 | { | 713 | { |
683 | setStatus(STATUS_ERROR); | 714 | setStatus(STATUS_ERROR); |
684 | return false; // error | 715 | return false; // error |
685 | } | 716 | } |
686 | mBusWatchID = llgst_bus_add_watch (bus, | 717 | mBusWatchID = gst_bus_add_watch (bus, |
687 | llmediaimplgstreamer_bus_callback, | 718 | llmediaimplgstreamer_bus_callback, |
688 | this); | 719 | this); |
689 | llgst_object_unref (bus); | 720 | gst_object_unref (bus); |
690 | 721 | ||
691 | if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { | 722 | if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { |
692 | // instantiate a custom video sink | 723 | // instantiate a custom video sink |
693 | mVideoSink = | 724 | mVideoSink = |
694 | GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); | 725 | GST_SLVIDEO(gst_element_factory_make ("private-slvideo", "slvideo")); |
695 | if (!mVideoSink) | 726 | if (!mVideoSink) |
696 | { | 727 | { |
697 | WARNMSG("Could not instantiate private-slvideo element."); | 728 | WARNMSG("Could not instantiate private-slvideo element."); |
@@ -721,8 +752,8 @@ MediaPluginGStreamer010::unload () | |||
721 | 752 | ||
722 | if (mPlaybin) | 753 | if (mPlaybin) |
723 | { | 754 | { |
724 | llgst_element_set_state (mPlaybin, GST_STATE_NULL); | 755 | gst_element_set_state (mPlaybin, GST_STATE_NULL); |
725 | llgst_object_unref (GST_OBJECT (mPlaybin)); | 756 | gst_object_unref (GST_OBJECT (mPlaybin)); |
726 | mPlaybin = NULL; | 757 | mPlaybin = NULL; |
727 | } | 758 | } |
728 | 759 | ||
@@ -755,7 +786,10 @@ MediaPluginGStreamer010::startup() | |||
755 | 786 | ||
756 | // Init the glib type system - we need it. | 787 | // Init the glib type system - we need it. |
757 | g_type_init(); | 788 | g_type_init(); |
789 | set_gst_plugin_path(); | ||
790 | |||
758 | 791 | ||
792 | /* | ||
759 | // Get symbols! | 793 | // Get symbols! |
760 | #if LL_DARWIN | 794 | #if LL_DARWIN |
761 | if (! grab_gst_syms("libgstreamer-0.10.dylib", | 795 | if (! grab_gst_syms("libgstreamer-0.10.dylib", |
@@ -771,24 +805,24 @@ MediaPluginGStreamer010::startup() | |||
771 | WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); | 805 | WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); |
772 | return false; | 806 | return false; |
773 | } | 807 | } |
774 | 808 | */ | |
775 | if (llgst_segtrap_set_enabled) | 809 | // if (gst_segtrap_set_enabled) |
776 | { | 810 | // { |
777 | llgst_segtrap_set_enabled(FALSE); | 811 | gst_segtrap_set_enabled(FALSE); |
778 | } | 812 | // } |
779 | else | 813 | // else |
780 | { | 814 | // { |
781 | WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); | 815 | // WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); |
782 | } | 816 | // } |
783 | 817 | /* | |
784 | #if LL_LINUX | 818 | #if LL_LINUX |
785 | // Gstreamer tries a fork during init, waitpid-ing on it, | 819 | // Gstreamer tries a fork during init, waitpid-ing on it, |
786 | // which conflicts with any installed SIGCHLD handler... | 820 | // which conflicts with any installed SIGCHLD handler... |
787 | struct sigaction tmpact, oldact; | 821 | struct sigaction tmpact, oldact; |
788 | if (llgst_registry_fork_set_enabled) { | 822 | if (gst_registry_fork_set_enabled) { |
789 | // if we can disable SIGCHLD-using forking behaviour, | 823 | // if we can disable SIGCHLD-using forking behaviour, |
790 | // do it. | 824 | // do it. |
791 | llgst_registry_fork_set_enabled(false); | 825 | gst_registry_fork_set_enabled(false); |
792 | } | 826 | } |
793 | else { | 827 | else { |
794 | // else temporarily install default SIGCHLD handler | 828 | // else temporarily install default SIGCHLD handler |
@@ -799,24 +833,24 @@ MediaPluginGStreamer010::startup() | |||
799 | sigaction(SIGCHLD, &tmpact, &oldact); | 833 | sigaction(SIGCHLD, &tmpact, &oldact); |
800 | } | 834 | } |
801 | #endif // LL_LINUX | 835 | #endif // LL_LINUX |
802 | 836 | */ | |
803 | // Protect against GStreamer resetting the locale, yuck. | 837 | // Protect against GStreamer resetting the locale, yuck. |
804 | static std::string saved_locale; | 838 | static std::string saved_locale; |
805 | saved_locale = setlocale(LC_ALL, NULL); | 839 | saved_locale = setlocale(LC_ALL, NULL); |
806 | 840 | ||
807 | // finally, try to initialize GStreamer! | 841 | // finally, try to initialize GStreamer! |
808 | GError *err = NULL; | 842 | GError *err = NULL; |
809 | gboolean init_gst_success = llgst_init_check(NULL, NULL, &err); | 843 | gboolean init_gst_success = gst_init_check(NULL, NULL, &err); |
810 | 844 | ||
811 | // restore old locale | 845 | // restore old locale |
812 | setlocale(LC_ALL, saved_locale.c_str() ); | 846 | setlocale(LC_ALL, saved_locale.c_str() ); |
813 | 847 | /* | |
814 | #if LL_LINUX | 848 | #if LL_LINUX |
815 | // restore old SIGCHLD handler | 849 | // restore old SIGCHLD handler |
816 | if (!llgst_registry_fork_set_enabled) | 850 | if (!gst_registry_fork_set_enabled) |
817 | sigaction(SIGCHLD, &oldact, NULL); | 851 | sigaction(SIGCHLD, &oldact, NULL); |
818 | #endif // LL_LINUX | 852 | #endif // LL_LINUX |
819 | 853 | */ | |
820 | if (!init_gst_success) // fail | 854 | if (!init_gst_success) // fail |
821 | { | 855 | { |
822 | if (err) | 856 | if (err) |
@@ -830,16 +864,139 @@ MediaPluginGStreamer010::startup() | |||
830 | } | 864 | } |
831 | return false; | 865 | return false; |
832 | } | 866 | } |
833 | 867 | ||
868 | // Set up logging facilities | ||
869 | gst_debug_remove_log_function( gst_debug_log_default ); | ||
870 | // gst_debug_add_log_function( gstreamer_log, NULL ); | ||
871 | |||
834 | // Init our custom plugins - only really need do this once. | 872 | // Init our custom plugins - only really need do this once. |
835 | gst_slvideo_init_class(); | 873 | gst_slvideo_init_class(); |
836 | 874 | /* | |
875 | // List the plugins GStreamer can find | ||
876 | LL_DEBUGS("MediaImpl") << "Found GStreamer plugins:" << LL_ENDL; | ||
877 | GList *list; | ||
878 | GstRegistry *registry = gst_registry_get_default(); | ||
879 | std::string loaded = ""; | ||
880 | for (list = gst_registry_get_plugin_list(registry); | ||
881 | list != NULL; | ||
882 | list = g_list_next(list)) | ||
883 | { | ||
884 | GstPlugin *list_plugin = (GstPlugin *)list->data; | ||
885 | (bool)gst_plugin_is_loaded(list_plugin) ? loaded = "Yes" : loaded = "No"; | ||
886 | LL_DEBUGS("MediaImpl") << gst_plugin_get_name(list_plugin) << ", loaded? " << loaded << LL_ENDL; | ||
887 | } | ||
888 | gst_plugin_list_free(list); | ||
889 | */ | ||
837 | mDoneInit = true; | 890 | mDoneInit = true; |
838 | } | 891 | } |
839 | 892 | ||
840 | return true; | 893 | return true; |
841 | } | 894 | } |
842 | 895 | ||
896 | void MediaPluginGStreamer010::set_gst_plugin_path() | ||
897 | { | ||
898 | // Linux sets GST_PLUGIN_PATH in wrapper.sh, not here. | ||
899 | #if LL_WINDOWS || LL_DARWIN | ||
900 | |||
901 | std::string imp_dir = ""; | ||
902 | |||
903 | // Get the current working directory: | ||
904 | #if LL_WINDOWS | ||
905 | char* raw_dir; | ||
906 | raw_dir = _getcwd(NULL,0); | ||
907 | if( raw_dir != NULL ) | ||
908 | { | ||
909 | imp_dir = std::string( raw_dir ); | ||
910 | } | ||
911 | #elif LL_DARWIN | ||
912 | CFBundleRef main_bundle = CFBundleGetMainBundle(); | ||
913 | if( main_bundle != NULL ) | ||
914 | { | ||
915 | CFURLRef bundle_url = CFBundleCopyBundleURL( main_bundle ); | ||
916 | if( bundle_url != NULL ) | ||
917 | { | ||
918 | #ifndef MAXPATHLEN | ||
919 | #define MAXPATHLEN 1024 | ||
920 | #endif | ||
921 | char raw_dir[MAXPATHLEN]; | ||
922 | if( CFURLGetFileSystemRepresentation( bundle_url, true, (UInt8 *)raw_dir, MAXPATHLEN) ) | ||
923 | { | ||
924 | imp_dir = std::string( raw_dir ) + "/Contents/MacOS/"; | ||
925 | } | ||
926 | CFRelease(bundle_url); | ||
927 | } | ||
928 | } | ||
929 | #endif | ||
930 | |||
931 | if( imp_dir == "" ) | ||
932 | { | ||
933 | WARNMSG("Could not get application directory, not setting GST_PLUGIN_PATH."); | ||
934 | return; | ||
935 | } | ||
936 | |||
937 | DEBUGMSG("Imprudence is installed at %s", imp_dir); | ||
938 | |||
939 | // ":" on Mac and 'Nix, ";" on Windows | ||
940 | std::string separator = G_SEARCHPATH_SEPARATOR_S; | ||
941 | |||
942 | // Grab the current path, if it's set. | ||
943 | std::string old_plugin_path = ""; | ||
944 | char *old_path = getenv("GST_PLUGIN_PATH"); | ||
945 | if(old_path == NULL) | ||
946 | { | ||
947 | DEBUGMSG("Did not find user-set GST_PLUGIN_PATH."); | ||
948 | } | ||
949 | else | ||
950 | { | ||
951 | old_plugin_path = separator + std::string( old_path ); | ||
952 | } | ||
953 | |||
954 | |||
955 | // Search both Imprudence and Imprudence\lib\gstreamer-plugins. | ||
956 | // But we also want to search the path the user has set, if any. | ||
957 | std::string plugin_path = | ||
958 | "GST_PLUGIN_PATH=" + | ||
959 | #if LL_WINDOWS | ||
960 | imp_dir + "\\lib\\gstreamer-plugins" + | ||
961 | #elif LL_DARWIN | ||
962 | imp_dir + separator + | ||
963 | imp_dir + "/../Resources/lib/gstreamer-plugins" + | ||
964 | #endif | ||
965 | old_plugin_path; | ||
966 | |||
967 | int put_result; | ||
968 | |||
969 | // Place GST_PLUGIN_PATH in the environment settings | ||
970 | #if LL_WINDOWS | ||
971 | put_result = _putenv( (char*)plugin_path.c_str() ); | ||
972 | #elif LL_DARWIN | ||
973 | put_result = putenv( (char*)plugin_path.c_str() ); | ||
974 | #endif | ||
975 | |||
976 | if( put_result == -1 ) | ||
977 | { | ||
978 | WARNMSG("Setting GST_PLUGIN_PATH failed!"); | ||
979 | } | ||
980 | else | ||
981 | { | ||
982 | DEBUGMSG("GST_PLUGIN_PATH set to %s", getenv("GST_PLUGIN_PATH")); | ||
983 | } | ||
984 | |||
985 | // Don't load system plugins. We only want to use ours, to avoid conflicts. | ||
986 | #if LL_WINDOWS | ||
987 | put_result = _putenv( "GST_PLUGIN_SYSTEM_PATH=\"\"" ); | ||
988 | #elif LL_DARWIN | ||
989 | put_result = putenv( "GST_PLUGIN_SYSTEM_PATH=\"\"" ); | ||
990 | #endif | ||
991 | |||
992 | if( put_result == -1 ) | ||
993 | { | ||
994 | WARNMSG("Setting GST_PLUGIN_SYSTEM_PATH=\"\" failed!"); | ||
995 | } | ||
996 | |||
997 | #endif // LL_WINDOWS || LL_DARWIN | ||
998 | } | ||
999 | |||
843 | 1000 | ||
844 | void | 1001 | void |
845 | MediaPluginGStreamer010::sizeChanged() | 1002 | MediaPluginGStreamer010::sizeChanged() |
@@ -881,7 +1038,7 @@ MediaPluginGStreamer010::closedown() | |||
881 | if (!mDoneInit) | 1038 | if (!mDoneInit) |
882 | return false; // error | 1039 | return false; // error |
883 | 1040 | ||
884 | ungrab_gst_syms(); | 1041 | // ungrab_gst_syms(); |
885 | 1042 | ||
886 | mDoneInit = false; | 1043 | mDoneInit = false; |
887 | 1044 | ||
@@ -902,11 +1059,10 @@ std::string | |||
902 | MediaPluginGStreamer010::getVersion() | 1059 | MediaPluginGStreamer010::getVersion() |
903 | { | 1060 | { |
904 | std::string plugin_version = "GStreamer010 media plugin, GStreamer version "; | 1061 | std::string plugin_version = "GStreamer010 media plugin, GStreamer version "; |
905 | if (mDoneInit && | 1062 | if (mDoneInit) // && gst_version) |
906 | llgst_version) | ||
907 | { | 1063 | { |
908 | guint major, minor, micro, nano; | 1064 | guint major, minor, micro, nano; |
909 | llgst_version(&major, &minor, µ, &nano); | 1065 | gst_version(&major, &minor, µ, &nano); |
910 | plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO); | 1066 | plugin_version += llformat("%u.%u.%u.%u (runtime), %u.%u.%u.%u (headers)", (unsigned int)major, (unsigned int)minor, (unsigned int)micro, (unsigned int)nano, (unsigned int)GST_VERSION_MAJOR, (unsigned int)GST_VERSION_MINOR, (unsigned int)GST_VERSION_MICRO, (unsigned int)GST_VERSION_NANO); |
911 | } | 1067 | } |
912 | else | 1068 | else |
diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp index e903df7..e713e22 100644 --- a/linden/indra/newview/lloverlaybar.cpp +++ b/linden/indra/newview/lloverlaybar.cpp | |||
@@ -43,7 +43,7 @@ | |||
43 | #include "llagent.h" | 43 | #include "llagent.h" |
44 | #include "llbutton.h" | 44 | #include "llbutton.h" |
45 | #include "llchatbar.h" | 45 | #include "llchatbar.h" |
46 | #include "llfloaterchat.h" | 46 | //#include "llfloaterchat.h" |
47 | #include "llfocusmgr.h" | 47 | #include "llfocusmgr.h" |
48 | #include "llimview.h" | 48 | #include "llimview.h" |
49 | #include "llmediaremotectrl.h" | 49 | #include "llmediaremotectrl.h" |
@@ -75,60 +75,10 @@ LLOverlayBar *gOverlayBar = NULL; | |||
75 | 75 | ||
76 | extern S32 MENU_BAR_HEIGHT; | 76 | extern S32 MENU_BAR_HEIGHT; |
77 | 77 | ||
78 | //awfixme | ||
79 | /* | ||
80 | class LLTitleObserver | ||
81 | : public LLMediaObserver | ||
82 | { | ||
83 | public: | ||
84 | void init(std::string url); | ||
85 | *//*virtual*//* void onMediaTitleChange(const EventType& event_in); | ||
86 | private: | ||
87 | LLMediaBase* mMediaSource; | ||
88 | }; | ||
89 | |||
90 | static LLTitleObserver sTitleObserver; | ||
91 | |||
92 | static LLRegisterWidget<LLMediaRemoteCtrl> r("media_remote"); | ||
93 | |||
94 | void LLTitleObserver::init(std::string url) | ||
95 | { | ||
96 | |||
97 | if (!gAudiop) | ||
98 | { | ||
99 | return; | ||
100 | } | ||
101 | |||
102 | mMediaSource = gAudiop->getStreamMedia(); // LLViewerMedia::getSource(); | ||
103 | |||
104 | if ( mMediaSource ) | ||
105 | { | ||
106 | mMediaSource->addObserver(this); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | //virtual | ||
111 | void LLTitleObserver::onMediaTitleChange(const EventType& event_in) | ||
112 | { | ||
113 | if ( !gSavedSettings.getBOOL("ShowStreamTitle") ) | ||
114 | { | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | LLChat chat; | ||
119 | //TODO: set this in XUI | ||
120 | std::string playing_msg = "Playing: " + event_in.getStringValue(); | ||
121 | chat.mText = playing_msg; | ||
122 | LLFloaterChat::addChat(chat, FALSE, FALSE); | ||
123 | } | ||
124 | */ | ||
125 | |||
126 | // | 78 | // |
127 | // Functions | 79 | // Functions |
128 | // | 80 | // |
129 | 81 | ||
130 | |||
131 | |||
132 | void* LLOverlayBar::createMediaRemote(void* userdata) | 82 | void* LLOverlayBar::createMediaRemote(void* userdata) |
133 | { | 83 | { |
134 | LLOverlayBar *self = (LLOverlayBar*)userdata; | 84 | LLOverlayBar *self = (LLOverlayBar*)userdata; |
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 237a967..64a2308 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp | |||
@@ -39,7 +39,7 @@ | |||
39 | #else | 39 | #else |
40 | # include <sys/stat.h> // mkdir() | 40 | # include <sys/stat.h> // mkdir() |
41 | #endif | 41 | #endif |
42 | 42 | #include "llpluginclassmediaowner.h" | |
43 | #include "llviewermedia_streamingaudio.h" | 43 | #include "llviewermedia_streamingaudio.h" |
44 | #include "llaudioengine.h" | 44 | #include "llaudioengine.h" |
45 | 45 | ||
diff --git a/linden/indra/newview/llviewermedia_streamingaudio.cpp b/linden/indra/newview/llviewermedia_streamingaudio.cpp index 06946da..575dbc8 100644 --- a/linden/indra/newview/llviewermedia_streamingaudio.cpp +++ b/linden/indra/newview/llviewermedia_streamingaudio.cpp | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "linden_common.h" | 36 | #include "linden_common.h" |
37 | #include "llpluginclassmedia.h" | 37 | #include "llpluginclassmedia.h" |
38 | #include "llviewermedia.h" | 38 | #include "llviewermedia.h" |
39 | #include "llviewercontrol.h" | ||
39 | 40 | ||
40 | #include "llviewermedia_streamingaudio.h" | 41 | #include "llviewermedia_streamingaudio.h" |
41 | 42 | ||
@@ -43,6 +44,8 @@ | |||
43 | #include "llvfs.h" | 44 | #include "llvfs.h" |
44 | #include "lldir.h" | 45 | #include "lldir.h" |
45 | 46 | ||
47 | #include "llchat.h" | ||
48 | #include "llfloaterchat.h" | ||
46 | 49 | ||
47 | LLStreamingAudio_MediaPlugins::LLStreamingAudio_MediaPlugins() : | 50 | LLStreamingAudio_MediaPlugins::LLStreamingAudio_MediaPlugins() : |
48 | mMediaPlugin(NULL), | 51 | mMediaPlugin(NULL), |
@@ -153,9 +156,26 @@ std::string LLStreamingAudio_MediaPlugins::getURL() | |||
153 | return mURL; | 156 | return mURL; |
154 | } | 157 | } |
155 | 158 | ||
159 | void LLStreamingAudio_MediaPlugins::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) | ||
160 | { | ||
161 | if (event == MEDIA_EVENT_NAME_CHANGED) | ||
162 | { | ||
163 | std::string title = self->getMediaName(); | ||
164 | if (!title.empty() && gSavedSettings.getBOOL("ShowStreamTitle")) | ||
165 | { | ||
166 | //llinfos << "Playing: " << title << llendl; | ||
167 | LLChat chat; | ||
168 | //TODO: set this in XUI | ||
169 | std::string playing_msg = "Playing: " + title; | ||
170 | chat.mText = playing_msg; | ||
171 | LLFloaterChat::addChat(chat, FALSE, FALSE); | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | |||
156 | LLPluginClassMedia* LLStreamingAudio_MediaPlugins::initializeMedia(const std::string& media_type) | 176 | LLPluginClassMedia* LLStreamingAudio_MediaPlugins::initializeMedia(const std::string& media_type) |
157 | { | 177 | { |
158 | LLPluginClassMediaOwner* owner = NULL; | 178 | LLPluginClassMediaOwner* owner = this; |
159 | S32 default_size = 1; // audio-only - be minimal, doesn't matter | 179 | S32 default_size = 1; // audio-only - be minimal, doesn't matter |
160 | LLPluginClassMedia* media_source = LLViewerMediaImpl::newSourceFromMediaType(media_type, owner, default_size, default_size); | 180 | LLPluginClassMedia* media_source = LLViewerMediaImpl::newSourceFromMediaType(media_type, owner, default_size, default_size); |
161 | 181 | ||
diff --git a/linden/indra/newview/llviewermedia_streamingaudio.h b/linden/indra/newview/llviewermedia_streamingaudio.h index 270bab7..816e213 100644 --- a/linden/indra/newview/llviewermedia_streamingaudio.h +++ b/linden/indra/newview/llviewermedia_streamingaudio.h | |||
@@ -36,12 +36,13 @@ | |||
36 | 36 | ||
37 | 37 | ||
38 | #include "stdtypes.h" // from llcommon | 38 | #include "stdtypes.h" // from llcommon |
39 | |||
40 | #include "llstreamingaudio.h" | 39 | #include "llstreamingaudio.h" |
41 | 40 | ||
42 | class LLPluginClassMedia; | 41 | class LLPluginClassMedia; |
43 | 42 | ||
44 | class LLStreamingAudio_MediaPlugins : public LLStreamingAudioInterface | 43 | class LLStreamingAudio_MediaPlugins : |
44 | public LLStreamingAudioInterface, | ||
45 | public LLPluginClassMediaOwner | ||
45 | { | 46 | { |
46 | public: | 47 | public: |
47 | LLStreamingAudio_MediaPlugins(); | 48 | LLStreamingAudio_MediaPlugins(); |
@@ -56,14 +57,17 @@ class LLStreamingAudio_MediaPlugins : public LLStreamingAudioInterface | |||
56 | /*virtual*/ F32 getGain(); | 57 | /*virtual*/ F32 getGain(); |
57 | /*virtual*/ std::string getURL(); | 58 | /*virtual*/ std::string getURL(); |
58 | 59 | ||
60 | // inherited from LLPluginClassMediaOwner | ||
61 | /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); | ||
62 | |||
59 | private: | 63 | private: |
60 | LLPluginClassMedia* initializeMedia(const std::string& media_type); | 64 | LLPluginClassMedia* initializeMedia(const std::string& media_type); |
61 | 65 | ||
62 | LLPluginClassMedia *mMediaPlugin; | 66 | LLPluginClassMedia *mMediaPlugin; |
63 | |||
64 | std::string mURL; | 67 | std::string mURL; |
65 | F32 mGain; | 68 | F32 mGain; |
66 | }; | 69 | }; |
67 | 70 | ||
68 | 71 | ||
72 | |||
69 | #endif //LL_VIEWERMEDIA_STREAMINGAUDIO_H | 73 | #endif //LL_VIEWERMEDIA_STREAMINGAUDIO_H |